Skip to content

Commit 0ed5604

Browse files
committed
feat: compact view for mail layouts
Signed-off-by: greta <[email protected]>
1 parent dd44f8b commit 0ed5604

File tree

6 files changed

+96
-14
lines changed

6 files changed

+96
-14
lines changed

lib/Controller/PageController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ public function index(): TemplateResponse {
224224
'start-mailbox-id' => $this->preferences->getPreference($this->currentUserId, 'start-mailbox-id'),
225225
'follow-up-reminders' => $this->preferences->getPreference($this->currentUserId, 'follow-up-reminders', 'true'),
226226
'sort-favorites' => $this->preferences->getPreference($this->currentUserId, 'sort-favorites', 'false'),
227+
'compact-mode' => $this->preferences->getPreference($this->currentUserId, 'compact-mode', 'false'),
227228
]);
228229
$this->initialStateService->provideInitialState(
229230
'prefill_displayName',

src/components/AppSettingsMenu.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@
7979
</NcRadioGroupButton>
8080
</NcRadioGroup>
8181

82+
<NcFormBox>
83+
<NcFormBoxSwitch
84+
v-model="compactMode"
85+
:label="t('mail', 'Set compact mode')"
86+
@update:modelValue="compactMode = $event" />
87+
</NcFormBox>
88+
8289
<NcRadioGroup :model-value="sortOrder" :label="t('mail', 'Sorting')" @update:modelValue="onSortByDate">
8390
<NcRadioGroupButton :label="t('mail', 'Newest first')" value="newest" />
8491
<NcRadioGroupButton :label="t('mail', 'Oldest first')" value="oldest" />
@@ -462,6 +469,16 @@ export default {
462469
},
463470
},
464471
472+
compactMode: {
473+
get() {
474+
return this.mainStore.getPreference('compact-mode', 'false') === 'true'
475+
},
476+
477+
set(value) {
478+
this.setCompactMode(value)
479+
},
480+
},
481+
465482
layoutMessageView: {
466483
get() {
467484
const preference = this.mainStore.getPreference('layout-message-view')
@@ -526,6 +543,17 @@ export default {
526543
}
527544
},
528545
546+
async setCompactMode(value) {
547+
try {
548+
await this.mainStore.savePreference({
549+
key: 'compact-mode',
550+
value: value ? 'true' : 'false',
551+
})
552+
} catch (error) {
553+
Logger.error('Could not save preferences', { error })
554+
}
555+
},
556+
529557
async setLayoutMessageView(value) {
530558
try {
531559
await this.mainStore.savePreference({

src/components/Envelope.vue

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
:name="addresses"
2121
:details="formatted()"
2222
:one-line="oneLineLayout"
23+
:compact="compactMode"
2324
:is-read="showImportantIconVariant"
2425
:is-important="isImportant"
2526
@click.exact="onClick"
@@ -53,20 +54,41 @@
5354
@click.prevent="hasWriteAcl ? onToggleJunk() : false" />
5455
<div
5556
class="hovering-status"
56-
:class="{ 'hover-active': hoveringAvatar && !selected }"
57+
:class="{ 'hover-active': hoveringAvatar && !selected && !compactMode }"
5758
@mouseenter="hoveringAvatar = true"
58-
@mouseleave="hoveringAvatar = false"
59-
@click.stop.exact.prevent="toggleSelected"
60-
@click.shift.exact.prevent="onSelectMultiple">
61-
<template v-if="hoveringAvatar || selected">
62-
<CheckIcon :size="28" class="check-icon" :class="{ 'app-content-list-item-avatar-selected': selected }" />
59+
@mouseleave="hoveringAvatar = false">
60+
<template v-if="compactMode">
61+
<div
62+
class="compact-checkbox-wrapper"
63+
@mousedown.stop.prevent
64+
@click.stop.prevent>
65+
<NcCheckboxRadioSwitch
66+
type="checkbox"
67+
class="compact-checkbox"
68+
:checked="selected"
69+
@update:checked="toggleSelected" />
70+
</div>
6371
</template>
72+
6473
<template v-else>
65-
<Avatar
66-
:display-name="addresses"
67-
:email="avatarEmail"
68-
:fetch-avatar="data.fetchAvatarFromClient"
69-
:avatar="data.avatar" />
74+
<div
75+
@click.stop.exact.prevent="toggleSelected"
76+
@click.shift.exact.prevent="onSelectMultiple">
77+
<template v-if="hoveringAvatar || selected">
78+
<CheckIcon
79+
:size="28"
80+
class="check-icon"
81+
:class="{ 'app-content-list-item-avatar-selected': selected }" />
82+
</template>
83+
84+
<template v-else>
85+
<Avatar
86+
:display-name="addresses"
87+
:email="avatarEmail"
88+
:fetch-avatar="data.fetchAvatarFromClient"
89+
:avatar="data.avatar" />
90+
</template>
91+
</div>
7092
</template>
7193
</div>
7294
</template>
@@ -91,7 +113,7 @@
91113
</span>
92114
</div>
93115
<div
94-
v-if="data.encrypted || data.previewText"
116+
v-if="!compactMode && (data.encrypted || data.previewText)"
95117
class="envelope__preview-text"
96118
:title="data.summary ? t('mail', 'This summary was AI generated') : null">
97119
<NcAssistantIcon v-if="data.summary" :size="15" class="envelope__preview-text__icon" />
@@ -433,7 +455,7 @@ import {
433455
NcActionLink as ActionLink,
434456
NcActionText as ActionText,
435457
NcActionInput,
436-
NcActionSeparator, NcAssistantIcon,
458+
NcActionSeparator, NcAssistantIcon, NcCheckboxRadioSwitch,
437459
} from '@nextcloud/vue'
438460
import escapeHtml from 'escape-html'
439461
import { mapState, mapStores } from 'pinia'
@@ -506,6 +528,7 @@ export default {
506528
EnvelopeSkeleton,
507529
JunkIcon,
508530
ActionButton,
531+
NcCheckboxRadioSwitch,
509532
MoveModal,
510533
OpenInNewIcon,
511534
PlusIcon,
@@ -614,6 +637,10 @@ export default {
614637
return this.mainStore.getPreference('layout-message-view', 'threaded') === 'threaded'
615638
},
616639
640+
compactMode() {
641+
return this.mainStore.getPreference('compact-mode', 'false') === 'true'
642+
},
643+
617644
hasMultipleRecipients() {
618645
if (!this.account) {
619646
console.error('account is undefined', {
@@ -871,6 +898,14 @@ export default {
871898
},
872899
},
873900
901+
watch: {
902+
compactMode(enabled) {
903+
if (enabled) {
904+
this.hoveringAvatar = false
905+
}
906+
},
907+
},
908+
874909
mounted() {
875910
this.onWindowResize()
876911
window.addEventListener('resize', this.onWindowResize)

src/components/EnvelopeList.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
:select-mode="selectMode"
133133
:has-multiple-accounts="hasMultipleAccounts"
134134
:selected-envelopes="selectedEnvelopes"
135+
:compact-mode="compactMode"
135136
@delete="$emit('delete', env.databaseId)"
136137
@update:selected="onEnvelopeSelectToggle(env, index, $event)"
137138
@select-multiple="onEnvelopeSelectMultiple(env, index)"
@@ -257,6 +258,11 @@ export default {
257258
type: Boolean,
258259
default: false,
259260
},
261+
262+
compactMode: {
263+
type: Boolean,
264+
default: false,
265+
},
260266
},
261267
262268
data() {

src/components/EnvelopeSkeleton.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,14 +616,22 @@ export default {
616616
flex-direction: row;
617617
align-content: center;
618618
align-items: center;
619+
min-width: 0;
619620
620621
&__name {
622+
flex: 0 0 auto;
623+
min-width: 0;
624+
max-width: 40%;
625+
white-space: nowrap;
626+
overflow: hidden;
627+
text-overflow: ellipsis;
621628
align-self: center;
622-
min-width: 300px;
623629
padding-inline-end: calc(var(--default-grid-baseline) * 2);
624630
}
625631
626632
&__inner {
633+
flex: 1 1 auto;
634+
min-width: 0;
627635
overflow-y: hidden;
628636
}
629637

src/init.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ export default function initAfterAppCreation() {
8989
key: 'smime-sign-aliases',
9090
value: loadState('mail', 'smime-sign-aliases', []),
9191
})
92+
mainStore.savePreferenceMutation({
93+
key: 'compact-mode',
94+
value: preferences['compact-mode'],
95+
})
9296

9397
mainStore.setQuickActions(loadState('mail', 'quick-actions', []))
9498

0 commit comments

Comments
 (0)