From eb624f17b73adc8ab66ff6738d9349dbf54eec87 Mon Sep 17 00:00:00 2001 From: Louis Chemineau <louis@chmn.me> Date: Tue, 4 Apr 2023 16:51:02 +0200 Subject: [PATCH 1/5] Use more appropriate icon for visibility Signed-off-by: Louis Chemineau <louis@chmn.me> --- src/components/Composer/VisibilitySelect.vue | 102 ------------------ src/components/TimelinePost.vue | 13 ++- .../{ => Visibility}/VisibilitiesInfos.js | 18 ++-- src/components/Visibility/VisibilityIcon.vue | 59 ++++++++++ .../Visibility/VisibilitySelect.vue | 90 ++++++++++++++++ 5 files changed, 165 insertions(+), 117 deletions(-) delete mode 100644 src/components/Composer/VisibilitySelect.vue rename src/components/{ => Visibility}/VisibilitiesInfos.js (64%) create mode 100644 src/components/Visibility/VisibilityIcon.vue create mode 100644 src/components/Visibility/VisibilitySelect.vue diff --git a/src/components/Composer/VisibilitySelect.vue b/src/components/Composer/VisibilitySelect.vue deleted file mode 100644 index a4e994d4..00000000 --- a/src/components/Composer/VisibilitySelect.vue +++ /dev/null @@ -1,102 +0,0 @@ -<!-- - - @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net> - - @copyright Copyright (c) 2022 Carl Schwan <carl@carlschwan.eu> - - - - @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 v-click-outside="hidePopoverMenu" class="popovermenu-parent"> - <NcButton :title="t('social', 'Change visibility')" - type="tertiary" - :class="currentVisibilityIconClass" - @click.prevent="togglePopoverMenu" /> - <div :class="{open: menuOpened}" class="popovermenu"> - <NcPopoverMenu :menu="visibilityPopover" /> - </div> - </div> -</template> -<script> -import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' -import NcPopoverMenu from '@nextcloud/vue/dist/Components/NcPopoverMenu.js' -import visibilitiesInfo from '../VisibilitiesInfos.js' -import { translate } from '@nextcloud/l10n' - -export default { - name: 'VisibilitySelect', - components: { - NcPopoverMenu, - NcButton, - }, - props: { - visibility: { - type: String, - required: true, - }, - }, - data() { - return { - menuOpened: false, - } - }, - computed: { - /** @return {string} */ - currentVisibilityIconClass() { - return visibilitiesInfo.find(({ id }) => this.visibility === id).icon - }, - - /** @return {object[]} */ - visibilityPopover() { - return visibilitiesInfo.map(visibilityInfo => { - return { - ...visibilityInfo, - action: () => this.switchType(visibilityInfo.id), - active: this.visibility === visibilityInfo.id, - } - }) - }, - }, - methods: { - togglePopoverMenu() { - this.menuOpened = !this.menuOpened - }, - - hidePopoverMenu() { - this.menuOpened = false - }, - - switchType(visibility) { - this.$emit('update:visibility', visibility) - this.menuOpened = false - localStorage.setItem('social.lastPostType', visibility) - }, - - t: translate, - }, -} -</script> -<style scoped> -.popovermenu-parent { - position: relative; -} - -.popovermenu { - top: 55px; -} -</style> diff --git a/src/components/TimelinePost.vue b/src/components/TimelinePost.vue index 1a474733..6c09e50f 100644 --- a/src/components/TimelinePost.vue +++ b/src/components/TimelinePost.vue @@ -14,10 +14,10 @@ </span> </router-link> </div> - <div v-if="visibility" + <VisibilityIcon v-if="visibility" + :title="visibility.text" class="post-visibility" - :class="{ [visibility.icon]: true }" - :title="visibility.text" /> + :visibility="visibility.id" /> <a :data-timestamp="timestamp" class="post-timestamp live-relative-timestamp" :title="formattedDate" @@ -105,7 +105,8 @@ import HeartOutline from 'vue-material-design-icons/HeartOutline.vue' import logger from '../services/logger.js' import moment from '@nextcloud/moment' import MessageContent from './MessageContent.js' -import visibilitiesInfo from './VisibilitiesInfos.js' +import visibilitiesInfo from './Visibility/VisibilitiesInfos.js' +import VisibilityIcon from './Visibility/VisibilityIcon.vue' export default { name: 'TimelinePost', @@ -119,6 +120,7 @@ export default { Heart, HeartOutline, MessageContent, + VisibilityIcon, }, mixins: [currentUser], props: { @@ -284,6 +286,8 @@ export default { justify-content: space-between; .post-author-wrapper { + flex-grow: 1; + &:hover { text-decoration: underline; } @@ -299,7 +303,6 @@ export default { } .post-visibility { - flex-grow: 1; opacity: 0.5; background-position: right; } diff --git a/src/components/VisibilitiesInfos.js b/src/components/Visibility/VisibilitiesInfos.js similarity index 64% rename from src/components/VisibilitiesInfos.js rename to src/components/Visibility/VisibilitiesInfos.js index 2261a090..09882113 100644 --- a/src/components/VisibilitiesInfos.js +++ b/src/components/Visibility/VisibilitiesInfos.js @@ -1,34 +1,32 @@ import { translate as t } from '@nextcloud/l10n' -const visibilityToClass = { - public: 'icon-link', - followers: 'icon-contacts-dark', - direct: 'icon-external', - unlisted: 'icon-password', -} +/** + * @typedef {object} Visibility + * @property {string} id - One of 'public', 'followers', 'direct', 'unlisted' + * @property {string} text - Short label of the visibility + * @property {string} longtext - Description of the visibility + */ + +/** @type {Visibility[]} */ export default [ { id: 'public', - icon: visibilityToClass.public, text: t('social', 'Public'), longtext: t('social', 'Post to public timelines'), }, { id: 'unlisted', - icon: visibilityToClass.unlisted, text: t('social', 'Unlisted'), longtext: t('social', 'Do not post to public timelines'), }, { id: 'followers', - icon: visibilityToClass.followers, text: t('social', 'Followers'), longtext: t('social', 'Post to followers only'), }, { id: 'direct', - icon: visibilityToClass.direct, text: t('social', 'Direct'), longtext: t('social', 'Post to mentioned users only'), }, diff --git a/src/components/Visibility/VisibilityIcon.vue b/src/components/Visibility/VisibilityIcon.vue new file mode 100644 index 00000000..882f9bb9 --- /dev/null +++ b/src/components/Visibility/VisibilityIcon.vue @@ -0,0 +1,59 @@ +<!-- + - @copyright Copyright (c) 2023 Louis Chmn <louis@chmn.me> + - + - @2023 Louis Chmn <louis@chmn.me> + - + - @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> + <Earth v-if="visibility === 'public'" :size="22" /> + <AccountMultiple v-else-if="visibility === 'followers'" :size="22" /> + <LockOpen v-else-if="visibility === 'unlisted'" :size="22" /> + <At v-else-if="visibility === 'direct'" :size="22" /> +</template> +<script> +import Earth from 'vue-material-design-icons/Earth.vue' +import LockOpen from 'vue-material-design-icons/LockOpen.vue' +import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue' +import At from 'vue-material-design-icons/At.vue' + +export default { + name: 'VisibilityIcon', + components: { + Earth, + LockOpen, + AccountMultiple, + At, + }, + props: { + visibility: { + type: String, + required: true, + }, + }, + data() { + return {} + }, + computed: { + + }, + methods: { + + }, +} +</script> diff --git a/src/components/Visibility/VisibilitySelect.vue b/src/components/Visibility/VisibilitySelect.vue new file mode 100644 index 00000000..df8819d9 --- /dev/null +++ b/src/components/Visibility/VisibilitySelect.vue @@ -0,0 +1,90 @@ +<!-- + - @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net> + - @copyright Copyright (c) 2022 Carl Schwan <carl@carlschwan.eu> + - + - @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> + <NcActions type="tertiary" :menu-title="selectedVisibilityDetails.text" :aria-label="t('social', 'Choose a visibility')"> + <template #icon> + <VisibilityIcon :visibility="selectedVisibilityDetails.id" :size="20" /> + </template> + <NcActionButton v-for="visibilityDetails of visibilitiesInfo" + :key="visibilityDetails.id" + :class="{'selected-visibility': visibilityDetails.id === selectedVisibilityDetails.id}" + :close-after-click="true" + @click="switchType(visibilityDetails)"> + <template #icon> + <VisibilityIcon :visibility="visibilityDetails.id" :size="20" /> + </template> + {{ visibilityDetails.longtext }} + </NcActionButton> + </NcActions> +</template> +<script> +import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' +import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' +import { translate } from '@nextcloud/l10n' +import visibilitiesInfo from './VisibilitiesInfos.js' +import VisibilityIcon from './VisibilityIcon.vue' + +export default { + name: 'VisibilitySelect', + components: { + NcActions, + NcActionButton, + VisibilityIcon, + }, + props: { + visibility: { + type: String, + required: true, + }, + }, + data() { + return { + visibilitiesInfo, + } + }, + computed: { + /** @return {import('./VisibilitiesInfos.js').Visibility} */ + selectedVisibilityDetails() { + return visibilitiesInfo.find(({ id }) => this.visibility === id) + }, + }, + methods: { + switchType(visibility) { + this.$emit('update:visibility', visibility.id) + // this.menuOpened = false + localStorage.setItem('social.lastPostType', visibility.id) + }, + + t: translate, + }, +} +</script> +<style scoped> +.selected-visibility { + border: 1px solid var(--color-success); + border-left-width: 4px; + border-radius: 6px; + background: var(--color-background-hover); +} +</style> From 896108ea40f12db77dd723de21a494cb8c91efef Mon Sep 17 00:00:00 2001 From: Louis Chemineau <louis@chmn.me> Date: Tue, 4 Apr 2023 16:51:28 +0200 Subject: [PATCH 2/5] Use more appropriate icon for attachments Signed-off-by: Louis Chemineau <louis@chmn.me> --- src/components/Composer/Composer.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Composer/Composer.vue b/src/components/Composer/Composer.vue index a1ee329f..df9fa55c 100644 --- a/src/components/Composer/Composer.vue +++ b/src/components/Composer/Composer.vue @@ -85,7 +85,7 @@ :aria-label="t('social', 'Add attachment')" @click.prevent="clickImportInput"> <template #icon> - <FileUpload :size="22" decorative title="" /> + <Paperclip :size="22" decorative title="" /> </template> </NcButton> @@ -118,7 +118,7 @@ import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline.vue' import Close from 'vue-material-design-icons/Close.vue' -import FileUpload from 'vue-material-design-icons/FileUpload.vue' +import Paperclip from 'vue-material-design-icons/Paperclip.vue' import debounce from 'debounce' import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js' import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' @@ -131,7 +131,7 @@ import axios from '@nextcloud/axios' import ActorAvatar from '../ActorAvatar.vue' import { generateUrl } from '@nextcloud/router' import PreviewGrid from './PreviewGrid.vue' -import VisibilitySelect from './VisibilitySelect.vue' +import VisibilitySelect from '../Visibility/VisibilitySelect.vue' import SubmitStatusButton from './SubmitStatusButton.vue' import MessageContent from '../MessageContent.js' @@ -148,7 +148,7 @@ export default { NcEmojiPicker, NcButton, ActorAvatar, - FileUpload, + Paperclip, VueTribute, EmoticonOutline, Close, From 7eb659a90ddbb63dfbd55789e07d4d030c8c1401 Mon Sep 17 00:00:00 2001 From: Louis Chemineau <louis@chmn.me> Date: Tue, 4 Apr 2023 17:18:12 +0200 Subject: [PATCH 3/5] Use mastodon's label for visibilities description Signed-off-by: Louis Chemineau <louis@chmn.me> --- src/components/Visibility/VisibilitiesInfos.js | 10 +++++----- src/components/Visibility/VisibilitySelect.vue | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Visibility/VisibilitiesInfos.js b/src/components/Visibility/VisibilitiesInfos.js index 09882113..783d8b9f 100644 --- a/src/components/Visibility/VisibilitiesInfos.js +++ b/src/components/Visibility/VisibilitiesInfos.js @@ -5,7 +5,7 @@ import { translate as t } from '@nextcloud/l10n' * @typedef {object} Visibility * @property {string} id - One of 'public', 'followers', 'direct', 'unlisted' * @property {string} text - Short label of the visibility - * @property {string} longtext - Description of the visibility + * @property {string} description - Description of the visibility */ /** @type {Visibility[]} */ @@ -13,21 +13,21 @@ export default [ { id: 'public', text: t('social', 'Public'), - longtext: t('social', 'Post to public timelines'), + description: t('social', 'Visible for all'), }, { id: 'unlisted', text: t('social', 'Unlisted'), - longtext: t('social', 'Do not post to public timelines'), + description: t('social', 'Visible for all, but opted-out of discovery features'), }, { id: 'followers', text: t('social', 'Followers'), - longtext: t('social', 'Post to followers only'), + description: t('social', 'Visible to followers only'), }, { id: 'direct', text: t('social', 'Direct'), - longtext: t('social', 'Post to mentioned users only'), + description: t('social', 'Visible to mentioned users only'), }, ] diff --git a/src/components/Visibility/VisibilitySelect.vue b/src/components/Visibility/VisibilitySelect.vue index df8819d9..c5c4e7a7 100644 --- a/src/components/Visibility/VisibilitySelect.vue +++ b/src/components/Visibility/VisibilitySelect.vue @@ -34,7 +34,7 @@ <template #icon> <VisibilityIcon :visibility="visibilityDetails.id" :size="20" /> </template> - {{ visibilityDetails.longtext }} + {{ visibilityDetails.description }} </NcActionButton> </NcActions> </template> From 97e3f7aa6802f659c274898f7b36502ae1553884 Mon Sep 17 00:00:00 2001 From: Louis Chemineau <louis@chmn.me> Date: Tue, 4 Apr 2023 17:21:44 +0200 Subject: [PATCH 4/5] Use outline instead of border for selected visibility Signed-off-by: Louis Chemineau <louis@chmn.me> --- src/components/Visibility/VisibilitySelect.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Visibility/VisibilitySelect.vue b/src/components/Visibility/VisibilitySelect.vue index c5c4e7a7..824299f0 100644 --- a/src/components/Visibility/VisibilitySelect.vue +++ b/src/components/Visibility/VisibilitySelect.vue @@ -82,8 +82,7 @@ export default { </script> <style scoped> .selected-visibility { - border: 1px solid var(--color-success); - border-left-width: 4px; + outline: 1px solid var(--color-success); border-radius: 6px; background: var(--color-background-hover); } From 749008690d0756166503aa4236adc593e222a711 Mon Sep 17 00:00:00 2001 From: Louis Chemineau <louis@chmn.me> Date: Wed, 5 Apr 2023 11:44:29 +0200 Subject: [PATCH 5/5] Lint front-end files Signed-off-by: Louis Chemineau <louis@chmn.me> --- src/components/Visibility/VisibilitiesInfos.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Visibility/VisibilitiesInfos.js b/src/components/Visibility/VisibilitiesInfos.js index 783d8b9f..af2c64c0 100644 --- a/src/components/Visibility/VisibilitiesInfos.js +++ b/src/components/Visibility/VisibilitiesInfos.js @@ -1,6 +1,5 @@ import { translate as t } from '@nextcloud/l10n' - /** * @typedef {object} Visibility * @property {string} id - One of 'public', 'followers', 'direct', 'unlisted'