diff options
| author | Marie <github@yuugi.dev> | 2025-02-07 03:50:12 +0000 |
|---|---|---|
| committer | Marie <github@yuugi.dev> | 2025-02-07 03:50:12 +0000 |
| commit | d6c4b728dfab23deffd7c071d46fd93b08570748 (patch) | |
| tree | 8f19ffeb3007ab5b626911044063331a1637c370 | |
| parent | merge: Allow users to set a default content warning for their new posts (reso... (diff) | |
| parent | show a "follow back" button on "user followed you" and "received follow reque... (diff) | |
| download | sharkey-d6c4b728dfab23deffd7c071d46fd93b08570748.tar.gz sharkey-d6c4b728dfab23deffd7c071d46fd93b08570748.tar.bz2 sharkey-d6c4b728dfab23deffd7c071d46fd93b08570748.zip | |
merge: Add "follow back" button on follow-related notifications (resolves #895) (!873)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/873
Closes #895
Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
| -rw-r--r-- | packages/backend/src/server/api/endpoints/users/show.ts | 6 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkNotification.vue | 43 |
2 files changed, 43 insertions, 6 deletions
diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts index 7ebca78a7d..118362149d 100644 --- a/packages/backend/src/server/api/endpoints/users/show.ts +++ b/packages/backend/src/server/api/endpoints/users/show.ts @@ -57,10 +57,10 @@ export const meta = { }, }, - // 5 calls per 2 seconds + // up to 50 calls @ 4 per second limit: { - duration: 1000 * 2, - max: 5, + max: 50, + dripRate: 250, }, } as const; diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue index 4620b966af..f979287bdd 100644 --- a/packages/frontend/src/components/MkNotification.vue +++ b/packages/frontend/src/components/MkNotification.vue @@ -122,6 +122,9 @@ SPDX-License-Identifier: AGPL-3.0-only </div> <template v-else-if="notification.type === 'follow'"> <span :class="$style.text" style="opacity: 0.6;">{{ i18n.ts.youGotNewFollower }}</span> + <div v-if="full" :class="$style.followRequestCommands"> + <MkFollowButton v-if="userDetailed" :class="$style.followCommandButton" :user="userDetailed" :transparent="false" :full="false"/> + </div> </template> <template v-else-if="notification.type === 'followRequestAccepted'"> <div :class="$style.text" style="opacity: 0.6;">{{ i18n.ts.followRequestAccepted }}</div> @@ -136,6 +139,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div v-if="full && !followRequestDone" :class="$style.followRequestCommands"> <MkButton :class="$style.followRequestCommandButton" rounded primary @click="acceptFollowRequest()"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton> <MkButton :class="$style.followRequestCommandButton" rounded danger @click="rejectFollowRequest()"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> + <MkFollowButton v-if="userDetailed" :class="$style.followCommandButton" :user="userDetailed" :transparent="false" :full="false"/> </div> </template> <span v-else-if="notification.type === 'test'" :class="$style.text">{{ i18n.ts._notification.notificationWillBeDisplayedLikeThis }}</span> @@ -179,8 +183,9 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { ref } from 'vue'; +import { Ref, ref, watch } from 'vue'; import * as Misskey from 'misskey-js'; +import { UserDetailed } from 'misskey-js/autogen/models.js'; import MkReactionIcon from '@/components/MkReactionIcon.vue'; import MkButton from '@/components/MkButton.vue'; import { getNoteSummary } from '@/scripts/get-note-summary.js'; @@ -190,6 +195,7 @@ import { i18n } from '@/i18n.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; import { signinRequired } from '@/account.js'; import { infoImageUrl } from '@/instance.js'; +import MkFollowButton from '@/components/MkFollowButton.vue'; const $i = signinRequired(); @@ -202,6 +208,26 @@ const props = withDefaults(defineProps<{ full: false, }); +const userDetailed: Ref<UserDetailed | null> = ref(null); + +// watch() is required because computed() doesn't support async. +watch(props, async () => { + const type = props.notification.type; + + // To avoid extra lookups, only do the query when it actually matters. + if (type === 'follow' || type === 'receiveFollowRequest') { + const user = await misskeyApi('users/show', { + userId: props.notification.userId, + }); + + userDetailed.value = user; + followRequestDone.value = !user.hasPendingFollowRequestToYou; + } else { + userDetailed.value = null; + followRequestDone.value = false; + } +}, { immediate: true }); + type ExportCompletedNotification = Misskey.entities.Notification & { type: 'exportCompleted' }; const exportEntityName = { @@ -216,7 +242,7 @@ const exportEntityName = { userList: i18n.ts.lists, } as const satisfies Record<ExportCompletedNotification['exportedEntity'], string>; -const followRequestDone = ref(false); +const followRequestDone = ref(true); const acceptFollowRequest = () => { if (!('user' in props.notification)) return; @@ -434,13 +460,24 @@ function getActualReactedUsersCount(notification: Misskey.entities.Notification) .followRequestCommands { display: flex; gap: 8px; - max-width: 300px; margin-top: 8px; + width: 100%; } .followRequestCommandButton { + max-width: 175px; + width: 100%; +} + +.flexSpacer { flex: 1; } +.followCommandButton { + margin-left: auto; + flex-grow: 0; + flex-shrink: 0; +} + .reactionsItem { display: inline-block; position: relative; |