diff --git a/locales/en-US.yml b/locales/en-US.yml index cb2bf987e..e9ab2a7dc 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -794,6 +794,7 @@ customCssWarn: "This setting should only be used if you know what it does. Enter global: "Global" recommended: "Recommended" squareAvatars: "Display squared avatars" +seperateRenoteQuote: "Seperate renote and quote buttons" sent: "Sent" received: "Received" searchResult: "Search results" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 593b1d935..609019e7d 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -793,6 +793,7 @@ customCss: "カスタムCSS" customCssWarn: "この設定は必ず知識のある方が行ってください。不適切な設定を行うとクライアントが正常に使用できなくなる恐れがあります。" global: "グローバル" squareAvatars: "アイコンを四角形で表示" +seperateRenoteQuote: "リノートと引用ボタンを分ける" sent: "送信" received: "受信" searchResult: "検索結果" diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue index 5445085c9..ce00b50e6 100644 --- a/packages/client/src/components/MkNote.vue +++ b/packages/client/src/components/MkNote.vue @@ -77,6 +77,7 @@ <p v-if="appearNote.repliesCount > 0" class="count">{{ appearNote.repliesCount }}</p> </button> <XRenoteButton ref="renoteButton" class="button" :note="appearNote" :count="appearNote.renoteCount"/> + <XQuoteButton class="button" :note="appearNote"/> <button v-if="appearNote.myReaction == null" ref="reactButton" class="button _button" @click="react()"> <i class="fas fa-plus"></i> </button> @@ -113,6 +114,7 @@ import XMediaList from '@/components/MkMediaList.vue'; import XCwButton from '@/components/MkCwButton.vue'; import XPoll from '@/components/MkPoll.vue'; import XRenoteButton from '@/components/MkRenoteButton.vue'; +import XQuoteButton from '@/components/MkQuoteButton.vue'; import MkUrlPreview from '@/components/MkUrlPreview.vue'; import MkInstanceTicker from '@/components/MkInstanceTicker.vue'; import MkVisibility from '@/components/MkVisibility.vue'; diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue index 173ae4444..0a4c8440d 100644 --- a/packages/client/src/components/MkNoteDetailed.vue +++ b/packages/client/src/components/MkNoteDetailed.vue @@ -87,6 +87,7 @@ <p v-if="appearNote.repliesCount > 0" class="count">{{ appearNote.repliesCount }}</p> </button> <XRenoteButton ref="renoteButton" class="button" :note="appearNote" :count="appearNote.renoteCount"/> + <XQuoteButton class="button" :note="appearNote"/> <button v-if="appearNote.myReaction == null" ref="reactButton" class="button _button" @click="react()"> <i class="fas fa-plus"></i> </button> @@ -123,6 +124,7 @@ import XMediaList from '@/components/MkMediaList.vue'; import XCwButton from '@/components/MkCwButton.vue'; import XPoll from '@/components/MkPoll.vue'; import XRenoteButton from '@/components/MkRenoteButton.vue'; +import XQuoteButton from '@/components/MkQuoteButton.vue'; import MkUrlPreview from '@/components/MkUrlPreview.vue'; import MkInstanceTicker from '@/components/MkInstanceTicker.vue'; import MkVisibility from '@/components/MkVisibility.vue'; diff --git a/packages/client/src/components/MkQuoteButton.vue b/packages/client/src/components/MkQuoteButton.vue new file mode 100644 index 000000000..200145b4f --- /dev/null +++ b/packages/client/src/components/MkQuoteButton.vue @@ -0,0 +1,50 @@ +<template> +<button + v-if="canRenote && $store.state.seperateRenoteQuote" + class="eddddedb _button" + @click="quote()" +> + <i class="fas fa-quote-right"></i> +</button> +</template> + +<script lang="ts" setup> +import { computed } from 'vue'; +import type { Note } from 'misskey-js/built/entities'; +import { pleaseLogin } from '@/scripts/please-login'; +import * as os from '@/os'; +import { $i } from '@/account'; + +const props = defineProps<{ + note: Note; +}>(); + +const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i?.id); + +function quote(): void { + pleaseLogin(); + os.post({ + renote: props.note, + }); +} +</script> + +<style lang="scss" scoped> +.eddddedb { + display: inline-block; + height: 32px; + margin: 2px; + padding: 0 6px; + border-radius: 4px; + + &.renoted { + background: var(--accent); + } + + > .count { + display: inline; + margin-left: 8px; + opacity: 0.7; + } +} +</style> diff --git a/packages/client/src/components/MkRenoteButton.vue b/packages/client/src/components/MkRenoteButton.vue index 068a9fba6..9eaada863 100644 --- a/packages/client/src/components/MkRenoteButton.vue +++ b/packages/client/src/components/MkRenoteButton.vue @@ -22,6 +22,7 @@ import * as os from '@/os'; import { $i } from '@/account'; import { useTooltip } from '@/scripts/use-tooltip'; import { i18n } from '@/i18n'; +import { defaultStore } from "@/store"; const props = defineProps<{ note: misskey.entities.Note; @@ -52,25 +53,33 @@ useTooltip(buttonRef, async (showing) => { const renote = (viaKeyboard = false) => { pleaseLogin(); - os.popupMenu([{ - text: i18n.ts.renote, - icon: 'fas fa-retweet', - action: () => { - os.api('notes/create', { - renoteId: props.note.id, - }); - }, - }, { - text: i18n.ts.quote, - icon: 'fas fa-quote-right', - action: () => { - os.post({ - renote: props.note, - }); - }, - }], buttonRef.value, { - viaKeyboard, - }); + if (defaultStore.state.seperateRenoteQuote) { + os.api('notes/create', { + renoteId: props.note.id, + visibility: props.note.visibility, + }); + } else { + os.popupMenu([{ + text: i18n.ts.renote, + icon: 'fas fa-retweet', + action: () => { + os.api('notes/create', { + renoteId: props.note.id, + visibility: props.note.visibility, + }); + }, + }, { + text: i18n.ts.quote, + icon: 'fas fa-quote-right', + action: () => { + os.post({ + renote: props.note, + }); + }, + }], buttonRef.value, { + viaKeyboard, + }); + } }; </script> diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue index ace0f9aa7..9f96d63b2 100644 --- a/packages/client/src/pages/settings/general.vue +++ b/packages/client/src/pages/settings/general.vue @@ -51,6 +51,7 @@ <FormSwitch v-model="loadRawImages" class="_formBlock">{{ i18n.ts.loadRawImages }}</FormSwitch> <FormSwitch v-model="disableShowingAnimatedImages" class="_formBlock">{{ i18n.ts.disableShowingAnimatedImages }}</FormSwitch> <FormSwitch v-model="squareAvatars" class="_formBlock">{{ i18n.ts.squareAvatars }}</FormSwitch> + <FormSwitch v-model="seperateRenoteQuote" class="_formBlock">{{ i18n.ts.seperateRenoteQuote }}</FormSwitch> <FormSwitch v-model="useSystemFont" class="_formBlock">{{ i18n.ts.useSystemFont }}</FormSwitch> <FormSwitch v-model="useOsNativeEmojis" class="_formBlock"> {{ i18n.ts.useOsNativeEmojis }} @@ -144,6 +145,7 @@ const instanceTicker = computed(defaultStore.makeGetterSetter('instanceTicker')) const enableInfiniteScroll = computed(defaultStore.makeGetterSetter('enableInfiniteScroll')); const enterSendsMessage = computed(defaultStore.makeGetterSetter('enterSendsMessage')); const useReactionPickerForContextMenu = computed(defaultStore.makeGetterSetter('useReactionPickerForContextMenu')); +const seperateRenoteQuote = computed(defaultStore.makeGetterSetter('seperateRenoteQuote')); const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars')); const showUpdates = computed(defaultStore.makeGetterSetter('showUpdates')); const swipeOnDesktop = computed(defaultStore.makeGetterSetter('swipeOnDesktop')); @@ -181,6 +183,7 @@ watch([ showAds, showUpdates, swipeOnDesktop, + seperateRenoteQuote, ], async () => { await reloadAsk(); }); diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts index d66970e4c..6e044b465 100644 --- a/packages/client/src/store.ts +++ b/packages/client/src/store.ts @@ -123,6 +123,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: 'quiet' as 'nothing' | 'quiet' | 'reload' | 'dialog', }, + seperateRenoteQuote: { + where: 'device', + default: true, + }, nsfw: { where: 'device', default: 'respect' as 'respect' | 'force' | 'ignore',