mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-11 00:14:50 +03:00
Revamp mobile including CSS flexbox for messageListItem
This commit is contained in:
parent
6238b97f08
commit
10f9ce39d9
70 changed files with 479 additions and 821 deletions
|
|
@ -4,7 +4,8 @@ import {
|
|||
doc,
|
||||
$htmlCL,
|
||||
leftPanelDisabled,
|
||||
Settings
|
||||
Settings,
|
||||
isMobile
|
||||
} from 'Common/Globals';
|
||||
|
||||
import { KeyState } from 'Common/Enums';
|
||||
|
|
@ -48,7 +49,7 @@ export class AbstractApp {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
download(link) {
|
||||
if (Settings.app('mobile')) {
|
||||
if (isMobile()) {
|
||||
open(link, '_self');
|
||||
focus();
|
||||
} else {
|
||||
|
|
@ -82,8 +83,7 @@ export class AbstractApp {
|
|||
}
|
||||
|
||||
bootstart() {
|
||||
const mobile = Settings.app('mobile'),
|
||||
register = (key, ClassObject, templateID) => ko.components.register(key, {
|
||||
const register = (key, ClassObject, templateID) => ko.components.register(key, {
|
||||
template: { element: templateID || (key + 'Component') },
|
||||
viewModel: {
|
||||
createViewModel: (params, componentInfo) => {
|
||||
|
|
@ -110,7 +110,7 @@ export class AbstractApp {
|
|||
register('Select', SelectComponent);
|
||||
register('TextArea', TextAreaComponent);
|
||||
register('CheckboxSimple', CheckboxComponent, 'CheckboxComponent');
|
||||
if (mobile || !Settings.app('materialDesign')) {
|
||||
if (isMobile() || !Settings.app('materialDesign')) {
|
||||
register('Checkbox', CheckboxComponent);
|
||||
} else {
|
||||
register('Checkbox', CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
|
||||
|
|
@ -118,7 +118,7 @@ export class AbstractApp {
|
|||
|
||||
initOnStartOrLangChange();
|
||||
|
||||
if (mobile) {
|
||||
if (isMobile()) {
|
||||
leftPanelDisabled(true);
|
||||
} else {
|
||||
window.addEventListener('resize', () => leftPanelDisabled(767 >= window.innerWidth));
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {
|
|||
ClientSideKeyName
|
||||
} from 'Common/EnumsUser';
|
||||
|
||||
import { doc, createElement, $htmlCL, Settings, leftPanelDisabled } from 'Common/Globals';
|
||||
import { doc, createElement, $htmlCL, Settings, leftPanelDisabled, isMobile } from 'Common/Globals';
|
||||
|
||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||
|
||||
|
|
@ -871,12 +871,11 @@ class AppUser extends AbstractApp {
|
|||
}
|
||||
}
|
||||
|
||||
initVerticalLayoutResizer(sClientSideKeyName) {
|
||||
initVerticalLayoutResizer() {
|
||||
const left = doc.getElementById('rl-left'),
|
||||
right = doc.getElementById('rl-right'),
|
||||
fDisable = bDisable => {
|
||||
this.setLayoutResizer(left, right, sClientSideKeyName, bDisable ? null : 'width');
|
||||
};
|
||||
fDisable = bDisable =>
|
||||
this.setLayoutResizer(left, right, ClientSideKeyName.FolderListSize, bDisable ? null : 'width');
|
||||
if (left && right) {
|
||||
fDisable(false);
|
||||
leftPanelDisabled.subscribe(value => fDisable(value));
|
||||
|
|
@ -1023,8 +1022,8 @@ class AppUser extends AbstractApp {
|
|||
}, 500);
|
||||
}
|
||||
|
||||
if (!Settings.app('mobile')) {
|
||||
setTimeout(() => this.initVerticalLayoutResizer(ClientSideKeyName.FolderListSize), 1);
|
||||
if (!isMobile()) {
|
||||
setTimeout(() => this.initVerticalLayoutResizer(), 1);
|
||||
}
|
||||
} else {
|
||||
this.logout();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ export const $htmlCL = doc.documentElement.classList;
|
|||
|
||||
export const Settings = rl.settings;
|
||||
|
||||
/** @media screen and (max-width: 600px) { */
|
||||
export const isMobile = () => $htmlCL.contains('rl-mobile'); // || rl.settings.app('mobile')
|
||||
|
||||
export const dropdownVisibility = ko.observable(false).extend({ rateLimit: 0 });
|
||||
|
||||
export const moveAction = ko.observable(false);
|
||||
|
|
|
|||
6
dev/External/User/ko.js
vendored
6
dev/External/User/ko.js
vendored
|
|
@ -2,7 +2,7 @@ import 'External/ko';
|
|||
import ko from 'ko';
|
||||
import { HtmlEditor } from 'Common/Html';
|
||||
import { timeToNode } from 'Common/Momentor';
|
||||
import { doc } from 'Common/Globals';
|
||||
import { doc, isMobile } from 'Common/Globals';
|
||||
import { EmailAddressesComponent } from 'Component/EmailAddresses';
|
||||
|
||||
const rlContentType = 'snappymail/action',
|
||||
|
|
@ -86,7 +86,7 @@ ko.bindingHandlers.emailsTags = {
|
|||
// Start dragging selected messages
|
||||
ko.bindingHandlers.dragmessages = {
|
||||
init: (element, fValueAccessor) => {
|
||||
if (!rl.settings.app('mobile')) {
|
||||
if (!isMobile()) {
|
||||
element.addEventListener("dragstart", e => {
|
||||
let data = fValueAccessor()(e);
|
||||
dragImage || (dragImage = doc.getElementById('messagesDragImage'));
|
||||
|
|
@ -119,7 +119,7 @@ ko.bindingHandlers.dragmessages = {
|
|||
// Drop selected messages on folder
|
||||
ko.bindingHandlers.dropmessages = {
|
||||
init: (element, fValueAccessor) => {
|
||||
if (!rl.settings.app('mobile')) {
|
||||
if (!isMobile()) {
|
||||
const folder = fValueAccessor(),
|
||||
// folder = ko.dataFor(element),
|
||||
fnStop = e => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { doc, $htmlCL } from 'Common/Globals';
|
||||
import { doc, $htmlCL/*, isMobile*/ } from 'Common/Globals';
|
||||
import { isNonEmptyArray } from 'Common/Utils';
|
||||
|
||||
let currentScreen = null,
|
||||
|
|
@ -9,7 +9,7 @@ let currentScreen = null,
|
|||
|
||||
const SCREENS = {},
|
||||
autofocus = dom => {
|
||||
// if (!rl.settings.app('mobile')) {
|
||||
// if (!isMobile()) {
|
||||
const af = dom.querySelector('[autofocus]');
|
||||
af && af.focus();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@ export class MessageModel extends AbstractModel {
|
|||
|
||||
this.addObservables({
|
||||
subject: '',
|
||||
subjectPrefix: '',
|
||||
subjectSuffix: '',
|
||||
size: 0,
|
||||
dateTimeStampInUTC: 0,
|
||||
priority: MessagePriority.Normal,
|
||||
|
|
@ -117,8 +115,6 @@ export class MessageModel extends AbstractModel {
|
|||
clear() {
|
||||
this._reset();
|
||||
this.subject('');
|
||||
this.subjectPrefix('');
|
||||
this.subjectSuffix('');
|
||||
this.size(0);
|
||||
this.dateTimeStampInUTC(0);
|
||||
this.priority(MessagePriority.Normal);
|
||||
|
|
@ -192,14 +188,6 @@ export class MessageModel extends AbstractModel {
|
|||
json.Priority = MessagePriority.High == p || MessagePriority.Low == p ? p : MessagePriority.Normal;
|
||||
}
|
||||
if (super.revivePropertiesFromJson(json)) {
|
||||
if (isArray(json.SubjectParts)) {
|
||||
this.subjectPrefix(json.SubjectParts[0]);
|
||||
this.subjectSuffix(json.SubjectParts[1]);
|
||||
} else {
|
||||
this.subjectPrefix('');
|
||||
this.subjectSuffix(this.subject());
|
||||
}
|
||||
|
||||
// this.foundedCIDs = isArray(json.FoundedCIDs) ? json.FoundedCIDs : [];
|
||||
// this.attachments(AttachmentCollectionModel.reviveFromJson(json.Attachments, this.foundedCIDs));
|
||||
|
||||
|
|
@ -454,9 +442,6 @@ export class MessageModel extends AbstractModel {
|
|||
this.checked(message.checked());
|
||||
this.hasAttachments(message.hasAttachments());
|
||||
this.attachmentsSpecData(message.attachmentsSpecData());
|
||||
|
||||
this.subjectPrefix(this.subjectPrefix());
|
||||
this.subjectSuffix(this.subjectSuffix());
|
||||
}
|
||||
|
||||
this.body = null;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Capa } from 'Common/Enums';
|
||||
import { Focused, ClientSideKeyName } from 'Common/EnumsUser';
|
||||
import { doc, leftPanelDisabled, leftPanelType, moveAction, Settings } from 'Common/Globals';
|
||||
import { doc, leftPanelDisabled, leftPanelType, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
import { pString, pInt } from 'Common/Utils';
|
||||
import { getFolderFromCacheList, getFolderFullNameRaw, getFolderInboxName } from 'Common/Cache';
|
||||
import { i18n } from 'Common/Translator';
|
||||
|
|
@ -56,7 +56,7 @@ export class MailBoxUserScreen extends AbstractScreen {
|
|||
AppStore.focusedState(Focused.None);
|
||||
AppStore.focusedState(Focused.MessageList);
|
||||
|
||||
if (Settings.app('mobile')) {
|
||||
if (isMobile()) {
|
||||
leftPanelDisabled(true);
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ export class MailBoxUserScreen extends AbstractScreen {
|
|||
* @returns {void}
|
||||
*/
|
||||
onBuild() {
|
||||
if (!Settings.app('mobile')) {
|
||||
if (!isMobile()) {
|
||||
setTimeout(() =>
|
||||
rl.app.initHorizontalLayoutResizer(ClientSideKeyName.MessageListSize)
|
||||
, 1);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Capa, KeyState } from 'Common/Enums';
|
||||
import { keyScope, leftPanelType, leftPanelDisabled, Settings } from 'Common/Globals';
|
||||
import { keyScope, leftPanelType, leftPanelDisabled, Settings, isMobile } from 'Common/Globals';
|
||||
import { runSettingsViewModelHooks } from 'Common/Plugins';
|
||||
import { initOnStartOrLangChange, i18n } from 'Common/Translator';
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ export class SettingsUserScreen extends AbstractSettingsScreen {
|
|||
keyScope(KeyState.Settings);
|
||||
leftPanelType('');
|
||||
|
||||
if (Settings.app('mobile')) {
|
||||
if (isMobile()) {
|
||||
leftPanelDisabled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import ko from 'ko';
|
||||
import { isMobile } from 'Common/Globals';
|
||||
|
||||
export const ThemeStore = {
|
||||
themes: ko.observableArray(),
|
||||
|
|
@ -11,8 +12,10 @@ export const ThemeStore = {
|
|||
|
||||
this.themes(Array.isArray(themes) ? themes : []);
|
||||
this.theme(Settings.get('Theme'));
|
||||
this.themeBackgroundName(Settings.get('UserBackgroundName'));
|
||||
this.themeBackgroundHash(Settings.get('UserBackgroundHash'));
|
||||
if (!isMobile()) {
|
||||
this.themeBackgroundName(Settings.get('UserBackgroundName'));
|
||||
this.themeBackgroundHash(Settings.get('UserBackgroundHash'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import ko from 'ko';
|
|||
import { KeyState } from 'Common/Enums';
|
||||
import { Focused } from 'Common/EnumsUser';
|
||||
|
||||
import { keyScope, leftPanelDisabled, Settings } from 'Common/Globals';
|
||||
import { keyScope, leftPanelDisabled, Settings, isMobile } from 'Common/Globals';
|
||||
|
||||
class AppUserStore {
|
||||
constructor() {
|
||||
|
|
@ -22,27 +22,19 @@ class AppUserStore {
|
|||
contactsIsAllowed: false
|
||||
});
|
||||
|
||||
const isMobile = Settings.app('mobile');
|
||||
|
||||
this.focusedState.subscribe((value) => {
|
||||
this.focusedState.subscribe(value => {
|
||||
switch (value) {
|
||||
case Focused.MessageList:
|
||||
keyScope(KeyState.MessageList);
|
||||
if (isMobile) {
|
||||
leftPanelDisabled(true);
|
||||
}
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
break;
|
||||
case Focused.MessageView:
|
||||
keyScope(KeyState.MessageView);
|
||||
if (isMobile) {
|
||||
leftPanelDisabled(true);
|
||||
}
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
break;
|
||||
case Focused.FolderList:
|
||||
keyScope(KeyState.FolderList);
|
||||
if (isMobile) {
|
||||
leftPanelDisabled(false);
|
||||
}
|
||||
isMobile() && leftPanelDisabled(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { StorageResultType, Notification } from 'Common/Enums';
|
||||
import { Layout, Focused, MessageSetAction } from 'Common/EnumsUser';
|
||||
import { Focused, MessageSetAction } from 'Common/EnumsUser';
|
||||
import { doc } from 'Common/Globals';
|
||||
import { pInt, pString } from 'Common/Utils';
|
||||
import { plainToHtml } from 'Common/UtilsUser';
|
||||
|
|
@ -211,7 +211,7 @@ class MessageUserStore {
|
|||
|
||||
this.message.subscribe(message => {
|
||||
if (message) {
|
||||
if (Layout.NoPreview === SettingsStore.layout()) {
|
||||
if (!SettingsStore.usePreviewPane()) {
|
||||
AppStore.focusedState(Focused.MessageView);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ 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 } from 'Common/Globals';
|
||||
import { doc, isMobile } from 'Common/Globals';
|
||||
|
||||
class SettingsUserStore {
|
||||
constructor() {
|
||||
|
|
@ -34,7 +34,7 @@ class SettingsUserStore {
|
|||
autoLogout: 30
|
||||
});
|
||||
|
||||
this.usePreviewPane = ko.computed(() => Layout.NoPreview !== this.layout());
|
||||
this.usePreviewPane = ko.computed(() => Layout.NoPreview !== this.layout() && !isMobile());
|
||||
|
||||
this.subscribers();
|
||||
}
|
||||
|
|
@ -42,9 +42,9 @@ class SettingsUserStore {
|
|||
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', isMobile() || Layout.NoPreview === value);
|
||||
htmlCL.toggle('rl-side-preview-pane', !isMobile() && Layout.SidePreview === value);
|
||||
htmlCL.toggle('rl-bottom-preview-pane', !isMobile() && 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(!!settingsGet('UseCheckboxesInList'));
|
||||
this.useCheckboxesInList(!!(isMobile() || settingsGet('UseCheckboxesInList')));
|
||||
this.allowDraftAutosave(!!settingsGet('AllowDraftAutosave'));
|
||||
this.useThreads(!!settingsGet('UseThreads'));
|
||||
this.replySameFolder(!!settingsGet('ReplySameFolder'));
|
||||
|
|
|
|||
|
|
@ -26,16 +26,6 @@
|
|||
100% {transform: translateX(0)}
|
||||
}
|
||||
|
||||
html.rl-started-trigger.no-mobile .b-login-content .loginFormWrapper {
|
||||
/*transform: scale(1.1);*/
|
||||
transform: translateY(-20px);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/*html.rl-started-trigger.no-mobile #rl-content {
|
||||
opacity: 0.7;
|
||||
}*/
|
||||
|
||||
html.rl-started-delay {
|
||||
|
||||
#rl-left {
|
||||
|
|
@ -56,97 +46,105 @@ html.rl-started-delay {
|
|||
}
|
||||
|
||||
html {
|
||||
&.rgba.backgroundsize .e-strip-animation {
|
||||
.e-strip-animation {
|
||||
background-size: 60px 60px;
|
||||
.rl-strip-animation(0, 0.1);
|
||||
animation: animate-stripes 2s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
html.no-mobile {
|
||||
@media screen and (min-width: 1000px) {
|
||||
|
||||
.b-login-content {
|
||||
.alertError {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transition: opacity 0.5s linear;
|
||||
html.rl-started-trigger .b-login-content .loginFormWrapper {
|
||||
/*transform: scale(1.1);*/
|
||||
transform: translateY(-20px);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
html {
|
||||
.b-login-content {
|
||||
.alertError {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transition: opacity 0.5s linear;
|
||||
}
|
||||
.alertError[hidden] {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.alertError[hidden] {
|
||||
|
||||
.b-login-content .errorAnimated {
|
||||
animation: login-form-shake 400ms ease-in-out;
|
||||
}
|
||||
|
||||
.b-login-content .errorAnimated .buttonLogin {
|
||||
color: #b94a48;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.b-login-content .afterLoginHide {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.b-login-content .errorAnimated {
|
||||
animation: login-form-shake 400ms ease-in-out;
|
||||
}
|
||||
|
||||
.b-login-content .errorAnimated .buttonLogin {
|
||||
color: #b94a48;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.b-login-content .afterLoginHide {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.b-login-content .loginFormWrapper {
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
|
||||
& .button-delete-transitions {
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
& .b-folders .e-item .anim-action-class {
|
||||
animation: highlight-folder-row 0.5s linear;
|
||||
}
|
||||
|
||||
& .b-folders .btn.buttonContacts {
|
||||
transition: margin 0.3s linear;
|
||||
}
|
||||
|
||||
& .b-folders .b-content.opacity-on-panel-disabled {
|
||||
transition: opacity 0.3s linear;
|
||||
}
|
||||
|
||||
& .messageList {
|
||||
.messageListItem {
|
||||
transition: max-height 400ms ease;
|
||||
.b-login-content .loginFormWrapper {
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
.listDragOver {
|
||||
transition: all 400ms ease;
|
||||
|
||||
& .button-delete-transitions {
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
}
|
||||
|
||||
& .b-list-content {
|
||||
.e-contact-item {
|
||||
transition: max-height 400ms ease;
|
||||
& .b-folders .e-item .anim-action-class {
|
||||
animation: highlight-folder-row 0.5s linear;
|
||||
}
|
||||
}
|
||||
|
||||
& .modal.b-domain-content {
|
||||
.modal-body {
|
||||
transition: left 500ms ease;
|
||||
& .b-folders .btn.buttonContacts {
|
||||
transition: margin 0.3s linear;
|
||||
}
|
||||
}
|
||||
|
||||
#rl-popups > .rl-view-model .modal {
|
||||
transition: all .2s ease-out;
|
||||
}
|
||||
#rl-popups > .rl-view-model:not(.show) .modal {
|
||||
top: -25%;
|
||||
}
|
||||
#rl-popups > .rl-view-model .modal.fade {
|
||||
opacity: 1;
|
||||
}
|
||||
#rl-popups > .rl-view-model:not(.show) .modal.fade {
|
||||
opacity: 0;
|
||||
}
|
||||
& .b-folders .b-content.opacity-on-panel-disabled {
|
||||
transition: opacity 0.3s linear;
|
||||
}
|
||||
|
||||
& .b-compose.loading .b-header-toolbar {
|
||||
background-size: 60px 60px;
|
||||
.rl-strip-animation(255, 0.2);
|
||||
animation: animate-stripes 2s linear infinite;
|
||||
& .messageList {
|
||||
.messageListItem {
|
||||
transition: max-height 400ms ease;
|
||||
}
|
||||
.listDragOver {
|
||||
transition: all 400ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
& .b-list-content {
|
||||
.e-contact-item {
|
||||
transition: max-height 400ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
& .modal.b-domain-content {
|
||||
.modal-body {
|
||||
transition: left 500ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
#rl-popups > .rl-view-model .modal {
|
||||
transition: all .2s ease-out;
|
||||
}
|
||||
#rl-popups > .rl-view-model:not(.show) .modal {
|
||||
top: -25%;
|
||||
}
|
||||
#rl-popups > .rl-view-model .modal.fade {
|
||||
opacity: 1;
|
||||
}
|
||||
#rl-popups > .rl-view-model:not(.show) .modal.fade {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
& .b-compose.loading .b-header-toolbar {
|
||||
background-size: 60px 60px;
|
||||
.rl-strip-animation(255, 0.2);
|
||||
animation: animate-stripes 2s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,10 +90,8 @@
|
|||
background-image: none;
|
||||
background: rgba(0, 0, 0, .5) !important;
|
||||
|
||||
.attachmentIcon {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 #000;
|
||||
}
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 #000;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,10 +112,7 @@
|
|||
|
||||
&.hideContactListCheckbox {
|
||||
.checkboxItem {
|
||||
display: none !important;
|
||||
}
|
||||
.sidebarParent {
|
||||
margin-right: 10px !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,32 +129,13 @@
|
|||
cursor: pointer;
|
||||
|
||||
margin: 0;
|
||||
border: 0 solid transparent;
|
||||
border: 0;
|
||||
border-left: 6px solid #eee;
|
||||
z-index: 100;
|
||||
border-bottom: 1px solid #ddd;
|
||||
|
||||
.delimiter {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 1px;
|
||||
background-color: #999;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebarParent {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
background-color: #eee;
|
||||
float: left;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.focused .sidebarParent {
|
||||
background-color: #bbb;
|
||||
&.focused {
|
||||
border-left-color: #bbb;
|
||||
}
|
||||
|
||||
&.deleted {
|
||||
|
|
@ -197,28 +175,22 @@
|
|||
}
|
||||
|
||||
&.checked {
|
||||
border-left-color: #69A8F5;
|
||||
z-index: 101;
|
||||
|
||||
.sidebarParent {
|
||||
background-color: #69A8F5;
|
||||
}
|
||||
|
||||
&.focused .sidebarParent {
|
||||
background-color: darken(#69A8F5, 5%) !important;
|
||||
&.focused {
|
||||
border-left-color: darken(#69A8F5, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
|
||||
background-color: #fff;
|
||||
border-left-color: #398CF2;
|
||||
z-index: 102;
|
||||
|
||||
.sidebarParent {
|
||||
background-color: #398CF2;
|
||||
}
|
||||
|
||||
&.focused .sidebarParent {
|
||||
background-color: darken(#398CF2, 5%) !important;
|
||||
&.focused {
|
||||
border-left-color: darken(#398CF2, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -394,7 +366,7 @@
|
|||
cursor: pointer;
|
||||
|
||||
margin: 0;
|
||||
border: 0 solid transparent;
|
||||
border: 0;
|
||||
z-index: 100;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,7 +389,8 @@ html.rl-bottom-preview-pane {
|
|||
}
|
||||
}
|
||||
|
||||
html.rl-mobile .hide-on-mobile {
|
||||
html.rl-mobile .hide-mobile,
|
||||
html:not(.rl-mobile) .show-mobile {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@
|
|||
.language-button {
|
||||
padding: 5px;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.e-mobile-switcher {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ html, body {
|
|||
}
|
||||
|
||||
body {
|
||||
background-color: var(--main-bg-color, #e3e3e3);
|
||||
background-size: var(--main-bg-size);
|
||||
background: var(--main-bg-color, #e3e3e3);
|
||||
color: var(--main-color, #333);
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
|
|
@ -28,11 +27,13 @@ body {
|
|||
}
|
||||
|
||||
/*
|
||||
.rl-mobile / .no-mobile
|
||||
.rl-mobile
|
||||
*/
|
||||
@media screen and (min-width: 1000px) {
|
||||
body {
|
||||
background-image: var(--main-bg-image);
|
||||
background-size: var(--main-bg-size);
|
||||
background-repeat: var(--main-bg-repeat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -183,19 +183,6 @@ html.rl-no-preview-pane {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.delimiter {
|
||||
display: block;
|
||||
height: 1px;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.messageListItem:last-child {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
&.selected {
|
||||
border-bottom: 1px solid #bfd5ef;
|
||||
}
|
||||
}
|
||||
|
||||
.fullThreadsParent {
|
||||
height: 25px;
|
||||
padding: 3px 5px;
|
||||
|
|
@ -206,49 +193,24 @@ html.rl-no-preview-pane {
|
|||
.messageListItem {
|
||||
|
||||
position: relative;
|
||||
height: 52px;
|
||||
max-height: 60px;
|
||||
font-size: 12px;
|
||||
line-height: 21px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
margin: 0;
|
||||
border: 0 solid transparent;
|
||||
padding: 5px 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.2);
|
||||
border-left: 6px solid #eee;
|
||||
|
||||
z-index: 100;
|
||||
|
||||
background-color: #f9f9f9;
|
||||
|
||||
/* &:nth-child(even) {
|
||||
background-color: #f3f3f3;
|
||||
}*/
|
||||
|
||||
.delimiter {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 1px;
|
||||
background-color: #999;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.sidebarParent {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
background-color: #eee;
|
||||
float: left;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.focused {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
&.focused .sidebarParent {
|
||||
background-color: #ccc !important;
|
||||
border-left-color: #ccc;
|
||||
}
|
||||
|
||||
.importantMark {
|
||||
|
|
@ -260,7 +222,7 @@ html.rl-no-preview-pane {
|
|||
|
||||
&.deleted-mark {
|
||||
opacity: .7;
|
||||
.sender, .subject, .subject-prefix, .subject-suffix {
|
||||
.subjectParent {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
|
|
@ -269,15 +231,6 @@ html.rl-no-preview-pane {
|
|||
display: inline;
|
||||
}
|
||||
|
||||
&.e-single-line {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
&.e-single-line .wrapper {
|
||||
line-height: 25px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
&.new {
|
||||
max-height: 0;
|
||||
}
|
||||
|
|
@ -288,62 +241,36 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
|
||||
.checkboxMessage {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin-top: 11px;
|
||||
padding: 0 8px 0 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&.e-single-line .checkboxMessage {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.flagParent {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
padding: 0 10px 0 5px;
|
||||
}
|
||||
|
||||
&.e-single-line .flagParent {
|
||||
float: left;
|
||||
padding: 0 8px 0 2px;
|
||||
}
|
||||
|
||||
.dateParent {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
position: relative;
|
||||
time {
|
||||
margin: 0 5px;
|
||||
color: #999;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
&.e-single-line .dateParent {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.threadsParent {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.attachmentParent {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
position: relative;
|
||||
margin: 2px 10px 0 5px;
|
||||
}
|
||||
|
||||
&.e-single-line .attachmentParent {
|
||||
float: left;
|
||||
margin: 0 8px 0 0;
|
||||
color: #666;
|
||||
text-shadow: 0 1px 0 #eee;
|
||||
}
|
||||
|
||||
.senderParent {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.threadsCountParent {
|
||||
|
|
@ -366,25 +293,10 @@ html.rl-no-preview-pane {
|
|||
border-color: #666;
|
||||
}
|
||||
|
||||
&.e-single-line .senderParent {
|
||||
display: inline-block;
|
||||
text-overflow: none;
|
||||
width: 200px;
|
||||
float: left;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.subjectParent {
|
||||
display: block;
|
||||
color: #000;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.e-single-line .subjectParent {
|
||||
}
|
||||
|
||||
.senderParent, .subjectParent, .dateParent {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +307,7 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
|
||||
&.emptySubject .subjectParent {
|
||||
.subject, .subject-prefix, .subject-suffix {
|
||||
.subject {
|
||||
display: none;
|
||||
}
|
||||
.emptySubjectText {
|
||||
|
|
@ -403,7 +315,8 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
}
|
||||
|
||||
.sender, .subject, .subject-suffix {
|
||||
.sender, .subject {
|
||||
margin-left: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
|
@ -432,20 +345,6 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
}
|
||||
|
||||
.subject-prefix {
|
||||
color: #888;
|
||||
/*font-style: italic;*/
|
||||
}
|
||||
|
||||
.attachment {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flagOff, .flagOn, .flagOnHalf {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.flagOff {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
|
|
@ -454,12 +353,12 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
|
||||
.flagOn, .flagOnHalf {
|
||||
display: none;
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.replyFlag, .forwardFlag {
|
||||
display: none;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
&.answered .replyFlag {
|
||||
|
|
@ -470,81 +369,53 @@ html.rl-no-preview-pane {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
&.withAttachments .attachment {
|
||||
display: inline-block;
|
||||
color: #666;
|
||||
text-shadow: 0 1px 0 #eee;
|
||||
&:not(.withAttachments) .attachmentParent {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.hasUnseenSubMessage {
|
||||
background-color: #FFFFD9;
|
||||
.sidebarParent {
|
||||
background-color: lighten(orange, 30%);
|
||||
}
|
||||
&.focused .sidebarParent {
|
||||
background-color: darken(orange, 10%) !important;
|
||||
border-left-color: lighten(orange, 30%);
|
||||
&.focused {
|
||||
border-left-color: darken(orange, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&.unseen {
|
||||
background-color: #FFFFD9;
|
||||
.sender, .subject, .subject-suffix {
|
||||
border-left-color: orange;
|
||||
.sender, .subjectParent {
|
||||
font-weight: bold;
|
||||
}
|
||||
.sidebarParent {
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
&.focused .sidebarParent {
|
||||
background-color: darken(orange, 10%) !important;
|
||||
&.focused {
|
||||
border-left-color: darken(orange, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&.checked {
|
||||
.sidebarParent {
|
||||
background-color: lighten(#398CF2, 10%) !important;
|
||||
}
|
||||
border-left-color: lighten(#398CF2, 10%);
|
||||
|
||||
&.focused .sidebarParent {
|
||||
background-color: darken(#398CF2, 5%) !important;
|
||||
&.focused {
|
||||
border-left-color: darken(#398CF2, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: #DFEFFF;
|
||||
border-bottom-color: rgba(57, 140, 242, 0.2);
|
||||
border-left-color: #398CF2;
|
||||
z-index: 101;
|
||||
|
||||
.sidebarParent {
|
||||
background-color: #398CF2 !important;
|
||||
}
|
||||
|
||||
.delimiter {
|
||||
background-color: #398CF2;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
+ .messageListItem .delimiter {
|
||||
background-color: #398CF2;
|
||||
opacity: 0.3;
|
||||
+ .messageListItem {
|
||||
border-bottom-color: rgba(57, 140, 242, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&.hasFlaggedSubMessage {
|
||||
.flagOff, .flagOn {
|
||||
display: none;
|
||||
}
|
||||
.flagOnHalf {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&.flagged {
|
||||
.flagOff, .flagOnHalf {
|
||||
display: none;
|
||||
}
|
||||
.flagOn {
|
||||
display: inline-block;
|
||||
}
|
||||
&:not(.flagged) .flagOn,
|
||||
&:not(.hasFlaggedSubMessage) .flagOnHalf,
|
||||
&.flagged .flagOff, &.hasFlaggedSubMessage .flagOff {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -560,10 +431,7 @@ html.rl-no-preview-pane {
|
|||
|
||||
&.hideMessageListCheckbox {
|
||||
.checkboxMessage, .checkboxCheckAll {
|
||||
display: none !important;
|
||||
}
|
||||
.sidebarParent {
|
||||
margin-right: 10px !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -572,7 +440,7 @@ html.rl-no-preview-pane {
|
|||
@media screen and (min-width: 1401px) {
|
||||
.messageList .b-content .messageListItem {
|
||||
font-size: 13px;
|
||||
.dateParent {
|
||||
time {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
|
@ -598,3 +466,76 @@ html.rl-mobile {
|
|||
width: 160px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.messageListItem {
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
> * {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
order: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.rl-side-preview-pane, .rl-mobile {
|
||||
|
||||
.messageListItem {
|
||||
|
||||
.checkboxMessage {
|
||||
margin: 10px 0 -5px;
|
||||
}
|
||||
|
||||
.subjectParent {
|
||||
flex: 1 0 auto;
|
||||
margin-left: 30px;
|
||||
order: 1;
|
||||
width: calc(100% - 60px);
|
||||
}
|
||||
|
||||
.senderParent {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
.flagParent {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.attachmentParent {
|
||||
order: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html:not(.rl-mobile):not(.rl-side-preview-pane) .messageList {
|
||||
|
||||
.messageListItem {
|
||||
|
||||
line-height: 25px;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.checkboxMessage {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.flagParent {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.attachmentParent {
|
||||
margin: 6px 8px 0 0;
|
||||
}
|
||||
|
||||
.senderParent {
|
||||
font-weight: normal;
|
||||
text-overflow: none;
|
||||
flex: 0 0 25%;
|
||||
}
|
||||
|
||||
.subjectParent {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,6 @@ html.rl-no-preview-pane {
|
|||
|
||||
.messageItemHeader {
|
||||
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
border-top: 0;
|
||||
|
|
@ -133,12 +132,6 @@ html.rl-no-preview-pane {
|
|||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
.date {
|
||||
}
|
||||
|
||||
.subjectParent {
|
||||
font-size: 18px;
|
||||
|
|
@ -157,9 +150,7 @@ html.rl-no-preview-pane {
|
|||
}
|
||||
|
||||
.informationShort {
|
||||
margin: 4px 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 50px;
|
||||
margin: 4px 50px 0 5px;
|
||||
|
||||
a {
|
||||
.g-ui-link;
|
||||
|
|
|
|||
|
|
@ -169,7 +169,3 @@ textarea + .settings-save-trigger {
|
|||
.list-table {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
html.mobile .hide-mobile {
|
||||
display:none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,7 @@ class LoginAdminView extends AbstractViewCenter {
|
|||
constructor() {
|
||||
super('Admin/Login', 'AdminLogin');
|
||||
|
||||
const appSettingsGet = rl.settings.app;
|
||||
this.mobile = !!appSettingsGet('mobile');
|
||||
this.mobileDevice = !!appSettingsGet('mobileDevice');
|
||||
|
||||
this.hideSubmitButton = appSettingsGet('hideSubmitButton');
|
||||
this.hideSubmitButton = rl.settings.app('hideSubmitButton');
|
||||
|
||||
this.addObservables({
|
||||
login: '',
|
||||
|
|
|
|||
|
|
@ -1090,7 +1090,7 @@ class ComposePopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
setFocusInPopup() {
|
||||
// rl.settings.app('mobile') ||
|
||||
// isMobile() ||
|
||||
setTimeout(() => {
|
||||
if (!this.to()) {
|
||||
this.to.focused(true);
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class FilterPopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
if (this.isNew() && this.filter()/* && !rl.settings.app('mobile')*/) {
|
||||
if (this.isNew() && this.filter()/* && !isMobile()*/) {
|
||||
this.filter().nameFocused(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class FolderCreatePopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
// rl.settings.app('mobile') ||
|
||||
// isMobile() ||
|
||||
this.folderNameFocused(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ class IdentityPopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
if (!this.owner()/* && !rl.settings.app('mobile')*/) {
|
||||
if (!this.owner()/* && !isMobile()*/) {
|
||||
this.emailFocused(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class TwoFactorTestPopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
onShowWithDelay() {
|
||||
// rl.settings.app('mobile') ||
|
||||
// isMobile() ||
|
||||
this.codeFocused(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ export class AbstractSystemDropDownUserView extends AbstractViewRight {
|
|||
constructor(name) {
|
||||
super(name, 'SystemDropDown');
|
||||
|
||||
this.mobile = !!Settings.app('mobile');
|
||||
this.mobileDevice = !!Settings.app('mobileDevice');
|
||||
|
||||
this.allowSettings = !!Settings.capa(Capa.Settings);
|
||||
this.allowHelp = !!Settings.capa(Capa.Help);
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,6 @@ class LoginUserView extends AbstractViewCenter {
|
|||
signMeType: LoginSignMeType.Unused
|
||||
});
|
||||
|
||||
this.mobile = !!Settings.app('mobile');
|
||||
this.mobileDevice = !!Settings.app('mobileDevice');
|
||||
|
||||
this.forgotPasswordLinkUrl = Settings.app('forgotPasswordLinkUrl');
|
||||
this.registrationLinkUrl = Settings.app('registrationLinkUrl');
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { Capa, KeyState } from 'Common/Enums';
|
||||
import { Focused, Layout } from 'Common/EnumsUser';
|
||||
import { leftPanelDisabled, moveAction, Settings } from 'Common/Globals';
|
||||
import { Focused } from 'Common/EnumsUser';
|
||||
import { leftPanelDisabled, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
import { mailBox, settings } from 'Common/Links';
|
||||
import { setFolderHash } from 'Common/Cache';
|
||||
|
||||
|
|
@ -54,12 +54,9 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
onBuild(dom) {
|
||||
const qs = s => dom.querySelector(s),
|
||||
eqs = (ev, s) => ev.target.closestWithin(s, dom),
|
||||
isMobile = Settings.app('mobile'),
|
||||
fSelectFolder = (el, event, starred) => {
|
||||
const isMove = moveAction();
|
||||
if (isMobile) {
|
||||
leftPanelDisabled(true);
|
||||
}
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
|
|
@ -78,7 +75,7 @@ export class FolderListMailBoxUserView extends AbstractViewLeft {
|
|||
event.ctrlKey
|
||||
);
|
||||
} else {
|
||||
if (Layout.NoPreview === SettingsStore.layout()) {
|
||||
if (!SettingsStore.usePreviewPane()) {
|
||||
MessageStore.message(null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {
|
|||
} from 'Common/Enums';
|
||||
|
||||
import {
|
||||
Layout,
|
||||
Focused,
|
||||
ComposeType,
|
||||
FolderType,
|
||||
|
|
@ -16,7 +15,7 @@ import {
|
|||
|
||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||
|
||||
import { doc, leftPanelDisabled, moveAction, Settings } from 'Common/Globals';
|
||||
import { doc, leftPanelDisabled, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
|
||||
import { computedPaginatorHelper } from 'Common/UtilsUser';
|
||||
import { File } from 'Common/File';
|
||||
|
|
@ -61,7 +60,6 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
this.iGoToUpUpOrDownDownTimeout = 0;
|
||||
|
||||
this.mobile = !!Settings.app('mobile');
|
||||
this.newMoveToFolder = !!Settings.get('NewMoveToFolder');
|
||||
|
||||
this.allowReload = !!Settings.capa(Capa.Reload);
|
||||
|
|
@ -125,11 +123,6 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.sLastSearchValue = '';
|
||||
|
||||
this.addComputables({
|
||||
messageListItemTemplate: () =>
|
||||
this.mobile || Layout.SidePreview === SettingsStore.layout()
|
||||
? 'MailMessageListItem'
|
||||
: 'MailMessageListItemNoPreviewPane',
|
||||
|
||||
messageListSearchDesc: () => {
|
||||
const value = MessageStore.messageListEndSearch();
|
||||
return value ? i18n('MESSAGE_LIST/SEARCH_RESULT_FOR', { 'SEARCH': value }) : ''
|
||||
|
|
@ -179,9 +172,9 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
isUnSpamVisible: () =>
|
||||
this.isSpamFolder() && !this.isSpamDisabled() && !this.isDraftFolder() && !this.isSentFolder(),
|
||||
|
||||
mobileCheckedStateShow: () => this.mobile ? 0 < MessageStore.messageListChecked().length : true,
|
||||
mobileCheckedStateShow: () => isMobile() ? 0 < MessageStore.messageListChecked().length : true,
|
||||
|
||||
mobileCheckedStateHide: () => this.mobile ? !MessageStore.messageListChecked().length : true,
|
||||
mobileCheckedStateHide: () => isMobile() ? !MessageStore.messageListChecked().length : true,
|
||||
|
||||
messageListFocused: () => Focused.MessageList === AppStore.focusedState()
|
||||
});
|
||||
|
|
@ -388,7 +381,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
return false;
|
||||
});
|
||||
|
||||
if (Layout.NoPreview === SettingsStore.layout() && !this.message()) {
|
||||
if (!SettingsStore.usePreviewPane() && !this.message()) {
|
||||
this.selector.iFocusedNextHelper = up ? -1 : 1;
|
||||
} else {
|
||||
this.selector.iSelectNextHelper = up ? -1 : 1;
|
||||
|
|
@ -405,8 +398,8 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
useAutoSelect() {
|
||||
return !this.messageListDisableAutoSelect()
|
||||
&& !/is:unseen/.test(this.mainMessageListSearch())
|
||||
&& Layout.NoPreview !== SettingsStore.layout();
|
||||
&& !/is:unseen/.test(this.mainMessageListSearch())
|
||||
&& SettingsStore.usePreviewPane();
|
||||
}
|
||||
|
||||
searchEnterAction() {
|
||||
|
|
@ -680,7 +673,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.selector.init(dom.querySelector('.b-content'), KeyState.MessageList);
|
||||
|
||||
dom.addEventListener('click', event => {
|
||||
this.mobile && leftPanelDisabled(true);
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
|
||||
if (eqs(event, '.messageList .b-message-list-wrapper') && Focused.MessageView === AppStore.focusedState()) {
|
||||
AppStore.focusedState(Focused.MessageList);
|
||||
|
|
@ -706,7 +699,7 @@ export class MessageListMailBoxUserView extends AbstractViewRight {
|
|||
this.initUploaderForAppend();
|
||||
this.initShortcuts();
|
||||
|
||||
if (!rl.settings.app('mobile') && Settings.capa(Capa.Prefetch)) {
|
||||
if (!isMobile() && Settings.capa(Capa.Prefetch)) {
|
||||
ifvisible.idle(this.prefetchNextTick.bind(this));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,10 @@ import {
|
|||
ClientSideKeyName,
|
||||
FolderType,
|
||||
Focused,
|
||||
Layout,
|
||||
MessageSetAction
|
||||
} from 'Common/EnumsUser';
|
||||
|
||||
import { $htmlCL, leftPanelDisabled, keyScopeReal, moveAction, Settings } from 'Common/Globals';
|
||||
import { $htmlCL, leftPanelDisabled, keyScopeReal, moveAction, Settings, isMobile } from 'Common/Globals';
|
||||
|
||||
import { inFocus } from 'Common/Utils';
|
||||
import { mailToHelper } from 'Common/UtilsUser';
|
||||
|
|
@ -86,8 +85,6 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
this.allowMessageActions = !!Settings.capa(Capa.MessageActions);
|
||||
this.allowMessageListActions = !!Settings.capa(Capa.MessageListActions);
|
||||
|
||||
this.mobile = !!Settings.app('mobile');
|
||||
|
||||
this.attachmentsActions = AppStore.attachmentsActions;
|
||||
|
||||
this.message = MessageStore.message;
|
||||
|
|
@ -287,14 +284,14 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
@command((self) => !self.messageListAndMessageViewLoading())
|
||||
goUpCommand() {
|
||||
dispatchEvent(new CustomEvent('mailbox.message-list.selector.go-up',
|
||||
{detail:Layout.NoPreview === this.layout() ? !!this.message() : true}
|
||||
{detail:SettingsStore.usePreviewPane() || !!this.message()}
|
||||
));
|
||||
}
|
||||
|
||||
@command((self) => !self.messageListAndMessageViewLoading())
|
||||
goDownCommand() {
|
||||
dispatchEvent(new CustomEvent('mailbox.message-list.selector.go-down',
|
||||
{detail:Layout.NoPreview === this.layout() ? !!this.message() : true}
|
||||
{detail:SettingsStore.usePreviewPane() || !!this.message()}
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -408,7 +405,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
this.oHeaderDom = dom.querySelector('.messageItemHeader');
|
||||
if (this.oHeaderDom) {
|
||||
if (!this.resizeObserver) {
|
||||
this.resizeObserver = new ResizeObserver(this.checkHeaderHeight.throttle(50).bind(this));
|
||||
this.resizeObserver = new ResizeObserver(this.checkHeaderHeight.debounce(50).bind(this));
|
||||
}
|
||||
this.resizeObserver.observe(this.oHeaderDom);
|
||||
} else if (this.resizeObserver) {
|
||||
|
|
@ -417,7 +414,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
const eqs = (ev, s) => ev.target.closestWithin(s, dom);
|
||||
dom.addEventListener('click', event => {
|
||||
this.mobile && leftPanelDisabled(true);
|
||||
isMobile() && leftPanelDisabled(true);
|
||||
|
||||
let el = eqs(event, 'a');
|
||||
if (el) {
|
||||
|
|
@ -506,7 +503,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
*/
|
||||
escShortcuts() {
|
||||
if (this.viewModelVisible && this.message()) {
|
||||
const preview = Layout.NoPreview !== this.layout();
|
||||
const preview = SettingsStore.usePreviewPane();
|
||||
if (this.fullScreenMode()) {
|
||||
this.fullScreenMode(false);
|
||||
|
||||
|
|
@ -616,7 +613,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
|
||||
// change focused state
|
||||
shortcuts.add('arrowleft', '', KeyState.MessageView, () => {
|
||||
if (!this.fullScreenMode() && this.message() && Layout.NoPreview !== this.layout()) {
|
||||
if (!this.fullScreenMode() && this.message() && SettingsStore.usePreviewPane()) {
|
||||
if (this.oMessageScrollerDom && 0 < this.oMessageScrollerDom.scrollLeft) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -626,7 +623,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
|||
});
|
||||
// shortcuts.add('tab', 'shift', KeyState.MessageView, (event, handler) => {
|
||||
shortcuts.add('tab', '', KeyState.MessageView, () => {
|
||||
if (!this.fullScreenMode() && this.message() && Layout.NoPreview !== this.layout()) {
|
||||
if (!this.fullScreenMode() && this.message() && SettingsStore.usePreviewPane()) {
|
||||
AppStore.focusedState(Focused.MessageList);
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { KeyState } from 'Common/Enums';
|
||||
import { leftPanelDisabled } from 'Common/Globals';
|
||||
import { leftPanelDisabled, isMobile } from 'Common/Globals';
|
||||
import { settings, mailbox } from 'Common/Links';
|
||||
import { getFolderInboxName } from 'Common/Cache';
|
||||
|
||||
|
|
@ -15,13 +15,11 @@ export class MenuSettingsUserView extends AbstractViewLeft {
|
|||
|
||||
this.leftPanelDisabled = leftPanelDisabled;
|
||||
|
||||
this.mobile = rl.settings.app('mobile');
|
||||
|
||||
this.menu = screen.menu;
|
||||
}
|
||||
|
||||
onBuild(dom) {
|
||||
if (this.mobile) {
|
||||
if (isMobile()) {
|
||||
dom.addEventListener('click', event =>
|
||||
event.target.closestWithin('.b-settings-menu .e-item.selectable', dom) && leftPanelDisabled(true)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { mailbox } from 'Common/Links';
|
||||
import { getFolderInboxName } from 'Common/Cache';
|
||||
import { leftPanelDisabled } from 'Common/Globals';
|
||||
import { leftPanelDisabled, isMobile } from 'Common/Globals';
|
||||
|
||||
import MessageStore from 'Stores/User/Message';
|
||||
|
||||
|
|
@ -10,8 +10,6 @@ export class PaneSettingsUserView extends AbstractViewRight {
|
|||
constructor() {
|
||||
super('User/Settings/Pane', 'SettingsPane');
|
||||
|
||||
this.mobile = rl.settings.app('mobile');
|
||||
|
||||
this.leftPanelDisabled = leftPanelDisabled;
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +32,7 @@ export class PaneSettingsUserView extends AbstractViewRight {
|
|||
}
|
||||
|
||||
onBuild(dom) {
|
||||
this.mobile && dom.addEventListener('click', () => leftPanelDisabled(true));
|
||||
isMobile() && dom.addEventListener('click', () => leftPanelDisabled(true));
|
||||
}
|
||||
|
||||
backToMailBoxClick() {
|
||||
|
|
|
|||
14
dev/boot.js
14
dev/boot.js
|
|
@ -129,7 +129,7 @@ win.rl = {
|
|||
if (RL_APP_DATA.Title) {
|
||||
title += (title ? ' - ' : '') + RL_APP_DATA.Title;
|
||||
}
|
||||
doc.title = null == title ? '' : '' + title;
|
||||
doc.title = title;
|
||||
},
|
||||
|
||||
initData: appData => {
|
||||
|
|
@ -172,15 +172,7 @@ setInterval(setTimestamp, 60000); // 1m
|
|||
|
||||
[eId('app-css'),eId('app-theme-link')].forEach(css => css.href = css.dataset.href);
|
||||
|
||||
loadScript('./?/'
|
||||
+ (options.admin ? 'Admin' : '')
|
||||
+ 'AppData@'
|
||||
+ (options.mobile ? 'mobile' : 'no-mobile')
|
||||
+ (options.mobileDevice ? '-1' : '-0')
|
||||
+ '/'
|
||||
+ (rl.hash.get() || '0')
|
||||
+ '/'
|
||||
+ Math.random().toString().substr(2)
|
||||
+ '/').then(() => {});
|
||||
loadScript(`./?/${options.admin ? 'Admin' : ''}AppData/${rl.hash.get() || '0'}/${Math.random().toString().substr(2)}/`)
|
||||
.then(() => {});
|
||||
|
||||
})(this);
|
||||
|
|
|
|||
|
|
@ -660,7 +660,7 @@ class Actions
|
|||
{
|
||||
if (null === $this->oAddressBookProvider) {
|
||||
$oDriver = null;
|
||||
if ($this->GetCapa(false, false, Enumerations\Capa::CONTACTS, $oAccount)) {
|
||||
if ($this->GetCapa(false, Enumerations\Capa::CONTACTS, $oAccount)) {
|
||||
if ($this->Config()->Get('contacts', 'enable', false) || $bForceEnable) {
|
||||
$oDriver = $this->fabrica('address-book', $oAccount);
|
||||
}
|
||||
|
|
@ -983,12 +983,12 @@ class Actions
|
|||
return $this->GetAccountFromCustomToken($this->getLocalAuthToken(), $bThrowExceptionOnFalse, true, true);
|
||||
}
|
||||
|
||||
public function AppDataSystem(bool $bAdmin = false, bool $bMobile = false, bool $bMobileDevice = false): array
|
||||
public function AppDataSystem(bool $bAdmin = false): array
|
||||
{
|
||||
$oConfig = $this->Config();
|
||||
|
||||
$aAttachmentsActions = array();
|
||||
if ($this->GetCapa(false, $bMobile, Enumerations\Capa::ATTACHMENTS_ACTIONS)) {
|
||||
if ($this->GetCapa(false, Enumerations\Capa::ATTACHMENTS_ACTIONS)) {
|
||||
if (\class_exists('PharData') || \class_exists('ZipArchive')) {
|
||||
$aAttachmentsActions[] = 'zip';
|
||||
}
|
||||
|
|
@ -997,8 +997,6 @@ class Actions
|
|||
return \array_merge(array(
|
||||
'version' => APP_VERSION,
|
||||
'admin' => $bAdmin,
|
||||
'mobile' => $bMobile,
|
||||
'mobileDevice' => $bMobileDevice,
|
||||
'webPath' => Utils::WebPath(),
|
||||
'webVersionPath' => Utils::WebVersionPath(),
|
||||
'token' => $oConfig->Get('security', 'csrf_protection', false) ? Utils::GetCsrfToken() : '',
|
||||
|
|
@ -1027,7 +1025,7 @@ class Actions
|
|||
) : array());
|
||||
}
|
||||
|
||||
public function AppData(bool $bAdmin, bool $bMobile = false, bool $bMobileDevice = false, string $sAuthAccountHash = ''): array
|
||||
public function AppData(bool $bAdmin, string $sAuthAccountHash = ''): array
|
||||
{
|
||||
if (0 < \strlen($sAuthAccountHash) && \preg_match('/[^_\-\.a-zA-Z0-9]/', $sAuthAccountHash)) {
|
||||
$sAuthAccountHash = '';
|
||||
|
|
@ -1071,7 +1069,7 @@ class Actions
|
|||
'Admin' => array(),
|
||||
'Capa' => array(),
|
||||
'Plugins' => array(),
|
||||
'System' => $this->AppDataSystem($bAdmin, $bMobile, $bMobileDevice),
|
||||
'System' => $this->AppDataSystem($bAdmin),
|
||||
|
||||
'NewMoveToFolder' => (bool) $oConfig->Get('interface', 'new_move_to_folder_button', true),
|
||||
'AllowLanguagesOnSettings' => (bool) $oConfig->Get('webmail', 'allow_languages_on_settings', true),
|
||||
|
|
@ -1165,11 +1163,11 @@ class Actions
|
|||
}
|
||||
}
|
||||
|
||||
$aResult['Capa'] = $this->Capa(false, $bMobile, $oAccount);
|
||||
$aResult['Capa'] = $this->Capa(false, $oAccount);
|
||||
|
||||
if ($aResult['Auth'] && !$aResult['RequireTwoFactor']) {
|
||||
if ($this->GetCapa(false, $bMobile, Enumerations\Capa::TWO_FACTOR, $oAccount) &&
|
||||
$this->GetCapa(false, $bMobile, Enumerations\Capa::TWO_FACTOR_FORCE, $oAccount) &&
|
||||
if ($this->GetCapa(false, Enumerations\Capa::TWO_FACTOR, $oAccount) &&
|
||||
$this->GetCapa(false, Enumerations\Capa::TWO_FACTOR_FORCE, $oAccount) &&
|
||||
$this->TwoFactorAuthProvider()->IsActive()) {
|
||||
$aData = $this->getTwoFactorInfo($oAccount, true);
|
||||
|
||||
|
|
@ -1207,7 +1205,7 @@ class Actions
|
|||
);
|
||||
}
|
||||
|
||||
$aResult['Capa'] = $this->Capa(true, $bMobile);
|
||||
$aResult['Capa'] = $this->Capa(true);
|
||||
}
|
||||
|
||||
$aResult['ProjectHash'] = \md5($aResult['AccountHash'] . APP_VERSION . $this->Plugins()->Hash());
|
||||
|
|
@ -1222,7 +1220,7 @@ class Actions
|
|||
$oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount);
|
||||
|
||||
if ($oSettingsLocal instanceof Settings) {
|
||||
// if ($this->GetCapa(false, $bMobile, Enumerations\Capa::FOLDERS, $oAccount))
|
||||
// if ($this->GetCapa(false, Enumerations\Capa::FOLDERS, $oAccount))
|
||||
|
||||
$aResult['SentFolder'] = (string)$oSettingsLocal->GetConf('SentFolder', '');
|
||||
$aResult['DraftFolder'] = (string)$oSettingsLocal->GetConf('DraftFolder', '');
|
||||
|
|
@ -1232,7 +1230,7 @@ class Actions
|
|||
$aResult['NullFolder'] = (string)$oSettingsLocal->GetConf('NullFolder', '');
|
||||
}
|
||||
|
||||
if ($this->GetCapa(false, $bMobile, Enumerations\Capa::SETTINGS, $oAccount)) {
|
||||
if ($this->GetCapa(false, Enumerations\Capa::SETTINGS, $oAccount)) {
|
||||
if ($oSettings instanceof Settings) {
|
||||
if ($oConfig->Get('webmail', 'allow_languages_on_settings', true)) {
|
||||
$sLanguage = (string)$oSettings->GetConf('Language', $sLanguage);
|
||||
|
|
@ -1249,11 +1247,11 @@ class Actions
|
|||
$aResult['AutoLogout'] = (int)$oSettings->GetConf('AutoLogout', $aResult['AutoLogout']);
|
||||
$aResult['Layout'] = (int)$oSettings->GetConf('Layout', $aResult['Layout']);
|
||||
|
||||
if (!$this->GetCapa(false, $bMobile, Enumerations\Capa::AUTOLOGOUT, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Enumerations\Capa::AUTOLOGOUT, $oAccount)) {
|
||||
$aResult['AutoLogout'] = 0;
|
||||
}
|
||||
|
||||
if ($this->GetCapa(false, $bMobile, Enumerations\Capa::USER_BACKGROUND, $oAccount)) {
|
||||
if ($this->GetCapa(false, Enumerations\Capa::USER_BACKGROUND, $oAccount)) {
|
||||
$aResult['UserBackgroundName'] = (string)$oSettings->GetConf('UserBackgroundName', $aResult['UserBackgroundName']);
|
||||
$aResult['UserBackgroundHash'] = (string)$oSettings->GetConf('UserBackgroundHash', $aResult['UserBackgroundHash']);
|
||||
}
|
||||
|
|
@ -1265,7 +1263,7 @@ class Actions
|
|||
$aResult['UseThreads'] = (bool)$oSettingsLocal->GetConf('UseThreads', $aResult['UseThreads']);
|
||||
$aResult['ReplySameFolder'] = (bool)$oSettingsLocal->GetConf('ReplySameFolder', $aResult['ReplySameFolder']);
|
||||
|
||||
if ($this->GetCapa(false, $bMobile, Enumerations\Capa::THEMES, $oAccount)) {
|
||||
if ($this->GetCapa(false, Enumerations\Capa::THEMES, $oAccount)) {
|
||||
$sTheme = (string)$oSettingsLocal->GetConf('Theme', $sTheme);
|
||||
}
|
||||
}
|
||||
|
|
@ -1327,16 +1325,6 @@ class Actions
|
|||
$aResult['MailToEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['MailToEmail']);
|
||||
$aResult['DevEmail'] = \MailSo\Base\Utils::IdnToUtf8($aResult['DevEmail']);
|
||||
|
||||
// Mobile override
|
||||
if ($bMobile) {
|
||||
$aResult['Layout'] = Enumerations\Layout::NO_PREVIEW;
|
||||
|
||||
$aResult['UseCheckboxesInList'] = true;
|
||||
|
||||
$aResult['UserBackgroundName'] = '';
|
||||
$aResult['UserBackgroundHash'] = '';
|
||||
}
|
||||
|
||||
$this->Plugins()->InitAppData($bAdmin, $aResult, $oAccount);
|
||||
|
||||
return $aResult;
|
||||
|
|
@ -1611,7 +1599,7 @@ class Actions
|
|||
|
||||
public function GetAccounts(Model\Account $oAccount): array
|
||||
{
|
||||
if ($this->GetCapa(false, false, Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
if ($this->GetCapa(false, Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
$sAccounts = $this->StorageProvider()->Get($oAccount,
|
||||
Providers\Storage\Enumerations\StorageType::CONFIG,
|
||||
'accounts'
|
||||
|
|
@ -1866,7 +1854,7 @@ class Actions
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Enumerations\Capa::USER_BACKGROUND, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Enumerations\Capa::USER_BACKGROUND, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -2041,7 +2029,7 @@ class Actions
|
|||
return $this->DefaultResponse(__FUNCTION__, true);
|
||||
}
|
||||
|
||||
public function Capa(bool $bAdmin, bool $bMobile = false, ?Model\Account $oAccount = null): array
|
||||
public function Capa(bool $bAdmin, ?Model\Account $oAccount = null): array
|
||||
{
|
||||
$oConfig = $this->Config();
|
||||
|
||||
|
|
@ -2078,7 +2066,7 @@ class Actions
|
|||
$aResult[] = Enumerations\Capa::IDENTITIES;
|
||||
}
|
||||
|
||||
if ($oConfig->Get('capa', 'x-templates', true) && !$bMobile) {
|
||||
if ($oConfig->Get('capa', 'x-templates', true)) {
|
||||
$aResult[] = Enumerations\Capa::TEMPLATES;
|
||||
}
|
||||
|
||||
|
|
@ -2086,11 +2074,11 @@ class Actions
|
|||
$aResult[] = Enumerations\Capa::THEMES;
|
||||
}
|
||||
|
||||
if ($oConfig->Get('webmail', 'allow_user_background', false) && !$bMobile) {
|
||||
if ($oConfig->Get('webmail', 'allow_user_background', false)) {
|
||||
$aResult[] = Enumerations\Capa::USER_BACKGROUND;
|
||||
}
|
||||
|
||||
if ($oConfig->Get('security', 'openpgp', false) && !$bMobile) {
|
||||
if ($oConfig->Get('security', 'openpgp', false)) {
|
||||
$aResult[] = Enumerations\Capa::OPEN_PGP;
|
||||
}
|
||||
|
||||
|
|
@ -2112,7 +2100,7 @@ class Actions
|
|||
}
|
||||
}
|
||||
|
||||
if ($oConfig->Get('capa', 'help', true) && !$bMobile) {
|
||||
if ($oConfig->Get('capa', 'help', true)) {
|
||||
$aResult[] = Enumerations\Capa::HELP;
|
||||
}
|
||||
|
||||
|
|
@ -2135,7 +2123,7 @@ class Actions
|
|||
if ($oConfig->Get('capa', 'search', true)) {
|
||||
$aResult[] = Enumerations\Capa::SEARCH;
|
||||
|
||||
if ($oConfig->Get('capa', 'search_adv', true) && !$bMobile) {
|
||||
if ($oConfig->Get('capa', 'search_adv', true)) {
|
||||
$aResult[] = Enumerations\Capa::SEARCH_ADV;
|
||||
}
|
||||
}
|
||||
|
|
@ -2144,7 +2132,7 @@ class Actions
|
|||
$aResult[] = Enumerations\Capa::ATTACHMENT_THUMBNAILS;
|
||||
}
|
||||
|
||||
if ($oConfig->Get('labs', 'allow_prefetch', false) && !$bMobile) {
|
||||
if ($oConfig->Get('labs', 'allow_prefetch', false)) {
|
||||
$aResult[] = Enumerations\Capa::PREFETCH;
|
||||
}
|
||||
|
||||
|
|
@ -2153,9 +2141,9 @@ class Actions
|
|||
return $aResult;
|
||||
}
|
||||
|
||||
public function GetCapa(bool $bAdmin, bool $bMobile, string $sName, ?Model\Account $oAccount = null): bool
|
||||
public function GetCapa(bool $bAdmin, string $sName, ?Model\Account $oAccount = null): bool
|
||||
{
|
||||
return \in_array($sName, $this->Capa($bAdmin, $bMobile, $oAccount));
|
||||
return \in_array($sName, $this->Capa($bAdmin, $oAccount));
|
||||
}
|
||||
|
||||
public function etag(string $sKey): string
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ trait Accounts
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ trait Accounts
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ trait Accounts
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::IDENTITIES, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Capa::IDENTITIES, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ trait Accounts
|
|||
|
||||
$mAccounts = false;
|
||||
|
||||
if ($this->GetCapa(false, false, Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
if ($this->GetCapa(false, Capa::ADDITIONAL_ACCOUNTS, $oAccount)) {
|
||||
$mAccounts = $this->GetAccounts($oAccount);
|
||||
$mAccounts = \array_keys($mAccounts);
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ trait Accounts
|
|||
public function GetIdentities(Account $account): array
|
||||
{
|
||||
// A custom name for a single identity is also stored in this system
|
||||
$allowMultipleIdentities = $this->GetCapa(false, false, Capa::IDENTITIES, $account);
|
||||
$allowMultipleIdentities = $this->GetCapa(false, Capa::IDENTITIES, $account);
|
||||
|
||||
// Get all identities
|
||||
$identities = $this->IdentitiesProvider()->GetIdentities($account, $allowMultipleIdentities);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ trait Filters
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::FILTERS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ trait Filters
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Capa::FILTERS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ trait Filters
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Capa::FILTERS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ trait Filters
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||
if (!$this->GetCapa(false, Capa::FILTERS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ trait Folders
|
|||
$oFolderCollection = null;
|
||||
$this->Plugins()->RunHook('filter.folders-before', array($oAccount, $oFolderCollection));
|
||||
|
||||
$bUseFolders = $this->GetCapa(false, false, Capa::FOLDERS, $oAccount);
|
||||
$bUseFolders = $this->GetCapa(false, Capa::FOLDERS, $oAccount);
|
||||
|
||||
if (null === $oFolderCollection)
|
||||
{
|
||||
|
|
@ -157,7 +157,7 @@ trait Folders
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FOLDERS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::FOLDERS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ trait Folders
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FOLDERS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::FOLDERS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ trait Folders
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FOLDERS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::FOLDERS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -263,7 +263,7 @@ trait Folders
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FOLDERS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::FOLDERS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -291,7 +291,7 @@ trait Folders
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FOLDERS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::FOLDERS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ trait Messages
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::COMPOSER, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::COMPOSER, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ trait Messages
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::COMPOSER, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::COMPOSER, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -349,7 +349,7 @@ trait Messages
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::COMPOSER, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::COMPOSER, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,8 +232,6 @@ trait Response
|
|||
$mResult[$prop] = $this->responseObject($mResult[$prop], $sParent, $aParameters);
|
||||
}
|
||||
|
||||
$mResult['SubjectParts'] = $this->explodeSubject($mResult['Subject']);
|
||||
|
||||
$sSubject = $mResult['Subject'];
|
||||
$mResult['Hash'] = \md5($mResult['Folder'].$mResult['Uid']);
|
||||
$mResult['RequestHash'] = Utils::EncodeKeyValuesQ(array(
|
||||
|
|
@ -252,7 +250,7 @@ trait Response
|
|||
$mResult['IsForwarded'] = \strlen($sForwardedFlag) && \in_array(\strtolower($sForwardedFlag), $aFlags);
|
||||
$mResult['IsReadReceipt'] = \strlen($sReadReceiptFlag) && \in_array(\strtolower($sReadReceiptFlag), $aFlags);
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::COMPOSER, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::COMPOSER, $oAccount))
|
||||
{
|
||||
$mResult['IsReadReceipt'] = true;
|
||||
}
|
||||
|
|
@ -392,7 +390,7 @@ trait Response
|
|||
|| ($mFoundedContentLocationUrls && \in_array(\trim($mResponse->ContentLocation()), $mFoundedContentLocationUrls));
|
||||
|
||||
$mResult['Framed'] = $this->isFileHasFramedPreview($mResult['FileName']);
|
||||
$mResult['IsThumbnail'] = $this->GetCapa(false, false, Capa::ATTACHMENT_THUMBNAILS) && $this->isFileHasThumbnail($mResult['FileName']);
|
||||
$mResult['IsThumbnail'] = $this->GetCapa(false, Capa::ATTACHMENT_THUMBNAILS) && $this->isFileHasThumbnail($mResult['FileName']);
|
||||
|
||||
$mResult['Download'] = Utils::EncodeKeyValuesQ(array(
|
||||
'V' => APP_VERSION,
|
||||
|
|
@ -466,48 +464,4 @@ trait Response
|
|||
|
||||
return $mResponse;
|
||||
}
|
||||
|
||||
private function explodeSubject(string $sSubject) : array
|
||||
{
|
||||
$aResult = array('', '');
|
||||
if (0 < \strlen($sSubject))
|
||||
{
|
||||
$bDrop = false;
|
||||
$aPrefix = array();
|
||||
$aSuffix = array();
|
||||
|
||||
$aParts = \explode(':', $sSubject);
|
||||
foreach ($aParts as $sPart)
|
||||
{
|
||||
if (!$bDrop &&
|
||||
(\preg_match('/^(RE|FWD)$/i', \trim($sPart)) || \preg_match('/^(RE|FWD)[\[\(][\d]+[\]\)]$/i', \trim($sPart))))
|
||||
{
|
||||
$aPrefix[] = $sPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSuffix[] = $sPart;
|
||||
$bDrop = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < \count($aPrefix))
|
||||
{
|
||||
$aResult[0] = \rtrim(\trim(\implode(':', $aPrefix)), ':').': ';
|
||||
}
|
||||
|
||||
if (0 < \count($aSuffix))
|
||||
{
|
||||
$aResult[1] = \trim(\implode(':', $aSuffix));
|
||||
}
|
||||
|
||||
if (0 === \strlen($aResult[1]))
|
||||
{
|
||||
$aResult = array('', $sSubject);
|
||||
}
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ trait Templates
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::TEMPLATES, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ trait Templates
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::TEMPLATES, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ trait Templates
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::TEMPLATES, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ trait Templates
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::TEMPLATES, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::TEMPLATES, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ trait TwoFactor
|
|||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->TwoFactorAuthProvider()->IsActive() ||
|
||||
!$this->GetCapa(false, false, Capa::TWO_FACTOR, $oAccount))
|
||||
!$this->GetCapa(false, Capa::TWO_FACTOR, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ trait TwoFactor
|
|||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->TwoFactorAuthProvider()->IsActive() ||
|
||||
!$this->GetCapa(false, false, Capa::TWO_FACTOR, $oAccount))
|
||||
!$this->GetCapa(false, Capa::TWO_FACTOR, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ trait TwoFactor
|
|||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->TwoFactorAuthProvider()->IsActive() ||
|
||||
!$this->GetCapa(false, false, Capa::TWO_FACTOR, $oAccount))
|
||||
!$this->GetCapa(false, Capa::TWO_FACTOR, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ trait TwoFactor
|
|||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->TwoFactorAuthProvider()->IsActive() ||
|
||||
!$this->GetCapa(false, false, Capa::TWO_FACTOR, $oAccount))
|
||||
!$this->GetCapa(false, Capa::TWO_FACTOR, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ trait TwoFactor
|
|||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->TwoFactorAuthProvider()->IsActive() ||
|
||||
!$this->GetCapa(false, false, Capa::TWO_FACTOR, $oAccount))
|
||||
!$this->GetCapa(false, Capa::TWO_FACTOR, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ trait TwoFactor
|
|||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->TwoFactorAuthProvider()->IsActive() ||
|
||||
!$this->GetCapa(false, false, Capa::TWO_FACTOR, $oAccount))
|
||||
!$this->GetCapa(false, Capa::TWO_FACTOR, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ trait User
|
|||
*/
|
||||
public function DoAttachmentsActions() : array
|
||||
{
|
||||
if (!$this->GetCapa(false, false, Capa::ATTACHMENTS_ACTIONS))
|
||||
if (!$this->GetCapa(false, Capa::ATTACHMENTS_ACTIONS))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -311,7 +311,7 @@ trait User
|
|||
public function DoSettingsUpdate() : array
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
if (!$this->GetCapa(false, false, Capa::SETTINGS, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::SETTINGS, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
@ -333,7 +333,7 @@ trait User
|
|||
$oSettings->SetConf('Language', $this->ValidateLanguage($oConfig->Get('webmail', 'language', 'en')));
|
||||
}
|
||||
|
||||
if ($this->GetCapa(false, false, Capa::THEMES, $oAccount))
|
||||
if ($this->GetCapa(false, Capa::THEMES, $oAccount))
|
||||
{
|
||||
$this->setSettingsFromParams($oSettingsLocal, 'Theme', 'string', function ($sTheme) use ($self) {
|
||||
return $self->ValidateTheme($sTheme);
|
||||
|
|
@ -377,7 +377,7 @@ trait User
|
|||
{
|
||||
$oAccount = $this->initMailClientConnection();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::QUOTA, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::QUOTA, $oAccount))
|
||||
{
|
||||
return $this->DefaultResponse(__FUNCTION__, array(0, 0, 0, 0));
|
||||
}
|
||||
|
|
@ -510,7 +510,7 @@ trait User
|
|||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::USER_BACKGROUND, $oAccount))
|
||||
if (!$this->GetCapa(false, Capa::USER_BACKGROUND, $oAccount))
|
||||
{
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,9 +308,6 @@ Enables caching in the system'),
|
|||
),
|
||||
|
||||
'labs' => array(
|
||||
'allow_mobile_version' => array(true,
|
||||
'Experimental settings. Handle with care.
|
||||
'),
|
||||
'ignore_folders_subscription' => array(false),
|
||||
'update_channel' => array('stable'),
|
||||
'allow_prefetch' => array(true),
|
||||
|
|
|
|||
|
|
@ -142,27 +142,6 @@ class Service
|
|||
|
||||
if ($bIndex)
|
||||
{
|
||||
$bMobile = false;
|
||||
$bMobileDevice = false;
|
||||
if ($this->oActions->Config()->Get('labs', 'allow_mobile_version', false))
|
||||
{
|
||||
$bUseMobileVersionForTablets = $this->oActions->Config()->Get('labs', 'use_mobile_version_for_tablets', false);
|
||||
$bMobileDevice = UserAgent::isMobile() &&
|
||||
($bUseMobileVersionForTablets ? true : !UserAgent::isTablet());
|
||||
$sMobileType = (string) Utils::GetCookie(Actions::RL_MOBILE_TYPE, '');
|
||||
switch ($sMobileType) {
|
||||
default:
|
||||
$bMobile = $bMobileDevice;
|
||||
break;
|
||||
case 'mobile':
|
||||
$bMobile = true;
|
||||
break;
|
||||
case 'desktop':
|
||||
$bMobile = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
||||
|
|
@ -176,7 +155,7 @@ class Service
|
|||
return $this;
|
||||
}
|
||||
|
||||
$aTemplateParameters = $this->indexTemplateParameters($bAdmin, $bMobile, $bMobileDevice);
|
||||
$aTemplateParameters = $this->indexTemplateParameters($bAdmin);
|
||||
|
||||
$sCacheFileName = '';
|
||||
if ($this->oActions->Config()->Get('labs', 'cache_system_data', true) && !empty($aTemplateParameters['{{BaseHash}}']))
|
||||
|
|
@ -207,12 +186,6 @@ class Service
|
|||
$sResult .= '][cached:'.($bCached ? 'true' : 'false');
|
||||
// $sResult .= '][hash:'.$aTemplateParameters['{{BaseHash}}'];
|
||||
// $sResult .= '][session:'.\md5(Utils::GetShortToken());
|
||||
|
||||
if ($bMobile)
|
||||
{
|
||||
$sResult .= '][mobile:true';
|
||||
}
|
||||
|
||||
$sResult .= ']-->';
|
||||
}
|
||||
else if (!headers_sent())
|
||||
|
|
@ -233,12 +206,25 @@ class Service
|
|||
return $this->oActions->StaticPath($sPath);
|
||||
}
|
||||
|
||||
private function indexTemplateParameters(bool $bAdmin = false, bool $bMobile = false, bool $bMobileDevice = false) : array
|
||||
private function indexTemplateParameters(bool $bAdmin = false) : array
|
||||
{
|
||||
$sLanguage = 'en';
|
||||
$sTheme = 'Default';
|
||||
switch (Utils::GetCookie(Actions::RL_MOBILE_TYPE, '')) {
|
||||
case 'mobile':
|
||||
$bMobile = true;
|
||||
break;
|
||||
case 'desktop':
|
||||
$bMobile = false;
|
||||
break;
|
||||
default:
|
||||
$bMobile = UserAgent::isMobile() && (
|
||||
$this->oActions->Config()->Get('labs', 'use_mobile_version_for_tablets', false)
|
||||
|| !UserAgent::isTablet());
|
||||
break;
|
||||
}
|
||||
|
||||
list($sLanguage, $sTheme) = $this->oActions->GetLanguageAndTheme($bAdmin, $bMobile);
|
||||
list($sLanguage, $sTheme) = $this->oActions->GetLanguageAndTheme($bAdmin);
|
||||
|
||||
$oConfig = $this->oActions->Config();
|
||||
|
||||
|
|
@ -262,19 +248,17 @@ class Service
|
|||
'{{BaseAppPolyfillsScriptLink}}' => '',
|
||||
'{{BaseAppBootScriptLink}}' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'boot'.($bAppJsDebug ? '' : '.min').'.js'),
|
||||
'{{BaseAppBootScript}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/js/min/boot.min.js'),
|
||||
'{{BaseViewport}}' => $bMobile ? 'width=device-width,initial-scale=1,user-scalable=no' : 'width=950,maximum-scale=2',
|
||||
'{{BaseContentSecurityPolicy}}' => '',
|
||||
'{{BaseDir}}' => false && \in_array($sLanguage, array('ar', 'he', 'ur')) ? 'rtl' : 'ltr',
|
||||
'{{BaseAppManifestLink}}' => $this->staticPath('manifest.json'),
|
||||
'{{BaseAppBootCss}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/css/boot.min.css'),
|
||||
'{{BaseCssClass}}' => ($bMobileDevice ? 'mobile' : 'no-mobile') . ($bMobile ? ' rl-mobile' : ''),
|
||||
'{{BaseCssClass}}' => $bMobile ? ' rl-mobile' : '',
|
||||
'{{LoadingDescriptionEsc}}' => \htmlspecialchars($LoadingDescription, ENT_QUOTES|ENT_IGNORE, 'UTF-8'),
|
||||
'{{RainloopBootData}}' => \json_encode(array(
|
||||
'admin' => $bAdmin,
|
||||
'language' => $sLanguage,
|
||||
'theme' => $sTheme,
|
||||
'mobile' => $bMobile,
|
||||
'mobileDevice' => $bMobileDevice
|
||||
'mobile' => $bMobile
|
||||
))
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -661,14 +661,14 @@ class ServiceActions
|
|||
return $bJson ? \MailSo\Base\Utils::Php2js(array($sTheme, $sResult), $this->Logger()) : $sResult;
|
||||
}
|
||||
|
||||
public function ServiceAppData(string $sAdd = '') : string
|
||||
public function ServiceAppData() : string
|
||||
{
|
||||
return $this->localAppData(false, $sAdd);
|
||||
return $this->localAppData(false);
|
||||
}
|
||||
|
||||
public function ServiceAdminAppData(string $sAdd = '') : string
|
||||
public function ServiceAdminAppData() : string
|
||||
{
|
||||
return $this->localAppData(true, $sAdd);
|
||||
return $this->localAppData(true);
|
||||
}
|
||||
|
||||
public function ServiceMobileVersion() : string
|
||||
|
|
@ -897,7 +897,7 @@ class ServiceActions
|
|||
|
||||
$oAccount = $this->oActions->GetAccount();
|
||||
|
||||
if ($oAccount && $this->oActions->GetCapa(false, false, Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount))
|
||||
if ($oAccount && $this->oActions->GetCapa(false, Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount))
|
||||
{
|
||||
$oAccountToLogin = null;
|
||||
$sEmail = empty($this->aPaths[2]) ? '' : \urldecode(\trim($this->aPaths[2]));
|
||||
|
|
@ -948,7 +948,7 @@ class ServiceActions
|
|||
return $this->ErrorTemplates($sTitle, \nl2br($sDesc));
|
||||
}
|
||||
|
||||
private function localAppData(bool $bAdmin = false, string $sAdd = '') : string
|
||||
private function localAppData(bool $bAdmin = false) : string
|
||||
{
|
||||
\header('Content-Type: application/javascript; charset=utf-8');
|
||||
$this->oHttp->ServerNoCache();
|
||||
|
|
@ -987,9 +987,7 @@ class ServiceActions
|
|||
}
|
||||
|
||||
$sResult = 'rl.initData('
|
||||
.\json_encode($this->oActions->AppData($bAdmin,
|
||||
0 === \strpos($sAdd, 'mobile'), '1' === \substr($sAdd, -1),
|
||||
$sAuthAccountHash))
|
||||
.\json_encode($this->oActions->AppData($bAdmin, $sAuthAccountHash))
|
||||
.');';
|
||||
|
||||
$this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPDATA');
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<meta http-equiv="refresh" content="0; URL=./?/NoScript" />
|
||||
</noscript>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="{{BaseViewport}}">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="google" content="notranslate" />
|
||||
<meta name="robots" content="noindex,nofollow,noodp" />
|
||||
|
|
|
|||
|
|
@ -52,9 +52,7 @@
|
|||
autocorrect="off" autocapitalize="off" spellcheck="false" style="padding-right: 35px;"
|
||||
data-bind="textInput: additionalCode, disable: submitRequest"
|
||||
data-i18n="[placeholder]LOGIN/LABEL_VERIFICATION_CODE" />
|
||||
<span class="add-on">
|
||||
<i class="fontastic">🔑</i>
|
||||
</span>
|
||||
<span class="add-on fontastic">🔑</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls plugin-mark-Login-BottomControlGroup"
|
||||
|
|
@ -109,19 +107,15 @@
|
|||
</form>
|
||||
</div>
|
||||
<div class="e-mobile-switcher">
|
||||
<span data-bind="visible: !mobile">
|
||||
<span class="hide-mobile">
|
||||
<i class="fontastic">📱</i>
|
||||
|
||||
<a href="./?/MobileVersion/" tabindex="-1">
|
||||
<span data-i18n="MOBILE/BUTTON_MOBILE_VERSION"></span>
|
||||
</a>
|
||||
<a href="./?/MobileVersion/" tabindex="-1" data-i18n="MOBILE/BUTTON_MOBILE_VERSION"></a>
|
||||
</span>
|
||||
<span data-bind="visible: mobile">
|
||||
<span class="show-mobile">
|
||||
<i class="fontastic">💻</i>
|
||||
|
||||
<a href="./?/DesktopVersion/" tabindex="-1">
|
||||
<span data-i18n="MOBILE/BUTTON_DESKTOP_VERSION"></span>
|
||||
</a>
|
||||
<a href="./?/DesktopVersion/" tabindex="-1" data-i18n="MOBILE/BUTTON_DESKTOP_VERSION"></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="b-folders g-ui-user-select-none" data-bind="css: {'focused': folderListFocused, 'single-root-inbox': foldersListWithSingleInboxRootFolder, 'inbox-is-starred': isInboxStarred}">
|
||||
<div class="b-toolbar btn-toolbar hide-on-mobile">
|
||||
<div class="b-toolbar btn-toolbar hide-mobile">
|
||||
<a class="btn buttonCompose" data-bind="visible: allowComposer, click: composeClick, tooltip: 'FOLDER_LIST/BUTTON_NEW_MESSAGE', css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}">
|
||||
<i class="icon-paper-plane"></i>
|
||||
<span class="buttonComposeText" data-i18n="FOLDER_LIST/BUTTON_NEW_MESSAGE"></span>
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="b-content show-on-panel-disabled" data-bind="click: function () { leftPanelDisabled(false); }"></div>
|
||||
<div class="b-footer btn-toolbar hide-on-mobile" data-bind="visible: allowFolders">
|
||||
<div class="b-footer btn-toolbar hide-mobile" data-bind="visible: allowFolders">
|
||||
<div class="btn-group">
|
||||
<a class="btn buttonResize" data-bind="click: function () { leftPanelDisabled(!leftPanelDisabled()); }">
|
||||
<i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i>
|
||||
|
|
@ -27,9 +27,7 @@
|
|||
<a class="btn" data-bind="click: createFolder">
|
||||
<i data-bind="css: {'icon-folder-add': !foldersChanging(), 'icon-spinner': foldersChanging()}"></i>
|
||||
</a>
|
||||
<a class="btn" data-bind="click: configureFolders">
|
||||
<i class="fontastic">⚙</i>
|
||||
</a>
|
||||
<a class="btn fontastic" data-bind="click: configureFolders">⚙</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,24 +3,22 @@
|
|||
data-bind="css: {'message-selected': isMessageSelected, 'message-focused': !messageListFocused(), 'hideMessageListCheckbox': !useCheckboxesInList() }">
|
||||
<div class="toolbar">
|
||||
<div class="btn-toolbar">
|
||||
<!-- ko if: mobile -->
|
||||
<!-- ko if: allowFolders -->
|
||||
<a class="btn btn-thin-2" data-bind="click: showLeft, visible: leftPanelDisabled()">
|
||||
<a class="btn btn-thin-2 show-mobile" data-bind="click: showLeft, visible: leftPanelDisabled()">
|
||||
<i class="icon-right-middle"></i>
|
||||
</a>
|
||||
<a class="btn btn-thin-2" data-bind="click: hideLeft, visible: !leftPanelDisabled()">
|
||||
<a class="btn btn-thin-2 show-mobile" data-bind="click: hideLeft, visible: !leftPanelDisabled()">
|
||||
<i class="icon-left-middle"></i>
|
||||
</a>
|
||||
<!-- /ko -->
|
||||
<a class="btn buttonCompose" data-bind="click: composeClick, tooltip: 'FOLDER_LIST/BUTTON_NEW_MESSAGE', css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}, visible: allowComposer && mobileCheckedStateHide()">
|
||||
<a class="btn buttonCompose show-mobile" data-bind="click: composeClick, tooltip: 'FOLDER_LIST/BUTTON_NEW_MESSAGE', css: {'btn-warning': composeInEdit, 'btn-success': !composeInEdit()}, visible: allowComposer && mobileCheckedStateHide()">
|
||||
<i class="icon-paper-plane"></i>
|
||||
</a>
|
||||
<!-- /ko -->
|
||||
<a class="btn buttonReload" data-bind="command: reloadCommand, tooltip: 'MESSAGE_LIST/BUTTON_RELOAD', visible: allowReload && mobileCheckedStateHide()">
|
||||
<i class="icon-spinner" data-bind="css: {'not-animated': !messageListCompleteLoadingThrottleForAnimation()}"></i>
|
||||
</a>
|
||||
<!-- ko if: !newMoveToFolder -->
|
||||
<div class="btn-group dropdown colored-toggle hide-on-mobile" data-bind="visible: allowMessageListActions, registerBootstrapDropdown: true, openDropdownTrigger: moveDropdownTrigger">
|
||||
<div class="btn-group dropdown colored-toggle hide-mobile" data-bind="visible: allowMessageListActions, registerBootstrapDropdown: true, openDropdownTrigger: moveDropdownTrigger">
|
||||
<a id="move-dropdown-id" href="#" tabindex="-1" class="btn dropdown-toggle buttonMove" data-toggle="dropdown" data-bind="command: moveCommand, tooltip: 'GLOBAL/MOVE_TO'">
|
||||
<i class="icon-copy visible-on-ctrl-btn"></i>
|
||||
<i class="fontastic hidden-on-ctrl-btn">📁</i>
|
||||
|
|
@ -157,7 +155,47 @@
|
|||
<span data-i18n="MESSAGE_LIST/EMPTY_SEARCH_LIST"></span>
|
||||
</div>
|
||||
<div data-bind="dragmessages: getDragData">
|
||||
<div class="messageListPlace" data-bind="template: { name: messageListItemTemplate(), foreach: messageList }"></div>
|
||||
<div class="messageListPlace" data-bind="foreach: messageList">
|
||||
|
||||
<div class="messageListItem" data-bind="css: lineAsCss()">
|
||||
<div class="checkboxMessage fontastic" data-bind="text: checked() ? '☑' : '☐'"></div>
|
||||
|
||||
<div class="flagParent">
|
||||
<i class="flagOn fontastic">★</i>
|
||||
<i class="flagOnHalf fontastic">☆</i>
|
||||
<i class="flagOff fontastic">☆</i>
|
||||
<!-- ⚐⚑ -->
|
||||
</div>
|
||||
|
||||
<div class="senderParent actionHandle">
|
||||
<i class="replyFlag fontastic">←</i>
|
||||
<i class="forwardFlag fontastic">→</i>
|
||||
<span class="sender" data-bind="text: senderEmailsString, attr: {'title': senderClearEmailsString}"></span>
|
||||
</div>
|
||||
|
||||
<div class="attachmentParent actionHandle">
|
||||
<i data-bind="css: attachmentIconClass"></i>
|
||||
</div>
|
||||
|
||||
<div class="subjectParent actionHandle">
|
||||
<b class="importantMark">!</b>
|
||||
<span class="emptySubjectText" data-bind="text: $root.emptySubjectValue"></span>
|
||||
<span class="subject" data-bind="text: subject"></span>
|
||||
</div>
|
||||
|
||||
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
||||
<span class="threads-len">
|
||||
<span class="threads-len-data">
|
||||
<span data-bind="text: threadsLen"></span>
|
||||
<i class="icon-right-mini"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<time class="actionHandle" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></time>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="messagesDragImage"><span class="text"></span> <i class="icon-mail icon-white"></i></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
<div class="messageListItem" data-bind="css: lineAsCss()">
|
||||
<div class="sidebarParent">
|
||||
|
||||
</div>
|
||||
<div class="delimiter"></div>
|
||||
<div class="wrapper">
|
||||
<div class="flagParent">
|
||||
<i class="flagOn fontastic">★</i>
|
||||
<i class="flagOnHalf fontastic">☆</i>
|
||||
<i class="flagOff fontastic">☆</i>
|
||||
</div>
|
||||
<div class="dateParent actionHandle">
|
||||
<time class="date" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></time>
|
||||
</div>
|
||||
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
||||
<span class="threads-len">
|
||||
<span class="threads-len-data">
|
||||
<span data-bind="text: threadsLen"></span>
|
||||
<i class="icon-right-mini"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="checkboxMessage fontastic" data-bind="text: checked() ? '☑' : '☐'"></div>
|
||||
<div class="senderParent actionHandle">
|
||||
<span class="replyFlag"><i class="fontastic">←</i> </span>
|
||||
<span class="forwardFlag"><i class="fontastic">→</i> </span>
|
||||
<span class="sender" data-bind="text: senderEmailsString, attr: {'title': senderClearEmailsString}"></span>
|
||||
|
||||
</div>
|
||||
<div class="attachmentParent actionHandle">
|
||||
<span class="attachment">
|
||||
<i data-bind="css: attachmentIconClass"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="subjectParent actionHandle">
|
||||
<b class="importantMark">!</b>
|
||||
<span class="subject emptySubjectText" data-bind="text: $root.emptySubjectValue"></span>
|
||||
<span class="subject-prefix" data-bind="text: subjectPrefix"></span><span class="subject-suffix" data-bind="text: subjectSuffix"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<div class="messageListItem e-single-line" data-bind="css: lineAsCss()">
|
||||
<div class="sidebarParent">
|
||||
|
||||
</div>
|
||||
<div class="delimiter"></div>
|
||||
<div class="wrapper">
|
||||
<div class="dateParent actionHandle">
|
||||
<time class="date" data-moment-format="SHORT" data-moment-format-title="FULL" data-bind="moment: dateTimeStampInUTC"></time>
|
||||
</div>
|
||||
<div class="threadsParent" data-bind="visible: 1 < threadsLen()">
|
||||
<span class="threads-len">
|
||||
<span class="threads-len-data">
|
||||
<span data-bind="text: threadsLen"></span>
|
||||
<i class="icon-right-mini"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="checkboxMessage fontastic" data-bind="text: checked() ? '☑' : '☐'"></div>
|
||||
<div class="flagParent">
|
||||
<i class="flagOn fontastic">★</i>
|
||||
<i class="flagOnHalf fontastic">☆</i>
|
||||
<i class="flagOff fontastic">☆</i>
|
||||
</div>
|
||||
<div class="senderParent actionHandle">
|
||||
<span class="replyFlag"><i class="fontastic">←</i> </span>
|
||||
<span class="forwardFlag"><i class="fontastic">→</i> </span>
|
||||
<span class="sender" data-bind="text: senderEmailsString, attr: {'title': senderClearEmailsString}"></span>
|
||||
|
||||
</div>
|
||||
<div class="attachmentParent actionHandle">
|
||||
<span class="attachment">
|
||||
<i data-bind="css: attachmentIconClass"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="subjectParent actionHandle">
|
||||
<b class="importantMark">!</b>
|
||||
<span class="subject emptySubjectText" data-bind="text: $root.emptySubjectValue"></span>
|
||||
<span class="subject-prefix" data-bind="text: subjectPrefix"></span><span class="subject-suffix" data-bind="text: subjectSuffix"></span>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,14 +3,10 @@
|
|||
<div class="toolbar top-toolbar g-ui-user-select-none" data-bind="visible: !usePreviewPane()">
|
||||
<div class="messageButtons btn-toolbar">
|
||||
<div class="btn-group" data-bind="tooltip: 'GLOBAL/CLOSE'">
|
||||
<a class="btn buttonClose" data-bind="command: closeMessageCommand">
|
||||
<i class="fontastic">✖</i>
|
||||
</a>
|
||||
<a class="btn buttonClose fontastic" data-bind="command: closeMessageCommand">✖</a>
|
||||
</div>
|
||||
<div class="btn-group" data-bind="visible: isDraftFolder(), tooltip: 'MESSAGE/BUTTON_EDIT'">
|
||||
<a class="btn btn-success buttonEdit" data-bind="command: messageEditCommand">
|
||||
<i class="fontastic icon-white">🖉</i>
|
||||
</a>
|
||||
<a class="btn btn-success buttonEdit fontastic icon-white" data-bind="command: messageEditCommand">🖉</a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<a class="btn button-archive" data-bind="visible: !isDraftFolder() && !isArchiveFolder() && !isArchiveDisabled(), command: archiveCommand, tooltip: 'GLOBAL/TO_ARCHIVE'">
|
||||
|
|
@ -55,18 +51,12 @@
|
|||
|
||||
<div class="message-fixed-button-toolbar" data-bind="visible: message">
|
||||
<div class="btn-group" style="margin-right: -11px;">
|
||||
<a class="btn btn-thin-2 btn-transparent buttonReply"
|
||||
data-bind="visible: 'reply' === lastReplyAction() && allowComposer, command: replyCommand, tooltip: 'MESSAGE/BUTTON_REPLY'">
|
||||
<i class="fontastic">←</i>
|
||||
</a>
|
||||
<a class="btn btn-thin-2 btn-transparent buttonReplyAll"
|
||||
data-bind="visible: 'replyall' === lastReplyAction() && allowComposer, command: replyAllCommand, tooltip: 'MESSAGE/BUTTON_REPLY_ALL'">
|
||||
<i class="fontastic">↞</i>
|
||||
</a>
|
||||
<a class="btn btn-thin-2 btn-transparent buttonForward"
|
||||
data-bind="visible: 'forward' === lastReplyAction() && allowComposer, command: forwardCommand, tooltip: 'MESSAGE/BUTTON_FORWARD'">
|
||||
<i class="fontastic">→</i>
|
||||
</a>
|
||||
<a class="btn btn-thin-2 btn-transparent buttonReply fontastic"
|
||||
data-bind="visible: 'reply' === lastReplyAction() && allowComposer, command: replyCommand, tooltip: 'MESSAGE/BUTTON_REPLY'">←</a>
|
||||
<a class="btn btn-thin-2 btn-transparent buttonReplyAll fontastic"
|
||||
data-bind="visible: 'replyall' === lastReplyAction() && allowComposer, command: replyAllCommand, tooltip: 'MESSAGE/BUTTON_REPLY_ALL'">↞</a>
|
||||
<a class="btn btn-thin-2 btn-transparent buttonForward fontastic"
|
||||
data-bind="visible: 'forward' === lastReplyAction() && allowComposer, command: forwardCommand, tooltip: 'MESSAGE/BUTTON_FORWARD'">→</a>
|
||||
<div class="btn-group" data-bind="registerBootstrapDropdown: true, visible: allowComposer || allowMessageListActions || allowMessageActions" style="display: inline-block">
|
||||
<a class="btn btn-thin-2 btn-transparent dropdown-toggle" id="more-view-dropdown-id" href="#" tabindex="-1" data-toggle="dropdown" style="margin-left: -4px; margin-right: 2px" data-bind="command: messageVisibilityCommand">
|
||||
<span data-bind="visible: !allowComposer" class="fontastic">⋮</span>
|
||||
|
|
@ -167,10 +157,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group hide-on-mobile" data-bind="visible: isDraftFolder(), tooltip: 'MESSAGE/BUTTON_EDIT'" style="margin-right: 5px">
|
||||
<a class="btn btn-success buttonEdit" data-bind="command: messageEditCommand">
|
||||
<i class="fontastic icon-white">🖉</i>
|
||||
</a>
|
||||
<div class="btn-group hide-mobile" data-bind="visible: isDraftFolder(), tooltip: 'MESSAGE/BUTTON_EDIT'" style="margin-right: 5px">
|
||||
<a class="btn btn-success buttonEdit fontastic icon-white" data-bind="command: messageEditCommand">🖉</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -302,18 +290,14 @@
|
|||
<i class="attachmentIconText attachmentMainIconText" data-bind="text: iconText()"></i>
|
||||
</div>
|
||||
<div class="iconBG" data-bind="attr: { 'style': linkThumbnailPreviewStyle() }"></div>
|
||||
<div class="iconPreview">
|
||||
<i class="attachmentIcon fontastic show-hover">👁</i>
|
||||
</div>
|
||||
<div class="iconPreview attachmentIcon fontastic show-hover">👁</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="showPreplay">
|
||||
<div class="iconMain">
|
||||
<i class="attachmentIcon attachmentMainIcon" data-bind="css: iconClass()"></i>
|
||||
</div>
|
||||
<div class="iconPreview">
|
||||
<i class="attachmentIcon fontastic show-hover">▶</i>
|
||||
</div>
|
||||
<div class="iconPreview attachmentIcon fontastic show-hover">▶</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="attachmentNameParent">
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
<div class="modal-header b-header-toolbar g-ui-user-select-none">
|
||||
<a class="btn btn-large button-send" data-bind="command: sendCommand, tooltipErrorTip: sendErrorDesc, css: {'btn-success': sendButtonSuccess, 'btn-danger': sendError, 'btn-warning': sendSuccessButSaveError }">
|
||||
<i class="icon-white" data-bind="css: {'icon-paper-plane': !sending(), 'icon-spinner big': sending()}"></i>
|
||||
<span class="i18n hide-on-mobile" data-i18n="COMPOSE/BUTTON_SEND"></span>
|
||||
<span class="i18n hide-mobile" data-i18n="COMPOSE/BUTTON_SEND"></span>
|
||||
</a>
|
||||
<a class="btn button-save" data-bind="visible: allowFolders, command: saveCommand, tooltipErrorTip: savedErrorDesc, css: {'btn-danger': savedError }">
|
||||
<i class="fontastic" data-bind="css: {'icon-spinner': saving(), 'icon-white': savedError()}">💾</i>
|
||||
<span class="i18n hide-on-mobile" data-i18n="GLOBAL/SAVE"></span>
|
||||
<span class="i18n hide-mobile" data-i18n="GLOBAL/SAVE"></span>
|
||||
</a>
|
||||
|
||||
<a class="close" data-bind="click: tryToClosePopup, tooltip: 'GLOBAL/CANCEL'">×</a>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<a class="btn btn-danger button-delete button-delete-transitions" data-bind="command: deleteCommand">
|
||||
<i class="fontastic icon-white">🗑</i>
|
||||
</a>
|
||||
<span class="saved-text hide-on-mobile" data-bind="text: savedTimeText"></span>
|
||||
<span class="saved-text hide-mobile" data-bind="text: savedTimeText"></span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="b-header g-ui-user-select-none">
|
||||
|
|
|
|||
|
|
@ -19,15 +19,11 @@
|
|||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<a class="btn button-delete" data-bind="command: deleteCommand">
|
||||
<i class="fontastic">🗑</i>
|
||||
</a>
|
||||
<a class="btn button-delete fontastic" data-bind="command: deleteCommand">🗑</a>
|
||||
</div>
|
||||
|
||||
<div class="btn-group dropdown colored-toggle" data-bind="registerBootstrapDropdown: true">
|
||||
<a id="contacts-more-dropdown-id" class="btn dropdown-toggle" href="#" tabindex="-1" data-toggle="dropdown">
|
||||
<i class="fontastic" data-bind="css: {'icon-spinner': contacts.importing() || contacts.syncing()}">☰</i>
|
||||
</a>
|
||||
<a id="contacts-more-dropdown-id" class="btn dropdown-toggle fontastic" href="#" tabindex="-1" data-toggle="dropdown" data-bind="css: {'icon-spinner': contacts.importing() || contacts.syncing()}">☰</a>
|
||||
<ul class="dropdown-menu g-ui-menu right-edge" role="menu" aria-labelledby="contacts-more-dropdown-id">
|
||||
<li class="e-item" role="presentation">
|
||||
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="initDom: importUploaderButton">
|
||||
|
|
@ -35,13 +31,13 @@
|
|||
<span data-i18n="CONTACTS/BUTTON_IMPORT"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="e-item dividerbar hide-mobile" role="presentation">
|
||||
<li class="e-item dividerbar" role="presentation">
|
||||
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: exportCsv">
|
||||
<i data-bind="css: {'icon-export': !contacts.exportingCsv(), 'icon-spinner': contacts.exportingCsv}"></i>
|
||||
<span data-i18n="CONTACTS/BUTTON_EXPORT_CSV"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="e-item hide-mobile" role="presentation">
|
||||
<li class="e-item" role="presentation">
|
||||
<a class="e-link menuitem" href="#" tabindex="-1" data-bind="click: exportVcf">
|
||||
<i data-bind="css: {'icon-export': !contacts.exportingVcf(), 'icon-spinner': contacts.exportingVcf}"></i>
|
||||
<span data-i18n="CONTACTS/BUTTON_EXPORT_VCARD"></span>
|
||||
|
|
@ -79,16 +75,11 @@
|
|||
</div>
|
||||
<div class="e-contact-foreach g-ui-user-select-none" data-bind="foreach: contacts, visible: 0 < contacts().length">
|
||||
<div class="e-contact-item g-ui-user-select-none" data-bind="css: lineAsCss()">
|
||||
<div class="sidebarParent">
|
||||
<div class="checkboxItem fontastic" data-bind="text: checked() ? '☑' : '☐'"></div>
|
||||
<div class="nameParent actionHandle">
|
||||
<span class="listName" data-bind="text: display"></span>
|
||||
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div class="checkboxItem fontastic" data-bind="text: checked() ? '☑' : '☐'"></div>
|
||||
<div class="nameParent actionHandle">
|
||||
<span class="listName" data-bind="text: display"></span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -75,9 +75,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-filter" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oFilter) { $root.filterForDeletion(oFilter); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-filter fontastic" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oFilter) { $root.filterForDeletion(oFilter); }">🗑</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-account" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oAccount) { $root.accountForDeletion(oAccount); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-account fontastic" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oAccount) { $root.accountForDeletion(oAccount); }">🗑</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -83,9 +81,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-identity" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oIdentity) { $root.identityForDeletion(oIdentity); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-identity fontastic" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oIdentity) { $root.identityForDeletion(oIdentity); }">🗑</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-script" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oScript) { $root.scriptForDeletion(oScript); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-script fontastic" data-bind="visible: !deleteAccess() && canBeDeleted(), click: function (oScript) { $root.scriptForDeletion(oScript); }">🗑</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@
|
|||
<div class="controls">
|
||||
<input type="text" class="span5" data-bind="value: actionValueFourth"
|
||||
data-i18n="[placeholder]POPUPS_FILTER/VACATION_RECIPIENTS_LABEL" />
|
||||
<button class="btn setRecipientsBtn" data-bind="click: setRecipients">
|
||||
<i class="fontastic">✚</i>
|
||||
</button>
|
||||
<button class="btn setRecipientsBtn fontastic" data-bind="click: setRecipients">✚</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" style="margin-bottom: 0">
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
<input class="span3" type="text" data-bind="value: value" />
|
||||
|
||||
<span class="delete-action button-delete pull-right" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-action button-delete pull-right fontastic" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">🗑</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
<input class="span3" type="text" data-bind="value: value" />
|
||||
|
||||
<span class="delete-action button-delete pull-right" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-action button-delete pull-right fontastic" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">🗑</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
<input class="span3" type="text" data-bind="value: value" />
|
||||
|
||||
<span class="delete-action button-delete pull-right" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-action button-delete pull-right fontastic" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">🗑</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
<input class="span3" type="text" data-bind="value: value" />
|
||||
|
||||
<span class="delete-action button-delete pull-right" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-action button-delete pull-right fontastic" style="margin-top: 5px;"
|
||||
data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }">🗑</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
value: showImages
|
||||
}
|
||||
}"></div>
|
||||
<div class="hide-on-mobile" data-bind="component: {
|
||||
<div class="hide-mobile" data-bind="component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'SETTINGS_GENERAL/LABEL_USE_CHECKBOXES_IN_LIST',
|
||||
|
|
|
|||
|
|
@ -37,9 +37,7 @@
|
|||
<!-- ko foreach: openpgpkeysPrivate -->
|
||||
<tr class="open-pgp-key-item">
|
||||
<td>
|
||||
<span class="open-pgp-key-img" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PRIVATE">
|
||||
<i class="fontastic">🔒</i>
|
||||
</span>
|
||||
<span class="open-pgp-key-img fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PRIVATE">🔒</span>
|
||||
<span class="open-pgp-key-user">
|
||||
<!-- ko foreach: users -->
|
||||
<div class="open-pgp-key-user-address" data-bind="text: $data"></div>
|
||||
|
|
@ -50,23 +48,17 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-open-pgp-key" data-bind="visible: !deleteAccess(), click: function (openPgpKey) { $root.openPgpKeyForDeletion(openPgpKey); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-open-pgp-key fontastic" data-bind="visible: !deleteAccess(), click: function (openPgpKey) { $root.openPgpKeyForDeletion(openPgpKey); }">🗑</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="view-open-pgp-key" data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">
|
||||
<i class="fontastic">👁</i>
|
||||
</span>
|
||||
<span class="view-open-pgp-key fontastic" data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">👁</span>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /ko -->
|
||||
<!-- ko foreach: openpgpkeysPublic -->
|
||||
<tr class="open-pgp-key-item">
|
||||
<td>
|
||||
<span class="open-pgp-key-img" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PUBLIC">
|
||||
<i class="fontastic">🔑</i>
|
||||
</span>
|
||||
<span class="open-pgp-key-img fontastic" data-i18n="[title]SETTINGS_OPEN_PGP/TITLE_PUBLIC">🔑</span>
|
||||
<span class="open-pgp-key-user">
|
||||
<!-- ko foreach: users -->
|
||||
<div class="open-pgp-key-user-address">
|
||||
|
|
@ -79,14 +71,10 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-open-pgp-key" data-bind="visible: !deleteAccess(), click: function (openPgpKey) { $root.openPgpKeyForDeletion(openPgpKey); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-open-pgp-key fontastic" data-bind="visible: !deleteAccess(), click: function (openPgpKey) { $root.openPgpKeyForDeletion(openPgpKey); }">🗑</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="view-open-pgp-key" data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">
|
||||
<i class="fontastic">👁</i>
|
||||
</span>
|
||||
<span class="view-open-pgp-key fontastic" data-bind="click: function (openPgpKey) { $root.viewOpenPgpKey(openPgpKey); }">👁</span>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /ko -->
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<div class="b-settings b-settins-right">
|
||||
<div class="b-toolbar" style="padding-left: 0">
|
||||
<div class="btn-toolbar" style="margin-top: 2px;">
|
||||
<div class="btn-group" data-bind="visible: mobile && leftPanelDisabled()">
|
||||
<div class="btn-group show-mobile" data-bind="visible: leftPanelDisabled()">
|
||||
<a class="btn btn-thin-2" data-bind="click: showLeft">
|
||||
<i class="icon-right-middle"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group" data-bind="visible: mobile && !leftPanelDisabled()" style="margin-left: -1px">
|
||||
<div class="btn-group show-mobile" data-bind="visible: !leftPanelDisabled()" style="margin-left: -1px">
|
||||
<a class="btn btn-thin-2" data-bind="click: hideLeft">
|
||||
<i class="icon-left-middle"></i>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -34,9 +34,7 @@
|
|||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-template" data-bind="visible: !deleteAccess(), click: function (oTemplate) { $root.templateForDeletion(oTemplate); }">
|
||||
<i class="fontastic">🗑</i>
|
||||
</span>
|
||||
<span class="delete-template fontastic" data-bind="visible: !deleteAccess(), click: function (oTemplate) { $root.templateForDeletion(oTemplate); }">🗑</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</div>
|
||||
<i class="stopIcon fontastic">⏸</i>
|
||||
</div>
|
||||
<div class="accountPlace hide-on-mobile" data-bind="text: emailTitle()"></div>
|
||||
<div class="accountPlace hide-mobile" data-bind="text: emailTitle()"></div>
|
||||
<div class="btn-group dropdown colored-toggle" data-bind="registerBootstrapDropdown: true, openDropdownTrigger: accountMenuDropdownTrigger">
|
||||
<a id="top-system-dropdown-id" href="#" tabindex="-1" class="btn single btn-ellipsis btn-block dropdown-toggle system-dropdown" data-toggle="dropdown">
|
||||
<i class="fontastic" data-bind="css: {'icon-spinner': accounts.loading()}">👤</i>
|
||||
|
|
@ -64,13 +64,13 @@
|
|||
<span data-i18n="TOP_TOOLBAR/BUTTON_HELP"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="e-item dividerbar" role="presentation" data-bind="visible: mobile">
|
||||
<li class="e-item dividerbar show-mobile" role="presentation">
|
||||
<a class="e-link menuitem" href="./?/DesktopVersion/" tabindex="-1">
|
||||
<i class="fontastic">💻</i>
|
||||
<span data-i18n="MOBILE/BUTTON_DESKTOP_VERSION"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="e-item dividerbar" role="presentation" data-bind="visible: !mobile">
|
||||
<li class="e-item dividerbar hide-mobile" role="presentation">
|
||||
<a class="e-link menuitem" href="./?/MobileVersion/" tabindex="-1">
|
||||
<i class="fontastic">📱</i>
|
||||
<span data-i18n="MOBILE/BUTTON_MOBILE_VERSION"></span>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
--main-color: #333;
|
||||
--main-bg-color: #e3e3e3;
|
||||
--main-bg-image: none; // "images/background.png"
|
||||
--main-bg-size: inherit;
|
||||
--main-bg-size: auto;
|
||||
--main-bg-repeat: repeat;
|
||||
|
||||
// LOADING
|
||||
--loading-color: #000; // #ddd
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue