Compare commits
152 Commits
Author | SHA1 | Date | |
---|---|---|---|
e615a3fdf3 | |||
f670345d45 | |||
3220d69a69 | |||
c87a43bdba | |||
fa6a7186e0 | |||
34a5adf951 | |||
4b3ece439e | |||
10dc97c43f | |||
2c59da36c2 | |||
f457fb6067 | |||
6843019481 | |||
17cc5a9b95 | |||
b51843ed50 | |||
ecf44a4fc7 | |||
8be0188140 | |||
1008e38abc | |||
b862e53a56 | |||
94042c2ea9 | |||
1d76bb42bb | |||
d71a3b59b4 | |||
1e0c486f2a | |||
98ec9e2254 | |||
f18c6c26a5 | |||
b6f69b6477 | |||
901709057e | |||
30c4718b0d | |||
24fe68d75f | |||
d0de0bc815 | |||
9643b1c44a | |||
c1d02a4e1b | |||
be842b5071 | |||
c2eb80b44c | |||
9ed2a82d3b | |||
b28eb54cac | |||
683d3a70b2 | |||
84fb010789 | |||
278c586414 | |||
e9165bc6e0 | |||
e3d190072f | |||
e7004ef9f1 | |||
8336601ded | |||
1dfb82b85b | |||
0ffc30dcbf | |||
3aa74de53c | |||
f78f5c7b02 | |||
0345fe6b30 | |||
a51ba0d57c | |||
6a7719ccf3 | |||
4c18d9edc6 | |||
c6d0fe3c6e | |||
03e1d3fbc4 | |||
700f8c9bb4 | |||
5a0fd674bb | |||
44099c551c | |||
111f44ce09 | |||
c3c885de47 | |||
6d536c61e8 | |||
8a8c079b2f | |||
b4a30e2a25 | |||
f19f92c538 | |||
e1a946ab45 | |||
aa1817737e | |||
25ec5a24ab | |||
68784b3f8e | |||
2118fadc48 | |||
f14cde4db9 | |||
75ce3f2eb8 | |||
ca2230f690 | |||
aa1dbe2710 | |||
deddeb570e | |||
0ed197d4d9 | |||
046976dffc | |||
bb8139196e | |||
1fea2cdcbe | |||
fe3dd25bc3 | |||
5b09209ef9 | |||
62db650e3c | |||
b847886254 | |||
c6e69ffae4 | |||
b24f368d3f | |||
4dc8351f56 | |||
f3ab8199a5 | |||
28d953933a | |||
77d9ae92f6 | |||
7d00754587 | |||
982b5eb698 | |||
20a9c25d70 | |||
eebed9944c | |||
507a192489 | |||
689dc3b9d5 | |||
d765803b83 | |||
0fabb6a057 | |||
23efaae85e | |||
5b2f15726f | |||
bc3a5f3512 | |||
ba05f236bd | |||
6ac92ac4b8 | |||
d9a1cd082c | |||
a32071541a | |||
eb4f625bbd | |||
e36d45507a | |||
e32884f07f | |||
1344ffa67d | |||
e07210524f | |||
6f3996c061 | |||
fd06fd4dc1 | |||
d86d5feae3 | |||
0e20a8f07b | |||
a40d784e3a | |||
e145131b95 | |||
92873b8bb5 | |||
d359b71c81 | |||
f1a0bf4257 | |||
ea4e2da58d | |||
1301b3b49e | |||
424625846e | |||
b238d7b934 | |||
011e4fded2 | |||
2fe872a9c9 | |||
02c1515a0f | |||
5e9d2d079d | |||
fdc16253d1 | |||
7e83cd2d74 | |||
083eb75eff | |||
f50afa768f | |||
1a80fe91ce | |||
4de1a5ef6c | |||
d0d389299b | |||
dc70804350 | |||
78d691571b | |||
b7cbf4a42a | |||
87ca7c50b4 | |||
6c7550b3f3 | |||
4239ffa13f | |||
c6cfb0df76 | |||
dc174ca759 | |||
b61cfd0407 | |||
53405e54a8 | |||
c7ef7531a9 | |||
626b4bf314 | |||
323d0e0154 | |||
6d1338317b | |||
1ce26d8aec | |||
7ba3d3ec98 | |||
24f58b3ecb | |||
d1d8587096 | |||
96db630f5e | |||
91fae0ae8b | |||
bfa1235b48 | |||
95d324a413 | |||
ef3535319b | |||
e9c04f4fa0 |
51
README.md
51
README.md
@ -1,4 +1,4 @@
|
||||
<img src="https://github.com/syuilo/misskey/blob/b3f42e62af698a67c2250533c437569559f1fdf9/src/himasaku/resources/himasaku.png?raw=true" align="right" width="320px"/>
|
||||
<img src="https://github.com/syuilo/misskey/blob/develop/assets/ai-orig.png?raw=true" align="right" height="320px"/>
|
||||
|
||||
[](https://misskey.xyz/)
|
||||
================================================================
|
||||
@ -7,12 +7,12 @@
|
||||
[![][dependencies-badge]][dependencies-link]
|
||||
[](http://makeapullrequest.com) [](https://greenkeeper.io/)
|
||||
|
||||
Sophisticated microblogging platform, evolving forever.
|
||||
**Sophisticated microblogging platform, evolving forever.**
|
||||
|
||||
[Misskey](https://misskey.xyz) is a decentralized microblogging platform born on Earth.
|
||||
Since it exists within the Fediverse (a universe where various social media platforms are organized),
|
||||
it is mutually linked with other social media platforms.
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet?
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? [Find instance!](https://joinmisskey.github.io/)
|
||||
|
||||
<a href="https://www.patreon.com/syuilo"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="Become a Patron!" width="160" /></a>
|
||||
|
||||
@ -20,15 +20,44 @@ Why don't you take a short break from the hustle and bustle of the city, and div
|
||||
|
||||
:sparkles: Features
|
||||
----------------------------------------------------------------
|
||||
* Rich text contents
|
||||
* Reactions
|
||||
* User lists
|
||||
* Customizable column view (called MisskeyDeck)
|
||||
* Customizable widgets
|
||||
* Private messages
|
||||
* ActivityPub support
|
||||
|
||||
and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz).
|
||||
<img src="/assets/about/post.png" align="left" height="200px"/>
|
||||
|
||||
<h3 align="left">Posting</h3>
|
||||
<p align="left">
|
||||
Just post your idea, hot topics and anything you want to share. You may want to decorate your words, attach your favorite pictures, send files including movies and create a poll - those are the things you can do on Misskey!
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<img src="/assets/about/reaction.png" align="right" height="200px"/>
|
||||
|
||||
<h3 align="right">Reactions</h3>
|
||||
<p align="right">
|
||||
Easiest way to tell your emotions. Misskey allows you to add various type of reactions to other’s post. The emotional experience on Misskey will never be on other SNSs which only able to push “likes”.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<img src="/assets/about/ui.png" align="left" height="200px"/>
|
||||
|
||||
<h3 align="left">Interface</h3>
|
||||
<p align="left">
|
||||
No UI fits for everyone. Therefore, Misskey has a highly customizable UI for your taste. You can edit layouts of your timeline, place selectable widgets you can easily move and create your unique home as this place will be your home.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<img src="/assets/about/drive.png" align="right" width="300px"/>
|
||||
|
||||
<h3 align="right">Misskey Drive</h3>
|
||||
<p align="right">
|
||||
Wanna post a picture you have already uploaded? Wish to organize, name and create a folder for your uploaded files? Misskey Drive is the best solution for you. Very easy to share your files online.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz) or [other instances](https://joinmisskey.github.io/).
|
||||
|
||||
:package: Create your own instance
|
||||
----------------------------------------------------------------
|
||||
|
@ -10,7 +10,7 @@ Misskeyサーバーの構築にご関心をお寄せいただきありがとう
|
||||
|
||||
*1.* Misskeyユーザーの作成
|
||||
----------------------------------------------------------------
|
||||
Misskeyのrootで実行しない方がよいため、代わりにユーザーを作成します。
|
||||
Misskeyはrootユーザーで実行しない方がよいため、代わりにユーザーを作成します。
|
||||
Debianの例:
|
||||
|
||||
```
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "こまこまのこまり"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Verwirrt"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "Was machst du gerade?"
|
||||
b: "Was ist so passiert?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "Die Verbindung scheint zu funktionieren. Bitte lade die Seite neu."
|
||||
flush: "Cache leeren"
|
||||
set-version: "Version angeben"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "Einen Nutzer suchen"
|
||||
you: "Du"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "Zeige Details"
|
||||
private: "Dieser Beitrag ist eine privat"
|
||||
deleted: "Dieser Beitrag wurde entfernt"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Laden fehlgeschlagen."
|
||||
retry: "Erneut versuchen"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "Verhalten"
|
||||
fetch-on-scroll: "Aktualisieren beim scrollen"
|
||||
fetch-on-scroll-desc: "Wenn du runterscrollst empfängt die Seite automatisch zusätzliche Inhalte."
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "Automatische Pop-out Fenster"
|
||||
auto-popout-desc: "Pop-out ein offenes Fenster wenn möglich. Diese Einstellung wird im Browser gespeichert."
|
||||
advanced: "Erweiterte Einstellungen"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "Profil aktualisieren"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "Profil wurde aktualisiert"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of the fediverse"
|
||||
about-title: "A ⭐ of the fediverse."
|
||||
about: "Thank you for finding Misskey. Misskey is a <b>decentralized microblogging platform</b> born on Earth. Since it exists within the Fediverse (a universe where various social media platforms are organized), it is mutually linked with other social media platforms. Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet?"
|
||||
intro:
|
||||
title: "What is Misskey?"
|
||||
about: "Misskey is a open-source <b>decentralized microblogging service</b>. Sophisticated fully customizable Ui, varieties of reaction for posts, free file storage providing integrated management system and other advancing functions are available. Also, network system called “Fediverse” enables us to communicate with users on other SNSs. Like, if you post something, then your posts will sent not only to Misskey but also mastodon. Just imagine that the planet is sending a microwave to other planet to communication."
|
||||
features: "Features"
|
||||
rich-contents: "Post"
|
||||
rich-contents-desc: "Just post your idea, hot topics and anything you want to share. You may want to decorate your words, attach your favorite pictures, send files including movies and create a poll - those are the things you can do on Misskey!"
|
||||
reaction: "Reactions"
|
||||
reaction-desc: "Easiest way to tell your emotions. Misskey allows you to add various type of reactions to other’s post. The emotional experience on Misskey will never be on other SNSs which only able to push “likes”."
|
||||
ui: "Interface"
|
||||
ui-desc: "No UI fits for everyone. Therefore, Misskey has a highly customizable UI for your taste. Make your original home by editing, adjusting layouts of timeline and placing selectable widgets you can easily customize."
|
||||
drive: "Misskey Drive"
|
||||
drive-desc: "Wanna post a picture you have already uploaded? Wish to organize, name and create a folder for your uploaded files? Misskey Drive is the best solution for you. Very easy to share your files online."
|
||||
outro: "Check further Misskey-unique features on your eyes! Feeling like this is not for you, try other instances as Misskey is a decentralized SNS so that you can easily find your mates. Then, GLHF!"
|
||||
adblock:
|
||||
detected: "Please disable ad blocker."
|
||||
warning: "Some features may be unavailable or cause malfunctions if ad blocking features are enabled. <strong>Misskey is not running ads</strong>."
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Confused"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "Public"
|
||||
home: "Home"
|
||||
home-desc: "Post to the home timeline only"
|
||||
followers: "Followers"
|
||||
followers-desc: "Post to followers only"
|
||||
specified: "Direct"
|
||||
specified-desc: "Post to specified users only"
|
||||
private: "Private"
|
||||
note-placeholders:
|
||||
a: "What are you doing?"
|
||||
b: "What's happening?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "Looks like we have a connection. Please reload the page."
|
||||
flush: "Clean cache"
|
||||
set-version: "Specify version"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "Hide"
|
||||
show: "See more"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "Find a user"
|
||||
you: "You"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "Show details"
|
||||
private: "Post is private"
|
||||
deleted: "Post has been deleted"
|
||||
hide: "Hide"
|
||||
see-more: "See more"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Loading failed."
|
||||
retry: "Retry"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "Behavior"
|
||||
fetch-on-scroll: "Endless loading on scroll"
|
||||
fetch-on-scroll-desc: "When you scroll down the page, it automatically fetches additional content."
|
||||
note-visibility: "Post visibility"
|
||||
default-note-visibility: "Default visibility"
|
||||
remember-note-visibility: "Remember post visibility"
|
||||
auto-popout: "Auto pop-out window"
|
||||
auto-popout-desc: "If it's possible, pop-out display will be used instead of opening a new window. This setting is stored in your browser."
|
||||
advanced: "Advanced settings"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "Birthday"
|
||||
save: "Update profile"
|
||||
locked-account: "Protect your account"
|
||||
is-locked: "Make your posts private"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "Other"
|
||||
is-bot: "This account is a Bot"
|
||||
is-cat: "This account is a Cat"
|
||||
@ -905,7 +931,7 @@ desktop/views/pages/user/user.friends.vue:
|
||||
no-users: "No frequent mentions"
|
||||
desktop/views/pages/user/user.vue:
|
||||
is-suspended: "This account has been suspended."
|
||||
is-remote: "The user is a remote user. The profile that you see here may not complete."
|
||||
is-remote: "This profile belongs to a remote user. The profile that you see here may not be complete. "
|
||||
view-remote: "See their complete profile"
|
||||
desktop/views/pages/user/user.home.vue:
|
||||
last-used-at: "Last active:"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "Close"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "Reposted by {}"
|
||||
more: "See more"
|
||||
less: "Hide"
|
||||
private: "This post is private"
|
||||
deleted: "This post has been deleted"
|
||||
location: "Location"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "Avatar"
|
||||
banner: "Banner"
|
||||
is-cat: "This account is a Cat"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "Advanced"
|
||||
privacy: "Privacy"
|
||||
save: "Update profile"
|
||||
saved: "Profile updated"
|
||||
uploading: "Uploading"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "Top"
|
||||
behavior: "Behavior"
|
||||
fetch-on-scroll: "Endless loading on scroll"
|
||||
note-visibility: "Post visibility"
|
||||
default-note-visibility: "Default visibility"
|
||||
remember-note-visibility: "Remember post visibility"
|
||||
disable-via-mobile: "Don't mark the post as 'from mobile'"
|
||||
load-raw-images: "Show attached images in original quality"
|
||||
load-remote-media: "Show media from a remote server"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "Una ⭐️ del fediverso"
|
||||
about-title: "Una ⭐️ del fediverso"
|
||||
about: "Gracias por encontrae Misskey. Misskey es una <b>plataforma descentralizada de microblogging</b> nacida en la Tierra. Gracias a existir dentro del Fediverso (un universo donde se organizan varias plataformas sociales) se encuentra enlazada mutuamente con otras plataformas sociales. ¿Por què no te tomas un respiro del caos de la ciudad y te sumerges es una nueva manera de entender Internet?"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "Por favor, desactive el bloqueador de publicidad."
|
||||
warning: "<strong>Misskey no tiene anuncios publicitarios.</strong> Sin embargo, algunas características podrían no estar disponibles si el bloqueador de publicidad está habilitado."
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "confundido"
|
||||
rip: "RIP"
|
||||
pudding: "Chafado"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "¿Qué haces?"
|
||||
b: "¿Qué está pasando?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "Parece que la conexión ha sido posible. Por favor refresca la página."
|
||||
flush: "Limpiar la memoria caché"
|
||||
set-version: "Escoge la versión"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "Encuentra un usuario"
|
||||
you: "Tu"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "Mostrar detalles"
|
||||
private: "Esta publicación es privada"
|
||||
deleted: "Esta publicación ha sido borrada"
|
||||
hide: "Esconder"
|
||||
see-more: "Ver más"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Error al cargar."
|
||||
retry: "Reintentar"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "Acciones"
|
||||
fetch-on-scroll: "Desplazamiento infinito"
|
||||
fetch-on-scroll-desc: "Cuando te deslizas al final de la página nuevo contenido se carga automáticamente."
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "Ventana emergente automática"
|
||||
auto-popout-desc: "Muestra una ventana emergente si es posible. Esta configuración depende del navegador."
|
||||
advanced: "Configuración avanzada"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "Fecha de nacimiento"
|
||||
save: "Perfil actualizado"
|
||||
locked-account: "Protege tu cuenta"
|
||||
is-locked: "Crear una nota privada"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "Une ⭐ du fédiverse"
|
||||
about-title: "Une ⭐ du fédivers."
|
||||
about: "Merci d'avoir découvert Misskey. Misskey est une <b>plateforme de microblogage distribuée</b> née sur Terre. Parce qu'il fait partie du Fédivers (un univers composé de diverses plateformes de réseaux sociaux organisées), il est mutuellement connecté avec d'autres plateformes de réseaux sociaux. Désirez-vous prendre une pause, pendant un instant, loin de l'agitation de la ville et plonger dans un nouvel Internet ?"
|
||||
intro:
|
||||
title: "C’est quoi Misskey ?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "Fonctionnalités"
|
||||
rich-contents: "Notes"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "Réactions"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "Interface utilisateur"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "Drive"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "Veuillez désactiver votre bloqueur de publicités"
|
||||
warning: "<strong>Misskey n'utilise pas de publicités</strong>, mais quelques options peuvent être non disponibles ou fonctionneraient mal si un bloqueur de publicités est activé."
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Confus"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "Public"
|
||||
home: "Accueil"
|
||||
home-desc: "Publier sur le fil local uniquement"
|
||||
followers: "Abonnés·es"
|
||||
followers-desc: "Publier à vos abonnés·es uniquement"
|
||||
specified: "Direct"
|
||||
specified-desc: "Publier aux utilisateurs·trices mentionnés·es"
|
||||
private: "Privé"
|
||||
note-placeholders:
|
||||
a: "Que faites-vous maintenant ?"
|
||||
b: "Quoi de neuf ?"
|
||||
@ -173,7 +195,7 @@ common/views/components/games/reversi/reversi.game.vue:
|
||||
surrendered: "Par abandon"
|
||||
is-llotheo: "石の少ない方が勝ち(ロセオ)"
|
||||
looped-map: "Carte en boucle"
|
||||
can-put-everywhere: "どこでも置けるモード"
|
||||
can-put-everywhere: "Peut poser partout"
|
||||
common/views/components/games/reversi/reversi.index.vue:
|
||||
title: "Misskey Reversi"
|
||||
sub-title: "Jouer à Reversi avec vos ami·e·s !"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "Succès de la connexion au serveur de Misskey. Veuillez recharger la page."
|
||||
flush: "Vider le cache"
|
||||
set-version: "Choisissez une version"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "Trouver un·e utilisateur·trice"
|
||||
you: "Vous"
|
||||
@ -261,8 +286,8 @@ common/views/components/nav.vue:
|
||||
develop: "Développeur·se·s"
|
||||
feedback: "Remarques"
|
||||
common/views/components/note-menu.vue:
|
||||
detail: "詳細"
|
||||
copy-link: "リンクをコピー"
|
||||
detail: "Détails"
|
||||
copy-link: "Copier le lien"
|
||||
favorite: "Mettre cette note en favoris"
|
||||
pin: "Épingler sur votre profil"
|
||||
delete: "Supprimer"
|
||||
@ -341,8 +366,8 @@ common/views/components/visibility-chooser.vue:
|
||||
specified-desc: "Publier aux utilisateur·rice·s mentionné·e·s"
|
||||
private: "Privé"
|
||||
common/views/components/trends.vue:
|
||||
count: "{}人が投稿"
|
||||
empty: "トレンドなし"
|
||||
count: "{} utilisateurs·trices mentionnés·es"
|
||||
empty: "Aucune tendance"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "Récupération"
|
||||
no-broadcasts: "Aucune annonce"
|
||||
@ -395,7 +420,7 @@ common/views/widgets/tips.vue:
|
||||
tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができます"
|
||||
tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています"
|
||||
tips-line21: "Vous pouvez aussi utiliser l'API pour développer des Bots."
|
||||
tips-line23: "まゆかわいいよまゆ"
|
||||
tips-line23: "Mayu est mignone avec ses sourcils."
|
||||
tips-line24: "Misskey a vu le jour en 2014"
|
||||
tips-line25: "対応ブラウザではMisskeyを開いていなくても通知を受け取れます"
|
||||
common/views/pages/follow.vue:
|
||||
@ -441,8 +466,8 @@ desktop/views/components/charts.vue:
|
||||
local-notes: "投稿の増減 (ローカル)"
|
||||
remote-notes: "投稿の増減 (リモート)"
|
||||
notes-total: "投稿の累計"
|
||||
users: "ユーザーの増減"
|
||||
users-total: "ユーザーの累計"
|
||||
users: "Nombre d’utilisateurs·trices : augmentation/diminution"
|
||||
users-total: "Nombre total d’utilisateurs·trices : total cumulé"
|
||||
drive: "ドライブ使用量の増減"
|
||||
drive-total: "ドライブ使用量の累計"
|
||||
drive-files: "ドライブのファイル数の増減"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "Afficher les détails"
|
||||
private: "cette publication est privée"
|
||||
deleted: "cette publication a été supprimée"
|
||||
hide: "Masquer"
|
||||
see-more: "Voir plus"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Échec du chargement."
|
||||
retry: "Réessayer"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "Comportement"
|
||||
fetch-on-scroll: "Chargement lors du défilement"
|
||||
fetch-on-scroll-desc: "Chargement automatique du contenu lors du défilement de la page."
|
||||
note-visibility: "Visibilité de la publication"
|
||||
default-note-visibility: "Visibilité par défaut"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "Fenêtre contextuelle automatique"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "Paramètres avancés"
|
||||
@ -651,9 +677,9 @@ desktop/views/components/settings.vue:
|
||||
delete-wallpaper: "Supprimer le fond d'écran"
|
||||
dark-mode: "Mode nuit"
|
||||
circle-icons: "Utiliser des icônes circulaires"
|
||||
contrasted-acct: "ユーザー名にコントラストを付ける"
|
||||
contrasted-acct: "Nom d’utilisateur contrasté"
|
||||
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: "Afficher le formulaire en haut du fil"
|
||||
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"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "Date de naissance"
|
||||
save: "Mettre à jour le profil"
|
||||
locked-account: "Protéger votre compte"
|
||||
is-locked: "Rendre la note privée"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "Autre"
|
||||
is-bot: "Ce compte est un Bot"
|
||||
is-cat: "Ce compte est un Chat"
|
||||
@ -866,10 +892,10 @@ desktop/views/pages/welcome.vue:
|
||||
signin-button: "Se connecter"
|
||||
signup-button: "S'inscrire"
|
||||
timeline: "Fil d'actualité"
|
||||
announcements: "お知らせ"
|
||||
photos: "最近の画像"
|
||||
announcements: "Notices"
|
||||
photos: "Images récentes"
|
||||
powered-by-misskey: "Propulsé par <b>Misskey</b>."
|
||||
info: "情報"
|
||||
info: "Informations"
|
||||
desktop/views/pages/drive.vue:
|
||||
title: "Lecteur de Misskey"
|
||||
desktop/views/pages/favorites.vue:
|
||||
@ -979,14 +1005,14 @@ mobile/views/components/drive-file-chooser.vue:
|
||||
mobile/views/components/drive-folder-chooser.vue:
|
||||
select-folder: "Choisissez un dossier"
|
||||
mobile/views/components/drive.file.vue:
|
||||
nsfw: "閲覧注意"
|
||||
nsfw: "CW"
|
||||
mobile/views/components/drive.file-detail.vue:
|
||||
download: "Télécharger"
|
||||
rename: "Renommer"
|
||||
move: "Déplacer"
|
||||
hash: "Hash (md5)"
|
||||
exif: "EXIF"
|
||||
nsfw: "閲覧注意"
|
||||
nsfw: "CW"
|
||||
mobile/views/components/media-image.vue:
|
||||
sensitive: "Le contenu est NSFW"
|
||||
click-to-show: "Cliquer pour afficher"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "Fermer"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "Renoté par {}"
|
||||
more: "Voir plus"
|
||||
less: "Masquer"
|
||||
private: "cette publication est privée"
|
||||
deleted: "cette publication a été supprimée"
|
||||
location: "Géolocalisation"
|
||||
@ -1053,7 +1077,7 @@ mobile/views/components/timeline.vue:
|
||||
load-more: "Afficher plus"
|
||||
mobile/views/components/ui.header.vue:
|
||||
welcome-back: "Content de vous revoir ! "
|
||||
adjective: "さん"
|
||||
adjective: "M."
|
||||
mobile/views/components/ui.nav.vue:
|
||||
timeline: "Fil d'actualité"
|
||||
notifications: "Notifications"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "Avatar"
|
||||
banner: "Bannière"
|
||||
is-cat: "Ce compte est un Bot"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "Mettre à jour le profil"
|
||||
saved: "Profil mis à jour avec succès"
|
||||
uploading: "En cours d'envoi"
|
||||
@ -1166,11 +1193,14 @@ mobile/views/pages/settings.vue:
|
||||
post-style: "Style de la publication"
|
||||
post-style-standard: "Standard"
|
||||
post-style-smart: "Intelligent"
|
||||
notification-position: "通知の表示"
|
||||
notification-position-bottom: "下"
|
||||
notification-position-top: "上"
|
||||
notification-position: "Style de notification"
|
||||
notification-position-bottom: "en bas"
|
||||
notification-position-top: "en haut"
|
||||
behavior: "Comportement"
|
||||
fetch-on-scroll: "Chargement lors du défilement"
|
||||
note-visibility: "Visibilité de la publication"
|
||||
default-note-visibility: "Visibilité par défaut"
|
||||
remember-note-visibility: "Se souvenir du mode de visibilité de la publication"
|
||||
disable-via-mobile: "Ne pas mentionner que ma publication provient d'un 'périphérique mobile'"
|
||||
load-raw-images: "Afficher les photos jointes en haute qualité"
|
||||
load-remote-media: "Afficher les médias sur le serveur distant"
|
||||
@ -1190,7 +1220,7 @@ mobile/views/pages/settings.vue:
|
||||
settings: "Réglages"
|
||||
signout: "Déconnexion"
|
||||
sound: "Sons"
|
||||
enable-sounds: "サウンドを有効にする"
|
||||
enable-sounds: "Activer les sons"
|
||||
mobile/views/pages/user.vue:
|
||||
follows-you: "vous suit"
|
||||
following: "Abonnements"
|
||||
@ -1235,7 +1265,7 @@ docs:
|
||||
res: "Réponse"
|
||||
require-credential: "Ce point de communication nécessite une authentification."
|
||||
require-permission: "Ce point de communication nécessite la permission {permission}."
|
||||
has-limit: "レートリミットがあります。"
|
||||
has-limit: "Il y’a un taux limite."
|
||||
duration-limit: "直近{duration}ミリ秒の間のこのエンドポイントへのリクエスト数の合計が{max}を超える場合はリクエストできません。"
|
||||
min-interval-limit: "前回のリクエストから{interval}ミリ秒経っていない場合はリクエストできません。"
|
||||
show-src: "Vous pouvez voir le code source ce point de communication."
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "こまこまのこまり"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -116,6 +116,10 @@ common:
|
||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||
verified-user: "公式アカウント"
|
||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||
always-show-nsfw: "常に閲覧注意のメディアを表示する"
|
||||
always-mark-nsfw: "常にメディアを閲覧注意として投稿"
|
||||
show-full-acct: "ユーザー名のホストを省略しない"
|
||||
this-setting-is-this-device-only: "このデバイスのみ"
|
||||
|
||||
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||
|
||||
@ -273,6 +277,10 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
@ -666,8 +674,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
@ -878,7 +884,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1192,8 +1198,6 @@ mobile/views/components/friends-maker.vue:
|
||||
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1353,6 +1357,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "ようMisskeyを見つけてくれて、おおきにやで。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>やねん。Fediverse(ぎょうさんのSNSで構成されとる宇宙)っちゅうもんの中におるから、お隣さんのSNSとも仲良うさせてもろてんねん。ちょいとやかましい心斎橋から離れて、新しいインターネットにダイブしてみぃひん?"
|
||||
intro:
|
||||
title: "Misskeyってなんやねん"
|
||||
about: "Misskeyってのはな、オープンソースの<b>分散型マイクロブログSNS</b>のことや。ごっついええ感じにできるUIやったり、投稿へのリアクションやったり、ファイルをまとめとけるドライブやったり、いろんな機能が目白押しや。Fediverseに対応しとるから、よそのSNSともノリツッコミできるんやで。タイガースが東京ドームに野球しに行くようなもんや。"
|
||||
features: "ええとこ"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "思っとること、タイガースの実況、他に言いたいことがあればなんでも言ってええで。いろんな構文あるから、好きにつこうてくれや。画像や動画、アンケートも添付できるで。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてや"
|
||||
warning: "<strong>Misskeyは広告を掲載してへん</strong>けど、広告をブロックしはる機能がおると一部の機能が利用できんくなったり、不具合が発生するかも分からん。知らんけど。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "こまこまのこまりやわぁ"
|
||||
rip: "RIP"
|
||||
pudding: "アメちゃんちゃうんちゃう?"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今なにしてん?"
|
||||
b: "何かあったんか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようやわ。ページを再度読み込みしてな。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あんさん"
|
||||
@ -261,7 +286,7 @@ common/views/components/nav.vue:
|
||||
develop: "開発者"
|
||||
feedback: "フィードバック"
|
||||
common/views/components/note-menu.vue:
|
||||
detail: "詳細"
|
||||
detail: "もっと"
|
||||
copy-link: "リンクをコピー"
|
||||
favorite: "お気に入り"
|
||||
pin: "ピン留め"
|
||||
@ -289,7 +314,7 @@ common/views/components/signin.vue:
|
||||
token: "トークン"
|
||||
signing-in: "サインイン中や..."
|
||||
signin: "サインイン"
|
||||
or: "または"
|
||||
or: "それか"
|
||||
signin-with-twitter: "Twitterでサインイン"
|
||||
login-failed: "なんかログインできんかったわ。ユーザー名とパスワードとかを確認してや。"
|
||||
common/views/components/signup.vue:
|
||||
@ -299,12 +324,12 @@ common/views/components/signup.vue:
|
||||
checking: "確認中や…"
|
||||
available: "使えるで"
|
||||
unavailable: "もう使われとるで"
|
||||
error: "通信エラー"
|
||||
error: "通信あかんわ"
|
||||
invalid-format: "a~z、A~Z、0~9、_が使えるで"
|
||||
too-short: "1文字以上でお願いします!"
|
||||
too-short: "1文字以上やで!"
|
||||
too-long: "20文字以内でお願いします"
|
||||
password: "パスワード"
|
||||
password-placeholder: "8文字以上を推奨します"
|
||||
password-placeholder: "8文字以上にしときや"
|
||||
weak-password: "へぼいパスワード"
|
||||
normal-password: "ぼちぼちなパスワード"
|
||||
strong-password: "良さげなパスワード"
|
||||
@ -319,18 +344,18 @@ common/views/components/special-message.vue:
|
||||
new-year: "Happy New Year!"
|
||||
christmas: "Merry Christmas!"
|
||||
common/views/components/stream-indicator.vue:
|
||||
connecting: "接続中"
|
||||
reconnecting: "再接続中"
|
||||
connected: "接続完了"
|
||||
connecting: "つないどるで"
|
||||
reconnecting: "つなぎ直すで"
|
||||
connected: "つないだわ"
|
||||
common/views/components/twitter-setting.vue:
|
||||
description: "あんさんがつことるTwitterアカウントをMisskeyアカウントに接続しとくと、あんさんのプロフィールにTwitterアカウント情報が表示されるようになったり、Twitterをつこた便利なサインインが使えるようになったりすんで。"
|
||||
connected-to: "次のTwitterアカウントに接続されとるで"
|
||||
detail: "詳細..."
|
||||
reconnect: "再接続する"
|
||||
reconnect: "つなぎ直す"
|
||||
connect: "Twitterと接続する"
|
||||
disconnect: "切断する"
|
||||
disconnect: "さいならする"
|
||||
common/views/components/uploader.vue:
|
||||
waiting: "待機中"
|
||||
waiting: "待っとる"
|
||||
common/views/components/visibility-chooser.vue:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
@ -344,7 +369,7 @@ common/views/components/trends.vue:
|
||||
count: "{}人が投稿"
|
||||
empty: "トレンドなし"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "確認中"
|
||||
fetching: "見てみるわ…"
|
||||
no-broadcasts: "お知らせはあらへんで"
|
||||
have-a-nice-day: "良い一日を!"
|
||||
next: "次"
|
||||
@ -371,12 +396,12 @@ common/views/widgets/server.vue:
|
||||
toggle: "表示を切り替え"
|
||||
common/views/widgets/memo.vue:
|
||||
title: "付箋"
|
||||
memo: "ここに書いて!"
|
||||
memo: "書くんや!"
|
||||
save: "保存"
|
||||
common/views/widgets/slideshow.vue:
|
||||
folder-customize-mode: "フォルダを指定するんやったら、一旦カスタマイズモードを終了してや"
|
||||
folder: "クリックしてフォルダを指定してください"
|
||||
no-image: "このフォルダには画像がありません"
|
||||
folder: "クリックしてフォルダ決めてや"
|
||||
no-image: "このフォルダには画像無いわ"
|
||||
common/views/widgets/tips.vue:
|
||||
tips-line1: "<kbd>t</kbd>でタイムラインにフォーカスできんで"
|
||||
tips-line2: "<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開くで"
|
||||
@ -409,13 +434,13 @@ desktop:
|
||||
banner: "バナー"
|
||||
uploading-banner: "新しいバナーをアップロードしとるで"
|
||||
banner-updated: "バナーを更新したで"
|
||||
choose-banner: "バナーにする画像を選択"
|
||||
avatar-crop-title: "アバターとして表示する部分を選択"
|
||||
choose-banner: "バナーにする画像選んでや"
|
||||
avatar-crop-title: "どこアバターとして出しとく?"
|
||||
avatar: "アバター"
|
||||
uploading-avatar: "新しいアバターをアップロードしています"
|
||||
avatar-updated: "アバターを更新しました"
|
||||
choose-avatar: "アバターにする画像を選択"
|
||||
invalid-filetype: "この形式のファイルはサポートされていません"
|
||||
invalid-filetype: "この形式のファイル無理やねん"
|
||||
desktop/views/components/activity.chart.vue:
|
||||
total: "Black ... Total"
|
||||
notes: "Blue ... Notes"
|
||||
@ -467,29 +492,29 @@ desktop/views/components/drive-window.vue:
|
||||
desktop/views/components/drive.file.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
nsfw: "閲覧注意"
|
||||
nsfw: "見たらあかんで"
|
||||
contextmenu:
|
||||
rename: "名前を変えるで"
|
||||
mark-as-sensitive: "閲覧注意に設定"
|
||||
unmark-as-sensitive: "閲覧注意を解除"
|
||||
mark-as-sensitive: "見たらあかん感じにしとく"
|
||||
unmark-as-sensitive: "やっぱ見せたるわ"
|
||||
copy-url: "URLをコピー"
|
||||
download: "ダウンロード"
|
||||
else-files: "その他..."
|
||||
set-as-avatar: "アイコンに設定"
|
||||
set-as-banner: "バナーに設定"
|
||||
else-files: "もっとあるで…"
|
||||
set-as-avatar: "アイコンにする"
|
||||
set-as-banner: "バナーにする"
|
||||
open-in-app: "アプリで開く"
|
||||
add-app: "アプリを追加"
|
||||
rename-file: "ファイル名の変更"
|
||||
add-app: "アプリ増やす"
|
||||
rename-file: "ファイル名をいらう(変える)"
|
||||
input-new-file-name: "新しいファイル名を入力してや"
|
||||
copied: "コピー完了や"
|
||||
copied-url-to-clipboard: "URLをクリップボードにコピーしました"
|
||||
copied-url-to-clipboard: "URLをクリップボードに写したわ"
|
||||
desktop/views/components/drive.folder.vue:
|
||||
unable-to-process: "操作を完了できません"
|
||||
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。"
|
||||
unable-to-process: "あかん、無理やわ"
|
||||
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーや。"
|
||||
unhandled-error: "ようわからん"
|
||||
contextmenu:
|
||||
move-to-this-folder: "このフォルダへ移動"
|
||||
show-in-new-window: "新しいウィンドウで表示"
|
||||
move-to-this-folder: "ここに持ってくるわ"
|
||||
show-in-new-window: "新しいウィンドウで出す"
|
||||
rename: "名前を変えるで"
|
||||
rename-folder: "フォルダ名を変えるで"
|
||||
input-new-folder-name: "新しいフォルダ名を入力してや"
|
||||
@ -497,24 +522,24 @@ desktop/views/components/drive.nav-folder.vue:
|
||||
drive: "ドライブ"
|
||||
desktop/views/components/drive.vue:
|
||||
search: "検索"
|
||||
load-more: "もっと読み込む"
|
||||
load-more: "もっとあらへんのか!"
|
||||
empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね"
|
||||
empty-drive: "ドライブには何もあらへんで。"
|
||||
empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。"
|
||||
empty-folder: "このフォルダーは空です"
|
||||
unable-to-process: "操作を完了できません"
|
||||
unable-to-process: "あかん、無理やわ"
|
||||
circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。"
|
||||
unhandled-error: "不明なエラー"
|
||||
unhandled-error: "ようわからん"
|
||||
url-upload: "URLアップロード"
|
||||
url-of-file: "アップロードしたいファイルのURL"
|
||||
url-upload-requested: "アップロードをリクエストしました"
|
||||
url-of-file: "このURLのファイルをアップロードしたいねん"
|
||||
url-upload-requested: "アップロードしたい言うといたで"
|
||||
may-take-time: "アップロードが完了するまで時間がかかる場合があります。"
|
||||
create-folder: "フォルダー作成"
|
||||
folder-name: "フォルダー名"
|
||||
contextmenu:
|
||||
create-folder: "フォルダーを作成"
|
||||
upload: "ファイルをアップロード"
|
||||
url-upload: "URLからアップロード"
|
||||
create-folder: "フォルダー作る"
|
||||
upload: "ファイル上げる"
|
||||
url-upload: "URLつこうて上げる"
|
||||
desktop/views/components/media-image.vue:
|
||||
sensitive: "ちょっと見せられへんわ"
|
||||
click-to-show: "クリックして見せるで"
|
||||
@ -522,30 +547,30 @@ desktop/views/components/media-video.vue:
|
||||
sensitive: "ちょっと見せられへんわ"
|
||||
click-to-show: "クリックして見せるで"
|
||||
desktop/views/components/follow-button.vue:
|
||||
following: "フォロー中"
|
||||
following: "フォローしとる"
|
||||
follow: "フォロー"
|
||||
request-pending: "フォロー許可待ち"
|
||||
follow-request: "フォロー申請"
|
||||
request-pending: "フォローの許し待っとる"
|
||||
follow-request: "フォロー許してくれや!言うてみる"
|
||||
desktop/views/components/followers-window.vue:
|
||||
followers: "{} のフォロワー"
|
||||
desktop/views/components/followers.vue:
|
||||
empty: "フォロワーはいないようです。"
|
||||
empty: "フォロワーはおらんっぽいで、知らんけど。"
|
||||
desktop/views/components/following-window.vue:
|
||||
following: "{} のフォロー"
|
||||
desktop/views/components/following.vue:
|
||||
empty: "フォロー中のユーザーはいないようです。"
|
||||
empty: "フォロー中のユーザーはおらんっぽいで、知らんけど。"
|
||||
desktop/views/components/friends-maker.vue:
|
||||
title: "気になるユーザーをフォロー:"
|
||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
||||
fetching: "読み込んでいます"
|
||||
refresh: "もっと見る"
|
||||
title: "おもろそうやな:"
|
||||
empty: "おもろいユーザー居らんかったわ"
|
||||
fetching: "読みこんどるで…"
|
||||
refresh: "もっとあるやろ!"
|
||||
close: "閉じる"
|
||||
desktop/views/components/game-window.vue:
|
||||
game: "ゲーム"
|
||||
desktop/views/components/home.vue:
|
||||
done: "完了"
|
||||
add-widget: "ウィジェットを追加:"
|
||||
add: "追加"
|
||||
add-widget: "ウィジェット増やす"
|
||||
add: "増やす"
|
||||
desktop/views/input-dialog.vue:
|
||||
cancel: "やめとくわ"
|
||||
ok: "決定"
|
||||
@ -554,32 +579,30 @@ desktop/views/components/messaging-room-window.vue:
|
||||
desktop/views/components/messaging-window.vue:
|
||||
title: "メッセージ"
|
||||
desktop/views/components/note-detail.vue:
|
||||
more: "会話をもっと読み込む"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
more: "もっと会話あるやろ!"
|
||||
private: "この投稿は見せられへんわ"
|
||||
deleted: "この投稿なんか無くなってもうたわ"
|
||||
reposted-by: "{}がRenote"
|
||||
location: "位置情報"
|
||||
location: "ここおるで:"
|
||||
renote: "Renote"
|
||||
add-reaction: "リアクション"
|
||||
desktop/views/components/notes.note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
reply: "返信"
|
||||
reply: "返す"
|
||||
renote: "Renote"
|
||||
add-reaction: "リアクション"
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
load-more: "もっと読み込む"
|
||||
error: "あかん、読み込めへんわ"
|
||||
retry: "もっぺん"
|
||||
load-more: "もっとあらへんのか!"
|
||||
desktop/views/components/notifications.vue:
|
||||
more: "もっと見る"
|
||||
empty: "ありません!"
|
||||
more: "もっとあるやろ!"
|
||||
empty: "あらへん!"
|
||||
desktop/views/components/post-form.vue:
|
||||
add-visible-user: "+ユーザーを追加"
|
||||
add-visible-user: "+ユーザー増やす"
|
||||
attach-location-information: "いる場所くっつけるで"
|
||||
hide-contents: "内容を隠す"
|
||||
reply-placeholder: "この投稿への返信..."
|
||||
@ -589,13 +612,13 @@ desktop/views/components/post-form.vue:
|
||||
renote: "Renote"
|
||||
posted: "投稿したで!"
|
||||
replied: "返信したで!"
|
||||
reposted: "Renoteしました!"
|
||||
reposted: "Renoteしたで!"
|
||||
note-failed: "投稿に失敗したで"
|
||||
reply-failed: "返信に失敗したで"
|
||||
renote-failed: "Renoteに失敗しました"
|
||||
renote-failed: "Renoteでけへん"
|
||||
posting: "投稿中"
|
||||
attach-media-from-local: "PCからメディアを添付"
|
||||
attach-media-from-drive: "ドライブからメディアを添付"
|
||||
attach-media-from-local: "PCからメディア持ってくる"
|
||||
attach-media-from-drive: "ドライブからメディア持ってくる"
|
||||
attach-cancel: "くっつけるのやめよか"
|
||||
insert-a-kao: "v('ω')v"
|
||||
create-poll: "アンケートを作成"
|
||||
@ -606,16 +629,16 @@ desktop/views/components/post-form.vue:
|
||||
geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。"
|
||||
error: "エラー"
|
||||
enter-username: "ユーザー名を入力してや"
|
||||
annotations: "内容への注釈 (オプション)"
|
||||
annotations: "もっと教えてな(別にええけど)"
|
||||
desktop/views/components/post-form-window.vue:
|
||||
note: "新規投稿"
|
||||
reply: "返信"
|
||||
reply: "返す"
|
||||
attaches: "添付: {}メディア"
|
||||
uploading-media: "{}個のメディアをアップロード中"
|
||||
uploading-media: "{}個のメディアを上げてるで…"
|
||||
desktop/views/components/progress-dialog.vue:
|
||||
waiting: "待機中"
|
||||
waiting: "待っとる"
|
||||
desktop/views/components/renote-form.vue:
|
||||
quote: "引用する..."
|
||||
quote: "持ってくる…"
|
||||
cancel: "やめとくわ"
|
||||
renote: "Renote"
|
||||
reposting: "しています..."
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -649,38 +675,38 @@ desktop/views/components/settings.vue:
|
||||
customize: "ホームをカスタマイズ"
|
||||
choose-wallpaper: "壁紙を選択"
|
||||
delete-wallpaper: "壁紙を削除"
|
||||
dark-mode: "ダークモード"
|
||||
circle-icons: "円形のアイコンを使用"
|
||||
contrasted-acct: "ユーザー名にコントラストを付ける"
|
||||
gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用"
|
||||
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||
show-clock-on-header: "右上に時計を表示する"
|
||||
show-reply-target: "リプライ先を表示する"
|
||||
show-my-renotes: "自分の行ったRenoteをタイムラインに表示する"
|
||||
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
|
||||
show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する"
|
||||
show-maps: "マップの自動展開"
|
||||
show-maps-desc: "位置情報が添付された投稿のマップを自動的に展開します。"
|
||||
dark-mode: "夜にすんで"
|
||||
circle-icons: "アイコンもタコ焼きも丸いやんな?"
|
||||
contrasted-acct: "ユーザー名ようわからんし見やすしといて"
|
||||
gradient-window-header: "ウィンドウのタイトルバーにグラデーション付ける"
|
||||
post-form-on-timeline: "タイムラインの上の方で投稿できるようにせえへん?"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示すんで"
|
||||
show-clock-on-header: "右上をカリヨン広場にする(時計表示)"
|
||||
show-reply-target: "どこにリプライするんや見せて"
|
||||
show-my-renotes: "わしのRenoteもタイムライン載せてくれや"
|
||||
show-renoted-my-notes: "わしのRenoteもタイムライン載せてくれや"
|
||||
show-local-renotes: "ローカル投稿のRenoteも見たいんや"
|
||||
show-maps: "地図勝手にバァーって開いてくれ"
|
||||
show-maps-desc: "どこにおるんかわかっとる投稿の地図は自動で見せるで"
|
||||
sound: "サウンド"
|
||||
enable-sounds: "サウンドを有効にする"
|
||||
enable-sounds-desc: "投稿やメッセージを送受信したときなどにサウンドを再生します。この設定はブラウザに記憶されます。"
|
||||
enable-sounds: "サウンド鳴らす"
|
||||
enable-sounds-desc: "投稿やメッセージもろたとき、音鳴らしたるわ。大丈夫や、この設定はブラウザが覚えてくれとる。"
|
||||
volume: "ボリューム"
|
||||
test: "テスト"
|
||||
mobile: "モバイル"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグなんて要らんわ"
|
||||
language: "言語"
|
||||
pick-language: "言語を選択"
|
||||
recommended: "推奨"
|
||||
pick-language: "言語選んでや"
|
||||
recommended: "おすすめ"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
language-desc: "変更はページの再度読み込み後に反映されます。"
|
||||
specify-language: "言語選んでくれ"
|
||||
language-desc: "変更はページの再度読み込み後に反映されんで。"
|
||||
cache: "キャッシュ"
|
||||
clean-cache: "クリーンアップ"
|
||||
cache-warn: "クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。"
|
||||
cache-cleared: "キャッシュを削除しました"
|
||||
cache-cleared-desc: "ページを再度読み込みしてください。"
|
||||
auto-watch: "投稿の自動ウォッチ"
|
||||
clean-cache: "お掃除"
|
||||
cache-warn: "お掃除するとな、ブラウザが覚えてくれとるアカウントのあれこれや書きかけの投稿・返信・メッセージや設定情報なんかのデータが全部飛んでいくんや。これやったらページ再読込しといてな。"
|
||||
cache-cleared: "キャッシュお掃除したで"
|
||||
cache-cleared-desc: "もっぺんページ読みこみ直してくれや"
|
||||
auto-watch: "投稿勝手にウォッチしといてや"
|
||||
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
||||
about: "Misskeyについて"
|
||||
operator: "このサーバーの運営者"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskey를 찾아 주셔서 감사합니다. Misskey은 지구에서 태어난 <b>분산 마이크로 블로그 SNS </b> 입니다. Fediverse (다양한 SNS로 구성되는 우주)에 존재하는 다른 SNS와 상호 연결되어 있습니다. 잠시 도시의 번잡함에서 벗어나 새로운 인터넷에 다이브 해 보지 않겠습니까."
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "광고 차단기를 해제하십시오"
|
||||
warning: "<strong>Misskey는 광고를 게재하지 않습니다</strong> 그러나 광고를 차단하는 기능 기능을 사용할 경우 일부 기능을 사용할 수 없게 될 가능성이나 결함이 발생하는 경우가 있습니다."
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "곤란하고 있어"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "지금 어떻게하고있어?"
|
||||
b: "뭔가 있었습니까?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "당신"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "Deel alles met anderen die ook Misskey gebruiken."
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Verward"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "Het verbinden lijkt te lukken. Herlaad de pagina."
|
||||
flush: "Cache leegmaken"
|
||||
set-version: "Versie opgeven"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "Gebruiker zoeken"
|
||||
you: "Jij"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "Details tonen"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Laden mislukt."
|
||||
retry: "Opnieuw proberen"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "Gedrag"
|
||||
fetch-on-scroll: "Ophalen bij scrollen"
|
||||
fetch-on-scroll-desc: "Als je omlaag scrolt, wordt de rest van de inhoud automatisch opgehaald."
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "Venster automatisch uitvouwen"
|
||||
auto-popout-desc: "Venster uitvouwen, indien mogelijk. Deze instelling wordt opgeslagen in je browser."
|
||||
advanced: "Geavanceerde instellingen"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "Geboortedatum"
|
||||
save: "Profiel bijwerken"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "Dit account is een Bot"
|
||||
is-cat: "Dit account is een Kat"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "Renote door {}"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "Gebruikersafbeelding"
|
||||
banner: "Omslagfoto"
|
||||
is-cat: "Dit account is een Kat"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "Profiel bijwerken"
|
||||
saved: "Profiel bijgewerkt"
|
||||
uploading: "Bezig met uploaden"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "Gedrag"
|
||||
fetch-on-scroll: "Ophalen bij scrollen"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "Zonder 'mobiele berichten'"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Forvirret"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "⭐ Fediwersum"
|
||||
about-title: "⭐ Fediwersum"
|
||||
about: "Dziękujemy za znalezienie Misskey. Misskey jest <b>zdecentralizowaną platformą mikroblogową</b> powstałą na Ziemi. Ponieważ działa ona w Fediwersum (uniwersum, w którego skład wchodzi wiele sieci społecznościowych), jest ona połączona z innymi platformami społecznościowymi. Spróbujesz odpocząć od zatłoczoneo miasta i zanurzyć się w nowym Internecie?"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "Spróbuj wyłączyć blokadę reklam."
|
||||
warning: "<strong>Misskey nie zawiera reklam</strong>, ale część funkcji może nie działać prawidłowo z włączonym blokowaniem reklam."
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Zmieszany"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "Co robisz?"
|
||||
b: "Co się wydarzyło?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "Wygląda na to, że udało się połączyć. Odśwież stronę."
|
||||
flush: "Wyczyść pamięć podręczną"
|
||||
set-version: "Określ wersję"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "Znajdź użytkownika"
|
||||
you: "Ty"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "Pokaż szczegóły"
|
||||
private: "ten wpis jest prywatny"
|
||||
deleted: "ten wpis został usunięty"
|
||||
hide: "Zwiń"
|
||||
see-more: "Więcej"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "Ładowanie nie powiodło się."
|
||||
retry: "Spróbuj ponownie"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "Zachowanie"
|
||||
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||
fetch-on-scroll-desc: "Po przewinięciu na dół strony automatycznie zostaną załadowane nowe treści."
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "Automatycznie pojawiające się okna"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "Ustawienia zaawansowane"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "Data urodzenia"
|
||||
save: "Aktualizuj profil"
|
||||
locked-account: "Zabezpiecz swoje konto"
|
||||
is-locked: "Uczyń wpis prywatnym"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "Inne"
|
||||
is-bot: "To konto jest prowadzone przez bota"
|
||||
is-cat: "To konto jest prowadzone przez kota"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "Zamknij"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "Udostępniono przez {}"
|
||||
more: "Rozwiń"
|
||||
less: "Zwiń"
|
||||
private: "ten wpis jest prywatny"
|
||||
deleted: "ten wpis został usunięty"
|
||||
location: "Informacje o lokalizacji"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "Awatar"
|
||||
banner: "Baner"
|
||||
is-cat: "To konto jest prowadzone przez kota"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "Aktualizuj profil"
|
||||
saved: "Pomyślnie zaktualizowano profil"
|
||||
uploading: "Wysyłanie"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "Zachowanie"
|
||||
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "Nie oznaczaj wpisów jako „wysłane z telefonu”"
|
||||
load-raw-images: "Wyświetlaj załączone zdjęcia w wysokiej jakości"
|
||||
load-remote-media: "Wyświetlaj zawartość multimedialną ze zdalnych serwerów"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "Uma ⭐ do fediverso"
|
||||
about-title: "Uma ⭐ do fediverso."
|
||||
about: "Obrigado por encontrar Misskey. Uma <b>plataforma descentralizada de microblog</b> nascida na Terra. Já que ela existe no Fediverso (um universo onde várias plataformas de mídia social são organizadas), ela é ligada com outras plataformas.Por que você não tira uma folga do agito e confusão da cidade, e mergulha em uma nova internet?"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "Por favor, desative o bloqueador de anúncios."
|
||||
warning: "Alguns recursos podem não estar disponíveis ou apresentar mal funcionamento se o bloqueio de anúncios estiver ativado. <strong>Misskey não está usando anúncios</strong>"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "Confuso"
|
||||
rip: "RIP"
|
||||
pudding: "Pudim"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "O que está fazendo?"
|
||||
b: "O que está acontecendo?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "Limpar o cache"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "Você"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "こまこまのこまり"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
@ -6,6 +6,19 @@ common:
|
||||
misskey: "A ⭐ of fediverse"
|
||||
about-title: "A ⭐ of fediverse."
|
||||
about: "Misskeyを見つけていただき、ありがとうございます。Misskeyは、地球で生まれた<b>分散マイクロブログSNS</b>です。Fediverse(様々なSNSで構成される宇宙)の中に存在するため、他のSNSと相互に繋がっています。暫し都会の喧騒から離れて、新しいインターネットにダイブしてみませんか。"
|
||||
intro:
|
||||
title: "Misskeyって?"
|
||||
about: "Misskeyはオープンソースの<b>分散型マイクロブログSNS</b>です。リッチで高度にカスタマイズできるUI、投稿へのリアクション、ファイルを一元管理できるドライブなど、先進的な機能を揃えています。また、Fediverseと呼ばれるネットワークに接続できるため、他のSNSともやり取りできます。例えば、あなたが何か投稿すると、その投稿はMisskeyだけでなく他のSNSにも伝わります。ちょうどある惑星から他の惑星に電波を発信している様子をイメージしてください。"
|
||||
features: "特徴"
|
||||
rich-contents: "投稿"
|
||||
rich-contents-desc: "自分の考え、話題の出来事、皆と共有したいことについて発信してください。必要であれば、様々な構文を使って投稿を装飾したり、好きな画像、動画などのファイルやアンケートを添付することもできます。"
|
||||
reaction: "リアクション"
|
||||
reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。"
|
||||
ui: "インターフェース"
|
||||
ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。"
|
||||
drive: "ドライブ"
|
||||
drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。"
|
||||
outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!"
|
||||
adblock:
|
||||
detected: "広告ブロッカーを無効にしてください"
|
||||
warning: "<strong>Misskeyは広告を掲載していません</strong>が、広告をブロックする機能が有効だと一部の機能が利用できなかったり、不具合が発生する場合があります。"
|
||||
@ -68,6 +81,15 @@ common:
|
||||
confused: "こまこまのこまり"
|
||||
rip: "RIP"
|
||||
pudding: "Pudding"
|
||||
note-visibility:
|
||||
public: "公開"
|
||||
home: "ホーム"
|
||||
home-desc: "ホームタイムラインにのみ公開"
|
||||
followers: "フォロワー"
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -231,6 +253,9 @@ common/views/components/connect-failed.troubleshooter.vue:
|
||||
success-desc: "正常に接続できるようです。ページを再度読み込みしてください。"
|
||||
flush: "キャッシュの削除"
|
||||
set-version: "バージョン指定"
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
@ -569,8 +594,6 @@ desktop/views/components/notes.note.vue:
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
hide: "隠す"
|
||||
see-more: "もっと見る"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
@ -640,6 +663,9 @@ desktop/views/components/settings.vue:
|
||||
behaviour: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
fetch-on-scroll-desc: "ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -752,7 +778,7 @@ desktop/views/components/settings.profile.vue:
|
||||
birthday: "誕生日"
|
||||
save: "保存"
|
||||
locked-account: "アカウントの保護"
|
||||
is-locked: "投稿を非公開にする"
|
||||
is-locked: "フォローを承認制にする"
|
||||
other: "その他"
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-cat: "このアカウントはCatです"
|
||||
@ -1006,8 +1032,6 @@ mobile/views/components/friends-maker.vue:
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
more: "もっと見る"
|
||||
less: "隠す"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1136,6 +1160,9 @@ mobile/views/pages/settings/settings.profile.vue:
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
is-cat: "このアカウントはCatです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
@ -1171,6 +1198,9 @@ mobile/views/pages/settings.vue:
|
||||
notification-position-top: "上"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
|
14
package.json
14
package.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "8.33.1",
|
||||
"clientVersion": "1.0.9497",
|
||||
"version": "8.39.0",
|
||||
"clientVersion": "1.0.9650",
|
||||
"codename": "nighthike",
|
||||
"main": "./built/index.js",
|
||||
"private": true,
|
||||
@ -58,7 +58,7 @@
|
||||
"@types/minio": "7.0.0",
|
||||
"@types/mkdirp": "0.5.2",
|
||||
"@types/mocha": "5.2.3",
|
||||
"@types/mongodb": "3.1.4",
|
||||
"@types/mongodb": "3.1.7",
|
||||
"@types/ms": "0.7.30",
|
||||
"@types/node": "10.9.4",
|
||||
"@types/portscanner": "2.1.0",
|
||||
@ -94,7 +94,7 @@
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "1.0.0",
|
||||
"dateformat": "3.0.3",
|
||||
"debug": "3.1.0",
|
||||
"debug": "4.0.1",
|
||||
"deep-equal": "1.0.1",
|
||||
"deepcopy": "0.6.3",
|
||||
"diskusage": "0.2.4",
|
||||
@ -194,7 +194,7 @@
|
||||
"stylus": "0.54.5",
|
||||
"stylus-loader": "3.0.2",
|
||||
"summaly": "2.2.0",
|
||||
"systeminformation": "3.45.1",
|
||||
"systeminformation": "3.45.6",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"textarea-caret": "3.1.0",
|
||||
"tmp": "0.0.33",
|
||||
@ -212,7 +212,7 @@
|
||||
"vue-cropperjs": "2.2.1",
|
||||
"vue-js-modal": "1.3.26",
|
||||
"vue-json-tree-view": "2.1.4",
|
||||
"vue-loader": "15.4.1",
|
||||
"vue-loader": "15.4.2",
|
||||
"vue-router": "3.0.1",
|
||||
"vue-style-loader": "4.1.2",
|
||||
"vue-template-compiler": "2.5.17",
|
||||
@ -222,7 +222,7 @@
|
||||
"vuex-persistedstate": "2.5.4",
|
||||
"web-push": "3.3.2",
|
||||
"webfinger.js": "2.6.6",
|
||||
"webpack": "4.17.2",
|
||||
"webpack": "4.19.0",
|
||||
"webpack-cli": "3.1.0",
|
||||
"websocket": "1.0.26",
|
||||
"ws": "6.0.0",
|
||||
|
@ -18,6 +18,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const langs = LANGS;
|
||||
|
||||
//#region Load settings
|
||||
let settings = null;
|
||||
const vuex = localStorage.getItem('vuex');
|
||||
@ -40,10 +42,10 @@
|
||||
//#region Detect the user language
|
||||
let lang = null;
|
||||
|
||||
if (LANGS.includes(navigator.language)) {
|
||||
if (langs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = LANGS.find(x => x.split('-')[0] == navigator.language);
|
||||
lang = langs.find(x => x.split('-')[0] == navigator.language);
|
||||
|
||||
if (lang == null) {
|
||||
// Fallback
|
||||
@ -52,7 +54,7 @@
|
||||
}
|
||||
|
||||
if (settings && settings.device.lang &&
|
||||
LANGS.includes(settings.device.lang)) {
|
||||
langs.includes(settings.device.lang)) {
|
||||
lang = settings.device.lang;
|
||||
}
|
||||
//#endregion
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<span class="mk-acct">
|
||||
<span class="name">@{{ user.username }}</span>
|
||||
<span class="host" :class="{ fade: $store.state.settings.contrastedAcct }" v-if="user.host || detail">@{{ user.host || host }}</span>
|
||||
<span class="host" :class="{ fade: $store.state.settings.contrastedAcct }" v-if="user.host || detail || $store.state.settings.showFullAcct">@{{ user.host || host }}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<span class="mk-avatar" :class="{ cat }" :title="user | acct" v-if="disableLink && !disablePreview" v-user-preview="user.id" @click="onClick">
|
||||
<span class="inner" :style="style"></span>
|
||||
<span class="mk-avatar" :style="style" :class="{ cat }" :title="user | acct" v-if="disableLink && !disablePreview" v-user-preview="user.id" @click="onClick">
|
||||
<span class="inner" :style="icon"></span>
|
||||
</span>
|
||||
<span class="mk-avatar" :class="{ cat }" :title="user | acct" v-else-if="disableLink && disablePreview" @click="onClick">
|
||||
<span class="inner" :style="style"></span>
|
||||
<span class="mk-avatar" :style="style" :class="{ cat }" :title="user | acct" v-else-if="disableLink && disablePreview" @click="onClick">
|
||||
<span class="inner" :style="icon"></span>
|
||||
</span>
|
||||
<router-link class="mk-avatar" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && !disablePreview" v-user-preview="user.id">
|
||||
<span class="inner" :style="style"></span>
|
||||
<router-link class="mk-avatar" :style="style" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && !disablePreview" v-user-preview="user.id">
|
||||
<span class="inner" :style="icon"></span>
|
||||
</router-link>
|
||||
<router-link class="mk-avatar" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && disablePreview">
|
||||
<span class="inner" :style="style"></span>
|
||||
<router-link class="mk-avatar" :style="style" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && disablePreview">
|
||||
<span class="inner" :style="icon"></span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
@ -42,6 +42,11 @@ export default Vue.extend({
|
||||
return this.user.isCat && this.$store.state.settings.circleIcons;
|
||||
},
|
||||
style(): any {
|
||||
return {
|
||||
borderRadius: this.$store.state.settings.circleIcons ? '100%' : null
|
||||
};
|
||||
},
|
||||
icon(): any {
|
||||
return {
|
||||
backgroundColor: this.lightmode
|
||||
? `rgb(${this.user.avatarColor.slice(0, 3).join(',')})`
|
||||
|
44
src/client/app/common/views/components/cw-button.vue
Normal file
44
src/client/app/common/views/components/cw-button.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<button class="nrvgflfuaxwgkxoynpnumyookecqrrvh" @click="toggle">{{ value ? '%i18n:@hide%' : '%i18n:@show%' }}</button>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle() {
|
||||
this.$emit('input', !this.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
root(isDark)
|
||||
display inline-block
|
||||
padding 4px 8px
|
||||
font-size 0.7em
|
||||
color isDark ? #393f4f : #fff
|
||||
background isDark ? #687390 : #b1b9c1
|
||||
border-radius 2px
|
||||
cursor pointer
|
||||
user-select none
|
||||
|
||||
&:hover
|
||||
background isDark ? #707b97 : #bbc4ce
|
||||
|
||||
.nrvgflfuaxwgkxoynpnumyookecqrrvh[data-darkmode]
|
||||
root(true)
|
||||
|
||||
.nrvgflfuaxwgkxoynpnumyookecqrrvh:not([data-darkmode])
|
||||
root(false)
|
||||
|
||||
</style>
|
@ -1,5 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
import cwButton from './cw-button.vue';
|
||||
import tagCloud from './tag-cloud.vue';
|
||||
import trends from './trends.vue';
|
||||
import analogClock from './analog-clock.vue';
|
||||
@ -42,6 +43,7 @@ import uiSelect from './ui/select.vue';
|
||||
import formButton from './ui/form/button.vue';
|
||||
import formRadio from './ui/form/radio.vue';
|
||||
|
||||
Vue.component('mk-cw-button', cwButton);
|
||||
Vue.component('mk-tag-cloud', tagCloud);
|
||||
Vue.component('mk-trends', trends);
|
||||
Vue.component('mk-analog-clock', analogClock);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Vue from 'vue';
|
||||
import Vue, { VNode } from 'vue';
|
||||
import * as emojilib from 'emojilib';
|
||||
import { length } from 'stringz';
|
||||
import parse from '../../../../../mfm/parse';
|
||||
@ -6,10 +6,7 @@ import getAcct from '../../../../../misc/acct/render';
|
||||
import { url } from '../../../config';
|
||||
import MkUrl from './url.vue';
|
||||
import MkGoogle from './google.vue';
|
||||
|
||||
const flatten = list => list.reduce(
|
||||
(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
|
||||
);
|
||||
import { concat } from '../../../../../prelude/array';
|
||||
|
||||
export default Vue.component('misskey-flavored-markdown', {
|
||||
props: {
|
||||
@ -32,20 +29,20 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
},
|
||||
|
||||
render(createElement) {
|
||||
let ast;
|
||||
let ast: any[];
|
||||
|
||||
if (this.ast == null) {
|
||||
// Parse text to ast
|
||||
ast = parse(this.text);
|
||||
} else {
|
||||
ast = this.ast;
|
||||
ast = this.ast as any[];
|
||||
}
|
||||
|
||||
let bigCount = 0;
|
||||
let motionCount = 0;
|
||||
|
||||
// Parse ast to DOM
|
||||
const els = flatten(ast.map(token => {
|
||||
const els = concat(ast.map((token): VNode[] => {
|
||||
switch (token.type) {
|
||||
case 'text': {
|
||||
const text = token.content.replace(/(\r\n|\n|\r)/g, '\n');
|
||||
@ -56,12 +53,12 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
x[x.length - 1].pop();
|
||||
return x;
|
||||
} else {
|
||||
return createElement('span', text.replace(/\n/g, ' '));
|
||||
return [createElement('span', text.replace(/\n/g, ' '))];
|
||||
}
|
||||
}
|
||||
|
||||
case 'bold': {
|
||||
return createElement('b', token.bold);
|
||||
return [createElement('b', token.bold)];
|
||||
}
|
||||
|
||||
case 'big': {
|
||||
@ -95,23 +92,23 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
}
|
||||
|
||||
case 'url': {
|
||||
return createElement(MkUrl, {
|
||||
return [createElement(MkUrl, {
|
||||
props: {
|
||||
url: token.content,
|
||||
target: '_blank'
|
||||
}
|
||||
});
|
||||
})];
|
||||
}
|
||||
|
||||
case 'link': {
|
||||
return createElement('a', {
|
||||
return [createElement('a', {
|
||||
attrs: {
|
||||
class: 'link',
|
||||
href: token.url,
|
||||
target: '_blank',
|
||||
title: token.url
|
||||
}
|
||||
}, token.title);
|
||||
}, token.title)];
|
||||
}
|
||||
|
||||
case 'mention': {
|
||||
@ -129,16 +126,16 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
}
|
||||
|
||||
case 'hashtag': {
|
||||
return createElement('a', {
|
||||
return [createElement('a', {
|
||||
attrs: {
|
||||
href: `${url}/tags/${encodeURIComponent(token.hashtag)}`,
|
||||
target: '_blank'
|
||||
}
|
||||
}, token.content);
|
||||
}, token.content)];
|
||||
}
|
||||
|
||||
case 'code': {
|
||||
return createElement('pre', {
|
||||
return [createElement('pre', {
|
||||
class: 'code'
|
||||
}, [
|
||||
createElement('code', {
|
||||
@ -146,15 +143,15 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
innerHTML: token.html
|
||||
}
|
||||
})
|
||||
]);
|
||||
])];
|
||||
}
|
||||
|
||||
case 'inline-code': {
|
||||
return createElement('code', {
|
||||
return [createElement('code', {
|
||||
domProps: {
|
||||
innerHTML: token.html
|
||||
}
|
||||
});
|
||||
})];
|
||||
}
|
||||
|
||||
case 'quote': {
|
||||
@ -164,43 +161,45 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||
const x = text2.split('\n')
|
||||
.map(t => [createElement('span', t), createElement('br')]);
|
||||
x[x.length - 1].pop();
|
||||
return createElement('div', {
|
||||
return [createElement('div', {
|
||||
attrs: {
|
||||
class: 'quote'
|
||||
}
|
||||
}, x);
|
||||
}, x)];
|
||||
} else {
|
||||
return createElement('span', {
|
||||
return [createElement('span', {
|
||||
attrs: {
|
||||
class: 'quote'
|
||||
}
|
||||
}, text2.replace(/\n/g, ' '));
|
||||
}, text2.replace(/\n/g, ' '))];
|
||||
}
|
||||
}
|
||||
|
||||
case 'title': {
|
||||
return createElement('div', {
|
||||
return [createElement('div', {
|
||||
attrs: {
|
||||
class: 'title'
|
||||
}
|
||||
}, token.title);
|
||||
}, token.title)];
|
||||
}
|
||||
|
||||
case 'emoji': {
|
||||
const emoji = emojilib.lib[token.emoji];
|
||||
return createElement('span', emoji ? emoji.char : token.content);
|
||||
return [createElement('span', emoji ? emoji.char : token.content)];
|
||||
}
|
||||
|
||||
case 'search': {
|
||||
return createElement(MkGoogle, {
|
||||
return [createElement(MkGoogle, {
|
||||
props: {
|
||||
q: token.query
|
||||
}
|
||||
});
|
||||
})];
|
||||
}
|
||||
|
||||
default: {
|
||||
console.log('unknown ast type:', token.type);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
@ -32,7 +32,6 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import parseAcct from '../../../../../misc/acct/parse';
|
||||
import getUserName from '../../../../../misc/get-user-name';
|
||||
import Progress from '../../../common/scripts/loading';
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="ldwbgwstjsdgcjruamauqdrffetqudry" v-if="image.isSensitive && hide" @click="hide = false">
|
||||
<div class="ldwbgwstjsdgcjruamauqdrffetqudry" v-if="image.isSensitive && hide && !$store.state.device.alwaysShowNsfw" @click="hide = false">
|
||||
<div>
|
||||
<b>%fa:exclamation-triangle% %i18n:@sensitive%</b>
|
||||
<span>%i18n:@click-to-show%</span>
|
||||
|
@ -37,20 +37,26 @@
|
||||
</router-link>
|
||||
</header>
|
||||
<div class="body">
|
||||
<div class="text">
|
||||
<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
|
||||
<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
|
||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||
</div>
|
||||
<div class="files" v-if="p.files.length > 0">
|
||||
<mk-media-list :media-list="p.files" :raw="true"/>
|
||||
</div>
|
||||
<mk-poll v-if="p.poll" :note="p"/>
|
||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
||||
<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="renote" v-if="p.renote">
|
||||
<mk-note-preview :note="p.renote"/>
|
||||
<p v-if="p.cw != null" class="cw">
|
||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="p.cw == null || showContent">
|
||||
<div class="text">
|
||||
<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
|
||||
<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
|
||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||
</div>
|
||||
<div class="files" v-if="p.files.length > 0">
|
||||
<mk-media-list :media-list="p.files" :raw="true"/>
|
||||
</div>
|
||||
<mk-poll v-if="p.poll" :note="p"/>
|
||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
||||
<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="renote" v-if="p.renote">
|
||||
<mk-note-preview :note="p.renote"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
@ -105,6 +111,7 @@ export default Vue.extend({
|
||||
|
||||
data() {
|
||||
return {
|
||||
showContent: false,
|
||||
conversation: [],
|
||||
conversationFetching: false,
|
||||
replies: []
|
||||
@ -118,17 +125,21 @@ export default Vue.extend({
|
||||
this.note.fileIds.length == 0 &&
|
||||
this.note.poll == null);
|
||||
},
|
||||
|
||||
p(): any {
|
||||
return this.isRenote ? this.note.renote : this.note;
|
||||
},
|
||||
|
||||
reactionsCount(): number {
|
||||
return this.p.reactionCounts
|
||||
? sum(Object.values(this.p.reactionCounts))
|
||||
: 0;
|
||||
},
|
||||
|
||||
title(): string {
|
||||
return new Date(this.p.createdAt).toLocaleString();
|
||||
},
|
||||
|
||||
urls(): string[] {
|
||||
if (this.p.text) {
|
||||
const ast = parse(this.p.text);
|
||||
@ -183,22 +194,26 @@ export default Vue.extend({
|
||||
this.conversation = conversation.reverse();
|
||||
});
|
||||
},
|
||||
|
||||
reply() {
|
||||
(this as any).os.new(MkPostFormWindow, {
|
||||
reply: this.p
|
||||
});
|
||||
},
|
||||
|
||||
renote() {
|
||||
(this as any).os.new(MkRenoteFormWindow, {
|
||||
note: this.p
|
||||
});
|
||||
},
|
||||
|
||||
react() {
|
||||
(this as any).os.new(MkReactionPicker, {
|
||||
source: this.$refs.reactButton,
|
||||
note: this.p
|
||||
});
|
||||
},
|
||||
|
||||
menu() {
|
||||
(this as any).os.new(MkNoteMenu, {
|
||||
source: this.$refs.menuButton,
|
||||
@ -326,37 +341,49 @@ root(isDark)
|
||||
> .body
|
||||
padding 8px 0
|
||||
|
||||
> .text
|
||||
> .cw
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
overflow-wrap break-word
|
||||
font-size 1.5em
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
> .renote
|
||||
margin 8px 0
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
> .mk-note-preview
|
||||
padding 16px
|
||||
border dashed 1px #c0dac6
|
||||
border-radius 8px
|
||||
> .content
|
||||
> .text
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
overflow-wrap break-word
|
||||
font-size 1.5em
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
> .location
|
||||
margin 4px 0
|
||||
font-size 12px
|
||||
color #ccc
|
||||
> .renote
|
||||
margin 8px 0
|
||||
|
||||
> .map
|
||||
width 100%
|
||||
height 300px
|
||||
> *
|
||||
padding 16px
|
||||
border dashed 1px #c0dac6
|
||||
border-radius 8px
|
||||
|
||||
&:empty
|
||||
display none
|
||||
> .location
|
||||
margin 4px 0
|
||||
font-size 12px
|
||||
color #ccc
|
||||
|
||||
> .mk-url-preview
|
||||
margin-top 8px
|
||||
> .map
|
||||
width 100%
|
||||
height 300px
|
||||
|
||||
&:empty
|
||||
display none
|
||||
|
||||
> .mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
> footer
|
||||
font-size 1.2em
|
||||
|
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<div class="mk-note-preview" :title="title">
|
||||
<div class="qiziqtywpuaucsgarwajitwaakggnisj" :title="title">
|
||||
<mk-avatar class="avatar" :user="note.user" v-if="!mini"/>
|
||||
<div class="main">
|
||||
<mk-note-header class="header" :note="note" :mini="true"/>
|
||||
<div class="body">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
<p v-if="note.cw != null" class="cw">
|
||||
<span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="note.cw == null || showContent">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -25,6 +31,13 @@ export default Vue.extend({
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
showContent: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
title(): string {
|
||||
return new Date(this.note.createdAt).toLocaleString();
|
||||
@ -52,16 +65,28 @@ root(isDark)
|
||||
|
||||
> .body
|
||||
|
||||
> .text
|
||||
> .cw
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
overflow-wrap break-word
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
.mk-note-preview[data-darkmode]
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
> .content
|
||||
> .text
|
||||
cursor default
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
|
||||
.qiziqtywpuaucsgarwajitwaakggnisj[data-darkmode]
|
||||
root(true)
|
||||
|
||||
.mk-note-preview:not([data-darkmode])
|
||||
.qiziqtywpuaucsgarwajitwaakggnisj:not([data-darkmode])
|
||||
root(false)
|
||||
|
||||
</style>
|
||||
|
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<div class="sub" :title="title">
|
||||
<div class="tkfdzaxtkdeianobciwadajxzbddorql" :title="title">
|
||||
<mk-avatar class="avatar" :user="note.user"/>
|
||||
<div class="main">
|
||||
<mk-note-header class="header" :note="note"/>
|
||||
<div class="body">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
<p v-if="note.cw != null" class="cw">
|
||||
<span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="note.cw == null || showContent">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -14,7 +20,19 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['note'],
|
||||
props: {
|
||||
note: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
showContent: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
title(): string {
|
||||
return new Date(this.note.createdAt).toLocaleString();
|
||||
@ -48,20 +66,32 @@ root(isDark)
|
||||
|
||||
> .body
|
||||
|
||||
> .text
|
||||
> .cw
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
overflow-wrap break-word
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
pre
|
||||
max-height 120px
|
||||
font-size 80%
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
.sub[data-darkmode]
|
||||
> .content
|
||||
> .text
|
||||
cursor default
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
|
||||
pre
|
||||
max-height 120px
|
||||
font-size 80%
|
||||
|
||||
.tkfdzaxtkdeianobciwadajxzbddorql[data-darkmode]
|
||||
root(true)
|
||||
|
||||
.sub:not([data-darkmode])
|
||||
.tkfdzaxtkdeianobciwadajxzbddorql:not([data-darkmode])
|
||||
root(false)
|
||||
|
||||
</style>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<div class="body">
|
||||
<p v-if="p.cw != null" class="cw">
|
||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||
<span class="toggle" @click="showContent = !showContent">{{ showContent ? '%i18n:@hide%' : '%i18n:@see-more%' }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="p.cw == null || showContent">
|
||||
<div class="text">
|
||||
@ -34,9 +34,7 @@
|
||||
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
||||
<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="renote" v-if="p.renote">
|
||||
<mk-note-preview :note="p.renote"/>
|
||||
</div>
|
||||
<div class="renote" v-if="p.renote"><mk-note-preview :note="p.renote"/></div>
|
||||
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
||||
</div>
|
||||
</div>
|
||||
@ -96,7 +94,12 @@ export default Vue.extend({
|
||||
XSub
|
||||
},
|
||||
|
||||
props: ['note'],
|
||||
props: {
|
||||
note: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
@ -398,19 +401,6 @@ root(isDark)
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
> .toggle
|
||||
display inline-block
|
||||
padding 4px 8px
|
||||
font-size 0.7em
|
||||
color isDark ? #393f4f : #fff
|
||||
background isDark ? #687390 : #b1b9c1
|
||||
border-radius 2px
|
||||
cursor pointer
|
||||
user-select none
|
||||
|
||||
&:hover
|
||||
background isDark ? #707b97 : #bbc4ce
|
||||
|
||||
> .content
|
||||
|
||||
> .text
|
||||
@ -469,7 +459,7 @@ root(isDark)
|
||||
> .renote
|
||||
margin 8px 0
|
||||
|
||||
> .mk-note-preview
|
||||
> *
|
||||
padding 16px
|
||||
border dashed 1px isDark ? #4e945e : #c0dac6
|
||||
border-radius 8px
|
||||
|
@ -10,8 +10,7 @@
|
||||
</div>
|
||||
|
||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||
<!--<transition-group name="mk-notes" class="transition">-->
|
||||
<div class="notes">
|
||||
<transition-group name="mk-notes" class="notes transition" tag="div">
|
||||
<template v-for="(note, i) in _notes">
|
||||
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/>
|
||||
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
||||
@ -19,8 +18,7 @@
|
||||
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
<!--</transition-group>-->
|
||||
</transition-group>
|
||||
|
||||
<footer v-if="more">
|
||||
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
|
@ -2,8 +2,7 @@
|
||||
<div class="mk-notifications">
|
||||
<div class="notifications" v-if="notifications.length != 0">
|
||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||
<!-- <transition-group name="mk-notifications" class="transition"> -->
|
||||
<div>
|
||||
<transition-group name="mk-notifications" class="transition" tag="div">
|
||||
<template v-for="(notification, i) in _notifications">
|
||||
<div class="notification" :class="notification.type" :key="notification.id">
|
||||
<mk-time :time="notification.createdAt"/>
|
||||
@ -97,8 +96,7 @@
|
||||
<span>%fa:angle-down%{{ _notifications[i + 1]._datetext }}</span>
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
<!-- </transition-group> -->
|
||||
</transition-group>
|
||||
</div>
|
||||
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
|
||||
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
|
||||
|
@ -45,7 +45,7 @@
|
||||
<span v-if="visibility === 'specified'">%fa:envelope%</span>
|
||||
<span v-if="visibility === 'private'">%fa:lock%</span>
|
||||
</button>
|
||||
<p class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</p>
|
||||
<p class="text-count" :class="{ over: this.trimmedLength(text) > 1000 }">{{ 1000 - this.trimmedLength(text) }}</p>
|
||||
<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
|
||||
{{ posting ? '%i18n:@posting%' : submitText }}<mk-ellipsis v-if="posting"/>
|
||||
</button>
|
||||
@ -62,7 +62,9 @@ import getFace from '../../../common/scripts/get-face';
|
||||
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
|
||||
import parse from '../../../../../mfm/parse';
|
||||
import { host } from '../../../config';
|
||||
import { erase } from '../../../../../prelude/array';
|
||||
import { erase, unique } from '../../../../../prelude/array';
|
||||
import { length } from 'stringz';
|
||||
import parseAcct from '../../../../../misc/acct/parse';
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
@ -146,7 +148,7 @@ export default Vue.extend({
|
||||
canPost(): boolean {
|
||||
return !this.posting &&
|
||||
(1 <= this.text.length || 1 <= this.files.length || this.poll || this.renote) &&
|
||||
(this.text.trim().length <= 1000);
|
||||
(length(this.text.trim()) <= 1000);
|
||||
}
|
||||
},
|
||||
|
||||
@ -198,6 +200,10 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
methods: {
|
||||
trimmedLength(text: string) {
|
||||
return length(text.trim());
|
||||
},
|
||||
|
||||
addTag(tag: string) {
|
||||
insertTextAtCursor(this.$refs.text, ` #${tag} `);
|
||||
},
|
||||
@ -337,10 +343,9 @@ export default Vue.extend({
|
||||
addVisibleUser() {
|
||||
(this as any).apis.input({
|
||||
title: '%i18n:@enter-username%'
|
||||
}).then(username => {
|
||||
(this as any).api('users/show', {
|
||||
username
|
||||
}).then(user => {
|
||||
}).then(acct => {
|
||||
if (acct.startsWith('@')) acct = acct.substr(1);
|
||||
(this as any).api('users/show', parseAcct(acct)).then(user => {
|
||||
this.visibleUsers.push(user);
|
||||
});
|
||||
});
|
||||
@ -392,7 +397,7 @@ export default Vue.extend({
|
||||
if (this.text && this.text != '') {
|
||||
const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
|
||||
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
||||
localStorage.setItem('hashtags', JSON.stringify(hashtags.concat(history).reduce((a, c) => a.includes(c) ? a : [...a, c], [])));
|
||||
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="mk-renote-form">
|
||||
<mk-note-preview :note="note"/>
|
||||
<mk-note-preview class="preview" :note="note"/>
|
||||
<template v-if="!quote">
|
||||
<footer>
|
||||
<a class="quote" v-if="!quote" @click="onQuote">%i18n:@quote%</a>
|
||||
@ -61,7 +61,7 @@ export default Vue.extend({
|
||||
|
||||
root(isDark)
|
||||
|
||||
> .mk-note-preview
|
||||
> .preview
|
||||
margin 16px 22px
|
||||
|
||||
> footer
|
||||
|
@ -30,6 +30,7 @@
|
||||
<h2>%i18n:@other%</h2>
|
||||
<mk-switch v-model="$store.state.i.isBot" @change="onChangeIsBot" text="%i18n:@is-bot%"/>
|
||||
<mk-switch v-model="$store.state.i.isCat" @change="onChangeIsCat" text="%i18n:@is-cat%"/>
|
||||
<mk-switch v-model="alwaysMarkNsfw" text="%i18n:common.always-mark-nsfw%"/>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
@ -46,6 +47,12 @@ export default Vue.extend({
|
||||
birthday: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
alwaysMarkNsfw: {
|
||||
get() { return this.$store.state.i.settings.alwaysMarkNsfw; },
|
||||
set(value) { (this as any).api('i/update', { alwaysMarkNsfw: value }); }
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.name = this.$store.state.i.name || '';
|
||||
this.location = this.$store.state.i.profile.location;
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
<section class="web" v-show="page == 'web'">
|
||||
<h1>%i18n:@behaviour%</h1>
|
||||
<mk-switch v-model="$store.state.settings.fetchOnScroll" @change="onChangeFetchOnScroll" text="%i18n:@fetch-on-scroll%">
|
||||
<mk-switch v-model="fetchOnScroll" text="%i18n:@fetch-on-scroll%">
|
||||
<span>%i18n:@fetch-on-scroll-desc%</span>
|
||||
</mk-switch>
|
||||
<mk-switch v-model="autoPopout" text="%i18n:@auto-popout%">
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
<section>
|
||||
<header>%i18n:@note-visibility%</header>
|
||||
<mk-switch v-model="$store.state.settings.rememberNoteVisibility" @change="onChangeRememberNoteVisibility" text="%i18n:@remember-note-visibility%"/>
|
||||
<mk-switch v-model="rememberNoteVisibility" text="%i18n:@remember-note-visibility%"/>
|
||||
<section>
|
||||
<header>%i18n:@default-note-visibility%</header>
|
||||
<ui-select v-model="defaultNoteVisibility">
|
||||
@ -59,24 +59,26 @@
|
||||
<button class="ui" @click="updateWallpaper">%i18n:@choose-wallpaper%</button>
|
||||
<button class="ui" @click="deleteWallpaper">%i18n:@delete-wallpaper%</button>
|
||||
<mk-switch v-model="darkmode" text="%i18n:@dark-mode%"/>
|
||||
<mk-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons" text="%i18n:@circle-icons%"/>
|
||||
<mk-switch v-model="$store.state.settings.contrastedAcct" @change="onChangeContrastedAcct" text="%i18n:@contrasted-acct%"/>
|
||||
<mk-switch v-model="$store.state.settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="%i18n:@gradient-window-header%"/>
|
||||
<mk-switch v-model="$store.state.settings.iLikeSushi" @change="onChangeILikeSushi" text="%i18n:common.i-like-sushi%"/>
|
||||
<mk-switch v-model="circleIcons" text="%i18n:@circle-icons%"/>
|
||||
<mk-switch v-model="contrastedAcct" text="%i18n:@contrasted-acct%"/>
|
||||
<mk-switch v-model="showFullAcct" text="%i18n:common.show-full-acct%"/>
|
||||
<mk-switch v-model="gradientWindowHeader" text="%i18n:@gradient-window-header%"/>
|
||||
<mk-switch v-model="iLikeSushi" text="%i18n:common.i-like-sushi%"/>
|
||||
</div>
|
||||
<mk-switch v-model="$store.state.settings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="%i18n:@post-form-on-timeline%"/>
|
||||
<mk-switch v-model="$store.state.settings.suggestRecentHashtags" @change="onChangeSuggestRecentHashtags" text="%i18n:@suggest-recent-hashtags%"/>
|
||||
<mk-switch v-model="$store.state.settings.showClockOnHeader" @change="onChangeShowClockOnHeader" text="%i18n:@show-clock-on-header%"/>
|
||||
<mk-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget" text="%i18n:@show-reply-target%"/>
|
||||
<mk-switch v-model="$store.state.settings.showMyRenotes" @change="onChangeShowMyRenotes" text="%i18n:@show-my-renotes%"/>
|
||||
<mk-switch v-model="$store.state.settings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes" text="%i18n:@show-renoted-my-notes%"/>
|
||||
<mk-switch v-model="$store.state.settings.showLocalRenotes" @change="onChangeShowLocalRenotes" text="%i18n:@show-local-renotes%"/>
|
||||
<mk-switch v-model="$store.state.settings.showMaps" @change="onChangeShowMaps" text="%i18n:@show-maps%">
|
||||
<mk-switch v-model="showPostFormOnTopOfTl" text="%i18n:@post-form-on-timeline%"/>
|
||||
<mk-switch v-model="suggestRecentHashtags" text="%i18n:@suggest-recent-hashtags%"/>
|
||||
<mk-switch v-model="showClockOnHeader" text="%i18n:@show-clock-on-header%"/>
|
||||
<mk-switch v-model="alwaysShowNsfw" text="%i18n:common.always-show-nsfw%"/>
|
||||
<mk-switch v-model="showReplyTarget" text="%i18n:@show-reply-target%"/>
|
||||
<mk-switch v-model="showMyRenotes" text="%i18n:@show-my-renotes%"/>
|
||||
<mk-switch v-model="showRenotedMyNotes" text="%i18n:@show-renoted-my-notes%"/>
|
||||
<mk-switch v-model="showLocalRenotes" text="%i18n:@show-local-renotes%"/>
|
||||
<mk-switch v-model="showMaps" text="%i18n:@show-maps%">
|
||||
<span>%i18n:@show-maps-desc%</span>
|
||||
</mk-switch>
|
||||
<mk-switch v-model="$store.state.settings.disableAnimatedMfm" @change="onChangeDisableAnimatedMfm" text="%i18n:common.disable-animated-mfm%"/>
|
||||
<mk-switch v-model="$store.state.settings.games.reversi.showBoardLabels" @change="onChangeReversiBoardLabels" text="%i18n:common.show-reversi-board-labels%"/>
|
||||
<mk-switch v-model="$store.state.settings.games.reversi.useContrastStones" @change="onChangeUseContrastReversiStones" text="%i18n:common.use-contrast-reversi-stones%"/>
|
||||
<mk-switch v-model="disableAnimatedMfm" text="%i18n:common.disable-animated-mfm%"/>
|
||||
<mk-switch v-model="games_reversi_showBoardLabels" text="%i18n:common.show-reversi-board-labels%"/>
|
||||
<mk-switch v-model="games_reversi_useContrastStones" text="%i18n:common.use-contrast-reversi-stones%"/>
|
||||
</section>
|
||||
|
||||
<section class="web" v-show="page == 'web'">
|
||||
@ -98,7 +100,7 @@
|
||||
|
||||
<section class="web" v-show="page == 'web'">
|
||||
<h1>%i18n:@mobile%</h1>
|
||||
<mk-switch v-model="$store.state.settings.disableViaMobile" @change="onChangeDisableViaMobile" text="%i18n:@disable-via-mobile%"/>
|
||||
<mk-switch v-model="disableViaMobile" text="%i18n:@disable-via-mobile%"/>
|
||||
</section>
|
||||
|
||||
<section class="web" v-show="page == 'web'">
|
||||
@ -255,11 +257,6 @@ export default Vue.extend({
|
||||
set(value) { this.$store.commit('device/set', { key: 'apiViaStream', value }); }
|
||||
},
|
||||
|
||||
defaultNoteVisibility: {
|
||||
get() { return this.$store.state.settings.defaultNoteVisibility; },
|
||||
set(value) { this.$store.commit('settings/set', { key: 'defaultNoteVisibility', value }); }
|
||||
},
|
||||
|
||||
autoPopout: {
|
||||
get() { return this.$store.state.device.autoPopout; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'autoPopout', value }); }
|
||||
@ -298,7 +295,112 @@ export default Vue.extend({
|
||||
enableExperimentalFeatures: {
|
||||
get() { return this.$store.state.device.enableExperimentalFeatures; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'enableExperimentalFeatures', value }); }
|
||||
}
|
||||
},
|
||||
|
||||
alwaysShowNsfw: {
|
||||
get() { return this.$store.state.device.alwaysShowNsfw; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'alwaysShowNsfw', value }); }
|
||||
},
|
||||
|
||||
fetchOnScroll: {
|
||||
get() { return this.$store.state.settings.fetchOnScroll; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'fetchOnScroll', value }); }
|
||||
},
|
||||
|
||||
rememberNoteVisibility: {
|
||||
get() { return this.$store.state.settings.rememberNoteVisibility; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'rememberNoteVisibility', value }); }
|
||||
},
|
||||
|
||||
defaultNoteVisibility: {
|
||||
get() { return this.$store.state.settings.defaultNoteVisibility; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'defaultNoteVisibility', value }); }
|
||||
},
|
||||
|
||||
showReplyTarget: {
|
||||
get() { return this.$store.state.settings.showReplyTarget; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showReplyTarget', value }); }
|
||||
},
|
||||
|
||||
showMyRenotes: {
|
||||
get() { return this.$store.state.settings.showMyRenotes; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showMyRenotes', value }); }
|
||||
},
|
||||
|
||||
showRenotedMyNotes: {
|
||||
get() { return this.$store.state.settings.showRenotedMyNotes; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showRenotedMyNotes', value }); }
|
||||
},
|
||||
|
||||
showLocalRenotes: {
|
||||
get() { return this.$store.state.settings.showLocalRenotes; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showLocalRenotes', value }); }
|
||||
},
|
||||
|
||||
showPostFormOnTopOfTl: {
|
||||
get() { return this.$store.state.settings.showPostFormOnTopOfTl; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showPostFormOnTopOfTl', value }); }
|
||||
},
|
||||
|
||||
suggestRecentHashtags: {
|
||||
get() { return this.$store.state.settings.suggestRecentHashtags; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'suggestRecentHashtags', value }); }
|
||||
},
|
||||
|
||||
showClockOnHeader: {
|
||||
get() { return this.$store.state.settings.showClockOnHeader; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showClockOnHeader', value }); }
|
||||
},
|
||||
|
||||
showMaps: {
|
||||
get() { return this.$store.state.settings.showMaps; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showMaps', value }); }
|
||||
},
|
||||
|
||||
circleIcons: {
|
||||
get() { return this.$store.state.settings.circleIcons; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'circleIcons', value }); }
|
||||
},
|
||||
|
||||
contrastedAcct: {
|
||||
get() { return this.$store.state.settings.contrastedAcct; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'contrastedAcct', value }); }
|
||||
},
|
||||
|
||||
showFullAcct: {
|
||||
get() { return this.$store.state.settings.showFullAcct; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showFullAcct', value }); }
|
||||
},
|
||||
|
||||
iLikeSushi: {
|
||||
get() { return this.$store.state.settings.iLikeSushi; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'iLikeSushi', value }); }
|
||||
},
|
||||
|
||||
games_reversi_showBoardLabels: {
|
||||
get() { return this.$store.state.settings.games.reversi.showBoardLabels; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.showBoardLabels', value }); }
|
||||
},
|
||||
|
||||
games_reversi_useContrastStones: {
|
||||
get() { return this.$store.state.settings.games.reversi.useContrastStones; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useContrastStones', value }); }
|
||||
},
|
||||
|
||||
disableAnimatedMfm: {
|
||||
get() { return this.$store.state.settings.disableAnimatedMfm; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableAnimatedMfm', value }); }
|
||||
},
|
||||
|
||||
disableViaMobile: {
|
||||
get() { return this.$store.state.settings.disableViaMobile; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableViaMobile', value }); }
|
||||
},
|
||||
|
||||
gradientWindowHeader: {
|
||||
get() { return this.$store.state.settings.gradientWindowHeader; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'gradientWindowHeader', value }); }
|
||||
},
|
||||
},
|
||||
created() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
@ -327,125 +429,11 @@ export default Vue.extend({
|
||||
wallpaperId: null
|
||||
});
|
||||
},
|
||||
onChangeFetchOnScroll(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'fetchOnScroll',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeRememberNoteVisibility(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'rememberNoteVisibility',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeAutoWatch(v) {
|
||||
(this as any).api('i/update', {
|
||||
autoWatch: v
|
||||
});
|
||||
},
|
||||
onChangeDark(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'dark',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowPostFormOnTopOfTl(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showPostFormOnTopOfTl',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeSuggestRecentHashtags(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'suggestRecentHashtags',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowClockOnHeader(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showClockOnHeader',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowReplyTarget(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showReplyTarget',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowMyRenotes(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showMyRenotes',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowRenotedMyNotes(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showRenotedMyNotes',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowLocalRenotes(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showLocalRenotes',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeShowMaps(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showMaps',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeCircleIcons(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'circleIcons',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeContrastedAcct(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'contrastedAcct',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeILikeSushi(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'iLikeSushi',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeReversiBoardLabels(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'games.reversi.showBoardLabels',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeUseContrastReversiStones(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'games.reversi.useContrastStones',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeDisableAnimatedMfm(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'disableAnimatedMfm',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeGradientWindowHeader(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'gradientWindowHeader',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
onChangeDisableViaMobile(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'disableViaMobile',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
checkForUpdate() {
|
||||
this.checkingForUpdate = true;
|
||||
checkForUpdate((this as any).os, true, true).then(newer => {
|
||||
|
@ -2,8 +2,8 @@
|
||||
<div class="mk-timeline">
|
||||
<header>
|
||||
<span :data-active="src == 'home'" @click="src = 'home'">%fa:home% %i18n:@home%</span>
|
||||
<span :data-active="src == 'local'" @click="src = 'local'">%fa:R comments% %i18n:@local%</span>
|
||||
<span :data-active="src == 'hybrid'" @click="src = 'hybrid'">%fa:share-alt% %i18n:@hybrid%</span>
|
||||
<span :data-active="src == 'local'" @click="src = 'local'" v-if="enableLocalTimeline">%fa:R comments% %i18n:@local%</span>
|
||||
<span :data-active="src == 'hybrid'" @click="src = 'hybrid'" v-if="enableLocalTimeline">%fa:share-alt% %i18n:@hybrid%</span>
|
||||
<span :data-active="src == 'global'" @click="src = 'global'">%fa:globe% %i18n:@global%</span>
|
||||
<span :data-active="src == 'list'" @click="src = 'list'" v-if="list">%fa:list% {{ list.title }}</span>
|
||||
<button @click="chooseList" title="%i18n:@list%">%fa:list%</button>
|
||||
@ -29,7 +29,8 @@ export default Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
src: 'home',
|
||||
list: null
|
||||
list: null,
|
||||
enableLocalTimeline: false
|
||||
};
|
||||
},
|
||||
|
||||
@ -44,6 +45,10 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
created() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.enableLocalTimeline = !meta.disableLocalTimeline;
|
||||
});
|
||||
|
||||
if (this.$store.state.device.tl) {
|
||||
this.src = this.$store.state.device.tl.src;
|
||||
if (this.src == 'list') {
|
||||
|
@ -1,17 +1,16 @@
|
||||
<template>
|
||||
<div class="root item">
|
||||
<mk-avatar class="avatar" :user="user"/>
|
||||
<div class="main">
|
||||
<header>
|
||||
<router-link class="name" :to="user | userPage" v-user-preview="user.id">{{ user | userName }}</router-link>
|
||||
<span class="username">@{{ user | acct }}</span>
|
||||
</header>
|
||||
<div class="body">
|
||||
<p class="followed" v-if="user.isFollowed">%i18n:@followed%</p>
|
||||
<div class="description">{{ user.description }}</div>
|
||||
<div class="zvdbznxvfixtmujpsigoccczftvpiwqh">
|
||||
<div class="banner" :style="bannerStyle"></div>
|
||||
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
|
||||
<div class="body">
|
||||
<router-link :to="user | userPage" class="name">{{ user | userName }}</router-link>
|
||||
<span class="username">@{{ user | acct }}</span>
|
||||
<div class="description">
|
||||
<misskey-flavored-markdown v-if="user.description" :text="user.description" :i="$store.state.i"/>
|
||||
</div>
|
||||
<p class="followed" v-if="user.isFollowed">%i18n:@followed%</p>
|
||||
<mk-follow-button :user="user" :size="'big'"/>
|
||||
</div>
|
||||
<mk-follow-button :user="user"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -19,76 +18,69 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['user']
|
||||
props: ['user'],
|
||||
|
||||
computed: {
|
||||
bannerStyle(): any {
|
||||
if (this.user.bannerUrl == null) return {};
|
||||
return {
|
||||
backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null,
|
||||
backgroundImage: `url(${ this.user.bannerUrl })`
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.root.item
|
||||
padding 16px
|
||||
font-size 16px
|
||||
.zvdbznxvfixtmujpsigoccczftvpiwqh
|
||||
$bg = #fff
|
||||
|
||||
&:after
|
||||
content ""
|
||||
display block
|
||||
clear both
|
||||
margin 16px auto
|
||||
max-width calc(100% - 32px)
|
||||
font-size 16px
|
||||
text-align center
|
||||
background $bg
|
||||
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||
|
||||
> .banner
|
||||
height 100px
|
||||
background-color #f9f4f4
|
||||
background-position center
|
||||
background-size cover
|
||||
|
||||
> .avatar
|
||||
display block
|
||||
float left
|
||||
margin 0 16px 0 0
|
||||
width 58px
|
||||
height 58px
|
||||
border-radius 8px
|
||||
margin -40px auto 0 auto
|
||||
width 80px
|
||||
height 80px
|
||||
border-radius 100%
|
||||
border solid 4px $bg
|
||||
|
||||
> .main
|
||||
float left
|
||||
width calc(100% - 74px)
|
||||
> .body
|
||||
padding 4px 32px 32px 32px
|
||||
|
||||
> header
|
||||
margin-bottom 2px
|
||||
@media (max-width 400px)
|
||||
padding 4px 16px 16px 16px
|
||||
|
||||
> .name
|
||||
display inline
|
||||
margin 0
|
||||
padding 0
|
||||
color #777
|
||||
font-size 1em
|
||||
font-weight 700
|
||||
text-align left
|
||||
text-decoration none
|
||||
> .name
|
||||
font-size 20px
|
||||
font-weight bold
|
||||
|
||||
&:hover
|
||||
text-decoration underline
|
||||
> .username
|
||||
display block
|
||||
opacity 0.7
|
||||
|
||||
> .username
|
||||
text-align left
|
||||
margin 0 0 0 8px
|
||||
color #ccc
|
||||
> .description
|
||||
margin 16px 0
|
||||
|
||||
> .body
|
||||
> .followed
|
||||
display inline-block
|
||||
margin 0 0 4px 0
|
||||
padding 2px 8px
|
||||
vertical-align top
|
||||
font-size 10px
|
||||
color #71afc7
|
||||
background #eefaff
|
||||
border-radius 4px
|
||||
|
||||
> .description
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
overflow-wrap break-word
|
||||
font-size 1.1em
|
||||
color #717171
|
||||
|
||||
> .mk-follow-button
|
||||
position absolute
|
||||
top 16px
|
||||
right 16px
|
||||
> .followed
|
||||
margin 0 0 16px 0
|
||||
padding 0
|
||||
line-height 24px
|
||||
font-size 0.8em
|
||||
color #71afc7
|
||||
background #eefaff
|
||||
border-radius 4px
|
||||
|
||||
</style>
|
||||
|
@ -33,7 +33,7 @@ export default Vue.extend({
|
||||
props: ['fetch', 'count', 'youKnowCount'],
|
||||
data() {
|
||||
return {
|
||||
limit: 30,
|
||||
limit: 20,
|
||||
mode: 'all',
|
||||
fetching: true,
|
||||
moreFetching: false,
|
||||
@ -73,10 +73,14 @@ export default Vue.extend({
|
||||
|
||||
.mk-users-list
|
||||
height 100%
|
||||
background #fff
|
||||
overflow auto
|
||||
background #eee
|
||||
|
||||
> nav
|
||||
z-index 1
|
||||
z-index 10
|
||||
position sticky
|
||||
top 0
|
||||
background #fff
|
||||
box-shadow 0 1px 0 rgba(#000, 0.1)
|
||||
|
||||
> div
|
||||
@ -114,16 +118,14 @@ export default Vue.extend({
|
||||
background #eee
|
||||
border-radius 20px
|
||||
|
||||
> .users
|
||||
height calc(100% - 54px)
|
||||
overflow auto
|
||||
> button
|
||||
display block
|
||||
width calc(100% - 32px)
|
||||
margin 16px
|
||||
padding 16px
|
||||
|
||||
> *
|
||||
border-bottom solid 1px rgba(#000, 0.05)
|
||||
|
||||
> *
|
||||
max-width 600px
|
||||
margin 0 auto
|
||||
&:hover
|
||||
background rgba(#000, 0.1)
|
||||
|
||||
> .no
|
||||
margin 0
|
||||
|
@ -1,22 +1,34 @@
|
||||
<template>
|
||||
<div class="obdskegsannmntldydackcpzezagxqfy mk-admin-card">
|
||||
<header>%i18n:@dashboard%</header>
|
||||
|
||||
<div v-if="stats" class="stats">
|
||||
<div><b>%fa:user% {{ stats.originalUsersCount | number }}</b><span>%i18n:@original-users%</span></div>
|
||||
<div><span>%fa:user% {{ stats.usersCount | number }}</span><span>%i18n:@all-users%</span></div>
|
||||
<div><b>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</b><span>%i18n:@original-notes%</span></div>
|
||||
<div><span>%fa:pencil-alt% {{ stats.notesCount | number }}</span><span>%i18n:@all-notes%</span></div>
|
||||
</div>
|
||||
|
||||
<div class="cpu-memory">
|
||||
<x-cpu-memory :connection="connection"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" v-model="disableRegistration" @change="updateMeta">
|
||||
<span>disableRegistration</span>
|
||||
</label>
|
||||
<button class="ui" @click="invite">%i18n:@invite%</button>
|
||||
<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
|
||||
|
||||
<div class="form">
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" v-model="disableRegistration" @change="updateMeta">
|
||||
<span>%i18n:@disableRegistration%</span>
|
||||
</label>
|
||||
<button class="ui" @click="invite">%i18n:@invite%</button>
|
||||
<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" v-model="disableLocalTimeline" @change="updateMeta">
|
||||
<span>%i18n:@disableLocalTimeline%</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -33,6 +45,7 @@ export default Vue.extend({
|
||||
return {
|
||||
stats: null,
|
||||
disableRegistration: false,
|
||||
disableLocalTimeline: false,
|
||||
inviteCode: null,
|
||||
connection: null,
|
||||
connectionId: null
|
||||
@ -44,6 +57,7 @@ export default Vue.extend({
|
||||
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.disableRegistration = meta.disableRegistration;
|
||||
this.disableLocalTimeline = meta.disableLocalTimeline;
|
||||
});
|
||||
|
||||
(this as any).api('stats').then(stats => {
|
||||
@ -61,7 +75,8 @@ export default Vue.extend({
|
||||
},
|
||||
updateMeta() {
|
||||
(this as any).api('admin/update-meta', {
|
||||
disableRegistration: this.disableRegistration
|
||||
disableRegistration: this.disableRegistration,
|
||||
disableLocalTimeline: this.disableLocalTimeline
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -97,4 +112,8 @@ export default Vue.extend({
|
||||
border solid 1px #eee
|
||||
border-radius: 8px
|
||||
|
||||
> .form
|
||||
> div
|
||||
border-bottom solid 1px #eee
|
||||
|
||||
</style>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<div class="body">
|
||||
<p v-if="p.cw != null" class="cw">
|
||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||
<span class="toggle" @click="showContent = !showContent">{{ showContent ? '%i18n:@less%' : '%i18n:@more%' }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="p.cw == null || showContent">
|
||||
<div class="text">
|
||||
@ -394,7 +394,7 @@ root(isDark)
|
||||
> .renote
|
||||
margin 8px 0
|
||||
|
||||
> .mk-note-preview
|
||||
> *
|
||||
padding 16px
|
||||
border dashed 1px isDark ? #4e945e : #c0dac6
|
||||
border-radius 8px
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="qjewsnkgzzxlxtzncydssfbgjibiehcy" v-if="image.isSensitive && hide" @click="hide = false">
|
||||
<div class="qjewsnkgzzxlxtzncydssfbgjibiehcy" v-if="image.isSensitive && hide && !$store.state.device.alwaysShowNsfw" @click="hide = false">
|
||||
<div>
|
||||
<b>%fa:exclamation-triangle% %i18n:@sensitive%</b>
|
||||
<span>%i18n:@click-to-show%</span>
|
||||
|
@ -35,20 +35,26 @@
|
||||
</div>
|
||||
</header>
|
||||
<div class="body">
|
||||
<div class="text">
|
||||
<span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
|
||||
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
|
||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||
</div>
|
||||
<div class="files" v-if="p.files.length > 0">
|
||||
<mk-media-list :media-list="p.files" :raw="true"/>
|
||||
</div>
|
||||
<mk-poll v-if="p.poll" :note="p"/>
|
||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
||||
<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="renote" v-if="p.renote">
|
||||
<mk-note-preview :note="p.renote"/>
|
||||
<p v-if="p.cw != null" class="cw">
|
||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="p.cw == null || showContent">
|
||||
<div class="text">
|
||||
<span v-if="p.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
|
||||
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</span>
|
||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||
</div>
|
||||
<div class="files" v-if="p.files.length > 0">
|
||||
<mk-media-list :media-list="p.files" :raw="true"/>
|
||||
</div>
|
||||
<mk-poll v-if="p.poll" :note="p"/>
|
||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
||||
<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="renote" v-if="p.renote">
|
||||
<mk-note-preview :note="p.renote"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<router-link class="time" :to="p | notePage">
|
||||
@ -104,6 +110,7 @@ export default Vue.extend({
|
||||
|
||||
data() {
|
||||
return {
|
||||
showContent: false,
|
||||
conversation: [],
|
||||
conversationFetching: false,
|
||||
replies: []
|
||||
@ -334,44 +341,57 @@ root(isDark)
|
||||
> .body
|
||||
padding 8px 0
|
||||
|
||||
> .text
|
||||
> .cw
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
overflow-wrap break-word
|
||||
font-size 16px
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
@media (min-width 500px)
|
||||
font-size 24px
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
> .renote
|
||||
margin 8px 0
|
||||
> .content
|
||||
|
||||
> .mk-note-preview
|
||||
padding 16px
|
||||
border dashed 1px #c0dac6
|
||||
border-radius 8px
|
||||
|
||||
> .location
|
||||
margin 4px 0
|
||||
font-size 12px
|
||||
color #ccc
|
||||
|
||||
> .map
|
||||
width 100%
|
||||
height 200px
|
||||
|
||||
&:empty
|
||||
display none
|
||||
|
||||
> .mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
> .files
|
||||
> img
|
||||
> .text
|
||||
display block
|
||||
max-width 100%
|
||||
margin 0
|
||||
padding 0
|
||||
overflow-wrap break-word
|
||||
font-size 16px
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
@media (min-width 500px)
|
||||
font-size 24px
|
||||
|
||||
> .renote
|
||||
margin 8px 0
|
||||
|
||||
> *
|
||||
padding 16px
|
||||
border dashed 1px #c0dac6
|
||||
border-radius 8px
|
||||
|
||||
> .location
|
||||
margin 4px 0
|
||||
font-size 12px
|
||||
color #ccc
|
||||
|
||||
> .map
|
||||
width 100%
|
||||
height 200px
|
||||
|
||||
&:empty
|
||||
display none
|
||||
|
||||
> .mk-url-preview
|
||||
margin-top 8px
|
||||
|
||||
> .files
|
||||
> img
|
||||
display block
|
||||
max-width 100%
|
||||
|
||||
> .time
|
||||
font-size 16px
|
||||
|
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<div class="mk-note-preview" :class="{ smart: $store.state.device.postStyle == 'smart' }">
|
||||
<div class="yohlumlkhizgfkvvscwfcrcggkotpvry" :class="{ smart: $store.state.device.postStyle == 'smart' }">
|
||||
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle != 'smart'"/>
|
||||
<div class="main">
|
||||
<mk-note-header class="header" :note="note" :mini="true"/>
|
||||
<div class="body">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
<p v-if="note.cw != null" class="cw">
|
||||
<span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="note.cw == null || showContent">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -14,7 +20,18 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
props: ['note']
|
||||
props: {
|
||||
note: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
showContent: false
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -65,16 +82,28 @@ root(isDark)
|
||||
|
||||
> .body
|
||||
|
||||
> .text
|
||||
> .cw
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
overflow-wrap break-word
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
.mk-note-preview[data-darkmode]
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
> .content
|
||||
> .text
|
||||
cursor default
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
|
||||
.yohlumlkhizgfkvvscwfcrcggkotpvry[data-darkmode]
|
||||
root(true)
|
||||
|
||||
.mk-note-preview:not([data-darkmode])
|
||||
.yohlumlkhizgfkvvscwfcrcggkotpvry:not([data-darkmode])
|
||||
root(false)
|
||||
|
||||
</style>
|
||||
|
@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<div class="sub" :class="{ smart: $store.state.device.postStyle == 'smart' }">
|
||||
<div class="zlrxdaqttccpwhpaagdmkawtzklsccam" :class="{ smart: $store.state.device.postStyle == 'smart' }">
|
||||
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle != 'smart'"/>
|
||||
<div class="main">
|
||||
<mk-note-header class="header" :note="note" :mini="true"/>
|
||||
<div class="body">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
<p v-if="note.cw != null" class="cw">
|
||||
<span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="note.cw == null || showContent">
|
||||
<mk-sub-note-content class="text" :note="note"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -24,6 +30,12 @@ export default Vue.extend({
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
showContent: false
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@ -77,20 +89,31 @@ root(isDark)
|
||||
margin-bottom 2px
|
||||
|
||||
> .body
|
||||
|
||||
> .text
|
||||
> .cw
|
||||
cursor default
|
||||
display block
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
overflow-wrap break-word
|
||||
color isDark ? #fff : #717171
|
||||
|
||||
pre
|
||||
max-height 120px
|
||||
font-size 80%
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
.sub[data-darkmode]
|
||||
> .content
|
||||
> .text
|
||||
margin 0
|
||||
padding 0
|
||||
color isDark ? #959ba7 : #717171
|
||||
|
||||
pre
|
||||
max-height 120px
|
||||
font-size 80%
|
||||
|
||||
.zlrxdaqttccpwhpaagdmkawtzklsccam[data-darkmode]
|
||||
root(true)
|
||||
|
||||
.sub:not([data-darkmode])
|
||||
.zlrxdaqttccpwhpaagdmkawtzklsccam:not([data-darkmode])
|
||||
root(false)
|
||||
|
||||
</style>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<div class="body">
|
||||
<p v-if="p.cw != null" class="cw">
|
||||
<span class="text" v-if="p.cw != ''">{{ p.cw }}</span>
|
||||
<span class="toggle" @click="showContent = !showContent">{{ showContent ? '%i18n:@less%' : '%i18n:@more%' }}</span>
|
||||
<mk-cw-button v-model="showContent"/>
|
||||
</p>
|
||||
<div class="content" v-show="p.cw == null || showContent">
|
||||
<div class="text">
|
||||
@ -35,9 +35,7 @@
|
||||
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
||||
<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="renote" v-if="p.renote">
|
||||
<mk-note-preview :note="p.renote"/>
|
||||
</div>
|
||||
<div class="renote" v-if="p.renote"><mk-note-preview :note="p.renote"/></div>
|
||||
</div>
|
||||
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
|
||||
</div>
|
||||
@ -352,19 +350,6 @@ root(isDark)
|
||||
> .text
|
||||
margin-right 8px
|
||||
|
||||
> .toggle
|
||||
display inline-block
|
||||
padding 4px 8px
|
||||
font-size 0.7em
|
||||
color isDark ? #393f4f : #fff
|
||||
background isDark ? #687390 : #b1b9c1
|
||||
border-radius 2px
|
||||
cursor pointer
|
||||
user-select none
|
||||
|
||||
&:hover
|
||||
background isDark ? #707b97 : #bbc4ce
|
||||
|
||||
> .content
|
||||
|
||||
> .text
|
||||
@ -436,7 +421,7 @@ root(isDark)
|
||||
> .renote
|
||||
margin 8px 0
|
||||
|
||||
> .mk-note-preview
|
||||
> *
|
||||
padding 16px
|
||||
border dashed 1px isDark ? #4e945e : #c0dac6
|
||||
border-radius 8px
|
||||
|
@ -14,8 +14,7 @@
|
||||
</div>
|
||||
|
||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||
<!-- <transition-group name="mk-notes" class="transition"> -->
|
||||
<div class="transition">
|
||||
<transition-group name="mk-notes" class="transition" tag="div">
|
||||
<template v-for="(note, i) in _notes">
|
||||
<mk-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/>
|
||||
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
||||
@ -23,8 +22,7 @@
|
||||
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
<!-- </transition-group> -->
|
||||
</transition-group>
|
||||
|
||||
<footer v-if="more">
|
||||
<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
|
@ -45,7 +45,7 @@ export default Vue.extend({
|
||||
$height = 78px
|
||||
|
||||
position fixed
|
||||
z-index 1024
|
||||
z-index 10000
|
||||
left 0
|
||||
right 0
|
||||
width 100%
|
||||
|
@ -4,14 +4,14 @@
|
||||
<header>
|
||||
<button class="cancel" @click="cancel">%fa:times%</button>
|
||||
<div>
|
||||
<span class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</span>
|
||||
<span class="text-count" :class="{ over: trimmedLength(text) > 1000 }">{{ 1000 - trimmedLength(text) }}</span>
|
||||
<span class="geo" v-if="geo">%fa:map-marker-alt%</span>
|
||||
<button class="submit" :disabled="!canPost" @click="post">{{ submitText }}</button>
|
||||
</div>
|
||||
</header>
|
||||
<div class="form">
|
||||
<mk-note-preview v-if="reply" :note="reply"/>
|
||||
<mk-note-preview v-if="renote" :note="renote"/>
|
||||
<mk-note-preview class="preview" v-if="reply" :note="reply"/>
|
||||
<mk-note-preview class="preview" v-if="renote" :note="renote"/>
|
||||
<div v-if="visibility == 'specified'" class="visibleUsers">
|
||||
<span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span>
|
||||
<a @click="addVisibleUser">+%i18n:@add-visible-user%</a>
|
||||
@ -60,6 +60,8 @@ import getFace from '../../../common/scripts/get-face';
|
||||
import parse from '../../../../../mfm/parse';
|
||||
import { host } from '../../../config';
|
||||
import { erase } from '../../../../../prelude/array';
|
||||
import { length } from 'stringz';
|
||||
import parseAcct from '../../../../../misc/acct/parse';
|
||||
|
||||
export default Vue.extend({
|
||||
components: {
|
||||
@ -179,6 +181,10 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
methods: {
|
||||
trimmedLength(text: string) {
|
||||
return length(text.trim());
|
||||
},
|
||||
|
||||
addTag(tag: string) {
|
||||
insertTextAtCursor(this.$refs.text, ` #${tag} `);
|
||||
},
|
||||
@ -253,10 +259,9 @@ export default Vue.extend({
|
||||
addVisibleUser() {
|
||||
(this as any).apis.input({
|
||||
title: '%i18n:@username-prompt%'
|
||||
}).then(username => {
|
||||
(this as any).api('users/show', {
|
||||
username
|
||||
}).then(user => {
|
||||
}).then(acct => {
|
||||
if (acct.startsWith('@')) acct = acct.substr(1);
|
||||
(this as any).api('users/show', parseAcct(acct)).then(user => {
|
||||
this.visibleUsers.push(user);
|
||||
});
|
||||
});
|
||||
@ -303,7 +308,7 @@ export default Vue.extend({
|
||||
if (this.text && this.text != '') {
|
||||
const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
|
||||
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
||||
localStorage.setItem('hashtags', JSON.stringify(hashtags.concat(history).reduce((a, c) => a.includes(c) ? a : [...a, c], [])));
|
||||
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
||||
}
|
||||
},
|
||||
|
||||
@ -382,7 +387,7 @@ root(isDark)
|
||||
max-width 500px
|
||||
margin 0 auto
|
||||
|
||||
> .mk-note-preview
|
||||
> .preview
|
||||
padding 16px
|
||||
|
||||
> .visibleUsers
|
||||
|
@ -24,8 +24,8 @@
|
||||
<div class="body">
|
||||
<div>
|
||||
<span :data-active="src == 'home'" @click="src = 'home'">%fa:home% %i18n:@home%</span>
|
||||
<span :data-active="src == 'local'" @click="src = 'local'">%fa:R comments% %i18n:@local%</span>
|
||||
<span :data-active="src == 'hybrid'" @click="src = 'hybrid'">%fa:share-alt% %i18n:@hybrid%</span>
|
||||
<span :data-active="src == 'local'" @click="src = 'local'" v-if="enableLocalTimeline">%fa:R comments% %i18n:@local%</span>
|
||||
<span :data-active="src == 'hybrid'" @click="src = 'hybrid'" v-if="enableLocalTimeline">%fa:share-alt% %i18n:@hybrid%</span>
|
||||
<span :data-active="src == 'global'" @click="src = 'global'">%fa:globe% %i18n:@global%</span>
|
||||
<template v-if="lists">
|
||||
<span v-for="l in lists" :data-active="src == 'list' && list == l" @click="src = 'list'; list = l" :key="l.id">%fa:list% {{ l.title }}</span>
|
||||
@ -60,7 +60,8 @@ export default Vue.extend({
|
||||
src: 'home',
|
||||
list: null,
|
||||
lists: null,
|
||||
showNav: false
|
||||
showNav: false,
|
||||
enableLocalTimeline: false
|
||||
};
|
||||
},
|
||||
|
||||
@ -85,6 +86,10 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
created() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.enableLocalTimeline = !meta.disableLocalTimeline;
|
||||
});
|
||||
|
||||
if (this.$store.state.device.tl) {
|
||||
this.src = this.$store.state.device.tl.src;
|
||||
if (this.src == 'list') {
|
||||
|
@ -12,21 +12,23 @@
|
||||
|
||||
<section>
|
||||
<ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.contrastedAcct" @change="onChangeContrastedAcct">%i18n:@contrasted-acct%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.iLikeSushi" @change="onChangeILikeSushi">%i18n:common.i-like-sushi%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.disableAnimatedMfm" @change="onChangeDisableAnimatedMfm">%i18n:common.disable-animated-mfm%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.games.reversi.showBoardLabels" @change="onChangeReversiBoardLabels">%i18n:common.show-reversi-board-labels%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.games.reversi.useContrastStones" @change="onChangeUseContrastReversiStones">%i18n:common.use-contrast-reversi-stones%</ui-switch>
|
||||
<ui-switch v-model="circleIcons">%i18n:@circle-icons%</ui-switch>
|
||||
<ui-switch v-model="contrastedAcct">%i18n:@contrasted-acct%</ui-switch>
|
||||
<ui-switch v-model="showFullAcct">%i18n:common.show-full-acct%</ui-switch>
|
||||
<ui-switch v-model="iLikeSushi">%i18n:common.i-like-sushi%</ui-switch>
|
||||
<ui-switch v-model="disableAnimatedMfm">%i18n:common.disable-animated-mfm%</ui-switch>
|
||||
<ui-switch v-model="alwaysShowNsfw">%i18n:common.always-show-nsfw% (%i18n:common.this-setting-is-this-device-only%)</ui-switch>
|
||||
<ui-switch v-model="games_reversi_showBoardLabels">%i18n:common.show-reversi-board-labels%</ui-switch>
|
||||
<ui-switch v-model="games_reversi_useContrastStones">%i18n:common.use-contrast-reversi-stones%</ui-switch>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>%i18n:@timeline%</header>
|
||||
<div>
|
||||
<ui-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget">%i18n:@show-reply-target%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.showMyRenotes" @change="onChangeShowMyRenotes">%i18n:@show-my-renotes%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes">%i18n:@show-renoted-my-notes%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.showLocalRenotes" @change="onChangeShowLocalRenotes">%i18n:@show-local-renotes%</ui-switch>
|
||||
<ui-switch v-model="showReplyTarget">%i18n:@show-reply-target%</ui-switch>
|
||||
<ui-switch v-model="showMyRenotes">%i18n:@show-my-renotes%</ui-switch>
|
||||
<ui-switch v-model="showRenotedMyNotes">%i18n:@show-renoted-my-notes%</ui-switch>
|
||||
<ui-switch v-model="showLocalRenotes">%i18n:@show-local-renotes%</ui-switch>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -47,16 +49,16 @@
|
||||
<div slot="title">%fa:cog% %i18n:@behavior%</div>
|
||||
|
||||
<section>
|
||||
<ui-switch v-model="$store.state.settings.fetchOnScroll" @change="onChangeFetchOnScroll">%i18n:@fetch-on-scroll%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.disableViaMobile" @change="onChangeDisableViaMobile">%i18n:@disable-via-mobile%</ui-switch>
|
||||
<ui-switch v-model="fetchOnScroll">%i18n:@fetch-on-scroll%</ui-switch>
|
||||
<ui-switch v-model="disableViaMobile">%i18n:@disable-via-mobile%</ui-switch>
|
||||
<ui-switch v-model="loadRawImages">%i18n:@load-raw-images%</ui-switch>
|
||||
<ui-switch v-model="$store.state.settings.loadRemoteMedia" @change="onChangeLoadRemoteMedia">%i18n:@load-remote-media%</ui-switch>
|
||||
<ui-switch v-model="loadRemoteMedia">%i18n:@load-remote-media%</ui-switch>
|
||||
<ui-switch v-model="lightmode">%i18n:@i-am-under-limited-internet%</ui-switch>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>%i18n:@note-visibility%</header>
|
||||
<ui-switch v-model="$store.state.settings.rememberNoteVisibility" @change="onChangeRememberNoteVisibility">%i18n:@remember-note-visibility%</ui-switch>
|
||||
<ui-switch v-model="rememberNoteVisibility">%i18n:@remember-note-visibility%</ui-switch>
|
||||
<section>
|
||||
<header>%i18n:@default-note-visibility%</header>
|
||||
<ui-select v-model="defaultNoteVisibility">
|
||||
@ -166,6 +168,11 @@ export default Vue.extend({
|
||||
set(value) { this.$store.commit('device/set', { key: 'darkmode', value }); }
|
||||
},
|
||||
|
||||
alwaysShowNsfw: {
|
||||
get() { return this.$store.state.device.alwaysShowNsfw; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'alwaysShowNsfw', value }); }
|
||||
},
|
||||
|
||||
postStyle: {
|
||||
get() { return this.$store.state.device.postStyle; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'postStyle', value }); }
|
||||
@ -176,11 +183,6 @@ export default Vue.extend({
|
||||
set(value) { this.$store.commit('device/set', { key: 'mobileNotificationPosition', value }); }
|
||||
},
|
||||
|
||||
defaultNoteVisibility: {
|
||||
get() { return this.$store.state.settings.defaultNoteVisibility; },
|
||||
set(value) { this.$store.commit('settings/set', { key: 'defaultNoteVisibility', value }); }
|
||||
},
|
||||
|
||||
lightmode: {
|
||||
get() { return this.$store.state.device.lightmode; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'lightmode', value }); }
|
||||
@ -200,6 +202,86 @@ export default Vue.extend({
|
||||
get() { return this.$store.state.device.enableSounds; },
|
||||
set(value) { this.$store.commit('device/set', { key: 'enableSounds', value }); }
|
||||
},
|
||||
|
||||
fetchOnScroll: {
|
||||
get() { return this.$store.state.settings.fetchOnScroll; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'fetchOnScroll', value }); }
|
||||
},
|
||||
|
||||
rememberNoteVisibility: {
|
||||
get() { return this.$store.state.settings.rememberNoteVisibility; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'rememberNoteVisibility', value }); }
|
||||
},
|
||||
|
||||
disableViaMobile: {
|
||||
get() { return this.$store.state.settings.disableViaMobile; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableViaMobile', value }); }
|
||||
},
|
||||
|
||||
loadRemoteMedia: {
|
||||
get() { return this.$store.state.settings.loadRemoteMedia; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'loadRemoteMedia', value }); }
|
||||
},
|
||||
|
||||
circleIcons: {
|
||||
get() { return this.$store.state.settings.circleIcons; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'circleIcons', value }); }
|
||||
},
|
||||
|
||||
contrastedAcct: {
|
||||
get() { return this.$store.state.settings.contrastedAcct; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'contrastedAcct', value }); }
|
||||
},
|
||||
|
||||
showFullAcct: {
|
||||
get() { return this.$store.state.settings.showFullAcct; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showFullAcct', value }); }
|
||||
},
|
||||
|
||||
iLikeSushi: {
|
||||
get() { return this.$store.state.settings.iLikeSushi; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'iLikeSushi', value }); }
|
||||
},
|
||||
|
||||
games_reversi_showBoardLabels: {
|
||||
get() { return this.$store.state.settings.games.reversi.showBoardLabels; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.showBoardLabels', value }); }
|
||||
},
|
||||
|
||||
games_reversi_useContrastStones: {
|
||||
get() { return this.$store.state.settings.games.reversi.useContrastStones; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'games.reversi.useContrastStones', value }); }
|
||||
},
|
||||
|
||||
disableAnimatedMfm: {
|
||||
get() { return this.$store.state.settings.disableAnimatedMfm; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableAnimatedMfm', value }); }
|
||||
},
|
||||
|
||||
showReplyTarget: {
|
||||
get() { return this.$store.state.settings.showReplyTarget; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showReplyTarget', value }); }
|
||||
},
|
||||
|
||||
showMyRenotes: {
|
||||
get() { return this.$store.state.settings.showMyRenotes; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showMyRenotes', value }); }
|
||||
},
|
||||
|
||||
showRenotedMyNotes: {
|
||||
get() { return this.$store.state.settings.showRenotedMyNotes; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showRenotedMyNotes', value }); }
|
||||
},
|
||||
|
||||
showLocalRenotes: {
|
||||
get() { return this.$store.state.settings.showLocalRenotes; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'showLocalRenotes', value }); }
|
||||
},
|
||||
|
||||
defaultNoteVisibility: {
|
||||
get() { return this.$store.state.settings.defaultNoteVisibility; },
|
||||
set(value) { this.$store.dispatch('settings/set', { key: 'defaultNoteVisibility', value }); }
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@ -211,104 +293,6 @@ export default Vue.extend({
|
||||
(this as any).os.signout();
|
||||
},
|
||||
|
||||
onChangeFetchOnScroll(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'fetchOnScroll',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeRememberNoteVisibility(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'rememberNoteVisibility',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeDisableViaMobile(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'disableViaMobile',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeLoadRemoteMedia(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'loadRemoteMedia',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeCircleIcons(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'circleIcons',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeContrastedAcct(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'contrastedAcct',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeILikeSushi(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'iLikeSushi',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeReversiBoardLabels(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'games.reversi.showBoardLabels',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeUseContrastReversiStones(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'games.reversi.useContrastStones',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeDisableAnimatedMfm(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'disableAnimatedMfm',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeShowReplyTarget(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showReplyTarget',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeShowMyRenotes(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showMyRenotes',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeShowRenotedMyNotes(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showRenotedMyNotes',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
onChangeShowLocalRenotes(v) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'showLocalRenotes',
|
||||
value: v
|
||||
});
|
||||
},
|
||||
|
||||
checkForUpdate() {
|
||||
this.checkingForUpdate = true;
|
||||
checkForUpdate((this as any).os, true, true).then(newer => {
|
||||
|
@ -40,11 +40,26 @@
|
||||
<span slot="text" v-if="bannerUploading">%i18n:@uploading%<mk-ellipsis/></span>
|
||||
</ui-input>
|
||||
|
||||
<ui-switch v-model="isCat">%i18n:@is-cat%</ui-switch>
|
||||
|
||||
<ui-button @click="save">%i18n:@save%</ui-button>
|
||||
<ui-button @click="save(true)">%i18n:@save%</ui-button>
|
||||
</ui-form>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>%i18n:@advanced%</header>
|
||||
|
||||
<div>
|
||||
<ui-switch v-model="isCat" @change="save(false)">%i18n:@is-cat%</ui-switch>
|
||||
<ui-switch v-model="alwaysMarkNsfw">%i18n:common.always-mark-nsfw%</ui-switch>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>%i18n:@privacy%</header>
|
||||
|
||||
<div>
|
||||
<ui-switch v-model="isLocked" @change="save(false)">%i18n:@is-locked%</ui-switch>
|
||||
</div>
|
||||
</section>
|
||||
</ui-card>
|
||||
</template>
|
||||
|
||||
@ -64,12 +79,20 @@ export default Vue.extend({
|
||||
avatarId: null,
|
||||
bannerId: null,
|
||||
isCat: false,
|
||||
isLocked: false,
|
||||
saving: false,
|
||||
avatarUploading: false,
|
||||
bannerUploading: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
alwaysMarkNsfw: {
|
||||
get() { return this.$store.state.i.settings.alwaysMarkNsfw; },
|
||||
set(value) { (this as any).api('i/update', { alwaysMarkNsfw: value }); }
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.name = this.$store.state.i.name || '';
|
||||
this.username = this.$store.state.i.username;
|
||||
@ -79,6 +102,7 @@ export default Vue.extend({
|
||||
this.avatarId = this.$store.state.i.avatarId;
|
||||
this.bannerId = this.$store.state.i.bannerId;
|
||||
this.isCat = this.$store.state.i.isCat;
|
||||
this.isLocked = this.$store.state.i.isLocked;
|
||||
},
|
||||
|
||||
methods: {
|
||||
@ -126,7 +150,7 @@ export default Vue.extend({
|
||||
});
|
||||
},
|
||||
|
||||
save() {
|
||||
save(notify) {
|
||||
this.saving = true;
|
||||
|
||||
(this as any).api('i/update', {
|
||||
@ -136,7 +160,8 @@ export default Vue.extend({
|
||||
birthday: this.birthday || null,
|
||||
avatarId: this.avatarId,
|
||||
bannerId: this.bannerId,
|
||||
isCat: this.isCat
|
||||
isCat: this.isCat,
|
||||
isLocked: this.isLocked
|
||||
}).then(i => {
|
||||
this.saving = false;
|
||||
this.$store.state.i.avatarId = i.avatarId;
|
||||
@ -144,7 +169,9 @@ export default Vue.extend({
|
||||
this.$store.state.i.bannerId = i.bannerId;
|
||||
this.$store.state.i.bannerUrl = i.bannerUrl;
|
||||
|
||||
alert('%i18n:@saved%');
|
||||
if (notify) {
|
||||
alert('%i18n:@saved%');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ const defaultSettings = {
|
||||
showClockOnHeader: true,
|
||||
circleIcons: true,
|
||||
contrastedAcct: true,
|
||||
showFullAcct: false,
|
||||
gradientWindowHeader: false,
|
||||
showReplyTarget: true,
|
||||
showMyRenotes: true,
|
||||
@ -47,6 +48,7 @@ const defaultDeviceSettings = {
|
||||
debug: false,
|
||||
lightmode: false,
|
||||
loadRawImages: false,
|
||||
alwaysShowNsfw: false,
|
||||
postStyle: 'standard',
|
||||
mobileNotificationPosition: 'bottom'
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"copyright": "Copyright (c) 2014-2018 syuilo",
|
||||
"themeColor": "#f6584f",
|
||||
"themeColor": "#fb4e4e",
|
||||
"themeColorForeground": "#fff"
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { capitalize } from "../../../prelude/string";
|
||||
import { capitalize, toUpperCase } from "../../../prelude/string";
|
||||
|
||||
function escape(text: string) {
|
||||
return text
|
||||
@ -92,7 +92,7 @@ const _keywords = [
|
||||
|
||||
const keywords = _keywords
|
||||
.concat(_keywords.map(capitalize))
|
||||
.concat(_keywords.map(k => k.toUpperCase()))
|
||||
.concat(_keywords.map(toUpperCase))
|
||||
.sort((a, b) => b.length - a.length);
|
||||
|
||||
const symbols = [
|
||||
|
@ -4,6 +4,7 @@ import { pack as packUser } from './user';
|
||||
import { pack as packFile } from './drive-file';
|
||||
import db from '../db/mongodb';
|
||||
import MessagingHistory, { deleteMessagingHistory } from './messaging-history';
|
||||
import { length } from 'stringz';
|
||||
|
||||
const MessagingMessage = db.get<IMessagingMessage>('messagingMessages');
|
||||
export default MessagingMessage;
|
||||
@ -19,7 +20,7 @@ export interface IMessagingMessage {
|
||||
}
|
||||
|
||||
export function isValidText(text: string): boolean {
|
||||
return text.length <= 1000 && text.trim() != '';
|
||||
return length(text.trim()) <= 1000 && text.trim() != '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,5 +12,6 @@ export type IMeta = {
|
||||
originalUsersCount: number;
|
||||
};
|
||||
disableRegistration?: boolean;
|
||||
disableLocalTimeline?: boolean;
|
||||
hidedTags?: string[];
|
||||
};
|
||||
|
@ -2,6 +2,7 @@ import * as mongo from 'mongodb';
|
||||
const deepcopy = require('deepcopy');
|
||||
import rap from '@prezzemolo/rap';
|
||||
import db from '../db/mongodb';
|
||||
import { length } from 'stringz';
|
||||
import { IUser, pack as packUser } from './user';
|
||||
import { pack as packApp } from './app';
|
||||
import PollVote, { deletePollVote } from './poll-vote';
|
||||
@ -24,11 +25,11 @@ Note.createIndex({
|
||||
export default Note;
|
||||
|
||||
export function isValidText(text: string): boolean {
|
||||
return text.length <= 1000 && text.trim() != '';
|
||||
return length(text.trim()) <= 1000 && text.trim() != '';
|
||||
}
|
||||
|
||||
export function isValidCw(text: string): boolean {
|
||||
return text.length <= 100;
|
||||
return length(text.trim()) <= 100;
|
||||
}
|
||||
|
||||
export type INote = {
|
||||
@ -162,6 +163,66 @@ export async function deleteNote(note: string | mongo.ObjectID | INote) {
|
||||
console.log(`Note: deleted ${n._id}`);
|
||||
}
|
||||
|
||||
export const hideNote = async (packedNote: any, meId: mongo.ObjectID) => {
|
||||
let hide = false;
|
||||
|
||||
// visibility が private かつ投稿者のIDが自分のIDではなかったら非表示
|
||||
if (packedNote.visibility == 'private' && (meId == null || !meId.equals(packedNote.userId))) {
|
||||
hide = true;
|
||||
}
|
||||
|
||||
// visibility が specified かつ自分が指定されていなかったら非表示
|
||||
if (packedNote.visibility == 'specified') {
|
||||
if (meId == null) {
|
||||
hide = true;
|
||||
} else if (meId.equals(packedNote.userId)) {
|
||||
hide = false;
|
||||
} else {
|
||||
// 指定されているかどうか
|
||||
const specified = packedNote.visibleUserIds.some((id: mongo.ObjectID) => id.equals(meId));
|
||||
|
||||
if (specified) {
|
||||
hide = false;
|
||||
} else {
|
||||
hide = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示
|
||||
if (packedNote.visibility == 'followers') {
|
||||
if (meId == null) {
|
||||
hide = true;
|
||||
} else if (meId.equals(packedNote.userId)) {
|
||||
hide = false;
|
||||
} else {
|
||||
// フォロワーかどうか
|
||||
const following = await Following.findOne({
|
||||
followeeId: packedNote.userId,
|
||||
followerId: meId
|
||||
});
|
||||
|
||||
if (following == null) {
|
||||
hide = true;
|
||||
} else {
|
||||
hide = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hide) {
|
||||
packedNote.fileIds = [];
|
||||
packedNote.files = [];
|
||||
packedNote.text = null;
|
||||
packedNote.poll = null;
|
||||
packedNote.cw = null;
|
||||
packedNote.tags = [];
|
||||
packedNote.tagsLower = [];
|
||||
packedNote.geo = null;
|
||||
packedNote.isHidden = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pack a note for API response
|
||||
*
|
||||
@ -174,11 +235,13 @@ export const pack = async (
|
||||
note: string | mongo.ObjectID | INote,
|
||||
me?: string | mongo.ObjectID | IUser,
|
||||
options?: {
|
||||
detail: boolean
|
||||
detail?: boolean;
|
||||
skipHide?: boolean;
|
||||
}
|
||||
) => {
|
||||
const opts = Object.assign({
|
||||
detail: true
|
||||
detail: true,
|
||||
skipHide: false
|
||||
}, options);
|
||||
|
||||
// Me
|
||||
@ -207,52 +270,6 @@ export const pack = async (
|
||||
|
||||
if (!_note) throw `invalid note arg ${note}`;
|
||||
|
||||
let hide = false;
|
||||
|
||||
// visibility が private かつ投稿者のIDが自分のIDではなかったら非表示
|
||||
if (_note.visibility == 'private' && (meId == null || !meId.equals(_note.userId))) {
|
||||
hide = true;
|
||||
}
|
||||
|
||||
// visibility が specified かつ自分が指定されていなかったら非表示
|
||||
if (_note.visibility == 'specified') {
|
||||
if (meId == null) {
|
||||
hide = true;
|
||||
} else if (meId.equals(_note.userId)) {
|
||||
hide = false;
|
||||
} else {
|
||||
// 指定されているかどうか
|
||||
const specified = _note.visibleUserIds.some((id: mongo.ObjectID) => id.equals(meId));
|
||||
|
||||
if (specified) {
|
||||
hide = false;
|
||||
} else {
|
||||
hide = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示
|
||||
if (_note.visibility == 'followers') {
|
||||
if (meId == null) {
|
||||
hide = true;
|
||||
} else if (meId.equals(_note.userId)) {
|
||||
hide = false;
|
||||
} else {
|
||||
// フォロワーかどうか
|
||||
const following = await Following.findOne({
|
||||
followeeId: _note.userId,
|
||||
followerId: meId
|
||||
});
|
||||
|
||||
if (following == null) {
|
||||
hide = true;
|
||||
} else {
|
||||
hide = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const id = _note._id;
|
||||
|
||||
// Rename _id to id
|
||||
@ -274,7 +291,7 @@ export const pack = async (
|
||||
}
|
||||
|
||||
// Populate files
|
||||
_note.files = hide ? [] : Promise.all(_note.fileIds.map((fileId: mongo.ObjectID) =>
|
||||
_note.files = Promise.all(_note.fileIds.map((fileId: mongo.ObjectID) =>
|
||||
packFile(fileId)
|
||||
));
|
||||
|
||||
@ -304,7 +321,7 @@ export const pack = async (
|
||||
}
|
||||
|
||||
// Poll
|
||||
if (meId && _note.poll && !hide) {
|
||||
if (meId && _note.poll) {
|
||||
_note.poll = (async poll => {
|
||||
const vote = await PollVote
|
||||
.findOne({
|
||||
@ -349,15 +366,8 @@ export const pack = async (
|
||||
_note.text = _note.text.replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ');
|
||||
}
|
||||
|
||||
if (hide) {
|
||||
_note.fileIds = [];
|
||||
_note.text = null;
|
||||
_note.poll = null;
|
||||
_note.cw = null;
|
||||
_note.tags = [];
|
||||
_note.tagsLower = [];
|
||||
_note.geo = null;
|
||||
_note.isHidden = true;
|
||||
if (!opts.skipHide) {
|
||||
await hideNote(_note, meId);
|
||||
}
|
||||
|
||||
return _note;
|
||||
|
@ -102,7 +102,10 @@ export interface ILocalUser extends IUserBase {
|
||||
twoFactorEnabled: boolean;
|
||||
twoFactorTempSecret?: string;
|
||||
clientSettings: any;
|
||||
settings: any;
|
||||
settings: {
|
||||
autoWatch: boolean;
|
||||
alwaysMarkNsfw?: boolean;
|
||||
};
|
||||
hasUnreadNotification: boolean;
|
||||
hasUnreadMessagingMessage: boolean;
|
||||
}
|
||||
|
@ -1,3 +1,11 @@
|
||||
export function capitalize(s: string): string {
|
||||
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
||||
return toUpperCase(s.charAt(0)) + toLowerCase(s.slice(1));
|
||||
}
|
||||
|
||||
export function toUpperCase(s: string): string {
|
||||
return s.toUpperCase();
|
||||
}
|
||||
|
||||
export function toLowerCase(s: string): string {
|
||||
return s.toLowerCase();
|
||||
}
|
||||
|
@ -4,9 +4,8 @@ import parse from '../../../mfm/parse';
|
||||
import config from '../../../config';
|
||||
|
||||
export default function(note: INote) {
|
||||
if (note.text == null) return null;
|
||||
|
||||
let html = toHtml(parse(note.text), note.mentionedRemoteUsers);
|
||||
if (html == null) html = '';
|
||||
|
||||
if (note.poll != null) {
|
||||
const url = `${config.url}/notes/${note._id}`;
|
||||
|
@ -91,7 +91,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
|
||||
const reply = note.inReplyTo ? await resolveNote(note.inReplyTo, resolver) : null;
|
||||
|
||||
// テキストのパース
|
||||
const text = htmlToMFM(note.content);
|
||||
const text = note._misskey_content ? note._misskey_content : htmlToMFM(note.content);
|
||||
|
||||
// ユーザーの情報が古かったらついでに更新しておく
|
||||
if (actor.updatedAt == null || Date.now() - actor.updatedAt.getTime() > 1000 * 60 * 60 * 24) {
|
||||
|
@ -87,6 +87,7 @@ export default async function renderNote(note: INote, dive = true): Promise<any>
|
||||
attributedTo,
|
||||
summary: note.cw,
|
||||
content: toHtml(note),
|
||||
_misskey_content_: note.text,
|
||||
published: note.createdAt.toISOString(),
|
||||
to,
|
||||
cc,
|
||||
|
@ -40,6 +40,7 @@ export interface IOrderedCollection extends IObject {
|
||||
|
||||
export interface INote extends IObject {
|
||||
type: 'Note';
|
||||
_misskey_content: string;
|
||||
}
|
||||
|
||||
export interface IPerson extends IObject {
|
||||
|
@ -105,7 +105,7 @@ export default async (ctx: Router.IRouterContext) => {
|
||||
* @param note Note
|
||||
*/
|
||||
export async function packActivity(note: INote): Promise<object> {
|
||||
if (note.renoteId && note.text == null) {
|
||||
if (note.renoteId && note.text == null && note.poll == null && (note.fileIds == null || note.fileIds.length == 0)) {
|
||||
const renote = await Note.findOne(note.renoteId);
|
||||
return renderAnnounce(renote.uri ? renote.uri : `${config.url}/notes/${renote._id}`, note);
|
||||
}
|
||||
|
@ -23,6 +23,12 @@ export const meta = {
|
||||
}
|
||||
}),
|
||||
|
||||
disableLocalTimeline: $.bool.optional.nullable.note({
|
||||
desc: {
|
||||
'ja-JP': 'ローカルタイムライン(とソーシャルタイムライン)を無効にするか否か'
|
||||
}
|
||||
}),
|
||||
|
||||
hidedTags: $.arr($.str).optional.nullable.note({
|
||||
desc: {
|
||||
'ja-JP': '統計などで無視するハッシュタグ'
|
||||
@ -45,6 +51,10 @@ export default (params: any) => new Promise(async (res, rej) => {
|
||||
set.disableRegistration = ps.disableRegistration;
|
||||
}
|
||||
|
||||
if (typeof ps.disableLocalTimeline === 'boolean') {
|
||||
set.disableLocalTimeline = ps.disableLocalTimeline;
|
||||
}
|
||||
|
||||
if (Array.isArray(ps.hidedTags)) {
|
||||
set.hidedTags = ps.hidedTags;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ export const meta = {
|
||||
}
|
||||
}),
|
||||
|
||||
isSensitive: $.bool.optional.note({
|
||||
default: false,
|
||||
isSensitive: $.bool.optional.nullable.note({
|
||||
default: null,
|
||||
desc: {
|
||||
'ja-JP': 'このメディアが「閲覧注意」(NSFW)かどうか',
|
||||
'en-US': 'Whether this media is NSFW'
|
||||
|
@ -57,7 +57,7 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
|
||||
}
|
||||
|
||||
// Create following
|
||||
create(follower, followee);
|
||||
await create(follower, followee);
|
||||
|
||||
// Send response
|
||||
res(await pack(followee._id, user));
|
||||
|
@ -57,7 +57,7 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
|
||||
}
|
||||
|
||||
// Delete following
|
||||
deleteFollowing(follower, followee);
|
||||
await deleteFollowing(follower, followee);
|
||||
|
||||
// Send response
|
||||
res(await pack(followee._id, user));
|
||||
|
@ -6,6 +6,7 @@ import acceptAllFollowRequests from '../../../../services/following/requests/acc
|
||||
import { IApp } from '../../../../models/app';
|
||||
import config from '../../../../config';
|
||||
import { publishToFollowers } from '../../../../services/i/update';
|
||||
import getParams from '../../get-params';
|
||||
|
||||
export const meta = {
|
||||
desc: {
|
||||
@ -15,75 +16,111 @@ export const meta = {
|
||||
|
||||
requireCredential: true,
|
||||
|
||||
kind: 'account-write'
|
||||
kind: 'account-write',
|
||||
|
||||
params: {
|
||||
name: $.str.optional.nullable.pipe(isValidName).note({
|
||||
desc: {
|
||||
'ja-JP': '名前(ハンドルネームやニックネーム)'
|
||||
}
|
||||
}),
|
||||
|
||||
description: $.str.optional.nullable.pipe(isValidDescription).note({
|
||||
desc: {
|
||||
'ja-JP': 'アカウントの説明や自己紹介'
|
||||
}
|
||||
}),
|
||||
|
||||
location: $.str.optional.nullable.pipe(isValidLocation).note({
|
||||
desc: {
|
||||
'ja-JP': '住んでいる地域、所在'
|
||||
}
|
||||
}),
|
||||
|
||||
birthday: $.str.optional.nullable.pipe(isValidBirthday).note({
|
||||
desc: {
|
||||
'ja-JP': '誕生日 (YYYY-MM-DD形式)'
|
||||
}
|
||||
}),
|
||||
|
||||
avatarId: $.type(ID).optional.nullable.note({
|
||||
desc: {
|
||||
'ja-JP': 'アイコンに設定する画像のドライブファイルID'
|
||||
}
|
||||
}),
|
||||
|
||||
bannerId: $.type(ID).optional.nullable.note({
|
||||
desc: {
|
||||
'ja-JP': 'バナーに設定する画像のドライブファイルID'
|
||||
}
|
||||
}),
|
||||
|
||||
wallpaperId: $.type(ID).optional.nullable.note({
|
||||
desc: {
|
||||
'ja-JP': '壁紙に設定する画像のドライブファイルID'
|
||||
}
|
||||
}),
|
||||
|
||||
isLocked: $.bool.optional.note({
|
||||
desc: {
|
||||
'ja-JP': '鍵アカウントか否か'
|
||||
}
|
||||
}),
|
||||
|
||||
isBot: $.bool.optional.note({
|
||||
desc: {
|
||||
'ja-JP': 'Botか否か'
|
||||
}
|
||||
}),
|
||||
|
||||
isCat: $.bool.optional.note({
|
||||
desc: {
|
||||
'ja-JP': '猫か否か'
|
||||
}
|
||||
}),
|
||||
|
||||
autoWatch: $.bool.optional.note({
|
||||
desc: {
|
||||
'ja-JP': '投稿の自動ウォッチをするか否か'
|
||||
}
|
||||
}),
|
||||
|
||||
alwaysMarkNsfw: $.bool.optional.note({
|
||||
desc: {
|
||||
'ja-JP': 'アップロードするメディアをデフォルトで「閲覧注意」として設定するか'
|
||||
}
|
||||
}),
|
||||
}
|
||||
};
|
||||
|
||||
export default async (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
|
||||
const [ps, psErr] = getParams(meta, params);
|
||||
if (psErr) throw psErr;
|
||||
|
||||
const isSecure = user != null && app == null;
|
||||
|
||||
const updates = {} as any;
|
||||
|
||||
// Get 'name' parameter
|
||||
const [name, nameErr] = $.str.optional.nullable.pipe(isValidName).get(params.name);
|
||||
if (nameErr) return rej('invalid name param');
|
||||
if (name) updates.name = name;
|
||||
if (ps.name !== undefined) updates.name = ps.name;
|
||||
if (ps.description !== undefined) updates.description = ps.description;
|
||||
if (ps.location !== undefined) updates['profile.location'] = ps.location;
|
||||
if (ps.birthday !== undefined) updates['profile.birthday'] = ps.birthday;
|
||||
if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
|
||||
if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
|
||||
if (ps.wallpaperId !== undefined) updates.wallpaperId = ps.wallpaperId;
|
||||
if (typeof ps.isLocked == 'boolean') updates.isLocked = ps.isLocked;
|
||||
if (typeof ps.isBot == 'boolean') updates.isBot = ps.isBot;
|
||||
if (typeof ps.isCat == 'boolean') updates.isCat = ps.isCat;
|
||||
if (typeof ps.autoWatch == 'boolean') updates['settings.autoWatch'] = ps.autoWatch;
|
||||
if (typeof ps.alwaysMarkNsfw == 'boolean') updates['settings.alwaysMarkNsfw'] = ps.alwaysMarkNsfw;
|
||||
|
||||
// Get 'description' parameter
|
||||
const [description, descriptionErr] = $.str.optional.nullable.pipe(isValidDescription).get(params.description);
|
||||
if (descriptionErr) return rej('invalid description param');
|
||||
if (description !== undefined) updates.description = description;
|
||||
|
||||
// Get 'location' parameter
|
||||
const [location, locationErr] = $.str.optional.nullable.pipe(isValidLocation).get(params.location);
|
||||
if (locationErr) return rej('invalid location param');
|
||||
if (location !== undefined) updates['profile.location'] = location;
|
||||
|
||||
// Get 'birthday' parameter
|
||||
const [birthday, birthdayErr] = $.str.optional.nullable.pipe(isValidBirthday).get(params.birthday);
|
||||
if (birthdayErr) return rej('invalid birthday param');
|
||||
if (birthday !== undefined) updates['profile.birthday'] = birthday;
|
||||
|
||||
// Get 'avatarId' parameter
|
||||
const [avatarId, avatarIdErr] = $.type(ID).optional.nullable.get(params.avatarId);
|
||||
if (avatarIdErr) return rej('invalid avatarId param');
|
||||
if (avatarId !== undefined) updates.avatarId = avatarId;
|
||||
|
||||
// Get 'bannerId' parameter
|
||||
const [bannerId, bannerIdErr] = $.type(ID).optional.nullable.get(params.bannerId);
|
||||
if (bannerIdErr) return rej('invalid bannerId param');
|
||||
if (bannerId !== undefined) updates.bannerId = bannerId;
|
||||
|
||||
// Get 'wallpaperId' parameter
|
||||
const [wallpaperId, wallpaperIdErr] = $.type(ID).optional.nullable.get(params.wallpaperId);
|
||||
if (wallpaperIdErr) return rej('invalid wallpaperId param');
|
||||
if (wallpaperId !== undefined) updates.wallpaperId = wallpaperId;
|
||||
|
||||
// Get 'isLocked' parameter
|
||||
const [isLocked, isLockedErr] = $.bool.optional.get(params.isLocked);
|
||||
if (isLockedErr) return rej('invalid isLocked param');
|
||||
if (isLocked != null) updates.isLocked = isLocked;
|
||||
|
||||
// Get 'isBot' parameter
|
||||
const [isBot, isBotErr] = $.bool.optional.get(params.isBot);
|
||||
if (isBotErr) return rej('invalid isBot param');
|
||||
if (isBot != null) updates.isBot = isBot;
|
||||
|
||||
// Get 'isCat' parameter
|
||||
const [isCat, isCatErr] = $.bool.optional.get(params.isCat);
|
||||
if (isCatErr) return rej('invalid isCat param');
|
||||
if (isCat != null) updates.isCat = isCat;
|
||||
|
||||
// Get 'autoWatch' parameter
|
||||
const [autoWatch, autoWatchErr] = $.bool.optional.get(params.autoWatch);
|
||||
if (autoWatchErr) return rej('invalid autoWatch param');
|
||||
if (autoWatch != null) updates['settings.autoWatch'] = autoWatch;
|
||||
|
||||
if (avatarId) {
|
||||
if (ps.avatarId) {
|
||||
const avatar = await DriveFile.findOne({
|
||||
_id: avatarId
|
||||
_id: ps.avatarId
|
||||
});
|
||||
|
||||
if (avatar == null) return rej('avatar not found');
|
||||
if (!avatar.contentType.startsWith('image/')) return rej('avatar not an image');
|
||||
|
||||
updates.avatarUrl = avatar.metadata.thumbnailUrl || avatar.metadata.url || `${config.drive_url}/${avatar._id}`;
|
||||
|
||||
@ -92,12 +129,13 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
|
||||
}
|
||||
}
|
||||
|
||||
if (bannerId) {
|
||||
if (ps.bannerId) {
|
||||
const banner = await DriveFile.findOne({
|
||||
_id: bannerId
|
||||
_id: ps.bannerId
|
||||
});
|
||||
|
||||
if (banner == null) return rej('banner not found');
|
||||
if (!banner.contentType.startsWith('image/')) return rej('banner not an image');
|
||||
|
||||
updates.bannerUrl = banner.metadata.url || `${config.drive_url}/${banner._id}`;
|
||||
|
||||
@ -106,13 +144,13 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
|
||||
}
|
||||
}
|
||||
|
||||
if (wallpaperId !== undefined) {
|
||||
if (wallpaperId === null) {
|
||||
if (ps.wallpaperId !== undefined) {
|
||||
if (ps.wallpaperId === null) {
|
||||
updates.wallpaperUrl = null;
|
||||
updates.wallpaperColor = null;
|
||||
} else {
|
||||
const wallpaper = await DriveFile.findOne({
|
||||
_id: wallpaperId
|
||||
_id: ps.wallpaperId
|
||||
});
|
||||
|
||||
if (wallpaper == null) return rej('wallpaper not found');
|
||||
@ -142,7 +180,7 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
|
||||
publishUserStream(user._id, 'meUpdated', iObj);
|
||||
|
||||
// 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認
|
||||
if (user.isLocked && isLocked === false) {
|
||||
if (user.isLocked && ps.isLocked === false) {
|
||||
acceptAllFollowRequests(user);
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
},
|
||||
broadcasts: meta.broadcasts,
|
||||
disableRegistration: meta.disableRegistration,
|
||||
disableLocalTimeline: meta.disableLocalTimeline,
|
||||
driveCapacityPerLocalUserMb: config.localDriveCapacityMb,
|
||||
recaptchaSitekey: config.recaptcha ? config.recaptcha.site_key : null,
|
||||
swPublickey: config.sw ? config.sw.public_key : null,
|
||||
|
@ -132,25 +132,14 @@ export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (
|
||||
let files: IDriveFile[] = [];
|
||||
const fileIds = ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null;
|
||||
if (fileIds != null) {
|
||||
// Fetch files
|
||||
// forEach だと途中でエラーなどがあっても return できないので
|
||||
// 敢えて for を使っています。
|
||||
for (const fileId of fileIds) {
|
||||
// Fetch file
|
||||
// SELECT _id
|
||||
const entity = await DriveFile.findOne({
|
||||
files = await Promise.all(fileIds.map(fileId => {
|
||||
return DriveFile.findOne({
|
||||
_id: fileId,
|
||||
'metadata.userId': user._id
|
||||
});
|
||||
}));
|
||||
|
||||
if (entity === null) {
|
||||
return rej('file not found');
|
||||
} else {
|
||||
files.push(entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
files = null;
|
||||
files = files.filter(file => file != null);
|
||||
}
|
||||
|
||||
let renote: INote = null;
|
||||
|
@ -79,9 +79,6 @@ export const meta = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get hybrid timeline of myself
|
||||
*/
|
||||
export default async (params: any, user: ILocalUser) => {
|
||||
const [ps, psErr] = getParams(meta, params);
|
||||
if (psErr) throw psErr;
|
||||
|
@ -43,6 +43,10 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
|
||||
return rej('note not found');
|
||||
}
|
||||
|
||||
if (note.deletedAt != null) {
|
||||
return rej('this not is already deleted');
|
||||
}
|
||||
|
||||
try {
|
||||
await create(user, note, ps.reaction);
|
||||
} catch (e) {
|
||||
|
@ -125,10 +125,11 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
ids.forEach(id => ps.excludeUserIds.push(id));
|
||||
}
|
||||
|
||||
let q: any = {
|
||||
const q: any = {
|
||||
$and: [{
|
||||
tagsLower: ps.tag.toLowerCase()
|
||||
}]
|
||||
}],
|
||||
deletedAt: { $exists: false }
|
||||
};
|
||||
|
||||
const push = (x: any) => q.$and.push(x);
|
||||
@ -339,7 +340,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
}
|
||||
|
||||
if (q.$and.length == 0) {
|
||||
q = {};
|
||||
delete q.$and;
|
||||
}
|
||||
|
||||
// Search notes
|
||||
|
@ -73,8 +73,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
}
|
||||
|
||||
// Serialize
|
||||
const users = await Promise.all(following.map(async f =>
|
||||
await pack(f.followerId, me, { detail: true })));
|
||||
const users = await Promise.all(following.map(f => pack(f.followerId, me, { detail: true })));
|
||||
|
||||
// Response
|
||||
res({
|
||||
|
@ -73,8 +73,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||
}
|
||||
|
||||
// Serialize
|
||||
const users = await Promise.all(following.map(async f =>
|
||||
await pack(f.followeeId, me, { detail: true })));
|
||||
const users = await Promise.all(following.map(f => pack(f.followeeId, me, { detail: true })));
|
||||
|
||||
// Response
|
||||
res({
|
||||
|
@ -36,6 +36,13 @@ export default async function(
|
||||
|
||||
// Subscribe Home stream channel
|
||||
subscriber.on(`user-stream:${user._id}`, async x => {
|
||||
// Renoteなら再pack
|
||||
if (x.type == 'note' && x.body.renoteId != null) {
|
||||
x.body.renote = await pack(x.body.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
//#region 流れてきたメッセージがミュートしているユーザーが関わるものだったら無視する
|
||||
if (x.type == 'note') {
|
||||
if (mutedUserIds.includes(x.body.userId)) {
|
||||
@ -54,13 +61,6 @@ export default async function(
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// Renoteなら再pack
|
||||
if (x.type == 'note' && x.body.renoteId != null) {
|
||||
x.body.renote = await pack(x.body.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
connection.send(JSON.stringify(x));
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,13 @@ export default async function(
|
||||
subscriber.on(`hybrid-timeline:${user._id}`, onEvent);
|
||||
|
||||
async function onEvent(note: any) {
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await pack(note.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
//#region 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
|
||||
if (mutedUserIds.indexOf(note.userId) != -1) {
|
||||
return;
|
||||
@ -31,13 +38,6 @@ export default async function(
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await pack(note.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
connection.send(JSON.stringify({
|
||||
type: 'note',
|
||||
body: note
|
||||
|
@ -16,6 +16,13 @@ export default async function(
|
||||
|
||||
// Subscribe stream
|
||||
subscriber.on('local-timeline', async note => {
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await pack(note.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
//#region 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
|
||||
if (mutedUserIds.indexOf(note.userId) != -1) {
|
||||
return;
|
||||
@ -28,13 +35,6 @@ export default async function(
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// Renoteなら再pack
|
||||
if (note.renoteId != null) {
|
||||
note.renote = await pack(note.renoteId, user, {
|
||||
detail: true
|
||||
});
|
||||
}
|
||||
|
||||
connection.send(JSON.stringify({
|
||||
type: 'note',
|
||||
body: note
|
||||
|
@ -36,8 +36,11 @@ async function save(path: string, name: string, type: string, hash: string, size
|
||||
|
||||
if (config.drive && config.drive.storage == 'minio') {
|
||||
const minio = new Minio.Client(config.drive.config);
|
||||
const key = `${config.drive.prefix}/${uuid.v4()}/${name}`;
|
||||
const thumbnailKey = `${config.drive.prefix}/${uuid.v4()}/${name}.thumbnail.jpg`;
|
||||
|
||||
const keyDir = `${config.drive.prefix}/${uuid.v4()}`;
|
||||
const key = `${keyDir}/${name}`;
|
||||
const thumbnailKeyDir = `${config.drive.prefix}/${uuid.v4()}`;
|
||||
const thumbnailKey = `${thumbnailKeyDir}/${name}.thumbnail.jpg`;
|
||||
|
||||
const baseUrl = config.drive.baseUrl
|
||||
|| `${ config.drive.config.useSSL ? 'https' : 'http' }://${ config.drive.config.endPoint }${ config.drive.config.port ? `:${config.drive.config.port}` : '' }/${ config.drive.bucket }`;
|
||||
@ -61,8 +64,8 @@ async function save(path: string, name: string, type: string, hash: string, size
|
||||
key: key,
|
||||
thumbnailKey: thumbnailKey
|
||||
},
|
||||
url: `${ baseUrl }/${ key }`,
|
||||
thumbnailUrl: thumbnail ? `${ baseUrl }/${ thumbnailKey }` : null
|
||||
url: `${ baseUrl }/${ keyDir }/${ encodeURIComponent(name) }`,
|
||||
thumbnailUrl: thumbnail ? `${ baseUrl }/${ thumbnailKeyDir }/${ encodeURIComponent(name) }.thumbnail.jpg` : null
|
||||
});
|
||||
|
||||
const file = await DriveFile.insert({
|
||||
@ -150,7 +153,7 @@ export default async function(
|
||||
isLink: boolean = false,
|
||||
url: string = null,
|
||||
uri: string = null,
|
||||
sensitive = false
|
||||
sensitive: boolean = null
|
||||
): Promise<IDriveFile> {
|
||||
// Calc md5 hash
|
||||
const calcHash = new Promise<string>((res, rej) => {
|
||||
@ -326,7 +329,13 @@ export default async function(
|
||||
properties: properties,
|
||||
withoutChunks: isLink,
|
||||
isRemote: isLink,
|
||||
isSensitive: sensitive
|
||||
isSensitive: (sensitive !== null && sensitive !== undefined)
|
||||
? sensitive
|
||||
: isLocalUser(user)
|
||||
? user.settings.alwaysMarkNsfw
|
||||
? true
|
||||
: false
|
||||
: false
|
||||
} as IMetadata;
|
||||
|
||||
if (url !== null) {
|
||||
|
@ -107,20 +107,22 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
|
||||
data.visibleUsers = erase(null, data.visibleUsers);
|
||||
}
|
||||
|
||||
// リプライ対象が削除された投稿だったらreject
|
||||
if (data.reply && data.reply.deletedAt != null) {
|
||||
return rej();
|
||||
}
|
||||
|
||||
// Renote対象が削除された投稿だったらreject
|
||||
if (data.renote && data.renote.deletedAt != null) {
|
||||
return rej();
|
||||
}
|
||||
|
||||
// リプライ先が自分以外の非公開の投稿なら禁止
|
||||
// リプライ対象が自分以外の非公開の投稿なら禁止
|
||||
if (data.reply && data.reply.visibility == 'private' && !data.reply.userId.equals(user._id)) {
|
||||
return rej();
|
||||
}
|
||||
|
||||
// Renote先が自分以外の非公開の投稿なら禁止
|
||||
// Renote対象が自分以外の非公開の投稿なら禁止
|
||||
if (data.renote && data.renote.visibility == 'private' && !data.renote.userId.equals(user._id)) {
|
||||
return rej();
|
||||
}
|
||||
@ -182,7 +184,7 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
|
||||
|
||||
const noteActivity = await renderActivity(data, note);
|
||||
|
||||
if (isLocalUser(user)) {
|
||||
if (isLocalUser(user) && note.visibility != 'private') {
|
||||
deliverNoteToMentionedRemoteUsers(mentionedUsers, user, noteActivity);
|
||||
}
|
||||
|
||||
@ -239,7 +241,7 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
|
||||
});
|
||||
|
||||
async function renderActivity(data: Option, note: INote) {
|
||||
const content = data.renote && data.text == null
|
||||
const content = data.renote && data.text == null && data.poll == null && (data.files == null || data.files.length == 0)
|
||||
? renderAnnounce(data.renote.uri ? data.renote.uri : `${config.url}/notes/${data.renote._id}`, note)
|
||||
: renderCreate(await renderNote(note, false), note);
|
||||
|
||||
@ -267,10 +269,12 @@ async function publish(user: IUser, note: INote, noteObj: any, reply: INote, ren
|
||||
}
|
||||
|
||||
if (['private', 'followers', 'specified'].includes(note.visibility)) {
|
||||
// Publish event to myself's stream
|
||||
publishUserStream(note.userId, 'note', await pack(note, user, {
|
||||
const detailPackedNote = await pack(note, user, {
|
||||
detail: true
|
||||
}));
|
||||
});
|
||||
// Publish event to myself's stream
|
||||
publishUserStream(note.userId, 'note', detailPackedNote);
|
||||
publishHybridTimelineStream(note.userId, detailPackedNote);
|
||||
} else {
|
||||
// Publish event to myself's stream
|
||||
publishUserStream(note.userId, 'note', noteObj);
|
||||
@ -282,6 +286,9 @@ async function publish(user: IUser, note: INote, noteObj: any, reply: INote, ren
|
||||
|
||||
if (note.visibility == 'public') {
|
||||
publishHybridTimelineStream(null, noteObj);
|
||||
} else {
|
||||
// Publish event to myself's stream
|
||||
publishHybridTimelineStream(note.userId, noteObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -442,6 +449,11 @@ async function publishToUserLists(note: INote, noteObj: any) {
|
||||
}
|
||||
|
||||
async function publishToFollowers(note: INote, noteObj: any, user: IUser, noteActivity: any) {
|
||||
const detailPackedNote = await pack(note, null, {
|
||||
detail: true,
|
||||
skipHide: true
|
||||
});
|
||||
|
||||
const followers = await Following.find({
|
||||
followeeId: note.userId
|
||||
});
|
||||
@ -460,10 +472,10 @@ async function publishToFollowers(note: INote, noteObj: any, user: IUser, noteAc
|
||||
}
|
||||
|
||||
// Publish event to followers stream
|
||||
publishUserStream(following.followerId, 'note', noteObj);
|
||||
publishUserStream(following.followerId, 'note', detailPackedNote);
|
||||
|
||||
if (isRemoteUser(user) || note.visibility != 'public') {
|
||||
publishHybridTimelineStream(following.followerId, noteObj);
|
||||
publishHybridTimelineStream(following.followerId, detailPackedNote);
|
||||
}
|
||||
} else {
|
||||
// フォロワーがリモートユーザーかつ投稿者がローカルユーザーなら投稿を配信
|
||||
|
@ -25,7 +25,8 @@ export default async function(user: IUser, note: INote) {
|
||||
tags: [],
|
||||
fileIds: [],
|
||||
poll: null,
|
||||
geo: null
|
||||
geo: null,
|
||||
cw: null
|
||||
}
|
||||
});
|
||||
|
||||
|
135
src/stream.ts
135
src/stream.ts
@ -1,58 +1,97 @@
|
||||
import * as mongo from 'mongodb';
|
||||
import Xev from 'xev';
|
||||
|
||||
const ev = new Xev();
|
||||
import Meta, { IMeta } from './models/meta';
|
||||
|
||||
type ID = string | mongo.ObjectID;
|
||||
|
||||
function publish(channel: string, type: string, value?: any): void {
|
||||
const message = type == null ? value : value == null ?
|
||||
{ type: type } :
|
||||
{ type: type, body: value };
|
||||
class Publisher {
|
||||
private ev: Xev;
|
||||
private meta: IMeta;
|
||||
|
||||
ev.emit(channel, message);
|
||||
constructor() {
|
||||
this.ev = new Xev();
|
||||
|
||||
setInterval(async () => {
|
||||
this.meta = await Meta.findOne({});
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
public getMeta = async () => {
|
||||
if (this.meta != null) return this.meta;
|
||||
|
||||
this.meta = await Meta.findOne({});
|
||||
return this.meta;
|
||||
}
|
||||
|
||||
private publish = (channel: string, type: string, value?: any): void => {
|
||||
const message = type == null ? value : value == null ?
|
||||
{ type: type } :
|
||||
{ type: type, body: value };
|
||||
|
||||
this.ev.emit(channel, message);
|
||||
}
|
||||
|
||||
public publishUserStream = (userId: ID, type: string, value?: any): void => {
|
||||
this.publish(`user-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishDriveStream = (userId: ID, type: string, value?: any): void => {
|
||||
this.publish(`drive-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishNoteStream = (noteId: ID, type: string): void => {
|
||||
this.publish(`note-stream:${noteId}`, null, noteId);
|
||||
}
|
||||
|
||||
public publishUserListStream = (listId: ID, type: string, value?: any): void => {
|
||||
this.publish(`user-list-stream:${listId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishMessagingStream = (userId: ID, otherpartyId: ID, type: string, value?: any): void => {
|
||||
this.publish(`messaging-stream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishMessagingIndexStream = (userId: ID, type: string, value?: any): void => {
|
||||
this.publish(`messaging-index-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishReversiStream = (userId: ID, type: string, value?: any): void => {
|
||||
this.publish(`reversi-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishReversiGameStream = (gameId: ID, type: string, value?: any): void => {
|
||||
this.publish(`reversi-game-stream:${gameId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
public publishLocalTimelineStream = async (note: any): Promise<void> => {
|
||||
const meta = await this.getMeta();
|
||||
if (meta.disableLocalTimeline) return;
|
||||
this.publish('local-timeline', null, note);
|
||||
}
|
||||
|
||||
public publishHybridTimelineStream = async (userId: ID, note: any): Promise<void> => {
|
||||
const meta = await this.getMeta();
|
||||
if (meta.disableLocalTimeline) return;
|
||||
this.publish(userId ? `hybrid-timeline:${userId}` : 'hybrid-timeline', null, note);
|
||||
}
|
||||
|
||||
public publishGlobalTimelineStream = (note: any): void => {
|
||||
this.publish('global-timeline', null, note);
|
||||
}
|
||||
}
|
||||
|
||||
export function publishUserStream(userId: ID, type: string, value?: any): void {
|
||||
publish(`user-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
const publisher = new Publisher();
|
||||
|
||||
export function publishDriveStream(userId: ID, type: string, value?: any): void {
|
||||
publish(`drive-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
export default publisher;
|
||||
|
||||
export function publishNoteStream(noteId: ID, type: string): void {
|
||||
publish(`note-stream:${noteId}`, null, noteId);
|
||||
}
|
||||
|
||||
export function publishUserListStream(listId: ID, type: string, value?: any): void {
|
||||
publish(`user-list-stream:${listId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
export function publishMessagingStream(userId: ID, otherpartyId: ID, type: string, value?: any): void {
|
||||
publish(`messaging-stream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
export function publishMessagingIndexStream(userId: ID, type: string, value?: any): void {
|
||||
publish(`messaging-index-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
export function publishReversiStream(userId: ID, type: string, value?: any): void {
|
||||
publish(`reversi-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
export function publishReversiGameStream(gameId: ID, type: string, value?: any): void {
|
||||
publish(`reversi-game-stream:${gameId}`, type, typeof value === 'undefined' ? null : value);
|
||||
}
|
||||
|
||||
export function publishLocalTimelineStream(note: any): void {
|
||||
publish('local-timeline', null, note);
|
||||
}
|
||||
|
||||
export function publishHybridTimelineStream(userId: ID, note: any): void {
|
||||
publish(userId ? `hybrid-timeline:${userId}` : 'hybrid-timeline', null, note);
|
||||
}
|
||||
|
||||
export function publishGlobalTimelineStream(note: any): void {
|
||||
publish('global-timeline', null, note);
|
||||
}
|
||||
export const publishUserStream = publisher.publishUserStream;
|
||||
export const publishDriveStream = publisher.publishDriveStream;
|
||||
export const publishNoteStream = publisher.publishNoteStream;
|
||||
export const publishUserListStream = publisher.publishUserListStream;
|
||||
export const publishMessagingStream = publisher.publishMessagingStream;
|
||||
export const publishMessagingIndexStream = publisher.publishMessagingIndexStream;
|
||||
export const publishReversiStream = publisher.publishReversiStream;
|
||||
export const publishReversiGameStream = publisher.publishReversiGameStream;
|
||||
export const publishLocalTimelineStream = publisher.publishLocalTimelineStream;
|
||||
export const publishHybridTimelineStream = publisher.publishHybridTimelineStream;
|
||||
export const publishGlobalTimelineStream = publisher.publishGlobalTimelineStream;
|
||||
|
Reference in New Issue
Block a user