mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Move changeTheme and convertThemeName to Themes.js
This commit is contained in:
parent
10835a6f82
commit
04c11ddc49
6 changed files with 76 additions and 94 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import 'External/User/ko';
|
import 'External/User/ko';
|
||||||
|
|
||||||
import { SMAudio } from 'Common/Audio';
|
import { SMAudio } from 'Common/Audio';
|
||||||
import { isArray, pString, changeTheme } from 'Common/Utils';
|
import { isArray, pString } from 'Common/Utils';
|
||||||
import { mailToHelper, setLayoutResizer, dropdownsDetectVisibility } from 'Common/UtilsUser';
|
import { mailToHelper, setLayoutResizer, dropdownsDetectVisibility } from 'Common/UtilsUser';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|
@ -38,7 +38,7 @@ import { IdentityUserStore } from 'Stores/User/Identity';
|
||||||
import { FolderUserStore } from 'Stores/User/Folder';
|
import { FolderUserStore } from 'Stores/User/Folder';
|
||||||
import { PgpUserStore } from 'Stores/User/Pgp';
|
import { PgpUserStore } from 'Stores/User/Pgp';
|
||||||
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
||||||
import { ThemeStore } from 'Stores/Theme';
|
import { ThemeStore, changeTheme } from 'Stores/Theme';
|
||||||
import { LanguageStore } from 'Stores/Language';
|
import { LanguageStore } from 'Stores/Language';
|
||||||
import { MessageUserStore } from 'Stores/User/Message';
|
import { MessageUserStore } from 'Stores/User/Message';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
import { SaveSettingStatus } from 'Common/Enums';
|
|
||||||
import { elementById } from 'Common/Globals';
|
|
||||||
|
|
||||||
let __themeTimer = 0,
|
|
||||||
__themeJson = null;
|
|
||||||
|
|
||||||
export const
|
export const
|
||||||
isArray = Array.isArray,
|
isArray = Array.isArray,
|
||||||
arrayLength = array => isArray(array) && array.length,
|
arrayLength = array => isArray(array) && array.length,
|
||||||
|
|
@ -19,12 +13,6 @@ export const
|
||||||
return isNaN(value) || !isFinite(value) ? defaultValue : value;
|
return isNaN(value) || !isFinite(value) ? defaultValue : value;
|
||||||
},
|
},
|
||||||
|
|
||||||
convertThemeName = theme => theme
|
|
||||||
.replace(/@custom$/, '')
|
|
||||||
.replace(/([A-Z])/g, ' $1')
|
|
||||||
.replace(/[^a-zA-Z0-9]+/g, ' ')
|
|
||||||
.trim(),
|
|
||||||
|
|
||||||
defaultOptionsAfterRender = (domItem, item) =>
|
defaultOptionsAfterRender = (domItem, item) =>
|
||||||
item && undefined !== item.disabled && domItem?.classList.toggle('disabled', domItem.disabled = item.disabled),
|
item && undefined !== item.disabled && domItem?.classList.toggle('disabled', domItem.disabled = item.disabled),
|
||||||
|
|
||||||
|
|
@ -37,34 +25,4 @@ export const
|
||||||
*/
|
*/
|
||||||
b64EncodeJSONSafe = data => b64EncodeJSON(data).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''),
|
b64EncodeJSONSafe = data => b64EncodeJSON(data).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''),
|
||||||
|
|
||||||
changeTheme = (value, themeTrigger = ()=>0) => {
|
|
||||||
const themeStyle = elementById('app-theme-style'),
|
|
||||||
clearTimer = () => {
|
|
||||||
__themeTimer = setTimeout(() => themeTrigger(SaveSettingStatus.Idle), 1000);
|
|
||||||
__themeJson = null;
|
|
||||||
},
|
|
||||||
url = themeStyle.dataset.href.replace(/(Admin|User)\/-\/[^/]+\//, '$1/-/' + value + '/') + 'Json/';
|
|
||||||
|
|
||||||
clearTimeout(__themeTimer);
|
|
||||||
|
|
||||||
themeTrigger(SaveSettingStatus.Saving);
|
|
||||||
|
|
||||||
if (__themeJson) {
|
|
||||||
__themeJson.abort();
|
|
||||||
}
|
|
||||||
let init = {};
|
|
||||||
if (window.AbortController) {
|
|
||||||
__themeJson = new AbortController();
|
|
||||||
init.signal = __themeJson.signal;
|
|
||||||
}
|
|
||||||
rl.fetchJSON(url, init)
|
|
||||||
.then(data => {
|
|
||||||
if (2 === arrayLength(data)) {
|
|
||||||
themeStyle.textContent = data[1];
|
|
||||||
themeTrigger(SaveSettingStatus.Success);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(clearTimer, clearTimer);
|
|
||||||
},
|
|
||||||
|
|
||||||
getKeyByValue = (o, v) => Object.keys(o).find(key => o[key] === v);
|
getKeyByValue = (o, v) => Object.keys(o).find(key => o[key] === v);
|
||||||
|
|
|
||||||
|
|
@ -32,23 +32,20 @@ oRequests = {},
|
||||||
|
|
||||||
abort = (sAction, sReason, bClearOnly) => {
|
abort = (sAction, sReason, bClearOnly) => {
|
||||||
if (oRequests[sAction]) {
|
if (oRequests[sAction]) {
|
||||||
if (!bClearOnly && oRequests[sAction].abort) {
|
bClearOnly || oRequests[sAction].abort(sReason || 'AbortError');
|
||||||
// oRequests[sAction].__aborted = true;
|
|
||||||
oRequests[sAction].abort(sReason || 'AbortError');
|
|
||||||
}
|
|
||||||
|
|
||||||
oRequests[sAction] = null;
|
oRequests[sAction] = null;
|
||||||
delete oRequests[sAction];
|
delete oRequests[sAction];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchJSON = (action, sGetAdd, params, timeout, jsonCallback) => {
|
fetchJSON = (action, sUrl, params, timeout, jsonCallback) => {
|
||||||
params = params || {};
|
if (params) {
|
||||||
if (params instanceof FormData) {
|
if (params instanceof FormData) {
|
||||||
params.set('Action', action);
|
params.set('Action', action);
|
||||||
} else {
|
} else {
|
||||||
params.Action = action;
|
params.Action = action;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Don't abort, read https://github.com/the-djmaze/snappymail/issues/487
|
// Don't abort, read https://github.com/the-djmaze/snappymail/issues/487
|
||||||
// abort(action);
|
// abort(action);
|
||||||
const controller = new AbortController(),
|
const controller = new AbortController(),
|
||||||
|
|
@ -56,7 +53,7 @@ fetchJSON = (action, sGetAdd, params, timeout, jsonCallback) => {
|
||||||
oRequests[action] = controller;
|
oRequests[action] = controller;
|
||||||
// Currently there is no way to combine multiple signals, so AbortSignal.timeout() not possible
|
// Currently there is no way to combine multiple signals, so AbortSignal.timeout() not possible
|
||||||
timeout && setTimeout(() => abort(action, 'TimeoutError'), timeout);
|
timeout && setTimeout(() => abort(action, 'TimeoutError'), timeout);
|
||||||
return rl.fetchJSON(getURL(sGetAdd), {signal: signal}, sGetAdd ? null : params).then(jsonCallback).catch(err => {
|
return rl.fetchJSON(sUrl, {signal: signal}, params).then(jsonCallback).catch(err => {
|
||||||
err.aborted = signal.aborted;
|
err.aborted = signal.aborted;
|
||||||
err.reason = signal.reason;
|
err.reason = signal.reason;
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
|
|
@ -123,15 +120,13 @@ export class AbstractFetchRemote
|
||||||
* @param {?number=} iTimeout
|
* @param {?number=} iTimeout
|
||||||
* @param {string=} sGetAdd = ''
|
* @param {string=} sGetAdd = ''
|
||||||
*/
|
*/
|
||||||
request(sAction, fCallback, params, iTimeout, sGetAdd, abortActions) {
|
request(sAction, fCallback, params, iTimeout, sGetAdd) {
|
||||||
params = params || {};
|
params = params || {};
|
||||||
|
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
||||||
abortActions && console.error('abortActions is obsolete');
|
fetchJSON(sAction, getURL(sGetAdd),
|
||||||
|
sGetAdd ? null : (params || {}),
|
||||||
fetchJSON(sAction, sGetAdd,
|
|
||||||
params,
|
|
||||||
undefined === iTimeout ? 30000 : pInt(iTimeout),
|
undefined === iTimeout ? 30000 : pInt(iTimeout),
|
||||||
data => {
|
data => {
|
||||||
let cached = false;
|
let cached = false;
|
||||||
|
|
@ -141,9 +136,6 @@ export class AbstractFetchRemote
|
||||||
|
|
||||||
let iError = 0;
|
let iError = 0;
|
||||||
if (sAction && oRequests[sAction]) {
|
if (sAction && oRequests[sAction]) {
|
||||||
if (oRequests[sAction].__aborted) {
|
|
||||||
iError = 2;
|
|
||||||
}
|
|
||||||
abort(sAction, 0, 1);
|
abort(sAction, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,9 +187,13 @@ export class AbstractFetchRemote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get(action, url) {
|
||||||
|
return fetchJSON(action, url);
|
||||||
|
}
|
||||||
|
|
||||||
post(action, fTrigger, params, timeOut) {
|
post(action, fTrigger, params, timeOut) {
|
||||||
this.setTrigger(fTrigger, true);
|
this.setTrigger(fTrigger, true);
|
||||||
return fetchJSON(action, '', params, pInt(timeOut, 30000),
|
return fetchJSON(action, getURL(), params || {}, pInt(timeOut, 30000),
|
||||||
data => {
|
data => {
|
||||||
abort(action, 0, 1);
|
abort(action, 0, 1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import ko from 'ko';
|
import ko from 'ko';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isArray,
|
isArray
|
||||||
changeTheme,
|
|
||||||
convertThemeName
|
|
||||||
} from 'Common/Utils';
|
} from 'Common/Utils';
|
||||||
|
|
||||||
import { addObservablesTo, addSubscribablesTo, addComputablesTo } from 'External/ko';
|
import { addObservablesTo, addSubscribablesTo, addComputablesTo } from 'External/ko';
|
||||||
|
|
@ -17,7 +15,7 @@ import { showScreenPopup } from 'Knoin/Knoin';
|
||||||
|
|
||||||
import Remote from 'Remote/Admin/Fetch';
|
import Remote from 'Remote/Admin/Fetch';
|
||||||
|
|
||||||
import { ThemeStore } from 'Stores/Theme';
|
import { ThemeStore, convertThemeName, changeTheme } from 'Stores/Theme';
|
||||||
import { LanguageStore } from 'Stores/Language';
|
import { LanguageStore } from 'Stores/Language';
|
||||||
import { LanguagesPopupView } from 'View/Popup/Languages';
|
import { LanguagesPopupView } from 'View/Popup/Languages';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import { addObservablesTo } from 'External/ko';
|
import { addObservablesTo } from 'External/ko';
|
||||||
|
|
||||||
import { SaveSettingStatus, UploadErrorCode } from 'Common/Enums';
|
import { SaveSettingStatus, UploadErrorCode } from 'Common/Enums';
|
||||||
import { changeTheme, convertThemeName } from 'Common/Utils';
|
|
||||||
import { themePreviewLink, serverRequest } from 'Common/Links';
|
import { themePreviewLink, serverRequest } from 'Common/Links';
|
||||||
import { i18n } from 'Common/Translator';
|
import { i18n } from 'Common/Translator';
|
||||||
import { SettingsCapa } from 'Common/Globals';
|
import { SettingsCapa } from 'Common/Globals';
|
||||||
|
|
||||||
import { ThemeStore } from 'Stores/Theme';
|
import { ThemeStore, convertThemeName, changeTheme } from 'Stores/Theme';
|
||||||
|
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
import ko from 'ko';
|
import ko from 'ko';
|
||||||
import { doc, $htmlCL, elementById, leftPanelDisabled, Settings, SettingsGet } from 'Common/Globals';
|
import { doc, $htmlCL, elementById, leftPanelDisabled, Settings, SettingsGet } from 'Common/Globals';
|
||||||
import { isArray } from 'Common/Utils';
|
import { isArray, arrayLength } from 'Common/Utils';
|
||||||
import { serverRequestRaw } from 'Common/Links';
|
import { serverRequestRaw } from 'Common/Links';
|
||||||
|
import { SaveSettingStatus } from 'Common/Enums';
|
||||||
|
|
||||||
export const ThemeStore = {
|
let __themeTimer = 0;
|
||||||
|
|
||||||
|
export const
|
||||||
|
ThemeStore = {
|
||||||
theme: ko.observable(''),
|
theme: ko.observable(''),
|
||||||
themes: ko.observableArray(),
|
themes: ko.observableArray(),
|
||||||
userBackgroundName: ko.observable(''),
|
userBackgroundName: ko.observable(''),
|
||||||
|
|
@ -28,7 +32,34 @@ export const ThemeStore = {
|
||||||
|
|
||||||
leftPanelDisabled(ThemeStore.isMobile());
|
leftPanelDisabled(ThemeStore.isMobile());
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
|
changeTheme = (value, themeTrigger = ()=>0) => {
|
||||||
|
const themeStyle = elementById('app-theme-style'),
|
||||||
|
clearTimer = () => {
|
||||||
|
__themeTimer = setTimeout(() => themeTrigger(SaveSettingStatus.Idle), 1000);
|
||||||
|
},
|
||||||
|
url = themeStyle.dataset.href.replace(/(Admin|User)\/-\/[^/]+\//, '$1/-/' + value + '/') + 'Json/';
|
||||||
|
|
||||||
|
clearTimeout(__themeTimer);
|
||||||
|
|
||||||
|
themeTrigger(SaveSettingStatus.Saving);
|
||||||
|
|
||||||
|
rl.app.Remote.abort('theme').get('theme', url)
|
||||||
|
.then(data => {
|
||||||
|
if (2 === arrayLength(data)) {
|
||||||
|
themeStyle.textContent = data[1];
|
||||||
|
themeTrigger(SaveSettingStatus.Success);
|
||||||
|
}
|
||||||
|
clearTimer();
|
||||||
|
}, clearTimer);
|
||||||
|
},
|
||||||
|
|
||||||
|
convertThemeName = theme => theme
|
||||||
|
.replace(/@custom$/, '')
|
||||||
|
.replace(/([A-Z])/g, ' $1')
|
||||||
|
.replace(/[^a-zA-Z0-9]+/g, ' ')
|
||||||
|
.trim();
|
||||||
|
|
||||||
ThemeStore.isMobile.subscribe(value => $htmlCL.toggle('rl-mobile', value));
|
ThemeStore.isMobile.subscribe(value => $htmlCL.toggle('rl-mobile', value));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue