投稿フォームでどこからでもチャンネルに投げられるようにしたい
This commit is contained in:
parent
272dc208b4
commit
20e4c6b01e
|
@ -19,20 +19,20 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.headerRight">
|
<div :class="$style.headerRight">
|
||||||
<template v-if="!(channel != null && fixed)">
|
<template v-if="!(postChannel != null && fixed)">
|
||||||
<button v-if="channel == null" ref="visibilityButton" v-click-anime v-tooltip="i18n.ts.visibility" :class="['_button', $style.headerRightItem, $style.visibility]" @click="setVisibility">
|
<button v-if="postChannel == null" ref="visibilityButton" v-click-anime v-tooltip="i18n.ts.visibility" :class="['_button', $style.headerRightItem, $style.visibility]" @click="setVisibility">
|
||||||
<span v-if="visibility === 'public'"><i class="ti ti-world"></i></span>
|
<span v-if="visibility === 'public'"><i class="ti ti-world"></i></span>
|
||||||
<span v-if="visibility === 'home'"><i class="ti ti-home"></i></span>
|
<span v-if="visibility === 'home'"><i class="ti ti-home"></i></span>
|
||||||
<span v-if="visibility === 'followers'"><i class="ti ti-lock"></i></span>
|
<span v-if="visibility === 'followers'"><i class="ti ti-lock"></i></span>
|
||||||
<span v-if="visibility === 'specified'"><i class="ti ti-mail"></i></span>
|
<span v-if="visibility === 'specified'"><i class="ti ti-mail"></i></span>
|
||||||
<span :class="$style.headerRightButtonText">{{ i18n.ts._visibility[visibility] }}</span>
|
<span :class="$style.headerRightButtonText">{{ i18n.ts._visibility[visibility] }}</span>
|
||||||
</button>
|
</button>
|
||||||
<button v-else class="_button" :class="[$style.headerRightItem, $style.visibility]" disabled>
|
<button v-else v-tooltip="i18n.ts.visibility" v-click-anime class="_button" :class="[$style.headerRightItem, $style.visibility]" @click="setVisibility">
|
||||||
<span><i class="ti ti-device-tv"></i></span>
|
<span><i class="ti ti-device-tv"></i></span>
|
||||||
<span :class="$style.headerRightButtonText">{{ channel.name }}</span>
|
<span :class="$style.headerRightButtonText">{{ postChannel.name }}</span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<button v-click-anime v-tooltip="i18n.ts._visibility.disableFederation" class="_button" :class="[$style.headerRightItem, { [$style.danger]: localOnly }]" :disabled="channel != null || visibility === 'specified'" @click="toggleLocalOnly">
|
<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">
|
||||||
<span v-if="!localOnly"><i class="ti ti-rocket"></i></span>
|
<span v-if="!localOnly"><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>
|
||||||
|
@ -128,6 +128,8 @@ import { emojiPicker } from '@/scripts/emoji-picker.js';
|
||||||
|
|
||||||
const modal = inject('modal');
|
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;
|
||||||
|
@ -152,6 +154,8 @@ const props = withDefaults(defineProps<{
|
||||||
mock: false,
|
mock: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let postChannel = ref(props.channel)
|
||||||
|
|
||||||
provide('mock', props.mock);
|
provide('mock', props.mock);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
@ -199,7 +203,7 @@ const showingOptions = ref(false);
|
||||||
const textAreaReadOnly = ref(false);
|
const textAreaReadOnly = ref(false);
|
||||||
|
|
||||||
const draftKey = computed((): string => {
|
const draftKey = computed((): string => {
|
||||||
let key = props.channel ? `channel:${props.channel.id}` : '';
|
let key = postChannel.value ? `channel:${postChannel.value.id}` : '';
|
||||||
|
|
||||||
if (props.renote) {
|
if (props.renote) {
|
||||||
key += `renote:${props.renote.id}`;
|
key += `renote:${props.renote.id}`;
|
||||||
|
@ -217,7 +221,7 @@ const placeholder = computed((): string => {
|
||||||
return i18n.ts._postForm.quotePlaceholder;
|
return i18n.ts._postForm.quotePlaceholder;
|
||||||
} else if (props.reply) {
|
} else if (props.reply) {
|
||||||
return i18n.ts._postForm.replyPlaceholder;
|
return i18n.ts._postForm.replyPlaceholder;
|
||||||
} else if (props.channel) {
|
} else if (postChannel.value) {
|
||||||
return i18n.ts._postForm.channelPlaceholder;
|
return i18n.ts._postForm.channelPlaceholder;
|
||||||
} else {
|
} else {
|
||||||
const xs = [
|
const xs = [
|
||||||
|
@ -306,7 +310,7 @@ if ($i?.isSilenced && visibility.value === 'public') {
|
||||||
visibility.value = 'home';
|
visibility.value = 'home';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.channel) {
|
if (postChannel.value) {
|
||||||
visibility.value = 'public';
|
visibility.value = 'public';
|
||||||
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
|
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
|
||||||
}
|
}
|
||||||
|
@ -447,12 +451,6 @@ function upload(file: File, name?: string): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setVisibility() {
|
function setVisibility() {
|
||||||
if (props.channel) {
|
|
||||||
visibility.value = 'public';
|
|
||||||
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), {
|
os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), {
|
||||||
currentVisibility: visibility.value,
|
currentVisibility: visibility.value,
|
||||||
isSilenced: $i?.isSilenced,
|
isSilenced: $i?.isSilenced,
|
||||||
|
@ -465,11 +463,16 @@ function setVisibility() {
|
||||||
defaultStore.set('visibility', visibility.value);
|
defaultStore.set('visibility', visibility.value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
changeChannel: channel => {
|
||||||
|
postChannel.value = channel;
|
||||||
|
visibility.value = 'public';
|
||||||
|
localOnly.value = true;
|
||||||
|
}
|
||||||
}, 'closed');
|
}, 'closed');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleLocalOnly() {
|
async function toggleLocalOnly() {
|
||||||
if (props.channel) {
|
if (postChannel.value) {
|
||||||
visibility.value = 'public';
|
visibility.value = 'public';
|
||||||
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
|
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
|
||||||
return;
|
return;
|
||||||
|
@ -736,7 +739,7 @@ async function post(ev?: MouseEvent) {
|
||||||
fileIds: files.value.length > 0 ? files.value.map(f => f.id) : undefined,
|
fileIds: files.value.length > 0 ? files.value.map(f => f.id) : undefined,
|
||||||
replyId: props.reply ? props.reply.id : undefined,
|
replyId: props.reply ? props.reply.id : undefined,
|
||||||
renoteId: props.renote ? props.renote.id : quoteId.value ? quoteId.value : undefined,
|
renoteId: props.renote ? props.renote.id : quoteId.value ? quoteId.value : undefined,
|
||||||
channelId: props.channel ? props.channel.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: localOnly.value,
|
||||||
|
|
|
@ -37,6 +37,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<span :class="$style.itemDescription">{{ i18n.ts._visibility.specifiedDescription }}</span>
|
<span :class="$style.itemDescription">{{ i18n.ts._visibility.specifiedDescription }}</span>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-for="channel in channels" :class="$style.item" class="_button" @click="chooseChannel(channel)" >
|
||||||
|
<div :class="$style.body" :style="{borderLeft: `solid 2px ${channel.color}`}">
|
||||||
|
<span :class="$style.itemTitle">{{ channel.name }}</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</MkModal>
|
</MkModal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -46,6 +51,7 @@ import { nextTick, shallowRef, ref } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkModal from '@/components/MkModal.vue';
|
import MkModal from '@/components/MkModal.vue';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
import * as os from "@/os.js";
|
||||||
|
|
||||||
const modal = shallowRef<InstanceType<typeof MkModal>>();
|
const modal = shallowRef<InstanceType<typeof MkModal>>();
|
||||||
|
|
||||||
|
@ -64,6 +70,32 @@ const emit = defineEmits<{
|
||||||
|
|
||||||
const v = ref(props.currentVisibility);
|
const v = ref(props.currentVisibility);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visibility とチャンネルはそれぞれ独立だけど、今のところはチャンネル投稿は連合なしだし公開範囲も変更できないようである
|
||||||
|
|
||||||
|
packages/frontend/src/components/MkPostForm.vue :475
|
||||||
|
if (props.channel) {
|
||||||
|
visibility.value = 'public';
|
||||||
|
localOnly.value = true; // TODO: チャンネルが連合するようになった折には消す
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
const channels = ref([]);
|
||||||
|
async function getChannel(){
|
||||||
|
const res = await os.api('channels/my-favorites', {
|
||||||
|
limit: 100,
|
||||||
|
});
|
||||||
|
channels.value.splice(0, 0, ...res);
|
||||||
|
}
|
||||||
|
getChannel();
|
||||||
|
|
||||||
|
async function chooseChannel(channel: string ){
|
||||||
|
emit("changeChannel", channel);
|
||||||
|
await nextTick();
|
||||||
|
if (modal.value) modal.value.close();
|
||||||
|
}
|
||||||
|
|
||||||
function choose(visibility: typeof Misskey.noteVisibilities[number]): void {
|
function choose(visibility: typeof Misskey.noteVisibilities[number]): void {
|
||||||
v.value = visibility;
|
v.value = visibility;
|
||||||
emit('changeVisibility', visibility);
|
emit('changeVisibility', visibility);
|
||||||
|
|
Loading…
Reference in New Issue