logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 3e99006e2ab06d2c8ade2eb20e12b1d2fbbcaac2
parent e232ba0ec5542020f83ea685b8fb491b23def627
Author: HJ <30-hj@users.noreply.git.pleroma.social>
Date:   Wed, 22 May 2024 12:15:57 +0000

Merge branch 'quotes-count' into 'develop'

Display quotes count on posts and add quotes list page

See merge request pleroma/pleroma-fe!1885

Diffstat:

Achangelog.d/quotes-count.add2++
Msrc/boot/routes.js2++
Asrc/components/quotes_timeline/quotes_timeline.js26++++++++++++++++++++++++++
Asrc/components/quotes_timeline/quotes_timeline.vue10++++++++++
Msrc/components/status/status.js3+++
Msrc/components/status/status.scss1+
Msrc/components/status/status.vue15++++++++++++++-
Msrc/components/timeline/timeline.js3+++
Msrc/components/timeline_menu/timeline_menu.js3++-
Msrc/i18n/en.json4+++-
Msrc/modules/api.js5+++--
Msrc/services/api/api.service.js9++++++++-
Msrc/services/backend_interactor_service/backend_interactor_service.js4++--
Msrc/services/entity_normalizer/entity_normalizer.service.js1+
Msrc/services/timeline_fetcher/timeline_fetcher.service.js8+++++---
15 files changed, 85 insertions(+), 11 deletions(-)

diff --git a/changelog.d/quotes-count.add b/changelog.d/quotes-count.add @@ -0,0 +1 @@ +Display quotes count on posts and add quotes list page +\ No newline at end of file diff --git a/src/boot/routes.js b/src/boot/routes.js @@ -25,6 +25,7 @@ import ListsTimeline from 'components/lists_timeline/lists_timeline.vue' import ListsEdit from 'components/lists_edit/lists_edit.vue' import NavPanel from 'src/components/nav_panel/nav_panel.vue' import AnnouncementsPage from 'components/announcements_page/announcements_page.vue' +import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue' export default (store) => { const validateAuthenticatedRoute = (to, from, next) => { @@ -51,6 +52,7 @@ export default (store) => { { name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline }, { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline }, { name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } }, + { name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline }, { name: 'remote-user-profile-acct', path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)', diff --git a/src/components/quotes_timeline/quotes_timeline.js b/src/components/quotes_timeline/quotes_timeline.js @@ -0,0 +1,26 @@ +import Timeline from '../timeline/timeline.vue' + +const QuotesTimeline = { + created () { + this.$store.commit('clearTimeline', { timeline: 'quotes' }) + this.$store.dispatch('startFetchingTimeline', { timeline: 'quotes', statusId: this.statusId }) + }, + components: { + Timeline + }, + computed: { + statusId () { return this.$route.params.id }, + timeline () { return this.$store.state.statuses.timelines.quotes } + }, + watch: { + statusId () { + this.$store.commit('clearTimeline', { timeline: 'quotes' }) + this.$store.dispatch('startFetchingTimeline', { timeline: 'quotes', statusId: this.statusId }) + } + }, + unmounted () { + this.$store.dispatch('stopFetchingTimeline', 'quotes') + } +} + +export default QuotesTimeline diff --git a/src/components/quotes_timeline/quotes_timeline.vue b/src/components/quotes_timeline/quotes_timeline.vue @@ -0,0 +1,10 @@ +<template> + <Timeline + :title="$t('nav.quotes')" + :timeline="timeline" + :timeline-name="'quotes'" + :status-id="statusId" + /> +</template> + +<script src='./quotes_timeline.js'></script> diff --git a/src/components/status/status.js b/src/components/status/status.js @@ -373,6 +373,9 @@ const Status = { hidePostStats () { return this.mergedConfig.hidePostStats }, + shouldDisplayFavsAndRepeats () { + return !this.hidePostStats && this.isFocused && (this.combinedFavsAndRepeatsUsers.length > 0 || this.statusFromGlobalRepository.quotes_count) + }, muteBotStatuses () { return this.mergedConfig.muteBotStatuses }, diff --git a/src/components/status/status.scss b/src/components/status/status.scss @@ -374,6 +374,7 @@ font-weight: bolder; font-size: 1.1em; line-height: 1em; + color: var(--text); } &:hover .stat-title { diff --git a/src/components/status/status.vue b/src/components/status/status.vue @@ -484,7 +484,7 @@ <transition name="fade"> <div - v-if="!hidePostStats && isFocused && combinedFavsAndRepeatsUsers.length > 0" + v-if="shouldDisplayFavsAndRepeats" class="favs-repeated-users" > <div class="stats"> @@ -512,6 +512,19 @@ </div> </div> </UserListPopover> + <router-link + v-if="statusFromGlobalRepository.quotes_count > 0" + :to="{ name: 'quotes', params: { id: status.id } }" + > + <div + class="stat-count" + > + <a class="stat-title">{{ $t('status.quotes') }}</a> + <div class="stat-number"> + {{ statusFromGlobalRepository.quotes_count }} + </div> + </div> + </router-link> <div class="avatar-row"> <AvatarList :users="combinedFavsAndRepeatsUsers" /> </div> diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js @@ -25,6 +25,7 @@ const Timeline = { 'title', 'userId', 'listId', + 'statusId', 'tag', 'embedded', 'count', @@ -121,6 +122,7 @@ const Timeline = { showImmediately, userId: this.userId, listId: this.listId, + statusId: this.statusId, tag: this.tag }) }, @@ -183,6 +185,7 @@ const Timeline = { showImmediately: true, userId: this.userId, listId: this.listId, + statusId: this.statusId, tag: this.tag }).then(({ statuses }) => { if (statuses && statuses.length === 0) { diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js @@ -19,7 +19,8 @@ export const timelineNames = () => { bookmarks: 'nav.bookmarks', dms: 'nav.dms', 'public-timeline': 'nav.public_tl', - 'public-external-timeline': 'nav.twkn' + 'public-external-timeline': 'nav.twkn', + quotes: 'nav.quotes' } } diff --git a/src/i18n/en.json b/src/i18n/en.json @@ -189,7 +189,8 @@ "mobile_notifications": "Open notifications (there are unread ones)", "mobile_notifications_close": "Close notifications", "mobile_notifications_mark_as_seen": "Mark all as seen", - "announcements": "Announcements" + "announcements": "Announcements", + "quotes": "Quotes" }, "notifications": { "broken_favorite": "Unknown status, searching for it…", @@ -1048,6 +1049,7 @@ "status": { "favorites": "Favorites", "repeats": "Repeats", + "quotes": "Quotes", "repeat_confirm": "Do you really want to repeat this status?", "repeat_confirm_title": "Repeat confirmation", "repeat_confirm_accept_button": "Repeat", diff --git a/src/modules/api.js b/src/modules/api.js @@ -202,12 +202,13 @@ const api = { timeline = 'friends', tag = false, userId = false, - listId = false + listId = false, + statusId = false }) { if (store.state.fetchers[timeline]) return const fetcher = store.state.backendInteractor.startFetchingTimeline({ - timeline, store, userId, listId, tag + timeline, store, userId, listId, statusId, tag }) store.commit('addFetcher', { fetcherName: timeline, fetcher }) }, diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js @@ -108,6 +108,7 @@ const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_SCROBBLES_URL = id => `/api/v1/pleroma/accounts/${id}/scrobbles` +const PLEROMA_STATUS_QUOTES_URL = id => `/api/v1/pleroma/statuses/${id}/quotes` const PLEROMA_USER_FAVORITES_TIMELINE_URL = id => `/api/v1/pleroma/accounts/${id}/favourites` const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config' @@ -685,6 +686,7 @@ const fetchTimeline = ({ until = false, userId = false, listId = false, + statusId = false, tag = false, withMuted = false, replyVisibility = 'all', @@ -702,7 +704,8 @@ const fetchTimeline = ({ favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL, tag: MASTODON_TAG_TIMELINE_URL, - bookmarks: MASTODON_BOOKMARK_TIMELINE_URL + bookmarks: MASTODON_BOOKMARK_TIMELINE_URL, + quotes: PLEROMA_STATUS_QUOTES_URL } const isNotifications = timeline === 'notifications' const params = [] @@ -721,6 +724,10 @@ const fetchTimeline = ({ url = url(listId) } + if (timeline === 'quotes') { + url = url(statusId) + } + if (minId) { params.push(['min_id', minId]) } diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js @@ -5,8 +5,8 @@ import followRequestFetcher from '../../services/follow_request_fetcher/follow_r import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js' const backendInteractorService = credentials => ({ - startFetchingTimeline ({ timeline, store, userId = false, listId = false, tag }) { - return timelineFetcher.startFetching({ timeline, store, credentials, userId, listId, tag }) + startFetchingTimeline ({ timeline, store, userId = false, listId = false, statusId = false, tag }) { + return timelineFetcher.startFetching({ timeline, store, credentials, userId, listId, statusId, tag }) }, fetchTimeline (args) { diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js @@ -331,6 +331,7 @@ export const parseStatus = (data) => { output.quote_id = pleroma.quote_id ? pleroma.quote_id : (output.quote ? output.quote.id : undefined) output.quote_url = pleroma.quote_url output.quote_visible = pleroma.quote_visible + output.quotes_count = pleroma.quotes_count } else { output.text = data.content output.summary = data.spoiler_text diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -24,6 +24,7 @@ const fetchAndUpdate = ({ showImmediately = false, userId = false, listId = false, + statusId = false, tag = false, until, since @@ -47,6 +48,7 @@ const fetchAndUpdate = ({ args.userId = userId args.listId = listId + args.statusId = statusId args.tag = tag args.withMuted = !hideMutedPosts if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) { @@ -78,15 +80,15 @@ const fetchAndUpdate = ({ }) } -const startFetching = ({ timeline = 'friends', credentials, store, userId = false, listId = false, tag = false }) => { +const startFetching = ({ timeline = 'friends', credentials, store, userId = false, listId = false, statusId = false, tag = false }) => { const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] const showImmediately = timelineData.visibleStatuses.length === 0 timelineData.userId = userId timelineData.listId = listId - fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, listId, tag }) + fetchAndUpdate({ timeline, credentials, store, showImmediately, userId, listId, statusId, tag }) const boundFetchAndUpdate = () => - fetchAndUpdate({ timeline, credentials, store, userId, listId, tag }) + fetchAndUpdate({ timeline, credentials, store, userId, listId, statusId, tag }) return promiseInterval(boundFetchAndUpdate, 10000) } const timelineFetcher = {