diff --git a/locales/en-US.yml b/locales/en-US.yml
index 9f675778a..880203922 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -96,6 +96,9 @@ unfollow: "Unfollow"
followRequestPending: "Follow request pending"
enterEmoji: "Enter an emoji"
renote: "Boost"
+renoteAsUnlisted: "Boost (Unlisted)"
+renoteToFollowers: "Boost (Followers)"
+renoteToRecipients: "Boost (Recipients)"
unrenote: "Take back boost"
renoted: "Boosted."
cantRenote: "This post can't be boosted."
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index b7ead22e8..0bdc4af1d 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -96,6 +96,9 @@ unfollow: "フォロー解除"
followRequestPending: "フォロー許可待ち"
enterEmoji: "絵文字を入力"
renote: "ブースト"
+renoteAsUnlisted: "ホームにブースト"
+renoteToFollowers: "フォロワー限定でブースト"
+renoteToRecipients: "宛先のユーザーにブースト"
unrenote: "ブースト解除"
renoted: "ブーストしました。"
cantRenote: "この投稿はブーストできません。"
diff --git a/packages/client/src/components/MkMenu.vue b/packages/client/src/components/MkMenu.vue
index 1b8a609c9..c0502387a 100644
--- a/packages/client/src/components/MkMenu.vue
+++ b/packages/client/src/components/MkMenu.vue
@@ -10,20 +10,26 @@
- {{ item.text }}
+ {{ item.text }}
+
+
+
- {{ item.text }}
+ {{ item.text }}
- {{ item.text }}
+
+
+
+ {{ item.text }}
- {{ item.text }}
+ {{ item.text }}
diff --git a/packages/client/src/components/MkRenoteButton.vue b/packages/client/src/components/MkRenoteButton.vue
index 5a9369a90..11bcd8bd5 100644
--- a/packages/client/src/components/MkRenoteButton.vue
+++ b/packages/client/src/components/MkRenoteButton.vue
@@ -64,24 +64,91 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
const users = renotes.map(x => x.user.id);
const hasRenotedBefore = users.includes($i.id);
- let buttonActions = [{
- text: i18n.ts.renote,
- icon: 'ph-repeat ph-bold ph-lg',
- danger: false,
- action: () => {
- os.api('notes/create', {
- renoteId: props.note.id,
- visibility: props.note.visibility,
- });
- const el = ev && (ev.currentTarget ?? ev.target) as HTMLElement | null | undefined;
- if (el) {
- const rect = el.getBoundingClientRect();
- const x = rect.left + (el.offsetWidth / 2);
- const y = rect.top + (el.offsetHeight / 2);
- os.popup(Ripple, { x, y }, {}, 'end');
- }
- },
- }];
+ let buttonActions = [];
+
+ if (props.note.visibility === 'public') {
+ buttonActions.push({
+ text: i18n.ts.renote,
+ textStyle: 'font-weight: bold',
+ icon: 'ph-repeat ph-bold ph-lg',
+ danger: false,
+ action: () => {
+ os.api('notes/create', {
+ renoteId: props.note.id,
+ visibility: 'public',
+ });
+ const el = ev && (ev.currentTarget ?? ev.target) as HTMLElement | null | undefined;
+ if (el) {
+ const rect = el.getBoundingClientRect();
+ const x = rect.left + (el.offsetWidth / 2);
+ const y = rect.top + (el.offsetHeight / 2);
+ os.popup(Ripple, { x, y }, {}, 'end');
+ }
+ },
+ });
+ }
+
+ if (['public', 'home'].includes(props.note.visibility)) {
+ buttonActions.push({
+ text: i18n.ts.renoteAsUnlisted,
+ icons: ['ph-repeat ph-bold ph-lg', 'ph-house ph-bold ph-lg'],
+ danger: false,
+ action: () => {
+ os.api('notes/create', {
+ renoteId: props.note.id,
+ visibility: 'home',
+ });
+ const el = ev && (ev.currentTarget ?? ev.target) as HTMLElement | null | undefined;
+ if (el) {
+ const rect = el.getBoundingClientRect();
+ const x = rect.left + (el.offsetWidth / 2);
+ const y = rect.top + (el.offsetHeight / 2);
+ os.popup(Ripple, { x, y }, {}, 'end');
+ }
+ },
+ });
+ }
+
+ if (props.note.visibility === 'specified') {
+ buttonActions.push({
+ text: i18n.ts.renoteToRecipients,
+ icons: ['ph-repeat ph-bold ph-lg', 'ph-envelope-simple-open ph-bold ph-lg'],
+ danger: false,
+ action: () => {
+ os.api('notes/create', {
+ renoteId: props.note.id,
+ visibility: 'specified',
+ visibleUserIds: props.note.visibleUserIds,
+ });
+ const el = ev && (ev.currentTarget ?? ev.target) as HTMLElement | null | undefined;
+ if (el) {
+ const rect = el.getBoundingClientRect();
+ const x = rect.left + (el.offsetWidth / 2);
+ const y = rect.top + (el.offsetHeight / 2);
+ os.popup(Ripple, { x, y }, {}, 'end');
+ }
+ },
+ });
+ } else {
+ buttonActions.push({
+ text: i18n.ts.renoteToFollowers,
+ icons: ['ph-repeat ph-bold ph-lg', 'ph-lock-simple-open ph-bold ph-lg'],
+ danger: false,
+ action: () => {
+ os.api('notes/create', {
+ renoteId: props.note.id,
+ visibility: 'followers',
+ });
+ const el = ev && (ev.currentTarget ?? ev.target) as HTMLElement | null | undefined;
+ if (el) {
+ const rect = el.getBoundingClientRect();
+ const x = rect.left + (el.offsetWidth / 2);
+ const y = rect.top + (el.offsetHeight / 2);
+ os.popup(Ripple, { x, y }, {}, 'end');
+ }
+ },
+ });
+ }
if (!defaultStore.state.seperateRenoteQuote) {
buttonActions.push({
diff --git a/packages/client/src/types/menu.ts b/packages/client/src/types/menu.ts
index e1bfc20a3..a7ce81c71 100644
--- a/packages/client/src/types/menu.ts
+++ b/packages/client/src/types/menu.ts
@@ -5,11 +5,16 @@ export type MenuAction = (ev: MouseEvent) => void;
export type MenuDivider = null;
export type MenuNull = undefined;
-export type MenuLabel = { type: "label"; text: string };
+export type MenuLabel = {
+ type: "label";
+ text: string;
+ textStyle?: string;
+};
export type MenuLink = {
type: "link";
to: string;
text: string;
+ textStyle?: string;
icon?: string;
indicate?: boolean;
avatar?: Misskey.entities.User;
@@ -20,6 +25,7 @@ export type MenuA = {
target?: string;
download?: string;
text: string;
+ textStyle?: string;
icon?: string;
indicate?: boolean;
};
@@ -35,11 +41,13 @@ export type MenuSwitch = {
type: "switch";
ref: Ref;
text: string;
+ textStyle?: string;
disabled?: boolean;
};
export type MenuButton = {
type?: "button";
text: string;
+ textStyle?: string;
icon?: string;
indicate?: boolean;
danger?: boolean;
@@ -48,9 +56,22 @@ export type MenuButton = {
avatar?: Misskey.entities.User;
action: MenuAction;
};
+export type MenuButtonMultipleIcons = {
+ type?: "button";
+ text: string;
+ textStyle?: string;
+ icons: string[];
+ indicate?: boolean;
+ danger?: boolean;
+ active?: boolean;
+ hidden?: boolean;
+ avatar?: Misskey.entities.User;
+ action: MenuAction;
+};
export type MenuParent = {
type: "parent";
text: string;
+ textStyle?: string;
icon?: string;
children: OuterMenuItem[];
};
@@ -66,9 +87,10 @@ type OuterMenuItem =
| MenuUser
| MenuSwitch
| MenuButton
+ | MenuButtonMultipleIcons
| MenuParent;
type OuterPromiseMenuItem = Promise<
- MenuLabel | MenuLink | MenuA | MenuUser | MenuSwitch | MenuButton | MenuParent
+ MenuLabel | MenuLink | MenuA | MenuUser | MenuSwitch | MenuButton | MenuButtonMultipleIcons | MenuParent
>;
export type MenuItem = OuterMenuItem | OuterPromiseMenuItem;
export type InnerMenuItem =
@@ -80,4 +102,5 @@ export type InnerMenuItem =
| MenuUser
| MenuSwitch
| MenuButton
+ | MenuButtonMultipleIcons
| MenuParent;