summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2025-06-03 18:44:01 +0900
committerGitHub <noreply@github.com>2025-06-03 18:44:01 +0900
commit4af8c7f8b0a753cb91d5145de2906a895e636668 (patch)
tree80c0d0e61d1eb256db6ad2cc04996257c92ec41d /packages
parentfix(frontend): fix user search pagination (diff)
downloadmisskey-4af8c7f8b0a753cb91d5145de2906a895e636668.tar.gz
misskey-4af8c7f8b0a753cb91d5145de2906a895e636668.tar.bz2
misskey-4af8c7f8b0a753cb91d5145de2906a895e636668.zip
enhance(frontend): リアクションビューワーで使用可能なリアクションを優先して表示するオプション (#16149)
* enhance(frontend): リアクションビューワーで使用可能なリアクションを優先して表示するオプション * Update Changelog * tweak * fix * enhance: リアクティブじゃなくする --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages')
-rw-r--r--packages/frontend-shared/js/emojilist.ts4
-rw-r--r--packages/frontend/src/components/MkReactionsViewer.vue19
-rw-r--r--packages/frontend/src/pages/settings/preferences.vue10
-rw-r--r--packages/frontend/src/preferences/def.ts3
4 files changed, 35 insertions, 1 deletions
diff --git a/packages/frontend-shared/js/emojilist.ts b/packages/frontend-shared/js/emojilist.ts
index f8bbf39177..09bea06719 100644
--- a/packages/frontend-shared/js/emojilist.ts
+++ b/packages/frontend-shared/js/emojilist.ts
@@ -48,6 +48,10 @@ export function getUnicodeEmoji(char: string): UnicodeEmojiDef | string {
?? char;
}
+export function isSupportedEmoji(char: string): boolean {
+ return unicodeEmojisMap.has(colorizeEmoji(char)) || unicodeEmojisMap.has(char);
+}
+
export function getEmojiName(char: string): string {
// Colorize it because emojilist.json assumes that
const idx = _indexByChar.get(colorizeEmoji(char)) ?? _indexByChar.get(char);
diff --git a/packages/frontend/src/components/MkReactionsViewer.vue b/packages/frontend/src/components/MkReactionsViewer.vue
index 725978179e..bd9ef50157 100644
--- a/packages/frontend/src/components/MkReactionsViewer.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.vue
@@ -33,7 +33,10 @@ import * as Misskey from 'misskey-js';
import { inject, watch, ref } from 'vue';
import { TransitionGroup } from 'vue';
import XReaction from '@/components/MkReactionsViewer.reaction.vue';
+import { $i } from '@/i.js';
import { prefer } from '@/preferences.js';
+import { customEmojisMap } from '@/custom-emojis.js';
+import { isSupportedEmoji } from '@@/js/emojilist.js';
import { DI } from '@/di.js';
const props = withDefaults(defineProps<{
@@ -70,6 +73,12 @@ function onMockToggleReaction(emoji: string, count: number) {
emit('mockUpdateMyReaction', emoji, (count - _reactions.value[i][1]));
}
+function canReact(reaction: string) {
+ if (!$i) return false;
+ // TODO: CheckPermissions
+ return !reaction.match(/@\w/) && (customEmojisMap.has(reaction) || isSupportedEmoji(reaction));
+}
+
watch([() => props.reactions, () => props.maxNumber], ([newSource, maxNumber]) => {
let newReactions: [string, number][] = [];
hasMoreReactions.value = Object.keys(newSource).length > maxNumber;
@@ -86,7 +95,15 @@ watch([() => props.reactions, () => props.maxNumber], ([newSource, maxNumber]) =
newReactions = [
...newReactions,
...Object.entries(newSource)
- .sort(([, a], [, b]) => b - a)
+ .sort(([emojiA, countA], [emojiB, countB]) => {
+ if (prefer.s.showAvailableReactionsFirstInNote) {
+ if (!canReact(emojiA) && canReact(emojiB)) return 1;
+ if (canReact(emojiA) && !canReact(emojiB)) return -1;
+ return countB - countA;
+ } else {
+ return countB - countA;
+ }
+ })
.filter(([y], i) => i < maxNumber && !newReactionsNames.includes(y)),
];
diff --git a/packages/frontend/src/pages/settings/preferences.vue b/packages/frontend/src/pages/settings/preferences.vue
index 678cfb93c0..00f810cc37 100644
--- a/packages/frontend/src/pages/settings/preferences.vue
+++ b/packages/frontend/src/pages/settings/preferences.vue
@@ -229,6 +229,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
+
+ <SearchMarker :keywords="['reaction', 'order']">
+ <MkPreferenceContainer k="showAvailableReactionsFirstInNote">
+ <MkSwitch v-model="showAvailableReactionsFirstInNote">
+ <template #label><SearchLabel>{{ i18n.ts._settings.showAvailableReactionsFirstInNote }}</SearchLabel></template>
+ </MkSwitch>
+ </MkPreferenceContainer>
+ </SearchMarker>
</div>
<SearchMarker :keywords="['reaction', 'size', 'scale', 'display']">
@@ -824,6 +832,7 @@ const showFixedPostFormInChannel = prefer.model('showFixedPostFormInChannel');
const numberOfPageCache = prefer.model('numberOfPageCache');
const enableInfiniteScroll = prefer.model('enableInfiniteScroll');
const useReactionPickerForContextMenu = prefer.model('useReactionPickerForContextMenu');
+const showAvailableReactionsFirstInNote = prefer.model('showAvailableReactionsFirstInNote');
const useGroupedNotifications = prefer.model('useGroupedNotifications');
const alwaysConfirmFollow = prefer.model('alwaysConfirmFollow');
const confirmWhenRevealingSensitiveMedia = prefer.model('confirmWhenRevealingSensitiveMedia');
@@ -917,6 +926,7 @@ watch([
enableHorizontalSwipe,
enablePullToRefresh,
reduceAnimation,
+ showAvailableReactionsFirstInNote,
], async () => {
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
});
diff --git a/packages/frontend/src/preferences/def.ts b/packages/frontend/src/preferences/def.ts
index 5aadf835f2..6eb9b2408a 100644
--- a/packages/frontend/src/preferences/def.ts
+++ b/packages/frontend/src/preferences/def.ts
@@ -377,6 +377,9 @@ export const PREF_DEF = definePreferences({
showTitlebar: {
default: false,
},
+ showAvailableReactionsFirstInNote: {
+ default: false,
+ },
plugins: {
default: [] as Plugin[],
mergeStrategy: (a, b) => {