mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Improve Squire toolbar
Cleanup some JS code
This commit is contained in:
parent
e52b9abc61
commit
0158a5fe1e
|
@ -23,18 +23,13 @@ export function root(startupUrl = '') {
|
|||
return HASH_PREFIX + pString(startupUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
export function rootAdmin() {
|
||||
return Settings.app('adminHostUse') ? ROOT : SERVER_PREFIX + (Settings.app('adminPath') || 'admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
export function logoutLink() {
|
||||
return rl.adminArea() ? rootAdmin() : ROOT;
|
||||
return (rl.adminArea() && !Settings.app('adminHostUse'))
|
||||
? SERVER_PREFIX + (Settings.app('adminPath') || 'admin')
|
||||
: ROOT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
.squire-toolbar select {
|
||||
font-size: 12px;
|
||||
padding-left: 0;
|
||||
padding: 4px 1.5em 4px 6px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
width: 7em;
|
||||
|
@ -18,6 +18,9 @@
|
|||
.squire-toolbar select[data-action="fontSize"] {
|
||||
width: 5em;
|
||||
}
|
||||
.squire-toolbar button {
|
||||
font-family: snappymail, var(--fontSans)
|
||||
}
|
||||
.squire-toolbar button[data-action="bold"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import { decorateKoCommands, showScreenPopup } from 'Knoin/Knoin';
|
|||
import { AbstractViewCenter } from 'Knoin/AbstractViews';
|
||||
|
||||
import { Settings } from 'Common/Globals';
|
||||
import { rootAdmin } from 'Common/Links';
|
||||
|
||||
import { LanguagesPopupView } from 'View/Popup/Languages';
|
||||
|
||||
|
@ -161,8 +160,6 @@ class LoginUserView extends AbstractViewCenter {
|
|||
this.submitRequest(false);
|
||||
|
||||
setTimeout(() => this.querySelector('.inputAdditionalCode').focus(), 100);
|
||||
} else if (oData.Admin) {
|
||||
setTimeout(() => location.href = rootAdmin(), 100);
|
||||
} else {
|
||||
rl.route.reload();
|
||||
}
|
||||
|
|
|
@ -64,14 +64,12 @@
|
|||
<span data-i18n="TOP_TOOLBAR/BUTTON_HELP"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="e-item dividerbar show-mobile" role="presentation">
|
||||
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: layoutDesktop">
|
||||
<li class="e-item dividerbar" role="presentation">
|
||||
<a class="e-link menuitem show-mobile" href="#" tabindex="-1" data-bind="click: layoutDesktop">
|
||||
<i class="fontastic">💻</i>
|
||||
<span data-i18n="MOBILE/BUTTON_DESKTOP_VERSION"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="e-item dividerbar hide-mobile" role="presentation">
|
||||
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: layoutMobile">
|
||||
<a class="e-link menuitem hide-mobile" href="#" tabindex="-1" data-bind="click: layoutMobile">
|
||||
<i class="fontastic">📱</i>
|
||||
<span data-i18n="MOBILE/BUTTON_MOBILE_VERSION"></span>
|
||||
</a>
|
||||
|
|
|
@ -67,7 +67,7 @@ config.paths.js = {
|
|||
'dev/shortcuts.js',
|
||||
'vendors/routes/hasher.js',
|
||||
'vendors/routes/crossroads.js',
|
||||
'vendors/jua/jua.min.js',
|
||||
'vendors/jua/jua.js',
|
||||
'vendors/qr.js/qr.min.js',
|
||||
'vendors/bootstrap/js/bootstrap.native.js',
|
||||
'vendors/knockout/build/output/knockout-latest.js',
|
||||
|
|
BIN
vendors/fontastic/fonts/snappymail.woff
vendored
BIN
vendors/fontastic/fonts/snappymail.woff
vendored
Binary file not shown.
BIN
vendors/fontastic/fonts/snappymail.woff2
vendored
BIN
vendors/fontastic/fonts/snappymail.woff2
vendored
Binary file not shown.
332
vendors/jua/jua.js
vendored
332
vendors/jua/jua.js
vendored
|
@ -82,173 +82,6 @@
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Jua} oJua
|
||||
* @param {Object} oOptions
|
||||
*/
|
||||
class XHRDriver
|
||||
{
|
||||
constructor(oJua, oOptions)
|
||||
{
|
||||
this.oXhrs = {};
|
||||
this.oUids = {};
|
||||
this.oJua = oJua;
|
||||
this.oOptions = Object.assign({
|
||||
action: '',
|
||||
name: 'juaFile',
|
||||
hidden: {},
|
||||
disableMultiple: false
|
||||
}, oOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sUid
|
||||
*/
|
||||
regTaskUid(sUid)
|
||||
{
|
||||
this.oUids[sUid] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sUid
|
||||
* @param {?} oFileInfo
|
||||
*/
|
||||
uploadTask(sUid, oFileInfo)
|
||||
{
|
||||
if (false === this.oUids[sUid] || !oFileInfo || !oFileInfo['File'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const
|
||||
self = this,
|
||||
oXhr = new XMLHttpRequest(),
|
||||
oFormData = new FormData(),
|
||||
sAction = this.oOptions.action,
|
||||
aHidden = this.oOptions.hidden,
|
||||
fStartFunction = this.oJua.getEvent('onStart'),
|
||||
fProgressFunction = this.oJua.getEvent('onProgress')
|
||||
;
|
||||
|
||||
oXhr.open('POST', sAction, true);
|
||||
|
||||
if (fProgressFunction && oXhr.upload)
|
||||
{
|
||||
oXhr.upload.onprogress = oEvent => {
|
||||
if (oEvent && oEvent.lengthComputable && defined(oEvent.loaded) && defined(oEvent.total))
|
||||
{
|
||||
fProgressFunction(sUid, oEvent.loaded, oEvent.total);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
oXhr.onreadystatechange = () => {
|
||||
if (4 === oXhr.readyState)
|
||||
{
|
||||
delete self.oXhrs[sUid];
|
||||
let bResult = false,
|
||||
oResult = null;
|
||||
if (200 === oXhr.status)
|
||||
{
|
||||
try
|
||||
{
|
||||
oResult = JSON.parse(oXhr.responseText);
|
||||
bResult = true;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
this.oJua.getEvent('onComplete')(sUid, bResult, bResult ? oResult : null);
|
||||
}
|
||||
};
|
||||
|
||||
fStartFunction && fStartFunction(sUid);
|
||||
|
||||
oFormData.append(this.oOptions.name, oFileInfo['File']);
|
||||
Object.entries(aHidden).forEach(([key, value]) =>
|
||||
oFormData.append(key, (typeof value === "function" ? value(oFileInfo) : value).toString())
|
||||
);
|
||||
|
||||
oXhr.send(oFormData);
|
||||
|
||||
this.oXhrs[sUid] = oXhr;
|
||||
return true;
|
||||
}
|
||||
catch (oError)
|
||||
{
|
||||
console.error(oError)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
generateNewInput(oClickElement)
|
||||
{
|
||||
if (oClickElement)
|
||||
{
|
||||
const self = this,
|
||||
oInput = doc.createElement('input'),
|
||||
onClick = ()=>oInput.click();
|
||||
|
||||
oInput.type = 'file';
|
||||
oInput.tabIndex = -1;
|
||||
oInput.style.display = 'none';
|
||||
oInput.multiple = !self.oOptions.disableMultiple;
|
||||
|
||||
oClickElement.addEventListener('click', onClick);
|
||||
|
||||
oInput.addEventListener('input', () => {
|
||||
const fFileCallback = oFile => {
|
||||
self.oJua.addNewFile(oFile);
|
||||
setTimeout(() => {
|
||||
oInput.remove();
|
||||
oClickElement.removeEventListener('click', onClick);
|
||||
self.generateNewInput(oClickElement);
|
||||
}, 10);
|
||||
};
|
||||
if (oInput.files && oInput.files.length) {
|
||||
getDataFromFiles(oInput.files, fFileCallback,
|
||||
self.oOptions.multipleSizeLimit,
|
||||
self.oJua.getEvent('onLimitReached')
|
||||
);
|
||||
} else {
|
||||
fFileCallback({
|
||||
'FileName': oInput.value.split('\\').pop().split('/').pop(),
|
||||
'Size': null,
|
||||
'Type': null,
|
||||
'Folder': '',
|
||||
'File' : null
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cancel(sUid)
|
||||
{
|
||||
this.oUids[sUid] = false;
|
||||
if (this.oXhrs[sUid])
|
||||
{
|
||||
try
|
||||
{
|
||||
this.oXhrs[sUid].abort && this.oXhrs[sUid].abort();
|
||||
}
|
||||
catch (oError)
|
||||
{
|
||||
console.error(oError);
|
||||
}
|
||||
|
||||
delete this.oXhrs[sUid];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Queue extends Array
|
||||
{
|
||||
constructor(limit) {
|
||||
|
@ -294,6 +127,10 @@
|
|||
};
|
||||
|
||||
oOptions = Object.assign({
|
||||
action: '',
|
||||
name: 'juaFile',
|
||||
hidden: {},
|
||||
disableMultiple: false,
|
||||
queueSize: 10,
|
||||
clickElement: null,
|
||||
dragAndDropElement: null,
|
||||
|
@ -302,10 +139,11 @@
|
|||
multipleSizeLimit: iDefLimit
|
||||
}, oOptions || {});
|
||||
|
||||
self.oXhrs = {};
|
||||
self.oUids = {};
|
||||
self.oOptions = oOptions;
|
||||
self.oQueue = new Queue(oOptions.queueSize);
|
||||
|
||||
self.oDriver = new XHRDriver(self, oOptions);
|
||||
|
||||
let el = oOptions.clickElement;
|
||||
if (el) {
|
||||
el.style.position = 'relative';
|
||||
|
@ -314,7 +152,7 @@
|
|||
el.style.display = 'inline-block';
|
||||
}
|
||||
|
||||
self.oDriver.generateNewInput(el);
|
||||
self.generateNewInput(el);
|
||||
}
|
||||
|
||||
el = oOptions.dragAndDropElement;
|
||||
|
@ -458,14 +296,6 @@
|
|||
return this.oEvents[sName] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sUid
|
||||
*/
|
||||
cancel(sUid)
|
||||
{
|
||||
this.oDriver.cancel(sUid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} oFileInfo
|
||||
*/
|
||||
|
@ -483,12 +313,152 @@
|
|||
const fOnSelect = this.getEvent('onSelect');
|
||||
if (oFileInfo && (!fOnSelect || (false !== fOnSelect(sUid, oFileInfo))))
|
||||
{
|
||||
this.oDriver.regTaskUid(sUid);
|
||||
this.oQueue.push((...args) => this.oDriver.uploadTask(...args), sUid, oFileInfo);
|
||||
this.oUids[sUid] = true;
|
||||
this.oQueue.push((...args) => this.uploadTask(...args), sUid, oFileInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.oDriver.cancel(sUid);
|
||||
this.cancel(sUid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sUid
|
||||
* @param {?} oFileInfo
|
||||
*/
|
||||
uploadTask(sUid, oFileInfo)
|
||||
{
|
||||
if (false === this.oUids[sUid] || !oFileInfo || !oFileInfo['File'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const
|
||||
self = this,
|
||||
oXhr = new XMLHttpRequest(),
|
||||
oFormData = new FormData(),
|
||||
sAction = this.oOptions.action,
|
||||
aHidden = this.oOptions.hidden,
|
||||
fStartFunction = this.getEvent('onStart'),
|
||||
fProgressFunction = this.getEvent('onProgress')
|
||||
;
|
||||
|
||||
oXhr.open('POST', sAction, true);
|
||||
|
||||
if (fProgressFunction && oXhr.upload)
|
||||
{
|
||||
oXhr.upload.onprogress = oEvent => {
|
||||
if (oEvent && oEvent.lengthComputable && defined(oEvent.loaded) && defined(oEvent.total))
|
||||
{
|
||||
fProgressFunction(sUid, oEvent.loaded, oEvent.total);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
oXhr.onreadystatechange = () => {
|
||||
if (4 === oXhr.readyState)
|
||||
{
|
||||
delete self.oXhrs[sUid];
|
||||
let bResult = false,
|
||||
oResult = null;
|
||||
if (200 === oXhr.status)
|
||||
{
|
||||
try
|
||||
{
|
||||
oResult = JSON.parse(oXhr.responseText);
|
||||
bResult = true;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
this.getEvent('onComplete')(sUid, bResult, bResult ? oResult : null);
|
||||
}
|
||||
};
|
||||
|
||||
fStartFunction && fStartFunction(sUid);
|
||||
|
||||
oFormData.append(this.oOptions.name, oFileInfo['File']);
|
||||
Object.entries(aHidden).forEach(([key, value]) =>
|
||||
oFormData.append(key, (typeof value === "function" ? value(oFileInfo) : value).toString())
|
||||
);
|
||||
|
||||
oXhr.send(oFormData);
|
||||
|
||||
this.oXhrs[sUid] = oXhr;
|
||||
return true;
|
||||
}
|
||||
catch (oError)
|
||||
{
|
||||
console.error(oError)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
generateNewInput(oClickElement)
|
||||
{
|
||||
if (oClickElement)
|
||||
{
|
||||
const self = this,
|
||||
oInput = doc.createElement('input'),
|
||||
onClick = ()=>oInput.click();
|
||||
|
||||
oInput.type = 'file';
|
||||
oInput.tabIndex = -1;
|
||||
oInput.style.display = 'none';
|
||||
oInput.multiple = !self.oOptions.disableMultiple;
|
||||
|
||||
oClickElement.addEventListener('click', onClick);
|
||||
|
||||
oInput.addEventListener('input', () => {
|
||||
const fFileCallback = oFile => {
|
||||
self.addNewFile(oFile);
|
||||
setTimeout(() => {
|
||||
oInput.remove();
|
||||
oClickElement.removeEventListener('click', onClick);
|
||||
self.generateNewInput(oClickElement);
|
||||
}, 10);
|
||||
};
|
||||
if (oInput.files && oInput.files.length) {
|
||||
getDataFromFiles(oInput.files, fFileCallback,
|
||||
self.oOptions.multipleSizeLimit,
|
||||
self.getEvent('onLimitReached')
|
||||
);
|
||||
} else {
|
||||
fFileCallback({
|
||||
'FileName': oInput.value.split('\\').pop().split('/').pop(),
|
||||
'Size': null,
|
||||
'Type': null,
|
||||
'Folder': '',
|
||||
'File' : null
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sUid
|
||||
*/
|
||||
cancel(sUid)
|
||||
{
|
||||
this.oUids[sUid] = false;
|
||||
if (this.oXhrs[sUid])
|
||||
{
|
||||
try
|
||||
{
|
||||
this.oXhrs[sUid].abort && this.oXhrs[sUid].abort();
|
||||
}
|
||||
catch (oError)
|
||||
{
|
||||
console.error(oError);
|
||||
}
|
||||
|
||||
delete this.oXhrs[sUid];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
vendors/jua/jua.min.js
vendored
2
vendors/jua/jua.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue