mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 12:36:57 +00:00
add clip and translate buttons to MkNoteSub / SkNoteSub
This commit is contained in:
parent
b5357ac90d
commit
5412ae27a6
2 changed files with 40 additions and 4 deletions
|
@ -59,6 +59,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<button v-if="note.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(note)">
|
<button v-if="note.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(note)">
|
||||||
<i class="ph-minus ph-bold ph-lg"></i>
|
<i class="ph-minus ph-bold ph-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-if="prefer.s.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @click.stop="clip()">
|
||||||
|
<i class="ti ti-paperclip"></i>
|
||||||
|
</button>
|
||||||
|
<button v-if="prefer.s.showTranslationButtonInNoteFooter && $i?.policies.canUseTranslator && instance.translatorAvailable" ref="translationButton" class="_button" :class="$style.footerButton" :disabled="translating || !!translation" @click.stop="translate()">
|
||||||
|
<i class="ti ti-language-hiragana"></i>
|
||||||
|
</button>
|
||||||
<button ref="menuButton" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
|
<button ref="menuButton" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
|
||||||
<i class="ph-dots-three ph-bold ph-lg"></i>
|
<i class="ph-dots-three ph-bold ph-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -78,7 +84,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, shallowRef, watch } from 'vue';
|
import { computed, inject, type Ref, ref, shallowRef, useTemplateRef, watch } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { computeMergedCw } from '@@/js/compute-merged-cw.js';
|
import { computeMergedCw } from '@@/js/compute-merged-cw.js';
|
||||||
import * as config from '@@/js/config.js';
|
import * as config from '@@/js/config.js';
|
||||||
|
@ -101,11 +107,12 @@ import { showMovedDialog } from '@/utility/show-moved-dialog.js';
|
||||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||||
import { reactionPicker } from '@/utility/reaction-picker.js';
|
import { reactionPicker } from '@/utility/reaction-picker.js';
|
||||||
import { claimAchievement } from '@/utility/achievements.js';
|
import { claimAchievement } from '@/utility/achievements.js';
|
||||||
import { getNoteMenu } from '@/utility/get-note-menu.js';
|
import { getNoteClipMenu, getNoteMenu, translateNote } from '@/utility/get-note-menu.js';
|
||||||
import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js';
|
import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { useNoteCapture } from '@/use/use-note-capture.js';
|
import { useNoteCapture } from '@/use/use-note-capture.js';
|
||||||
import SkMutedNote from '@/components/SkMutedNote.vue';
|
import SkMutedNote from '@/components/SkMutedNote.vue';
|
||||||
|
import { instance } from '@/instance';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
note: Misskey.entities.Note;
|
note: Misskey.entities.Note;
|
||||||
|
@ -128,6 +135,7 @@ const translating = ref(false);
|
||||||
const isDeleted = ref(false);
|
const isDeleted = ref(false);
|
||||||
const renoted = ref(false);
|
const renoted = ref(false);
|
||||||
const reactButton = shallowRef<HTMLElement>();
|
const reactButton = shallowRef<HTMLElement>();
|
||||||
|
const clipButton = useTemplateRef('clipButton');
|
||||||
const renoteButton = shallowRef<HTMLElement>();
|
const renoteButton = shallowRef<HTMLElement>();
|
||||||
const quoteButton = shallowRef<HTMLElement>();
|
const quoteButton = shallowRef<HTMLElement>();
|
||||||
const menuButton = shallowRef<HTMLElement>();
|
const menuButton = shallowRef<HTMLElement>();
|
||||||
|
@ -153,6 +161,8 @@ const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
|
||||||
url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`,
|
url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', null);
|
||||||
|
|
||||||
async function addReplyTo(replyNote: Misskey.entities.Note) {
|
async function addReplyTo(replyNote: Misskey.entities.Note) {
|
||||||
replies.value.unshift(replyNote);
|
replies.value.unshift(replyNote);
|
||||||
appearNote.value.repliesCount += 1;
|
appearNote.value.repliesCount += 1;
|
||||||
|
@ -376,6 +386,14 @@ function menu(): void {
|
||||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function clip(): Promise<void> {
|
||||||
|
os.popupMenu(await getNoteClipMenu({ note: props.note, isDeleted, currentClip: currentClip?.value }), clipButton.value).then(focus);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function translate() {
|
||||||
|
await translateNote(appearNote.value.id, translation, translating);
|
||||||
|
}
|
||||||
|
|
||||||
if (props.detail) {
|
if (props.detail) {
|
||||||
misskeyApi('notes/children', {
|
misskeyApi('notes/children', {
|
||||||
noteId: props.note.id,
|
noteId: props.note.id,
|
||||||
|
|
|
@ -67,6 +67,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<button v-if="note.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(note)">
|
<button v-if="note.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(note)">
|
||||||
<i class="ph-minus ph-bold ph-lg"></i>
|
<i class="ph-minus ph-bold ph-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-if="prefer.s.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @click.stop="clip()">
|
||||||
|
<i class="ti ti-paperclip"></i>
|
||||||
|
</button>
|
||||||
|
<button v-if="prefer.s.showTranslationButtonInNoteFooter && $i?.policies.canUseTranslator && instance.translatorAvailable" ref="translationButton" class="_button" :class="$style.footerButton" :disabled="translating || !!translation" @click.stop="translate()">
|
||||||
|
<i class="ti ti-language-hiragana"></i>
|
||||||
|
</button>
|
||||||
<button ref="menuButton" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
|
<button ref="menuButton" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
|
||||||
<i class="ph-dots-three ph-bold ph-lg"></i>
|
<i class="ph-dots-three ph-bold ph-lg"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -86,7 +92,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, ref, shallowRef, watch } from 'vue';
|
import { computed, inject, type Ref, ref, shallowRef, useTemplateRef, watch } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { computeMergedCw } from '@@/js/compute-merged-cw.js';
|
import { computeMergedCw } from '@@/js/compute-merged-cw.js';
|
||||||
import * as config from '@@/js/config.js';
|
import * as config from '@@/js/config.js';
|
||||||
|
@ -109,11 +115,12 @@ import { showMovedDialog } from '@/utility/show-moved-dialog.js';
|
||||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||||
import { reactionPicker } from '@/utility/reaction-picker.js';
|
import { reactionPicker } from '@/utility/reaction-picker.js';
|
||||||
import { claimAchievement } from '@/utility/achievements.js';
|
import { claimAchievement } from '@/utility/achievements.js';
|
||||||
import { getNoteMenu } from '@/utility/get-note-menu.js';
|
import { getNoteClipMenu, getNoteMenu, translateNote } from '@/utility/get-note-menu.js';
|
||||||
import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js';
|
import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { useNoteCapture } from '@/use/use-note-capture.js';
|
import { useNoteCapture } from '@/use/use-note-capture.js';
|
||||||
import SkMutedNote from '@/components/SkMutedNote.vue';
|
import SkMutedNote from '@/components/SkMutedNote.vue';
|
||||||
|
import { instance } from '@/instance';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
note: Misskey.entities.Note;
|
note: Misskey.entities.Note;
|
||||||
|
@ -142,6 +149,7 @@ const translating = ref(false);
|
||||||
const isDeleted = ref(false);
|
const isDeleted = ref(false);
|
||||||
const renoted = ref(false);
|
const renoted = ref(false);
|
||||||
const reactButton = shallowRef<HTMLElement>();
|
const reactButton = shallowRef<HTMLElement>();
|
||||||
|
const clipButton = useTemplateRef('clipButton');
|
||||||
const renoteButton = shallowRef<HTMLElement>();
|
const renoteButton = shallowRef<HTMLElement>();
|
||||||
const quoteButton = shallowRef<HTMLElement>();
|
const quoteButton = shallowRef<HTMLElement>();
|
||||||
const menuButton = shallowRef<HTMLElement>();
|
const menuButton = shallowRef<HTMLElement>();
|
||||||
|
@ -167,6 +175,8 @@ const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
|
||||||
url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`,
|
url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', null);
|
||||||
|
|
||||||
async function addReplyTo(replyNote: Misskey.entities.Note) {
|
async function addReplyTo(replyNote: Misskey.entities.Note) {
|
||||||
replies.value.unshift(replyNote);
|
replies.value.unshift(replyNote);
|
||||||
appearNote.value.repliesCount += 1;
|
appearNote.value.repliesCount += 1;
|
||||||
|
@ -390,6 +400,14 @@ function menu(): void {
|
||||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function clip(): Promise<void> {
|
||||||
|
os.popupMenu(await getNoteClipMenu({ note: props.note, isDeleted, currentClip: currentClip?.value }), clipButton.value).then(focus);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function translate() {
|
||||||
|
await translateNote(appearNote.value.id, translation, translating);
|
||||||
|
}
|
||||||
|
|
||||||
if (props.detail) {
|
if (props.detail) {
|
||||||
misskeyApi('notes/children', {
|
misskeyApi('notes/children', {
|
||||||
noteId: props.note.id,
|
noteId: props.note.id,
|
||||||
|
|
Loading…
Add table
Reference in a new issue