Compare commits
	
		
			423 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 6d9716f90e | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | aa31061d90 | ||
|   | acc7797dff | ||
|   | 7959196dc7 | ||
|   | c6ff6939a5 | ||
|   | 769960f29e | ||
|   | d92e9759f3 | ||
|   | bf7e19b288 | ||
|   | 98954cd6d4 | ||
|   | 538bb978ed | ||
|   | 10232c5866 | ||
|   | 5cd6a0db16 | ||
|   | ff0a05a2d6 | ||
|   | e34b264af2 | ||
|   | 00d79487cd | ||
|   | 3cace734c7 | ||
|   | f428372869 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 5dd2feba9b | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | a1b026239e | ||
|   | 40735ce76b | ||
|   | 4a00c13b33 | ||
|   | 8e359d54bd | ||
|   | 2448bf4e4e | ||
|   | 91e0fc8c62 | ||
|   | b4f86feddb | ||
|   | ccf8e44acc | ||
|   | 451acb77df | ||
|   | e2c6227f47 | ||
|   | ebd1c877ad | ||
|   | 498094b3c7 | ||
|   | 1cc183ecdb | ||
|   | e8948452fd | ||
|   | ade7e62836 | ||
|   | 395cfa6108 | ||
|   | b5ff2abdb9 | ||
|   | 229e85b2c5 | ||
|   | 37058e3480 | ||
|   | a1b82e9723 | ||
|   | db943df0c8 | ||
|   | ff8d300ea8 | ||
|   | 8b490b9b94 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | f83f8631ac | ||
|   | 1915ccabdd | ||
|   | 6fea2f52f1 | ||
|   | f77eaaa08a | ||
|   | 7c5bc03492 | ||
|   | 72a1af6cd4 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 4bce6f14f3 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | a38ce86f87 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | f539491502 | ||
|   | d279f8e9ff | ||
|   | eaec936fa6 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 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 | ||
|   | 8ee771ca77 | ||
|   | 488bbc9651 | ||
|   | 29b2bdf613 | ||
|   | 7e35048829 | ||
|   | 4d6b9f62e5 | ||
|   | 5f9a9867eb | ||
|   | 059a8e07d2 | ||
|   | cf82f56e66 | ||
|   | 2778bd14d4 | ||
|   | 5b0446739c | ||
|   | 55f235d0ac | ||
|   | 4ec44c68e9 | ||
|   | e6952d499a | ||
|   | e0b82f827b | ||
|   | 0bccb17e82 | ||
|   | b251b8c6a9 | ||
|   | c2a62f632b | ||
|   | 359da9a5a1 | ||
|   | 2a235151ed | ||
|   | 9e318d5ebc | ||
|   | 6819eb3b4d | ||
|   | 4c6fb60dd2 | ||
|   | bffb9a5c45 | ||
|   | dca4053a67 | ||
|   | fd07f00d14 | ||
|   | bbeb6d534e | ||
|   | 37b5afa1a3 | ||
|   | 63b8af4531 | ||
|   | e89e76076a | ||
|   | 18b4f74cdb | ||
|   | b80d0a3b12 | ||
|   | e53dde385c | ||
|   | 6a7a4c20e6 | ||
|   | 6434dac04d | ||
|   | 5deb1bf40e | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 9cd334576c | ||
|   | ae36bf301a | ||
|   | 9f60688d37 | ||
|   | 6a5a9de795 | ||
|   | ca0ea9e57c | ||
|   | a77a7e8112 | ||
|   | b26ea2edc0 | ||
|   | 02b99dfd76 | ||
|   | af02b0f115 | ||
|   | 9b3c379678 | ||
|   | a423fd7695 | ||
|   | de6e1d8c9b | ||
|   | d9db3e8629 | ||
|   | ac1c81b7d6 | ||
|   | 49b2eec534 | ||
|   | f0abc46429 | ||
|   | 9fd4f5ee0a | ||
|   | 5e202c3def | ||
|   | 48223c1c76 | ||
|   | dddf7834cc | ||
|   | 66ef30b2cc | ||
|   | f802fe57b9 | ||
|   | ead884ce89 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 6a87e9f690 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 5b943722fb | ||
|   | 4d92b14308 | ||
|   | 167c96d14e | ||
|   | 8a42373753 | ||
|   | c1751a9b84 | ||
|   | 4e11da98d9 | ||
|   | 1b7d98c17e | ||
|   | 3038434712 | ||
|   | 117ab633a1 | ||
|   | e50fa4762d | ||
|   | aed1e839ba | ||
|   | 00f2974a2a | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 073c96af47 | ||
|   | 71da498364 | ||
|   | 8e9c11f160 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 98f6b23249 | ||
|   | 89288d8e0d | ||
|   | 724121eeaa | ||
|   | edee95a5ca | ||
|   | 0c2361bf72 | ||
|   | 92f8dc48e3 | ||
|   | 06a0fff4b0 | ||
|   | d55e4621ac | ||
|   | bc6bda3714 | ||
|   | d3aafd3f13 | ||
|   | 1a508de1c4 | ||
|   | 768cc0aff5 | ||
|   | 67f4c1f429 | ||
|   | 2d4ceec0a5 | ||
|   | 3e2a0cd89a | ||
|   | d1f4f2f663 | ||
|   | 6e3bf26cad | ||
|   | 672377f116 | ||
|   | 80ee5afba7 | ||
|   | f55fcd3305 | ||
|   | 64fc14ade5 | ||
|   | 807f245657 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 62f966dc27 | ||
|   | 09f97bf7a7 | ||
|   | 69460e494c | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 9bef723346 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | b99eabb2cf | ||
|   | 17be3f3d0f | ||
|   | 05fe2cb173 | ||
|   | 428be14c27 | ||
|   | a04fa8441e | ||
|   | 7bcfa84e1a | ||
|   | 1cc5986df3 | ||
|   | 7aa5d03875 | ||
|   | a59fbfac19 | ||
|   | 677f9ee8f6 | ||
|   | f4a16be2b4 | ||
|   | 46b967ee4a | ||
|   | 78568accd1 | ||
|   | e9f20a0fad | ||
|   | bbd9894e6b | ||
|   | f92745e381 | ||
|   | 2762b78bcc | ||
|   | 2d4ed2c8c2 | ||
|   | 2de8e8c358 | ||
|   | eb7b638db3 | ||
|   | 321e851b26 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | f8340be3bf | ||
|   | 02341ceb6e | ||
|   | 3dcdd7a5d7 | ||
|   | 85188b5de2 | ||
|   | b721d049c6 | ||
|   | e518fff944 | ||
|   | 048128c7e1 | ||
|   | d3717449c2 | ||
|   | 04de6218d3 | ||
|   | 0082473d78 | ||
|   | 77baca8e6e | ||
|   | 6a7169630c | ||
|   | 6b2089e043 | ||
|   | 14ad3af30d | ||
|   | e7e6d833b7 | ||
|   | d1a9561135 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | c7bda6f908 | ||
|   | ef43721e32 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | ba6cd874aa | ||
|   | f283d2423f | ||
|   | c07f668f14 | ||
|   | 596524a63c | ||
|   | 975e4dd285 | ||
|   | 09b05c8552 | ||
|   | 530ee6f80e | ||
|   | 6ad31dca76 | ||
|   | d423f8ae57 | ||
|   | 8e5ce7f8e3 | ||
|   | 33dfc21e4b | ||
|   | 3266f3948a | ||
|   | 7259887124 | ||
|   | 800de03187 | ||
|   | 78ba305e5c | ||
|   | bfed1475bb | ||
|   | 3281d263c4 | ||
|   | a9a1798e3a | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 6806eafaed | ||
|   | 3e20ea5b2e | ||
|   | 3f30a69b8b | ||
|   | 2d2e16d9f6 | ||
|   | 9c32118b77 | ||
|   | ecf2eb4738 | ||
|   | 3d754ea7eb | ||
|   | f755f24560 | ||
|   | 699879d95d | ||
|   | 6677508ba7 | ||
|   | 58da32358b | ||
|   | 491bc75095 | ||
|   | b9eafeee3f | ||
|   | c56ff5d88d | ||
|   | f5dd83a44a | ||
|   | 9a295a85b1 | ||
|   | 8e06d93c31 | ||
|   | 1a42200137 | ||
|   | bbf33d2475 | ||
|   | 93203ebfd1 | ||
|   | 67053eeaa0 | ||
|   | 43baf4ad6a | ||
|   | 5b2a36e47b | ||
|   | 2a0862a24e | ||
|   | ce31027b2e | ||
|   | 3f66c77821 | ||
|   | bc713656ec | ||
|   | 46d89faebc | ||
|   | 7135c0e308 | ||
|   | 1962bfb4a5 | ||
|   | a1fca2550e | ||
|   | c17f99b7a5 | ||
|   | 7cd76d60c2 | ||
|   | fa7c8cfe5b | ||
|   | 05fb8d35af | ||
|   | eaa827e2d9 | ||
|   | f365ea4585 | ||
|   | 5d2e43ffb9 | ||
|   | e9a97ed99a | ||
|   | fe98102600 | ||
|   | aae8845664 | ||
|   | 81a4388ecc | ||
|   | be3ab026fd | ||
|   | f92f9d8cb0 | ||
|   | 08a59591ae | ||
|   | a09a244242 | ||
|   | 483a61d90d | ||
|   | 385fb7586b | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | c624da70ef | ||
|   | 675668c395 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | bc9c7efe85 | ||
|   | 2488d40421 | ||
|   | bf7875bfaa | ||
|   | a84fa30774 | ||
|   | c19a763b3d | ||
|   | 0875460974 | ||
|   | f0b08d3936 | ||
|   | 16520c7b4c | ||
|   | 65549d06d9 | ||
|   | 52da66d550 | ||
|   | 251c3c3fe4 | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | ce2d2a10c1 | ||
|   | 3b6d242ef6 | ||
|   | 0ebe801af4 | ||
|   | 05daa7ac7d | ||
|   | 990a583e5e | ||
|   | d9b02a18bf | ||
|   | 30aae79e5c | ||
|   | a149c121fb | ||
|   | 47f4b51207 | ||
|   | 79f4d886d0 | ||
|   | 2b556aba03 | ||
|   | 4f62043b0c | ||
|   | b1ae304c51 | ||
|   | 425bc032d0 | ||
|   | 0156b75bde | ||
|   | 8bc8fc58de | ||
|   | 9bf847b1fb | ||
|   | 0b078d203b | ||
|   | df59018b47 | ||
|   | b2681dcb5d | ||
|   | 46fa471636 | ||
|   | 5f2c441996 | ||
|   | a79cc42b26 | ||
|   | 739c993911 | ||
|   | cb180e00de | ||
|   | 4d46a61051 | ||
|   | 81969ea8b2 | ||
|   | ac474f3884 | ||
|   | a39aaf6eb1 | ||
|   | 68a7661f08 | ||
|   | ffcb2f755c | ||
| ![greenkeeper[bot]](/assets/img/avatar_default.png)  | 366e0d6bde | ||
|   | b3a3238e43 | ||
|   | 92828028db | ||
|   | bd97e315ff | ||
|   | 51083419f5 | ||
|   | b23bfd4d86 | ||
|   | 7de3e847bd | ||
|   | 0d1a541dba | ||
|   | 2717109fe2 | ||
|   | 60ca0626ce | ||
|   | 15dae0ae65 | ||
|   | 1c680118a0 | ||
|   | ad5efbba59 | ||
|   | 6dc7baa5e9 | ||
|   | c2b886e750 | ||
|   | edb61e52c5 | ||
|   | 1f53d1a149 | 
| @@ -1,18 +1,19 @@ | ||||
| #!/usr/bin/env bash | ||||
| # BEARER_TOKEN= | ||||
| # CAMPAIGN_ID= | ||||
| # GITHUB_TOKEN= | ||||
| # HEAD='acid-chicken:patch-autogen' | ||||
| # 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_BEARER_TOKEN= | ||||
| # __MISSKEY_CAMPAIGN_ID= | ||||
| # __MISSKEY_GITHUB_TOKEN= | ||||
| # __MISSKEY_HEAD=acid-chicken:patch-autogen | ||||
| # __MISSKEY_REPO=syuilo/misskey | ||||
| # __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)/.." && \ | ||||
| touch null.cache && \ | ||||
| rm *.cache && \ | ||||
| git checkout master && \ | ||||
| git pull origin master && \ | ||||
| git pull upstream master && \ | ||||
| git checkout $__MISSKEY_BRANCH && \ | ||||
| git pull origin $__MISSKEY_BRANCH && \ | ||||
| git pull upstream $__MISSKEY_BRANCH && \ | ||||
| git stash && \ | ||||
| git rebase -f upstream/master && \ | ||||
| git rebase -f upstream/$__MISSKEY_BRANCH && \ | ||||
| git branch patch-autogen && \ | ||||
| git checkout patch-autogen && \ | ||||
| git reset --hard HEAD || \ | ||||
| @@ -20,12 +21,12 @@ exit 1 | ||||
| touch patreon.md.cache && \ | ||||
| rm 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 : | ||||
|  do | ||||
|   touch 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 && \ | ||||
|   rm patreon.cache && \ | ||||
|   cat patreon.raw.cache | \ | ||||
| @@ -42,31 +43,31 @@ while : | ||||
|   xargs -I% echo '<td><a href="%</a></td>' >> patreon.md.cache && \ | ||||
|   echo '</tr></table>' >> patreon.md.cache || \ | ||||
|   exit 1 | ||||
|   NEW_URL="$(cat patreon.raw.cache | jq -r '.links.next')" | ||||
|   test "$NEW_URL" = 'null' && \ | ||||
|   new_url="$(cat patreon.raw.cache | jq -r '.links.next')" | ||||
|   test "$new_url" = 'null' && \ | ||||
|   break || \ | ||||
|   URL="$NEW_URL" | ||||
|   URL="$url" | ||||
| done | ||||
| IGNORE= && \ | ||||
| ignore= && \ | ||||
| echo -e "\n**Last updated:** $(date -uR | sed 's/\+0000/UTC/')\n<!-- PATREON_END -->" >> patreon.md.cache && \ | ||||
| touch README.md && \ | ||||
| touch .autogen/README.md && \ | ||||
| rm .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 | ||||
|   if [[ -z "$IGNORE" ]] | ||||
|   if [[ -z "$ignore" ]] | ||||
|    then | ||||
|     if [[ "$LINE" = '<!-- PATREON_START -->' ]] | ||||
|     if [[ "$line" = '<!-- PATREON_START -->' ]] | ||||
|      then | ||||
|       IGNORE='PATREON_INSIDE' | ||||
|       ignore='PATREON_INSIDE' | ||||
|      else | ||||
|       echo "$LINE" >> README.md | ||||
|       echo "$line" >> README.md | ||||
|     fi | ||||
|    else | ||||
|     if [[ "$LINE" = '<!-- PATREON_END -->' ]] | ||||
|      then | ||||
|       IGNORE= | ||||
|       ignore= | ||||
|       cat patreon.md.cache >> README.md | ||||
|     fi | ||||
|   fi | ||||
| @@ -80,7 +81,7 @@ test 4 -lt $(cat diff.cache | wc -l) && \ | ||||
| git add README.md && \ | ||||
| git commit -m 'Update README.md [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 checkout master | ||||
| git checkout $__MISSKEY_BRANCH | ||||
| git branch -D patch-autogen | ||||
|   | ||||
| @@ -138,3 +138,6 @@ drive: | ||||
|  | ||||
| # Clustering | ||||
| # clusterLimit: 1 | ||||
|  | ||||
| # Summaly proxy | ||||
| # summalyProxy: "http://example.com" | ||||
|   | ||||
| @@ -47,13 +47,13 @@ Please run `node cli/migration/5.0.0` before launch. | ||||
|  | ||||
| オセロがリバーシに変更されました。 | ||||
|  | ||||
| Othello is now Reversi. | ||||
| Othello is rename to Reversi. | ||||
|  | ||||
| ### Migration | ||||
|  | ||||
| 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 | ||||
| ----- | ||||
|   | ||||
| @@ -1,27 +1,27 @@ | ||||
| # Contribution guide | ||||
| :v: Misskeyへの貢献ありがとうございます。 :v: | ||||
| :v: Thanks for your contributions :v: | ||||
|  | ||||
| ## Issueの報告 | ||||
| 新機能の提案や不具合の報告は https://github.com/syuilo/misskey/issues で管理しています。 | ||||
| Issueを作成する前に、既に同じIssueが作成されていないかご確認ください。 | ||||
| もし既にIssueが作成されている場合は、既存のIssueにコメントをしたりリアクションをするようお願いします。 | ||||
| ## Issues | ||||
| Feature suggestions and bug reports are filed in https://github.com/syuilo/misskey/issues . | ||||
| Before creating a new issue, please search existing issues to avoid duplication. | ||||
| If you find the existing issue, please add your reaction or comment to the issue. | ||||
|  | ||||
| ## Issueの解決 | ||||
| [pr-welcomeのラベルがついているIssue](https://github.com/syuilo/misskey/labels/pr-welcome) | ||||
| の解決を目的としたPull Requestを作成してくださると非常にありがたいです。 | ||||
| ## Internationalization (i18n) | ||||
| Please see [Translation guide](./docs/translate.en.md). | ||||
|  | ||||
| ## 翻訳の改善 | ||||
| ソースコード中の `%i18n:id%` という形の文字列は、言語ファイルの対応するテキストに置換されます。 | ||||
| 言語ファイルは /locales ディレクトリに存在します。 | ||||
| ## Localization (l10n) | ||||
| Please use [Crowdin](https://crowdin.com/project/misskey) for localization. | ||||
|  | ||||
| ## ドキュメントの編集 | ||||
| 現在Misskeyはドキュメントが大きく不足しています。 | ||||
| ドキュメントは /docs ディレクトリに存在します。 | ||||
|  | ||||
|  | ||||
| ## テストの追加 | ||||
| 現在Misskeyはテストが大きく不足しています。 | ||||
| テストコードは /test ディレクトリに存在します。 | ||||
| ## Documentation | ||||
| * Documents for contributors are located in `/docs`. | ||||
| * Documents for instance admins are located in `/docs`. | ||||
| * Documents for end users are located in `src/docs`. | ||||
|  | ||||
| ## 自動テスト及び自動リリース | ||||
| Travis CIで行っています。 | ||||
| 設定ファイルは /.travis に存在します。 | ||||
| ## Test | ||||
| * Test codes are located in `/test`. | ||||
|  | ||||
| ## 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 | ||||
| * User lists | ||||
| * Customizable column view (called MisskeyDeck) | ||||
|   * and widgets! | ||||
| * Customizable widgets | ||||
| * Private messages | ||||
| * ActivityPub support | ||||
|  | ||||
| @@ -32,40 +32,29 @@ and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz | ||||
|  | ||||
| :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!** | ||||
|  | ||||
| ### i18n | ||||
|  | ||||
| Please see [Translation guide](./docs/translate.en.md). | ||||
|  | ||||
| ### l10n | ||||
|  | ||||
| Misskey is using Crowdin for l10n. | ||||
|  | ||||
| [](https://crowdin.com/project/misskey) | ||||
| Please see [Contribution guide](./CONTRIBUTING.md). | ||||
|  | ||||
| :heart: Backers & Sponsors | ||||
| ---------------------------------------------------------------- | ||||
| <!-- PATREON_START --> | ||||
| <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/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/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/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://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> | ||||
| <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=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/AxellaMC">Axella</a></td> | ||||
| <td><a href="https://www.patreon.com/user?u=3384329">べすれい</a></td> | ||||
| <td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td> | ||||
| <td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td> | ||||
| @@ -76,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/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/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/12959468/c249e15aebec4424b5c0f427173671b6/1?token-time=2145916800&token-hash=lubpCEdxAkxPlpR2O6bvZ7BIh8Q4nGf-U_mE1qpjVAQ%3D" alt="fujishan"></td> | ||||
| </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=12931605">Reiju</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/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/fujishan">fujishan</a></td> | ||||
| </tr></table> | ||||
|  | ||||
| **Last updated:** Wed, 22 Aug 2018 05:25:06 UTC | ||||
| **Last updated:** Sun, 02 Sep 2018 05:30:06 UTC | ||||
| <!-- PATREON_END --> | ||||
|  | ||||
| :four_leaf_clover: Copyright | ||||
|   | ||||
| @@ -1,40 +0,0 @@ | ||||
| const { default: User, deleteUser } = require('../built/models/user'); | ||||
| const { default: zip } = require('@prezzemolo/zip') | ||||
|  | ||||
| const migrate = async (user) => { | ||||
| 	try { | ||||
| 		await deleteUser(user._id); | ||||
| 		return true; | ||||
| 	} catch (e) { | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| async function main() { | ||||
| 	const count = await User.count({ | ||||
| 		uri: /#/ | ||||
| 	}); | ||||
|  | ||||
| 	const dop = 1 | ||||
| 	const idop = ((count - (count % dop)) / dop) + 1 | ||||
|  | ||||
| 	return zip( | ||||
| 		1, | ||||
| 		async (time) => { | ||||
| 			console.log(`${time} / ${idop}`) | ||||
| 			const doc = await User.find({ | ||||
| 				uri: /#/ | ||||
| 			}, { | ||||
| 				limit: dop, skip: time * dop | ||||
| 			}) | ||||
| 			return Promise.all(doc.map(migrate)) | ||||
| 		}, | ||||
| 		idop | ||||
| 	).then(a => { | ||||
| 		const rv = [] | ||||
| 		a.forEach(e => rv.push(...e)) | ||||
| 		return rv | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| main().then(console.dir).catch(console.error) | ||||
| @@ -54,7 +54,7 @@ Please visit https://www.google.com/recaptcha/intro/ and generate 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. | ||||
|  | ||||
| ``` 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)` | ||||
| 3. `npm install` | ||||
| 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)` | ||||
| 3. `npm install` | ||||
| 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... | ||||
| * i18n ... please see [Translation guide](../docs/translate.en.md). | ||||
| * l10n ... please visit https://crowdin.com/project/misskey | ||||
| Please see [Contribution guide](../CONTRIBUTING.md) for more information. | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "引き分け" | ||||
|     my-turn: "あなたのターンです" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "引き分け" | ||||
|     my-turn: "あなたのターンです" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "Entwickler" | ||||
|   feedback: "Feedback" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "Diese Anmerkung favorisieren" | ||||
|   pin: "An die Profilseite pinnen" | ||||
|   delete: "Löschen" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "Direkt" | ||||
|   specified-desc: "Poste nur für bestimmte Benutzer" | ||||
|   private: "Privat" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "Laden" | ||||
|   no-broadcasts: "Keine Broadcasts" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "Serverinformationen" | ||||
|   toggle: "Sicht umschalten" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Schwarz ... komplett" | ||||
|   notes: "Blau ... Hinweise" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "Übergang in Fensterköpfen" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "Zeige Antworten" | ||||
|   show-my-renotes: "Zeige meine Reposts auf der Zeitleiste" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -84,9 +84,10 @@ common: | ||||
|   my-token-regenerated: "Your token has been regenerated, so you will be signed out." | ||||
|   i-like-sushi: "I prefer sushi rather than pudding" | ||||
|   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" | ||||
|   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: | ||||
|     drawn: "Draw" | ||||
|     my-turn: "Your turn" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "Developers" | ||||
|   feedback: "Feedback" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "Details" | ||||
|   copy-link: "Copy link" | ||||
|   favorite: "Favorite this note" | ||||
|   pin: "Pin to your profile" | ||||
|   delete: "Delete" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "Direct" | ||||
|   specified-desc: "Post to specified users only" | ||||
|   private: "Private" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{} users mentioned" | ||||
|   empty: "No popular hashtag trends" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "Fetching" | ||||
|   no-broadcasts: "No announcements" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "Toggle views" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "Hashtags" | ||||
|   count: "{} users mentioned" | ||||
|   empty: "No popular hashtag trends" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "Server info" | ||||
|   toggle: "Toggle views" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "Uploading a new avatar" | ||||
|   avatar-updated: "Successfully updated the avatar" | ||||
|   choose-avatar: "Select an image for the avatar" | ||||
|   invalid-filetype: "This filetype is not acceptable here" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "Use gradients on window headers" | ||||
|   post-form-on-timeline: "Display post form at the top of the timeline" | ||||
|   suggest-recent-hashtags: "Show recent popular hashtags on the post form" | ||||
|   show-clock-on-header: "Show clock on upper-right" | ||||
|   show-reply-target: "Display reply target" | ||||
|   show-my-renotes: "Show my renotes in the timeline" | ||||
|   show-renoted-my-notes: "Show renoted my posts in timelines" | ||||
| @@ -819,7 +825,7 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "Dashboard" | ||||
|   all-users: "All Users" | ||||
|   original-users: "Users on this instance" | ||||
|   all-notes: "All Posts" | ||||
|   all-notes: "All the posts" | ||||
|   original-notes: "Posts on this instance" | ||||
|   invite: "Invite" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "Reposted by {}" | ||||
|   private: "This post is private" | ||||
|   deleted: "This post has been deleted" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "All Users" | ||||
|   original-users: "Users on this instance" | ||||
|   all-notes: "All the posts" | ||||
|   original-notes: "Posts on this instance" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "More details..." | ||||
|   gotit: "Got it!" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "Logging in..." | ||||
|   signup-button: "Sign up" | ||||
|   timeline: "Timeline" | ||||
|   announcements: "Announcements" | ||||
|   photos: "Recent uploaded" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey storage" | ||||
| @@ -1066,7 +1079,7 @@ mobile/views/pages/favorites.vue: | ||||
|   title: "Favorites" | ||||
| mobile/views/pages/user-lists.vue: | ||||
|   title: "Lists" | ||||
|   enter-list-name: "Enter list name" | ||||
|   enter-list-name: "Enter a name of the list to make" | ||||
| mobile/views/pages/drive.vue: | ||||
|   drive: "Drive" | ||||
|   more: "Load more" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "Post design" | ||||
|   post-style-standard: "Standard" | ||||
|   post-style-smart: "Smart" | ||||
|   notification-position: "Notification style" | ||||
|   notification-position-bottom: "Bottom" | ||||
|   notification-position-top: "Top" | ||||
|   behavior: "Behavior" | ||||
|   fetch-on-scroll: "Endless loading on scroll" | ||||
|   disable-via-mobile: "Don't mark the post as 'from mobile'" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "Updates will be applied after reloading the page" | ||||
|   settings: "Settings" | ||||
|   signout: "Sign out" | ||||
|   sound: "Sounds" | ||||
|   enableSounds: "Enable sounds" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "Follows you" | ||||
|   following: "Following" | ||||
|   | ||||
| @@ -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." | ||||
|   application-authorization: "Autorizaciones de la aplicación." | ||||
|   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!" | ||||
|   customization-tips: | ||||
|     title: "Consejos de personalización" | ||||
| @@ -58,7 +58,7 @@ common: | ||||
|     friday: "Viernes" | ||||
|     saturday: "Sábado" | ||||
|   reactions: | ||||
|     like: "いいね" | ||||
|     like: "Me gusta" | ||||
|     love: "amor" | ||||
|     laugh: "risa" | ||||
|     hmm: "hmm" | ||||
| @@ -84,9 +84,10 @@ common: | ||||
|   my-token-regenerated: "Tu token se ha regenerado vas a ser desconectado." | ||||
|   i-like-sushi: "Prefiero sushi a pudín" | ||||
|   show-reversi-board-labels: "Mostrar etiquetas de filas y columnas en Reversi" | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   use-contrast-reversi-stones: "Hacer el color de la piedra claro en Reversi" | ||||
|   verified-user: "Cuenta verificada" | ||||
|   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: | ||||
|     drawn: "Empatado" | ||||
|     my-turn: "Mi turno" | ||||
| @@ -170,9 +171,9 @@ common/views/components/games/reversi/reversi.vue: | ||||
| common/views/components/games/reversi/reversi.game.vue: | ||||
|   surrender: "Rendirse" | ||||
|   surrendered: "Por rendirse" | ||||
|   is-llotheo: "石の少ない方が勝ち(ロセオ)" | ||||
|   looped-map: "ループマップ" | ||||
|   can-put-everywhere: "どこでも置けるモード" | ||||
|   is-llotheo: "El último gana (Llotheo)" | ||||
|   looped-map: "Mapa en bucle" | ||||
|   can-put-everywhere: "Puedes colocar donde quieras" | ||||
| common/views/components/games/reversi/reversi.index.vue: | ||||
|   title: "Misskey Reversi" | ||||
|   sub-title: "¡Juega Reversi con tus amigos!" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "Desarrolladores" | ||||
|   feedback: "Opiniones" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "Detalles" | ||||
|   copy-link: "Copiar enlace" | ||||
|   favorite: "Me gusta esta nota" | ||||
|   pin: "Fijar en el perfil" | ||||
|   delete: "Borrar" | ||||
| @@ -288,10 +291,10 @@ common/views/components/signin.vue: | ||||
|   signin: "Entra" | ||||
|   or: "O" | ||||
|   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: | ||||
|   invitation-code: "招待コード" | ||||
|   invitation-info: "招待コードをお持ちでない方は、<a href=\"{}\">管理者</a>までご連絡ください。" | ||||
|   invitation-code: "Código de invitación" | ||||
|   invitation-info: "Si no tienes un código de invitación, por favor contacta un <a href=\"{}\">administrador</a>." | ||||
|   username: "Usuario" | ||||
|   checking: "Comprobando..." | ||||
|   available: "Disponible" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "Directo" | ||||
|   specified-desc: "Publica solo para los seguidores que quieras" | ||||
|   private: "Privada" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "Recuperando" | ||||
|   no-broadcasts: "Sin emisión" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "Alternar vistas" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "Etiquetas" | ||||
|   count: "{} usuarios mencionados" | ||||
|   empty: "Ninguna tendencia popular ahora" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "Información del servidor" | ||||
|   toggle: "Alternar vistas" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "Cargando un nuevo avatar" | ||||
|   avatar-updated: "Avatar actualizado" | ||||
|   choose-avatar: "Escoge una imagen de avatar" | ||||
|   invalid-filetype: "Este tipo de archivo no es compatible aquí" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Negro ... Total" | ||||
|   notes: "Azul ... Notas" | ||||
| @@ -425,23 +430,23 @@ desktop/views/components/calendar.vue: | ||||
|   next: "Próximo mes" | ||||
|   go: "Click para navegar" | ||||
| desktop/views/components/charts.vue: | ||||
|   title: "チャート" | ||||
|   per-day: "1日ごと" | ||||
|   per-hour: "1時間ごと" | ||||
|   notes: "投稿" | ||||
|   users: "ユーザー" | ||||
|   drive: "ドライブ" | ||||
|   title: "Gráficos" | ||||
|   per-day: "por día" | ||||
|   per-hour: "por hora" | ||||
|   notes: "Publicaciones" | ||||
|   users: "Usuarios" | ||||
|   drive: "Unidad" | ||||
|   charts: | ||||
|     notes: "投稿の増減 (統合)" | ||||
|     local-notes: "投稿の増減 (ローカル)" | ||||
|     remote-notes: "投稿の増減 (リモート)" | ||||
|     notes-total: "投稿の累計" | ||||
|     users: "ユーザーの増減" | ||||
|     users-total: "ユーザーの累計" | ||||
|     drive: "ドライブ使用量の増減" | ||||
|     drive-total: "ドライブ使用量の累計" | ||||
|     drive-files: "ドライブのファイル数の増減" | ||||
|     drive-files-total: "ドライブのファイル数の累計" | ||||
|     notes: "Número de publicaciones: aumentar/disminuir (Combinado)" | ||||
|     local-notes: "Número de publicaciones: aumentar/disminuir (Local)" | ||||
|     remote-notes: "Número de publicaciones: aumentar/disminuir (Remoto)" | ||||
|     notes-total: "Número de publicaciones: Acumulativo total" | ||||
|     users: "Número de usuarios: aumentar/disminuir" | ||||
|     users-total: "Número de usuarios: Acumulativo total" | ||||
|     drive: "Capacidad de almacenamiento usada: aumentar/disminuir" | ||||
|     drive-total: "Capacidad de almacenamiento usada: Acumulativa total" | ||||
|     drive-files: "Número de archivos almacenados: aumentar/disminuir" | ||||
|     drive-files-total: "Número de archivos almacenados: Acumulativo total" | ||||
| desktop/views/components/choose-file-from-drive-window.vue: | ||||
|   choose-file: "Escoger archivos" | ||||
|   upload: "Cargar archivos de tu dispositivo" | ||||
| @@ -462,7 +467,7 @@ desktop/views/components/drive-window.vue: | ||||
| desktop/views/components/drive.file.vue: | ||||
|   avatar: "Avatar" | ||||
|   banner: "Banner" | ||||
|   nsfw: "閲覧注意" | ||||
|   nsfw: "Ver más" | ||||
|   contextmenu: | ||||
|     rename: "Renombrar" | ||||
|     mark-as-sensitive: "Marcar como 'sensible'" | ||||
| @@ -514,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')" | ||||
|   click-to-show: "Click para mostrar" | ||||
| desktop/views/components/media-video.vue: | ||||
|   sensitive: "閲覧注意" | ||||
|   click-to-show: "クリックして表示" | ||||
|   sensitive: "Este contenido no es apropiado para ver en el trabajo" | ||||
|   click-to-show: "Click para mostrar" | ||||
| desktop/views/components/follow-button.vue: | ||||
|   following: "Siguiendo" | ||||
|   follow: "Sigue" | ||||
|   request-pending: "Pendiente de aprobación" | ||||
|   follow-request: "フォロー申請" | ||||
|   follow-request: "Solicitud de seguir" | ||||
| desktop/views/components/followers-window.vue: | ||||
|   followers: "{} のフォロワー" | ||||
|   followers: "{} seguidores" | ||||
| desktop/views/components/followers.vue: | ||||
|   empty: "フォロワーはいないようです。" | ||||
|   empty: "Parece que no tienes seguidores aún." | ||||
| desktop/views/components/following-window.vue: | ||||
|   following: "{} のフォロー" | ||||
|   following: "Siguiendo {}" | ||||
| desktop/views/components/following.vue: | ||||
|   empty: "フォロー中のユーザーはいないようです。" | ||||
|   empty: "Parece que aún no sigues a nadie." | ||||
| desktop/views/components/friends-maker.vue: | ||||
|   title: "気になるユーザーをフォロー:" | ||||
|   empty: "おすすめのユーザーは見つかりませんでした。" | ||||
|   fetching: "読み込んでいます" | ||||
|   refresh: "もっと見る" | ||||
|   close: "閉じる" | ||||
|   title: "Usuarios recomendados:" | ||||
|   empty: "No se pudieron encontrar usuarios para recomendar" | ||||
|   fetching: "Cargando" | ||||
|   refresh: "Más" | ||||
|   close: "Cerrar" | ||||
| desktop/views/components/game-window.vue: | ||||
|   game: "リバーシ" | ||||
|   game: "Reversi" | ||||
| desktop/views/components/home.vue: | ||||
|   done: "完了" | ||||
|   done: "Listo" | ||||
|   add-widget: "Agregar accesorio:" | ||||
|   add: "Agregar" | ||||
| desktop/views/input-dialog.vue: | ||||
| @@ -564,8 +569,8 @@ desktop/views/components/notes.note.vue: | ||||
|   detail: "Mostrar detalles" | ||||
|   private: "Esta publicación es privada" | ||||
|   deleted: "Esta publicación ha sido borrada" | ||||
|   hide: "隠す" | ||||
|   see-more: "もっと見る" | ||||
|   hide: "Esconder" | ||||
|   see-more: "Ver más" | ||||
| desktop/views/components/notes.vue: | ||||
|   error: "Error al cargar." | ||||
|   retry: "Reintentar" | ||||
| @@ -601,7 +606,7 @@ desktop/views/components/post-form.vue: | ||||
|   geolocation-alert: "Tu dispositivo no tiene soporte de geolocalización." | ||||
|   error: "Error" | ||||
|   enter-username: "Por favor escribe un nombre de usuario..." | ||||
|   annotations: "内容への注釈 (オプション)" | ||||
|   annotations: "Anotaciones a la publicación (opcional)" | ||||
| desktop/views/components/post-form-window.vue: | ||||
|   note: "Nota nueva" | ||||
|   reply: "Responder" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "Usar degradados en las cabeceras de las páginas" | ||||
|   post-form-on-timeline: "Mostrar el formulario de las entradas encima de la línea de tiempo" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -764,40 +770,40 @@ desktop/views/components/timeline.vue: | ||||
|   global: "グローバル" | ||||
|   list: "リスト" | ||||
| desktop/views/components/ui.header.vue: | ||||
|   welcome-back: "おかえりなさい、" | ||||
|   adjective: "さん" | ||||
|   welcome-back: "Bienvenido/a de vuelta," | ||||
|   adjective: "-san" | ||||
| desktop/views/components/ui.header.account.vue: | ||||
|   profile: "プロフィール" | ||||
|   drive: "ドライブ" | ||||
|   favorites: "お気に入り" | ||||
|   lists: "リスト" | ||||
|   follow-requests: "フォロー申請" | ||||
|   customize: "ホームのカスタマイズ" | ||||
|   admin: "管理" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   dark: "闇に飲まれる" | ||||
|   profile: "Tu perfil" | ||||
|   drive: "Unidad" | ||||
|   favorites: "Favoritos" | ||||
|   lists: "Listas" | ||||
|   follow-requests: "Solicitudes de seguimiento" | ||||
|   customize: "Personalizar la página de inicio" | ||||
|   admin: "Admin" | ||||
|   settings: "Configuraciones" | ||||
|   signout: "Desconectarse" | ||||
|   dark: "Sumergirse en la oscuridad" | ||||
| desktop/views/components/ui.header.nav.vue: | ||||
|   home: "ホーム" | ||||
|   deck: "デッキ" | ||||
|   messaging: "メッセージ" | ||||
|   game: "ゲーム" | ||||
|   home: "Inicio" | ||||
|   deck: "Cubierta" | ||||
|   messaging: "Mensajes" | ||||
|   game: "Juegos" | ||||
| desktop/views/components/ui.header.notifications.vue: | ||||
|   title: "通知" | ||||
|   title: "Notificaciones" | ||||
| desktop/views/components/ui.header.post.vue: | ||||
|   post: "新規投稿" | ||||
|   post: "Crear una publicación" | ||||
| desktop/views/components/ui.header.search.vue: | ||||
|   placeholder: "検索" | ||||
|   placeholder: "Buscar" | ||||
| desktop/views/components/received-follow-requests-window.vue: | ||||
|   title: "フォロー申請" | ||||
|   accept: "承認" | ||||
|   reject: "拒否" | ||||
|   title: "Solicitudes de seguidores" | ||||
|   accept: "Aceptar" | ||||
|   reject: "Rechazar" | ||||
| desktop/views/components/user-lists-window.vue: | ||||
|   title: "リスト" | ||||
|   create-list: "リストを作成" | ||||
|   list-name: "リスト名" | ||||
|   title: "Listas de usuario" | ||||
|   create-list: "Crear lista" | ||||
|   list-name: "Nombre de lista" | ||||
| desktop/views/components/user-preview.vue: | ||||
|   notes: "投稿" | ||||
|   notes: "Publicaciones" | ||||
|   following: "フォロー" | ||||
|   followers: "フォロワー" | ||||
| desktop/views/components/users-list.vue: | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "Compte vérifié" | ||||
|   disable-animated-mfm: "Désactiver les textes animés dans les publications" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "Partie nulle" | ||||
|     my-turn: "C’est votre tour" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "Développeur·se·s" | ||||
|   feedback: "Remarques" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "Mettre cette note en favoris" | ||||
|   pin: "Épingler sur votre profil" | ||||
|   delete: "Supprimer" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "Direct" | ||||
|   specified-desc: "Publier aux utilisateur·rice·s mentionné·e·s" | ||||
|   private: "Privé" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "Récupération" | ||||
|   no-broadcasts: "Aucune annonce" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "Basculer entre les vues" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "Étiquettes" | ||||
|   count: "{} utilisateur·rice·s mentionné·e·s" | ||||
|   empty: "Aucune tendance" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "Informations sur le serveur" | ||||
|   toggle: "Afficher les vues" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "Téléversement du nouvel avatar" | ||||
|   avatar-updated: "L'avatar est mis à jour" | ||||
|   choose-avatar: "Choisir un avatar" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Noirs ... Total" | ||||
|   notes: "Bleu ... Notes" | ||||
| @@ -425,12 +430,12 @@ desktop/views/components/calendar.vue: | ||||
|   next: "Mois prochain" | ||||
|   go: "Cliquez pour naviguer" | ||||
| desktop/views/components/charts.vue: | ||||
|   title: "チャート" | ||||
|   per-day: "1日ごと" | ||||
|   per-hour: "1時間ごと" | ||||
|   notes: "投稿" | ||||
|   users: "ユーザー" | ||||
|   drive: "ドライブ" | ||||
|   title: "Graphiques" | ||||
|   per-day: "par jour" | ||||
|   per-hour: "par heure" | ||||
|   notes: "Publications" | ||||
|   users: "Utilisateurs" | ||||
|   drive: "Drive" | ||||
|   charts: | ||||
|     notes: "投稿の増減 (統合)" | ||||
|     local-notes: "投稿の増減 (ローカル)" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "Utiliser les dégradés sur la barre de titre de la fenêtre" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "Afficher les hashtags populaires dans le champs de saisie" | ||||
|   show-clock-on-header: "Afficher l'horloge à droite sur le coté supérieur" | ||||
|   show-reply-target: "Afficher les réponses" | ||||
|   show-my-renotes: "Afficher mes republications dans le fil" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -817,8 +823,8 @@ desktop/views/pages/admin/admin.vue: | ||||
|   update: "Mises à jour" | ||||
| desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "Tableau de bord" | ||||
|   all-users: "Tou·te·s les utilisateur·rice·s" | ||||
|   original-users: "Utilisateur·rice·s sur cette instance" | ||||
|   all-users: "Toutes les utilisateurrices" | ||||
|   original-users: "Utilisateurrices sur cette instance" | ||||
|   all-notes: "Toutes les publications" | ||||
|   original-notes: "Publication sur cette instance" | ||||
|   invite: "Invitation" | ||||
| @@ -837,7 +843,7 @@ desktop/views/pages/admin/admin.verify-user.vue: | ||||
| desktop/views/pages/admin/admin.unverify-user.vue: | ||||
|   unverify-user: "ユーザーの公式アカウント解除" | ||||
|   unverify: "Ôter la vérification du compte" | ||||
|   unverified: "公式アカウントを解除しました" | ||||
|   unverified: "Ce compte n'est pas vérifié" | ||||
| desktop/views/pages/deck/deck.tl-column.vue: | ||||
|   is-media-only: "Les publications médias uniquement" | ||||
|   is-media-view: "Vue média" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "Reposté par {}" | ||||
|   private: "cette publication est privée" | ||||
|   deleted: "cette publication a été supprimée" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "Toutes les utilisateurrices" | ||||
|   original-users: "Utilisateurrices sur cette instance" | ||||
|   all-notes: "Toutes les publications" | ||||
|   original-notes: "Publication sur cette instance" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "à propos" | ||||
|   gotit: "J'ai compris !" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "Se connecter" | ||||
|   signup-button: "S'inscrire" | ||||
|   timeline: "Fil d'actualité" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Propulsé par <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Lecteur de Misskey" | ||||
| @@ -1052,7 +1065,7 @@ mobile/views/components/ui.nav.vue: | ||||
|   game: "Jeux" | ||||
|   darkmode: "Mode nuit" | ||||
|   settings: "Réglages" | ||||
|   admin: "管理" | ||||
|   admin: "Admin" | ||||
|   about: "À propose de Misskey" | ||||
| mobile/views/components/user-timeline.vue: | ||||
|   no-notes: "Cette utilisateur semble n'avoir rien poster pour le moment" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "Style de la publication" | ||||
|   post-style-standard: "Standard" | ||||
|   post-style-smart: "Intelligent" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "Comportement" | ||||
|   fetch-on-scroll: "Chargement lors du défilement" | ||||
|   disable-via-mobile: "Ne pas mentionner que ma publication provient d'un 'périphérique mobile'" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "Les mises à jour seront appliquées une fois la page est rechargée." | ||||
|   settings: "Réglages" | ||||
|   signout: "Déconnexion" | ||||
|   sound: "Sons" | ||||
|   enableSounds: "Activer le son" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "vous suit" | ||||
|   following: "Abonnements" | ||||
|   | ||||
| @@ -5,24 +5,9 @@ | ||||
| const fs = require('fs'); | ||||
| const yaml = require('js-yaml'); | ||||
|  | ||||
| const loadLang = lang => yaml.safeLoad( | ||||
| 	fs.readFileSync(`${__dirname}/${lang}.yml`, 'utf-8')); | ||||
| const langs = ['de-DE', 'en-US', 'fr-FR', 'ja-JP', 'ja-KS', 'pl-PL', 'es-ES', 'nl-NL']; | ||||
|  | ||||
| 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 = { | ||||
| 	'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; | ||||
| module.exports = locales.reduce((a, b) => ({ ...a, ...b })); | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "引き分け" | ||||
|     my-turn: "あなたのターンです" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -94,6 +94,8 @@ common: | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" | ||||
|  | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|  | ||||
|   reversi: | ||||
|     drawn: "引き分け" | ||||
|     my-turn: "あなたのターンです" | ||||
| @@ -283,6 +285,8 @@ common/views/components/nav.vue: | ||||
|   feedback: "フィードバック" | ||||
|  | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -371,6 +375,10 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
|  | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
|  | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -399,8 +407,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|  | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
|  | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
| @@ -456,6 +462,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
|  | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
| @@ -732,6 +739,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -934,8 +942,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
|  | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
| @@ -971,8 +979,8 @@ desktop/views/pages/deck/deck.note.vue: | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|  | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
| @@ -982,6 +990,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
|  | ||||
| desktop/views/pages/drive.vue: | ||||
| @@ -1347,6 +1357,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1367,6 +1380,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
|  | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストをつけんで!" | ||||
|   verified-user: "アメちゃん付きアカウント" | ||||
|   disable-animated-mfm: "投稿内のちょろちょろ動いてんのを止める" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "おあいこ" | ||||
|     my-turn: "あんさんのターンや" | ||||
| @@ -207,9 +208,9 @@ common/views/components/games/reversi/reversi.room.vue: | ||||
|   ready: "準備完了" | ||||
|   cancel-ready: "準備続行" | ||||
| common/views/components/connect-failed.vue: | ||||
|   title: "サーバーに接続できません" | ||||
|   description: "インターネット回線に問題があるか、サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから{再度お試し}ください。" | ||||
|   thanks: "いつもMisskeyをご利用いただきありがとうございます。" | ||||
|   title: "サーバーに接続でけへんわ" | ||||
|   description: "インターネット回線に問題が起きとるか、サーバーがダウンまたはメンテナンスしとるっぽいわ。知らんけど。とりあえずあとで{再試行}してや。" | ||||
|   thanks: "いつもMisskeyをつこてくれてほんまありがとな。" | ||||
|   troubleshoot: "トラブルシュート" | ||||
| common/views/components/connect-failed.troubleshooter.vue: | ||||
|   title: "トラブルシューティング" | ||||
| @@ -219,99 +220,101 @@ common/views/components/connect-failed.troubleshooter.vue: | ||||
|   checking-internet: "インターネット接続を確認中" | ||||
|   server: "サーバー接続" | ||||
|   checking-server: "サーバー接続を確認中" | ||||
|   finding: "問題を調べています" | ||||
|   no-network: "ネットワークに接続されていません" | ||||
|   no-network-desc: "お使いのPCのネットワーク接続が正常か確認してください。" | ||||
|   no-internet: "インターネットに接続されていません" | ||||
|   no-internet-desc: "ネットワークには接続されていますが、インターネットには接続されていないようです。お使いのPCのインターネット接続が正常か確認してください。" | ||||
|   no-server: "Misskeyのサーバーに接続できません" | ||||
|   no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。" | ||||
|   success: "Misskeyのサーバーに接続できました" | ||||
|   success-desc: "正常に接続できるようです。ページを再度読み込みしてください。" | ||||
|   finding: "問題を調べとるで" | ||||
|   no-network: "ネットワークに接続されとらんで" | ||||
|   no-network-desc: "つこてるPCのネットワーク接続が正常か確認してや。" | ||||
|   no-internet: "インターネットに接続されとらんで" | ||||
|   no-internet-desc: "ネットワークには接続されとるけど、インターネットには接続されとらんようやわ。つこてるPCのインターネット接続が正常か確認してや。" | ||||
|   no-server: "Misskeyのサーバーに接続でけへんわ" | ||||
|   no-server-desc: "つこてるPCのインターネット接続は正常やけど、Misskeyのサーバーにはつながらんわ。多分サーバーがダウンまたはメンテナンスしとるわ、知らんけど。すまんけどしばらくしてから再度アクセスしてみてや。" | ||||
|   success: "Misskeyのサーバーに接続できたわ" | ||||
|   success-desc: "正常に接続できるようやわ。ページを再度読み込みしてな。" | ||||
|   flush: "キャッシュの削除" | ||||
|   set-version: "バージョン指定" | ||||
| common/views/components/messaging.vue: | ||||
|   search-user: "ユーザーを探す" | ||||
|   you: "あなた" | ||||
|   no-history: "履歴はありません" | ||||
|   you: "あんさん" | ||||
|   no-history: "履歴はあらへんで" | ||||
| common/views/components/messaging-room.vue: | ||||
|   empty: "このユーザーと話したことはありません" | ||||
|   empty: "このユーザーと話したことはあらへんで" | ||||
|   more: "もっと読む" | ||||
|   no-history: "これより過去の履歴はありません" | ||||
|   no-history: "これより過去の履歴はあらへんで" | ||||
|   resize-form: "ドラッグしてフォームの広さを調整" | ||||
|   new-message: "新しいメッセージがあります" | ||||
|   only-one-file-attached: "メッセージに添付できるのはひとつのファイルのみです" | ||||
|   new-message: "新しいメッセージがあるで" | ||||
|   only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで" | ||||
| common/views/components/messaging-room.form.vue: | ||||
|   input-message-here: "ここにメッセージを入力" | ||||
|   input-message-here: "ここにメッセージ書いてや" | ||||
|   send: "送信" | ||||
|   attach-from-local: "PCからファイルを添付する" | ||||
|   attach-from-drive: "ドライブからファイルを添付する" | ||||
|   only-one-file-attached: "メッセージに添付できるのはひとつのファイルのみです" | ||||
|   only-one-file-attached: "メッセージに添付できんのはひとつのファイルのみやで" | ||||
| common/views/components/messaging-room.message.vue: | ||||
|   is-read: "既読" | ||||
|   deleted: "このメッセージは削除されました" | ||||
|   deleted: "このメッセージは削除されたわ" | ||||
| common/views/components/nav.vue: | ||||
|   about: "Misskeyについて" | ||||
|   stats: "統計" | ||||
|   status: "ステータス" | ||||
|   wiki: "Wiki" | ||||
|   donors: "ドナー" | ||||
|   donors: "支援者" | ||||
|   repository: "リポジトリ" | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
|   delete-confirm: "この投稿を削除しますか?" | ||||
|   delete: "ほかす" | ||||
|   delete-confirm: "この投稿を削除してもええか?" | ||||
|   remote: "投稿元で見る" | ||||
| common/views/components/poll.vue: | ||||
|   vote-to: "「{}」に投票する" | ||||
|   vote-to: "「{}」に投票や!" | ||||
|   vote-count: "{}票" | ||||
|   total-users: "{}人が投票" | ||||
|   vote: "投票する" | ||||
|   show-result: "結果を見る" | ||||
|   voted: "投票済み" | ||||
|   vote: "投票するで" | ||||
|   show-result: "結果を見よか" | ||||
|   voted: "投票済みや" | ||||
| common/views/components/poll-editor.vue: | ||||
|   no-only-one-choice: "アンケートには、選択肢が最低2つ必要です" | ||||
|   no-only-one-choice: "選択肢が最低2つ必要やで" | ||||
|   choice-n: "選択肢{}" | ||||
|   remove: "この選択肢を削除" | ||||
|   remove: "この選択肢を消すで" | ||||
|   add: "+選択肢を追加" | ||||
|   destroy: "アンケートを破棄" | ||||
|   destroy: "アンケートをほかそ" | ||||
| common/views/components/reaction-picker.vue: | ||||
|   choose-reaction: "リアクションを選択" | ||||
| common/views/components/signin.vue: | ||||
|   username: "ユーザー名" | ||||
|   password: "パスワード" | ||||
|   token: "トークン" | ||||
|   signing-in: "やってます..." | ||||
|   signing-in: "サインイン中や..." | ||||
|   signin: "サインイン" | ||||
|   or: "または" | ||||
|   signin-with-twitter: "Twitterでログイン" | ||||
|   login-failed: "ログインできませんでした。ユーザー名とパスワードを確認してください。" | ||||
|   signin-with-twitter: "Twitterでサインイン" | ||||
|   login-failed: "なんかログインできんかったわ。ユーザー名とパスワードとかを確認してや。" | ||||
| common/views/components/signup.vue: | ||||
|   invitation-code: "招待コード" | ||||
|   invitation-info: "招待コードをお持ちでない方は、<a href=\"{}\">管理者</a>までご連絡ください。" | ||||
|   username: "ユーザー名" | ||||
|   checking: "確認しています..." | ||||
|   available: "利用できます" | ||||
|   unavailable: "既に利用されています" | ||||
|   checking: "確認中や…" | ||||
|   available: "使えるで" | ||||
|   unavailable: "もう使われとるで" | ||||
|   error: "通信エラー" | ||||
|   invalid-format: "a~z、A~Z、0~9、_が使えます" | ||||
|   invalid-format: "a~z、A~Z、0~9、_が使えるで" | ||||
|   too-short: "1文字以上でお願いします!" | ||||
|   too-long: "20文字以内でお願いします" | ||||
|   password: "パスワード" | ||||
|   password-placeholder: "8文字以上を推奨します" | ||||
|   weak-password: "弱いパスワード" | ||||
|   normal-password: "まあまあのパスワード" | ||||
|   strong-password: "強いパスワード" | ||||
|   retype: "再入力" | ||||
|   retype-placeholder: "確認のため再入力してください" | ||||
|   password-matched: "確認されました" | ||||
|   password-not-matched: "一致していません" | ||||
|   weak-password: "へぼいパスワード" | ||||
|   normal-password: "ぼちぼちなパスワード" | ||||
|   strong-password: "良さげなパスワード" | ||||
|   retype: "もっかい入力頼むで" | ||||
|   retype-placeholder: "確認のためもっぺん入力してや" | ||||
|   password-matched: "一致しとるで" | ||||
|   password-not-matched: "一致しとらんで" | ||||
|   recaptcha: "認証" | ||||
|   create: "アカウント作成" | ||||
|   some-error: "何らかの原因によりアカウントの作成に失敗しました。再度お試しください。" | ||||
|   some-error: "何かよう分からんけど、アカウントの作成に失敗してしもたわ。すまんがもっぺん試してくれへんか?" | ||||
| common/views/components/special-message.vue: | ||||
|   new-year: "Happy New Year!" | ||||
|   christmas: "Merry Christmas!" | ||||
| @@ -320,8 +323,8 @@ common/views/components/stream-indicator.vue: | ||||
|   reconnecting: "再接続中" | ||||
|   connected: "接続完了" | ||||
| common/views/components/twitter-setting.vue: | ||||
|   description: "お使いのTwitterアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでTwitterアカウント情報が表示されるようになったり、Twitterを用いた便利なサインインを利用できるようになります。" | ||||
|   connected-to: "次のTwitterアカウントに接続されています" | ||||
|   description: "あんさんがつことるTwitterアカウントをMisskeyアカウントに接続しとくと、あんさんのプロフィールにTwitterアカウント情報が表示されるようになったり、Twitterをつこた便利なサインインが使えるようになったりすんで。" | ||||
|   connected-to: "次のTwitterアカウントに接続されとるで" | ||||
|   detail: "詳細..." | ||||
|   reconnect: "再接続する" | ||||
|   connect: "Twitterと接続する" | ||||
| @@ -337,9 +340,12 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
|   no-broadcasts: "お知らせはあらへんで" | ||||
|   have-a-nice-day: "良い一日を!" | ||||
|   next: "次" | ||||
| common/views/widgets/calendar.vue: | ||||
| @@ -351,17 +357,15 @@ common/views/widgets/calendar.vue: | ||||
|   this-year: "今年:" | ||||
| common/views/widgets/donation.vue: | ||||
|   title: "寄付のお願い" | ||||
|   text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かります。Misskeyは広告を掲載したりしないため、収入を皆様からの寄付に頼っています。もしご興味があれば、{}までご連絡ください。ご協力ありがとうございます。" | ||||
|   text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かるんや。Misskeyは広告を掲載したりせんから、収入を皆様からの寄付に頼ってますねん。もし興味があるなら、{}までご連絡よろしゅう頼んます。ご協力おおきに。" | ||||
| common/views/widgets/photo-stream.vue: | ||||
|   title: "フォトストリーム" | ||||
|   no-photos: "写真はありません" | ||||
|   no-photos: "写真はあらへんで" | ||||
| common/views/widgets/posts-monitor.vue: | ||||
|   title: "投稿チャート" | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -370,30 +374,30 @@ common/views/widgets/memo.vue: | ||||
|   memo: "ここに書いて!" | ||||
|   save: "保存" | ||||
| common/views/widgets/slideshow.vue: | ||||
|   folder-customize-mode: "フォルダを指定するには、カスタマイズモードを終了してください" | ||||
|   folder-customize-mode: "フォルダを指定するんやったら、一旦カスタマイズモードを終了してや" | ||||
|   folder: "クリックしてフォルダを指定してください" | ||||
|   no-image: "このフォルダには画像がありません" | ||||
| common/views/widgets/tips.vue: | ||||
|   tips-line1: "<kbd>t</kbd>でタイムラインにフォーカスできます" | ||||
|   tips-line2: "<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開きます" | ||||
|   tips-line3: "投稿フォームにはファイルをドラッグ&ドロップできます" | ||||
|   tips-line4: "投稿フォームにクリップボードにある画像データをペーストできます" | ||||
|   tips-line5: "ドライブにファイルをドラッグ&ドロップしてアップロードできます" | ||||
|   tips-line6: "ドライブでファイルをドラッグしてフォルダ移動できます" | ||||
|   tips-line7: "ドライブでフォルダをドラッグしてフォルダ移動できます" | ||||
|   tips-line8: "ホームは設定からカスタマイズできます" | ||||
|   tips-line9: "MisskeyはAGPLv3です" | ||||
|   tips-line10: "タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れます" | ||||
|   tips-line11: "投稿の ... をクリックして、投稿をユーザーページにピン留めできます" | ||||
|   tips-line13: "投稿に添付したファイルは全てドライブに保存されます" | ||||
|   tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます" | ||||
|   tips-line17: "「**」でテキストを囲むと**強調表示**されます" | ||||
|   tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができます" | ||||
|   tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています" | ||||
|   tips-line21: "APIを利用してbotの開発なども行えます" | ||||
|   tips-line1: "<kbd>t</kbd>でタイムラインにフォーカスできんで" | ||||
|   tips-line2: "<kbd>p</kbd>または<kbd>n</kbd>で投稿フォームを開くで" | ||||
|   tips-line3: "投稿フォームにはファイルをドラッグ&ドロップできんで" | ||||
|   tips-line4: "投稿フォームにクリップボードにおる画像データをペーストできんで" | ||||
|   tips-line5: "ドライブにファイルをドラッグ&ドロップしてアップロードできんで" | ||||
|   tips-line6: "ドライブやと、ファイルをドラッグしてフォルダ移動できんで" | ||||
|   tips-line7: "ドライブやと、フォルダをドラッグしてフォルダ移動できんで" | ||||
|   tips-line8: "ホームは設定からカスタマイズできんで" | ||||
|   tips-line9: "MisskeyはAGPLv3やで" | ||||
|   tips-line10: "タイムマシンウィジェットを利用すると、簡単に過去のタイムラインに遡れんで" | ||||
|   tips-line11: "投稿の ... をクリックして、ピン留めから投稿をユーザーページにピン留めできんで" | ||||
|   tips-line13: "投稿に添付したファイルは全てドライブに保存されんで" | ||||
|   tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できんで" | ||||
|   tips-line17: "「**」でテキストを囲ったると**強調表示**されんで" | ||||
|   tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができんで" | ||||
|   tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示してんねん" | ||||
|   tips-line21: "APIをつこてbotの開発なども行えるで" | ||||
|   tips-line23: "まゆかわいいよまゆ" | ||||
|   tips-line24: "Misskeyは2014年にサービスを開始しました" | ||||
|   tips-line25: "対応ブラウザではMisskeyを開いていなくても通知を受け取れます" | ||||
|   tips-line24: "Misskeyは2014年にサービスを開始したんよ" | ||||
|   tips-line25: "対応ブラウザやったらMisskeyを開いとらんでも通知を受け取れんで" | ||||
| common/views/pages/follow.vue: | ||||
|   signed-in-as: "{}としてサインイン中" | ||||
|   following: "フォロー中" | ||||
| @@ -403,14 +407,15 @@ common/views/pages/follow.vue: | ||||
| desktop: | ||||
|   banner-crop-title: "バナーとして表示する部分を選択" | ||||
|   banner: "バナー" | ||||
|   uploading-banner: "新しいバナーをアップロードしています" | ||||
|   banner-updated: "バナーを更新しました" | ||||
|   uploading-banner: "新しいバナーをアップロードしとるで" | ||||
|   banner-updated: "バナーを更新したで" | ||||
|   choose-banner: "バナーにする画像を選択" | ||||
|   avatar-crop-title: "アバターとして表示する部分を選択" | ||||
|   avatar: "アバター" | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -420,10 +425,10 @@ desktop/views/components/activity.vue: | ||||
|   title: "アクティビティ" | ||||
|   toggle: "表示を切り替え" | ||||
| desktop/views/components/calendar.vue: | ||||
|   title: "{1}年 {2}月" | ||||
|   title: "{1}年 {2} 月" | ||||
|   prev: "前の月" | ||||
|   next: "次の月" | ||||
|   go: "クリックして時間遡行" | ||||
|   go: "クリックしてタイムリープ" | ||||
| desktop/views/components/charts.vue: | ||||
|   title: "チャート" | ||||
|   per-day: "1日ごと" | ||||
| @@ -464,7 +469,7 @@ desktop/views/components/drive.file.vue: | ||||
|   banner: "バナー" | ||||
|   nsfw: "閲覧注意" | ||||
|   contextmenu: | ||||
|     rename: "名前を変更" | ||||
|     rename: "名前を変えるで" | ||||
|     mark-as-sensitive: "閲覧注意に設定" | ||||
|     unmark-as-sensitive: "閲覧注意を解除" | ||||
|     copy-url: "URLをコピー" | ||||
| @@ -475,26 +480,26 @@ desktop/views/components/drive.file.vue: | ||||
|     open-in-app: "アプリで開く" | ||||
|     add-app: "アプリを追加" | ||||
|     rename-file: "ファイル名の変更" | ||||
|     input-new-file-name: "新しいファイル名を入力してください" | ||||
|     copied: "コピー完了" | ||||
|     input-new-file-name: "新しいファイル名を入力してや" | ||||
|     copied: "コピー完了や" | ||||
|     copied-url-to-clipboard: "URLをクリップボードにコピーしました" | ||||
| desktop/views/components/drive.folder.vue: | ||||
|   unable-to-process: "操作を完了できません" | ||||
|   circular-reference-detected: "移動先のフォルダーは、移動するフォルダーのサブフォルダーです。" | ||||
|   unhandled-error: "不明なエラー" | ||||
|   unhandled-error: "ようわからん" | ||||
|   contextmenu: | ||||
|     move-to-this-folder: "このフォルダへ移動" | ||||
|     show-in-new-window: "新しいウィンドウで表示" | ||||
|     rename: "名前を変更" | ||||
|     rename-folder: "フォルダ名の変更" | ||||
|     input-new-folder-name: "新しいフォルダ名を入力してください" | ||||
|     rename: "名前を変えるで" | ||||
|     rename-folder: "フォルダ名を変えるで" | ||||
|     input-new-folder-name: "新しいフォルダ名を入力してや" | ||||
| desktop/views/components/drive.nav-folder.vue: | ||||
|   drive: "ドライブ" | ||||
| desktop/views/components/drive.vue: | ||||
|   search: "検索" | ||||
|   load-more: "もっと読み込む" | ||||
|   empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね" | ||||
|   empty-drive: "ドライブには何もありません。" | ||||
|   empty-drive: "ドライブには何もあらへんで。" | ||||
|   empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。" | ||||
|   empty-folder: "このフォルダーは空です" | ||||
|   unable-to-process: "操作を完了できません" | ||||
| @@ -511,11 +516,11 @@ desktop/views/components/drive.vue: | ||||
|     upload: "ファイルをアップロード" | ||||
|     url-upload: "URLからアップロード" | ||||
| desktop/views/components/media-image.vue: | ||||
|   sensitive: "閲覧注意" | ||||
|   click-to-show: "クリックして表示" | ||||
|   sensitive: "ちょっと見せられへんわ" | ||||
|   click-to-show: "クリックして見せるで" | ||||
| desktop/views/components/media-video.vue: | ||||
|   sensitive: "閲覧注意" | ||||
|   click-to-show: "クリックして表示" | ||||
|   sensitive: "ちょっと見せられへんわ" | ||||
|   click-to-show: "クリックして見せるで" | ||||
| desktop/views/components/follow-button.vue: | ||||
|   following: "フォロー中" | ||||
|   follow: "フォロー" | ||||
| @@ -536,7 +541,7 @@ desktop/views/components/friends-maker.vue: | ||||
|   refresh: "もっと見る" | ||||
|   close: "閉じる" | ||||
| desktop/views/components/game-window.vue: | ||||
|   game: "リバーシ" | ||||
|   game: "ゲーム" | ||||
| desktop/views/components/home.vue: | ||||
|   done: "完了" | ||||
|   add-widget: "ウィジェットを追加:" | ||||
| @@ -575,32 +580,32 @@ desktop/views/components/notifications.vue: | ||||
|   empty: "ありません!" | ||||
| desktop/views/components/post-form.vue: | ||||
|   add-visible-user: "+ユーザーを追加" | ||||
|   attach-location-information: "位置情報を添付する" | ||||
|   attach-location-information: "いる場所くっつけるで" | ||||
|   hide-contents: "内容を隠す" | ||||
|   reply-placeholder: "この投稿への返信..." | ||||
|   quote-placeholder: "この投稿を引用..." | ||||
|   submit: "投稿" | ||||
|   reply: "返信" | ||||
|   renote: "Renote" | ||||
|   posted: "投稿しました!" | ||||
|   replied: "返信しました!" | ||||
|   posted: "投稿したで!" | ||||
|   replied: "返信したで!" | ||||
|   reposted: "Renoteしました!" | ||||
|   note-failed: "投稿に失敗しました" | ||||
|   reply-failed: "返信に失敗しました" | ||||
|   note-failed: "投稿に失敗したで" | ||||
|   reply-failed: "返信に失敗したで" | ||||
|   renote-failed: "Renoteに失敗しました" | ||||
|   posting: "投稿中" | ||||
|   attach-media-from-local: "PCからメディアを添付" | ||||
|   attach-media-from-drive: "ドライブからメディアを添付" | ||||
|   attach-cancel: "添付取り消し" | ||||
|   attach-cancel: "くっつけるのやめよか" | ||||
|   insert-a-kao: "v('ω')v" | ||||
|   create-poll: "アンケートを作成" | ||||
|   text-remain: "残り{}文字" | ||||
|   recent-tags: "最近" | ||||
|   recent-tags: "最近のタグ" | ||||
|   click-to-tagging: "クリックでタグ付け" | ||||
|   visibility: "公開範囲" | ||||
|   geolocation-alert: "お使いの端末は位置情報に対応していません" | ||||
|   geolocation-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。" | ||||
|   error: "エラー" | ||||
|   enter-username: "ユーザー名を入力してください" | ||||
|   enter-username: "ユーザー名を入力してや" | ||||
|   annotations: "内容への注釈 (オプション)" | ||||
| desktop/views/components/post-form-window.vue: | ||||
|   note: "新規投稿" | ||||
| @@ -639,7 +644,7 @@ desktop/views/components/settings.vue: | ||||
|   auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。" | ||||
|   advanced: "詳細設定" | ||||
|   api-via-stream: "ストリームを経由したAPIリクエスト" | ||||
|   api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。" | ||||
|   api-via-stream-desc: "この設定をオンにすると、WebSocket接続を経由してAPIリクエストが行われんで(パフォーマンス向上するかも、知らんけど)。オフにすると、ネイティブの fetch API が利用されるで。この設定はこのデバイスのみ有効やで。" | ||||
|   display: "デザインと表示" | ||||
|   customize: "ホームをカスタマイズ" | ||||
|   choose-wallpaper: "壁紙を選択" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -686,9 +692,9 @@ desktop/views/components/settings.vue: | ||||
|   prevent-update: "アップデートを延期する(非推奨)" | ||||
|   prevent-update-desc: "この設定をオンにしてもアップデートが反映される場合があります。この設定はこのデバイスのみ有効です。" | ||||
|   no-updates: "利用可能な更新はありません" | ||||
|   no-updates-desc: "お使いのMisskeyは最新です。" | ||||
|   update-available: "新しいバージョンが利用可能です" | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   no-updates-desc: "つこてるMisskeyは最新や!" | ||||
|   update-available: "新しいバージョンが利用可能や" | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されるで。" | ||||
|   advanced-settings: "高度な設定" | ||||
|   debug-mode: "デバッグモードを有効にする" | ||||
|   debug-mode-desc: "この設定はブラウザに記憶されます。" | ||||
| @@ -707,28 +713,28 @@ desktop/views/components/settings.2fa.vue: | ||||
|   unregister: "設定を解除" | ||||
|   unregistered: "二段階認証が無効になりました。" | ||||
|   enter-password: "パスワードを入力してください" | ||||
|   authenticator: "まず、Google Authenticatorをお使いのデバイスにインストールします:" | ||||
|   howtoinstall: "インストール方法はこちら" | ||||
|   scan: "次に、表示されているQRコードをスキャンします:" | ||||
|   done: "お使いのデバイスに表示されているトークンを入力して完了します:" | ||||
|   submit: "完了" | ||||
|   success: "設定が完了しました!" | ||||
|   failed: "設定に失敗しました。トークンに誤りがないかご確認ください。" | ||||
|   info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。" | ||||
|   authenticator: "まず、Google Authenticatorとかのをつこてるデバイスにインストールしてや:" | ||||
|   howtoinstall: "インストール方法はここやで" | ||||
|   scan: "んで、ここに出とるQRコードをスキャンしてな:" | ||||
|   done: "最後にデバイスに表示されとるトークンを入力してな:" | ||||
|   submit: "送信" | ||||
|   success: "設定が完了したで!" | ||||
|   failed: "なんか設定に失敗したで。トークンを間違えとらんか確認してや。" | ||||
|   info: "次のサインインからは、パスワードに加えてデバイスに出とるトークンを入力してな。" | ||||
| desktop/views/components/settings.api.vue: | ||||
|   intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。" | ||||
|   caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。" | ||||
|   regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。" | ||||
|   intro: "APIを利用するには、上記のトークンを「i」っちゅうキーでパラメータに付加してリクエストしてや。" | ||||
|   caution: "アカウントを不正利用されるかも知れんから、このトークンは第三者に教えたらあかんで(アプリなどにも入力しんといてな)。" | ||||
|   regeneration-of-token: "万が一このトークンが漏れたとかその可能性があったらトークンを再生成できるで。" | ||||
|   regenerate-token: "トークンを再生成" | ||||
|   token: "Token:" | ||||
|   enter-password: "パスワードを入力してください" | ||||
|   token: "トークン:" | ||||
|   enter-password: "パスワードを入力してや" | ||||
| desktop/views/components/settings.apps.vue: | ||||
|   no-apps: "連携しているアプリケーションはありません" | ||||
|   no-apps: "連携しているアプリケーションはあらへんで" | ||||
| desktop/views/components/settings.drive.vue: | ||||
|   max: "中" | ||||
|   in-use: "使用中" | ||||
| desktop/views/components/settings.mute.vue: | ||||
|   no-users: "ミュートしているユーザーはいません" | ||||
|   no-users: "ミュートしているユーザーはおらんで" | ||||
| desktop/views/components/settings.password.vue: | ||||
|   reset: "パスワードを変更する" | ||||
|   enter-current-password: "現在のパスワードを入力してください" | ||||
| @@ -764,7 +770,7 @@ desktop/views/components/timeline.vue: | ||||
|   global: "グローバル" | ||||
|   list: "リスト" | ||||
| desktop/views/components/ui.header.vue: | ||||
|   welcome-back: "おかえりなさい、" | ||||
|   welcome-back: "おかえり、" | ||||
|   adjective: "さん" | ||||
| desktop/views/components/ui.header.account.vue: | ||||
|   profile: "プロフィール" | ||||
| @@ -772,7 +778,7 @@ desktop/views/components/ui.header.account.vue: | ||||
|   favorites: "お気に入り" | ||||
|   lists: "リスト" | ||||
|   follow-requests: "フォロー申請" | ||||
|   customize: "ホームのカスタマイズ" | ||||
|   customize: "ホームをカスタマイズ" | ||||
|   admin: "管理" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
| @@ -794,7 +800,7 @@ desktop/views/components/received-follow-requests-window.vue: | ||||
|   reject: "拒否" | ||||
| desktop/views/components/user-lists-window.vue: | ||||
|   title: "リスト" | ||||
|   create-list: "リストを作成" | ||||
|   create-list: "新しいリストを作成" | ||||
|   list-name: "リスト名" | ||||
| desktop/views/components/user-preview.vue: | ||||
|   notes: "投稿" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -829,11 +835,11 @@ desktop/views/pages/admin/admin.suspend-user.vue: | ||||
| desktop/views/pages/admin/admin.unsuspend-user.vue: | ||||
|   unsuspend-user: "ユーザーの凍結の解除" | ||||
|   unsuspend: "凍結の解除" | ||||
|   unsuspended: "凍結を解除しました" | ||||
|   unsuspended: "凍結を解除したで" | ||||
| desktop/views/pages/admin/admin.verify-user.vue: | ||||
|   verify-user: "ユーザーの公式アカウント設定" | ||||
|   verify: "公式アカウントにする" | ||||
|   verified: "公式アカウントにしました" | ||||
|   verified: "公式アカウントにしたで" | ||||
| desktop/views/pages/admin/admin.unverify-user.vue: | ||||
|   unverify-user: "ユーザーの公式アカウント解除" | ||||
|   unverify: "公式アカウントを解除する" | ||||
| @@ -846,21 +852,28 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
|   signin: "ログイン" | ||||
|   signup: "新規登録" | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   signin: "サインイン" | ||||
|   signup: "サインアップ" | ||||
|   signin-button: "サインイン中…" | ||||
|   signup-button: "サインアップ" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
|   title: "ドライブ" | ||||
| desktop/views/pages/favorites.vue: | ||||
|   more: "さらに読み込む" | ||||
|   more: "もっと読み込んでくで" | ||||
| desktop/views/pages/home-customize.vue: | ||||
|   title: "ホームのカスタマイズ" | ||||
|   title: "ホームをカスタマイズ" | ||||
| desktop/views/pages/note.vue: | ||||
|   prev: "前の投稿" | ||||
|   next: "次の投稿" | ||||
| @@ -895,19 +908,19 @@ desktop/views/pages/user/user.vue: | ||||
| desktop/views/pages/user/user.home.vue: | ||||
|   last-used-at: "最終アクセス" | ||||
| desktop/views/pages/user/user.photos.vue: | ||||
|   title: "フォト" | ||||
|   title: "写真" | ||||
|   loading: "読み込み中" | ||||
|   no-photos: "写真はありません" | ||||
|   no-photos: "写真はあらへんで" | ||||
| desktop/views/pages/user/user.profile.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   follows-you: "フォローされとるで" | ||||
|   stalk: "ストークする" | ||||
|   stalking: "ストーキングしています" | ||||
|   stalking: "ストーキングしとるで" | ||||
|   unstalk: "ストーク解除" | ||||
|   mute: "ミュートする" | ||||
|   muted: "ミュートしています" | ||||
|   muted: "ミュートしとるで" | ||||
|   unmute: "ミュート解除" | ||||
|   push-to-a-list: "リストに追加" | ||||
|   list-pushed: "{user}を{list}に追加しました。" | ||||
|   list-pushed: "{user}を{list}に追加したで。" | ||||
| desktop/views/pages/user/user.header.vue: | ||||
|   posts: "投稿" | ||||
|   following: "フォロー" | ||||
| @@ -926,7 +939,7 @@ desktop/views/widgets/notifications.vue: | ||||
| desktop/views/widgets/polls.vue: | ||||
|   title: "アンケート" | ||||
|   refresh: "他を見る" | ||||
|   nothing: "ありません!" | ||||
|   nothing: "あらへん!" | ||||
| desktop/views/widgets/post-form.vue: | ||||
|   title: "投稿" | ||||
|   note: "投稿" | ||||
| @@ -948,7 +961,7 @@ mobile/views/components/drive.vue: | ||||
|   count-separator: "、" | ||||
|   file-count: "ファイル" | ||||
|   load-more: "もっと読み込む" | ||||
|   nothing-in-drive: "ドライブには何もありません" | ||||
|   nothing-in-drive: "ドライブには何もあらへんで。" | ||||
|   folder-is-empty: "このフォルダは空です" | ||||
|   prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>" | ||||
|   deletion-alert: "ごめんなさい!フォルダの削除は未実装です...。" | ||||
| @@ -1025,9 +1038,9 @@ mobile/views/components/post-form.vue: | ||||
|   quote-placeholder: "この投稿を引用... (オプション)" | ||||
|   reply-placeholder: "この投稿への返信..." | ||||
|   cw-placeholder: "内容への注釈 (オプション)" | ||||
|   location-alert: "お使いの端末は位置情報に対応していません" | ||||
|   location-alert: "あんさんのつことる端末は位置情報に対応しとらんみたいやわ、知らんけど。" | ||||
|   error: "エラー" | ||||
|   username-prompt: "ユーザー名を入力してください" | ||||
|   username-prompt: "ユーザー名を入力してや" | ||||
| mobile/views/components/sub-note-content.vue: | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| @@ -1066,7 +1079,7 @@ mobile/views/pages/favorites.vue: | ||||
|   title: "お気に入り" | ||||
| mobile/views/pages/user-lists.vue: | ||||
|   title: "リスト" | ||||
|   enter-list-name: "リスト名を入力してください" | ||||
|   enter-list-name: "リスト名を入力してや" | ||||
| mobile/views/pages/drive.vue: | ||||
|   drive: "ドライブ" | ||||
|   more: "もっと見る" | ||||
| @@ -1082,7 +1095,7 @@ mobile/views/pages/home.vue: | ||||
|   hybrid: "ソーシャル" | ||||
|   global: "グローバル" | ||||
| mobile/views/pages/tag.vue: | ||||
|   no-posts-found: "ハッシュタグ「{}」が付けられた投稿は見つかりませんでした。" | ||||
|   no-posts-found: "ハッシュタグ「{}」が付けられた投稿はあらへんで。" | ||||
| mobile/views/pages/welcome.vue: | ||||
|   signup: "新規登録" | ||||
| mobile/views/pages/widgets.vue: | ||||
| @@ -1149,7 +1162,10 @@ mobile/views/pages/settings.vue: | ||||
|   show-local-renotes: "ローカルの投稿のRenoteを表示する" | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   post-style-smart: "べっぴんさん" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "게시물의 문자 애니메이션을 비활성화 할" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "무승부" | ||||
|     my-turn: "당신의 차례입니다" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
							
								
								
									
										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: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "Wyłącz animowany tekst we wpisach" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "Remis" | ||||
|     my-turn: "Twoja kolej" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "Autorzy" | ||||
|   feedback: "Podziel się opinią" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "Dodaj do ulubionych" | ||||
|   pin: "Przypnij do profilu" | ||||
|   delete: "Usuń" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "Bezpośredni" | ||||
|   specified-desc: "Tylko dla określonych użytkowników" | ||||
|   private: "Prywatny" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "Sprawdzanie" | ||||
|   no-broadcasts: "Brak transmisji" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "Przełącz widok" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "Hashtagi" | ||||
|   count: "Wspomniany przez {} użytkowników" | ||||
|   empty: "Brak popularnych hashtagów" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "Informacje o serwerze" | ||||
|   toggle: "Przełącz widok" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "Wysyłanie awatara" | ||||
|   avatar-updated: "Wysłano awatar" | ||||
|   choose-avatar: "Wybierz awatar" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Czarny … Łącznie" | ||||
|   notes: "Niebieski … Wpisy" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "Używaj gradientów na pasku tytułu okna" | ||||
|   post-form-on-timeline: "Wyświetlaj formularz tworzenia wpisu w górnej części osi czasu" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "Pokazuj cel odpowiedzi" | ||||
|   show-my-renotes: "Pokazuj moje udostępnienia na osi czasu" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "Udostępniono przez {}" | ||||
|   private: "ten wpis jest prywatny" | ||||
|   deleted: "ten wpis został usunięty" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "O Misskey" | ||||
|   gotit: "Rozumiem!" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "Zaloguj się" | ||||
|   signup-button: "Zarejestruj się" | ||||
|   timeline: "Oś czasu" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Oparto o <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Dysk Misskey" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "Styl wpisów" | ||||
|   post-style-standard: "Standardowy" | ||||
|   post-style-smart: "Inteligentny" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "Zachowanie" | ||||
|   fetch-on-scroll: "Automatycznie ładuj po przeciągnięciu w dół" | ||||
|   disable-via-mobile: "Nie oznaczaj wpisów jako „wysłane z telefonu”" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "Odśwież stronę, aby zastosować aktualizację." | ||||
|   settings: "Ustawienia" | ||||
|   signout: "Wyloguj" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "Śledzi Cię" | ||||
|   following: "Śledzeni" | ||||
|   | ||||
| @@ -58,7 +58,7 @@ common: | ||||
|     friday: "sexta" | ||||
|     saturday: "sábado" | ||||
|   reactions: | ||||
|     like: "いいね" | ||||
|     like: "Curtir" | ||||
|     love: "Amei" | ||||
|     laugh: "Riso" | ||||
|     hmm: "Hmm...?" | ||||
| @@ -81,12 +81,13 @@ common: | ||||
|   ok: "OK" | ||||
|   update-available-title: "Atualização disponível" | ||||
|   update-available: "Uma nova versão de Misskey está disponível ({newer}). A versão atual é {current}. Recarregue a página para atualizar." | ||||
|   my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。" | ||||
|   my-token-regenerated: "Seu token foi recriado, portanto você foi deslogado." | ||||
|   i-like-sushi: "Eu prefiro sushi a pudim" | ||||
|   show-reversi-board-labels: "Mostrar etiquetas de colunas e linhas no Reversi" | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "Conta verificada" | ||||
|   disable-animated-mfm: "Desativar texto animado nas publicações" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "Empatado" | ||||
|     my-turn: "Seu turno" | ||||
| @@ -97,7 +98,7 @@ common: | ||||
|     black: "Pretas" | ||||
|     white: "Brancas" | ||||
|     total: "Total" | ||||
|     this-turn: "{}ターン目" | ||||
|     this-turn: "Turno de {}" | ||||
|   widgets: | ||||
|     analog-clock: "Relógio analógico" | ||||
|     profile: "Perfil" | ||||
| @@ -106,16 +107,16 @@ common: | ||||
|     activity: "Atividade" | ||||
|     rss: "Leitor de RSS" | ||||
|     memo: "Nota adesiva" | ||||
|     trends: "トレンド" | ||||
|     trends: "Tendências" | ||||
|     photo-stream: "フォトストリーム" | ||||
|     posts-monitor: "投稿チャート" | ||||
|     posts-monitor: "Gráfico de publicações" | ||||
|     slideshow: "スライドショー" | ||||
|     version: "Versão" | ||||
|     broadcast: "ブロードキャスト" | ||||
|     notifications: "Notificações" | ||||
|     users: "Usuário sugeridos" | ||||
|     polls: "Enquetes" | ||||
|     post-form: "投稿フォーム" | ||||
|     post-form: "Formulário de publicação" | ||||
|     messaging: "Mensagens" | ||||
|     server: "Informações do servidor" | ||||
|     donation: "Doações" | ||||
| @@ -135,10 +136,10 @@ common: | ||||
|     swap-up: "Mover para cima" | ||||
|     swap-down: "Mover para baixo" | ||||
|     remove: "Remover" | ||||
|     add-column: "カラムを追加" | ||||
|     add-column: "Adicionar coluna" | ||||
|     rename: "Renomear" | ||||
|     stack-left: "左に重ねる" | ||||
|     pop-right: "右に出す" | ||||
|     pop-right: "Acoplar à direita" | ||||
| auth/views/form.vue: | ||||
|   share-access: "Você <b>permite</b> que <i>{{ app.name }}</i> acesse sua conta?" | ||||
|   permission-ask: "Este aplicativo precisa das seguintes permissões:" | ||||
| @@ -151,18 +152,18 @@ auth/views/form.vue: | ||||
|   drive-write: "ドライブを操作する。" | ||||
|   notification-read: "通知を見る。" | ||||
|   notification-write: "通知を操作する。" | ||||
|   cancel: "キャンセル" | ||||
|   accept: "アクセスを許可" | ||||
|   cancel: "Cancelar" | ||||
|   accept: "Permitir acesso" | ||||
| auth/views/index.vue: | ||||
|   loading: "読み込み中" | ||||
|   loading: "Carregando" | ||||
|   denied: "アプリケーションの連携をキャンセルしました。" | ||||
|   denied-paragraph: "このアプリがあなたのアカウントにアクセスすることはありません。" | ||||
|   already-authorized: "このアプリは既に連携済みです" | ||||
|   allowed: "アプリケーションの連携を許可しました" | ||||
|   callback-url: "アプリケーションに戻っています" | ||||
|   please-go-back: "アプリケーションに戻って、やっていってください。" | ||||
|   error: "セッションが存在しません。" | ||||
|   sign-in: "サインインしてください" | ||||
|   already-authorized: "Este aplicativo já foi autorizado" | ||||
|   allowed: "Aplicativos com acesso autorizado" | ||||
|   callback-url: "Voltando ao aplicativo" | ||||
|   please-go-back: "Por favor, volte ao aplicativo." | ||||
|   error: "A sessão não existe." | ||||
|   sign-in: "Por favor, entre." | ||||
| common/views/components/games/reversi/reversi.vue: | ||||
|   matching: | ||||
|     waiting-for: "{}を待っています" | ||||
| @@ -176,17 +177,17 @@ common/views/components/games/reversi/reversi.game.vue: | ||||
| common/views/components/games/reversi/reversi.index.vue: | ||||
|   title: "Misskey Reversi" | ||||
|   sub-title: "他のMisskeyユーザーとリバーシで対戦しよう" | ||||
|   invite: "招待" | ||||
|   rule: "遊び方" | ||||
|   invite: "Convidar" | ||||
|   rule: "Como jogar" | ||||
|   rule-desc: "リバーシは、相手と交互に石をボードに置いて、相手の石を挟んで自分の色に変えてゆき、最終的に残った石が多い方が勝ちというボードゲームです。" | ||||
|   mode-invite: "招待" | ||||
|   mode-invite-desc: "指定したユーザーと対戦するモードです。" | ||||
|   invitations: "対局の招待があります!" | ||||
|   my-games: "自分の対局" | ||||
|   all-games: "みんなの対局" | ||||
|   enter-username: "ユーザー名を入力してください" | ||||
|   mode-invite: "Convidar" | ||||
|   mode-invite-desc: "Convidar um usuário para jogar" | ||||
|   invitations: "Você foi convidado!" | ||||
|   my-games: "Meu jogo" | ||||
|   all-games: "Todos os jogos" | ||||
|   enter-username: "Digite o nome de usuário." | ||||
|   game-state: | ||||
|     ended: "終了" | ||||
|     ended: "Terminado" | ||||
|     playing: "進行中" | ||||
| common/views/components/games/reversi/reversi.room.vue: | ||||
|   settings-of-the-game: "ゲームの設定" | ||||
| @@ -228,11 +229,11 @@ common/views/components/connect-failed.troubleshooter.vue: | ||||
|   no-server-desc: "お使いのPCのインターネット接続は正常ですが、Misskeyのサーバーには接続できませんでした。サーバーがダウンまたはメンテナンスしている可能性があるので、しばらくしてから再度御アクセスください。" | ||||
|   success: "Misskeyのサーバーに接続できました" | ||||
|   success-desc: "正常に接続できるようです。ページを再度読み込みしてください。" | ||||
|   flush: "キャッシュの削除" | ||||
|   flush: "Limpar o cache" | ||||
|   set-version: "バージョン指定" | ||||
| common/views/components/messaging.vue: | ||||
|   search-user: "ユーザーを探す" | ||||
|   you: "あなた" | ||||
|   you: "Você" | ||||
|   no-history: "履歴はありません" | ||||
| common/views/components/messaging-room.vue: | ||||
|   empty: "このユーザーと話したことはありません" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "Todos os usuários" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "Todas as notas" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "Timeline" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Desenvolvido por <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Drive Misskey" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "引き分け" | ||||
|     my-turn: "あなたのターンです" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
| @@ -87,6 +87,7 @@ common: | ||||
|   use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける" | ||||
|   verified-user: "公式アカウント" | ||||
|   disable-animated-mfm: "投稿内の動きのあるテキストを無効にする" | ||||
|   do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。' | ||||
|   reversi: | ||||
|     drawn: "引き分け" | ||||
|     my-turn: "あなたのターンです" | ||||
| @@ -260,6 +261,8 @@ common/views/components/nav.vue: | ||||
|   develop: "開発者" | ||||
|   feedback: "フィードバック" | ||||
| common/views/components/note-menu.vue: | ||||
|   detail: "詳細" | ||||
|   copy-link: "リンクをコピー" | ||||
|   favorite: "お気に入り" | ||||
|   pin: "ピン留め" | ||||
|   delete: "削除" | ||||
| @@ -337,6 +340,9 @@ common/views/components/visibility-chooser.vue: | ||||
|   specified: "ダイレクト" | ||||
|   specified-desc: "指定したユーザーにのみ公開" | ||||
|   private: "非公開" | ||||
| common/views/components/trends.vue: | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "確認中" | ||||
|   no-broadcasts: "お知らせはありません" | ||||
| @@ -360,8 +366,6 @@ common/views/widgets/posts-monitor.vue: | ||||
|   toggle: "表示を切り替え" | ||||
| common/views/widgets/hashtags.vue: | ||||
|   title: "ハッシュタグ" | ||||
|   count: "{}人が投稿" | ||||
|   empty: "トレンドなし" | ||||
| common/views/widgets/server.vue: | ||||
|   title: "サーバー情報" | ||||
|   toggle: "表示を切り替え" | ||||
| @@ -411,6 +415,7 @@ desktop: | ||||
|   uploading-avatar: "新しいアバターをアップロードしています" | ||||
|   avatar-updated: "アバターを更新しました" | ||||
|   choose-avatar: "アバターにする画像を選択" | ||||
|   invalid-filetype: "この形式のファイルはサポートされていません" | ||||
| desktop/views/components/activity.chart.vue: | ||||
|   total: "Black ... Total" | ||||
|   notes: "Blue ... Notes" | ||||
| @@ -649,6 +654,7 @@ desktop/views/components/settings.vue: | ||||
|   gradient-window-header: "ウィンドウのタイトルバーにグラデーションを使用" | ||||
|   post-form-on-timeline: "タイムライン上部に投稿フォームを表示する" | ||||
|   suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する" | ||||
|   show-clock-on-header: "右上に時計を表示する" | ||||
|   show-reply-target: "リプライ先を表示する" | ||||
|   show-my-renotes: "自分の行ったRenoteをタイムラインに表示する" | ||||
|   show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する" | ||||
| @@ -819,8 +825,8 @@ desktop/views/pages/admin/admin.dashboard.vue: | ||||
|   dashboard: "ダッシュボード" | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全てのノート" | ||||
|   original-notes: "このインスタンスのノート" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
|   invite: "招待" | ||||
| desktop/views/pages/admin/admin.suspend-user.vue: | ||||
|   suspend-user: "ユーザーの凍結" | ||||
| @@ -846,6 +852,11 @@ desktop/views/pages/deck/deck.note.vue: | ||||
|   reposted-by: "{}がRenote" | ||||
|   private: "この投稿は非公開です" | ||||
|   deleted: "この投稿は削除されました" | ||||
| desktop/views/pages/stats/stats.vue: | ||||
|   all-users: "全てのユーザー" | ||||
|   original-users: "このインスタンスのユーザー" | ||||
|   all-notes: "全ての投稿" | ||||
|   original-notes: "このインスタンスの投稿" | ||||
| desktop/views/pages/welcome.vue: | ||||
|   about: "詳しく..." | ||||
|   gotit: "わかった" | ||||
| @@ -854,6 +865,8 @@ desktop/views/pages/welcome.vue: | ||||
|   signin-button: "やってる" | ||||
|   signup-button: "やる" | ||||
|   timeline: "タイムライン" | ||||
|   announcements: "お知らせ" | ||||
|   photos: "最近の画像" | ||||
|   powered-by-misskey: "Powered by <b>Misskey</b>." | ||||
| desktop/views/pages/drive.vue: | ||||
|   title: "Misskey Drive" | ||||
| @@ -1150,6 +1163,9 @@ mobile/views/pages/settings.vue: | ||||
|   post-style: "投稿の表示スタイル" | ||||
|   post-style-standard: "標準" | ||||
|   post-style-smart: "スマート" | ||||
|   notification-position: "通知の表示" | ||||
|   notification-position-bottom: "下" | ||||
|   notification-position-top: "上" | ||||
|   behavior: "動作" | ||||
|   fetch-on-scroll: "スクロールで自動読み込み" | ||||
|   disable-via-mobile: "「モバイルからの投稿」フラグを付けない" | ||||
| @@ -1170,6 +1186,8 @@ mobile/views/pages/settings.vue: | ||||
|   update-available-desc: "ページを再度読み込みすると更新が適用されます。" | ||||
|   settings: "設定" | ||||
|   signout: "サインアウト" | ||||
|   sound: "サウンド" | ||||
|   enableSounds: "サウンドを有効にする" | ||||
| mobile/views/pages/user.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   following: "フォロー" | ||||
|   | ||||
							
								
								
									
										32
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| { | ||||
| 	"name": "misskey", | ||||
| 	"author": "syuilo <i@syuilo.com>", | ||||
| 	"version": "8.10.0", | ||||
| 	"clientVersion": "1.0.8972", | ||||
| 	"version": "8.28.0", | ||||
| 	"clientVersion": "1.0.9400", | ||||
| 	"codename": "nighthike", | ||||
| 	"main": "./built/index.js", | ||||
| 	"private": true, | ||||
| @@ -32,7 +32,7 @@ | ||||
| 		"@types/debug": "0.0.30", | ||||
| 		"@types/deep-equal": "1.0.1", | ||||
| 		"@types/double-ended-queue": "2.1.0", | ||||
| 		"@types/elasticsearch": "5.0.25", | ||||
| 		"@types/elasticsearch": "5.0.26", | ||||
| 		"@types/file-type": "5.2.1", | ||||
| 		"@types/gulp": "3.8.36", | ||||
| 		"@types/gulp-htmlmin": "1.3.32", | ||||
| @@ -55,12 +55,12 @@ | ||||
| 		"@types/koa-send": "4.1.1", | ||||
| 		"@types/koa-views": "2.0.3", | ||||
| 		"@types/koa__cors": "2.2.3", | ||||
| 		"@types/minio": "6.0.2", | ||||
| 		"@types/minio": "7.0.0", | ||||
| 		"@types/mkdirp": "0.5.2", | ||||
| 		"@types/mocha": "5.2.3", | ||||
| 		"@types/mongodb": "3.1.4", | ||||
| 		"@types/ms": "0.7.30", | ||||
| 		"@types/node": "10.9.1", | ||||
| 		"@types/node": "10.9.4", | ||||
| 		"@types/portscanner": "2.1.0", | ||||
| 		"@types/pug": "2.0.4", | ||||
| 		"@types/qrcode": "1.2.0", | ||||
| @@ -76,11 +76,11 @@ | ||||
| 		"@types/speakeasy": "2.0.2", | ||||
| 		"@types/systeminformation": "3.23.0", | ||||
| 		"@types/tmp": "0.0.33", | ||||
| 		"@types/uuid": "3.4.3", | ||||
| 		"@types/uuid": "3.4.4", | ||||
| 		"@types/webpack": "4.4.11", | ||||
| 		"@types/webpack-stream": "3.2.10", | ||||
| 		"@types/websocket": "0.0.39", | ||||
| 		"@types/ws": "6.0.0", | ||||
| 		"@types/websocket": "0.0.40", | ||||
| 		"@types/ws": "6.0.1", | ||||
| 		"animejs": "2.2.0", | ||||
| 		"autosize": "4.0.2", | ||||
| 		"autwh": "0.1.0", | ||||
| @@ -158,10 +158,10 @@ | ||||
| 		"mongodb": "3.1.1", | ||||
| 		"monk": "6.0.6", | ||||
| 		"ms": "2.1.1", | ||||
| 		"nan": "2.10.0", | ||||
| 		"nan": "2.11.0", | ||||
| 		"nested-property": "0.0.7", | ||||
| 		"node-sass": "4.9.3", | ||||
| 		"node-sass-json-importer": "3.3.1", | ||||
| 		"node-sass-json-importer": "4.0.1", | ||||
| 		"nprogress": "0.2.0", | ||||
| 		"object-assign-deep": "0.4.0", | ||||
| 		"on-build-webpack": "0.1.0", | ||||
| @@ -190,11 +190,11 @@ | ||||
| 		"single-line-log": "1.1.2", | ||||
| 		"speakeasy": "2.0.0", | ||||
| 		"stringz": "1.0.0", | ||||
| 		"style-loader": "0.22.1", | ||||
| 		"style-loader": "0.23.0", | ||||
| 		"stylus": "0.54.5", | ||||
| 		"stylus-loader": "3.0.2", | ||||
| 		"summaly": "2.1.4", | ||||
| 		"systeminformation": "3.42.9", | ||||
| 		"summaly": "2.2.0", | ||||
| 		"systeminformation": "3.45.1", | ||||
| 		"syuilo-password-strength": "0.0.1", | ||||
| 		"textarea-caret": "3.1.0", | ||||
| 		"tmp": "0.0.33", | ||||
| @@ -210,9 +210,9 @@ | ||||
| 		"vue": "2.5.17", | ||||
| 		"vue-chartjs": "3.4.0", | ||||
| 		"vue-cropperjs": "2.2.1", | ||||
| 		"vue-js-modal": "1.3.19", | ||||
| 		"vue-js-modal": "1.3.26", | ||||
| 		"vue-json-tree-view": "2.1.4", | ||||
| 		"vue-loader": "15.4.0", | ||||
| 		"vue-loader": "15.4.1", | ||||
| 		"vue-router": "3.0.1", | ||||
| 		"vue-style-loader": "4.1.2", | ||||
| 		"vue-template-compiler": "2.5.17", | ||||
| @@ -221,7 +221,7 @@ | ||||
| 		"vuex-persistedstate": "2.5.4", | ||||
| 		"web-push": "3.3.2", | ||||
| 		"webfinger.js": "2.6.6", | ||||
| 		"webpack": "4.17.1", | ||||
| 		"webpack": "4.17.2", | ||||
| 		"webpack-cli": "3.1.0", | ||||
| 		"websocket": "1.0.26", | ||||
| 		"ws": "6.0.0", | ||||
|   | ||||
| @@ -6,6 +6,10 @@ html | ||||
| 		&, * | ||||
| 			cursor progress !important | ||||
|  | ||||
| html | ||||
| 	// iOSのため | ||||
| 	overflow auto | ||||
|  | ||||
| body | ||||
| 	overflow-wrap break-word | ||||
|  | ||||
|   | ||||
| @@ -80,7 +80,7 @@ export default Vue.extend({ | ||||
| 		accepted() { | ||||
| 			this.state = 'accepted'; | ||||
| 			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}`; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -51,8 +51,9 @@ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (settings) { | ||||
| 		if (settings.device.lang) lang = settings.device.lang; | ||||
| 	if (settings && settings.device.lang && | ||||
| 		LANGS.includes(settings.device.lang)) { | ||||
| 		lang = settings.device.lang; | ||||
| 	} | ||||
| 	//#endregion | ||||
|  | ||||
| @@ -93,7 +94,7 @@ | ||||
|  | ||||
| 	// Get salt query | ||||
| 	const salt = localStorage.getItem('salt') | ||||
| 		? '?salt=' + localStorage.getItem('salt') | ||||
| 		? `?salt=${localStorage.getItem('salt')}` | ||||
| 		: ''; | ||||
|  | ||||
| 	// Load an app script | ||||
| @@ -139,7 +140,7 @@ | ||||
| 		// Random | ||||
| 		localStorage.setItem('salt', Math.random().toString()); | ||||
|  | ||||
| 		// Clear cache (serive worker) | ||||
| 		// Clear cache (service worker) | ||||
| 		try { | ||||
| 			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('v', newer); | ||||
|  | ||||
| 		// Clear cache (serive worker) | ||||
| 		// Clear cache (service worker) | ||||
| 		try { | ||||
| 			if (navigator.serviceWorker.controller) { | ||||
| 				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 { | ||||
| 	constructor(os: MiOS, me, game) { | ||||
| 		super(os, 'games/reversi-game', { | ||||
| 			i: me ? me.token : null, | ||||
| 		super(os, 'games/reversi-game', me ? { | ||||
| 			i: me.token, | ||||
| 			game: game.id | ||||
| 		} : { | ||||
| 			game: game.id | ||||
| 		}); | ||||
| 	} | ||||
|   | ||||
| @@ -7,9 +7,9 @@ import MiOS from '../../../mios'; | ||||
|  */ | ||||
| export class LocalTimelineStream extends Stream { | ||||
| 	constructor(os: MiOS, me) { | ||||
| 		super(os, 'local-timeline', { | ||||
| 		super(os, 'local-timeline', me ? { | ||||
| 			i: me.token | ||||
| 		}); | ||||
| 		} : {}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { EventEmitter } from 'eventemitter3'; | ||||
| import * as uuid from 'uuid'; | ||||
| 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 | ||||
| 	 */ | ||||
| 	public dispose(userId) { | ||||
| 		this.users = this.users.filter(id => id != userId); | ||||
| 		this.users = erase(userId, this.users); | ||||
|  | ||||
| 		this._connection.user = `Managed (${ this.users.length })`; | ||||
|  | ||||
|   | ||||
| @@ -44,11 +44,11 @@ export default class Connection extends EventEmitter { | ||||
|  | ||||
| 		const query = params | ||||
| 			? Object.keys(params) | ||||
| 				.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])) | ||||
| 				.map(k => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`) | ||||
| 				.join('&') | ||||
| 			: 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('close', this.onClose); | ||||
| 		this.socket.addEventListener('message', this.onMessage); | ||||
|   | ||||
| @@ -1,14 +1,20 @@ | ||||
| <template> | ||||
| <span class="mk-acct"> | ||||
| 	<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> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { host } from '../../../config'; | ||||
| export default Vue.extend({ | ||||
| 	props: ['user'] | ||||
| 	props: ['user', 'detail'], | ||||
| 	data() { | ||||
| 		return { | ||||
| 			host | ||||
| 		}; | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -125,7 +125,7 @@ export default Vue.extend({ | ||||
| 			} | ||||
|  | ||||
| 			if (this.type == 'user') { | ||||
| 				const cacheKey = 'autocomplete:user:' + this.q; | ||||
| 				const cacheKey = `autocomplete:user:${this.q}`; | ||||
| 				const cache = sessionStorage.getItem(cacheKey); | ||||
| 				if (cache) { | ||||
| 					const users = JSON.parse(cache); | ||||
| @@ -148,7 +148,7 @@ export default Vue.extend({ | ||||
| 					this.hashtags = JSON.parse(localStorage.getItem('hashtags') || '[]'); | ||||
| 					this.fetching = false; | ||||
| 				} else { | ||||
| 					const cacheKey = 'autocomplete:hashtag:' + this.q; | ||||
| 					const cacheKey = `autocomplete:hashtag:${this.q}`; | ||||
| 					const cache = sessionStorage.getItem(cacheKey); | ||||
| 					if (cache) { | ||||
| 						const hashtags = JSON.parse(cache); | ||||
|   | ||||
| @@ -57,7 +57,7 @@ export default Vue.extend({ | ||||
| 		} | ||||
|  | ||||
| 		// Check internet connection | ||||
| 		fetch('https://google.com?rand=' + Math.random(), { | ||||
| 		fetch(`https://google.com?rand=${Math.random()}`, { | ||||
| 			mode: 'no-cors' | ||||
| 		}).then(() => { | ||||
| 			this.internet = true; | ||||
|   | ||||
| @@ -159,11 +159,9 @@ export default Vue.extend({ | ||||
| 				canPutEverywhere: this.game.settings.canPutEverywhere, | ||||
| 				loopedBoard: this.game.settings.loopedBoard | ||||
| 			}); | ||||
| 			this.logs.forEach((log, i) => { | ||||
| 				if (i < v) { | ||||
| 					this.o.put(log.color, log.pos); | ||||
| 				} | ||||
| 			}); | ||||
| 			for (const log of this.logs.slice(0, v)) { | ||||
| 				this.o.put(log.color, log.pos); | ||||
| 			} | ||||
| 			this.$forceUpdate(); | ||||
| 		} | ||||
| 	}, | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| import trends from './trends.vue'; | ||||
| import analogClock from './analog-clock.vue'; | ||||
| import menu from './menu.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 formRadio from './ui/form/radio.vue'; | ||||
|  | ||||
| Vue.component('mk-trends', trends); | ||||
| Vue.component('mk-analog-clock', analogClock); | ||||
| Vue.component('mk-menu', menu); | ||||
| Vue.component('mk-note-header', noteHeader); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="mk-menu"> | ||||
| <div class="onchrpzrvnoruiaenfcqvccjfuupzzwv"> | ||||
| 	<div class="backdrop" ref="backdrop" @click="close"></div> | ||||
| 	<div class="popover" :class="{ hukidasi }" ref="popover"> | ||||
| 		<template v-for="item in items"> | ||||
| @@ -119,9 +119,10 @@ export default Vue.extend({ | ||||
| <style lang="stylus" scoped> | ||||
| @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 | ||||
|  | ||||
| 	> .backdrop | ||||
| @@ -131,14 +132,14 @@ $border-color = rgba(27, 31, 35, 0.15) | ||||
| 		z-index 10000 | ||||
| 		width 100% | ||||
| 		height 100% | ||||
| 		background rgba(#000, 0.1) | ||||
| 		background rgba(#000, isDark ? 0.5 : 0.1) | ||||
| 		opacity 0 | ||||
|  | ||||
| 	> .popover | ||||
| 		position absolute | ||||
| 		z-index 10001 | ||||
| 		padding 8px 0 | ||||
| 		background #fff | ||||
| 		background $bg-color | ||||
| 		border 1px solid $border-color | ||||
| 		border-radius 4px | ||||
| 		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-left solid $balloon-size transparent | ||||
| 				border-right solid $balloon-size transparent | ||||
| 				border-bottom solid $balloon-size #fff | ||||
| 				border-bottom solid $balloon-size $bg-color | ||||
|  | ||||
| 		> button | ||||
| 			display block | ||||
| 			padding 8px 16px | ||||
| 			width 100% | ||||
| 			color isDark ? #d6dce2 : #111 | ||||
|  | ||||
| 			&:hover | ||||
| 				color $theme-color-foreground | ||||
| @@ -191,6 +193,12 @@ $border-color = rgba(27, 31, 35, 0.15) | ||||
| 		> div | ||||
| 			margin 8px 0 | ||||
| 			height 1px | ||||
| 			background #eee | ||||
| 			background isDark ? #1c2023 : #eee | ||||
|  | ||||
| .onchrpzrvnoruiaenfcqvccjfuupzzwv[data-darkmode] | ||||
| 	root(true) | ||||
|  | ||||
| .onchrpzrvnoruiaenfcqvccjfuupzzwv:not([data-darkmode]) | ||||
| 	root(false) | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| 	@dragover.prevent.stop="onDragover" | ||||
| 	@drop.prevent.stop="onDrop" | ||||
| > | ||||
| 	<div class="stream"> | ||||
| 	<div class="body"> | ||||
| 		<p class="init" v-if="init">%fa:spinner .spin%%i18n:common.loading%</p> | ||||
| 		<p class="empty" v-if="!init && messages.length == 0">%fa:info-circle%%i18n:@empty%</p> | ||||
| 		<p class="no-history" v-if="!init && messages.length > 0 && !existMoreMessages">%fa:flag%%i18n:@no-history%</p> | ||||
| @@ -77,6 +77,12 @@ export default Vue.extend({ | ||||
| 		this.connection.on('message', this.onMessage); | ||||
| 		this.connection.on('read', this.onRead); | ||||
|  | ||||
| 		if (this.isNaked) { | ||||
| 			window.addEventListener('scroll', this.onScroll, { passive: true }); | ||||
| 		} else { | ||||
| 			this.$el.addEventListener('scroll', this.onScroll, { passive: true }); | ||||
| 		} | ||||
|  | ||||
| 		document.addEventListener('visibilitychange', this.onVisibilitychange); | ||||
|  | ||||
| 		this.fetchMessages().then(() => { | ||||
| @@ -90,6 +96,12 @@ export default Vue.extend({ | ||||
| 		this.connection.off('read', this.onRead); | ||||
| 		this.connection.close(); | ||||
|  | ||||
| 		if (this.isNaked) { | ||||
| 			window.removeEventListener('scroll', this.onScroll); | ||||
| 		} else { | ||||
| 			this.$el.removeEventListener('scroll', this.onScroll); | ||||
| 		} | ||||
|  | ||||
| 		document.removeEventListener('visibilitychange', this.onVisibilitychange); | ||||
| 	}, | ||||
|  | ||||
| @@ -226,6 +238,14 @@ export default Vue.extend({ | ||||
| 			}, 4000); | ||||
| 		}, | ||||
|  | ||||
| 		onScroll() { | ||||
| 			const el = this.isNaked ? window.document.documentElement : this.$el; | ||||
| 			const current = el.scrollTop + el.clientHeight; | ||||
| 			if (current > el.scrollHeight - 1) { | ||||
| 				this.showIndicator = false; | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
| 		onVisibilitychange() { | ||||
| 			if (document.hidden) return; | ||||
| 			this.messages.forEach(message => { | ||||
| @@ -251,7 +271,7 @@ root(isDark) | ||||
| 	height 100% | ||||
| 	background isDark ? #191b22 : #fff | ||||
|  | ||||
| 	> .stream | ||||
| 	> .body | ||||
| 		width 100% | ||||
| 		max-width 600px | ||||
| 		margin 0 auto | ||||
|   | ||||
| @@ -205,17 +205,8 @@ export default Vue.component('misskey-flavored-markdown', { | ||||
| 			} | ||||
| 		})); | ||||
|  | ||||
| 		const _els = []; | ||||
| 		els.forEach((el, i) => { | ||||
| 			if (el.tag == 'br') { | ||||
| 				if (!['div', 'pre'].includes(els[i - 1].tag)) { | ||||
| 					_els.push(el); | ||||
| 				} | ||||
| 			} else { | ||||
| 				_els.push(el); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// el.tag === 'br' のとき i !== 0 が保証されるため、短絡評価により els[i - 1] は配列外参照しない | ||||
| 		const _els = els.filter((el, i) => !(el.tag === 'br' && ['div', 'pre'].includes(els[i - 1].tag))); | ||||
| 		return createElement('span', _els); | ||||
| 	} | ||||
| }); | ||||
|   | ||||
| @@ -26,8 +26,8 @@ export default Vue.extend({ | ||||
| 	}, | ||||
| 	created() { | ||||
| 		(this as any).os.getMeta().then(meta => { | ||||
| 			if (meta.repositoryUrl) this.repositoryUrl = meta.repositoryUrl; | ||||
| 			if (meta.feedbackUrl) this.feedbackUrl = meta.feedbackUrl; | ||||
| 			if (meta.maintainer.repository_url) this.repositoryUrl = meta.maintainer.repository_url; | ||||
| 			if (meta.maintainer.feedback_url) this.feedbackUrl = meta.maintainer.feedback_url; | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
|   | ||||
| @@ -6,17 +6,27 @@ | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { url } from '../../../config'; | ||||
| import copyToClipboard from '../../../common/scripts/copy-to-clipboard'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	props: ['note', 'source', 'compact'], | ||||
| 	computed: { | ||||
| 		items() { | ||||
| 			const items = []; | ||||
| 			items.push({ | ||||
| 			const items = [{ | ||||
| 				icon: '%fa:info-circle%', | ||||
| 				text: '%i18n:@detail%', | ||||
| 				action: this.detail | ||||
| 			}, { | ||||
| 				icon: '%fa:link%', | ||||
| 				text: '%i18n:@copy-link%', | ||||
| 				action: this.copyLink | ||||
| 			}, null, { | ||||
| 				icon: '%fa:star%', | ||||
| 				text: '%i18n:@favorite%', | ||||
| 				action: this.favorite | ||||
| 			}); | ||||
| 			}]; | ||||
|  | ||||
| 			if (this.note.userId == this.$store.state.i.id) { | ||||
| 				items.push({ | ||||
| 					icon: '%fa:thumbtack%', | ||||
| @@ -42,6 +52,14 @@ export default Vue.extend({ | ||||
| 		} | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		detail() { | ||||
| 			this.$router.push(`/notes/${ this.note.id }`); | ||||
| 		}, | ||||
|  | ||||
| 		copyLink() { | ||||
| 			copyToClipboard(`${url}/notes/${ this.note.id }`); | ||||
| 		}, | ||||
|  | ||||
| 		pin() { | ||||
| 			(this as any).api('i/pin', { | ||||
| 				noteId: this.note.id | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { erase } from '../../../../../prelude/array'; | ||||
| export default Vue.extend({ | ||||
| 	data() { | ||||
| 		return { | ||||
| @@ -53,7 +54,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 		get() { | ||||
| 			return { | ||||
| 				choices: this.choices.filter(choice => choice != '') | ||||
| 				choices: erase('', this.choices) | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
|   | ||||
| @@ -21,6 +21,7 @@ | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { sum } from '../../../../../prelude/array'; | ||||
| export default Vue.extend({ | ||||
| 	props: ['note'], | ||||
| 	data() { | ||||
| @@ -33,7 +34,7 @@ export default Vue.extend({ | ||||
| 			return this.note.poll; | ||||
| 		}, | ||||
| 		total(): number { | ||||
| 			return this.poll.choices.reduce((a, b) => a + b.votes, 0); | ||||
| 			return sum(this.poll.choices.map(x => x.votes)); | ||||
| 		}, | ||||
| 		isVoted(): boolean { | ||||
| 			return this.poll.choices.some(c => c.isVoted); | ||||
|   | ||||
| @@ -78,7 +78,7 @@ export default Vue.extend({ | ||||
| 			cursor wait !important | ||||
|  | ||||
| 	> .avatar | ||||
| 		margin 16px auto 0 auto | ||||
| 		margin 0 auto 0 auto | ||||
| 		width 64px | ||||
| 		height 64px | ||||
| 		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) | ||||
| 	margin 16px | ||||
| 	padding 16px | ||||
| 	color isDark ? #fff : #000 | ||||
| 	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) | ||||
|  | ||||
| 	@media (min-width 500px) | ||||
| 		padding 32px | ||||
|  | ||||
| 	> header | ||||
| 		font-weight normal | ||||
| 		font-size 24px | ||||
| 		padding 16px | ||||
| 		font-weight bold | ||||
| 		font-size 20px | ||||
| 		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] | ||||
| 	root(true) | ||||
|  | ||||
|   | ||||
| @@ -55,7 +55,7 @@ export default Vue.extend({ | ||||
|  | ||||
| root(isDark) | ||||
| 	display inline-block | ||||
| 	margin 32px 32px 32px 0 | ||||
| 	margin 0 32px 0 0 | ||||
| 	cursor pointer | ||||
| 	transition all 0.3s | ||||
|  | ||||
|   | ||||
| @@ -64,6 +64,12 @@ root(isDark) | ||||
| 	cursor pointer | ||||
| 	transition all 0.3s | ||||
|  | ||||
| 	&:first-child | ||||
| 		margin-top 0 | ||||
|  | ||||
| 	&:last-child | ||||
| 		margin-bottom 0 | ||||
|  | ||||
| 	> * | ||||
| 		user-select none | ||||
|  | ||||
| @@ -89,6 +95,7 @@ root(isDark) | ||||
|  | ||||
| 	> .button | ||||
| 		display inline-block | ||||
| 		flex-shrink 0 | ||||
| 		margin 3px 0 0 0 | ||||
| 		width 34px | ||||
| 		height 14px | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| 	</blockquote> | ||||
| </div> | ||||
| <div v-else class="mk-url-preview"> | ||||
| 	<a :href="url" target="_blank" :title="url" v-if="!fetching"> | ||||
| 	<a :class="{ mini }" :href="url" target="_blank" :title="url" v-if="!fetching"> | ||||
| 		<div class="thumbnail" v-if="thumbnail" :style="`background-image: url(${thumbnail})`"></div> | ||||
| 		<article> | ||||
| 			<header> | ||||
| @@ -28,18 +28,105 @@ | ||||
| import Vue from 'vue'; | ||||
| import { url as misskeyUrl } from '../../../config'; | ||||
|  | ||||
| // THIS IS THE WHITELIST FOR THE EMBED PLAYER | ||||
| const whiteList = [ | ||||
| 	'afreecatv.com', | ||||
| 	'aparat.com', | ||||
| 	'applemusic.com', | ||||
| 	'amazon.com', | ||||
| 	'awa.fm', | ||||
| 	'bandcamp.com', | ||||
| 	'bbc.co.uk', | ||||
| 	'beatport.com', | ||||
| 	'bilibili.com', | ||||
| 	'boomstream.com', | ||||
| 	'breakers.tv', | ||||
| 	'cam4.com', | ||||
| 	'cavelis.net', | ||||
| 	'chaturbate.com', | ||||
| 	'cnn.com', | ||||
| 	'cybergame.tv', | ||||
| 	'dailymotion.com', | ||||
| 	'deezer.com', | ||||
| 	'djlive.pl', | ||||
| 	'e-onkyo.com', | ||||
| 	'eventials.com', | ||||
| 	'facebook.com', | ||||
| 	'fc2.com', | ||||
| 	'gameplank.tv', | ||||
| 	'goodgame.ru', | ||||
| 	'google.com', | ||||
| 	'hardtunes.com', | ||||
| 	'instagram.com', | ||||
| 	'johnnylooch.com', | ||||
| 	'kexp.org', | ||||
| 	'lahzenegar.com', | ||||
| 	'liveedu.tv', | ||||
| 	'livetube.cc', | ||||
| 	'livestream.com', | ||||
| 	'meridix.com', | ||||
| 	'mixcloud.com', | ||||
| 	'mixer.com', | ||||
| 	'mobcrush.com', | ||||
| 	'mylive.in.th', | ||||
| 	'myspace.com', | ||||
| 	'netflix.com', | ||||
| 	'newretrowave.com', | ||||
| 	'nhk.or.jp', | ||||
| 	'nicovideo.jp', | ||||
| 	'nico.ms', | ||||
| 	'noisetrade.com', | ||||
| 	'nood.tv', | ||||
| 	'npr.org', | ||||
| 	'openrec.tv', | ||||
| 	'pandora.com', | ||||
| 	'pandora.tv', | ||||
| 	'picarto.tv', | ||||
| 	'pscp.tv', | ||||
| 	'restream.io', | ||||
| 	'reverbnation.com', | ||||
| 	'sermonaudio.com', | ||||
| 	'smashcast.tv', | ||||
| 	'songkick.com', | ||||
| 	'soundcloud.com', | ||||
| 	'spinninrecords.com', | ||||
| 	'spotify.com', | ||||
| 	'stitcher.com', | ||||
| 	'stream.me', | ||||
| 	'switchboard.live', | ||||
| 	'tunein.com', | ||||
| 	'twitcasting.tv', | ||||
| 	'twitch.tv', | ||||
| 	'twitter.com', | ||||
| 	'vaughnlive.tv', | ||||
| 	'veoh.com', | ||||
| 	'vimeo.com', | ||||
| 	'watchpeoplecode.com', | ||||
| 	'web.tv', | ||||
| 	'youtube.com', | ||||
| 	'youtu.be' | ||||
| ]; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	props: { | ||||
| 		url: { | ||||
| 			type: String, | ||||
| 			require: true | ||||
| 		}, | ||||
|  | ||||
| 		detail: { | ||||
| 			type: Boolean, | ||||
| 			required: false, | ||||
| 			default: false | ||||
| 		}, | ||||
|  | ||||
| 		mini: { | ||||
| 			type: Boolean, | ||||
| 			required: false, | ||||
| 			default: false | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	data() { | ||||
| 		return { | ||||
| 			fetching: true, | ||||
| @@ -57,6 +144,7 @@ export default Vue.extend({ | ||||
| 			misskeyUrl | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| 	created() { | ||||
| 		const url = new URL(this.url); | ||||
|  | ||||
| @@ -81,97 +169,22 @@ export default Vue.extend({ | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		fetch('/url?url=' + encodeURIComponent(this.url)).then(res => { | ||||
|  | ||||
| 		fetch(`/url?url=${encodeURIComponent(this.url)}`).then(res => { | ||||
| 			res.json().then(info => { | ||||
| 				if (info.url != null) { | ||||
| 					this.title = info.title; | ||||
| 					this.description = info.description; | ||||
| 					this.thumbnail = info.thumbnail; | ||||
| 					this.icon = info.icon; | ||||
| 					this.sitename = info.sitename; | ||||
| 					this.fetching = false; | ||||
| 					if ([ // THIS IS THE WHITELIST FOR THE EMBED PLAYER | ||||
| 						'afreecatv.com', | ||||
| 						'aparat.com', | ||||
| 						'applemusic.com', | ||||
| 						'amazon.com', | ||||
| 						'awa.fm', | ||||
| 						'bandcamp.com', | ||||
| 						'bbc.co.uk', | ||||
| 						'beatport.com', | ||||
| 						'bilibili.com', | ||||
| 						'boomstream.com', | ||||
| 						'breakers.tv', | ||||
| 						'cam4.com', | ||||
| 						'cavelis.net', | ||||
| 						'chaturbate.com', | ||||
| 						'cnn.com', | ||||
| 						'cybergame.tv', | ||||
| 						'dailymotion.com', | ||||
| 						'deezer.com', | ||||
| 						'djlive.pl', | ||||
| 						'e-onkyo.com', | ||||
| 						'eventials.com', | ||||
| 						'facebook.com', | ||||
| 						'fc2.com', | ||||
| 						'gameplank.tv', | ||||
| 						'goodgame.ru', | ||||
| 						'google.com', | ||||
| 						'hardtunes.com', | ||||
| 						'instagram.com', | ||||
| 						'johnnylooch.com', | ||||
| 						'kexp.org', | ||||
| 						'lahzenegar.com', | ||||
| 						'liveedu.tv', | ||||
| 						'livetube.cc', | ||||
| 						'livestream.com', | ||||
| 						'meridix.com', | ||||
| 						'mixcloud.com', | ||||
| 						'mixer.com', | ||||
| 						'mobcrush.com', | ||||
| 						'mylive.in.th', | ||||
| 						'myspace.com', | ||||
| 						'netflix.com', | ||||
| 						'newretrowave.com', | ||||
| 						'nhk.or.jp', | ||||
| 						'nicovideo.jp', | ||||
| 						'nico.ms', | ||||
| 						'noisetrade.com', | ||||
| 						'nood.tv', | ||||
| 						'npr.org', | ||||
| 						'openrec.tv', | ||||
| 						'pandora.com', | ||||
| 						'pandora.tv', | ||||
| 						'picarto.tv', | ||||
| 						'pscp.tv', | ||||
| 						'restream.io', | ||||
| 						'reverbnation.com', | ||||
| 						'sermonaudio.com', | ||||
| 						'smashcast.tv', | ||||
| 						'songkick.com', | ||||
| 						'soundcloud.com', | ||||
| 						'spinninrecords.com', | ||||
| 						'spotify.com', | ||||
| 						'stitcher.com', | ||||
| 						'stream.me', | ||||
| 						'switchboard.live', | ||||
| 						'tunein.com', | ||||
| 						'twitcasting.tv', | ||||
| 						'twitch.tv', | ||||
| 						'twitter.com', | ||||
| 						'vaughnlive.tv', | ||||
| 						'veoh.com', | ||||
| 						'vimeo.com', | ||||
| 						'watchpeoplecode.com', | ||||
| 						'web.tv', | ||||
| 						'youtube.com', | ||||
| 						'youtu.be' | ||||
| 					].some(x => x == url.hostname || url.hostname.endsWith(`.${x}`))) | ||||
| 						this.player = info.player; | ||||
| 				}	// info.url | ||||
| 			})	// json | ||||
| 		});	// fetch | ||||
| 	}	// created | ||||
| 				if (info.url == null) return; | ||||
| 				this.title = info.title; | ||||
| 				this.description = info.description; | ||||
| 				this.thumbnail = info.thumbnail; | ||||
| 				this.icon = info.icon; | ||||
| 				this.sitename = info.sitename; | ||||
| 				this.fetching = false; | ||||
| 				if (whiteList.some(x => x == url.hostname || url.hostname.endsWith(`.${x}`))) { | ||||
| 					this.player = info.player; | ||||
| 				} | ||||
| 			}) | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| @@ -286,6 +299,29 @@ root(isDark) | ||||
| 						width 12px | ||||
| 						height 12px | ||||
|  | ||||
| 		&.mini | ||||
| 			font-size 10px | ||||
|  | ||||
| 			> .thumbnail | ||||
| 				position relative | ||||
| 				width 100% | ||||
| 				height 60px | ||||
|  | ||||
| 			> article | ||||
| 				left 0 | ||||
| 				width 100% | ||||
| 				padding 8px | ||||
|  | ||||
| 				> header | ||||
| 					margin-bottom 4px | ||||
|  | ||||
| 				> footer | ||||
| 					margin-top 4px | ||||
|  | ||||
| 					> img | ||||
| 						width 12px | ||||
| 						height 12px | ||||
|  | ||||
| .mk-url-preview[data-darkmode] | ||||
| 	root(true) | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { toUnicode as decodePunycode } from 'punycode'; | ||||
| export default Vue.extend({ | ||||
| 	props: ['url', 'target'], | ||||
| 	data() { | ||||
| @@ -27,11 +28,11 @@ export default Vue.extend({ | ||||
| 	created() { | ||||
| 		const url = new URL(this.url); | ||||
| 		this.schema = url.protocol; | ||||
| 		this.hostname = url.hostname; | ||||
| 		this.hostname = decodePunycode(url.hostname); | ||||
| 		this.port = url.port; | ||||
| 		this.pathname = url.pathname; | ||||
| 		this.query = url.search; | ||||
| 		this.hash = url.hash; | ||||
| 		this.pathname = decodeURIComponent(url.pathname); | ||||
| 		this.query = decodeURIComponent(url.search); | ||||
| 		this.hash = decodeURIComponent(url.hash); | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|   | ||||
| @@ -31,15 +31,30 @@ export default Vue.extend({ | ||||
| 			default: undefined | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	data() { | ||||
| 		return { | ||||
| 			fetching: true, | ||||
| 			notes: [] | ||||
| 			notes: [], | ||||
| 			connection: null, | ||||
| 			connectionId: null | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| 	mounted() { | ||||
| 		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: { | ||||
| 		fetch(cb?) { | ||||
| 			this.fetching = true; | ||||
| @@ -48,14 +63,21 @@ export default Vue.extend({ | ||||
| 				local: true, | ||||
| 				reply: false, | ||||
| 				renote: false, | ||||
| 				media: false, | ||||
| 				poll: false, | ||||
| 				bot: false | ||||
| 				file: false, | ||||
| 				poll: false | ||||
| 			}).then(notes => { | ||||
| 				this.notes = notes; | ||||
| 				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> | ||||
|   | ||||
| @@ -191,7 +191,7 @@ class Autocomplete { | ||||
| 			const acct = renderAcct(value); | ||||
|  | ||||
| 			// 挿入 | ||||
| 			this.text = trimmedBefore + '@' + acct + ' ' + after; | ||||
| 			this.text = `${trimmedBefore}@${acct} ${after}`; | ||||
|  | ||||
| 			// キャレットを戻す | ||||
| 			this.vm.$nextTick(() => { | ||||
| @@ -207,7 +207,7 @@ class Autocomplete { | ||||
| 			const after = source.substr(caret); | ||||
|  | ||||
| 			// 挿入 | ||||
| 			this.text = trimmedBefore + '#' + value + ' ' + after; | ||||
| 			this.text = `${trimmedBefore}#${value} ${after}`; | ||||
|  | ||||
| 			// キャレットを戻す | ||||
| 			this.vm.$nextTick(() => { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| 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?) => { | ||||
| 	return '/@' + Vue.filter('acct')(user) + (path ? '/' + path : ''); | ||||
| 	return `/@${Vue.filter('acct')(user)}${(path ? `/${path}` : '')}`; | ||||
| }); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
| <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> | ||||
| 		<div class="banner" :style="bannerStyle"></div> | ||||
| @@ -83,7 +83,7 @@ export default Vue.extend({ | ||||
| 						userId: this.user.id | ||||
| 					}); | ||||
| 				} else { | ||||
| 					if (this.user.isLocked && this.user.hasPendingFollowRequestFromYou) { | ||||
| 					if (this.user.hasPendingFollowRequestFromYou) { | ||||
| 						this.user = await (this as any).api('following/requests/cancel', { | ||||
| 							userId: this.user.id | ||||
| 						}); | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <template> | ||||
| <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"> | ||||
| 			<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> | ||||
| 	</mk-widget-container> | ||||
| </div> | ||||
| @@ -13,13 +13,12 @@ import define from '../../../common/define-widget'; | ||||
| export default define({ | ||||
| 	name: 'analog-clock', | ||||
| 	props: () => ({ | ||||
| 		design: -1 | ||||
| 		style: 0 | ||||
| 	}) | ||||
| }).extend({ | ||||
| 	methods: { | ||||
| 		func() { | ||||
| 			if (++this.props.design > 2) | ||||
| 				this.props.design = -1; | ||||
| 			this.props.style = (this.props.style + 1) % 4; | ||||
| 			this.save(); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <template> | ||||
| <div class="mkw-broadcast" | ||||
| 	:data-found="broadcasts.length != 0" | ||||
| <div class="anltbovirfeutcigvwgmgxipejaeozxi" | ||||
| 	:data-found="announcements && announcements.length != 0" | ||||
| 	:data-melt="props.design == 1" | ||||
| 	:data-mobile="platform == 'mobile'" | ||||
| > | ||||
| @@ -14,18 +14,17 @@ | ||||
| 		</svg> | ||||
| 	</div> | ||||
| 	<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"> | ||||
| 		<span v-if="broadcasts.length != 0" v-html="broadcasts[i].text"></span> | ||||
| 		<template v-if="broadcasts.length == 0">%i18n:@have-a-nice-day%</template> | ||||
| 		<span v-if="announcements.length != 0" v-html="announcements[i].text"></span> | ||||
| 		<template v-if="announcements.length == 0">%i18n:@have-a-nice-day%</template> | ||||
| 	</p> | ||||
| 	<a v-if="broadcasts.length > 1" @click="next">%i18n:@next% >></a> | ||||
| 	<a v-if="announcements.length > 1" @click="next">%i18n:@next% >></a> | ||||
| </div> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import define from '../../../common/define-widget'; | ||||
| import { lang } from '../../../config'; | ||||
|  | ||||
| export default define({ | ||||
| 	name: 'broadcast', | ||||
| @@ -37,26 +36,18 @@ export default define({ | ||||
| 		return { | ||||
| 			i: 0, | ||||
| 			fetching: true, | ||||
| 			broadcasts: [] | ||||
| 			announcements: [] | ||||
| 		}; | ||||
| 	}, | ||||
| 	mounted() { | ||||
| 		(this as any).os.getMeta().then(meta => { | ||||
| 			let broadcasts = []; | ||||
| 			if (meta.broadcasts) { | ||||
| 				meta.broadcasts.forEach(broadcast => { | ||||
| 					if (broadcast[lang]) { | ||||
| 						broadcasts.push(broadcast[lang]); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| 			this.broadcasts = broadcasts; | ||||
| 			this.announcements = meta.broadcasts; | ||||
| 			this.fetching = false; | ||||
| 		}); | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		next() { | ||||
| 			if (this.i == this.broadcasts.length - 1) { | ||||
| 			if (this.i == this.announcements.length - 1) { | ||||
| 				this.i = 0; | ||||
| 			} else { | ||||
| 				this.i++; | ||||
| @@ -75,7 +66,7 @@ export default define({ | ||||
| </script> | ||||
|  | ||||
| <style lang="stylus" scoped> | ||||
| .mkw-broadcast | ||||
| root(isDark) | ||||
| 	padding 10px | ||||
| 	border solid 1px #4078c0 | ||||
| 	border-radius 6px | ||||
| @@ -142,15 +133,11 @@ export default define({ | ||||
| 		z-index 1 | ||||
| 		margin 0 | ||||
| 		font-size 0.7em | ||||
| 		color #555 | ||||
| 		color isDark ? #fff : #555 | ||||
|  | ||||
| 		&.fetching | ||||
| 			text-align center | ||||
|  | ||||
| 		a | ||||
| 			color #555 | ||||
| 			text-decoration underline | ||||
|  | ||||
| 	> a | ||||
| 		display block | ||||
| 		font-size 0.7em | ||||
| @@ -159,4 +146,10 @@ export default define({ | ||||
| 		> p | ||||
| 			color #fff | ||||
|  | ||||
| .anltbovirfeutcigvwgmgxipejaeozxi[data-darkmode] | ||||
| 	root(true) | ||||
|  | ||||
| .anltbovirfeutcigvwgmgxipejaeozxi:not([data-darkmode]) | ||||
| 	root(false) | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -2,9 +2,9 @@ | ||||
| <div class="mkw-donation" :data-mobile="platform == 'mobile'"> | ||||
| 	<article> | ||||
| 		<h1>%fa:heart%%i18n:@title%</h1> | ||||
| 		<p> | ||||
| 		<p v-if="meta"> | ||||
| 			{{ '%i18n:@text%'.substr(0, '%i18n:@text%'.indexOf('{')) }} | ||||
| 			<a href="https://syuilo.com">@syuilo</a> | ||||
| 			<a :href="meta.maintainer.url">{{ meta.maintainer.name }}</a> | ||||
| 			{{ '%i18n:@text%'.substr('%i18n:@text%'.indexOf('}') + 1) }} | ||||
| 		</p> | ||||
| 	</article> | ||||
| @@ -15,6 +15,17 @@ | ||||
| import define from '../../../common/define-widget'; | ||||
| export default define({ | ||||
| 	name: 'donation' | ||||
| }).extend({ | ||||
| 	data() { | ||||
| 		return { | ||||
| 			meta: null | ||||
| 		}; | ||||
| 	}, | ||||
| 	created() { | ||||
| 		(this as any).os.getMeta().then(meta => { | ||||
| 			this.meta = meta; | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -4,20 +4,7 @@ | ||||
| 		<template slot="header">%fa:hashtag%%i18n:@title%</template> | ||||
|  | ||||
| 		<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> | ||||
| 			<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> --> | ||||
| 			<mk-trends/> | ||||
| 		</div> | ||||
| 	</mk-widget-container> | ||||
| </div> | ||||
| @@ -25,7 +12,6 @@ | ||||
|  | ||||
| <script lang="ts"> | ||||
| import define from '../../../common/define-widget'; | ||||
| import XChart from './hashtags.chart.vue'; | ||||
|  | ||||
| export default define({ | ||||
| 	name: 'hashtags', | ||||
| @@ -33,89 +19,11 @@ export default define({ | ||||
| 		compact: false | ||||
| 	}) | ||||
| }).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: { | ||||
| 		func() { | ||||
| 			this.props.compact = !this.props.compact; | ||||
| 			this.save(); | ||||
| 		}, | ||||
| 		fetch() { | ||||
| 			(this as any).api('hashtags/trend').then(stats => { | ||||
| 				this.stats = stats; | ||||
| 				this.fetching = false; | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </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> | ||||
|   | ||||
| @@ -4,6 +4,7 @@ declare const _THEME_COLOR_: string; | ||||
| declare const _COPYRIGHT_: string; | ||||
| declare const _VERSION_: string; | ||||
| declare const _CODENAME_: string; | ||||
| declare const _ENV_: string; | ||||
|  | ||||
| const address = new URL(location.href); | ||||
|  | ||||
| @@ -18,3 +19,4 @@ export const themeColor = _THEME_COLOR_; | ||||
| export const copyright = _COPYRIGHT_; | ||||
| export const version = _VERSION_; | ||||
| export const codename = _CODENAME_; | ||||
| export const env = _ENV_; | ||||
|   | ||||
| @@ -3,8 +3,21 @@ import { apiUrl } from '../../config'; | ||||
| import CropWindow from '../views/components/crop-window.vue'; | ||||
| import ProgressDialog from '../views/components/progress-dialog.vue'; | ||||
|  | ||||
| export default (os: OS) => (cb, file = null) => { | ||||
| 	const fileSelected = file => { | ||||
| export default (os: OS) => { | ||||
|  | ||||
| 	const cropImage = file => new Promise((resolve, reject) => { | ||||
|  | ||||
| 		const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$'); | ||||
| 		if (!regex.test(file.name) ) { | ||||
| 			os.apis.dialog({ | ||||
| 				title: '%fa:info-circle% %i18n:desktop.invalid-filetype%', | ||||
| 				text: null, | ||||
| 				actions: [{ | ||||
| 					text: '%i18n:common.got-it%' | ||||
| 				}] | ||||
| 			}); | ||||
| 			return reject('invalid-filetype'); | ||||
| 		} | ||||
|  | ||||
| 		const w = os.new(CropWindow, { | ||||
| 			image: file, | ||||
| @@ -19,27 +32,29 @@ export default (os: OS) => (cb, file = null) => { | ||||
|  | ||||
| 			os.api('drive/folders/find', { | ||||
| 				name: '%i18n:desktop.avatar%' | ||||
| 			}).then(iconFolder => { | ||||
| 				if (iconFolder.length === 0) { | ||||
| 			}).then(avatarFolder => { | ||||
| 				if (avatarFolder.length === 0) { | ||||
| 					os.api('drive/folders/create', { | ||||
| 						name: '%i18n:desktop.avatar%' | ||||
| 					}).then(iconFolder => { | ||||
| 						upload(data, iconFolder); | ||||
| 						resolve(upload(data, iconFolder)); | ||||
| 					}); | ||||
| 				} else { | ||||
| 					upload(data, iconFolder[0]); | ||||
| 					resolve(upload(data, avatarFolder[0])); | ||||
| 				} | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| 		w.$once('skipped', () => { | ||||
| 			set(file); | ||||
| 			resolve(file); | ||||
| 		}); | ||||
|  | ||||
| 		document.body.appendChild(w.$el); | ||||
| 	}; | ||||
| 		w.$once('cancelled', reject); | ||||
|  | ||||
| 	const upload = (data, folder) => { | ||||
| 		document.body.appendChild(w.$el); | ||||
| 	}); | ||||
|  | ||||
| 	const upload = (data, folder) => new Promise((resolve, reject) => { | ||||
| 		const dialog = os.new(ProgressDialog, { | ||||
| 			title: '%i18n:desktop.uploading-avatar%' | ||||
| 		}); | ||||
| @@ -52,18 +67,19 @@ export default (os: OS) => (cb, file = null) => { | ||||
| 		xhr.onload = e => { | ||||
| 			const file = JSON.parse((e.target as any).response); | ||||
| 			(dialog as any).close(); | ||||
| 			set(file); | ||||
| 			resolve(file); | ||||
| 		}; | ||||
| 		xhr.onerror = reject; | ||||
|  | ||||
| 		xhr.upload.onprogress = e => { | ||||
| 			if (e.lengthComputable) (dialog as any).update(e.loaded, e.total); | ||||
| 		}; | ||||
|  | ||||
| 		xhr.send(data); | ||||
| 	}; | ||||
| 	}); | ||||
|  | ||||
| 	const set = file => { | ||||
| 		os.api('i/update', { | ||||
| 	const setAvatar = file => { | ||||
| 		return os.api('i/update', { | ||||
| 			avatarId: file.id | ||||
| 		}).then(i => { | ||||
| 			os.store.commit('updateIKeyValue', { | ||||
| @@ -83,18 +99,21 @@ export default (os: OS) => (cb, file = null) => { | ||||
| 				}] | ||||
| 			}); | ||||
|  | ||||
| 			if (cb) cb(i); | ||||
| 			return i; | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	if (file) { | ||||
| 		fileSelected(file); | ||||
| 	} else { | ||||
| 		os.apis.chooseDriveFile({ | ||||
| 			multiple: false, | ||||
| 			title: '%fa:image% %i18n:desktop.choose-avatar%' | ||||
| 		}).then(file => { | ||||
| 			fileSelected(file); | ||||
| 		}); | ||||
| 	} | ||||
| 	return (file = null) => { | ||||
| 		const selectedFile = file | ||||
| 			? Promise.resolve(file) | ||||
| 			: os.apis.chooseDriveFile({ | ||||
| 				multiple: false, | ||||
| 				title: '%fa:image% %i18n:desktop.choose-avatar%' | ||||
| 			}); | ||||
|  | ||||
| 		return selectedFile | ||||
| 			.then(cropImage) | ||||
| 			.then(setAvatar) | ||||
| 			.catch(err => err && console.warn(err)); | ||||
| 	}; | ||||
| }; | ||||
|   | ||||
| @@ -6,6 +6,19 @@ import ProgressDialog from '../views/components/progress-dialog.vue'; | ||||
| export default (os: OS) => { | ||||
|  | ||||
| 	const cropImage = file => new Promise((resolve, reject) => { | ||||
|  | ||||
| 		const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$'); | ||||
| 		if (!regex.test(file.name) ) { | ||||
| 			os.apis.dialog({ | ||||
| 				title: '%fa:info-circle% %i18n:desktop.invalid-filetype%', | ||||
| 				text: null, | ||||
| 				actions: [{ | ||||
| 					text: '%i18n:common.got-it%' | ||||
| 				}] | ||||
| 			}); | ||||
| 			return reject('invalid-filetype'); | ||||
| 		} | ||||
|  | ||||
| 		const w = os.new(CropWindow, { | ||||
| 			image: file, | ||||
| 			title: '%i18n:desktop.banner-crop-title%', | ||||
|   | ||||
| @@ -34,10 +34,25 @@ | ||||
| import Vue from 'vue'; | ||||
| import XChart from './charts.chart.ts'; | ||||
|  | ||||
| const colors = { | ||||
| 	local: 'rgb(246, 88, 79)', | ||||
| 	remote: 'rgb(65, 221, 222)', | ||||
|  | ||||
| 	localPlus: 'rgb(52, 178, 118)', | ||||
| 	remotePlus: 'rgb(158, 255, 209)', | ||||
| 	localMinus: 'rgb(255, 97, 74)', | ||||
| 	remoteMinus: 'rgb(255, 149, 134)' | ||||
| }; | ||||
|  | ||||
| const rgba = (color: string): string => { | ||||
| 	return color.replace('rgb', 'rgba').replace(')', ', 0.1)'); | ||||
| }; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XChart | ||||
| 	}, | ||||
|  | ||||
| 	data() { | ||||
| 		return { | ||||
| 			chart: null, | ||||
| @@ -45,6 +60,7 @@ export default Vue.extend({ | ||||
| 			span: 'hour' | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| 	computed: { | ||||
| 		data(): any { | ||||
| 			if (this.chart == null) return null; | ||||
| @@ -61,6 +77,7 @@ export default Vue.extend({ | ||||
| 				case 'drive-files-total': return this.driveFilesTotalChart(); | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
| 		stats(): any[] { | ||||
| 			return ( | ||||
| 				this.span == 'day' ? this.chart.perDay : | ||||
| @@ -69,11 +86,15 @@ export default Vue.extend({ | ||||
| 			); | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	created() { | ||||
| 		(this as any).api('chart').then(chart => { | ||||
| 		(this as any).api('chart', { | ||||
| 			limit: 32 | ||||
| 		}).then(chart => { | ||||
| 			this.chart = chart; | ||||
| 		}); | ||||
| 	}, | ||||
|  | ||||
| 	methods: { | ||||
| 		notesChart(type: string): any { | ||||
| 			const data = this.stats.slice().reverse().map(x => ({ | ||||
| @@ -160,24 +181,24 @@ export default Vue.extend({ | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount })) | ||||
| 				}, { | ||||
| 					label: 'Local', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.local), | ||||
| 					borderColor: colors.local, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localCount })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remote), | ||||
| 					borderColor: colors.remote, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount })) | ||||
| 				}] | ||||
| 			}, { | ||||
| 				scales: { | ||||
| @@ -217,24 +238,24 @@ export default Vue.extend({ | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount + x.localCount })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount })) | ||||
| 				}, { | ||||
| 					label: 'Local', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.local), | ||||
| 					borderColor: colors.local, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localCount })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remote), | ||||
| 					borderColor: colors.remote, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount })) | ||||
| 				}] | ||||
| 			}, { | ||||
| 				scales: { | ||||
| @@ -276,29 +297,11 @@ export default Vue.extend({ | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localInc + x.localDec + x.remoteInc + x.remoteDec })) | ||||
| 				}, { | ||||
| 					label: 'Remote +', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteInc })) | ||||
| 				}, { | ||||
| 					label: 'Remote -', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteDec })) | ||||
| 				}, { | ||||
| 					label: 'Local +', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.localPlus), | ||||
| 					borderColor: colors.localPlus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| @@ -306,12 +309,30 @@ export default Vue.extend({ | ||||
| 				}, { | ||||
| 					label: 'Local -', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.localMinus), | ||||
| 					borderColor: colors.localMinus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localDec })) | ||||
| 				}, { | ||||
| 					label: 'Remote +', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remotePlus), | ||||
| 					borderColor: colors.remotePlus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteInc })) | ||||
| 				}, { | ||||
| 					label: 'Remote -', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remoteMinus), | ||||
| 					borderColor: colors.remoteMinus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteDec })) | ||||
| 				}] | ||||
| 			}, { | ||||
| 				scales: { | ||||
| @@ -351,31 +372,31 @@ export default Vue.extend({ | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteSize + x.localSize })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteSize })) | ||||
| 				}, { | ||||
| 					label: 'Local', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.local), | ||||
| 					borderColor: colors.local, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localSize })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remote), | ||||
| 					borderColor: colors.remote, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteSize })) | ||||
| 				}] | ||||
| 			}, { | ||||
| 				scales: { | ||||
| 					yAxes: [{ | ||||
| 						ticks: { | ||||
| 							callback: value => { | ||||
| 								return Vue.filter('bytes')(value); | ||||
| 								return Vue.filter('bytes')(value, 1); | ||||
| 							} | ||||
| 						} | ||||
| 					}] | ||||
| @@ -384,7 +405,7 @@ export default Vue.extend({ | ||||
| 					callbacks: { | ||||
| 						label: (tooltipItem, data) => { | ||||
| 							const label = data.datasets[tooltipItem.datasetIndex].label || ''; | ||||
| 							return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel)}`; | ||||
| 							return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel, 1)}`; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| @@ -410,29 +431,11 @@ export default Vue.extend({ | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localInc + x.localDec + x.remoteInc + x.remoteDec })) | ||||
| 				}, { | ||||
| 					label: 'Remote +', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteInc })) | ||||
| 				}, { | ||||
| 					label: 'Remote -', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteDec })) | ||||
| 				}, { | ||||
| 					label: 'Local +', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.localPlus), | ||||
| 					borderColor: colors.localPlus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| @@ -440,12 +443,30 @@ export default Vue.extend({ | ||||
| 				}, { | ||||
| 					label: 'Local -', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.localMinus), | ||||
| 					borderColor: colors.localMinus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localDec })) | ||||
| 				}, { | ||||
| 					label: 'Remote +', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remotePlus), | ||||
| 					borderColor: colors.remotePlus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteInc })) | ||||
| 				}, { | ||||
| 					label: 'Remote -', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remoteMinus), | ||||
| 					borderColor: colors.remoteMinus, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteDec })) | ||||
| 				}] | ||||
| 			}, { | ||||
| 				scales: { | ||||
| @@ -485,24 +506,24 @@ export default Vue.extend({ | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localCount + x.remoteCount })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(65, 221, 222, 0.1)', | ||||
| 					borderColor: '#41ddde', | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount })) | ||||
| 				}, { | ||||
| 					label: 'Local', | ||||
| 					fill: true, | ||||
| 					backgroundColor: 'rgba(246, 88, 79, 0.1)', | ||||
| 					borderColor: '#f6584f', | ||||
| 					backgroundColor: rgba(colors.local), | ||||
| 					borderColor: colors.local, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.localCount })) | ||||
| 				}, { | ||||
| 					label: 'Remote', | ||||
| 					fill: true, | ||||
| 					backgroundColor: rgba(colors.remote), | ||||
| 					borderColor: colors.remote, | ||||
| 					borderWidth: 2, | ||||
| 					pointBackgroundColor: '#fff', | ||||
| 					lineTension: 0, | ||||
| 					data: data.map(x => ({ t: x.date, y: x.remoteCount })) | ||||
| 				}] | ||||
| 			}, { | ||||
| 				scales: { | ||||
| @@ -561,6 +582,6 @@ export default Vue.extend({ | ||||
| 	> div | ||||
| 		> * | ||||
| 			display block | ||||
| 			height 300px | ||||
| 			height 320px | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -163,7 +163,7 @@ export default Vue.extend({ | ||||
| 							}); | ||||
| 							break; | ||||
| 						default: | ||||
| 							alert('%i18n:@unhandled-error% ' + err); | ||||
| 							alert(`%i18n:@unhandled-error% ${err}`); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
|   | ||||
| @@ -323,7 +323,7 @@ export default Vue.extend({ | ||||
| 							}); | ||||
| 							break; | ||||
| 						default: | ||||
| 							alert('%i18n:@unhandled-error% ' + err); | ||||
| 							alert(`%i18n:@unhandled-error% ${err}`); | ||||
| 					} | ||||
| 				}); | ||||
| 			} | ||||
| @@ -404,7 +404,7 @@ export default Vue.extend({ | ||||
| 					folder: folder | ||||
| 				}); | ||||
| 			} else { | ||||
| 				window.open(url + '/i/drive/folder/' + folder.id, | ||||
| 				window.open(`${url}/i/drive/folder/${folder.id}`, | ||||
| 					'drive_window', | ||||
| 					'height=500, width=800'); | ||||
| 			} | ||||
|   | ||||
| @@ -55,13 +55,15 @@ export default Vue.extend({ | ||||
| 	methods: { | ||||
| 		onFollow(user) { | ||||
| 			if (user.id == this.u.id) { | ||||
| 				this.user.isFollowing = user.isFollowing; | ||||
| 				this.u.isFollowing = user.isFollowing; | ||||
| 				this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou; | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
| 		onUnfollow(user) { | ||||
| 			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 | ||||
| 					}); | ||||
| 				} else { | ||||
| 					if (this.u.isLocked && this.u.hasPendingFollowRequestFromYou) { | ||||
| 					if (this.u.hasPendingFollowRequestFromYou) { | ||||
| 						this.u = await (this as any).api('following/requests/cancel', { | ||||
| 							userId: this.u.id | ||||
| 						}); | ||||
|   | ||||
| @@ -48,7 +48,7 @@ export default Vue.extend({ | ||||
| 			const mouseY = e.clientY - rect.top; | ||||
| 			const xp = mouseX / this.$el.offsetWidth * 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}")`; | ||||
| 		}, | ||||
|  | ||||
|   | ||||
| @@ -42,12 +42,12 @@ | ||||
| 				<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span> | ||||
| 				<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/> | ||||
| 			</div> | ||||
| 			<div class="media" v-if="p.media.length > 0"> | ||||
| 				<mk-media-list :media-list="p.media" :raw="true"/> | ||||
| 			<div class="files" v-if="p.files.length > 0"> | ||||
| 				<mk-media-list :media-list="p.files" :raw="true"/> | ||||
| 			</div> | ||||
| 			<mk-poll v-if="p.poll" :note="p"/> | ||||
| 			<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/> | ||||
| 			<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> | ||||
| 			<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> | ||||
| 			<div class="map" v-if="p.geo" ref="map"></div> | ||||
| 			<div class="renote" v-if="p.renote"> | ||||
| 				<mk-note-preview :note="p.renote"/> | ||||
| @@ -86,6 +86,7 @@ import MkRenoteFormWindow from './renote-form-window.vue'; | ||||
| import MkNoteMenu from '../../../common/views/components/note-menu.vue'; | ||||
| import MkReactionPicker from '../../../common/views/components/reaction-picker.vue'; | ||||
| import XSub from './notes.note.sub.vue'; | ||||
| import { sum } from '../../../../../prelude/array'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| @@ -114,7 +115,7 @@ export default Vue.extend({ | ||||
| 		isRenote(): boolean { | ||||
| 			return (this.note.renote && | ||||
| 				this.note.text == null && | ||||
| 				this.note.mediaIds.length == 0 && | ||||
| 				this.note.fileIds.length == 0 && | ||||
| 				this.note.poll == null); | ||||
| 		}, | ||||
| 		p(): any { | ||||
| @@ -122,9 +123,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
| 		reactionsCount(): number { | ||||
| 			return this.p.reactionCounts | ||||
| 				? Object.keys(this.p.reactionCounts) | ||||
| 					.map(key => this.p.reactionCounts[key]) | ||||
| 					.reduce((a, b) => a + b) | ||||
| 				? sum(Object.values(this.p.reactionCounts)) | ||||
| 				: 0; | ||||
| 		}, | ||||
| 		title(): string { | ||||
|   | ||||
| @@ -28,11 +28,11 @@ | ||||
| 						<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> | ||||
| 					</div> | ||||
| 					<div class="media" v-if="p.media.length > 0"> | ||||
| 						<mk-media-list :media-list="p.media"/> | ||||
| 					<div class="files" v-if="p.files.length > 0"> | ||||
| 						<mk-media-list :media-list="p.files"/> | ||||
| 					</div> | ||||
| 					<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/> | ||||
| 					<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a> | ||||
| 					<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a> | ||||
| 					<div class="map" v-if="p.geo" ref="map"></div> | ||||
| 					<div class="renote" v-if="p.renote"> | ||||
| 						<mk-note-preview :note="p.renote"/> | ||||
| @@ -78,6 +78,7 @@ import MkRenoteFormWindow from './renote-form-window.vue'; | ||||
| import MkNoteMenu from '../../../common/views/components/note-menu.vue'; | ||||
| import MkReactionPicker from '../../../common/views/components/reaction-picker.vue'; | ||||
| import XSub from './notes.note.sub.vue'; | ||||
| import { sum } from '../../../../../prelude/array'; | ||||
|  | ||||
| function focus(el, fn) { | ||||
| 	const target = fn(el); | ||||
| @@ -110,7 +111,7 @@ export default Vue.extend({ | ||||
| 		isRenote(): boolean { | ||||
| 			return (this.note.renote && | ||||
| 				this.note.text == null && | ||||
| 				this.note.mediaIds.length == 0 && | ||||
| 				this.note.fileIds.length == 0 && | ||||
| 				this.note.poll == null); | ||||
| 		}, | ||||
|  | ||||
| @@ -120,9 +121,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 		reactionsCount(): number { | ||||
| 			return this.p.reactionCounts | ||||
| 				? Object.keys(this.p.reactionCounts) | ||||
| 					.map(key => this.p.reactionCounts[key]) | ||||
| 					.reduce((a, b) => a + b) | ||||
| 				? sum(Object.values(this.p.reactionCounts)) | ||||
| 				: 0; | ||||
| 		}, | ||||
|  | ||||
|   | ||||
| @@ -122,7 +122,7 @@ export default Vue.extend({ | ||||
| 		prepend(note, silent = false) { | ||||
| 			//#region 弾く | ||||
| 			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 (isMyNote && isPureRenote) { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| 		<span class="icon" v-if="geo">%fa:map-marker-alt%</span> | ||||
| 		<span v-if="!reply">%i18n:@note%</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> | ||||
|  | ||||
| @@ -14,7 +14,7 @@ | ||||
| 			:reply="reply" | ||||
| 			@posted="onPosted" | ||||
| 			@change-uploadings="onChangeUploadings" | ||||
| 			@change-attached-media="onChangeMedia" | ||||
| 			@change-attached-files="onChangeFiles" | ||||
| 			@geo-attached="onGeoAttached" | ||||
| 			@geo-dettached="onGeoDettached"/> | ||||
| 	</div> | ||||
| @@ -29,7 +29,7 @@ export default Vue.extend({ | ||||
| 	data() { | ||||
| 		return { | ||||
| 			uploadings: [], | ||||
| 			media: [], | ||||
| 			files: [], | ||||
| 			geo: null | ||||
| 		}; | ||||
| 	}, | ||||
| @@ -42,8 +42,8 @@ export default Vue.extend({ | ||||
| 		onChangeUploadings(files) { | ||||
| 			this.uploadings = files; | ||||
| 		}, | ||||
| 		onChangeMedia(media) { | ||||
| 			this.media = media; | ||||
| 		onChangeFiles(files) { | ||||
| 			this.files = files; | ||||
| 		}, | ||||
| 		onGeoAttached(geo) { | ||||
| 			this.geo = geo; | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| 			@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder" | ||||
| 			v-autocomplete="'text'" | ||||
| 		></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 }"> | ||||
| 				<div v-for="file in files" :key="file.id"> | ||||
| 					<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="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="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="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"> | ||||
| @@ -62,6 +62,7 @@ import getFace from '../../../common/scripts/get-face'; | ||||
| import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue'; | ||||
| import parse from '../../../../../mfm/parse'; | ||||
| import { host } from '../../../config'; | ||||
| import { erase } from '../../../../../prelude/array'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| @@ -110,9 +111,9 @@ export default Vue.extend({ | ||||
| 	computed: { | ||||
| 		draftId(): string { | ||||
| 			return this.renote | ||||
| 				? 'renote:' + this.renote.id | ||||
| 				? `renote:${this.renote.id}` | ||||
| 				: this.reply | ||||
| 					? 'reply:' + this.reply.id | ||||
| 					? `reply:${this.reply.id}` | ||||
| 					: 'note'; | ||||
| 		}, | ||||
|  | ||||
| @@ -188,7 +189,7 @@ export default Vue.extend({ | ||||
| 							(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) { | ||||
| 			this.files.push(driveFile); | ||||
| 			this.$emit('change-attached-media', this.files); | ||||
| 			this.$emit('change-attached-files', this.files); | ||||
| 		}, | ||||
|  | ||||
| 		detachMedia(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() { | ||||
| @@ -249,7 +250,7 @@ export default Vue.extend({ | ||||
| 			this.text = ''; | ||||
| 			this.files = []; | ||||
| 			this.poll = false; | ||||
| 			this.$emit('change-attached-media', this.files); | ||||
| 			this.$emit('change-attached-files', this.files); | ||||
| 		}, | ||||
|  | ||||
| 		onKeydown(e) { | ||||
| @@ -297,7 +298,7 @@ export default Vue.extend({ | ||||
| 			if (driveFile != null && driveFile != '') { | ||||
| 				const file = JSON.parse(driveFile); | ||||
| 				this.files.push(file); | ||||
| 				this.$emit('change-attached-media', this.files); | ||||
| 				this.$emit('change-attached-files', this.files); | ||||
| 				e.preventDefault(); | ||||
| 			} | ||||
| 			//#endregion | ||||
| @@ -313,7 +314,7 @@ export default Vue.extend({ | ||||
| 				this.geo = pos.coords; | ||||
| 				this.$emit('geo-attached', this.geo); | ||||
| 			}, err => { | ||||
| 				alert('%i18n:@error%: ' + err.message); | ||||
| 				alert(`%i18n:@error%: ${err.message}`); | ||||
| 			}, { | ||||
| 					enableHighAccuracy: true | ||||
| 				}); | ||||
| @@ -346,7 +347,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
|  | ||||
| 		removeVisibleUser(user) { | ||||
| 			this.visibleUsers = this.visibleUsers.filter(u => u != user); | ||||
| 			this.visibleUsers = erase(user, this.visibleUsers); | ||||
| 		}, | ||||
|  | ||||
| 		post() { | ||||
| @@ -354,7 +355,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 			(this as any).api('notes/create', { | ||||
| 				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, | ||||
| 				renoteId: this.renote ? this.renote.id : undefined, | ||||
| 				poll: this.poll ? (this.$refs.poll as any).get() : undefined, | ||||
| @@ -514,7 +515,7 @@ root(isDark) | ||||
| 				margin-right 8px | ||||
| 				white-space nowrap | ||||
|  | ||||
| 		> .medias | ||||
| 		> .files | ||||
| 			margin 0 | ||||
| 			padding 0 | ||||
| 			background isDark ? #181b23 : lighten($theme-color, 98%) | ||||
|   | ||||
| @@ -49,6 +49,7 @@ | ||||
| 			</div> | ||||
| 			<mk-switch v-model="$store.state.settings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="%i18n:@post-form-on-timeline%"/> | ||||
| 			<mk-switch v-model="$store.state.settings.suggestRecentHashtags" @change="onChangeSuggestRecentHashtags" text="%i18n:@suggest-recent-hashtags%"/> | ||||
| 			<mk-switch v-model="$store.state.settings.showClockOnHeader" @change="onChangeShowClockOnHeader" text="%i18n:@show-clock-on-header%"/> | ||||
| 			<mk-switch v-model="$store.state.settings.showReplyTarget" @change="onChangeShowReplyTarget" text="%i18n:@show-reply-target%"/> | ||||
| 			<mk-switch v-model="$store.state.settings.showMyRenotes" @change="onChangeShowMyRenotes" text="%i18n:@show-my-renotes%"/> | ||||
| 			<mk-switch v-model="$store.state.settings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes" text="%i18n:@show-renoted-my-notes%"/> | ||||
| @@ -333,6 +334,12 @@ export default Vue.extend({ | ||||
| 				value: v | ||||
| 			}); | ||||
| 		}, | ||||
| 		onChangeShowClockOnHeader(v) { | ||||
| 			this.$store.dispatch('settings/set', { | ||||
| 				key: 'showClockOnHeader', | ||||
| 				value: v | ||||
| 			}); | ||||
| 		}, | ||||
| 		onChangeShowReplyTarget(v) { | ||||
| 			this.$store.dispatch('settings/set', { | ||||
| 				key: 'showReplyTarget', | ||||
|   | ||||
| @@ -7,9 +7,9 @@ | ||||
| 		<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> | ||||
| 	</div> | ||||
| 	<details v-if="note.media.length > 0"> | ||||
| 		<summary>({{ '%i18n:@media-count%'.replace('{}', note.media.length) }})</summary> | ||||
| 		<mk-media-list :media-list="note.media"/> | ||||
| 	<details v-if="note.files.length > 0"> | ||||
| 		<summary>({{ '%i18n:@media-count%'.replace('{}', note.files.length) }})</summary> | ||||
| 		<mk-media-list :media-list="note.files"/> | ||||
| 	</details> | ||||
| 	<details v-if="note.poll"> | ||||
| 		<summary>%i18n:@poll%</summary> | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| 			<li class="deck" :class="{ active: $route.name == 'deck' }" @click="goToTop"> | ||||
| 				<router-link to="/deck"> | ||||
| 					%fa:columns% | ||||
| 					<p>%i18n:@deck% <small>(beta)</small></p> | ||||
| 					<p>%i18n:@deck%</p> | ||||
| 				</router-link> | ||||
| 			</li> | ||||
| 			<li class="messaging"> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| <template> | ||||
| <div class="header"> | ||||
| 	<p class="warn" v-if="env != 'production'">%i18n:common.do-not-use-in-production%</p> | ||||
| 	<mk-special-message/> | ||||
| 	<div class="main" ref="main"> | ||||
| 		<div class="backdrop"></div> | ||||
| @@ -17,7 +18,7 @@ | ||||
| 					<x-account v-if="$store.getters.isSignedIn"/> | ||||
| 					<x-notifications v-if="$store.getters.isSignedIn"/> | ||||
| 					<x-post v-if="$store.getters.isSignedIn"/> | ||||
| 					<x-clock/> | ||||
| 					<x-clock v-if="$store.state.settings.showClockOnHeader"/> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| @@ -28,6 +29,7 @@ | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import * as anime from 'animejs'; | ||||
| import { env } from '../../../config'; | ||||
|  | ||||
| import XNav from './ui.header.nav.vue'; | ||||
| import XSearch from './ui.header.search.vue'; | ||||
| @@ -43,7 +45,13 @@ export default Vue.extend({ | ||||
| 		XAccount, | ||||
| 		XNotifications, | ||||
| 		XPost, | ||||
| 		XClock, | ||||
| 		XClock | ||||
| 	}, | ||||
|  | ||||
| 	data() { | ||||
| 		return { | ||||
| 			env: env | ||||
| 		}; | ||||
| 	}, | ||||
|  | ||||
| 	mounted() { | ||||
| @@ -119,6 +127,15 @@ root(isDark) | ||||
| 	width 100% | ||||
| 	box-shadow 0 1px 1px rgba(#000, 0.075) | ||||
|  | ||||
| 	> .warn | ||||
| 		display block | ||||
| 		margin 0 | ||||
| 		padding 4px | ||||
| 		text-align center | ||||
| 		font-size 12px | ||||
| 		background #f00 | ||||
| 		color #fff | ||||
|  | ||||
| 	> .main | ||||
| 		height 48px | ||||
|  | ||||
|   | ||||
| @@ -48,7 +48,7 @@ export default Vue.extend({ | ||||
| 				this.open(); | ||||
| 			}); | ||||
| 		} else { | ||||
| 			const query = this.user[0] == '@' ? | ||||
| 			const query = this.user.startsWith('@') ? | ||||
| 				parseAcct(this.user.substr(1)) : | ||||
| 				{ userId: this.user }; | ||||
|  | ||||
|   | ||||
| @@ -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> | ||||
| @@ -1,11 +1,11 @@ | ||||
| <template> | ||||
| <div class="obdskegsannmntldydackcpzezagxqfy card"> | ||||
| <div class="obdskegsannmntldydackcpzezagxqfy mk-admin-card"> | ||||
| 	<header>%i18n:@dashboard%</header> | ||||
| 	<div v-if="stats" class="stats"> | ||||
| 		<div><b>%fa:user% {{ stats.originalUsersCount | number }}</b><span>%i18n:@original-users%</span></div> | ||||
| 		<div><span>%fa:user% {{ stats.usersCount | number }}</span><span>%i18n:@all-users%</span></div> | ||||
| 		<div><b>%fa:pen% {{ stats.originalNotesCount | number }}</b><span>%i18n:@original-notes%</span></div> | ||||
| 		<div><span>%fa:pen% {{ stats.notesCount | number }}</span><span>%i18n:@all-notes%</span></div> | ||||
| 		<div><b>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</b><span>%i18n:@original-notes%</span></div> | ||||
| 		<div><span>%fa:pencil-alt% {{ stats.notesCount | number }}</span><span>%i18n:@all-notes%</span></div> | ||||
| 	</div> | ||||
| 	<div class="cpu-memory"> | ||||
| 		<x-cpu-memory :connection="connection"/> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="card"> | ||||
| <div class="mk-admin-card"> | ||||
| 	<header>%i18n:@suspend-user%</header> | ||||
| 	<input v-model="username" type="text" class="ui"/> | ||||
| 	<button class="ui" @click="suspendUser" :disabled="suspending">%i18n:@suspend%</button> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="card"> | ||||
| <div class="mk-admin-card"> | ||||
| 	<header>%i18n:@unsuspend-user%</header> | ||||
| 	<input v-model="username" type="text" class="ui"/> | ||||
| 	<button class="ui" @click="unsuspendUser" :disabled="unsuspending">%i18n:@unsuspend%</button> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="card"> | ||||
| <div class="mk-admin-card"> | ||||
| 	<header>%i18n:@unverify-user%</header> | ||||
| 	<input v-model="username" type="text" class="ui"/> | ||||
| 	<button class="ui" @click="unverifyUser" :disabled="unverifying">%i18n:@unverify%</button> | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="card"> | ||||
| <div class="mk-admin-card"> | ||||
| 	<header>%i18n:@verify-user%</header> | ||||
| 	<input v-model="username" type="text" class="ui"/> | ||||
| 	<button class="ui" @click="verifyUser" :disabled="verifying">%i18n:@verify%</button> | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| 		<ul> | ||||
| 			<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('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('update')" :class="{ active: page == 'update' }">%i18n:@update%</li> --> | ||||
| 		</ul> | ||||
| @@ -13,6 +14,9 @@ | ||||
| 			<x-dashboard/> | ||||
| 			<x-charts/> | ||||
| 		</div> | ||||
| 		<div v-show="page == 'announcements'"> | ||||
| 			<x-announcements/> | ||||
| 		</div> | ||||
| 		<div v-if="page == 'users'"> | ||||
| 			<x-suspend-user/> | ||||
| 			<x-unsuspend-user/> | ||||
| @@ -28,6 +32,7 @@ | ||||
| <script lang="ts"> | ||||
| import Vue from "vue"; | ||||
| import XDashboard from "./admin.dashboard.vue"; | ||||
| import XAnnouncements from "./admin.announcements.vue"; | ||||
| import XSuspendUser from "./admin.suspend-user.vue"; | ||||
| import XUnsuspendUser from "./admin.unsuspend-user.vue"; | ||||
| import XVerifyUser from "./admin.verify-user.vue"; | ||||
| @@ -37,6 +42,7 @@ import XCharts from "../../components/charts.vue"; | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XDashboard, | ||||
| 		XAnnouncements, | ||||
| 		XSuspendUser, | ||||
| 		XUnsuspendUser, | ||||
| 		XVerifyUser, | ||||
| @@ -103,7 +109,7 @@ export default Vue.extend({ | ||||
| 			> div | ||||
| 				max-width 800px | ||||
|  | ||||
| .card | ||||
| .mk-admin-card | ||||
| 	padding 32px | ||||
| 	background #fff | ||||
| 	box-shadow 0 2px 8px rgba(#000, 0.1) | ||||
|   | ||||
| @@ -3,18 +3,20 @@ | ||||
| 		@dragover.prevent.stop="onDragover" | ||||
| 		@dragenter.prevent="onDragenter" | ||||
| 		@dragleave="onDragleave" | ||||
| 		@drop.prevent.stop="onDrop" | ||||
| > | ||||
| 		@drop.prevent.stop="onDrop"> | ||||
| 	<header :class="{ indicate: count > 0 }" | ||||
| 			draggable="true" | ||||
| 			@click="toggleActive" | ||||
| 			@click="goTop" | ||||
| 			@dragstart="onDragstart" | ||||
| 			@dragend="onDragend" | ||||
| 			@contextmenu.prevent.stop="onContextmenu" | ||||
| 		> | ||||
| 			@contextmenu.prevent.stop="onContextmenu"> | ||||
| 		<button class="toggleActive" @click="toggleActive" v-if="isStacked"> | ||||
| 			<template v-if="active">%fa:angle-up%</template> | ||||
| 			<template v-else>%fa:angle-down%</template> | ||||
| 		</button> | ||||
| 		<slot name="header"></slot> | ||||
| 		<span class="count" v-if="count > 0">({{ count }})</span> | ||||
| 		<button ref="menu" @click.stop="showMenu">%fa:caret-down%</button> | ||||
| 		<button class="menu" ref="menu" @click.stop="showMenu">%fa:caret-down%</button> | ||||
| 	</header> | ||||
| 	<div ref="body" v-show="active"> | ||||
| 		<slot></slot> | ||||
| @@ -26,6 +28,7 @@ | ||||
| import Vue from 'vue'; | ||||
| import Menu from '../../../../common/views/components/menu.vue'; | ||||
| import contextmenu from '../../../api/contextmenu'; | ||||
| import { countIf } from '../../../../../../prelude/array'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	props: { | ||||
| @@ -115,7 +118,7 @@ export default Vue.extend({ | ||||
| 		toggleActive() { | ||||
| 			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)); | ||||
| 			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; | ||||
| 		}, | ||||
|  | ||||
| @@ -211,6 +214,13 @@ export default Vue.extend({ | ||||
| 			}); | ||||
| 		}, | ||||
|  | ||||
| 		goTop() { | ||||
| 			this.$refs.body.scrollTo({ | ||||
| 				top: 0, | ||||
| 				behavior: 'smooth' | ||||
| 			}); | ||||
| 		}, | ||||
|  | ||||
| 		onDragstart(e) { | ||||
| 			e.dataTransfer.effectAllowed = 'move'; | ||||
| 			e.dataTransfer.setData('mk-deck-column', this.column.id); | ||||
| @@ -302,6 +312,7 @@ root(isDark) | ||||
| 					color #bbb | ||||
|  | ||||
| 	> header | ||||
| 		display flex | ||||
| 		z-index 1 | ||||
| 		line-height $header-height | ||||
| 		padding 0 16px | ||||
| @@ -328,10 +339,8 @@ root(isDark) | ||||
| 			margin-left 4px | ||||
| 			opacity 0.5 | ||||
|  | ||||
| 		> button | ||||
| 			position absolute | ||||
| 			top 0 | ||||
| 			right 0 | ||||
| 		> .toggleActive | ||||
| 		> .menu | ||||
| 			width $header-height | ||||
| 			line-height $header-height | ||||
| 			font-size 16px | ||||
| @@ -343,6 +352,13 @@ root(isDark) | ||||
| 			&:active | ||||
| 				color isDark ? #b2c1d5 : #999 | ||||
|  | ||||
| 		> .toggleActive | ||||
| 			margin-left -16px | ||||
|  | ||||
| 		> .menu | ||||
| 			margin-left auto | ||||
| 			margin-right -16px | ||||
|  | ||||
| 	> div | ||||
| 		height "calc(100% - %s)" % $header-height | ||||
| 		overflow auto | ||||
|   | ||||
| @@ -68,7 +68,7 @@ export default Vue.extend({ | ||||
| 				(this as any).api('notes/user-list-timeline', { | ||||
| 					listId: this.list.id, | ||||
| 					limit: fetchLimit + 1, | ||||
| 					mediaOnly: this.mediaOnly, | ||||
| 					withFiles: this.mediaOnly, | ||||
| 					includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 					includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| 					includeLocalRenotes: this.$store.state.settings.showLocalRenotes | ||||
| @@ -90,7 +90,7 @@ export default Vue.extend({ | ||||
| 				listId: this.list.id, | ||||
| 				limit: fetchLimit + 1, | ||||
| 				untilId: (this.$refs.timeline as any).tail().id, | ||||
| 				mediaOnly: this.mediaOnly, | ||||
| 				withFiles: this.mediaOnly, | ||||
| 				includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 				includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| 				includeLocalRenotes: this.$store.state.settings.showLocalRenotes | ||||
| @@ -109,7 +109,7 @@ export default Vue.extend({ | ||||
| 			return promise; | ||||
| 		}, | ||||
| 		onNote(note) { | ||||
| 			if (this.mediaOnly && note.media.length == 0) return; | ||||
| 			if (this.mediaOnly && note.files.length == 0) return; | ||||
|  | ||||
| 			// Prepend a note | ||||
| 			(this.$refs.timeline as any).prepend(note); | ||||
|   | ||||
| @@ -28,14 +28,15 @@ | ||||
| 						<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/> | ||||
| 						<a class="rp" v-if="p.renote != null">RP:</a> | ||||
| 					</div> | ||||
| 					<div class="media" v-if="p.media.length > 0"> | ||||
| 						<mk-media-list :media-list="p.media"/> | ||||
| 					<div class="files" v-if="p.files.length > 0"> | ||||
| 						<mk-media-list :media-list="p.files"/> | ||||
| 					</div> | ||||
| 					<mk-poll v-if="p.poll" :note="p" ref="pollViewer"/> | ||||
| 					<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> | ||||
| 					<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a> | ||||
| 					<div class="renote" v-if="p.renote"> | ||||
| 						<mk-note-preview :note="p.renote" :mini="true"/> | ||||
| 					</div> | ||||
| 					<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="false" :mini="true"/> | ||||
| 				</div> | ||||
| 				<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span> | ||||
| 			</div> | ||||
| @@ -53,11 +54,11 @@ | ||||
| 	</article> | ||||
| </div> | ||||
| <div v-else class="srwrkujossgfuhrbnvqkybtzxpblgchi"> | ||||
| 	<div v-if="note.media.length > 0"> | ||||
| 		<mk-media-list :media-list="note.media"/> | ||||
| 	<div v-if="note.files.length > 0"> | ||||
| 		<mk-media-list :media-list="note.files"/> | ||||
| 	</div> | ||||
| 	<div v-if="note.renote && note.renote.media.length > 0"> | ||||
| 		<mk-media-list :media-list="note.renote.media"/> | ||||
| 	<div v-if="note.renote && note.renote.files.length > 0"> | ||||
| 		<mk-media-list :media-list="note.renote.files"/> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
| @@ -99,7 +100,7 @@ export default Vue.extend({ | ||||
| 		isRenote(): boolean { | ||||
| 			return (this.note.renote && | ||||
| 				this.note.text == null && | ||||
| 				this.note.mediaIds.length == 0 && | ||||
| 				this.note.fileIds.length == 0 && | ||||
| 				this.note.poll == null); | ||||
| 		}, | ||||
|  | ||||
| @@ -370,7 +371,7 @@ root(isDark) | ||||
| 					.mk-url-preview | ||||
| 						margin-top 8px | ||||
|  | ||||
| 					> .media | ||||
| 					> .files | ||||
| 						> img | ||||
| 							display block | ||||
| 							max-width 100% | ||||
|   | ||||
| @@ -127,7 +127,7 @@ export default Vue.extend({ | ||||
| 		prepend(note, silent = false) { | ||||
| 			//#region 弾く | ||||
| 			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 (isMyNote && isPureRenote) { | ||||
|   | ||||
| @@ -96,7 +96,7 @@ export default Vue.extend({ | ||||
| 			(this.$refs.timeline as any).init(() => new Promise((res, rej) => { | ||||
| 				(this as any).api(this.endpoint, { | ||||
| 					limit: fetchLimit + 1, | ||||
| 					mediaOnly: this.mediaOnly, | ||||
| 					withFiles: this.mediaOnly, | ||||
| 					includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 					includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| 					includeLocalRenotes: this.$store.state.settings.showLocalRenotes | ||||
| @@ -117,7 +117,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 			const promise = (this as any).api(this.endpoint, { | ||||
| 				limit: fetchLimit + 1, | ||||
| 				mediaOnly: this.mediaOnly, | ||||
| 				withFiles: this.mediaOnly, | ||||
| 				untilId: (this.$refs.timeline as any).tail().id, | ||||
| 				includeMyRenotes: this.$store.state.settings.showMyRenotes, | ||||
| 				includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes, | ||||
| @@ -138,7 +138,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
|  | ||||
| 		onNote(note) { | ||||
| 			if (this.mediaOnly && note.media.length == 0) return; | ||||
| 			if (this.mediaOnly && note.files.length == 0) return; | ||||
|  | ||||
| 			// Prepend a note | ||||
| 			(this.$refs.timeline as any).prepend(note); | ||||
|   | ||||
| @@ -31,7 +31,7 @@ export default Vue.extend({ | ||||
| 			const title = folder.name + ' | %i18n:@title%'; | ||||
|  | ||||
| 			// Rewrite URL | ||||
| 			history.pushState(null, title, '/i/drive/folder/' + folder.id); | ||||
| 			history.pushState(null, title, `/i/drive/folder/${folder.id}`); | ||||
|  | ||||
| 			document.title = title; | ||||
| 		} | ||||
|   | ||||
| @@ -16,10 +16,10 @@ export default Vue.extend({ | ||||
| 	methods: { | ||||
| 		nav(game, actualNav) { | ||||
| 			if (actualNav) { | ||||
| 				this.$router.push('/reversi/' + game.id); | ||||
| 				this.$router.push(`/reversi/${game.id}`); | ||||
| 			} else { | ||||
| 				// 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.fetching = false; | ||||
|  | ||||
| 				document.title = 'メッセージ: ' + getUserName(this.user); | ||||
| 				document.title = `メッセージ: ${getUserName(this.user)}`; | ||||
|  | ||||
| 				Progress.done(); | ||||
| 			}); | ||||
|   | ||||
| @@ -16,7 +16,7 @@ import Vue from 'vue'; | ||||
| export default Vue.extend({ | ||||
| 	data() { | ||||
| 		return { | ||||
| 			name: (this as any).os.instanceName, | ||||
| 			name: null, | ||||
| 			posted: false, | ||||
| 			text: new URLSearchParams(location.search).get('text') | ||||
| 		}; | ||||
| @@ -25,6 +25,11 @@ export default Vue.extend({ | ||||
| 		close() { | ||||
| 			window.close(); | ||||
| 		} | ||||
| 	}, | ||||
| 	mounted() { | ||||
| 		(this as any).os.getMeta().then(meta => { | ||||
| 			this.name = meta.name; | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user