1
1
mirror of https://github.com/kokonect-link/cherrypick synced 2024-10-30 23:01:48 +09:00

Merge branch 'develop'

This commit is contained in:
syuilo 2018-08-30 22:16:04 +09:00
commit ae36bf301a
116 changed files with 1020 additions and 691 deletions

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Schwarz ... komplett" total: "Schwarz ... komplett"
notes: "Blau ... Hinweise" notes: "Blau ... Hinweise"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "Übergang in Fensterköpfen" gradient-window-header: "Übergang in Fensterköpfen"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "Zeige Antworten" show-reply-target: "Zeige Antworten"
show-my-renotes: "Zeige meine Reposts auf der Zeitleiste" show-my-renotes: "Zeige meine Reposts auf der Zeitleiste"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "Uploading a new avatar" uploading-avatar: "Uploading a new avatar"
avatar-updated: "Successfully updated the avatar" avatar-updated: "Successfully updated the avatar"
choose-avatar: "Select an image for the avatar" choose-avatar: "Select an image for the avatar"
invalid-filetype: "This filetype is not acceptable here"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "Use gradients on window headers" gradient-window-header: "Use gradients on window headers"
post-form-on-timeline: "Display post form at the top of the timeline" post-form-on-timeline: "Display post form at the top of the timeline"
suggest-recent-hashtags: "Show recent popular hashtags on the post form" suggest-recent-hashtags: "Show recent popular hashtags on the post form"
show-clock-on-header: "Show clock on upper-right"
show-reply-target: "Display reply target" show-reply-target: "Display reply target"
show-my-renotes: "Show my renotes in the timeline" show-my-renotes: "Show my renotes in the timeline"
show-renoted-my-notes: "Show renoted my posts in timelines" show-renoted-my-notes: "Show renoted my posts in timelines"
@ -819,7 +821,7 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "Dashboard" dashboard: "Dashboard"
all-users: "All Users" all-users: "All Users"
original-users: "Users on this instance" original-users: "Users on this instance"
all-notes: "All Posts" all-notes: "All the posts"
original-notes: "Posts on this instance" original-notes: "Posts on this instance"
invite: "Invite" invite: "Invite"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "Reposted by {}" reposted-by: "Reposted by {}"
private: "This post is private" private: "This post is private"
deleted: "This post has been deleted" deleted: "This post has been deleted"
desktop/views/pages/stats/stats.vue:
all-users: "All Users"
original-users: "Users on this instance"
all-notes: "All the posts"
original-notes: "Posts on this instance"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "More details..." about: "More details..."
gotit: "Got it!" gotit: "Got it!"
@ -1066,7 +1073,7 @@ mobile/views/pages/favorites.vue:
title: "Favorites" title: "Favorites"
mobile/views/pages/user-lists.vue: mobile/views/pages/user-lists.vue:
title: "Lists" title: "Lists"
enter-list-name: "Enter list name" enter-list-name: "Enter a name of the list to make"
mobile/views/pages/drive.vue: mobile/views/pages/drive.vue:
drive: "Drive" drive: "Drive"
more: "Load more" more: "Load more"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "Updates will be applied after reloading the page" update-available-desc: "Updates will be applied after reloading the page"
settings: "Settings" settings: "Settings"
signout: "Sign out" signout: "Sign out"
sound: "Sounds"
enableSounds: "Enable sounds"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "Follows you" follows-you: "Follows you"
following: "Following" following: "Following"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "Cargando un nuevo avatar" uploading-avatar: "Cargando un nuevo avatar"
avatar-updated: "Avatar actualizado" avatar-updated: "Avatar actualizado"
choose-avatar: "Escoge una imagen de avatar" choose-avatar: "Escoge una imagen de avatar"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Negro ... Total" total: "Negro ... Total"
notes: "Azul ... Notas" notes: "Azul ... Notas"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "Usar degradados en las cabeceras de las páginas" gradient-window-header: "Usar degradados en las cabeceras de las páginas"
post-form-on-timeline: "Mostrar el formulario de las entradas encima de la línea de tiempo" post-form-on-timeline: "Mostrar el formulario de las entradas encima de la línea de tiempo"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "Téléversement du nouvel avatar" uploading-avatar: "Téléversement du nouvel avatar"
avatar-updated: "L'avatar est mis à jour" avatar-updated: "L'avatar est mis à jour"
choose-avatar: "Choisir un avatar" choose-avatar: "Choisir un avatar"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Noirs ... Total" total: "Noirs ... Total"
notes: "Bleu ... Notes" notes: "Bleu ... Notes"
@ -425,12 +426,12 @@ desktop/views/components/calendar.vue:
next: "Mois prochain" next: "Mois prochain"
go: "Cliquez pour naviguer" go: "Cliquez pour naviguer"
desktop/views/components/charts.vue: desktop/views/components/charts.vue:
title: "チャート" title: "Graphiques"
per-day: "1日ごと" per-day: "par jour"
per-hour: "1時間ごと" per-hour: "par heure"
notes: "投稿" notes: "Publications"
users: "ユーザー" users: "Utilisateurs"
drive: "ドライブ" drive: "Drive"
charts: charts:
notes: "投稿の増減 (統合)" notes: "投稿の増減 (統合)"
local-notes: "投稿の増減 (ローカル)" local-notes: "投稿の増減 (ローカル)"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "Utiliser les dégradés sur la barre de titre de la fenêtre" gradient-window-header: "Utiliser les dégradés sur la barre de titre de la fenêtre"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "Afficher les hashtags populaires dans le champs de saisie" suggest-recent-hashtags: "Afficher les hashtags populaires dans le champs de saisie"
show-clock-on-header: "Afficher l'horloge à droite sur le coté supérieur"
show-reply-target: "Afficher les réponses" show-reply-target: "Afficher les réponses"
show-my-renotes: "Afficher mes republications dans le fil" show-my-renotes: "Afficher mes republications dans le fil"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -817,8 +819,8 @@ desktop/views/pages/admin/admin.vue:
update: "Mises à jour" update: "Mises à jour"
desktop/views/pages/admin/admin.dashboard.vue: desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "Tableau de bord" dashboard: "Tableau de bord"
all-users: "Tou·te·s les utilisateur·rice·s" all-users: "Toutes les utilisateurrices"
original-users: "Utilisateur·rice·s sur cette instance" original-users: "Utilisateurrices sur cette instance"
all-notes: "Toutes les publications" all-notes: "Toutes les publications"
original-notes: "Publication sur cette instance" original-notes: "Publication sur cette instance"
invite: "Invitation" invite: "Invitation"
@ -837,7 +839,7 @@ desktop/views/pages/admin/admin.verify-user.vue:
desktop/views/pages/admin/admin.unverify-user.vue: desktop/views/pages/admin/admin.unverify-user.vue:
unverify-user: "ユーザーの公式アカウント解除" unverify-user: "ユーザーの公式アカウント解除"
unverify: "Ôter la vérification du compte" unverify: "Ôter la vérification du compte"
unverified: "公式アカウントを解除しました" unverified: "Ce compte n'est pas vérifié"
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"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "Reposté par {}" reposted-by: "Reposté par {}"
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"
desktop/views/pages/stats/stats.vue:
all-users: "Toutes les utilisateurrices"
original-users: "Utilisateurrices sur cette instance"
all-notes: "Toutes les publications"
original-notes: "Publication sur cette instance"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "à propos" about: "à propos"
gotit: "J'ai compris !" gotit: "J'ai compris !"
@ -1052,7 +1059,7 @@ mobile/views/components/ui.nav.vue:
game: "Jeux" game: "Jeux"
darkmode: "Mode nuit" darkmode: "Mode nuit"
settings: "Réglages" settings: "Réglages"
admin: "管理" admin: "Admin"
about: "À propose de Misskey" about: "À propose de Misskey"
mobile/views/components/user-timeline.vue: mobile/views/components/user-timeline.vue:
no-notes: "Cette utilisateur semble n'avoir rien poster pour le moment" no-notes: "Cette utilisateur semble n'avoir rien poster pour le moment"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "Les mises à jour seront appliquées une fois la page est rechargée." update-available-desc: "Les mises à jour seront appliquées une fois la page est rechargée."
settings: "Réglages" settings: "Réglages"
signout: "Déconnexion" signout: "Déconnexion"
sound: "Sons"
enableSounds: "Activer le son"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "vous suit" follows-you: "vous suit"
following: "Abonnements" following: "Abonnements"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -94,6 +94,8 @@ common:
verified-user: "公式アカウント" verified-user: "公式アカウント"
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
reversi: reversi:
drawn: "引き分け" drawn: "引き分け"
my-turn: "あなたのターンです" my-turn: "あなたのターンです"
@ -456,6 +458,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
@ -1368,6 +1371,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"

View File

