Compare commits

..

28 Commits

Author SHA1 Message Date
7c3873887d 10.38.1 2018-11-04 03:45:05 +09:00
247ea4cf12 Merge pull request #3083 from syuilo/l10n_develop
New Crowdin translations
2018-11-04 03:44:30 +09:00
0b7af5c669 [Client] Fix bug 2018-11-04 03:44:06 +09:00
2b62a4e2e5 New translations ja-JP.yml (English) 2018-11-04 03:42:45 +09:00
65bfa3c0d6 Fix: update_client_setting (#3086) 2018-11-04 03:33:37 +09:00
84db15694d Do not send needless emojis in note
投稿作成時に含まれている絵文字を保存しておくように

SEE: https://github.com/syuilo/misskey/pull/3085#issuecomment-435608434
2018-11-04 03:32:20 +09:00
746189ba37 New translations ja-JP.yml (Norwegian) 2018-11-04 03:23:44 +09:00
74e845b3ac New translations ja-JP.yml (Dutch) 2018-11-04 03:23:39 +09:00
90fe70540e New translations ja-JP.yml (Japanese, Kansai) 2018-11-04 03:23:36 +09:00
f28af75191 New translations ja-JP.yml (Spanish) 2018-11-04 03:23:31 +09:00
924bb2bc70 New translations ja-JP.yml (Russian) 2018-11-04 03:23:26 +09:00
19d60f3d51 New translations ja-JP.yml (Portuguese) 2018-11-04 03:23:22 +09:00
6903476868 New translations ja-JP.yml (Polish) 2018-11-04 03:23:16 +09:00
cf0dccc209 New translations ja-JP.yml (Korean) 2018-11-04 03:23:10 +09:00
cfd959129d New translations ja-JP.yml (Italian) 2018-11-04 03:23:06 +09:00
819287951c New translations ja-JP.yml (German) 2018-11-04 03:23:02 +09:00
e136193925 New translations ja-JP.yml (French) 2018-11-04 03:22:57 +09:00
8c631864d9 New translations ja-JP.yml (English) 2018-11-04 03:22:53 +09:00
d7d0f6ae2e New translations ja-JP.yml (Chinese Simplified) 2018-11-04 03:22:47 +09:00
b83b3fb9d1 New translations ja-JP.yml (Catalan) 2018-11-04 03:22:43 +09:00
dfce5bc0af [Client] Improve Emoji management page of admin panel 2018-11-04 03:18:57 +09:00
3487ddabea [API] Implement some Emoji APIs 2018-11-04 03:18:32 +09:00
2dbff75e7a New translations ja-JP.yml (French) 2018-11-04 02:53:30 +09:00
02465ded9f New translations ja-JP.yml (French) 2018-11-04 02:41:50 +09:00
ffcd387945 New translations ja-JP.yml (French) 2018-11-04 02:31:36 +09:00
4806346707 New translations ja-JP.yml (French) 2018-11-04 02:21:09 +09:00
31c3f6abf7 Fix: welcome-timeline (#3084) 2018-11-04 01:49:08 +09:00
83e47fdd60 New translations ja-JP.yml (English) 2018-11-04 01:21:56 +09:00
27 changed files with 357 additions and 103 deletions

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1010,11 +1010,15 @@ admin/views/emoji.vue:
add-emoji: add-emoji:
title: "Add emoji" title: "Add emoji"
name: "Emoji name" name: "Emoji name"
name-desc: "a~z 0~9 _ の文字が使えます。" name-desc: "You can use the characters a~z 0~9 _"
aliases: "Aliases" aliases: "Aliases"
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "You can add more than one, separated by spaces."
url: "Image URL" url: "Image URL"
add: "Add" add: "Add"
emojis:
title: "Emojis"
update: "Update"
remove: "Remove"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "Announcements" announcements: "Announcements"
save: "Save" save: "Save"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -445,7 +445,7 @@ common/views/components/profile-editor.vue:
is-cat: "Ce compte est un Chat" is-cat: "Ce compte est un Chat"
is-bot: "Ce compte est un Bot" is-bot: "Ce compte est un Bot"
is-locked: "Demandes dabonnements requièrent lapprobation" is-locked: "Demandes dabonnements requièrent lapprobation"
careful-bot: "Botからのフォローだけ承認制にする" careful-bot: "Les demandes dabonnements venant de Bots requièrent lapprobation"
advanced: "Avancé" advanced: "Avancé"
privacy: "Vie privée" privacy: "Vie privée"
save: "Mettre à jour le profil" save: "Mettre à jour le profil"
@ -502,7 +502,7 @@ common/views/widgets/tips.vue:
tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます" tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます"
tips-line17: "Vous pouvez mettre un texte en surbrillance en le mettant entre ** **" tips-line17: "Vous pouvez mettre un texte en surbrillance en le mettant entre ** **"
tips-line19: "Plusieurs fenêtres peuvent être détachées en dehors du navigateur." tips-line19: "Plusieurs fenêtres peuvent être détachées en dehors du navigateur."
tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています" tips-line20: "Pourcentage sur le widget calendrier qui indique le pourcentage de temps passé"
tips-line21: "Vous pouvez aussi utiliser l'API pour développer des Bots." tips-line21: "Vous pouvez aussi utiliser l'API pour développer des Bots."
tips-line23: "Mayu est mignone avec ses sourcils." tips-line23: "Mayu est mignone avec ses sourcils."
tips-line24: "Misskey a vu le jour en 2014" tips-line24: "Misskey a vu le jour en 2014"
@ -549,7 +549,7 @@ desktop/views/components/charts.vue:
drive: "Drive" drive: "Drive"
network: "Réseau" network: "Réseau"
charts: charts:
federation-instances: "インスタンスの増減" federation-instances: "Nombre dinstances : augmentation/diminution"
federation-instances-total: "Nombre total dinstances" federation-instances-total: "Nombre total dinstances"
notes: "投稿の増減 (統合)" notes: "投稿の増減 (統合)"
local-notes: "投稿の増減 (ローカル)" local-notes: "投稿の増減 (ローカル)"
@ -782,7 +782,7 @@ desktop/views/components/settings.vue:
timeline: "Chronologie" timeline: "Chronologie"
show-my-renotes: "Afficher mes republications dans le fil" show-my-renotes: "Afficher mes republications dans le fil"
show-renoted-my-notes: "Afficher mes republications dans les fils" show-renoted-my-notes: "Afficher mes republications dans les fils"
show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する" show-local-renotes: "Afficher les partages locaux sur les fils"
show-maps: "Afficher la carte" show-maps: "Afficher la carte"
deck-column-align: "デッキのカラムの位置" deck-column-align: "デッキのカラムの位置"
deck-column-align-center: "Centrer" deck-column-align-center: "Centrer"
@ -866,22 +866,22 @@ common/views/components/api-settings.vue:
desktop/views/components/settings.apps.vue: desktop/views/components/settings.apps.vue:
no-apps: "Aucune application autorisée" no-apps: "Aucune application autorisée"
common/views/components/drive-settings.vue: common/views/components/drive-settings.vue:
max: "容量" max: "Maximale"
in-use: "utilisé" in-use: "utilisé"
stats: "Statistiques" stats: "Statistiques"
common/views/components/mute-and-block.vue: common/views/components/mute-and-block.vue:
mute-and-block: "ミュートとブロック" mute-and-block: "Silencer / Bloquer"
mute: "ミュート" mute: "Mettre en sourdine"
block: "ブロック" block: "En cours blocage"
no-muted-users: "ミュートしているユーザーはいません" no-muted-users: "Aucun utilisateur·rice nest mis·e en sourdine"
no-blocked-users: "ブロックしているユーザーはいません" no-blocked-users: "Aucun utilisateur·rice nest bloqué·e"
common/views/components/password-settings.vue: common/views/components/password-settings.vue:
reset: "パスワードを変更する" reset: "Modifier le mot de passe"
enter-current-password: "現在のパスワードを入力してください" enter-current-password: "Entrez votre mot de passe actuel"
enter-new-password: "新しいパスワードを入力してください" enter-new-password: "Saisissez le nouveau mot de passe"
enter-new-password-again: "もう一度新しいパスワードを入力してください" enter-new-password-again: "Entrez à nouveau le nouveau mot de passe"
not-match: "新しいパスワードが一致しません" not-match: "Les nouveaux mots de passe ne sont pas identiques"
changed: "パスワードを変更しました" changed: "Mot de passe modifié avec succès"
desktop/views/components/sub-note-content.vue: desktop/views/components/sub-note-content.vue:
private: "cette publication est privée" private: "cette publication est privée"
deleted: "cette publication a été supprimée" deleted: "cette publication a été supprimée"
@ -948,82 +948,86 @@ desktop/views/components/window.vue:
popout: "ポップアウト" popout: "ポップアウト"
close: "Fermer" close: "Fermer"
admin/views/index.vue: admin/views/index.vue:
dashboard: "ダッシュボード" dashboard: "Tableau de bord"
instance: "インスタンス" instance: "Instance"
emoji: "カスタム絵文字" emoji: "Emoji"
users: "ユーザー" users: "Utilisateur·rice·s"
update: "更新" update: "Mise à jour"
announcements: "お知らせ" announcements: "Annonces"
hashtags: "ハッシュタグ" hashtags: "Hashtags"
back-to-misskey: "Misskeyに戻る" back-to-misskey: "Retour vers Misskey"
admin/views/dashboard.vue: admin/views/dashboard.vue:
dashboard: "ダッシュボード" dashboard: "Tableau de bord"
accounts: "アカウント" accounts: "Comptes"
notes: "投稿" notes: "Notes"
drive: "ドライブ" drive: "Lecteur"
instances: "インスタンス" instances: "Instances"
this-instance: "このインスタンス" this-instance: "Cette instance"
federated: "連合" federated: "Fédérées"
invite: "招待" invite: "Inviter"
banner-url: "Banner URL" banner-url: "URL de la bannière"
disableRegistration: "Disable new user registration" disableRegistration: "Désactiver lenregistrement de nouveaux utilisateur·rice·s"
disableLocalTimeline: "Disable the local timeline" disableLocalTimeline: "Désactiver le fil local"
admin/views/charts.vue: admin/views/charts.vue:
title: "チャート" title: "Graph"
per-day: "1日ごと" per-day: "par jour"
per-hour: "1時間ごと" per-hour: "par heure"
federation: "フェデレーション" federation: "Fédération"
notes: "投稿" notes: "Publications"
users: "ユーザー" users: "Utilisateur·rice·s"
drive: "ドライブ" drive: "Lecteur"
network: "ネットワーク" network: "Réseau"
charts: charts:
federation-instances: "インスタンスの増減" federation-instances: "Nombre dinstances : augmentation/diminution"
federation-instances-total: "インスタンスの積算" federation-instances-total: "Nombre total dinstances"
notes: "投稿の増減 (統合)" notes: "投稿の増減 (統合)"
local-notes: "投稿の増減 (ローカル)" local-notes: "投稿の増減 (ローカル)"
remote-notes: "投稿の増減 (リモート)" remote-notes: "投稿の増減 (リモート)"
notes-total: "投稿の積算" notes-total: "Total des publications"
users: "ユーザーの増減" users: "Nombre dutilisateur·rice·s : augmentation/diminution"
users-total: "ユーザーの積算" users-total: "Nombre total des utilisateur·rice·s"
drive: "ドライブ使用量の増減" drive: "ドライブ使用量の増減"
drive-total: "ドライブ使用量の積算" drive-total: "Utilisation totale du lecteur"
drive-files: "ドライブのファイル数の増減" drive-files: "ドライブのファイル数の増減"
drive-files-total: "ドライブのファイル数の積算" drive-files-total: "Nombre total de fichiers sur le lecteur"
network-requests: "リクエスト" network-requests: "Requêtes"
network-time: "応答時間" network-time: "Temps de réponse"
network-usage: "通信量" network-usage: "Traffic"
admin/views/users.vue: admin/views/users.vue:
suspend-user: "ユーザーの凍結" suspend-user: "Suspendre un·e utilisateur·rice"
suspend: "凍結" suspend: "Suspendre"
suspended: "凍結しました" suspended: "Suspendu·e avec succès."
unsuspend-user: "ユーザーの凍結の解除" unsuspend-user: "Lever la suspension dutilisateur·rice·s"
unsuspend: "凍結の解除" unsuspend: "Suspension levée"
unsuspended: "凍結を解除しました" unsuspended: "La suspension de lutilisateur·rice a été levée avec succès"
verify-user: "ユーザーの公式アカウント設定" verify-user: "Paramètres de vérification du compte utilisateur"
verify: "公式アカウントにする" verify: "公式アカウントにする"
verified: "公式アカウントにしました" verified: "公式アカウントにしました"
unverify-user: "ユーザーの公式アカウント解除" unverify-user: "ユーザーの公式アカウント解除"
unverify: "公式アカウントを解除する" unverify: "Ôter la vérification du compte"
unverified: "公式アカウントを解除しました" unverified: "Ce compte n'est plus vérifié"
admin/views/emoji.vue: admin/views/emoji.vue:
add-emoji: add-emoji:
title: "絵文字の登録" title: "Ajouter un émoji"
name: "絵文字名" name: "Nom de lémoji"
name-desc: "a~z 0~9 _ の文字が使えます。" name-desc: "a~z 0~9 _ の文字が使えます。"
aliases: "エイリアス" aliases: "Aliases"
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "Vous pouvez définir plus dun, séparés par des espaces."
url: "絵文字画像URL" url: "URL de limage"
add: "追加" add: "Ajouter"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "Annonces"
save: "保存" save: "Enregistrer"
remove: "削除" remove: "Supprimer"
add: "追加" add: "Ajouter"
title: "タイトル" title: "Titre"
text: "内容" text: "Contenu"
admin/views/hashtags.vue: admin/views/hashtags.vue:
hided-tags: "Hidden Tags" hided-tags: "Tags cachés"
desktop/views/pages/deck/deck.tl-column.vue: desktop/views/pages/deck/deck.tl-column.vue:
is-media-only: "Les publications médias uniquement" is-media-only: "Les publications médias uniquement"
is-media-view: "Vue média" is-media-view: "Vue média"
@ -1370,7 +1374,7 @@ mobile/views/pages/settings.vue:
sound: "Sons" sound: "Sons"
enable-sounds: "Activer les sons" enable-sounds: "Activer les sons"
mark-as-read-all-unread-notes: "Marquer toutes les publications comme lues" mark-as-read-all-unread-notes: "Marquer toutes les publications comme lues"
password: "パスワード" password: "Mot de Passe"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "Vous suit" follows-you: "Vous suit"
following: "Abonnements" following: "Abonnements"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1142,6 +1142,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1015,6 +1015,10 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
emojis:
title: "絵文字一覧"
update: "更新"
remove: "削除"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
save: "保存" save: "保存"

View File

@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "10.38.0", "version": "10.38.1",
"clientVersion": "1.0.11454", "clientVersion": "1.0.11482",
"codename": "nighthike", "codename": "nighthike",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,

View File

@ -34,8 +34,8 @@ export default Vue.extend({
mounted() { mounted() {
this.connection = (this as any).os.stream.useSharedConnection('apLog'); this.connection = (this as any).os.stream.useSharedConnection('apLog');
this.connection.on('stats', this.onLog); this.connection.on('log', this.onLog);
this.connection.on('statsLog', this.onLogs); this.connection.on('logs', this.onLogs);
this.connection.send('requestLog', { this.connection.send('requestLog', {
id: Math.random().toString().substr(2, 8), id: Math.random().toString().substr(2, 8),
length: 50 length: 50

View File

@ -17,6 +17,28 @@
<ui-button @click="add">%i18n:@add-emoji.add%</ui-button> <ui-button @click="add">%i18n:@add-emoji.add%</ui-button>
</section> </section>
</ui-card> </ui-card>
<ui-card>
<div slot="title">%fa:grin R% %i18n:@emojis.title%</div>
<section v-for="emoji in emojis">
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
<ui-input v-model="emoji.name">
<span>%i18n:@add-emoji.name%</span>
<span slot="text">%i18n:@add-emoji.name-desc%</span>
</ui-input>
<ui-input v-model="emoji.aliases">
<span>%i18n:@add-emoji.aliases%</span>
<span slot="text">%i18n:@add-emoji.aliases-desc%</span>
</ui-input>
<ui-input v-model="emoji.url">
<span>%i18n:@add-emoji.url%</span>
</ui-input>
<ui-button-group>
<ui-button inline @click="updateEmoji(emoji)">%fa:save R% %i18n:@emojis.update%</ui-button>
<ui-button inline @click="removeEmoji(emoji)">%fa:trash-alt R% %i18n:@emojis.remove%</ui-button>
</ui-button-group>
</section>
</ui-card>
</div> </div>
</template> </template>
@ -29,16 +51,54 @@ export default Vue.extend({
name: '', name: '',
url: '', url: '',
aliases: '', aliases: '',
emojis: []
}; };
}, },
mounted() {
this.fetchEmojis();
},
methods: { methods: {
add() { add() {
(this as any).api('admin/add-emoji', { (this as any).api('admin/emoji/add', {
name: this.name, name: this.name,
url: this.url, url: this.url,
aliases: this.aliases.split(' ') aliases: this.aliases.split(' ')
}).then(() => { }).then(() => {
(this as any).os.apis.dialog({ text: `Added` }); (this as any).os.apis.dialog({ text: `Added` });
this.fetchEmojis();
}).catch(e => {
(this as any).os.apis.dialog({ text: `Failed ${e}` });
});
},
fetchEmojis() {
(this as any).api('admin/emoji/list').then(emojis => {
emojis.forEach(e => e.aliases = (e.aliases || []).join(' '));
this.emojis = emojis;
});
},
updateEmoji(emoji) {
(this as any).api('admin/emoji/update', {
id: emoji.id,
name: emoji.name,
url: emoji.url,
aliases: emoji.aliases.split(' ')
}).then(() => {
(this as any).os.apis.dialog({ text: `Updated` });
}).catch(e => {
(this as any).os.apis.dialog({ text: `Failed ${e}` });
});
},
removeEmoji(emoji) {
(this as any).api('admin/emoji/remove', {
id: emoji.id
}).then(() => {
(this as any).os.apis.dialog({ text: `Removed` });
this.fetchEmojis();
}).catch(e => { }).catch(e => {
(this as any).os.apis.dialog({ text: `Failed ${e}` }); (this as any).os.apis.dialog({ text: `Failed ${e}` });
}); });

View File

@ -14,7 +14,7 @@
</div> </div>
</header> </header>
<div class="text"> <div class="text">
<misskey-flavored-markdown v-if="note.text" :text="note.text" :customEmojis="p.emojis"/> <misskey-flavored-markdown v-if="note.text" :text="note.text" :customEmojis="note.emojis"/>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,3 +1,4 @@
import * as mongo from 'mongodb';
import db from '../db/mongodb'; import db from '../db/mongodb';
const Emoji = db.get<IEmoji>('emoji'); const Emoji = db.get<IEmoji>('emoji');
@ -8,20 +9,10 @@ Emoji.createIndex(['name', 'host'], { unique: true });
export default Emoji; export default Emoji;
export type IEmoji = { export type IEmoji = {
_id: mongo.ObjectID;
name: string; name: string;
host: string; host: string;
url: string; url: string;
aliases?: string[]; aliases?: string[];
updatedAt?: Date; updatedAt?: Date;
}; };
export const packEmojis = async (
host: string,
// MeiTODO: filter
) => {
return await Emoji.find({ host }, {
fields: {
_id: false
}
});
};

View File

@ -12,7 +12,7 @@ import { packMany as packFileMany, IDriveFile } from './drive-file';
import Favorite from './favorite'; import Favorite from './favorite';
import Following from './following'; import Following from './following';
import config from '../config'; import config from '../config';
import { packEmojis } from './emoji'; import Emoji from './emoji';
const Note = db.get<INote>('notes'); const Note = db.get<INote>('notes');
Note.createIndex('uri', { sparse: true, unique: true }); Note.createIndex('uri', { sparse: true, unique: true });
@ -50,6 +50,7 @@ export type INote = {
text: string; text: string;
tags: string[]; tags: string[];
tagsLower: string[]; tagsLower: string[];
emojis: string[];
cw: string; cw: string;
userId: mongo.ObjectID; userId: mongo.ObjectID;
appId: mongo.ObjectID; appId: mongo.ObjectID;
@ -231,7 +232,22 @@ export const pack = async (
// _note._userを消す前か、_note.userを解決した後でないとホストがわからない // _note._userを消す前か、_note.userを解決した後でないとホストがわからない
if (_note._user) { if (_note._user) {
_note.emojis = packEmojis(_note._user.host); const host = _note._user.host;
// 互換性のため。(古いMisskeyではNoteにemojisが無い)
if (_note.emojis == null) {
_note.emojis = Emoji.find({
host: host
}, {
fields: { _id: false }
});
} else {
_note.emojis = Emoji.find({
name: { $in: _note.emojis },
host: host
}, {
fields: { _id: false }
});
}
} }
// Rename _id to id // Rename _id to id

View File

@ -1,6 +1,6 @@
import $ from 'cafy'; import $ from 'cafy';
import Emoji from '../../../../models/emoji'; import Emoji from '../../../../../models/emoji';
import define from '../../define'; import define from '../../../define';
export const meta = { export const meta = {
desc: { desc: {

View File

@ -0,0 +1,33 @@
import $ from 'cafy';
import Emoji from '../../../../../models/emoji';
import define from '../../../define';
export const meta = {
desc: {
'ja-JP': 'カスタム絵文字を取得します。'
},
requireCredential: true,
requireAdmin: true,
params: {
host: {
validator: $.str.optional.nullable,
default: null as any
}
}
};
export default define(meta, (ps) => new Promise(async (res, rej) => {
const emojis = await Emoji.find({
host: ps.host
});
res(emojis.map(e => ({
id: e._id,
name: e.name,
aliases: e.aliases,
host: e.host,
url: e.url
})));
}));

View File

@ -0,0 +1,31 @@
import $ from 'cafy';
import Emoji from '../../../../../models/emoji';
import define from '../../../define';
import ID from '../../../../../misc/cafy-id';
export const meta = {
desc: {
'ja-JP': 'カスタム絵文字を削除します。'
},
requireCredential: true,
requireAdmin: true,
params: {
id: {
validator: $.type(ID)
}
}
};
export default define(meta, (ps) => new Promise(async (res, rej) => {
const emoji = await Emoji.findOne({
_id: ps.id
});
if (emoji == null) return rej('emoji not found');
await Emoji.remove({ _id: emoji._id });
res();
}));

View File

@ -0,0 +1,49 @@
import $ from 'cafy';
import Emoji from '../../../../../models/emoji';
import define from '../../../define';
import ID from '../../../../../misc/cafy-id';
export const meta = {
desc: {
'ja-JP': 'カスタム絵文字を更新します。'
},
requireCredential: true,
requireAdmin: true,
params: {
id: {
validator: $.type(ID)
},
name: {
validator: $.str
},
url: {
validator: $.str
},
aliases: {
validator: $.arr($.str)
}
}
};
export default define(meta, (ps) => new Promise(async (res, rej) => {
const emoji = await Emoji.findOne({
_id: ps.id
});
if (emoji == null) return rej('emoji not found');
await Emoji.update({ _id: emoji._id }, {
$set: {
name: ps.name,
aliases: ps.aliases,
url: ps.url
}
});
res();
}));

View File

@ -21,7 +21,7 @@ export const meta = {
export default define(meta, (ps, user) => new Promise(async (res, rej) => { export default define(meta, (ps, user) => new Promise(async (res, rej) => {
const x: any = {}; const x: any = {};
x[`clientSettings.${name}`] = ps.value; x[`clientSettings.${ps.name}`] = ps.value;
await User.update(user._id, { await User.update(user._id, {
$set: x $set: x
@ -31,7 +31,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
// Publish event // Publish event
publishMainStream(user._id, 'clientSettingUpdated', { publishMainStream(user._id, 'clientSettingUpdated', {
key: name, key: ps.name,
value: ps.value value: ps.value
}); });
})); }));

View File

@ -30,6 +30,7 @@ import { erase, unique } from '../../prelude/array';
import insertNoteUnread from './unread'; import insertNoteUnread from './unread';
import registerInstance from '../register-instance'; import registerInstance from '../register-instance';
import Instance from '../../models/instance'; import Instance from '../../models/instance';
import { TextElementEmoji } from '../../mfm/parse/elements/emoji';
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
@ -146,6 +147,8 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
const tags = extractHashtags(tokens); const tags = extractHashtags(tokens);
const emojis = extractEmojis(tokens);
const mentionedUsers = await extractMentionedUsers(tokens); const mentionedUsers = await extractMentionedUsers(tokens);
if (data.reply && !user._id.equals(data.reply.userId) && !mentionedUsers.some(u => u._id.equals(data.reply.userId))) { if (data.reply && !user._id.equals(data.reply.userId) && !mentionedUsers.some(u => u._id.equals(data.reply.userId))) {
@ -160,7 +163,7 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
}); });
} }
const note = await insertNote(user, data, tags, mentionedUsers); const note = await insertNote(user, data, tags, emojis, mentionedUsers);
res(note); res(note);
@ -371,7 +374,7 @@ async function publish(user: IUser, note: INote, noteObj: any, reply: INote, ren
publishToUserLists(note, noteObj); publishToUserLists(note, noteObj);
} }
async function insertNote(user: IUser, data: Option, tags: string[], mentionedUsers: IUser[]) { async function insertNote(user: IUser, data: Option, tags: string[], emojis: string[], mentionedUsers: IUser[]) {
const insert: any = { const insert: any = {
createdAt: data.createdAt, createdAt: data.createdAt,
fileIds: data.files ? data.files.map(file => file._id) : [], fileIds: data.files ? data.files.map(file => file._id) : [],
@ -382,6 +385,7 @@ async function insertNote(user: IUser, data: Option, tags: string[], mentionedUs
cw: data.cw == null ? null : data.cw, cw: data.cw == null ? null : data.cw,
tags, tags,
tagsLower: tags.map(tag => tag.toLowerCase()), tagsLower: tags.map(tag => tag.toLowerCase()),
emojis,
userId: user._id, userId: user._id,
viaMobile: data.viaMobile, viaMobile: data.viaMobile,
geo: data.geo || null, geo: data.geo || null,
@ -449,6 +453,16 @@ function extractHashtags(tokens: ReturnType<typeof parse>): string[] {
return unique(hashtags); return unique(hashtags);
} }
function extractEmojis(tokens: ReturnType<typeof parse>): string[] {
// Extract emojis
const emojis = tokens
.filter(t => t.type == 'emoji')
.map(t => (t as TextElementEmoji).emoji)
.filter(emoji => emoji.length <= 100);
return unique(emojis);
}
function index(note: INote) { function index(note: INote) {
if (note.text == null || config.elasticsearch == null) return; if (note.text == null || config.elasticsearch == null) return;