Skip to content

Commit 78ff90f

Browse files
authored
Merge pull request #13493 from misskey-dev/develop
Release: 2024.3.1
2 parents 7e706ea + 3afdafe commit 78ff90f

17 files changed

+124
-33
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@
1212
1313
-->
1414

15+
## 2024.3.1
16+
17+
### General
18+
-
19+
20+
### Client
21+
- Fix: 絵文字関係の不具合を修正 (#13485)
22+
- 履歴に残っている or ピン留めされた絵文字がコントロールパネルより削除されていた際にリアクションデッキが表示できなくなる
23+
- Unicode絵文字が履歴に残っている or ピン留めされているとリアクションデッキが表示できなくなる
24+
- Fix: カスタム絵文字の画像読み込みに失敗した際はテキストではなくダミー画像を表示 #13487
25+
26+
### Server
27+
-
28+
1529
## 2024.3.0
1630

1731
### General

locales/fr-FR.yml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,11 @@ hcaptcha: "hCaptcha"
380380
enableHcaptcha: "Activer hCaptcha"
381381
hcaptchaSiteKey: "Clé du site"
382382
hcaptchaSecretKey: "Clé secrète"
383+
mcaptcha: "mCaptcha"
384+
enableMcaptcha: "Activer mCaptcha"
383385
mcaptchaSiteKey: "Clé du site"
384386
mcaptchaSecretKey: "Clé secrète"
387+
mcaptchaInstanceUrl: "URL de l'instance de mCaptcha"
385388
recaptcha: "reCAPTCHA"
386389
enableRecaptcha: "Activer reCAPTCHA"
387390
recaptchaSiteKey: "Clé du site"
@@ -523,7 +526,7 @@ hideThisNote: "Masquer cette note"
523526
showFeaturedNotesInTimeline: "Afficher les notes des Tendances dans le fil d'actualité"
524527
objectStorage: "Stockage d'objets"
525528
useObjectStorage: "Utiliser le stockage d'objets"
526-
objectStorageBaseUrl: "Base URL"
529+
objectStorageBaseUrl: "URL de base"
527530
objectStorageBaseUrlDesc: "Préfixe d’URL utilisé pour construire l’URL vers le référencement d’objet (média). Spécifiez son URL si vous utilisez un CDN ou un proxy, sinon spécifiez l’adresse accessible au public selon le guide de service que vous allez utiliser. P.ex. 'https://<bucket>.s3.amazonaws.com' pour AWS S3 et 'https://storage.googleapis.com/<bucket>' pour GCS."
528531
objectStorageBucket: "Bucket"
529532
objectStorageBucketDesc: "Veuillez spécifier le nom du compartiment utilisé sur le service configuré."
@@ -628,6 +631,7 @@ medium: "Moyen"
628631
small: "Petit"
629632
generateAccessToken: "Générer un jeton d'accès"
630633
permission: "Autorisations "
634+
adminPermission: "Droits de l'administrateur"
631635
enableAll: "Tout activer"
632636
disableAll: "Tout désactiver"
633637
tokenRequested: "Autoriser l'accès au compte"
@@ -1031,12 +1035,18 @@ nonSensitiveOnlyForLocalLikeOnlyForRemote: "Non sensibles seulement (mentions j'
10311035
rolesAssignedToMe: "Rôles attribués à moi"
10321036
resetPasswordConfirm: "Souhaitez-vous réinitialiser votre mot de passe ?"
10331037
sensitiveWords: "Mots sensibles"
1038+
sensitiveWordsDescription2: "Séparer par une espace pour créer une expression AND ; entourer de barres obliques pour créer une expression régulière."
1039+
prohibitedWords: "Mots interdits"
1040+
prohibitedWordsDescription2: "Séparer par une espace pour créer une expression AND ; entourer de barres obliques pour créer une expression régulière."
10341041
hiddenTags: "Hashtags cachés"
10351042
hiddenTagsDescription: "Les hashtags définis ne s'afficheront pas dans les tendances. Vous pouvez définir plusieurs hashtags en faisant un saut de ligne."
10361043
notesSearchNotAvailable: "La recherche de notes n'est pas disponible."
10371044
license: "Licence"
1045+
unfavoriteConfirm: "Vraiment supprimer des favoris ?"
10381046
myClips: "Mes clips"
10391047
drivecleaner: "Nettoyeur du Disque"
1048+
retryAllQueuesNow: "Réessayer tous les fils d'attente immédiatement"
1049+
retryAllQueuesConfirmTitle: "Vraiment réessayer ?"
10401050
retryAllQueuesConfirmText: "Cela peut augmenter temporairement la charge du serveur."
10411051
enableChartsForRemoteUser: "Générer les graphiques pour les utilisateurs distants"
10421052
enableChartsForFederatedInstances: "Générer les graphiques pour les instances distantes"
@@ -1046,6 +1056,8 @@ limitWidthOfReaction: "Limiter la largeur maximale des réactions et les affiche
10461056
noteIdOrUrl: "Identifiant de la note ou URL"
10471057
video: "Vidéo"
10481058
videos: "Vidéos"
1059+
audio: "Audio"
1060+
audioFiles: "Fichiers audio"
10491061
dataSaver: "Économiseur de données"
10501062
accountMigration: "Migration de compte"
10511063
accountMoved: "Cet·te utilisateur·rice a migré son compte vers :"
@@ -1084,7 +1096,10 @@ specifyUser: "Spécifier l'utilisateur·rice"
10841096
failedToPreviewUrl: "Aperçu d'URL échoué"
10851097
update: "Mettre à jour"
10861098
rolesThatCanBeUsedThisEmojiAsReaction: "Rôles qui peuvent utiliser cet émoji comme réaction"
1099+
rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription: "Si aucun rôle n'est spécifié, tout le monde peut utiliser cet émoji comme réaction."
1100+
rolesThatCanBeUsedThisEmojiAsReactionPublicRoleWarn: "Il faut un rôle public."
10871101
cancelReactionConfirm: "Supprimez la réaction ?"
1102+
changeReactionConfirm: "Changer la réaction ?"
10881103
later: "Plus tard"
10891104
goToMisskey: "Retour vers Misskey"
10901105
additionalEmojiDictionary: "Dictionnaires d'émojis additionnels"
@@ -1110,11 +1125,13 @@ used: "Utilisé"
11101125
expired: "Expiré"
11111126
doYouAgree: "Êtes-vous d’accord ?"
11121127
beSureToReadThisAsItIsImportant: "Assurez-vous de le lire ; c'est important."
1128+
iHaveReadXCarefullyAndAgree: "J'ai lu le contenu de « {x} » et donne mon accord."
11131129
dialog: "Dialogue"
11141130
icon: "Avatar"
11151131
forYou: "Pour vous"
11161132
currentAnnouncements: "Annonces actuelles"
11171133
pastAnnouncements: "Annonces passées"
1134+
youHaveUnreadAnnouncements: "Il y a des annonces non lues."
11181135
replies: "Réponses"
11191136
renotes: "Renotes"
11201137
loadReplies: "Inclure les réponses"
@@ -1129,6 +1146,7 @@ showRenotes: "Afficher les renotes"
11291146
edited: "Modifié"
11301147
notificationRecieveConfig: "Paramètres des notifications"
11311148
mutualFollow: "Abonnement mutuel"
1149+
fileAttachedOnly: "Avec fichiers joints seulement"
11321150
showRepliesToOthersInTimeline: "Afficher les réponses aux autres dans le fil"
11331151
hideRepliesToOthersInTimeline: "Masquer les réponses aux autres dans le fil"
11341152
showRepliesToOthersInTimelineAll: "Afficher les réponses de toutes les personnes que vous suivez dans le fil"
@@ -1137,6 +1155,11 @@ confirmShowRepliesAll: "Cette opération est irréversible. Voulez-vous vraiment
11371155
confirmHideRepliesAll: "Cette opération est irréversible. Voulez-vous vraiment masquer les réponses de toutes les personnes que vous suivez dans le fil ?"
11381156
externalServices: "Services externes"
11391157
sourceCode: "Code source"
1158+
sourceCodeIsNotYetProvided: "Le code source n'est pas encore disponible. Veuillez signaler ce problème aux administrateurs."
1159+
repositoryUrl: "URL du dépôt"
1160+
repositoryUrlDescription: "Entrez l'URL du dépôt où se trouve le code source ici. Si vous utilisez Misskey tel quel (sans changer le code source), entrez https://github.com/misskey-dev/misskey"
1161+
feedback: "Commentaires"
1162+
feedbackUrl: "URL pour les commentaires"
11401163
impressum: "Impressum"
11411164
impressumUrl: "URL de l'impressum"
11421165
impressumDescription: "Dans certains pays comme l'Allemagne, il est obligatoire d'afficher les informations sur l'opérateur d'un site (un impressum)."
@@ -1164,11 +1187,32 @@ remainingN: "Restants : {n}"
11641187
overwriteContentConfirm: "Voulez-vous remplacer le contenu actuel ?"
11651188
seasonalScreenEffect: "Effet d'écran saisonnier"
11661189
decorate: "Décorer"
1190+
addMfmFunction: "Insérer MFM"
1191+
enableQuickAddMfmFunction: "Afficher le sélecteur de MFM avancé"
1192+
bubbleGame: "Jeu de bulles"
11671193
sfx: "Effets sonores"
1194+
soundWillBePlayed: "Le son sera joué"
11681195
showReplay: "Voir le replay"
1196+
replay: "Rediffusion"
1197+
replaying: "En cours de rediffusion"
1198+
endReplay: "Arrêter la rediffusion"
1199+
copyReplayData: "Copier les données de la rediffusion"
11691200
ranking: "Classement"
11701201
lastNDays: "Derniers {n} jours"
1202+
backToTitle: "Retourner au titre"
1203+
hemisphere: "Votre région"
1204+
enableHorizontalSwipe: "Glisser pour changer d'onglet"
1205+
loading: "Chargement en cours"
11711206
surrender: "Annuler"
1207+
gameRetry: "Réessayer"
1208+
_bubbleGame:
1209+
howToPlay: "Comment jouer"
1210+
hold: "Réserver"
1211+
_score:
1212+
score: "Score"
1213+
scoreYen: "Montant gagné"
1214+
highScore: "Meilleur score"
1215+
yen: "{yen} yens"
11721216
_announcement:
11731217
forExistingUsers: "Pour les utilisateurs existants seulement"
11741218
readConfirmTitle: "Marquer comme lu ?"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "misskey",
3-
"version": "2024.3.0",
3+
"version": "2024.3.1",
44
"codename": "nasubi",
55
"repository": {
66
"type": "git",

packages/frontend/src/components/MkAutocomplete.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
2222
</ol>
2323
<ol v-else-if="emojis.length > 0" ref="suggests" :class="$style.list">
2424
<li v-for="emoji in emojis" :key="emoji.emoji" :class="$style.item" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
25-
<MkCustomEmoji v-if="'isCustomEmoji' in emoji && emoji.isCustomEmoji" :name="emoji.emoji" :class="$style.emoji"/>
25+
<MkCustomEmoji v-if="'isCustomEmoji' in emoji && emoji.isCustomEmoji" :name="emoji.emoji" :class="$style.emoji" :fallbackToImage="true"/>
2626
<MkEmoji v-else :emoji="emoji.emoji" :class="$style.emoji"/>
2727
<!-- eslint-disable-next-line vue/no-v-html -->
2828
<span v-if="q" :class="$style.emojiName" v-html="sanitizeHtml(emoji.name.replace(q, `<b>${q}</b>`))"></span>
@@ -77,7 +77,7 @@ const emojiDb = computed(() => {
7777
unicodeEmojiDB.push({
7878
emoji: emoji,
7979
name: k,
80-
aliasOf: getEmojiName(emoji)!,
80+
aliasOf: getEmojiName(emoji),
8181
url: char2path(emoji),
8282
});
8383
}

packages/frontend/src/components/MkEmojiPicker.section.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
2020
@pointerenter="computeButtonTitle"
2121
@click="emit('chosen', emoji, $event)"
2222
>
23-
<MkCustomEmoji v-if="emoji[0] === ':'" class="emoji" :name="emoji" :normal="true"/>
23+
<MkCustomEmoji v-if="emoji[0] === ':'" class="emoji" :name="emoji" :normal="true" :fallbackToImage="true"/>
2424
<MkEmoji v-else class="emoji" :emoji="emoji" :normal="true"/>
2525
</button>
2626
</div>
@@ -87,7 +87,7 @@ const shown = ref(!!props.initialShown);
8787
function computeButtonTitle(ev: MouseEvent): void {
8888
const elm = ev.target as HTMLElement;
8989
const emoji = elm.dataset.emoji as string;
90-
elm.title = getEmojiName(emoji) ?? emoji;
90+
elm.title = getEmojiName(emoji);
9191
}
9292
9393
function nestedChosen(emoji: any, ev: MouseEvent) {

packages/frontend/src/components/MkEmojiPicker.vue

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
1919
tabindex="0"
2020
@click="chosen(emoji, $event)"
2121
>
22-
<MkCustomEmoji class="emoji" :name="emoji.name"/>
22+
<MkCustomEmoji class="emoji" :name="emoji.name" :fallbackToImage="true"/>
2323
</button>
2424
</div>
2525
<div v-if="searchResultUnicode.length > 0" class="body">
@@ -353,7 +353,7 @@ watch(q, () => {
353353
searchResultUnicode.value = Array.from(searchUnicode());
354354
});
355355
356-
function canReact(emoji: Misskey.entities.EmojiSimple | UnicodeEmojiDef): boolean {
356+
function canReact(emoji: Misskey.entities.EmojiSimple | UnicodeEmojiDef | string): boolean {
357357
return !props.targetNote || checkReactionPermissions($i!, props.targetNote, emoji);
358358
}
359359
@@ -378,19 +378,22 @@ function getKey(emoji: string | Misskey.entities.EmojiSimple | UnicodeEmojiDef):
378378
return typeof emoji === 'string' ? emoji : 'char' in emoji ? emoji.char : `:${emoji.name}:`;
379379
}
380380
381-
function getDef(emoji: string) {
381+
function getDef(emoji: string): string | Misskey.entities.EmojiSimple | UnicodeEmojiDef {
382382
if (emoji.includes(':')) {
383-
return customEmojisMap.get(emoji.replace(/:/g, ''))!;
383+
// カスタム絵文字が存在する場合はその情報を持つオブジェクトを返し、
384+
// サーバの管理画面から削除された等で情報が見つからない場合は名前の文字列をそのまま返しておく(undefinedを返すとエラーになるため)
385+
const name = emoji.replaceAll(':', '');
386+
return customEmojisMap.get(name) ?? emoji;
384387
} else {
385-
return getUnicodeEmoji(emoji)!;
388+
return getUnicodeEmoji(emoji);
386389
}
387390
}
388391
389392
/** @see MkEmojiPicker.section.vue */
390393
function computeButtonTitle(ev: MouseEvent): void {
391394
const elm = ev.target as HTMLElement;
392395
const emoji = elm.dataset.emoji as string;
393-
elm.title = getEmojiName(emoji) ?? emoji;
396+
elm.title = getEmojiName(emoji);
394397
}
395398
396399
function chosen(emoji: any, ev?: MouseEvent) {

packages/frontend/src/components/MkReactionIcon.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
44
-->
55

66
<template>
7-
<MkCustomEmoji v-if="reaction[0] === ':'" ref="elRef" :name="reaction" :normal="true" :noStyle="noStyle" :url="emojiUrl"/>
7+
<MkCustomEmoji v-if="reaction[0] === ':'" ref="elRef" :name="reaction" :normal="true" :noStyle="noStyle" :url="emojiUrl" :fallbackToImage="true"/>
88
<MkEmoji v-else ref="elRef" :emoji="reaction" :normal="true" :noStyle="noStyle"/>
99
</template>
1010

packages/frontend/src/components/MkReactionsViewer.details.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function getReactionName(reaction: string): string {
4444
if (trimLocal.startsWith(':')) {
4545
return trimLocal;
4646
}
47-
return getEmojiName(reaction) ?? reaction;
47+
return getEmojiName(reaction);
4848
}
4949
</script>
5050

packages/frontend/src/components/global/MkCustomEmoji.stories.impl.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,18 @@ export const Missing = {
4848
name: Default.args.name,
4949
},
5050
} satisfies StoryObj<typeof MkCustomEmoji>;
51+
export const ErrorToText = {
52+
...Default,
53+
args: {
54+
url: 'https://example.com/404',
55+
name: Default.args.name,
56+
},
57+
} satisfies StoryObj<typeof MkCustomEmoji>;
58+
export const ErrorToImage = {
59+
...Default,
60+
args: {
61+
url: 'https://example.com/404',
62+
name: Default.args.name,
63+
fallbackToImage: true,
64+
},
65+
} satisfies StoryObj<typeof MkCustomEmoji>;

packages/frontend/src/components/global/MkCustomEmoji.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ SPDX-License-Identifier: AGPL-3.0-only
44
-->
55

66
<template>
7-
<span v-if="errored">:{{ customEmojiName }}:</span>
7+
<img
8+
v-if="errored && fallbackToImage"
9+
:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
10+
src="/client-assets/dummy.png"
11+
:title="alt"
12+
/>
13+
<span v-else-if="errored">:{{ customEmojiName }}:</span>
814
<img
915
v-else
1016
:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
@@ -39,6 +45,7 @@ const props = defineProps<{
3945
useOriginalSize?: boolean;
4046
menu?: boolean;
4147
menuReaction?: boolean;
48+
fallbackToImage?: boolean;
4249
}>();
4350
4451
const react = inject<((name: string) => void) | null>('react', null);

0 commit comments

Comments
 (0)