@ -207,9 +207,9 @@ common/views/components/games/reversi/reversi.room.vue:
ready: "準備完了" ready: "準備完了"
cancel-ready: "準備続行" cancel-ready: "準備続行"
common/views/components/connect-failed.vue: common/views/components/connect-failed.vue:
title: "サーバーに接続できません" title: "サーバーに接続でけへんわ"
description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。" description: "インターネット回線に問題が起きとるか、サーバーがダウンまたはメンテナンスしとるっぽいわ。知らんけど。とりあえずあとで{再試行}してや。"
thanks: "いつもMisskeyをご利用いただきありがとうございます。" thanks: "いつもMisskeyをつこてくれてほんまありがとな。"
troubleshoot: "トラブルシュート" troubleshoot: "トラブルシュート"
common/views/components/connect-failed.troubleshooter.vue: common/views/components/connect-failed.troubleshooter.vue:
title: "トラブルシューティング" title: "トラブルシューティング"
@ -219,99 +219,99 @@ common/views/components/connect-failed.troubleshooter.vue:
checking-internet: "インターネット接続を確認中" checking-internet: "インターネット接続を確認中"
server: "サーバー接続" server: "サーバー接続"
checking-server: "サーバー接続を確認中" checking-server: "サーバー接続を確認中"
finding: "問題を調べています" finding: "問題を調べとるで"
no-network: "ネットワークに接続されていません" no-network: "ネットワークに接続されとらんで"
no-network-desc: "お使いのPCのネットワーク接続が正常か確認してください。" no-network-desc: "つこてるPCのネットワーク接続が正常か確認してや。"
no-internet: "インターネットに接続されていません" no-internet: "インターネットに接続されとらんで"
no-internet-desc: "ネットワークには接続されていますが、インターネットには接続されていないようです。お使いのPCのインターネット接続が正常か確認してください。" no-internet-desc: "ネットワークには接続されとるけど、インターネットには接続されとらんようやわ。つこてるPCのインターネット接続が正常か確認してや。"
no-server: "Misskeyのサーバーに接続できません" no-server: "Misskeyのサーバーに接続でけへんわ"
no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。" no-server-desc: "つこてるPCのインターネット接続は正常やけど、Misskeyのサーバーにはつながらんわ。多分サーバーがダウンまたはメンテナンスしとるわ、知らんけど。すまんけどしばらくしてから再度アクセスしてみてや。"
success: "Misskeyのサーバーに接続できました" success: "Misskeyのサーバーに接続でき"
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。" success-desc: "正常に接続できるようやわ。ページを再度読み込みしてな。"
flush: "キャッシュの削除" flush: "キャッシュの削除"
set-version: "バージョン指定" set-version: "バージョン指定"
common/views/components/messaging.vue: common/views/components/messaging.vue:
search-user: "ユーザーを探す" search-user: "ユーザーを探す"
you: "あなた" you: "あんさん"
no-history: "履歴はありません" no-history: "履歴はあらへんで"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはありません" empty: "このユーザーと話したことはあらへんで"
more: "もっと読む" more: "もっと読む"
no-history: "これより過去の履歴はありません" no-history: "これより過去の履歴はあらへんで"
resize-form: "ドラッグしてフォームの広さを調整" resize-form: "ドラッグしてフォームの広さを調整"
new-message: "新しいメッセージがあります" new-message: "新しいメッセージがあるで"
only-one-file-attached: "メッセージに添付できるのはひとつのファイルのみです" only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで"
common/views/components/messaging-room.form.vue: common/views/components/messaging-room.form.vue:
input-message-here: "ここにメッセージを入力" input-message-here: "ここにメッセージ書いてや"
send: "送信" send: "送信"
attach-from-local: "PCからファイルを添付する" attach-from-local: "PCからファイルを添付する"
attach-from-drive: "ドライブからファイルを添付する" attach-from-drive: "ドライブからファイルを添付する"
only-one-file-attached: "メッセージに添付できるのはひとつのファイルのみです" only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで"
common/views/components/messaging-room.message.vue: common/views/components/messaging-room.message.vue:
is-read: "既読" is-read: "既読"
deleted: "このメッセージは削除されました" deleted: "このメッセージは削除され"
common/views/components/nav.vue: common/views/components/nav.vue:
about: "Misskeyについて" about: "Misskeyについて"
stats: "統計" stats: "統計"
status: "ステータス" status: "ステータス"
wiki: "Wiki" wiki: "Wiki"
donors: "ドナー" donors: "支援者"
repository: "リポジトリ" repository: "リポジトリ"
develop: "開発者" develop: "開発者"
feedback: "フィードバック" feedback: "フィードバック"
common/views/components/note-menu.vue: common/views/components/note-menu.vue:
favorite: "お気に入り" favorite: "お気に入り"
pin: "ピン留め" pin: "ピン留め"
delete: "削除" delete: "ほかす"
delete-confirm: "この投稿を削除しますか?" delete-confirm: "この投稿を削除してもええか?"
remote: "投稿元で見る" remote: "投稿元で見る"
common/views/components/poll.vue: common/views/components/poll.vue:
vote-to: "「{}」に投票する" vote-to: "「{}」に投票や!"
vote-count: "{}票" vote-count: "{}票"
total-users: "{}人が投票" total-users: "{}人が投票"
vote: "投票する" vote: "投票する"
show-result: "結果を見" show-result: "結果を見よか"
voted: "投票済み" voted: "投票済み"
common/views/components/poll-editor.vue: common/views/components/poll-editor.vue:
no-only-one-choice: "アンケートには、選択肢が最低2つ必要で" no-only-one-choice: "選択肢が最低2つ必要で"
choice-n: "選択肢{}" choice-n: "選択肢{}"
remove: "この選択肢を削除" remove: "この選択肢を消すで"
add: "+選択肢を追加" add: "+選択肢を追加"
destroy: "アンケートを破棄" destroy: "アンケートをほかそ"
common/views/components/reaction-picker.vue: common/views/components/reaction-picker.vue:
choose-reaction: "リアクションを選択" choose-reaction: "リアクションを選択"
common/views/components/signin.vue: common/views/components/signin.vue:
username: "ユーザー名" username: "ユーザー名"
password: "パスワード" password: "パスワード"
token: "トークン" token: "トークン"
signing-in: "ってます..." signing-in: "サインイン中や..."
signin: "サインイン" signin: "サインイン"
or: "または" or: "または"
signin-with-twitter: "Twitterでログイン" signin-with-twitter: "Twitterでサインイン"
login-failed: "ログインできませんでした。ユーザー名とパスワードを確認してください。" login-failed: "なんかログインできんかったわ。ユーザー名とパスワードとかを確認してや。"
common/views/components/signup.vue: common/views/components/signup.vue:
invitation-code: "招待コード" invitation-code: "招待コード"
invitation-info: "招待コードをお持ちでない方は、<a href=\"{}\">管理者</a>までご連絡ください。" invitation-info: "招待コードをお持ちでない方は、<a href=\"{}\">管理者</a>までご連絡ください。"
username: "ユーザー名" username: "ユーザー名"
checking: "確認しています..." checking: "確認中や…"
available: "利用できます" available: "使えるで"
unavailable: "既に利用されています" unavailable: "もう使われとるで"
error: "通信エラー" error: "通信エラー"
invalid-format: "a~z、A~Z、0~9、_が使えます" invalid-format: "a~z、A~Z、0~9、_が使えるで"
too-short: "1文字以上でお願いします" too-short: "1文字以上でお願いします"
too-long: "20文字以内でお願いします" too-long: "20文字以内でお願いします"
password: "パスワード" password: "パスワード"
password-placeholder: "8文字以上を推奨します" password-placeholder: "8文字以上を推奨します"
weak-password: "いパスワード" weak-password: "へぼいパスワード"
normal-password: "まあまあのパスワード" normal-password: "ぼちぼちなパスワード"
strong-password: "強いパスワード" strong-password: "良さげなパスワード"
retype: "再入力" retype: "もっかい入力頼むで"
retype-placeholder: "確認のため再入力してください" retype-placeholder: "確認のためもっぺん入力してや"
password-matched: "確認されました" password-matched: "一致しとるで"
password-not-matched: "一致していません" password-not-matched: "一致しとらんで"
recaptcha: "認証" recaptcha: "認証"
create: "アカウント作成" create: "アカウント作成"
some-error: "何らかの原因によりアカウントの作成に失敗しました。再度お試しください。" some-error: "何かよう分からんけど、アカウントの作成に失敗してしもたわ。すまんがもっぺん試してくれへんか?"
common/views/components/special-message.vue: common/views/components/special-message.vue:
new-year: "Happy New Year!" new-year: "Happy New Year!"
christmas: "Merry Christmas!" christmas: "Merry Christmas!"
@ -320,8 +320,8 @@ common/views/components/stream-indicator.vue:
reconnecting: "再接続中" reconnecting: "再接続中"
connected: "接続完了" connected: "接続完了"
common/views/components/twitter-setting.vue: common/views/components/twitter-setting.vue:
description: "お使いのTwitterアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでTwitterアカウント情報が表示されるようになったり、Twitterを用いた便利なサインインを利用できるようになります。" description: "あんさんがつことるTwitterアカウントをMisskeyアカウントに接続しとくと、あんさんのプロフィールにTwitterアカウント情報が表示されるようになったり、Twitterをつこた便利なサインインが使えるようになったりすんで。"
connected-to: "次のTwitterアカウントに接続されています" connected-to: "次のTwitterアカウントに接続されとるで"
detail: "詳細..." detail: "詳細..."
reconnect: "再接続する" reconnect: "再接続する"
connect: "Twitterと接続する" connect: "Twitterと接続する"
@ -339,7 +339,7 @@ common/views/components/visibility-chooser.vue:
private: "非公開" private: "非公開"
common/views/widgets/broadcast.vue: common/views/widgets/broadcast.vue:
fetching: "確認中" fetching: "確認中"
no-broadcasts: "お知らせはありません" no-broadcasts: "お知らせはあらへんで"
have-a-nice-day: "良い一日を!" have-a-nice-day: "良い一日を!"
next: "次" next: "次"
common/views/widgets/calendar.vue: common/views/widgets/calendar.vue:
@ -351,17 +351,17 @@ common/views/widgets/calendar.vue:
this-year: "今年:" this-year: "今年:"
common/views/widgets/donation.vue: common/views/widgets/donation.vue:
title: "寄付のお願い" title: "寄付のお願い"
text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かります。Misskeyは広告を掲載したりしないため、収入を皆様からの寄付に頼っています。もしご興味があれば、{}までご連絡ください。ご協力ありがとうございます。" text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かるんや。Misskeyは広告を掲載したりせんから、収入を皆様からの寄付に頼ってますねん。もし興味があるなら、{}までご連絡よろしゅう頼んます。ご協力おおきに。"
common/views/widgets/photo-stream.vue: common/views/widgets/photo-stream.vue:
title: "フォトストリーム" title: "フォトストリーム"
no-photos: "写真はありません" no-photos: "写真はあらへんで"
common/views/widgets/posts-monitor.vue: common/views/widgets/posts-monitor.vue:
title: "投稿チャート" title: "投稿チャート"
toggle: "表示を切り替え" toggle: "表示を切り替え"
common/views/widgets/hashtags.vue: common/views/widgets/hashtags.vue:
title: "ハッシュタグ" title: "ハッシュタグ"
count: "{}人が投稿" count: "{}人が投稿"
empty: "トレンドなし" empty: "流行は自分で作るんや"
common/views/widgets/server.vue: common/views/widgets/server.vue:
title: "サーバー情報" title: "サーバー情報"
toggle: "表示を切り替え" toggle: "表示を切り替え"
@ -370,30 +370,30 @@ common/views/widgets/memo.vue:
memo: "ここに書いて!" memo: "ここに書いて!"
save: "保存" save: "保存"
common/views/widgets/slideshow.vue: common/views/widgets/slideshow.vue:
folder-customize-mode: "フォルダを指定するには、カスタマイズモードを終了してください" folder-customize-mode: "フォルダを指定するんやったら、一旦カスタマイズモードを終了してや"
folder: "クリックしてフォルダを指定してください" folder: "クリックしてフォルダを指定してください"
no-image: "このフォルダには画像がありません" no-image: "このフォルダには画像がありません"
common/views/widgets/tips.vue: common/views/widgets/tips.vue:
tips-line1: "<kbd>t</kbd>でタイムラインにフォーカスできます" tips-line1: "<kbd>t</kbd>でタイムラインにフォーカスできんで"
tips-line2: "<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます" tips-line2: "<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開くで"
tips-line3: "投稿フォームにはファイルをドラッグ&ドロップできます" tips-line3: "投稿フォームにはファイルをドラッグ&ドロップできんで"
tips-line4: "投稿フォームにクリップボードにある画像データをペーストできます" tips-line4: "投稿フォームにクリップボードにおる画像データをペーストできんで"
tips-line5: "ドライブにファイルをドラッグ&ドロップしてアップロードできます" tips-line5: "ドライブにファイルをドラッグ&ドロップしてアップロードできんで"
tips-line6: "ドライブでファイルをドラッグしてフォルダ移動できます" tips-line6: "ドライブやと、ファイルをドラッグしてフォルダ移動できんで"
tips-line7: "ドライブでフォルダをドラッグしてフォルダ移動できます" tips-line7: "ドライブやと、フォルダをドラッグしてフォルダ移動できんで"
tips-line8: "ホームは設定からカスタマイズできます" tips-line8: "ホームは設定からカスタマイズできんで"
tips-line9: "MisskeyはAGPLv3" tips-line9: "MisskeyはAGPLv3で"
tips-line10: "タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れます" tips-line10: "タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れんで"
tips-line11: "投稿の ... をクリックして、投稿をユーザーページにピン留めできます" tips-line11: "投稿の ... をクリックして、ピン留めから投稿をユーザーページにピン留めできんで"
tips-line13: "投稿に添付したファイルは全てドライブに保存されます" tips-line13: "投稿に添付したファイルは全てドライブに保存されんで"
tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます" tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できんで"
tips-line17: "「**」でテキストを囲むと**強調表示**されます" tips-line17: "「**」でテキストを囲ったると**強調表示**されんで"
tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができます" tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができんで"
tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています" tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示してんねん"
tips-line21: "APIを利用してbotの開発なども行えます" tips-line21: "APIをつこてbotの開発なども行えるで"
tips-line23: "まゆかわいいよまゆ" tips-line23: "まゆかわいいよまゆ"
tips-line24: "Misskeyは2014年にサービスを開始しました" tips-line24: "Misskeyは2014年にサービスを開始しんよ"
tips-line25: "対応ブラウザではMisskeyを開いていなくても通知を受け取れます" tips-line25: "対応ブラウザやったらMisskeyを開いとらんでも通知を受け取れんで"
common/views/pages/follow.vue: common/views/pages/follow.vue:
signed-in-as: "{}としてサインイン中" signed-in-as: "{}としてサインイン中"
following: "フォロー中" following: "フォロー中"
@ -403,14 +403,15 @@ common/views/pages/follow.vue:
desktop: desktop:
banner-crop-title: "バナーとして表示する部分を選択" banner-crop-title: "バナーとして表示する部分を選択"
banner: "バナー" banner: "バナー"
uploading-banner: "新しいバナーをアップロードしています" uploading-banner: "新しいバナーをアップロードしとるで"
banner-updated: "バナーを更新しました" banner-updated: "バナーを更新し"
choose-banner: "バナーにする画像を選択" choose-banner: "バナーにする画像を選択"
avatar-crop-title: "アバターとして表示する部分を選択" avatar-crop-title: "アバターとして表示する部分を選択"
avatar: "アバター" avatar: "アバター"
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -420,10 +421,10 @@ desktop/views/components/activity.vue:
title: "アクティビティ" title: "アクティビティ"
toggle: "表示を切り替え" toggle: "表示を切り替え"
desktop/views/components/calendar.vue: desktop/views/components/calendar.vue:
title: "{1}年 {2}月" title: "{1}年 {2} 月"
prev: "前の月" prev: "前の月"
next: "次の月" next: "次の月"
go: "クリックして時間遡行" go: "クリックしてタイムリープ"
desktop/views/components/charts.vue: desktop/views/components/charts.vue:
title: "チャート" title: "チャート"
per-day: "1日ごと" per-day: "1日ごと"
@ -464,7 +465,7 @@ desktop/views/components/drive.file.vue:
banner: "バナー" banner: "バナー"
nsfw: "閲覧注意" nsfw: "閲覧注意"
contextmenu: contextmenu:
rename: "名前を変" rename: "名前を変えるで"
mark-as-sensitive: "閲覧注意に設定" mark-as-sensitive: "閲覧注意に設定"
unmark-as-sensitive: "閲覧注意を解除" unmark-as-sensitive: "閲覧注意を解除"
copy-url: "URLをコピー" copy-url: "URLをコピー"
@ -475,26 +476,26 @@ desktop/views/components/drive.file.vue:
open-in-app: "アプリで開く" open-in-app: "アプリで開く"
add-app: "アプリを追加" add-app: "アプリを追加"
rename-file: "ファイル名の変更" rename-file: "ファイル名の変更"
input-new-file-name: "新しいファイル名を入力してください" input-new-file-name: "新しいファイル名を入力して"
copied: "コピー完了" copied: "コピー完了"
copied-url-to-clipboard: "URLをクリップボードにコピーしました" copied-url-to-clipboard: "URLをクリップボードにコピーしました"
desktop/views/components/drive.folder.vue: desktop/views/components/drive.folder.vue:
unable-to-process: "操作を完了できません" unable-to-process: "操作を完了できません"
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。" circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。"
unhandled-error: "不明なエラー" unhandled-error: "ようわからん"
contextmenu: contextmenu:
move-to-this-folder: "このフォルダへ移動" move-to-this-folder: "このフォルダへ移動"
show-in-new-window: "新しいウィンドウで表示" show-in-new-window: "新しいウィンドウで表示"
rename: "名前を変" rename: "名前を変えるで"
rename-folder: "フォルダ名の変更" rename-folder: "フォルダ名を変えるで"
input-new-folder-name: "新しいフォルダ名を入力してください" input-new-folder-name: "新しいフォルダ名を入力して"
desktop/views/components/drive.nav-folder.vue: desktop/views/components/drive.nav-folder.vue:
drive: "ドライブ" drive: "ドライブ"
desktop/views/components/drive.vue: desktop/views/components/drive.vue:
search: "検索" search: "検索"
load-more: "もっと読み込む" load-more: "もっと読み込む"
empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね" empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね"
empty-drive: "ドライブには何もありません。" empty-drive: "ドライブには何もあらへんで。"
empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。" empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。"
empty-folder: "このフォルダーは空です" empty-folder: "このフォルダーは空です"
unable-to-process: "操作を完了できません" unable-to-process: "操作を完了できません"
@ -511,11 +512,11 @@ desktop/views/components/drive.vue:
upload: "ファイルをアップロード" upload: "ファイルをアップロード"
url-upload: "URLからアップロード" url-upload: "URLからアップロード"
desktop/views/components/media-image.vue: desktop/views/components/media-image.vue:
sensitive: "閲覧注意" sensitive: "ちょっと見せられへんわ"
click-to-show: "クリックして表示" click-to-show: "クリックして見せるで"
desktop/views/components/media-video.vue: desktop/views/components/media-video.vue:
sensitive: "閲覧注意" sensitive: "ちょっと見せられへんわ"
click-to-show: "クリックして表示" click-to-show: "クリックして見せるで"
desktop/views/components/follow-button.vue: desktop/views/components/follow-button.vue:
following: "フォロー中" following: "フォロー中"
follow: "フォロー" follow: "フォロー"
@ -536,7 +537,7 @@ desktop/views/components/friends-maker.vue:
refresh: "もっと見る" refresh: "もっと見る"
close: "閉じる" close: "閉じる"
desktop/views/components/game-window.vue: desktop/views/components/game-window.vue:
game: "リバーシ" game: "ゲーム"
desktop/views/components/home.vue: desktop/views/components/home.vue:
done: "完了" done: "完了"
add-widget: "ウィジェットを追加:" add-widget: "ウィジェットを追加:"
@ -575,32 +576,32 @@ desktop/views/components/notifications.vue:
empty: "ありません!" empty: "ありません!"
desktop/views/components/post-form.vue: desktop/views/components/post-form.vue:
add-visible-user: "+ユーザーを追加" add-visible-user: "+ユーザーを追加"
attach-location-information: "位置情報を添付する" attach-location-information: "いる場所くっつけるで"
hide-contents: "内容を隠す" hide-contents: "内容を隠す"
reply-placeholder: "この投稿への返信..." reply-placeholder: "この投稿への返信..."
quote-placeholder: "この投稿を引用..." quote-placeholder: "この投稿を引用..."
submit: "投稿" submit: "投稿"
reply: "返信" reply: "返信"
renote: "Renote" renote: "Renote"
posted: "投稿しました!" posted: "投稿し"
replied: "返信しました!" replied: "返信し"
reposted: "Renoteしました" reposted: "Renoteしました"
note-failed: "投稿に失敗しました" note-failed: "投稿に失敗し"
reply-failed: "返信に失敗しました" reply-failed: "返信に失敗し"
renote-failed: "Renoteに失敗しました" renote-failed: "Renoteに失敗しました"
posting: "投稿中" posting: "投稿中"
attach-media-from-local: "PCからメディアを添付" attach-media-from-local: "PCからメディアを添付"
attach-media-from-drive: "ドライブからメディアを添付" attach-media-from-drive: "ドライブからメディアを添付"
attach-cancel: "添付取り消し" attach-cancel: "くっつけるのやめよか"
insert-a-kao: "v('ω')v" insert-a-kao: "v('ω')v"
create-poll: "アンケートを作成" create-poll: "アンケートを作成"
text-remain: "残り{}文字" text-remain: "残り{}文字"
recent-tags: "最近" recent-tags: "最近のタグ"
click-to-tagging: "クリックでタグ付け" click-to-tagging: "クリックでタグ付け"
visibility: "公開範囲" visibility: "公開範囲"
geolocation-alert: "お使いの端末は位置情報に対応していません" geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー" error: "エラー"
enter-username: "ユーザー名を入力してください" enter-username: "ユーザー名を入力して"
annotations: "内容への注釈 (オプション)" annotations: "内容への注釈 (オプション)"
desktop/views/components/post-form-window.vue: desktop/views/components/post-form-window.vue:
note: "新規投稿" note: "新規投稿"
@ -639,7 +640,7 @@ desktop/views/components/settings.vue:
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。" auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
advanced: "詳細設定" advanced: "詳細設定"
api-via-stream: "ストリームを経由したAPIリクエスト" api-via-stream: "ストリームを経由したAPIリクエスト"
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。" api-via-stream-desc: "この設定をオンにすると、WebSocket接続を経由してAPIリクエストが行われんで(パフォーマンス向上するかも、知らんけど)。オフにすると、ネイティブの fetch API が利用されるで。この設定はこのデバイスのみ有効やで。"
display: "デザインと表示" display: "デザインと表示"
customize: "ホームをカスタマイズ" customize: "ホームをカスタマイズ"
choose-wallpaper: "壁紙を選択" choose-wallpaper: "壁紙を選択"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -686,9 +688,9 @@ desktop/views/components/settings.vue:
prevent-update: "アップデートを延期する(非推奨)" prevent-update: "アップデートを延期する(非推奨)"
prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。" prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。"
no-updates: "利用可能な更新はありません" no-updates: "利用可能な更新はありません"
no-updates-desc: "お使いのMisskeyは最新です。" no-updates-desc: "つこてるMisskeyは最新や"
update-available: "新しいバージョンが利用可能です" update-available: "新しいバージョンが利用可能"
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されるで。"
advanced-settings: "高度な設定" advanced-settings: "高度な設定"
debug-mode: "デバッグモードを有効にする" debug-mode: "デバッグモードを有効にする"
debug-mode-desc: "この設定はブラウザに記憶されます。" debug-mode-desc: "この設定はブラウザに記憶されます。"
@ -707,28 +709,28 @@ desktop/views/components/settings.2fa.vue:
unregister: "設定を解除" unregister: "設定を解除"
unregistered: "二段階認証が無効になりました。" unregistered: "二段階認証が無効になりました。"
enter-password: "パスワードを入力してください" enter-password: "パスワードを入力してください"
authenticator: "まず、Google Authenticatorをお使いのデバイスにインストールします:" authenticator: "まず、Google Authenticatorとかのをつこてるデバイスにインストールしてや:"
howtoinstall: "インストール方法はこちら" howtoinstall: "インストール方法はここやで"
scan: "次に、表示されているQRコードをスキャンします:" scan: "んで、ここに出とるQRコードをスキャンしてな:"
done: "お使いのデバイスに表示されているトークンを入力して完了します:" done: "最後にデバイスに表示されとるトークンを入力してな:"
submit: "完了" submit: "送信"
success: "設定が完了しました!" success: "設定が完了し"
failed: "設定に失敗しました。トークンに誤りがないかご確認ください。" failed: "なんか設定に失敗したで。トークンを間違えとらんか確認してや。"
info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。" info: "次のサインインからは、パスワードに加えてデバイスに出とるトークンを入力してな。"
desktop/views/components/settings.api.vue: desktop/views/components/settings.api.vue:
intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。" intro: "APIを利用するには、上記のトークンを「i」っちゅうキーでパラメータに付加してリクエストしてや。"
caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。" caution: "アカウントを不正利用されるかも知れんから、このトークンは第三者に教えたらあかんで(アプリなどにも入力しんといてな)。"
regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。" regeneration-of-token: "万が一このトークンが漏れたとかその可能性があったらトークンを再生成できるで。"
regenerate-token: "トークンを再生成" regenerate-token: "トークンを再生成"
token: "Token:" token: "トークン:"
enter-password: "パスワードを入力してください" enter-password: "パスワードを入力して"
desktop/views/components/settings.apps.vue: desktop/views/components/settings.apps.vue:
no-apps: "連携しているアプリケーションはありません" no-apps: "連携しているアプリケーションはあらへんで"
desktop/views/components/settings.drive.vue: desktop/views/components/settings.drive.vue:
max: "中" max: "中"
in-use: "使用中" in-use: "使用中"
desktop/views/components/settings.mute.vue: desktop/views/components/settings.mute.vue:
no-users: "ミュートしているユーザーはいません" no-users: "ミュートしているユーザーはおらんで"
desktop/views/components/settings.password.vue: desktop/views/components/settings.password.vue:
reset: "パスワードを変更する" reset: "パスワードを変更する"
enter-current-password: "現在のパスワードを入力してください" enter-current-password: "現在のパスワードを入力してください"
@ -764,7 +766,7 @@ desktop/views/components/timeline.vue:
global: "グローバル" global: "グローバル"
list: "リスト" list: "リスト"
desktop/views/components/ui.header.vue: desktop/views/components/ui.header.vue:
welcome-back: "おかえりなさい、" welcome-back: "おかえり、"
adjective: "さん" adjective: "さん"
desktop/views/components/ui.header.account.vue: desktop/views/components/ui.header.account.vue:
profile: "プロフィール" profile: "プロフィール"
@ -772,7 +774,7 @@ desktop/views/components/ui.header.account.vue:
favorites: "お気に入り" favorites: "お気に入り"
lists: "リスト" lists: "リスト"
follow-requests: "フォロー申請" follow-requests: "フォロー申請"
customize: "ホームカスタマイズ" customize: "ホームカスタマイズ"
admin: "管理" admin: "管理"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
@ -794,7 +796,7 @@ desktop/views/components/received-follow-requests-window.vue:
reject: "拒否" reject: "拒否"
desktop/views/components/user-lists-window.vue: desktop/views/components/user-lists-window.vue:
title: "リスト" title: "リスト"
create-list: "リストを作成" create-list: "新しいリストを作成"
list-name: "リスト名" list-name: "リスト名"
desktop/views/components/user-preview.vue: desktop/views/components/user-preview.vue:
notes: "投稿" notes: "投稿"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -829,11 +831,11 @@ desktop/views/pages/admin/admin.suspend-user.vue:
desktop/views/pages/admin/admin.unsuspend-user.vue: desktop/views/pages/admin/admin.unsuspend-user.vue:
unsuspend-user: "ユーザーの凍結の解除" unsuspend-user: "ユーザーの凍結の解除"
unsuspend: "凍結の解除" unsuspend: "凍結の解除"
unsuspended: "凍結を解除しました" unsuspended: "凍結を解除し"
desktop/views/pages/admin/admin.verify-user.vue: desktop/views/pages/admin/admin.verify-user.vue:
verify-user: "ユーザーの公式アカウント設定" verify-user: "ユーザーの公式アカウント設定"
verify: "公式アカウントにする" verify: "公式アカウントにする"
verified: "公式アカウントにしました" verified: "公式アカウントにし"
desktop/views/pages/admin/admin.unverify-user.vue: desktop/views/pages/admin/admin.unverify-user.vue:
unverify-user: "ユーザーの公式アカウント解除" unverify-user: "ユーザーの公式アカウント解除"
unverify: "公式アカウントを解除する" unverify: "公式アカウントを解除する"
@ -846,21 +848,26 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
signin: "ログイン" signin: "サインイン"
signup: "新規登録" signup: "サインアップ"
signin-button: "やってる" signin-button: "サインイン中…"
signup-button: "やる" signup-button: "サインアップ"
timeline: "タイムライン" timeline: "タイムライン"
powered-by-misskey: "Powered by <b>Misskey</b>." powered-by-misskey: "Powered by <b>Misskey</b>."
desktop/views/pages/drive.vue: desktop/views/pages/drive.vue:
title: "Misskey Drive" title: "ドライブ"
desktop/views/pages/favorites.vue: desktop/views/pages/favorites.vue:
more: "さらに読み込む" more: "もっと読み込んでくで"
desktop/views/pages/home-customize.vue: desktop/views/pages/home-customize.vue:
title: "ホームカスタマイズ" title: "ホームカスタマイズ"
desktop/views/pages/note.vue: desktop/views/pages/note.vue:
prev: "前の投稿" prev: "前の投稿"
next: "次の投稿" next: "次の投稿"
@ -895,19 +902,19 @@ desktop/views/pages/user/user.vue:
desktop/views/pages/user/user.home.vue: desktop/views/pages/user/user.home.vue:
last-used-at: "最終アクセス" last-used-at: "最終アクセス"
desktop/views/pages/user/user.photos.vue: desktop/views/pages/user/user.photos.vue:
title: "フォト" title: "写真"
loading: "読み込み中" loading: "読み込み中"
no-photos: "写真はありません" no-photos: "写真はあらへんで"
desktop/views/pages/user/user.profile.vue: desktop/views/pages/user/user.profile.vue:
follows-you: "フォローされています" follows-you: "フォローされとるで"
stalk: "ストークする" stalk: "ストークする"
stalking: "ストーキングしています" stalking: "ストーキングしとるで"
unstalk: "ストーク解除" unstalk: "ストーク解除"
mute: "ミュートする" mute: "ミュートする"
muted: "ミュートしています" muted: "ミュートしとるで"
unmute: "ミュート解除" unmute: "ミュート解除"
push-to-a-list: "リストに追加" push-to-a-list: "リストに追加"
list-pushed: "{user}を{list}に追加しました。" list-pushed: "{user}を{list}に追加し。"
desktop/views/pages/user/user.header.vue: desktop/views/pages/user/user.header.vue:
posts: "投稿" posts: "投稿"
following: "フォロー" following: "フォロー"
@ -926,7 +933,7 @@ desktop/views/widgets/notifications.vue:
desktop/views/widgets/polls.vue: desktop/views/widgets/polls.vue:
title: "アンケート" title: "アンケート"
refresh: "他を見る" refresh: "他を見る"
nothing: "ありません!" nothing: "あらへん!"
desktop/views/widgets/post-form.vue: desktop/views/widgets/post-form.vue:
title: "投稿" title: "投稿"
note: "投稿" note: "投稿"
@ -948,7 +955,7 @@ mobile/views/components/drive.vue:
count-separator: "、" count-separator: "、"
file-count: "ファイル" file-count: "ファイル"
load-more: "もっと読み込む" load-more: "もっと読み込む"
nothing-in-drive: "ドライブには何もありません" nothing-in-drive: "ドライブには何もあらへんで。"
folder-is-empty: "このフォルダは空です" folder-is-empty: "このフォルダは空です"
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>" prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
deletion-alert: "ごめんなさい!フォルダの削除は未実装です...。" deletion-alert: "ごめんなさい!フォルダの削除は未実装です...。"
@ -1025,9 +1032,9 @@ mobile/views/components/post-form.vue:
quote-placeholder: "この投稿を引用... (オプション)" quote-placeholder: "この投稿を引用... (オプション)"
reply-placeholder: "この投稿への返信..." reply-placeholder: "この投稿への返信..."
cw-placeholder: "内容への注釈 (オプション)" cw-placeholder: "内容への注釈 (オプション)"
location-alert: "お使いの端末は位置情報に対応していません" location-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
error: "エラー" error: "エラー"
username-prompt: "ユーザー名を入力してください" username-prompt: "ユーザー名を入力して"
mobile/views/components/sub-note-content.vue: mobile/views/components/sub-note-content.vue:
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
@ -1066,7 +1073,7 @@ mobile/views/pages/favorites.vue:
title: "お気に入り" title: "お気に入り"
mobile/views/pages/user-lists.vue: mobile/views/pages/user-lists.vue:
title: "リスト" title: "リスト"
enter-list-name: "リスト名を入力してください" enter-list-name: "リスト名を入力して"
mobile/views/pages/drive.vue: mobile/views/pages/drive.vue:
drive: "ドライブ" drive: "ドライブ"
more: "もっと見る" more: "もっと見る"
@ -1082,7 +1089,7 @@ mobile/views/pages/home.vue:
hybrid: "ソーシャル" hybrid: "ソーシャル"
global: "グローバル" global: "グローバル"
mobile/views/pages/tag.vue: mobile/views/pages/tag.vue:
no-posts-found: "ハッシュタグ「{}」が付けられた投稿は見つかりませんでした。" no-posts-found: "ハッシュタグ「{}」が付けられた投稿はあらへんで。"
mobile/views/pages/welcome.vue: mobile/views/pages/welcome.vue:
signup: "新規登録" signup: "新規登録"
mobile/views/pages/widgets.vue: mobile/views/pages/widgets.vue:
@ -1149,7 +1156,7 @@ mobile/views/pages/settings.vue:
show-local-renotes: "ローカルの投稿のRenoteを表示する" show-local-renotes: "ローカルの投稿のRenoteを表示する"
post-style: "投稿の表示スタイル" post-style: "投稿の表示スタイル"
post-style-standard: "標準" post-style-standard: "標準"
post-style-smart: "スマート" post-style-smart: "べっぴんさん"
behavior: "動作" behavior: "動作"
fetch-on-scroll: "スクロールで自動読み込み" fetch-on-scroll: "スクロールで自動読み込み"
disable-via-mobile: "「モバイルからの投稿」フラグを付けない" disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "Wysyłanie awatara" uploading-avatar: "Wysyłanie awatara"
avatar-updated: "Wysłano awatar" avatar-updated: "Wysłano awatar"
choose-avatar: "Wybierz awatar" choose-avatar: "Wybierz awatar"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Czarny … Łącznie" total: "Czarny … Łącznie"
notes: "Niebieski … Wpisy" notes: "Niebieski … Wpisy"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "Używaj gradientów na pasku tytułu okna" gradient-window-header: "Używaj gradientów na pasku tytułu okna"
post-form-on-timeline: "Wyświetlaj formularz tworzenia wpisu w górnej części osi czasu" post-form-on-timeline: "Wyświetlaj formularz tworzenia wpisu w górnej części osi czasu"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "Pokazuj cel odpowiedzi" show-reply-target: "Pokazuj cel odpowiedzi"
show-my-renotes: "Pokazuj moje udostępnienia na osi czasu" show-my-renotes: "Pokazuj moje udostępnienia na osi czasu"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "Udostępniono przez {}" reposted-by: "Udostępniono przez {}"
private: "ten wpis jest prywatny" private: "ten wpis jest prywatny"
deleted: "ten wpis został usunięty" deleted: "ten wpis został usunięty"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "O Misskey" about: "O Misskey"
gotit: "Rozumiem!" gotit: "Rozumiem!"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "Odśwież stronę, aby zastosować aktualizację." update-available-desc: "Odśwież stronę, aby zastosować aktualizację."
settings: "Ustawienia" settings: "Ustawienia"
signout: "Wyloguj" signout: "Wyloguj"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "Śledzi Cię" follows-you: "Śledzi Cię"
following: "Śledzeni" following: "Śledzeni"

View File

@ -58,7 +58,7 @@ common:
friday: "sexta" friday: "sexta"
saturday: "sábado" saturday: "sábado"
reactions: reactions:
like: "いいね" like: "Curtir"
love: "Amei" love: "Amei"
laugh: "Riso" laugh: "Riso"
hmm: "Hmm...?" hmm: "Hmm...?"
@ -81,7 +81,7 @@ common:
ok: "OK" ok: "OK"
update-available-title: "Atualização disponível" update-available-title: "Atualização disponível"
update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar." update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar."
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" my-token-regenerated: "Seu token foi recriado, portanto você foi deslogado."
i-like-sushi: "Eu prefiro sushi a pudim" i-like-sushi: "Eu prefiro sushi a pudim"
show-reversi-board-labels: "Mostrar etiquetas de colunas e linhas no Reversi" show-reversi-board-labels: "Mostrar etiquetas de colunas e linhas no Reversi"
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
@ -97,7 +97,7 @@ common:
black: "Pretas" black: "Pretas"
white: "Brancas" white: "Brancas"
total: "Total" total: "Total"
this-turn: "{}ターン目" this-turn: "Turno de {}"
widgets: widgets:
analog-clock: "Relógio analógico" analog-clock: "Relógio analógico"
profile: "Perfil" profile: "Perfil"
@ -106,16 +106,16 @@ common:
activity: "Atividade" activity: "Atividade"
rss: "Leitor de RSS" rss: "Leitor de RSS"
memo: "Nota adesiva" memo: "Nota adesiva"
trends: "トレンド" trends: "Tendências"
photo-stream: "フォトストリーム" photo-stream: "フォトストリーム"
posts-monitor: "投稿チャート" posts-monitor: "Gráfico de publicações"
slideshow: "スライドショー" slideshow: "スライドショー"
version: "Versão" version: "Versão"
broadcast: "ブロードキャスト" broadcast: "ブロードキャスト"
notifications: "Notificações" notifications: "Notificações"
users: "Usuário sugeridos" users: "Usuário sugeridos"
polls: "Enquetes" polls: "Enquetes"
post-form: "投稿フォーム" post-form: "Formulário de publicação"
messaging: "Mensagens" messaging: "Mensagens"
server: "Informações do servidor" server: "Informações do servidor"
donation: "Doações" donation: "Doações"
@ -135,10 +135,10 @@ common:
swap-up: "Mover para cima" swap-up: "Mover para cima"
swap-down: "Mover para baixo" swap-down: "Mover para baixo"
remove: "Remover" remove: "Remover"
add-column: "カラムを追加" add-column: "Adicionar coluna"
rename: "Renomear" rename: "Renomear"
stack-left: "左に重ねる" stack-left: "左に重ねる"
pop-right: "右に出す" pop-right: "Acoplar à direita"
auth/views/form.vue: auth/views/form.vue:
share-access: "Você <b>permite</b> que <i>{{ app.name }}</i> acesse sua conta?" share-access: "Você <b>permite</b> que <i>{{ app.name }}</i> acesse sua conta?"
permission-ask: "Este aplicativo precisa das seguintes permissões:" permission-ask: "Este aplicativo precisa das seguintes permissões:"
@ -151,18 +151,18 @@ auth/views/form.vue:
drive-write: "ドライブを操作する。" drive-write: "ドライブを操作する。"
notification-read: "通知を見る。" notification-read: "通知を見る。"
notification-write: "通知を操作する。" notification-write: "通知を操作する。"
cancel: "キャンセル" cancel: "Cancelar"
accept: "アクセスを許可" accept: "Permitir acesso"
auth/views/index.vue: auth/views/index.vue:
loading: "読み込み中" loading: "Carregando"
denied: "アプリケーションの連携をキャンセルしました。" denied: "アプリケーションの連携をキャンセルしました。"
denied-paragraph: "このアプリがあなたのアカウントにアクセスすることはありません。" denied-paragraph: "このアプリがあなたのアカウントにアクセスすることはありません。"
already-authorized: "このアプリは既に連携済みです" already-authorized: "Este aplicativo já foi autorizado"
allowed: "アプリケーションの連携を許可しました" allowed: "Aplicativos com acesso autorizado"
callback-url: "アプリケーションに戻っています" callback-url: "Voltando ao aplicativo"
please-go-back: "アプリケーションに戻って、やっていってください。" please-go-back: "Por favor, volte ao aplicativo."
error: "セッションが存在しません。" error: "A sessão não existe."
sign-in: "サインインしてください" sign-in: "Por favor, entre."
common/views/components/games/reversi/reversi.vue: common/views/components/games/reversi/reversi.vue:
matching: matching:
waiting-for: "{}を待っています" waiting-for: "{}を待っています"
@ -176,17 +176,17 @@ common/views/components/games/reversi/reversi.game.vue:
common/views/components/games/reversi/reversi.index.vue: common/views/components/games/reversi/reversi.index.vue:
title: "Misskey Reversi" title: "Misskey Reversi"
sub-title: "他のMisskeyユーザーとリバーシで対戦しよう" sub-title: "他のMisskeyユーザーとリバーシで対戦しよう"
invite: "招待" invite: "Convidar"
rule: "遊び方" rule: "Como jogar"
rule-desc: "リバーシは、相手と交互に石をボードに置いて、相手の石を挟んで自分の色に変えてゆき、最終的に残った石が多い方が勝ちというボードゲームです。" rule-desc: "リバーシは、相手と交互に石をボードに置いて、相手の石を挟んで自分の色に変えてゆき、最終的に残った石が多い方が勝ちというボードゲームです。"
mode-invite: "招待" mode-invite: "Convidar"
mode-invite-desc: "指定したユーザーと対戦するモードです。" mode-invite-desc: "Convidar um usuário para jogar"
invitations: "対局の招待があります!" invitations: "Você foi convidado!"
my-games: "自分の対局" my-games: "Meu jogo"
all-games: "みんなの対局" all-games: "Todos os jogos"
enter-username: "ユーザー名を入力してください" enter-username: "Digite o nome de usuário."
game-state: game-state:
ended: "終了" ended: "Terminado"
playing: "進行中" playing: "進行中"
common/views/components/games/reversi/reversi.room.vue: common/views/components/games/reversi/reversi.room.vue:
settings-of-the-game: "ゲームの設定" settings-of-the-game: "ゲームの設定"
@ -228,11 +228,11 @@ common/views/components/connect-failed.troubleshooter.vue:
no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。" no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。"
success: "Misskeyのサーバーに接続できました" success: "Misskeyのサーバーに接続できました"
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。" success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
flush: "キャッシュの削除" flush: "Limpar o cache"
set-version: "バージョン指定" set-version: "バージョン指定"
common/views/components/messaging.vue: common/views/components/messaging.vue:
search-user: "ユーザーを探す" search-user: "ユーザーを探す"
you: "あなた" you: "Você"
no-history: "履歴はありません" no-history: "履歴はありません"
common/views/components/messaging-room.vue: common/views/components/messaging-room.vue:
empty: "このユーザーと話したことはありません" empty: "このユーザーと話したことはありません"
@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "Todos os usuários" all-users: "Todos os usuários"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "Todas as notas" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -411,6 +411,7 @@ desktop:
uploading-avatar: "新しいアバターをアップロードしています" uploading-avatar: "新しいアバターをアップロードしています"
avatar-updated: "アバターを更新しました" avatar-updated: "アバターを更新しました"
choose-avatar: "アバターにする画像を選択" choose-avatar: "アバターにする画像を選択"
invalid-filetype: "この形式のファイルはサポートされていません"
desktop/views/components/activity.chart.vue: desktop/views/components/activity.chart.vue:
total: "Black ... Total" total: "Black ... Total"
notes: "Blue ... Notes" notes: "Blue ... Notes"
@ -649,6 +650,7 @@ desktop/views/components/settings.vue:
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
show-clock-on-header: "右上に時計を表示する"
show-reply-target: "リプライ先を表示する" show-reply-target: "リプライ先を表示する"
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
@ -819,8 +821,8 @@ desktop/views/pages/admin/admin.dashboard.vue:
dashboard: "ダッシュボード" dashboard: "ダッシュボード"
all-users: "全てのユーザー" all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー" original-users: "このインスタンスのユーザー"
all-notes: "全てのノート" all-notes: "全ての投稿"
original-notes: "このインスタンスのノート" original-notes: "このインスタンスの投稿"
invite: "招待" invite: "招待"
desktop/views/pages/admin/admin.suspend-user.vue: desktop/views/pages/admin/admin.suspend-user.vue:
suspend-user: "ユーザーの凍結" suspend-user: "ユーザーの凍結"
@ -846,6 +848,11 @@ desktop/views/pages/deck/deck.note.vue:
reposted-by: "{}がRenote" reposted-by: "{}がRenote"
private: "この投稿は非公開です" private: "この投稿は非公開です"
deleted: "この投稿は削除されました" deleted: "この投稿は削除されました"
desktop/views/pages/stats/stats.vue:
all-users: "全てのユーザー"
original-users: "このインスタンスのユーザー"
all-notes: "全ての投稿"
original-notes: "このインスタンスの投稿"
desktop/views/pages/welcome.vue: desktop/views/pages/welcome.vue:
about: "詳しく..." about: "詳しく..."
gotit: "わかった" gotit: "わかった"
@ -1170,6 +1177,8 @@ mobile/views/pages/settings.vue:
update-available-desc: "ページを再度読み込みすると更新が適用されます。" update-available-desc: "ページを再度読み込みすると更新が適用されます。"
settings: "設定" settings: "設定"
signout: "サインアウト" signout: "サインアウト"
sound: "サウンド"
enableSounds: "サウンドを有効にする"
mobile/views/pages/user.vue: mobile/views/pages/user.vue:
follows-you: "フォローされています" follows-you: "フォローされています"
following: "フォロー" following: "フォロー"

View File

@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "8.15.0", "version": "8.16.0",
"clientVersion": "1.0.9031", "clientVersion": "1.0.9191",
"codename": "nighthike", "codename": "nighthike",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,
@ -32,7 +32,7 @@
"@types/debug": "0.0.30", "@types/debug": "0.0.30",
"@types/deep-equal": "1.0.1", "@types/deep-equal": "1.0.1",
"@types/double-ended-queue": "2.1.0", "@types/double-ended-queue": "2.1.0",
"@types/elasticsearch": "5.0.25", "@types/elasticsearch": "5.0.26",
"@types/file-type": "5.2.1", "@types/file-type": "5.2.1",
"@types/gulp": "3.8.36", "@types/gulp": "3.8.36",
"@types/gulp-htmlmin": "1.3.32", "@types/gulp-htmlmin": "1.3.32",
@ -60,7 +60,7 @@
"@types/mocha": "5.2.3", "@types/mocha": "5.2.3",
"@types/mongodb": "3.1.4", "@types/mongodb": "3.1.4",
"@types/ms": "0.7.30", "@types/ms": "0.7.30",
"@types/node": "10.9.2", "@types/node": "10.9.3",
"@types/portscanner": "2.1.0", "@types/portscanner": "2.1.0",
"@types/pug": "2.0.4", "@types/pug": "2.0.4",
"@types/qrcode": "1.2.0", "@types/qrcode": "1.2.0",
@ -76,10 +76,10 @@
"@types/speakeasy": "2.0.2", "@types/speakeasy": "2.0.2",
"@types/systeminformation": "3.23.0", "@types/systeminformation": "3.23.0",
"@types/tmp": "0.0.33", "@types/tmp": "0.0.33",
"@types/uuid": "3.4.3", "@types/uuid": "3.4.4",
"@types/webpack": "4.4.11", "@types/webpack": "4.4.11",
"@types/webpack-stream": "3.2.10", "@types/webpack-stream": "3.2.10",
"@types/websocket": "0.0.39", "@types/websocket": "0.0.40",
"@types/ws": "6.0.0", "@types/ws": "6.0.0",
"animejs": "2.2.0", "animejs": "2.2.0",
"autosize": "4.0.2", "autosize": "4.0.2",
@ -158,7 +158,7 @@
"mongodb": "3.1.1", "mongodb": "3.1.1",
"monk": "6.0.6", "monk": "6.0.6",
"ms": "2.1.1", "ms": "2.1.1",
"nan": "2.10.0", "nan": "2.11.0",
"nested-property": "0.0.7", "nested-property": "0.0.7",
"node-sass": "4.9.3", "node-sass": "4.9.3",
"node-sass-json-importer": "3.3.1", "node-sass-json-importer": "3.3.1",
@ -190,11 +190,11 @@
"single-line-log": "1.1.2", "single-line-log": "1.1.2",
"speakeasy": "2.0.0", "speakeasy": "2.0.0",
"stringz": "1.0.0", "stringz": "1.0.0",
"style-loader": "0.22.1", "style-loader": "0.23.0",
"stylus": "0.54.5", "stylus": "0.54.5",
"stylus-loader": "3.0.2", "stylus-loader": "3.0.2",
"summaly": "2.1.4", "summaly": "2.2.0",
"systeminformation": "3.43.0", "systeminformation": "3.44.2",
"syuilo-password-strength": "0.0.1", "syuilo-password-strength": "0.0.1",
"textarea-caret": "3.1.0", "textarea-caret": "3.1.0",
"tmp": "0.0.33", "tmp": "0.0.33",
@ -210,9 +210,9 @@
"vue": "2.5.17", "vue": "2.5.17",
"vue-chartjs": "3.4.0", "vue-chartjs": "3.4.0",
"vue-cropperjs": "2.2.1", "vue-cropperjs": "2.2.1",
"vue-js-modal": "1.3.19", "vue-js-modal": "1.3.24",
"vue-json-tree-view": "2.1.4", "vue-json-tree-view": "2.1.4",
"vue-loader": "15.4.0", "vue-loader": "15.4.1",
"vue-router": "3.0.1", "vue-router": "3.0.1",
"vue-style-loader": "4.1.2", "vue-style-loader": "4.1.2",
"vue-template-compiler": "2.5.17", "vue-template-compiler": "2.5.17",

View File

@ -28,18 +28,99 @@
import Vue from 'vue'; import Vue from 'vue';
import { url as misskeyUrl } from '../../../config'; import { url as misskeyUrl } from '../../../config';
// THIS IS THE WHITELIST FOR THE EMBED PLAYER
const whiteList = [
'afreecatv.com',
'aparat.com',
'applemusic.com',
'amazon.com',
'awa.fm',
'bandcamp.com',
'bbc.co.uk',
'beatport.com',
'bilibili.com',
'boomstream.com',
'breakers.tv',
'cam4.com',
'cavelis.net',
'chaturbate.com',
'cnn.com',
'cybergame.tv',
'dailymotion.com',
'deezer.com',
'djlive.pl',
'e-onkyo.com',
'eventials.com',
'facebook.com',
'fc2.com',
'gameplank.tv',
'goodgame.ru',
'google.com',
'hardtunes.com',
'instagram.com',
'johnnylooch.com',
'kexp.org',
'lahzenegar.com',
'liveedu.tv',
'livetube.cc',
'livestream.com',
'meridix.com',
'mixcloud.com',
'mixer.com',
'mobcrush.com',
'mylive.in.th',
'myspace.com',
'netflix.com',
'newretrowave.com',
'nhk.or.jp',
'nicovideo.jp',
'nico.ms',
'noisetrade.com',
'nood.tv',
'npr.org',
'openrec.tv',
'pandora.com',
'pandora.tv',
'picarto.tv',
'pscp.tv',
'restream.io',
'reverbnation.com',
'sermonaudio.com',
'smashcast.tv',
'songkick.com',
'soundcloud.com',
'spinninrecords.com',
'spotify.com',
'stitcher.com',
'stream.me',
'switchboard.live',
'tunein.com',
'twitcasting.tv',
'twitch.tv',
'twitter.com',
'vaughnlive.tv',
'veoh.com',
'vimeo.com',
'watchpeoplecode.com',
'web.tv',
'youtube.com',
'youtu.be'
];
export default Vue.extend({ export default Vue.extend({
props: { props: {
url: { url: {
type: String, type: String,
require: true require: true
}, },
detail: { detail: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false default: false
} }
}, },
data() { data() {
return { return {
fetching: true, fetching: true,
@ -57,6 +138,7 @@ export default Vue.extend({
misskeyUrl misskeyUrl
}; };
}, },
created() { created() {
const url = new URL(this.url); const url = new URL(this.url);
@ -81,97 +163,22 @@ export default Vue.extend({
} }
return; return;
} }
fetch('/url?url=' + encodeURIComponent(this.url)).then(res => { fetch('/url?url=' + encodeURIComponent(this.url)).then(res => {
res.json().then(info => { res.json().then(info => {
if (info.url != null) { if (info.url == null) return;
this.title = info.title; this.title = info.title;
this.description = info.description; this.description = info.description;
this.thumbnail = info.thumbnail; this.thumbnail = info.thumbnail;
this.icon = info.icon; this.icon = info.icon;
this.sitename = info.sitename; this.sitename = info.sitename;
this.fetching = false; this.fetching = false;
if ([ // THIS IS THE WHITELIST FOR THE EMBED PLAYER if (whiteList.some(x => x == url.hostname || url.hostname.endsWith(`.${x}`))) {
'afreecatv.com', this.player = info.player;
'aparat.com', }
'applemusic.com', })
'amazon.com', });
'awa.fm', }
'bandcamp.com',
'bbc.co.uk',
'beatport.com',
'bilibili.com',
'boomstream.com',
'breakers.tv',
'cam4.com',
'cavelis.net',
'chaturbate.com',
'cnn.com',
'cybergame.tv',
'dailymotion.com',
'deezer.com',
'djlive.pl',
'e-onkyo.com',
'eventials.com',
'facebook.com',
'fc2.com',
'gameplank.tv',
'goodgame.ru',
'google.com',
'hardtunes.com',
'instagram.com',
'johnnylooch.com',
'kexp.org',
'lahzenegar.com',
'liveedu.tv',
'livetube.cc',
'livestream.com',
'meridix.com',
'mixcloud.com',
'mixer.com',
'mobcrush.com',
'mylive.in.th',
'myspace.com',
'netflix.com',
'newretrowave.com',
'nhk.or.jp',
'nicovideo.jp',
'nico.ms',
'noisetrade.com',
'nood.tv',
'npr.org',
'openrec.tv',
'pandora.com',
'pandora.tv',
'picarto.tv',
'pscp.tv',
'restream.io',
'reverbnation.com',
'sermonaudio.com',
'smashcast.tv',
'songkick.com',
'soundcloud.com',
'spinninrecords.com',
'spotify.com',
'stitcher.com',
'stream.me',
'switchboard.live',
'tunein.com',
'twitcasting.tv',
'twitch.tv',
'twitter.com',
'vaughnlive.tv',
'veoh.com',
'vimeo.com',
'watchpeoplecode.com',
'web.tv',
'youtube.com',
'youtu.be'
].some(x => x == url.hostname || url.hostname.endsWith(`.${x}`)))
this.player = info.player;
} // info.url
}) // json
}); // fetch
} // created
}); });
</script> </script>

View File

@ -2,7 +2,7 @@
<div class="mkw-donation" :data-mobile="platform == 'mobile'"> <div class="mkw-donation" :data-mobile="platform == 'mobile'">
<article> <article>
<h1>%fa:heart%%i18n:@title%</h1> <h1>%fa:heart%%i18n:@title%</h1>
<p> <p v-if="meta">
{{ '%i18n:@text%'.substr(0, '%i18n:@text%'.indexOf('{')) }} {{ '%i18n:@text%'.substr(0, '%i18n:@text%'.indexOf('{')) }}
<a :href="meta.maintainer.url">{{ meta.maintainer.name }}</a> <a :href="meta.maintainer.url">{{ meta.maintainer.name }}</a>
{{ '%i18n:@text%'.substr('%i18n:@text%'.indexOf('}') + 1) }} {{ '%i18n:@text%'.substr('%i18n:@text%'.indexOf('}') + 1) }}

View File

@ -4,6 +4,7 @@ declare const _THEME_COLOR_: string;
declare const _COPYRIGHT_: string; declare const _COPYRIGHT_: string;
declare const _VERSION_: string; declare const _VERSION_: string;
declare const _CODENAME_: string; declare const _CODENAME_: string;
declare const _ENV_: string;
const address = new URL(location.href); const address = new URL(location.href);
@ -18,3 +19,4 @@ export const themeColor = _THEME_COLOR_;
export const copyright = _COPYRIGHT_; export const copyright = _COPYRIGHT_;
export const version = _VERSION_; export const version = _VERSION_;
export const codename = _CODENAME_; export const codename = _CODENAME_;
export const env = _ENV_;

View File

@ -3,8 +3,21 @@ import { apiUrl } from '../../config';
import CropWindow from '../views/components/crop-window.vue'; import CropWindow from '../views/components/crop-window.vue';
import ProgressDialog from '../views/components/progress-dialog.vue'; import ProgressDialog from '../views/components/progress-dialog.vue';
export default (os: OS) => (cb, file = null) => { export default (os: OS) => {
const fileSelected = file => {
const cropImage = file => new Promise((resolve, reject) => {
const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
if (!regex.test(file.name) ) {
os.apis.dialog({
title: '%fa:info-circle% %i18n:desktop.invalid-filetype%',
text: null,
actions: [{
text: '%i18n:common.got-it%'
}]
});
reject();
}
const w = os.new(CropWindow, { const w = os.new(CropWindow, {
image: file, image: file,
@ -19,27 +32,29 @@ export default (os: OS) => (cb, file = null) => {
os.api('drive/folders/find', { os.api('drive/folders/find', {
name: '%i18n:desktop.avatar%' name: '%i18n:desktop.avatar%'
}).then(iconFolder => { }).then(avatarFolder => {
if (iconFolder.length === 0) { if (avatarFolder.length === 0) {
os.api('drive/folders/create', { os.api('drive/folders/create', {
name: '%i18n:desktop.avatar%' name: '%i18n:desktop.avatar%'
}).then(iconFolder => { }).then(iconFolder => {
upload(data, iconFolder); resolve(upload(data, iconFolder));
}); });
} else { } else {
upload(data, iconFolder[0]); resolve(upload(data, avatarFolder[0]));
} }
}); });
}); });
w.$once('skipped', () => { w.$once('skipped', () => {
set(file); resolve(file);
}); });
document.body.appendChild(w.$el); w.$once('cancelled', reject);
};
const upload = (data, folder) => { document.body.appendChild(w.$el);
});
const upload = (data, folder) => new Promise((resolve, reject) => {
const dialog = os.new(ProgressDialog, { const dialog = os.new(ProgressDialog, {
title: '%i18n:desktop.uploading-avatar%' title: '%i18n:desktop.uploading-avatar%'
}); });
@ -52,18 +67,19 @@ export default (os: OS) => (cb, file = null) => {
xhr.onload = e => { xhr.onload = e => {
const file = JSON.parse((e.target as any).response); const file = JSON.parse((e.target as any).response);
(dialog as any).close(); (dialog as any).close();
set(file); resolve(file);
}; };
xhr.onerror = reject;
xhr.upload.onprogress = e => { xhr.upload.onprogress = e => {
if (e.lengthComputable) (dialog as any).update(e.loaded, e.total); if (e.lengthComputable) (dialog as any).update(e.loaded, e.total);
}; };
xhr.send(data); xhr.send(data);
}; });
const set = file => { const setAvatar = file => {
os.api('i/update', { return os.api('i/update', {
avatarId: file.id avatarId: file.id
}).then(i => { }).then(i => {
os.store.commit('updateIKeyValue', { os.store.commit('updateIKeyValue', {
@ -83,18 +99,21 @@ export default (os: OS) => (cb, file = null) => {
}] }]
}); });
if (cb) cb(i); return i;
}); });
}; };
if (file) { return (file = null) => {
fileSelected(file); const selectedFile = file
} else { ? Promise.resolve(file)
os.apis.chooseDriveFile({ : os.apis.chooseDriveFile({
multiple: false, multiple: false,
title: '%fa:image% %i18n:desktop.choose-avatar%' title: '%fa:image% %i18n:desktop.choose-avatar%'
}).then(file => { });
fileSelected(file);
}); return selectedFile
} .then(cropImage)
.then(setAvatar)
.catch(err => err && console.warn(err));
};
}; };

View File

@ -6,6 +6,19 @@ import ProgressDialog from '../views/components/progress-dialog.vue';
export default (os: OS) => { export default (os: OS) => {
const cropImage = file => new Promise((resolve, reject) => { const cropImage = file => new Promise((resolve, reject) => {
const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$');
if (!regex.test(file.name) ) {
os.apis.dialog({
title: '%fa:info-circle% %i18n:desktop.invalid-filetype%',
text: null,
actions: [{
text: '%i18n:common.got-it%'
}]
});
reject();
}
const w = os.new(CropWindow, { const w = os.new(CropWindow, {
image: file, image: file,
title: '%i18n:desktop.banner-crop-title%', title: '%i18n:desktop.banner-crop-title%',

View File

@ -88,7 +88,9 @@ export default Vue.extend({
}, },
created() { created() {
(this as any).api('chart').then(chart => { (this as any).api('chart', {
limit: 32
}).then(chart => {
this.chart = chart; this.chart = chart;
}); });
}, },
@ -580,6 +582,6 @@ export default Vue.extend({
> div > div
> * > *
display block display block
height 300px height 320px
</style> </style>

View File

@ -47,7 +47,7 @@
</div> </div>
<mk-poll v-if="p.poll" :note="p"/> <mk-poll v-if="p.poll" :note="p"/>
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/> <mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> <a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
<div class="map" v-if="p.geo" ref="map"></div> <div class="map" v-if="p.geo" ref="map"></div>
<div class="renote" v-if="p.renote"> <div class="renote" v-if="p.renote">
<mk-note-preview :note="p.renote"/> <mk-note-preview :note="p.renote"/>

View File

@ -32,7 +32,7 @@
<mk-media-list :media-list="p.media"/> <mk-media-list :media-list="p.media"/>
</div> </div>
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/> <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a> <a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
<div class="map" v-if="p.geo" ref="map"></div> <div class="map" v-if="p.geo" ref="map"></div>
<div class="renote" v-if="p.renote"> <div class="renote" v-if="p.renote">
<mk-note-preview :note="p.renote"/> <mk-note-preview :note="p.renote"/>

View File

@ -11,7 +11,7 @@
<li class="deck" :class="{ active: $route.name == 'deck' }" @click="goToTop"> <li class="deck" :class="{ active: $route.name == 'deck' }" @click="goToTop">
<router-link to="/deck"> <router-link to="/deck">
%fa:columns% %fa:columns%
<p>%i18n:@deck% <small>(beta)</small></p> <p>%i18n:@deck%</p>
</router-link> </router-link>
</li> </li>
<li class="messaging"> <li class="messaging">

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="header"> <div class="header">
<p class="warn" v-if="env != 'production'">%i18n:common.do-not-use-in-production%</p>
<mk-special-message/> <mk-special-message/>
<div class="main" ref="main"> <div class="main" ref="main">
<div class="backdrop"></div> <div class="backdrop"></div>
@ -28,6 +29,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import * as anime from 'animejs'; import * as anime from 'animejs';
import { env } from '../../../config';
import XNav from './ui.header.nav.vue'; import XNav from './ui.header.nav.vue';
import XSearch from './ui.header.search.vue'; import XSearch from './ui.header.search.vue';
@ -43,7 +45,13 @@ export default Vue.extend({
XAccount, XAccount,
XNotifications, XNotifications,
XPost, XPost,
XClock, XClock
},
data() {
return {
env: env
};
}, },
mounted() { mounted() {
@ -119,6 +127,15 @@ root(isDark)
width 100% width 100%
box-shadow 0 1px 1px rgba(#000, 0.075) box-shadow 0 1px 1px rgba(#000, 0.075)
> .warn
display block
margin 0
padding 4px
text-align center
font-size 12px
background #f00
color #fff
> .main > .main
height 48px height 48px

View File

@ -32,7 +32,7 @@
<mk-media-list :media-list="p.media"/> <mk-media-list :media-list="p.media"/>
</div> </div>
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/> <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> <a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
<div class="renote" v-if="p.renote"> <div class="renote" v-if="p.renote">
<mk-note-preview :note="p.renote" :mini="true"/> <mk-note-preview :note="p.renote" :mini="true"/>
</div> </div>

View File

@ -60,5 +60,5 @@ export default Vue.extend({
font-size 70% font-size 70%
> div > div
max-width 800px max-width 850px
</style> </style>

View File

@ -40,10 +40,12 @@ export default Vue.extend({
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
root(isDark)
.friends .friends
background #fff background isDark ? #282C37 : #fff
border solid 1px rgba(#000, 0.075) border solid 1px rgba(#000, 0.075)
border-radius 6px border-radius 6px
overflow hidden
> .title > .title
z-index 1 z-index 1
@ -52,7 +54,8 @@ export default Vue.extend({
line-height 42px line-height 42px
font-size 0.9em font-size 0.9em
font-weight bold font-weight bold
color #888 background isDark ? #313543 : inherit
color isDark ? #e3e5e8 : #888
box-shadow 0 1px rgba(#000, 0.07) box-shadow 0 1px rgba(#000, 0.07)
> i > i
@ -70,7 +73,7 @@ export default Vue.extend({
> .user > .user
padding 16px padding 16px
border-bottom solid 1px #eee border-bottom solid 1px isDark ? #21242f : #eee
&:last-child &:last-child
border-bottom none border-bottom none
@ -96,18 +99,24 @@ export default Vue.extend({
margin 0 margin 0
font-size 16px font-size 16px
line-height 24px line-height 24px
color #555 color isDark ? #ccc : #555
> .username > .username
display block display block
margin 0 margin 0
font-size 15px font-size 15px
line-height 16px line-height 16px
color #ccc color isDark ? #555 : #ccc
> .mk-follow-button > .mk-follow-button
position absolute position absolute
top 16px top 16px
right 16px right 16px
.friends[data-darkmode]
root(true)
.friends:not([data-darkmode])
root(false)
</style> </style>

View File

@ -39,10 +39,12 @@ export default Vue.extend({
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
root(isDark)
.photos .photos
background #fff background isDark ? #282C37 : #fff
border solid 1px rgba(#000, 0.075) border solid 1px rgba(#000, 0.075)
border-radius 6px border-radius 6px
overflow hidden
> .title > .title
z-index 1 z-index 1
@ -51,7 +53,8 @@ export default Vue.extend({
line-height 42px line-height 42px
font-size 0.9em font-size 0.9em
font-weight bold font-weight bold
color #888 background: isDark ? #313543 : inherit
color isDark ? #e3e5e8 : #888
box-shadow 0 1px rgba(#000, 0.07) box-shadow 0 1px rgba(#000, 0.07)
> i > i
@ -85,4 +88,10 @@ export default Vue.extend({
> i > i
margin-right 4px margin-right 4px
.photos[data-darkmode]
root(true)
.photos:not([data-darkmode])
root(false)
</style> </style>

View File

@ -138,7 +138,7 @@ root(isDark)
padding 16px padding 16px
font-size 12px font-size 12px
color #aaa color #aaa
background #fff background isDark ? #21242f : #fff
border solid 1px rgba(#000, 0.075) border solid 1px rgba(#000, 0.075)
border-radius 6px border-radius 6px

View File

@ -19,8 +19,8 @@ import { version, codename, lang } from './config';
let elementLocale; let elementLocale;
switch (lang) { switch (lang) {
case 'ja': elementLocale = ElementLocaleJa; break; case 'ja-JP': elementLocale = ElementLocaleJa; break;
case 'en': elementLocale = ElementLocaleEn; break; case 'en-US': elementLocale = ElementLocaleEn; break;
default: elementLocale = ElementLocaleEn; break; default: elementLocale = ElementLocaleEn; break;
} }

View File

@ -45,7 +45,7 @@
</div> </div>
<mk-poll v-if="p.poll" :note="p"/> <mk-poll v-if="p.poll" :note="p"/>
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/> <mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> <a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
<div class="map" v-if="p.geo" ref="map"></div> <div class="map" v-if="p.geo" ref="map"></div>
<div class="renote" v-if="p.renote"> <div class="renote" v-if="p.renote">
<mk-note-preview :note="p.renote"/> <mk-note-preview :note="p.renote"/>

View File

@ -33,7 +33,7 @@
</div> </div>
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/> <mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
<mk-url-preview v-for="url in urls" :url="url" :key="url"/> <mk-url-preview v-for="url in urls" :url="url" :key="url"/>
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> <a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
<div class="map" v-if="p.geo" ref="map"></div> <div class="map" v-if="p.geo" ref="map"></div>
<div class="renote" v-if="p.renote"> <div class="renote" v-if="p.renote">
<mk-note-preview :note="p.renote"/> <mk-note-preview :note="p.renote"/>

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="header"> <div class="header" ref="root">
<p class="warn" v-if="env != 'production'">%i18n:common.do-not-use-in-production%</p>
<mk-special-message/> <mk-special-message/>
<div class="main" ref="main"> <div class="main" ref="main">
<div class="backdrop"></div> <div class="backdrop"></div>
@ -20,6 +21,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import * as anime from 'animejs'; import * as anime from 'animejs';
import { env } from '../../../config';
export default Vue.extend({ export default Vue.extend({
props: ['func'], props: ['func'],
@ -27,7 +29,8 @@ export default Vue.extend({
return { return {
hasGameInvitation: false, hasGameInvitation: false,
connection: null, connection: null,
connectionId: null connectionId: null,
env: env
}; };
}, },
computed: { computed: {
@ -39,7 +42,7 @@ export default Vue.extend({
} }
}, },
mounted() { mounted() {
this.$store.commit('setUiHeaderHeight', 48); this.$store.commit('setUiHeaderHeight', this.$refs.root.offsetHeight);
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection = (this as any).os.stream.getConnection(); this.connection = (this as any).os.stream.getConnection();
@ -133,6 +136,15 @@ root(isDark)
height 3px height 3px
background $theme-color background $theme-color
> .warn
display block
margin 0
padding 4px
text-align center
font-size 12px
background #f00
color #fff
> .main > .main
color rgba(#fff, 0.9) color rgba(#fff, 0.9)

View File

@ -31,7 +31,14 @@ export default Vue.extend({
connectionId: null connectionId: null
}; };
}, },
watch: {
'$store.state.uiHeaderHeight'() {
this.$el.style.paddingTop = this.$store.state.uiHeaderHeight + 'px';
}
},
mounted() { mounted() {
this.$el.style.paddingTop = this.$store.state.uiHeaderHeight + 'px';
if (this.$store.getters.isSignedIn) { if (this.$store.getters.isSignedIn) {
this.connection = (this as any).os.stream.getConnection(); this.connection = (this as any).os.stream.getConnection();
this.connectionId = (this as any).os.stream.use(); this.connectionId = (this as any).os.stream.use();

View File

@ -41,6 +41,12 @@
<ui-switch v-model="lightmode">%i18n:@i-am-under-limited-internet%</ui-switch> <ui-switch v-model="lightmode">%i18n:@i-am-under-limited-internet%</ui-switch>
</ui-card> </ui-card>
<ui-card>
<div slot="title">%fa:volume-up% %i18n:@sound%</div>
<ui-switch v-model="enableSounds">%i18n:@enable-sounds%</ui-switch>
</ui-card>
<ui-card> <ui-card>
<div slot="title">%fa:language% %i18n:@lang%</div> <div slot="title">%fa:language% %i18n:@lang%</div>
@ -142,6 +148,11 @@ export default Vue.extend({
get() { return this.$store.state.device.lang; }, get() { return this.$store.state.device.lang; },
set(value) { this.$store.commit('device/set', { key: 'lang', value }); } set(value) { this.$store.commit('device/set', { key: 'lang', value }); }
}, },
enableSounds: {
get() { return this.$store.state.device.enableSounds; },
set(value) { this.$store.commit('device/set', { key: 'enableSounds', value }); }
},
}, },
mounted() { mounted() {

View File

@ -13,7 +13,7 @@ const defaultSettings = {
showMaps: true, showMaps: true,
showPostFormOnTopOfTl: false, showPostFormOnTopOfTl: false,
suggestRecentHashtags: true, suggestRecentHashtags: true,
showClockOnHeader: false, showClockOnHeader: true,
circleIcons: true, circleIcons: true,
gradientWindowHeader: false, gradientWindowHeader: false,
showReplyTarget: true, showReplyTarget: true,

View File

@ -15,7 +15,7 @@ block main
span.path= endpointUrl.path span.path= endpointUrl.path
if endpoint.desc if endpoint.desc
p#desc= endpoint.desc[lang] || endpoint.desc['ja'] p#desc= endpoint.desc[lang] || endpoint.desc['ja-JP']
if endpoint.requireCredential if endpoint.requireCredential
div.ui.info: p div.ui.info: p

View File

@ -1,90 +1,90 @@
name: "DriveFile" name: "DriveFile"
desc: desc:
ja: "ドライブのファイル。" ja-JP: "ドライブのファイル。"
en: "A file of Drive." en-US: "A file of Drive."
props: props:
id: id:
type: "id" type: "id"
optional: false optional: false
desc: desc:
ja: "ファイルID" ja-JP: "ファイルID"
en: "The ID of this file" en-US: "The ID of this file"
createdAt: createdAt:
type: "date" type: "date"
optional: false optional: false
desc: desc:
ja: "アップロード日時" ja-JP: "アップロード日時"
en: "The upload date of this file" en-US: "The upload date of this file"
userId: userId:
type: "id(User)" type: "id(User)"
optional: false optional: false
desc: desc:
ja: "所有者ID" ja-JP: "所有者ID"
en: "The ID of the owner of this file" en-US: "The ID of the owner of this file"
user: user:
type: "entity(User)" type: "entity(User)"
optional: true optional: true
desc: desc:
ja: "所有者" ja-JP: "所有者"
en: "The owner of this file" en-US: "The owner of this file"
name: name:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ファイル名" ja-JP: "ファイル名"
en: "The name of this file" en-US: "The name of this file"
md5: md5:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ファイルのMD5ハッシュ値" ja-JP: "ファイルのMD5ハッシュ値"
en: "The md5 hash value of this file" en-US: "The md5 hash value of this file"
type: type:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ファイルの種類" ja-JP: "ファイルの種類"
en: "The type of this file" en-US: "The type of this file"
datasize: datasize:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "ファイルサイズ(bytes)" ja-JP: "ファイルサイズ(bytes)"
en: "The size of this file (bytes)" en-US: "The size of this file (bytes)"
url: url:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ファイルのURL" ja-JP: "ファイルのURL"
en: "The URL of this file" en-US: "The URL of this file"
folderId: folderId:
type: "id(DriveFolder)" type: "id(DriveFolder)"
optional: true optional: true
desc: desc:
ja: "フォルダID" ja-JP: "フォルダID"
en: "The ID of the folder of this file" en-US: "The ID of the folder of this file"
folder: folder:
type: "entity(DriveFolder)" type: "entity(DriveFolder)"
optional: true optional: true
desc: desc:
ja: "フォルダ" ja-JP: "フォルダ"
en: "The folder of this file" en-US: "The folder of this file"
isSensitive: isSensitive:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "このメディアが「閲覧注意」(NSFW)かどうか" ja-JP: "このメディアが「閲覧注意」(NSFW)かどうか"
en: "Whether this media is NSFW" en-US: "Whether this media is NSFW"

View File

@ -1,41 +1,41 @@
name: "DriveFolder" name: "DriveFolder"
desc: desc:
ja: "ドライブのフォルダを表します。" ja-JP: "ドライブのフォルダを表します。"
en: "A folder of Drive." en-US: "A folder of Drive."
props: props:
id: id:
type: "id" type: "id"
optional: false optional: false
desc: desc:
ja: "フォルダID" ja-JP: "フォルダID"
en: "The ID of this folder" en-US: "The ID of this folder"
createdAt: createdAt:
type: "date" type: "date"
optional: false optional: false
desc: desc:
ja: "作成日時" ja-JP: "作成日時"
en: "The created date of this folder" en-US: "The created date of this folder"
userId: userId:
type: "id(User)" type: "id(User)"
optional: false optional: false
desc: desc:
ja: "所有者ID" ja-JP: "所有者ID"
en: "The ID of the owner of this folder" en-US: "The ID of the owner of this folder"
parentId: parentId:
type: "entity(DriveFolder)" type: "entity(DriveFolder)"
optional: false optional: false
desc: desc:
ja: "親フォルダのID (ルートなら null)" ja-JP: "親フォルダのID (ルートなら null)"
en: "The ID of parent folder" en-US: "The ID of parent folder"
name: name:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "フォルダ名" ja-JP: "フォルダ名"
en: "The name of this folder" en-US: "The name of this folder"

View File

@ -1,190 +1,190 @@
name: "Note" name: "Note"
desc: desc:
ja: "投稿。" ja-JP: "投稿。"
en: "A note." en-US: "A note."
props: props:
id: id:
type: "id" type: "id"
optional: false optional: false
desc: desc:
ja: "投稿ID" ja-JP: "投稿ID"
en: "The ID of this note" en-US: "The ID of this note"
createdAt: createdAt:
type: "date" type: "date"
optional: false optional: false
desc: desc:
ja: "投稿日時" ja-JP: "投稿日時"
en: "The posted date of this note" en-US: "The posted date of this note"
viaMobile: viaMobile:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "モバイル端末から投稿したか否か(自己申告であることに留意)" ja-JP: "モバイル端末から投稿したか否か(自己申告であることに留意)"
en: "Whether this note sent via a mobile device" en-US: "Whether this note sent via a mobile device"
text: text:
type: "string" type: "string"
optional: true optional: true
desc: desc:
ja: "投稿の本文" ja-JP: "投稿の本文"
en: "The text of this note" en-US: "The text of this note"
mediaIds: mediaIds:
type: "id(DriveFile)[]" type: "id(DriveFile)[]"
optional: true optional: true
desc: desc:
ja: "添付されているメディアのID (なければレスポンスでは空配列)" ja-JP: "添付されているメディアのID (なければレスポンスでは空配列)"
en: "The IDs of the attached media (empty array for response if no media is attached)" en-US: "The IDs of the attached media (empty array for response if no media is attached)"
media: media:
type: "entity(DriveFile)[]" type: "entity(DriveFile)[]"
optional: true optional: true
desc: desc:
ja: "添付されているメディア" ja-JP: "添付されているメディア"
en: "The attached media" en-US: "The attached media"
userId: userId:
type: "id(User)" type: "id(User)"
optional: false optional: false
desc: desc:
ja: "投稿者ID" ja-JP: "投稿者ID"
en: "The ID of author of this note" en-US: "The ID of author of this note"
user: user:
type: "entity(User)" type: "entity(User)"
optional: true optional: true
desc: desc:
ja: "投稿者" ja-JP: "投稿者"
en: "The author of this note" en-US: "The author of this note"
myReaction: myReaction:
type: "string" type: "string"
optional: true optional: true
desc: desc:
ja: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>" ja-JP: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>"
en: "The your <a href='/docs/api/reactions'>reaction</a> of this note" en-US: "The your <a href='/docs/api/reactions'>reaction</a> of this note"
reactionCounts: reactionCounts:
type: "object" type: "object"
optional: false optional: false
desc: desc:
ja: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト" ja-JP: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト"
replyId: replyId:
type: "id(Note)" type: "id(Note)"
optional: true optional: true
desc: desc:
ja: "返信した投稿のID" ja-JP: "返信した投稿のID"
en: "The ID of the replyed note" en-US: "The ID of the replyed note"
reply: reply:
type: "entity(Note)" type: "entity(Note)"
optional: true optional: true
desc: desc:
ja: "返信した投稿" ja-JP: "返信した投稿"
en: "The replyed note" en-US: "The replyed note"
renoteId: renoteId:
type: "id(Note)" type: "id(Note)"
optional: true optional: true
desc: desc:
ja: "引用した投稿のID" ja-JP: "引用した投稿のID"
en: "The ID of the quoted note" en-US: "The ID of the quoted note"
renote: renote:
type: "entity(Note)" type: "entity(Note)"
optional: true optional: true
desc: desc:
ja: "引用した投稿" ja-JP: "引用した投稿"
en: "The quoted note" en-US: "The quoted note"
poll: poll:
type: "object" type: "object"
optional: true optional: true
desc: desc:
ja: "投票" ja-JP: "投票"
en: "The poll" en-US: "The poll"
props: props:
choices: choices:
type: "object[]" type: "object[]"
optional: false optional: false
desc: desc:
ja: "投票の選択肢" ja-JP: "投票の選択肢"
en: "The choices of this poll" en-US: "The choices of this poll"
props: props:
id: id:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "選択肢ID" ja-JP: "選択肢ID"
en: "The ID of this choice" en-US: "The ID of this choice"
isVoted: isVoted:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "自分がこの選択肢に投票したかどうか" ja-JP: "自分がこの選択肢に投票したかどうか"
en: "Whether you voted to this choice" en-US: "Whether you voted to this choice"
text: text:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "選択肢本文" ja-JP: "選択肢本文"
en: "The text of this choice" en-US: "The text of this choice"
votes: votes:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "この選択肢に投票された数" ja-JP: "この選択肢に投票された数"
en: "The number voted for this choice" en-US: "The number voted for this choice"
geo: geo:
type: "object" type: "object"
optional: true optional: true
desc: desc:
ja: "位置情報" ja-JP: "位置情報"
en: "Geo location" en-US: "Geo location"
props: props:
coordinates: coordinates:
type: "number[]" type: "number[]"
optional: false optional: false
desc: desc:
ja: "座標。最初に経度:-180〜180で表す。最後に緯度-90〜90で表す。" ja-JP: "座標。最初に経度:-180〜180で表す。最後に緯度-90〜90で表す。"
altitude: altitude:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "高度。メートル単位で表す。" ja-JP: "高度。メートル単位で表す。"
accuracy: accuracy:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "緯度、経度の精度。メートル単位で表す。" ja-JP: "緯度、経度の精度。メートル単位で表す。"
altitudeAccuracy: altitudeAccuracy:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "高度の精度。メートル単位で表す。" ja-JP: "高度の精度。メートル単位で表す。"
heading: heading:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。" ja-JP: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。"
speed: speed:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "速度。メートル / 秒数で表す。" ja-JP: "速度。メートル / 秒数で表す。"

View File

@ -1,174 +1,174 @@
name: "User" name: "User"
desc: desc:
ja: "ユーザー。" ja-JP: "ユーザー。"
en: "A user." en-US: "A user."
props: props:
id: id:
type: "id" type: "id"
optional: false optional: false
desc: desc:
ja: "ユーザーID" ja-JP: "ユーザーID"
en: "The ID of this user" en-US: "The ID of this user"
createdAt: createdAt:
type: "date" type: "date"
optional: false optional: false
desc: desc:
ja: "アカウント作成日時" ja-JP: "アカウント作成日時"
en: "The registered date of this user" en-US: "The registered date of this user"
username: username:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ユーザー名" ja-JP: "ユーザー名"
en: "The username of this user" en-US: "The username of this user"
description: description:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "アカウントの説明(自己紹介)" ja-JP: "アカウントの説明(自己紹介)"
en: "The description of this user" en-US: "The description of this user"
avatarId: avatarId:
type: "id(DriveFile)" type: "id(DriveFile)"
optional: true optional: true
desc: desc:
ja: "アバターのID" ja-JP: "アバターのID"
en: "The ID of the avatar of this user" en-US: "The ID of the avatar of this user"
avatarUrl: avatarUrl:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "アバターのURL" ja-JP: "アバターのURL"
en: "The URL of the avatar of this user" en-US: "The URL of the avatar of this user"
bannerId: bannerId:
type: "id(DriveFile)" type: "id(DriveFile)"
optional: true optional: true
desc: desc:
ja: "バナーのID" ja-JP: "バナーのID"
en: "The ID of the banner of this user" en-US: "The ID of the banner of this user"
bannerUrl: bannerUrl:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "バナーのURL" ja-JP: "バナーのURL"
en: "The URL of the banner of this user" en-US: "The URL of the banner of this user"
followersCount: followersCount:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "フォロワーの数" ja-JP: "フォロワーの数"
en: "The number of the followers for this user" en-US: "The number of the followers for this user"
followingCount: followingCount:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "フォローしているユーザーの数" ja-JP: "フォローしているユーザーの数"
en: "The number of the following users for this user" en-US: "The number of the following users for this user"
isFollowing: isFollowing:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "自分がこのユーザーをフォローしているか" ja-JP: "自分がこのユーザーをフォローしているか"
isFollowed: isFollowed:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "自分がこのユーザーにフォローされているか" ja-JP: "自分がこのユーザーにフォローされているか"
isMuted: isMuted:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "自分がこのユーザーをミュートしているか" ja-JP: "自分がこのユーザーをミュートしているか"
en: "Whether you muted this user" en-US: "Whether you muted this user"
notesCount: notesCount:
type: "number" type: "number"
optional: false optional: false
desc: desc:
ja: "投稿の数" ja-JP: "投稿の数"
en: "The number of the notes of this user" en-US: "The number of the notes of this user"
pinnedNote: pinnedNote:
type: "entity(Note)" type: "entity(Note)"
optional: true optional: true
desc: desc:
ja: "ピン留めされた投稿" ja-JP: "ピン留めされた投稿"
en: "The pinned note of this user" en-US: "The pinned note of this user"
pinnedNoteId: pinnedNoteId:
type: "id(Note)" type: "id(Note)"
optional: true optional: true
desc: desc:
ja: "ピン留めされた投稿のID" ja-JP: "ピン留めされた投稿のID"
en: "The ID of the pinned note of this user" en-US: "The ID of the pinned note of this user"
host: host:
type: "string | null" type: "string | null"
optional: false optional: false
desc: desc:
ja: "ホスト (例: example.com:3000)" ja-JP: "ホスト (例: example.com:3000)"
en: "Host (e.g. example.com:3000)" en-US: "Host (e.g. example.com:3000)"
twitter: twitter:
type: "object" type: "object"
optional: true optional: true
desc: desc:
ja: "連携されているTwitterアカウント情報" ja-JP: "連携されているTwitterアカウント情報"
en: "The info of the connected twitter account of this user" en-US: "The info of the connected twitter account of this user"
props: props:
userId: userId:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ユーザーID" ja-JP: "ユーザーID"
en: "The user ID" en-US: "The user ID"
screenName: screenName:
type: "string" type: "string"
optional: false optional: false
desc: desc:
ja: "ユーザー名" ja-JP: "ユーザー名"
en: "The screen name of this user" en-US: "The screen name of this user"
isBot: isBot:
type: "boolean" type: "boolean"
optional: true optional: true
desc: desc:
ja: "botか否か(自己申告であることに留意)" ja-JP: "botか否か(自己申告であることに留意)"
en: "Whether is bot or not" en-US: "Whether is bot or not"
profile: profile:
type: "object" type: "object"
optional: false optional: false
desc: desc:
ja: "プロフィール" ja-JP: "プロフィール"
en: "The profile of this user" en-US: "The profile of this user"
props: props:
location: location:
type: "string" type: "string"
optional: true optional: true
desc: desc:
ja: "場所" ja-JP: "場所"
en: "The location of this user" en-US: "The location of this user"
birthday: birthday:
type: "string" type: "string"
optional: true optional: true
desc: desc:
ja: "誕生日 (YYYY-MM-DD)" ja-JP: "誕生日 (YYYY-MM-DD)"
en: "The birthday of this user (YYYY-MM-DD)" en-US: "The birthday of this user (YYYY-MM-DD)"

View File

@ -7,7 +7,7 @@ block meta
block main block main
h1= name h1= name
p#desc= desc[lang] || desc['ja'] p#desc= desc[lang] || desc['ja-JP']
section section
h2= i18n('docs.api.entities.properties') h2= i18n('docs.api.entities.properties')

View File

@ -31,4 +31,4 @@ mixin propTable(props)
td.name= prop.name td.name= prop.name
td.type td.type
+type(prop) +type(prop)
td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja'] : null td.desc!= prop.desc ? prop.desc[lang] || prop.desc['ja-JP'] : null

View File

@ -16,7 +16,7 @@ html(lang= lang)
nav nav
ul ul
each doc in docs each doc in docs
li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja'] li: a(href=`/docs/${lang}/${doc.name}`)= doc.title[lang] || doc.title['ja-JP']
section section
h2 API h2 API
ul ul

View File

@ -6,6 +6,8 @@ import parseAcct from '../../../misc/acct/parse';
import User, { IRemoteUser } from '../../../models/user'; import User, { IRemoteUser } from '../../../models/user';
import perform from '../../../remote/activitypub/perform'; import perform from '../../../remote/activitypub/perform';
import { resolvePerson } from '../../../remote/activitypub/models/person'; import { resolvePerson } from '../../../remote/activitypub/models/person';
import { toUnicode } from 'punycode';
import { URL } from 'url';
const log = debug('misskey:queue:inbox'); const log = debug('misskey:queue:inbox');
@ -32,6 +34,15 @@ export default async (job: bq.Job, done: any): Promise<void> => {
return; return;
} }
// アクティビティ内のホストの検証
try {
ValidateActivity(activity, host);
} catch (e) {
console.warn(e);
done();
return;
}
user = await User.findOne({ usernameLower: username, host: host.toLowerCase() }) as IRemoteUser; user = await User.findOne({ usernameLower: username, host: host.toLowerCase() }) as IRemoteUser;
// アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する // アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
@ -39,6 +50,16 @@ export default async (job: bq.Job, done: any): Promise<void> => {
user = await resolvePerson(activity.actor) as IRemoteUser; user = await resolvePerson(activity.actor) as IRemoteUser;
} }
} else { } else {
// アクティビティ内のホストの検証
const host = toUnicode(new URL(signature.keyId).hostname.toLowerCase());
try {
ValidateActivity(activity, host);
} catch (e) {
console.warn(e);
done();
return;
}
user = await User.findOne({ user = await User.findOne({
host: { $ne: null }, host: { $ne: null },
'publicKey.id': signature.keyId 'publicKey.id': signature.keyId
@ -69,3 +90,37 @@ export default async (job: bq.Job, done: any): Promise<void> => {
done(e); done(e);
} }
}; };
/**
* Validate host in activity
* @param activity Activity
* @param host Expect host
*/
function ValidateActivity(activity: any, host: string) {
// id (if exists)
if (typeof activity.id === 'string') {
const uriHost = toUnicode(new URL(activity.id).hostname.toLowerCase());
if (host !== uriHost) throw new Error('activity.id has different host');
}
// actor (if exists)
if (typeof activity.actor === 'string') {
const uriHost = toUnicode(new URL(activity.actor).hostname.toLowerCase());
if (host !== uriHost) throw new Error('activity.actor has different host');
}
// For Create activity
if (activity.type === 'Create' && activity.object) {
// object.id (if exists)
if (typeof activity.object.id === 'string') {
const uriHost = toUnicode(new URL(activity.object.id).hostname.toLowerCase());
if (host !== uriHost) throw new Error('activity.object.id has different host');
}
// object.attributedTo (if exists)
if (typeof activity.object.attributedTo === 'string') {
const uriHost = toUnicode(new URL(activity.object.attributedTo).hostname.toLowerCase());
if (host !== uriHost) throw new Error('activity.object.attributedTo has different host');
}
}
}

View File

@ -4,18 +4,25 @@ import * as debug from 'debug';
import config from '../../../config'; import config from '../../../config';
import User, { validateUsername, isValidName, IUser, IRemoteUser } from '../../../models/user'; import User, { validateUsername, isValidName, IUser, IRemoteUser } from '../../../models/user';
import webFinger from '../../webfinger';
import Resolver from '../resolver'; import Resolver from '../resolver';
import { resolveImage } from './image'; import { resolveImage } from './image';
import { isCollectionOrOrderedCollection, IObject, IPerson } from '../type'; import { isCollectionOrOrderedCollection, IPerson } from '../type';
import { IDriveFile } from '../../../models/drive-file'; import { IDriveFile } from '../../../models/drive-file';
import Meta from '../../../models/meta'; import Meta from '../../../models/meta';
import htmlToMFM from '../../../mfm/html-to-mfm'; import htmlToMFM from '../../../mfm/html-to-mfm';
import { updateUserStats } from '../../../services/update-chart'; import { updateUserStats } from '../../../services/update-chart';
import { URL } from 'url';
const log = debug('misskey:activitypub'); const log = debug('misskey:activitypub');
function validatePerson(x: any) { /**
* Validate Person object
* @param x Fetched person object
* @param uri Fetch target URI
*/
function validatePerson(x: any, uri: string) {
const expectHost = toUnicode(new URL(uri).hostname.toLowerCase());
if (x == null) { if (x == null) {
return new Error('invalid person: object is null'); return new Error('invalid person: object is null');
} }
@ -40,6 +47,24 @@ function validatePerson(x: any) {
return new Error('invalid person: invalid name'); return new Error('invalid person: invalid name');
} }
if (typeof x.id !== 'string') {
return new Error('invalid person: id is not a string');
}
const idHost = toUnicode(new URL(x.id).hostname.toLowerCase());
if (idHost !== expectHost) {
return new Error('invalid person: id has different host');
}
if (typeof x.publicKey.id !== 'string') {
return new Error('invalid person: publicKey.id is not a string');
}
const publicKeyIdHost = toUnicode(new URL(x.publicKey.id).hostname.toLowerCase());
if (publicKeyIdHost !== expectHost) {
return new Error('invalid person: publicKey.id has different host');
}
return null; return null;
} }
@ -48,8 +73,8 @@ function validatePerson(x: any) {
* *
* Misskeyに対象のPersonが登録されていればそれを返します * Misskeyに対象のPersonが登録されていればそれを返します
*/ */
export async function fetchPerson(value: string | IObject, resolver?: Resolver): Promise<IUser> { export async function fetchPerson(uri: string, resolver?: Resolver): Promise<IUser> {
const uri = typeof value == 'string' ? value : value.id; if (typeof uri !== 'string') throw 'uri is not string';
// URIがこのサーバーを指しているならデータベースからフェッチ // URIがこのサーバーを指しているならデータベースからフェッチ
if (uri.startsWith(config.url + '/')) { if (uri.startsWith(config.url + '/')) {
@ -71,12 +96,14 @@ export async function fetchPerson(value: string | IObject, resolver?: Resolver):
/** /**
* Personを作成します * Personを作成します
*/ */
export async function createPerson(value: any, resolver?: Resolver): Promise<IUser> { export async function createPerson(uri: string, resolver?: Resolver): Promise<IUser> {
if (typeof uri !== 'string') throw 'uri is not string';
if (resolver == null) resolver = new Resolver(); if (resolver == null) resolver = new Resolver();
const object = await resolver.resolve(value) as any; const object = await resolver.resolve(uri) as any;
const err = validatePerson(object); const err = validatePerson(object, uri);
if (err) { if (err) {
throw err; throw err;
@ -86,7 +113,7 @@ export async function createPerson(value: any, resolver?: Resolver): Promise<IUs
log(`Creating the Person: ${person.id}`); log(`Creating the Person: ${person.id}`);
const [followersCount = 0, followingCount = 0, notesCount = 0, finger] = await Promise.all([ const [followersCount = 0, followingCount = 0, notesCount = 0] = await Promise.all([
resolver.resolve(person.followers).then( resolver.resolve(person.followers).then(
resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined,
() => undefined () => undefined
@ -98,11 +125,10 @@ export async function createPerson(value: any, resolver?: Resolver): Promise<IUs
resolver.resolve(person.outbox).then( resolver.resolve(person.outbox).then(
resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined, resolved => isCollectionOrOrderedCollection(resolved) ? resolved.totalItems : undefined,
() => undefined () => undefined
), )
webFinger(person.id)
]); ]);
const host = toUnicode(finger.subject.replace(/^.*?@/, '')).toLowerCase(); const host = toUnicode(new URL(object.id).hostname.toLowerCase());
const isBot = object.type == 'Service'; const isBot = object.type == 'Service';
@ -192,8 +218,8 @@ export async function createPerson(value: any, resolver?: Resolver): Promise<IUs
* *
* Misskeyに対象のPersonが登録されていなければ無視します * Misskeyに対象のPersonが登録されていなければ無視します
*/ */
export async function updatePerson(value: string | IObject, resolver?: Resolver): Promise<void> { export async function updatePerson(uri: string, resolver?: Resolver): Promise<void> {
const uri = typeof value == 'string' ? value : value.id; if (typeof uri !== 'string') throw 'uri is not string';
// URIがこのサーバーを指しているならスキップ // URIがこのサーバーを指しているならスキップ
if (uri.startsWith(config.url + '/')) { if (uri.startsWith(config.url + '/')) {
@ -210,9 +236,9 @@ export async function updatePerson(value: string | IObject, resolver?: Resolver)
if (resolver == null) resolver = new Resolver(); if (resolver == null) resolver = new Resolver();
const object = await resolver.resolve(value) as any; const object = await resolver.resolve(uri) as any;
const err = validatePerson(object); const err = validatePerson(object, uri);
if (err) { if (err) {
throw err; throw err;
@ -275,8 +301,8 @@ export async function updatePerson(value: string | IObject, resolver?: Resolver)
* Misskeyに対象のPersonが登録されていればそれを返し * Misskeyに対象のPersonが登録されていればそれを返し
* Misskeyに登録しそれを返します * Misskeyに登録しそれを返します
*/ */
export async function resolvePerson(value: string | IObject, verifier?: string): Promise<IUser> { export async function resolvePerson(uri: string, verifier?: string): Promise<IUser> {
const uri = typeof value == 'string' ? value : value.id; if (typeof uri !== 'string') throw 'uri is not string';
//#region このサーバーに既に登録されていたらそれを返す //#region このサーバーに既に登録されていたらそれを返す
const exist = await fetchPerson(uri); const exist = await fetchPerson(uri);
@ -287,5 +313,5 @@ export async function resolvePerson(value: string | IObject, verifier?: string):
//#endregion //#endregion
// リモートサーバーからフェッチしてきて登録 // リモートサーバーからフェッチしてきて登録
return await createPerson(value); return await createPerson(uri);
} }

View File

@ -2,6 +2,7 @@ import { request } from 'https';
const { sign } = require('http-signature'); const { sign } = require('http-signature');
import { URL } from 'url'; import { URL } from 'url';
import * as debug from 'debug'; import * as debug from 'debug';
const crypto = require('crypto');
import config from '../../config'; import config from '../../config';
import { ILocalUser } from '../../models/user'; import { ILocalUser } from '../../models/user';
@ -13,6 +14,12 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
const { protocol, hostname, port, pathname, search } = new URL(url); const { protocol, hostname, port, pathname, search } = new URL(url);
const data = JSON.stringify(object);
const sha256 = crypto.createHash('sha256');
sha256.update(data);
const hash = sha256.digest('base64');
const req = request({ const req = request({
protocol, protocol,
hostname, hostname,
@ -20,7 +27,8 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
method: 'POST', method: 'POST',
path: pathname + search, path: pathname + search,
headers: { headers: {
'Content-Type': 'application/activity+json' 'Content-Type': 'application/activity+json',
'Digest': `SHA-256=${hash}`
} }
}, res => { }, res => {
log(`${url} --> ${res.statusCode}`); log(`${url} --> ${res.statusCode}`);
@ -35,7 +43,8 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
sign(req, { sign(req, {
authorizationHeaderName: 'Signature', authorizationHeaderName: 'Signature',
key: user.keypair, key: user.keypair,
keyId: `${config.url}/users/${user._id}/publickey` keyId: `${config.url}/users/${user._id}/publickey`,
headers: ['date', 'host', 'digest']
}); });
// Signature: Signature ... => Signature: ... // Signature: Signature ... => Signature: ...
@ -43,5 +52,5 @@ export default (user: ILocalUser, url: string, object: any) => new Promise((reso
sig = sig.replace(/^Signature /, ''); sig = sig.replace(/^Signature /, '');
req.setHeader('Signature', sig); req.setHeader('Signature', sig);
req.end(JSON.stringify(object)); req.end(data);
}); });

View File

@ -3,7 +3,7 @@ import RegistrationTicket from '../../../../models/registration-tickets';
export const meta = { export const meta = {
desc: { desc: {
ja: '招待コードを発行します。' 'ja-JP': '招待コードを発行します。'
}, },
requireCredential: true, requireCredential: true,

View File

@ -5,8 +5,8 @@ import User from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーを凍結します。', 'ja-JP': '指定したユーザーを凍結します。',
en: 'Suspend a user.' 'en-US': 'Suspend a user.'
}, },
requireCredential: true, requireCredential: true,
@ -15,8 +15,8 @@ export const meta = {
params: { params: {
userId: $.type(ID).note({ userId: $.type(ID).note({
desc: { desc: {
ja: '対象のユーザーID', 'ja-JP': '対象のユーザーID',
en: 'The user ID which you want to suspend' 'en-US': 'The user ID which you want to suspend'
} }
}), }),
} }

View File

@ -5,8 +5,8 @@ import User from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーの凍結を解除します。', 'ja-JP': '指定したユーザーの凍結を解除します。',
en: 'Unsuspend a user.' 'en-US': 'Unsuspend a user.'
}, },
requireCredential: true, requireCredential: true,
@ -15,8 +15,8 @@ export const meta = {
params: { params: {
userId: $.type(ID).note({ userId: $.type(ID).note({
desc: { desc: {
ja: '対象のユーザーID', 'ja-JP': '対象のユーザーID',
en: 'The user ID which you want to unsuspend' 'en-US': 'The user ID which you want to unsuspend'
} }
}), }),
} }

View File

@ -5,8 +5,8 @@ import User from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーの公式アカウントを解除します。', 'ja-JP': '指定したユーザーの公式アカウントを解除します。',
en: 'Mark a user as unverified.' 'en-US': 'Mark a user as unverified.'
}, },
requireCredential: true, requireCredential: true,
@ -15,8 +15,8 @@ export const meta = {
params: { params: {
userId: $.type(ID).note({ userId: $.type(ID).note({
desc: { desc: {
ja: '対象のユーザーID', 'ja-JP': '対象のユーザーID',
en: 'The user ID which you want to unverify' 'en-US': 'The user ID which you want to unverify'
} }
}), }),
} }

View File

@ -4,7 +4,7 @@ import getParams from '../../get-params';
export const meta = { export const meta = {
desc: { desc: {
ja: 'インスタンスの設定を更新します。' 'ja-JP': 'インスタンスの設定を更新します。'
}, },
requireCredential: true, requireCredential: true,
@ -13,7 +13,7 @@ export const meta = {
params: { params: {
disableRegistration: $.bool.optional.nullable.note({ disableRegistration: $.bool.optional.nullable.note({
desc: { desc: {
ja: '招待制か否か' 'ja-JP': '招待制か否か'
} }
}), }),
} }

View File

@ -5,8 +5,8 @@ import User from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーを公式アカウントにします。', 'ja-JP': '指定したユーザーを公式アカウントにします。',
en: 'Mark a user as verified.' 'en-US': 'Mark a user as verified.'
}, },
requireCredential: true, requireCredential: true,
@ -15,8 +15,8 @@ export const meta = {
params: { params: {
userId: $.type(ID).note({ userId: $.type(ID).note({
desc: { desc: {
ja: '対象のユーザーID', 'ja-JP': '対象のユーザーID',
en: 'The user ID which you want to verify' 'en-US': 'The user ID which you want to verify'
} }
}), }),
} }

View File

@ -1,4 +1,6 @@
import $ from 'cafy';
import Stats, { IStats } from '../../../models/stats'; import Stats, { IStats } from '../../../models/stats';
import getParams from '../get-params';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
@ -44,11 +46,26 @@ function migrateStats(stats: IStats[]) {
} }
export const meta = { export const meta = {
desc: {
'ja-JP': 'インスタンスの統計を取得します。'
},
params: {
limit: $.num.optional.range(1, 100).note({
default: 30,
desc: {
'ja-JP': '最大数'
}
}),
}
}; };
export default (params: any) => new Promise(async (res, rej) => { export default (params: any) => new Promise(async (res, rej) => {
const daysRange = 30; const [ps, psErr] = getParams(meta, params);
const hoursRange = 30; if (psErr) throw psErr;
const daysRange = ps.limit;
const hoursRange = ps.limit;
const now = new Date(); const now = new Date();
const y = now.getFullYear(); const y = now.getFullYear();

View File

@ -4,8 +4,8 @@ import config from '../../../config';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブの情報を取得します。', 'ja-JP': 'ドライブの情報を取得します。',
en: 'Get drive information.' 'en-US': 'Get drive information.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブのファイル一覧を取得します。', 'ja-JP': 'ドライブのファイル一覧を取得します。',
en: 'Get files of drive.' 'en-US': 'Get files of drive.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -8,8 +8,8 @@ import getParams from '../../../get-params';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブにファイルをアップロードします。', 'ja-JP': 'ドライブにファイルをアップロードします。',
en: 'Upload a file to drive.' 'en-US': 'Upload a file to drive.'
}, },
requireCredential: true, requireCredential: true,
@ -27,15 +27,15 @@ export const meta = {
folderId: $.type(ID).optional.nullable.note({ folderId: $.type(ID).optional.nullable.note({
default: null, default: null,
desc: { desc: {
ja: 'フォルダID' 'ja-JP': 'フォルダID'
} }
}), }),
isSensitive: $.bool.optional.note({ isSensitive: $.bool.optional.note({
default: false, default: false,
desc: { desc: {
ja: 'このメディアが「閲覧注意」(NSFW)かどうか', 'ja-JP': 'このメディアが「閲覧注意」(NSFW)かどうか',
en: 'Whether this media is NSFW' 'en-US': 'Whether this media is NSFW'
} }
}) })
} }

View File

@ -6,8 +6,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブのファイルを削除します。', 'ja-JP': 'ドライブのファイルを削除します。',
en: 'Delete a file of drive.' 'en-US': 'Delete a file of drive.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したドライブのファイルの情報を取得します。', 'ja-JP': '指定したドライブのファイルの情報を取得します。',
en: 'Get specified file of drive.' 'en-US': 'Get specified file of drive.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -7,8 +7,8 @@ import getParams from '../../../get-params';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したドライブのファイルの情報を更新します。', 'ja-JP': '指定したドライブのファイルの情報を更新します。',
en: 'Update specified file of drive.' 'en-US': 'Update specified file of drive.'
}, },
requireCredential: true, requireCredential: true,
@ -18,30 +18,30 @@ export const meta = {
params: { params: {
fileId: $.type(ID).note({ fileId: $.type(ID).note({
desc: { desc: {
ja: '対象のファイルID' 'ja-JP': '対象のファイルID'
} }
}), }),
folderId: $.type(ID).optional.nullable.note({ folderId: $.type(ID).optional.nullable.note({
default: undefined, default: undefined,
desc: { desc: {
ja: 'フォルダID' 'ja-JP': 'フォルダID'
} }
}), }),
name: $.str.optional.pipe(validateFileName).note({ name: $.str.optional.pipe(validateFileName).note({
default: undefined, default: undefined,
desc: { desc: {
ja: 'ファイル名', 'ja-JP': 'ファイル名',
en: 'Name of the file' 'en-US': 'Name of the file'
} }
}), }),
isSensitive: $.bool.optional.note({ isSensitive: $.bool.optional.note({
default: undefined, default: undefined,
desc: { desc: {
ja: 'このメディアが「閲覧注意」(NSFW)かどうか', 'ja-JP': 'このメディアが「閲覧注意」(NSFW)かどうか',
en: 'Whether this media is NSFW' 'en-US': 'Whether this media is NSFW'
} }
}) })
} }

View File

@ -6,7 +6,7 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブに指定されたURLに存在するファイルをアップロードします。' 'ja-JP': 'ドライブに指定されたURLに存在するファイルをアップロードします。'
}, },
limit: { limit: {

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブのフォルダ一覧を取得します。', 'ja-JP': 'ドライブのフォルダ一覧を取得します。',
en: 'Get folders of drive.' 'en-US': 'Get folders of drive.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ドライブのフォルダを作成します。', 'ja-JP': 'ドライブのフォルダを作成します。',
en: 'Create a folder of drive.' 'en-US': 'Create a folder of drive.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,7 +4,7 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したドライブのフォルダの情報を取得します。' 'ja-JP': '指定したドライブのフォルダの情報を取得します。'
}, },
requireCredential: true, requireCredential: true,

View File

@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したドライブのフォルダの情報を更新します。', 'ja-JP': '指定したドライブのフォルダの情報を更新します。',
en: 'Update specified folder of drive.' 'en-US': 'Update specified folder of drive.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -6,8 +6,8 @@ import create from '../../../../services/following/create';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーをフォローします。', 'ja-JP': '指定したユーザーをフォローします。',
en: 'Follow a user.' 'en-US': 'Follow a user.'
}, },
limit: { limit: {

View File

@ -6,8 +6,8 @@ import deleteFollowing from '../../../../services/following/delete';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーのフォローを解除します。', 'ja-JP': '指定したユーザーのフォローを解除します。',
en: 'Unfollow a user.' 'en-US': 'Unfollow a user.'
}, },
limit: { limit: {

View File

@ -4,8 +4,8 @@ import User, { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分に届いた、指定したフォローリクエストを承認します。', 'ja-JP': '自分に届いた、指定したフォローリクエストを承認します。',
en: 'Accept a follow request.' 'en-US': 'Accept a follow request.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import User, { pack, ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分が作成した、指定したフォローリクエストをキャンセルします。', 'ja-JP': '自分が作成した、指定したフォローリクエストをキャンセルします。',
en: 'Cancel a follow request.' 'en-US': 'Cancel a follow request.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分に届いたフォローリクエストの一覧を取得します。', 'ja-JP': '自分に届いたフォローリクエストの一覧を取得します。',
en: 'Get all pending received follow requests.' 'en-US': 'Get all pending received follow requests.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import User, { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分に届いた、指定したフォローリクエストを拒否します。', 'ja-JP': '自分に届いた、指定したフォローリクエストを拒否します。',
en: 'Reject a follow request.' 'en-US': 'Reject a follow request.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーをストーキングします。', 'ja-JP': '指定したユーザーをストーキングします。',
en: 'Stalk a user.' 'en-US': 'Stalk a user.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーのストーキングをやめます。', 'ja-JP': '指定したユーザーのストーキングをやめます。',
en: 'Unstalk a user.' 'en-US': 'Unstalk a user.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -6,7 +6,7 @@ import { publishReversiGameStream } from '../../../../../../stream';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したリバーシの対局で投了します。' 'ja-JP': '指定したリバーシの対局で投了します。'
}, },
requireCredential: true, requireCredential: true,
@ -14,7 +14,7 @@ export const meta = {
params: { params: {
gameId: $.type(ID).note({ gameId: $.type(ID).note({
desc: { desc: {
ja: '投了したい対局' 'ja-JP': '投了したい対局'
} }
}) })
} }

View File

@ -5,7 +5,7 @@ const escapeRegexp = require('escape-regexp');
export const meta = { export const meta = {
desc: { desc: {
ja: 'ハッシュタグを検索します。' 'ja-JP': 'ハッシュタグを検索します。'
}, },
requireCredential: false, requireCredential: false,
@ -14,20 +14,20 @@ export const meta = {
limit: $.num.optional.range(1, 100).note({ limit: $.num.optional.range(1, 100).note({
default: 10, default: 10,
desc: { desc: {
ja: '最大数' 'ja-JP': '最大数'
} }
}), }),
query: $.str.note({ query: $.str.note({
desc: { desc: {
ja: 'クエリ' 'ja-JP': 'クエリ'
} }
}), }),
offset: $.num.optional.min(0).note({ offset: $.num.optional.min(0).note({
default: 0, default: 0,
desc: { desc: {
ja: 'オフセット' 'ja-JP': 'オフセット'
} }
}) })
} }

View File

@ -3,7 +3,7 @@ import { IApp } from '../../../models/app';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分のアカウント情報を取得します。' 'ja-JP': '自分のアカウント情報を取得します。'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'お気に入りに登録した投稿一覧を取得します。', 'ja-JP': 'お気に入りに登録した投稿一覧を取得します。',
en: 'Get favorited notes' 'en-US': 'Get favorited notes'
}, },
requireCredential: true, requireCredential: true,

View File

@ -8,8 +8,8 @@ import config from '../../../../config';
export const meta = { export const meta = {
desc: { desc: {
ja: 'アカウント情報を更新します。', 'ja-JP': 'アカウント情報を更新します。',
en: 'Update myself' 'en-US': 'Update myself'
}, },
requireCredential: true, requireCredential: true,

View File

@ -6,8 +6,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: 'Messagingの履歴を取得します。', 'ja-JP': 'Messagingの履歴を取得します。',
en: 'Show messaging history.' 'en-US': 'Show messaging history.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -6,8 +6,8 @@ import read from '../../common/read-messaging-message';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーとのMessagingのメッセージ一覧を取得します。', 'ja-JP': '指定したユーザーとのMessagingのメッセージ一覧を取得します。',
en: 'Get messages of messaging.' 'en-US': 'Get messages of messaging.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -12,8 +12,8 @@ import pushSw from '../../../../../push-sw';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定したユーザーへMessagingのメッセージを送信します。', 'ja-JP': '指定したユーザーへMessagingのメッセージを送信します。',
en: 'Create a message of messaging.' 'en-US': 'Create a message of messaging.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -6,8 +6,8 @@ import getParams from '../../../get-params';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定した自分宛てのメッセージを既読にします。', 'ja-JP': '指定した自分宛てのメッセージを既読にします。',
en: 'Mark as read a message of messaging.' 'en-US': 'Mark as read a message of messaging.'
}, },
requireCredential: true, requireCredential: true,
@ -17,8 +17,8 @@ export const meta = {
params: { params: {
messageId: $.type(ID).note({ messageId: $.type(ID).note({
desc: { desc: {
ja: '既読にするメッセージのID', 'ja-JP': '既読にするメッセージのID',
en: 'The ID of a message that you want to mark as read' 'en-US': 'The ID of a message that you want to mark as read'
} }
}) })
} }

View File

@ -4,8 +4,8 @@ import Mute from '../../../../models/mute';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ユーザーをミュートします。', 'ja-JP': 'ユーザーをミュートします。',
en: 'Mute a user' 'en-US': 'Mute a user'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import Mute from '../../../../models/mute';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ユーザーのミュートを解除します。', 'ja-JP': 'ユーザーのミュートを解除します。',
en: 'Unmute a user' 'en-US': 'Unmute a user'
}, },
requireCredential: true, requireCredential: true,

View File

@ -5,8 +5,8 @@ import { getFriendIds } from '../../common/get-friends';
export const meta = { export const meta = {
desc: { desc: {
ja: 'ミュートしているユーザー一覧を取得します。', 'ja-JP': 'ミュートしているユーザー一覧を取得します。',
en: 'Get muted users.' 'en-US': 'Get muted users.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -4,8 +4,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分のアプリケーション一覧を取得します。', 'ja-JP': '自分のアプリケーション一覧を取得します。',
en: 'Get my apps' 'en-US': 'Get my apps'
}, },
requireCredential: true requireCredential: true

View File

@ -9,7 +9,7 @@ import getParams from '../../get-params';
export const meta = { export const meta = {
desc: { desc: {
ja: '投稿します。' 'ja-JP': '投稿します。'
}, },
requireCredential: true, requireCredential: true,
@ -25,33 +25,33 @@ export const meta = {
visibility: $.str.optional.or(['public', 'home', 'followers', 'specified', 'private']).note({ visibility: $.str.optional.or(['public', 'home', 'followers', 'specified', 'private']).note({
default: 'public', default: 'public',
desc: { desc: {
ja: '投稿の公開範囲' 'ja-JP': '投稿の公開範囲'
} }
}), }),
visibleUserIds: $.arr($.type(ID)).optional.unique().min(1).note({ visibleUserIds: $.arr($.type(ID)).optional.unique().min(1).note({
desc: { desc: {
ja: '(投稿の公開範囲が specified の場合)投稿を閲覧できるユーザー' 'ja-JP': '(投稿の公開範囲が specified の場合)投稿を閲覧できるユーザー'
} }
}), }),
text: $.str.optional.nullable.pipe(isValidText).note({ text: $.str.optional.nullable.pipe(isValidText).note({
default: null, default: null,
desc: { desc: {
ja: '投稿内容' 'ja-JP': '投稿内容'
} }
}), }),
cw: $.str.optional.nullable.pipe(isValidCw).note({ cw: $.str.optional.nullable.pipe(isValidCw).note({
desc: { desc: {
ja: 'コンテンツの警告。このパラメータを指定すると設定したテキストで投稿のコンテンツを隠す事が出来ます。' 'ja-JP': 'コンテンツの警告。このパラメータを指定すると設定したテキストで投稿のコンテンツを隠す事が出来ます。'
} }
}), }),
viaMobile: $.bool.optional.note({ viaMobile: $.bool.optional.note({
default: false, default: false,
desc: { desc: {
ja: 'モバイルデバイスからの投稿か否か。' 'ja-JP': 'モバイルデバイスからの投稿か否か。'
} }
}), }),
@ -66,20 +66,20 @@ export const meta = {
speed: $.num.nullable speed: $.num.nullable
}).optional.nullable.strict().note({ }).optional.nullable.strict().note({
desc: { desc: {
ja: '位置情報' 'ja-JP': '位置情報'
}, },
ref: 'geo' ref: 'geo'
}), }),
mediaIds: $.arr($.type(ID)).optional.unique().range(1, 4).note({ mediaIds: $.arr($.type(ID)).optional.unique().range(1, 4).note({
desc: { desc: {
ja: '添付するメディア' 'ja-JP': '添付するメディア'
} }
}), }),
renoteId: $.type(ID).optional.note({ renoteId: $.type(ID).optional.note({
desc: { desc: {
ja: 'Renote対象' 'ja-JP': 'Renote対象'
} }
}), }),
@ -90,7 +90,7 @@ export const meta = {
.each(c => c.length > 0 && c.length < 50) .each(c => c.length > 0 && c.length < 50)
}).optional.strict().note({ }).optional.strict().note({
desc: { desc: {
ja: 'アンケート' 'ja-JP': 'アンケート'
}, },
ref: 'poll' ref: 'poll'
}) })
@ -102,7 +102,7 @@ export const meta = {
createdNote: { createdNote: {
type: 'entity(Note)', type: 'entity(Note)',
desc: { desc: {
ja: '作成した投稿' 'ja-JP': '作成した投稿'
} }
} }
} }

View File

@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定した投稿を削除します。', 'ja-JP': '指定した投稿を削除します。',
en: 'Delete a note.' 'en-US': 'Delete a note.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定した投稿をお気に入りに登録します。', 'ja-JP': '指定した投稿をお気に入りに登録します。',
en: 'Favorite a note.' 'en-US': 'Favorite a note.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -5,8 +5,8 @@ import { ILocalUser } from '../../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '指定した投稿のお気に入りを解除します。', 'ja-JP': '指定した投稿のお気に入りを解除します。',
en: 'Unfavorite a note.' 'en-US': 'Unfavorite a note.'
}, },
requireCredential: true, requireCredential: true,

View File

@ -10,65 +10,65 @@ export const meta = {
name: 'notes/hybrid-timeline', name: 'notes/hybrid-timeline',
desc: { desc: {
ja: 'ハイブリッドタイムラインを取得します。' 'ja-JP': 'ハイブリッドタイムラインを取得します。'
}, },
params: { params: {
limit: $.num.optional.range(1, 100).note({ limit: $.num.optional.range(1, 100).note({
default: 10, default: 10,
desc: { desc: {
ja: '最大数' 'ja-JP': '最大数'
} }
}), }),
sinceId: $.type(ID).optional.note({ sinceId: $.type(ID).optional.note({
desc: { desc: {
ja: '指定すると、この投稿を基点としてより新しい投稿を取得します' 'ja-JP': '指定すると、この投稿を基点としてより新しい投稿を取得します'
} }
}), }),
untilId: $.type(ID).optional.note({ untilId: $.type(ID).optional.note({
desc: { desc: {
ja: '指定すると、この投稿を基点としてより古い投稿を取得します' 'ja-JP': '指定すると、この投稿を基点としてより古い投稿を取得します'
} }
}), }),
sinceDate: $.num.optional.note({ sinceDate: $.num.optional.note({
desc: { desc: {
ja: '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' 'ja-JP': '指定した時間を基点としてより新しい投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。'
} }
}), }),
untilDate: $.num.optional.note({ untilDate: $.num.optional.note({
desc: { desc: {
ja: '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。' 'ja-JP': '指定した時間を基点としてより古い投稿を取得します。数値は、1970年1月1日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。'
} }
}), }),
includeMyRenotes: $.bool.optional.note({ includeMyRenotes: $.bool.optional.note({
default: true, default: true,
desc: { desc: {
ja: '自分の行ったRenoteを含めるかどうか' 'ja-JP': '自分の行ったRenoteを含めるかどうか'
} }
}), }),
includeRenotedMyNotes: $.bool.optional.note({ includeRenotedMyNotes: $.bool.optional.note({
default: true, default: true,
desc: { desc: {
ja: 'Renoteされた自分の投稿を含めるかどうか' 'ja-JP': 'Renoteされた自分の投稿を含めるかどうか'
} }
}), }),
includeLocalRenotes: $.bool.optional.note({ includeLocalRenotes: $.bool.optional.note({
default: true, default: true,
desc: { desc: {
ja: 'Renoteされたローカルの投稿を含めるかどうか' 'ja-JP': 'Renoteされたローカルの投稿を含めるかどうか'
} }
}), }),
mediaOnly: $.bool.optional.note({ mediaOnly: $.bool.optional.note({
desc: { desc: {
ja: 'true にすると、メディアが添付された投稿だけ取得します' 'ja-JP': 'true にすると、メディアが添付された投稿だけ取得します'
} }
}), }),
} }

View File

@ -6,8 +6,8 @@ import { ILocalUser } from '../../../../models/user';
export const meta = { export const meta = {
desc: { desc: {
ja: '自分に言及している投稿の一覧を取得します。', 'ja-JP': '自分に言及している投稿の一覧を取得します。',
en: 'Get mentions of myself.' 'en-US': 'Get mentions of myself.'
}, },
requireCredential: true requireCredential: true

Some files were not shown because too many files have changed in this diff Show More