diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index ce71d0e81d..695265ee59 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -10,6 +10,7 @@ namespace OCA\Mail\Controller; +use OCA\Contacts\Event\LoadContactsOcaApiEvent; use OCA\Mail\AppInfo\Application; use OCA\Mail\Contracts\IMailManager; use OCA\Mail\Contracts\IUserPreferences; @@ -318,6 +319,11 @@ function (SmimeCertificate $certificate) { $csp->addAllowedFrameDomain('\'self\''); $response->setContentSecurityPolicy($csp); $this->dispatcher->dispatchTyped(new RenderReferenceEvent()); + + if (class_exists(LoadContactsOcaApiEvent::class)) { + $this->dispatcher->dispatchTyped(new LoadContactsOcaApiEvent()); + } + return $response; } diff --git a/src/components/DisplayContactDetails.vue b/src/components/DisplayContactDetails.vue new file mode 100644 index 0000000000..4841d4a8e7 --- /dev/null +++ b/src/components/DisplayContactDetails.vue @@ -0,0 +1,41 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + + + + diff --git a/src/components/MailboxThread.vue b/src/components/MailboxThread.vue index 46820b8d35..ea55c9fa8d 100644 --- a/src/components/MailboxThread.vue +++ b/src/components/MailboxThread.vue @@ -243,7 +243,7 @@ export default { .length > 0 }, importantMessagesInitialPageSize() { - if (window.innerHeight > 900) { + if (window.innerHeight > 1024) { return 7 } if (window.innerHeight > 750) { diff --git a/src/components/NewMessageModal.vue b/src/components/NewMessageModal.vue index 373d1aeb7f..a695b113d1 100644 --- a/src/components/NewMessageModal.vue +++ b/src/components/NewMessageModal.vue @@ -4,7 +4,7 @@ --> - - + @@ -138,6 +146,7 @@ import DefaultComposerIcon from 'vue-material-design-icons/ArrowCollapse.vue' import { deleteDraft, saveDraft, updateDraft } from '../service/DraftService.js' import useOutboxStore from '../store/outboxStore.js' import { mapStores } from 'pinia' +import RecipientInfo from './RecipientInfo.vue' export default { name: 'NewMessageModal', @@ -150,6 +159,7 @@ export default { MinimizeIcon, MaximizeIcon, DefaultComposerIcon, + RecipientInfo, }, props: { accounts: { @@ -174,6 +184,12 @@ export default { cookedComposerData: undefined, changed: false, largerModal: false, + isLargeScreen: window.innerWidth >= 1024, + isMaximized: false, + recipient: { + name: '', + email: '', + }, } }, computed: { @@ -194,6 +210,15 @@ export default { } return t('mail', 'New message') }, + hasContactDetailsApi() { + return !!window.OCA?.Contacts?.mountContactDetails + }, + showRecipientPane() { + return this.hasContactDetailsApi + && this.composerData.to + && this.composerData.to.length > 0 + && !this.isMaximized + }, composerMessage() { return this.$store.getters.composerMessage }, @@ -206,6 +231,11 @@ export default { smartReply() { return this.composerData?.smartReply ?? null }, + modalSize() { + return this.isLargeScreen && this.hasContactDetailsApi && this.composerData.to && this.composerData.to.length > 0 + ? 'large' + : (this.largerModal ? 'large' : 'normal') + }, }, created() { const id = this.composerData?.id @@ -218,11 +248,16 @@ export default { await this.$nextTick() this.updateCookedComposerData() await this.openModalSize() + window.addEventListener('resize', this.checkScreenSize) }, beforeDestroy() { window.removeEventListener('beforeunload', this.onBeforeUnload) + window.removeEventListener('resize', this.checkScreenSize) }, methods: { + checkScreenSize() { + this.isLargeScreen = window.innerWidth >= 1024 + }, async openModalSize() { try { const sizePreference = this.$store.getters.getPreference('modalSize') @@ -232,6 +267,7 @@ export default { } }, async onMaximize() { + this.isMaximized = !this.isMaximized this.largerModal = !this.largerModal try { await this.$store.dispatch('savePreference', { @@ -242,6 +278,16 @@ export default { console.error('Failed to save preference', error) } }, + async onMinimize() { + this.isMaximized = false + this.modalFirstOpen = false + + await this.$store.dispatch('closeMessageComposer') + if (!this.$store.getters.composerMessageIsSaved && this.changed) { + await this.onDraft(this.cookedComposerData, { showToast: true }) + } + + }, handleShow(element) { this.additionalTrapElements.push(element) }, @@ -528,15 +574,6 @@ export default { console.info('No unsaved changes. See you!') } }, - async onMinimize() { - this.modalFirstOpen = false - - await this.$store.dispatch('closeMessageComposer') - if (!this.$store.getters.composerMessageIsSaved && this.changed) { - await this.onDraft(this.cookedComposerData, { showToast: true }) - } - - }, async onClose() { this.$store.commit('setComposerIndicatorDisabled', true) await this.onMinimize() @@ -591,4 +628,32 @@ export default { height: 100%; display: flex; } +.modal-content { + display: flex; + height: 100%; + flex-direction: row; + width: 100%; +} + +.left-pane { + flex: 1; + overflow-y: auto; +} + +.right-pane { + flex: 0 0 400px; + overflow-y: auto; + padding-left: 5px; + border-left: 1px solid #ccc; + @media (max-width: 1024px) { + display: none; + } +} + +.modal-content.with-recipient .left-pane { + flex: 1; +} +.modal-content .left-pane { + width: 100%; +} diff --git a/src/components/RecipientInfo.vue b/src/components/RecipientInfo.vue new file mode 100644 index 0000000000..935b4a5194 --- /dev/null +++ b/src/components/RecipientInfo.vue @@ -0,0 +1,151 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + + + + +