diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-02-09 10:35:28 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-02-09 10:35:28 +0900 |
| commit | 7afee5977fe60f0e69e148f38974e02141c8f8c6 (patch) | |
| tree | c0cb99fa15fc15734f0ab3635eae8cb027b6c2dc | |
| parent | refactor(client): use css modules (diff) | |
| download | misskey-7afee5977fe60f0e69e148f38974e02141c8f8c6.tar.gz misskey-7afee5977fe60f0e69e148f38974e02141c8f8c6.tar.bz2 misskey-7afee5977fe60f0e69e148f38974e02141c8f8c6.zip | |
feat(client): add channel column to deck
| -rw-r--r-- | CHANGELOG.md | 9 | ||||
| -rw-r--r-- | locales/ja-JP.yml | 2 | ||||
| -rw-r--r-- | packages/frontend/src/pages/channel.vue | 4 | ||||
| -rw-r--r-- | packages/frontend/src/pages/share.vue | 32 | ||||
| -rw-r--r-- | packages/frontend/src/pages/timeline.vue | 4 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck.vue | 1 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/channel-column.vue | 71 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/column-core.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/ui/deck/deck-store.ts | 3 | ||||
| -rw-r--r-- | packages/frontend/src/widgets/WidgetPostForm.vue | 6 |
10 files changed, 110 insertions, 24 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f914bd4b..d7ee9ae169 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ You should also include the user name that made the change. --> + +## 13.x.x (unreleased) + +### Improvements +- Client: デッキにチャンネルカラムを追加 + +### Bugfixes +- + ## 13.5.2 (2023/02/08) ### Changes diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 6286367b50..8e8fddfb89 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -129,6 +129,7 @@ unblockConfirm: "ブロック解除しますか?" suspendConfirm: "凍結しますか?" unsuspendConfirm: "解凍しますか?" selectList: "リストを選択" +selectChannel: "チャンネルを選択" selectAntenna: "アンテナを選択" selectWidget: "ウィジェットを選択" editWidgets: "ウィジェットを編集" @@ -1922,5 +1923,6 @@ _deck: tl: "タイムライン" antenna: "アンテナ" list: "リスト" + channel: "チャンネル" mentions: "あなた宛て" direct: "ダイレクト" diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index 96340a36b9..0fb33e30f7 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -23,7 +23,7 @@ </div> </div> - <XPostForm v-if="$i" :channel="channel" class="post-form _panel _margin" fixed/> + <MkPostForm v-if="$i" :channel="channel" class="post-form _panel _margin" fixed/> <XTimeline :key="channelId" class="_margin" src="channel" :channel="channelId" @before="before" @after="after"/> </div> @@ -34,7 +34,7 @@ <script lang="ts" setup> import { computed, inject, watch } from 'vue'; import MkContainer from '@/components/MkContainer.vue'; -import XPostForm from '@/components/MkPostForm.vue'; +import MkPostForm from '@/components/MkPostForm.vue'; import XTimeline from '@/components/MkTimeline.vue'; import XChannelFollowButton from '@/components/MkChannelFollowButton.vue'; import * as os from '@/os'; diff --git a/packages/frontend/src/pages/share.vue b/packages/frontend/src/pages/share.vue index a7e797eeab..d8b956b6d1 100644 --- a/packages/frontend/src/pages/share.vue +++ b/packages/frontend/src/pages/share.vue @@ -29,7 +29,7 @@ import { noteVisibilities } from 'misskey-js'; import * as Acct from 'misskey-js/built/acct'; import * as Misskey from 'misskey-js'; import MkButton from '@/components/MkButton.vue'; -import XPostForm from '@/components/MkPostForm.vue'; +import MkPostForm from '@/components/MkPostForm.vue'; import * as os from '@/os'; import { mainRouter } from '@/router'; import { definePageMetadata } from '@/scripts/page-metadata'; @@ -69,14 +69,14 @@ async function init() { ...(visibleAccts ? visibleAccts.split(',').map(Acct.parse) : []), ] // TypeScriptの指示通りに変換する - .map(q => 'username' in q ? { username: q.username, host: q.host === null ? undefined : q.host } : q) - .map(q => os.api('users/show', q) - .then(user => { - visibleUsers.push(user); - }, () => { - console.error(`Invalid user query: ${JSON.stringify(q)}`); - }), - ), + .map(q => 'username' in q ? { username: q.username, host: q.host === null ? undefined : q.host } : q) + .map(q => os.api('users/show', q) + .then(user => { + visibleUsers.push(user); + }, () => { + console.error(`Invalid user query: ${JSON.stringify(q)}`); + }), + ), ); } @@ -120,13 +120,13 @@ async function init() { if (fileIds) { await Promise.all( fileIds.split(',') - .map(fileId => os.api('drive/files/show', { fileId }) - .then(file => { - files.push(file); - }, () => { - console.error(`Failed to fetch a file ${fileId}`); - }), - ), + .map(fileId => os.api('drive/files/show', { fileId }) + .then(file => { + files.push(file); + }, () => { + console.error(`Failed to fetch a file ${fileId}`); + }), + ), ); } //#endregion diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 080772951e..057409484c 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -4,7 +4,7 @@ <MkSpacer :content-max="800"> <div ref="rootEl" v-hotkey.global="keymap"> <XTutorial v-if="$i && $store.reactiveState.tutorial.value != -1" class="_panel" style="margin-bottom: var(--margin);"/> - <XPostForm v-if="$store.reactiveState.showFixedPostForm.value" :class="$style.postForm" class="post-form _panel" fixed style="margin-bottom: var(--margin);"/> + <MkPostForm v-if="$store.reactiveState.showFixedPostForm.value" :class="$style.postForm" class="post-form _panel" fixed style="margin-bottom: var(--margin);"/> <div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div> <div :class="$style.tl"> @@ -24,7 +24,7 @@ <script lang="ts" setup> import { defineAsyncComponent, computed, watch } from 'vue'; import XTimeline from '@/components/MkTimeline.vue'; -import XPostForm from '@/components/MkPostForm.vue'; +import MkPostForm from '@/components/MkPostForm.vue'; import { scroll } from '@/scripts/scroll'; import * as os from '@/os'; import { defaultStore } from '@/store'; diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index fd6caaa58c..b09721dec9 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -146,6 +146,7 @@ const addColumn = async (ev) => { 'tl', 'antenna', 'list', + 'channel', 'mentions', 'direct', ]; diff --git a/packages/frontend/src/ui/deck/channel-column.vue b/packages/frontend/src/ui/deck/channel-column.vue new file mode 100644 index 0000000000..5a84237c80 --- /dev/null +++ b/packages/frontend/src/ui/deck/channel-column.vue @@ -0,0 +1,71 @@ +<template> +<XColumn :menu="menu" :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)"> + <template #header> + <i class="ti ti-device-tv"></i><span style="margin-left: 8px;">{{ column.name }}</span> + </template> + + <template v-if="column.channelId"> + <div style="padding: 8px; text-align: center;"> + <MkButton primary gradate rounded inline @click="post"><i class="ti ti-pencil"></i></MkButton> + </div> + <XTimeline ref="timeline" src="channel" :channel="column.channelId" @after="() => emit('loaded')"/> + </template> +</XColumn> +</template> + +<script lang="ts" setup> +import { } from 'vue'; +import XColumn from './column.vue'; +import { updateColumn, Column } from './deck-store'; +import XTimeline from '@/components/MkTimeline.vue'; +import MkButton from '@/components/MkButton.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 XTimeline>>(); + +if (props.column.channelId == null) { + setChannel(); +} + +async function setChannel() { + const channels = await os.api('channels/followed'); + const { canceled, result: channel } = await os.select({ + title: i18n.ts.selectChannel, + items: channels.map(x => ({ + value: x, text: x.name, + })), + default: props.column.channelId, + }); + if (canceled) return; + updateColumn(props.column.id, { + channelId: channel.id, + name: channel.name, + }); +} + +function post() { + os.post({ + channel: { + id: props.column.channelId, + }, + instant: true, + }); +} + +const menu = [{ + icon: 'ti ti-pencil', + text: i18n.ts.selectChannel, + action: setChannel, +}]; +</script> diff --git a/packages/frontend/src/ui/deck/column-core.vue b/packages/frontend/src/ui/deck/column-core.vue index 30c0dc5e1c..083e91bb03 100644 --- a/packages/frontend/src/ui/deck/column-core.vue +++ b/packages/frontend/src/ui/deck/column-core.vue @@ -6,6 +6,7 @@ <XNotificationsColumn v-else-if="column.type === 'notifications'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> <XTlColumn v-else-if="column.type === 'tl'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> <XListColumn v-else-if="column.type === 'list'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> +<XChannelColumn v-else-if="column.type === 'channel'" :column="column" :is-stacked="isStacked" @parent-focus="emit('parent-focus', $event)"/> <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)"/> @@ -17,6 +18,7 @@ import XMainColumn from './main-column.vue'; import XTlColumn from './tl-column.vue'; import XAntennaColumn from './antenna-column.vue'; import XListColumn from './list-column.vue'; +import XChannelColumn from './channel-column.vue'; import XNotificationsColumn from './notifications-column.vue'; import XWidgetsColumn from './widgets-column.vue'; import XMentionsColumn from './mentions-column.vue'; diff --git a/packages/frontend/src/ui/deck/deck-store.ts b/packages/frontend/src/ui/deck/deck-store.ts index 56db7398e5..80c202a2ef 100644 --- a/packages/frontend/src/ui/deck/deck-store.ts +++ b/packages/frontend/src/ui/deck/deck-store.ts @@ -14,7 +14,7 @@ type ColumnWidget = { export type Column = { id: string; - type: 'main' | 'widgets' | 'notifications' | 'tl' | 'antenna' | 'list' | 'mentions' | 'direct'; + type: 'main' | 'widgets' | 'notifications' | 'tl' | 'antenna' | 'channel' | 'list' | 'mentions' | 'direct'; name: string | null; width: number; widgets?: ColumnWidget[]; @@ -22,6 +22,7 @@ export type Column = { flexible?: boolean; antennaId?: string; listId?: string; + channelId?: string; includingTypes?: typeof notificationTypes[number][]; tl?: 'home' | 'local' | 'social' | 'global'; }; diff --git a/packages/frontend/src/widgets/WidgetPostForm.vue b/packages/frontend/src/widgets/WidgetPostForm.vue index 54226c1dbf..f8bebcbf96 100644 --- a/packages/frontend/src/widgets/WidgetPostForm.vue +++ b/packages/frontend/src/widgets/WidgetPostForm.vue @@ -1,12 +1,12 @@ <template> -<XPostForm class="_panel mkw-postForm data-cy-mkw-postForm" :fixed="true" :autofocus="false"/> +<MkPostForm class="_panel mkw-post-form data-cy-mkw-postForm" :fixed="true" :autofocus="false"/> </template> <script lang="ts" setup> import { } from 'vue'; -import { GetFormResultType } from '@/scripts/form'; import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget'; -import XPostForm from '@/components/MkPostForm.vue'; +import { GetFormResultType } from '@/scripts/form'; +import MkPostForm from '@/components/MkPostForm.vue'; const name = 'postForm'; |