diff options
author | Julius Härtl <jus@bitgrid.net> | 2019-06-21 13:15:02 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2019-06-21 13:16:00 +0300 |
commit | 1587d53855dce603d5ffe00f5ec1505248c66aec (patch) | |
tree | c389f5aa622bf4ce36684feab796e0b0247892a0 | |
parent | ecff28bdeecceb1041c8eb5a3c331cd92ff17a01 (diff) |
Hide avatar list in popover
Signed-off-by: Julius Härtl <jus@bitgrid.net>
-rw-r--r-- | lib/Service/ApiService.php | 2 | ||||
-rw-r--r-- | src/components/EditorWrapper.vue | 26 | ||||
-rw-r--r-- | src/components/SessionList.vue | 143 |
3 files changed, 150 insertions, 21 deletions
diff --git a/lib/Service/ApiService.php b/lib/Service/ApiService.php index de6e4229a..351e8fe89 100644 --- a/lib/Service/ApiService.php +++ b/lib/Service/ApiService.php @@ -186,6 +186,6 @@ class ApiService { if ($guestName === '') { return new DataResponse([ 'message' => 'A guest name needs to be provided'], 500); } - return $this->sessionService->updateSession($documentId, $sessionId, $sessionToken, $guestName); + return new DataResponse($this->sessionService->updateSession($documentId, $sessionId, $sessionToken, $guestName)); } } diff --git a/src/components/EditorWrapper.vue b/src/components/EditorWrapper.vue index e88587de9..80f912823 100644 --- a/src/components/EditorWrapper.vue +++ b/src/components/EditorWrapper.vue @@ -35,10 +35,7 @@ <div v-tooltip="lastSavedStatusTooltip" class="save-status" :class="lastSavedStatusClass"> {{ lastSavedStatus }} </div> - <avatar v-for="session in activeSessions" :key="session.id" - :user="session.userId" - :display-name="session.guestName ? session.guestName : session.displayName" - :style="sessionStyle(session)" /> + <session-list :sessions="filteredSessions" /> </div> </menu-bar> <menu-bubble v-if="!readOnly" :editor="tiptap" /> @@ -65,20 +62,18 @@ import isMobile from './../mixins/isMobile' import Tooltip from 'nextcloud-vue/dist/Directives/Tooltip' -const COLLABORATOR_IDLE_TIME = 5 -const COLLABORATOR_DISCONNECT_TIME = 20 const EDITOR_PUSH_DEBOUNCE = 200 export default { name: 'EditorWrapper', components: { EditorContent, - Avatar: () => import('nextcloud-vue/dist/Components/Avatar'), MenuBar: () => import('./MenuBar'), MenuBubble: () => import('./MenuBubble'), ReadOnlyEditor: () => import('./ReadOnlyEditor'), CollisionResolveDialog: () => import('./CollisionResolveDialog'), - GuestNameDialog: () => import('./GuestNameDialog') + GuestNameDialog: () => import('./GuestNameDialog'), + SessionList: () => import('./SessionList') }, directives: { Tooltip @@ -127,18 +122,6 @@ export default { } }, computed: { - activeSessions() { - return Object.values(this.filteredSessions).filter((session) => session.lastContact > Date.now() / 1000 - COLLABORATOR_DISCONNECT_TIME && session.id !== this.currentSession.id && session.userId !== null) - }, - sessionStyle() { - return (session) => { - return { - 'opacity': session.lastContact > Date.now() / 1000 - COLLABORATOR_IDLE_TIME ? 1 : 0.5, - 'border-color': session.color - } - } - }, - lastSavedStatus() { let status = (this.dirtyStateIndicator ? '*' : '') if (!this.isMobile) { @@ -350,6 +333,9 @@ export default { } else { Vue.set(this.filteredSessions, sessionKey, session) } + if (session.id === this.currentSession.id) { + Vue.set(this.filteredSessions[sessionKey], 'isCurrent', true) + } } } } diff --git a/src/components/SessionList.vue b/src/components/SessionList.vue new file mode 100644 index 000000000..84995d96f --- /dev/null +++ b/src/components/SessionList.vue @@ -0,0 +1,143 @@ +<!-- + - @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> + - + - @author Julius Härtl <jus@bitgrid.net> + - + - @license GNU AGPL version 3 or any later version + - + - This program is free software: you can redistribute it and/or modify + - it under the terms of the GNU Affero General Public License as + - published by the Free Software Foundation, either version 3 of the + - License, or (at your option) any later version. + - + - This program is distributed in the hope that it will be useful, + - but WITHOUT ANY WARRANTY; without even the implied warranty of + - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + - GNU Affero General Public License for more details. + - + - You should have received a copy of the GNU Affero General Public License + - along with this program. If not, see <http://www.gnu.org/licenses/>. + - + --> + +<template> + <div class="session-list"> + <div class="avatar-list" @click="popoverVisible=!popoverVisible"> + <div v-if="sessionsPopover.length > 0" class="avatardiv icon-more" /> + <avatar v-for="session in sessionsVisible" :key="session.id" + :url="avatarUrl(session)" :disable-tooltip="true" :style="sessionStyle(session)" + :size="32" /> + </div> + <popover-menu v-show="sessionsPopover.length > 0 && popoverVisible" :menu="sessionsPopover" class="popovermenu menu-right" /> + </div> +</template> + +<script> +import Avatar from 'nextcloud-vue/dist/Components/Avatar' +import PopoverMenu from 'nextcloud-vue/dist/Components/PopoverMenu' + +const COLLABORATOR_IDLE_TIME = 10 +const COLLABORATOR_DISCONNECT_TIME = 30 + +export default { + name: 'SessionList', + components: { + Avatar, + PopoverMenu + }, + props: { + sessions: { + type: Object, + default: () => { return {} } + } + }, + data() { + return { + popoverVisible: '', + myName: '' + } + }, + computed: { + avatarUrl() { + return (session) => { + const user = !session.guestName ? session.userId : session.guestName + const size = 32 + const guest = !!session.guestName + const avatarUrl = OC.generateUrl( + guest ? '/avatar/guest/{user}/{size}' : '/avatar/{user}/{size}', + { + user: user, + size: size + }) + return window.location.protocol + '//' + window.location.host + avatarUrl + } + }, + activeSessions() { + return Object.values(this.sessions).filter((session) => + session.lastContact > Date.now() / 1000 - COLLABORATOR_DISCONNECT_TIME && !session.isCurrent && session.userId !== null) + }, + sessionStyle() { + return (session) => { + return { + 'opacity': session.lastContact > Date.now() / 1000 - COLLABORATOR_IDLE_TIME ? 1 : 0.5 + // 'border-color': session.color + } + } + }, + sessionsVisible() { + return this.activeSessions.slice(0, 3) + }, + sessionsPopover() { + return [ + ...this.activeSessions.slice(3).map((session) => { + return { + href: '#', + icon: this.avatarUrl(session), + text: session.guestName ? session.guestName : session.displayName + } + }) + ] + } + }, + methods: { + } +} +</script> + +<style scoped lang="scss"> + .session-list { + position: relative; + + /deep/ .popovermenu { + margin-right: -4px; + img { + padding: 0; + width: 32px !important; + height: 32px !important; + margin: 6px; + border-radius: 50%; + } + } + } + + .avatar-list { + display: inline-flex; + flex-direction: row-reverse; + + .avatardiv, + /deep/ .avatardiv { + width: 36px; + height: 36px; + margin-right: -8px; + border: 2px solid var(--color-main-background); + background-color: var(--color-main-background) !important; + box-sizing: content-box !important; + &.icon-more { + width: 32px; + height: 32px; + opacity: .5; + background-color: var(--color-background-dark) !important; + } + } + } +</style> |