From 15bed586dcd1d10a6a05c664cf5bab72cdbf2a46 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 15 Nov 2020 13:57:02 +0200 Subject: [PATCH 001/369] report notification wip --- src/components/interactions/interactions.js | 2 ++ src/components/interactions/interactions.vue | 9 +++++++++ .../entity_normalizer/entity_normalizer.service.js | 7 +++++++ src/services/notification_utils/notification_utils.js | 6 +++++- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js index 7fe5e76d..54275a7b 100644 --- a/src/components/interactions/interactions.js +++ b/src/components/interactions/interactions.js @@ -4,6 +4,8 @@ const tabModeDict = { mentions: ['mention'], 'likes+repeats': ['repeat', 'like'], follows: ['follow'], + reactions: ['pleroma:emoji_reaction'], + reports: ['pleroma:report'], moves: ['move'] } diff --git a/src/components/interactions/interactions.vue b/src/components/interactions/interactions.vue index 57d5d87c..b7291c02 100644 --- a/src/components/interactions/interactions.vue +++ b/src/components/interactions/interactions.vue @@ -21,6 +21,15 @@ key="follows" :label="$t('interactions.follows')" /> + + { : parseUser(data.target) output.from_profile = parseUser(data.account) output.emoji = data.emoji + if (data.report) { + output.report = data.report + output.report.content = data.report.content + output.report.acct = parseUser(data.report.acct) + output.report.actor = parseUser(data.report.actor) + output.report.statuses = data.report.statuses.map(parseStatus) + } } else { const parsedNotice = parseStatus(data.notice) output.type = data.ntype diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index d912d19f..dff97aa2 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -14,7 +14,8 @@ export const visibleTypes = store => { rootState.config.notificationVisibility.follows && 'follow', rootState.config.notificationVisibility.followRequest && 'follow_request', rootState.config.notificationVisibility.moves && 'move', - rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction' + rootState.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction', + rootState.config.notificationVisibility.reports && 'pleroma:report' ].filter(_ => _)) } @@ -91,6 +92,9 @@ export const prepareNotificationObject = (notification, i18n) => { case 'follow_request': i18nString = 'follow_request' break + case 'pleroma:report': + i18nString = 'reported' + break } if (notification.type === 'pleroma:emoji_reaction') { From 5e96260a4f855e2d93915c1b428a7209a882c8cb Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Fri, 4 Dec 2020 12:48:15 +0200 Subject: [PATCH 002/369] add test data for dev --- src/services/api/api.service.js | 282 ++++++++++++++++++ .../entity_normalizer.service.js | 2 +- .../notifications_fetcher.service.js | 1 + 3 files changed, 284 insertions(+), 1 deletion(-) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 8da933c4..6b825c37 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -484,6 +484,285 @@ const deleteUser = ({ credentials, user }) => { }) } +/* eslint-disable */ +const report = { + "account": { + "acct": "reporting_account", + "avatar": "https://develop.ilja.space/images/avi.png", + "avatar_static": "https://develop.ilja.space/images/avi.png", + "bot": false, + "created_at": "2020-09-03T14:17:00.000Z", + "display_name": "Reporting Account", + "emojis": [], + "fields": [], + "followers_count": 0, + "following_count": 0, + "header": "https://develop.ilja.space/images/banner.png", + "header_static": "https://develop.ilja.space/images/banner.png", + "id": "9ymg9LnKk74wuk9lXk", + "locked": false, + "note": "I'm an account made for an example report notification. I'm the one that will do the reporting.", + "pleroma": { + "accepts_chat_messages": true, + "ap_id": "https://develop.ilja.space/users/reporting_account", + "background_image": null, + "confirmation_pending": false, + "deactivated": false, + "favicon": null, + "hide_favorites": true, + "hide_followers": false, + "hide_followers_count": false, + "hide_follows": false, + "hide_follows_count": false, + "is_admin": false, + "is_moderator": false, + "relationship": {}, + "skip_thread_containment": false, + "tags": [] + }, + "source": { + "fields": [], + "note": "", + "pleroma": { + "actor_type": "Person", + "discoverable": false + }, + "sensitive": false + }, + "statuses_count": 0, + "url": "https://develop.ilja.space/users/reporting_account", + "username": "reporting_account" + }, + "created_at": "2020-09-03T14:22:59.000Z", + "id": "5", + "pleroma": { + "is_muted": false, + "is_seen": false + }, + "report": { + "account": { + "local": true, + "locked": false, + "acct": "reported_account", + "followers_count": 0, + "fields": [], + "avatar": "https://develop.ilja.space/images/avi.png", + "actor_type": "Person", + "url": "https://develop.ilja.space/users/reported_account", + "deactivated": false, + "id": "9ymgGklmHjZ2OpxVLM", + "bot": false, + "roles": { + "admin": false, + "moderator": false + }, + "statuses_count": 1, + "nickname": "reported_account", + "display_name": "Reported Account", + "source": { + "fields": [], + "note": "", + "pleroma": { + "actor_type": "Person", + "discoverable": false + }, + "sensitive": false + }, + "pleroma": { + "accepts_chat_messages": true, + "ap_id": "https://develop.ilja.space/users/reported_account", + "background_image": null, + "confirmation_pending": false, + "favicon": null, + "hide_favorites": true, + "hide_followers": false, + "hide_followers_count": false, + "hide_follows": false, + "hide_follows_count": false, + "is_admin": false, + "is_moderator": false, + "relationship": {}, + "skip_thread_containment": false, + "tags": [] + }, + "emojis": [], + "created_at": "2020-09-03T14:18:21.000Z", + "username": "reported_account", + "note": "I'm an account made for an example report notification. I'm the one that will be reported.", + "approval_pending": false, + "avatar_static": "https://develop.ilja.space/images/avi.png", + "header": "https://develop.ilja.space/images/banner.png", + "registration_reason": null, + "confirmation_pending": false, + "header_static": "https://develop.ilja.space/images/banner.png", + "following_count": 0, + "tags": [] + }, + "actor": { + "local": true, + "locked": false, + "acct": "reporting_account", + "followers_count": 0, + "fields": [], + "avatar": "https://develop.ilja.space/images/avi.png", + "actor_type": "Person", + "url": "https://develop.ilja.space/users/reporting_account", + "deactivated": false, + "id": "9ymg9LnKk74wuk9lXk", + "bot": false, + "roles": { + "admin": false, + "moderator": false + }, + "statuses_count": 0, + "nickname": "reporting_account", + "display_name": "Reporting Account", + "source": { + "fields": [], + "note": "", + "pleroma": { + "actor_type": "Person", + "discoverable": false + }, + "sensitive": false + }, + "pleroma": { + "accepts_chat_messages": true, + "ap_id": "https://develop.ilja.space/users/reporting_account", + "background_image": null, + "confirmation_pending": false, + "favicon": null, + "hide_favorites": true, + "hide_followers": false, + "hide_followers_count": false, + "hide_follows": false, + "hide_follows_count": false, + "is_admin": false, + "is_moderator": false, + "relationship": {}, + "skip_thread_containment": false, + "tags": [] + }, + "emojis": [], + "created_at": "2020-09-03T14:17:00.000Z", + "username": "reporting_account", + "note": "I'm an account made for an example report notification. I'm the one that will do the reporting.", + "approval_pending": false, + "avatar_static": "https://develop.ilja.space/images/avi.png", + "header": "https://develop.ilja.space/images/banner.png", + "registration_reason": null, + "confirmation_pending": false, + "header_static": "https://develop.ilja.space/images/banner.png", + "following_count": 0, + "tags": [] + }, + "content": "This is the report created by "reporting_account". It reports "reported_account".", + "created_at": "2020-09-03T14:22:59.000Z", + "id": "9ymggNcUyfIW8Cq1zM", + "notes": [], + "state": "open", + "statuses": [ + { + "account": { + "acct": "reported_account", + "avatar": "https://develop.ilja.space/images/avi.png", + "avatar_static": "https://develop.ilja.space/images/avi.png", + "bot": false, + "created_at": "2020-09-03T14:18:21.000Z", + "display_name": "Reported Account", + "emojis": [], + "fields": [], + "followers_count": 0, + "following_count": 0, + "header": "https://develop.ilja.space/images/banner.png", + "header_static": "https://develop.ilja.space/images/banner.png", + "id": "9ymgGklmHjZ2OpxVLM", + "locked": false, + "note": "I'm an account made for an example report notification. I'm the one that will be reported.", + "pleroma": { + "accepts_chat_messages": true, + "ap_id": "https://develop.ilja.space/users/reported_account", + "background_image": null, + "confirmation_pending": false, + "favicon": null, + "hide_favorites": true, + "hide_followers": false, + "hide_followers_count": false, + "hide_follows": false, + "hide_follows_count": false, + "is_admin": false, + "is_moderator": false, + "relationship": {}, + "skip_thread_containment": false, + "tags": [] + }, + "source": { + "fields": [], + "note": "", + "pleroma": { + "actor_type": "Person", + "discoverable": false + }, + "sensitive": false + }, + "statuses_count": 1, + "url": "https://develop.ilja.space/users/reported_account", + "username": "reported_account" + }, + "application": { + "name": "Web", + "website": null + }, + "bookmarked": false, + "card": null, + "content": "A post I made that will be included in the report", + "created_at": "2020-09-03T14:18:51.000Z", + "emojis": [], + "favourited": false, + "favourites_count": 0, + "id": "9ymgJaQxAbTzDDZMJs", + "in_reply_to_account_id": null, + "in_reply_to_id": null, + "language": null, + "media_attachments": [], + "mentions": [], + "muted": false, + "pinned": false, + "pleroma": { + "content": { + "text/plain": "A post I made that will be included in the report" + }, + "conversation_id": 7, + "direct_conversation_id": null, + "emoji_reactions": [], + "expires_at": null, + "in_reply_to_account_acct": null, + "local": true, + "parent_visible": false, + "spoiler_text": { + "text/plain": "" + }, + "thread_muted": false + }, + "poll": null, + "reblog": null, + "reblogged": false, + "reblogs_count": 0, + "replies_count": 0, + "sensitive": false, + "spoiler_text": "", + "tags": [], + "text": null, + "uri": "https://develop.ilja.space/objects/8fe7611a-07e7-403a-ae08-f74580b6cc53", + "url": "https://develop.ilja.space/notice/9ymgJaQxAbTzDDZMJs", + "visibility": "public" + } + ] + }, + "type": "pleroma:report" +} +/* eslint-enable */ + const fetchTimeline = ({ timeline, credentials, @@ -561,6 +840,9 @@ const fetchTimeline = ({ .then((data) => data.json()) .then((data) => { if (!data.errors) { + if (isNotifications) { + return { data: [parseNotification(report)], pagination } + } return { data: data.map(isNotifications ? parseNotification : parseStatus), pagination } } else { data.status = status diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 0fd01176..c71bc15a 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -376,7 +376,7 @@ export const parseNotification = (data) => { if (data.report) { output.report = data.report output.report.content = data.report.content - output.report.acct = parseUser(data.report.acct) + output.report.acct = parseUser(data.report.account) output.report.actor = parseUser(data.report.actor) output.report.statuses = data.report.statuses.map(parseStatus) } diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index beeb167c..91861b21 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -61,6 +61,7 @@ const fetchNotifications = ({ store, args, older }) => { messageArgs: [error.message], timeout: 5000 }) + console.error(error) }) } From a4e3cccf1cba238e5bfd96ea8c60f0d12bc6b7aa Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Wed, 6 Jan 2021 18:31:34 +0200 Subject: [PATCH 003/369] somewhat workign version still with fixture --- src/components/notification/notification.js | 3 + src/components/notification/notification.scss | 28 +++ src/components/notification/notification.vue | 34 +++ src/components/notifications/notifications.js | 1 + .../notifications/notifications.scss | 6 +- src/i18n/en.json | 3 +- src/modules/config.js | 3 +- src/services/api/api.service.js | 197 +++++++++--------- .../entity_normalizer.service.js | 1 - 9 files changed, 177 insertions(+), 99 deletions(-) diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js index 4aa9affd..a920bb3e 100644 --- a/src/components/notification/notification.js +++ b/src/components/notification/notification.js @@ -76,6 +76,9 @@ const Notification = { this.$store.dispatch('dismissNotificationLocal', { id: this.notification.id }) this.$store.dispatch('removeFollowRequest', this.user) }) + }, + testlog (a) { + console.log(a) } }, computed: { diff --git a/src/components/notification/notification.scss b/src/components/notification/notification.scss index f5905560..b103db86 100644 --- a/src/components/notification/notification.scss +++ b/src/components/notification/notification.scss @@ -56,6 +56,34 @@ margin: 0 0.1em; } + .report-content { + margin: 0.5em 0; + } + + .reported-status { + border: 1px solid $fallback--faint; + border-color: var(--faint, $fallback--faint); + border-radius: $fallback--inputRadius; + border-radius: var(--inputRadius, $fallback--inputRadius); + color: $fallback--text; + color: var(--text, $fallback--text); + display: block; + padding: 0.5em; + margin: 0.5em 0; + + .status-content { + pointer-events: none; + } + + .reported-status-name { + font-weight: bold; + } + + .reported-status-timeago { + float: right; + } + } + &.-type--repeat .type-icon { color: $fallback--cGreen; color: var(--cGreen, $fallback--cGreen); diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue index f56aa977..39e3bda0 100644 --- a/src/components/notification/notification.vue +++ b/src/components/notification/notification.vue @@ -106,6 +106,9 @@ + + {{ $t('notifications.submitted_report') }} +
+
+ Reported user: + + @{{ notification.report.acct.screen_name }} + + +
+
+ Reported statuses: + + + {{ status.user.name }} + + + +
+
diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue index 7f35b7b5..8da691c0 100644 --- a/src/components/react_button/react_button.vue +++ b/src/components/react_button/react_button.vue @@ -6,6 +6,7 @@ :offset="{ y: 5 }" :bound-to="{ x: 'container' }" remove-padding + popover-class="ReactButton popover-default" @show="focusInput" > diff --git a/src/services/date_utils/date_utils.js b/src/services/date_utils/date_utils.js index 32e13bca..677c184c 100644 --- a/src/services/date_utils/date_utils.js +++ b/src/services/date_utils/date_utils.js @@ -10,31 +10,29 @@ export const relativeTime = (date, nowThreshold = 1) => { if (typeof date === 'string') date = Date.parse(date) const round = Date.now() > date ? Math.floor : Math.ceil const d = Math.abs(Date.now() - date) - let r = { num: round(d / YEAR), key: 'time.years' } + let r = { num: round(d / YEAR), key: 'time.unit.years' } if (d < nowThreshold * SECOND) { r.num = 0 r.key = 'time.now' } else if (d < MINUTE) { r.num = round(d / SECOND) - r.key = 'time.seconds' + r.key = 'time.unit.seconds' } else if (d < HOUR) { r.num = round(d / MINUTE) - r.key = 'time.minutes' + r.key = 'time.unit.minutes' } else if (d < DAY) { r.num = round(d / HOUR) - r.key = 'time.hours' + r.key = 'time.unit.hours' } else if (d < WEEK) { r.num = round(d / DAY) - r.key = 'time.days' + r.key = 'time.unit.days' } else if (d < MONTH) { r.num = round(d / WEEK) - r.key = 'time.weeks' + r.key = 'time.unit.weeks' } else if (d < YEAR) { r.num = round(d / MONTH) - r.key = 'time.months' + r.key = 'time.unit.months' } - // Remove plural form when singular - if (r.num === 1) r.key = r.key.slice(0, -1) return r } From e3b9c00d5e1bfadc0e1e1bcd06c43cf53035f0c0 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 8 Jun 2022 03:22:15 +0300 Subject: [PATCH 033/369] hide popovers on scroll --- src/components/popover/popover.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index c65689bd..09e07b4c 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -168,6 +168,9 @@ const Popover = { if (this.hidden) return if (this.$el.contains(e.target)) return this.hidePopover() + }, + onScroll () { + this.hidePopover() } }, updated () { @@ -183,9 +186,11 @@ const Popover = { }, created () { document.addEventListener('click', this.onClickOutside) + window.addEventListener('scroll', this.onScroll) }, unmounted () { document.removeEventListener('click', this.onClickOutside) + window.removeEventListener('scroll', this.onScroll) this.hidePopover() } } From 772ddade2123595817a16a2f9c56824a87f9e97c Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 7 Jun 2022 20:22:25 -0400 Subject: [PATCH 034/369] Add English translations for correctly i18nized time units --- src/i18n/en.json | 46 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/i18n/en.json b/src/i18n/en.json index 0cfda804..a5c43a73 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -692,38 +692,26 @@ } }, "time": { - "day": "{0} day", - "days": "{0} days", - "day_short": "{0}d", - "days_short": "{0}d", - "hour": "{0} hour", - "hours": "{0} hours", - "hour_short": "{0}h", - "hours_short": "{0}h", + "unit": { + "days": "{0} day | {0} days", + "days_short": "{0}d", + "hours": "{0} hour | {0} hours", + "hours_short": "{0}h", + "minutes": "{0} minute | {0} minutes", + "minutes_short": "{0}min", + "months": "{0} month | {0} months", + "months_short": "{0}mo", + "seconds": "{0} second | {0} seconds", + "seconds_short": "{0}s", + "weeks": "{0} week | {0} weeks", + "weeks_short": "{0}w", + "years": "{0} year | {0} years", + "years_short": "{0}y" + }, "in_future": "in {0}", "in_past": "{0} ago", - "minute": "{0} minute", - "minutes": "{0} minutes", - "minute_short": "{0}min", - "minutes_short": "{0}min", - "month": "{0} month", - "months": "{0} months", - "month_short": "{0}mo", - "months_short": "{0}mo", "now": "just now", - "now_short": "now", - "second": "{0} second", - "seconds": "{0} seconds", - "second_short": "{0}s", - "seconds_short": "{0}s", - "week": "{0} week", - "weeks": "{0} weeks", - "week_short": "{0}w", - "weeks_short": "{0}w", - "year": "{0} year", - "years": "{0} years", - "year_short": "{0}y", - "years_short": "{0}y" + "now_short": "now" }, "timeline": { "collapse": "Collapse", From 71b5462a059708e036bd2c998758e8fa1e205450 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 8 Jun 2022 03:22:50 +0300 Subject: [PATCH 035/369] vPadding is no longer needed --- src/components/popover/popover.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index 09e07b4c..1e8b3fb6 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -109,16 +109,10 @@ const Popover = { if (origin.y + content.offsetHeight > yBounds.max) usingTop = true if (origin.y - content.offsetHeight < yBounds.min) usingTop = false - let vPadding = 0 - if (this.removePadding && usingTop) { - const anchorStyle = getComputedStyle(anchorEl) - vPadding = parseFloat(anchorStyle.paddingTop) + parseFloat(anchorStyle.paddingBottom) - } - const yOffset = (this.offset && this.offset.y) || 0 const translateY = usingTop - ? yOffset - content.offsetHeight - vPadding - : yOffset + anchorHeight + vPadding + ? yOffset - content.offsetHeight + : yOffset + anchorHeight const xOffset = (this.offset && this.offset.x) || 0 const translateX = horizOffset + xOffset From 13cff692f0633bfccb7896e774fcf4820ddbb4c2 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 7 Jun 2022 20:34:08 -0400 Subject: [PATCH 036/369] Fix tests --- test/unit/specs/services/date_utils/date_utils.spec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/unit/specs/services/date_utils/date_utils.spec.js b/test/unit/specs/services/date_utils/date_utils.spec.js index 2d61dbac..bd1efe81 100644 --- a/test/unit/specs/services/date_utils/date_utils.spec.js +++ b/test/unit/specs/services/date_utils/date_utils.spec.js @@ -11,30 +11,30 @@ describe('DateUtils', () => { it('rounds down for past', () => { const time = Date.now() - 1.8 * DateUtils.HOUR - expect(DateUtils.relativeTime(time)).to.eql({ num: 1, key: 'time.hour' }) + expect(DateUtils.relativeTime(time)).to.eql({ num: 1, key: 'time.unit.hours' }) }) it('rounds up for future', () => { const time = Date.now() + 1.8 * DateUtils.HOUR - expect(DateUtils.relativeTime(time)).to.eql({ num: 2, key: 'time.hours' }) + expect(DateUtils.relativeTime(time)).to.eql({ num: 2, key: 'time.unit.hours' }) }) it('uses plural when necessary', () => { const time = Date.now() - 3.8 * DateUtils.WEEK - expect(DateUtils.relativeTime(time)).to.eql({ num: 3, key: 'time.weeks' }) + expect(DateUtils.relativeTime(time)).to.eql({ num: 3, key: 'time.unit.weeks' }) }) it('works with date string', () => { const time = Date.now() - 4 * DateUtils.MONTH const dateString = new Date(time).toISOString() - expect(DateUtils.relativeTime(dateString)).to.eql({ num: 4, key: 'time.months' }) + expect(DateUtils.relativeTime(dateString)).to.eql({ num: 4, key: 'time.unit.months' }) }) }) describe('relativeTimeShort', () => { it('returns the short version of the same relative time', () => { const time = Date.now() + 2 * DateUtils.YEAR - expect(DateUtils.relativeTimeShort(time)).to.eql({ num: 2, key: 'time.years_short' }) + expect(DateUtils.relativeTimeShort(time)).to.eql({ num: 2, key: 'time.unit.years_short' }) }) }) }) From 1ce78435c48cec23b396e4c5dca21e3116dc9f8c Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 7 Jun 2022 21:47:21 -0400 Subject: [PATCH 037/369] Show underlay for mobile --- src/App.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.scss b/src/App.scss index 5cd0b96e..7e6d0dfc 100644 --- a/src/App.scss +++ b/src/App.scss @@ -310,7 +310,6 @@ nav { border-top-right-radius: 0; } - .underlay, #sidebar, #notifs-column { display: none; From 1a333aabba759fb68449ead9c47e986f456e8c8c Mon Sep 17 00:00:00 2001 From: Sean King Date: Tue, 7 Jun 2022 21:31:48 -0600 Subject: [PATCH 038/369] Add edit status functionality --- CONTRIBUTORS.md | 1 + src/App.js | 2 + src/App.vue | 1 + .../edit_status_modal/edit_status_modal.js | 75 ++++++++++++++++ .../edit_status_modal/edit_status_modal.vue | 48 ++++++++++ src/components/extra_buttons/extra_buttons.js | 13 +++ .../extra_buttons/extra_buttons.vue | 11 +++ .../post_status_form/post_status_form.js | 45 +++++++--- .../post_status_form/post_status_form.vue | 1 + src/i18n/en.json | 2 + src/main.js | 3 + src/modules/api.js | 2 + src/modules/editStatus.js | 25 ++++++ src/modules/statuses.js | 6 ++ src/services/api/api.service.js | 88 ++++++++++++++++++- .../entity_normalizer.service.js | 12 +++ .../status_poster/status_poster.service.js | 42 +++++++++ 17 files changed, 365 insertions(+), 12 deletions(-) create mode 100644 src/components/edit_status_modal/edit_status_modal.js create mode 100644 src/components/edit_status_modal/edit_status_modal.vue create mode 100644 src/modules/editStatus.js diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f666a4ef..18f4a930 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -10,3 +10,4 @@ Contributors of this project. - shpuld (shpuld@shitposter.club): CSS and styling - Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images. - hj (hj@shigusegubu.club): Code +- Sean King (seanking@freespeechextremist.com): Code diff --git a/src/App.js b/src/App.js index f01f8788..6e0e34a8 100644 --- a/src/App.js +++ b/src/App.js @@ -11,6 +11,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil import MobileNav from './components/mobile_nav/mobile_nav.vue' import DesktopNav from './components/desktop_nav/desktop_nav.vue' import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue' +import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue' import PostStatusModal from './components/post_status_modal/post_status_modal.vue' import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue' import { windowWidth, windowHeight } from './services/window_utils/window_utils' @@ -35,6 +36,7 @@ export default { SettingsModal, UserReportingModal, PostStatusModal, + EditStatusModal, GlobalNoticeList }, data: () => ({ diff --git a/src/App.vue b/src/App.vue index 5b448972..9484f993 100644 --- a/src/App.vue +++ b/src/App.vue @@ -52,6 +52,7 @@ +
@@ -257,7 +257,7 @@ @keydown.enter.prevent="" >

- {{ localDescription }} + {{ attachment.description }}

From 31571361d378db5a42a2c955060637782d546fb3 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 11 Jun 2022 18:17:28 -0400 Subject: [PATCH 042/369] Fix top bar input text colour --- src/components/desktop_nav/desktop_nav.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/desktop_nav/desktop_nav.scss b/src/components/desktop_nav/desktop_nav.scss index 0ca9802e..eddd9707 100644 --- a/src/components/desktop_nav/desktop_nav.scss +++ b/src/components/desktop_nav/desktop_nav.scss @@ -3,6 +3,10 @@ .DesktopNav { width: 100%; + input { + color: var(--inputTopbarText, var(--inputText)); + } + a { color: var(--topBarLink, $fallback--link); } From 80ec88beabefd41e75040dd35364a94783e423a0 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 11 Jun 2022 16:32:46 -0600 Subject: [PATCH 043/369] Use statusId instead of repliedUser.id --- src/components/edit_status_modal/edit_status_modal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/edit_status_modal/edit_status_modal.js b/src/components/edit_status_modal/edit_status_modal.js index 14320d21..75adfea7 100644 --- a/src/components/edit_status_modal/edit_status_modal.js +++ b/src/components/edit_status_modal/edit_status_modal.js @@ -29,7 +29,7 @@ const EditStatusModal = { }, watch: { params (newVal, oldVal) { - if (get(newVal, 'repliedUser.id') !== get(oldVal, 'repliedUser.id')) { + if (get(newVal, 'statusId') !== get(oldVal, 'statusId')) { this.resettingForm = true this.$nextTick(() => { this.resettingForm = false From 32ecdfdd8738befa004f865f496b7df17a4c2030 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 11 Jun 2022 16:38:03 -0600 Subject: [PATCH 044/369] Don't pollute the original timeline when new media attachment is added --- src/components/extra_buttons/extra_buttons.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js index 9508a707..8a703953 100644 --- a/src/components/extra_buttons/extra_buttons.js +++ b/src/components/extra_buttons/extra_buttons.js @@ -80,7 +80,7 @@ const ExtraButtons = { statusText: data.text, statusIsSensitive: this.status.nsfw, statusPoll: this.status.poll, - statusFiles: this.status.attachments, + statusFiles: [...this.status.attachments], visibility: this.status.visibility, statusContentType: data.content_type })) From 29e7972d8b46e9ad15ecc0cdd398f6054fe0004a Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 11 Jun 2022 16:44:08 -0600 Subject: [PATCH 045/369] Credit to the chad tusooa --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 18f4a930..bfc41ac4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -11,3 +11,4 @@ Contributors of this project. - Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images. - hj (hj@shigusegubu.club): Code - Sean King (seanking@freespeechextremist.com): Code +- Tusooa Zhu (tusooa@kazv.moe): Code From c195e3571c113d29778ad86f4cbea019716fe787 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 11 Jun 2022 20:33:12 -0400 Subject: [PATCH 046/369] Handle explicit mention changes in status updates --- src/components/status_body/status_body.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js index b8f6f9a0..0a3dcf79 100644 --- a/src/components/status_body/status_body.js +++ b/src/components/status_body/status_body.js @@ -125,6 +125,13 @@ const StatusContent = { generateTagLink (tag) { return `/tag/${tag}` } + }, + watch: { + 'status.raw_html' (newVal, oldVal) { + if (newVal !== oldVal) { + this.parseReadyDone = false + } + } } } From 6e42409b8a0002ecbc75433b4f0881f10eb58bff Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 11 Jun 2022 19:30:29 -0600 Subject: [PATCH 047/369] Fetch status when highlighting it --- src/components/conversation/conversation.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 2ef2977a..1e6c0008 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -395,6 +395,7 @@ const conversation = { setHighlight (id) { if (!id) return this.highlight = id + this.$store.dispatch('fetchStatus', id) this.$store.dispatch('fetchFavsAndRepeats', id) this.$store.dispatch('fetchEmojiReactionsBy', id) }, From 8dac3932fed30e4238c2a7ef9cef8255a5c83a5a Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 11 Jun 2022 20:10:16 -0600 Subject: [PATCH 048/369] Only refetch status on highlight if streaming is not enabled --- src/components/conversation/conversation.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 1e6c0008..f8df9eb5 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -1,6 +1,8 @@ import { reduce, filter, findIndex, clone, get } from 'lodash' import Status from '../status/status.vue' import ThreadTree from '../thread_tree/thread_tree.vue' +import { WSConnectionStatus } from '../../services/api/api.service.js' +import { mapGetters, mapState } from 'vuex' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -77,6 +79,9 @@ const conversation = { const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2 return maxDepth >= 1 ? maxDepth : 1 }, + streamingEnabled () { + return this.mergedConfig.useStreamingApi && this.mastoUserSocketStatus === WSConnectionStatus.JOINED + }, displayStyle () { return this.$store.getters.mergedConfig.conversationDisplay }, @@ -339,7 +344,11 @@ const conversation = { }, maybeHighlight () { return this.isExpanded ? this.highlight : null - } + }, + ...mapGetters(['mergedConfig']), + ...mapState({ + mastoUserSocketStatus: state => state.api.mastoUserSocketStatus + }) }, components: { Status, @@ -395,7 +404,11 @@ const conversation = { setHighlight (id) { if (!id) return this.highlight = id - this.$store.dispatch('fetchStatus', id) + + if (!this.streamingEnabled) { + this.$store.dispatch('fetchStatus', id) + } + this.$store.dispatch('fetchFavsAndRepeats', id) this.$store.dispatch('fetchEmojiReactionsBy', id) }, From 87fa7b82fb597ea597ee228c97cb2350a7d6c044 Mon Sep 17 00:00:00 2001 From: Sean King Date: Sat, 11 Jun 2022 20:40:53 -0600 Subject: [PATCH 049/369] Add warning for editing statuses --- src/components/post_status_form/post_status_form.js | 3 +++ src/components/post_status_form/post_status_form.vue | 8 ++++++++ src/i18n/en.json | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index d73219ad..ae81bfa6 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -261,6 +261,9 @@ const PostStatusForm = { uploadFileLimitReached () { return this.newStatus.files.length >= this.fileLimit }, + isEdit () { + return typeof this.statusId !== 'undefined' && this.statusId.trim() !== '' + }, ...mapGetters(['mergedConfig']), ...mapState({ mobileLayout: state => state.interface.mobileLayout diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 60cab745..650b5b8c 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -66,6 +66,14 @@ {{ $t('post_status.direct_warning_to_first_only') }} {{ $t('post_status.direct_warning_to_all') }}

+

+ {{ $t('post_status.edit_remote_warning') }} +
+ {{ $t('post_status.edit_unsupported_warning') }} +

Date: Sat, 11 Jun 2022 23:51:13 -0600 Subject: [PATCH 050/369] Clarification on unsupported edit features warning --- src/i18n/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/en.json b/src/i18n/en.json index a303c0e8..b7a1dcbf 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -217,7 +217,7 @@ "direct_warning_to_all": "This post will be visible to all the mentioned users.", "direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.", "edit_remote_warning": "Other remote instances may not support editing and unable to receive the latest version of your post.", - "edit_unsupported_warning": "Pleroma currently does not support editing mentions or polls.", + "edit_unsupported_warning": "Pleroma does not support removing mentions or editing polls.", "posting": "Posting", "post": "Post", "preview": "Preview", From 9c8738ff22a0563b16b19e57e8042c65c4a0b7e2 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Sun, 12 Jun 2022 13:38:12 +0200 Subject: [PATCH 051/369] EmojiPicker: Workaround to search immediately on mobile See https://github.com/vuejs/vue/pull/9814 --- src/components/emoji_picker/emoji_picker.js | 5 +++-- src/components/emoji_picker/emoji_picker.vue | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 6b589079..bd5c2e39 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -6,6 +6,7 @@ import { faStickyNote, faSmileBeam } from '@fortawesome/free-solid-svg-icons' +import { trim } from 'lodash' library.add( faBoxOpen, @@ -176,7 +177,7 @@ const EmojiPicker = { filteredEmoji () { return filterByKeyword( this.$store.state.instance.customEmoji || [], - this.keyword + trim(this.keyword) ) }, customEmojiBuffer () { @@ -197,7 +198,7 @@ const EmojiPicker = { id: 'standard', text: this.$t('emoji.unicode'), icon: 'box-open', - emojis: filterByKeyword(standardEmojis, this.keyword) + emojis: filterByKeyword(standardEmojis, trim(this.keyword)) } ] }, diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 3262a3d9..a7269120 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -47,6 +47,7 @@ type="text" class="form-control" :placeholder="$t('emoji.search_emoji')" + @input="$event.target.composing = false" >
Date: Sun, 12 Jun 2022 13:48:21 +0200 Subject: [PATCH 052/369] ReactButton: Workaround for android composition mode --- src/components/react_button/react_button.js | 3 ++- src/components/react_button/react_button.vue | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js index ce82c90d..e6f9dbff 100644 --- a/src/components/react_button/react_button.js +++ b/src/components/react_button/react_button.js @@ -1,6 +1,7 @@ import Popover from '../popover/popover.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faSmileBeam } from '@fortawesome/free-regular-svg-icons' +import { trim } from 'lodash' library.add(faSmileBeam) @@ -43,7 +44,7 @@ const ReactButton = { }, emojis () { if (this.filterWord !== '') { - const filterWordLowercase = this.filterWord.toLowerCase() + const filterWordLowercase = trim(this.filterWord.toLowerCase()) let orderedEmojiList = [] for (const emoji of this.$store.state.instance.emoji) { if (emoji.replacement === this.filterWord) return [emoji] diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue index 7f35b7b5..8a4b4d3b 100644 --- a/src/components/react_button/react_button.vue +++ b/src/components/react_button/react_button.vue @@ -12,6 +12,7 @@
From ce00954e7c0c6b4d5640c886f88065db749d49c7 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 12 Jun 2022 15:21:09 +0300 Subject: [PATCH 053/369] turns out it is needed still + some code cleanup --- src/components/popover/popover.js | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index 1e8b3fb6..a91c084f 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -58,10 +58,18 @@ const Popover = { const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el // SVGs don't have offsetWidth/Height, use fallback const anchorHeight = anchorEl.offsetHeight || anchorEl.clientHeight + const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth const anchorScreenBox = anchorEl.getBoundingClientRect() - // Screen position of the origin point for popover - const origin = { x: anchorScreenBox.left, y: anchorScreenBox.top } + const anchorStyle = getComputedStyle(anchorEl) + const topPadding = parseFloat(anchorStyle.paddingTop) + const bottomPadding = parseFloat(anchorStyle.paddingBottom) + + // Screen position of the origin point for popover = center of the anchor + const origin = { + x: anchorScreenBox.left + anchorWidth * 0.5, + y: anchorScreenBox.top + anchorHeight * 0.5 + } const content = this.$refs.content // Minor optimization, don't call a slow reflow call if we don't have to @@ -89,15 +97,17 @@ const Popover = { max: window.innerHeight - (margin.bottom || 5) } - let horizOffset = 0 + let horizOffset = content.offsetWidth * -0.5 + const leftBorder = origin.x + horizOffset + const rightBorder = origin.x - horizOffset // If overflowing from left, move it so that it doesn't - if ((origin.x) < xBounds.min) { - horizOffset += -origin.x + xBounds.min + if (leftBorder < xBounds.min) { + horizOffset += xBounds.min - leftBorder } // If overflowing from right, move it so that it doesn't - if ((origin.x + horizOffset + content.offsetWidth) > xBounds.max) { - horizOffset -= (origin.x + horizOffset + content.offsetWidth) - xBounds.max + if (rightBorder > xBounds.max) { + horizOffset -= rightBorder - xBounds.max } // Default to whatever user wished with placement prop @@ -106,23 +116,25 @@ const Popover = { // Handle special cases, first force to displaying on top if there's not space on bottom, // regardless of what placement value was. Then check if there's not space on top, and // force to bottom, again regardless of what placement value was. - if (origin.y + content.offsetHeight > yBounds.max) usingTop = true - if (origin.y - content.offsetHeight < yBounds.min) usingTop = false + const topBoundary = origin.y - anchorHeight * 0.5 + (this.removePadding ? topPadding : 0) + const bottomBoundary = origin.y + anchorHeight * 0.5 - (this.removePadding ? bottomPadding : 0) + if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true + if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false const yOffset = (this.offset && this.offset.y) || 0 const translateY = usingTop - ? yOffset - content.offsetHeight - : yOffset + anchorHeight + ? topBoundary - yOffset - content.offsetHeight + : bottomBoundary + yOffset const xOffset = (this.offset && this.offset.x) || 0 - const translateX = horizOffset + xOffset + const translateX = origin.x + horizOffset + xOffset // Note, separate translateX and translateY avoids blurry text on chromium, // single translate or translate3d resulted in blurry text. this.styles = { opacity: 1, - left: `${Math.round(origin.x + translateX)}px`, - top: `${Math.round(origin.y + translateY)}px`, + left: `${Math.round(translateX)}px`, + top: `${Math.round(translateY)}px`, position: 'fixed' } From 61d63b0e616392d841b78095ae8045e98d2b2fa6 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 12 Jun 2022 15:23:43 +0300 Subject: [PATCH 054/369] fix popovers so that all of them have shadows --- src/components/popover/popover.vue | 2 ++ src/components/status_popover/status_popover.vue | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue index 8f6ef2e6..6103fbdc 100644 --- a/src/components/popover/popover.vue +++ b/src/components/popover/popover.vue @@ -42,6 +42,8 @@ z-index: 500; position: absolute; min-width: 0; + box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); + box-shadow: var(--popupShadow); } .popover-default { diff --git a/src/components/status_popover/status_popover.vue b/src/components/status_popover/status_popover.vue index fdca8c9c..b6a3be32 100644 --- a/src/components/status_popover/status_popover.vue +++ b/src/components/status_popover/status_popover.vue @@ -52,8 +52,6 @@ border-width: 1px; border-radius: $fallback--tooltipRadius; border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); - box-shadow: var(--popupShadow); /* TODO cleanup this */ .Status.Status { From 55adcd822e194be8aaeb9d6b649de90e9d5e1e45 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 12 Jun 2022 16:31:56 +0300 Subject: [PATCH 055/369] fix animations, replace ugly old mentionlink tooltips with new usercard ones --- src/App.scss | 2 +- src/components/mention_link/mention_link.js | 8 +- src/components/mention_link/mention_link.scss | 7 +- src/components/mention_link/mention_link.vue | 133 ++++++++++-------- src/components/popover/popover.js | 40 ++++-- src/components/popover/popover.vue | 36 ++--- .../settings_modal/tabs/general_tab.vue | 2 +- src/i18n/en.json | 2 +- 8 files changed, 140 insertions(+), 90 deletions(-) diff --git a/src/App.scss b/src/App.scss index 5cd0b96e..79c07683 100644 --- a/src/App.scss +++ b/src/App.scss @@ -829,7 +829,7 @@ option { // Vue transitions .fade-enter-active, .fade-leave-active { - transition: opacity 0.2s; + transition: opacity 0.3s; } .fade-enter-from, diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js index 55eea195..4b088f88 100644 --- a/src/components/mention_link/mention_link.js +++ b/src/components/mention_link/mention_link.js @@ -2,6 +2,7 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p import { mapGetters, mapState } from 'vuex' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' import UserAvatar from '../user_avatar/user_avatar.vue' +import { defineAsyncComponent } from 'vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faAt @@ -14,7 +15,9 @@ library.add( const MentionLink = { name: 'MentionLink', components: { - UserAvatar + UserAvatar, + Popover: defineAsyncComponent(() => import('../popover/popover.vue')), + UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue')) }, props: { url: { @@ -36,6 +39,7 @@ const MentionLink = { }, methods: { onClick () { + if (this.shouldShowTooltip) return const link = generateProfileLink( this.userId || this.user.id, this.userScreenName || this.user.screen_name @@ -110,7 +114,7 @@ const MentionLink = { } }, shouldShowTooltip () { - return this.mergedConfig.mentionLinkShowTooltip && this.mergedConfig.mentionLinkDisplay === 'short' && this.isRemote + return this.mergedConfig.mentionLinkShowTooltip }, shouldShowAvatar () { return this.mergedConfig.mentionLinkShowAvatar diff --git a/src/components/mention_link/mention_link.scss b/src/components/mention_link/mention_link.scss index 1d856ff9..3b3a05b1 100644 --- a/src/components/mention_link/mention_link.scss +++ b/src/components/mention_link/mention_link.scss @@ -101,7 +101,6 @@ } &:hover .new .full { - opacity: 1; pointer-events: initial; } @@ -113,3 +112,9 @@ color: var(--faint, $fallback--faint); } } + +.mention-link-popover { + max-width: 70ch; + max-height: 20rem; + overflow: hidden; +} diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue index 022f04c7..686ad27f 100644 --- a/src/components/mention_link/mention_link.vue +++ b/src/components/mention_link/mention_link.vue @@ -9,66 +9,85 @@ class="original" target="_blank" v-html="content" - /> + - - - {{ !useAtIcon ? '@' : '' }} - + + + diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index a91c084f..3c3a95bd 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -31,13 +31,18 @@ const Popover = { // If true, subtract padding when calculating position for the popover, // use it when popover offset looks to be different on top vs bottom. - removePadding: Boolean + removePadding: Boolean, + + // self-explanatory (i hope) + disabled: Boolean }, data () { return { hidden: true, - styles: { opacity: 0 }, - oldSize: { width: 0, height: 0 } + styles: {}, + oldSize: { width: 0, height: 0 }, + // used to avoid blinking if hovered onto popover + graceTimeout: null } }, methods: { @@ -47,9 +52,7 @@ const Popover = { }, updateStyles () { if (this.hidden) { - this.styles = { - opacity: 0 - } + this.styles = {} return } @@ -132,7 +135,6 @@ const Popover = { // Note, separate translateX and translateY avoids blurry text on chromium, // single translate or translate3d resulted in blurry text. this.styles = { - opacity: 1, left: `${Math.round(translateX)}px`, top: `${Math.round(translateY)}px`, position: 'fixed' @@ -143,6 +145,7 @@ const Popover = { } }, showPopover () { + if (this.disabled) return const wasHidden = this.hidden this.hidden = false this.$nextTick(() => { @@ -153,13 +156,30 @@ const Popover = { hidePopover () { if (!this.hidden) this.$emit('close') this.hidden = true - this.styles = { opacity: 0 } }, onMouseenter (e) { - if (this.trigger === 'hover') this.showPopover() + if (this.trigger === 'hover') { + clearTimeout(this.graceTimeout) + this.graceTimeout = null + this.showPopover() + } }, onMouseleave (e) { - if (this.trigger === 'hover') this.hidePopover() + if (this.trigger === 'hover') { + this.graceTimeout = setTimeout(() => this.hidePopover(), 1) + } + }, + onMouseenterContent (e) { + if (this.trigger === 'hover') { + clearTimeout(this.graceTimeout) + this.graceTimeout = null + this.showPopover() + } + }, + onMouseleaveContent (e) { + if (this.trigger === 'hover') { + this.graceTimeout = setTimeout(() => this.hidePopover(), 1) + } }, onClick (e) { if (this.trigger === 'click') { diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue index 6103fbdc..528c4fb2 100644 --- a/src/components/popover/popover.vue +++ b/src/components/popover/popover.vue @@ -1,5 +1,5 @@ + + From 60571685c2e42e44b75157c3d52f162bf39c4bab Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 16 Jun 2022 17:06:16 +0300 Subject: [PATCH 067/369] popover controls for user-card --- src/components/user_card/user_card.js | 24 +++++++++--- src/components/user_card/user_card.scss | 39 +++++++++++++++----- src/components/user_card/user_card.vue | 37 ++++++++++++++++--- src/components/user_popover/user_popover.vue | 5 +-- 4 files changed, 81 insertions(+), 24 deletions(-) diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 4168c54a..52e8c079 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -14,7 +14,9 @@ import { faRss, faSearchPlus, faExternalLinkAlt, - faEdit + faEdit, + faTimes, + faExpandAlt } from '@fortawesome/free-solid-svg-icons' library.add( @@ -22,12 +24,21 @@ library.add( faBell, faSearchPlus, faExternalLinkAlt, - faEdit + faEdit, + faTimes, + faExpandAlt ) export default { props: [ - 'userId', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar' + 'userId', + 'switcher', + 'selected', + 'hideBio', + 'rounded', + 'bordered', + 'allowZoomingAvatar', + 'onClose' ], data () { return { @@ -47,9 +58,10 @@ export default { }, classes () { return [{ - 'user-card-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius - 'user-card-rounded': this.rounded === true, // set border-radius for all sides - 'user-card-bordered': this.bordered === true // set border for all sides + '-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius + '-rounded': this.rounded === true, // set border-radius for all sides + '-bordered': this.bordered === true, // set border for all sides + '-popover': !!this.onClose // set popover rounding }] }, style () { diff --git a/src/components/user_card/user_card.scss b/src/components/user_card/user_card.scss index 2e153120..65299e60 100644 --- a/src/components/user_card/user_card.scss +++ b/src/components/user_card/user_card.scss @@ -42,8 +42,10 @@ mask-composite: exclude; background-size: cover; mask-size: 100% 60%; - border-top-left-radius: calc(var(--panelRadius) - 1px); - border-top-right-radius: calc(var(--panelRadius) - 1px); + border-top-left-radius: calc(var(--__roundnessTop, --panelRadius) - 1px); + border-top-right-radius: calc(var(--__roundnessTop, --panelRadius) - 1px); + border-bottom-left-radius: calc(var(--__roundnessBottom, --panelRadius) - 1px); + border-bottom-right-radius: calc(var(--__roundnessBottom, --panelRadius) - 1px); background-color: var(--profileBg); z-index: -2; @@ -72,21 +74,33 @@ } } - // Modifiers - - &-rounded-t { + &.-rounded-t { border-top-left-radius: $fallback--panelRadius; border-top-left-radius: var(--panelRadius, $fallback--panelRadius); border-top-right-radius: $fallback--panelRadius; border-top-right-radius: var(--panelRadius, $fallback--panelRadius); + + --__roundnessTop: var(--panelRadius); + --__roundnessBottom: 0; } - &-rounded { + &.-rounded { border-radius: $fallback--panelRadius; border-radius: var(--panelRadius, $fallback--panelRadius); + + --__roundnessTop: var(--panelRadius); + --__roundnessBottom: var(--panelRadius); } - &-bordered { + &.-popover { + border-radius: $fallback--tooltipRadius; + border-radius: var(--tooltipRadius, $fallback--tooltipRadius); + + --__roundnessTop: var(--tooltipRadius); + --__roundnessBottom: var(--tooltipRadius); + } + + &.-bordered { border-width: 1px; border-style: solid; border-color: $fallback--border; @@ -99,6 +113,15 @@ color: var(--lightText, $fallback--lightText); padding: 0 26px; + a { + color: $fallback--lightText; + color: var(--lightText, $fallback--lightText); + + &:hover { + color: var(--icon); + } + } + .container { min-width: 0; padding: 16px 0 6px; @@ -206,8 +229,6 @@ flex: 0 1 auto; text-overflow: ellipsis; overflow: hidden; - color: $fallback--lightText; - color: var(--lightText, $fallback--lightText); } .dailyAvg { diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 67837845..936d6798 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -8,7 +8,7 @@ :style="style" class="background-image" /> -