Compare commits
185 Commits
Author | SHA1 | Date | |
---|---|---|---|
95ce8dce3d | |||
0b5eec4ca8 | |||
6d9716f90e | |||
aa31061d90 | |||
acc7797dff | |||
7959196dc7 | |||
c6ff6939a5 | |||
769960f29e | |||
d92e9759f3 | |||
bf7e19b288 | |||
98954cd6d4 | |||
538bb978ed | |||
10232c5866 | |||
5cd6a0db16 | |||
ff0a05a2d6 | |||
e34b264af2 | |||
00d79487cd | |||
3cace734c7 | |||
f428372869 | |||
5dd2feba9b | |||
a1b026239e | |||
40735ce76b | |||
4a00c13b33 | |||
8e359d54bd | |||
2448bf4e4e | |||
91e0fc8c62 | |||
b4f86feddb | |||
ccf8e44acc | |||
451acb77df | |||
e2c6227f47 | |||
ebd1c877ad | |||
498094b3c7 | |||
1cc183ecdb | |||
e8948452fd | |||
ade7e62836 | |||
395cfa6108 | |||
b5ff2abdb9 | |||
229e85b2c5 | |||
37058e3480 | |||
a1b82e9723 | |||
db943df0c8 | |||
ff8d300ea8 | |||
8b490b9b94 | |||
f83f8631ac | |||
1915ccabdd | |||
6fea2f52f1 | |||
f77eaaa08a | |||
7c5bc03492 | |||
72a1af6cd4 | |||
4bce6f14f3 | |||
a38ce86f87 | |||
f539491502 | |||
d279f8e9ff | |||
eaec936fa6 | |||
a0735b0e7a | |||
5b039a1bee | |||
921609cab1 | |||
199573ccee | |||
977200b7cd | |||
6abff253ea | |||
ba64de334a | |||
dc1d7fa9d7 | |||
f42665d4bc | |||
a5eb19c878 | |||
60fa8e13d6 | |||
ecbaea463b | |||
814ddeb436 | |||
d6466106e8 | |||
633f5384f9 | |||
fa7989772c | |||
0e395612a6 | |||
fb3f52f3ad | |||
ba11c71d65 | |||
bdc3081167 | |||
430efcf1b9 | |||
996450dd7c | |||
fa779f0417 | |||
25cec6d28a | |||
c5f8403cea | |||
a9ae9a65c8 | |||
3698c679e2 | |||
881df20f1b | |||
7d269c0441 | |||
ba38f64353 | |||
db3ae303cb | |||
66f3a155e6 | |||
639b483e6c | |||
09843a409b | |||
e894ed5a8b | |||
d7808299fd | |||
f92e0c16d2 | |||
d94b3757be | |||
13e822cba6 | |||
c57bf87f52 | |||
99fbd60265 | |||
ea9b48db3c | |||
c145c994a9 | |||
d033998b56 | |||
3136c714bf | |||
c0ee134f19 | |||
d15ebe5732 | |||
ef630195fa | |||
e31921151e | |||
f94992abbe | |||
b00060c09c | |||
f6217d96d2 | |||
3a6947c7ed | |||
0fb528ddf8 | |||
14c03f226d | |||
4f0d844b43 | |||
b93395fc4c | |||
34eacb7e2d | |||
0177023ead | |||
a4678e45de | |||
f24869625e | |||
01beb705a2 | |||
ce28c70c35 | |||
5e0f5c31e7 | |||
b28dd4be52 | |||
291beb45fc | |||
ffb345ccb5 | |||
d2abe2cd81 | |||
acffc3e522 | |||
0962e62b8c | |||
91ebd310b7 | |||
2974c74b4e | |||
3d24112d2d | |||
4a977cd523 | |||
4b1886990f | |||
f3499b787c | |||
5209a584a2 | |||
57a63d38aa | |||
3efffbcf22 | |||
15eaebe522 | |||
eee98358ac | |||
795fc5e7bc | |||
70ac668474 | |||
1004e0d6e8 | |||
52aa64fcb6 | |||
7860d97a10 | |||
409b37b271 | |||
ad9b9964fa | |||
d2b5276f43 | |||
7204e2a84c | |||
1377fa3332 | |||
bf087bfccf | |||
e846e3d571 | |||
d646e62888 | |||
c008154d18 | |||
29bd4de26a | |||
7559b8da6c | |||
35218e84fc | |||
2c135fa2f6 | |||
21da6bd047 | |||
f1d65a66b4 | |||
63e2dbbb0d | |||
a228c522f1 | |||
a951c337b8 | |||
db3efb3791 | |||
5f9a9867eb | |||
059a8e07d2 | |||
cf82f56e66 | |||
2778bd14d4 | |||
5b0446739c | |||
55f235d0ac | |||
4ec44c68e9 | |||
e6952d499a | |||
e0b82f827b | |||
0bccb17e82 | |||
b251b8c6a9 | |||
c2a62f632b | |||
37b5afa1a3 | |||
b80d0a3b12 | |||
9f60688d37 | |||
ca0ea9e57c | |||
a77a7e8112 | |||
b26ea2edc0 | |||
02b99dfd76 | |||
af02b0f115 | |||
9b3c379678 | |||
a423fd7695 | |||
de6e1d8c9b | |||
d9db3e8629 | |||
ac1c81b7d6 | |||
49b2eec534 |
@ -1,18 +1,19 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# BEARER_TOKEN=
|
# __MISSKEY_BEARER_TOKEN=
|
||||||
# CAMPAIGN_ID=
|
# __MISSKEY_CAMPAIGN_ID=
|
||||||
# GITHUB_TOKEN=
|
# __MISSKEY_GITHUB_TOKEN=
|
||||||
# HEAD='acid-chicken:patch-autogen'
|
# __MISSKEY_HEAD=acid-chicken:patch-autogen
|
||||||
# REPO='syuilo/misskey'
|
# __MISSKEY_REPO=syuilo/misskey
|
||||||
test "$(curl -LSs -w '\n' -- "https://api.github.com/repos/$REPO/pulls?access_token=$GITHUB_TOKEN" | jq -r '.[].head.label' | grep $HEAD)" && exit 1
|
# __MISSKEY_BRANCH=develop
|
||||||
|
test "$(curl -LSs -w '\n' -- "https://api.github.com/repos/$REPO/pulls?access_token=$__MISSKEY_GITHUB_TOKEN" | jq -r '.[].head.label' | grep $__MISSKEY_HEAD)" && exit 1
|
||||||
cd "$(dirname $0)/.." && \
|
cd "$(dirname $0)/.." && \
|
||||||
touch null.cache && \
|
touch null.cache && \
|
||||||
rm *.cache && \
|
rm *.cache && \
|
||||||
git checkout master && \
|
git checkout $__MISSKEY_BRANCH && \
|
||||||
git pull origin master && \
|
git pull origin $__MISSKEY_BRANCH && \
|
||||||
git pull upstream master && \
|
git pull upstream $__MISSKEY_BRANCH && \
|
||||||
git stash && \
|
git stash && \
|
||||||
git rebase -f upstream/master && \
|
git rebase -f upstream/$__MISSKEY_BRANCH && \
|
||||||
git branch patch-autogen && \
|
git branch patch-autogen && \
|
||||||
git checkout patch-autogen && \
|
git checkout patch-autogen && \
|
||||||
git reset --hard HEAD || \
|
git reset --hard HEAD || \
|
||||||
@ -20,12 +21,12 @@ exit 1
|
|||||||
touch patreon.md.cache && \
|
touch patreon.md.cache && \
|
||||||
rm patreon.md.cache && \
|
rm patreon.md.cache && \
|
||||||
echo '<!-- PATREON_START -->' > patreon.md.cache && \
|
echo '<!-- PATREON_START -->' > patreon.md.cache && \
|
||||||
URL="https://www.patreon.com/api/oauth2/v2/campaigns/$CAMPAIGN_ID/members?include=currently_entitled_tiers,user&fields%5Btier%5D=title&fields%5Buser%5D=full_name,thumb_url,url,hide_pledges"
|
url="https://www.patreon.com/api/oauth2/v2/campaigns/$__MISSKEY_CAMPAIGN_ID/members?include=currently_entitled_tiers,user&fields%5Btier%5D=title&fields%5Buser%5D=full_name,thumb_url,url,hide_pledges"
|
||||||
while :
|
while :
|
||||||
do
|
do
|
||||||
touch patreon.raw.cache && \
|
touch patreon.raw.cache && \
|
||||||
rm patreon.raw.cache && \
|
rm patreon.raw.cache && \
|
||||||
curl -LSs -w '\n' -H "Authorization: Bearer $BEARER_TOKEN" -- $URL > patreon.raw.cache && \
|
curl -LSs -w '\n' -H "Authorization: Bearer $__MISSKEY_BEARER_TOKEN" -- $url > patreon.raw.cache && \
|
||||||
touch patreon.cache && \
|
touch patreon.cache && \
|
||||||
rm patreon.cache && \
|
rm patreon.cache && \
|
||||||
cat patreon.raw.cache | \
|
cat patreon.raw.cache | \
|
||||||
@ -42,31 +43,31 @@ while :
|
|||||||
xargs -I% echo '<td><a href="%</a></td>' >> patreon.md.cache && \
|
xargs -I% echo '<td><a href="%</a></td>' >> patreon.md.cache && \
|
||||||
echo '</tr></table>' >> patreon.md.cache || \
|
echo '</tr></table>' >> patreon.md.cache || \
|
||||||
exit 1
|
exit 1
|
||||||
NEW_URL="$(cat patreon.raw.cache | jq -r '.links.next')"
|
new_url="$(cat patreon.raw.cache | jq -r '.links.next')"
|
||||||
test "$NEW_URL" = 'null' && \
|
test "$new_url" = 'null' && \
|
||||||
break || \
|
break || \
|
||||||
URL="$NEW_URL"
|
URL="$url"
|
||||||
done
|
done
|
||||||
IGNORE= && \
|
ignore= && \
|
||||||
echo -e "\n**Last updated:** $(date -uR | sed 's/\+0000/UTC/')\n<!-- PATREON_END -->" >> patreon.md.cache && \
|
echo -e "\n**Last updated:** $(date -uR | sed 's/\+0000/UTC/')\n<!-- PATREON_END -->" >> patreon.md.cache && \
|
||||||
touch README.md && \
|
touch README.md && \
|
||||||
touch .autogen/README.md && \
|
touch .autogen/README.md && \
|
||||||
rm .autogen/README.md && \
|
rm .autogen/README.md && \
|
||||||
mv README.md .autogen/README.md && \
|
mv README.md .autogen/README.md && \
|
||||||
cat .autogen/README.md | while IFS= read LINE;
|
cat .autogen/README.md | while IFS= read line;
|
||||||
do
|
do
|
||||||
if [[ -z "$IGNORE" ]]
|
if [[ -z "$ignore" ]]
|
||||||
then
|
then
|
||||||
if [[ "$LINE" = '<!-- PATREON_START -->' ]]
|
if [[ "$line" = '<!-- PATREON_START -->' ]]
|
||||||
then
|
then
|
||||||
IGNORE='PATREON_INSIDE'
|
ignore='PATREON_INSIDE'
|
||||||
else
|
else
|
||||||
echo "$LINE" >> README.md
|
echo "$line" >> README.md
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ "$LINE" = '<!-- PATREON_END -->' ]]
|
if [[ "$LINE" = '<!-- PATREON_END -->' ]]
|
||||||
then
|
then
|
||||||
IGNORE=
|
ignore=
|
||||||
cat patreon.md.cache >> README.md
|
cat patreon.md.cache >> README.md
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -80,7 +81,7 @@ test 4 -lt $(cat diff.cache | wc -l) && \
|
|||||||
git add README.md && \
|
git add README.md && \
|
||||||
git commit -m 'Update README.md [AUTOGEN]' && \
|
git commit -m 'Update README.md [AUTOGEN]' && \
|
||||||
git push -f origin patch-autogen && \
|
git push -f origin patch-autogen && \
|
||||||
curl -LSs -w '\n' -X POST -d '{"title":"[AUTOMATED] Update README.md","body":"*This pull request was created by a tool.*","head":"'$HEAD'","base":"master"}' -- "https://api.github.com/repos/$REPO/pulls?access_token=$GITHUB_TOKEN"
|
curl -LSs -w '\n' -X POST -d '{"title":"[AUTOMATED] Update README.md","body":"*This pull request was created by a tool.*","head":"'$__MISSKEY_HEAD'","base":"'$__MISSKEY_BRANCH'"}' -- "https://api.github.com/repos/$__MISSKEY_REPO/pulls?access_token=$__MISSKEY_GITHUB_TOKEN"
|
||||||
git stash
|
git stash
|
||||||
git checkout master
|
git checkout $__MISSKEY_BRANCH
|
||||||
git branch -D patch-autogen
|
git branch -D patch-autogen
|
||||||
|
2
.npmrc
2
.npmrc
@ -1,2 +1,2 @@
|
|||||||
save-exact=true
|
save-exact = true
|
||||||
package-lock = false
|
package-lock = false
|
||||||
|
@ -47,13 +47,13 @@ Please run `node cli/migration/5.0.0` before launch.
|
|||||||
|
|
||||||
オセロがリバーシに変更されました。
|
オセロがリバーシに変更されました。
|
||||||
|
|
||||||
Othello is now Reversi.
|
Othello is rename to Reversi.
|
||||||
|
|
||||||
### Migration
|
### Migration
|
||||||
|
|
||||||
MongoDBの、`othelloGames`と`othelloMatchings`コレクションをそれぞれ`reversiGames`と`reversiMatchings`にリネームしてください。
|
MongoDBの、`othelloGames`と`othelloMatchings`コレクションをそれぞれ`reversiGames`と`reversiMatchings`にリネームしてください。
|
||||||
|
|
||||||
You need to rename `othelloGames` and `othelloMatchings` MongoDB collections to `reversiGames` and `reversiMatchings`.
|
Please rename `othelloGames` and `othelloMatchings` MongoDB collections to `reversiGames` and `reversiMatchings` respectively.
|
||||||
|
|
||||||
3.0.0
|
3.0.0
|
||||||
-----
|
-----
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
# Contribution guide
|
# Contribution guide
|
||||||
:v: Misskeyへの貢献ありがとうございます。 :v:
|
:v: Thanks for your contributions :v:
|
||||||
|
|
||||||
## Issueの報告
|
## Issues
|
||||||
新機能の提案や不具合の報告は https://github.com/syuilo/misskey/issues で管理しています。
|
Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues .
|
||||||
Issueを作成する前に、既に同じIssueが作成されていないかご確認ください。
|
Before creating a new issue, please search existing issues to avoid duplication.
|
||||||
もし既にIssueが作成されている場合は、既存のIssueにコメントをしたりリアクションをするようお願いします。
|
If you find the existing issue, please add your reaction or comment to the issue.
|
||||||
|
|
||||||
## Issueの解決
|
## Internationalization (i18n)
|
||||||
[pr-welcomeのラベルがついているIssue](https://github.com/syuilo/misskey/labels/pr-welcome)
|
Please see [Translation guide](./docs/translate.en.md).
|
||||||
の解決を目的としたPull Requestを作成してくださると非常にありがたいです。
|
|
||||||
|
|
||||||
## 翻訳の改善
|
## Localization (l10n)
|
||||||
ソースコード中の `%i18n:id%` という形の文字列は、言語ファイルの対応するテキストに置換されます。
|
Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
|
||||||
言語ファイルは /locales ディレクトリに存在します。
|
|
||||||
|
|
||||||
## ドキュメントの編集
|

|
||||||
現在Misskeyはドキュメントが大きく不足しています。
|
|
||||||
ドキュメントは /docs ディレクトリに存在します。
|
|
||||||
|
|
||||||
## テストの追加
|
## Documentation
|
||||||
現在Misskeyはテストが大きく不足しています。
|
* Documents for contributors are located in `/docs`.
|
||||||
テストコードは /test ディレクトリに存在します。
|
* Documents for instance admins are located in `/docs`.
|
||||||
|
* Documents for end users are located in `src/docs`.
|
||||||
|
|
||||||
## 自動テスト及び自動リリース
|
## Test
|
||||||
Travis CIで行っています。
|
* Test codes are located in `/test`.
|
||||||
設定ファイルは /.travis に存在します。
|
|
||||||
|
## Continuous integration
|
||||||
|
Misskey uses Travis for automated test.
|
||||||
|
Configuration files are located in `/.travis`.
|
||||||
|
29
README.md
29
README.md
@ -24,7 +24,7 @@ Why don't you take a short break from the hustle and bustle of the city, and div
|
|||||||
* Reactions
|
* Reactions
|
||||||
* User lists
|
* User lists
|
||||||
* Customizable column view (called MisskeyDeck)
|
* Customizable column view (called MisskeyDeck)
|
||||||
* and widgets!
|
* Customizable widgets
|
||||||
* Private messages
|
* Private messages
|
||||||
* ActivityPub support
|
* ActivityPub support
|
||||||
|
|
||||||
@ -32,38 +32,25 @@ and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz
|
|||||||
|
|
||||||
:package: Create your own instance
|
:package: Create your own instance
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
If you want to run your own instance of Misskey,
|
Please see [Setup and installation guide](./docs/setup.en.md).
|
||||||
please see [Setup and installation guide](./docs/setup.en.md).
|
|
||||||
|
|
||||||
:wrench: Contribute
|
:wrench: Contribution
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
**[PR](https://github.com/syuilo/misskey/pulls)s welcome!**
|
Please see [Contribution guide](./CONTRIBUTING.md).
|
||||||
|
|
||||||
### i18n
|
|
||||||
|
|
||||||
Please see [Translation guide](./docs/translate.en.md).
|
|
||||||
|
|
||||||
### l10n
|
|
||||||
|
|
||||||
Misskey is using Crowdin for l10n.
|
|
||||||
|
|
||||||
[](https://crowdin.com/project/misskey)
|
|
||||||
|
|
||||||
:heart: Backers & Sponsors
|
:heart: Backers & Sponsors
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
<!-- PATREON_START -->
|
<!-- PATREON_START -->
|
||||||
<table><tr>
|
<table><tr>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12378075/0156f769e20f412594fa6b87d85fe228/1?token-time=2145916800&token-hash=IsIJRUXszzoD6-7pDnRY8I05T9nSznc4GTaxj7C9SwU%3D" alt="39ff"></td>
|
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=Yd60FK_SWfQO56SeiJpy1tDHOnCV4xdEywQe8gn5_Wo%3D" alt="negao"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=Yd60FK_SWfQO56SeiJpy1tDHOnCV4xdEywQe8gn5_Wo%3D" alt="negao"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13099460/43cecdbaa63a40d79bf50a96b9910b9d/1?token-time=2145916800&token-hash=d6P5MWHHsCMxUuBAEPAoVc5wLUR19mIhqAq7Ma9h9rI%3D" alt="ne_moni"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13099460/43cecdbaa63a40d79bf50a96b9910b9d/1?token-time=2145916800&token-hash=d6P5MWHHsCMxUuBAEPAoVc5wLUR19mIhqAq7Ma9h9rI%3D" alt="ne_moni"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/1?token-time=2145916800&token-hash=f03BFb4S2FUx9YEt87TnEmifb4h33OywGBW2akQVtQY%3D" alt="Melilot"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/1?token-time=2145916800&token-hash=f03BFb4S2FUx9YEt87TnEmifb4h33OywGBW2akQVtQY%3D" alt="Melilot"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/1?token-time=2145916800&token-hash=DVrSdOqQq2dufgNgWZ3XMnEtl_ZAktr8Lhf2tbHKtoA%3D" alt="Axella"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/2?token-time=2145916800&token-hash=rwZ8qvbm_kpA4ib3kc07tVKupXeySpY5ATQFGxfL9v0%3D" alt="Axella"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=0eu4-m1gTWA9PhptVZt6rdKcusqcD7RB87rJT23VVFI%3D" alt="べすれい"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=0eu4-m1gTWA9PhptVZt6rdKcusqcD7RB87rJT23VVFI%3D" alt="べすれい"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=GgJ_NmUB6_nnRNLVGUWjV-WX91On7BOu59LKncYV9fE%3D" alt="gutfuckllc"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=GgJ_NmUB6_nnRNLVGUWjV-WX91On7BOu59LKncYV9fE%3D" alt="gutfuckllc"></td>
|
||||||
<td><img src="https://c8.patreon.com/2/100/12718187" alt="Peter G."></td>
|
<td><img src="https://c8.patreon.com/2/100/12718187" alt="Peter G."></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=zwSu01tOtn5xTUucDZHuPsCxF2HBEMVs9ROJKTlEV_o%3D" alt="nemu"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=zwSu01tOtn5xTUucDZHuPsCxF2HBEMVs9ROJKTlEV_o%3D" alt="nemu"></td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><a href="https://www.patreon.com/user?u=12378075">39ff</a></td>
|
|
||||||
<td><a href="https://www.patreon.com/user?u=12731202">negao</a></td>
|
<td><a href="https://www.patreon.com/user?u=12731202">negao</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=13099460">ne_moni</a></td>
|
<td><a href="https://www.patreon.com/user?u=13099460">ne_moni</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
||||||
@ -78,20 +65,16 @@ Misskey is using Crowdin for l10n.
|
|||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12931605/ead494101f364dffa90efe49e36fb494/1?token-time=2145916800&token-hash=NzSFPjIlodXyv41rwK61aZWVZWfI4surJaNj8vWKvqM%3D" alt="Reiju"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12931605/ead494101f364dffa90efe49e36fb494/1?token-time=2145916800&token-hash=NzSFPjIlodXyv41rwK61aZWVZWfI4surJaNj8vWKvqM%3D" alt="Reiju"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=UERBN4OyP7Nh5XwwdDg0N0IE5cD6_qUQMO81Z5Wizso%3D" alt="Hiratake"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=UERBN4OyP7Nh5XwwdDg0N0IE5cD6_qUQMO81Z5Wizso%3D" alt="Hiratake"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=S1zP0QyLU52Dqq6dtc9qNYyWfW86XrYHiR4NMbeOrnA%3D" alt="dansup"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=S1zP0QyLU52Dqq6dtc9qNYyWfW86XrYHiR4NMbeOrnA%3D" alt="dansup"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/4950409/28e7d016209243759d9316be2e21381d/2?token-time=2145916800&token-hash=LuEaDkchH3GQWUcTOhBQ8xfKQYF0s5FjlZRd7Yduia8%3D" alt="mikan54951"></td>
|
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1?token-time=2145916800&token-hash=tMosUojzUYJCH_3t--tvYA-SMCyrS__hzSndyaRSnbo%3D" alt="Takashi Shibuya"></td>
|
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1?token-time=2145916800&token-hash=tMosUojzUYJCH_3t--tvYA-SMCyrS__hzSndyaRSnbo%3D" alt="Takashi Shibuya"></td>
|
||||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12959468/c249e15aebec4424b5c0f427173671b6/1?token-time=2145916800&token-hash=lubpCEdxAkxPlpR2O6bvZ7BIh8Q4nGf-U_mE1qpjVAQ%3D" alt="fujishan"></td>
|
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><a href="https://www.patreon.com/user?u=5881381">Naoki Kosaka</a></td>
|
<td><a href="https://www.patreon.com/user?u=5881381">Naoki Kosaka</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=12931605">Reiju</a></td>
|
<td><a href="https://www.patreon.com/user?u=12931605">Reiju</a></td>
|
||||||
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
|
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
|
||||||
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
|
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
|
||||||
<td><a href="https://www.patreon.com/user?u=4950409">mikan54951</a></td>
|
|
||||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||||
<td><a href="https://www.patreon.com/fujishan">fujishan</a></td>
|
|
||||||
</tr></table>
|
</tr></table>
|
||||||
|
|
||||||
**Last updated:** Sun, 26 Aug 2018 08:55:06 UTC
|
**Last updated:** Sun, 02 Sep 2018 05:30:06 UTC
|
||||||
<!-- PATREON_END -->
|
<!-- PATREON_END -->
|
||||||
|
|
||||||
:four_leaf_clover: Copyright
|
:four_leaf_clover: Copyright
|
||||||
|
@ -54,7 +54,7 @@ Please visit https://www.google.com/recaptcha/intro/ and generate keys.
|
|||||||
|
|
||||||
*(optional)* Generating VAPID keys
|
*(optional)* Generating VAPID keys
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
If you want to enable ServiceWroker, you need to generate VAPID keys:
|
If you want to enable ServiceWorker, you need to generate VAPID keys:
|
||||||
Unless you have set your global node_modules location elsewhere, you need to run this in root.
|
Unless you have set your global node_modules location elsewhere, you need to run this in root.
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
@ -131,6 +131,7 @@ You can check if the service is running with `systemctl status misskey`.
|
|||||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||||
3. `npm install`
|
3. `npm install`
|
||||||
4. `npm run build`
|
4. `npm run build`
|
||||||
|
5. Check [ChangeLog](../CHANGELOG.md) for migration information
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ WantedBy=multi-user.target
|
|||||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||||
3. `npm install`
|
3. `npm install`
|
||||||
4. `npm run build`
|
4. `npm run build`
|
||||||
|
5. [ChangeLog](../CHANGELOG.md)でマイグレーション情報を確認する
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
# **Please DO NOT edit these files** except `ja-JP.yml`.
|
# **DO NOT edit locale files** except `ja-JP.yml`.
|
||||||
|
|
||||||
If you want to...
|
Please see [Contribution guide](../CONTRIBUTING.md) for more information.
|
||||||
* i18n ... please see [Translation guide](../docs/translate.en.md).
|
|
||||||
* l10n ... please visit https://crowdin.com/project/misskey
|
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "引き分け"
|
drawn: "引き分け"
|
||||||
my-turn: "あなたのターンです"
|
my-turn: "あなたのターンです"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "削除"
|
delete: "削除"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "引き分け"
|
drawn: "引き分け"
|
||||||
my-turn: "あなたのターンです"
|
my-turn: "あなたのターンです"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "Entwickler"
|
develop: "Entwickler"
|
||||||
feedback: "Feedback"
|
feedback: "Feedback"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "Diese Anmerkung favorisieren"
|
favorite: "Diese Anmerkung favorisieren"
|
||||||
pin: "An die Profilseite pinnen"
|
pin: "An die Profilseite pinnen"
|
||||||
delete: "Löschen"
|
delete: "Löschen"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "Direkt"
|
specified: "Direkt"
|
||||||
specified-desc: "Poste nur für bestimmte Benutzer"
|
specified-desc: "Poste nur für bestimmte Benutzer"
|
||||||
private: "Privat"
|
private: "Privat"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "Laden"
|
fetching: "Laden"
|
||||||
no-broadcasts: "Keine Broadcasts"
|
no-broadcasts: "Keine Broadcasts"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Serverinformationen"
|
title: "Serverinformationen"
|
||||||
toggle: "Sicht umschalten"
|
toggle: "Sicht umschalten"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -84,9 +84,10 @@ common:
|
|||||||
my-token-regenerated: "Your token has been regenerated, so you will be signed out."
|
my-token-regenerated: "Your token has been regenerated, so you will be signed out."
|
||||||
i-like-sushi: "I prefer sushi rather than pudding"
|
i-like-sushi: "I prefer sushi rather than pudding"
|
||||||
show-reversi-board-labels: "Show row and column labels in Reversi"
|
show-reversi-board-labels: "Show row and column labels in Reversi"
|
||||||
use-contrast-reversi-stones: "Make the stone color clear"
|
use-contrast-reversi-stones: "Make the stone color clear in reversi"
|
||||||
verified-user: "Verified account"
|
verified-user: "Verified account"
|
||||||
disable-animated-mfm: "Disable animated texts in a post"
|
disable-animated-mfm: "Disable animated texts in a post"
|
||||||
|
do-not-use-in-production: 'As this is for development, do not use this in production.'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "Draw"
|
drawn: "Draw"
|
||||||
my-turn: "Your turn"
|
my-turn: "Your turn"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "Developers"
|
develop: "Developers"
|
||||||
feedback: "Feedback"
|
feedback: "Feedback"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "Details"
|
||||||
|
copy-link: "Copy link"
|
||||||
favorite: "Favorite this note"
|
favorite: "Favorite this note"
|
||||||
pin: "Pin to your profile"
|
pin: "Pin to your profile"
|
||||||
delete: "Delete"
|
delete: "Delete"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "Direct"
|
specified: "Direct"
|
||||||
specified-desc: "Post to specified users only"
|
specified-desc: "Post to specified users only"
|
||||||
private: "Private"
|
private: "Private"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{} users mentioned"
|
||||||
|
empty: "No popular hashtag trends"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "Fetching"
|
fetching: "Fetching"
|
||||||
no-broadcasts: "No announcements"
|
no-broadcasts: "No announcements"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "Toggle views"
|
toggle: "Toggle views"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "Hashtags"
|
title: "Hashtags"
|
||||||
count: "{} users mentioned"
|
|
||||||
empty: "No popular hashtag trends"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Server info"
|
title: "Server info"
|
||||||
toggle: "Toggle views"
|
toggle: "Toggle views"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "Logging in..."
|
signin-button: "Logging in..."
|
||||||
signup-button: "Sign up"
|
signup-button: "Sign up"
|
||||||
timeline: "Timeline"
|
timeline: "Timeline"
|
||||||
|
announcements: "Announcements"
|
||||||
|
photos: "Recent uploaded"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey storage"
|
title: "Misskey storage"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "Post design"
|
post-style: "Post design"
|
||||||
post-style-standard: "Standard"
|
post-style-standard: "Standard"
|
||||||
post-style-smart: "Smart"
|
post-style-smart: "Smart"
|
||||||
|
notification-position: "Notification style"
|
||||||
|
notification-position-bottom: "Bottom"
|
||||||
|
notification-position-top: "Top"
|
||||||
behavior: "Behavior"
|
behavior: "Behavior"
|
||||||
fetch-on-scroll: "Endless loading on scroll"
|
fetch-on-scroll: "Endless loading on scroll"
|
||||||
disable-via-mobile: "Don't mark the post as 'from mobile'"
|
disable-via-mobile: "Don't mark the post as 'from mobile'"
|
||||||
|
@ -11,7 +11,7 @@ common:
|
|||||||
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."
|
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."
|
||||||
application-authorization: "Autorizaciones de la aplicación."
|
application-authorization: "Autorizaciones de la aplicación."
|
||||||
close: "Cerrar"
|
close: "Cerrar"
|
||||||
do-not-copy-paste: "ここにコードを入力したり張り付けたりしないでください。アカウントが不正利用される可能性があります。"
|
do-not-copy-paste: "Por favor no copies código aquí. Tu cuenta puede resultar comprometida."
|
||||||
got-it: "¡Listo!"
|
got-it: "¡Listo!"
|
||||||
customization-tips:
|
customization-tips:
|
||||||
title: "Consejos de personalización"
|
title: "Consejos de personalización"
|
||||||
@ -58,7 +58,7 @@ common:
|
|||||||
friday: "Viernes"
|
friday: "Viernes"
|
||||||
saturday: "Sábado"
|
saturday: "Sábado"
|
||||||
reactions:
|
reactions:
|
||||||
like: "いいね"
|
like: "Me gusta"
|
||||||
love: "amor"
|
love: "amor"
|
||||||
laugh: "risa"
|
laugh: "risa"
|
||||||
hmm: "hmm"
|
hmm: "hmm"
|
||||||
@ -84,9 +84,10 @@ common:
|
|||||||
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
|
my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado."
|
||||||
i-like-sushi: "Prefiero sushi a pudín"
|
i-like-sushi: "Prefiero sushi a pudín"
|
||||||
show-reversi-board-labels: "Mostrar etiquetas de filas y columnas en Reversi"
|
show-reversi-board-labels: "Mostrar etiquetas de filas y columnas en Reversi"
|
||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "Hacer el color de la piedra claro en Reversi"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "Cuenta verificada"
|
||||||
disable-animated-mfm: "Desactivar texto animado en una publicación"
|
disable-animated-mfm: "Desactivar texto animado en una publicación"
|
||||||
|
do-not-use-in-production: 'Esto está en desarrollo, no usarlo para producción.'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "Empatado"
|
drawn: "Empatado"
|
||||||
my-turn: "Mi turno"
|
my-turn: "Mi turno"
|
||||||
@ -170,9 +171,9 @@ common/views/components/games/reversi/reversi.vue:
|
|||||||
common/views/components/games/reversi/reversi.game.vue:
|
common/views/components/games/reversi/reversi.game.vue:
|
||||||
surrender: "Rendirse"
|
surrender: "Rendirse"
|
||||||
surrendered: "Por rendirse"
|
surrendered: "Por rendirse"
|
||||||
is-llotheo: "石の少ない方が勝ち(ロセオ)"
|
is-llotheo: "El último gana (Llotheo)"
|
||||||
looped-map: "ループマップ"
|
looped-map: "Mapa en bucle"
|
||||||
can-put-everywhere: "どこでも置けるモード"
|
can-put-everywhere: "Puedes colocar donde quieras"
|
||||||
common/views/components/games/reversi/reversi.index.vue:
|
common/views/components/games/reversi/reversi.index.vue:
|
||||||
title: "Misskey Reversi"
|
title: "Misskey Reversi"
|
||||||
sub-title: "¡Juega Reversi con tus amigos!"
|
sub-title: "¡Juega Reversi con tus amigos!"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "Desarrolladores"
|
develop: "Desarrolladores"
|
||||||
feedback: "Opiniones"
|
feedback: "Opiniones"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "Detalles"
|
||||||
|
copy-link: "Copiar enlace"
|
||||||
favorite: "Me gusta esta nota"
|
favorite: "Me gusta esta nota"
|
||||||
pin: "Fijar en el perfil"
|
pin: "Fijar en el perfil"
|
||||||
delete: "Borrar"
|
delete: "Borrar"
|
||||||
@ -288,10 +291,10 @@ common/views/components/signin.vue:
|
|||||||
signin: "Entra"
|
signin: "Entra"
|
||||||
or: "O"
|
or: "O"
|
||||||
signin-with-twitter: "Ingresar con Twitter"
|
signin-with-twitter: "Ingresar con Twitter"
|
||||||
login-failed: "ログインできませんでした。ユーザー名とパスワードを確認してください。"
|
login-failed: "Autenticación fallida. Asegúrate de haber usado el nombre de usuario y contraseña correctos."
|
||||||
common/views/components/signup.vue:
|
common/views/components/signup.vue:
|
||||||
invitation-code: "招待コード"
|
invitation-code: "Código de invitación"
|
||||||
invitation-info: "招待コードをお持ちでない方は、<a href=\"{}\">管理者</a>までご連絡ください。"
|
invitation-info: "Si no tienes un código de invitación, por favor contacta un <a href=\"{}\">administrador</a>."
|
||||||
username: "Usuario"
|
username: "Usuario"
|
||||||
checking: "Comprobando..."
|
checking: "Comprobando..."
|
||||||
available: "Disponible"
|
available: "Disponible"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "Directo"
|
specified: "Directo"
|
||||||
specified-desc: "Publica solo para los seguidores que quieras"
|
specified-desc: "Publica solo para los seguidores que quieras"
|
||||||
private: "Privada"
|
private: "Privada"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "Recuperando"
|
fetching: "Recuperando"
|
||||||
no-broadcasts: "Sin emisión"
|
no-broadcasts: "Sin emisión"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "Alternar vistas"
|
toggle: "Alternar vistas"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "Etiquetas"
|
title: "Etiquetas"
|
||||||
count: "{} usuarios mencionados"
|
|
||||||
empty: "Ninguna tendencia popular ahora"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Información del servidor"
|
title: "Información del servidor"
|
||||||
toggle: "Alternar vistas"
|
toggle: "Alternar vistas"
|
||||||
@ -411,7 +415,7 @@ desktop:
|
|||||||
uploading-avatar: "Cargando un nuevo avatar"
|
uploading-avatar: "Cargando un nuevo avatar"
|
||||||
avatar-updated: "Avatar actualizado"
|
avatar-updated: "Avatar actualizado"
|
||||||
choose-avatar: "Escoge una imagen de avatar"
|
choose-avatar: "Escoge una imagen de avatar"
|
||||||
invalid-filetype: "この形式のファイルはサポートされていません"
|
invalid-filetype: "Este tipo de archivo no es compatible aquí"
|
||||||
desktop/views/components/activity.chart.vue:
|
desktop/views/components/activity.chart.vue:
|
||||||
total: "Negro ... Total"
|
total: "Negro ... Total"
|
||||||
notes: "Azul ... Notas"
|
notes: "Azul ... Notas"
|
||||||
@ -426,23 +430,23 @@ desktop/views/components/calendar.vue:
|
|||||||
next: "Próximo mes"
|
next: "Próximo mes"
|
||||||
go: "Click para navegar"
|
go: "Click para navegar"
|
||||||
desktop/views/components/charts.vue:
|
desktop/views/components/charts.vue:
|
||||||
title: "チャート"
|
title: "Gráficos"
|
||||||
per-day: "1日ごと"
|
per-day: "por día"
|
||||||
per-hour: "1時間ごと"
|
per-hour: "por hora"
|
||||||
notes: "投稿"
|
notes: "Publicaciones"
|
||||||
users: "ユーザー"
|
users: "Usuarios"
|
||||||
drive: "ドライブ"
|
drive: "Unidad"
|
||||||
charts:
|
charts:
|
||||||
notes: "投稿の増減 (統合)"
|
notes: "Número de publicaciones: aumentar/disminuir (Combinado)"
|
||||||
local-notes: "投稿の増減 (ローカル)"
|
local-notes: "Número de publicaciones: aumentar/disminuir (Local)"
|
||||||
remote-notes: "投稿の増減 (リモート)"
|
remote-notes: "Número de publicaciones: aumentar/disminuir (Remoto)"
|
||||||
notes-total: "投稿の累計"
|
notes-total: "Número de publicaciones: Acumulativo total"
|
||||||
users: "ユーザーの増減"
|
users: "Número de usuarios: aumentar/disminuir"
|
||||||
users-total: "ユーザーの累計"
|
users-total: "Número de usuarios: Acumulativo total"
|
||||||
drive: "ドライブ使用量の増減"
|
drive: "Capacidad de almacenamiento usada: aumentar/disminuir"
|
||||||
drive-total: "ドライブ使用量の累計"
|
drive-total: "Capacidad de almacenamiento usada: Acumulativa total"
|
||||||
drive-files: "ドライブのファイル数の増減"
|
drive-files: "Número de archivos almacenados: aumentar/disminuir"
|
||||||
drive-files-total: "ドライブのファイル数の累計"
|
drive-files-total: "Número de archivos almacenados: Acumulativo total"
|
||||||
desktop/views/components/choose-file-from-drive-window.vue:
|
desktop/views/components/choose-file-from-drive-window.vue:
|
||||||
choose-file: "Escoger archivos"
|
choose-file: "Escoger archivos"
|
||||||
upload: "Cargar archivos de tu dispositivo"
|
upload: "Cargar archivos de tu dispositivo"
|
||||||
@ -463,7 +467,7 @@ desktop/views/components/drive-window.vue:
|
|||||||
desktop/views/components/drive.file.vue:
|
desktop/views/components/drive.file.vue:
|
||||||
avatar: "Avatar"
|
avatar: "Avatar"
|
||||||
banner: "Banner"
|
banner: "Banner"
|
||||||
nsfw: "閲覧注意"
|
nsfw: "Ver más"
|
||||||
contextmenu:
|
contextmenu:
|
||||||
rename: "Renombrar"
|
rename: "Renombrar"
|
||||||
mark-as-sensitive: "Marcar como 'sensible'"
|
mark-as-sensitive: "Marcar como 'sensible'"
|
||||||
@ -515,31 +519,31 @@ desktop/views/components/media-image.vue:
|
|||||||
sensitive: "El contenido es NSFW (no seguro para ver en el trabajo, 'not safe for work')"
|
sensitive: "El contenido es NSFW (no seguro para ver en el trabajo, 'not safe for work')"
|
||||||
click-to-show: "Click para mostrar"
|
click-to-show: "Click para mostrar"
|
||||||
desktop/views/components/media-video.vue:
|
desktop/views/components/media-video.vue:
|
||||||
sensitive: "閲覧注意"
|
sensitive: "Este contenido no es apropiado para ver en el trabajo"
|
||||||
click-to-show: "クリックして表示"
|
click-to-show: "Click para mostrar"
|
||||||
desktop/views/components/follow-button.vue:
|
desktop/views/components/follow-button.vue:
|
||||||
following: "Siguiendo"
|
following: "Siguiendo"
|
||||||
follow: "Sigue"
|
follow: "Sigue"
|
||||||
request-pending: "Pendiente de aprobación"
|
request-pending: "Pendiente de aprobación"
|
||||||
follow-request: "フォロー申請"
|
follow-request: "Solicitud de seguir"
|
||||||
desktop/views/components/followers-window.vue:
|
desktop/views/components/followers-window.vue:
|
||||||
followers: "{} のフォロワー"
|
followers: "{} seguidores"
|
||||||
desktop/views/components/followers.vue:
|
desktop/views/components/followers.vue:
|
||||||
empty: "フォロワーはいないようです。"
|
empty: "Parece que no tienes seguidores aún."
|
||||||
desktop/views/components/following-window.vue:
|
desktop/views/components/following-window.vue:
|
||||||
following: "{} のフォロー"
|
following: "Siguiendo {}"
|
||||||
desktop/views/components/following.vue:
|
desktop/views/components/following.vue:
|
||||||
empty: "フォロー中のユーザーはいないようです。"
|
empty: "Parece que aún no sigues a nadie."
|
||||||
desktop/views/components/friends-maker.vue:
|
desktop/views/components/friends-maker.vue:
|
||||||
title: "気になるユーザーをフォロー:"
|
title: "Usuarios recomendados:"
|
||||||
empty: "おすすめのユーザーは見つかりませんでした。"
|
empty: "No se pudieron encontrar usuarios para recomendar"
|
||||||
fetching: "読み込んでいます"
|
fetching: "Cargando"
|
||||||
refresh: "もっと見る"
|
refresh: "Más"
|
||||||
close: "閉じる"
|
close: "Cerrar"
|
||||||
desktop/views/components/game-window.vue:
|
desktop/views/components/game-window.vue:
|
||||||
game: "リバーシ"
|
game: "Reversi"
|
||||||
desktop/views/components/home.vue:
|
desktop/views/components/home.vue:
|
||||||
done: "完了"
|
done: "Listo"
|
||||||
add-widget: "Agregar accesorio:"
|
add-widget: "Agregar accesorio:"
|
||||||
add: "Agregar"
|
add: "Agregar"
|
||||||
desktop/views/input-dialog.vue:
|
desktop/views/input-dialog.vue:
|
||||||
@ -565,8 +569,8 @@ desktop/views/components/notes.note.vue:
|
|||||||
detail: "Mostrar detalles"
|
detail: "Mostrar detalles"
|
||||||
private: "Esta publicación es privada"
|
private: "Esta publicación es privada"
|
||||||
deleted: "Esta publicación ha sido borrada"
|
deleted: "Esta publicación ha sido borrada"
|
||||||
hide: "隠す"
|
hide: "Esconder"
|
||||||
see-more: "もっと見る"
|
see-more: "Ver más"
|
||||||
desktop/views/components/notes.vue:
|
desktop/views/components/notes.vue:
|
||||||
error: "Error al cargar."
|
error: "Error al cargar."
|
||||||
retry: "Reintentar"
|
retry: "Reintentar"
|
||||||
@ -602,7 +606,7 @@ desktop/views/components/post-form.vue:
|
|||||||
geolocation-alert: "Tu dispositivo no tiene soporte de geolocalización."
|
geolocation-alert: "Tu dispositivo no tiene soporte de geolocalización."
|
||||||
error: "Error"
|
error: "Error"
|
||||||
enter-username: "Por favor escribe un nombre de usuario..."
|
enter-username: "Por favor escribe un nombre de usuario..."
|
||||||
annotations: "内容への注釈 (オプション)"
|
annotations: "Anotaciones a la publicación (opcional)"
|
||||||
desktop/views/components/post-form-window.vue:
|
desktop/views/components/post-form-window.vue:
|
||||||
note: "Nota nueva"
|
note: "Nota nueva"
|
||||||
reply: "Responder"
|
reply: "Responder"
|
||||||
@ -766,40 +770,40 @@ desktop/views/components/timeline.vue:
|
|||||||
global: "グローバル"
|
global: "グローバル"
|
||||||
list: "リスト"
|
list: "リスト"
|
||||||
desktop/views/components/ui.header.vue:
|
desktop/views/components/ui.header.vue:
|
||||||
welcome-back: "おかえりなさい、"
|
welcome-back: "Bienvenido/a de vuelta,"
|
||||||
adjective: "さん"
|
adjective: "-san"
|
||||||
desktop/views/components/ui.header.account.vue:
|
desktop/views/components/ui.header.account.vue:
|
||||||
profile: "プロフィール"
|
profile: "Tu perfil"
|
||||||
drive: "ドライブ"
|
drive: "Unidad"
|
||||||
favorites: "お気に入り"
|
favorites: "Favoritos"
|
||||||
lists: "リスト"
|
lists: "Listas"
|
||||||
follow-requests: "フォロー申請"
|
follow-requests: "Solicitudes de seguimiento"
|
||||||
customize: "ホームのカスタマイズ"
|
customize: "Personalizar la página de inicio"
|
||||||
admin: "管理"
|
admin: "Admin"
|
||||||
settings: "設定"
|
settings: "Configuraciones"
|
||||||
signout: "サインアウト"
|
signout: "Desconectarse"
|
||||||
dark: "闇に飲まれる"
|
dark: "Sumergirse en la oscuridad"
|
||||||
desktop/views/components/ui.header.nav.vue:
|
desktop/views/components/ui.header.nav.vue:
|
||||||
home: "ホーム"
|
home: "Inicio"
|
||||||
deck: "デッキ"
|
deck: "Cubierta"
|
||||||
messaging: "メッセージ"
|
messaging: "Mensajes"
|
||||||
game: "ゲーム"
|
game: "Juegos"
|
||||||
desktop/views/components/ui.header.notifications.vue:
|
desktop/views/components/ui.header.notifications.vue:
|
||||||
title: "通知"
|
title: "Notificaciones"
|
||||||
desktop/views/components/ui.header.post.vue:
|
desktop/views/components/ui.header.post.vue:
|
||||||
post: "新規投稿"
|
post: "Crear una publicación"
|
||||||
desktop/views/components/ui.header.search.vue:
|
desktop/views/components/ui.header.search.vue:
|
||||||
placeholder: "検索"
|
placeholder: "Buscar"
|
||||||
desktop/views/components/received-follow-requests-window.vue:
|
desktop/views/components/received-follow-requests-window.vue:
|
||||||
title: "フォロー申請"
|
title: "Solicitudes de seguidores"
|
||||||
accept: "承認"
|
accept: "Aceptar"
|
||||||
reject: "拒否"
|
reject: "Rechazar"
|
||||||
desktop/views/components/user-lists-window.vue:
|
desktop/views/components/user-lists-window.vue:
|
||||||
title: "リスト"
|
title: "Listas de usuario"
|
||||||
create-list: "リストを作成"
|
create-list: "Crear lista"
|
||||||
list-name: "リスト名"
|
list-name: "Nombre de lista"
|
||||||
desktop/views/components/user-preview.vue:
|
desktop/views/components/user-preview.vue:
|
||||||
notes: "投稿"
|
notes: "Publicaciones"
|
||||||
following: "フォロー"
|
following: "フォロー"
|
||||||
followers: "フォロワー"
|
followers: "フォロワー"
|
||||||
desktop/views/components/users-list.vue:
|
desktop/views/components/users-list.vue:
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "Compte vérifié"
|
verified-user: "Compte vérifié"
|
||||||
disable-animated-mfm: "Désactiver les textes animés dans les publications"
|
disable-animated-mfm: "Désactiver les textes animés dans les publications"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "Partie nulle"
|
drawn: "Partie nulle"
|
||||||
my-turn: "C’est votre tour"
|
my-turn: "C’est votre tour"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "Développeur·se·s"
|
develop: "Développeur·se·s"
|
||||||
feedback: "Remarques"
|
feedback: "Remarques"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "Mettre cette note en favoris"
|
favorite: "Mettre cette note en favoris"
|
||||||
pin: "Épingler sur votre profil"
|
pin: "Épingler sur votre profil"
|
||||||
delete: "Supprimer"
|
delete: "Supprimer"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "Direct"
|
specified: "Direct"
|
||||||
specified-desc: "Publier aux utilisateur·rice·s mentionné·e·s"
|
specified-desc: "Publier aux utilisateur·rice·s mentionné·e·s"
|
||||||
private: "Privé"
|
private: "Privé"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "Récupération"
|
fetching: "Récupération"
|
||||||
no-broadcasts: "Aucune annonce"
|
no-broadcasts: "Aucune annonce"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "Basculer entre les vues"
|
toggle: "Basculer entre les vues"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "Étiquettes"
|
title: "Étiquettes"
|
||||||
count: "{} utilisateur·rice·s mentionné·e·s"
|
|
||||||
empty: "Aucune tendance"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Informations sur le serveur"
|
title: "Informations sur le serveur"
|
||||||
toggle: "Afficher les vues"
|
toggle: "Afficher les vues"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "Se connecter"
|
signin-button: "Se connecter"
|
||||||
signup-button: "S'inscrire"
|
signup-button: "S'inscrire"
|
||||||
timeline: "Fil d'actualité"
|
timeline: "Fil d'actualité"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Propulsé par <b>Misskey</b>."
|
powered-by-misskey: "Propulsé par <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Lecteur de Misskey"
|
title: "Lecteur de Misskey"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "Style de la publication"
|
post-style: "Style de la publication"
|
||||||
post-style-standard: "Standard"
|
post-style-standard: "Standard"
|
||||||
post-style-smart: "Intelligent"
|
post-style-smart: "Intelligent"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "Comportement"
|
behavior: "Comportement"
|
||||||
fetch-on-scroll: "Chargement lors du défilement"
|
fetch-on-scroll: "Chargement lors du défilement"
|
||||||
disable-via-mobile: "Ne pas mentionner que ma publication provient d'un 'périphérique mobile'"
|
disable-via-mobile: "Ne pas mentionner que ma publication provient d'un 'périphérique mobile'"
|
||||||
|
@ -5,24 +5,9 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
|
|
||||||
const loadLang = lang => yaml.safeLoad(
|
const langs = ['de-DE', 'en-US', 'fr-FR', 'ja-JP', 'ja-KS', 'pl-PL', 'es-ES', 'nl-NL'];
|
||||||
fs.readFileSync(`${__dirname}/${lang}.yml`, 'utf-8'));
|
|
||||||
|
|
||||||
const native = loadLang('ja-JP');
|
const loadLocale = lang => yaml.safeLoad(fs.readFileSync(`${__dirname}/${lang}.yml`, 'utf-8'));
|
||||||
|
const locales = langs.map(lang => ({ [lang]: loadLocale(lang) }));
|
||||||
|
|
||||||
const langs = {
|
module.exports = locales.reduce((a, b) => ({ ...a, ...b }));
|
||||||
'de-DE': loadLang('de-DE'),
|
|
||||||
'en-US': loadLang('en-US'),
|
|
||||||
'fr-FR': loadLang('fr-FR'),
|
|
||||||
'ja-JP': native,
|
|
||||||
'ja-KS': loadLang('ja-KS'),
|
|
||||||
'pl-PL': loadLang('pl-PL'),
|
|
||||||
'es-ES': loadLang('es-ES')
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.values(langs).forEach(locale => {
|
|
||||||
// Extend native language (Japanese)
|
|
||||||
locale = Object.assign({}, native, locale);
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = langs;
|
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "引き分け"
|
drawn: "引き分け"
|
||||||
my-turn: "あなたのターンです"
|
my-turn: "あなたのターンです"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "削除"
|
delete: "削除"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -375,6 +375,10 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
|
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -403,8 +407,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
|
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
@ -988,6 +990,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
|
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
@ -1353,6 +1357,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストをつけんで!"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストをつけんで!"
|
||||||
verified-user: "アメちゃん付きアカウント"
|
verified-user: "アメちゃん付きアカウント"
|
||||||
disable-animated-mfm: "投稿内のちょろちょろ動いてんのを止める"
|
disable-animated-mfm: "投稿内のちょろちょろ動いてんのを止める"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "おあいこ"
|
drawn: "おあいこ"
|
||||||
my-turn: "あんさんのターンや"
|
my-turn: "あんさんのターンや"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "ほかす"
|
delete: "ほかす"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはあらへんで"
|
no-broadcasts: "お知らせはあらへんで"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "流行は自分で作るんや"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "サインイン中…"
|
signin-button: "サインイン中…"
|
||||||
signup-button: "サインアップ"
|
signup-button: "サインアップ"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "ドライブ"
|
title: "ドライブ"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "べっぴんさん"
|
post-style-smart: "べっぴんさん"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "게시물의 문자 애니메이션을 비활성화 할"
|
disable-animated-mfm: "게시물의 문자 애니메이션을 비활성화 할"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "무승부"
|
drawn: "무승부"
|
||||||
my-turn: "당신의 차례입니다"
|
my-turn: "당신의 차례입니다"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "削除"
|
delete: "削除"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
1246
locales/nl-NL.yml
Normal file
1246
locales/nl-NL.yml
Normal file
File diff suppressed because it is too large
Load Diff
1246
locales/no-NO.yml
Normal file
1246
locales/no-NO.yml
Normal file
File diff suppressed because it is too large
Load Diff
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "Wyłącz animowany tekst we wpisach"
|
disable-animated-mfm: "Wyłącz animowany tekst we wpisach"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "Remis"
|
drawn: "Remis"
|
||||||
my-turn: "Twoja kolej"
|
my-turn: "Twoja kolej"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "Autorzy"
|
develop: "Autorzy"
|
||||||
feedback: "Podziel się opinią"
|
feedback: "Podziel się opinią"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "Dodaj do ulubionych"
|
favorite: "Dodaj do ulubionych"
|
||||||
pin: "Przypnij do profilu"
|
pin: "Przypnij do profilu"
|
||||||
delete: "Usuń"
|
delete: "Usuń"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "Bezpośredni"
|
specified: "Bezpośredni"
|
||||||
specified-desc: "Tylko dla określonych użytkowników"
|
specified-desc: "Tylko dla określonych użytkowników"
|
||||||
private: "Prywatny"
|
private: "Prywatny"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "Sprawdzanie"
|
fetching: "Sprawdzanie"
|
||||||
no-broadcasts: "Brak transmisji"
|
no-broadcasts: "Brak transmisji"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "Przełącz widok"
|
toggle: "Przełącz widok"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "Hashtagi"
|
title: "Hashtagi"
|
||||||
count: "Wspomniany przez {} użytkowników"
|
|
||||||
empty: "Brak popularnych hashtagów"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "Informacje o serwerze"
|
title: "Informacje o serwerze"
|
||||||
toggle: "Przełącz widok"
|
toggle: "Przełącz widok"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "Zaloguj się"
|
signin-button: "Zaloguj się"
|
||||||
signup-button: "Zarejestruj się"
|
signup-button: "Zarejestruj się"
|
||||||
timeline: "Oś czasu"
|
timeline: "Oś czasu"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Oparto o <b>Misskey</b>."
|
powered-by-misskey: "Oparto o <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Dysk Misskey"
|
title: "Dysk Misskey"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "Styl wpisów"
|
post-style: "Styl wpisów"
|
||||||
post-style-standard: "Standardowy"
|
post-style-standard: "Standardowy"
|
||||||
post-style-smart: "Inteligentny"
|
post-style-smart: "Inteligentny"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "Zachowanie"
|
behavior: "Zachowanie"
|
||||||
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół"
|
||||||
disable-via-mobile: "Nie oznaczaj wpisów jako „wysłane z telefonu”"
|
disable-via-mobile: "Nie oznaczaj wpisów jako „wysłane z telefonu”"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "Conta verificada"
|
verified-user: "Conta verificada"
|
||||||
disable-animated-mfm: "Desativar texto animado nas publicações"
|
disable-animated-mfm: "Desativar texto animado nas publicações"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "Empatado"
|
drawn: "Empatado"
|
||||||
my-turn: "Seu turno"
|
my-turn: "Seu turno"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "削除"
|
delete: "削除"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "Timeline"
|
timeline: "Timeline"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Desenvolvido por <b>Misskey</b>."
|
powered-by-misskey: "Desenvolvido por <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Drive Misskey"
|
title: "Drive Misskey"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "引き分け"
|
drawn: "引き分け"
|
||||||
my-turn: "あなたのターンです"
|
my-turn: "あなたのターンです"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "削除"
|
delete: "削除"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
@ -87,6 +87,7 @@ common:
|
|||||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||||
verified-user: "公式アカウント"
|
verified-user: "公式アカウント"
|
||||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||||
|
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||||
reversi:
|
reversi:
|
||||||
drawn: "引き分け"
|
drawn: "引き分け"
|
||||||
my-turn: "あなたのターンです"
|
my-turn: "あなたのターンです"
|
||||||
@ -260,6 +261,8 @@ common/views/components/nav.vue:
|
|||||||
develop: "開発者"
|
develop: "開発者"
|
||||||
feedback: "フィードバック"
|
feedback: "フィードバック"
|
||||||
common/views/components/note-menu.vue:
|
common/views/components/note-menu.vue:
|
||||||
|
detail: "詳細"
|
||||||
|
copy-link: "リンクをコピー"
|
||||||
favorite: "お気に入り"
|
favorite: "お気に入り"
|
||||||
pin: "ピン留め"
|
pin: "ピン留め"
|
||||||
delete: "削除"
|
delete: "削除"
|
||||||
@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue:
|
|||||||
specified: "ダイレクト"
|
specified: "ダイレクト"
|
||||||
specified-desc: "指定したユーザーにのみ公開"
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
private: "非公開"
|
private: "非公開"
|
||||||
|
common/views/components/trends.vue:
|
||||||
|
count: "{}人が投稿"
|
||||||
|
empty: "トレンドなし"
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue:
|
|||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
common/views/widgets/hashtags.vue:
|
common/views/widgets/hashtags.vue:
|
||||||
title: "ハッシュタグ"
|
title: "ハッシュタグ"
|
||||||
count: "{}人が投稿"
|
|
||||||
empty: "トレンドなし"
|
|
||||||
common/views/widgets/server.vue:
|
common/views/widgets/server.vue:
|
||||||
title: "サーバー情報"
|
title: "サーバー情報"
|
||||||
toggle: "表示を切り替え"
|
toggle: "表示を切り替え"
|
||||||
@ -861,6 +865,8 @@ desktop/views/pages/welcome.vue:
|
|||||||
signin-button: "やってる"
|
signin-button: "やってる"
|
||||||
signup-button: "やる"
|
signup-button: "やる"
|
||||||
timeline: "タイムライン"
|
timeline: "タイムライン"
|
||||||
|
announcements: "お知らせ"
|
||||||
|
photos: "最近の画像"
|
||||||
powered-by-misskey: "Powered by <b>Misskey</b>."
|
powered-by-misskey: "Powered by <b>Misskey</b>."
|
||||||
desktop/views/pages/drive.vue:
|
desktop/views/pages/drive.vue:
|
||||||
title: "Misskey Drive"
|
title: "Misskey Drive"
|
||||||
@ -1157,6 +1163,9 @@ mobile/views/pages/settings.vue:
|
|||||||
post-style: "投稿の表示スタイル"
|
post-style: "投稿の表示スタイル"
|
||||||
post-style-standard: "標準"
|
post-style-standard: "標準"
|
||||||
post-style-smart: "スマート"
|
post-style-smart: "スマート"
|
||||||
|
notification-position: "通知の表示"
|
||||||
|
notification-position-bottom: "下"
|
||||||
|
notification-position-top: "上"
|
||||||
behavior: "動作"
|
behavior: "動作"
|
||||||
fetch-on-scroll: "スクロールで自動読み込み"
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
17
package.json
17
package.json
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "8.19.0",
|
"version": "8.28.1",
|
||||||
"clientVersion": "1.0.9217",
|
"clientVersion": "1.0.9400",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"@types/koa-send": "4.1.1",
|
"@types/koa-send": "4.1.1",
|
||||||
"@types/koa-views": "2.0.3",
|
"@types/koa-views": "2.0.3",
|
||||||
"@types/koa__cors": "2.2.3",
|
"@types/koa__cors": "2.2.3",
|
||||||
"@types/minio": "6.0.2",
|
"@types/minio": "7.0.0",
|
||||||
"@types/mkdirp": "0.5.2",
|
"@types/mkdirp": "0.5.2",
|
||||||
"@types/mocha": "5.2.3",
|
"@types/mocha": "5.2.3",
|
||||||
"@types/mongodb": "3.1.4",
|
"@types/mongodb": "3.1.4",
|
||||||
@ -80,7 +80,7 @@
|
|||||||
"@types/webpack": "4.4.11",
|
"@types/webpack": "4.4.11",
|
||||||
"@types/webpack-stream": "3.2.10",
|
"@types/webpack-stream": "3.2.10",
|
||||||
"@types/websocket": "0.0.40",
|
"@types/websocket": "0.0.40",
|
||||||
"@types/ws": "6.0.0",
|
"@types/ws": "6.0.1",
|
||||||
"animejs": "2.2.0",
|
"animejs": "2.2.0",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
@ -161,7 +161,7 @@
|
|||||||
"nan": "2.11.0",
|
"nan": "2.11.0",
|
||||||
"nested-property": "0.0.7",
|
"nested-property": "0.0.7",
|
||||||
"node-sass": "4.9.3",
|
"node-sass": "4.9.3",
|
||||||
"node-sass-json-importer": "3.3.1",
|
"node-sass-json-importer": "4.0.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"object-assign-deep": "0.4.0",
|
"object-assign-deep": "0.4.0",
|
||||||
"on-build-webpack": "0.1.0",
|
"on-build-webpack": "0.1.0",
|
||||||
@ -194,7 +194,7 @@
|
|||||||
"stylus": "0.54.5",
|
"stylus": "0.54.5",
|
||||||
"stylus-loader": "3.0.2",
|
"stylus-loader": "3.0.2",
|
||||||
"summaly": "2.2.0",
|
"summaly": "2.2.0",
|
||||||
"systeminformation": "3.44.2",
|
"systeminformation": "3.45.1",
|
||||||
"syuilo-password-strength": "0.0.1",
|
"syuilo-password-strength": "0.0.1",
|
||||||
"textarea-caret": "3.1.0",
|
"textarea-caret": "3.1.0",
|
||||||
"tmp": "0.0.33",
|
"tmp": "0.0.33",
|
||||||
@ -210,19 +210,18 @@
|
|||||||
"vue": "2.5.17",
|
"vue": "2.5.17",
|
||||||
"vue-chartjs": "3.4.0",
|
"vue-chartjs": "3.4.0",
|
||||||
"vue-cropperjs": "2.2.1",
|
"vue-cropperjs": "2.2.1",
|
||||||
"vue-js-modal": "1.3.24",
|
"vue-js-modal": "1.3.26",
|
||||||
"vue-json-tree-view": "2.1.4",
|
"vue-json-tree-view": "2.1.4",
|
||||||
"vue-loader": "15.4.1",
|
"vue-loader": "15.4.1",
|
||||||
"vue-router": "3.0.1",
|
"vue-router": "3.0.1",
|
||||||
"vue-style-loader": "4.1.2",
|
"vue-style-loader": "4.1.2",
|
||||||
"vue-template-compiler": "2.5.17",
|
"vue-template-compiler": "2.5.17",
|
||||||
"vue-thin-modal": "1.1.1",
|
|
||||||
"vuedraggable": "2.16.0",
|
"vuedraggable": "2.16.0",
|
||||||
"vuex": "3.0.1",
|
"vuex": "3.0.1",
|
||||||
"vuex-persistedstate": "2.5.4",
|
"vuex-persistedstate": "2.5.4",
|
||||||
"web-push": "3.3.2",
|
"web-push": "3.3.2",
|
||||||
"webfinger.js": "2.6.6",
|
"webfinger.js": "2.6.6",
|
||||||
"webpack": "4.17.1",
|
"webpack": "4.17.2",
|
||||||
"webpack-cli": "3.1.0",
|
"webpack-cli": "3.1.0",
|
||||||
"websocket": "1.0.26",
|
"websocket": "1.0.26",
|
||||||
"ws": "6.0.0",
|
"ws": "6.0.0",
|
||||||
|
@ -6,6 +6,10 @@ html
|
|||||||
&, *
|
&, *
|
||||||
cursor progress !important
|
cursor progress !important
|
||||||
|
|
||||||
|
html
|
||||||
|
// iOSのため
|
||||||
|
overflow auto
|
||||||
|
|
||||||
body
|
body
|
||||||
overflow-wrap break-word
|
overflow-wrap break-word
|
||||||
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<router-view id="app"></router-view>
|
||||||
<router-view id="app"></router-view>
|
|
||||||
<modal-portal/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -80,7 +80,7 @@ export default Vue.extend({
|
|||||||
accepted() {
|
accepted() {
|
||||||
this.state = 'accepted';
|
this.state = 'accepted';
|
||||||
if (this.session.app.callbackUrl) {
|
if (this.session.app.callbackUrl) {
|
||||||
location.href = this.session.app.callbackUrl + '?token=' + this.session.token;
|
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@
|
|||||||
|
|
||||||
// Get salt query
|
// Get salt query
|
||||||
const salt = localStorage.getItem('salt')
|
const salt = localStorage.getItem('salt')
|
||||||
? '?salt=' + localStorage.getItem('salt')
|
? `?salt=${localStorage.getItem('salt')}`
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
// Load an app script
|
// Load an app script
|
||||||
@ -140,7 +140,7 @@
|
|||||||
// Random
|
// Random
|
||||||
localStorage.setItem('salt', Math.random().toString());
|
localStorage.setItem('salt', Math.random().toString());
|
||||||
|
|
||||||
// Clear cache (serive worker)
|
// Clear cache (service worker)
|
||||||
try {
|
try {
|
||||||
navigator.serviceWorker.controller.postMessage('clear');
|
navigator.serviceWorker.controller.postMessage('clear');
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ export default async function(mios: MiOS, force = false, silent = false) {
|
|||||||
localStorage.setItem('should-refresh', 'true');
|
localStorage.setItem('should-refresh', 'true');
|
||||||
localStorage.setItem('v', newer);
|
localStorage.setItem('v', newer);
|
||||||
|
|
||||||
// Clear cache (serive worker)
|
// Clear cache (service worker)
|
||||||
try {
|
try {
|
||||||
if (navigator.serviceWorker.controller) {
|
if (navigator.serviceWorker.controller) {
|
||||||
navigator.serviceWorker.controller.postMessage('clear');
|
navigator.serviceWorker.controller.postMessage('clear');
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
const gcd = (a, b) => !b ? a : gcd(b, a % b);
|
|
||||||
export default gcd;
|
|
@ -1,53 +0,0 @@
|
|||||||
export default function(qs: string) {
|
|
||||||
const q = {
|
|
||||||
text: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
qs.split(' ').forEach(x => {
|
|
||||||
if (/^([a-z_]+?):(.+?)$/.test(x)) {
|
|
||||||
const [key, value] = x.split(':');
|
|
||||||
switch (key) {
|
|
||||||
case 'user':
|
|
||||||
q['includeUserUsernames'] = value.split(',');
|
|
||||||
break;
|
|
||||||
case 'exclude_user':
|
|
||||||
q['excludeUserUsernames'] = value.split(',');
|
|
||||||
break;
|
|
||||||
case 'follow':
|
|
||||||
q['following'] = value == 'null' ? null : value == 'true';
|
|
||||||
break;
|
|
||||||
case 'reply':
|
|
||||||
q['reply'] = value == 'null' ? null : value == 'true';
|
|
||||||
break;
|
|
||||||
case 'renote':
|
|
||||||
q['renote'] = value == 'null' ? null : value == 'true';
|
|
||||||
break;
|
|
||||||
case 'media':
|
|
||||||
q['media'] = value == 'null' ? null : value == 'true';
|
|
||||||
break;
|
|
||||||
case 'poll':
|
|
||||||
q['poll'] = value == 'null' ? null : value == 'true';
|
|
||||||
break;
|
|
||||||
case 'until':
|
|
||||||
case 'since':
|
|
||||||
// YYYY-MM-DD
|
|
||||||
if (/^[0-9]+\-[0-9]+\-[0-9]+$/) {
|
|
||||||
const [yyyy, mm, dd] = value.split('-');
|
|
||||||
q[`${key}_date`] = (new Date(parseInt(yyyy, 10), parseInt(mm, 10) - 1, parseInt(dd, 10))).getTime();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
q[key] = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
q.text += x + ' ';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (q.text) {
|
|
||||||
q.text = q.text.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
|
@ -3,8 +3,10 @@ import MiOS from '../../../../../mios';
|
|||||||
|
|
||||||
export class ReversiGameStream extends Stream {
|
export class ReversiGameStream extends Stream {
|
||||||
constructor(os: MiOS, me, game) {
|
constructor(os: MiOS, me, game) {
|
||||||
super(os, 'games/reversi-game', {
|
super(os, 'games/reversi-game', me ? {
|
||||||
i: me ? me.token : null,
|
i: me.token,
|
||||||
|
game: game.id
|
||||||
|
} : {
|
||||||
game: game.id
|
game: game.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ import MiOS from '../../../mios';
|
|||||||
*/
|
*/
|
||||||
export class LocalTimelineStream extends Stream {
|
export class LocalTimelineStream extends Stream {
|
||||||
constructor(os: MiOS, me) {
|
constructor(os: MiOS, me) {
|
||||||
super(os, 'local-timeline', {
|
super(os, 'local-timeline', me ? {
|
||||||
i: me.token
|
i: me.token
|
||||||
});
|
} : {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { EventEmitter } from 'eventemitter3';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
import Connection from './stream';
|
import Connection from './stream';
|
||||||
|
import { erase } from '../../../../../prelude/array';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ストリーム接続を管理するクラス
|
* ストリーム接続を管理するクラス
|
||||||
@ -89,7 +90,7 @@ export default abstract class StreamManager<T extends Connection> extends EventE
|
|||||||
* @param userId use で発行したユーザーID
|
* @param userId use で発行したユーザーID
|
||||||
*/
|
*/
|
||||||
public dispose(userId) {
|
public dispose(userId) {
|
||||||
this.users = this.users.filter(id => id != userId);
|
this.users = erase(userId, this.users);
|
||||||
|
|
||||||
this._connection.user = `Managed (${ this.users.length })`;
|
this._connection.user = `Managed (${ this.users.length })`;
|
||||||
|
|
||||||
|
@ -44,11 +44,11 @@ export default class Connection extends EventEmitter {
|
|||||||
|
|
||||||
const query = params
|
const query = params
|
||||||
? Object.keys(params)
|
? Object.keys(params)
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
.map(k => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`)
|
||||||
.join('&')
|
.join('&')
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
this.socket = new ReconnectingWebsocket(`${wsUrl}/${endpoint}${query ? '?' + query : ''}`);
|
this.socket = new ReconnectingWebsocket(`${wsUrl}/${endpoint}${query ? `?${query}` : ''}`);
|
||||||
this.socket.addEventListener('open', this.onOpen);
|
this.socket.addEventListener('open', this.onOpen);
|
||||||
this.socket.addEventListener('close', this.onClose);
|
this.socket.addEventListener('close', this.onClose);
|
||||||
this.socket.addEventListener('message', this.onMessage);
|
this.socket.addEventListener('message', this.onMessage);
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="mk-acct">
|
<span class="mk-acct">
|
||||||
<span class="name">@{{ user.username }}</span>
|
<span class="name">@{{ user.username }}</span>
|
||||||
<span class="host" v-if="user.host">@{{ user.host }}</span>
|
<span class="host" v-if="user.host || detail">@{{ user.host || host }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { host } from '../../../config';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['user']
|
props: ['user', 'detail'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
host
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.type == 'user') {
|
if (this.type == 'user') {
|
||||||
const cacheKey = 'autocomplete:user:' + this.q;
|
const cacheKey = `autocomplete:user:${this.q}`;
|
||||||
const cache = sessionStorage.getItem(cacheKey);
|
const cache = sessionStorage.getItem(cacheKey);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
const users = JSON.parse(cache);
|
const users = JSON.parse(cache);
|
||||||
@ -148,7 +148,7 @@ export default Vue.extend({
|
|||||||
this.hashtags = JSON.parse(localStorage.getItem('hashtags') || '[]');
|
this.hashtags = JSON.parse(localStorage.getItem('hashtags') || '[]');
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
} else {
|
} else {
|
||||||
const cacheKey = 'autocomplete:hashtag:' + this.q;
|
const cacheKey = `autocomplete:hashtag:${this.q}`;
|
||||||
const cache = sessionStorage.getItem(cacheKey);
|
const cache = sessionStorage.getItem(cacheKey);
|
||||||
if (cache) {
|
if (cache) {
|
||||||
const hashtags = JSON.parse(cache);
|
const hashtags = JSON.parse(cache);
|
||||||
|
@ -57,7 +57,7 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check internet connection
|
// Check internet connection
|
||||||
fetch('https://google.com?rand=' + Math.random(), {
|
fetch(`https://google.com?rand=${Math.random()}`, {
|
||||||
mode: 'no-cors'
|
mode: 'no-cors'
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.internet = true;
|
this.internet = true;
|
||||||
|
@ -159,11 +159,9 @@ export default Vue.extend({
|
|||||||
canPutEverywhere: this.game.settings.canPutEverywhere,
|
canPutEverywhere: this.game.settings.canPutEverywhere,
|
||||||
loopedBoard: this.game.settings.loopedBoard
|
loopedBoard: this.game.settings.loopedBoard
|
||||||
});
|
});
|
||||||
this.logs.forEach((log, i) => {
|
for (const log of this.logs.slice(0, v)) {
|
||||||
if (i < v) {
|
this.o.put(log.color, log.pos);
|
||||||
this.o.put(log.color, log.pos);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
this.$forceUpdate();
|
this.$forceUpdate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import trends from './trends.vue';
|
||||||
import analogClock from './analog-clock.vue';
|
import analogClock from './analog-clock.vue';
|
||||||
import menu from './menu.vue';
|
import menu from './menu.vue';
|
||||||
import noteHeader from './note-header.vue';
|
import noteHeader from './note-header.vue';
|
||||||
@ -40,6 +41,7 @@ import uiSelect from './ui/select.vue';
|
|||||||
import formButton from './ui/form/button.vue';
|
import formButton from './ui/form/button.vue';
|
||||||
import formRadio from './ui/form/radio.vue';
|
import formRadio from './ui/form/radio.vue';
|
||||||
|
|
||||||
|
Vue.component('mk-trends', trends);
|
||||||
Vue.component('mk-analog-clock', analogClock);
|
Vue.component('mk-analog-clock', analogClock);
|
||||||
Vue.component('mk-menu', menu);
|
Vue.component('mk-menu', menu);
|
||||||
Vue.component('mk-note-header', noteHeader);
|
Vue.component('mk-note-header', noteHeader);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-menu">
|
<div class="onchrpzrvnoruiaenfcqvccjfuupzzwv">
|
||||||
<div class="backdrop" ref="backdrop" @click="close"></div>
|
<div class="backdrop" ref="backdrop" @click="close"></div>
|
||||||
<div class="popover" :class="{ hukidasi }" ref="popover">
|
<div class="popover" :class="{ hukidasi }" ref="popover">
|
||||||
<template v-for="item in items">
|
<template v-for="item in items">
|
||||||
@ -119,9 +119,10 @@ export default Vue.extend({
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
$border-color = rgba(27, 31, 35, 0.15)
|
root(isDark)
|
||||||
|
$bg-color = isDark ? #2c303c : #fff
|
||||||
|
$border-color = rgba(27, 31, 35, 0.15)
|
||||||
|
|
||||||
.mk-menu
|
|
||||||
position initial
|
position initial
|
||||||
|
|
||||||
> .backdrop
|
> .backdrop
|
||||||
@ -131,14 +132,14 @@ $border-color = rgba(27, 31, 35, 0.15)
|
|||||||
z-index 10000
|
z-index 10000
|
||||||
width 100%
|
width 100%
|
||||||
height 100%
|
height 100%
|
||||||
background rgba(#000, 0.1)
|
background rgba(#000, isDark ? 0.5 : 0.1)
|
||||||
opacity 0
|
opacity 0
|
||||||
|
|
||||||
> .popover
|
> .popover
|
||||||
position absolute
|
position absolute
|
||||||
z-index 10001
|
z-index 10001
|
||||||
padding 8px 0
|
padding 8px 0
|
||||||
background #fff
|
background $bg-color
|
||||||
border 1px solid $border-color
|
border 1px solid $border-color
|
||||||
border-radius 4px
|
border-radius 4px
|
||||||
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
|
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
|
||||||
@ -172,12 +173,13 @@ $border-color = rgba(27, 31, 35, 0.15)
|
|||||||
border-top solid $balloon-size transparent
|
border-top solid $balloon-size transparent
|
||||||
border-left solid $balloon-size transparent
|
border-left solid $balloon-size transparent
|
||||||
border-right solid $balloon-size transparent
|
border-right solid $balloon-size transparent
|
||||||
border-bottom solid $balloon-size #fff
|
border-bottom solid $balloon-size $bg-color
|
||||||
|
|
||||||
> button
|
> button
|
||||||
display block
|
display block
|
||||||
padding 8px 16px
|
padding 8px 16px
|
||||||
width 100%
|
width 100%
|
||||||
|
color isDark ? #d6dce2 : #111
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
color $theme-color-foreground
|
color $theme-color-foreground
|
||||||
@ -191,6 +193,12 @@ $border-color = rgba(27, 31, 35, 0.15)
|
|||||||
> div
|
> div
|
||||||
margin 8px 0
|
margin 8px 0
|
||||||
height 1px
|
height 1px
|
||||||
background #eee
|
background isDark ? #1c2023 : #eee
|
||||||
|
|
||||||
|
.onchrpzrvnoruiaenfcqvccjfuupzzwv[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.onchrpzrvnoruiaenfcqvccjfuupzzwv:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -205,17 +205,8 @@ export default Vue.component('misskey-flavored-markdown', {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const _els = [];
|
// el.tag === 'br' のとき i !== 0 が保証されるため、短絡評価により els[i - 1] は配列外参照しない
|
||||||
els.forEach((el, i) => {
|
const _els = els.filter((el, i) => !(el.tag === 'br' && ['div', 'pre'].includes(els[i - 1].tag)));
|
||||||
if (el.tag == 'br') {
|
|
||||||
if (!['div', 'pre'].includes(els[i - 1].tag)) {
|
|
||||||
_els.push(el);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_els.push(el);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return createElement('span', _els);
|
return createElement('span', _els);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { erase } from '../../../../../prelude/array';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -53,7 +54,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
get() {
|
get() {
|
||||||
return {
|
return {
|
||||||
choices: this.choices.filter(choice => choice != '')
|
choices: erase('', this.choices)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { sum } from '../../../../../prelude/array';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['note'],
|
props: ['note'],
|
||||||
data() {
|
data() {
|
||||||
@ -33,7 +34,7 @@ export default Vue.extend({
|
|||||||
return this.note.poll;
|
return this.note.poll;
|
||||||
},
|
},
|
||||||
total(): number {
|
total(): number {
|
||||||
return this.poll.choices.reduce((a, b) => a + b.votes, 0);
|
return sum(this.poll.choices.map(x => x.votes));
|
||||||
},
|
},
|
||||||
isVoted(): boolean {
|
isVoted(): boolean {
|
||||||
return this.poll.choices.some(c => c.isVoted);
|
return this.poll.choices.some(c => c.isVoted);
|
||||||
|
@ -78,7 +78,7 @@ export default Vue.extend({
|
|||||||
cursor wait !important
|
cursor wait !important
|
||||||
|
|
||||||
> .avatar
|
> .avatar
|
||||||
margin 16px auto 0 auto
|
margin 0 auto 0 auto
|
||||||
width 64px
|
width 64px
|
||||||
height 64px
|
height 64px
|
||||||
background #ddd
|
background #ddd
|
||||||
|
105
src/client/app/common/views/components/trends.vue
Normal file
105
src/client/app/common/views/components/trends.vue
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<template>
|
||||||
|
<div class="csqvmxybqbycalfhkxvyfrgbrdalkaoc">
|
||||||
|
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
|
||||||
|
<p class="empty" v-else-if="stats.length == 0">%fa:exclamation-circle%%i18n:@empty%</p>
|
||||||
|
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||||
|
<!-- <transition-group v-else tag="div" name="chart"> -->
|
||||||
|
<div>
|
||||||
|
<div v-for="stat in stats" :key="stat.tag">
|
||||||
|
<div class="tag">
|
||||||
|
<router-link :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
||||||
|
<p>{{ '%i18n:@count%'.replace('{}', stat.usersCount) }}</p>
|
||||||
|
</div>
|
||||||
|
<x-chart class="chart" :src="stat.chart"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- </transition-group> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import XChart from './trends.chart.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
XChart
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
stats: [],
|
||||||
|
fetching: true,
|
||||||
|
clock: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.fetch();
|
||||||
|
this.clock = setInterval(this.fetch, 1000 * 60);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.clock);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetch() {
|
||||||
|
(this as any).api('hashtags/trend').then(stats => {
|
||||||
|
this.stats = stats;
|
||||||
|
this.fetching = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
root(isDark)
|
||||||
|
> .fetching
|
||||||
|
> .empty
|
||||||
|
margin 0
|
||||||
|
padding 16px
|
||||||
|
text-align center
|
||||||
|
color #aaa
|
||||||
|
|
||||||
|
> [data-fa]
|
||||||
|
margin-right 4px
|
||||||
|
|
||||||
|
> div
|
||||||
|
.chart-move
|
||||||
|
transition transform 1s ease
|
||||||
|
|
||||||
|
> div
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
padding 14px 16px
|
||||||
|
|
||||||
|
&:not(:last-child)
|
||||||
|
border-bottom solid 1px isDark ? #393f4f : #eee
|
||||||
|
|
||||||
|
> .tag
|
||||||
|
flex 1
|
||||||
|
overflow hidden
|
||||||
|
font-size 14px
|
||||||
|
color isDark ? #9baec8 : #65727b
|
||||||
|
|
||||||
|
> a
|
||||||
|
display block
|
||||||
|
width 100%
|
||||||
|
white-space nowrap
|
||||||
|
overflow hidden
|
||||||
|
text-overflow ellipsis
|
||||||
|
color inherit
|
||||||
|
|
||||||
|
> p
|
||||||
|
margin 0
|
||||||
|
font-size 75%
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
> .chart
|
||||||
|
height 30px
|
||||||
|
|
||||||
|
.csqvmxybqbycalfhkxvyfrgbrdalkaoc[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.csqvmxybqbycalfhkxvyfrgbrdalkaoc:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
@ -24,19 +24,34 @@ export default Vue.extend({
|
|||||||
|
|
||||||
root(isDark)
|
root(isDark)
|
||||||
margin 16px
|
margin 16px
|
||||||
padding 16px
|
|
||||||
color isDark ? #fff : #000
|
color isDark ? #fff : #000
|
||||||
background isDark ? #282C37 : #fff
|
background isDark ? #282C37 : #fff
|
||||||
box-shadow 0 3px 1px -2px rgba(#000, 0.2), 0 2px 2px 0 rgba(#000, 0.14), 0 1px 5px 0 rgba(#000, 0.12)
|
box-shadow 0 3px 1px -2px rgba(#000, 0.2), 0 2px 2px 0 rgba(#000, 0.14), 0 1px 5px 0 rgba(#000, 0.12)
|
||||||
|
|
||||||
@media (min-width 500px)
|
|
||||||
padding 32px
|
|
||||||
|
|
||||||
> header
|
> header
|
||||||
font-weight normal
|
padding 16px
|
||||||
font-size 24px
|
font-weight bold
|
||||||
|
font-size 20px
|
||||||
color isDark ? #fff : #444
|
color isDark ? #fff : #444
|
||||||
|
|
||||||
|
@media (min-width 500px)
|
||||||
|
padding 24px 32px
|
||||||
|
|
||||||
|
> section
|
||||||
|
padding 20px 16px
|
||||||
|
border-top solid 1px isDark ? rgba(#000, 0.3) : rgba(#000, 0.1)
|
||||||
|
|
||||||
|
@media (min-width 500px)
|
||||||
|
padding 32px
|
||||||
|
|
||||||
|
&.fit-top
|
||||||
|
padding-top 0
|
||||||
|
|
||||||
|
> header
|
||||||
|
margin-bottom 16px
|
||||||
|
font-weight bold
|
||||||
|
color isDark ? #fff : #444
|
||||||
|
|
||||||
.ui-card[data-darkmode]
|
.ui-card[data-darkmode]
|
||||||
root(true)
|
root(true)
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
root(isDark)
|
root(isDark)
|
||||||
display inline-block
|
display inline-block
|
||||||
margin 32px 32px 32px 0
|
margin 0 32px 0 0
|
||||||
cursor pointer
|
cursor pointer
|
||||||
transition all 0.3s
|
transition all 0.3s
|
||||||
|
|
||||||
|
@ -64,6 +64,12 @@ root(isDark)
|
|||||||
cursor pointer
|
cursor pointer
|
||||||
transition all 0.3s
|
transition all 0.3s
|
||||||
|
|
||||||
|
&:first-child
|
||||||
|
margin-top 0
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
margin-bottom 0
|
||||||
|
|
||||||
> *
|
> *
|
||||||
user-select none
|
user-select none
|
||||||
|
|
||||||
@ -89,6 +95,7 @@ root(isDark)
|
|||||||
|
|
||||||
> .button
|
> .button
|
||||||
display inline-block
|
display inline-block
|
||||||
|
flex-shrink 0
|
||||||
margin 3px 0 0 0
|
margin 3px 0 0 0
|
||||||
width 34px
|
width 34px
|
||||||
height 14px
|
height 14px
|
||||||
|
@ -170,7 +170,7 @@ export default Vue.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch('/url?url=' + encodeURIComponent(this.url)).then(res => {
|
fetch(`/url?url=${encodeURIComponent(this.url)}`).then(res => {
|
||||||
res.json().then(info => {
|
res.json().then(info => {
|
||||||
if (info.url == null) return;
|
if (info.url == null) return;
|
||||||
this.title = info.title;
|
this.title = info.title;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { toUnicode as decodePunycode } from 'punycode';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['url', 'target'],
|
props: ['url', 'target'],
|
||||||
data() {
|
data() {
|
||||||
@ -27,11 +28,11 @@ export default Vue.extend({
|
|||||||
created() {
|
created() {
|
||||||
const url = new URL(this.url);
|
const url = new URL(this.url);
|
||||||
this.schema = url.protocol;
|
this.schema = url.protocol;
|
||||||
this.hostname = url.hostname;
|
this.hostname = decodePunycode(url.hostname);
|
||||||
this.port = url.port;
|
this.port = url.port;
|
||||||
this.pathname = url.pathname;
|
this.pathname = decodeURIComponent(url.pathname);
|
||||||
this.query = url.search;
|
this.query = decodeURIComponent(url.search);
|
||||||
this.hash = url.hash;
|
this.hash = decodeURIComponent(url.hash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -31,15 +31,30 @@ export default Vue.extend({
|
|||||||
default: undefined
|
default: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetching: true,
|
fetching: true,
|
||||||
notes: []
|
notes: [],
|
||||||
|
connection: null,
|
||||||
|
connectionId: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetch();
|
this.fetch();
|
||||||
|
|
||||||
|
this.connection = (this as any).os.streams.localTimelineStream.getConnection();
|
||||||
|
this.connectionId = (this as any).os.streams.localTimelineStream.use();
|
||||||
|
|
||||||
|
this.connection.on('note', this.onNote);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.connection.off('note', this.onNote);
|
||||||
|
(this as any).os.streams.localTimelineStream.dispose(this.connectionId);
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetch(cb?) {
|
fetch(cb?) {
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
@ -48,14 +63,21 @@ export default Vue.extend({
|
|||||||
local: true,
|
local: true,
|
||||||
reply: false,
|
reply: false,
|
||||||
renote: false,
|
renote: false,
|
||||||
media: false,
|
file: false,
|
||||||
poll: false,
|
poll: false
|
||||||
bot: false
|
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
this.notes = notes;
|
this.notes = notes;
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
|
onNote(note) {
|
||||||
|
if (note.replyId != null) return;
|
||||||
|
if (note.renoteId != null) return;
|
||||||
|
if (note.poll != null) return;
|
||||||
|
|
||||||
|
this.notes.unshift(note);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -191,7 +191,7 @@ class Autocomplete {
|
|||||||
const acct = renderAcct(value);
|
const acct = renderAcct(value);
|
||||||
|
|
||||||
// 挿入
|
// 挿入
|
||||||
this.text = trimmedBefore + '@' + acct + ' ' + after;
|
this.text = `${trimmedBefore}@${acct} ${after}`;
|
||||||
|
|
||||||
// キャレットを戻す
|
// キャレットを戻す
|
||||||
this.vm.$nextTick(() => {
|
this.vm.$nextTick(() => {
|
||||||
@ -207,7 +207,7 @@ class Autocomplete {
|
|||||||
const after = source.substr(caret);
|
const after = source.substr(caret);
|
||||||
|
|
||||||
// 挿入
|
// 挿入
|
||||||
this.text = trimmedBefore + '#' + value + ' ' + after;
|
this.text = `${trimmedBefore}#${value} ${after}`;
|
||||||
|
|
||||||
// キャレットを戻す
|
// キャレットを戻す
|
||||||
this.vm.$nextTick(() => {
|
this.vm.$nextTick(() => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
Vue.filter('notePage', note => {
|
Vue.filter('notePage', note => {
|
||||||
return '/notes/' + note.id;
|
return `/notes/${note.id}`;
|
||||||
});
|
});
|
||||||
|
@ -11,5 +11,5 @@ Vue.filter('userName', user => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Vue.filter('userPage', (user, path?) => {
|
Vue.filter('userPage', (user, path?) => {
|
||||||
return '/@' + Vue.filter('acct')(user) + (path ? '/' + path : '');
|
return `/@${Vue.filter('acct')(user)}${(path ? `/${path}` : '')}`;
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="syxhndwprovvuqhmyvveewmbqayniwkv" v-if="!fetching" :data-darkmode="$store.state.device.darkmode">
|
<div class="syxhndwprovvuqhmyvveewmbqayniwkv" v-if="!fetching" :data-darkmode="$store.state.device.darkmode">
|
||||||
<div class="signed-in-as" v-html="'%i18n:@signed-in-as%'.replace('{}', '<b>' + myName + '</b>')"></div>
|
<div class="signed-in-as" v-html="'%i18n:@signed-in-as%'.replace('{}', `<b>${myName}`)"></div>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div class="banner" :style="bannerStyle"></div>
|
<div class="banner" :style="bannerStyle"></div>
|
||||||
@ -83,7 +83,7 @@ export default Vue.extend({
|
|||||||
userId: this.user.id
|
userId: this.user.id
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.user.isLocked && this.user.hasPendingFollowRequestFromYou) {
|
if (this.user.hasPendingFollowRequestFromYou) {
|
||||||
this.user = await (this as any).api('following/requests/cancel', {
|
this.user = await (this as any).api('following/requests/cancel', {
|
||||||
userId: this.user.id
|
userId: this.user.id
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mkw-analog-clock">
|
<div class="mkw-analog-clock">
|
||||||
<mk-widget-container :naked="!(props.design % 2)" :show-header="false">
|
<mk-widget-container :naked="props.style % 2 === 0" :show-header="false">
|
||||||
<div class="mkw-analog-clock--body">
|
<div class="mkw-analog-clock--body">
|
||||||
<mk-analog-clock :dark="$store.state.device.darkmode" :smooth="!(props.design && ~props.design)"/>
|
<mk-analog-clock :dark="$store.state.device.darkmode" :smooth="props.style < 2"/>
|
||||||
</div>
|
</div>
|
||||||
</mk-widget-container>
|
</mk-widget-container>
|
||||||
</div>
|
</div>
|
||||||
@ -13,13 +13,12 @@ import define from '../../../common/define-widget';
|
|||||||
export default define({
|
export default define({
|
||||||
name: 'analog-clock',
|
name: 'analog-clock',
|
||||||
props: () => ({
|
props: () => ({
|
||||||
design: -1
|
style: 0
|
||||||
})
|
})
|
||||||
}).extend({
|
}).extend({
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
if (++this.props.design > 2)
|
this.props.style = (this.props.style + 1) % 4;
|
||||||
this.props.design = -1;
|
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mkw-broadcast"
|
<div class="anltbovirfeutcigvwgmgxipejaeozxi"
|
||||||
:data-found="broadcasts.length != 0"
|
:data-found="announcements && announcements.length != 0"
|
||||||
:data-melt="props.design == 1"
|
:data-melt="props.design == 1"
|
||||||
:data-mobile="platform == 'mobile'"
|
:data-mobile="platform == 'mobile'"
|
||||||
>
|
>
|
||||||
@ -14,18 +14,17 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="fetching" v-if="fetching">%i18n:@fetching%<mk-ellipsis/></p>
|
<p class="fetching" v-if="fetching">%i18n:@fetching%<mk-ellipsis/></p>
|
||||||
<h1 v-if="!fetching">{{ broadcasts.length == 0 ? '%i18n:@no-broadcasts%' : broadcasts[i].title }}</h1>
|
<h1 v-if="!fetching">{{ announcements.length == 0 ? '%i18n:@no-broadcasts%' : announcements[i].title }}</h1>
|
||||||
<p v-if="!fetching">
|
<p v-if="!fetching">
|
||||||
<span v-if="broadcasts.length != 0" v-html="broadcasts[i].text"></span>
|
<span v-if="announcements.length != 0" v-html="announcements[i].text"></span>
|
||||||
<template v-if="broadcasts.length == 0">%i18n:@have-a-nice-day%</template>
|
<template v-if="announcements.length == 0">%i18n:@have-a-nice-day%</template>
|
||||||
</p>
|
</p>
|
||||||
<a v-if="broadcasts.length > 1" @click="next">%i18n:@next% >></a>
|
<a v-if="announcements.length > 1" @click="next">%i18n:@next% >></a>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import define from '../../../common/define-widget';
|
import define from '../../../common/define-widget';
|
||||||
import { lang } from '../../../config';
|
|
||||||
|
|
||||||
export default define({
|
export default define({
|
||||||
name: 'broadcast',
|
name: 'broadcast',
|
||||||
@ -37,26 +36,18 @@ export default define({
|
|||||||
return {
|
return {
|
||||||
i: 0,
|
i: 0,
|
||||||
fetching: true,
|
fetching: true,
|
||||||
broadcasts: []
|
announcements: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
(this as any).os.getMeta().then(meta => {
|
(this as any).os.getMeta().then(meta => {
|
||||||
let broadcasts = [];
|
this.announcements = meta.broadcasts;
|
||||||
if (meta.broadcasts) {
|
|
||||||
meta.broadcasts.forEach(broadcast => {
|
|
||||||
if (broadcast[lang]) {
|
|
||||||
broadcasts.push(broadcast[lang]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.broadcasts = broadcasts;
|
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
next() {
|
next() {
|
||||||
if (this.i == this.broadcasts.length - 1) {
|
if (this.i == this.announcements.length - 1) {
|
||||||
this.i = 0;
|
this.i = 0;
|
||||||
} else {
|
} else {
|
||||||
this.i++;
|
this.i++;
|
||||||
@ -75,7 +66,7 @@ export default define({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mkw-broadcast
|
root(isDark)
|
||||||
padding 10px
|
padding 10px
|
||||||
border solid 1px #4078c0
|
border solid 1px #4078c0
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
@ -142,15 +133,11 @@ export default define({
|
|||||||
z-index 1
|
z-index 1
|
||||||
margin 0
|
margin 0
|
||||||
font-size 0.7em
|
font-size 0.7em
|
||||||
color #555
|
color isDark ? #fff : #555
|
||||||
|
|
||||||
&.fetching
|
&.fetching
|
||||||
text-align center
|
text-align center
|
||||||
|
|
||||||
a
|
|
||||||
color #555
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> a
|
> a
|
||||||
display block
|
display block
|
||||||
font-size 0.7em
|
font-size 0.7em
|
||||||
@ -159,4 +146,10 @@ export default define({
|
|||||||
> p
|
> p
|
||||||
color #fff
|
color #fff
|
||||||
|
|
||||||
|
.anltbovirfeutcigvwgmgxipejaeozxi[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.anltbovirfeutcigvwgmgxipejaeozxi:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -4,20 +4,7 @@
|
|||||||
<template slot="header">%fa:hashtag%%i18n:@title%</template>
|
<template slot="header">%fa:hashtag%%i18n:@title%</template>
|
||||||
|
|
||||||
<div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'">
|
<div class="mkw-hashtags--body" :data-mobile="platform == 'mobile'">
|
||||||
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
|
<mk-trends/>
|
||||||
<p class="empty" v-else-if="stats.length == 0">%fa:exclamation-circle%%i18n:@empty%</p>
|
|
||||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
|
||||||
<!-- <transition-group v-else tag="div" name="chart"> -->
|
|
||||||
<div>
|
|
||||||
<div v-for="stat in stats" :key="stat.tag">
|
|
||||||
<div class="tag">
|
|
||||||
<router-link :to="`/tags/${ encodeURIComponent(stat.tag) }`" :title="stat.tag">#{{ stat.tag }}</router-link>
|
|
||||||
<p>{{ '%i18n:@count%'.replace('{}', stat.usersCount) }}</p>
|
|
||||||
</div>
|
|
||||||
<x-chart class="chart" :src="stat.chart"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- </transition-group> -->
|
|
||||||
</div>
|
</div>
|
||||||
</mk-widget-container>
|
</mk-widget-container>
|
||||||
</div>
|
</div>
|
||||||
@ -25,7 +12,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import define from '../../../common/define-widget';
|
import define from '../../../common/define-widget';
|
||||||
import XChart from './hashtags.chart.vue';
|
|
||||||
|
|
||||||
export default define({
|
export default define({
|
||||||
name: 'hashtags',
|
name: 'hashtags',
|
||||||
@ -33,89 +19,11 @@ export default define({
|
|||||||
compact: false
|
compact: false
|
||||||
})
|
})
|
||||||
}).extend({
|
}).extend({
|
||||||
components: {
|
|
||||||
XChart
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
stats: [],
|
|
||||||
fetching: true,
|
|
||||||
clock: null
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.fetch();
|
|
||||||
this.clock = setInterval(this.fetch, 1000 * 60);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.clock);
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
func() {
|
func() {
|
||||||
this.props.compact = !this.props.compact;
|
this.props.compact = !this.props.compact;
|
||||||
this.save();
|
this.save();
|
||||||
},
|
|
||||||
fetch() {
|
|
||||||
(this as any).api('hashtags/trend').then(stats => {
|
|
||||||
this.stats = stats;
|
|
||||||
this.fetching = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
root(isDark)
|
|
||||||
.mkw-hashtags--body
|
|
||||||
> .fetching
|
|
||||||
> .empty
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color #aaa
|
|
||||||
|
|
||||||
> [data-fa]
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> div
|
|
||||||
.chart-move
|
|
||||||
transition transform 1s ease
|
|
||||||
|
|
||||||
> div
|
|
||||||
display flex
|
|
||||||
align-items center
|
|
||||||
padding 14px 16px
|
|
||||||
|
|
||||||
&:not(:last-child)
|
|
||||||
border-bottom solid 1px isDark ? #393f4f : #eee
|
|
||||||
|
|
||||||
> .tag
|
|
||||||
flex 1
|
|
||||||
overflow hidden
|
|
||||||
font-size 14px
|
|
||||||
color isDark ? #9baec8 : #65727b
|
|
||||||
|
|
||||||
> a
|
|
||||||
display block
|
|
||||||
width 100%
|
|
||||||
white-space nowrap
|
|
||||||
overflow hidden
|
|
||||||
text-overflow ellipsis
|
|
||||||
color inherit
|
|
||||||
|
|
||||||
> p
|
|
||||||
margin 0
|
|
||||||
font-size 75%
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
> .chart
|
|
||||||
height 30px
|
|
||||||
|
|
||||||
.mkw-hashtags[data-darkmode]
|
|
||||||
root(true)
|
|
||||||
|
|
||||||
.mkw-hashtags:not([data-darkmode])
|
|
||||||
root(false)
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -163,7 +163,7 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
alert('%i18n:@unhandled-error% ' + err);
|
alert(`%i18n:@unhandled-error% ${err}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
alert('%i18n:@unhandled-error% ' + err);
|
alert(`%i18n:@unhandled-error% ${err}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -404,7 +404,7 @@ export default Vue.extend({
|
|||||||
folder: folder
|
folder: folder
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
window.open(url + '/i/drive/folder/' + folder.id,
|
window.open(`${url}/i/drive/folder/${folder.id}`,
|
||||||
'drive_window',
|
'drive_window',
|
||||||
'height=500, width=800');
|
'height=500, width=800');
|
||||||
}
|
}
|
||||||
|
@ -55,13 +55,15 @@ export default Vue.extend({
|
|||||||
methods: {
|
methods: {
|
||||||
onFollow(user) {
|
onFollow(user) {
|
||||||
if (user.id == this.u.id) {
|
if (user.id == this.u.id) {
|
||||||
this.user.isFollowing = user.isFollowing;
|
this.u.isFollowing = user.isFollowing;
|
||||||
|
this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnfollow(user) {
|
onUnfollow(user) {
|
||||||
if (user.id == this.u.id) {
|
if (user.id == this.u.id) {
|
||||||
this.user.isFollowing = user.isFollowing;
|
this.u.isFollowing = user.isFollowing;
|
||||||
|
this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ export default Vue.extend({
|
|||||||
userId: this.u.id
|
userId: this.u.id
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.u.isLocked && this.u.hasPendingFollowRequestFromYou) {
|
if (this.u.hasPendingFollowRequestFromYou) {
|
||||||
this.u = await (this as any).api('following/requests/cancel', {
|
this.u = await (this as any).api('following/requests/cancel', {
|
||||||
userId: this.u.id
|
userId: this.u.id
|
||||||
});
|
});
|
||||||
|
@ -48,7 +48,7 @@ export default Vue.extend({
|
|||||||
const mouseY = e.clientY - rect.top;
|
const mouseY = e.clientY - rect.top;
|
||||||
const xp = mouseX / this.$el.offsetWidth * 100;
|
const xp = mouseX / this.$el.offsetWidth * 100;
|
||||||
const yp = mouseY / this.$el.offsetHeight * 100;
|
const yp = mouseY / this.$el.offsetHeight * 100;
|
||||||
this.$el.style.backgroundPosition = xp + '% ' + yp + '%';
|
this.$el.style.backgroundPosition = `${xp}% ${yp}%`;
|
||||||
this.$el.style.backgroundImage = `url("${this.image.url}")`;
|
this.$el.style.backgroundImage = `url("${this.image.url}")`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@
|
|||||||
<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</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"/>
|
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="media" v-if="p.media.length > 0">
|
<div class="files" v-if="p.files.length > 0">
|
||||||
<mk-media-list :media-list="p.media" :raw="true"/>
|
<mk-media-list :media-list="p.files" :raw="true"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p"/>
|
<mk-poll v-if="p.poll" :note="p"/>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
||||||
@ -86,6 +86,7 @@ import MkRenoteFormWindow from './renote-form-window.vue';
|
|||||||
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
||||||
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
||||||
import XSub from './notes.note.sub.vue';
|
import XSub from './notes.note.sub.vue';
|
||||||
|
import { sum } from '../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
@ -114,7 +115,7 @@ export default Vue.extend({
|
|||||||
isRenote(): boolean {
|
isRenote(): boolean {
|
||||||
return (this.note.renote &&
|
return (this.note.renote &&
|
||||||
this.note.text == null &&
|
this.note.text == null &&
|
||||||
this.note.mediaIds.length == 0 &&
|
this.note.fileIds.length == 0 &&
|
||||||
this.note.poll == null);
|
this.note.poll == null);
|
||||||
},
|
},
|
||||||
p(): any {
|
p(): any {
|
||||||
@ -122,9 +123,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
reactionsCount(): number {
|
reactionsCount(): number {
|
||||||
return this.p.reactionCounts
|
return this.p.reactionCounts
|
||||||
? Object.keys(this.p.reactionCounts)
|
? sum(Object.values(this.p.reactionCounts))
|
||||||
.map(key => this.p.reactionCounts[key])
|
|
||||||
.reduce((a, b) => a + b)
|
|
||||||
: 0;
|
: 0;
|
||||||
},
|
},
|
||||||
title(): string {
|
title(): string {
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :class="$style.text"/>
|
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :class="$style.text"/>
|
||||||
<a class="rp" v-if="p.renote">RP:</a>
|
<a class="rp" v-if="p.renote">RP:</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="media" v-if="p.media.length > 0">
|
<div class="files" v-if="p.files.length > 0">
|
||||||
<mk-media-list :media-list="p.media"/>
|
<mk-media-list :media-list="p.files"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
||||||
<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
|
<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
|
||||||
@ -78,6 +78,7 @@ import MkRenoteFormWindow from './renote-form-window.vue';
|
|||||||
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
||||||
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
||||||
import XSub from './notes.note.sub.vue';
|
import XSub from './notes.note.sub.vue';
|
||||||
|
import { sum } from '../../../../../prelude/array';
|
||||||
|
|
||||||
function focus(el, fn) {
|
function focus(el, fn) {
|
||||||
const target = fn(el);
|
const target = fn(el);
|
||||||
@ -110,7 +111,7 @@ export default Vue.extend({
|
|||||||
isRenote(): boolean {
|
isRenote(): boolean {
|
||||||
return (this.note.renote &&
|
return (this.note.renote &&
|
||||||
this.note.text == null &&
|
this.note.text == null &&
|
||||||
this.note.mediaIds.length == 0 &&
|
this.note.fileIds.length == 0 &&
|
||||||
this.note.poll == null);
|
this.note.poll == null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -120,9 +121,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
reactionsCount(): number {
|
reactionsCount(): number {
|
||||||
return this.p.reactionCounts
|
return this.p.reactionCounts
|
||||||
? Object.keys(this.p.reactionCounts)
|
? sum(Object.values(this.p.reactionCounts))
|
||||||
.map(key => this.p.reactionCounts[key])
|
|
||||||
.reduce((a, b) => a + b)
|
|
||||||
: 0;
|
: 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ export default Vue.extend({
|
|||||||
prepend(note, silent = false) {
|
prepend(note, silent = false) {
|
||||||
//#region 弾く
|
//#region 弾く
|
||||||
const isMyNote = note.userId == this.$store.state.i.id;
|
const isMyNote = note.userId == this.$store.state.i.id;
|
||||||
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
const isPureRenote = note.renoteId != null && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
||||||
|
|
||||||
if (this.$store.state.settings.showMyRenotes === false) {
|
if (this.$store.state.settings.showMyRenotes === false) {
|
||||||
if (isMyNote && isPureRenote) {
|
if (isMyNote && isPureRenote) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<span class="icon" v-if="geo">%fa:map-marker-alt%</span>
|
<span class="icon" v-if="geo">%fa:map-marker-alt%</span>
|
||||||
<span v-if="!reply">%i18n:@note%</span>
|
<span v-if="!reply">%i18n:@note%</span>
|
||||||
<span v-if="reply">%i18n:@reply%</span>
|
<span v-if="reply">%i18n:@reply%</span>
|
||||||
<span class="count" v-if="media.length != 0">{{ '%i18n:@attaches%'.replace('{}', media.length) }}</span>
|
<span class="count" v-if="files.length != 0">{{ '%i18n:@attaches%'.replace('{}', files.length) }}</span>
|
||||||
<span class="count" v-if="uploadings.length != 0">{{ '%i18n:@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
|
<span class="count" v-if="uploadings.length != 0">{{ '%i18n:@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -14,7 +14,7 @@
|
|||||||
:reply="reply"
|
:reply="reply"
|
||||||
@posted="onPosted"
|
@posted="onPosted"
|
||||||
@change-uploadings="onChangeUploadings"
|
@change-uploadings="onChangeUploadings"
|
||||||
@change-attached-media="onChangeMedia"
|
@change-attached-files="onChangeFiles"
|
||||||
@geo-attached="onGeoAttached"
|
@geo-attached="onGeoAttached"
|
||||||
@geo-dettached="onGeoDettached"/>
|
@geo-dettached="onGeoDettached"/>
|
||||||
</div>
|
</div>
|
||||||
@ -29,7 +29,7 @@ export default Vue.extend({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
uploadings: [],
|
uploadings: [],
|
||||||
media: [],
|
files: [],
|
||||||
geo: null
|
geo: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -42,8 +42,8 @@ export default Vue.extend({
|
|||||||
onChangeUploadings(files) {
|
onChangeUploadings(files) {
|
||||||
this.uploadings = files;
|
this.uploadings = files;
|
||||||
},
|
},
|
||||||
onChangeMedia(media) {
|
onChangeFiles(files) {
|
||||||
this.media = media;
|
this.files = files;
|
||||||
},
|
},
|
||||||
onGeoAttached(geo) {
|
onGeoAttached(geo) {
|
||||||
this.geo = geo;
|
this.geo = geo;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder"
|
@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder"
|
||||||
v-autocomplete="'text'"
|
v-autocomplete="'text'"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="medias" :class="{ with: poll }" v-show="files.length != 0">
|
<div class="files" :class="{ with: poll }" v-show="files.length != 0">
|
||||||
<x-draggable :list="files" :options="{ animation: 150 }">
|
<x-draggable :list="files" :options="{ animation: 150 }">
|
||||||
<div v-for="file in files" :key="file.id">
|
<div v-for="file in files" :key="file.id">
|
||||||
<div class="img" :style="{ backgroundImage: `url(${file.thumbnailUrl})` }" :title="file.name"></div>
|
<div class="img" :style="{ backgroundImage: `url(${file.thumbnailUrl})` }" :title="file.name"></div>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<button class="upload" title="%i18n:@attach-media-from-local%" @click="chooseFile">%fa:upload%</button>
|
<button class="upload" title="%i18n:@attach-media-from-local%" @click="chooseFile">%fa:upload%</button>
|
||||||
<button class="drive" title="%i18n:@attach-media-from-drive%" @click="chooseFileFromDrive">%fa:cloud%</button>
|
<button class="drive" title="%i18n:@attach-media-from-drive%" @click="chooseFileFromDrive">%fa:cloud%</button>
|
||||||
<button class="kao" title="%i18n:@insert-a-kao%" @click="kao">%fa:R smile%</button>
|
<button class="kao" title="%i18n:@insert-a-kao%" @click="kao">%fa:R smile%</button>
|
||||||
<button class="poll" title="%i18n:@create-poll%" @click="poll = true">%fa:chart-pie%</button>
|
<button class="poll" title="%i18n:@create-poll%" @click="poll = !poll">%fa:chart-pie%</button>
|
||||||
<button class="poll" title="%i18n:@hide-contents%" @click="useCw = !useCw">%fa:eye-slash%</button>
|
<button class="poll" title="%i18n:@hide-contents%" @click="useCw = !useCw">%fa:eye-slash%</button>
|
||||||
<button class="geo" title="%i18n:@attach-location-information%" @click="geo ? removeGeo() : setGeo()">%fa:map-marker-alt%</button>
|
<button class="geo" title="%i18n:@attach-location-information%" @click="geo ? removeGeo() : setGeo()">%fa:map-marker-alt%</button>
|
||||||
<button class="visibility" title="%i18n:@visibility%" @click="setVisibility" ref="visibilityButton">
|
<button class="visibility" title="%i18n:@visibility%" @click="setVisibility" ref="visibilityButton">
|
||||||
@ -62,6 +62,7 @@ import getFace from '../../../common/scripts/get-face';
|
|||||||
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
|
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
|
||||||
import parse from '../../../../../mfm/parse';
|
import parse from '../../../../../mfm/parse';
|
||||||
import { host } from '../../../config';
|
import { host } from '../../../config';
|
||||||
|
import { erase } from '../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
@ -110,9 +111,9 @@ export default Vue.extend({
|
|||||||
computed: {
|
computed: {
|
||||||
draftId(): string {
|
draftId(): string {
|
||||||
return this.renote
|
return this.renote
|
||||||
? 'renote:' + this.renote.id
|
? `renote:${this.renote.id}`
|
||||||
: this.reply
|
: this.reply
|
||||||
? 'reply:' + this.reply.id
|
? `reply:${this.reply.id}`
|
||||||
: 'note';
|
: 'note';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -188,7 +189,7 @@ export default Vue.extend({
|
|||||||
(this.$refs.poll as any).set(draft.data.poll);
|
(this.$refs.poll as any).set(draft.data.poll);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,12 +226,12 @@ export default Vue.extend({
|
|||||||
|
|
||||||
attachMedia(driveFile) {
|
attachMedia(driveFile) {
|
||||||
this.files.push(driveFile);
|
this.files.push(driveFile);
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
},
|
},
|
||||||
|
|
||||||
detachMedia(id) {
|
detachMedia(id) {
|
||||||
this.files = this.files.filter(x => x.id != id);
|
this.files = this.files.filter(x => x.id != id);
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChangeFile() {
|
onChangeFile() {
|
||||||
@ -249,7 +250,7 @@ export default Vue.extend({
|
|||||||
this.text = '';
|
this.text = '';
|
||||||
this.files = [];
|
this.files = [];
|
||||||
this.poll = false;
|
this.poll = false;
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeydown(e) {
|
onKeydown(e) {
|
||||||
@ -297,7 +298,7 @@ export default Vue.extend({
|
|||||||
if (driveFile != null && driveFile != '') {
|
if (driveFile != null && driveFile != '') {
|
||||||
const file = JSON.parse(driveFile);
|
const file = JSON.parse(driveFile);
|
||||||
this.files.push(file);
|
this.files.push(file);
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
@ -313,7 +314,7 @@ export default Vue.extend({
|
|||||||
this.geo = pos.coords;
|
this.geo = pos.coords;
|
||||||
this.$emit('geo-attached', this.geo);
|
this.$emit('geo-attached', this.geo);
|
||||||
}, err => {
|
}, err => {
|
||||||
alert('%i18n:@error%: ' + err.message);
|
alert(`%i18n:@error%: ${err.message}`);
|
||||||
}, {
|
}, {
|
||||||
enableHighAccuracy: true
|
enableHighAccuracy: true
|
||||||
});
|
});
|
||||||
@ -346,7 +347,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeVisibleUser(user) {
|
removeVisibleUser(user) {
|
||||||
this.visibleUsers = this.visibleUsers.filter(u => u != user);
|
this.visibleUsers = erase(user, this.visibleUsers);
|
||||||
},
|
},
|
||||||
|
|
||||||
post() {
|
post() {
|
||||||
@ -354,7 +355,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
(this as any).api('notes/create', {
|
(this as any).api('notes/create', {
|
||||||
text: this.text == '' ? undefined : this.text,
|
text: this.text == '' ? undefined : this.text,
|
||||||
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
fileIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
||||||
replyId: this.reply ? this.reply.id : undefined,
|
replyId: this.reply ? this.reply.id : undefined,
|
||||||
renoteId: this.renote ? this.renote.id : undefined,
|
renoteId: this.renote ? this.renote.id : undefined,
|
||||||
poll: this.poll ? (this.$refs.poll as any).get() : undefined,
|
poll: this.poll ? (this.$refs.poll as any).get() : undefined,
|
||||||
@ -514,7 +515,7 @@ root(isDark)
|
|||||||
margin-right 8px
|
margin-right 8px
|
||||||
white-space nowrap
|
white-space nowrap
|
||||||
|
|
||||||
> .medias
|
> .files
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
background isDark ? #181b23 : lighten($theme-color, 98%)
|
background isDark ? #181b23 : lighten($theme-color, 98%)
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
<misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i"/>
|
<misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i"/>
|
||||||
<a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RP: ...</a>
|
<a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RP: ...</a>
|
||||||
</div>
|
</div>
|
||||||
<details v-if="note.media.length > 0">
|
<details v-if="note.files.length > 0">
|
||||||
<summary>({{ '%i18n:@media-count%'.replace('{}', note.media.length) }})</summary>
|
<summary>({{ '%i18n:@media-count%'.replace('{}', note.files.length) }})</summary>
|
||||||
<mk-media-list :media-list="note.media"/>
|
<mk-media-list :media-list="note.files"/>
|
||||||
</details>
|
</details>
|
||||||
<details v-if="note.poll">
|
<details v-if="note.poll">
|
||||||
<summary>%i18n:@poll%</summary>
|
<summary>%i18n:@poll%</summary>
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div class="qldxjjsrseehkusjuoooapmsprvfrxyl mk-admin-card">
|
||||||
|
<header>%i18n:@announcements%</header>
|
||||||
|
<textarea v-model="broadcasts"></textarea>
|
||||||
|
<button class="ui" @click="save">%i18n:@save%</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from "vue";
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
broadcasts: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
(this as any).os.getMeta().then(meta => {
|
||||||
|
this.broadcasts = JSON.stringify(meta.broadcasts, null, ' ');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
save() {
|
||||||
|
(this as any).api('admin/update-meta', {
|
||||||
|
broadcasts: JSON.parse(this.broadcasts)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
.qldxjjsrseehkusjuoooapmsprvfrxyl
|
||||||
|
textarea
|
||||||
|
width 100%
|
||||||
|
min-height 300px
|
||||||
|
|
||||||
|
</style>
|
@ -4,6 +4,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }">%fa:chalkboard .fw%%i18n:@dashboard%</li>
|
<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }">%fa:chalkboard .fw%%i18n:@dashboard%</li>
|
||||||
<li @click="nav('users')" :class="{ active: page == 'users' }">%fa:users .fw%%i18n:@users%</li>
|
<li @click="nav('users')" :class="{ active: page == 'users' }">%fa:users .fw%%i18n:@users%</li>
|
||||||
|
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }">%fa:broadcast-tower .fw%%i18n:@announcements%</li>
|
||||||
<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }">%fa:cloud .fw%%i18n:@drive%</li> -->
|
<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }">%fa:cloud .fw%%i18n:@drive%</li> -->
|
||||||
<!-- <li @click="nav('update')" :class="{ active: page == 'update' }">%i18n:@update%</li> -->
|
<!-- <li @click="nav('update')" :class="{ active: page == 'update' }">%i18n:@update%</li> -->
|
||||||
</ul>
|
</ul>
|
||||||
@ -13,6 +14,9 @@
|
|||||||
<x-dashboard/>
|
<x-dashboard/>
|
||||||
<x-charts/>
|
<x-charts/>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-show="page == 'announcements'">
|
||||||
|
<x-announcements/>
|
||||||
|
</div>
|
||||||
<div v-if="page == 'users'">
|
<div v-if="page == 'users'">
|
||||||
<x-suspend-user/>
|
<x-suspend-user/>
|
||||||
<x-unsuspend-user/>
|
<x-unsuspend-user/>
|
||||||
@ -28,6 +32,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import XDashboard from "./admin.dashboard.vue";
|
import XDashboard from "./admin.dashboard.vue";
|
||||||
|
import XAnnouncements from "./admin.announcements.vue";
|
||||||
import XSuspendUser from "./admin.suspend-user.vue";
|
import XSuspendUser from "./admin.suspend-user.vue";
|
||||||
import XUnsuspendUser from "./admin.unsuspend-user.vue";
|
import XUnsuspendUser from "./admin.unsuspend-user.vue";
|
||||||
import XVerifyUser from "./admin.verify-user.vue";
|
import XVerifyUser from "./admin.verify-user.vue";
|
||||||
@ -37,6 +42,7 @@ import XCharts from "../../components/charts.vue";
|
|||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XDashboard,
|
XDashboard,
|
||||||
|
XAnnouncements,
|
||||||
XSuspendUser,
|
XSuspendUser,
|
||||||
XUnsuspendUser,
|
XUnsuspendUser,
|
||||||
XVerifyUser,
|
XVerifyUser,
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Menu from '../../../../common/views/components/menu.vue';
|
import Menu from '../../../../common/views/components/menu.vue';
|
||||||
import contextmenu from '../../../api/contextmenu';
|
import contextmenu from '../../../api/contextmenu';
|
||||||
|
import { countIf } from '../../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
@ -117,7 +118,7 @@ export default Vue.extend({
|
|||||||
toggleActive() {
|
toggleActive() {
|
||||||
if (!this.isStacked) return;
|
if (!this.isStacked) return;
|
||||||
const vms = this.$store.state.settings.deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id));
|
const vms = this.$store.state.settings.deck.layout.find(ids => ids.indexOf(this.column.id) != -1).map(id => this.getColumnVm(id));
|
||||||
if (this.active && vms.filter(vm => vm.$el.classList.contains('active')).length == 1) return;
|
if (this.active && countIf(vm => vm.$el.classList.contains('active'), vms) == 1) return;
|
||||||
this.active = !this.active;
|
this.active = !this.active;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ export default Vue.extend({
|
|||||||
(this as any).api('notes/user-list-timeline', {
|
(this as any).api('notes/user-list-timeline', {
|
||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
mediaOnly: this.mediaOnly,
|
withFiles: this.mediaOnly,
|
||||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
||||||
@ -90,7 +90,7 @@ export default Vue.extend({
|
|||||||
listId: this.list.id,
|
listId: this.list.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilId: (this.$refs.timeline as any).tail().id,
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
mediaOnly: this.mediaOnly,
|
withFiles: this.mediaOnly,
|
||||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
||||||
@ -109,7 +109,7 @@ export default Vue.extend({
|
|||||||
return promise;
|
return promise;
|
||||||
},
|
},
|
||||||
onNote(note) {
|
onNote(note) {
|
||||||
if (this.mediaOnly && note.media.length == 0) return;
|
if (this.mediaOnly && note.files.length == 0) return;
|
||||||
|
|
||||||
// Prepend a note
|
// Prepend a note
|
||||||
(this.$refs.timeline as any).prepend(note);
|
(this.$refs.timeline as any).prepend(note);
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||||
<a class="rp" v-if="p.renote != null">RP:</a>
|
<a class="rp" v-if="p.renote != null">RP:</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="media" v-if="p.media.length > 0">
|
<div class="files" v-if="p.files.length > 0">
|
||||||
<mk-media-list :media-list="p.media"/>
|
<mk-media-list :media-list="p.files"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
||||||
<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
||||||
@ -54,11 +54,11 @@
|
|||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="srwrkujossgfuhrbnvqkybtzxpblgchi">
|
<div v-else class="srwrkujossgfuhrbnvqkybtzxpblgchi">
|
||||||
<div v-if="note.media.length > 0">
|
<div v-if="note.files.length > 0">
|
||||||
<mk-media-list :media-list="note.media"/>
|
<mk-media-list :media-list="note.files"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="note.renote && note.renote.media.length > 0">
|
<div v-if="note.renote && note.renote.files.length > 0">
|
||||||
<mk-media-list :media-list="note.renote.media"/>
|
<mk-media-list :media-list="note.renote.files"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -100,7 +100,7 @@ export default Vue.extend({
|
|||||||
isRenote(): boolean {
|
isRenote(): boolean {
|
||||||
return (this.note.renote &&
|
return (this.note.renote &&
|
||||||
this.note.text == null &&
|
this.note.text == null &&
|
||||||
this.note.mediaIds.length == 0 &&
|
this.note.fileIds.length == 0 &&
|
||||||
this.note.poll == null);
|
this.note.poll == null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ root(isDark)
|
|||||||
.mk-url-preview
|
.mk-url-preview
|
||||||
margin-top 8px
|
margin-top 8px
|
||||||
|
|
||||||
> .media
|
> .files
|
||||||
> img
|
> img
|
||||||
display block
|
display block
|
||||||
max-width 100%
|
max-width 100%
|
||||||
|
@ -127,7 +127,7 @@ export default Vue.extend({
|
|||||||
prepend(note, silent = false) {
|
prepend(note, silent = false) {
|
||||||
//#region 弾く
|
//#region 弾く
|
||||||
const isMyNote = note.userId == this.$store.state.i.id;
|
const isMyNote = note.userId == this.$store.state.i.id;
|
||||||
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
const isPureRenote = note.renoteId != null && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
||||||
|
|
||||||
if (this.$store.state.settings.showMyRenotes === false) {
|
if (this.$store.state.settings.showMyRenotes === false) {
|
||||||
if (isMyNote && isPureRenote) {
|
if (isMyNote && isPureRenote) {
|
||||||
|
@ -96,7 +96,7 @@ export default Vue.extend({
|
|||||||
(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
|
(this.$refs.timeline as any).init(() => new Promise((res, rej) => {
|
||||||
(this as any).api(this.endpoint, {
|
(this as any).api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
mediaOnly: this.mediaOnly,
|
withFiles: this.mediaOnly,
|
||||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
||||||
@ -117,7 +117,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
const promise = (this as any).api(this.endpoint, {
|
const promise = (this as any).api(this.endpoint, {
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
mediaOnly: this.mediaOnly,
|
withFiles: this.mediaOnly,
|
||||||
untilId: (this.$refs.timeline as any).tail().id,
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
@ -138,7 +138,7 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onNote(note) {
|
onNote(note) {
|
||||||
if (this.mediaOnly && note.media.length == 0) return;
|
if (this.mediaOnly && note.files.length == 0) return;
|
||||||
|
|
||||||
// Prepend a note
|
// Prepend a note
|
||||||
(this.$refs.timeline as any).prepend(note);
|
(this.$refs.timeline as any).prepend(note);
|
||||||
|
@ -31,7 +31,7 @@ export default Vue.extend({
|
|||||||
const title = folder.name + ' | %i18n:@title%';
|
const title = folder.name + ' | %i18n:@title%';
|
||||||
|
|
||||||
// Rewrite URL
|
// Rewrite URL
|
||||||
history.pushState(null, title, '/i/drive/folder/' + folder.id);
|
history.pushState(null, title, `/i/drive/folder/${folder.id}`);
|
||||||
|
|
||||||
document.title = title;
|
document.title = title;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,10 @@ export default Vue.extend({
|
|||||||
methods: {
|
methods: {
|
||||||
nav(game, actualNav) {
|
nav(game, actualNav) {
|
||||||
if (actualNav) {
|
if (actualNav) {
|
||||||
this.$router.push('/reversi/' + game.id);
|
this.$router.push(`/reversi/${game.id}`);
|
||||||
} else {
|
} else {
|
||||||
// TODO: https://github.com/vuejs/vue-router/issues/703
|
// TODO: https://github.com/vuejs/vue-router/issues/703
|
||||||
this.$router.push('/reversi/' + game.id);
|
this.$router.push(`/reversi/${game.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ export default Vue.extend({
|
|||||||
this.user = user;
|
this.user = user;
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
|
|
||||||
document.title = 'メッセージ: ' + getUserName(this.user);
|
document.title = `メッセージ: ${getUserName(this.user)}`;
|
||||||
|
|
||||||
Progress.done();
|
Progress.done();
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<div class="title">
|
<div class="title">
|
||||||
<p class="name">{{ user | userName }}</p>
|
<p class="name">{{ user | userName }}</p>
|
||||||
<div>
|
<div>
|
||||||
<span class="username"><mk-acct :user="user"/></span>
|
<span class="username"><mk-acct :user="user" :detail="true" /></span>
|
||||||
<span v-if="user.isBot" title="%i18n:@is-bot%">%fa:robot%</span>
|
<span v-if="user.isBot" title="%i18n:@is-bot%">%fa:robot%</span>
|
||||||
<span class="location" v-if="user.host === null && user.profile.location">%fa:map-marker% {{ user.profile.location }}</span>
|
<span class="location" v-if="user.host === null && user.profile.location">%fa:map-marker% {{ user.profile.location }}</span>
|
||||||
<span class="birthday" v-if="user.host === null && user.profile.birthday">%fa:birthday-cake% {{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳)</span>
|
<span class="birthday" v-if="user.host === null && user.profile.birthday">%fa:birthday-cake% {{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳)</span>
|
||||||
|
@ -24,12 +24,12 @@ export default Vue.extend({
|
|||||||
mounted() {
|
mounted() {
|
||||||
(this as any).api('users/notes', {
|
(this as any).api('users/notes', {
|
||||||
userId: this.user.id,
|
userId: this.user.id,
|
||||||
withMedia: true,
|
withFiles: true,
|
||||||
limit: 9
|
limit: 9
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
notes.forEach(note => {
|
notes.forEach(note => {
|
||||||
note.media.forEach(media => {
|
note.files.forEach(file => {
|
||||||
if (this.images.length < 9) this.images.push(media);
|
if (this.images.length < 9) this.images.push(file);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
|
@ -66,7 +66,7 @@ export default Vue.extend({
|
|||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
untilDate: this.date ? this.date.getTime() : undefined,
|
untilDate: this.date ? this.date.getTime() : undefined,
|
||||||
includeReplies: this.mode == 'with-replies',
|
includeReplies: this.mode == 'with-replies',
|
||||||
withMedia: this.mode == 'with-media'
|
withFiles: this.mode == 'with-media'
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
if (notes.length == fetchLimit + 1) {
|
if (notes.length == fetchLimit + 1) {
|
||||||
notes.pop();
|
notes.pop();
|
||||||
@ -86,7 +86,7 @@ export default Vue.extend({
|
|||||||
userId: this.user.id,
|
userId: this.user.id,
|
||||||
limit: fetchLimit + 1,
|
limit: fetchLimit + 1,
|
||||||
includeReplies: this.mode == 'with-replies',
|
includeReplies: this.mode == 'with-replies',
|
||||||
withMedia: this.mode == 'with-media',
|
withFiles: this.mode == 'with-media',
|
||||||
untilId: (this.$refs.timeline as any).tail().id
|
untilId: (this.$refs.timeline as any).tail().id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,45 +1,85 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-welcome">
|
<div class="mk-welcome">
|
||||||
<img ref="pointer" class="pointer" src="/assets/pointer.png" alt="">
|
|
||||||
<button @click="dark">
|
<button @click="dark">
|
||||||
<template v-if="$store.state.device.darkmode">%fa:moon%</template>
|
<template v-if="$store.state.device.darkmode">%fa:moon%</template>
|
||||||
<template v-else>%fa:R moon%</template>
|
<template v-else>%fa:R moon%</template>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<mk-forkit class="forkit"/>
|
||||||
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="container">
|
<div class="main block">
|
||||||
<div class="info">
|
<div>
|
||||||
<span><b>{{ host }}</b></span>
|
<h1 v-if="name != 'Misskey'">{{ name }}</h1>
|
||||||
<span class="stats" v-if="stats">
|
<h1 v-else><img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" :alt="name"></h1>
|
||||||
<span>%fa:user% {{ stats.originalUsersCount | number }}</span>
|
|
||||||
<span>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</span>
|
<div class="info">
|
||||||
</span>
|
<span><b>{{ host }}</b> - <span v-html="'%i18n:@powered-by-misskey%'"></span></span>
|
||||||
</div>
|
<span class="stats" v-if="stats">
|
||||||
<main>
|
<span>%fa:user% {{ stats.originalUsersCount | number }}</span>
|
||||||
<div class="about">
|
<span>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</span>
|
||||||
<h1 v-if="name != 'Misskey'">{{ name }}</h1>
|
</span>
|
||||||
<h1 v-else><img :src="$store.state.device.darkmode ? 'assets/title.dark.svg' : 'assets/title.light.svg'" :alt="name"></h1>
|
</div>
|
||||||
<p class="powerd-by" v-if="name != 'Misskey'" v-html="'%i18n:@powered-by-misskey%'"></p>
|
|
||||||
<p class="desc" v-html="description || '%i18n:common.about%'"></p>
|
<p class="desc" v-html="description || '%i18n:common.about%'"></p>
|
||||||
<a ref="signup" @click="signup">📦 %i18n:@signup%</a>
|
|
||||||
|
<p class="sign">
|
||||||
|
<span class="signup" @click="signup">%i18n:@signup%</span>
|
||||||
|
<span class="divider">|</span>
|
||||||
|
<span class="signin" @click="signin">%i18n:@signin%</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<img src="/assets/pointer.png" alt="" class="char">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="announcements block">
|
||||||
|
<header>%fa:broadcast-tower% %i18n:@announcements%</header>
|
||||||
|
<div v-if="announcements && announcements.length > 0">
|
||||||
|
<div v-for="announcement in announcements">
|
||||||
|
<h1 v-html="announcement.title"></h1>
|
||||||
|
<div v-html="announcement.text"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="photos block">
|
||||||
|
<header>%fa:images% %i18n:@photos%</header>
|
||||||
|
<div>
|
||||||
|
<div v-for="photo in photos" :style="`background-image: url(${photo.thumbnailUrl})`"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="nav block">
|
||||||
|
<div>
|
||||||
|
<mk-nav class="nav"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="side">
|
||||||
|
<div class="trends block">
|
||||||
|
<div>
|
||||||
|
<mk-trends/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tl block">
|
||||||
|
<header>%fa:comment-alt R% %i18n:@timeline%</header>
|
||||||
|
<div>
|
||||||
|
<mk-welcome-timeline class="tl" :max="20"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="login">
|
|
||||||
<mk-signin/>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
<div class="hashtags">
|
|
||||||
<router-link v-for="tag in tags" :key="tag" :to="`/tags/${ tag }`" :title="tag">#{{ tag }}</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
<mk-nav class="nav"/>
|
|
||||||
</div>
|
</div>
|
||||||
<mk-forkit class="forkit"/>
|
|
||||||
<img src="assets/title.dark.svg" :alt="name">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tl">
|
|
||||||
<mk-welcome-timeline :max="20"/>
|
<modal name="signup" :class="$store.state.device.darkmode ? 'modal-dark' : 'modal-light'" width="450px" height="auto" scrollable>
|
||||||
</div>
|
<header class="formHeader">%i18n:@signup%</header>
|
||||||
<modal name="signup" width="500px" height="auto" scrollable>
|
<mk-signup class="form"/>
|
||||||
<header :class="$style.signupFormHeader">%i18n:@signup%</header>
|
</modal>
|
||||||
<mk-signup :class="$style.signupForm"/>
|
|
||||||
|
<modal name="signin" :class="$store.state.device.darkmode ? 'modal-dark' : 'modal-light'" width="450px" height="auto" scrollable>
|
||||||
|
<header class="formHeader">%i18n:@signin%</header>
|
||||||
|
<mk-signin class="form"/>
|
||||||
</modal>
|
</modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -47,6 +87,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { host, copyright } from '../../../config';
|
import { host, copyright } from '../../../config';
|
||||||
|
import { concat } from '../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
@ -56,43 +97,46 @@ export default Vue.extend({
|
|||||||
host,
|
host,
|
||||||
name: 'Misskey',
|
name: 'Misskey',
|
||||||
description: '',
|
description: '',
|
||||||
pointerInterval: null,
|
announcements: [],
|
||||||
tags: []
|
photos: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
(this as any).os.getMeta().then(meta => {
|
(this as any).os.getMeta().then(meta => {
|
||||||
this.name = meta.name;
|
this.name = meta.name;
|
||||||
this.description = meta.description;
|
this.description = meta.description;
|
||||||
|
this.announcements = meta.broadcasts;
|
||||||
});
|
});
|
||||||
|
|
||||||
(this as any).api('stats').then(stats => {
|
(this as any).api('stats').then(stats => {
|
||||||
this.stats = stats;
|
this.stats = stats;
|
||||||
});
|
});
|
||||||
|
|
||||||
(this as any).api('hashtags/trend').then(stats => {
|
const image = [
|
||||||
this.tags = stats.map(x => x.tag);
|
'image/jpeg',
|
||||||
|
'image/png',
|
||||||
|
'image/gif'
|
||||||
|
];
|
||||||
|
|
||||||
|
(this as any).api('notes/local-timeline', {
|
||||||
|
fileType: image,
|
||||||
|
limit: 6
|
||||||
|
}).then((notes: any[]) => {
|
||||||
|
const files = concat(notes.map((n: any): any[] => n.files));
|
||||||
|
this.photos = files.filter(f => image.includes(f.type)).slice(0, 6);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
this.point();
|
|
||||||
this.pointerInterval = setInterval(this.point, 100);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.pointerInterval);
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
point() {
|
|
||||||
const x = this.$refs.signup.getBoundingClientRect();
|
|
||||||
this.$refs.pointer.style.top = x.top + x.height + 'px';
|
|
||||||
this.$refs.pointer.style.left = x.left + 'px';
|
|
||||||
},
|
|
||||||
signup() {
|
signup() {
|
||||||
this.$modal.show('signup');
|
this.$modal.show('signup');
|
||||||
},
|
},
|
||||||
|
|
||||||
signin() {
|
signin() {
|
||||||
this.$modal.show('signin');
|
this.$modal.show('signin');
|
||||||
},
|
},
|
||||||
|
|
||||||
dark() {
|
dark() {
|
||||||
this.$store.commit('device/set', {
|
this.$store.commit('device/set', {
|
||||||
key: 'darkmode',
|
key: 'darkmode',
|
||||||
@ -103,11 +147,40 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style lang="stylus">
|
||||||
#wait {
|
#wait
|
||||||
right: auto;
|
right auto
|
||||||
left: 15px;
|
left 15px
|
||||||
}
|
|
||||||
|
.v--modal-overlay
|
||||||
|
background rgba(0, 0, 0, 0.6)
|
||||||
|
|
||||||
|
.modal-light
|
||||||
|
.v--modal-box
|
||||||
|
color #777
|
||||||
|
|
||||||
|
.formHeader
|
||||||
|
border-bottom solid 1px #eee
|
||||||
|
|
||||||
|
.modal-dark
|
||||||
|
.v--modal-box
|
||||||
|
background #313543
|
||||||
|
color #fff
|
||||||
|
|
||||||
|
.formHeader
|
||||||
|
border-bottom solid 1px rgba(#000, 0.2)
|
||||||
|
|
||||||
|
.modal-light
|
||||||
|
.modal-dark
|
||||||
|
.form
|
||||||
|
padding 24px 48px 48px 48px
|
||||||
|
|
||||||
|
.formHeader
|
||||||
|
text-align center
|
||||||
|
padding 48px 0 12px 0
|
||||||
|
margin 0 48px
|
||||||
|
font-size 1.5em
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@ -116,145 +189,170 @@ export default Vue.extend({
|
|||||||
root(isDark)
|
root(isDark)
|
||||||
display flex
|
display flex
|
||||||
min-height 100vh
|
min-height 100vh
|
||||||
|
//background-color #00070F
|
||||||
|
//background-image url('/assets/bg.jpg')
|
||||||
|
//background-position center
|
||||||
|
//background-size cover
|
||||||
|
|
||||||
> .pointer
|
> .forkit
|
||||||
display block
|
|
||||||
position absolute
|
position absolute
|
||||||
z-index 1
|
|
||||||
top 0
|
top 0
|
||||||
right 0
|
right 0
|
||||||
width 180px
|
|
||||||
margin 0 0 0 -180px
|
|
||||||
transform rotateY(180deg) translateX(-10px) translateY(-48px)
|
|
||||||
pointer-events none
|
|
||||||
|
|
||||||
> button
|
> button
|
||||||
position fixed
|
position fixed
|
||||||
z-index 1
|
z-index 1
|
||||||
top 0
|
bottom 16px
|
||||||
left 0
|
left 16px
|
||||||
padding 16px
|
padding 16px
|
||||||
font-size 18px
|
font-size 18px
|
||||||
color #fff
|
color isDark ? #fff : #444
|
||||||
|
|
||||||
display none // TODO
|
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
flex 1
|
display grid
|
||||||
padding 64px 0 0 0
|
grid-template-rows 1fr 1fr 64px
|
||||||
text-align center
|
grid-template-columns 1fr 1fr 350px
|
||||||
background #578394
|
gap 16px
|
||||||
background-position center
|
width 100%
|
||||||
background-size cover
|
max-width 1200px
|
||||||
|
height 100vh
|
||||||
|
min-height 950px
|
||||||
|
margin 0 auto
|
||||||
|
padding 64px
|
||||||
|
|
||||||
&:before
|
.block
|
||||||
content ''
|
color isDark ? #fff : #444
|
||||||
display block
|
background isDark ? #282C37 : #fff
|
||||||
position absolute
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
top 0
|
//border-radius 8px
|
||||||
left 0
|
overflow auto
|
||||||
right 0
|
|
||||||
bottom 0
|
|
||||||
background rgba(#000, 0.5)
|
|
||||||
|
|
||||||
> .forkit
|
> header
|
||||||
position absolute
|
z-index 1
|
||||||
top 0
|
padding 0 16px
|
||||||
right 0
|
line-height 48px
|
||||||
|
background isDark ? #313543 : #fff
|
||||||
|
|
||||||
> img
|
if !isDark
|
||||||
position absolute
|
box-shadow 0 1px 0px rgba(0, 0, 0, 0.1)
|
||||||
bottom 16px
|
|
||||||
right 16px
|
|
||||||
width 150px
|
|
||||||
|
|
||||||
> .container
|
& + div
|
||||||
$aboutWidth = 380px
|
max-height calc(100% - 48px)
|
||||||
$loginWidth = 340px
|
|
||||||
$width = $aboutWidth + $loginWidth
|
|
||||||
|
|
||||||
> .info
|
> div
|
||||||
margin 0 auto 16px auto
|
overflow auto
|
||||||
width $width
|
|
||||||
font-size 14px
|
|
||||||
color #fff
|
|
||||||
|
|
||||||
> .stats
|
> .main
|
||||||
margin-left 16px
|
grid-row 1
|
||||||
padding-left 16px
|
grid-column 1 / 3
|
||||||
border-left solid 1px #fff
|
border-top solid 5px $theme-color
|
||||||
|
|
||||||
> *
|
> div
|
||||||
margin-right 16px
|
padding 32px
|
||||||
|
min-height 100%
|
||||||
|
|
||||||
> main
|
> h1
|
||||||
display flex
|
margin 0
|
||||||
margin auto
|
|
||||||
width $width
|
|
||||||
border-radius 8px
|
|
||||||
overflow hidden
|
|
||||||
box-shadow 0 2px 8px rgba(#000, 0.3)
|
|
||||||
|
|
||||||
> .about
|
> img
|
||||||
width $aboutWidth
|
margin -8px 0 0 -16px
|
||||||
color #444
|
max-width 280px
|
||||||
background #fff
|
|
||||||
|
> .info
|
||||||
|
margin 0 auto 16px auto
|
||||||
|
width $width
|
||||||
|
font-size 14px
|
||||||
|
|
||||||
|
> .stats
|
||||||
|
margin-left 16px
|
||||||
|
padding-left 16px
|
||||||
|
border-left solid 1px isDark ? #fff : #444
|
||||||
|
|
||||||
|
> *
|
||||||
|
margin-right 16px
|
||||||
|
|
||||||
|
> .sign
|
||||||
|
font-size 120%
|
||||||
|
|
||||||
|
> .divider
|
||||||
|
margin 0 16px
|
||||||
|
|
||||||
|
> .signin
|
||||||
|
> .signup
|
||||||
|
cursor pointer
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color $theme-color
|
||||||
|
|
||||||
|
> .char
|
||||||
|
display block
|
||||||
|
position absolute
|
||||||
|
right 0
|
||||||
|
bottom 0
|
||||||
|
width 180px
|
||||||
|
opacity 0.3
|
||||||
|
|
||||||
|
> *:not(.char)
|
||||||
|
z-index 1
|
||||||
|
|
||||||
|
> .announcements
|
||||||
|
grid-row 2
|
||||||
|
grid-column 1
|
||||||
|
|
||||||
|
> div
|
||||||
|
padding 32px
|
||||||
|
|
||||||
|
> div
|
||||||
|
padding 0 0 16px 0
|
||||||
|
margin 0 0 16px 0
|
||||||
|
border-bottom 1px solid isDark ? rgba(#000, 0.2) : rgba(#000, 0.05)
|
||||||
|
|
||||||
> h1
|
> h1
|
||||||
margin 0 0 16px 0
|
|
||||||
padding 32px 32px 0 32px
|
|
||||||
color #444
|
|
||||||
|
|
||||||
> img
|
|
||||||
width 170px
|
|
||||||
vertical-align bottom
|
|
||||||
|
|
||||||
> .powerd-by
|
|
||||||
margin 16px
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
> .desc
|
|
||||||
margin 0
|
margin 0
|
||||||
padding 0 32px 16px 32px
|
font-size 1.25em
|
||||||
|
|
||||||
> a
|
> .photos
|
||||||
display inline-block
|
grid-row 2
|
||||||
margin 0 0 32px 0
|
grid-column 2
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
> .login
|
> div
|
||||||
width $loginWidth
|
display grid
|
||||||
padding 16px 32px 32px 32px
|
grid-template-rows 1fr 1fr 1fr
|
||||||
background isDark ? #2e3440 : #f5f5f5
|
grid-template-columns 1fr 1fr
|
||||||
|
gap 8px
|
||||||
|
height 100%
|
||||||
|
padding 16px
|
||||||
|
|
||||||
> .hashtags
|
> div
|
||||||
margin 16px auto
|
//border-radius 4px
|
||||||
width $width
|
background-position center center
|
||||||
font-size 14px
|
background-size cover
|
||||||
color #fff
|
|
||||||
background rgba(#000, 0.3)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> *
|
> .nav
|
||||||
display inline-block
|
display flex
|
||||||
margin 14px
|
justify-content center
|
||||||
|
align-items center
|
||||||
|
grid-row 3
|
||||||
|
grid-column 1 / 3
|
||||||
|
font-size 14px
|
||||||
|
|
||||||
> .nav
|
> .side
|
||||||
display block
|
display grid
|
||||||
margin 16px 0
|
grid-row 1 / 4
|
||||||
font-size 14px
|
grid-column 3
|
||||||
color #fff
|
grid-template-rows 1fr 350px
|
||||||
|
grid-template-columns 1fr
|
||||||
|
gap 16px
|
||||||
|
|
||||||
> .tl
|
> .tl
|
||||||
margin 0
|
grid-row 1
|
||||||
width 410px
|
grid-column 1
|
||||||
height 100vh
|
overflow auto
|
||||||
text-align left
|
|
||||||
background isDark ? #313543 : #fff
|
|
||||||
|
|
||||||
> *
|
> .trends
|
||||||
max-height 100%
|
grid-row 2
|
||||||
overflow auto
|
grid-column 1
|
||||||
|
padding 8px
|
||||||
|
|
||||||
.mk-welcome[data-darkmode]
|
.mk-welcome[data-darkmode]
|
||||||
root(true)
|
root(true)
|
||||||
@ -263,29 +361,3 @@ root(isDark)
|
|||||||
root(false)
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="stylus" module>
|
|
||||||
.signupForm
|
|
||||||
padding 24px 48px 48px 48px
|
|
||||||
|
|
||||||
.signupFormHeader
|
|
||||||
padding 48px 0 12px 0
|
|
||||||
margin: 0 48px
|
|
||||||
font-size 1.5em
|
|
||||||
color #777
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
.signinForm
|
|
||||||
padding 24px 48px 48px 48px
|
|
||||||
|
|
||||||
.signinFormHeader
|
|
||||||
padding 48px 0 12px 0
|
|
||||||
margin: 0 48px
|
|
||||||
font-size 1.5em
|
|
||||||
color #777
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
.nav
|
|
||||||
a
|
|
||||||
color #666
|
|
||||||
</style>
|
|
||||||
|
@ -49,7 +49,7 @@ export default define({
|
|||||||
offset: this.offset,
|
offset: this.offset,
|
||||||
renote: false,
|
renote: false,
|
||||||
reply: false,
|
reply: false,
|
||||||
media: false,
|
file: false,
|
||||||
poll: false
|
poll: false
|
||||||
}).then(notes => {
|
}).then(notes => {
|
||||||
const note = notes ? notes[0] : null;
|
const note = notes ? notes[0] : null;
|
||||||
|
@ -5,14 +5,12 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex';
|
import Vuex from 'vuex';
|
||||||
import VueRouter from 'vue-router';
|
import VueRouter from 'vue-router';
|
||||||
import VModal from 'vue-js-modal';
|
|
||||||
import * as TreeView from 'vue-json-tree-view';
|
import * as TreeView from 'vue-json-tree-view';
|
||||||
import VAnimateCss from 'v-animate-css';
|
import VAnimateCss from 'v-animate-css';
|
||||||
import Element from 'element-ui';
|
import Element from 'element-ui';
|
||||||
import ElementLocaleEn from 'element-ui/lib/locale/lang/en';
|
import ElementLocaleEn from 'element-ui/lib/locale/lang/en';
|
||||||
import ElementLocaleJa from 'element-ui/lib/locale/lang/ja';
|
import ElementLocaleJa from 'element-ui/lib/locale/lang/ja';
|
||||||
import VueThinModal from 'vue-thin-modal';
|
import VModal from 'vue-js-modal';
|
||||||
import 'vue-thin-modal/dist/vue-thin-modal.css';
|
|
||||||
|
|
||||||
import App from './app.vue';
|
import App from './app.vue';
|
||||||
import checkForUpdate from './common/scripts/check-for-update';
|
import checkForUpdate from './common/scripts/check-for-update';
|
||||||
@ -28,13 +26,10 @@ switch (lang) {
|
|||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
Vue.use(VModal);
|
|
||||||
Vue.use(TreeView);
|
Vue.use(TreeView);
|
||||||
Vue.use(VAnimateCss);
|
Vue.use(VAnimateCss);
|
||||||
Vue.use(Element, { locale: elementLocale });
|
Vue.use(Element, { locale: elementLocale });
|
||||||
Vue.use(VueThinModal, {
|
Vue.use(VModal);
|
||||||
autoMountPortal: false
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register global directives
|
// Register global directives
|
||||||
require('./common/views/directives');
|
require('./common/views/directives');
|
||||||
|
@ -3,7 +3,7 @@ import { EventEmitter } from 'eventemitter3';
|
|||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
import initStore from './store';
|
import initStore from './store';
|
||||||
import { apiUrl, swPublickey, version, lang, googleMapsApiKey } from './config';
|
import { apiUrl, version, lang } from './config';
|
||||||
import Progress from './common/scripts/loading';
|
import Progress from './common/scripts/loading';
|
||||||
import Connection from './common/scripts/streaming/stream';
|
import Connection from './common/scripts/streaming/stream';
|
||||||
import { HomeStreamManager } from './common/scripts/streaming/home';
|
import { HomeStreamManager } from './common/scripts/streaming/home';
|
||||||
@ -17,6 +17,7 @@ import Err from './common/views/components/connect-failed.vue';
|
|||||||
import { LocalTimelineStreamManager } from './common/scripts/streaming/local-timeline';
|
import { LocalTimelineStreamManager } from './common/scripts/streaming/local-timeline';
|
||||||
import { HybridTimelineStreamManager } from './common/scripts/streaming/hybrid-timeline';
|
import { HybridTimelineStreamManager } from './common/scripts/streaming/hybrid-timeline';
|
||||||
import { GlobalTimelineStreamManager } from './common/scripts/streaming/global-timeline';
|
import { GlobalTimelineStreamManager } from './common/scripts/streaming/global-timeline';
|
||||||
|
import { erase } from '../../prelude/array';
|
||||||
|
|
||||||
//#region api requests
|
//#region api requests
|
||||||
let spinner = null;
|
let spinner = null;
|
||||||
@ -230,13 +231,13 @@ export default class MiOS extends EventEmitter {
|
|||||||
//#region Init stream managers
|
//#region Init stream managers
|
||||||
this.streams.serverStatsStream = new ServerStatsStreamManager(this);
|
this.streams.serverStatsStream = new ServerStatsStreamManager(this);
|
||||||
this.streams.notesStatsStream = new NotesStatsStreamManager(this);
|
this.streams.notesStatsStream = new NotesStatsStreamManager(this);
|
||||||
|
this.streams.localTimelineStream = new LocalTimelineStreamManager(this, this.store.state.i);
|
||||||
|
|
||||||
this.once('signedin', () => {
|
this.once('signedin', () => {
|
||||||
// Init home stream manager
|
// Init home stream manager
|
||||||
this.stream = new HomeStreamManager(this, this.store.state.i);
|
this.stream = new HomeStreamManager(this, this.store.state.i);
|
||||||
|
|
||||||
// Init other stream manager
|
// Init other stream manager
|
||||||
this.streams.localTimelineStream = new LocalTimelineStreamManager(this, this.store.state.i);
|
|
||||||
this.streams.hybridTimelineStream = new HybridTimelineStreamManager(this, this.store.state.i);
|
this.streams.hybridTimelineStream = new HybridTimelineStreamManager(this, this.store.state.i);
|
||||||
this.streams.globalTimelineStream = new GlobalTimelineStreamManager(this, this.store.state.i);
|
this.streams.globalTimelineStream = new GlobalTimelineStreamManager(this, this.store.state.i);
|
||||||
this.streams.driveStream = new DriveStreamManager(this, this.store.state.i);
|
this.streams.driveStream = new DriveStreamManager(this, this.store.state.i);
|
||||||
@ -361,7 +362,7 @@ export default class MiOS extends EventEmitter {
|
|||||||
|
|
||||||
// A public key your push server will use to send
|
// A public key your push server will use to send
|
||||||
// messages to client apps via a push server.
|
// messages to client apps via a push server.
|
||||||
applicationServerKey: urlBase64ToUint8Array(swPublickey)
|
applicationServerKey: urlBase64ToUint8Array(this.meta.data.swPublickey)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Subscribe push notification
|
// Subscribe push notification
|
||||||
@ -537,7 +538,7 @@ export default class MiOS extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public unregisterStreamConnection(connection: Connection) {
|
public unregisterStreamConnection(connection: Connection) {
|
||||||
this.connections = this.connections.filter(c => c != connection);
|
this.connections = erase(connection, this.connections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
src/client/app/mobile/api/post.ts
Normal file
23
src/client/app/mobile/api/post.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import PostForm from '../views/components/post-form-dialog.vue';
|
||||||
|
|
||||||
|
export default (os) => (opts) => {
|
||||||
|
const o = opts || {};
|
||||||
|
|
||||||
|
document.documentElement.style.overflow = 'hidden';
|
||||||
|
|
||||||
|
function recover() {
|
||||||
|
document.documentElement.style.overflow = 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
const vm = new PostForm({
|
||||||
|
parent: os.app,
|
||||||
|
propsData: {
|
||||||
|
reply: o.reply,
|
||||||
|
renote: o.renote
|
||||||
|
}
|
||||||
|
}).$mount();
|
||||||
|
vm.$once('cancel', recover);
|
||||||
|
vm.$once('posted', recover);
|
||||||
|
document.body.appendChild(vm.$el);
|
||||||
|
(vm as any).focus();
|
||||||
|
};
|
@ -14,6 +14,7 @@ import chooseDriveFolder from './api/choose-drive-folder';
|
|||||||
import chooseDriveFile from './api/choose-drive-file';
|
import chooseDriveFile from './api/choose-drive-file';
|
||||||
import dialog from './api/dialog';
|
import dialog from './api/dialog';
|
||||||
import input from './api/input';
|
import input from './api/input';
|
||||||
|
import post from './api/post';
|
||||||
import notify from './api/notify';
|
import notify from './api/notify';
|
||||||
|
|
||||||
import MkIndex from './views/pages/index.vue';
|
import MkIndex from './views/pages/index.vue';
|
||||||
@ -90,7 +91,7 @@ init((launch) => {
|
|||||||
chooseDriveFile,
|
chooseDriveFile,
|
||||||
dialog: dialog(os),
|
dialog: dialog(os),
|
||||||
input,
|
input,
|
||||||
post: () => alert('deprecated'),
|
post: post(os),
|
||||||
notify
|
notify
|
||||||
}));
|
}));
|
||||||
}, true);
|
}, true);
|
||||||
|
@ -17,13 +17,3 @@ body
|
|||||||
display flex
|
display flex
|
||||||
flex-direction column
|
flex-direction column
|
||||||
min-height 100%
|
min-height 100%
|
||||||
|
|
||||||
.modal-backdrop
|
|
||||||
z-index 10000 !important
|
|
||||||
|
|
||||||
.modal-content-wrapper
|
|
||||||
z-index 10001 !important
|
|
||||||
|
|
||||||
.modal-content
|
|
||||||
padding 0 !important
|
|
||||||
background-color transparent !important
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-drive-file-chooser">
|
<div class="cdxzvcfawjxdyxsekbxbfgtplebnoneb">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<header>
|
<header>
|
||||||
<h1>%i18n:@select-file%<span class="count" v-if="files.length > 0">({{ files.length }})</span></h1>
|
<h1>%i18n:@select-file%<span class="count" v-if="files.length > 0">({{ files.length }})</span></h1>
|
||||||
<button class="close" @click="cancel">%fa:times%</button>
|
<button class="close" @click="cancel">%fa:times%</button>
|
||||||
<button v-if="multiple" class="ok" @click="ok">%fa:check%</button>
|
<button v-if="multiple" class="ok" @click="ok">%fa:check%</button>
|
||||||
</header>
|
</header>
|
||||||
<mk-drive ref="browser"
|
<mk-drive class="drive" ref="browser"
|
||||||
:select-file="true"
|
:select-file="true"
|
||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
@change-selection="onChangeSelection"
|
@change-selection="onChangeSelection"
|
||||||
@ -46,7 +46,7 @@ export default Vue.extend({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-drive-file-chooser
|
root(isDark)
|
||||||
position fixed
|
position fixed
|
||||||
z-index 20000
|
z-index 20000
|
||||||
top 0
|
top 0
|
||||||
@ -59,10 +59,11 @@ export default Vue.extend({
|
|||||||
> .body
|
> .body
|
||||||
width 100%
|
width 100%
|
||||||
height 100%
|
height 100%
|
||||||
background #fff
|
background isDark ? #282c37 : #fff
|
||||||
|
|
||||||
> header
|
> header
|
||||||
border-bottom solid 1px #eee
|
border-bottom solid 1px isDark ? #1b1f29 : #eee
|
||||||
|
color isDark ? #fff : #111
|
||||||
|
|
||||||
> h1
|
> h1
|
||||||
margin 0
|
margin 0
|
||||||
@ -90,9 +91,15 @@ export default Vue.extend({
|
|||||||
line-height 42px
|
line-height 42px
|
||||||
width 42px
|
width 42px
|
||||||
|
|
||||||
> .mk-drive
|
> .drive
|
||||||
height calc(100% - 42px)
|
height calc(100% - 42px)
|
||||||
overflow scroll
|
overflow scroll
|
||||||
-webkit-overflow-scrolling touch
|
-webkit-overflow-scrolling touch
|
||||||
|
|
||||||
|
.cdxzvcfawjxdyxsekbxbfgtplebnoneb[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.cdxzvcfawjxdyxsekbxbfgtplebnoneb:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import * as EXIF from 'exif-js';
|
import * as EXIF from 'exif-js';
|
||||||
import * as hljs from 'highlight.js';
|
import * as hljs from 'highlight.js';
|
||||||
import gcd from '../../../common/scripts/gcd';
|
import { gcd } from '../../../../../prelude/math';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['file'],
|
props: ['file'],
|
||||||
|
@ -48,12 +48,14 @@ export default Vue.extend({
|
|||||||
onFollow(user) {
|
onFollow(user) {
|
||||||
if (user.id == this.u.id) {
|
if (user.id == this.u.id) {
|
||||||
this.u.isFollowing = user.isFollowing;
|
this.u.isFollowing = user.isFollowing;
|
||||||
|
this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnfollow(user) {
|
onUnfollow(user) {
|
||||||
if (user.id == this.u.id) {
|
if (user.id == this.u.id) {
|
||||||
this.u.isFollowing = user.isFollowing;
|
this.u.isFollowing = user.isFollowing;
|
||||||
|
this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ export default Vue.extend({
|
|||||||
userId: this.u.id
|
userId: this.u.id
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.u.isLocked && this.u.hasPendingFollowRequestFromYou) {
|
if (this.u.hasPendingFollowRequestFromYou) {
|
||||||
this.u = await (this as any).api('following/requests/cancel', {
|
this.u = await (this as any).api('following/requests/cancel', {
|
||||||
userId: this.u.id
|
userId: this.u.id
|
||||||
});
|
});
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
<span v-if="p.deletedAt" style="opacity: 0.5">(%i18n:@deleted%)</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"/>
|
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="media" v-if="p.media.length > 0">
|
<div class="files" v-if="p.files.length > 0">
|
||||||
<mk-media-list :media-list="p.media" :raw="true"/>
|
<mk-media-list :media-list="p.files" :raw="true"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p"/>
|
<mk-poll v-if="p.poll" :note="p"/>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
|
||||||
@ -75,13 +75,6 @@
|
|||||||
<div class="replies" v-if="!compact">
|
<div class="replies" v-if="!compact">
|
||||||
<x-sub v-for="note in replies" :key="note.id" :note="note"/>
|
<x-sub v-for="note in replies" :key="note.id" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<modal name="replyForm">
|
|
||||||
<mk-post-form @posted="replyFormClosed" @cancel="replyFormClosed" :reply="p"/>
|
|
||||||
</modal>
|
|
||||||
<modal name="renoteForm">
|
|
||||||
<mk-post-form @posted="renoteFormClosed" @cancel="renoteFormClosed" :renote="p"/>
|
|
||||||
</modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -92,6 +85,7 @@ import parse from '../../../../../mfm/parse';
|
|||||||
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
||||||
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
||||||
import XSub from './note.sub.vue';
|
import XSub from './note.sub.vue';
|
||||||
|
import { sum } from '../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
@ -120,7 +114,7 @@ export default Vue.extend({
|
|||||||
isRenote(): boolean {
|
isRenote(): boolean {
|
||||||
return (this.note.renote &&
|
return (this.note.renote &&
|
||||||
this.note.text == null &&
|
this.note.text == null &&
|
||||||
this.note.mediaIds.length == 0 &&
|
this.note.fileIds.length == 0 &&
|
||||||
this.note.poll == null);
|
this.note.poll == null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -130,9 +124,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
reactionsCount(): number {
|
reactionsCount(): number {
|
||||||
return this.p.reactionCounts
|
return this.p.reactionCounts
|
||||||
? Object.keys(this.p.reactionCounts)
|
? sum(Object.values(this.p.reactionCounts))
|
||||||
.map(key => this.p.reactionCounts[key])
|
|
||||||
.reduce((a, b) => a + b)
|
|
||||||
: 0;
|
: 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -192,19 +184,15 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
reply() {
|
reply() {
|
||||||
this.$modal.push('replyForm');
|
(this as any).apis.post({
|
||||||
},
|
reply: this.p
|
||||||
|
});
|
||||||
replyFormClosed() {
|
|
||||||
this.$modal.pop();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
renote() {
|
renote() {
|
||||||
this.$modal.push('renoteForm');
|
(this as any).apis.post({
|
||||||
},
|
renote: this.p
|
||||||
|
});
|
||||||
renoteFormClosed() {
|
|
||||||
this.$modal.pop();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
react() {
|
react() {
|
||||||
@ -380,7 +368,7 @@ root(isDark)
|
|||||||
> .mk-url-preview
|
> .mk-url-preview
|
||||||
margin-top 8px
|
margin-top 8px
|
||||||
|
|
||||||
> .media
|
> .files
|
||||||
> img
|
> img
|
||||||
display block
|
display block
|
||||||
max-width 100%
|
max-width 100%
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :class="$style.text"/>
|
<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :class="$style.text"/>
|
||||||
<a class="rp" v-if="p.renote != null">RP:</a>
|
<a class="rp" v-if="p.renote != null">RP:</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="media" v-if="p.media.length > 0">
|
<div class="files" v-if="p.files.length > 0">
|
||||||
<mk-media-list :media-list="p.media"/>
|
<mk-media-list :media-list="p.files"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
||||||
@ -60,13 +60,6 @@
|
|||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<modal name="replyForm">
|
|
||||||
<mk-post-form @posted="replyFormClosed" @cancel="replyFormClosed" :reply="p"/>
|
|
||||||
</modal>
|
|
||||||
<modal name="renoteForm">
|
|
||||||
<mk-post-form @posted="renoteFormClosed" @cancel="renoteFormClosed" :renote="p"/>
|
|
||||||
</modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -77,6 +70,7 @@ import parse from '../../../../../mfm/parse';
|
|||||||
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
||||||
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
||||||
import XSub from './note.sub.vue';
|
import XSub from './note.sub.vue';
|
||||||
|
import { sum } from '../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
@ -97,7 +91,7 @@ export default Vue.extend({
|
|||||||
isRenote(): boolean {
|
isRenote(): boolean {
|
||||||
return (this.note.renote &&
|
return (this.note.renote &&
|
||||||
this.note.text == null &&
|
this.note.text == null &&
|
||||||
this.note.mediaIds.length == 0 &&
|
this.note.fileIds.length == 0 &&
|
||||||
this.note.poll == null);
|
this.note.poll == null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -107,9 +101,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
reactionsCount(): number {
|
reactionsCount(): number {
|
||||||
return this.p.reactionCounts
|
return this.p.reactionCounts
|
||||||
? Object.keys(this.p.reactionCounts)
|
? sum(Object.values(this.p.reactionCounts))
|
||||||
.map(key => this.p.reactionCounts[key])
|
|
||||||
.reduce((a, b) => a + b)
|
|
||||||
: 0;
|
: 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -202,19 +194,15 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
reply() {
|
reply() {
|
||||||
this.$modal.push('replyForm');
|
(this as any).apis.post({
|
||||||
},
|
reply: this.p
|
||||||
|
});
|
||||||
replyFormClosed() {
|
|
||||||
this.$modal.pop();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
renote() {
|
renote() {
|
||||||
this.$modal.push('renoteForm');
|
(this as any).apis.post({
|
||||||
},
|
renote: this.p
|
||||||
|
});
|
||||||
renoteFormClosed() {
|
|
||||||
this.$modal.pop();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
react() {
|
react() {
|
||||||
@ -425,7 +413,7 @@ root(isDark)
|
|||||||
.mk-url-preview
|
.mk-url-preview
|
||||||
margin-top 8px
|
margin-top 8px
|
||||||
|
|
||||||
> .media
|
> .files
|
||||||
> img
|
> img
|
||||||
display block
|
display block
|
||||||
max-width 100%
|
max-width 100%
|
||||||
@ -482,10 +470,6 @@ root(isDark)
|
|||||||
&.reacted
|
&.reacted
|
||||||
color $theme-color
|
color $theme-color
|
||||||
|
|
||||||
&.menu
|
|
||||||
@media (max-width 350px)
|
|
||||||
display none
|
|
||||||
|
|
||||||
.note[data-darkmode]
|
.note[data-darkmode]
|
||||||
root(true)
|
root(true)
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ export default Vue.extend({
|
|||||||
prepend(note, silent = false) {
|
prepend(note, silent = false) {
|
||||||
//#region 弾く
|
//#region 弾く
|
||||||
const isMyNote = note.userId == this.$store.state.i.id;
|
const isMyNote = note.userId == this.$store.state.i.id;
|
||||||
const isPureRenote = note.renoteId != null && note.text == null && note.mediaIds.length == 0 && note.poll == null;
|
const isPureRenote = note.renoteId != null && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
||||||
|
|
||||||
if (this.$store.state.settings.showMyRenotes === false) {
|
if (this.$store.state.settings.showMyRenotes === false) {
|
||||||
if (isMyNote && isPureRenote) {
|
if (isMyNote && isPureRenote) {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-notify">
|
<div class="mk-notify" :class="pos">
|
||||||
<mk-notification-preview :notification="notification"/>
|
<div>
|
||||||
|
<mk-notification-preview :notification="notification"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -10,11 +12,16 @@ import * as anime from 'animejs';
|
|||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['notification'],
|
props: ['notification'],
|
||||||
|
computed: {
|
||||||
|
pos() {
|
||||||
|
return this.$store.state.device.mobileNotificationPosition;
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
anime({
|
anime({
|
||||||
targets: this.$el,
|
targets: this.$el,
|
||||||
bottom: '0px',
|
[this.pos]: '0px',
|
||||||
duration: 500,
|
duration: 500,
|
||||||
easing: 'easeOutQuad'
|
easing: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
@ -22,7 +29,7 @@ export default Vue.extend({
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
anime({
|
anime({
|
||||||
targets: this.$el,
|
targets: this.$el,
|
||||||
bottom: '-64px',
|
[this.pos]: `-${this.$el.offsetHeight}px`,
|
||||||
duration: 500,
|
duration: 500,
|
||||||
easing: 'easeOutQuad',
|
easing: 'easeOutQuad',
|
||||||
complete: () => this.$destroy()
|
complete: () => this.$destroy()
|
||||||
@ -35,15 +42,32 @@ export default Vue.extend({
|
|||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-notify
|
.mk-notify
|
||||||
|
$height = 78px
|
||||||
|
|
||||||
position fixed
|
position fixed
|
||||||
z-index 1024
|
z-index 1024
|
||||||
bottom -64px
|
|
||||||
left 0
|
left 0
|
||||||
|
right 0
|
||||||
width 100%
|
width 100%
|
||||||
height 64px
|
max-width 500px
|
||||||
|
height $height
|
||||||
|
margin 0 auto
|
||||||
|
padding 8px
|
||||||
pointer-events none
|
pointer-events none
|
||||||
-webkit-backdrop-filter blur(2px)
|
font-size 80%
|
||||||
backdrop-filter blur(2px)
|
|
||||||
background-color rgba(#000, 0.5)
|
&.bottom
|
||||||
|
bottom -($height)
|
||||||
|
|
||||||
|
&.top
|
||||||
|
top -($height)
|
||||||
|
|
||||||
|
> div
|
||||||
|
height 100%
|
||||||
|
-webkit-backdrop-filter blur(2px)
|
||||||
|
backdrop-filter blur(2px)
|
||||||
|
background-color rgba(#000, 0.5)
|
||||||
|
border-radius 7px
|
||||||
|
overflow hidden
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
126
src/client/app/mobile/views/components/post-form-dialog.vue
Normal file
126
src/client/app/mobile/views/components/post-form-dialog.vue
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ulveipglmagnxfgvitaxyszerjwiqmwl">
|
||||||
|
<div class="bg" ref="bg"></div>
|
||||||
|
<div class="main" ref="main">
|
||||||
|
<mk-post-form ref="form"
|
||||||
|
:reply="reply"
|
||||||
|
:renote="renote"
|
||||||
|
:initial-text="initialText"
|
||||||
|
:instant="instant"
|
||||||
|
@posted="onPosted"
|
||||||
|
@cancel="onCanceled"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import * as anime from 'animejs';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
reply: {
|
||||||
|
type: Object,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
renote: {
|
||||||
|
type: Object,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
initialText: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
instant: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
(this.$refs.bg as any).style.pointerEvents = 'auto';
|
||||||
|
anime({
|
||||||
|
targets: this.$refs.bg,
|
||||||
|
opacity: 1,
|
||||||
|
duration: 100,
|
||||||
|
easing: 'linear'
|
||||||
|
});
|
||||||
|
|
||||||
|
anime({
|
||||||
|
targets: this.$refs.main,
|
||||||
|
opacity: 1,
|
||||||
|
translateY: [-16, 0],
|
||||||
|
duration: 300,
|
||||||
|
easing: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
focus() {
|
||||||
|
this.$refs.form.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
(this.$refs.bg as any).style.pointerEvents = 'none';
|
||||||
|
anime({
|
||||||
|
targets: this.$refs.bg,
|
||||||
|
opacity: 0,
|
||||||
|
duration: 300,
|
||||||
|
easing: 'linear'
|
||||||
|
});
|
||||||
|
|
||||||
|
(this.$refs.main as any).style.pointerEvents = 'none';
|
||||||
|
anime({
|
||||||
|
targets: this.$refs.main,
|
||||||
|
opacity: 0,
|
||||||
|
translateY: 16,
|
||||||
|
duration: 300,
|
||||||
|
easing: 'easeOutQuad',
|
||||||
|
complete: () => this.$destroy()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onPosted() {
|
||||||
|
this.$emit('posted');
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
onCanceled() {
|
||||||
|
this.$emit('cancel');
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.ulveipglmagnxfgvitaxyszerjwiqmwl
|
||||||
|
> .bg
|
||||||
|
display block
|
||||||
|
position fixed
|
||||||
|
z-index 10000
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
background rgba(#000, 0.7)
|
||||||
|
opacity 0
|
||||||
|
pointer-events none
|
||||||
|
|
||||||
|
> .main
|
||||||
|
display block
|
||||||
|
position fixed
|
||||||
|
z-index 10000
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
height 100%
|
||||||
|
overflow auto
|
||||||
|
margin 0 auto 0 auto
|
||||||
|
opacity 0
|
||||||
|
transform translateY(-16px)
|
||||||
|
|
||||||
|
</style>
|
@ -59,6 +59,7 @@ import MkVisibilityChooser from '../../../common/views/components/visibility-cho
|
|||||||
import getFace from '../../../common/scripts/get-face';
|
import getFace from '../../../common/scripts/get-face';
|
||||||
import parse from '../../../../../mfm/parse';
|
import parse from '../../../../../mfm/parse';
|
||||||
import { host } from '../../../config';
|
import { host } from '../../../config';
|
||||||
|
import { erase } from '../../../../../prelude/array';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
@ -105,9 +106,9 @@ export default Vue.extend({
|
|||||||
computed: {
|
computed: {
|
||||||
draftId(): string {
|
draftId(): string {
|
||||||
return this.renote
|
return this.renote
|
||||||
? 'renote:' + this.renote.id
|
? `renote:${this.renote.id}`
|
||||||
: this.reply
|
: this.reply
|
||||||
? 'reply:' + this.reply.id
|
? `reply:${this.reply.id}`
|
||||||
: 'note';
|
: 'note';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -170,6 +171,8 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.focus();
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.focus();
|
this.focus();
|
||||||
});
|
});
|
||||||
@ -198,12 +201,12 @@ export default Vue.extend({
|
|||||||
|
|
||||||
attachMedia(driveFile) {
|
attachMedia(driveFile) {
|
||||||
this.files.push(driveFile);
|
this.files.push(driveFile);
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
},
|
},
|
||||||
|
|
||||||
detachMedia(file) {
|
detachMedia(file) {
|
||||||
this.files = this.files.filter(x => x.id != file.id);
|
this.files = this.files.filter(x => x.id != file.id);
|
||||||
this.$emit('change-attached-media', this.files);
|
this.$emit('change-attached-files', this.files);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChangeFile() {
|
onChangeFile() {
|
||||||
@ -227,7 +230,7 @@ export default Vue.extend({
|
|||||||
navigator.geolocation.getCurrentPosition(pos => {
|
navigator.geolocation.getCurrentPosition(pos => {
|
||||||
this.geo = pos.coords;
|
this.geo = pos.coords;
|
||||||
}, err => {
|
}, err => {
|
||||||
alert('%i18n:@error%: ' + err.message);
|
alert(`%i18n:@error%: ${err.message}`);
|
||||||
}, {
|
}, {
|
||||||
enableHighAccuracy: true
|
enableHighAccuracy: true
|
||||||
});
|
});
|
||||||
@ -260,14 +263,14 @@ export default Vue.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeVisibleUser(user) {
|
removeVisibleUser(user) {
|
||||||
this.visibleUsers = this.visibleUsers.filter(u => u != user);
|
this.visibleUsers = erase(user, this.visibleUsers);
|
||||||
},
|
},
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.text = '';
|
this.text = '';
|
||||||
this.files = [];
|
this.files = [];
|
||||||
this.poll = false;
|
this.poll = false;
|
||||||
this.$emit('change-attached-media');
|
this.$emit('change-attached-files');
|
||||||
},
|
},
|
||||||
|
|
||||||
post() {
|
post() {
|
||||||
@ -275,7 +278,7 @@ export default Vue.extend({
|
|||||||
const viaMobile = this.$store.state.settings.disableViaMobile !== true;
|
const viaMobile = this.$store.state.settings.disableViaMobile !== true;
|
||||||
(this as any).api('notes/create', {
|
(this as any).api('notes/create', {
|
||||||
text: this.text == '' ? undefined : this.text,
|
text: this.text == '' ? undefined : this.text,
|
||||||
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
fileIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
|
||||||
replyId: this.reply ? this.reply.id : undefined,
|
replyId: this.reply ? this.reply.id : undefined,
|
||||||
renoteId: this.renote ? this.renote.id : undefined,
|
renoteId: this.renote ? this.renote.id : undefined,
|
||||||
poll: this.poll ? (this.$refs.poll as any).get() : undefined,
|
poll: this.poll ? (this.$refs.poll as any).get() : undefined,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user