fix MkPostForm.vue

This commit is contained in:
samunohito 2023-12-18 11:04:08 +09:00
parent 974acf4086
commit fb3288d720
1 changed files with 40 additions and 38 deletions

View File

@ -22,18 +22,18 @@ SPDX-License-Identifier: AGPL-3.0-only
<button ref="visibilityButton" v-click-anime v-tooltip="i18n.ts.visibility" :class="['_button', $style.headerRightItem, $style.visibility]" @click="setVisibility"> <button ref="visibilityButton" v-click-anime v-tooltip="i18n.ts.visibility" :class="['_button', $style.headerRightItem, $style.visibility]" @click="setVisibility">
<template v-if="postChannel"> <template v-if="postChannel">
<span><i class="ti ti-device-tv"></i></span> <span><i class="ti ti-device-tv"></i></span>
<span v-if="postChannel" :class="$style.headerRightButtonText">{{ postChannel.name }}</span> <span v-if="postChannel" :class="$style.headerRightButtonText">{{ postChannelName }}</span>
</template> </template>
<template v-else> <template v-else>
<span v-if="visibility === 'public'"><i class="ti ti-world"></i></span> <span v-if="actualVisibility === 'public'"><i class="ti ti-world"></i></span>
<span v-if="visibility === 'home'"><i class="ti ti-home"></i></span> <span v-if="actualVisibility === 'home'"><i class="ti ti-home"></i></span>
<span v-if="visibility === 'followers'"><i class="ti ti-lock"></i></span> <span v-if="actualVisibility === 'followers'"><i class="ti ti-lock"></i></span>
<span v-if="visibility === 'specified'"><i class="ti ti-mail"></i></span> <span v-if="actualVisibility === 'specified'"><i class="ti ti-mail"></i></span>
<span :class="$style.headerRightButtonText">{{ i18n.ts._visibility[visibility] }}</span> <span :class="$style.headerRightButtonText">{{ i18n.ts._visibility[actualVisibility] }}</span>
</template> </template>
</button> </button>
<button v-click-anime v-tooltip="i18n.ts._visibility.disableFederation" class="_button" :class="[$style.headerRightItem, { [$style.danger]: localOnly }]" :disabled="postChannel != null || visibility === 'specified'" @click="toggleLocalOnly"> <button v-click-anime v-tooltip="i18n.ts._visibility.disableFederation" class="_button" :class="[$style.headerRightItem, { [$style.danger]: actualLocalOnly }]" :disabled="postChannel != null || actualVisibility === 'specified'" @click="toggleLocalOnly">
<span v-if="!localOnly"><i class="ti ti-rocket"></i></span> <span v-if="!actualLocalOnly"><i class="ti ti-rocket"></i></span>
<span v-else><i class="ti ti-rocket-off"></i></span> <span v-else><i class="ti ti-rocket-off"></i></span>
</button> </button>
<button v-click-anime v-tooltip="i18n.ts.reactionAcceptance" class="_button" :class="[$style.headerRightItem, { [$style.danger]: reactionAcceptance === 'likeOnly' }]" @click="toggleReactionAcceptance"> <button v-click-anime v-tooltip="i18n.ts.reactionAcceptance" class="_button" :class="[$style.headerRightItem, { [$style.danger]: reactionAcceptance === 'likeOnly' }]" @click="toggleReactionAcceptance">
@ -54,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkNoteSimple v-if="reply" :class="$style.targetNote" :note="reply"/> <MkNoteSimple v-if="reply" :class="$style.targetNote" :note="reply"/>
<MkNoteSimple v-if="renote" :class="$style.targetNote" :note="renote"/> <MkNoteSimple v-if="renote" :class="$style.targetNote" :note="renote"/>
<div v-if="quoteId" :class="$style.withQuote"><i class="ti ti-quote"></i> {{ i18n.ts.quoteAttached }}<button @click="quoteId = null"><i class="ti ti-x"></i></button></div> <div v-if="quoteId" :class="$style.withQuote"><i class="ti ti-quote"></i> {{ i18n.ts.quoteAttached }}<button @click="quoteId = null"><i class="ti ti-x"></i></button></div>
<div v-if="visibility === 'specified'" :class="$style.toSpecified"> <div v-if="actualVisibility === 'specified'" :class="$style.toSpecified">
<span style="margin-right: 8px;">{{ i18n.ts.recipient }}</span> <span style="margin-right: 8px;">{{ i18n.ts.recipient }}</span>
<div :class="$style.visibleUsers"> <div :class="$style.visibleUsers">
<span v-for="u in visibleUsers" :key="u.id" :class="$style.visibleUser"> <span v-for="u in visibleUsers" :key="u.id" :class="$style.visibleUser">
@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInfo v-if="hasNotSpecifiedMentions" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo> <MkInfo v-if="hasNotSpecifiedMentions" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo>
<input v-show="useCw" ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown"> <input v-show="useCw" ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown">
<div :class="[$style.textOuter, { [$style.withCw]: useCw }]"> <div :class="[$style.textOuter, { [$style.withCw]: useCw }]">
<div v-if="channel" :class="$style.colorBar" :style="{ background: channel.color }"></div> <div v-if="postChannel" :class="$style.colorBar" :style="{ background: postChannel.color }"></div>
<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/> <textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
<div v-if="maxTextLength - textLength < 100" :class="['_acrylic', $style.textCount, { [$style.textOver]: textLength > maxTextLength }]">{{ maxTextLength - textLength }}</div> <div v-if="maxTextLength - textLength < 100" :class="['_acrylic', $style.textCount, { [$style.textOver]: textLength > maxTextLength }]">{{ maxTextLength - textLength }}</div>
</div> </div>
@ -132,7 +132,7 @@ const modal = inject('modal');
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
reply?: Misskey.entities.Note; reply?: Misskey.entities.Note;
renote?: Misskey.entities.Note; renote?: Misskey.entities.Note;
channel?: Misskey.entities.Channel; // TODO channel?: Misskey.entities.Channel;
mention?: Misskey.entities.User; mention?: Misskey.entities.User;
specified?: Misskey.entities.User; specified?: Misskey.entities.User;
initialText?: string; initialText?: string;
@ -153,8 +153,6 @@ const props = withDefaults(defineProps<{
mock: false, mock: false,
}); });
let postChannel = ref<Misskey.entities.Channel | null>(props.channel);
provide('mock', props.mock); provide('mock', props.mock);
const emit = defineEmits<{ const emit = defineEmits<{
@ -201,6 +199,20 @@ const imeText = ref('');
const showingOptions = ref(false); const showingOptions = ref(false);
const textAreaReadOnly = ref(false); const textAreaReadOnly = ref(false);
const postChannel = ref<Misskey.entities.Channel | null>(props.channel ?? null);
const postChannelName = computed<string>(() => postChannel.value?.name ?? '');
/**
* {@link localOnly}が持つ値にチャンネル選択有無を加味した値を計算するチャンネル選択時は強制的にfalse
* チャンネル選択有無を考慮する必要がある場面では{@link localOnly}ではなくこの値を使用する
*/
const actualLocalOnly = computed<boolean>(() => postChannel.value ? true : localOnly.value);
/**
* {@link visibility}が持つ値にチャンネル選択有無を加味した値を計算するチャンネル選択時は強制的にpublic
* チャンネル選択有無を考慮する必要がある場面では{@link actualVisibility}ではなくこの値を使用する
*/
const actualVisibility = computed<typeof Misskey.noteVisibilities[number]>(() => postChannel.value ? 'public' : visibility.value);
const draftKey = computed((): string => { const draftKey = computed((): string => {
let key = postChannel.value ? `channel:${postChannel.value.id}` : ''; let key = postChannel.value ? `channel:${postChannel.value.id}` : '';
@ -265,7 +277,7 @@ watch(text, () => {
checkMissingMention(); checkMissingMention();
}, { immediate: true }); }, { immediate: true });
watch(visibility, () => { watch(actualVisibility, () => {
checkMissingMention(); checkMissingMention();
}, { immediate: true }); }, { immediate: true });
@ -309,11 +321,6 @@ if ($i?.isSilenced && visibility.value === 'public') {
visibility.value = 'home'; 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 && ['home', 'followers', 'specified'].includes(props.reply.visibility)) {
if (props.reply.visibility === 'home' && visibility.value === 'followers') { if (props.reply.visibility === 'home' && visibility.value === 'followers') {
@ -363,7 +370,7 @@ function watchForDraft() {
} }
function checkMissingMention() { function checkMissingMention() {
if (visibility.value === 'specified') { if (actualVisibility.value === 'specified') {
const ast = mfm.parse(text.value); const ast = mfm.parse(text.value);
for (const x of extractMentions(ast)) { for (const x of extractMentions(ast)) {
@ -451,11 +458,12 @@ function upload(file: File, name?: string): void {
function setVisibility() { function setVisibility() {
os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), { os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), {
currentVisibility: visibility.value, currentVisibility: actualVisibility.value,
isSilenced: $i?.isSilenced, isSilenced: $i?.isSilenced,
localOnly: localOnly.value, // false
localOnly: postChannel.value ? false : actualLocalOnly.value,
src: visibilityButton.value, src: visibilityButton.value,
currentChannel: postChannel.value, currentChannel: postChannel.value,
}, { }, {
changeVisibility: v => { changeVisibility: v => {
visibility.value = v; visibility.value = v;
@ -464,21 +472,14 @@ function setVisibility() {
defaultStore.set('visibility', visibility.value); defaultStore.set('visibility', visibility.value);
} }
}, },
changeChannel: channel => { changeChannel: channel => {
postChannel.value = channel; // computedlocalOnlyvisibility
visibility.value = 'public'; postChannel.value = channel;
localOnly.value = true; },
}
}, 'closed'); }, 'closed');
} }
async function toggleLocalOnly() { async function toggleLocalOnly() {
if (postChannel.value) {
visibility.value = 'public';
localOnly.value = true; // TODO:
return;
}
const neverShowInfo = miLocalStorage.getItem('neverShowLocalOnlyInfo'); const neverShowInfo = miLocalStorage.getItem('neverShowLocalOnlyInfo');
if (!localOnly.value && neverShowInfo !== 'true') { if (!localOnly.value && neverShowInfo !== 'true') {
@ -711,7 +712,8 @@ async function post(ev?: MouseEvent) {
text.value.includes('$[scale') || text.value.includes('$[scale') ||
text.value.includes('$[position'); text.value.includes('$[position');
if (annoying && visibility.value === 'public') { // 稿public
if (annoying && actualVisibility.value === 'public' && !postChannel.value) {
const { canceled, result } = await os.actions({ const { canceled, result } = await os.actions({
type: 'warning', type: 'warning',
text: i18n.ts.thisPostMayBeAnnoying, text: i18n.ts.thisPostMayBeAnnoying,
@ -743,9 +745,9 @@ async function post(ev?: MouseEvent) {
channelId: postChannel.value ? postChannel.value.id : undefined, channelId: postChannel.value ? postChannel.value.id : undefined,
poll: poll.value, poll: poll.value,
cw: useCw.value ? cw.value ?? '' : null, cw: useCw.value ? cw.value ?? '' : null,
localOnly: localOnly.value, localOnly: actualLocalOnly.value,
visibility: visibility.value, visibility: actualVisibility.value,
visibleUserIds: visibility.value === 'specified' ? visibleUsers.value.map(u => u.id) : undefined, visibleUserIds: actualVisibility.value === 'specified' ? visibleUsers.value.map(u => u.id) : undefined,
reactionAcceptance: reactionAcceptance.value, reactionAcceptance: reactionAcceptance.value,
}; };