From a07483996ef3ac2b7e2a52ff0841f1fb6ba55121 Mon Sep 17 00:00:00 2001
From: Lhcfl <Lhcfl@outlook.com>
Date: Mon, 15 Apr 2024 15:12:51 +0800
Subject: [PATCH 1/3] feat: add slash quote

---
 locales/en-US.yml                             |  1 +
 locales/zh-CN.yml                             |  1 +
 packages/client/src/components/MkPostForm.vue | 17 ++++--
 .../src/components/MkPostFormDialog.vue       |  5 ++
 .../client/src/components/MkQuoteButton.vue   | 54 ++++++++++++++++++-
 5 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/locales/en-US.yml b/locales/en-US.yml
index d552e1e3a2..ce6fd91ca1 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -2229,3 +2229,4 @@ autocorrectNoteLanguage: "Show a warning if the post language does not match the
 incorrectLanguageWarning: "It looks like your post is in {detected}, but you selected
   {current}.\nWould you like to set the language to {detected} instead?"
 noteEditHistory: "Post edit history"
+slashQuote: "Slash quote"
diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml
index c496d05381..552efb268e 100644
--- a/locales/zh-CN.yml
+++ b/locales/zh-CN.yml
@@ -2057,3 +2057,4 @@ autocorrectNoteLanguage: 当帖子语言不符合自动检测的结果的时候
 incorrectLanguageWarning: "看上去您帖子使用的语言是{detected},但您选择的语言是{current}。\n要改为以{detected}发帖吗?"
 noteEditHistory: "帖子编辑历史"
 media: 媒体
+slashQuote: "斜杠引用"
diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue
index aeb51f7bf7..528b98d9d2 100644
--- a/packages/client/src/components/MkPostForm.vue
+++ b/packages/client/src/components/MkPostForm.vue
@@ -363,6 +363,11 @@ const props = withDefaults(
 		autofocus?: boolean;
 		showMfmCheatSheet?: boolean;
 		editId?: entities.Note["id"];
+		selectRange?: [
+			start: number,
+			end: number,
+			direction?: "forward" | "backward" | "none",
+		];
 	}>(),
 	{
 		initialVisibleUsers: () => [],
@@ -683,10 +688,14 @@ function togglePoll() {
 function focus() {
 	if (textareaEl.value) {
 		textareaEl.value.focus();
-		textareaEl.value.setSelectionRange(
-			textareaEl.value.value.length,
-			textareaEl.value.value.length,
-		);
+		if (props.selectRange) {
+			textareaEl.value.setSelectionRange(...props.selectRange);
+		} else {
+			textareaEl.value.setSelectionRange(
+				textareaEl.value.value.length,
+				textareaEl.value.value.length,
+			);
+		}
 	}
 }
 
diff --git a/packages/client/src/components/MkPostFormDialog.vue b/packages/client/src/components/MkPostFormDialog.vue
index 56f009c338..8b09475ff8 100644
--- a/packages/client/src/components/MkPostFormDialog.vue
+++ b/packages/client/src/components/MkPostFormDialog.vue
@@ -43,6 +43,11 @@ const props = defineProps<{
 	fixed?: boolean;
 	autofocus?: boolean;
 	editId?: entities.Note["id"];
+	selectRange?: [
+		start: number,
+		end: number,
+		direction?: "forward" | "backward" | "none",
+	];
 }>();
 
 const emit = defineEmits<{
diff --git a/packages/client/src/components/MkQuoteButton.vue b/packages/client/src/components/MkQuoteButton.vue
index f4004b0cdb..2617d3655e 100644
--- a/packages/client/src/components/MkQuoteButton.vue
+++ b/packages/client/src/components/MkQuoteButton.vue
@@ -1,5 +1,6 @@
 <template>
 	<button
+		ref="el"
 		v-if="canRenote && defaultStore.state.seperateRenoteQuote"
 		v-tooltip.noDelay.bottom="i18n.ts.quote"
 		class="eddddedb _button"
@@ -10,8 +11,8 @@
 </template>
 
 <script lang="ts" setup>
-import { computed } from "vue";
-import type { entities } from "firefish-js";
+import { computed, ref } from "vue";
+import { acct, type entities } from "firefish-js";
 import { pleaseLogin } from "@/scripts/please-login";
 import * as os from "@/os";
 import { me } from "@/me";
@@ -23,6 +24,8 @@ const props = defineProps<{
 	note: entities.Note;
 }>();
 
+const el = ref<HTMLButtonElement>();
+
 const canRenote = computed(
 	() =>
 		["public", "home"].includes(props.note.visibility) ||
@@ -31,10 +34,57 @@ const canRenote = computed(
 
 function quote(): void {
 	pleaseLogin();
+	if (
+		props.note.renote != null &&
+		(props.note.text != null ||
+			props.note.fileIds.length === 0 ||
+			props.note.poll != null)
+	) {
+		menu();
+	} else {
+		normalQuote();
+	}
+}
+
+function normalQuote(): void {
 	os.post({
 		renote: props.note,
 	});
 }
+
+function slashQuote(): void {
+	os.post({
+		initialText: ` // @${acct.toString(props.note.user)}: ${props.note.text}`,
+		selectRange: [0, 0],
+		renote: props.note.renote,
+		channel: props.note.channel,
+	});
+}
+
+function menu(viaKeyboard = false): void {
+	os.popupMenu(
+		[
+			{
+				text: i18n.ts.quote,
+				icon: `${icon("ph-quotes")}`,
+				action: normalQuote,
+			},
+			{
+				text: i18n.ts.slashQuote,
+				icon: `${icon("ph-notches")}`,
+				action: slashQuote,
+			},
+		],
+		el.value,
+		{
+			viaKeyboard,
+		},
+	).then(focus);
+}
+
+function focus(): void {
+	el.value!.focus();
+}
 </script>
 
 <style lang="scss" scoped>

From a85652311943c817f1cc2d14af8313e53409e4e4 Mon Sep 17 00:00:00 2001
From: Lhcfl <Lhcfl@outlook.com>
Date: Mon, 22 Apr 2024 09:09:39 +0800
Subject: [PATCH 2/3] fix: add slashquote in MkRenoteButton

---
 .../client/src/components/MkRenoteButton.vue  | 24 ++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/packages/client/src/components/MkRenoteButton.vue b/packages/client/src/components/MkRenoteButton.vue
index 7250757da4..4a1c44029d 100644
--- a/packages/client/src/components/MkRenoteButton.vue
+++ b/packages/client/src/components/MkRenoteButton.vue
@@ -22,7 +22,7 @@
 
 <script lang="ts" setup>
 import { computed, ref } from "vue";
-import type { entities } from "firefish-js";
+import { acct, type entities } from "firefish-js";
 import Ripple from "@/components/MkRipple.vue";
 import XDetails from "@/components/MkUsersTooltip.vue";
 import { pleaseLogin } from "@/scripts/please-login";
@@ -231,6 +231,28 @@ const renote = (viaKeyboard = false, ev?: MouseEvent) => {
 				});
 			},
 		});
+		if (
+			props.note.renote != null &&
+			(props.note.text != null ||
+				props.note.fileIds.length === 0 ||
+				props.note.poll != null)
+		) {
+			buttonActions.push({
+				text: i18n.ts.slashQuote,
+				icon: `${icon("ph-notches")}`,
+				danger: false,
+				action: () => {
+					os.post({
+						initialText: ` // @${acct.toString(props.note.user)}: ${
+							props.note.text
+						}`,
+						selectRange: [0, 0],
+						renote: props.note.renote,
+						channel: props.note.channel,
+					});
+				},
+			});
+		}
 	}
 
 	if (hasRenotedBefore.value) {

From 0272b08df8e1c890dc89bad7d5dc1d0d7a46edc0 Mon Sep 17 00:00:00 2001
From: naskya <m@naskya.net>
Date: Sun, 28 Apr 2024 09:02:03 +0900
Subject: [PATCH 3/3] locale: update en-US.yml

---
 locales/en-US.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/locales/en-US.yml b/locales/en-US.yml
index 7b46795097..08fcc490ea 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -2239,5 +2239,5 @@ autocorrectNoteLanguage: "Show a warning if the post language does not match the
 incorrectLanguageWarning: "It looks like your post is in {detected}, but you selected
   {current}.\nWould you like to set the language to {detected} instead?"
 noteEditHistory: "Post edit history"
-slashQuote: "Slash quote"
+slashQuote: "Chain quote"
 foldNotification: "Group similar notifications"