mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-12-24 08:04:16 +08:00
Revamp Mobile/Desktop switcher without completely reloading.
Remove switcher from login page, it became useless.
This commit is contained in:
parent
292f3289ac
commit
d7994ddab6
35 changed files with 159 additions and 202 deletions
|
@ -3,9 +3,9 @@ import ko from 'ko';
|
|||
import {
|
||||
doc,
|
||||
$htmlCL,
|
||||
elementById,
|
||||
leftPanelDisabled,
|
||||
Settings,
|
||||
isMobile
|
||||
Settings
|
||||
} from 'Common/Globals';
|
||||
|
||||
import { KeyState } from 'Common/Enums';
|
||||
|
@ -49,7 +49,7 @@ export class AbstractApp {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
download(link) {
|
||||
if (isMobile()) {
|
||||
if (ThemeStore.isMobile()) {
|
||||
open(link, '_self');
|
||||
focus();
|
||||
} else {
|
||||
|
@ -110,7 +110,7 @@ export class AbstractApp {
|
|||
register('Select', SelectComponent);
|
||||
register('TextArea', TextAreaComponent);
|
||||
register('CheckboxSimple', CheckboxComponent, 'CheckboxComponent');
|
||||
if (isMobile() || !Settings.app('materialDesign')) {
|
||||
if (/*ThemeStore.isMobile() || */!Settings.app('materialDesign')) {
|
||||
register('Checkbox', CheckboxComponent);
|
||||
} else {
|
||||
register('Checkbox', CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
|
||||
|
@ -118,11 +118,8 @@ export class AbstractApp {
|
|||
|
||||
initOnStartOrLangChange();
|
||||
|
||||
if (isMobile()) {
|
||||
leftPanelDisabled(true);
|
||||
} else {
|
||||
window.addEventListener('resize', () => leftPanelDisabled(767 >= window.innerWidth));
|
||||
}
|
||||
leftPanelDisabled(ThemeStore.isMobile());
|
||||
addEventListener('resize', () => leftPanelDisabled(ThemeStore.isMobile() || 767 >= innerWidth));
|
||||
|
||||
leftPanelDisabled.valueHasMutated();
|
||||
|
||||
|
@ -134,9 +131,8 @@ export class AbstractApp {
|
|||
* @returns {void}
|
||||
*/
|
||||
hideLoading() {
|
||||
const id = id => doc.getElementById(id);
|
||||
id('rl-content').hidden = false;
|
||||
id('rl-loading').remove();
|
||||
elementById('rl-content').hidden = false;
|
||||
elementById('rl-loading').remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@ import {
|
|||
ClientSideKeyName
|
||||
} from 'Common/EnumsUser';
|
||||
|
||||
import { doc, createElement, $htmlCL, Settings, leftPanelDisabled, isMobile } from 'Common/Globals';
|
||||
import {
|
||||
doc,
|
||||
elementById,
|
||||
createElement,
|
||||
$htmlCL,
|
||||
Settings,
|
||||
leftPanelDisabled
|
||||
} from 'Common/Globals';
|
||||
|
||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||
|
||||
|
@ -50,6 +57,7 @@ import FolderStore from 'Stores/User/Folder';
|
|||
import PgpStore from 'Stores/User/Pgp';
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
import QuotaStore from 'Stores/User/Quota';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import * as Local from 'Storage/Client';
|
||||
|
||||
|
@ -866,18 +874,18 @@ class AppUser extends AbstractApp {
|
|||
(bDisable || !$htmlCL.contains('rl-bottom-preview-pane')) ? null : 'height');
|
||||
};
|
||||
if (top && bottom) {
|
||||
fDisable(false);
|
||||
fDisable(ThemeStore.isMobile());
|
||||
addEventListener('rl-layout', e => fDisable(Layout.BottomPreview !== e.detail));
|
||||
}
|
||||
}
|
||||
|
||||
initVerticalLayoutResizer() {
|
||||
const left = doc.getElementById('rl-left'),
|
||||
right = doc.getElementById('rl-right'),
|
||||
const left = elementById('rl-left'),
|
||||
right = elementById('rl-right'),
|
||||
fDisable = bDisable =>
|
||||
this.setLayoutResizer(left, right, ClientSideKeyName.FolderListSize, bDisable ? null : 'width');
|
||||
if (left && right) {
|
||||
fDisable(false);
|
||||
fDisable(ThemeStore.isMobile());
|
||||
leftPanelDisabled.subscribe(value => fDisable(value));
|
||||
}
|
||||
}
|
||||
|
@ -1022,9 +1030,7 @@ class AppUser extends AbstractApp {
|
|||
}, 500);
|
||||
}
|
||||
|
||||
if (!isMobile()) {
|
||||
setTimeout(() => this.initVerticalLayoutResizer(), 1);
|
||||
}
|
||||
setTimeout(() => this.initVerticalLayoutResizer(), 1);
|
||||
} else {
|
||||
this.logout();
|
||||
}
|
||||
|
|
|
@ -5,10 +5,9 @@ export const doc = document;
|
|||
|
||||
export const $htmlCL = doc.documentElement.classList;
|
||||
|
||||
export const Settings = rl.settings;
|
||||
export const elementById = id => doc.getElementById(id);
|
||||
|
||||
/** @media screen and (max-width: 600px) { */
|
||||
export const isMobile = () => $htmlCL.contains('rl-mobile');
|
||||
export const Settings = rl.settings;
|
||||
|
||||
export const dropdownVisibility = ko.observable(false).extend({ rateLimit: 0 });
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { SaveSettingsStep } from 'Common/Enums';
|
||||
import { doc } from 'Common/Globals';
|
||||
import { doc, elementById } from 'Common/Globals';
|
||||
|
||||
export const
|
||||
isArray = Array.isArray,
|
||||
|
@ -29,7 +29,7 @@ export function pString(value) {
|
|||
export function inFocus() {
|
||||
try {
|
||||
return doc.activeElement && doc.activeElement.matches(
|
||||
'input,textarea,iframe,.cke_editable'
|
||||
'input,textarea,.cke_editable'
|
||||
);
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
@ -83,13 +83,13 @@ let __themeTimer = 0,
|
|||
* @returns {void}
|
||||
*/
|
||||
export function changeTheme(value, themeTrigger = ()=>{}) {
|
||||
const themeLink = doc.getElementById('app-theme-link'),
|
||||
const themeLink = elementById('app-theme-link'),
|
||||
clearTimer = () => {
|
||||
__themeTimer = setTimeout(() => themeTrigger(SaveSettingsStep.Idle), 1000);
|
||||
__themeJson = null;
|
||||
};
|
||||
|
||||
let themeStyle = doc.getElementById('app-theme-style'),
|
||||
let themeStyle = elementById('app-theme-style'),
|
||||
url = (themeLink && themeLink.href) || (themeStyle && themeStyle.dataset.href);
|
||||
|
||||
if (url) {
|
||||
|
|
107
dev/External/User/ko.js
vendored
107
dev/External/User/ko.js
vendored
|
@ -2,8 +2,9 @@ import 'External/ko';
|
|||
import ko from 'ko';
|
||||
import { HtmlEditor } from 'Common/Html';
|
||||
import { timeToNode } from 'Common/Momentor';
|
||||
import { doc, isMobile } from 'Common/Globals';
|
||||
import { elementById } from 'Common/Globals';
|
||||
import { EmailAddressesComponent } from 'Component/EmailAddresses';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
const rlContentType = 'snappymail/action',
|
||||
|
||||
|
@ -86,72 +87,68 @@ ko.bindingHandlers.emailsTags = {
|
|||
// Start dragging selected messages
|
||||
ko.bindingHandlers.dragmessages = {
|
||||
init: (element, fValueAccessor) => {
|
||||
if (!isMobile()) {
|
||||
element.addEventListener("dragstart", e => {
|
||||
let data = fValueAccessor()(e);
|
||||
dragImage || (dragImage = doc.getElementById('messagesDragImage'));
|
||||
if (data && dragImage) {
|
||||
dragImage.querySelector('.text').textContent = data.uids.length;
|
||||
let img = dragImage.querySelector('.icon-white');
|
||||
img.classList.toggle('icon-copy', e.ctrlKey);
|
||||
img.classList.toggle('icon-mail', !e.ctrlKey);
|
||||
element.addEventListener("dragstart", e => {
|
||||
let data = fValueAccessor()(e);
|
||||
dragImage || (dragImage = elementById('messagesDragImage'));
|
||||
if (data && dragImage && !ThemeStore.isMobile()) {
|
||||
dragImage.querySelector('.text').textContent = data.uids.length;
|
||||
let img = dragImage.querySelector('.icon-white');
|
||||
img.classList.toggle('icon-copy', e.ctrlKey);
|
||||
img.classList.toggle('icon-mail', !e.ctrlKey);
|
||||
|
||||
// Else Chrome doesn't show it
|
||||
dragImage.style.left = e.clientX + 'px';
|
||||
dragImage.style.top = e.clientY + 'px';
|
||||
dragImage.style.right = 'auto';
|
||||
// Else Chrome doesn't show it
|
||||
dragImage.style.left = e.clientX + 'px';
|
||||
dragImage.style.top = e.clientY + 'px';
|
||||
dragImage.style.right = 'auto';
|
||||
|
||||
setDragAction(e, 'messages', e.ctrlKey ? 'copy' : 'move', data, dragImage);
|
||||
setDragAction(e, 'messages', e.ctrlKey ? 'copy' : 'move', data, dragImage);
|
||||
|
||||
// Remove the Chrome visibility
|
||||
dragImage.style.cssText = '';
|
||||
} else {
|
||||
e.preventDefault();
|
||||
}
|
||||
// Remove the Chrome visibility
|
||||
dragImage.style.cssText = '';
|
||||
} else {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
}, false);
|
||||
element.addEventListener("dragend", () => dragData = null);
|
||||
element.setAttribute('draggable', true);
|
||||
}
|
||||
}, false);
|
||||
element.addEventListener("dragend", () => dragData = null);
|
||||
element.setAttribute('draggable', true);
|
||||
}
|
||||
};
|
||||
|
||||
// Drop selected messages on folder
|
||||
ko.bindingHandlers.dropmessages = {
|
||||
init: (element, fValueAccessor) => {
|
||||
if (!isMobile()) {
|
||||
const folder = fValueAccessor(),
|
||||
// folder = ko.dataFor(element),
|
||||
fnStop = e => {
|
||||
e.preventDefault();
|
||||
element.classList.remove('droppableHover');
|
||||
dragTimer.stop();
|
||||
},
|
||||
fnHover = e => {
|
||||
if ('messages' === getDragAction(e)) {
|
||||
fnStop(e);
|
||||
element.classList.add('droppableHover');
|
||||
if (folder && folder.collapsed()) {
|
||||
dragTimer.start(() => {
|
||||
folder.collapsed(false);
|
||||
rl.app.setExpandedFolder(folder.fullNameHash, true);
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
};
|
||||
element.addEventListener("dragenter", fnHover);
|
||||
element.addEventListener("dragover", fnHover);
|
||||
element.addEventListener("dragleave", fnStop);
|
||||
element.addEventListener("drop", e => {
|
||||
fnStop(e);
|
||||
if ('messages' === getDragAction(e) && ['move','copy'].includes(e.dataTransfer.effectAllowed)) {
|
||||
let data = dragData.data;
|
||||
if (folder && data && data.folder && Array.isArray(data.uids)) {
|
||||
rl.app.moveMessagesToFolder(data.folder, data.uids, folder.fullNameRaw, data.copy && e.ctrlKey);
|
||||
const folder = fValueAccessor(),
|
||||
// folder = ko.dataFor(element),
|
||||
fnStop = e => {
|
||||
e.preventDefault();
|
||||
element.classList.remove('droppableHover');
|
||||
dragTimer.stop();
|
||||
},
|
||||
fnHover = e => {
|
||||
if ('messages' === getDragAction(e)) {
|
||||
fnStop(e);
|
||||
element.classList.add('droppableHover');
|
||||
if (folder && folder.collapsed()) {
|
||||
dragTimer.start(() => {
|
||||
folder.collapsed(false);
|
||||
rl.app.setExpandedFolder(folder.fullNameHash, true);
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
element.addEventListener("dragenter", fnHover);
|
||||
element.addEventListener("dragover", fnHover);
|
||||
element.addEventListener("dragleave", fnStop);
|
||||
element.addEventListener("drop", e => {
|
||||
fnStop(e);
|
||||
if ('messages' === getDragAction(e) && ['move','copy'].includes(e.dataTransfer.effectAllowed)) {
|
||||
let data = dragData.data;
|
||||
if (folder && data && data.folder && Array.isArray(data.uids)) {
|
||||
rl.app.moveMessagesToFolder(data.folder, data.uids, folder.fullNameRaw, data.copy && e.ctrlKey);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import ko from 'ko';
|
|||
|
||||
import { pString } from 'Common/Utils';
|
||||
import { settings } from 'Common/Links';
|
||||
import { doc } from 'Common/Globals';
|
||||
import { doc, elementById } from 'Common/Globals';
|
||||
|
||||
import { AbstractScreen } from 'Knoin/AbstractScreen';
|
||||
|
||||
|
@ -45,7 +45,7 @@ export class AbstractSettingsScreen extends AbstractScreen {
|
|||
if (RoutedSettingsViewModel.__builded && RoutedSettingsViewModel.__vm) {
|
||||
settingsScreen = RoutedSettingsViewModel.__vm;
|
||||
} else {
|
||||
const vmPlace = doc.getElementById('rl-settings-subscreen');
|
||||
const vmPlace = elementById('rl-settings-subscreen');
|
||||
if (vmPlace) {
|
||||
settingsScreen = new RoutedSettingsViewModel();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Capa } from 'Common/Enums';
|
||||
import { Focused } from 'Common/EnumsUser';
|
||||
import { doc, leftPanelDisabled, leftPanelType, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
import { doc, leftPanelDisabled, leftPanelType, moveAction, Settings } from 'Common/Globals';
|
||||
import { pString, pInt } from 'Common/Utils';
|
||||
import { getFolderFromCacheList, getFolderFullNameRaw, getFolderInboxName } from 'Common/Cache';
|
||||
import { i18n } from 'Common/Translator';
|
||||
|
@ -10,6 +10,7 @@ import AccountStore from 'Stores/User/Account';
|
|||
import SettingsStore from 'Stores/User/Settings';
|
||||
import FolderStore from 'Stores/User/Folder';
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import { SystemDropDownMailBoxUserView } from 'View/User/MailBox/SystemDropDown';
|
||||
import { FolderListMailBoxUserView } from 'View/User/MailBox/FolderList';
|
||||
|
@ -56,7 +57,7 @@ export class MailBoxUserScreen extends AbstractScreen {
|
|||
AppStore.focusedState(Focused.None);
|
||||
AppStore.focusedState(Focused.MessageList);
|
||||
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
|
||||
if (Settings.capa(Capa.Folders)) {
|
||||
leftPanelType('');
|
||||
|
@ -115,9 +116,7 @@ export class MailBoxUserScreen extends AbstractScreen {
|
|||
* @returns {void}
|
||||
*/
|
||||
onBuild() {
|
||||
if (!isMobile()) {
|
||||
setTimeout(() => rl.app.initHorizontalLayoutResizer(), 1);
|
||||
}
|
||||
setTimeout(() => rl.app.initHorizontalLayoutResizer(), 1);
|
||||
|
||||
doc.addEventListener('click', event =>
|
||||
event.target.closest('#rl-right') && moveAction(false)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Capa, KeyState } from 'Common/Enums';
|
||||
import { keyScope, leftPanelType, leftPanelDisabled, Settings, isMobile } from 'Common/Globals';
|
||||
import { keyScope, leftPanelType, leftPanelDisabled, Settings } from 'Common/Globals';
|
||||
import { runSettingsViewModelHooks } from 'Common/Plugins';
|
||||
import { initOnStartOrLangChange, i18n } from 'Common/Translator';
|
||||
|
||||
import AppStore from 'Stores/User/App';
|
||||
import AccountStore from 'Stores/User/Account';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import { AbstractSettingsScreen, settingsAddViewModel } from 'Screen/AbstractSettings';
|
||||
|
||||
|
@ -104,7 +105,7 @@ export class SettingsUserScreen extends AbstractSettingsScreen {
|
|||
keyScope(KeyState.Settings);
|
||||
leftPanelType('');
|
||||
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
}
|
||||
|
||||
setSettingsTitle() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import ko from 'ko';
|
||||
import { isMobile } from 'Common/Globals';
|
||||
import { $htmlCL } from 'Common/Globals';
|
||||
|
||||
export const ThemeStore = {
|
||||
themes: ko.observableArray(),
|
||||
|
@ -12,7 +12,7 @@ export const ThemeStore = {
|
|||
|
||||
this.themes(Array.isArray(themes) ? themes : []);
|
||||
this.theme(Settings.get('Theme'));
|
||||
if (!isMobile()) {
|
||||
if (!this.isMobile()) {
|
||||
this.themeBackgroundName(Settings.get('UserBackgroundName'));
|
||||
this.themeBackgroundHash(Settings.get('UserBackgroundHash'));
|
||||
}
|
||||
|
@ -20,3 +20,6 @@ export const ThemeStore = {
|
|||
};
|
||||
|
||||
ThemeStore.theme = ko.observable('').extend({ limitedList: ThemeStore.themes });
|
||||
|
||||
ThemeStore.isMobile = ko.observable($htmlCL.contains('rl-mobile'));
|
||||
ThemeStore.isMobile.subscribe(value => $htmlCL.toggle('rl-mobile', value));
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import ko from 'ko';
|
||||
import { KeyState } from 'Common/Enums';
|
||||
import { Focused } from 'Common/EnumsUser';
|
||||
|
||||
import { keyScope, leftPanelDisabled, Settings, isMobile } from 'Common/Globals';
|
||||
import { keyScope, leftPanelDisabled, Settings } from 'Common/Globals';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
class AppUserStore {
|
||||
constructor() {
|
||||
|
@ -26,15 +26,15 @@ class AppUserStore {
|
|||
switch (value) {
|
||||
case Focused.MessageList:
|
||||
keyScope(KeyState.MessageList);
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
break;
|
||||
case Focused.MessageView:
|
||||
keyScope(KeyState.MessageView);
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
break;
|
||||
case Focused.FolderList:
|
||||
keyScope(KeyState.FolderList);
|
||||
isMobile() && leftPanelDisabled(false);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -2,7 +2,7 @@ import ko from 'ko';
|
|||
|
||||
import { StorageResultType, Notification } from 'Common/Enums';
|
||||
import { Focused, MessageSetAction } from 'Common/EnumsUser';
|
||||
import { doc } from 'Common/Globals';
|
||||
import { doc, elementById } from 'Common/Globals';
|
||||
import { pInt, pString } from 'Common/Utils';
|
||||
import { plainToHtml } from 'Common/UtilsUser';
|
||||
|
||||
|
@ -493,7 +493,7 @@ class MessageUserStore {
|
|||
if (messagesDom) {
|
||||
id = 'rl-mgs-' + message.hash.replace(/[^a-zA-Z0-9]/g, '');
|
||||
|
||||
const textBody = doc.getElementById(id);
|
||||
const textBody = elementById(id);
|
||||
if (textBody) {
|
||||
message.body = textBody;
|
||||
message.fetchDataFromDom();
|
||||
|
|
|
@ -3,7 +3,8 @@ import ko from 'ko';
|
|||
import { MESSAGES_PER_PAGE_VALUES } from 'Common/Consts';
|
||||
import { Layout, EditorDefaultType } from 'Common/EnumsUser';
|
||||
import { pInt } from 'Common/Utils';
|
||||
import { doc, isMobile } from 'Common/Globals';
|
||||
import { $htmlCL } from 'Common/Globals';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
class SettingsUserStore {
|
||||
constructor() {
|
||||
|
@ -34,17 +35,16 @@ class SettingsUserStore {
|
|||
autoLogout: 30
|
||||
});
|
||||
|
||||
this.usePreviewPane = ko.computed(() => Layout.NoPreview !== this.layout() && !isMobile());
|
||||
this.usePreviewPane = ko.computed(() => Layout.NoPreview !== this.layout() && !ThemeStore.isMobile());
|
||||
|
||||
this.subscribers();
|
||||
}
|
||||
|
||||
subscribers() {
|
||||
const htmlCL = doc.documentElement.classList;
|
||||
this.layout.subscribe(value => {
|
||||
htmlCL.toggle('rl-no-preview-pane', Layout.NoPreview === value);
|
||||
htmlCL.toggle('rl-side-preview-pane', Layout.SidePreview === value);
|
||||
htmlCL.toggle('rl-bottom-preview-pane', Layout.BottomPreview === value);
|
||||
$htmlCL.toggle('rl-no-preview-pane', Layout.NoPreview === value);
|
||||
$htmlCL.toggle('rl-side-preview-pane', Layout.SidePreview === value);
|
||||
$htmlCL.toggle('rl-bottom-preview-pane', Layout.BottomPreview === value);
|
||||
dispatchEvent(new CustomEvent('rl-layout', {detail:value}));
|
||||
});
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class SettingsUserStore {
|
|||
this.messagesPerPage(settingsGet('MPP'));
|
||||
|
||||
this.showImages(!!settingsGet('ShowImages'));
|
||||
this.useCheckboxesInList(!!(isMobile() || settingsGet('UseCheckboxesInList')));
|
||||
this.useCheckboxesInList(!!(ThemeStore.isMobile() || settingsGet('UseCheckboxesInList')));
|
||||
this.allowDraftAutosave(!!settingsGet('AllowDraftAutosave'));
|
||||
this.useThreads(!!settingsGet('UseThreads'));
|
||||
this.replySameFolder(!!settingsGet('ReplySameFolder'));
|
||||
|
|
|
@ -165,19 +165,6 @@
|
|||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.e-mobile-switcher {
|
||||
color: var(--login-switch-color, #333);
|
||||
margin-top: 8px;
|
||||
text-align: center;
|
||||
a {
|
||||
color: var(--login-switch-color, #333);
|
||||
text-decoration: underline;
|
||||
&:hover {
|
||||
filter: brightness(1.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
|
|
|
@ -59,22 +59,6 @@
|
|||
color: #DA4F49;
|
||||
}
|
||||
|
||||
.b-message-view-iframe {
|
||||
}
|
||||
|
||||
.b-message-view-iframe-backdrop {
|
||||
display: none;
|
||||
background: transparent;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
opacity: .1;
|
||||
}
|
||||
|
||||
.content {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ import { KeyboardShortcutsHelpPopupView } from 'View/Popup/KeyboardShortcutsHelp
|
|||
import { AccountPopupView } from 'View/Popup/Account';
|
||||
import { ContactsPopupView } from 'View/Popup/Contacts';
|
||||
|
||||
import { Settings } from 'Common/Globals';
|
||||
import { doc, Settings, leftPanelDisabled } from 'Common/Globals';
|
||||
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
export class AbstractSystemDropDownUserView extends AbstractViewRight {
|
||||
constructor(name) {
|
||||
|
@ -82,6 +84,22 @@ export class AbstractSystemDropDownUserView extends AbstractViewRight {
|
|||
}
|
||||
}
|
||||
|
||||
layoutDesktop()
|
||||
{
|
||||
doc.cookie = 'rllayout=desktop';
|
||||
ThemeStore.isMobile(false);
|
||||
leftPanelDisabled(false);
|
||||
// location.reload();
|
||||
}
|
||||
|
||||
layoutMobile()
|
||||
{
|
||||
doc.cookie = 'rllayout=mobile';
|
||||
ThemeStore.isMobile(true);
|
||||
leftPanelDisabled(true);
|
||||
// location.reload();
|
||||
}
|
||||
|
||||
logoutClick() {
|
||||
rl.app.logout();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import ko from 'ko';
|
|||
|
||||
import { Capa, KeyState } from 'Common/Enums';
|
||||
import { Focused } from 'Common/EnumsUser';
|
||||
import { leftPanelDisabled, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
import { leftPanelDisabled, moveAction, Settings } from 'Common/Globals';
|
||||
import { mailBox, settings } from 'Common/Links';
|
||||
import { setFolderHash } from 'Common/Cache';
|
||||
|
||||
|
@ -10,6 +10,7 @@ import AppStore from 'Stores/User/App';
|
|||
import SettingsStore from 'Stores/User/Settings';
|
||||
import FolderStore from 'Stores/User/Folder';
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import { showScreenPopup } from 'Knoin/Knoin';
|
||||
import { AbstractViewLeft } from 'Knoin/AbstractViews';
|
||||
|
@ -56,7 +57,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
eqs = (ev, s) => ev.target.closestWithin(s, dom),
|
||||
fSelectFolder = (el, event, starred) => {
|
||||
const isMove = moveAction();
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
|
||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||
|
||||
import { doc, leftPanelDisabled, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
import { doc, leftPanelDisabled, moveAction, Settings } from 'Common/Globals';
|
||||
|
||||
import { computedPaginatorHelper } from 'Common/UtilsUser';
|
||||
import { File } from 'Common/File';
|
||||
|
@ -37,6 +37,7 @@ import QuotaStore from 'Stores/User/Quota';
|
|||
import SettingsStore from 'Stores/User/Settings';
|
||||
import FolderStore from 'Stores/User/Folder';
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import Remote from 'Remote/User/Fetch';
|
||||
|
||||
|
@ -172,9 +173,9 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
isUnSpamVisible: () =>
|
||||
this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder(),
|
||||
|
||||
mobileCheckedStateShow: () => isMobile() ? 0 < MessageStore.messageListChecked().length : true,
|
||||
mobileCheckedStateShow: () => ThemeStore.isMobile() ? 0 < MessageStore.messageListChecked().length : true,
|
||||
|
||||
mobileCheckedStateHide: () => isMobile() ? !MessageStore.messageListChecked().length : true,
|
||||
mobileCheckedStateHide: () => ThemeStore.isMobile() ? !MessageStore.messageListChecked().length : true,
|
||||
|
||||
messageListFocused: () => Focused.MessageList === AppStore.focusedState()
|
||||
});
|
||||
|
@ -673,7 +674,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.selector.init(dom.querySelector('.b-content'), KeyState.MessageList);
|
||||
|
||||
dom.addEventListener('click', event => {
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
|
||||
if (eqs(event, '.messageList .b-message-list-wrapper') && Focused.MessageView === AppStore.focusedState()) {
|
||||
AppStore.focusedState(Focused.MessageList);
|
||||
|
@ -699,7 +700,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.initUploaderForAppend();
|
||||
this.initShortcuts();
|
||||
|
||||
if (!isMobile() && Settings.capa(Capa.Prefetch)) {
|
||||
if (!ThemeStore.isMobile() && Settings.capa(Capa.Prefetch)) {
|
||||
ifvisible.idle(this.prefetchNextTick.bind(this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
MessageSetAction
|
||||
} from 'Common/EnumsUser';
|
||||
|
||||
import { $htmlCL, leftPanelDisabled, keyScopeReal, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
import { $htmlCL, leftPanelDisabled, keyScopeReal, moveAction, Settings } from 'Common/Globals';
|
||||
|
||||
import { inFocus } from 'Common/Utils';
|
||||
import { mailToHelper } from 'Common/UtilsUser';
|
||||
|
@ -32,6 +32,7 @@ import SettingsStore from 'Stores/User/Settings';
|
|||
import AccountStore from 'Stores/User/Account';
|
||||
import FolderStore from 'Stores/User/Folder';
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import * as Local from 'Storage/Client';
|
||||
|
||||
|
@ -413,7 +414,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
const eqs = (ev, s) => ev.target.closestWithin(s, dom);
|
||||
dom.addEventListener('click', event => {
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
ThemeStore.isMobile() && leftPanelDisabled(true);
|
||||
|
||||
let el = eqs(event, 'a');
|
||||
if (el) {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { KeyState } from 'Common/Enums';
|
||||
import { leftPanelDisabled, isMobile } from 'Common/Globals';
|
||||
import { leftPanelDisabled } from 'Common/Globals';
|
||||
import { settings, mailbox } from 'Common/Links';
|
||||
import { getFolderInboxName } from 'Common/Cache';
|
||||
|
||||
import { settingsMenuKeysHandler } from 'Knoin/Knoin';
|
||||
import { AbstractViewLeft } from 'Knoin/AbstractViews';
|
||||
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
export class MenuSettingsUserView extends AbstractViewLeft {
|
||||
/**
|
||||
* @param {Object} screen
|
||||
|
@ -19,9 +21,11 @@ export class MenuSettingsUserView extends AbstractViewLeft {
|
|||
}
|
||||
|
||||
onBuild(dom) {
|
||||
isMobile() && dom.addEventListener('click', event =>
|
||||
event.target.closestWithin('.b-settings-menu .e-item.selectable', dom) && leftPanelDisabled(true)
|
||||
);
|
||||
dom.addEventListener('click', event =>
|
||||
ThemeStore.isMobile()
|
||||
&& event.target.closestWithin('.b-settings-menu .e-item.selectable', dom)
|
||||
&& leftPanelDisabled(true)
|
||||
);
|
||||
|
||||
shortcuts.add('arrowup,arrowdown', '', KeyState.Settings,
|
||||
settingsMenuKeysHandler(dom.querySelectorAll('.b-settings-menu .e-item')));
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { mailbox } from 'Common/Links';
|
||||
import { getFolderInboxName } from 'Common/Cache';
|
||||
import { leftPanelDisabled, isMobile } from 'Common/Globals';
|
||||
import { leftPanelDisabled } from 'Common/Globals';
|
||||
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
import { ThemeStore } from 'Stores/Theme';
|
||||
|
||||
import { AbstractViewRight } from 'Knoin/AbstractViews';
|
||||
|
||||
|
@ -32,7 +33,7 @@ export class PaneSettingsUserView extends AbstractViewRight {
|
|||
}
|
||||
|
||||
onBuild(dom) {
|
||||
isMobile() && dom.addEventListener('click', () => leftPanelDisabled(true));
|
||||
dom.addEventListener('click', () => ThemeStore.isMobile() && leftPanelDisabled(true));
|
||||
}
|
||||
|
||||
backToMailBoxClick() {
|
||||
|
|
|
@ -5,7 +5,7 @@ const
|
|||
doc = document,
|
||||
eId = id => doc.getElementById(id),
|
||||
app = eId('rl-app'),
|
||||
options = app && app.dataset.boot && JSON.parse(app.dataset.boot) || {},
|
||||
admin = app && '1' == app.dataset.admin,
|
||||
|
||||
getCookie = name => {
|
||||
let data = doc.cookie.match('(^|;) ?'+name+'=([^;]*)(;|$)');
|
||||
|
@ -121,7 +121,7 @@ win.rl = {
|
|||
}
|
||||
},
|
||||
data: () => RL_APP_DATA,
|
||||
adminArea: () => options.admin,
|
||||
adminArea: () => admin,
|
||||
settings: {
|
||||
get: name => null == RL_APP_DATA[name] ? null : RL_APP_DATA[name],
|
||||
set: (name, value) => RL_APP_DATA[name] = value,
|
||||
|
@ -179,7 +179,7 @@ setInterval(setTimestamp, 60000); // 1m
|
|||
|
||||
[eId('app-css'),eId('app-theme-link')].forEach(css => css.href = css.dataset.href);
|
||||
|
||||
loadScript(`./?/${options.admin ? 'Admin' : ''}AppData/${rl.hash.get() || '0'}/${Math.random().toString().substr(2)}/`)
|
||||
loadScript(`./?/${admin ? 'Admin' : ''}AppData/${rl.hash.get() || '0'}/${Math.random().toString().substr(2)}/`)
|
||||
.then(() => {});
|
||||
|
||||
})(this);
|
||||
|
|
4
dev/bootstrap.js
vendored
4
dev/bootstrap.js
vendored
|
@ -1,4 +1,4 @@
|
|||
import { doc, dropdownVisibility } from 'Common/Globals';
|
||||
import { doc, elementById, dropdownVisibility } from 'Common/Globals';
|
||||
import { StorageResultType } from 'Common/Enums';
|
||||
import { i18n } from 'Common/Translator';
|
||||
|
||||
|
@ -136,7 +136,7 @@ export default (App) => {
|
|||
window.__APP_BOOT = fErrorCallback => {
|
||||
const cb = () => setTimeout(() => {
|
||||
if (rl.TEMPLATES) {
|
||||
doc.getElementById('rl-templates').innerHTML = rl.TEMPLATES;
|
||||
elementById('rl-templates').innerHTML = rl.TEMPLATES;
|
||||
setTimeout(() => App.bootstart(), 10);
|
||||
} else {
|
||||
fErrorCallback();
|
||||
|
|
|
@ -241,12 +241,7 @@ class Service
|
|||
'{{BaseAppBootCss}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/css/boot.min.css'),
|
||||
'{{BaseCssClass}}' => '',
|
||||
'{{LoadingDescriptionEsc}}' => \htmlspecialchars($LoadingDescription, ENT_QUOTES|ENT_IGNORE, 'UTF-8'),
|
||||
'{{RainloopBootData}}' => \json_encode(array(
|
||||
'admin' => $bAdmin,
|
||||
'language' => $sLanguage,
|
||||
'theme' => $sTheme,
|
||||
'mobile' => $bMobile
|
||||
))
|
||||
'{{BaseAppAdmin}}' => $bAdmin ? 1 : 0
|
||||
);
|
||||
|
||||
$aTemplateParameters['{{BaseHash}}'] = \md5(
|
||||
|
|
|
@ -4,8 +4,6 @@ namespace RainLoop;
|
|||
|
||||
class ServiceActions
|
||||
{
|
||||
const RL_LAYOUT = 'rllayout';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Base\Http
|
||||
*/
|
||||
|
@ -673,20 +671,6 @@ class ServiceActions
|
|||
return $this->localAppData(true);
|
||||
}
|
||||
|
||||
public function ServiceMobileVersion() : string
|
||||
{
|
||||
Utils::SetCookie(self::RL_LAYOUT, 'mobile', 0, null, null, null, false);
|
||||
$this->oActions->Location('./');
|
||||
return '';
|
||||
}
|
||||
|
||||
public function ServiceDesktopVersion() : string
|
||||
{
|
||||
Utils::SetCookie(self::RL_LAYOUT, 'desktop', 0, null, null, null, false);
|
||||
$this->oActions->Location('./');
|
||||
return '';
|
||||
}
|
||||
|
||||
public function ServiceNoScript() : string
|
||||
{
|
||||
return $this->localError($this->oActions->StaticI18N('STATIC/NO_SCRIPT_TITLE'), $this->oActions->StaticI18N('STATIC/NO_SCRIPT_DESC'));
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="rl-app" data-boot='{{RainloopBootData}}'>
|
||||
<div id="rl-app" data-admin='{{BaseAppAdmin}}'>
|
||||
<div id="rl-loading">
|
||||
<div id="rl-loading-desc">{{LoadingDescriptionEsc}}</div>
|
||||
<div class="e-spinner">
|
||||
|
|
|
@ -106,17 +106,5 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="e-mobile-switcher">
|
||||
<span class="hide-mobile">
|
||||
<i class="fontastic">📱</i>
|
||||
|
||||
<a href="./?/MobileVersion/" tabindex="-1" data-i18n="MOBILE/BUTTON_MOBILE_VERSION"></a>
|
||||
</span>
|
||||
<span class="show-mobile">
|
||||
<i class="fontastic">💻</i>
|
||||
|
||||
<a href="./?/DesktopVersion/" tabindex="-1" data-i18n="MOBILE/BUTTON_DESKTOP_VERSION"></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -65,13 +65,13 @@
|
|||
</a>
|
||||
</li>
|
||||
<li class="e-item dividerbar show-mobile" role="presentation">
|
||||
<a class="e-link menuitem" href="./?/DesktopVersion/" tabindex="-1">
|
||||
<a class="e-link menuitem" 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="./?/MobileVersion/" tabindex="-1">
|
||||
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: layoutMobile">
|
||||
<i class="fontastic">📱</i>
|
||||
<span data-i18n="MOBILE/BUTTON_MOBILE_VERSION"></span>
|
||||
</a>
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
--login-box-shadow: 0px 2px 10px rgba(0,0,0,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #ddd;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
--login-box-shadow: 0px 2px 10px rgba(0,0,0,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #ddd;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
--login-box-shadow: 0px 2px 10px rgba(0,0,0,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #ddd;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
--login-box-shadow: 0px 2px 10px rgba(0,0,0,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #ddd;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
--login-box-shadow: 0px 2px 10px rgba(0,0,0,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #fff;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
--login-box-shadow: 0px 2px 10px rgba(0,0,0,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #ddd;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
--login-bg-color: rgba(255,255,255,0.5);
|
||||
--login-border: none;
|
||||
--login-border-radius: 7px;
|
||||
--login-switch-color: #ddd;
|
||||
|
||||
// MENU
|
||||
--dropdown-menu-color: #333;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
--login-border-radius: 7px;
|
||||
--login-gradient-start: none; // #f4f4f4
|
||||
--login-gradient-end: none; // #dfdfdf
|
||||
--login-switch-color: #333;
|
||||
|
||||
--spinner-background: rgba(0,0,0,.3);
|
||||
--spinner-color: #fff;
|
||||
|
|
Loading…
Reference in a new issue