Merge branch 'develop' into watermark
This commit is contained in:
commit
3bbba7356c
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
- Feat: 画像にウォーターマークを付与できるようになりました
|
- Feat: 画像にウォーターマークを付与できるようになりました
|
||||||
|
- Enhance: ノートのリアクション一覧で、押せるリアクションを優先して表示できるようにするオプションを追加
|
||||||
- Fix: ドライブファイルの選択が不安定な問題を修正
|
- Fix: ドライブファイルの選択が不安定な問題を修正
|
||||||
- Fix: コントロールパネルのファイル欄などのデザインが崩れている問題を修正
|
- Fix: コントロールパネルのファイル欄などのデザインが崩れている問題を修正
|
||||||
- Fix: ユーザーの検索結果を追加で読み込むことができない問題を修正
|
- Fix: ユーザーの検索結果を追加で読み込むことができない問題を修正
|
||||||
|
|
|
@ -5829,6 +5829,10 @@ export interface Locale extends ILocale {
|
||||||
* URLプレビューを表示する
|
* URLプレビューを表示する
|
||||||
*/
|
*/
|
||||||
"showUrlPreview": string;
|
"showUrlPreview": string;
|
||||||
|
/**
|
||||||
|
* 利用できるリアクションを先頭に表示
|
||||||
|
*/
|
||||||
|
"showAvailableReactionsFirstInNote": string;
|
||||||
"_chat": {
|
"_chat": {
|
||||||
/**
|
/**
|
||||||
* 送信者の名前を表示
|
* 送信者の名前を表示
|
||||||
|
|
|
@ -1457,6 +1457,7 @@ _settings:
|
||||||
contentsUpdateFrequency_description: "高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。"
|
contentsUpdateFrequency_description: "高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。"
|
||||||
contentsUpdateFrequency_description2: "リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。"
|
contentsUpdateFrequency_description2: "リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。"
|
||||||
showUrlPreview: "URLプレビューを表示する"
|
showUrlPreview: "URLプレビューを表示する"
|
||||||
|
showAvailableReactionsFirstInNote: "利用できるリアクションを先頭に表示"
|
||||||
|
|
||||||
_chat:
|
_chat:
|
||||||
showSenderName: "送信者の名前を表示"
|
showSenderName: "送信者の名前を表示"
|
||||||
|
|
|
@ -48,6 +48,10 @@ export function getUnicodeEmoji(char: string): UnicodeEmojiDef | string {
|
||||||
?? char;
|
?? char;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isSupportedEmoji(char: string): boolean {
|
||||||
|
return unicodeEmojisMap.has(colorizeEmoji(char)) || unicodeEmojisMap.has(char);
|
||||||
|
}
|
||||||
|
|
||||||
export function getEmojiName(char: string): string {
|
export function getEmojiName(char: string): string {
|
||||||
// Colorize it because emojilist.json assumes that
|
// Colorize it because emojilist.json assumes that
|
||||||
const idx = _indexByChar.get(colorizeEmoji(char)) ?? _indexByChar.get(char);
|
const idx = _indexByChar.get(colorizeEmoji(char)) ?? _indexByChar.get(char);
|
||||||
|
|
|
@ -33,7 +33,10 @@ import * as Misskey from 'misskey-js';
|
||||||
import { inject, watch, ref } from 'vue';
|
import { inject, watch, ref } from 'vue';
|
||||||
import { TransitionGroup } from 'vue';
|
import { TransitionGroup } from 'vue';
|
||||||
import XReaction from '@/components/MkReactionsViewer.reaction.vue';
|
import XReaction from '@/components/MkReactionsViewer.reaction.vue';
|
||||||
|
import { $i } from '@/i.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
|
import { customEmojisMap } from '@/custom-emojis.js';
|
||||||
|
import { isSupportedEmoji } from '@@/js/emojilist.js';
|
||||||
import { DI } from '@/di.js';
|
import { DI } from '@/di.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
|
@ -70,6 +73,12 @@ function onMockToggleReaction(emoji: string, count: number) {
|
||||||
emit('mockUpdateMyReaction', emoji, (count - _reactions.value[i][1]));
|
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]) => {
|
watch([() => props.reactions, () => props.maxNumber], ([newSource, maxNumber]) => {
|
||||||
let newReactions: [string, number][] = [];
|
let newReactions: [string, number][] = [];
|
||||||
hasMoreReactions.value = Object.keys(newSource).length > maxNumber;
|
hasMoreReactions.value = Object.keys(newSource).length > maxNumber;
|
||||||
|
@ -86,7 +95,15 @@ watch([() => props.reactions, () => props.maxNumber], ([newSource, maxNumber]) =
|
||||||
newReactions = [
|
newReactions = [
|
||||||
...newReactions,
|
...newReactions,
|
||||||
...Object.entries(newSource)
|
...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)),
|
.filter(([y], i) => i < maxNumber && !newReactionsNames.includes(y)),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
</MkPreferenceContainer>
|
</MkPreferenceContainer>
|
||||||
</SearchMarker>
|
</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>
|
</div>
|
||||||
|
|
||||||
<SearchMarker :keywords="['reaction', 'size', 'scale', 'display']">
|
<SearchMarker :keywords="['reaction', 'size', 'scale', 'display']">
|
||||||
|
@ -824,6 +832,7 @@ const showFixedPostFormInChannel = prefer.model('showFixedPostFormInChannel');
|
||||||
const numberOfPageCache = prefer.model('numberOfPageCache');
|
const numberOfPageCache = prefer.model('numberOfPageCache');
|
||||||
const enableInfiniteScroll = prefer.model('enableInfiniteScroll');
|
const enableInfiniteScroll = prefer.model('enableInfiniteScroll');
|
||||||
const useReactionPickerForContextMenu = prefer.model('useReactionPickerForContextMenu');
|
const useReactionPickerForContextMenu = prefer.model('useReactionPickerForContextMenu');
|
||||||
|
const showAvailableReactionsFirstInNote = prefer.model('showAvailableReactionsFirstInNote');
|
||||||
const useGroupedNotifications = prefer.model('useGroupedNotifications');
|
const useGroupedNotifications = prefer.model('useGroupedNotifications');
|
||||||
const alwaysConfirmFollow = prefer.model('alwaysConfirmFollow');
|
const alwaysConfirmFollow = prefer.model('alwaysConfirmFollow');
|
||||||
const confirmWhenRevealingSensitiveMedia = prefer.model('confirmWhenRevealingSensitiveMedia');
|
const confirmWhenRevealingSensitiveMedia = prefer.model('confirmWhenRevealingSensitiveMedia');
|
||||||
|
@ -900,7 +909,6 @@ watch([
|
||||||
reactionsDisplaySize,
|
reactionsDisplaySize,
|
||||||
limitWidthOfReaction,
|
limitWidthOfReaction,
|
||||||
mediaListWithOneImageAppearance,
|
mediaListWithOneImageAppearance,
|
||||||
reactionsDisplaySize,
|
|
||||||
limitWidthOfReaction,
|
limitWidthOfReaction,
|
||||||
instanceTicker,
|
instanceTicker,
|
||||||
squareAvatars,
|
squareAvatars,
|
||||||
|
@ -917,6 +925,7 @@ watch([
|
||||||
enableHorizontalSwipe,
|
enableHorizontalSwipe,
|
||||||
enablePullToRefresh,
|
enablePullToRefresh,
|
||||||
reduceAnimation,
|
reduceAnimation,
|
||||||
|
showAvailableReactionsFirstInNote,
|
||||||
], async () => {
|
], async () => {
|
||||||
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
|
await reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
|
||||||
});
|
});
|
||||||
|
|
|
@ -378,6 +378,9 @@ export const PREF_DEF = definePreferences({
|
||||||
showTitlebar: {
|
showTitlebar: {
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
showAvailableReactionsFirstInNote: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
default: [] as Plugin[],
|
default: [] as Plugin[],
|
||||||
mergeStrategy: (a, b) => {
|
mergeStrategy: (a, b) => {
|
||||||
|
|
Loading…
Reference in New Issue