When login don't reload the whole browser. Just rebuilt screens

This commit is contained in:
djmaze 2021-11-01 11:24:11 +01:00
parent d3500e2921
commit e52addf346
16 changed files with 74 additions and 57 deletions

View file

@ -1,9 +1,6 @@
import ko from 'ko'; import ko from 'ko';
import { import { Settings, SettingsGet } from 'Common/Globals';
elementById,
Settings
} from 'Common/Globals';
import { logoutLink } from 'Common/Links'; import { logoutLink } from 'Common/Links';
import { i18nToNodes, initOnStartOrLangChange } from 'Common/Translator'; import { i18nToNodes, initOnStartOrLangChange } from 'Common/Translator';
@ -37,6 +34,12 @@ export class AbstractApp {
} }
} }
refresh() {
// rl.adminArea() || !translatorReload(false, );
rl.adminArea() || LanguageStore.language(SettingsGet('Language'));
this.start();
}
bootstart() { bootstart() {
const register = (key, ClassObject, templateID) => ko.components.register(key, { const register = (key, ClassObject, templateID) => ko.components.register(key, {
template: { element: templateID || (key + 'Component') }, template: { element: templateID || (key + 'Component') },
@ -68,14 +71,7 @@ export class AbstractApp {
LanguageStore.populate(); LanguageStore.populate();
ThemeStore.populate(); ThemeStore.populate();
}
/** this.start();
* @returns {void}
*/
hideLoading() {
elementById('rl-content').hidden = false;
elementById('rl-loading').remove();
} }
} }

View file

@ -16,8 +16,7 @@ class AdminApp extends AbstractApp {
this.weakPassword = ko.observable(false); this.weakPassword = ko.observable(false);
} }
bootstart() { start() {
super.bootstart();
if (!Settings.app('allowAdminPanel')) { if (!Settings.app('allowAdminPanel')) {
rl.route.root(); rl.route.root();
setTimeout(() => location.href = '/', 1); setTimeout(() => location.href = '/', 1);
@ -27,7 +26,6 @@ class AdminApp extends AbstractApp {
} else { } else {
startScreens([LoginAdminScreen]); startScreens([LoginAdminScreen]);
} }
this.hideLoading();
} }
} }

View file

@ -1,6 +1,6 @@
import 'External/User/ko'; import 'External/User/ko';
import { isArray, arrayLength, pInt, pString } from 'Common/Utils'; import { isArray, arrayLength, pInt, pString, forEachObjectValue } from 'Common/Utils';
import { isPosNumeric, delegateRunOnDestroy, mailToHelper } from 'Common/UtilsUser'; import { isPosNumeric, delegateRunOnDestroy, mailToHelper } from 'Common/UtilsUser';
import { import {
@ -187,7 +187,7 @@ class AppUser extends AbstractApp {
const sTrashFolder = FolderUserStore.trashFolder(), const sTrashFolder = FolderUserStore.trashFolder(),
sSpamFolder = FolderUserStore.spamFolder(); sSpamFolder = FolderUserStore.spamFolder();
Object.values(this.moveCache).forEach(item => { forEachObjectValue(this.moveCache, item => {
const isSpam = sSpamFolder === item.To, const isSpam = sSpamFolder === item.To,
isTrash = sTrashFolder === item.To, isTrash = sTrashFolder === item.To,
isHam = !isSpam && sSpamFolder === item.From && getFolderInboxName() === item.To; isHam = !isSpam && sSpamFolder === item.From && getFolderInboxName() === item.To;
@ -810,7 +810,9 @@ class AppUser extends AbstractApp {
return event.returnValue = "Are you sure you want to exit?"; return event.returnValue = "Are you sure you want to exit?";
} }
}, {capture: true}); }, {capture: true});
}
start() {
if (SettingsGet('Auth')) { if (SettingsGet('Auth')) {
rl.setWindowTitle(i18n('GLOBAL/LOADING')); rl.setWindowTitle(i18n('GLOBAL/LOADING'));
@ -830,7 +832,6 @@ class AppUser extends AbstractApp {
MailBoxUserScreen, MailBoxUserScreen,
SettingsUserScreen SettingsUserScreen
]); ]);
this.hideLoading();
setInterval(() => { setInterval(() => {
const cF = FolderUserStore.currentFolderFullNameRaw(), const cF = FolderUserStore.currentFolderFullNameRaw(),
@ -916,7 +917,6 @@ class AppUser extends AbstractApp {
} else { } else {
startScreens([LoginUserScreen]); startScreens([LoginUserScreen]);
this.hideLoading();
} }
} }

View file

@ -133,7 +133,7 @@ export const
* @param {boolean} admin * @param {boolean} admin
* @param {string} language * @param {string} language
*/ */
reload = (admin, language) => translatorReload = (admin, language) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
const script = createElement('script'); const script = createElement('script');
script.onload = () => { script.onload = () => {

View file

@ -10,6 +10,8 @@ export const
isFunction = v => typeof v === 'function', isFunction = v => typeof v === 'function',
pString = value => null != value ? '' + value : '', pString = value => null != value ? '' + value : '',
forEachObjectValue = (obj, fn) => Object.values(obj).forEach(fn),
pInt = (value, defaultValue = 0) => { pInt = (value, defaultValue = 0) => {
value = parseInt(value, 10); value = parseInt(value, 10);
return isNaN(value) || !isFinite(value) ? defaultValue : value; return isNaN(value) || !isFinite(value) ? defaultValue : value;

View file

@ -1,4 +1,4 @@
import { isArray, isFunction, addObservablesTo, addComputablesTo } from 'Common/Utils'; import { isArray, isFunction, addObservablesTo, addComputablesTo, forEachObjectValue } from 'Common/Utils';
function dispose(disposable) { function dispose(disposable) {
if (disposable && isFunction(disposable.dispose)) { if (disposable && isFunction(disposable.dispose)) {
@ -52,7 +52,7 @@ export class AbstractModel {
this.subscribables.forEach(dispose); this.subscribables.forEach(dispose);
/** clear object entries */ /** clear object entries */
// Object.entries(this).forEach(([key, value]) => { // Object.entries(this).forEach(([key, value]) => {
Object.values(this).forEach(value => { forEachObjectValue(this, value => {
/** clear CollectionModel */ /** clear CollectionModel */
let arr = ko.isObservableArray(value) ? value() : value; let arr = ko.isObservableArray(value) ? value() : value;
arr && arr.onDestroy && value.onDestroy(); arr && arr.onDestroy && value.onDestroy();

View file

@ -1,12 +1,14 @@
import ko from 'ko'; import ko from 'ko';
import { doc, $htmlCL } from 'Common/Globals'; import { doc, $htmlCL, elementById } from 'Common/Globals';
import { isFunction } from 'Common/Utils'; import { isFunction, forEachObjectValue } from 'Common/Utils';
let currentScreen = null, let
SCREENS = {},
currentScreen = null,
defaultScreenName = ''; defaultScreenName = '';
const SCREENS = {}, const
autofocus = dom => { autofocus = dom => {
const af = dom.querySelector('[autofocus]'); const af = dom.querySelector('[autofocus]');
af && af.focus(); af && af.focus();
@ -123,6 +125,15 @@ const SCREENS = {},
}); });
}, },
hideScreen = (screenToHide, destroy) => {
screenToHide.onHide && screenToHide.onHide();
forEachViewModel(screenToHide, (vm, dom) => {
dom.hidden = true;
vm.onHide && vm.onHide();
destroy && vm.viewModelDom.remove();
});
},
/** /**
* @param {string} screenName * @param {string} screenName
* @param {string} subPart * @param {string} subPart
@ -167,12 +178,7 @@ const SCREENS = {},
setTimeout(() => { setTimeout(() => {
// hide screen // hide screen
if (currentScreen && !isSameScreen) { if (currentScreen && !isSameScreen) {
currentScreen.onHide && currentScreen.onHide(); hideScreen(currentScreen);
forEachViewModel(currentScreen, (vm, dom) => {
dom.hidden = true;
vm.onHide && vm.onHide();
});
} }
// -- // --
@ -275,6 +281,12 @@ export const
* @returns {void} * @returns {void}
*/ */
startScreens = screensClasses => { startScreens = screensClasses => {
hasher.clear();
forEachObjectValue(SCREENS, screen => hideScreen(screen, 1));
SCREENS = {};
currentScreen = null,
defaultScreenName = '';
screensClasses.forEach(CScreen => { screensClasses.forEach(CScreen => {
if (CScreen) { if (CScreen) {
const vmScreen = new CScreen(), const vmScreen = new CScreen(),
@ -284,7 +296,7 @@ export const
} }
}); });
Object.values(SCREENS).forEach(vmScreen => vmScreen.onStart()); forEachObjectValue(SCREENS, vmScreen => vmScreen.onStart());
const cross = new Crossroads(); const cross = new Crossroads();
cross.addRoute(/^([a-zA-Z0-9-]*)\/?(.*)$/, screenOnRoute); cross.addRoute(/^([a-zA-Z0-9-]*)\/?(.*)$/, screenOnRoute);
@ -294,6 +306,10 @@ export const
setTimeout(() => $htmlCL.remove('rl-started-trigger'), 100); setTimeout(() => $htmlCL.remove('rl-started-trigger'), 100);
setTimeout(() => $htmlCL.add('rl-started-delay'), 200); setTimeout(() => $htmlCL.add('rl-started-delay'), 200);
const c = elementById('rl-content'), l = elementById('rl-loading');
c && (c.hidden = false);
l && l.remove();
}, },
decorateKoCommands = (thisArg, commands) => decorateKoCommands = (thisArg, commands) =>

View file

@ -13,7 +13,7 @@ import {
import { Capa, SaveSettingsStep } from 'Common/Enums'; import { Capa, SaveSettingsStep } from 'Common/Enums';
import { Settings, SettingsGet } from 'Common/Globals'; import { Settings, SettingsGet } from 'Common/Globals';
import { reload as translatorReload, convertLangName } from 'Common/Translator'; import { translatorReload, convertLangName } from 'Common/Translator';
import { showScreenPopup } from 'Knoin/Knoin'; import { showScreenPopup } from 'Knoin/Knoin';

View file

@ -1,7 +1,7 @@
import ko from 'ko'; import ko from 'ko';
import { getNotification } from 'Common/Translator'; import { getNotification } from 'Common/Translator';
import { addObservablesTo } from 'Common/Utils'; import { addObservablesTo, forEachObjectValue } from 'Common/Utils';
import { delegateRunOnDestroy } from 'Common/UtilsUser'; import { delegateRunOnDestroy } from 'Common/UtilsUser';
import { SieveUserStore } from 'Stores/User/Sieve'; import { SieveUserStore } from 'Stores/User/Sieve';
@ -50,7 +50,7 @@ export class FiltersUserSettings /*extends AbstractViewSettings*/ {
data.Result.Scripts.map(aItem => SieveScriptModel.reviveFromJson(aItem)).filter(v => v) data.Result.Scripts.map(aItem => SieveScriptModel.reviveFromJson(aItem)).filter(v => v)
); );
*/ */
Object.values(data.Result.Scripts).forEach(value => { forEachObjectValue(data.Result.Scripts, value => {
value = SieveScriptModel.reviveFromJson(value); value = SieveScriptModel.reviveFromJson(value);
value && this.scripts.push(value) value && this.scripts.push(value)
}); });

View file

@ -4,7 +4,7 @@ import { SaveSettingsStep } from 'Common/Enums';
import { EditorDefaultType, Layout } from 'Common/EnumsUser'; import { EditorDefaultType, Layout } from 'Common/EnumsUser';
import { Settings, SettingsGet } from 'Common/Globals'; import { Settings, SettingsGet } from 'Common/Globals';
import { isArray, settingsSaveHelperSimpleFunction, addObservablesTo, addSubscribablesTo, addComputablesTo } from 'Common/Utils'; import { isArray, settingsSaveHelperSimpleFunction, addObservablesTo, addSubscribablesTo, addComputablesTo } from 'Common/Utils';
import { i18n, trigger as translatorTrigger, reload as translatorReload, convertLangName } from 'Common/Translator'; import { i18n, trigger as translatorTrigger, translatorReload, convertLangName } from 'Common/Translator';
import { showScreenPopup } from 'Knoin/Knoin'; import { showScreenPopup } from 'Knoin/Knoin';

View file

@ -51,12 +51,12 @@ class LoginAdminView extends AbstractViewCenter {
this.submitRequest(true); this.submitRequest(true);
Remote.adminLogin( Remote.adminLogin(
iError => { (iError, oData) => {
if (iError) { if (iError) {
this.submitRequest(false); this.submitRequest(false);
this.submitError(getNotification(iError)); this.submitError(getNotification(iError));
} else { } else {
rl.route.reload(); rl.setData(oData.Result);
} }
}, },
name, name,

View file

@ -3,7 +3,7 @@ import ko from 'ko';
import { Notification } from 'Common/Enums'; import { Notification } from 'Common/Enums';
import { ClientSideKeyName } from 'Common/EnumsUser'; import { ClientSideKeyName } from 'Common/EnumsUser';
import { Settings, SettingsGet } from 'Common/Globals'; import { Settings, SettingsGet } from 'Common/Globals';
import { getNotification, reload as translatorReload, convertLangName } from 'Common/Translator'; import { getNotification, translatorReload, convertLangName } from 'Common/Translator';
import { LanguageStore } from 'Stores/Language'; import { LanguageStore } from 'Stores/Language';
@ -116,7 +116,8 @@ class LoginUserView extends AbstractViewCenter {
Notification.UnknownNotification)); Notification.UnknownNotification));
this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || ''); this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || '');
} else { } else {
rl.route.reload(); rl.setData(oData.Result);
// rl.route.reload();
} }
}, },
data data

View file

@ -68,6 +68,11 @@ win.rl = {
showError(e.message); showError(e.message);
throw e; throw e;
}); });
},
setData: appData => {
RL_APP_DATA = appData;
rl.app.refresh();
} }
}; };

