Skip to content

Commit f722dab

Browse files
committed
feat(files_sharing): show Account menu on public pages
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
1 parent 431580c commit f722dab

10 files changed

Lines changed: 196 additions & 146 deletions

File tree

apps/files_sharing/src/public-file-request.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import { defineAsyncComponent } from 'vue'
76
import { getBuilder } from '@nextcloud/browser-storage'
8-
import { getGuestNickname, setGuestNickname } from '@nextcloud/auth'
7+
import { getGuestNickname, getGuestUser } from '@nextcloud/auth'
98
import { getUploader } from '@nextcloud/upload'
10-
import { spawnDialog } from '@nextcloud/dialogs'
9+
import { loadState } from '@nextcloud/initial-state'
10+
import { showGuestUserPrompt } from '@nextcloud/dialogs'
11+
import { t } from '@nextcloud/l10n'
1112

1213
import logger from './services/logger'
14+
import { subscribe } from '@nextcloud/event-bus'
1315

1416
const storage = getBuilder('files_sharing').build()
1517

@@ -25,31 +27,47 @@ function registerFileRequestHeader(nickname: string) {
2527

2628
/**
2729
* Callback when a nickname was chosen
28-
* @param nickname The chosen nickname
2930
*/
30-
function onSetNickname(nickname: string): void {
31-
// Set the nickname
32-
setGuestNickname(nickname)
33-
// Set the dialog as shown
34-
storage.setItem('public-auth-prompt-shown', 'true')
31+
function onUpdatedNickname(): void {
3532
// Register header for uploader
36-
registerFileRequestHeader(nickname)
33+
registerFileRequestHeader(getGuestUser().displayName ?? '')
3734
}
35+
subscribe('user:info:changed', onUpdatedNickname)
3836

3937
window.addEventListener('DOMContentLoaded', () => {
4038
const nickname = getGuestNickname() ?? ''
4139
const dialogShown = storage.getItem('public-auth-prompt-shown') !== null
4240

41+
const owner = loadState('files_sharing', 'owner', '')
42+
const ownerDisplayName = loadState('files_sharing', 'ownerDisplayName', '')
43+
const label = loadState('files_sharing', 'label', '')
44+
const filename = loadState('files_sharing', 'filename', '')
45+
46+
// If the owner provided a custom label, use it instead of the filename
47+
const folder = label || filename
48+
49+
const options = {
50+
nickname,
51+
notice: t('files_sharing', 'To upload files to {folder}, you need to provide your name first.', { folder }),
52+
subtitle: undefined as string | undefined,
53+
title: t('files_sharing', 'Upload files to {folder}', { folder }),
54+
}
55+
56+
// If the guest already has a nickname, we just make them double check
57+
if (nickname) {
58+
options.notice = t('files_sharing', 'Please confirm your name to upload files to {folder}', { folder })
59+
}
60+
61+
// If the account owner set their name as public,
62+
// we show it in the subtitle
63+
if (owner) {
64+
options.subtitle = t('files_sharing', '{ownerDisplayName} shared a folder with you.', { ownerDisplayName })
65+
}
66+
4367
// If we don't have a nickname or the public auth prompt hasn't been shown yet, show it
4468
// We still show the prompt if the user has a nickname to double check
4569
if (!nickname || !dialogShown) {
46-
spawnDialog(
47-
defineAsyncComponent(() => import('./views/PublicAuthPrompt.vue')),
48-
{
49-
nickname,
50-
},
51-
onSetNickname as (...rest: unknown[]) => void,
52-
)
70+
showGuestUserPrompt(options)
5371
} else {
5472
logger.debug('Public auth prompt already shown.', { nickname })
5573
registerFileRequestHeader(nickname)

apps/files_sharing/src/views/PublicAuthPrompt.vue

Lines changed: 0 additions & 123 deletions
This file was deleted.

core/src/components/AccountMenu/AccountMenuEntry.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,14 @@ export default defineComponent({
7878
},
7979
8080
methods: {
81-
onClick(e) {
82-
this.loading = true
81+
onClick(e: MouseEvent) {
8382
this.$emit('click', e)
83+
84+
// Allow to not show the loading indicator
85+
// in case the click event was already handled
86+
if (!e.defaultPrevented) {
87+
this.loading = true
88+
}
8489
},
8590
},
8691
})

core/src/components/PublicPageMenu/PublicPageMenuEntry.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,24 @@
1111
role="presentation"
1212
@click="$emit('click')">
1313
<template #icon>
14-
<div role="presentation" :class="['icon', icon, 'public-page-menu-entry__icon']" />
14+
<slot v-if="$scopedSlots.icon" name="icon" />
15+
<div v-else role="presentation" :class="['icon', icon, 'public-page-menu-entry__icon']" />
1516
</template>
1617
</NcListItem>
1718
</template>
1819

1920
<script setup lang="ts">
20-
import NcListItem from '@nextcloud/vue/components/NcListItem'
2121
import { onMounted } from 'vue'
2222
23+
import NcListItem from '@nextcloud/vue/components/NcListItem'
24+
2325
const props = defineProps<{
2426
/** Only emit click event but do not open href */
2527
clickOnly?: boolean
2628
// menu entry props
2729
id: string
2830
label: string
29-
icon: string
31+
icon?: string
3032
href: string
3133
details?: string
3234
}>()

core/src/public-page-user-menu.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { getCSPNonce } from '@nextcloud/auth'
7+
import Vue from 'vue'
8+
9+
import PublicPageUserMenu from './views/PublicPageUserMenu.vue'
10+
11+
__webpack_nonce__ = getCSPNonce()
12+
13+
const View = Vue.extend(PublicPageUserMenu)
14+
const instance = new View()
15+
instance.$mount('#public-page-user-menu')

core/src/views/AccountMenu.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export default defineComponent({
211211
}
212212
}
213213
214-
// Ensure we do not wast space, as the header menu sets a default width of 350px
214+
// Ensure we do not waste space, as the header menu sets a default width of 350px
215215
:deep(.header-menu__content) {
216216
width: fit-content !important;
217217
}

0 commit comments

Comments
 (0)