Save dark mode to session; auto-save session (Noded/backend#17)
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Garrett Mills 2020-10-20 10:15:00 -05:00
parent e1c666e3ad
commit 5053632bf6
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
3 changed files with 120 additions and 8 deletions

View File

@ -55,7 +55,7 @@ steps:
- cd www - cd www
- sed -i 's/<base href="\\/" \\/>/<base href="\\/i\\/"\\/>/' index.html - sed -i 's/<base href="\\/" \\/>/<base href="\\/i\\/"\\/>/' index.html
- sed -i 's/Ionic App/Noded/' index.html - sed -i 's/Ionic App/Noded/' index.html
- echo -n '${DRONE_TAG}-staging' | sudo tee version.html - echo -n "$(uuidgen)" | sudo tee version.html
when: when:
event: promote event: promote
target: staging target: staging
@ -93,7 +93,7 @@ steps:
- cd www - cd www
- sed -i 's/<base href="\\/" \\/>/<base href="\\/i\\/"\\/>/' index.html - sed -i 's/<base href="\\/" \\/>/<base href="\\/i\\/"\\/>/' index.html
- sed -i 's/Ionic App/Noded/' index.html - sed -i 's/Ionic App/Noded/' index.html
- echo -n '${DRONE_TAG}-prod' | sudo tee version.html - echo -n "$(uuidgen)" | sudo tee version.html
when: when:
event: promote event: promote
target: production target: production

View File

@ -36,12 +36,7 @@ export class AppComponent implements OnInit {
actionMapping: { actionMapping: {
mouse: { mouse: {
dblClick: (tree, node, $event) => { dblClick: (tree, node, $event) => {
const id = node.data.id; this.navigateEditorToNode(node);
const nodeId = node.data.node_id;
if ( !node.data.virtual ) {
this.currentPageId = id;
this.router.navigate(['/editor', { id, ...(nodeId ? { node_id: nodeId } : {}) }]);
}
}, },
click: (tree, node, $event) => { click: (tree, node, $event) => {
TREE_ACTIONS.FOCUS(tree, node, $event); TREE_ACTIONS.FOCUS(tree, node, $event);
@ -165,6 +160,19 @@ export class AppComponent implements OnInit {
this.hasSearchOpen = false; this.hasSearchOpen = false;
} }
public navigateEditorToNode(node: any) {
if ( !node.data ) {
node = { data: node };
}
const id = node.data.id;
const nodeId = node.data.node_id;
if ( !node.data.virtual ) {
this.currentPageId = id;
this.router.navigate(['/editor', { id, ...(nodeId ? { node_id: nodeId } : {}) }]);
}
}
async onNodeMenuClick($event) { async onNodeMenuClick($event) {
let canManage = this.menuTarget.data.level === 'manage'; let canManage = this.menuTarget.data.level === 'manage';
if ( !canManage ) { if ( !canManage ) {
@ -368,6 +376,7 @@ export class AppComponent implements OnInit {
} }
async initializeApp() { async initializeApp() {
console.log('session', this);
this.loader = await this.loading.create({ this.loader = await this.loading.create({
message: 'Starting up...', message: 'Starting up...',
cssClass: 'noded-loading-mask', cssClass: 'noded-loading-mask',
@ -388,17 +397,46 @@ export class AppComponent implements OnInit {
this.session.systemBase = stat.system_base; this.session.systemBase = stat.system_base;
await this.session.initialize(); await this.session.initialize();
if ( this.session.get('user.preferences.dark_mode') ) {
this.toggleDark();
}
await this.statusBar.styleDefault(); await this.statusBar.styleDefault();
await this.splashScreen.hide(); await this.splashScreen.hide();
this.initialized$.next(true); this.initialized$.next(true);
if ( this.session.get('user.preferences.default_page') ) {
const id = this.session.get('user.preferences.default_page');
const node = this.findNode(id);
if ( node ) {
this.navigateEditorToNode(node);
}
}
} }
toggleDark() { toggleDark() {
// const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); // const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
this.darkMode = !this.darkMode; this.darkMode = !this.darkMode;
this.session.set('user.preferences.dark_mode', this.darkMode);
document.body.classList.toggle('dark', this.darkMode); document.body.classList.toggle('dark', this.darkMode);
} }
findNode(id: string, nodes = this.nodes) {
for ( const node of nodes ) {
if ( node.id === id ) {
return node;
}
if ( node.children ) {
const foundNode = this.findNode(id, node.children);
if ( foundNode ) {
return foundNode;
}
}
}
}
isDark() { isDark() {
return !!this.darkMode; return !!this.darkMode;
} }

View File

@ -1,5 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {ApiService} from './api.service'; import {ApiService} from './api.service';
import {debounce} from './editor.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -8,6 +9,22 @@ export class SessionService {
public appName!: string; public appName!: string;
public systemBase!: string; public systemBase!: string;
protected data: any = {}; protected data: any = {};
protected saveTriggered = false;
protected saving = false;
protected privTriggerSave = debounce(() => {
if ( this.saving ) {
this.triggerSave();
} else {
this.save();
}
this.saveTriggered = false;
}, 3000);
public triggerSave() {
this.saveTriggered = true;
this.privTriggerSave();
}
constructor( constructor(
protected readonly api: ApiService, protected readonly api: ApiService,
@ -30,6 +47,22 @@ export class SessionService {
}); });
} }
async save() {
this.saving = true;
return new Promise((res, rej) => {
this.api.post('/session', this.data || {}).subscribe({
next: result => {
res();
this.saving = false;
},
error: (e) => {
this.saving = false;
rej(e);
},
});
});
}
buildAppUrl(...parts: string[]): string { buildAppUrl(...parts: string[]): string {
parts = parts.map(x => { parts = parts.map(x => {
if ( x.startsWith('/') ) { if ( x.startsWith('/') ) {
@ -45,4 +78,45 @@ export class SessionService {
return `${this.systemBase}${this.systemBase.endsWith('/') ? '' : '/'}${parts.join('/')}`; return `${this.systemBase}${this.systemBase.endsWith('/') ? '' : '/'}${parts.join('/')}`;
} }
get(path?: string): any {
let current: any = this.data;
if ( !path ) {
return current;
}
const parts = path.split('.');
for ( const part of parts ) {
current = current?.[part];
}
return current;
}
set(pathOrValue: string | any, value?: any): any {
if ( typeof pathOrValue !== 'string' ) {
this.data = pathOrValue;
return;
}
if ( typeof value === 'undefined' ) {
return;
}
const parts = pathOrValue.split('.');
let last;
let current = this.data;
for ( const part of parts ) {
last = current;
current = current?.[part];
}
parts.reverse();
if ( last ) {
last[parts[0]] = value;
}
this.triggerSave();
}
} }