diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2024-11-15 17:30:54 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-15 17:30:54 +0900 |
| commit | c0d168260482caa974e3fc9e084b121fc32e8ec4 (patch) | |
| tree | addcc1432d1ba3097667ca3ba86d33cd87793615 /packages/frontend/src | |
| parent | update deps (#14950) (diff) | |
| download | misskey-c0d168260482caa974e3fc9e084b121fc32e8ec4.tar.gz misskey-c0d168260482caa974e3fc9e084b121fc32e8ec4.tar.bz2 misskey-c0d168260482caa974e3fc9e084b121fc32e8ec4.zip | |
feat: 送信したフォローリクエストを確認できるように (#14856)
* FEAT: Allow users to view pending follow requests they sent
This commit implements the `following/requests/sent` interface firstly
implemented on Firefish, and provides a UI interface to view the pending
follow requests users sent.
* ux: should not show follow requests tab when have no pending sent follow req
* fix default followreq tab
* fix default followreq tab
* restore missing hasPendingReceivedFollowRequest in navbar
* refactor
* use tabler icons
* tweak design
* Revert "ux: should not show follow requests tab when have no pending sent follow req"
This reverts commit e580b92c37f27c2849c6d27e22ca4c47086081bb.
* Update Changelog
* Update Changelog
* change tab titles
---------
Co-authored-by: Lhc_fl <lhcfl@outlook.com>
Co-authored-by: Hazelnoot <acomputerdog@gmail.com>
Diffstat (limited to 'packages/frontend/src')
| -rw-r--r-- | packages/frontend/src/components/MkFollowButton.vue | 10 | ||||
| -rw-r--r-- | packages/frontend/src/navbar.ts | 1 | ||||
| -rw-r--r-- | packages/frontend/src/pages/follow-requests.vue | 105 |
3 files changed, 78 insertions, 38 deletions
diff --git a/packages/frontend/src/components/MkFollowButton.vue b/packages/frontend/src/components/MkFollowButton.vue index cc07175907..c1dc67f776 100644 --- a/packages/frontend/src/components/MkFollowButton.vue +++ b/packages/frontend/src/components/MkFollowButton.vue @@ -91,7 +91,10 @@ async function onClick() { text: i18n.tsx.unfollowConfirm({ name: props.user.name || props.user.username }), }); - if (canceled) return; + if (canceled) { + wait.value = false; + return; + } await misskeyApi('following/delete', { userId: props.user.id, @@ -125,7 +128,10 @@ async function onClick() { }); hasPendingFollowRequestFromYou.value = true; - if ($i == null) return; + if ($i == null) { + wait.value = false; + return; + } claimAchievement('following1'); diff --git a/packages/frontend/src/navbar.ts b/packages/frontend/src/navbar.ts index ac730f8021..096d404a57 100644 --- a/packages/frontend/src/navbar.ts +++ b/packages/frontend/src/navbar.ts @@ -40,7 +40,6 @@ export const navbarItemDef = reactive({ followRequests: { title: i18n.ts.followRequests, icon: 'ti ti-user-plus', - show: computed(() => $i != null && $i.isLocked), indicated: computed(() => $i != null && $i.hasPendingReceivedFollowRequest), to: '/my/follow-requests', }, diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue index a840d0d0b3..8688863c2c 100644 --- a/packages/frontend/src/pages/follow-requests.vue +++ b/packages/frontend/src/pages/follow-requests.vue @@ -5,69 +5,104 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <MkStickyContainer> - <template #header><MkPageHeader/></template> + <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> <MkSpacer :contentMax="800"> - <MkPagination ref="paginationComponent" :pagination="pagination"> - <template #empty> - <div class="_fullinfo"> - <img :src="infoImageUrl" class="_ghost"/> - <div>{{ i18n.ts.noFollowRequests }}</div> - </div> - </template> - <template #default="{items}"> - <div class="mk-follow-requests"> - <div v-for="req in items" :key="req.id" class="user _panel"> - <MkAvatar class="avatar" :user="req.follower" indicator link preview/> - <div class="body"> - <div class="name"> - <MkA v-user-preview="req.follower.id" class="name" :to="userPage(req.follower)"><MkUserName :user="req.follower"/></MkA> - <p class="acct">@{{ acct(req.follower) }}</p> - </div> - <div class="commands"> - <MkButton class="command" rounded primary @click="accept(req.follower)"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton> - <MkButton class="command" rounded danger @click="reject(req.follower)"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> + <MkHorizontalSwipe v-model:tab="tab" :tabs="headerTabs"> + <div :key="tab" class="_gaps"> + <MkPagination ref="paginationComponent" :pagination="pagination"> + <template #empty> + <div class="_fullinfo"> + <img :src="infoImageUrl" class="_ghost"/> + <div>{{ i18n.ts.noFollowRequests }}</div> + </div> + </template> + <template #default="{items}"> + <div class="mk-follow-requests"> + <div v-for="req in items" :key="req.id" class="user _panel"> + <MkAvatar class="avatar" :user="displayUser(req)" indicator link preview/> + <div class="body"> + <div class="name"> + <MkA v-user-preview="displayUser(req).id" class="name" :to="userPage(displayUser(req))"><MkUserName :user="displayUser(req)"/></MkA> + <p class="acct">@{{ acct(displayUser(req)) }}</p> + </div> + <div v-if="tab === 'list'" class="commands"> + <MkButton class="command" rounded primary @click="accept(displayUser(req))"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton> + <MkButton class="command" rounded danger @click="reject(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> + </div> + <div v-else class="commands"> + <MkButton class="command" rounded danger @click="cancel(displayUser(req))"><i class="ti ti-x"/> {{ i18n.ts.cancel }}</MkButton> + </div> + </div> </div> </div> - </div> - </div> - </template> - </MkPagination> + </template> + </MkPagination> + </div> + </MkHorizontalSwipe> </MkSpacer> </MkStickyContainer> </template> <script lang="ts" setup> -import { shallowRef, computed } from 'vue'; -import MkPagination from '@/components/MkPagination.vue'; +import * as Misskey from 'misskey-js'; +import { shallowRef, computed, ref } from 'vue'; +import MkPagination, { type Paging } from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; import { userPage, acct } from '@/filters/user.js'; -import { misskeyApi } from '@/scripts/misskey-api.js'; +import * as os from '@/os.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { infoImageUrl } from '@/instance.js'; +import { $i } from '@/account.js'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; const paginationComponent = shallowRef<InstanceType<typeof MkPagination>>(); -const pagination = { - endpoint: 'following/requests/list' as const, +const pagination = computed<Paging>(() => tab.value === 'list' ? { + endpoint: 'following/requests/list', + limit: 10, +} : { + endpoint: 'following/requests/sent', limit: 10, -}; +}); + +function accept(user: Misskey.entities.UserLite) { + os.apiWithDialog('following/requests/accept', { userId: user.id }).then(() => { + paginationComponent.value?.reload(); + }); +} -function accept(user) { - misskeyApi('following/requests/accept', { userId: user.id }).then(() => { +function reject(user: Misskey.entities.UserLite) { + os.apiWithDialog('following/requests/reject', { userId: user.id }).then(() => { paginationComponent.value?.reload(); }); } -function reject(user) { - misskeyApi('following/requests/reject', { userId: user.id }).then(() => { +function cancel(user: Misskey.entities.UserLite) { + os.apiWithDialog('following/requests/cancel', { userId: user.id }).then(() => { paginationComponent.value?.reload(); }); } +function displayUser(req) { + return tab.value === 'list' ? req.follower : req.followee; +} + const headerActions = computed(() => []); -const headerTabs = computed(() => []); +const headerTabs = computed(() => [ + { + key: 'list', + title: i18n.ts._followRequest.recieved, + icon: 'ti ti-mail', + }, { + key: 'sent', + title: i18n.ts._followRequest.sent, + icon: 'ti ti-send', + }, +]); + +const tab = ref($i?.isLocked ? 'list' : 'sent'); definePageMetadata(() => ({ title: i18n.ts.followRequests, |