-
-
Notifications
You must be signed in to change notification settings - Fork 620
feat: view Collections on profiles, notifications, and a new Collections page #3685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
eaa6f4f
feat: support collections feature
shuuji3 9120fca
chore: refine collection notification styles
shuuji3 7fefb2e
Merge branch 'main' into shuuji3/feat/collection-api
shuuji3 1b9a35a
chore: apply code review suggestions
shuuji3 9322b4e
chore: show collections not supported message
shuuji3 273d658
fix: remove owner filter to include owner in `memberAccounts`
shuuji3 c6d41d4
fix: fix wrong condition
shuuji3 785461b
Merge branch 'main' into shuuji3/feat/collection-api
shuuji3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| activeClass: string | ||
| }>() | ||
| </script> | ||
|
|
||
| <template> | ||
| <NuxtLink | ||
| to="/collections" | ||
| :aria-label="$t('nav.collections')" | ||
| :active-class="activeClass" | ||
| flex flex-row items-center place-content-center h-full flex-1 | ||
| class="coarse-pointer:select-none" @click="$scrollToTop" | ||
| > | ||
| <div i-ri:shapes-line /> | ||
| </NuxtLink> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| <script setup lang="ts"> | ||
| import type { mastodon } from 'masto' | ||
|
|
||
| definePageMeta({ | ||
| name: 'account-collections', | ||
| }) | ||
|
|
||
| const { t } = useI18n() | ||
| const params = useRoute().params | ||
| const handle = computed(() => params.account as string) | ||
|
|
||
| const account = await fetchAccountByHandle(handle.value) | ||
|
|
||
| const client = useMastoClient() | ||
|
|
||
| let collectionData: mastodon.v1.Collections | null = null | ||
| if (account) { | ||
| try { | ||
| collectionData = await client.v1.accounts.$select(account.id).collections.list() | ||
| } | ||
| catch { | ||
| // server may not support collections | ||
| } | ||
| } | ||
|
|
||
| const collections = computed(() => collectionData?.collections ?? []) | ||
|
|
||
| if (account) { | ||
| useHydratedHead({ | ||
| title: () => `${t('nav.collections')} | ${getDisplayName(account)} (@${account.acct})`, | ||
| }) | ||
| } | ||
| </script> | ||
|
|
||
| <template> | ||
| <div> | ||
| <AccountTabs /> | ||
| <div v-if="collections.length > 0" divide-y="base"> | ||
| <NuxtLink | ||
| v-for="collection in collections" | ||
| :key="collection.id" | ||
| :to="{ | ||
| name: 'collection', | ||
| params: { server: params.server, id: collection.id }, | ||
| }" | ||
| block p-4 hover:bg-active transition-100 | ||
| > | ||
| <div flex items-center gap-3> | ||
| <div i-ri:shapes-line text-xl shrink-0 text-secondary /> | ||
| <div flex="~ col" min-w-0> | ||
| <div font-bold truncate> | ||
| {{ collection.name }} | ||
| </div> | ||
| <div v-if="collection.description" text-sm text-secondary truncate> | ||
| {{ collection.description }} | ||
| </div> | ||
| <div text-sm text-secondary> | ||
| <CommonLocalizedNumber keypath="collection.item_count" :count="collection.itemCount" /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </NuxtLink> | ||
| </div> | ||
| <div v-else p-4 text-secondary text-sm text-center> | ||
| {{ $t('collection.no_collections') }} | ||
| </div> | ||
| </div> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <script setup lang="ts"> | ||
| const route = useRoute() | ||
| const { t } = useI18n() | ||
|
|
||
| useHydratedHead({ | ||
| title: () => t('nav.collections'), | ||
| }) | ||
| </script> | ||
|
|
||
| <template> | ||
| <template v-if="route.name !== 'collection'"> | ||
| <MainContent> | ||
| <template #title> | ||
| <MainTitle icon="i-ri:shapes-line"> | ||
| {{ t('nav.collections') }} | ||
| </MainTitle> | ||
| </template> | ||
| <NuxtPage v-if="isHydrated" :key="route.fullPath" /> | ||
| </MainContent> | ||
| </template> | ||
| <template v-else> | ||
| <NuxtPage v-if="isHydrated" :key="route.fullPath" /> | ||
| </template> | ||
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| <script setup lang="ts"> | ||
| import type { mastodon } from 'masto' | ||
|
|
||
| definePageMeta({ | ||
| name: 'collection', | ||
| }) | ||
|
|
||
| const { t } = useI18n() | ||
| const params = useRoute().params | ||
| const collectionId = computed(() => params.id as string) | ||
|
|
||
| const client = useMastoClient() | ||
|
|
||
| const { data: collectionData } = await useAsyncData<mastodon.v1.CollectionWithAccounts | null>( | ||
| () => `collection-${collectionId.value}`, | ||
| () => client.v1.collections.$select(collectionId.value).fetch().catch(() => null), | ||
| { immediate: import.meta.client, default: () => shallowRef() }, | ||
| ) | ||
|
|
||
| const accounts = computed(() => collectionData.value?.accounts ?? []) | ||
| const collection = computed(() => collectionData.value?.collection) | ||
| const ownerAccount = computed(() => accounts.value.find(a => a.id === collection.value?.accountId)) | ||
|
|
||
| const memberAccounts = computed(() => | ||
| accounts.value.filter(a => a.id !== (ownerAccount.value?.id ?? ''), | ||
| )) | ||
|
|
||
| useHydratedHead({ | ||
| title: t('nav.collections'), | ||
| }) | ||
| </script> | ||
|
|
||
| <template> | ||
| <MainContent back> | ||
| <template #title> | ||
| <MainTitle> | ||
| {{ t('nav.collections') }} | ||
| </MainTitle> | ||
| </template> | ||
|
|
||
| <template v-if="!collectionData"> | ||
| <CommonNotFound> | ||
| {{ $t('error.collection_not_found') }} | ||
| </CommonNotFound> | ||
| </template> | ||
| <template v-else-if="collection"> | ||
| <div p-4 border="b base" space-y-3> | ||
| <div flex items-center gap-2 text-start text-lg font-bold> | ||
| {{ collection.name }} | ||
| </div> | ||
|
|
||
| <div v-if="ownerAccount" flex items-center gap-2 text-sm text-secondary> | ||
| <span mr5>{{ $t('collection.created_by') }}</span> | ||
| <AccountInlineInfo :account="ownerAccount" class="pl1" /> | ||
| </div> | ||
|
|
||
| <div flex text-sm text-secondary gap-4> | ||
| <span>{{ $t('collection.item_count', [collection.itemCount]) }}</span> | ||
|
shuuji3 marked this conversation as resolved.
|
||
| </div> | ||
|
|
||
| <div v-if="collection.description" text-secondary> | ||
| {{ collection.description }} | ||
| </div> | ||
|
|
||
| <div v-if="collection.tag" flex items-center gap-2> | ||
| <NuxtLink :to="getTagRoute(collection.tag.name)" text-primary text-sm font-bold hover:underline> | ||
| #{{ collection.tag.name }} | ||
| </NuxtLink> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div v-if="memberAccounts.length > 0" divide-y="base"> | ||
| <div | ||
| v-for="account in memberAccounts" | ||
| :key="account.id" | ||
| py3 px4 space-y-2 | ||
| > | ||
| <div flex justify-between items-center> | ||
| <AccountInfo | ||
| :account="account" | ||
| hover-card | ||
| as="router-link" | ||
| shrink overflow-hidden | ||
| :to="getAccountRoute(account)" | ||
| /> | ||
| <AccountFollowButton :account="account" /> | ||
| </div> | ||
| <div v-if="account.note" text-sm text-secondary> | ||
| <ContentRich | ||
| :content="account.note" :emojis="account.emojis" | ||
| /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <div v-else p-4 text-secondary text-sm text-center> | ||
| {{ $t('collection.empty') }} | ||
| </div> | ||
| </template> | ||
| </MainContent> | ||
| </template> | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can reduce the big block here by collapsing to one
v-else-iflike so: