mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-12-25 00:21:29 +08:00
When login don't reload the whole browser. Just rebuilt screens
This commit is contained in:
parent
d3500e2921
commit
e52addf346
16 changed files with 74 additions and 57 deletions
|
@ -1,9 +1,6 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import {
|
||||
elementById,
|
||||
Settings
|
||||
} from 'Common/Globals';
|
||||
import { Settings, SettingsGet } from 'Common/Globals';
|
||||
|
||||
import { logoutLink } from 'Common/Links';
|
||||
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() {
|
||||
const register = (key, ClassObject, templateID) => ko.components.register(key, {
|
||||
template: { element: templateID || (key + 'Component') },
|
||||
|
@ -68,14 +71,7 @@ export class AbstractApp {
|
|||
|
||||
LanguageStore.populate();
|
||||
ThemeStore.populate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
hideLoading() {
|
||||
elementById('rl-content').hidden = false;
|
||||
elementById('rl-loading').remove();
|
||||
this.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@ class AdminApp extends AbstractApp {
|
|||
this.weakPassword = ko.observable(false);
|
||||
}
|
||||
|
||||
bootstart() {
|
||||
super.bootstart();
|
||||
start() {
|
||||
if (!Settings.app('allowAdminPanel')) {
|
||||
rl.route.root();
|
||||
setTimeout(() => location.href = '/', 1);
|
||||
|
@ -27,7 +26,6 @@ class AdminApp extends AbstractApp {
|
|||
} else {
|
||||
startScreens([LoginAdminScreen]);
|
||||
}
|
||||
this.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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 {
|
||||
|
@ -187,7 +187,7 @@ class AppUser extends AbstractApp {
|
|||
const sTrashFolder = FolderUserStore.trashFolder(),
|
||||
sSpamFolder = FolderUserStore.spamFolder();
|
||||
|
||||
Object.values(this.moveCache).forEach(item => {
|
||||
forEachObjectValue(this.moveCache, item => {
|
||||
const isSpam = sSpamFolder === item.To,
|
||||
isTrash = sTrashFolder === 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?";
|
||||
}
|
||||
}, {capture: true});
|
||||
}
|
||||
|
||||
start() {
|
||||
if (SettingsGet('Auth')) {
|
||||
rl.setWindowTitle(i18n('GLOBAL/LOADING'));
|
||||
|
||||
|
@ -830,7 +832,6 @@ class AppUser extends AbstractApp {
|
|||
MailBoxUserScreen,
|
||||
SettingsUserScreen
|
||||
]);
|
||||
this.hideLoading();
|
||||
|
||||
setInterval(() => {
|
||||
const cF = FolderUserStore.currentFolderFullNameRaw(),
|
||||
|
@ -916,7 +917,6 @@ class AppUser extends AbstractApp {
|
|||
|
||||
} else {
|
||||
startScreens([LoginUserScreen]);
|
||||
this.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ export const
|
|||
* @param {boolean} admin
|
||||
* @param {string} language
|
||||
*/
|
||||
reload = (admin, language) =>
|
||||
translatorReload = (admin, language) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const script = createElement('script');
|
||||
script.onload = () => {
|
||||
|
|
|
@ -10,6 +10,8 @@ export const
|
|||
isFunction = v => typeof v === 'function',
|
||||
pString = value => null != value ? '' + value : '',
|
||||
|
||||
forEachObjectValue = (obj, fn) => Object.values(obj).forEach(fn),
|
||||
|
||||
pInt = (value, defaultValue = 0) => {
|
||||
value = parseInt(value, 10);
|
||||
return isNaN(value) || !isFinite(value) ? defaultValue : value;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { isArray, isFunction, addObservablesTo, addComputablesTo } from 'Common/Utils';
|
||||
import { isArray, isFunction, addObservablesTo, addComputablesTo, forEachObjectValue } from 'Common/Utils';
|
||||
|
||||
function dispose(disposable) {
|
||||
if (disposable && isFunction(disposable.dispose)) {
|
||||
|
@ -52,7 +52,7 @@ export class AbstractModel {
|
|||
this.subscribables.forEach(dispose);
|
||||
/** clear object entries */
|
||||
// Object.entries(this).forEach(([key, value]) => {
|
||||
Object.values(this).forEach(value => {
|
||||
forEachObjectValue(this, value => {
|
||||
/** clear CollectionModel */
|
||||
let arr = ko.isObservableArray(value) ? value() : value;
|
||||
arr && arr.onDestroy && value.onDestroy();
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { doc, $htmlCL } from 'Common/Globals';
|
||||
import { isFunction } from 'Common/Utils';
|
||||
import { doc, $htmlCL, elementById } from 'Common/Globals';
|
||||
import { isFunction, forEachObjectValue } from 'Common/Utils';
|
||||
|
||||
let currentScreen = null,
|
||||
let
|
||||
SCREENS = {},
|
||||
currentScreen = null,
|
||||
defaultScreenName = '';
|
||||
|
||||
const SCREENS = {},
|
||||
const
|
||||
autofocus = dom => {
|
||||
const af = dom.querySelector('[autofocus]');
|
||||
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} subPart
|
||||
|
@ -167,12 +178,7 @@ const SCREENS = {},
|
|||
setTimeout(() => {
|
||||
// hide screen
|
||||
if (currentScreen && !isSameScreen) {
|
||||
currentScreen.onHide && currentScreen.onHide();
|
||||
|
||||
forEachViewModel(currentScreen, (vm, dom) => {
|
||||
dom.hidden = true;
|
||||
vm.onHide && vm.onHide();
|
||||
});
|
||||
hideScreen(currentScreen);
|
||||
}
|
||||
// --
|
||||
|
||||
|
@ -275,6 +281,12 @@ export const
|
|||
* @returns {void}
|
||||
*/
|
||||
startScreens = screensClasses => {
|
||||
hasher.clear();
|
||||
forEachObjectValue(SCREENS, screen => hideScreen(screen, 1));
|
||||
SCREENS = {};
|
||||
currentScreen = null,
|
||||
defaultScreenName = '';
|
||||
|
||||
screensClasses.forEach(CScreen => {
|
||||
if (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();
|
||||
cross.addRoute(/^([a-zA-Z0-9-]*)\/?(.*)$/, screenOnRoute);
|
||||
|
@ -294,6 +306,10 @@ export const
|
|||
|
||||
setTimeout(() => $htmlCL.remove('rl-started-trigger'), 100);
|
||||
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) =>
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
|
||||
import { Capa, SaveSettingsStep } from 'Common/Enums';
|
||||
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';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { getNotification } from 'Common/Translator';
|
||||
import { addObservablesTo } from 'Common/Utils';
|
||||
import { addObservablesTo, forEachObjectValue } from 'Common/Utils';
|
||||
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
||||
|
||||
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)
|
||||
);
|
||||
*/
|
||||
Object.values(data.Result.Scripts).forEach(value => {
|
||||
forEachObjectValue(data.Result.Scripts, value => {
|
||||
value = SieveScriptModel.reviveFromJson(value);
|
||||
value && this.scripts.push(value)
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ import { SaveSettingsStep } from 'Common/Enums';
|
|||
import { EditorDefaultType, Layout } from 'Common/EnumsUser';
|
||||
import { Settings, SettingsGet } from 'Common/Globals';
|
||||
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';
|
||||
|
||||
|
|
|
@ -51,12 +51,12 @@ class LoginAdminView extends AbstractViewCenter {
|
|||
this.submitRequest(true);
|
||||
|
||||
Remote.adminLogin(
|
||||
iError => {
|
||||
(iError, oData) => {
|
||||
if (iError) {
|
||||
this.submitRequest(false);
|
||||
this.submitError(getNotification(iError));
|
||||
} else {
|
||||
rl.route.reload();
|
||||
rl.setData(oData.Result);
|
||||
}
|
||||
},
|
||||
name,
|
||||
|
|
|
@ -3,7 +3,7 @@ import ko from 'ko';
|
|||
import { Notification } from 'Common/Enums';
|
||||
import { ClientSideKeyName } from 'Common/EnumsUser';
|
||||
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';
|
||||
|
||||
|
@ -116,7 +116,8 @@ class LoginUserView extends AbstractViewCenter {
|
|||
Notification.UnknownNotification));
|
||||
this.submitErrorAddidional((oData && oData.ErrorMessageAdditional) || '');
|
||||
} else {
|
||||
rl.route.reload();
|
||||
rl.setData(oData.Result);
|
||||
// rl.route.reload();
|
||||
}
|
||||
},
|
||||
data
|
||||
|
|
|
@ -68,6 +68,11 @@ win.rl = {
|
|||
showError(e.message);
|
||||
throw e;
|
||||
});
|
||||
},
|
||||
|
||||
setData: appData => {
|
||||
RL_APP_DATA = appData;
|
||||
rl.app.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ trait Admin
|
|||
$sToken = $this->getAdminToken();
|
||||
$this->setAdminAuthToken($sToken);
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $sToken ? true : false);
|
||||
return $this->DefaultResponse(__FUNCTION__, $sToken ? $this->AppData(true) : false);
|
||||
}
|
||||
|
||||
public function DoAdminLogout() : array
|
||||
|
|
|
@ -58,7 +58,7 @@ trait User
|
|||
}
|
||||
}
|
||||
|
||||
return $this->TrueResponse(__FUNCTION__);
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->AppData(false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
27
vendors/routes/hasher.js
vendored
27
vendors/routes/hasher.js
vendored
|
@ -11,8 +11,6 @@
|
|||
// Private
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var _hash, _bindings = [];
|
||||
|
||||
const
|
||||
_hashValRegexp = /#(.*)$/,
|
||||
_hashRegexp = /^#/,
|
||||
|
@ -44,11 +42,12 @@
|
|||
// we should store raw value
|
||||
_registerChange(path);
|
||||
if (path === _hash) {
|
||||
path = '#' + encodeURI(path)
|
||||
// we check if path is still === _hash to avoid error in
|
||||
// case of multiple consecutive redirects [issue #39]
|
||||
replace
|
||||
? location.replace('#' + encodeURI(path))
|
||||
: (location.hash = '#' + encodeURI(path));
|
||||
? location.replace(path)
|
||||
: (location.hash = path);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -58,6 +57,10 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
hasher = /** @lends hasher */ {
|
||||
clear : () => {
|
||||
_bindings = [];
|
||||
hasher.active = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* </ul>
|
||||
*/
|
||||
init : () => {
|
||||
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));
|
||||
},
|
||||
init : () => hasher.dispatch(_trimHash(_hash)),
|
||||
|
||||
/**
|
||||
* Set Hash value, generating a new history record.
|
||||
|
@ -101,5 +95,10 @@
|
|||
replaceHash : (...path) => _setHash(path, true)
|
||||
};
|
||||
|
||||
var _hash = _getWindowHash(),
|
||||
_bindings = [];
|
||||
|
||||
addEventListener('hashchange', _checkHistory);
|
||||
|
||||
global.hasher = hasher;
|
||||
})(this);
|
||||
|
|
Loading…
Reference in a new issue