diff --git a/locales/index.d.ts b/locales/index.d.ts index cd15bd968f..58555089dd 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -2164,6 +2164,9 @@ export interface Locale { "followersDescription": string; "specified": string; "specifiedDescription": string; + "channel": string; + "channelDescription": string; + "channelSelected": string; "disableFederation": string; "disableFederationDescription": string; }; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 5537db9d56..ec725d1ee3 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2068,6 +2068,9 @@ _visibility: followersDescription: "自分のフォロワーのみに公開" specified: "ダイレクト" specifiedDescription: "指定したユーザーのみに公開" + channel: "チャンネル" + channelDescription: "選択したチャンネルに公開" + channelSelected: "選択中:{name}" disableFederation: "連合なし" disableFederationDescription: "他サーバーへの配信を行いません" diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index c6124da0e1..cfb96bb3ff 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -22,18 +22,18 @@ SPDX-License-Identifier: AGPL-3.0-only - {{ postChannel.name }} + {{ postChannelName }} - - - - - {{ i18n.ts._visibility[visibility] }} + + + + + {{ i18n.ts._visibility[actualVisibility] }} - - + + @@ -54,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.quoteAttached }} - + {{ i18n.ts.recipient }} @@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.notSpecifiedMentionWarning }} - {{ i18n.ts.add }} - + {{ maxTextLength - textLength }} @@ -132,7 +132,7 @@ const modal = inject('modal'); const props = withDefaults(defineProps<{ reply?: Misskey.entities.Note; renote?: Misskey.entities.Note; - channel?: Misskey.entities.Channel; // TODO + channel?: Misskey.entities.Channel; mention?: Misskey.entities.User; specified?: Misskey.entities.User; initialText?: string; @@ -153,8 +153,6 @@ const props = withDefaults(defineProps<{ mock: false, }); -let postChannel = ref(props.channel); - provide('mock', props.mock); const emit = defineEmits<{ @@ -201,6 +199,20 @@ const imeText = ref(''); const showingOptions = ref(false); const textAreaReadOnly = ref(false); +const postChannel = ref(props.channel ?? null); +const postChannelName = computed(() => postChannel.value?.name ?? ''); + +/** + * {@link localOnly}が持つ値にチャンネル選択有無を加味した値を計算する(チャンネル選択時は強制的にfalse) + * チャンネル選択有無を考慮する必要がある場面では{@link localOnly}ではなくこの値を使用する。 + */ +const actualLocalOnly = computed(() => postChannel.value ? true : localOnly.value); +/** + * {@link visibility}が持つ値にチャンネル選択有無を加味した値を計算する(チャンネル選択時は強制的にpublic)。 + * チャンネル選択有無を考慮する必要がある場面では{@link actualVisibility}ではなくこの値を使用する。 + */ +const actualVisibility = computed(() => postChannel.value ? 'public' : visibility.value); + const draftKey = computed((): string => { let key = postChannel.value ? `channel:${postChannel.value.id}` : ''; @@ -265,7 +277,7 @@ watch(text, () => { checkMissingMention(); }, { immediate: true }); -watch(visibility, () => { +watch(actualVisibility, () => { checkMissingMention(); }, { immediate: true }); @@ -309,11 +321,6 @@ if ($i?.isSilenced && visibility.value === 'public') { visibility.value = 'home'; } -if (postChannel.value) { - visibility.value = 'public'; - localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す -} - // 公開以外へのリプライ時は元の公開範囲を引き継ぐ if (props.reply && ['home', 'followers', 'specified'].includes(props.reply.visibility)) { if (props.reply.visibility === 'home' && visibility.value === 'followers') { @@ -363,7 +370,7 @@ function watchForDraft() { } function checkMissingMention() { - if (visibility.value === 'specified') { + if (actualVisibility.value === 'specified') { const ast = mfm.parse(text.value); for (const x of extractMentions(ast)) { @@ -451,11 +458,12 @@ function upload(file: File, name?: string): void { function setVisibility() { os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), { - currentVisibility: visibility.value, + currentVisibility: actualVisibility.value, isSilenced: $i?.isSilenced, - localOnly: localOnly.value, + // チャンネル→ダイレクトの選択変更ができなくなるので、チャンネル選択中の場合は意図的にfalseを渡すようにする + localOnly: postChannel.value ? false : actualLocalOnly.value, src: visibilityButton.value, - currentChannel: postChannel.value, + currentChannel: postChannel.value, }, { changeVisibility: v => { visibility.value = v; @@ -464,21 +472,14 @@ function setVisibility() { defaultStore.set('visibility', visibility.value); } }, - changeChannel: channel => { - postChannel.value = channel; - visibility.value = 'public'; - localOnly.value = true; - } + changeChannel: channel => { + // computedで読み替えをするので、localOnlyとvisibilityの変更はしない + postChannel.value = channel; + }, }, 'closed'); } async function toggleLocalOnly() { - if (postChannel.value) { - visibility.value = 'public'; - localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す - return; - } - const neverShowInfo = miLocalStorage.getItem('neverShowLocalOnlyInfo'); if (!localOnly.value && neverShowInfo !== 'true') { @@ -711,7 +712,8 @@ async function post(ev?: MouseEvent) { text.value.includes('$[scale') || text.value.includes('$[position'); - if (annoying && visibility.value === 'public') { + // チャンネル投稿時はサーバサイド側でpublicに変更されているため警告を出す意味がない + if (annoying && actualVisibility.value === 'public' && !postChannel.value) { const { canceled, result } = await os.actions({ type: 'warning', text: i18n.ts.thisPostMayBeAnnoying, @@ -743,9 +745,9 @@ async function post(ev?: MouseEvent) { channelId: postChannel.value ? postChannel.value.id : undefined, poll: poll.value, cw: useCw.value ? cw.value ?? '' : null, - localOnly: localOnly.value, - visibility: visibility.value, - visibleUserIds: visibility.value === 'specified' ? visibleUsers.value.map(u => u.id) : undefined, + localOnly: actualLocalOnly.value, + visibility: actualVisibility.value, + visibleUserIds: actualVisibility.value === 'specified' ? visibleUsers.value.map(u => u.id) : undefined, reactionAcceptance: reactionAcceptance.value, }; diff --git a/packages/frontend/src/components/MkVisibilityPicker.vue b/packages/frontend/src/components/MkVisibilityPicker.vue index d37f76942a..0b74f0a31e 100644 --- a/packages/frontend/src/components/MkVisibilityPicker.vue +++ b/packages/frontend/src/components/MkVisibilityPicker.vue @@ -9,37 +9,46 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.visibility }} - + {{ i18n.ts._visibility.public }} {{ i18n.ts._visibility.publicDescription }} - + {{ i18n.ts._visibility.home }} {{ i18n.ts._visibility.homeDescription }} - + {{ i18n.ts._visibility.followers }} {{ i18n.ts._visibility.followersDescription }} - + {{ i18n.ts._visibility.specified }} {{ i18n.ts._visibility.specifiedDescription }} - - - {{ channel.name }} + + + + + + + {{ i18n.ts._visibility.channel }} + + {{ i18n.t('_visibility.channelSelected', { name: currentChannelName }) }} + {{ i18n.ts._visibility.channelDescription }} + + @@ -47,13 +56,15 @@ SPDX-License-Identifier: AGPL-3.0-only