diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 7909607fce..3e8ac412a6 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -206,6 +206,7 @@ public function index(): TemplateResponse { 'attachment-size-limit' => $this->config->getSystemValue('app.mail.attachment-size-limit', 0), 'app-version' => $this->config->getAppValue('mail', 'installed_version'), 'external-avatars' => $this->preferences->getPreference($this->currentUserId, 'external-avatars', 'true'), + 'layout-mode' => $this->preferences->getPreference($this->currentUserId, 'layout-mode', 'vertical-split'), 'reply-mode' => $this->preferences->getPreference($this->currentUserId, 'reply-mode', 'top'), 'collect-data' => $this->preferences->getPreference($this->currentUserId, 'collect-data', 'true'), 'search-priority-body' => $this->preferences->getPreference($this->currentUserId, 'search-priority-body', 'false'), diff --git a/src/components/AppSettingsMenu.vue b/src/components/AppSettingsMenu.vue index d376158735..04e1115171 100755 --- a/src/components/AppSettingsMenu.vue +++ b/src/components/AppSettingsMenu.vue @@ -4,6 +4,28 @@ :name="t('mail', 'Mail settings')" :show-navigation="true" :open.sync="showSettings"> + + + + {{ t('mail', 'List') }} + + + + {{ t('mail', 'Vertical split') }} + +
- {{ t('mail', 'Newest') }} - - + {{ t('mail', 'Oldest') }} - +
@@ -202,12 +224,14 @@ - diff --git a/src/components/EnvelopeList.vue b/src/components/EnvelopeList.vue index 654669b26d..eb53216d7a 100644 --- a/src/components/EnvelopeList.vue +++ b/src/components/EnvelopeList.vue @@ -320,6 +320,7 @@ export default { showMoveModal: false, showTagModal: false, lastToggledIndex: undefined, + defaultView: false, } }, computed: { diff --git a/src/components/Mailbox.vue b/src/components/Mailbox.vue index f44c27ef9b..096444cd19 100644 --- a/src/components/Mailbox.vue +++ b/src/components/Mailbox.vue @@ -2,6 +2,7 @@ - @copyright 2020 Christoph Wurst - - @author 2020 Christoph Wurst + - @author Richard Steinmetz - - @license AGPL-3.0-or-later - @@ -111,7 +112,7 @@ export default { error: false, refreshing: false, loadingMore: false, - loadingEnvelopes: true, + loadingEnvelopes: false, loadingCacheInitialization: false, loadMailboxInterval: undefined, expanded: false, @@ -161,11 +162,14 @@ export default { this.loadMailboxInterval = setInterval(this.loadMailbox, 60000) }, async mounted() { - this.loadEnvelopes() - .then(() => { - logger.debug(`syncing mailbox ${this.mailbox.databaseId} (${this.searchQuery}) after mount`) - this.sync(false) - }) + if (this.$store.getters.hasFetchedInitialEnvelopes) { + return + } + + await this.loadEnvelopes() + logger.debug(`syncing mailbox ${this.mailbox.databaseId} (${this.searchQuery}) after mount`) + await this.sync(false) + this.$store.commit('setHasFetchedInitialEnvelopes', true) }, destroyed() { this.bus.off('load-more', this.onScroll) diff --git a/src/components/MailboxThread.vue b/src/components/MailboxThread.vue index 2bec34801f..bd9f22a02f 100644 --- a/src/components/MailboxThread.vue +++ b/src/components/MailboxThread.vue @@ -1,5 +1,8 @@ @@ -138,9 +142,13 @@ export default { priorityImportantQuery, priorityOtherQuery, startMailboxTimer: undefined, + hasContent: false, } }, computed: { + layoutMode() { + return this.$store.getters.getPreference('layout-mode', 'vertical-split') + }, unifiedAccount() { return this.$store.getters.getAccount(UNIFIED_ACCOUNT_ID) }, @@ -331,11 +339,6 @@ export default { background-color: var(--color-background-dark); } } -:deep(.button-vue--vue-secondary) { - position: sticky; - top:40px; - left: 10px; -} :deep(.app-content-wrapper) { overflow: auto; } @@ -357,4 +360,7 @@ export default { flex-direction: column; height: calc(100vh - var(--header-height)); } +:deep(.app-details-toggle) { + opacity: 1; +} diff --git a/src/main.js b/src/main.js index 877fdd8cbc..2d04682a06 100644 --- a/src/main.js +++ b/src/main.js @@ -109,6 +109,10 @@ store.commit('savePreference', { key: 'password-is-unavailable', value: loadState('mail', 'password-is-unavailable', false), }) +store.commit('savePreference', { + key: 'layout-mode', + value: getPreferenceFromPage('layout-mode'), +}) const accountSettings = loadState('mail', 'account-settings') const accounts = loadState('mail', 'accounts', []) diff --git a/src/store/actions.js b/src/store/actions.js index c65d65ed63..7c0b4f0a85 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1499,4 +1499,13 @@ export default { }, }) }, + async setLayout({ commit }, { list }) { + try { + commit('setOneLineLayout', { + list, + }) + } catch (error) { + logger.error('Could not set layouts', { error }) + } + }, } diff --git a/src/store/getters.js b/src/store/getters.js index ab7fbfd7f4..226d17b59a 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -155,4 +155,6 @@ export const getters = { getInbox: (state, getters) => (accountId) => { return getters.findMailboxBySpecialRole(accountId, 'inbox') }, + isOneLineLayout: (state) => state.list, + hasFetchedInitialEnvelopes: (state) => state.hasFetchedInitialEnvelopes, } diff --git a/src/store/index.js b/src/store/index.js index 6bdbda6fe3..5deb66f57a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -107,6 +107,7 @@ export default new Store({ sieveScript: {}, calendars: [], smimeCertificates: [], + hasFetchedInitialEnvelopes: false, }, getters, mutations, diff --git a/src/store/mutations.js b/src/store/mutations.js index f07f88fbe8..712856f68d 100644 --- a/src/store/mutations.js +++ b/src/store/mutations.js @@ -506,4 +506,10 @@ export default { addSmimeCertificate(state, { certificate }) { state.smimeCertificates = [...state.smimeCertificates, certificate] }, + setOneLineLayout(state, { list }) { + Vue.set(state, 'list', list) + }, + setHasFetchedInitialEnvelopes(state, hasFetchedInitialEnvelopes) { + state.hasFetchedInitialEnvelopes = hasFetchedInitialEnvelopes + }, } diff --git a/src/views/Home.vue b/src/views/Home.vue index 95a34d2f24..0ef21bcfcf 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -175,8 +175,4 @@ export default { flex: 1 1 100%; min-width: 70%; } -// Align the appNavigation toggle with the apps header toolbar -:deep(button.app-navigation-toggle) { - top: 8px; -} diff --git a/templates/index.php b/templates/index.php index acb3f98501..a5f1d5896f 100644 --- a/templates/index.php +++ b/templates/index.php @@ -33,4 +33,5 @@ + diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php index 1515d2c9ba..5264a6babc 100644 --- a/tests/Unit/Controller/PageControllerTest.php +++ b/tests/Unit/Controller/PageControllerTest.php @@ -168,7 +168,7 @@ public function testIndex(): void { $account1 = $this->createMock(Account::class); $account2 = $this->createMock(Account::class); $mailbox = $this->createMock(Mailbox::class); - $this->preferences->expects($this->exactly(8)) + $this->preferences->expects($this->exactly(9)) ->method('getPreference') ->willReturnMap([ [$this->userId, 'account-settings', '[]', json_encode([])], @@ -293,7 +293,7 @@ public function testIndex(): void { ->method('getLoginCredentials') ->willReturn($loginCredentials); - $this->initialState->expects($this->exactly(16)) + $this->initialState->expects($this->exactly(17)) ->method('provideInitialState') ->withConsecutive( ['debug', true],