Skip to content

Commit

Permalink
Added welcome page
Browse files Browse the repository at this point in the history
  • Loading branch information
VatMart committed Aug 6, 2024
1 parent b0d7c66 commit 90b8c3e
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 27 deletions.
37 changes: 35 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {ToolBarComponent} from "./component/tool-bar/tool-bar.component";
import {CanvasComponent} from "./component/canvas/canvas.component";
import {TabNavComponent} from "./component/tab-nav/tab-nav.component";
Expand All @@ -22,6 +22,7 @@ import {
FloatAnimationToolbarComponent
} from "./component/canvas/float-animation-toolbar/float-animation-toolbar.component";
import {ApplicationManagerService} from "./service/manager/application-manager.service";
import {LocalStorageService} from "./service/local-storage.service";

/**
* Main component of the application.
Expand All @@ -35,7 +36,7 @@ import {ApplicationManagerService} from "./service/manager/application-manager.s
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent implements OnInit, OnDestroy {
export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
private subscriptions!: Subscription;
@ViewChild('floatingEdgeWeightInput') floatingEdgeWeightInput!: FloatEdgeWeightInputComponent;
title = 'GraphWeb';
Expand All @@ -48,6 +49,7 @@ export class AppComponent implements OnInit, OnDestroy {

constructor(private applicationManager: ApplicationManagerService,
private graphService: GraphViewService,
private localStorageService: LocalStorageService,
private importService: ImportService,
private pixiManager: PixiManagerService,
private environmentService: EnvironmentService,
Expand All @@ -58,6 +60,7 @@ export class AppComponent implements OnInit, OnDestroy {
}

ngOnInit(): void {
// Initialize subscriptions
this.subscriptions = new Subscription();
// On notify error event
this.subscriptions.add(
Expand Down Expand Up @@ -157,11 +160,41 @@ export class AppComponent implements OnInit, OnDestroy {
this.applicationManager.initSubscriptions();
}

ngAfterViewInit(): void {
this.onAppInit();
}

ngOnDestroy(): void {
this.subscriptions.unsubscribe();
this.applicationManager.destroySubscriptions();
}

private onAppInit() {
// Show welcome dialog if needed
const lastAppUpload = this.localStorageService.getLastUploadAppTime();
const currentTime = Date.now();
if (lastAppUpload !== 0) {
// Check if the app was uploaded today
const lastAppUploadDate = new Date(lastAppUpload);
const currentUploadDate = new Date(currentTime);
// Difference in milliseconds
const differenceInMilliseconds = currentUploadDate.getTime() - lastAppUploadDate.getTime();
// Milliseconds in one day (24 hours)
const millisecondsInOneDay = 24 * 60 * 60 * 1000;
// Check if the difference is greater than one day
const isMoreThanOneDay = differenceInMilliseconds > millisecondsInOneDay;
if (isMoreThanOneDay) {
// Show welcome dialog
this.stateService.showWelcomeDialog();
}
} else { // First time app upload
// Show welcome dialog
this.stateService.showWelcomeDialog();
}
// Save current time
this.localStorageService.saveLastUploadAppTime(currentTime);
}

private notifyError(value: string) {
this.messageService.add({severity: 'error', summary: 'Error', detail: value, life: 5000});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
.welcome-page {
display: flex;
flex-direction: column;
justify-content: flex-start;
height: 95%;
background-color: white;
border-radius: 25px;
box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
overflow: hidden;
}

.header-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 100%;
padding: 20px 20px 0 20px;
}

.logo-container {
display: flex;
align-items: center;
padding-inline: 10px;
border-radius: 10px;
}

.image-container {
display: flex;
align-items: center;
border-radius: 50%;
padding: 10px;
background-color: var(--main-button-color);
}

.logo {
max-width: 40px;
max-height: 40px;
}

h1 {
margin-left: 8px;
text-align: center;
}

.welcome-page-content {
display: flex;
flex-direction: column;
overflow: auto;
padding: 20px;
}

h2 {
font-weight: 300;
}

.demo-container {
display: flex;
flex-direction: row;
max-width: 1600px;
flex-wrap: wrap;
justify-content: space-around;
margin-bottom: 10px;
}

.demo-image-container {
flex: 1 1 300px;
max-width: 45%;
display: flex;
flex-direction: column;
align-items: center;
margin-inline: 8px;
}

.demo-label {
font-weight: bold;
margin-block: 16px;
}

.demo-image {
width: 100%;
aspect-ratio: 1 / 1;
border-radius: 15px;
box-shadow: rgba(0, 0, 0, 0.2) 0px 18px 50px -10px;
overflow: hidden;
}

.demo-image img {
width: 100%;
height: 100%;
object-fit: cover; /* Ensures the image covers the entire container */
border-radius: inherit;
}

@media (max-width: 600px) {
.demo-image-container {
flex: 1 1 80%; /* Make images larger on smaller screens */
max-width: 80%; /* Allow images to take more space */
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<div class="welcome-page">
<header class="header-container">
<span class="logo-container">
<span class="image-container">
<img [ngSrc]="'assets/logo_white.png'" alt="Logo"
class="logo" height="251" width="249"/>
</span>
<h1 class="logo-label">GraphWeb</h1>
</span>
<p-button icon="pi pi-times" class="move-right" [rounded]="true" [text]="true" severity="danger"
(onClick)="ref.close();"/>
</header>

<div class="welcome-page-content">
<div class="subheader-container">
<h2>Visualize algorithms</h2>
</div>
<div class="demo-container">
<div class="demo-image-container">
<label class="demo-label">See full animation of algorithm</label>
<img [src]="'assets/gifs/DFSAnimation.gif'" alt="DFSAlgorithm" class="demo-image">
</div>
<div class="demo-image-container">
<label class="demo-label">...Or control animation with player</label>
<img [src]="'assets/gifs/ManageAnimationWithPlayer.gif'" alt="ManageAnimationWithPlayer" class="demo-image">
</div>
</div>
<div class="subheader-container">
<h2>Force Layout</h2>
</div>
<div class="demo-container">
<div class="demo-image-container">
<label class="demo-label">Enable Force layout to improve graph readability</label>
<img [src]="'assets/gifs/ForceLayoutDemo.gif'" alt="ForceLayoutDemo" class="demo-image">
</div>
</div>
<div class="subheader-container">
<h2>Create graph</h2>
</div>
<div class="demo-container">
<div class="demo-image-container">
<label class="demo-label">Generate huge trees with different n-arity</label>
<img [src]="'assets/img/HugeBinaryTree.png'" alt="HugeBinaryTree" class="demo-image">
</div>
<div class="demo-image-container">
<label class="demo-label">...Or graph with different options</label>
<img [src]="'assets/gifs/GenerateGraph.gif'" alt="GenerateGraphWithOptions" class="demo-image">
</div>
<div class="demo-image-container">
<label class="demo-label">... Or draw graph as you like</label>
<img [src]="'assets/gifs/DrawGraph.gif'" alt="DrawGraph" class="demo-image">
</div>
</div>
<div class="subheader-container">
<h2>Customize graph</h2>
</div>
<div class="demo-container">
<div class="demo-image-container">
<label class="demo-label">Change colors, sizes, or apply ready-made style template</label>
<img [src]="'assets/img/CustomisationExample.png'" alt="CustomizeGraph" class="demo-image">
</div>
</div>
<div class="subheader-container">
<h2>More features</h2>
<ul>
<li>Save and load graphs</li>
<li>Export graph as image</li>
<li>Export graph as JSON</li>
<li>Import graph as JSON, matrix, set of vertices and edges</li>
<li>Matrices representations of graph (ability to save matrix)</li>
<li>And new features are coming soon!</li>
</ul>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component } from '@angular/core';
import {DynamicDialogRef} from "primeng/dynamicdialog";
import {Button} from "primeng/button";
import {NgIf, NgOptimizedImage} from "@angular/common";

@Component({
selector: 'app-welcome-page-dialog',
standalone: true,
imports: [
Button,
NgIf,
NgOptimizedImage
],
templateUrl: './welcome-page-dialog.component.html',
styleUrl: './welcome-page-dialog.component.css'
})
export class WelcomePageDialogComponent {

constructor(public ref: DynamicDialogRef) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ export class AlgorithmsViewComponent implements OnInit, OnDestroy {
}
];
this.isAlgorithmModeActive = this.stateService.isAlgorithmModeActive();
console.log('Algorithm mode active:', this.isAlgorithmModeActive);
this.selectedAlgItem = this.algorithmItems.find(item => item.id === this.selectedAlg.value)!;

// Init subscriptions
Expand Down
21 changes: 2 additions & 19 deletions src/app/component/tool-bar/tool-bar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,28 +414,11 @@ export class ToolBarComponent implements OnInit, OnDestroy {
}

private openAboutDialog() {
this.dialogService.open(AboutPageDialogComponent, {
contentStyle: {
overflow: 'auto',
['background-image']: 'url(\'../../../../assets/img/AboutPageBackground.webp\')',
['background-size']: 'cover',
['background-repeat']: 'no-repeat',
['background-position']: 'center',
['align-content']: 'center',
padding: '2% 5%'
},
width: '95vw',
height: '95vh',
modal: true,
focusOnShow: false,
dismissableMask: true,
showHeader: false,
});
this.stateService.showAboutDialog();
}

private openWelcomePage() {
console.log("Welcome page opened"); // TODO remove
// TODO
this.stateService.showWelcomeDialog();
}

onToggleAddVertexButton() {
Expand Down
20 changes: 20 additions & 0 deletions src/app/service/event/state.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ export class StateService {
private callExportAsPngSource = new Subject<ExportAsPngRequest>();
public callExportAsPng$ = this.callExportAsPngSource.asObservable();

private showWelcomeDialogSource = new Subject<boolean>();
public showWelcomeDialog$ = this.showWelcomeDialogSource.asObservable();

private showAboutDialogSource = new Subject<boolean>();
public showAboutDialog$ = this.showAboutDialogSource.asObservable();

// --------------------------------------------------
// UI component states. Tool bar
// --------------------------------------------------
Expand Down Expand Up @@ -391,6 +397,20 @@ export class StateService {
this.callExportAsPngSource.next(request);
}

/**
* Show the welcome dialog.
*/
showWelcomeDialog() {
this.showWelcomeDialogSource.next(true);
}

/**
* Show the about page dialog.
*/
showAboutDialog() {
this.showAboutDialogSource.next(true);
}

/**
* Reset the UI state.
*/
Expand Down
Loading

0 comments on commit 90b8c3e

Please sign in to comment.