diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-04-12 11:40:08 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-04-12 11:40:08 +0900 |
| commit | 5d56799070006923701dcdaaa61d69c00e034209 (patch) | |
| tree | 945500d9ab955197da70ee5d9e8c478ddb9767e1 /packages/frontend/src | |
| parent | enhance: カスタム絵文字関連の変更 (#9794) (diff) | |
| download | misskey-5d56799070006923701dcdaaa61d69c00e034209.tar.gz misskey-5d56799070006923701dcdaaa61d69c00e034209.tar.bz2 misskey-5d56799070006923701dcdaaa61d69c00e034209.zip | |
feat: role timeline
Resolve #10581
Diffstat (limited to 'packages/frontend/src')
| -rw-r--r-- | packages/frontend/src/components/MkTimeline.vue | 10 | ||||
| -rw-r--r-- | packages/frontend/src/pages/explore.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/pages/role.vue | 27 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck.vue | 1 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/column-core.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/deck-store.ts | 1 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/role-timeline-column.vue | 67 |
7 files changed, 105 insertions, 5 deletions
diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue index 6741e7a18b..fb0a3a4b67 100644 --- a/packages/frontend/src/components/MkTimeline.vue +++ b/packages/frontend/src/components/MkTimeline.vue @@ -15,6 +15,7 @@ const props = defineProps<{ list?: string; antenna?: string; channel?: string; + role?: string; sound?: boolean; }>(); @@ -121,6 +122,15 @@ if (props.src === 'antenna') { channelId: props.channel, }); connection.on('note', prepend); +} else if (props.src === 'role') { + endpoint = 'roles/notes'; + query = { + roleId: props.role, + }; + connection = stream.useChannel('roleTimeline', { + roleId: props.role, + }); + connection.on('note', prepend); } const pagination = { diff --git a/packages/frontend/src/pages/explore.vue b/packages/frontend/src/pages/explore.vue index 2131188dde..5f3728b677 100644 --- a/packages/frontend/src/pages/explore.vue +++ b/packages/frontend/src/pages/explore.vue @@ -1,7 +1,7 @@ <template> <MkStickyContainer> <template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> - <div class="lznhrdub"> + <div> <div v-if="tab === 'featured'"> <XFeatured/> </div> diff --git a/packages/frontend/src/pages/role.vue b/packages/frontend/src/pages/role.vue index 2e9d3d6169..f2645394a2 100644 --- a/packages/frontend/src/pages/role.vue +++ b/packages/frontend/src/pages/role.vue @@ -1,13 +1,16 @@ <template> <MkStickyContainer> - <template #header><MkPageHeader/></template> + <template #header><MkPageHeader v-model:tab="tab" :tabs="headerTabs"/></template> - <MkSpacer :content-max="1200"> + <MkSpacer v-if="tab === 'users'" :content-max="1200"> <div class="_gaps_s"> <div v-if="role">{{ role.description }}</div> <MkUserList :pagination="users" :extractor="(item) => item.user"/> </div> </MkSpacer> + <MkSpacer v-else-if="tab === 'timeline'" :content-max="700"> + <MkTimeline ref="timeline" src="role" :role="props.role"/> + </MkSpacer> </MkStickyContainer> </template> @@ -16,11 +19,17 @@ import { computed, watch } from 'vue'; import * as os from '@/os'; import MkUserList from '@/components/MkUserList.vue'; import { definePageMetadata } from '@/scripts/page-metadata'; +import { i18n } from '@/i18n'; +import MkTimeline from '@/components/MkTimeline.vue'; -const props = defineProps<{ +const props = withDefaults(defineProps<{ role: string; -}>(); + initialTab?: string; +}>(), { + initialTab: 'users', +}); +let tab = $ref(props.initialTab); let role = $ref(); watch(() => props.role, () => { @@ -39,6 +48,16 @@ const users = $computed(() => ({ }, })); +const headerTabs = $computed(() => [{ + key: 'users', + icon: 'ti ti-users', + title: i18n.ts.users, +}, { + key: 'timeline', + icon: 'ti ti-pencil', + title: i18n.ts.timeline, +}]); + definePageMetadata(computed(() => ({ title: role?.name, icon: 'ti ti-badge', diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index 4db7c9413a..33e752513b 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -152,6 +152,7 @@ const addColumn = async (ev) => { 'channel', 'mentions', 'direct', + 'roleTimeline', ]; const { canceled, result: column } = await os.select({ diff --git a/packages/frontend/src/ui/deck/column-core.vue b/packages/frontend/src/ui/deck/column-core.vue index 083e91bb03..8e7addf359 100644 --- a/packages/frontend/src/ui/deck/column-core.vue +++ b/packages/frontend/src/ui/deck/column-core.vue @@ -10,6 +10,7 @@ <XAntennaColumn v-else-if="column.type === 'antenna'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> <XMentionsColumn v-else-if="column.type === 'mentions'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> <XDirectColumn v-else-if="column.type === 'direct'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> +<XRoleTimelineColumn v-else-if="column.type === 'roleTimeline'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> </template> <script lang="ts" setup> @@ -23,6 +24,7 @@ import XNotificationsColumn from './notifications-column.vue'; import XWidgetsColumn from './widgets-column.vue'; import XMentionsColumn from './mentions-column.vue'; import XDirectColumn from './direct-column.vue'; +import XRoleTimelineColumn from './role-timeline-column.vue'; import { Column } from './deck-store'; defineProps<{ diff --git a/packages/frontend/src/ui/deck/deck-store.ts b/packages/frontend/src/ui/deck/deck-store.ts index 1420ad8b30..a6784e9849 100644 --- a/packages/frontend/src/ui/deck/deck-store.ts +++ b/packages/frontend/src/ui/deck/deck-store.ts @@ -22,6 +22,7 @@ export type Column = { antennaId?: string; listId?: string; channelId?: string; + roleId?: string; includingTypes?: typeof notificationTypes[number][]; tl?: 'home' | 'local' | 'social' | 'global'; }; diff --git a/packages/frontend/src/ui/deck/role-timeline-column.vue b/packages/frontend/src/ui/deck/role-timeline-column.vue new file mode 100644 index 0000000000..5783b3f071 --- /dev/null +++ b/packages/frontend/src/ui/deck/role-timeline-column.vue @@ -0,0 +1,67 @@ +<template> +<XColumn :menu="menu" :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)"> + <template #header> + <i class="ti ti-badge"></i><span style="margin-left: 8px;">{{ column.name }}</span> + </template> + + <MkTimeline v-if="column.roleId" ref="timeline" src="role" :role="column.roleId" @after="() => emit('loaded')"/> +</XColumn> +</template> + +<script lang="ts" setup> +import { onMounted } from 'vue'; +import XColumn from './column.vue'; +import { updateColumn, Column } from './deck-store'; +import MkTimeline from '@/components/MkTimeline.vue'; +import * as os from '@/os'; +import { i18n } from '@/i18n'; + +const props = defineProps<{ + column: Column; + isStacked: boolean; +}>(); + +const emit = defineEmits<{ + (ev: 'loaded'): void; + (ev: 'parent-focus', direction: 'up' | 'down' | 'left' | 'right'): void; +}>(); + +let timeline = $shallowRef<InstanceType<typeof MkTimeline>>(); + +onMounted(() => { + if (props.column.roleId == null) { + setRole(); + } +}); + +async function setRole() { + const roles = await os.api('roles/list'); + const { canceled, result: role } = await os.select({ + title: i18n.ts.role, + items: roles.map(x => ({ + value: x, text: x.name, + })), + default: props.column.roleId, + }); + if (canceled) return; + updateColumn(props.column.id, { + roleId: role.id, + }); +} + +const menu = [{ + icon: 'ti ti-pencil', + text: i18n.ts.role, + action: setRole, +}]; + +/* +function focus() { + timeline.focus(); +} + +defineExpose({ + focus, +}); +*/ +</script> |