Skip to content

Commit 97d05cd

Browse files
feat: Allow disabling of threaded view
Signed-off-by: SebastianKrupinski <[email protected]>
1 parent 56c8fdd commit 97d05cd

File tree

10 files changed

+110
-2
lines changed

10 files changed

+110
-2
lines changed

Diff for: appinfo/routes.php

+5
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}',

Diff for: lib/Controller/PageController.php

+1
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'),

Diff for: lib/Controller/SettingsController.php

+5
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
}

Diff for: lib/Settings/AdminSettings.php

+6
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',

Diff for: src/components/AppSettingsMenu.vue

+31
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
},

Diff for: src/components/Thread.vue

+4
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ export default {
126126
return []
127127
}
128128

129+
if (this.mainStore.getPreference('layout-message-view', 'threaded') === 'singleton') {
130+
return [envelope]
131+
}
132+
129133
const envelopes = this.mainStore.getEnvelopesByThreadRootId(envelope.accountId, envelope.threadRootId)
130134
if (envelopes.length === 0) {
131135
return []

Diff for: src/components/settings/AdminSettings.vue

+35
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,36 @@
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 type="radio"
270+
name="message_view_mode_radio"
271+
value="threaded"
272+
:checked.sync="layoutMessageView"
273+
@update:checked="setLayoutMessageView('threaded')">
274+
{{ t('mail', 'Show all messages in thread') }}
275+
</NcCheckboxRadioSwitch>
276+
<NcCheckboxRadioSwitch type="radio"
277+
name="message_view_mode_radio"
278+
value="singleton"
279+
:checked.sync="layoutMessageView"
280+
@update:checked="setLayoutMessageView('singleton')">
281+
{{ t('mail', 'Show only the selected message') }}
282+
</NcCheckboxRadioSwitch>
283+
</p>
284+
</article>
285+
</div>
256286
</SettingsSection>
257287
</template>
258288

@@ -278,6 +308,7 @@ import {
278308
updateLlmEnabled,
279309
updateEnabledSmartReply,
280310
setImportanceClassificationEnabledByDefault,
311+
setLayoutMessageView,
281312
} from '../../service/SettingsService.js'
282313

283314
const googleOauthClientId = loadState('mail', 'google_oauth_client_id', null) ?? undefined
@@ -342,6 +373,7 @@ export default {
342373
isLlmFreePromptConfigured: loadState('mail', 'enabled_llm_free_prompt_backend'),
343374
isClassificationEnabledByDefault: loadState('mail', 'llm_processing', true),
344375
isImportanceClassificationEnabledByDefault: loadState('mail', 'importance_classification_default', true),
376+
layoutMessageView: loadState('mail', 'layout_message_view'),
345377
}
346378
},
347379
methods: {
@@ -410,6 +442,9 @@ export default {
410442
logger.error('Could not save default classification setting', { error })
411443
}
412444
},
445+
async setLayoutMessageView(value) {
446+
await setLayoutMessageView(value)
447+
},
413448
},
414449
}
415450
</script>

Diff for: src/init.js

+4
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'],

Diff for: src/service/SettingsService.js

+13
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+
}

Diff for: tests/Unit/Controller/PageControllerTest.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public function testIndex(): void {
168168
$account1 = $this->createMock(Account::class);
169169
$account2 = $this->createMock(Account::class);
170170
$mailbox = $this->createMock(Mailbox::class);
171-
$this->preferences->expects($this->exactly(10))
171+
$this->preferences->expects($this->exactly(11))
172172
->method('getPreference')
173173
->willReturnMap([
174174
[$this->userId, 'account-settings', '[]', json_encode([])],
@@ -179,6 +179,7 @@ public function testIndex(): void {
179179
[$this->userId, 'search-priority-body', 'false', 'false'],
180180
[$this->userId, 'start-mailbox-id', null, '123'],
181181
[$this->userId, 'layout-mode', 'vertical-split', 'vertical-split'],
182+
[$this->userId, 'layout-message-view', 'threaded', 'threaded'],
182183
[$this->userId, 'follow-up-reminders', 'true', 'true'],
183184
[$this->userId, 'internal-addresses', 'false', 'false'],
184185
]);
@@ -257,17 +258,19 @@ public function testIndex(): void {
257258
['version', '0.0.0', '26.0.0'],
258259
['app.mail.attachment-size-limit', 0, 123],
259260
]);
260-
$this->config->expects($this->exactly(6))
261+
$this->config->expects($this->exactly(7))
261262
->method('getAppValue')
262263
->withConsecutive(
263264
[ 'mail', 'installed_version' ],
265+
['mail', 'layout_message_view' ],
264266
['mail', 'google_oauth_client_id' ],
265267
['mail', 'microsoft_oauth_client_id' ],
266268
['mail', 'microsoft_oauth_tenant_id' ],
267269
['core', 'backgroundjobs_mode', 'ajax' ],
268270
['mail', 'allow_new_mail_accounts', 'yes'],
269271
)->willReturnOnConsecutiveCalls(
270272
$this->returnValue('1.2.3'),
273+
$this->returnValue('threaded'),
271274
$this->returnValue(''),
272275
$this->returnValue(''),
273276
$this->returnValue(''),
@@ -321,6 +324,7 @@ public function testIndex(): void {
321324
'tag-classified-messages' => 'false',
322325
'search-priority-body' => 'false',
323326
'layout-mode' => 'vertical-split',
327+
'layout-message-view' => 'threaded',
324328
'follow-up-reminders' => 'true',
325329
]],
326330
['prefill_displayName', 'Jane Doe'],

0 commit comments

Comments
 (0)