Skip to content

Commit ae8adf6

Browse files
feat: Allow disabling of threaded view
Signed-off-by: SebastianKrupinski <[email protected]>
1 parent 170f342 commit ae8adf6

File tree

9 files changed

+106
-0
lines changed

9 files changed

+106
-0
lines changed

appinfo/routes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@
345345
'url' => '/api/settings/importance-classification-default',
346346
'verb' => 'PUT'
347347
],
348+
[
349+
'name' => 'settings#setLayoutMessageView',
350+
'url' => '/api/settings/layout-message-view',
351+
'verb' => 'PUT'
352+
],
348353
[
349354
'name' => 'trusted_senders#setTrusted',
350355
'url' => '/api/trustedsenders/{email}',

lib/Controller/PageController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ public function index(): TemplateResponse {
211211
'app-version' => $this->config->getAppValue('mail', 'installed_version'),
212212
'external-avatars' => $this->preferences->getPreference($this->currentUserId, 'external-avatars', 'true'),
213213
'layout-mode' => $this->preferences->getPreference($this->currentUserId, 'layout-mode', 'vertical-split'),
214+
'layout-message-view' => $this->preferences->getPreference($this->currentUserId, 'layout-message-view', $this->config->getAppValue('mail', 'layout_message_view', 'threaded')),
214215
'reply-mode' => $this->preferences->getPreference($this->currentUserId, 'reply-mode', 'top'),
215216
'collect-data' => $this->preferences->getPreference($this->currentUserId, 'collect-data', 'true'),
216217
'search-priority-body' => $this->preferences->getPreference($this->currentUserId, 'search-priority-body', 'false'),

lib/Controller/SettingsController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,9 @@ public function setImportanceClassificationEnabledByDefault(bool $enabledByDefau
124124
return new JSONResponse([]);
125125
}
126126

127+
public function setLayoutMessageView(string $value): JSONResponse {
128+
$this->config->setAppValue('mail', 'layout_message_view', $value);
129+
return new JSONResponse([]);
130+
}
131+
127132
}

lib/Settings/AdminSettings.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ public function getForm() {
8080
$this->config->getAppValue('mail', 'allow_new_mail_accounts', 'yes') === 'yes'
8181
);
8282

83+
$this->initialStateService->provideInitialState(
84+
Application::APP_ID,
85+
'layout_message_view',
86+
$this->config->getAppValue('mail', 'layout_message_view', 'threaded')
87+
);
88+
8389
$this->initialStateService->provideInitialState(
8490
Application::APP_ID,
8591
'llm_processing',

src/components/AppSettingsMenu.vue

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@
7272
{{ t('mail', 'Horizontal split') }}
7373
</NcCheckboxRadioSwitch>
7474

75+
<h6>{{ t('mail', 'Message View Mode') }}</h6>
76+
<div class="sorting">
77+
<NcCheckboxRadioSwitch type="radio"
78+
name="message_view_mode_radio"
79+
value="threaded"
80+
:checked="layoutMessageView"
81+
@update:checked="setLayoutMessageView('threaded')">
82+
{{ t('mail', 'Show all messages in thread') }}
83+
</NcCheckboxRadioSwitch>
84+
<NcCheckboxRadioSwitch type="radio"
85+
name="message_view_mode_radio"
86+
value="singleton"
87+
:checked="layoutMessageView"
88+
@update:checked="setLayoutMessageView('singleton')">
89+
{{ t('mail', 'Show only the selected message') }}
90+
</NcCheckboxRadioSwitch>
91+
</div>
92+
7593
<h6>{{ t('mail', 'Sorting') }}</h6>
7694
<div class="sorting">
7795
<NcCheckboxRadioSwitch class="sorting__switch"
@@ -398,6 +416,9 @@ export default {
398416
layoutMode() {
399417
return this.mainStore.getPreference('layout-mode', 'vertical-split')
400418
},
419+
layoutMessageView() {
420+
return this.mainStore.getPreference('layout-message-view')
421+
},
401422
},
402423
watch: {
403424
showSettings(value) {
@@ -439,6 +460,16 @@ export default {
439460
Logger.error('Could not save preferences', { error })
440461
}
441462
},
463+
async setLayoutMessageView(value) {
464+
try {
465+
await this.mainStore.savePreference({
466+
key: 'layout-message-view',
467+
value,
468+
})
469+
} catch (error) {
470+
Logger.error('Could not save preferences', { error })
471+
}
472+
},
442473
async onOpen() {
443474
this.showSettings = true
444475
},

src/components/Thread.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ export default {
121121
return []
122122
}
123123

124+
if (this.mainStore.getPreference('layout-message-view', 'threaded') === 'singleton') {
125+
return [envelope]
126+
}
127+
124128
const envelopes = this.mainStore.getEnvelopesByThreadRootId(envelope.accountId, envelope.threadRootId)
125129
if (envelopes.length === 0) {
126130
return []

src/components/settings/AdminSettings.vue

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,38 @@
253253
</article>
254254
<MicrosoftAdminOauthSettings :tenant-id="microsoftOauthTenantId" :client-id="microsoftOauthClientId" />
255255
</div>
256+
<div class="app-description">
257+
<h3>{{ t('mail', 'User Interface Preference Defaults') }}</h3>
258+
<article>
259+
<p>
260+
{{ t('mail', 'These settings are used to pre-configure the user interface preferences they can be overridden by the user in the mail settings') }}
261+
</p>
262+
</article>
263+
<br>
264+
<article>
265+
<p>
266+
{{ t('mail', 'Message View Mode') }}
267+
</p>
268+
<p>
269+
<NcCheckboxRadioSwitch
270+
:checked.sync="layoutMessageView"
271+
value="threaded"
272+
name="message_view_mode_radio"
273+
type="radio"
274+
@update:checked="setLayoutMessageView('threaded')">
275+
{{ t('mail', 'Show all messages in thread') }}
276+
</NcCheckboxRadioSwitch>
277+
<NcCheckboxRadioSwitch
278+
:checked.sync="layoutMessageView"
279+
value="singleton"
280+
name="message_view_mode_radio"
281+
type="radio"
282+
@update:checked="setLayoutMessageView('singleton')">
283+
{{ t('mail', 'Show only the selected message') }}
284+
</NcCheckboxRadioSwitch>
285+
</p>
286+
</article>
287+
</div>
256288
</SettingsSection>
257289
</template>
258290

@@ -278,6 +310,7 @@ import {
278310
updateLlmEnabled,
279311
updateEnabledSmartReply,
280312
setImportanceClassificationEnabledByDefault,
313+
setLayoutMessageView,
281314
} from '../../service/SettingsService.js'
282315

283316
const googleOauthClientId = loadState('mail', 'google_oauth_client_id', null) ?? undefined
@@ -342,6 +375,7 @@ export default {
342375
isLlmFreePromptConfigured: loadState('mail', 'enabled_llm_free_prompt_backend'),
343376
isClassificationEnabledByDefault: loadState('mail', 'llm_processing', true),
344377
isImportanceClassificationEnabledByDefault: loadState('mail', 'importance_classification_default', true),
378+
layoutMessageView: loadState('mail', 'layout_message_view'),
345379
}
346380
},
347381
methods: {
@@ -410,6 +444,9 @@ export default {
410444
logger.error('Could not save default classification setting', { error })
411445
}
412446
},
447+
async setLayoutMessageView(value) {
448+
await setLayoutMessageView(value)
449+
},
413450
},
414451
}
415452
</script>

src/init.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ export default function initAfterAppCreation() {
7070
key: 'layout-mode',
7171
value: preferences['layout-mode'],
7272
})
73+
mainStore.savePreferenceMutation({
74+
key: 'layout-message-view',
75+
value: preferences['layout-message-view'],
76+
})
7377
mainStore.savePreferenceMutation({
7478
key: 'follow-up-reminders',
7579
value: preferences['follow-up-reminders'],

src/service/SettingsService.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,16 @@ export const setImportanceClassificationEnabledByDefault = async (enabledByDefau
8989
enabledByDefault,
9090
})
9191
}
92+
93+
/**
94+
* @param {boolean} value
95+
* @return {Promise<void>}
96+
*/
97+
export const setLayoutMessageView = async (value) => {
98+
const url = generateUrl('/apps/mail/api/settings/layout-message-view')
99+
const data = {
100+
value,
101+
}
102+
const resp = await axios.put(url, data)
103+
return resp.data
104+
}

0 commit comments

Comments
 (0)