View file

@ -198,7 +198,7 @@ trait Admin
$sToken = $this->getAdminToken(); $sToken = $this->getAdminToken();
$this->setAdminAuthToken($sToken); $this->setAdminAuthToken($sToken);
return $this->DefaultResponse(__FUNCTION__, $sToken ? true : false); return $this->DefaultResponse(__FUNCTION__, $sToken ? $this->AppData(true) : false);
} }
public function DoAdminLogout() : array public function DoAdminLogout() : array

View file

@ -58,7 +58,7 @@ trait User
} }
} }
return $this->TrueResponse(__FUNCTION__); return $this->DefaultResponse(__FUNCTION__, $this->AppData(false));
} }
/** /**

View file

@ -11,8 +11,6 @@
// Private // Private
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
var _hash, _bindings = [];
const const
_hashValRegexp = /#(.*)$/, _hashValRegexp = /#(.*)$/,
_hashRegexp = /^#/, _hashRegexp = /^#/,
@ -44,11 +42,12 @@
// we should store raw value // we should store raw value
_registerChange(path); _registerChange(path);
if (path === _hash) { if (path === _hash) {
path = '#' + encodeURI(path)
// we check if path is still === _hash to avoid error in // we check if path is still === _hash to avoid error in
// case of multiple consecutive redirects [issue #39] // case of multiple consecutive redirects [issue #39]
replace replace
? location.replace('#' + encodeURI(path)) ? location.replace(path)
: (location.hash = '#' + encodeURI(path)); : (location.hash = path);
} }
} }
}, },
@ -58,6 +57,10 @@
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
hasher = /** @lends hasher */ { hasher = /** @lends hasher */ {
clear : () => {
_bindings = [];
hasher.active = true;
},
/** /**
* Signal dispatched when hash value changes. * Signal dispatched when hash value changes.
@ -74,16 +77,7 @@
* <li>hasher won't dispatch CHANGE events by manually typing a new value or pressing the back/forward buttons before calling this method.</li> * <li>hasher won't dispatch CHANGE events by manually typing a new value or pressing the back/forward buttons before calling this method.</li>
* </ul> * </ul>
*/ */
init : () => { init : () => hasher.dispatch(_trimHash(_hash)),
hasher.init = ()=>0;
_hash = _getWindowHash();
//thought about branching/overloading hasher.init() to avoid checking multiple times but
//don't think worth doing it since it probably won't be called multiple times.
addEventListener('hashchange', _checkHistory);
hasher.dispatch(_trimHash(_hash));
},
/** /**
* Set Hash value, generating a new history record. * Set Hash value, generating a new history record.
@ -101,5 +95,10 @@
replaceHash : (...path) => _setHash(path, true) replaceHash : (...path) => _setHash(path, true)
}; };
var _hash = _getWindowHash(),
_bindings = [];
addEventListener('hashchange', _checkHistory);
global.hasher = hasher; global.hasher = hasher;
})(this); })(this);