Compare commits
1774 Commits
Author | SHA1 | Date | |
---|---|---|---|
3d62bd8007 | |||
7ad9560f53 | |||
c135d02895 | |||
0757f67bde | |||
c5dc25cb9e | |||
0fcf422dec | |||
21e801a325 | |||
183faf3b2a | |||
9fc66a2d1e | |||
12cf598e6b | |||
dd6cd6332c | |||
20ee2118ee | |||
1546160f6a | |||
dd77a6194e | |||
203fba0216 | |||
826a2466b7 | |||
273bc6507a | |||
2b13969b26 | |||
2f10ff1a2e | |||
1f52aea193 | |||
0a0e76679e | |||
845f3436cc | |||
f6a8c8cf76 | |||
af61a7a17f | |||
667ad8fe96 | |||
e1cc2394fa | |||
04e1e48f17 | |||
c417e2f4a1 | |||
02a27a8b12 | |||
d775e19059 | |||
35e7dca2bb | |||
6c4ea5e087 | |||
54a1e500e2 | |||
450ed2c471 | |||
bf97fcb2fd | |||
4edeae07a0 | |||
8e19e4d33b | |||
2a774c9414 | |||
6f50ed327d | |||
a51d384f19 | |||
e2b2e4633a | |||
46ec773128 | |||
1827a65874 | |||
1b4dd64cbe | |||
95b7d84025 | |||
137b081b8a | |||
76af9bbda7 | |||
17ab07ae9c | |||
4c4d06e49b | |||
5d9ef68f14 | |||
4689cf5591 | |||
58e7edf08a | |||
9c6c281ac3 | |||
2326d6208b | |||
cd4be4116b | |||
6697ca243c | |||
15ce89a88d | |||
4b13278a41 | |||
e01167fcab | |||
719ff26e79 | |||
2657328ac1 | |||
4b7cef239e | |||
49d9e51f72 | |||
40a5f79d76 | |||
9cfd0b7351 | |||
2223ecf890 | |||
06bad9c501 | |||
a479e65f3e | |||
a2e99e46b9 | |||
07a27cfb9a | |||
77f3a0d3a9 | |||
f9065943c5 | |||
d0aff4409d | |||
84ea1fbd4d | |||
d1d92be09a | |||
52b23af97e | |||
b76cd18dea | |||
cd3b30bf5c | |||
b87ebc6f9d | |||
4d7d119524 | |||
b4b6e9548d | |||
ebf9cd18c8 | |||
b1ccbb2deb | |||
562cd6ad0b | |||
a832672b59 | |||
309058f209 | |||
2a344dfbd8 | |||
866d4cd59a | |||
165350cca6 | |||
8c21b8a9a6 | |||
41e3a9a004 | |||
4dc6ec5387 | |||
96515c4544 | |||
b3637b5e8a | |||
43bcdf397e | |||
22c5db7121 | |||
1c6a8f8691 | |||
31b5175bb0 | |||
9add59aca9 | |||
16c65173c1 | |||
4f6ae4633f | |||
8aa1577713 | |||
5bd41704ae | |||
4d0b335748 | |||
5692ae59a1 | |||
84f1ce866b | |||
e68c6175ce | |||
0de11c3636 | |||
1f70657d4a | |||
73646aac9b | |||
e72c590c6b | |||
06e026b346 | |||
5621d5725c | |||
14d0a07b29 | |||
105fefd114 | |||
f81c10fe62 | |||
86a2aa42a4 | |||
42f5c3fe22 | |||
975740464c | |||
c57bffb142 | |||
d92a2cdb55 | |||
5b91463233 | |||
39eed3378f | |||
cf98d40a44 | |||
7d6436c90e | |||
0acf3a8f6d | |||
8b7324c8d3 | |||
a0b0d5dff7 | |||
bef0e36665 | |||
766e721ff3 | |||
93ad4b359e | |||
b3032ad84d | |||
4f76acd249 | |||
fcc4b2c704 | |||
12286f4915 | |||
193abfdbac | |||
0e13481eb4 | |||
b713cac4f1 | |||
2137c894ef | |||
f0d2ce4f19 | |||
e3a89d302f | |||
d01d2ef65e | |||
23c550acba | |||
b9db88f616 | |||
dee4a18d48 | |||
fa5073b042 | |||
9dda698dc8 | |||
99d0930fba | |||
a599524b5f | |||
5f34758e87 | |||
cdb8e41176 | |||
d8f3e9d4a3 | |||
da900439a3 | |||
ad0273ab99 | |||
8bbff90aca | |||
fcb3ba9947 | |||
23b3e33df6 | |||
9edac2cd74 | |||
fbe0d70661 | |||
8782a64b18 | |||
d3b81c3e00 | |||
fd816afcd0 | |||
ac423f1ef4 | |||
f11ebafe47 | |||
7947036af9 | |||
b722431720 | |||
295563caad | |||
26735815f1 | |||
c06a52c237 | |||
5678adf3b5 | |||
ac772dd389 | |||
2c4de8475f | |||
46facaf176 | |||
eea1b7fc63 | |||
f0e9386cd0 | |||
e4a4238b57 | |||
55e126998a | |||
608a30d37b | |||
7d22d6255d | |||
4e55436339 | |||
3adadc8a52 | |||
b525af822c | |||
bee8a5b065 | |||
f4d80122b3 | |||
2e8ea34413 | |||
7341d97a00 | |||
964b34bd3b | |||
38e8d4bbea | |||
cb106e6fe4 | |||
61411605b8 | |||
0ac7682188 | |||
d7af18efbd | |||
64bb6daa43 | |||
0a1951f24c | |||
8bb388f62a | |||
ee36956451 | |||
f1a0e95489 | |||
de5d9470af | |||
a9838495ce | |||
d34c080822 | |||
59f55a8291 | |||
79ace6238a | |||
89e88802b9 | |||
c7f969a002 | |||
18b186068d | |||
037c67cbfb | |||
c3ccee9097 | |||
2449183f44 | |||
1c98226621 | |||
b405669672 | |||
53fbe675a7 | |||
6bcc174456 | |||
a3493c4f07 | |||
545ced7826 | |||
a9a476a0d5 | |||
8dfd35303c | |||
498ca306e4 | |||
5a46e08165 | |||
c0c57044cc | |||
42d00b96c6 | |||
072360947b | |||
d60ba8e37d | |||
c10cf60059 | |||
880689e28a | |||
ade7050996 | |||
71b5fae4d9 | |||
d398e87ea1 | |||
6256d021e6 | |||
405f242ff9 | |||
8823a6c1a1 | |||
65a82f32be | |||
fd593458a6 | |||
3985fe6b09 | |||
db71a5da62 | |||
d76e3e4853 | |||
eead9fad03 | |||
b498072f9d | |||
f56a961db2 | |||
5d224f4eac | |||
5b5edae11c | |||
bd51154c46 | |||
749a1ff8b6 | |||
b06d46f46f | |||
7146a534df | |||
ef51e591ee | |||
9d2f4d3ffb | |||
f7e0b196eb | |||
feb7e58912 | |||
fbf04392c9 | |||
e650818952 | |||
76fcb1af87 | |||
cce3e52642 | |||
8c762e7b8e | |||
f0dafa04a5 | |||
81f39b3b36 | |||
b162471d3e | |||
2736e8d6fa | |||
182f6f8faa | |||
ff34655221 | |||
f6ce6109f9 | |||
899ac15d88 | |||
7132f2062c | |||
96b354c7f2 | |||
715664a523 | |||
e8ddfb4bfe | |||
2a1229978e | |||
b8af3515cd | |||
f99e3f3d42 | |||
d6057bd830 | |||
975e57ec48 | |||
bd35965c99 | |||
1029bff5ff | |||
6c1893f869 | |||
0a89ba60bd | |||
c6e418a242 | |||
d9a6666ba8 | |||
ab849fbbef | |||
9d6b6053a6 | |||
ddfd64944d | |||
51153ed287 | |||
0e7bbd1b32 | |||
5049791d7f | |||
1ebcf8d915 | |||
e01873811a | |||
d078b871e1 | |||
c6375ae864 | |||
483467e32f | |||
c84d43bc5f | |||
fdd42fc2d7 | |||
8573e258f8 | |||
6943c7d2d8 | |||
4a42bf7b19 | |||
b982f97c05 | |||
d9207788d3 | |||
0ad48cc896 | |||
5e191a1f5b | |||
8069e44d0a | |||
0a83f0fd67 | |||
83c54fb6b9 | |||
5f6b0f689f | |||
1b0b96526b | |||
edb0469787 | |||
3256a0914e | |||
3c15182f24 | |||
f7bc5e3c0b | |||
19f327701d | |||
6b30e371a2 | |||
98fd6de5a1 | |||
6635f25abe | |||
5f93106eab | |||
84f2994d47 | |||
96f5c6d616 | |||
b67923abb9 | |||
310f7b3359 | |||
c743c45989 | |||
0322c51913 | |||
b85e27c7e5 | |||
aa351d1f7f | |||
6b48b79758 | |||
104ea7e277 | |||
97de1ed3a8 | |||
d69e9741da | |||
0f5c737c1a | |||
cb9960b0ac | |||
1404539895 | |||
2f901da58c | |||
3637c1bfbc | |||
28c3edc844 | |||
9271a8c066 | |||
7b16bfc736 | |||
54450033e4 | |||
fbf676d518 | |||
47df0bbec1 | |||
708f8b3cc3 | |||
9de163ab09 | |||
e21be29131 | |||
1aabb725d0 | |||
3e17c34187 | |||
d57de01d37 | |||
71918fdbf0 | |||
cb8663873d | |||
0f204eebe1 | |||
dec572a6b7 | |||
28848ba969 | |||
4cfcd37a2b | |||
2b0d5516d1 | |||
3e3c3c10ab | |||
3cc282db14 | |||
4c1c865ba9 | |||
9423c99427 | |||
d1512c90f1 | |||
85c9993106 | |||
1d580009e4 | |||
22ad21597a | |||
76d8f66eff | |||
febdf0cbee | |||
ba05606074 | |||
030fe8bec7 | |||
4587c5a512 | |||
96646e584b | |||
fb2879df9c | |||
26ea338e8e | |||
1fad5ed6f3 | |||
20db10516c | |||
00631f58ec | |||
35273e53bc | |||
bfc458e935 | |||
bb819d42f1 | |||
5d76439224 | |||
3d0b704af8 | |||
05539ffc7b | |||
c86deab69c | |||
21f8dbf2de | |||
6731f904f2 | |||
f6e74f529e | |||
c860a2f7f3 | |||
7b141722ae | |||
fc516ffb7f | |||
11604593a6 | |||
6f3468ccd2 | |||
e3be90503c | |||
22d38e0d24 | |||
8b654fb40a | |||
91cd9831bc | |||
805d72d42f | |||
0d4a1719a6 | |||
32ab57e11b | |||
5174e16f7b | |||
9b746f3eb5 | |||
becd038660 | |||
2a6cfec0e6 | |||
dfc6ef4be6 | |||
c8b45f4f42 | |||
09c57e6d03 | |||
5edb1da097 | |||
b3ad3a6535 | |||
3709bb23bc | |||
28be5c0b81 | |||
60ef74047a | |||
f81596c8d5 | |||
075b7e3060 | |||
cc7d6198ec | |||
5766c2ce1b | |||
03fed08c03 | |||
4662641feb | |||
00e2ce9489 | |||
c2ec81f93a | |||
47561a6f8b | |||
c81eb49f9e | |||
205c0d44d5 | |||
dc1bdbaaa5 | |||
d619a92a37 | |||
59ad529162 | |||
c4c44e04fd | |||
fae58a9ab0 | |||
fa03c172f2 | |||
89ac15b4de | |||
10d3b81251 | |||
71dceca225 | |||
40de631d95 | |||
6985c39874 | |||
0938ea3964 | |||
4b4c19b242 | |||
d8620187ec | |||
520849d070 | |||
b6a028a8ed | |||
7db799a0ac | |||
1ab776c867 | |||
f4c9f63548 | |||
08da9d70cd | |||
96173e5c0b | |||
b37cc70742 | |||
96ee4299c7 | |||
6072b02f12 | |||
6ccbca0741 | |||
360394fd5c | |||
dcb45aa953 | |||
a8fcc1aad9 | |||
4d69cd86f1 | |||
6e14e58b89 | |||
af5839bb59 | |||
a53e0d9f73 | |||
49921f2dcf | |||
70d2d61b9a | |||
9abaf80f6b | |||
25948fc3c9 | |||
6b947c2139 | |||
98acf919f1 | |||
c9c2853150 | |||
2bc708f8e6 | |||
874b8fc3c2 | |||
7d6aac3431 | |||
e2fc7decad | |||
21bed71f5e | |||
747a5694f8 | |||
479a0a2deb | |||
14aef6ec89 | |||
f0d2b3f449 | |||
3b974428fc | |||
580191fb17 | |||
be0cb88b6c | |||
95c4e4497e | |||
2ec445f83e | |||
51b915428e | |||
1395cf89ce | |||
2a8f984db7 | |||
decf2d396f | |||
f7964da899 | |||
c8607ff7b6 | |||
e9f8897fe2 | |||
e0b107a3a0 | |||
abf2c89931 | |||
1d3e6a7197 | |||
288bf195e9 | |||
7e3cc11cc4 | |||
4e07e94af0 | |||
9cb49c9204 | |||
580dd729e5 | |||
49ab77c86e | |||
f98914b9f1 | |||
f3f3599b28 | |||
f67b1beee4 | |||
8395d0f1ba | |||
af203bee93 | |||
760fb79dad | |||
ee9d4119c2 | |||
90027efcbf | |||
1848de1dc4 | |||
1c93fcb1c4 | |||
e3389e7899 | |||
454632d785 | |||
c9bca7dc85 | |||
710ba526fa | |||
aa47b6732d | |||
20f83420ca | |||
d09a68ef11 | |||
b545be5799 | |||
4fc377584f | |||
a5f09c90dd | |||
ba407c3eb0 | |||
d059d7f972 | |||
c03e2dfbc0 | |||
45c5e7b967 | |||
c81a94ff75 | |||
acc6f54557 | |||
8025b121af | |||
78ec06bda3 | |||
6ef83d9c59 | |||
fca4ceef21 | |||
00f979f0e6 | |||
556677be7a | |||
624fd093f2 | |||
2ee438dece | |||
534de24406 | |||
014edce1b9 | |||
ac1f3de4c6 | |||
dced228cb0 | |||
a92244cc12 | |||
0717688933 | |||
87d54b7d40 | |||
ed51f5c7de | |||
66e2db0d52 | |||
03be4826df | |||
c9d5aef04f | |||
106cb3fe3e | |||
48320f8536 | |||
1a0845dc0a | |||
185d09f3ed | |||
8e25fb6cb7 | |||
e88ce1746d | |||
b8aad35009 | |||
47bd485a39 | |||
ad869d7469 | |||
d15cce5337 | |||
37daff6d61 | |||
5417e40f59 | |||
0fed33bfdb | |||
5dddc75d09 | |||
081578c604 | |||
6c47bf5b76 | |||
936bb1bcd0 | |||
d5241d9a3e | |||
05b4430c92 | |||
292e911de2 | |||
1c4ba2c037 | |||
452db13d0c | |||
c3f64b395b | |||
3fa6bf93a4 | |||
a13d76bec5 | |||
05cee078d0 | |||
706d3f3f95 | |||
c5cf034b5d | |||
3a04aa93f9 | |||
838cdbedbd | |||
9e85291cd3 | |||
7f77517fc8 | |||
b2f288dcac | |||
52b59e9d7b | |||
80c74b1fa7 | |||
91811ea500 | |||
57150fd910 | |||
cddbbdf5d0 | |||
423dc2349b | |||
5229bbd55d | |||
28311b9a2b | |||
663d17a485 | |||
08d005dfd9 | |||
02edbc131b | |||
0556a2a2da | |||
65d943e42a | |||
3bcb344ecb | |||
82d721d60b | |||
48dc56e834 | |||
2c33bd6e31 | |||
b6524616bc | |||
7e2b70f912 | |||
4f071a66b6 | |||
39f2303429 | |||
cacf072027 | |||
6ab1fdfe1a | |||
6e5c93f926 | |||
1670737075 | |||
fee235c4e4 | |||
7a39d489f2 | |||
7c634218d1 | |||
2704c5be73 | |||
489b51ba9f | |||
21807c29f1 | |||
3bc62fe3eb | |||
ba0e3c4a5f | |||
9ec1fb5e37 | |||
d708409462 | |||
07d05d4f86 | |||
bbdb2ebb40 | |||
f7908ba098 | |||
f2fda3075e | |||
1338a68979 | |||
e7da505fb3 | |||
5a9228372f | |||
c4a6ba9097 | |||
d5871b408b | |||
7b3338e373 | |||
d18ee12d2f | |||
ca9cc97940 | |||
a70070ac7d | |||
069d99b320 | |||
37d350dcad | |||
8653e09b59 | |||
7cd2d59576 | |||
a0839de38f | |||
b7c5c71c6f | |||
adab0adbdd | |||
2faa58928f | |||
ffb80efe21 | |||
6f959218ef | |||
be1125dcb9 | |||
9ab34c2301 | |||
0166d81d9e | |||
0b26efbd2f | |||
2cbaedf946 | |||
b66924fbe8 | |||
8c91148954 | |||
be0eff3dda | |||
85903ac9c6 | |||
dbdd778dc7 | |||
fc50dfd8d5 | |||
f444e132ee | |||
68f562c323 | |||
820ea69613 | |||
6f4b3853a1 | |||
a706ad0e80 | |||
820116affc | |||
52650342be | |||
85ddabdc65 | |||
0730cc4fa4 | |||
17b6ab0ef0 | |||
4e208b85bb | |||
00f8b29f6d | |||
9cf0fcadb1 | |||
c595efeead | |||
b56c6793a1 | |||
ebceffba1e | |||
3ae42d9b85 | |||
796237b3c6 | |||
cb7a97ee4c | |||
0cf758b6d1 | |||
d28fca320e | |||
8bd17703c3 | |||
a78eebc43f | |||
79fb5246df | |||
458b8c78dc | |||
64e0cbd6fc | |||
7fe937026b | |||
656cec65b9 | |||
8045bbff1c | |||
c1a7a21746 | |||
f3ee63fcbe | |||
7645c212a3 | |||
8b38e2ea58 | |||
c9eb6a8919 | |||
9a41fd4734 | |||
70d96ee076 | |||
3b6fb3959b | |||
484d705320 | |||
786031be66 | |||
bc0027ce43 | |||
3e7c6d9bdc | |||
5463e3e55e | |||
84a880086e | |||
89419b7136 | |||
9106ec74f7 | |||
ebf9a0921d | |||
c237f49016 | |||
709290d2da | |||
eb3180f3b6 | |||
681997509c | |||
79ff5888fd | |||
9ee9cf8d81 | |||
ee3c0f6f18 | |||
9dd463bff4 | |||
df297d0031 | |||
d18d1cb958 | |||
5bc0570888 | |||
8b43d75eaf | |||
89b37bd73d | |||
69f246ce7f | |||
6a97f0b7f6 | |||
d885b872f3 | |||
125849673a | |||
30c53e9ee0 | |||
981fb9e8f3 | |||
9fac22d880 | |||
b8f034064a | |||
6068227434 | |||
69cda49c88 | |||
039d821d20 | |||
44d93bc408 | |||
cfa76ac6f9 | |||
0ec2d16522 | |||
6bcac1fe14 | |||
bc9427d000 | |||
07c043361e | |||
e676a9a501 | |||
09e654c6d2 | |||
549cb1ba87 | |||
c633827e5e | |||
08142ead67 | |||
638d81b66e | |||
4c83c2f64d | |||
bf56f90fdc | |||
d8412aad7a | |||
c136741710 | |||
4fe8454da0 | |||
3f2161dadd | |||
3db516aa1a | |||
367bbbe605 | |||
5b70ff561c | |||
4486527e5d | |||
147e23d332 | |||
ee20e6950e | |||
1d217154ef | |||
27d304a1ab | |||
1d1a373ca8 | |||
bca3c6f8bf | |||
d83d661535 | |||
e16906afc3 | |||
a6dc0f3684 | |||
6120474548 | |||
121dd86299 | |||
5251d9f668 | |||
7ae3f569de | |||
142ebead59 | |||
e196086c64 | |||
8c6ed98505 | |||
98a2953c9c | |||
61d224695b | |||
6967def6c8 | |||
393c6aa79a | |||
fc05540404 | |||
1c589c7c18 | |||
284df27435 | |||
68c0600a5c | |||
b8163bd0e1 | |||
8c25b9dfad | |||
bf34f67583 | |||
0c63f410d6 | |||
069077ace4 | |||
5be947ea4d | |||
b41ffa75b7 | |||
cd80e02ebf | |||
dffcefb81f | |||
48df08d4dc | |||
4de9a08e55 | |||
3f46b5259b | |||
2faa8ea97c | |||
514690cf18 | |||
f4f78c1898 | |||
2d24befb15 | |||
184d88838c | |||
4490503d59 | |||
99750435ae | |||
fae920e578 | |||
0243b6d13b | |||
12bc725d68 | |||
b1a7b781ec | |||
7e1cad3e12 | |||
fd3f4c37a0 | |||
3acd2e0f0c | |||
b1b5a795c8 | |||
197e2c8377 | |||
fb8b0c291d | |||
706d47ec32 | |||
4eab2b3654 | |||
0a78f560e0 | |||
f6f79fb388 | |||
34235d4d44 | |||
21842ec190 | |||
026e1cc7e7 | |||
c65f4eebaf | |||
17baf8770a | |||
01f60edb17 | |||
15b11e59f4 | |||
a2db4db963 | |||
e87b9cc019 | |||
54cb94db1d | |||
1de8e1eeb1 | |||
1d8fb65959 | |||
28482627f7 | |||
4ee7df887d | |||
b040571fa8 | |||
fbd5e4bab8 | |||
498bdd1cd0 | |||
102cca8971 | |||
e710ad4c5f | |||
f64f6fd603 | |||
5995020c64 | |||
2dc86ec1ac | |||
d50bcbdb23 | |||
19afd0ba61 | |||
7a787fa95c | |||
4e85eb90cb | |||
d4474b953e | |||
0aaf3d7bd7 | |||
02bb2423af | |||
e9b25f17af | |||
96671c5c7e | |||
4fc786f062 | |||
51c0cca4ff | |||
bd344628f6 | |||
48deb35d4b | |||
f9792f0d5c | |||
0157033104 | |||
596f92cfcc | |||
b2dedf7f98 | |||
34393ef89f | |||
7e11cd3b99 | |||
dd1622296d | |||
77cb59a6ac | |||
a2b60e38a3 | |||
f0570bf111 | |||
b980164318 | |||
3e7ff586a5 | |||
923bbcbf6b | |||
8cc85931d6 | |||
b25522a091 | |||
97ae7e9ef4 | |||
d25bd65722 | |||
f4f98c25f7 | |||
336607568f | |||
e2843a5ce4 | |||
702875a78e | |||
0fa8c6afd2 | |||
96571866a3 | |||
f72b00bec7 | |||
1e7b5a0a98 | |||
9f09afc824 | |||
93b599dc8e | |||
1c722494de | |||
a464c8d1d0 | |||
51362e9a52 | |||
3c086fe8c7 | |||
f3b1248bd8 | |||
4e529ee7d0 | |||
a2b975a493 | |||
13055d1496 | |||
78b5af4e4f | |||
008432e156 | |||
d3d50b2f79 | |||
eefeb4c268 | |||
86d4f1981c | |||
7a8e97972c | |||
3555213155 | |||
5d3d8dffd6 | |||
dea8688c9d | |||
a235869cfa | |||
a8434b3bc5 | |||
f110b2b320 | |||
0543cffe00 | |||
0383cbe43f | |||
9dd1203583 | |||
4eeeaffdee | |||
6f73f3d7a1 | |||
aa9cd211dd | |||
3cdf4f01f8 | |||
d0f84643d8 | |||
89707ad436 | |||
163d81c1b0 | |||
81a7213583 | |||
8f92a07d68 | |||
31b30e3dd2 | |||
0a1ac12d97 | |||
e800104ac4 | |||
05cb94eb77 | |||
51499e04e0 | |||
0c993ef851 | |||
b27fced30d | |||
2b7da9d98c | |||
cd66f86f08 | |||
a2e7cab573 | |||
f81f7d51c5 | |||
7fb640e38f | |||
c7561be15f | |||
741c81bca9 | |||
1e38528716 | |||
58b3be438a | |||
4522568749 | |||
719f9c8c02 | |||
fe891da886 | |||
95b6684cfd | |||
66836836ab | |||
0db48c778f | |||
13a2f9373c | |||
ae4d504392 | |||
85d240625d | |||
db646b0ad9 | |||
2570d50957 | |||
7faecaadcf | |||
dcbcb18081 | |||
f1a61a268e | |||
d7636355a1 | |||
ed2993b3f2 | |||
1368c9d182 | |||
c5e3c07c16 | |||
f8395166af | |||
dc8f4c8d6a | |||
ed4860dfd9 | |||
5b0bf98b3c | |||
adffac1000 | |||
3a1672b061 | |||
e7658be6cd | |||
63533ad9c8 | |||
34b431fa1d | |||
958802dbe0 | |||
8681259597 | |||
f3d76c06db | |||
3f32a9bfff | |||
c497149765 | |||
9159613f2f | |||
70e95a5cdb | |||
b0f82749aa | |||
20c0690352 | |||
006ecec443 | |||
effcf0a609 | |||
3852d0b2c3 | |||
ec67590dbe | |||
65d0dbb7d8 | |||
f8af57dffb | |||
2b058be3aa | |||
67efd30553 | |||
8d1fdc5aa4 | |||
d033103163 | |||
53dff28a21 | |||
53c37036ee | |||
133c879a3a | |||
a105faeaae | |||
13404310a7 | |||
2373b114bf | |||
5bfc6b6547 | |||
8026a609bb | |||
10db61a0d2 | |||
40520f3997 | |||
c1d59716d1 | |||
d8698743a1 | |||
ade5055bc3 | |||
6e343d50f1 | |||
ce3f735654 | |||
9b5e623130 | |||
f0b0c5b540 | |||
dd2207d430 | |||
ffd6ac2434 | |||
27f93cc112 | |||
7ee88a69ec | |||
227798300f | |||
2ab8a5bc0a | |||
c222b9ae94 | |||
53a0f3c794 | |||
9ff349c548 | |||
37a360efd9 | |||
3a850823a9 | |||
4da53b7382 | |||
cb6f94735f | |||
c073a20969 | |||
6dc8a385ee | |||
f299c050b8 | |||
eed540a51c | |||
5db72c4d71 | |||
fc0bbfa759 | |||
6d63c81dd5 | |||
bea42924cb | |||
b48ef68c12 | |||
65109d140b | |||
0935bd4bd4 | |||
45bee7cc2f | |||
1c86a4bc26 | |||
b385cf2a9f | |||
40d3dc454d | |||
8e92848495 | |||
2d94a22a30 | |||
7a5a091c25 | |||
2baf810c71 | |||
d1ecef13ef | |||
495fa553ad | |||
854e649ea6 | |||
c047324b42 | |||
daac865c72 | |||
63d059b8d1 | |||
e3075a0dc7 | |||
6b6e597b95 | |||
eb0eadad5e | |||
f600fee16d | |||
7b88c54aa6 | |||
623dd57cc3 | |||
f6edd33adb | |||
ac20d73222 | |||
c59374d79d | |||
0d478046de | |||
f3479d1b98 | |||
2fdecb8a38 | |||
a95c3ee557 | |||
67c439c70a | |||
b96037cffa | |||
ebd8d34552 | |||
a653d9a83e | |||
07d6894c42 | |||
03588b3fd6 | |||
2e83440e70 | |||
2633873fcc | |||
5f33713f53 | |||
fe84c5010c | |||
7f39df0713 | |||
928d359dd2 | |||
184eb00133 | |||
e264a49b08 | |||
8caf853c80 | |||
b451c04787 | |||
1653977392 | |||
a0d9def98a | |||
92701e5cec | |||
0b6b6a4f2f | |||
3a2dc95850 | |||
163cf49f16 | |||
37fc3103f6 | |||
b7bd1ff69f | |||
dc36134f10 | |||
fea8821091 | |||
33faf40aca | |||
4410f8d7f7 | |||
3e6029e69d | |||
96c7707e6c | |||
d8e545db3c | |||
a9a6ba0aed | |||
a898c6ceab | |||
0205c5c2d7 | |||
f8074ab74b | |||
f15c491d5f | |||
c38a32dee9 | |||
4f5abed70d | |||
c9ac9923df | |||
bb14895fd8 | |||
6f92d601ec | |||
345143b0c1 | |||
dc80d5d376 | |||
d3544f9637 | |||
864b6ad1bd | |||
c58027e521 | |||
10fb399588 | |||
10f466c895 | |||
32068b4bcc | |||
381f2b7fdf | |||
1c3c733c6b | |||
8bc5febe66 | |||
20335e23f9 | |||
9dbc9115c9 | |||
fe707f88a4 | |||
9b23ebd4a3 | |||
bea450cc2c | |||
e80709f7aa | |||
cb71f92f42 | |||
2ca5348560 | |||
c8e98fdf8e | |||
0bfa041026 | |||
33bf474a1e | |||
53c559c001 | |||
1c99ef454b | |||
cf4cecd4df | |||
6a8835b923 | |||
f2b1cf92e1 | |||
6b79618e74 | |||
3db414add4 | |||
9ef641b403 | |||
6fa7819a44 | |||
59a1b9adbe | |||
3fbc7094f6 | |||
56c6227bc2 | |||
ee82f99f5a | |||
72d9a46156 | |||
683a85ecc0 | |||
89047fd66d | |||
789de130a2 | |||
46c026ce70 | |||
82290f6e4e | |||
8729525f95 | |||
df0115ffe8 | |||
0275b4fc9e | |||
9982fd71ba | |||
081060b7db | |||
0de64f1fc7 | |||
f0508c0a90 | |||
b51ae1dfaa | |||
6e7233d41b | |||
8ca27a4480 | |||
418041a56e | |||
17d20f5a18 | |||
77d2d84e05 | |||
3bde4285eb | |||
15efbfb244 | |||
55a57db958 | |||
91f624c900 | |||
d753489e49 | |||
36dd7c82db | |||
b00db74216 | |||
cf9f85eb2a | |||
bfa8414289 | |||
58dc9c9544 | |||
ba95ce18a8 | |||
ac10c40f31 | |||
de8b40c80f | |||
60fe69728d | |||
557607e842 | |||
40ac9de728 | |||
a725cd1946 | |||
b648706756 | |||
20f2e9fc6d | |||
858ced0a53 | |||
c9ca8f777f | |||
0d0be31527 | |||
96305a088c | |||
22e30b44b9 | |||
48d0e2fa5f | |||
0489291815 | |||
7a412500e1 | |||
dffaa72a88 | |||
152d61f906 | |||
b44ded5fc9 | |||
99d77cc843 | |||
bc385eec2d | |||
2c6b9403b3 | |||
89cdc59fe5 | |||
3e04e1ccea | |||
25f491a65f | |||
7fdde157e0 | |||
27f30a449a | |||
dc66a0cd66 | |||
f302ecd1e2 | |||
1afc2a227a | |||
ab594d1dfe | |||
647d32f506 | |||
1bc109b42c | |||
6e02e2a6b3 | |||
3372baad6c | |||
e9b3e3877a | |||
c84c5fbae7 | |||
2e7ab91f48 | |||
92c41c003a | |||
53688cdcdc | |||
70f864ea8b | |||
5dd94e551a | |||
afc1ed9897 | |||
df7562f98d | |||
1c7e799164 | |||
107a3f99f4 | |||
7e3cf4b4ad | |||
afdb23ff57 | |||
0ce64f8c33 | |||
2cd6ccb85c | |||
3dcf5374c2 | |||
1c7d5f3f64 | |||
bb0cb0a866 | |||
362dc29057 | |||
8af0218e4c | |||
09af9968b5 | |||
7d0b819c5a | |||
4bbb7eded3 | |||
72ea9e5522 | |||
743e5d947d | |||
f257853906 | |||
32983d3829 | |||
bdef33e88d | |||
a4a4194586 | |||
e36c538dc0 | |||
982a218bf2 | |||
f7aeca4c7c | |||
4b81bc864f | |||
a52cc62c04 | |||
81f69bff9e | |||
d9b2aa1880 | |||
3bddd986a0 | |||
d00712d817 | |||
d756fdbebf | |||
b2f2c74605 | |||
1407cd71b5 | |||
3dd3a7238d | |||
afc834ae4b | |||
357f190ce3 | |||
ab92762320 | |||
04942c8477 | |||
9c60f51e0d | |||
956ae2ac46 | |||
f2ed813337 | |||
7d9a7d1a3c | |||
2f67b6fb47 | |||
7444dde93e | |||
e62fad7bc6 | |||
2c6bad2501 | |||
6952bb2eca | |||
610972dbde | |||
926049055a | |||
db5f6b60df | |||
7be7b9d9fd | |||
366855c4cc | |||
e950beeeab | |||
5515b39f6c | |||
f5d0599e4d | |||
8fd7914f0f | |||
24ef98eb01 | |||
b3dd6cf001 | |||
6d4b474cb1 | |||
0a8876a3ae | |||
9a83a48331 | |||
7ed50b90bd | |||
b6fd5d7282 | |||
33243e7176 | |||
e8439679a5 | |||
06124dbbd5 | |||
857940f402 | |||
bcb04924ff | |||
2b6aeb9ebc | |||
648e4538fb | |||
cd4b3777da | |||
4acf506b7e | |||
543ca348bc | |||
03375412f1 | |||
0c7a9b6827 | |||
c54bc3c176 | |||
90973bedf4 | |||
757f70162e | |||
3047410b35 | |||
9d0d4c5eae | |||
cab5b4d601 | |||
517b6e25d9 | |||
94d394c29e | |||
a52099d175 | |||
f1cb7b862d | |||
0863e5d379 | |||
55dcd25df1 | |||
f3155ea180 | |||
2c5162671c | |||
fc8aeb5a66 | |||
995cf503eb | |||
0e49c11a4c | |||
0367c37b0a | |||
e0b9fe5e5d | |||
a4726e683b | |||
3b10e93efe | |||
02b07c1b5b | |||
5e54751bd4 | |||
34f1dc238d | |||
3c0f4bdf35 | |||
a68d370ad0 | |||
debb27ed30 | |||
97fbb857fb | |||
93f13ffc8e | |||
4d9dc93d46 | |||
22cd4c5d16 | |||
6883994b22 | |||
852a312753 | |||
afea0baaa8 | |||
2c477660a0 | |||
16a1cd3c9d | |||
db23dd2e01 | |||
eaa1ded5ba | |||
393e14196a | |||
8b005307ea | |||
c915ac0e72 | |||
1752bb896e | |||
9c8fa026f3 | |||
e93db6324a | |||
a10708bffa | |||
e65a7a142f | |||
72e0b2d470 | |||
43fb0f36a7 | |||
cf3533221b | |||
de522ebe14 | |||
2ace891dde | |||
e212d9f991 | |||
739f3f84d0 | |||
5e206c86be | |||
1ab37011ea | |||
b6e02f63cd | |||
60e10d4efa | |||
95ba7e43b1 | |||
9e5a2e5b17 | |||
dbbc416095 | |||
a479ad357c | |||
b1c12abb7c | |||
17d1a1d7bd | |||
ba50156a83 | |||
eb83ab41c0 | |||
4e6a917dab | |||
8c4f0d4589 | |||
3f7738204e | |||
e251a9b9fe | |||
01d43b9683 | |||
4d4a0c89a8 | |||
0a5524e9c8 | |||
c8fb5746b3 | |||
bbcc132978 | |||
d3e4f84285 | |||
62c470cf75 | |||
8ab31d3765 | |||
55fe1cf0a8 | |||
00cff51ff7 | |||
d6bc4a7aa1 | |||
4e57d12aea | |||
4a2d99c43f | |||
217c27df86 | |||
e6dcd438b4 | |||
de2b0224d6 | |||
3f8a72eb88 | |||
0387176e8c | |||
aa34e332f4 | |||
d13999d689 | |||
22c4e92728 | |||
df8128c0b1 | |||
ec534a3704 | |||
366d4cd3e2 | |||
4841926df1 | |||
f2f7bdc5a9 | |||
fd811eb325 | |||
915d352505 | |||
1d1024c57a | |||
73df6e0347 | |||
e6d62c5a7b | |||
470e48c0a5 | |||
9235f72a2e | |||
9fe6da79b2 | |||
1858437eb1 | |||
c3ba0dcd32 | |||
70f4b13089 | |||
cc57a4b671 | |||
6902700458 | |||
b772041547 | |||
79174c1a19 | |||
898850027a | |||
0d272b1fb0 | |||
7993a9eb90 | |||
42d419970d | |||
ad49268d8b | |||
76c345396a | |||
5690ef1ebc | |||
5616404b4d | |||
f92137f6c2 | |||
ca3373ba4e | |||
4e6115b414 | |||
ddf47051c9 | |||
d45478510c | |||
2641f89349 | |||
9d46d03c37 | |||
25b6de88a9 | |||
a24046e46a | |||
7e803ff9a9 | |||
246cead2b1 | |||
214f7f06bb | |||
6878f73a9f | |||
336b45b6f7 | |||
2a0b62d26d | |||
653ec0cbb0 | |||
120ab3f0a3 | |||
8bcbbbc1a3 | |||
13a75abc91 | |||
eace740c63 | |||
cb3a54de00 | |||
5fbc77795d | |||
ce4feae731 | |||
08f00d4990 | |||
6951f7e74a | |||
2b4d63b1bb | |||
8cbb961493 | |||
64c795938d | |||
67df681a48 | |||
9285bcf8bb | |||
b9b23a4b54 | |||
2f6371b085 | |||
2a5c3475a7 | |||
8a2698a5db | |||
f6919a171a | |||
82ebf67456 | |||
a60c8b2ee8 | |||
0a2b8ccfb6 | |||
698094b787 | |||
b57e111ea8 | |||
aa6bf2b54e | |||
454910d295 | |||
d44e620769 | |||
ac14adfd3e | |||
928d30ee1e | |||
3dd9b0f347 | |||
c57dd083c5 | |||
2a1d6c5406 | |||
112e9f69bd | |||
d50e537888 | |||
86d14d30fa | |||
710d3689d3 | |||
3fee011369 | |||
7cd4b8ba4f | |||
31132de18b | |||
c6cb271f6f | |||
b7c4afd20c | |||
70395d200a | |||
562a5f66fc | |||
b2f8003602 | |||
b7b36973f7 | |||
f7d5f597f3 | |||
79c7712241 | |||
8f5f3985f4 | |||
ef30f36f55 | |||
4198497237 | |||
9b1612574e | |||
ca8a218144 | |||
db9c2913cf | |||
286674c2bb | |||
7c259185bc | |||
79ffbf95db | |||
6e347e4221 | |||
28ccb14166 | |||
389315e000 | |||
af00464f5b | |||
f522b3df91 | |||
168db6891f | |||
4a77548672 | |||
e9ec4a3b84 | |||
375b2bb284 | |||
b922277896 | |||
8f6f810dbd | |||
8f0c433e05 | |||
e332e3c248 | |||
2f90c38604 | |||
fa33d12bd7 | |||
86ab496fd6 | |||
ca0cb6fd42 | |||
be52779bbc | |||
23b64794a4 | |||
d5fed29df3 | |||
644bc985e7 | |||
5c1dc31131 | |||
31fae1caa6 | |||
9bc85ac511 | |||
69d6dc22b9 | |||
c4f81fc1a7 | |||
9a866766e0 | |||
eb7153acee | |||
f3d98da329 | |||
aac1c50a77 | |||
0619a27916 | |||
49ba56493f | |||
bf0dae8cc3 | |||
fbf77afde1 | |||
5159caa9ff | |||
5aef35f0b7 | |||
4db2843e7b | |||
a390e57dff | |||
8d70587814 | |||
6f3775de9d | |||
5a0a3050ae | |||
cbbf141846 | |||
43c2b00cf8 | |||
046ccd49ca | |||
e7df6f5c0e | |||
c67110835c | |||
4c97b847e7 | |||
cfa4f0fe0b | |||
9672343360 | |||
80fdfe54c4 | |||
7fcbe87591 | |||
e401ba9e25 | |||
35db61f1b4 | |||
6c72545fc8 | |||
70385ca670 | |||
a8e72d39f7 | |||
0bf54b3ff6 | |||
db657c2a62 | |||
01964f3926 | |||
bfd6bb0fda | |||
3fc70996e2 | |||
cb0874f15a | |||
9239e37b45 | |||
57d80932a4 | |||
8569970fbe | |||
713e9ad5f4 | |||
59e229d962 | |||
3c5f09cda2 | |||
e42aa2530d | |||
1fd298ac9c | |||
1a73f52541 | |||
27e458f884 | |||
ba3e2a9371 | |||
831e8f8583 | |||
0ff390ed80 | |||
e3b8495431 | |||
da10ba3fea | |||
cc7de853b4 | |||
23d8235197 | |||
37e3d60ade | |||
83a3426dd5 | |||
a2549192ca | |||
9d3a1cab6e | |||
06f8d8f0a3 | |||
fa66b79e2d | |||
81312f5a93 | |||
ad84901f39 | |||
d2385a0e52 | |||
39285fc2d0 | |||
6e491c1466 | |||
84152aa663 | |||
600fc65c2f | |||
40e2733424 | |||
bceb02d760 | |||
aaaaf2681a | |||
3c3ef9bba0 | |||
338f3a981f | |||
a86ae9fa50 | |||
a3c4e8a1bc | |||
6a7c18e8db | |||
672b7a4c3d | |||
bf3fee4481 | |||
a3c8d1d732 | |||
bb03d8c49a | |||
fbd5abe3b6 | |||
5ac390abe9 | |||
766cae2299 | |||
d9828fdc6a | |||
4114ce4a04 | |||
6090630260 | |||
259cfeae17 | |||
ebe15c4711 | |||
75a740a110 | |||
0c085c4f74 | |||
1d819e79db | |||
515b79dcf0 | |||
269e12abb4 | |||
cf5be6ff5a | |||
f140adbc9d | |||
6c31406bb0 | |||
b6e8626908 | |||
64a3a4915a | |||
fd71f24d46 | |||
65b5c6753f | |||
7408bbce37 | |||
0f58978c9f | |||
01ca3fd6b2 | |||
26c366156b | |||
9d8f7b081d | |||
9d8ebb795d | |||
8be98e4cb8 | |||
3c229c9950 | |||
f2263faf7d | |||
39c7cf3e66 | |||
5ee24e5c09 | |||
a34fdc2068 | |||
2c2cd893b8 | |||
a43b0548ed | |||
93e95f56f4 | |||
cb0673b1ec | |||
cd018db945 | |||
50fe67b99b | |||
1dba82aae5 | |||
17c6d64750 | |||
b4c04efa23 | |||
152dd74abf | |||
0985f7f609 | |||
aecf9329bd | |||
b2384605e7 | |||
57ab5ab604 | |||
e493a20301 | |||
0bd5ed937c | |||
6a9b3bc64e | |||
4c1ef3e6a5 | |||
2ea250f954 | |||
5d810980f8 | |||
d51b4e27cc | |||
c01c555309 | |||
ce2e66d9b0 | |||
9550acd61e | |||
d95b5daa6d | |||
56d571c0f0 | |||
dc9a19b9c7 | |||
88a2c7715a | |||
2fa8cb1b73 | |||
5f8a66fdb9 | |||
57320a94f9 | |||
89f045d624 | |||
1a77dea7ed | |||
532a7b90f3 | |||
4e8c200349 | |||
d063d59a91 | |||
90429b787c | |||
7a2ef04ec3 | |||
76a9ea8d3d | |||
0a05a2d060 | |||
a7e2ee3b0c | |||
40efa90dd5 | |||
4ca0a22bfc | |||
20a943b193 | |||
552df8737d | |||
860f622d79 | |||
e76bf5707a | |||
bf37a72f59 | |||
840ad75830 | |||
4c7dd7228f | |||
46a51addad | |||
0a5fe37025 | |||
00bb403497 | |||
11afa8140c | |||
850396e9da | |||
5ee75be49e | |||
879116a20c | |||
e509b1f488 | |||
468ff7037f | |||
df23504ccf | |||
66e3cb8eda | |||
6ddd2389dc | |||
402efb8c50 | |||
7b6eae0ce4 | |||
26ce9725ce | |||
ebfaa18f12 | |||
cc81d41a05 | |||
212176ee5c | |||
a63ec05e41 | |||
0dcb527bf3 | |||
54710f17fc | |||
e58a6593c0 | |||
62132570e1 | |||
9f0b8ba2f8 | |||
adbe0fbcd1 | |||
7896242f57 | |||
4a6722b9e9 | |||
7c9fb5228b | |||
81805b01cc | |||
50824a7245 | |||
6f2953f3a7 | |||
dd3f007582 | |||
a4b2b093fc | |||
0fbf56219f | |||
0acacf7a8e | |||
c84500d914 | |||
a9cfbda858 | |||
33e79e4bb8 | |||
fab389e624 | |||
b1b02d0e32 | |||
0b40194d31 | |||
c2038bec73 | |||
8674d55c8e | |||
c7c0c9e79d | |||
2dff48167c | |||
71d42f64dc | |||
1b4072610a | |||
3826a820bb | |||
625eb376ae | |||
72cbab6514 | |||
c7a7059e26 | |||
550593b208 | |||
f76255fa63 | |||
15a2881083 | |||
37bfb79123 | |||
b62203b1f1 | |||
16136c252a | |||
75864a5125 | |||
a59f53e6da | |||
2ceaccf9ab | |||
036d46c459 | |||
5d3d78a73e | |||
6012e98ae6 | |||
9c0e990568 | |||
6167ed4c9f | |||
988d5405c3 | |||
ad0ea2fab2 | |||
d62c67208f | |||
2da1432e52 | |||
69eefc1425 | |||
27bdb26202 | |||
8b9454eaee | |||
6827bc0624 | |||
1fa24d709d | |||
fa4ea494bf | |||
9f32713093 | |||
380f9bb975 | |||
5bcce97ff0 | |||
825fdb2475 | |||
460bb21c1e | |||
251cef3129 | |||
d81c87af22 | |||
8f58e7208d | |||
cf0b7e26b5 | |||
3a1c3f9656 | |||
035bdd0279 | |||
f7c596beac | |||
ac8817ef34 | |||
372db65604 | |||
4a92635eae | |||
5e140d9a11 | |||
0b53ef9bae | |||
3f79c9ae49 | |||
5d882dc3df | |||
5b4205bdbc | |||
20cf2b3f77 | |||
3c0d2db3bc | |||
9aa65fb600 | |||
4dcb15ef0d | |||
ae6293cb6b | |||
2614771a7c | |||
ba2ebfad4f | |||
51ba738c4b | |||
c8081ed353 | |||
500fc47618 | |||
276edd7cc2 | |||
a9436306ab | |||
21d9afebc3 | |||
ab66162dbe | |||
0aacca3e78 | |||
bdcaa07cc8 | |||
5b684c6deb | |||
5ef8a8b5f0 | |||
10fa824f95 | |||
fccbecf159 | |||
60ef3e3563 | |||
ba845f5218 | |||
5105981e93 | |||
f05a688ac2 | |||
4bc919a912 | |||
25a69ec1b6 | |||
21303bd06a | |||
480d1c9f09 | |||
57f6ce280e | |||
f052d8912b | |||
6c95120023 | |||
24766fb79e | |||
300d3da6ff | |||
d779e18546 | |||
3261d54cd3 | |||
e0ec56abb5 | |||
1056a7167d | |||
b8e1162e2d | |||
4c81e400c4 | |||
a29d7a0475 | |||
d5408c429b | |||
501b07c383 | |||
9dd21a19ff | |||
a8d05cba5a | |||
f5ddfb29f2 | |||
ba228a6b10 | |||
cb6f390fb6 | |||
5675ecead9 | |||
001bb7bbcd | |||
1585bb12cf | |||
26b47c18fd | |||
665fa7f2aa | |||
0068dc30d3 | |||
8f39655fef | |||
b1a4fc03bc | |||
05d20f1044 | |||
66a90b3fb1 | |||
826d9d9fdf | |||
4a9a61f108 | |||
b72d15b56c | |||
8c68992594 | |||
c052028fc3 | |||
c46fbcf345 | |||
06b66f0209 | |||
2de48110bb | |||
87d4452d19 | |||
328fc64ca9 | |||
a6f8327aa2 | |||
d5ab6b41c9 | |||
ffdd0b7de7 | |||
1808eb6eee | |||
438563b505 | |||
92dfcdad57 | |||
c178cfabfa | |||
260e4c955d | |||
0c46f5ce70 | |||
6d67cd07a0 | |||
fb8af53751 | |||
37999f4af7 | |||
3b6ab327c1 |
3
.autogen/check_pr.jq
Normal file
@ -0,0 +1,3 @@
|
||||
.[]
|
||||
.head
|
||||
.label
|
2
.autogen/next_url.jq
Normal file
@ -0,0 +1,2 @@
|
||||
.links
|
||||
.next
|
39
.autogen/patreon.jq
Normal file
@ -0,0 +1,39 @@
|
||||
(
|
||||
.data |
|
||||
map(
|
||||
select(
|
||||
.relationships
|
||||
.currently_entitled_tiers
|
||||
.data[]
|
||||
)
|
||||
) |
|
||||
map(
|
||||
.relationships
|
||||
.user
|
||||
.data
|
||||
.id
|
||||
)
|
||||
) as $data |
|
||||
.included |
|
||||
map(
|
||||
select(
|
||||
.id as $id |
|
||||
$data |
|
||||
contains(
|
||||
[
|
||||
$id
|
||||
]
|
||||
)
|
||||
)
|
||||
) |
|
||||
map(
|
||||
.attributes |
|
||||
[
|
||||
.full_name,
|
||||
.thumb_url,
|
||||
.url
|
||||
] |
|
||||
@tsv
|
||||
) |
|
||||
.[] |
|
||||
@text
|
@ -5,7 +5,7 @@
|
||||
# __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
|
||||
test "$(curl -LSs -w '\n' -- "https://api.github.com/repos/$REPO/pulls?access_token=$__MISSKEY_GITHUB_TOKEN" | jq -r -f check_pr.jq | grep $__MISSKEY_HEAD)" && exit 1
|
||||
cd "$(dirname $0)/.." && \
|
||||
touch null.cache && \
|
||||
rm *.cache && \
|
||||
@ -30,12 +30,12 @@ while :
|
||||
touch patreon.cache && \
|
||||
rm patreon.cache && \
|
||||
cat patreon.raw.cache | \
|
||||
jq -r '(.data|map(select(.relationships.currently_entitled_tiers.data[]))|map(.relationships.user.data.id))as$data|.included|map(select(.id as$id|$data|contains([$id])))|map(.attributes|[.full_name,.thumb_url,.url]|@tsv)|.[]|@text' >> patreon.cache && \
|
||||
jq -r -f patreon.jq >> patreon.cache && \
|
||||
echo '<table><tr>' >> patreon.md.cache && \
|
||||
cat patreon.cache | \
|
||||
awk -F'\t' '{print $2,$1}' | \
|
||||
sed -e 's/ /\\" alt=\\"/' | \
|
||||
xargs -I% echo '<td><img src="%"></td>' >> patreon.md.cache && \
|
||||
xargs -I% echo '<td><img src="%" width="100"></td>' >> patreon.md.cache && \
|
||||
echo '</tr><tr>' >> patreon.md.cache && \
|
||||
cat patreon.cache | \
|
||||
awk -F'\t' '{print $3,$1}' | \
|
||||
@ -43,7 +43,7 @@ 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')"
|
||||
new_url="$(cat patreon.raw.cache | jq -r -f next_url.jq)"
|
||||
test "$new_url" = 'null' && \
|
||||
break || \
|
||||
URL="$url"
|
@ -1,11 +1,5 @@
|
||||
version: 2.1
|
||||
|
||||
general:
|
||||
branches:
|
||||
ignore:
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
|
||||
executors:
|
||||
default:
|
||||
working_directory: /tmp/workspace
|
||||
@ -17,8 +11,20 @@ executors:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: docker:latest
|
||||
alpine:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: alpine:latest
|
||||
|
||||
jobs:
|
||||
ok:
|
||||
executor: alpine
|
||||
steps:
|
||||
- run:
|
||||
name: OK
|
||||
command: |
|
||||
echo -e '\033[0;32mOK\033[0;39m'
|
||||
|
||||
build:
|
||||
executor: default
|
||||
steps:
|
||||
@ -102,7 +108,7 @@ jobs:
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
docker build . | tee docker.log
|
||||
docker build -t misskey/misskey .
|
||||
- when:
|
||||
condition: <<parameters.with_deploy>>
|
||||
steps:
|
||||
@ -111,8 +117,8 @@ jobs:
|
||||
command: |
|
||||
if [ "$DOCKERHUB_USERNAME$DOCKERHUB_PASSWORD" ]
|
||||
then
|
||||
tail -n 1 docker.log | read __Successfully __built tag
|
||||
docker tag $tag misskey/misskey
|
||||
apk update && apk add jq
|
||||
docker tag misskey/misskey misskey/misskey:$(cat package.json | jq -r .version)
|
||||
docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD
|
||||
docker push misskey/misskey
|
||||
else
|
||||
@ -123,10 +129,27 @@ workflows:
|
||||
version: 2
|
||||
build-and-test:
|
||||
jobs:
|
||||
- build
|
||||
- ok:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- build:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- test:
|
||||
requires:
|
||||
- build
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
# - master
|
||||
- l10n_develop
|
||||
- imgbot
|
||||
- test:
|
||||
without_redis: "true"
|
||||
requires:
|
||||
|
@ -1,6 +1,3 @@
|
||||
maintainer:
|
||||
name: syuilo
|
||||
url: 'https://syuilo.com'
|
||||
url: 'http://misskey.local'
|
||||
port: 80
|
||||
mongodb:
|
||||
|
@ -1,6 +1,3 @@
|
||||
maintainer:
|
||||
name: syuilo
|
||||
url: 'https://syuilo.com'
|
||||
url: 'http://misskey.local'
|
||||
port: 80
|
||||
mongodb:
|
||||
|
@ -1,10 +1,3 @@
|
||||
maintainer:
|
||||
name: example-maitainer-name # Your name
|
||||
url: http://example.com/ # Your contact (http or mailto)
|
||||
repository_url: https://github.com/syuilo/misskey # Repository URL
|
||||
feedback_url: https://github.com/syuilo/misskey/issues # Feedback URL (e.g. github issue)
|
||||
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
url: https://example.tld/
|
||||
|
||||
@ -115,44 +108,5 @@ autoAdmin: true
|
||||
# port: 9200
|
||||
# pass: null
|
||||
|
||||
# reCAPTCHA
|
||||
#recaptcha:
|
||||
# site_key: example-site-key
|
||||
# secret_key: example-secret-key
|
||||
|
||||
# ServiceWorker
|
||||
#sw:
|
||||
# # Public key of VAPID
|
||||
# public_key: example-sw-public-key
|
||||
#
|
||||
# # Private key of VAPID
|
||||
# private_key: example-sw-private-key
|
||||
|
||||
# Twitter integration
|
||||
# You need to set the oauth callback url as : https://<your-misskey-instance>/api/tw/cb
|
||||
#twitter:
|
||||
# consumer_key: example-twitter-consumer-key
|
||||
# consumer_secret: example-twitter-consumer-secret-key
|
||||
|
||||
# GitHub integration
|
||||
# You need to set the oauth callback url as : https://<your-misskey-instance>/api/gh/cb
|
||||
#github:
|
||||
# client_id: example-github-client-id
|
||||
# client_secret: example-github-client-secret
|
||||
|
||||
# Ghost
|
||||
# Ghost account is an account used for the purpose of delegating
|
||||
# followers when putting users in the list.
|
||||
#ghost: user-id-of-your-ghost-account
|
||||
|
||||
# Clustering
|
||||
#clusterLimit: 1
|
||||
|
||||
# Summaly proxy
|
||||
#summalyProxy: "http://example.com"
|
||||
|
||||
# User recommendation
|
||||
#user_recommendation:
|
||||
# external: true
|
||||
# engine: http://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}
|
||||
# timeout: 300000
|
||||
|
13
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# Summary
|
||||
|
||||
<!--
|
||||
-
|
||||
- * Please describe your changes here *
|
||||
-
|
||||
- If you are going to resolve some issue, please add this context.
|
||||
- Resolve #ISSUE_NUMBER
|
||||
-
|
||||
- If you are going to fix some bug issue, please add this context.
|
||||
- Fix #ISSUE_NUMBER
|
||||
-
|
||||
-->
|
1
.gitignore
vendored
@ -17,3 +17,4 @@ api-docs.json
|
||||
/mongo
|
||||
/elasticsearch
|
||||
*.code-workspace
|
||||
yarn.lock
|
||||
|
159
CHANGELOG.md
@ -1,9 +1,164 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
破壊的変更のみ記載。
|
||||
10.75.0
|
||||
----------
|
||||
* ダイレクトを非公開のように使えるように
|
||||
* モデレーターを凍結できないように
|
||||
* モデレーター登録を解除できるように
|
||||
* NSFWなメディアをユーザーページなどで表示しないように
|
||||
* 管理画面でユーザーを状態でフィルタできるように
|
||||
* 管理者がサインイン履歴を参照できるツール
|
||||
* Renote数を再度表示するように
|
||||
* インスタンス情報ページの追加
|
||||
* テーマの調整
|
||||
* UIの改善
|
||||
|
||||
This document describes breaking changes only.
|
||||
10.74.0
|
||||
----------
|
||||
* Pleromaとのフェデレーションを修正
|
||||
* インスタンスのキャラクター画像を設定できるように
|
||||
* Catモードの朝鮮語対応
|
||||
* CWが付いた投稿に返信する際、そのCWを引き継ぐように
|
||||
* 投稿のソースをクリップボードにコピーできるように
|
||||
* i/notifications API で取得する通知の種別を配列で指定できるように
|
||||
* パフォーマンスの改善
|
||||
* バグ修正
|
||||
|
||||
10.73.0
|
||||
-------
|
||||
* テーマの強化
|
||||
* line thiknessの設定はデバイスに保存するように
|
||||
|
||||
10.72.0
|
||||
-------
|
||||
* いくつかのテーマの追加
|
||||
* デザインの調整
|
||||
* バグ修正
|
||||
* など
|
||||
|
||||
10.71.0
|
||||
-------
|
||||
* いくつかのテーマの追加
|
||||
|
||||
10.70.1
|
||||
-------
|
||||
* notes/mentions にミュートを適用するように
|
||||
* Add id to return of users/relation
|
||||
* デザインの調整
|
||||
|
||||
10.70.0
|
||||
-------
|
||||
* フォローしているユーザーからのフォローを自動承認するオプション
|
||||
* 「非公開」の公開範囲を廃止
|
||||
* Renote数の表示を廃止
|
||||
* 投稿のフィルタリングを強化
|
||||
* デザインの調整
|
||||
|
||||
10.69.0
|
||||
-------
|
||||
* 通知の管理を強化
|
||||
* ユーザビリティの強化
|
||||
* デザインの調整
|
||||
|
||||
10.68.0
|
||||
-------
|
||||
* 特定ユーザーにメンション付きで新規投稿ができるボタンを追加
|
||||
* 自分の投稿にリアクションできないように
|
||||
* 数式に文法エラーがあるとき、数式のソースをそのまま表示するように
|
||||
* CWボタンにアンケートの有無を表記するように
|
||||
* デスクトップ版で設定を新しいタブで開くように
|
||||
* モバイル版で検索ができない問題を修正
|
||||
* i18nの修正
|
||||
|
||||
10.67.0
|
||||
-------
|
||||
* トークのメッセージを削除できるように
|
||||
* リアクションを取り消せるように
|
||||
* Misskey以外のソフトウェアからの「Like」アクティビティをプリンではなく「いいね」として扱うように
|
||||
* i18nの修正
|
||||
* バグ修正
|
||||
* など
|
||||
|
||||
10.66.2
|
||||
-------
|
||||
* i18nの修正
|
||||
* ドライブのファイル一覧取得APIでファイルサイズによるソートが機能していなかった問題を修正
|
||||
* リモートユーザーの更新時に、各ピン留め投稿の取得失敗は無視するように
|
||||
* リモートMisskeyユーザーの情報が登録/更新出来なくなっていたのを修正
|
||||
* メンションのリンク先URLに余計な@がプリフィクスされていたのを修正
|
||||
* ダイレクトでリプライする際、リプライ先のユーザーは自動的に公開先として追加するように
|
||||
* ダイレクトでメンションでもユーザーを指定できるように
|
||||
|
||||
10.66.1
|
||||
-------
|
||||
* ActivityPubのsharedInboxに関して修正
|
||||
* MFMでのカッコの判定を改善
|
||||
* バグ修正
|
||||
|
||||
10.66.0
|
||||
-------
|
||||
* ユーザーごとのRSSフィードを提供するように
|
||||
* リストのユーザーがすべて表示できない問題を修正
|
||||
* デザインの調整
|
||||
* パフォーマンスの改善
|
||||
|
||||
10.65.0
|
||||
-------
|
||||
* 検索で投稿やユーザーのURLを入力した際にそれをフェッチして表示するように
|
||||
* リストのリネームと削除をできるように
|
||||
* リストからユーザーを削除できるように
|
||||
* リモートの絵文字を更新するように
|
||||
* ActivityPubのための絵文字エンドポイントを実装
|
||||
* 管理者がドライブのファイルのNSFWを設定できるように
|
||||
* ServiceWorkerの設定を管理者ページで行えるように
|
||||
* メンションの判定を改善
|
||||
* リモートの投稿を引用した際にオリジナルのURLを挿入するように
|
||||
* クライアントのパフォーマンス改善
|
||||
* CWの内容がタブタイトルに表示されるのを修正
|
||||
* アカウントを作成したときにログイン状態にならない問題を修正
|
||||
* 時計の針にテーマカラーが適用されていなかったのを修正
|
||||
* 一部の日時の表示が日本語で表示されていたのを修正
|
||||
* プロフィールの写真欄に画像以外のファイルが含まれる問題を修正
|
||||
* メンションが含まれる投稿に返信する際、フォームに予めそれらのメンションがセットされた状態にならない問題を修正
|
||||
* デッキのTLにUIの動きを減らすオプションが適用されていなかったのを修正
|
||||
* ログイン画面のタイムラインに隠した投稿が表示される問題を修正
|
||||
* サジェストが複数開いてしまう問題を修正
|
||||
* APから来たタグに登録時の長さ制限が適用されていなかったのを修正
|
||||
|
||||
10.64.2
|
||||
-------
|
||||
* UIの動きを減らすオプションが一部のアニメーションに適用されなかったのを修正
|
||||
|
||||
10.64.1
|
||||
-------
|
||||
* レートリミットの調整
|
||||
* アニメーションの調整
|
||||
|
||||
10.64.0
|
||||
-------
|
||||
* いくつかのアニメーションを追加
|
||||
* OGP向けにインスタンスのバナー画像を提供するように
|
||||
* 管理者ページでドライブのファイルを表示できるように
|
||||
* ユーザビリティの強化
|
||||
* バグ修正
|
||||
|
||||
10.63.1
|
||||
-------
|
||||
* メンションの表示を改善
|
||||
* バグ修正
|
||||
|
||||
10.63.0
|
||||
-------
|
||||
* ActivityPubのユーザーフィールドをユーザーページに表示
|
||||
* 404ページの実装
|
||||
* パフォーマンスの向上
|
||||
* バグ修正
|
||||
|
||||
10.62.2
|
||||
-------
|
||||
* バグ修正
|
||||
* ユーザビリティの向上
|
||||
|
||||
10.0.0
|
||||
------
|
||||
|
@ -6,14 +6,14 @@ Feature suggestions and bug reports are filed in https://github.com/syuilo/missk
|
||||
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.
|
||||
|
||||
## Internationalization (i18n)
|
||||
Please see [Translation guide](./docs/translate.en.md).
|
||||
|
||||
## Localization (l10n)
|
||||
Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
|
||||
|
||||

|
||||
|
||||
## Internationalization (i18n)
|
||||
Misskey uses [vue-i18n](https://github.com/kazupon/vue-i18n).
|
||||
|
||||
## Documentation
|
||||
* Documents for contributors are located in `/docs`.
|
||||
* Documents for instance admins are located in `/docs`.
|
||||
@ -25,3 +25,16 @@ Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
|
||||
## Continuous integration
|
||||
Misskey uses CircleCI for automated test.
|
||||
Configuration files are located in `/.circleci`.
|
||||
|
||||
## Glossary
|
||||
### AP
|
||||
Stands for _**A**ctivity**P**ub_.
|
||||
|
||||
### MFM
|
||||
Stands for _**M**isskey **F**lavored **M**arkdown_.
|
||||
|
||||
### Mk
|
||||
Stands for _**M**iss**k**ey_.
|
||||
|
||||
### SW
|
||||
Stands for _**S**ervice**W**orker_.
|
||||
|
15
Dockerfile
@ -1,26 +1,27 @@
|
||||
FROM alpine:3.8 AS base
|
||||
FROM node:11-alpine AS base
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN apk add --no-cache nodejs nodejs-npm zlib
|
||||
RUN npm i -g npm@latest
|
||||
|
||||
WORKDIR /misskey
|
||||
|
||||
FROM base AS builder
|
||||
|
||||
RUN unlink /usr/bin/free
|
||||
RUN apk add --no-cache \
|
||||
gcc \
|
||||
g++ \
|
||||
libc-dev \
|
||||
python \
|
||||
autoconf \
|
||||
automake \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
pkgconfig \
|
||||
libtool \
|
||||
procps \
|
||||
python \
|
||||
zlib-dev
|
||||
RUN npm i -g node-gyp
|
||||
|
||||
|
82
README.md
@ -3,16 +3,18 @@
|
||||
[](https://misskey.xyz/)
|
||||
================================================================
|
||||
|
||||
[](https://circleci.com/gh/syuilo/misskey)
|
||||
[![][dependencies-badge]][dependencies-link]
|
||||
[](http://makeapullrequest.com)
|
||||
[](https://circleci.com/gh/syuilo/misskey)
|
||||
[](https://david-dm.org/syuilo/misskey)
|
||||
[](http://makeapullrequest.com)
|
||||
|
||||
**Sophisticated microblogging platform, evolving forever.**
|
||||
|
||||
[Misskey](https://misskey.xyz) is a decentralized microblogging platform born on Earth.
|
||||
<p align="justify">
|
||||
<a href="https://misskey.xyz">Misskey</a> is a decentralized microblogging platform born on Earth.
|
||||
Since it exists within the Fediverse (a universe where various social media platforms are organized),
|
||||
it is mutually linked with other social media platforms.
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? [Find instance!](https://joinmisskey.github.io/)
|
||||
Why don't you take a short break from the hustle and bustle of the city, and dive into a new Internet? <a href="https://joinmisskey.github.io/">Find instance!</a>
|
||||
</p>
|
||||
|
||||
<a href="https://www.patreon.com/syuilo"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" alt="Become a Patron!" width="160" /></a>
|
||||
|
||||
@ -24,8 +26,8 @@ Why don't you take a short break from the hustle and bustle of the city, and div
|
||||
<img src="/assets/about/post.png" align="left" height="200px"/>
|
||||
|
||||
<h3 align="left">Posting</h3>
|
||||
<p align="left">
|
||||
Just post your idea, hot topics and anything you want to share. You may want to decorate your words, attach your favorite pictures, send files including movies and create a poll - those are the things you can do on Misskey!
|
||||
<p align="justify">
|
||||
Just post your idea, hot topics and anything you want to share. You may decorate your words, attach your favorite pictures or movies, and create a poll - those are all supported in Misskey!
|
||||
</p>
|
||||
|
||||
---
|
||||
@ -33,8 +35,8 @@ Just post your idea, hot topics and anything you want to share. You may want to
|
||||
<img src="/assets/about/reaction.png" align="right" height="200px"/>
|
||||
|
||||
<h3 align="right">Reactions</h3>
|
||||
<p align="right">
|
||||
Easiest way to tell your emotions. Misskey allows you to add various type of reactions to other’s post. The emotional experience on Misskey will never be on other SNSs which only able to push “likes”.
|
||||
<p align="justify">
|
||||
The simplest way to tell your emotions to the posts. You can choose the best reaction from various reactions. Reactions on Misskey has much more expressive than other social media which only allows pushing “likes”.
|
||||
</p>
|
||||
|
||||
---
|
||||
@ -42,8 +44,8 @@ Easiest way to tell your emotions. Misskey allows you to add various type of rea
|
||||
<img src="/assets/about/ui.png" align="left" height="200px"/>
|
||||
|
||||
<h3 align="left">Interface</h3>
|
||||
<p align="left">
|
||||
Highly customizable UI for your taste. We understand no UI fits for everyone. You can edit layouts of your timeline, place selectable widgets you can easily move and create your unique home as this place will be your home.
|
||||
<p align="justify">
|
||||
Highly customizable UI for your taste. We understand no UI fits for everyone. Make your graceful home by editing, adjusting layouts of timeline, and placing widgets.
|
||||
</p>
|
||||
|
||||
---
|
||||
@ -51,13 +53,13 @@ Highly customizable UI for your taste. We understand no UI fits for everyone. Yo
|
||||
<img src="/assets/about/drive.png" align="right" width="300px"/>
|
||||
|
||||
<h3 align="right">Misskey Drive</h3>
|
||||
<p align="right">
|
||||
Wanna post a picture you have already uploaded? Wish to organize, name and create a folder for your uploaded files? Misskey Drive is the best solution for you. Very easy to share your files online.
|
||||
<p align="justify">
|
||||
Organized uploaded files. Wanna post a picture you have already uploaded? Wish to create a folder for your files? Misskey Drive is the best solution for you.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
and more! You can see it with your own eyes at [misskey.xyz](https://misskey.xyz) or [other instances](https://joinmisskey.github.io/).
|
||||
and more! Now it's time to experience the world with your own eyes at [misskey.xyz](https://misskey.xyz) or [other instances](https://joinmisskey.github.io/).
|
||||
|
||||
:package: Create your own instance
|
||||
----------------------------------------------------------------
|
||||
@ -71,60 +73,62 @@ Please see [Contribution guide](./CONTRIBUTING.md).
|
||||
----------------------------------------------------------------
|
||||
<!-- PATREON_START -->
|
||||
<table><tr>
|
||||
<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/12913507/f7181eacafe8469a93033d85f5969c29/2?token-time=2145916800&token-hash=mgPdX9TqZxEg4TTPuc477dxhIgYk9246qafjWZEqZ7g%3D" alt="Melilot"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=0eu4-m1gTWA9PhptVZt6rdKcusqcD7RB87rJT23VVFI%3D" alt="べすれい"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=GgJ_NmUB6_nnRNLVGUWjV-WX91On7BOu59LKncYV9fE%3D" alt="gutfuckllc"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1?token-time=2145916800&token-hash=I8lJVM8LeW6TSo5W6uIIRZ42cw83zp1wK_FsbzY0mcQ%3D" alt="mydarkstar"></td>
|
||||
<td><img src="https://c8.patreon.com/2/100/12718187" alt="Peter G."></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12190916/fb7fa7983c14425f890369535b1506a4/1?token-time=2145916800&token-hash=WeuDzzz24cRXJogyIkU-mxARqkdyms-rcZKbO-GpGjw%3D" alt="weep" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=prtYqPOiSHBulhM7NU0VzMaWx39-9ntdq25b6kafDNA%3D" alt="negao" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/2?token-time=2145916800&token-hash=djaJ9cwy9uwTiF9UFtxYQdS8Nw7BhyfaREzZUbErN-0%3D" alt="Melilot" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/3?token-time=2145916800&token-hash=LtV2lRi3L2jOWMLwccr9qWYfPrFlzIo2jYZHKzHEb6k%3D" alt="Xeltica" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=Ch3iF81ZGP0LMo894Y9ajpLisgtE91SnxtZE7fxsgrM%3D" alt="べすれい" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=1FlxS9MEgmNGH_RHUVHbO5hIXB5I1z0lvA33CTvYvjA%3D" alt="gutfuckllc" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/weepjp">weep</a></td>
|
||||
<td><a href="https://www.patreon.com/negao">negao</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
|
||||
<td><a href="https://www.patreon.com/Xeltica">Xeltica</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/mydarkstar">mydarkstar</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=zwSu01tOtn5xTUucDZHuPsCxF2HBEMVs9ROJKTlEV_o%3D" alt="nemu"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3?token-time=2145916800&token-hash=qsdn0-e6yLaLI6hUX9JAkyTR6a5UdnSp7T1foniBvGQ%3D" alt="YUKIMOCHI"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/8241184/39e18850e87a449e9c9a71acb3310ebd/2?token-time=2145916800&token-hash=iUXOQzRyJDv3PJxwS7Mjwg1459dzh2trOq6NFtXu_OM%3D" alt="Acid Chicken"></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/10789744/97175095d8f04c0f86225ff47cb98d40/1?token-time=2145916800&token-hash=P4BIzCX2I1CkEP66ottfhsC8Wr6BUSamjA-vq3pLqFI%3D" alt="Naoki Hirayama"></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/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=tB1e_r8RlZ5sFL0KV_e8dugapxatNBRK1Z3h67TO1g8%3D" alt="Gargron"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1?token-time=2145916800&token-hash=VZUtwrjQa8Jml4twCjHYQQZ64wHEY4oIlGl7Kc-VYUQ%3D" alt="Nokotaro Takeda"></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/eyJ3IjoyMDB9/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1?token-time=2145916800&token-hash=0xgcpqvFDqRcV_YIEhcPNVH7gs9sLg_BBnTJXCkN4ao%3D" alt="mydarkstar" width="100"></td>
|
||||
<td><img src="https://c8.patreon.com/2/200/12718187" alt="Peter G." width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=2PsbFNw0tnubZzgSXD01R6hIgncfiElG7H7HX2Y3dyo%3D" alt="nemu" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3?token-time=2145916800&token-hash=9JtETp0X8gI280Ne1E8bxn6j4Lw5o2k4mJkICx97V_k%3D" alt="YUKIMOCHI" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/8241184/39e18850e87a449e9c9a71acb3310ebd/2?token-time=2145916800&token-hash=zrInDotuEIFslKphuSiCqr3M-r-rveTXjVKWr-VK6M0%3D" alt="Acid Chicken" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=5T8XcaAf9Zyzfg3QubR06s_kJZkArVEM2dwObrBVAU4%3D" alt="Hiratake" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/10789744/97175095d8f04c0f86225ff47cb98d40/1?token-time=2145916800&token-hash=ubVARikVOg3v7NW6LDhtG-ClE1LTU3I2TJ3js2-5xDs%3D" alt="Naoki Hirayama" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
|
||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
|
||||
<td><a href="https://www.patreon.com/acid_chicken">Acid Chicken</a></td>
|
||||
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
|
||||
<td><a href="https://www.patreon.com/spinlock">Naoki Hirayama</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=Ksk_2l3gjPDbnzMUOCSW1E-hdPJsNs2tSR4_RAakRK8%3D" alt="dansup" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=CXe9AqlZy9AsYfiWd3OBYVOzvODoN47Litz0Tu4BFpU%3D" alt="Gargron" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1?token-time=2145916800&token-hash=xhR1n6NAAyEb-IUXLD6_dshkFa3mefU5ZZuk1L8qKTs%3D" alt="Nokotaro Takeda" width="100"></td>
|
||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1?token-time=2145916800&token-hash=uR-48MQ0A4j0irQSrCAQZJ-sJUSs_Fkihlg3-l59b7c%3D" alt="Takashi Shibuya" width="100"></td>
|
||||
</tr><tr>
|
||||
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
|
||||
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
|
||||
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
|
||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
|
||||
</tr></table>
|
||||
<table><tr>
|
||||
</tr><tr>
|
||||
</tr></table>
|
||||
|
||||
**Last updated:** Wed, 31 Oct 2018 23:21:06 UTC
|
||||
**Last updated:** Sun, 06 Jan 2019 21:53:06 UTC
|
||||
<!-- PATREON_END -->
|
||||
|
||||
:four_leaf_clover: Copyright
|
||||
----------------------------------------------------------------
|
||||
> Copyright (c) 2014-2018 syuilo
|
||||
> Copyright (c) 2014-2019 syuilo
|
||||
|
||||
Misskey is an open-source software licensed under the [GNU AGPLv3](LICENSE).
|
||||
|
||||
[![][agpl-3.0-badge]][AGPL-3.0]
|
||||
|
||||
[agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
[agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square
|
||||
[dependencies-link]: https://david-dm.org/syuilo/misskey
|
||||
[dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square
|
||||
[agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=for-the-badge
|
||||
|
||||
[backer-url]: #backers
|
||||
[backer-badge]: https://opencollective.com/misskey/backers/badge.svg
|
||||
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 317 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 200 KiB |
BIN
assets/ai.png
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 235 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@ -1,108 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 135.46667 135.46667"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
sodipodi:docname="favicon.svg"
|
||||
inkscape:export-filename="C:\Users\syuilo\projects\misskey\assets\favicon\16.png"
|
||||
inkscape:export-xdpi="3"
|
||||
inkscape:export-ydpi="3">
|
||||
version="1.1"
|
||||
viewBox="0 0 135.46667 135.46667"
|
||||
height="512"
|
||||
width="512">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect5115"
|
||||
is_visible="true"
|
||||
steps="1"
|
||||
threshold="0.000408163"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false"
|
||||
simplifyindividualpaths="false"
|
||||
simplifyJustCoalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect5111"
|
||||
is_visible="true"
|
||||
steps="1"
|
||||
threshold="0.000408163"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false"
|
||||
simplifyindividualpaths="false"
|
||||
simplifyJustCoalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect5104"
|
||||
is_visible="true"
|
||||
steps="1"
|
||||
threshold="0.000408163"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false"
|
||||
simplifyindividualpaths="false"
|
||||
simplifyJustCoalesce="false" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="15.466544"
|
||||
inkscape:cy="235.92965"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g4502"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="false"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1027"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="1072"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
objecttolerance="1"
|
||||
guidetolerance="1"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-others="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4504"
|
||||
spacingx="4.2333334"
|
||||
spacingy="4.2333334"
|
||||
empcolor="#ff3fff"
|
||||
empopacity="0.25098039"
|
||||
empspacing="4" />
|
||||
</sodipodi:namedview>
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
@ -116,32 +25,27 @@
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="レイヤー 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-30.809093,-111.78601)">
|
||||
style="fill:#2fa3bc;fill-opacity:1"
|
||||
transform="translate(-30.809093,-111.78601)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g4502"
|
||||
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)">
|
||||
style="fill:#2fa3bc;fill-opacity:1"
|
||||
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"
|
||||
id="g4502">
|
||||
<g
|
||||
style="fill:#2fa1bb;fill-opacity:1"
|
||||
id="g5125">
|
||||
id="g5125"
|
||||
transform="translate(-1.3333333e-6,-1.3439941e-6)"
|
||||
style="fill:#2fa3bc;fill-opacity:1">
|
||||
<g
|
||||
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"
|
||||
aria-label="Mi"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#2fa3bc;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text4489"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#2fa1bb;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
aria-label="Mi">
|
||||
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)">
|
||||
<path
|
||||
sodipodi:nodetypes="zccssscssccscczzzccsccsscscsccz"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5210"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa1bb;fill-opacity:1;stroke-width:0.28950602px"
|
||||
d="m 75.196381,231.17126 c -5.855419,0.0202 -10.885068,-3.50766 -13.2572,-7.61584 -1.266603,-1.79454 -3.772419,-2.43291 -3.807919,0 v 11.2332 c 0,4.51309 -1.645397,8.41504 -4.936191,11.70583 -3.196772,3.19677 -7.098714,4.79516 -11.705826,4.79516 -4.513089,0 -8.415031,-1.59839 -11.705825,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -61.7729 c 0,-3.47884 0.987238,-6.6286 2.961715,-9.44928 2.068499,-2.91471 4.701135,-4.9362 7.897906,-6.06447 1.786431,-0.65816 3.666885,-0.98724 5.641362,-0.98724 5.077225,0 9.308247,1.97448 12.693064,5.92343 1.786431,1.97448 2.820681,3.00873 3.102749,3.10275 0,0 13.408119,16.21319 13.78421,16.49526 0.376091,0.28206 1.480789,2.43848 4.127113,2.43848 2.646324,0 3.89218,-2.15642 4.26827,-2.43848 0.376091,-0.28207 13.784088,-16.49526 13.784088,-16.49526 0.09402,0.094 1.081261,-0.94022 2.961715,-3.10275 3.478837,-3.94895 7.756866,-5.92343 12.834096,-5.92343 1.88045,0 3.76091,0.32908 5.64136,0.98724 3.19677,1.12827 5.7824,3.14976 7.75688,6.06447 2.06849,2.82068 3.10274,5.97044 3.10274,9.44928 v 61.7729 c 0,4.51309 -1.6454,8.41504 -4.93619,11.70583 -3.19677,3.19677 -7.09871,4.79516 -11.70582,4.79516 -4.51309,0 -8.41504,-1.59839 -11.705828,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -11.2332 c -0.277898,-3.06563 -2.987588,-1.13379 -3.948953,0 -2.538613,4.70114 -7.401781,7.59567 -13.2572,7.61584 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5212"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa1bb;fill-opacity:1;stroke-width:0.28950602px"
|
||||
d="m 145.83461,185.00361 q -5.92343,0 -10.15445,-4.08999 -4.08999,-4.23102 -4.08999,-10.15445 0,-5.92343 4.08999,-10.01342 4.23102,-4.23102 10.15445,-4.23102 5.92343,0 10.15445,4.23102 4.23102,4.08999 4.23102,10.01342 0,5.92343 -4.23102,10.15445 -4.23102,4.08999 -10.15445,4.08999 z m 0.14103,2.82068 q 5.92343,0 10.01342,4.23102 4.23102,4.23102 4.23102,10.15445 v 34.83541 q 0,5.92343 -4.23102,10.15445 -4.08999,4.08999 -10.01342,4.08999 -5.92343,0 -10.15445,-4.08999 -4.23102,-4.23102 -4.23102,-10.15445 v -34.83541 q 0,-5.92343 4.23102,-10.15445 4.23102,-4.23102 10.15445,-4.23102 z" />
|
||||
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
|
||||
d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa3bc;fill-opacity:1;stroke-width:1.09609616px" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 430 B |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 671 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1015 B |
129
assets/mi.svg
@ -1,108 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 135.46667 135.46667"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
sodipodi:docname="mi.svg"
|
||||
inkscape:export-filename="C:\Users\syuilo\projects\misskey\assets\favicon\32.png"
|
||||
inkscape:export-xdpi="6"
|
||||
inkscape:export-ydpi="6">
|
||||
version="1.1"
|
||||
viewBox="0 0 135.46667 135.46667"
|
||||
height="512"
|
||||
width="512">
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect5115"
|
||||
is_visible="true"
|
||||
steps="1"
|
||||
threshold="0.000408163"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false"
|
||||
simplifyindividualpaths="false"
|
||||
simplifyJustCoalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect5111"
|
||||
is_visible="true"
|
||||
steps="1"
|
||||
threshold="0.000408163"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false"
|
||||
simplifyindividualpaths="false"
|
||||
simplifyJustCoalesce="false" />
|
||||
<inkscape:path-effect
|
||||
effect="simplify"
|
||||
id="path-effect5104"
|
||||
is_visible="true"
|
||||
steps="1"
|
||||
threshold="0.000408163"
|
||||
smooth_angles="360"
|
||||
helper_size="0"
|
||||
simplify_individual_paths="false"
|
||||
simplify_just_coalesce="false"
|
||||
simplifyindividualpaths="false"
|
||||
simplifyJustCoalesce="false" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="232.39583"
|
||||
inkscape:cy="251.50613"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g4502"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="false"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-center="true"
|
||||
inkscape:snap-page="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1027"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="1072"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
objecttolerance="1"
|
||||
guidetolerance="1"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-others="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4504"
|
||||
spacingx="4.2333334"
|
||||
spacingy="4.2333334"
|
||||
empcolor="#ff3fff"
|
||||
empopacity="0.25098039"
|
||||
empspacing="4" />
|
||||
</sodipodi:namedview>
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
@ -111,32 +20,30 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="レイヤー 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-30.809093,-111.78601)">
|
||||
transform="translate(-30.809093,-111.78601)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g4502"
|
||||
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)">
|
||||
transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"
|
||||
id="g4502">
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="g5125"
|
||||
transform="translate(-1.3333333e-6,-1.3439941e-6)"
|
||||
id="g5125">
|
||||
style="fill:#000000;fill-opacity:1">
|
||||
<g
|
||||
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"
|
||||
id="text4489"
|
||||
aria-label="Mi"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
aria-label="Mi">
|
||||
id="text4489"
|
||||
transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)">
|
||||
<path
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#000000;fill-opacity:1;stroke-width:1.09609616px"
|
||||
d="M 62.474609 76.585938 C 54.999059 76.585938 47.878825 77.832365 41.115234 80.324219 C 29.011968 84.595952 19.044417 92.249798 11.212891 103.28516 C 3.7373405 113.96451 0 125.88934 0 139.06055 L 0 372.93945 C 0 390.02642 6.0510264 404.79858 18.154297 417.25781 C 30.613543 429.36108 45.387643 435.41406 62.474609 435.41406 C 79.917556 435.41406 94.689698 429.36108 106.79297 417.25781 C 119.25222 404.79858 125.48242 390.02642 125.48242 372.93945 L 125.48242 330.4082 C 125.61683 321.19698 135.10492 323.61391 139.90039 330.4082 C 148.8815 345.96215 167.92265 359.32062 190.0918 359.24414 C 212.26095 359.16778 230.67374 348.20715 240.28516 330.4082 C 243.92497 326.11557 254.18418 318.80145 255.23633 330.4082 L 255.23633 372.93945 C 255.23633 390.02642 261.28735 404.79858 273.39062 417.25781 C 285.84985 429.36108 300.62397 435.41406 317.71094 435.41406 C 335.15388 435.41406 349.92603 429.36108 362.0293 417.25781 C 374.48853 404.79858 380.71875 390.02642 380.71875 372.93945 L 380.71875 139.06055 C 380.71875 125.88934 376.80415 113.96451 368.97266 103.28516 C 361.49709 92.249798 351.70678 84.595952 339.60352 80.324219 C 332.48396 77.832365 325.3637 76.585938 318.24414 76.585938 C 299.02128 76.585938 282.82549 84.062587 269.6543 99.013672 C 262.53473 107.20121 258.79542 111.11761 258.43945 110.76172 C 258.43945 110.76172 207.67587 172.14495 206.25195 173.21289 C 204.82804 174.2808 200.11102 182.44531 190.0918 182.44531 C 180.07257 182.44531 175.89071 174.2808 174.4668 173.21289 C 173.04288 172.14495 122.2793 110.76172 122.2793 110.76172 C 121.21136 110.40575 117.29484 106.48923 110.53125 99.013672 C 97.716024 84.062587 81.697447 76.585938 62.474609 76.585938 z M 457.53516 76.585938 C 442.58406 76.585937 429.7692 81.926117 419.08984 92.605469 C 408.76646 102.92885 403.60547 115.56648 403.60547 130.51758 C 403.60547 145.46868 408.76646 158.28354 419.08984 168.96289 C 429.7692 179.28627 442.58406 184.44922 457.53516 184.44922 C 472.48625 184.44922 485.30112 179.28627 495.98047 168.96289 C 506.65982 158.28354 512 145.46868 512 130.51758 C 512 115.56648 506.65982 102.92885 495.98047 92.605469 C 485.30112 81.926117 472.48625 76.585938 457.53516 76.585938 z M 458.06836 195.12695 C 443.11726 195.12695 430.3024 200.46713 419.62305 211.14648 C 408.94369 221.82584 403.60547 234.6407 403.60547 249.5918 L 403.60547 381.48242 C 403.60547 396.43352 408.94369 409.24838 419.62305 419.92773 C 430.3024 430.25112 443.11726 435.41406 458.06836 435.41406 C 473.01946 435.41406 485.65709 430.25112 495.98047 419.92773 C 506.65982 409.24838 512 396.43352 512 381.48242 L 512 249.5918 C 512 234.6407 506.65982 221.82584 495.98047 211.14648 C 485.65709 200.46713 473.01946 195.12695 458.06836 195.12695 z "
|
||||
id="path5210"
|
||||
transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)"
|
||||
id="path5210" />
|
||||
d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#000000;fill-opacity:1;stroke-width:1.09609616px" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 4.1 KiB |
BIN
assets/title.png
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
@ -1,29 +0,0 @@
|
||||
const mongo = require('mongodb');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const User = require('../built/models/user').default;
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
const user = args[0];
|
||||
|
||||
const q = user.startsWith('@') ? {
|
||||
username: user.split('@')[1],
|
||||
host: user.split('@')[2] || null
|
||||
} : { _id: new mongo.ObjectID(user) };
|
||||
|
||||
console.log(`Resetting password for ${user}...`);
|
||||
|
||||
const passwd = 'yo';
|
||||
|
||||
// Generate hash of password
|
||||
const hash = bcrypt.hashSync(passwd);
|
||||
|
||||
User.update(q, {
|
||||
$set: {
|
||||
password: hash
|
||||
}
|
||||
}).then(() => {
|
||||
console.log(`Password of ${user} is now '${passwd}'`);
|
||||
}, e => {
|
||||
console.error(e);
|
||||
});
|
@ -1,23 +0,0 @@
|
||||
const mongo = require('mongodb');
|
||||
const User = require('../built/models/user').default;
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
const user = args[0];
|
||||
|
||||
const q = user.startsWith('@') ? {
|
||||
username: user.split('@')[1],
|
||||
host: user.split('@')[2] || null
|
||||
} : { _id: new mongo.ObjectID(user) };
|
||||
|
||||
console.log(`Suspending ${user}...`);
|
||||
|
||||
User.update(q, {
|
||||
$set: {
|
||||
isSuspended: true
|
||||
}
|
||||
}).then(() => {
|
||||
console.log(`Suspended ${user}`);
|
||||
}, e => {
|
||||
console.error(e);
|
||||
});
|
@ -1,12 +0,0 @@
|
||||
const updatePerson = require('../built/remote/activitypub/models/person').updatePerson;
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const user = args[0];
|
||||
|
||||
console.log(`Updating ${user}...`);
|
||||
|
||||
updatePerson(user).then(() => {
|
||||
console.log(`Updated ${user}`);
|
||||
}, e => {
|
||||
console.error(e);
|
||||
});
|
22
docs/backup.fr.md
Normal file
@ -0,0 +1,22 @@
|
||||
Comment faire une sauvegarde de votre Misskey ?
|
||||
==========================
|
||||
|
||||
Assurez-vous d'avoir installé **mongodb-tools**.
|
||||
|
||||
---
|
||||
|
||||
Dans votre terminal :
|
||||
``` shell
|
||||
$ mongodump --archive=db-backup -u <VotreNomdUtilisateur> -p <VotreMotDePasse>
|
||||
```
|
||||
|
||||
Pour plus de détails, merci de consulter [la documentation de mongodump](https://docs.mongodb.com/manual/reference/program/mongodump/).
|
||||
|
||||
Restauration
|
||||
-------
|
||||
|
||||
``` shell
|
||||
$ mongorestore --archive=db-backup
|
||||
```
|
||||
|
||||
Pour plus de détails, merci de consulter [la documentation de mongorestore](https://docs.mongodb.com/manual/reference/program/mongorestore/).
|
@ -10,7 +10,7 @@ In your shell:
|
||||
$ mongodump --archive=db-backup -u <YourUserName> -p <YourPassword>
|
||||
```
|
||||
|
||||
For details, plese see [mongodump docs](https://docs.mongodb.com/manual/reference/program/mongodump/).
|
||||
For details, please see [mongodump docs](https://docs.mongodb.com/manual/reference/program/mongodump/).
|
||||
|
||||
Restore
|
||||
-------
|
||||
|
@ -13,11 +13,11 @@ This guide describes how to install and setup Misskey with Docker.
|
||||
2. `cd misskey` Move to misskey directory.
|
||||
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) tag.
|
||||
|
||||
*2.* Make configuration files
|
||||
*2.* Configure Misskey
|
||||
----------------------------------------------------------------
|
||||
1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
|
||||
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` Copy the `.config/mongo_initdb_example.js` and rename it to `mongo_initdb.js`.
|
||||
2. Edit `default.yml` and `mongo_initdb.js`.
|
||||
3. Edit `default.yml` and `mongo_initdb.js`.
|
||||
|
||||
*3.* Configure Docker
|
||||
----------------------------------------------------------------
|
||||
@ -31,12 +31,12 @@ Build misskey with the following:
|
||||
|
||||
*5.* That is it.
|
||||
----------------------------------------------------------------
|
||||
Well done! Now, you have an environment that run to Misskey.
|
||||
Well done! Now you have an environment to run Misskey.
|
||||
|
||||
### Launch normally
|
||||
Just `docker-compose up -d`. GLHF!
|
||||
|
||||
### Way to Update to latest version of your Misskey
|
||||
### How to update your Misskey server to the latest version
|
||||
1. `git fetch`
|
||||
2. `git stash`
|
||||
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||
@ -45,9 +45,9 @@ Just `docker-compose up -d`. GLHF!
|
||||
6. Check [ChangeLog](../CHANGELOG.md) for migration information
|
||||
7. `docker-compose stop && docker-compose up -d`
|
||||
|
||||
### Way to execute cli command:
|
||||
### How to execute [cli commands](manage.en.md):
|
||||
`docker-compose run --rm web node cli/mark-admin @example`
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
If you have any questions or troubles, feel free to contact us!
|
||||
If you have any questions or trouble, feel free to contact us!
|
||||
|
67
docs/docker.fr.md
Normal file
@ -0,0 +1,67 @@
|
||||
Guide Docker
|
||||
================================================================
|
||||
|
||||
Ce guide explique comment installer et configurer Misskey avec Docker.
|
||||
|
||||
[Version japonaise également disponible - Japanese version also available - 日本語版もあります](./docker.ja.md)
|
||||
[Version anglaise également disponible - English version also available - 英語版もあります](./docker.en.md)
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
*1.* Télécharger Misskey
|
||||
----------------------------------------------------------------
|
||||
1. `git clone -b master git://github.com/syuilo/misskey.git` Clone le dépôt de Misskey sur la branche master.
|
||||
2. `cd misskey` Permet de se déplacer dans le dossier du dépôt.
|
||||
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout sur le tag de la [dernière version](https://github.com/syuilo/misskey/releases/latest).
|
||||
|
||||
*2.* Configuration de Misskey
|
||||
----------------------------------------------------------------
|
||||
1. `cp .config/example.yml .config/default.yml` Copie le fichier `.config/example.yml` et le renommer en `default.yml`.
|
||||
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` Copie le fichier `.config/mongo_initdb_example.js` et le renomme en `mongo_initdb.js`.
|
||||
3. Editer `default.yml` et `mongo_initdb.js`.
|
||||
|
||||
*3.* Configurer Docker
|
||||
----------------------------------------------------------------
|
||||
Editez `docker-compose.yml`.
|
||||
|
||||
*4.* Contruire Misskey
|
||||
----------------------------------------------------------------
|
||||
Contruire l'image Docker avec:
|
||||
|
||||
`docker-compose build`
|
||||
|
||||
*5.* C'est tout !
|
||||
----------------------------------------------------------------
|
||||
Parfait, Vous avez un environnement prêt pour démarrer Misskey.
|
||||
|
||||
### Lancer normalement
|
||||
Utilisez la commande `docker-compose up -d`. GLHF!
|
||||
|
||||
### How to update your Misskey server to the latest version
|
||||
1. `git fetch`
|
||||
2. `git stash`
|
||||
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||
4. `git stash pop`
|
||||
5. `docker-compose build`
|
||||
6. Consultez le [ChangeLog](../CHANGELOG.md) pour avoir les éventuelles informations de migration
|
||||
7. `docker-compose stop && docker-compose up -d`
|
||||
|
||||
### Comment exécuter des [commandes](manage.fr.md)
|
||||
`docker-compose run --rm web node cli/mark-admin @example`
|
||||
|
||||
### Configuration d'ElasticSearch (pour la fonction de recherche)
|
||||
*1.* Préparation de l'environnement
|
||||
----------------------------------------------------------------
|
||||
1. `mkdir elasticsearch && chown 1000:1000 elasticsearch` Permet de créer le dossier d'accueil de la base ElasticSearch aves les bons droits
|
||||
2. `sysctl -w vm.max_map_count=262144` Augmente la valeur max du paramètre map_count du système (valeur minimum pour pouvoir lancer ES)
|
||||
|
||||
*2.* Après lancement du docker-compose, initialisation de la base ElasticSearch
|
||||
----------------------------------------------------------------
|
||||
1. `docker-compose -it web /bin/sh` Connexion dans le conteneur web
|
||||
2. `apk add curl` Ajout du paquet curl
|
||||
3. `curl -X PUT "es:9200/misskey" -H 'Content-Type: application/json' -d'{ "settings" : { "index" : { } }}'` Création de la base ES
|
||||
4. `exit`
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Si vous avez des questions ou des problèmes, n'hésitez pas à nous contacter !
|
70
docs/examples/misskey.nginx
Normal file
@ -0,0 +1,70 @@
|
||||
# Sample nginx configuration for Misskey
|
||||
#
|
||||
# 1. Replace example.tld to your domain
|
||||
# 2. Copy to /etc/nginx/sites-available/ and then symlink from /etc/nginx/sites-ebabled/
|
||||
# or copy to /etc/nginx/conf.d/
|
||||
|
||||
# For WebSocket
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name example.tld;
|
||||
|
||||
# For SSL domain validation
|
||||
root /var/www/html;
|
||||
location /.well-known/acme-challenge/ { allow all; }
|
||||
location /.well-known/pki-validation/ { allow all; }
|
||||
location / { return 301 https://$server_name$request_uri; }
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 http2;
|
||||
listen [::]:443 http2;
|
||||
server_name example.tld;
|
||||
ssl on;
|
||||
ssl_session_cache shared:ssl_session_cache:10m;
|
||||
|
||||
# To use Let's Encrypt certificate
|
||||
ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
|
||||
|
||||
# To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate)
|
||||
#ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
#ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
|
||||
# SSL protocol settings
|
||||
ssl_protocols TLSv1 TLSv1.2;
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# Change to your upload limit
|
||||
client_max_body_size 80m;
|
||||
|
||||
# Proxy to Node
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_http_version 1.1;
|
||||
proxy_redirect off;
|
||||
|
||||
# For WebSocket
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
|
||||
# Cache settings
|
||||
proxy_cache cache1;
|
||||
proxy_cache_lock on;
|
||||
proxy_cache_use_stale updating;
|
||||
add_header X-Cache $upstream_cache_status;
|
||||
}
|
||||
}
|
@ -8,28 +8,11 @@ coming soon
|
||||
node cli/mark-admin (User-ID or Username)
|
||||
```
|
||||
|
||||
## Mark as 'verified' user
|
||||
``` shell
|
||||
node cli/mark-verified (User-ID or Username)
|
||||
```
|
||||
|
||||
## Suspend users
|
||||
``` shell
|
||||
node cli/suspend (User-ID or Username)
|
||||
```
|
||||
e.g.
|
||||
``` shell
|
||||
# Use id
|
||||
node cli/suspend 57d01a501fdf2d07be417afe
|
||||
# By id
|
||||
node cli/mark-admin 57d01a501fdf2d07be417afe
|
||||
|
||||
# Use username
|
||||
# By username
|
||||
node cli/suspend @syuilo
|
||||
|
||||
# Use username (remote)
|
||||
node cli/suspend @syuilo@misskey.xyz
|
||||
```
|
||||
|
||||
## Reset password
|
||||
``` shell
|
||||
node cli/reset-password (User-ID or Username)
|
||||
```
|
||||
|
18
docs/manage.fr.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Guide d'administration
|
||||
|
||||
## Vérifier le status de la file d'attente des taches
|
||||
coming soon
|
||||
|
||||
## Marquer un utilisateur en tant que 'admin'
|
||||
``` shell
|
||||
node cli/mark-admin (ID utilisateur ou nom d'utilisateur)
|
||||
```
|
||||
|
||||
Exemple :
|
||||
``` shell
|
||||
# Par id
|
||||
node cli/mark-admin 57d01a501fdf2d07be417afe
|
||||
|
||||
# Par nom d'utilisateur
|
||||
node cli/suspend @syuilo
|
||||
```
|
@ -8,28 +8,11 @@ coming soon
|
||||
node cli/mark-admin (ユーザーID または ユーザー名)
|
||||
```
|
||||
|
||||
## 'verified'ユーザーを設定する
|
||||
``` shell
|
||||
node cli/mark-verified (ユーザーID または ユーザー名)
|
||||
```
|
||||
|
||||
## ユーザーを凍結する
|
||||
``` shell
|
||||
node cli/suspend (ユーザーID または ユーザー名)
|
||||
```
|
||||
例:
|
||||
``` shell
|
||||
# ユーザーID
|
||||
node cli/suspend 57d01a501fdf2d07be417afe
|
||||
node cli/mark-admin 57d01a501fdf2d07be417afe
|
||||
|
||||
# ユーザー名
|
||||
node cli/suspend @syuilo
|
||||
|
||||
# ユーザー名 (リモート)
|
||||
node cli/suspend @syuilo@misskey.xyz
|
||||
```
|
||||
|
||||
## ユーザーのパスワードをリセットする
|
||||
``` shell
|
||||
node cli/reset-password (ユーザーID または ユーザー名)
|
||||
node cli/mark-admin @syuilo
|
||||
```
|
||||
|
@ -10,7 +10,7 @@ This guide describes how to install and setup Misskey.
|
||||
|
||||
*1.* Create Misskey user
|
||||
----------------------------------------------------------------
|
||||
Running misskey on root is not a good idea so we create a user for that.
|
||||
Running misskey as root is not a good idea so we create a user for that.
|
||||
In debian for exemple :
|
||||
|
||||
```
|
||||
@ -32,7 +32,7 @@ Please install and setup these softwares:
|
||||
|
||||
*3.* Setup MongoDB
|
||||
----------------------------------------------------------------
|
||||
In root :
|
||||
As root:
|
||||
1. `mongo` Go to the mongo shell
|
||||
2. `use misskey` Use the misskey database
|
||||
3. `db.users.save( {dummy:"dummy"} )` Write dummy data to initialize the db.
|
||||
@ -47,29 +47,7 @@ In root :
|
||||
4. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest)
|
||||
5. `npm install` Install misskey dependencies.
|
||||
|
||||
*(optional)* reCAPTCHA tokens
|
||||
----------------------------------------------------------------
|
||||
If you want to enable reCAPTCHA, you need to generate reCAPTCHA tokens:
|
||||
Please visit https://www.google.com/recaptcha/intro/ and generate keys.
|
||||
|
||||
*(optional)* Generating 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
|
||||
npm install web-push -g
|
||||
web-push generate-vapid-keys
|
||||
```
|
||||
|
||||
*(optional)* Create a twitter application
|
||||
----------------------------------------------------------------
|
||||
If you want to enable the twitter integration, you need to create a twitter app at [https://developer.twitter.com/en/apply/user](https://developer.twitter.com/en/apply/user).
|
||||
|
||||
In the app you need to set the oauth callback url as : https://misskey-instance/api/tw/cb
|
||||
|
||||
|
||||
*5.* Make configuration file
|
||||
*5.* Configure Misskey
|
||||
----------------------------------------------------------------
|
||||
1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
|
||||
2. Edit `default.yml`
|
||||
@ -81,7 +59,7 @@ Build misskey with the following:
|
||||
|
||||
`npm run build`
|
||||
|
||||
If you're on Debian, you will need to install the `build-essential` package.
|
||||
If you're on Debian, you will need to install the `build-essential`, `python` package.
|
||||
|
||||
If you're still encountering errors about some modules, use node-gyp:
|
||||
|
||||
@ -126,7 +104,7 @@ WantedBy=multi-user.target
|
||||
|
||||
You can check if the service is running with `systemctl status misskey`.
|
||||
|
||||
### Way to Update to latest version of your Misskey
|
||||
### How to update your Misskey server to the latest version
|
||||
1. `git fetch`
|
||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||
3. `npm install`
|
||||
|
116
docs/setup.fr.md
Normal file
@ -0,0 +1,116 @@
|
||||
Guide d'installation et de configuration de Misskey
|
||||
================================================================
|
||||
|
||||
Nous vous remerçions de l'intrêt que vous manifestez pour l'installation de votre propre instance Misskey !
|
||||
Ce guide décrit les étapes à suivre afin d'installer et de configurer une instance Misskey.
|
||||
|
||||
[La version en japonnais est également disponible sur - 日本語版もあります](./setup.ja.md)
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
*1.* Création de l'utilisateur Misskey
|
||||
----------------------------------------------------------------
|
||||
Lancer misskey en tant qu'utilisateur est une mauvaise idée, nous avons besoin de créer un utilisateur dédié.
|
||||
Sur Debian, à titre d'exemple :
|
||||
|
||||
```
|
||||
adduser --disabled-password --disabled-login misskey
|
||||
```
|
||||
|
||||
*2.* Installation des dépendances
|
||||
----------------------------------------------------------------
|
||||
Installez les paquets suivants :
|
||||
|
||||
#### Dépendences :package:
|
||||
* **[Node.js](https://nodejs.org/en/)** >= 10.0.0
|
||||
* **[MongoDB](https://www.mongodb.com/)** >= 3.6
|
||||
|
||||
##### Optionnels
|
||||
* [Redis](https://redis.io/)
|
||||
* Redis est optionnel mais nous vous recommandons vivement de l'installer
|
||||
* [Elasticsearch](https://www.elastic.co/) - requis pour pouvoir activer la fonctionnalité de recherche
|
||||
|
||||
*3.* Paramètrage de MongoDB
|
||||
----------------------------------------------------------------
|
||||
En mode root :
|
||||
1. `mongo` Accédez au shell de mango
|
||||
2. `use misskey` Utilisez la base de données misskey
|
||||
3. `db.users.save( {dummy:"dummy"} )` Write dummy data to initialize the db.
|
||||
4. `db.createUser( { user: "misskey", pwd: "<password>", roles: [ { role: "readWrite", db: "misskey" } ] } )` Créez l'utilisateur misskey.
|
||||
5. `exit` Vous avez terminé !
|
||||
|
||||
*4.* Installation de Misskey
|
||||
----------------------------------------------------------------
|
||||
1. `su - misskey` Basculez vers l'utilisateur misskey.
|
||||
2. `git clone -b master git://github.com/syuilo/misskey.git` Clonez la branche master du dépôt misskey.
|
||||
3. `cd misskey` Accédez au dossier misskey.
|
||||
4. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Télécharge la [version la plus récente](https://github.com/syuilo/misskey/releases/latest)
|
||||
5. `npm install` Installez les dépendances de misskey.
|
||||
|
||||
*5.* Création du fichier de configuration
|
||||
----------------------------------------------------------------
|
||||
1. `cp .config/example.yml .config/default.yml` Copiez le fichier `.config/example.yml` et renommez-le `default.yml`.
|
||||
2. Editez le fichier `default.yml`
|
||||
|
||||
*6.* Construction de Misskey
|
||||
----------------------------------------------------------------
|
||||
|
||||
Construisez Misskey comme ceci :
|
||||
|
||||
`npm run build`
|
||||
|
||||
Si vous êtes sous Debian, vous serez amené à installer les paquets `build-essential`, `python`.
|
||||
|
||||
Si vous rencontrez des erreurs concernant certains modules, utilisez node-gyp:
|
||||
|
||||
1. `npm install -g node-gyp`
|
||||
2. `node-gyp configure`
|
||||
3. `node-gyp build`
|
||||
4. `npm run build`
|
||||
|
||||
*7.* C'est tout.
|
||||
----------------------------------------------------------------
|
||||
Excellent ! Maintenant, vous avez un environnement prêt pour lancer Misskey
|
||||
|
||||
### Lancement conventionnel
|
||||
Lancez tout simplement `npm start`. Bonne chance et amusez-vous bien !
|
||||
|
||||
### Démarrage avec systemd
|
||||
|
||||
1. Créez une service systemd sur : `/etc/systemd/system/misskey.service`
|
||||
2. Editez-le puis copiez et coller ceci dans le fichier :
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Misskey daemon
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=misskey
|
||||
ExecStart=/usr/bin/npm start
|
||||
WorkingDirectory=/home/misskey/misskey
|
||||
TimeoutSec=60
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog
|
||||
SyslogIdentifier=misskey
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
3. `systemctl daemon-reload ; systemctl enable misskey` Redémarre systemd et active le service misskey.
|
||||
4. `systemctl start misskey` Démarre le service misskey.
|
||||
|
||||
Vous pouvez vérifier si le service a démarré en utilisant la commande `systemctl status misskey`.
|
||||
|
||||
### Méthode de mise à jour vers la plus récente version de Misskey
|
||||
1. `git fetch`
|
||||
2. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)`
|
||||
3. `npm install`
|
||||
4. `npm run build`
|
||||
5. Consultez [ChangeLog](../CHANGELOG.md) pour les information de migration.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
Si vous rencontrez des difficultés ou avez d'autres questions, n'hésitez pas à nous contacter !
|
@ -53,20 +53,6 @@ adduser --disabled-password --disabled-login misskey
|
||||
4. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
|
||||
5. `npm install` Misskeyの依存パッケージをインストール
|
||||
|
||||
*(オプション)* reCAPTCHAトークン
|
||||
----------------------------------------------------------------
|
||||
reCAPTCHAを有効にする場合、reCAPTCHAトークンを取得する必要があります。
|
||||
https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してください。
|
||||
|
||||
*(オプション)* VAPIDキーペアの生成
|
||||
----------------------------------------------------------------
|
||||
ServiceWorkerを有効にする場合、VAPIDキーペアを生成する必要があります:
|
||||
|
||||
``` shell
|
||||
npm install web-push -g
|
||||
web-push generate-vapid-keys
|
||||
```
|
||||
|
||||
*5.* 設定ファイルを作成する
|
||||
----------------------------------------------------------------
|
||||
1. `cp .config/example.yml .config/default.yml` `.config/example.yml`をコピーし名前を`default.yml`にする。
|
||||
|
@ -1,27 +0,0 @@
|
||||
Misskey's Translation
|
||||
=====================
|
||||
|
||||
If you find an untranslated part on Misskey:
|
||||
--------------------------------------------
|
||||
|
||||
1. Look for untranslated parts in the misskey's source code.
|
||||
- For instance, if you find an untranslated part in: `src/client/app/mobile/views/pages/home.vue`.
|
||||
|
||||
2. Replace the untranslated portion with a character string of the form `%i18n:@foo%`.
|
||||
- In fact, `foo` should be a word that is appropriate for the situation and is easy to understand in English.
|
||||
- For example, if the untranslated portion is the following "タイムライン" you must write: `%i18n:@timeline%`.
|
||||
|
||||
3. Open the `locales/ja-JP.yml`, check whether the <strong>file name (path)</strong> found in step 1 exists, if not, create it.
|
||||
- Do not put the beginning of the path `src/client/app/` in the locale file.
|
||||
- For example, in this case we want to modify untranslated parts of `src/client/app/mobile/views/pages/home.vue`, so the key is `mobile/views/pages/home.vue`.
|
||||
|
||||
4. Add the text property using the `foo` keyword below the path that you found or created in step 2. Make sure to type your text in quotation marks. Text should always be inside of quotes.
|
||||
- For example, in this case we add timeline: `timeline: "タイムライン"` to `locales/ja-JP.yml`.
|
||||
|
||||
5. When you add text to the ja-JP file (of syuilo/misskey), it will automatically be applied to all other local language files within 24-48 hours. Translations added in ja-JP file should contain the original Japanese strings (example see step 4).
|
||||
|
||||
6. The new strings will automatically appear in the localized language files in the original Japanese text. After that, please go to [CrowdIn](https://crowdin.com/project/misskey) to do the localized translations in your language.
|
||||
|
||||
7. And done!
|
||||
|
||||
For more details, please refer to this [commit](https://github.com/syuilo/misskey/commit/10f6d5980fa7692ccb45fbc5f843458b69b7607c).
|
@ -1,23 +0,0 @@
|
||||
Traduction de Misskey
|
||||
=====================
|
||||
|
||||
Si vous trouvez un segment non-traduit sur Misskey :
|
||||
----------------------------------------------------
|
||||
|
||||
1. Veuillez chercher des parties non-traduites dans le code source de Misskey.
|
||||
- Par exemple, supposons que vous trouviez un segment non-traduit dans : `src/client/app/mobile/views/pages/home.vue`.
|
||||
|
||||
2. Remplacez la portion non-traduite par une chaîne de caractères de type `%i18n:@foo%`.
|
||||
- En fait, `foo` doit être un mot approprié à la situation et facile à comprendre en français.
|
||||
- Par exemple, si le segment non-traduit est「タイムライン」on peut écrire : `%i18n:@timeline%`.
|
||||
|
||||
3. Ouvrez chaque fichier linguistique dans /locales, vérifiez si le <strong>nom du fichier (chemin)</strong> trouvé dans l'étape 1 existe, sinon créez-le.
|
||||
- Ne mettez pas le début du chemin `src/client/app/` dans les fichiers /locales.
|
||||
- Par exemple, dans ce cas de figure, nous voulons modifier le segment non-traduit de : `src/client/app/mobile/views/pages/home.vue`donc il faut juste écrire : `mobile/views/pages/home.vue` dans les fichiers linguistiques.
|
||||
|
||||
4. Ajoutez la propriété du texte traduit grâce à la clef `foo`, en-dessous du chemin correspondant à votre modification que vous avez trouvé ou créé dans l'étape 2. À côté, veuillez indiquer entre "guillemets" la valeur de votre traduction.
|
||||
- Par exemple, dans ce cas de figure, nous ajoutons la propriété et la traduction `timeline: "Timeline"` à `locales/fr.yml`, mais aussi la propriété et la version originale `timeline: "タイムライン"` à `locales/ja-JP.yml`.
|
||||
|
||||
5. Vous avez réussi à traduire une portion de misskey !
|
||||
|
||||
Pour plus de détails, veuillez vous référer à ce [commit](https://github.com/syuilo/misskey/commit/10f6d5980fa7692ccb45fbc5f843458b69b7607c).
|
@ -1,23 +0,0 @@
|
||||
Misskeyの翻訳
|
||||
============
|
||||
|
||||
Misskey内の未翻訳箇所を見つけたら
|
||||
-------------------------------
|
||||
|
||||
1. Misskeyのソースコード内から未翻訳箇所を探してください。
|
||||
- 例えば`src/client/app/mobile/views/pages/home.vue`で未翻訳箇所を見つけたとします。
|
||||
|
||||
2. 未翻訳箇所を`%i18n:@foo%`のような形式の文字列に置換してください。
|
||||
- `foo`は実際にはその場に適したわかりやすい(英語の)名前にしてください。
|
||||
- 例えば未翻訳箇所が「タイムライン」というテキストだった場合、`%i18n:@timeline%`のようにします。
|
||||
|
||||
3. `locales/ja-JP.yml`を開き、1.で見つけた<strong>ファイル名(パス)</strong>のキーが存在するか確認し、無ければ作成してください。
|
||||
- パスの`src/client/app/`は省略してください。
|
||||
- 例えば、今回の例では`src/client/app/mobile/views/pages/home.vue`の未翻訳箇所を修正したいので、キーは`mobile/views/pages/home.vue`になります。
|
||||
|
||||
4. そのキーの直下に2.で置換した`foo`の部分をキーとし、テキストを値とするプロパティを追加します。
|
||||
- 例えば、今回の例で言うと`locales/ja-JP.yml`に`timeline: "タイムライン"`を追加します。
|
||||
|
||||
5. 完了です!
|
||||
|
||||
詳しくは、[このコミット](https://github.com/syuilo/misskey/commit/10f6d5980fa7692ccb45fbc5f843458b69b7607c)などを参考にしてください。
|
67
gulpfile.ts
@ -5,19 +5,18 @@
|
||||
import * as gulp from 'gulp';
|
||||
import * as gutil from 'gulp-util';
|
||||
import * as ts from 'gulp-typescript';
|
||||
const yaml = require('gulp-yaml');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
import tslint from 'gulp-tslint';
|
||||
const cssnano = require('gulp-cssnano');
|
||||
const stylus = require('gulp-stylus');
|
||||
import * as uglifyComposer from 'gulp-uglify/composer';
|
||||
import pug = require('gulp-pug');
|
||||
import * as rimraf from 'rimraf';
|
||||
import chalk from 'chalk';
|
||||
const imagemin = require('gulp-imagemin');
|
||||
import * as rename from 'gulp-rename';
|
||||
import * as mocha from 'gulp-mocha';
|
||||
import * as replace from 'gulp-replace';
|
||||
import * as htmlmin from 'gulp-htmlmin';
|
||||
const uglifyes = require('uglify-es');
|
||||
|
||||
const locales = require('./locales');
|
||||
@ -33,12 +32,11 @@ if (isDebug) {
|
||||
console.warn(chalk.yellow.bold(' built script will not be compressed.'));
|
||||
}
|
||||
|
||||
const constants = require('./src/const.json');
|
||||
|
||||
gulp.task('build', [
|
||||
'build:ts',
|
||||
'build:copy',
|
||||
'build:client',
|
||||
'locales',
|
||||
'doc'
|
||||
]);
|
||||
|
||||
@ -57,16 +55,7 @@ gulp.task('build:copy:views', () =>
|
||||
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
|
||||
);
|
||||
|
||||
// 互換性のため
|
||||
gulp.task('build:copy:lang', () =>
|
||||
gulp.src(['./built/client/assets/*.*-*.js'])
|
||||
.pipe(rename(path => {
|
||||
path.basename = path.basename.replace(/\-(.*)$/, '');
|
||||
}))
|
||||
.pipe(gulp.dest('./built/client/assets/'))
|
||||
);
|
||||
|
||||
gulp.task('build:copy', ['build:copy:views', 'build:copy:lang'], () =>
|
||||
gulp.task('build:copy', ['build:copy:views'], () =>
|
||||
gulp.src([
|
||||
'./build/Release/crypto_key.node',
|
||||
'./src/const.json',
|
||||
@ -116,7 +105,7 @@ gulp.task('default', ['build']);
|
||||
gulp.task('build:client', [
|
||||
'build:ts',
|
||||
'build:client:script',
|
||||
'build:client:pug',
|
||||
'build:client:styles',
|
||||
'copy:client'
|
||||
]);
|
||||
|
||||
@ -155,50 +144,10 @@ gulp.task('copy:client', [
|
||||
.pipe(gulp.dest('./built/client/assets/'))
|
||||
);
|
||||
|
||||
gulp.task('build:client:pug', [
|
||||
'copy:client',
|
||||
'build:client:script',
|
||||
'build:client:styles'
|
||||
], () =>
|
||||
gulp.src('./src/client/app/base.pug')
|
||||
.pipe(pug({
|
||||
locals: {
|
||||
themeColor: constants.themeColor
|
||||
}
|
||||
}))
|
||||
.pipe(htmlmin({
|
||||
// 真理値属性の簡略化 e.g.
|
||||
// <input value="foo" readonly="readonly"> to
|
||||
// <input value="foo" readonly>
|
||||
collapseBooleanAttributes: true,
|
||||
|
||||
// テキストの一部かもしれない空白も削除する e.g.
|
||||
// <div> <p> foo </p> </div> to
|
||||
// <div><p>foo</p></div>
|
||||
collapseWhitespace: true,
|
||||
|
||||
// タグ間の改行を保持する
|
||||
preserveLineBreaks: true,
|
||||
|
||||
// (できる場合は)属性のクォーテーション削除する e.g.
|
||||
// <p class="foo-bar" id="moo" title="blah blah">foo</p> to
|
||||
// <p class=foo-bar id=moo title="blah blah">foo</p>
|
||||
removeAttributeQuotes: true,
|
||||
|
||||
// 省略可能なタグを省略する e.g.
|
||||
// <html><p>yo</p></html> ro
|
||||
// <p>yo</p>
|
||||
removeOptionalTags: true,
|
||||
|
||||
// 属性の値がデフォルトと同じなら省略する e.g.
|
||||
// <input type="text"> to
|
||||
// <input>
|
||||
removeRedundantAttributes: true,
|
||||
|
||||
// CSSも圧縮する
|
||||
minifyCSS: true
|
||||
}))
|
||||
.pipe(gulp.dest('./built/client/app/'))
|
||||
gulp.task('locales', () =>
|
||||
gulp.src('./locales/*.yml')
|
||||
.pipe(yaml({ schema: 'DEFAULT_SAFE_SCHEMA' }))
|
||||
.pipe(gulp.dest('./built/client/assets/locales/'))
|
||||
);
|
||||
|
||||
gulp.task('doc', () =>
|
||||
|
@ -25,21 +25,12 @@ common:
|
||||
application-authorization: "アプリの連携"
|
||||
close: "閉じる"
|
||||
do-not-copy-paste: "ここにコードを入力したり張り付けたりしないでください。アカウントが不正利用される可能性があります。"
|
||||
BSoD:
|
||||
fatal-error: ":( 致命的な問題が発生しました。"
|
||||
update-browser-os: "お使いのブラウザ(またはOS)のバージョンを更新すると解決する可能性があります。"
|
||||
error-code: "エラーコード"
|
||||
browser-version: "ブラウザ バージョン"
|
||||
client-version: "クライアント バージョン"
|
||||
email-support: "問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。"
|
||||
thanks: "Thank you for using Misskey."
|
||||
load-more: "もっと読み込む"
|
||||
enter-password: "パスワードを入力してください"
|
||||
got-it: "わかった"
|
||||
customization-tips:
|
||||
title: "カスタマイズのヒント"
|
||||
paragraph1: "ホームのカスタマイズでは、ウィジェットを追加/削除したり、ドラッグ&ドロップして並べ替えたりすることができます。"
|
||||
paragraph2: "一部のウィジェットは、<strong><strong>右</strong>クリック</strong>することで表示を変更することができます。"
|
||||
paragraph3: "ウィジェットを削除するには、ヘッダーの<strong>「ゴミ箱」</strong>と書かれたエリアにウィジェットをドラッグ&ドロップします。"
|
||||
paragraph4: "カスタマイズを終了するには、右上の「完了」をクリックします。"
|
||||
paragraph: "<p>ホームのカスタマイズでは、ウィジェットを追加/削除したり、ドラッグ&ドロップして並べ替えたりすることができます。</p><p>一部のウィジェットは、<strong><strong>右</strong>クリック</strong>することで表示を変更することができます。</p><p>ウィジェットを削除するには、ヘッダーの<strong>「ゴミ箱」</strong>と書かれたエリアにウィジェットをドラッグ&ドロップします。</p><p>カスタマイズを終了するには、右上の「完了」をクリックします。</p>"
|
||||
gotit: "Got it!"
|
||||
notification:
|
||||
file-uploaded: "ファイルがアップロードされました"
|
||||
@ -63,6 +54,7 @@ common:
|
||||
month-and-day: "{month}月 {day}日"
|
||||
trash: "ゴミ箱"
|
||||
drive: "ドライブ"
|
||||
messaging: "トーク"
|
||||
weekday-short:
|
||||
sunday: "日"
|
||||
monday: "月"
|
||||
@ -98,7 +90,9 @@ common:
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
local-public: "公開 (ローカルのみ)"
|
||||
local-home: "ホーム (ローカルのみ)"
|
||||
local-followers: "フォロワー (ローカルのみ)"
|
||||
note-placeholders:
|
||||
a: "今どうしてる?"
|
||||
b: "何かありましたか?"
|
||||
@ -115,32 +109,41 @@ common:
|
||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||
i-like-sushi: "私は(プリンよりむしろ)寿司が好き"
|
||||
show-reversi-board-labels: "リバーシのボードの行と列のラベルを表示"
|
||||
use-contrast-reversi-stones: "リバーシのアイコンにコントラストを付ける"
|
||||
use-avatar-reversi-stones: "リバーシの石にアバターを使う"
|
||||
verified-user: "公式アカウント"
|
||||
disable-animated-mfm: "投稿内の動きのあるテキストを無効にする"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||
always-show-nsfw: "常に閲覧注意のメディアを表示する"
|
||||
always-mark-nsfw: "常にメディアを閲覧注意として投稿"
|
||||
show-full-acct: "ユーザー名のホストを省略しない"
|
||||
show-via: "viaを表示する"
|
||||
reduce-motion: "UIの動きを減らす"
|
||||
this-setting-is-this-device-only: "このデバイスのみ"
|
||||
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||
use-os-default-emojis: "OS標準の絵文字を使用"
|
||||
line-width: "線の太さ"
|
||||
line-width-thin: "細い"
|
||||
line-width-normal: "普通"
|
||||
line-width-thick: "太い"
|
||||
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
|
||||
user-suspended: "このユーザーは凍結されています。"
|
||||
is-remote-user: "このユーザー情報はコピーです。"
|
||||
is-remote-post: "この投稿情報はコピーです。"
|
||||
view-on-remote: "正確な情報を見る"
|
||||
renoted-by: "{user}がRenote"
|
||||
error:
|
||||
title: '問題が発生しました'
|
||||
retry: 'やり直す'
|
||||
title: "問題が発生しました"
|
||||
retry: "やり直す"
|
||||
reversi:
|
||||
drawn: "引き分け"
|
||||
my-turn: "あなたのターンです"
|
||||
opponent-turn: "相手のターンです"
|
||||
turn-of: "{}のターンです"
|
||||
past-turn-of: "{}のターン"
|
||||
won: "{}の勝ち"
|
||||
turn-of: "{name}のターンです"
|
||||
past-turn-of: "{name}のターン"
|
||||
won: "{name}の勝ち"
|
||||
black: "黒"
|
||||
white: "白"
|
||||
total: "合計"
|
||||
this-turn: "{}ターン目"
|
||||
this-turn: "{count}ターン目"
|
||||
widgets:
|
||||
analog-clock: "アナログ時計"
|
||||
profile: "プロフィール"
|
||||
@ -159,36 +162,15 @@ common:
|
||||
users: "おすすめユーザー"
|
||||
polls: "アンケート"
|
||||
post-form: "投稿フォーム"
|
||||
messaging: "メッセージ"
|
||||
server: "サーバー情報"
|
||||
donation: "寄付のお願い"
|
||||
nav: "ナビゲーション"
|
||||
tips: "ヒント"
|
||||
hashtags: "ハッシュタグ"
|
||||
deck:
|
||||
widgets: "ウィジェット"
|
||||
home: "ホーム"
|
||||
local: "ローカル"
|
||||
hybrid: "ソーシャル"
|
||||
hashtag: "ハッシュタグ"
|
||||
global: "グローバル"
|
||||
mentions: "あなた宛て"
|
||||
direct: "ダイレクト投稿"
|
||||
notifications: "通知"
|
||||
list: "リスト"
|
||||
swap-left: "左に移動"
|
||||
swap-right: "右に移動"
|
||||
swap-up: "上に移動"
|
||||
swap-down: "下に移動"
|
||||
remove: "カラムを削除"
|
||||
add-column: "カラムを追加"
|
||||
rename: "名前を変更"
|
||||
stack-left: "左に重ねる"
|
||||
pop-right: "右に出す"
|
||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||
ai-chan-kawaii: "藍ちゃかわいい"
|
||||
you: "あなた"
|
||||
auth/views/form.vue:
|
||||
share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
|
||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||
permission-ask: "このアプリは次の権限を要求しています:"
|
||||
account-read: "アカウントの情報を見る。"
|
||||
account-write: "アカウントの情報を操作する。"
|
||||
@ -282,6 +264,7 @@ common/views/components/media-banner.vue:
|
||||
sensitive: "閲覧注意"
|
||||
click-to-show: "クリックして表示"
|
||||
common/views/components/theme.vue:
|
||||
theme: "テーマ"
|
||||
light-theme: "非ダークモード時に使用するテーマ"
|
||||
dark-theme: "ダークモード時に使用するテーマ"
|
||||
light-themes: "明るいテーマ"
|
||||
@ -298,6 +281,7 @@ common/views/components/theme.vue:
|
||||
base-theme: "ベーステーマ"
|
||||
base-theme-light: "Light"
|
||||
base-theme-dark: "Dark"
|
||||
find-more-theme: "その他のテーマを入手"
|
||||
theme-name: "テーマ名"
|
||||
preview-created-theme: "プレビュー"
|
||||
invalid-theme: "テーマが正しくありません。"
|
||||
@ -319,13 +303,15 @@ common/views/components/theme.vue:
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
chars: "{count}文字"
|
||||
files: "{count}ファイル"
|
||||
poll: "アンケート"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "あなた"
|
||||
no-history: "履歴はありません"
|
||||
common/views/components/messaging-room.vue:
|
||||
empty: "このユーザーと話したことはありません"
|
||||
more: "もっと読む"
|
||||
no-history: "これより過去の履歴はありません"
|
||||
resize-form: "ドラッグしてフォームの広さを調整"
|
||||
new-message: "新しいメッセージがあります"
|
||||
@ -349,7 +335,9 @@ common/views/components/nav.vue:
|
||||
develop: "開発者"
|
||||
feedback: "フィードバック"
|
||||
common/views/components/note-menu.vue:
|
||||
mention: "メンション"
|
||||
detail: "詳細"
|
||||
copy-content: "内容をコピー"
|
||||
copy-link: "リンクをコピー"
|
||||
favorite: "お気に入り"
|
||||
unfavorite: "お気に入り解除"
|
||||
@ -373,6 +361,16 @@ common/views/components/poll-editor.vue:
|
||||
destroy: "アンケートを破棄"
|
||||
common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "リアクションを選択"
|
||||
common/views/components/emoji-picker.vue:
|
||||
custom-emoji: "カスタム絵文字"
|
||||
people: "人"
|
||||
animals-and-nature: "動物&自然"
|
||||
food-and-drink: "食べ物&飲み物"
|
||||
activity: "アクティビティ"
|
||||
travel-and-places: "場所"
|
||||
objects: "物"
|
||||
symbols: "記号"
|
||||
flags: "旗"
|
||||
common/views/components/signin.vue:
|
||||
username: "ユーザー名"
|
||||
password: "パスワード"
|
||||
@ -381,6 +379,8 @@ common/views/components/signin.vue:
|
||||
signin: "サインイン"
|
||||
or: "または"
|
||||
signin-with-twitter: "Twitterでログイン"
|
||||
signin-with-github: "GitHubでログイン"
|
||||
signin-with-discord: "Discordでログイン"
|
||||
login-failed: "ログインできませんでした。ユーザー名とパスワードを確認してください。"
|
||||
common/views/components/signup.vue:
|
||||
invitation-code: "招待コード"
|
||||
@ -412,12 +412,31 @@ common/views/components/stream-indicator.vue:
|
||||
connecting: "接続中"
|
||||
reconnecting: "再接続中"
|
||||
connected: "接続完了"
|
||||
common/views/components/twitter-setting.vue:
|
||||
description: "お使いのTwitterアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでTwitterアカウント情報が表示されるようになったり、Twitterを用いた便利なサインインを利用できるようになります。"
|
||||
connected-to: "次のTwitterアカウントに接続されています"
|
||||
common/views/components/notification-settings.vue:
|
||||
title: "通知"
|
||||
mark-as-read-all-notifications: "すべての通知を既読にする"
|
||||
mark-as-read-all-unread-notes: "すべての投稿を既読にする"
|
||||
mark-as-read-all-talk-messages: "すべてのトークを既読にする"
|
||||
auto-watch: "投稿の自動ウォッチ"
|
||||
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
||||
common/views/components/integration-settings.vue:
|
||||
title: "サービス連携"
|
||||
connect: "接続する"
|
||||
disconnect: "切断する"
|
||||
connected-to: "次のアカウントに接続されています"
|
||||
common/views/components/github-setting.vue:
|
||||
description: "お使いのGitHubアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでGitHubアカウント情報が表示されるようになったり、GitHubを用いた便利なサインインを利用できるようになります。"
|
||||
connected-to: "次のGitHubアカウントに接続されています"
|
||||
detail: "詳細..."
|
||||
reconnect: "再接続する"
|
||||
connect: "Twitterと接続する"
|
||||
connect: "GitHubと接続する"
|
||||
disconnect: "切断する"
|
||||
common/views/components/discord-setting.vue:
|
||||
description: "お使いのDiscordアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでDiscordアカウント情報が表示されるようになったり、Discordを用いた便利なサインインを利用できるようになります。"
|
||||
connected-to: "次のDiscordアカウントに接続されています"
|
||||
detail: "詳細..."
|
||||
reconnect: "再接続する"
|
||||
connect: "Discordと接続する"
|
||||
disconnect: "切断する"
|
||||
common/views/components/uploader.vue:
|
||||
waiting: "待機中"
|
||||
@ -429,16 +448,27 @@ common/views/components/visibility-chooser.vue:
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
local-public: "公開 (ローカルのみ)"
|
||||
local-public-desc: "リモートへは公開しない"
|
||||
local-home: "ホーム (ローカルのみ)"
|
||||
local-followers: "フォロワー (ローカルのみ)"
|
||||
common/views/components/trends.vue:
|
||||
count: "{}人が投稿"
|
||||
empty: "トレンドなし"
|
||||
common/views/components/language-settings.vue:
|
||||
title: "表示言語"
|
||||
pick-language: "言語を選択"
|
||||
recommended: "推奨"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
info: "変更はページの再度読み込み後に反映されます。"
|
||||
common/views/components/profile-editor.vue:
|
||||
title: "プロフィール"
|
||||
name: "名前"
|
||||
account: "アカウント"
|
||||
location: "場所"
|
||||
description: "自己紹介"
|
||||
language: "言語"
|
||||
birthday: "誕生日"
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
@ -446,12 +476,24 @@ common/views/components/profile-editor.vue:
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
careful-bot: "Botからのフォローだけ承認制にする"
|
||||
auto-accept-followed: "フォローしているユーザーからのフォローを自動承認する"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
upload-failed: "アップロードに失敗しました"
|
||||
email: "メール設定"
|
||||
email-address: "メールアドレス"
|
||||
email-verified: "メールアドレスが確認されました"
|
||||
email-not-verified: "メールアドレスが確認されていません。メールボックスをご確認ください。"
|
||||
common/views/components/user-list-editor.vue:
|
||||
users: "ユーザー"
|
||||
rename: "リスト名を変更"
|
||||
delete: "リストを削除"
|
||||
remove-user: "このリストから削除"
|
||||
delete-are-you-sure: "リスト「$1」を削除しますか?"
|
||||
deleted: "削除しました"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "確認中"
|
||||
no-broadcasts: "お知らせはありません"
|
||||
@ -464,9 +506,6 @@ common/views/widgets/calendar.vue:
|
||||
today: "今日:"
|
||||
this-month: "今月:"
|
||||
this-year: "今年:"
|
||||
common/views/widgets/donation.vue:
|
||||
title: "寄付のお願い"
|
||||
text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かります。Misskeyは広告を掲載したりしないため、収入を皆様からの寄付に頼っています。もしご興味があれば、{}までご連絡ください。ご協力ありがとうございます。"
|
||||
common/views/widgets/photo-stream.vue:
|
||||
title: "フォトストリーム"
|
||||
no-photos: "写真はありません"
|
||||
@ -504,9 +543,11 @@ common/views/widgets/tips.vue:
|
||||
tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができます"
|
||||
tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています"
|
||||
tips-line21: "APIを利用してbotの開発なども行えます"
|
||||
tips-line23: "まゆかわいいよまゆ"
|
||||
tips-line23: "藍かわいいよ藍"
|
||||
tips-line24: "Misskeyは2014年にサービスを開始しました"
|
||||
tips-line25: "対応ブラウザではMisskeyを開いていなくても通知を受け取れます"
|
||||
common/views/pages/not-found.vue:
|
||||
page-not-found: "ページが見つかりませんでした"
|
||||
common/views/pages/follow.vue:
|
||||
signed-in-as: "{}としてサインイン中"
|
||||
following: "フォロー中"
|
||||
@ -535,37 +576,12 @@ desktop/views/components/activity.vue:
|
||||
title: "アクティビティ"
|
||||
toggle: "表示を切り替え"
|
||||
desktop/views/components/calendar.vue:
|
||||
title: "{1}年 {2}月"
|
||||
title: "{year}年 {month}月"
|
||||
prev: "前の月"
|
||||
next: "次の月"
|
||||
go: "クリックして時間遡行"
|
||||
desktop/views/components/charts.vue:
|
||||
title: "チャート"
|
||||
per-day: "1日ごと"
|
||||
per-hour: "1時間ごと"
|
||||
federation: "フェデレーション"
|
||||
notes: "投稿"
|
||||
users: "ユーザー"
|
||||
drive: "ドライブ"
|
||||
network: "ネットワーク"
|
||||
charts:
|
||||
federation-instances: "インスタンスの増減"
|
||||
federation-instances-total: "インスタンスの積算"
|
||||
notes: "投稿の増減 (統合)"
|
||||
local-notes: "投稿の増減 (ローカル)"
|
||||
remote-notes: "投稿の増減 (リモート)"
|
||||
notes-total: "投稿の積算"
|
||||
users: "ユーザーの増減"
|
||||
users-total: "ユーザーの積算"
|
||||
drive: "ドライブ使用量の増減"
|
||||
drive-total: "ドライブ使用量の積算"
|
||||
drive-files: "ドライブのファイル数の増減"
|
||||
drive-files-total: "ドライブのファイル数の積算"
|
||||
network-requests: "リクエスト"
|
||||
network-time: "応答時間"
|
||||
network-usage: "通信量"
|
||||
desktop/views/components/choose-file-from-drive-window.vue:
|
||||
choose-file: "ファイル選択中"
|
||||
chosen-files: "{count}ファイル選択中"
|
||||
upload: "PCからドライブにファイルをアップロード"
|
||||
cancel: "キャンセル"
|
||||
ok: "決定"
|
||||
@ -611,7 +627,6 @@ desktop/views/components/drive.folder.vue:
|
||||
input-new-folder-name: "新しいフォルダ名を入力してください"
|
||||
desktop/views/components/drive.vue:
|
||||
search: "検索"
|
||||
load-more: "もっと読み込む"
|
||||
empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね"
|
||||
empty-drive: "ドライブには何もありません。"
|
||||
empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。"
|
||||
@ -635,12 +650,6 @@ desktop/views/components/media-image.vue:
|
||||
desktop/views/components/media-video.vue:
|
||||
sensitive: "閲覧注意"
|
||||
click-to-show: "クリックして表示"
|
||||
desktop/views/components/follow-button.vue:
|
||||
following: "フォロー中"
|
||||
follow: "フォロー"
|
||||
request-pending: "フォロー許可待ち"
|
||||
follow-processing: "フォロー処理中"
|
||||
follow-request: "フォロー申請"
|
||||
desktop/views/components/followers-window.vue:
|
||||
followers: "{} のフォロワー"
|
||||
desktop/views/components/followers.vue:
|
||||
@ -669,27 +678,24 @@ desktop/views/components/messaging-room-window.vue:
|
||||
desktop/views/components/messaging-window.vue:
|
||||
title: "メッセージ"
|
||||
desktop/views/components/note-detail.vue:
|
||||
more: "会話をもっと読み込む"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
reposted-by: "{}がRenote"
|
||||
location: "位置情報"
|
||||
renote: "Renote"
|
||||
add-reaction: "リアクション"
|
||||
undo-reaction: "リアクション解除"
|
||||
desktop/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
reply: "返信"
|
||||
renote: "Renote"
|
||||
add-reaction: "リアクション"
|
||||
undo-reaction: "リアクション解除"
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
load-more: "もっと読み込む"
|
||||
desktop/views/components/notifications.vue:
|
||||
more: "もっと見る"
|
||||
empty: "ありません!"
|
||||
desktop/views/components/post-form.vue:
|
||||
add-visible-user: "+ユーザーを追加"
|
||||
@ -714,6 +720,7 @@ desktop/views/components/post-form.vue:
|
||||
create-poll: "アンケートを作成"
|
||||
text-remain: "残り{}文字"
|
||||
recent-tags: "最近"
|
||||
local-only-message: "この投稿はローカルにのみ公開されます"
|
||||
click-to-tagging: "クリックでタグ付け"
|
||||
visibility: "公開範囲"
|
||||
geolocation-alert: "お使いの端末は位置情報に対応していません"
|
||||
@ -731,17 +738,22 @@ desktop/views/components/renote-form.vue:
|
||||
quote: "引用する..."
|
||||
cancel: "キャンセル"
|
||||
renote: "Renote"
|
||||
renote-home: "Renote (Home)"
|
||||
reposting: "しています..."
|
||||
success: "Renoteしました!"
|
||||
failure: "Renoteに失敗しました"
|
||||
desktop/views/components/renote-form-window.vue:
|
||||
title: "この投稿をRenoteしますか?"
|
||||
desktop/views/pages/user-following-or-followers.vue:
|
||||
following: "{user}のフォロー"
|
||||
followers: "{user}のフォロワー"
|
||||
desktop/views/components/settings-window.vue:
|
||||
settings: "設定"
|
||||
desktop/views/components/settings.vue:
|
||||
profile: "プロフィール"
|
||||
notification: "通知"
|
||||
apps: "アプリ"
|
||||
tags: "ハッシュタグ"
|
||||
mute-and-block: "ミュート/ブロック"
|
||||
blocking: "ブロック"
|
||||
security: "セキュリティ"
|
||||
@ -757,6 +769,8 @@ desktop/views/components/settings.vue:
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
web-search-engine: "ウェブ検索エンジン"
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -776,7 +790,6 @@ desktop/views/components/settings.vue:
|
||||
circle-icons: "円形のアイコンを使用"
|
||||
contrasted-acct: "ユーザー名にコントラストを付ける"
|
||||
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||
show-clock-on-header: "右上に時計を表示する"
|
||||
show-reply-target: "リプライ先を表示する"
|
||||
timeline: "タイムライン"
|
||||
@ -784,27 +797,27 @@ desktop/views/components/settings.vue:
|
||||
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
|
||||
show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する"
|
||||
show-maps: "マップの自動展開"
|
||||
deck-column-align: "デッキのカラムの位置"
|
||||
remain-deleted-note: "削除された投稿を表示し続ける"
|
||||
deck-column-align: "デッキのカラムの配置"
|
||||
deck-column-align-center: "中央"
|
||||
deck-column-align-left: "左"
|
||||
deck-column-align-flexible: "フレキシブル"
|
||||
deck-column-width: "デッキのカラムの幅"
|
||||
deck-column-width-narrow: "狭"
|
||||
deck-column-width-narrower: "やや狭"
|
||||
deck-column-width-normal: "普通"
|
||||
deck-column-width-wider: "やや広"
|
||||
deck-column-width-wide: "広"
|
||||
sound: "サウンド"
|
||||
enable-sounds: "サウンドを有効にする"
|
||||
enable-sounds-desc: "投稿やメッセージを送受信したときなどにサウンドを再生します。この設定はブラウザに記憶されます。"
|
||||
volume: "ボリューム"
|
||||
test: "テスト"
|
||||
language: "言語"
|
||||
pick-language: "言語を選択"
|
||||
recommended: "推奨"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
language-desc: "変更はページの再度読み込み後に反映されます。"
|
||||
cache: "キャッシュ"
|
||||
clean-cache: "クリーンアップ"
|
||||
cache-warn: "クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。"
|
||||
cache-cleared: "キャッシュを削除しました"
|
||||
cache-cleared-desc: "ページを再度読み込みしてください。"
|
||||
auto-watch: "投稿の自動ウォッチ"
|
||||
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
||||
about: "Misskeyについて"
|
||||
operator: "このサーバーの運営者"
|
||||
update: "Misskey Update"
|
||||
@ -843,6 +856,7 @@ desktop/views/components/settings.2fa.vue:
|
||||
enter-password: "パスワードを入力してください"
|
||||
authenticator: "まず、Google Authenticatorをお使いのデバイスにインストールします:"
|
||||
howtoinstall: "インストール方法はこちら"
|
||||
token: "トークン"
|
||||
scan: "次に、表示されているQRコードをスキャンします:"
|
||||
done: "お使いのデバイスに表示されているトークンを入力して完了します:"
|
||||
submit: "完了"
|
||||
@ -857,12 +871,13 @@ common/views/components/api-settings.vue:
|
||||
token: "Token:"
|
||||
enter-password: "パスワードを入力してください"
|
||||
console:
|
||||
title: 'APIコンソール'
|
||||
endpoint: 'エンドポイント'
|
||||
parameter: 'パラメータ'
|
||||
send: '送信'
|
||||
sending: '応答待ち'
|
||||
response: '結果'
|
||||
title: "APIコンソール"
|
||||
endpoint: "エンドポイント"
|
||||
parameter: "パラメータ"
|
||||
credential-info: "「i」パラメータは自動で付与されます。"
|
||||
send: "送信"
|
||||
sending: "応答待ち"
|
||||
response: "結果"
|
||||
desktop/views/components/settings.apps.vue:
|
||||
no-apps: "連携しているアプリケーションはありません"
|
||||
common/views/components/drive-settings.vue:
|
||||
@ -875,6 +890,10 @@ common/views/components/mute-and-block.vue:
|
||||
block: "ブロック"
|
||||
no-muted-users: "ミュートしているユーザーはいません"
|
||||
no-blocked-users: "ブロックしているユーザーはいません"
|
||||
word-mute: "ワードミュート"
|
||||
muted-words: "ミュートされたキーワード"
|
||||
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||
save: "保存"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "パスワードを変更する"
|
||||
enter-current-password: "現在のパスワードを入力してください"
|
||||
@ -882,11 +901,17 @@ common/views/components/password-settings.vue:
|
||||
enter-new-password-again: "もう一度新しいパスワードを入力してください"
|
||||
not-match: "新しいパスワードが一致しません"
|
||||
changed: "パスワードを変更しました"
|
||||
failed: "パスワード変更に失敗しました"
|
||||
desktop/views/components/sub-note-content.vue:
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
media-count: "{}つのメディア"
|
||||
poll: "アンケート"
|
||||
desktop/views/components/settings.tags.vue:
|
||||
title: "タグ"
|
||||
query: "クエリ (省略可)"
|
||||
add: "追加"
|
||||
save: "保存"
|
||||
desktop/views/components/taskmanager.vue:
|
||||
title: "タスクマネージャ"
|
||||
desktop/views/components/timeline.vue:
|
||||
@ -917,7 +942,6 @@ desktop/views/components/ui.header.account.vue:
|
||||
desktop/views/components/ui.header.nav.vue:
|
||||
home: "ホーム"
|
||||
deck: "デッキ"
|
||||
messaging: "メッセージ"
|
||||
game: "ゲーム"
|
||||
desktop/views/components/ui.header.notifications.vue:
|
||||
title: "通知"
|
||||
@ -940,7 +964,6 @@ desktop/views/components/user-preview.vue:
|
||||
desktop/views/components/users-list.vue:
|
||||
all: "すべて"
|
||||
iknow: "知り合い"
|
||||
load-more: "もっと"
|
||||
fetching: "読み込んでいます"
|
||||
desktop/views/components/users-list-item.vue:
|
||||
followed: "フォローされています"
|
||||
@ -951,8 +974,9 @@ admin/views/index.vue:
|
||||
dashboard: "ダッシュボード"
|
||||
instance: "インスタンス"
|
||||
emoji: "カスタム絵文字"
|
||||
moderators: "モデレーター"
|
||||
users: "ユーザー"
|
||||
update: "更新"
|
||||
federation: "連合"
|
||||
announcements: "お知らせ"
|
||||
hashtags: "ハッシュタグ"
|
||||
back-to-misskey: "Misskeyに戻る"
|
||||
@ -964,10 +988,77 @@ admin/views/dashboard.vue:
|
||||
instances: "インスタンス"
|
||||
this-instance: "このインスタンス"
|
||||
federated: "連合"
|
||||
admin/views/instance.vue:
|
||||
instance: "インスタンス"
|
||||
instance-name: "インスタンス名"
|
||||
instance-description: "インスタンスの紹介"
|
||||
host: "ホスト"
|
||||
banner-url: "バナー画像URL"
|
||||
error-image-url: "エラー画像URL"
|
||||
languages: "インスタンスの対象言語"
|
||||
languages-desc: "スペースで区切って複数設定できます。"
|
||||
maintainer-config: "管理者情報"
|
||||
maintainer-name: "管理者名"
|
||||
maintainer-email: "管理者の連絡先"
|
||||
drive-config: "ドライブの設定"
|
||||
cache-remote-files: "リモートのファイルをキャッシュする"
|
||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
|
||||
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
||||
remote-drive-capacity-mb: "リモートユーザーひとりあたりのドライブ容量"
|
||||
mb: "メガバイト単位"
|
||||
recaptcha-config: "reCAPTCHAの設定"
|
||||
recaptcha-info: "reCAPTCHAを有効にする場合、reCAPTCHAトークンを取得する必要があります。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してください。"
|
||||
enable-recaptcha: "reCAPTCHAを有効にする"
|
||||
recaptcha-site-key: "reCAPTCHA site key"
|
||||
recaptcha-secret-key: "reCAPTCHA secret key"
|
||||
twitter-integration-config: "Twitter連携の設定"
|
||||
twitter-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-twitter-integration: "Twitter連携を有効にする"
|
||||
twitter-integration-consumer-key: "Consumer key"
|
||||
twitter-integration-consumer-secret: "Consumer secret"
|
||||
github-integration-config: "GitHub連携の設定"
|
||||
github-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-github-integration: "GitHub連携を有効にする"
|
||||
github-integration-client-id: "Client ID"
|
||||
github-integration-client-secret: "Client Secret"
|
||||
discord-integration-config: "Discord連携の設定"
|
||||
discord-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-discord-integration: "Discord連携を有効にする"
|
||||
discord-integration-client-id: "Client ID"
|
||||
discord-integration-client-secret: "Client Secret"
|
||||
proxy-account-config: "プロキシアカウントの設定"
|
||||
proxy-account-info: "プロキシアカウントは、特定の条件下でユーザーのリモートフォローを代行するアカウントです。例えば、ユーザーがリモートユーザーをリストに入れたとき、リストに入れられたユーザーを誰もフォローしていないとアクティビティがサーバーに配達されないため、代わりにプロキシアカウントがフォローするようにします。"
|
||||
proxy-account-username: "プロキシアカウントのユーザー名"
|
||||
proxy-account-username-desc: "プロキシとして使用するアカウントのユーザー名を指定してください。"
|
||||
proxy-account-warn: "アカウントは自動で作られないため、そのユーザー名のアカウントを予め作成しておく必要があります。"
|
||||
max-note-text-length: "投稿の最大文字数"
|
||||
disable-registration: "ユーザー登録の受付を停止する"
|
||||
disable-local-timeline: "ローカルタイムラインを無効にする"
|
||||
invite: "招待"
|
||||
banner-url: "Banner URL"
|
||||
disableRegistration: "Disable new user registration"
|
||||
disableLocalTimeline: "Disable the local timeline"
|
||||
save: "保存"
|
||||
saved: "保存しました"
|
||||
user-recommendation-config: "おすすめユーザー"
|
||||
enable-external-user-recommendation: "外部ユーザーレコメンデーションを有効にする"
|
||||
external-user-recommendation-engine: "エンジン"
|
||||
external-user-recommendation-engine-desc: "例: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
|
||||
external-user-recommendation-timeout: "タイムアウト"
|
||||
external-user-recommendation-timeout-desc: "ミリ秒単位 (例: 300000)"
|
||||
email-config: "メールサーバーの設定"
|
||||
email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。"
|
||||
enable-email: "メール配信を有効にする"
|
||||
email: "メールアドレス"
|
||||
smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する"
|
||||
smtp-secure-info: "STARTTLS使用時はオフにします。"
|
||||
smtp-host: "SMTPホスト"
|
||||
smtp-port: "SMTPポート"
|
||||
smtp-user: "SMTPユーザー"
|
||||
smtp-pass: "SMTPパスワード"
|
||||
serviceworker-config: "ServiceWorker"
|
||||
enable-serviceworker: "ServiceWorkerを有効にする"
|
||||
serviceworker-info: "プッシュ通知を行うには有効する必要があります。"
|
||||
vapid-publickey: "VAPID公開鍵"
|
||||
vapid-privatekey: "VAPID秘密鍵"
|
||||
vapid-info: "ServiceWorkerを有効にする場合、VAPIDキーペアを生成する必要があります。シェルで次のようにします:"
|
||||
admin/views/charts.vue:
|
||||
title: "チャート"
|
||||
per-day: "1日ごと"
|
||||
@ -993,19 +1084,57 @@ admin/views/charts.vue:
|
||||
network-requests: "リクエスト"
|
||||
network-time: "応答時間"
|
||||
network-usage: "通信量"
|
||||
admin/views/drive.vue:
|
||||
sort:
|
||||
title: "ソート"
|
||||
createdAtAsc: "アップロード日時が古い順"
|
||||
createdAtDesc: "アップロード日時が新しい順"
|
||||
sizeAsc: "サイズが小さい順"
|
||||
sizeDesc: "サイズが大きい順"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
combined: "ローカル+リモート"
|
||||
local: "ローカル"
|
||||
remote: "リモート"
|
||||
delete: "削除"
|
||||
deleted: "削除しました"
|
||||
mark-as-sensitive: "閲覧注意に設定"
|
||||
unmark-as-sensitive: "閲覧注意を解除"
|
||||
admin/views/users.vue:
|
||||
suspend-user: "ユーザーの凍結"
|
||||
operation: "操作"
|
||||
username-or-userid: "ユーザー名またはユーザーID"
|
||||
user-not-found: "ユーザーが見つかりません"
|
||||
lookup: "照会"
|
||||
reset-password: "パスワードをリセット"
|
||||
password-updated: "パスワードは現在「{password}」です"
|
||||
suspend: "凍結"
|
||||
suspended: "凍結しました"
|
||||
unsuspend-user: "ユーザーの凍結の解除"
|
||||
unsuspend: "凍結の解除"
|
||||
unsuspended: "凍結を解除しました"
|
||||
verify-user: "ユーザーの公式アカウント設定"
|
||||
verify: "公式アカウントにする"
|
||||
verified: "公式アカウントにしました"
|
||||
unverify-user: "ユーザーの公式アカウント解除"
|
||||
unverify: "公式アカウントを解除する"
|
||||
unverified: "公式アカウントを解除しました"
|
||||
users:
|
||||
title: "ユーザー"
|
||||
sort:
|
||||
title: "ソート"
|
||||
createdAtAsc: "登録日時が古い順"
|
||||
createdAtDesc: "登録日時が新しい順"
|
||||
updatedAtAsc: "更新日時が古い順"
|
||||
updatedAtDesc: "更新日時が新しい順"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
combined: "ローカル+リモート"
|
||||
local: "ローカル"
|
||||
remote: "リモート"
|
||||
createdAt: "登録日時"
|
||||
updatedAt: "更新日時"
|
||||
admin/views/moderators.vue:
|
||||
add-moderator:
|
||||
title: "モデレーターの登録"
|
||||
add: "登録"
|
||||
added: "モデレーターを登録しました"
|
||||
admin/views/emoji.vue:
|
||||
add-emoji:
|
||||
title: "絵文字の登録"
|
||||
@ -1015,10 +1144,16 @@ admin/views/emoji.vue:
|
||||
aliases-desc: "スペースで区切って複数設定できます。"
|
||||
url: "絵文字画像URL"
|
||||
add: "追加"
|
||||
info: "50KB以下のPNG画像をおすすめします。"
|
||||
added: "絵文字を登録しました"
|
||||
emojis:
|
||||
title: "絵文字一覧"
|
||||
update: "更新"
|
||||
remove: "削除"
|
||||
updated: "更新しました"
|
||||
remove-emoji:
|
||||
are-you-sure: "「$1」を削除しますか?"
|
||||
removed: "削除しました"
|
||||
admin/views/announcements.vue:
|
||||
announcements: "お知らせ"
|
||||
save: "保存"
|
||||
@ -1026,26 +1161,12 @@ admin/views/announcements.vue:
|
||||
add: "追加"
|
||||
title: "タイトル"
|
||||
text: "内容"
|
||||
saved: "保存しました"
|
||||
_remove:
|
||||
are-you-sure: "「$1」を削除しますか?"
|
||||
removed: "削除しました"
|
||||
admin/views/hashtags.vue:
|
||||
hided-tags: "Hidden Tags"
|
||||
desktop/views/pages/deck/deck.tl-column.vue:
|
||||
is-media-only: "メディア投稿のみ"
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
desktop/views/pages/deck/deck.user-column.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
images: "画像"
|
||||
activity: "アクティビティ"
|
||||
timeline: "タイムライン"
|
||||
pinned-notes: "ピン留めされた投稿"
|
||||
push-to-a-list: "リストに追加"
|
||||
desktop/views/pages/stats/stats.vue:
|
||||
all-users: "全てのユーザー"
|
||||
original-users: "このインスタンスのユーザー"
|
||||
all-notes: "全ての投稿"
|
||||
original-notes: "このインスタンスの投稿"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "詳しく..."
|
||||
gotit: "わかった"
|
||||
@ -1060,8 +1181,6 @@ desktop/views/pages/welcome.vue:
|
||||
info: "情報"
|
||||
desktop/views/pages/drive.vue:
|
||||
title: "Misskey Drive"
|
||||
desktop/views/pages/favorites.vue:
|
||||
more: "さらに読み込む"
|
||||
desktop/views/pages/home-customize.vue:
|
||||
title: "ホームのカスタマイズ"
|
||||
desktop/views/pages/note.vue:
|
||||
@ -1074,11 +1193,11 @@ desktop/views/pages/selectdrive.vue:
|
||||
upload: "PCからドライブにファイルをアップロード"
|
||||
desktop/views/pages/search.vue:
|
||||
not-available: "検索機能はインスタンスの設定で無効になっています。"
|
||||
not-found: "「{}」に関する投稿は見つかりませんでした。"
|
||||
not-found: "「{q}」に関する投稿は見つかりませんでした。"
|
||||
desktop/views/pages/share.vue:
|
||||
share-with: "{}で共有"
|
||||
share-with: "{name}で共有"
|
||||
desktop/views/pages/tag.vue:
|
||||
no-posts-found: "ハッシュタグ「{}」が付けられた投稿は見つかりませんでした。"
|
||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||
desktop/views/pages/user-list.users.vue:
|
||||
users: "ユーザー"
|
||||
add-user: "ユーザーを追加"
|
||||
@ -1091,9 +1210,6 @@ desktop/views/pages/user/user.friends.vue:
|
||||
title: "よく話すユーザー"
|
||||
loading: "読み込み中"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
desktop/views/pages/user/user.vue:
|
||||
is-suspended: "このユーザーは凍結されています。"
|
||||
last-used-at: "最終アクセス"
|
||||
desktop/views/pages/user/user.photos.vue:
|
||||
title: "フォト"
|
||||
loading: "読み込み中"
|
||||
@ -1115,8 +1231,9 @@ desktop/views/pages/user/user.header.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
mention: "メンション"
|
||||
is-bot: "このアカウントはBotです"
|
||||
years-old: "歳"
|
||||
years-old: "{age}歳"
|
||||
year: "年"
|
||||
month: "月"
|
||||
day: "日"
|
||||
@ -1124,6 +1241,7 @@ desktop/views/pages/user/user.timeline.vue:
|
||||
default: "投稿"
|
||||
with-replies: "投稿と返信"
|
||||
with-media: "メディア"
|
||||
my-posts: "私の投稿"
|
||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
||||
desktop/views/widgets/messaging.vue:
|
||||
title: "メッセージ"
|
||||
@ -1153,7 +1271,6 @@ mobile/views/components/drive.vue:
|
||||
folder-count: "フォルダ"
|
||||
count-separator: "、"
|
||||
file-count: "ファイル"
|
||||
load-more: "もっと読み込む"
|
||||
nothing-in-drive: "ドライブには何もありません"
|
||||
folder-is-empty: "このフォルダは空です"
|
||||
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
|
||||
@ -1163,8 +1280,6 @@ mobile/views/components/drive.vue:
|
||||
root-move-alert: "現在いる場所はルートで、フォルダではないため移動はできません。移動したいフォルダに移動してからやってください。"
|
||||
url-prompt: "アップロードしたいファイルのURL"
|
||||
uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。"
|
||||
mobile/views/components/drive-file-detail.vue:
|
||||
rename: "名前を変更"
|
||||
mobile/views/components/drive-file-chooser.vue:
|
||||
select-file: "ファイルを選択"
|
||||
mobile/views/components/drive-folder-chooser.vue:
|
||||
@ -1186,7 +1301,7 @@ mobile/views/components/media-image.vue:
|
||||
mobile/views/components/media-video.vue:
|
||||
sensitive: "閲覧注意"
|
||||
click-to-show: "クリックして表示"
|
||||
mobile/views/components/follow-button.vue:
|
||||
common/views/components/follow-button.vue:
|
||||
following: "フォロー中"
|
||||
follow: "フォロー"
|
||||
request-pending: "フォロー許可待ち"
|
||||
@ -1199,14 +1314,12 @@ mobile/views/components/friends-maker.vue:
|
||||
refresh: "もっと見る"
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
mobile/views/components/note-detail.vue:
|
||||
reply: "返信"
|
||||
reaction: "リアクション"
|
||||
reposted-by: "{}がRenote"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1218,11 +1331,7 @@ mobile/views/components/note-sub.vue:
|
||||
admin: "admin"
|
||||
bot: "bot"
|
||||
cat: "cat"
|
||||
mobile/views/components/notes.vue:
|
||||
failed: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
mobile/views/components/notifications.vue:
|
||||
more: "もっと見る"
|
||||
empty: "ありません!"
|
||||
mobile/views/components/post-form.vue:
|
||||
add-visible-user: "ユーザーを追加"
|
||||
@ -1242,14 +1351,12 @@ mobile/views/components/sub-note-content.vue:
|
||||
poll: "アンケート"
|
||||
mobile/views/components/timeline.vue:
|
||||
empty: "投稿がありません"
|
||||
load-more: "もっと"
|
||||
mobile/views/components/ui.header.vue:
|
||||
welcome-back: "おかえりなさい、"
|
||||
adjective: "さん"
|
||||
mobile/views/components/ui.nav.vue:
|
||||
timeline: "タイムライン"
|
||||
notifications: "通知"
|
||||
messaging: "メッセージ"
|
||||
follow-requests: "フォロー申請"
|
||||
search: "検索"
|
||||
favorites: "お気に入り"
|
||||
@ -1263,24 +1370,20 @@ mobile/views/components/ui.nav.vue:
|
||||
mobile/views/components/user-timeline.vue:
|
||||
no-notes: "このユーザーは投稿していないようです。"
|
||||
no-notes-with-media: "メディア付き投稿はありません。"
|
||||
load-more: "もっと"
|
||||
mobile/views/components/users-list.vue:
|
||||
all: "すべて"
|
||||
known: "知り合い"
|
||||
load-more: "もっと"
|
||||
mobile/views/pages/favorites.vue:
|
||||
title: "お気に入り"
|
||||
mobile/views/pages/user-lists.vue:
|
||||
title: "リスト"
|
||||
enter-list-name: "リスト名を入力してください"
|
||||
mobile/views/pages/drive.vue:
|
||||
more: "もっと見る"
|
||||
mobile/views/pages/signup.vue:
|
||||
lets-start: "📦 始めましょう"
|
||||
mobile/views/pages/followers.vue:
|
||||
followers-of: "{}のフォロワー"
|
||||
followers-of: "{name}のフォロワー"
|
||||
mobile/views/pages/following.vue:
|
||||
following-of: "{}のフォロー"
|
||||
following-of: "{name}のフォロー"
|
||||
mobile/views/pages/home.vue:
|
||||
home: "ホーム"
|
||||
local: "ローカル"
|
||||
@ -1289,7 +1392,7 @@ mobile/views/pages/home.vue:
|
||||
mentions: "あなた宛て"
|
||||
messages: "メッセージ"
|
||||
mobile/views/pages/tag.vue:
|
||||
no-posts-found: "ハッシュタグ「{}」が付けられた投稿は見つかりませんでした。"
|
||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||
mobile/views/pages/welcome.vue:
|
||||
signup: "新規登録"
|
||||
mobile/views/pages/widgets.vue:
|
||||
@ -1300,11 +1403,7 @@ mobile/views/pages/widgets.vue:
|
||||
mobile/views/pages/widgets/activity.vue:
|
||||
activity: "アクティビティ"
|
||||
mobile/views/pages/share.vue:
|
||||
share-with: "{}で共有"
|
||||
mobile/views/pages/messaging.vue:
|
||||
messaging: "メッセージ"
|
||||
mobile/views/pages/messaging-room.vue:
|
||||
messaging: "メッセージ"
|
||||
share-with: "{name}で共有"
|
||||
mobile/views/pages/received-follow-requests.vue:
|
||||
title: "フォロー申請"
|
||||
accept: "承認"
|
||||
@ -1320,17 +1419,11 @@ mobile/views/pages/games/reversi.vue:
|
||||
reversi: "リバーシ"
|
||||
mobile/views/pages/search.vue:
|
||||
search: "検索"
|
||||
empty: "「{}」に関する投稿は見つかりませんでした。"
|
||||
not-found: "「{}」に関する投稿は見つかりませんでした。"
|
||||
not-found: "「{q}」に関する投稿は見つかりませんでした。"
|
||||
mobile/views/pages/selectdrive.vue:
|
||||
select-file: "ファイルを選択"
|
||||
mobile/views/pages/settings.vue:
|
||||
signed-in-as: "{}としてサインイン中"
|
||||
lang: "言語"
|
||||
lang-tip: "変更はページの再読み込み後に反映されます。"
|
||||
recommended: "推奨"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
design: "デザインと表示"
|
||||
dark-mode: "ダークモード"
|
||||
i-am-under-limited-internet: "私は通信を制限されている"
|
||||
@ -1347,19 +1440,16 @@ mobile/views/pages/settings.vue:
|
||||
notification-position: "通知の表示"
|
||||
notification-position-bottom: "下"
|
||||
notification-position-top: "上"
|
||||
theme: "テーマ"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
web-search-engine: "ウェブ検索エンジン"
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
twitter: "Twitter連携"
|
||||
twitter-connect: "Twitterアカウントに接続する"
|
||||
twitter-reconnect: "再接続する"
|
||||
twitter-disconnect: "切断する"
|
||||
update: "Misskey Update"
|
||||
version: "バージョン:"
|
||||
latest-version: "最新のバージョン:"
|
||||
@ -1373,7 +1463,6 @@ mobile/views/pages/settings.vue:
|
||||
signout: "サインアウト"
|
||||
sound: "サウンド"
|
||||
enable-sounds: "サウンドを有効にする"
|
||||
mark-as-read-all-unread-notes: "すべての投稿を既読にする"
|
||||
password: "パスワード"
|
||||
mobile/views/pages/user.vue:
|
||||
follows-you: "フォローされています"
|
||||
@ -1383,11 +1472,14 @@ mobile/views/pages/user.vue:
|
||||
overview: "概要"
|
||||
timeline: "タイムライン"
|
||||
media: "メディア"
|
||||
is-suspended: "このユーザーは凍結されています。"
|
||||
mute: "ミュート"
|
||||
unmute: "ミュート解除"
|
||||
block: "ブロック"
|
||||
unblock: "ブロック解除"
|
||||
years-old: "{age}歳"
|
||||
push-to-list: "リストに追加"
|
||||
select-list: "リストを選択してください"
|
||||
list-pushed: "{user}を{list}に追加しました"
|
||||
mobile/views/pages/user/home.vue:
|
||||
recent-notes: "最近の投稿"
|
||||
images: "画像"
|
||||
@ -1398,17 +1490,47 @@ mobile/views/pages/user/home.vue:
|
||||
followers-you-know: "知り合いのフォロワー"
|
||||
last-used-at: "最終ログイン"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
loading: "読み込み中"
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
loading: "読み込み中"
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
loading: "読み込み中"
|
||||
no-notes: "投稿はありません"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
loading: "読み込み中"
|
||||
no-photos: "写真はありません"
|
||||
deck:
|
||||
widgets: "ウィジェット"
|
||||
home: "ホーム"
|
||||
local: "ローカル"
|
||||
hybrid: "ソーシャル"
|
||||
hashtag: "ハッシュタグ"
|
||||
global: "グローバル"
|
||||
mentions: "あなた宛て"
|
||||
direct: "ダイレクト投稿"
|
||||
notifications: "通知"
|
||||
list: "リスト"
|
||||
swap-left: "左に移動"
|
||||
swap-right: "右に移動"
|
||||
swap-up: "上に移動"
|
||||
swap-down: "下に移動"
|
||||
remove: "カラムを削除"
|
||||
add-column: "カラムを追加"
|
||||
rename: "名前を変更"
|
||||
stack-left: "左に重ねる"
|
||||
pop-right: "右に出す"
|
||||
deck/deck.tl-column.vue:
|
||||
is-media-only: "メディア投稿のみ"
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
mention: "メンション"
|
||||
images: "画像"
|
||||
activity: "アクティビティ"
|
||||
timeline: "タイムライン"
|
||||
pinned-notes: "ピン留めされた投稿"
|
||||
push-to-a-list: "リストに追加"
|
||||
docs:
|
||||
edit-this-page-on-github: "間違いや改善点を見つけましたか?"
|
||||
edit-this-page-on-github-link: "このページをGitHubで編集"
|
||||
|
@ -5,7 +5,7 @@
|
||||
const fs = require('fs');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
const langs = ['de-DE', 'en-US', 'fr-FR', 'ja-JP', 'ja-KS', 'pl-PL', 'es-ES', 'nl-NL'];
|
||||
const langs = ['de-DE', 'en-US', 'fr-FR', 'ja-JP', 'ja-KS', 'pl-PL', 'es-ES', 'nl-NL', 'zh-CN', 'ko-KR'];
|
||||
|
||||
const loadLocale = lang => yaml.safeLoad(fs.readFileSync(`${__dirname}/${lang}.yml`, 'utf-8'));
|
||||
const locales = langs.map(lang => ({ [lang]: loadLocale(lang) }));
|
||||
|
2394
locales/ko-KR.yml
@ -25,21 +25,12 @@ common:
|
||||
application-authorization: "Aplicativos autorizados"
|
||||
close: "Fechar"
|
||||
do-not-copy-paste: "Por favor, não digite ou copie o código aqui. A conta pode ser comprometida."
|
||||
BSoD:
|
||||
fatal-error: ":( 致命的な問題が発生しました。"
|
||||
update-browser-os: "お使いのブラウザ(またはOS)のバージョンを更新すると解決する可能性があります。"
|
||||
error-code: "エラーコード"
|
||||
browser-version: "ブラウザ バージョン"
|
||||
client-version: "クライアント バージョン"
|
||||
email-support: "問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。"
|
||||
thanks: "Thank you for using Misskey."
|
||||
load-more: "もっと読み込む"
|
||||
enter-password: "パスワードを入力してください"
|
||||
got-it: "Entendi!"
|
||||
customization-tips:
|
||||
title: "Dicas de personalização"
|
||||
paragraph1: "Personalização da página inicial permite adicionar/remover, arrastar e soltar e reorganizar widgets."
|
||||
paragraph2: "Você pode mudar a visualização de alguns widgets <strong>clicando com o botão <strong>direito.</strong></strong>"
|
||||
paragraph3: "Para apagar um widget, o arraste e solte <strong>na área chamada \"Lixo\"</strong> no cabeçalho."
|
||||
paragraph4: "Para terminar a personalização clique em \"Terminar\" acima e à direita."
|
||||
paragraph: "<p>ホームのカスタマイズでは、ウィジェットを追加/削除したり、ドラッグ&ドロップして並べ替えたりすることができます。</p><p>一部のウィジェットは、<strong><strong>右</strong>クリック</strong>することで表示を変更することができます。</p><p>ウィジェットを削除するには、ヘッダーの<strong>「ゴミ箱」</strong>と書かれたエリアにウィジェットをドラッグ&ドロップします。</p><p>カスタマイズを終了するには、右上の「完了」をクリックします。</p>"
|
||||
gotit: "Entendi!"
|
||||
notification:
|
||||
file-uploaded: "Arquivo enviado!"
|
||||
@ -63,6 +54,7 @@ common:
|
||||
month-and-day: "{day}/{month}"
|
||||
trash: "Lixo"
|
||||
drive: "ドライブ"
|
||||
messaging: "トーク"
|
||||
weekday-short:
|
||||
sunday: "Dom"
|
||||
monday: "Seg"
|
||||
@ -98,7 +90,9 @@ common:
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
local-public: "公開 (ローカルのみ)"
|
||||
local-home: "ホーム (ローカルのみ)"
|
||||
local-followers: "フォロワー (ローカルのみ)"
|
||||
note-placeholders:
|
||||
a: "O que está fazendo?"
|
||||
b: "O que está acontecendo?"
|
||||
@ -115,32 +109,41 @@ common:
|
||||
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: "リバーシのアイコンにコントラストを付ける"
|
||||
use-avatar-reversi-stones: "リバーシの石にアバターを使う"
|
||||
verified-user: "Conta verificada"
|
||||
disable-animated-mfm: "Desativar texto animado nas publicações"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||
always-show-nsfw: "常に閲覧注意のメディアを表示する"
|
||||
always-mark-nsfw: "常にメディアを閲覧注意として投稿"
|
||||
show-full-acct: "ユーザー名のホストを省略しない"
|
||||
show-via: "viaを表示する"
|
||||
reduce-motion: "UIの動きを減らす"
|
||||
this-setting-is-this-device-only: "このデバイスのみ"
|
||||
do-not-use-in-production: 'これは開発ビルドです。本番環境で使用しないでください。'
|
||||
use-os-default-emojis: "OS標準の絵文字を使用"
|
||||
line-width: "線の太さ"
|
||||
line-width-thin: "細い"
|
||||
line-width-normal: "普通"
|
||||
line-width-thick: "太い"
|
||||
do-not-use-in-production: "これは開発ビルドです。本番環境で使用しないでください。"
|
||||
user-suspended: "このユーザーは凍結されています。"
|
||||
is-remote-user: "このユーザー情報はコピーです。"
|
||||
is-remote-post: "この投稿情報はコピーです。"
|
||||
view-on-remote: "正確な情報を見る"
|
||||
renoted-by: "{user}がRenote"
|
||||
error:
|
||||
title: '問題が発生しました'
|
||||
retry: 'やり直す'
|
||||
title: "問題が発生しました"
|
||||
retry: "やり直す"
|
||||
reversi:
|
||||
drawn: "Empatado"
|
||||
my-turn: "Seu turno"
|
||||
opponent-turn: "Turno do oponente"
|
||||
turn-of: "turno de {}"
|
||||
past-turn-of: "turno de {}"
|
||||
won: "{} venceu"
|
||||
turn-of: "{name}のターンです"
|
||||
past-turn-of: "{name}のターン"
|
||||
won: "{name}の勝ち"
|
||||
black: "Pretas"
|
||||
white: "Brancas"
|
||||
total: "Total"
|
||||
this-turn: "Turno de {}"
|
||||
this-turn: "{count}ターン目"
|
||||
widgets:
|
||||
analog-clock: "Relógio analógico"
|
||||
profile: "Perfil"
|
||||
@ -159,36 +162,15 @@ common:
|
||||
users: "Usuário sugeridos"
|
||||
polls: "Enquetes"
|
||||
post-form: "Formulário de publicação"
|
||||
messaging: "Mensagens"
|
||||
server: "Informações do servidor"
|
||||
donation: "Doações"
|
||||
nav: "Navegação"
|
||||
tips: "Dicas"
|
||||
hashtags: "Hashtags"
|
||||
deck:
|
||||
widgets: "Widgets"
|
||||
home: "Início"
|
||||
local: "Local"
|
||||
hybrid: "Social"
|
||||
hashtag: "ハッシュタグ"
|
||||
global: "Global"
|
||||
mentions: "あなた宛て"
|
||||
direct: "ダイレクト投稿"
|
||||
notifications: "Notificações"
|
||||
list: "Listas"
|
||||
swap-left: "Mover para a esquerda"
|
||||
swap-right: "Mover para a direita"
|
||||
swap-up: "Mover para cima"
|
||||
swap-down: "Mover para baixo"
|
||||
remove: "Remover"
|
||||
add-column: "Adicionar coluna"
|
||||
rename: "Renomear"
|
||||
stack-left: "左に重ねる"
|
||||
pop-right: "Acoplar à direita"
|
||||
dev: "アプリの作成に失敗しました。再度お試しください。"
|
||||
ai-chan-kawaii: "藍ちゃかわいい"
|
||||
you: "あなた"
|
||||
auth/views/form.vue:
|
||||
share-access: "Você <b>permite</b> que <i>{{ app.name }}</i> acesse sua conta?"
|
||||
share-access: "<i>{name}</i>があなたのアカウントにアクセスすることを許可しますか?"
|
||||
permission-ask: "Este aplicativo precisa das seguintes permissões:"
|
||||
account-read: "Ver informações da conta."
|
||||
account-write: "Modificar informações da conta."
|
||||
@ -282,6 +264,7 @@ common/views/components/media-banner.vue:
|
||||
sensitive: "閲覧注意"
|
||||
click-to-show: "クリックして表示"
|
||||
common/views/components/theme.vue:
|
||||
theme: "テーマ"
|
||||
light-theme: "非ダークモード時に使用するテーマ"
|
||||
dark-theme: "ダークモード時に使用するテーマ"
|
||||
light-themes: "明るいテーマ"
|
||||
@ -298,6 +281,7 @@ common/views/components/theme.vue:
|
||||
base-theme: "ベーステーマ"
|
||||
base-theme-light: "Light"
|
||||
base-theme-dark: "Dark"
|
||||
find-more-theme: "その他のテーマを入手"
|
||||
theme-name: "テーマ名"
|
||||
preview-created-theme: "プレビュー"
|
||||
invalid-theme: "テーマが正しくありません。"
|
||||
@ -319,13 +303,15 @@ common/views/components/theme.vue:
|
||||
common/views/components/cw-button.vue:
|
||||
hide: "隠す"
|
||||
show: "もっと見る"
|
||||
chars: "{count}文字"
|
||||
files: "{count}ファイル"
|
||||
poll: "アンケート"
|
||||
common/views/components/messaging.vue:
|
||||
search-user: "ユーザーを探す"
|
||||
you: "Você"
|
||||
no-history: "履歴はありません"
|
||||
common/views/components/messaging-room.vue:
|
||||
empty: "このユーザーと話したことはありません"
|
||||
more: "もっと読む"
|
||||
no-history: "これより過去の履歴はありません"
|
||||
resize-form: "ドラッグしてフォームの広さを調整"
|
||||
new-message: "新しいメッセージがあります"
|
||||
@ -349,7 +335,9 @@ common/views/components/nav.vue:
|
||||
develop: "開発者"
|
||||
feedback: "フィードバック"
|
||||
common/views/components/note-menu.vue:
|
||||
mention: "メンション"
|
||||
detail: "詳細"
|
||||
copy-content: "内容をコピー"
|
||||
copy-link: "リンクをコピー"
|
||||
favorite: "お気に入り"
|
||||
unfavorite: "お気に入り解除"
|
||||
@ -373,6 +361,16 @@ common/views/components/poll-editor.vue:
|
||||
destroy: "アンケートを破棄"
|
||||
common/views/components/reaction-picker.vue:
|
||||
choose-reaction: "リアクションを選択"
|
||||
common/views/components/emoji-picker.vue:
|
||||
custom-emoji: "カスタム絵文字"
|
||||
people: "人"
|
||||
animals-and-nature: "動物&自然"
|
||||
food-and-drink: "食べ物&飲み物"
|
||||
activity: "アクティビティ"
|
||||
travel-and-places: "場所"
|
||||
objects: "物"
|
||||
symbols: "記号"
|
||||
flags: "旗"
|
||||
common/views/components/signin.vue:
|
||||
username: "ユーザー名"
|
||||
password: "パスワード"
|
||||
@ -381,6 +379,8 @@ common/views/components/signin.vue:
|
||||
signin: "サインイン"
|
||||
or: "または"
|
||||
signin-with-twitter: "Twitterでログイン"
|
||||
signin-with-github: "GitHubでログイン"
|
||||
signin-with-discord: "Discordでログイン"
|
||||
login-failed: "ログインできませんでした。ユーザー名とパスワードを確認してください。"
|
||||
common/views/components/signup.vue:
|
||||
invitation-code: "招待コード"
|
||||
@ -412,12 +412,31 @@ common/views/components/stream-indicator.vue:
|
||||
connecting: "接続中"
|
||||
reconnecting: "再接続中"
|
||||
connected: "接続完了"
|
||||
common/views/components/twitter-setting.vue:
|
||||
description: "お使いのTwitterアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでTwitterアカウント情報が表示されるようになったり、Twitterを用いた便利なサインインを利用できるようになります。"
|
||||
connected-to: "次のTwitterアカウントに接続されています"
|
||||
common/views/components/notification-settings.vue:
|
||||
title: "通知"
|
||||
mark-as-read-all-notifications: "すべての通知を既読にする"
|
||||
mark-as-read-all-unread-notes: "すべての投稿を既読にする"
|
||||
mark-as-read-all-talk-messages: "すべてのトークを既読にする"
|
||||
auto-watch: "投稿の自動ウォッチ"
|
||||
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
||||
common/views/components/integration-settings.vue:
|
||||
title: "サービス連携"
|
||||
connect: "接続する"
|
||||
disconnect: "切断する"
|
||||
connected-to: "次のアカウントに接続されています"
|
||||
common/views/components/github-setting.vue:
|
||||
description: "お使いのGitHubアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでGitHubアカウント情報が表示されるようになったり、GitHubを用いた便利なサインインを利用できるようになります。"
|
||||
connected-to: "次のGitHubアカウントに接続されています"
|
||||
detail: "詳細..."
|
||||
reconnect: "再接続する"
|
||||
connect: "Twitterと接続する"
|
||||
connect: "GitHubと接続する"
|
||||
disconnect: "切断する"
|
||||
common/views/components/discord-setting.vue:
|
||||
description: "お使いのDiscordアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでDiscordアカウント情報が表示されるようになったり、Discordを用いた便利なサインインを利用できるようになります。"
|
||||
connected-to: "次のDiscordアカウントに接続されています"
|
||||
detail: "詳細..."
|
||||
reconnect: "再接続する"
|
||||
connect: "Discordと接続する"
|
||||
disconnect: "切断する"
|
||||
common/views/components/uploader.vue:
|
||||
waiting: "待機中"
|
||||
@ -429,16 +448,27 @@ common/views/components/visibility-chooser.vue:
|
||||
followers-desc: "自分のフォロワーにのみ公開"
|
||||
specified: "ダイレクト"
|
||||
specified-desc: "指定したユーザーにのみ公開"
|
||||
private: "非公開"
|
||||
local-public: "公開 (ローカルのみ)"
|
||||
local-public-desc: "リモートへは公開しない"
|
||||
local-home: "ホーム (ローカルのみ)"
|
||||
local-followers: "フォロワー (ローカルのみ)"
|
||||
common/views/components/trends.vue:
|
||||
count: "{}人が投稿"
|
||||
empty: "トレンドなし"
|
||||
common/views/components/language-settings.vue:
|
||||
title: "表示言語"
|
||||
pick-language: "言語を選択"
|
||||
recommended: "推奨"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
info: "変更はページの再度読み込み後に反映されます。"
|
||||
common/views/components/profile-editor.vue:
|
||||
title: "プロフィール"
|
||||
name: "名前"
|
||||
account: "アカウント"
|
||||
location: "場所"
|
||||
description: "自己紹介"
|
||||
language: "言語"
|
||||
birthday: "誕生日"
|
||||
avatar: "アイコン"
|
||||
banner: "バナー"
|
||||
@ -446,12 +476,24 @@ common/views/components/profile-editor.vue:
|
||||
is-bot: "このアカウントはBotです"
|
||||
is-locked: "フォローを承認制にする"
|
||||
careful-bot: "Botからのフォローだけ承認制にする"
|
||||
auto-accept-followed: "フォローしているユーザーからのフォローを自動承認する"
|
||||
advanced: "その他"
|
||||
privacy: "プライバシー"
|
||||
save: "保存"
|
||||
saved: "プロフィールを保存しました"
|
||||
uploading: "アップロード中"
|
||||
upload-failed: "アップロードに失敗しました"
|
||||
email: "メール設定"
|
||||
email-address: "メールアドレス"
|
||||
email-verified: "メールアドレスが確認されました"
|
||||
email-not-verified: "メールアドレスが確認されていません。メールボックスをご確認ください。"
|
||||
common/views/components/user-list-editor.vue:
|
||||
users: "ユーザー"
|
||||
rename: "リスト名を変更"
|
||||
delete: "リストを削除"
|
||||
remove-user: "このリストから削除"
|
||||
delete-are-you-sure: "リスト「$1」を削除しますか?"
|
||||
deleted: "削除しました"
|
||||
common/views/widgets/broadcast.vue:
|
||||
fetching: "確認中"
|
||||
no-broadcasts: "お知らせはありません"
|
||||
@ -464,9 +506,6 @@ common/views/widgets/calendar.vue:
|
||||
today: "今日:"
|
||||
this-month: "今月:"
|
||||
this-year: "今年:"
|
||||
common/views/widgets/donation.vue:
|
||||
title: "寄付のお願い"
|
||||
text: "Misskeyの運営にはドメイン、サーバー等のコストが掛かります。Misskeyは広告を掲載したりしないため、収入を皆様からの寄付に頼っています。もしご興味があれば、{}までご連絡ください。ご協力ありがとうございます。"
|
||||
common/views/widgets/photo-stream.vue:
|
||||
title: "フォトストリーム"
|
||||
no-photos: "写真はありません"
|
||||
@ -504,9 +543,11 @@ common/views/widgets/tips.vue:
|
||||
tips-line19: "いくつかのウィンドウはブラウザの外に切り離すことができます"
|
||||
tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています"
|
||||
tips-line21: "APIを利用してbotの開発なども行えます"
|
||||
tips-line23: "まゆかわいいよまゆ"
|
||||
tips-line23: "藍かわいいよ藍"
|
||||
tips-line24: "Misskeyは2014年にサービスを開始しました"
|
||||
tips-line25: "対応ブラウザではMisskeyを開いていなくても通知を受け取れます"
|
||||
common/views/pages/not-found.vue:
|
||||
page-not-found: "ページが見つかりませんでした"
|
||||
common/views/pages/follow.vue:
|
||||
signed-in-as: "{}としてサインイン中"
|
||||
following: "フォロー中"
|
||||
@ -535,37 +576,12 @@ desktop/views/components/activity.vue:
|
||||
title: "アクティビティ"
|
||||
toggle: "表示を切り替え"
|
||||
desktop/views/components/calendar.vue:
|
||||
title: "{1}年 {2}月"
|
||||
title: "{year}年 {month}月"
|
||||
prev: "前の月"
|
||||
next: "次の月"
|
||||
go: "クリックして時間遡行"
|
||||
desktop/views/components/charts.vue:
|
||||
title: "チャート"
|
||||
per-day: "1日ごと"
|
||||
per-hour: "1時間ごと"
|
||||
federation: "フェデレーション"
|
||||
notes: "投稿"
|
||||
users: "ユーザー"
|
||||
drive: "ドライブ"
|
||||
network: "ネットワーク"
|
||||
charts:
|
||||
federation-instances: "インスタンスの増減"
|
||||
federation-instances-total: "インスタンスの積算"
|
||||
notes: "投稿の増減 (統合)"
|
||||
local-notes: "投稿の増減 (ローカル)"
|
||||
remote-notes: "投稿の増減 (リモート)"
|
||||
notes-total: "投稿の積算"
|
||||
users: "ユーザーの増減"
|
||||
users-total: "ユーザーの積算"
|
||||
drive: "ドライブ使用量の増減"
|
||||
drive-total: "ドライブ使用量の積算"
|
||||
drive-files: "ドライブのファイル数の増減"
|
||||
drive-files-total: "ドライブのファイル数の積算"
|
||||
network-requests: "リクエスト"
|
||||
network-time: "応答時間"
|
||||
network-usage: "通信量"
|
||||
desktop/views/components/choose-file-from-drive-window.vue:
|
||||
choose-file: "ファイル選択中"
|
||||
chosen-files: "{count}ファイル選択中"
|
||||
upload: "PCからドライブにファイルをアップロード"
|
||||
cancel: "キャンセル"
|
||||
ok: "決定"
|
||||
@ -611,7 +627,6 @@ desktop/views/components/drive.folder.vue:
|
||||
input-new-folder-name: "新しいフォルダ名を入力してください"
|
||||
desktop/views/components/drive.vue:
|
||||
search: "検索"
|
||||
load-more: "もっと読み込む"
|
||||
empty-draghover: "ドロップですか?いいですよ、ボクはカワイイですからね"
|
||||
empty-drive: "ドライブには何もありません。"
|
||||
empty-drive-description: "右クリックして「ファイルをアップロード」を選んだり、ファイルをドラッグ&ドロップすることでもアップロードできます。"
|
||||
@ -635,12 +650,6 @@ desktop/views/components/media-image.vue:
|
||||
desktop/views/components/media-video.vue:
|
||||
sensitive: "閲覧注意"
|
||||
click-to-show: "クリックして表示"
|
||||
desktop/views/components/follow-button.vue:
|
||||
following: "フォロー中"
|
||||
follow: "フォロー"
|
||||
request-pending: "フォロー許可待ち"
|
||||
follow-processing: "フォロー処理中"
|
||||
follow-request: "フォロー申請"
|
||||
desktop/views/components/followers-window.vue:
|
||||
followers: "{} のフォロワー"
|
||||
desktop/views/components/followers.vue:
|
||||
@ -669,27 +678,24 @@ desktop/views/components/messaging-room-window.vue:
|
||||
desktop/views/components/messaging-window.vue:
|
||||
title: "メッセージ"
|
||||
desktop/views/components/note-detail.vue:
|
||||
more: "会話をもっと読み込む"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
reposted-by: "{}がRenote"
|
||||
location: "位置情報"
|
||||
renote: "Renote"
|
||||
add-reaction: "リアクション"
|
||||
undo-reaction: "リアクション解除"
|
||||
desktop/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
reply: "返信"
|
||||
renote: "Renote"
|
||||
add-reaction: "リアクション"
|
||||
undo-reaction: "リアクション解除"
|
||||
detail: "詳細"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
desktop/views/components/notes.vue:
|
||||
error: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
load-more: "もっと読み込む"
|
||||
desktop/views/components/notifications.vue:
|
||||
more: "もっと見る"
|
||||
empty: "ありません!"
|
||||
desktop/views/components/post-form.vue:
|
||||
add-visible-user: "+ユーザーを追加"
|
||||
@ -714,6 +720,7 @@ desktop/views/components/post-form.vue:
|
||||
create-poll: "アンケートを作成"
|
||||
text-remain: "残り{}文字"
|
||||
recent-tags: "最近"
|
||||
local-only-message: "この投稿はローカルにのみ公開されます"
|
||||
click-to-tagging: "クリックでタグ付け"
|
||||
visibility: "公開範囲"
|
||||
geolocation-alert: "お使いの端末は位置情報に対応していません"
|
||||
@ -731,17 +738,22 @@ desktop/views/components/renote-form.vue:
|
||||
quote: "引用する..."
|
||||
cancel: "キャンセル"
|
||||
renote: "Renote"
|
||||
renote-home: "Renote (Home)"
|
||||
reposting: "しています..."
|
||||
success: "Renoteしました!"
|
||||
failure: "Renoteに失敗しました"
|
||||
desktop/views/components/renote-form-window.vue:
|
||||
title: "この投稿をRenoteしますか?"
|
||||
desktop/views/pages/user-following-or-followers.vue:
|
||||
following: "{user}のフォロー"
|
||||
followers: "{user}のフォロワー"
|
||||
desktop/views/components/settings-window.vue:
|
||||
settings: "設定"
|
||||
desktop/views/components/settings.vue:
|
||||
profile: "プロフィール"
|
||||
notification: "通知"
|
||||
apps: "アプリ"
|
||||
tags: "ハッシュタグ"
|
||||
mute-and-block: "ミュート/ブロック"
|
||||
blocking: "ブロック"
|
||||
security: "セキュリティ"
|
||||
@ -757,6 +769,8 @@ desktop/views/components/settings.vue:
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
web-search-engine: "ウェブ検索エンジン"
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
auto-popout: "ウィンドウの自動ポップアウト"
|
||||
auto-popout-desc: "ウィンドウが開かれるとき、ポップアウト(ブラウザ外に切り離す)可能なら自動でポップアウトします。この設定はブラウザに記憶されます。"
|
||||
advanced: "詳細設定"
|
||||
@ -776,7 +790,6 @@ desktop/views/components/settings.vue:
|
||||
circle-icons: "円形のアイコンを使用"
|
||||
contrasted-acct: "ユーザー名にコントラストを付ける"
|
||||
post-form-on-timeline: "タイムライン上部に投稿フォームを表示する"
|
||||
suggest-recent-hashtags: "最近のハッシュタグを投稿フォームに表示する"
|
||||
show-clock-on-header: "右上に時計を表示する"
|
||||
show-reply-target: "リプライ先を表示する"
|
||||
timeline: "タイムライン"
|
||||
@ -784,27 +797,27 @@ desktop/views/components/settings.vue:
|
||||
show-renoted-my-notes: "自分の投稿のRenoteをタイムラインに表示する"
|
||||
show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する"
|
||||
show-maps: "マップの自動展開"
|
||||
deck-column-align: "デッキのカラムの位置"
|
||||
remain-deleted-note: "削除された投稿を表示し続ける"
|
||||
deck-column-align: "デッキのカラムの配置"
|
||||
deck-column-align-center: "中央"
|
||||
deck-column-align-left: "左"
|
||||
deck-column-align-flexible: "フレキシブル"
|
||||
deck-column-width: "デッキのカラムの幅"
|
||||
deck-column-width-narrow: "狭"
|
||||
deck-column-width-narrower: "やや狭"
|
||||
deck-column-width-normal: "普通"
|
||||
deck-column-width-wider: "やや広"
|
||||
deck-column-width-wide: "広"
|
||||
sound: "サウンド"
|
||||
enable-sounds: "サウンドを有効にする"
|
||||
enable-sounds-desc: "投稿やメッセージを送受信したときなどにサウンドを再生します。この設定はブラウザに記憶されます。"
|
||||
volume: "ボリューム"
|
||||
test: "テスト"
|
||||
language: "言語"
|
||||
pick-language: "言語を選択"
|
||||
recommended: "推奨"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
language-desc: "変更はページの再度読み込み後に反映されます。"
|
||||
cache: "キャッシュ"
|
||||
clean-cache: "クリーンアップ"
|
||||
cache-warn: "クリーンアップを行うと、ブラウザに記憶されたアカウント情報のキャッシュ、書きかけの投稿・返信・メッセージ、およびその他のデータ(設定情報含む)が削除されます。クリーンアップを行った後はページを再度読み込みする必要があります。"
|
||||
cache-cleared: "キャッシュを削除しました"
|
||||
cache-cleared-desc: "ページを再度読み込みしてください。"
|
||||
auto-watch: "投稿の自動ウォッチ"
|
||||
auto-watch-desc: "リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。"
|
||||
about: "Misskeyについて"
|
||||
operator: "このサーバーの運営者"
|
||||
update: "Misskey Update"
|
||||
@ -843,6 +856,7 @@ desktop/views/components/settings.2fa.vue:
|
||||
enter-password: "パスワードを入力してください"
|
||||
authenticator: "まず、Google Authenticatorをお使いのデバイスにインストールします:"
|
||||
howtoinstall: "インストール方法はこちら"
|
||||
token: "トークン"
|
||||
scan: "次に、表示されているQRコードをスキャンします:"
|
||||
done: "お使いのデバイスに表示されているトークンを入力して完了します:"
|
||||
submit: "完了"
|
||||
@ -857,12 +871,13 @@ common/views/components/api-settings.vue:
|
||||
token: "Token:"
|
||||
enter-password: "パスワードを入力してください"
|
||||
console:
|
||||
title: 'APIコンソール'
|
||||
endpoint: 'エンドポイント'
|
||||
parameter: 'パラメータ'
|
||||
send: '送信'
|
||||
sending: '応答待ち'
|
||||
response: '結果'
|
||||
title: "APIコンソール"
|
||||
endpoint: "エンドポイント"
|
||||
parameter: "パラメータ"
|
||||
credential-info: "「i」パラメータは自動で付与されます。"
|
||||
send: "送信"
|
||||
sending: "応答待ち"
|
||||
response: "結果"
|
||||
desktop/views/components/settings.apps.vue:
|
||||
no-apps: "連携しているアプリケーションはありません"
|
||||
common/views/components/drive-settings.vue:
|
||||
@ -875,6 +890,10 @@ common/views/components/mute-and-block.vue:
|
||||
block: "ブロック"
|
||||
no-muted-users: "ミュートしているユーザーはいません"
|
||||
no-blocked-users: "ブロックしているユーザーはいません"
|
||||
word-mute: "ワードミュート"
|
||||
muted-words: "ミュートされたキーワード"
|
||||
muted-words-description: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります"
|
||||
save: "保存"
|
||||
common/views/components/password-settings.vue:
|
||||
reset: "パスワードを変更する"
|
||||
enter-current-password: "現在のパスワードを入力してください"
|
||||
@ -882,11 +901,17 @@ common/views/components/password-settings.vue:
|
||||
enter-new-password-again: "もう一度新しいパスワードを入力してください"
|
||||
not-match: "新しいパスワードが一致しません"
|
||||
changed: "パスワードを変更しました"
|
||||
failed: "パスワード変更に失敗しました"
|
||||
desktop/views/components/sub-note-content.vue:
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
media-count: "{}つのメディア"
|
||||
poll: "アンケート"
|
||||
desktop/views/components/settings.tags.vue:
|
||||
title: "タグ"
|
||||
query: "クエリ (省略可)"
|
||||
add: "追加"
|
||||
save: "保存"
|
||||
desktop/views/components/taskmanager.vue:
|
||||
title: "タスクマネージャ"
|
||||
desktop/views/components/timeline.vue:
|
||||
@ -917,7 +942,6 @@ desktop/views/components/ui.header.account.vue:
|
||||
desktop/views/components/ui.header.nav.vue:
|
||||
home: "ホーム"
|
||||
deck: "デッキ"
|
||||
messaging: "メッセージ"
|
||||
game: "ゲーム"
|
||||
desktop/views/components/ui.header.notifications.vue:
|
||||
title: "通知"
|
||||
@ -940,7 +964,6 @@ desktop/views/components/user-preview.vue:
|
||||
desktop/views/components/users-list.vue:
|
||||
all: "すべて"
|
||||
iknow: "知り合い"
|
||||
load-more: "もっと"
|
||||
fetching: "読み込んでいます"
|
||||
desktop/views/components/users-list-item.vue:
|
||||
followed: "フォローされています"
|
||||
@ -951,8 +974,9 @@ admin/views/index.vue:
|
||||
dashboard: "ダッシュボード"
|
||||
instance: "インスタンス"
|
||||
emoji: "カスタム絵文字"
|
||||
moderators: "モデレーター"
|
||||
users: "ユーザー"
|
||||
update: "更新"
|
||||
federation: "連合"
|
||||
announcements: "お知らせ"
|
||||
hashtags: "ハッシュタグ"
|
||||
back-to-misskey: "Misskeyに戻る"
|
||||
@ -964,10 +988,77 @@ admin/views/dashboard.vue:
|
||||
instances: "インスタンス"
|
||||
this-instance: "このインスタンス"
|
||||
federated: "連合"
|
||||
admin/views/instance.vue:
|
||||
instance: "インスタンス"
|
||||
instance-name: "インスタンス名"
|
||||
instance-description: "インスタンスの紹介"
|
||||
host: "ホスト"
|
||||
banner-url: "バナー画像URL"
|
||||
error-image-url: "エラー画像URL"
|
||||
languages: "インスタンスの対象言語"
|
||||
languages-desc: "スペースで区切って複数設定できます。"
|
||||
maintainer-config: "管理者情報"
|
||||
maintainer-name: "管理者名"
|
||||
maintainer-email: "管理者の連絡先"
|
||||
drive-config: "ドライブの設定"
|
||||
cache-remote-files: "リモートのファイルをキャッシュする"
|
||||
cache-remote-files-desc: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクするようになります。そのためサーバーのストレージを節約できますが、プライバシー設定で直リンクを無効にしているユーザーにはファイルが見えなくなったり、サムネイルが生成されないので通信量が増加します。通常はこの設定をオンにしておくことをおすすめします。"
|
||||
local-drive-capacity-mb: "ローカルユーザーひとりあたりのドライブ容量"
|
||||
remote-drive-capacity-mb: "リモートユーザーひとりあたりのドライブ容量"
|
||||
mb: "メガバイト単位"
|
||||
recaptcha-config: "reCAPTCHAの設定"
|
||||
recaptcha-info: "reCAPTCHAを有効にする場合、reCAPTCHAトークンを取得する必要があります。https://www.google.com/recaptcha/intro/ にアクセスしてトークンを取得してください。"
|
||||
enable-recaptcha: "reCAPTCHAを有効にする"
|
||||
recaptcha-site-key: "reCAPTCHA site key"
|
||||
recaptcha-secret-key: "reCAPTCHA secret key"
|
||||
twitter-integration-config: "Twitter連携の設定"
|
||||
twitter-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-twitter-integration: "Twitter連携を有効にする"
|
||||
twitter-integration-consumer-key: "Consumer key"
|
||||
twitter-integration-consumer-secret: "Consumer secret"
|
||||
github-integration-config: "GitHub連携の設定"
|
||||
github-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-github-integration: "GitHub連携を有効にする"
|
||||
github-integration-client-id: "Client ID"
|
||||
github-integration-client-secret: "Client Secret"
|
||||
discord-integration-config: "Discord連携の設定"
|
||||
discord-integration-info: "コールバックURLは {url} に設定します。"
|
||||
enable-discord-integration: "Discord連携を有効にする"
|
||||
discord-integration-client-id: "Client ID"
|
||||
discord-integration-client-secret: "Client Secret"
|
||||
proxy-account-config: "プロキシアカウントの設定"
|
||||
proxy-account-info: "プロキシアカウントは、特定の条件下でユーザーのリモートフォローを代行するアカウントです。例えば、ユーザーがリモートユーザーをリストに入れたとき、リストに入れられたユーザーを誰もフォローしていないとアクティビティがサーバーに配達されないため、代わりにプロキシアカウントがフォローするようにします。"
|
||||
proxy-account-username: "プロキシアカウントのユーザー名"
|
||||
proxy-account-username-desc: "プロキシとして使用するアカウントのユーザー名を指定してください。"
|
||||
proxy-account-warn: "アカウントは自動で作られないため、そのユーザー名のアカウントを予め作成しておく必要があります。"
|
||||
max-note-text-length: "投稿の最大文字数"
|
||||
disable-registration: "ユーザー登録の受付を停止する"
|
||||
disable-local-timeline: "ローカルタイムラインを無効にする"
|
||||
invite: "招待"
|
||||
banner-url: "Banner URL"
|
||||
disableRegistration: "Disable new user registration"
|
||||
disableLocalTimeline: "Disable the local timeline"
|
||||
save: "保存"
|
||||
saved: "保存しました"
|
||||
user-recommendation-config: "おすすめユーザー"
|
||||
enable-external-user-recommendation: "外部ユーザーレコメンデーションを有効にする"
|
||||
external-user-recommendation-engine: "エンジン"
|
||||
external-user-recommendation-engine-desc: "例: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}"
|
||||
external-user-recommendation-timeout: "タイムアウト"
|
||||
external-user-recommendation-timeout-desc: "ミリ秒単位 (例: 300000)"
|
||||
email-config: "メールサーバーの設定"
|
||||
email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。"
|
||||
enable-email: "メール配信を有効にする"
|
||||
email: "メールアドレス"
|
||||
smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する"
|
||||
smtp-secure-info: "STARTTLS使用時はオフにします。"
|
||||
smtp-host: "SMTPホスト"
|
||||
smtp-port: "SMTPポート"
|
||||
smtp-user: "SMTPユーザー"
|
||||
smtp-pass: "SMTPパスワード"
|
||||
serviceworker-config: "ServiceWorker"
|
||||
enable-serviceworker: "ServiceWorkerを有効にする"
|
||||
serviceworker-info: "プッシュ通知を行うには有効する必要があります。"
|
||||
vapid-publickey: "VAPID公開鍵"
|
||||
vapid-privatekey: "VAPID秘密鍵"
|
||||
vapid-info: "ServiceWorkerを有効にする場合、VAPIDキーペアを生成する必要があります。シェルで次のようにします:"
|
||||
admin/views/charts.vue:
|
||||
title: "チャート"
|
||||
per-day: "1日ごと"
|
||||
@ -993,19 +1084,57 @@ admin/views/charts.vue:
|
||||
network-requests: "リクエスト"
|
||||
network-time: "応答時間"
|
||||
network-usage: "通信量"
|
||||
admin/views/drive.vue:
|
||||
sort:
|
||||
title: "ソート"
|
||||
createdAtAsc: "アップロード日時が古い順"
|
||||
createdAtDesc: "アップロード日時が新しい順"
|
||||
sizeAsc: "サイズが小さい順"
|
||||
sizeDesc: "サイズが大きい順"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
combined: "ローカル+リモート"
|
||||
local: "ローカル"
|
||||
remote: "リモート"
|
||||
delete: "削除"
|
||||
deleted: "削除しました"
|
||||
mark-as-sensitive: "閲覧注意に設定"
|
||||
unmark-as-sensitive: "閲覧注意を解除"
|
||||
admin/views/users.vue:
|
||||
suspend-user: "ユーザーの凍結"
|
||||
operation: "操作"
|
||||
username-or-userid: "ユーザー名またはユーザーID"
|
||||
user-not-found: "ユーザーが見つかりません"
|
||||
lookup: "照会"
|
||||
reset-password: "パスワードをリセット"
|
||||
password-updated: "パスワードは現在「{password}」です"
|
||||
suspend: "凍結"
|
||||
suspended: "凍結しました"
|
||||
unsuspend-user: "ユーザーの凍結の解除"
|
||||
unsuspend: "凍結の解除"
|
||||
unsuspended: "凍結を解除しました"
|
||||
verify-user: "ユーザーの公式アカウント設定"
|
||||
verify: "公式アカウントにする"
|
||||
verified: "公式アカウントにしました"
|
||||
unverify-user: "ユーザーの公式アカウント解除"
|
||||
unverify: "公式アカウントを解除する"
|
||||
unverified: "公式アカウントを解除しました"
|
||||
users:
|
||||
title: "ユーザー"
|
||||
sort:
|
||||
title: "ソート"
|
||||
createdAtAsc: "登録日時が古い順"
|
||||
createdAtDesc: "登録日時が新しい順"
|
||||
updatedAtAsc: "更新日時が古い順"
|
||||
updatedAtDesc: "更新日時が新しい順"
|
||||
origin:
|
||||
title: "オリジン"
|
||||
combined: "ローカル+リモート"
|
||||
local: "ローカル"
|
||||
remote: "リモート"
|
||||
createdAt: "登録日時"
|
||||
updatedAt: "更新日時"
|
||||
admin/views/moderators.vue:
|
||||
add-moderator:
|
||||
title: "モデレーターの登録"
|
||||
add: "登録"
|
||||
added: "モデレーターを登録しました"
|
||||
admin/views/emoji.vue:
|
||||
add-emoji:
|
||||
title: "絵文字の登録"
|
||||
@ -1015,10 +1144,16 @@ admin/views/emoji.vue:
|
||||
aliases-desc: "スペースで区切って複数設定できます。"
|
||||
url: "絵文字画像URL"
|
||||
add: "追加"
|
||||
info: "50KB以下のPNG画像をおすすめします。"
|
||||
added: "絵文字を登録しました"
|
||||
emojis:
|
||||
title: "絵文字一覧"
|
||||
update: "更新"
|
||||
remove: "削除"
|
||||
updated: "更新しました"
|
||||
remove-emoji:
|
||||
are-you-sure: "「$1」を削除しますか?"
|
||||
removed: "削除しました"
|
||||
admin/views/announcements.vue:
|
||||
announcements: "お知らせ"
|
||||
save: "保存"
|
||||
@ -1026,26 +1161,12 @@ admin/views/announcements.vue:
|
||||
add: "追加"
|
||||
title: "タイトル"
|
||||
text: "内容"
|
||||
saved: "保存しました"
|
||||
_remove:
|
||||
are-you-sure: "「$1」を削除しますか?"
|
||||
removed: "削除しました"
|
||||
admin/views/hashtags.vue:
|
||||
hided-tags: "Hidden Tags"
|
||||
desktop/views/pages/deck/deck.tl-column.vue:
|
||||
is-media-only: "メディア投稿のみ"
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
desktop/views/pages/deck/deck.user-column.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
images: "画像"
|
||||
activity: "アクティビティ"
|
||||
timeline: "タイムライン"
|
||||
pinned-notes: "ピン留めされた投稿"
|
||||
push-to-a-list: "リストに追加"
|
||||
desktop/views/pages/stats/stats.vue:
|
||||
all-users: "全てのユーザー"
|
||||
original-users: "このインスタンスのユーザー"
|
||||
all-notes: "全ての投稿"
|
||||
original-notes: "このインスタンスの投稿"
|
||||
desktop/views/pages/welcome.vue:
|
||||
about: "詳しく..."
|
||||
gotit: "わかった"
|
||||
@ -1060,8 +1181,6 @@ desktop/views/pages/welcome.vue:
|
||||
info: "情報"
|
||||
desktop/views/pages/drive.vue:
|
||||
title: "Drive Misskey"
|
||||
desktop/views/pages/favorites.vue:
|
||||
more: "Carregar mais"
|
||||
desktop/views/pages/home-customize.vue:
|
||||
title: "Personalizar a página inicial"
|
||||
desktop/views/pages/note.vue:
|
||||
@ -1074,11 +1193,11 @@ desktop/views/pages/selectdrive.vue:
|
||||
upload: "Envie arquivos do seu dispositivo"
|
||||
desktop/views/pages/search.vue:
|
||||
not-available: "A pesquisa está desligada nas configurações desta instância."
|
||||
not-found: "「{}」に関する投稿は見つかりませんでした。"
|
||||
not-found: "「{q}」に関する投稿は見つかりませんでした。"
|
||||
desktop/views/pages/share.vue:
|
||||
share-with: "{}で共有"
|
||||
share-with: "{name}で共有"
|
||||
desktop/views/pages/tag.vue:
|
||||
no-posts-found: "ハッシュタグ「{}」が付けられた投稿は見つかりませんでした。"
|
||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||
desktop/views/pages/user-list.users.vue:
|
||||
users: "ユーザー"
|
||||
add-user: "ユーザーを追加"
|
||||
@ -1091,9 +1210,6 @@ desktop/views/pages/user/user.friends.vue:
|
||||
title: "よく話すユーザー"
|
||||
loading: "読み込み中"
|
||||
no-users: "よく話すユーザーはいません"
|
||||
desktop/views/pages/user/user.vue:
|
||||
is-suspended: "このユーザーは凍結されています。"
|
||||
last-used-at: "最終アクセス"
|
||||
desktop/views/pages/user/user.photos.vue:
|
||||
title: "フォト"
|
||||
loading: "読み込み中"
|
||||
@ -1115,8 +1231,9 @@ desktop/views/pages/user/user.header.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
mention: "メンション"
|
||||
is-bot: "このアカウントはBotです"
|
||||
years-old: "歳"
|
||||
years-old: "{age}歳"
|
||||
year: "年"
|
||||
month: "月"
|
||||
day: "日"
|
||||
@ -1124,6 +1241,7 @@ desktop/views/pages/user/user.timeline.vue:
|
||||
default: "投稿"
|
||||
with-replies: "投稿と返信"
|
||||
with-media: "メディア"
|
||||
my-posts: "私の投稿"
|
||||
empty: "このユーザーはまだ何も投稿していないようです。"
|
||||
desktop/views/widgets/messaging.vue:
|
||||
title: "メッセージ"
|
||||
@ -1153,7 +1271,6 @@ mobile/views/components/drive.vue:
|
||||
folder-count: "フォルダ"
|
||||
count-separator: "、"
|
||||
file-count: "ファイル"
|
||||
load-more: "もっと読み込む"
|
||||
nothing-in-drive: "ドライブには何もありません"
|
||||
folder-is-empty: "このフォルダは空です"
|
||||
prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>"
|
||||
@ -1163,8 +1280,6 @@ mobile/views/components/drive.vue:
|
||||
root-move-alert: "現在いる場所はルートで、フォルダではないため移動はできません。移動したいフォルダに移動してからやってください。"
|
||||
url-prompt: "アップロードしたいファイルのURL"
|
||||
uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。"
|
||||
mobile/views/components/drive-file-detail.vue:
|
||||
rename: "名前を変更"
|
||||
mobile/views/components/drive-file-chooser.vue:
|
||||
select-file: "ファイルを選択"
|
||||
mobile/views/components/drive-folder-chooser.vue:
|
||||
@ -1186,7 +1301,7 @@ mobile/views/components/media-image.vue:
|
||||
mobile/views/components/media-video.vue:
|
||||
sensitive: "閲覧注意"
|
||||
click-to-show: "クリックして表示"
|
||||
mobile/views/components/follow-button.vue:
|
||||
common/views/components/follow-button.vue:
|
||||
following: "フォロー中"
|
||||
follow: "フォロー"
|
||||
request-pending: "フォロー許可待ち"
|
||||
@ -1199,14 +1314,12 @@ mobile/views/components/friends-maker.vue:
|
||||
refresh: "もっと見る"
|
||||
close: "閉じる"
|
||||
mobile/views/components/note.vue:
|
||||
reposted-by: "{}がRenote"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
mobile/views/components/note-detail.vue:
|
||||
reply: "返信"
|
||||
reaction: "リアクション"
|
||||
reposted-by: "{}がRenote"
|
||||
private: "この投稿は非公開です"
|
||||
deleted: "この投稿は削除されました"
|
||||
location: "位置情報"
|
||||
@ -1218,11 +1331,7 @@ mobile/views/components/note-sub.vue:
|
||||
admin: "admin"
|
||||
bot: "bot"
|
||||
cat: "cat"
|
||||
mobile/views/components/notes.vue:
|
||||
failed: "読み込みに失敗しました。"
|
||||
retry: "リトライ"
|
||||
mobile/views/components/notifications.vue:
|
||||
more: "もっと見る"
|
||||
empty: "ありません!"
|
||||
mobile/views/components/post-form.vue:
|
||||
add-visible-user: "ユーザーを追加"
|
||||
@ -1242,14 +1351,12 @@ mobile/views/components/sub-note-content.vue:
|
||||
poll: "アンケート"
|
||||
mobile/views/components/timeline.vue:
|
||||
empty: "投稿がありません"
|
||||
load-more: "もっと"
|
||||
mobile/views/components/ui.header.vue:
|
||||
welcome-back: "おかえりなさい、"
|
||||
adjective: "さん"
|
||||
mobile/views/components/ui.nav.vue:
|
||||
timeline: "タイムライン"
|
||||
notifications: "通知"
|
||||
messaging: "メッセージ"
|
||||
follow-requests: "フォロー申請"
|
||||
search: "検索"
|
||||
favorites: "お気に入り"
|
||||
@ -1263,24 +1370,20 @@ mobile/views/components/ui.nav.vue:
|
||||
mobile/views/components/user-timeline.vue:
|
||||
no-notes: "このユーザーは投稿していないようです。"
|
||||
no-notes-with-media: "メディア付き投稿はありません。"
|
||||
load-more: "もっと"
|
||||
mobile/views/components/users-list.vue:
|
||||
all: "すべて"
|
||||
known: "知り合い"
|
||||
load-more: "もっと"
|
||||
mobile/views/pages/favorites.vue:
|
||||
title: "お気に入り"
|
||||
mobile/views/pages/user-lists.vue:
|
||||
title: "リスト"
|
||||
enter-list-name: "リスト名を入力してください"
|
||||
mobile/views/pages/drive.vue:
|
||||
more: "もっと見る"
|
||||
mobile/views/pages/signup.vue:
|
||||
lets-start: "📦 始めましょう"
|
||||
mobile/views/pages/followers.vue:
|
||||
followers-of: "{}のフォロワー"
|
||||
followers-of: "{name}のフォロワー"
|
||||
mobile/views/pages/following.vue:
|
||||
following-of: "{}のフォロー"
|
||||
following-of: "{name}のフォロー"
|
||||
mobile/views/pages/home.vue:
|
||||
home: "ホーム"
|
||||
local: "ローカル"
|
||||
@ -1289,7 +1392,7 @@ mobile/views/pages/home.vue:
|
||||
mentions: "あなた宛て"
|
||||
messages: "メッセージ"
|
||||
mobile/views/pages/tag.vue:
|
||||
no-posts-found: "ハッシュタグ「{}」が付けられた投稿は見つかりませんでした。"
|
||||
no-posts-found: "ハッシュタグ「{q}」が付けられた投稿は見つかりませんでした。"
|
||||
mobile/views/pages/welcome.vue:
|
||||
signup: "新規登録"
|
||||
mobile/views/pages/widgets.vue:
|
||||
@ -1300,11 +1403,7 @@ mobile/views/pages/widgets.vue:
|
||||
mobile/views/pages/widgets/activity.vue:
|
||||
activity: "アクティビティ"
|
||||
mobile/views/pages/share.vue:
|
||||
share-with: "{}で共有"
|
||||
mobile/views/pages/messaging.vue:
|
||||
messaging: "メッセージ"
|
||||
mobile/views/pages/messaging-room.vue:
|
||||
messaging: "メッセージ"
|
||||
share-with: "{name}で共有"
|
||||
mobile/views/pages/received-follow-requests.vue:
|
||||
title: "フォロー申請"
|
||||
accept: "承認"
|
||||
@ -1320,17 +1419,11 @@ mobile/views/pages/games/reversi.vue:
|
||||
reversi: "リバーシ"
|
||||
mobile/views/pages/search.vue:
|
||||
search: "Pesquisar"
|
||||
empty: "「{}」に関する投稿は見つかりませんでした。"
|
||||
not-found: "「{}」に関する投稿は見つかりませんでした。"
|
||||
not-found: "「{q}」に関する投稿は見つかりませんでした。"
|
||||
mobile/views/pages/selectdrive.vue:
|
||||
select-file: "ファイルを選択"
|
||||
mobile/views/pages/settings.vue:
|
||||
signed-in-as: "{}としてサインイン中"
|
||||
lang: "言語"
|
||||
lang-tip: "変更はページの再読み込み後に反映されます。"
|
||||
recommended: "推奨"
|
||||
auto: "自動"
|
||||
specify-language: "言語を指定"
|
||||
design: "デザインと表示"
|
||||
dark-mode: "ダークモード"
|
||||
i-am-under-limited-internet: "私は通信を制限されている"
|
||||
@ -1347,19 +1440,16 @@ mobile/views/pages/settings.vue:
|
||||
notification-position: "通知の表示"
|
||||
notification-position-bottom: "下"
|
||||
notification-position-top: "上"
|
||||
theme: "テーマ"
|
||||
behavior: "動作"
|
||||
fetch-on-scroll: "スクロールで自動読み込み"
|
||||
note-visibility: "投稿の公開範囲"
|
||||
default-note-visibility: "デフォルトの公開範囲"
|
||||
remember-note-visibility: "投稿の公開範囲を記憶する"
|
||||
web-search-engine: "ウェブ検索エンジン"
|
||||
web-search-engine-desc: "例: https://www.google.com/?#q={{query}}"
|
||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||
load-raw-images: "添付された画像を高画質で表示する"
|
||||
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||
twitter: "Twitter連携"
|
||||
twitter-connect: "Conectar à sua conta no Twitter"
|
||||
twitter-reconnect: "Reconectar"
|
||||
twitter-disconnect: "Desconectar"
|
||||
update: "Atualizar Misskey"
|
||||
version: "Versão atual;"
|
||||
latest-version: "Última versão:"
|
||||
@ -1373,7 +1463,6 @@ mobile/views/pages/settings.vue:
|
||||
signout: "Sair"
|
||||
sound: "Sons"
|
||||
enable-sounds: "Ativar sons"
|
||||
mark-as-read-all-unread-notes: "すべての投稿を既読にする"
|
||||
password: "パスワード"
|
||||
mobile/views/pages/user.vue:
|
||||
follows-you: "Te segue"
|
||||
@ -1383,11 +1472,14 @@ mobile/views/pages/user.vue:
|
||||
overview: "概要"
|
||||
timeline: "Linha do tempo"
|
||||
media: "Mídia"
|
||||
is-suspended: "Esta conta foi suspensa"
|
||||
mute: "ミュート"
|
||||
unmute: "ミュート解除"
|
||||
block: "ブロック"
|
||||
unblock: "ブロック解除"
|
||||
years-old: "{age}歳"
|
||||
push-to-list: "リストに追加"
|
||||
select-list: "リストを選択してください"
|
||||
list-pushed: "{user}を{list}に追加しました"
|
||||
mobile/views/pages/user/home.vue:
|
||||
recent-notes: "Notas recentes"
|
||||
images: "Imagens"
|
||||
@ -1398,17 +1490,47 @@ mobile/views/pages/user/home.vue:
|
||||
followers-you-know: "Seguidores que você conhece"
|
||||
last-used-at: "Ativo pela última vez"
|
||||
mobile/views/pages/user/home.followers-you-know.vue:
|
||||
loading: "Carregando"
|
||||
no-users: "知り合いのユーザーはいません"
|
||||
mobile/views/pages/user/home.friends.vue:
|
||||
loading: "Carregando"
|
||||
no-users: "よく会話するユーザーはいません"
|
||||
mobile/views/pages/user/home.notes.vue:
|
||||
loading: "Carregando"
|
||||
no-notes: "Nenhuma mensagem"
|
||||
mobile/views/pages/user/home.photos.vue:
|
||||
loading: "Carregando"
|
||||
no-photos: "Sem fotos"
|
||||
deck:
|
||||
widgets: "ウィジェット"
|
||||
home: "ホーム"
|
||||
local: "ローカル"
|
||||
hybrid: "ソーシャル"
|
||||
hashtag: "ハッシュタグ"
|
||||
global: "グローバル"
|
||||
mentions: "あなた宛て"
|
||||
direct: "ダイレクト投稿"
|
||||
notifications: "通知"
|
||||
list: "リスト"
|
||||
swap-left: "左に移動"
|
||||
swap-right: "右に移動"
|
||||
swap-up: "上に移動"
|
||||
swap-down: "下に移動"
|
||||
remove: "カラムを削除"
|
||||
add-column: "カラムを追加"
|
||||
rename: "名前を変更"
|
||||
stack-left: "左に重ねる"
|
||||
pop-right: "右に出す"
|
||||
deck/deck.tl-column.vue:
|
||||
is-media-only: "メディア投稿のみ"
|
||||
is-media-view: "メディアビュー"
|
||||
edit: "オプション"
|
||||
deck/deck.user-column.vue:
|
||||
posts: "投稿"
|
||||
following: "フォロー"
|
||||
followers: "フォロワー"
|
||||
mention: "メンション"
|
||||
images: "画像"
|
||||
activity: "アクティビティ"
|
||||
timeline: "タイムライン"
|
||||
pinned-notes: "ピン留めされた投稿"
|
||||
push-to-a-list: "リストに追加"
|
||||
docs:
|
||||
edit-this-page-on-github: "間違いや改善点を見つけましたか?"
|
||||
edit-this-page-on-github-link: "Edite esta página no GitHub!"
|
||||
|
2538
locales/zh-CN.yml
135
package.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "10.41.0",
|
||||
"clientVersion": "1.0.11594",
|
||||
"version": "10.75.0",
|
||||
"clientVersion": "2.0.13368",
|
||||
"codename": "nighthike",
|
||||
"main": "./built/index.js",
|
||||
"private": true,
|
||||
@ -20,24 +20,23 @@
|
||||
"format": "gulp format"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.8",
|
||||
"@fortawesome/free-brands-svg-icons": "5.5.0",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.12",
|
||||
"@fortawesome/free-brands-svg-icons": "5.6.3",
|
||||
"@fortawesome/free-regular-svg-icons": "5.5.0",
|
||||
"@fortawesome/free-solid-svg-icons": "5.5.0",
|
||||
"@fortawesome/free-solid-svg-icons": "5.6.3",
|
||||
"@fortawesome/vue-fontawesome": "0.1.2",
|
||||
"@koa/cors": "2.2.2",
|
||||
"@koa/cors": "2.2.3",
|
||||
"@prezzemolo/rap": "0.1.2",
|
||||
"@prezzemolo/zip": "0.0.3",
|
||||
"@types/bcryptjs": "2.4.2",
|
||||
"@types/chai-http": "3.0.5",
|
||||
"@types/dateformat": "1.0.1",
|
||||
"@types/dateformat": "3.0.0",
|
||||
"@types/debug": "0.0.31",
|
||||
"@types/deep-equal": "1.0.1",
|
||||
"@types/double-ended-queue": "2.1.0",
|
||||
"@types/elasticsearch": "5.0.28",
|
||||
"@types/file-type": "5.2.1",
|
||||
"@types/elasticsearch": "5.0.30",
|
||||
"@types/file-type": "10.6.0",
|
||||
"@types/gulp": "3.8.36",
|
||||
"@types/gulp-htmlmin": "1.3.32",
|
||||
"@types/gulp-mocha": "0.0.32",
|
||||
"@types/gulp-rename": "0.0.33",
|
||||
"@types/gulp-replace": "0.0.31",
|
||||
@ -45,49 +44,51 @@
|
||||
"@types/gulp-util": "3.0.34",
|
||||
"@types/is-root": "1.0.0",
|
||||
"@types/is-url": "1.2.28",
|
||||
"@types/js-yaml": "3.11.2",
|
||||
"@types/koa": "2.0.46",
|
||||
"@types/koa-bodyparser": "5.0.1",
|
||||
"@types/js-yaml": "3.11.4",
|
||||
"@types/katex": "0.5.0",
|
||||
"@types/koa": "2.0.48",
|
||||
"@types/koa-bodyparser": "5.0.2",
|
||||
"@types/koa-compress": "2.0.8",
|
||||
"@types/koa-favicon": "2.0.19",
|
||||
"@types/koa-logger": "3.1.1",
|
||||
"@types/koa-mount": "3.0.1",
|
||||
"@types/koa-multer": "1.0.0",
|
||||
"@types/koa-router": "7.0.32",
|
||||
"@types/koa-router": "7.0.35",
|
||||
"@types/koa-send": "4.1.1",
|
||||
"@types/koa-views": "2.0.3",
|
||||
"@types/koa__cors": "2.2.3",
|
||||
"@types/minio": "7.0.0",
|
||||
"@types/minio": "7.0.1",
|
||||
"@types/mkdirp": "0.5.2",
|
||||
"@types/mocha": "5.2.5",
|
||||
"@types/mongodb": "3.1.12",
|
||||
"@types/mongodb": "3.1.14",
|
||||
"@types/ms": "0.7.30",
|
||||
"@types/node": "10.12.2",
|
||||
"@types/node": "10.12.18",
|
||||
"@types/nodemailer": "4.6.5",
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/parsimmon": "1.10.0",
|
||||
"@types/portscanner": "2.1.0",
|
||||
"@types/pug": "2.0.4",
|
||||
"@types/qrcode": "1.3.0",
|
||||
"@types/ratelimiter": "2.1.28",
|
||||
"@types/redis": "2.8.7",
|
||||
"@types/request": "2.48.0",
|
||||
"@types/redis": "2.8.10",
|
||||
"@types/request": "2.48.1",
|
||||
"@types/request-promise-native": "1.0.15",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@types/seedrandom": "2.4.27",
|
||||
"@types/sharp": "0.21.0",
|
||||
"@types/showdown": "1.7.5",
|
||||
"@types/single-line-log": "1.1.0",
|
||||
"@types/showdown": "1.9.0",
|
||||
"@types/speakeasy": "2.0.3",
|
||||
"@types/systeminformation": "3.23.0",
|
||||
"@types/systeminformation": "3.23.1",
|
||||
"@types/tinycolor2": "1.4.1",
|
||||
"@types/tmp": "0.0.33",
|
||||
"@types/uuid": "3.4.4",
|
||||
"@types/webpack": "4.4.17",
|
||||
"@types/webpack": "4.4.21",
|
||||
"@types/webpack-stream": "3.2.10",
|
||||
"@types/websocket": "0.0.40",
|
||||
"@types/ws": "6.0.1",
|
||||
"animejs": "2.2.0",
|
||||
"apexcharts": "2.1.9",
|
||||
"autobind-decorator": "2.1.0",
|
||||
"apexcharts": "2.5.1",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.2",
|
||||
"autwh": "0.1.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
@ -100,46 +101,48 @@
|
||||
"commander": "2.19.0",
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "1.0.1",
|
||||
"cssnano": "4.1.7",
|
||||
"dateformat": "3.0.3",
|
||||
"debug": "4.1.0",
|
||||
"deep-equal": "1.0.1",
|
||||
"deepcopy": "0.6.3",
|
||||
"diskusage": "0.2.5",
|
||||
"diskusage": "1.0.0",
|
||||
"double-ended-queue": "2.1.0-0",
|
||||
"elasticsearch": "15.2.0",
|
||||
"emojilib": "2.3.0",
|
||||
"emojilib": "2.4.0",
|
||||
"escape-regexp": "0.0.1",
|
||||
"eslint": "5.8.0",
|
||||
"eslint-plugin-vue": "4.7.1",
|
||||
"eslint": "5.11.1",
|
||||
"eslint-plugin-vue": "5.0.0",
|
||||
"eventemitter3": "3.1.0",
|
||||
"feed": "2.0.2",
|
||||
"file-loader": "2.0.0",
|
||||
"file-type": "10.4.0",
|
||||
"file-type": "10.7.0",
|
||||
"fuckadblock": "3.2.1",
|
||||
"gulp": "3.9.1",
|
||||
"gulp-cssnano": "2.1.3",
|
||||
"gulp-htmlmin": "5.0.1",
|
||||
"gulp-imagemin": "4.1.0",
|
||||
"gulp-mocha": "6.0.0",
|
||||
"gulp-pug": "4.0.1",
|
||||
"gulp-rename": "1.4.0",
|
||||
"gulp-replace": "1.0.0",
|
||||
"gulp-sourcemaps": "2.6.4",
|
||||
"gulp-stylus": "2.7.0",
|
||||
"gulp-tslint": "8.1.3",
|
||||
"gulp-typescript": "4.0.2",
|
||||
"gulp-typescript": "5.0.0",
|
||||
"gulp-uglify": "3.0.1",
|
||||
"gulp-util": "3.0.8",
|
||||
"hard-source-webpack-plugin": "0.12.0",
|
||||
"gulp-yaml": "2.0.2",
|
||||
"hard-source-webpack-plugin": "0.13.1",
|
||||
"html-minifier": "3.5.21",
|
||||
"http-signature": "1.2.0",
|
||||
"insert-text-at-cursor": "0.1.1",
|
||||
"is-root": "2.0.0",
|
||||
"is-url": "1.2.4",
|
||||
"js-yaml": "3.12.0",
|
||||
"jsdom": "13.0.0",
|
||||
"jsdom": "13.1.0",
|
||||
"json5": "2.1.0",
|
||||
"json5-loader": "1.0.1",
|
||||
"koa": "2.6.1",
|
||||
"katex": "0.10.0",
|
||||
"koa": "2.6.2",
|
||||
"koa-bodyparser": "4.2.1",
|
||||
"koa-compress": "3.0.0",
|
||||
"koa-favicon": "2.0.1",
|
||||
@ -151,30 +154,36 @@
|
||||
"koa-send": "5.0.0",
|
||||
"koa-slow": "2.1.0",
|
||||
"koa-views": "6.1.4",
|
||||
"loader-utils": "1.1.0",
|
||||
"mecab-async": "0.1.2",
|
||||
"merge-options": "1.0.1",
|
||||
"minio": "7.0.1",
|
||||
"langmap": "0.0.16",
|
||||
"loader-utils": "1.2.3",
|
||||
"lookup-dns-cache": "2.1.0",
|
||||
"minio": "7.0.2",
|
||||
"mkdirp": "0.5.1",
|
||||
"mocha": "5.2.0",
|
||||
"moji": "0.5.1",
|
||||
"mongodb": "3.1.8",
|
||||
"moment": "2.23.0",
|
||||
"mongodb": "3.1.10",
|
||||
"monk": "6.0.6",
|
||||
"ms": "2.1.1",
|
||||
"nan": "2.11.1",
|
||||
"nan": "2.12.1",
|
||||
"nested-property": "0.0.7",
|
||||
"nodemailer": "5.0.0",
|
||||
"nprogress": "0.2.0",
|
||||
"object-assign-deep": "0.4.0",
|
||||
"on-build-webpack": "0.1.0",
|
||||
"os-utils": "0.0.14",
|
||||
"parse5": "5.1.0",
|
||||
"parsimmon": "1.12.0",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss-loader": "3.0.0",
|
||||
"progress-bar-webpack-plugin": "1.11.0",
|
||||
"promise-any": "0.2.0",
|
||||
"promise-limit": "2.7.0",
|
||||
"promise-sequential": "1.1.1",
|
||||
"pug": "2.0.3",
|
||||
"punycode": "2.1.1",
|
||||
"qrcode": "1.3.0",
|
||||
"qrcode": "1.3.2",
|
||||
"randomcolor": "0.5.3",
|
||||
"ratelimiter": "3.2.0",
|
||||
"recaptcha-promise": "0.1.3",
|
||||
"reconnecting-websocket": "4.1.10",
|
||||
@ -185,53 +194,55 @@
|
||||
"rimraf": "2.6.2",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"sass-loader": "7.1.0",
|
||||
"seedrandom": "2.4.4",
|
||||
"sharp": "0.21.0",
|
||||
"showdown": "1.8.7",
|
||||
"sharp": "0.21.1",
|
||||
"showdown": "1.9.0",
|
||||
"showdown-highlightjs-extension": "0.1.2",
|
||||
"single-line-log": "1.1.2",
|
||||
"speakeasy": "2.0.0",
|
||||
"stringz": "1.0.0",
|
||||
"style-loader": "0.23.1",
|
||||
"stylus": "0.54.5",
|
||||
"stylus-loader": "3.0.2",
|
||||
"summaly": "2.2.0",
|
||||
"systeminformation": "3.45.9",
|
||||
"systeminformation": "3.52.2",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"terser-webpack-plugin": "1.2.1",
|
||||
"textarea-caret": "3.1.0",
|
||||
"tinycolor2": "1.4.1",
|
||||
"tmp": "0.0.33",
|
||||
"ts-loader": "5.3.0",
|
||||
"ts-loader": "5.3.1",
|
||||
"ts-node": "7.0.1",
|
||||
"tslint": "5.10.0",
|
||||
"typescript": "3.1.5",
|
||||
"typescript-eslint-parser": "20.1.1",
|
||||
"tslint": "5.12.0",
|
||||
"tslint-sonarts": "1.8.0",
|
||||
"typescript": "3.2.2",
|
||||
"typescript-eslint-parser": "21.0.2",
|
||||
"uglify-es": "3.3.9",
|
||||
"url-loader": "1.1.2",
|
||||
"uuid": "3.3.2",
|
||||
"v-animate-css": "0.0.2",
|
||||
"v-animate-css": "0.0.3",
|
||||
"vue": "2.5.17",
|
||||
"vue-color": "2.7.0",
|
||||
"vue-content-loading": "1.5.3",
|
||||
"vue-cropperjs": "2.2.2",
|
||||
"vue-js-modal": "1.3.26",
|
||||
"vue-cropperjs": "3.0.0",
|
||||
"vue-i18n": "8.6.0",
|
||||
"vue-js-modal": "1.3.28",
|
||||
"vue-loader": "15.4.2",
|
||||
"vue-router": "3.0.1",
|
||||
"vue-marquee-text-component": "1.1.1",
|
||||
"vue-router": "3.0.2",
|
||||
"vue-sequential-entrance": "1.1.3",
|
||||
"vue-style-loader": "4.1.2",
|
||||
"vue-svg-inline-loader": "1.2.1",
|
||||
"vue-sweetalert2": "1.5.6",
|
||||
"vue-svg-inline-loader": "1.2.7",
|
||||
"vue-template-compiler": "2.5.17",
|
||||
"vuedraggable": "2.16.0",
|
||||
"vuedraggable": "2.17.0",
|
||||
"vuewordcloud": "18.7.11",
|
||||
"vuex": "3.0.1",
|
||||
"vuex-persistedstate": "2.5.4",
|
||||
"web-push": "3.3.3",
|
||||
"webfinger.js": "2.6.6",
|
||||
"webpack": "4.25.1",
|
||||
"webfinger.js": "2.7.0",
|
||||
"webpack": "4.28.3",
|
||||
"webpack-cli": "3.1.2",
|
||||
"websocket": "1.0.28",
|
||||
"ws": "6.1.0",
|
||||
"ws": "6.1.2",
|
||||
"xev": "2.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,15 @@
|
||||
* チャートエンジン
|
||||
*/
|
||||
|
||||
import * as moment from 'moment';
|
||||
const nestedProperty = require('nested-property');
|
||||
import autobind from 'autobind-decorator';
|
||||
import * as mongo from 'mongodb';
|
||||
import db from '../db/mongodb';
|
||||
import { ICollection } from 'monk';
|
||||
|
||||
const utc = moment.utc;
|
||||
|
||||
export type Obj = { [key: string]: any };
|
||||
|
||||
export type Partial<T> = {
|
||||
@ -58,11 +61,12 @@ export default abstract class Chart<T> {
|
||||
|
||||
constructor(name: string, grouped = false) {
|
||||
this.collection = db.get<Log<T>>(`chart.${name}`);
|
||||
if (grouped) {
|
||||
this.collection.createIndex({ span: -1, date: -1, group: -1 }, { unique: true });
|
||||
} else {
|
||||
this.collection.createIndex({ span: -1, date: -1 }, { unique: true });
|
||||
}
|
||||
const keys = {
|
||||
span: -1,
|
||||
date: -1
|
||||
} as { [key: string]: 1 | -1; };
|
||||
if (grouped) keys.group = -1;
|
||||
this.collection.createIndex(keys, { unique: true });
|
||||
}
|
||||
|
||||
@autobind
|
||||
@ -70,14 +74,14 @@ export default abstract class Chart<T> {
|
||||
const query: Obj = {};
|
||||
|
||||
const dive = (x: Obj, path: string) => {
|
||||
Object.entries(x).forEach(([k, v]) => {
|
||||
for (const [k, v] of Object.entries(x)) {
|
||||
const p = path ? `${path}.${k}` : k;
|
||||
if (typeof v === 'number') {
|
||||
query[p] = v;
|
||||
} else {
|
||||
dive(v, p);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
dive(x, path);
|
||||
@ -87,12 +91,12 @@ export default abstract class Chart<T> {
|
||||
|
||||
@autobind
|
||||
private getCurrentDate(): [number, number, number, number] {
|
||||
const now = new Date();
|
||||
const now = moment().utc();
|
||||
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
const h = now.getHours();
|
||||
const y = now.year();
|
||||
const m = now.month();
|
||||
const d = now.date();
|
||||
const h = now.hour();
|
||||
|
||||
return [y, m, d, h];
|
||||
}
|
||||
@ -114,15 +118,15 @@ export default abstract class Chart<T> {
|
||||
const [y, m, d, h] = this.getCurrentDate();
|
||||
|
||||
const current =
|
||||
span == 'day' ? new Date(y, m, d) :
|
||||
span == 'hour' ? new Date(y, m, d, h) :
|
||||
span == 'day' ? utc([y, m, d]) :
|
||||
span == 'hour' ? utc([y, m, d, h]) :
|
||||
null;
|
||||
|
||||
// 現在(今日または今のHour)のログ
|
||||
const currentLog = await this.collection.findOne({
|
||||
group: group,
|
||||
span: span,
|
||||
date: current
|
||||
date: current.toDate()
|
||||
});
|
||||
|
||||
// ログがあればそれを返して終了
|
||||
@ -158,7 +162,7 @@ export default abstract class Chart<T> {
|
||||
log = await this.collection.insert({
|
||||
group: group,
|
||||
span: span,
|
||||
date: current,
|
||||
date: current.toDate(),
|
||||
data: data
|
||||
});
|
||||
} catch (e) {
|
||||
@ -225,8 +229,8 @@ export default abstract class Chart<T> {
|
||||
const [y, m, d, h] = this.getCurrentDate();
|
||||
|
||||
const gt =
|
||||
span == 'day' ? new Date(y, m, d - range) :
|
||||
span == 'hour' ? new Date(y, m, d, h - range) :
|
||||
span == 'day' ? utc([y, m, d]).subtract(range, 'days') :
|
||||
span == 'hour' ? utc([y, m, d, h]).subtract(range, 'hours') :
|
||||
null;
|
||||
|
||||
// ログ取得
|
||||
@ -234,7 +238,7 @@ export default abstract class Chart<T> {
|
||||
group: group,
|
||||
span: span,
|
||||
date: {
|
||||
$gt: gt
|
||||
$gte: gt.toDate()
|
||||
}
|
||||
}, {
|
||||
sort: {
|
||||
@ -264,22 +268,45 @@ export default abstract class Chart<T> {
|
||||
if (recentLog) {
|
||||
logs = [recentLog];
|
||||
}
|
||||
|
||||
// 要求された範囲の最も古い箇所に位置するログが存在しなかったら
|
||||
} else if (!utc(logs[logs.length - 1].date).isSame(gt)) {
|
||||
// 要求された範囲の最も古い箇所時点での最も新しいログを持ってきて末尾に追加する
|
||||
// (隙間埋めできないため)
|
||||
const outdatedLog = await this.collection.findOne({
|
||||
group: group,
|
||||
span: span,
|
||||
date: {
|
||||
$lt: gt.toDate()
|
||||
}
|
||||
}, {
|
||||
sort: {
|
||||
date: -1
|
||||
},
|
||||
fields: {
|
||||
_id: 0
|
||||
}
|
||||
});
|
||||
|
||||
if (outdatedLog) {
|
||||
logs.push(outdatedLog);
|
||||
}
|
||||
}
|
||||
|
||||
// 整形
|
||||
for (let i = (range - 1); i >= 0; i--) {
|
||||
const current =
|
||||
span == 'day' ? new Date(y, m, d - i) :
|
||||
span == 'hour' ? new Date(y, m, d, h - i) :
|
||||
span == 'day' ? utc([y, m, d]).subtract(i, 'days') :
|
||||
span == 'hour' ? utc([y, m, d, h]).subtract(i, 'hours') :
|
||||
null;
|
||||
|
||||
const log = logs.find(l => l.date.getTime() == current.getTime());
|
||||
const log = logs.find(l => utc(l.date).isSame(current));
|
||||
|
||||
if (log) {
|
||||
promisedChart.unshift(Promise.resolve(log.data));
|
||||
} else {
|
||||
// 隙間埋め
|
||||
const latest = logs.find(l => l.date.getTime() < current.getTime());
|
||||
const latest = logs.find(l => utc(l.date).isBefore(current));
|
||||
promisedChart.unshift(this.getTemplate(false, latest ? latest.data : null));
|
||||
}
|
||||
}
|
||||
@ -307,14 +334,14 @@ export default abstract class Chart<T> {
|
||||
* にする
|
||||
*/
|
||||
const dive = (x: Obj, path?: string) => {
|
||||
Object.entries(x).forEach(([k, v]) => {
|
||||
for (const [k, v] of Object.entries(x)) {
|
||||
const p = path ? `${path}.${k}` : k;
|
||||
if (typeof v == 'object') {
|
||||
dive(v, p);
|
||||
} else {
|
||||
nestedProperty.set(res, p, chart.map(s => nestedProperty.get(s, p)));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
dive(chart[0]);
|
||||
|
@ -9,6 +9,7 @@ import './style.styl';
|
||||
|
||||
import init from '../init';
|
||||
import Index from './views/index.vue';
|
||||
import NotFound from '../common/views/pages/not-found.vue';
|
||||
|
||||
init(launch => {
|
||||
document.title = 'Admin';
|
||||
@ -19,6 +20,7 @@ init(launch => {
|
||||
base: '/admin/',
|
||||
routes: [
|
||||
{ path: '/', component: Index },
|
||||
{ path: '*', component: NotFound }
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -1,30 +1,32 @@
|
||||
<template>
|
||||
<div class="cdeuzmsthagexbkpofbmatmugjuvogfb">
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="broadcast-tower"/> %i18n:@announcements%</div>
|
||||
<div slot="title"><fa icon="broadcast-tower"/> {{ $t('announcements') }}</div>
|
||||
<section v-for="(announcement, i) in announcements" class="fit-top">
|
||||
<ui-input v-model="announcement.title" @change="save">
|
||||
<span>%i18n:@title%</span>
|
||||
<span>{{ $t('title') }}</span>
|
||||
</ui-input>
|
||||
<ui-textarea v-model="announcement.text">
|
||||
<span>%i18n:@text%</span>
|
||||
<span>{{ $t('text') }}</span>
|
||||
</ui-textarea>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="save()"><fa :icon="['far', 'save']"/> %i18n:@save%</ui-button>
|
||||
<ui-button @click="remove(i)"><fa :icon="['far', 'trash-alt']"/> %i18n:@remove%</ui-button>
|
||||
<ui-horizon-group class="fit-bottom">
|
||||
<ui-button @click="save()"><fa :icon="['far', 'save']"/> {{ $t('save') }}</ui-button>
|
||||
<ui-button @click="remove(i)"><fa :icon="['far', 'trash-alt']"/> {{ $t('remove') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="add"><fa icon="plus"/> %i18n:@add%</ui-button>
|
||||
<ui-button @click="add"><fa icon="plus"/> {{ $t('add') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/announcements.vue'),
|
||||
data() {
|
||||
return {
|
||||
announcements: [],
|
||||
@ -32,47 +34,47 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
created() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.announcements = meta.broadcasts;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
add() {
|
||||
this.announcements.push({
|
||||
this.announcements.unshift({
|
||||
title: '',
|
||||
text: ''
|
||||
});
|
||||
},
|
||||
|
||||
remove(i) {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'warning',
|
||||
text: '%i18n:@_remove.are-you-sure%'.replace('$1', this.announcements.find((_, j) => j == i).title),
|
||||
text: this.$t('_remove.are-you-sure').replace('$1', this.announcements.find((_, j) => j == i).title),
|
||||
showCancelButton: true
|
||||
}).then(res => {
|
||||
if (!res.value) return;
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
this.announcements = this.announcements.filter((_, j) => j !== i);
|
||||
this.save(true);
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: '%i18n:@_remove.removed%'
|
||||
text: this.$t('_remove.removed')
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
save(silent) {
|
||||
(this as any).api('admin/update-meta', {
|
||||
this.$root.api('admin/update-meta', {
|
||||
broadcasts: this.announcements
|
||||
}).then(() => {
|
||||
if (!silent) {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: '%i18n:@saved%'
|
||||
text: this.$t('saved')
|
||||
});
|
||||
}
|
||||
}).catch(e => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
|
@ -3,17 +3,17 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><fa icon="exchange-alt"/> In/Out</th>
|
||||
<th><fa :icon="faExchangeAlt"/> In/Out</th>
|
||||
<th><fa :icon="faBolt"/> Activity</th>
|
||||
<th><fa icon="server"/> Host</th>
|
||||
<th><fa icon="bolt"/> Activity</th>
|
||||
<th><fa icon="user"/> Actor</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="log in logs" :key="log.id">
|
||||
<td :class="log.direction">{{ log.direction == 'in' ? '<' : '>' }} {{ log.direction }}</td>
|
||||
<td>{{ log.host }}</td>
|
||||
<td>{{ log.activity }}</td>
|
||||
<td>{{ log.host }}</td>
|
||||
<td>@{{ log.actor }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -23,17 +23,19 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { faBolt, faExchangeAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
logs: [],
|
||||
connection: null
|
||||
connection: null,
|
||||
faBolt, faExchangeAlt
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.connection = (this as any).os.stream.useSharedConnection('apLog');
|
||||
this.connection = this.$root.stream.useSharedConnection('apLog');
|
||||
this.connection.on('log', this.onLog);
|
||||
this.connection.on('logs', this.onLogs);
|
||||
this.connection.send('requestLog', {
|
||||
@ -54,7 +56,9 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
onLogs(logs) {
|
||||
logs.reverse().forEach(log => this.onLog(log));
|
||||
for (const log of logs.reverse()) {
|
||||
this.onLog(log)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -65,7 +69,7 @@ export default Vue.extend({
|
||||
display block
|
||||
padding 12px 16px 16px 16px
|
||||
height 250px
|
||||
overflow hidden
|
||||
overflow auto
|
||||
box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
|
||||
background var(--adminDashboardCardBg)
|
||||
border-radius 8px
|
||||
|
@ -1,36 +1,36 @@
|
||||
<template>
|
||||
<div class="qvgidhudpqhjttdhxubzuyrhyzgslujw">
|
||||
<header>
|
||||
<b><fa :icon="['far', 'chart-bar']"/> %i18n:@title%:</b>
|
||||
<b><fa :icon="['far', 'chart-bar']"/> {{ $t('title') }}:</b>
|
||||
<select v-model="src">
|
||||
<optgroup label="%i18n:@federation%">
|
||||
<option value="federation-instances">%i18n:@charts.federation-instances%</option>
|
||||
<option value="federation-instances-total">%i18n:@charts.federation-instances-total%</option>
|
||||
<optgroup :label="$t('federation')">
|
||||
<option value="federation-instances">{{ $t('charts.federation-instances') }}</option>
|
||||
<option value="federation-instances-total">{{ $t('charts.federation-instances-total') }}</option>
|
||||
</optgroup>
|
||||
<optgroup label="%i18n:@users%">
|
||||
<option value="users">%i18n:@charts.users%</option>
|
||||
<option value="users-total">%i18n:@charts.users-total%</option>
|
||||
<optgroup :label="$t('users')">
|
||||
<option value="users">{{ $t('charts.users') }}</option>
|
||||
<option value="users-total">{{ $t('charts.users-total') }}</option>
|
||||
</optgroup>
|
||||
<optgroup label="%i18n:@notes%">
|
||||
<option value="notes">%i18n:@charts.notes%</option>
|
||||
<option value="local-notes">%i18n:@charts.local-notes%</option>
|
||||
<option value="remote-notes">%i18n:@charts.remote-notes%</option>
|
||||
<option value="notes-total">%i18n:@charts.notes-total%</option>
|
||||
<optgroup :label="$t('notes')">
|
||||
<option value="notes">{{ $t('charts.notes') }}</option>
|
||||
<option value="local-notes">{{ $t('charts.local-notes') }}</option>
|
||||
<option value="remote-notes">{{ $t('charts.remote-notes') }}</option>
|
||||
<option value="notes-total">{{ $t('charts.notes-total') }}</option>
|
||||
</optgroup>
|
||||
<optgroup label="%i18n:@drive%">
|
||||
<option value="drive-files">%i18n:@charts.drive-files%</option>
|
||||
<option value="drive-files-total">%i18n:@charts.drive-files-total%</option>
|
||||
<option value="drive">%i18n:@charts.drive%</option>
|
||||
<option value="drive-total">%i18n:@charts.drive-total%</option>
|
||||
<optgroup :label="$t('drive')">
|
||||
<option value="drive-files">{{ $t('charts.drive-files') }}</option>
|
||||
<option value="drive-files-total">{{ $t('charts.drive-files-total') }}</option>
|
||||
<option value="drive">{{ $t('charts.drive') }}</option>
|
||||
<option value="drive-total">{{ $t('charts.drive-total') }}</option>
|
||||
</optgroup>
|
||||
<optgroup label="%i18n:@network%">
|
||||
<option value="network-requests">%i18n:@charts.network-requests%</option>
|
||||
<option value="network-time">%i18n:@charts.network-time%</option>
|
||||
<option value="network-usage">%i18n:@charts.network-usage%</option>
|
||||
<optgroup :label="$t('network')">
|
||||
<option value="network-requests">{{ $t('charts.network-requests') }}</option>
|
||||
<option value="network-time">{{ $t('charts.network-time') }}</option>
|
||||
<option value="network-usage">{{ $t('charts.network-usage') }}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
<div>
|
||||
<span @click="span = 'day'" :class="{ active: span == 'day' }">%i18n:@per-day%</span> | <span @click="span = 'hour'" :class="{ active: span == 'hour' }">%i18n:@per-hour%</span>
|
||||
<span @click="span = 'day'" :class="{ active: span == 'day' }">{{ $t('per-day') }}</span> | <span @click="span = 'hour'" :class="{ active: span == 'hour' }">{{ $t('per-hour') }}</span>
|
||||
</div>
|
||||
</header>
|
||||
<div ref="chart"></div>
|
||||
@ -39,6 +39,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
import * as ApexCharts from 'apexcharts';
|
||||
|
||||
@ -48,6 +49,7 @@ const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
|
||||
const negate = arr => arr.map(x => -x);
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/charts.vue'),
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
@ -103,17 +105,17 @@ export default Vue.extend({
|
||||
this.now = new Date();
|
||||
|
||||
const [perHour, perDay] = await Promise.all([Promise.all([
|
||||
(this as any).api('charts/federation', { limit: limit, span: 'hour' }),
|
||||
(this as any).api('charts/users', { limit: limit, span: 'hour' }),
|
||||
(this as any).api('charts/notes', { limit: limit, span: 'hour' }),
|
||||
(this as any).api('charts/drive', { limit: limit, span: 'hour' }),
|
||||
(this as any).api('charts/network', { limit: limit, span: 'hour' })
|
||||
this.$root.api('charts/federation', { limit: limit, span: 'hour' }),
|
||||
this.$root.api('charts/users', { limit: limit, span: 'hour' }),
|
||||
this.$root.api('charts/notes', { limit: limit, span: 'hour' }),
|
||||
this.$root.api('charts/drive', { limit: limit, span: 'hour' }),
|
||||
this.$root.api('charts/network', { limit: limit, span: 'hour' })
|
||||
]), Promise.all([
|
||||
(this as any).api('charts/federation', { limit: limit, span: 'day' }),
|
||||
(this as any).api('charts/users', { limit: limit, span: 'day' }),
|
||||
(this as any).api('charts/notes', { limit: limit, span: 'day' }),
|
||||
(this as any).api('charts/drive', { limit: limit, span: 'day' }),
|
||||
(this as any).api('charts/network', { limit: limit, span: 'day' })
|
||||
this.$root.api('charts/federation', { limit: limit, span: 'day' }),
|
||||
this.$root.api('charts/users', { limit: limit, span: 'day' }),
|
||||
this.$root.api('charts/notes', { limit: limit, span: 'day' }),
|
||||
this.$root.api('charts/drive', { limit: limit, span: 'day' }),
|
||||
this.$root.api('charts/network', { limit: limit, span: 'day' })
|
||||
])]);
|
||||
|
||||
const chart = {
|
||||
@ -138,6 +140,10 @@ export default Vue.extend({
|
||||
this.render();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.chartInstance.destroy();
|
||||
},
|
||||
|
||||
methods: {
|
||||
setSrc(src) {
|
||||
this.src = src;
|
||||
|
@ -47,7 +47,7 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
mounted() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.meta = meta;
|
||||
});
|
||||
|
||||
@ -117,6 +117,9 @@ export default Vue.extend({
|
||||
beforeDestroy() {
|
||||
this.connection.off('stats', this.onStats);
|
||||
this.connection.off('statsLog', this.onStatsLog);
|
||||
|
||||
this.cpuChart.destroy();
|
||||
this.memChart.destroy();
|
||||
},
|
||||
|
||||
methods: {
|
||||
@ -129,7 +132,9 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
onStatsLog(statsLog) {
|
||||
statsLog.reverse().forEach(stats => this.onStats(stats));
|
||||
for (const stats of statsLog.reverse()) {
|
||||
this.onStats(stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -5,20 +5,26 @@
|
||||
<p><b>Machine</b><span>{{ meta.machine }}</span></p>
|
||||
<p><b>OS</b><span>{{ meta.os }}</span></p>
|
||||
<p><b>Node</b><span>{{ meta.node }}</span></p>
|
||||
<p>%i18n:common.ai-chan-kawaii%</p>
|
||||
<p>{{ $t('@.ai-chan-kawaii') }}</p>
|
||||
</header>
|
||||
|
||||
<marquee-text v-if="instances.length > 0" class="instances" :repeat="10" :duration="60">
|
||||
<span v-for="instance in instances" class="instance">
|
||||
<b :style="{ background: instance.bg }">{{ instance.host }}</b>{{ instance.notesCount | number }} / {{ instance.usersCount | number }}
|
||||
</span>
|
||||
</marquee-text>
|
||||
|
||||
<div v-if="stats" class="stats">
|
||||
<div>
|
||||
<div>
|
||||
<div><fa icon="user"/></div>
|
||||
<div>
|
||||
<span>%i18n:@accounts%</span>
|
||||
<b class="primary">{{ stats.originalUsersCount | number }}</b>
|
||||
<span>{{ $t('accounts') }}</span>
|
||||
<b>{{ stats.originalUsersCount | number }}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span><fa icon="home"/> %i18n:@this-instance%</span>
|
||||
<span><fa icon="home"/> {{ $t('this-instance') }}</span>
|
||||
<span @click="setChartSrc('users')"><fa :icon="['far', 'chart-bar']"/></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -26,25 +32,25 @@
|
||||
<div>
|
||||
<div><fa icon="pencil-alt"/></div>
|
||||
<div>
|
||||
<span>%i18n:@notes%</span>
|
||||
<b class="primary">{{ stats.originalNotesCount | number }}</b>
|
||||
<span>{{ $t('notes') }}</span>
|
||||
<b>{{ stats.originalNotesCount | number }}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span><fa icon="home"/> %i18n:@this-instance%</span>
|
||||
<span><fa icon="home"/> {{ $t('this-instance') }}</span>
|
||||
<span @click="setChartSrc('notes')"><fa :icon="['far', 'chart-bar']"/></span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<div><fa icon="database"/></div>
|
||||
<div><fa :icon="faDatabase"/></div>
|
||||
<div>
|
||||
<span>%i18n:@drive%</span>
|
||||
<span>{{ $t('drive') }}</span>
|
||||
<b>{{ stats.driveUsageLocal | bytes }}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span><fa icon="home"/> %i18n:@this-instance%</span>
|
||||
<span><fa icon="home"/> {{ $t('this-instance') }}</span>
|
||||
<span @click="setChartSrc('drive')"><fa :icon="['far', 'chart-bar']"/></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,12 +58,12 @@
|
||||
<div>
|
||||
<div><fa :icon="['far', 'hdd']"/></div>
|
||||
<div>
|
||||
<span>%i18n:@instances%</span>
|
||||
<span>{{ $t('instances') }}</span>
|
||||
<b>{{ stats.instances | number }}</b>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span><fa icon="globe"/> %i18n:@federated%</span>
|
||||
<span><fa icon="globe"/> {{ $t('federated') }}</span>
|
||||
<span @click="setChartSrc('federation-instances-total')"><fa :icon="['far', 'chart-bar']"/></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -78,45 +84,73 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import XCpuMemory from "./cpu-memory.vue";
|
||||
import XCharts from "./charts.vue";
|
||||
import XApLog from "./ap-log.vue";
|
||||
import { faDatabase } from '@fortawesome/free-solid-svg-icons';
|
||||
import MarqueeText from 'vue-marquee-text-component';
|
||||
import randomColor from 'randomcolor';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/dashboard.vue'),
|
||||
|
||||
components: {
|
||||
XCpuMemory,
|
||||
XCharts,
|
||||
XApLog
|
||||
XApLog,
|
||||
MarqueeText
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
stats: null,
|
||||
connection: null,
|
||||
meta: null
|
||||
meta: null,
|
||||
instances: [],
|
||||
clock: null,
|
||||
faDatabase
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.connection = (this as any).os.stream.useSharedConnection('serverStats');
|
||||
this.connection = this.$root.stream.useSharedConnection('serverStats');
|
||||
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.updateStats();
|
||||
this.clock = setInterval(this.updateStats, 1000);
|
||||
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.meta = meta;
|
||||
});
|
||||
|
||||
(this as any).api('stats').then(stats => {
|
||||
this.stats = stats;
|
||||
this.$root.api('instances', {
|
||||
sort: '+notes'
|
||||
}).then(instances => {
|
||||
for (const i of instances) {
|
||||
i.bg = randomColor({
|
||||
seed: i.host,
|
||||
luminosity: 'dark'
|
||||
});
|
||||
}
|
||||
this.instances = instances;
|
||||
});
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.connection.dispose();
|
||||
clearInterval(this.clock);
|
||||
},
|
||||
|
||||
methods: {
|
||||
setChartSrc(src) {
|
||||
this.$refs.charts.setSrc(src);
|
||||
},
|
||||
|
||||
updateStats() {
|
||||
this.$root.api('stats', {}, false, true).then(stats => {
|
||||
this.stats = stats;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -131,7 +165,6 @@ export default Vue.extend({
|
||||
|
||||
> header
|
||||
display flex
|
||||
margin-bottom 16px
|
||||
padding-bottom 16px
|
||||
border-bottom solid 1px var(--adminDashboardHeaderBorder)
|
||||
color var(--adminDashboardHeaderFg)
|
||||
@ -156,6 +189,20 @@ export default Vue.extend({
|
||||
margin-left auto
|
||||
margin-right 0
|
||||
|
||||
> .instances
|
||||
padding 16px
|
||||
color var(--adminDashboardHeaderFg)
|
||||
font-size 13px
|
||||
|
||||
>>> .instance
|
||||
margin 0 10px
|
||||
|
||||
> b
|
||||
padding 2px 6px
|
||||
margin-right 4px
|
||||
border-radius 4px
|
||||
color #fff
|
||||
|
||||
> .stats
|
||||
display flex
|
||||
justify-content space-between
|
||||
@ -196,9 +243,6 @@ export default Vue.extend({
|
||||
> b
|
||||
display block
|
||||
|
||||
&.primary
|
||||
color var(--primary)
|
||||
|
||||
> div:last-child
|
||||
display flex
|
||||
padding 6px 16px
|
||||
|
189
src/client/app/admin/views/drive.vue
Normal file
@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<div class="pwnqwyet">
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="faCloud"/> {{ $t('@.drive') }}</div>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-select v-model="sort">
|
||||
<span slot="label">{{ $t('sort.title') }}</span>
|
||||
<option value="-createdAt">{{ $t('sort.createdAtAsc') }}</option>
|
||||
<option value="+createdAt">{{ $t('sort.createdAtDesc') }}</option>
|
||||
<option value="-size">{{ $t('sort.sizeAsc') }}</option>
|
||||
<option value="+size">{{ $t('sort.sizeDesc') }}</option>
|
||||
</ui-select>
|
||||
<ui-select v-model="origin">
|
||||
<span slot="label">{{ $t('origin.title') }}</span>
|
||||
<option value="combined">{{ $t('origin.combined') }}</option>
|
||||
<option value="local">{{ $t('origin.local') }}</option>
|
||||
<option value="remote">{{ $t('origin.remote') }}</option>
|
||||
</ui-select>
|
||||
</ui-horizon-group>
|
||||
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||
<div class="kidvdlkg" v-for="file in files">
|
||||
<div @click="file._open = !file._open">
|
||||
<div>
|
||||
<div class="thumbnail" :style="thumbnail(file)"></div>
|
||||
</div>
|
||||
<div>
|
||||
<header>
|
||||
<b>{{ file.name }}</b>
|
||||
<span class="username">@{{ file.user | acct }}</span>
|
||||
</header>
|
||||
<div>
|
||||
<div>
|
||||
<span style="margin-right:16px;">{{ file.type }}</span>
|
||||
<span>{{ file.datasize | bytes }}</span>
|
||||
</div>
|
||||
<div><mk-time :time="file.createdAt" mode="detail"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="file._open">
|
||||
<ui-input readonly :value="file.url"></ui-input>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="toggleSensitive(file)" v-if="file.isSensitive"><fa :icon="faEye"/> {{ $t('unmark-as-sensitive') }}</ui-button>
|
||||
<ui-button @click="toggleSensitive(file)" v-else><fa :icon="faEyeSlash"/> {{ $t('mark-as-sensitive') }}</ui-button>
|
||||
<ui-button @click="del(file)"><fa :icon="faTrashAlt"/> {{ $t('delete') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
</div>
|
||||
</div>
|
||||
</sequential-entrance>
|
||||
<ui-button v-if="existMore" @click="fetch">{{ $t('@.load-more') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { faCloud } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTrashAlt, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/drive.vue'),
|
||||
|
||||
data() {
|
||||
return {
|
||||
sort: '+createdAt',
|
||||
origin: 'combined',
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
files: [],
|
||||
existMore: false,
|
||||
faCloud, faTrashAlt, faEye, faEyeSlash
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
sort() {
|
||||
this.files = [];
|
||||
this.offset = 0;
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
origin() {
|
||||
this.files = [];
|
||||
this.offset = 0;
|
||||
this.fetch();
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
this.$root.api('admin/drive/files', {
|
||||
origin: this.origin,
|
||||
sort: this.sort,
|
||||
offset: this.offset,
|
||||
limit: this.limit + 1
|
||||
}).then(files => {
|
||||
if (files.length == this.limit + 1) {
|
||||
files.pop();
|
||||
this.existMore = true;
|
||||
} else {
|
||||
this.existMore = false;
|
||||
}
|
||||
for (const x of files) {
|
||||
x._open = false;
|
||||
}
|
||||
this.files = this.files.concat(files);
|
||||
this.offset += this.limit;
|
||||
});
|
||||
},
|
||||
|
||||
thumbnail(file: any): any {
|
||||
return {
|
||||
'background-color': file.properties.avgColor && file.properties.avgColor.length == 3 ? `rgb(${file.properties.avgColor.join(',')})` : 'transparent',
|
||||
'background-image': `url(${file.thumbnailUrl})`
|
||||
};
|
||||
},
|
||||
|
||||
async del(file: any) {
|
||||
const process = async () => {
|
||||
await this.$root.api('drive/files/delete', { fileId: file.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('deleted')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
toggleSensitive(file: any) {
|
||||
this.$root.api('drive/files/update', {
|
||||
fileId: file.id,
|
||||
isSensitive: !file.isSensitive
|
||||
});
|
||||
|
||||
file.isSensitive = !file.isSensitive;
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.pwnqwyet
|
||||
@media (min-width 500px)
|
||||
padding 16px
|
||||
|
||||
.kidvdlkg
|
||||
padding 16px 0
|
||||
border-top solid 1px var(--faceDivider)
|
||||
|
||||
> div:first-child
|
||||
display flex
|
||||
cursor pointer
|
||||
|
||||
> div:nth-child(1)
|
||||
> .thumbnail
|
||||
display block
|
||||
width 64px
|
||||
height 64px
|
||||
background-size cover
|
||||
background-position center center
|
||||
|
||||
> div:nth-child(2)
|
||||
flex 1
|
||||
padding-left 16px
|
||||
|
||||
@media (max-width 500px)
|
||||
font-size 14px
|
||||
|
||||
> header
|
||||
word-break break-word
|
||||
|
||||
> .username
|
||||
margin-left 8px
|
||||
opacity 0.7
|
||||
|
||||
</style>
|
@ -1,62 +1,70 @@
|
||||
<template>
|
||||
<div class="tumhkfkmgtvzljezfvmgkeurkfncshbe">
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="plus"/> %i18n:@add-emoji.title%</div>
|
||||
<div slot="title"><fa icon="plus"/> {{ $t('add-emoji.title') }}</div>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="name">
|
||||
<span>%i18n:@add-emoji.name%</span>
|
||||
<span slot="text">%i18n:@add-emoji.name-desc%</span>
|
||||
<span>{{ $t('add-emoji.name') }}</span>
|
||||
<span slot="desc">{{ $t('add-emoji.name-desc') }}</span>
|
||||
</ui-input>
|
||||
<ui-input v-model="aliases">
|
||||
<span>%i18n:@add-emoji.aliases%</span>
|
||||
<span slot="text">%i18n:@add-emoji.aliases-desc%</span>
|
||||
<span>{{ $t('add-emoji.aliases') }}</span>
|
||||
<span slot="desc">{{ $t('add-emoji.aliases-desc') }}</span>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input v-model="url">
|
||||
<i slot="icon"><fa icon="link"/></i>
|
||||
<span>%i18n:@add-emoji.url%</span>
|
||||
<span>{{ $t('add-emoji.url') }}</span>
|
||||
</ui-input>
|
||||
<ui-info>%i18n:@add-emoji.info%</ui-info>
|
||||
<ui-button @click="add">%i18n:@add-emoji.add%</ui-button>
|
||||
<ui-info>{{ $t('add-emoji.info') }}</ui-info>
|
||||
<ui-button @click="add">{{ $t('add-emoji.add') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['far', 'grin']"/> %i18n:@emojis.title%</div>
|
||||
<section v-for="emoji in emojis">
|
||||
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="emoji.name">
|
||||
<span>%i18n:@add-emoji.name%</span>
|
||||
<div slot="title"><fa :icon="faGrin"/> {{ $t('emojis.title') }}</div>
|
||||
<section v-for="emoji in emojis" class="oryfrbft">
|
||||
<div>
|
||||
<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
|
||||
</div>
|
||||
<div>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="emoji.name">
|
||||
<span>{{ $t('add-emoji.name') }}</span>
|
||||
</ui-input>
|
||||
<ui-input v-model="emoji.aliases">
|
||||
<span>{{ $t('add-emoji.aliases') }}</span>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input v-model="emoji.url">
|
||||
<i slot="icon"><fa icon="link"/></i>
|
||||
<span>{{ $t('add-emoji.url') }}</span>
|
||||
</ui-input>
|
||||
<ui-input v-model="emoji.aliases">
|
||||
<span>%i18n:@add-emoji.aliases%</span>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input v-model="emoji.url">
|
||||
<i slot="icon"><fa icon="link"/></i>
|
||||
<span>%i18n:@add-emoji.url%</span>
|
||||
</ui-input>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="updateEmoji(emoji)"><fa :icon="['far', 'save']"/> %i18n:@emojis.update%</ui-button>
|
||||
<ui-button @click="removeEmoji(emoji)"><fa :icon="['far', 'trash-alt']"/> %i18n:@emojis.remove%</ui-button>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group class="fit-bottom">
|
||||
<ui-button @click="updateEmoji(emoji)"><fa :icon="['far', 'save']"/> {{ $t('emojis.update') }}</ui-button>
|
||||
<ui-button @click="removeEmoji(emoji)"><fa :icon="['far', 'trash-alt']"/> {{ $t('emojis.remove') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
</div>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { faGrin } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/emoji.vue'),
|
||||
data() {
|
||||
return {
|
||||
name: '',
|
||||
url: '',
|
||||
aliases: '',
|
||||
emojis: []
|
||||
emojis: [],
|
||||
faGrin
|
||||
};
|
||||
},
|
||||
|
||||
@ -66,18 +74,18 @@ export default Vue.extend({
|
||||
|
||||
methods: {
|
||||
add() {
|
||||
(this as any).api('admin/emoji/add', {
|
||||
this.$root.api('admin/emoji/add', {
|
||||
name: this.name,
|
||||
url: this.url,
|
||||
aliases: this.aliases.split(' ').filter(x => x.length > 0)
|
||||
}).then(() => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: '%i18n:@add-emoji.added%'
|
||||
text: this.$t('add-emoji.added')
|
||||
});
|
||||
this.fetchEmojis();
|
||||
}).catch(e => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
@ -85,26 +93,28 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
fetchEmojis() {
|
||||
(this as any).api('admin/emoji/list').then(emojis => {
|
||||
this.$root.api('admin/emoji/list').then(emojis => {
|
||||
emojis.reverse();
|
||||
emojis.forEach(e => e.aliases = (e.aliases || []).join(' '));
|
||||
for (const e of emojis) {
|
||||
e.aliases = (e.aliases || []).join(' ');
|
||||
}
|
||||
this.emojis = emojis;
|
||||
});
|
||||
},
|
||||
|
||||
updateEmoji(emoji) {
|
||||
(this as any).api('admin/emoji/update', {
|
||||
this.$root.api('admin/emoji/update', {
|
||||
id: emoji.id,
|
||||
name: emoji.name,
|
||||
url: emoji.url,
|
||||
aliases: emoji.aliases.split(' ').filter(x => x.length > 0)
|
||||
}).then(() => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: '%i18n:@updated%'
|
||||
text: this.$t('updated')
|
||||
});
|
||||
}).catch(e => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
@ -112,23 +122,23 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
removeEmoji(emoji) {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'warning',
|
||||
text: '%i18n:@remove-emoji.are-you-sure%'.replace('$1', emoji.name),
|
||||
text: this.$t('remove-emoji.are-you-sure').replace('$1', emoji.name),
|
||||
showCancelButton: true
|
||||
}).then(res => {
|
||||
if (!res.value) return;
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
|
||||
(this as any).api('admin/emoji/remove', {
|
||||
this.$root.api('admin/emoji/remove', {
|
||||
id: emoji.id
|
||||
}).then(() => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: '%i18n:@remove-emoji.removed%'
|
||||
text: this.$t('remove-emoji.removed')
|
||||
});
|
||||
this.fetchEmojis();
|
||||
}).catch(e => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
@ -144,4 +154,21 @@ export default Vue.extend({
|
||||
@media (min-width 500px)
|
||||
padding 16px
|
||||
|
||||
.oryfrbft
|
||||
@media (min-width 500px)
|
||||
display flex
|
||||
|
||||
> div:first-child
|
||||
@media (max-width 500px)
|
||||
padding-bottom 16px
|
||||
|
||||
> img
|
||||
vertical-align bottom
|
||||
|
||||
> div:last-child
|
||||
flex 1
|
||||
|
||||
@media (min-width 500px)
|
||||
padding-left 16px
|
||||
|
||||
</style>
|
||||
|
@ -1,37 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@hided-tags%</div>
|
||||
<div slot="title">{{ $t('hided-tags') }}</div>
|
||||
<section>
|
||||
<textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hidedTags"></textarea>
|
||||
<ui-button @click="save">%i18n:@save%</ui-button>
|
||||
<ui-button @click="save">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/hashtags.vue'),
|
||||
data() {
|
||||
return {
|
||||
hidedTags: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.hidedTags = meta.hidedTags.join('\n');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
(this as any).api('admin/update-meta', {
|
||||
this.$root.api('admin/update-meta', {
|
||||
hidedTags: this.hidedTags.split('\n')
|
||||
}).then(() => {
|
||||
//(this as any).os.apis.dialog({ text: `Saved` });
|
||||
//this.$root.os.apis.dialog({ text: `Saved` });
|
||||
}).catch(e => {
|
||||
//(this as any).os.apis.dialog({ text: `Failed ${e}` });
|
||||
//this.$root.os.apis.dialog({ text: `Failed ${e}` });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -15,61 +15,72 @@
|
||||
</div>
|
||||
<div class="me">
|
||||
<img class="avatar" :src="$store.state.i.avatarUrl" alt="avatar"/>
|
||||
<p class="name">{{ $store.state.i | userName }}</p>
|
||||
<p class="name"><mk-user-name :user="$store.state.i"/></p>
|
||||
</div>
|
||||
<ul>
|
||||
<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }"><fa icon="home" fixed-width/>%i18n:@dashboard%</li>
|
||||
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>%i18n:@instance%</li>
|
||||
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>%i18n:@users%</li>
|
||||
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="['far', 'grin']" fixed-width/>%i18n:@emoji%</li>
|
||||
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>%i18n:@announcements%</li>
|
||||
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>%i18n:@hashtags%</li>
|
||||
|
||||
<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>%i18n:common.drive%</li> -->
|
||||
<!-- <li @click="nav('update')" :class="{ active: page == 'update' }">%i18n:@update%</li> -->
|
||||
<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }"><fa icon="home" fixed-width/>{{ $t('dashboard') }}</li>
|
||||
<li @click="nav('instance')" :class="{ active: page == 'instance' }"><fa icon="cog" fixed-width/>{{ $t('instance') }}</li>
|
||||
<li @click="nav('moderators')" :class="{ active: page == 'moderators' }"><fa :icon="faHeadset" fixed-width/>{{ $t('moderators') }}</li>
|
||||
<li @click="nav('users')" :class="{ active: page == 'users' }"><fa icon="users" fixed-width/>{{ $t('users') }}</li>
|
||||
<li @click="nav('drive')" :class="{ active: page == 'drive' }"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</li>
|
||||
<!-- <li @click="nav('federation')" :class="{ active: page == 'federation' }"><fa :icon="faShareAlt" fixed-width/>{{ $t('federation') }}</li> -->
|
||||
<li @click="nav('emoji')" :class="{ active: page == 'emoji' }"><fa :icon="faGrin" fixed-width/>{{ $t('emoji') }}</li>
|
||||
<li @click="nav('announcements')" :class="{ active: page == 'announcements' }"><fa icon="broadcast-tower" fixed-width/>{{ $t('announcements') }}</li>
|
||||
<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }"><fa icon="hashtag" fixed-width/>{{ $t('hashtags') }}</li>
|
||||
</ul>
|
||||
<div class="back-to-misskey">
|
||||
<a href="/"><fa icon="arrow-left"/> %i18n:@back-to-misskey%</a>
|
||||
<a href="/"><fa :icon="faArrowLeft"/> {{ $t('back-to-misskey') }}</a>
|
||||
</div>
|
||||
<div class="version">
|
||||
<small>Misskey {{ version }}</small>
|
||||
</div>
|
||||
</nav>
|
||||
<main>
|
||||
<div v-if="page == 'dashboard'"><x-dashboard/></div>
|
||||
<div v-if="page == 'instance'"><x-instance/></div>
|
||||
<div v-if="page == 'users'"><x-users/></div>
|
||||
<div v-if="page == 'emoji'"><x-emoji/></div>
|
||||
<div v-if="page == 'announcements'"><x-announcements/></div>
|
||||
<div v-if="page == 'hashtags'"><x-hashtags/></div>
|
||||
<div v-if="page == 'drive'"></div>
|
||||
<div v-if="page == 'update'"></div>
|
||||
<div class="page">
|
||||
<div v-if="page == 'dashboard'"><x-dashboard/></div>
|
||||
<div v-if="page == 'instance'"><x-instance/></div>
|
||||
<div v-if="page == 'moderators'"><x-moderators/></div>
|
||||
<div v-if="page == 'users'"><x-users/></div>
|
||||
<div v-if="page == 'emoji'"><x-emoji/></div>
|
||||
<div v-if="page == 'announcements'"><x-announcements/></div>
|
||||
<div v-if="page == 'hashtags'"><x-hashtags/></div>
|
||||
<div v-if="page == 'drive'"><x-drive/></div>
|
||||
<div v-if="page == 'update'"></div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { version } from '../../config';
|
||||
import XDashboard from "./dashboard.vue";
|
||||
import XInstance from "./instance.vue";
|
||||
import XModerators from "./moderators.vue";
|
||||
import XEmoji from "./emoji.vue";
|
||||
import XAnnouncements from "./announcements.vue";
|
||||
import XHashtags from "./hashtags.vue";
|
||||
import XUsers from "./users.vue";
|
||||
import XDrive from "./drive.vue";
|
||||
import { faHeadset, faArrowLeft, faShareAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faGrin } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
// Detect the user agent
|
||||
const ua = navigator.userAgent.toLowerCase();
|
||||
const isMobile = /mobile|iphone|ipad|android/.test(ua);
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/index.vue'),
|
||||
components: {
|
||||
XDashboard,
|
||||
XInstance,
|
||||
XModerators,
|
||||
XEmoji,
|
||||
XAnnouncements,
|
||||
XHashtags,
|
||||
XUsers
|
||||
XUsers,
|
||||
XDrive,
|
||||
},
|
||||
provide: {
|
||||
isMobile
|
||||
@ -79,7 +90,11 @@ export default Vue.extend({
|
||||
page: 'dashboard',
|
||||
version,
|
||||
isMobile,
|
||||
navOpend: !isMobile
|
||||
navOpend: !isMobile,
|
||||
faGrin,
|
||||
faArrowLeft,
|
||||
faHeadset,
|
||||
faShareAlt
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -90,7 +105,7 @@ export default Vue.extend({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
<style lang="stylus" scoped>
|
||||
.mk-admin
|
||||
$headerHeight = 48px
|
||||
|
||||
@ -251,7 +266,9 @@ export default Vue.extend({
|
||||
> main
|
||||
width 100%
|
||||
padding 0 0 0 250px
|
||||
max-width 1300px
|
||||
|
||||
> .page
|
||||
max-width 1150px
|
||||
|
||||
&.isMobile
|
||||
> main
|
||||
|
@ -1,81 +1,249 @@
|
||||
<template>
|
||||
<div class="axbwjelsbymowqjyywpirzhdlszoncqs">
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="cog"/> %i18n:@instance%</div>
|
||||
<div slot="title"><fa icon="cog"/> {{ $t('instance') }}</div>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="name">%i18n:@instance-name%</ui-input>
|
||||
<ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea>
|
||||
<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>%i18n:@banner-url%</ui-input>
|
||||
</section>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="maxNoteTextLength">%i18n:@max-note-text-length%</ui-input>
|
||||
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
||||
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
||||
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
||||
<ui-input v-model="mascotImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('logo-url') }}</ui-input>
|
||||
<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('banner-url') }}</ui-input>
|
||||
<ui-input v-model="errorImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('error-image-url') }}</ui-input>
|
||||
<ui-input v-model="languages"><i slot="icon"><fa icon="language"/></i>{{ $t('languages') }}<span slot="desc">{{ $t('languages-desc') }}</span></ui-input>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa icon="cloud"/> %i18n:@drive-config%</header>
|
||||
<ui-switch v-model="cacheRemoteFiles">%i18n:@cache-remote-files%<span slot="desc">%i18n:@cache-remote-files-desc%</span></ui-switch>
|
||||
<ui-input v-model="localDriveCapacityMb">%i18n:@local-drive-capacity-mb%<span slot="text">%i18n:@mb%</span><span slot="suffix">MB</span></ui-input>
|
||||
<ui-input v-model="remoteDriveCapacityMb" :disabled="!cacheRemoteFiles">%i18n:@remote-drive-capacity-mb%<span slot="text">%i18n:@mb%</span><span slot="suffix">MB</span></ui-input>
|
||||
<header><fa :icon="faHeadset"/> {{ $t('maintainer-config') }}</header>
|
||||
<ui-input v-model="maintainerName">{{ $t('maintainer-name') }}</ui-input>
|
||||
<ui-input v-model="maintainerEmail" type="email"><i slot="icon"><fa :icon="farEnvelope"/></i>{{ $t('maintainer-email') }}</ui-input>
|
||||
</section>
|
||||
<section class="fit-top fit-bottom">
|
||||
<ui-input v-model="maxNoteTextLength">{{ $t('max-note-text-length') }}</ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta">%i18n:@save%</ui-button>
|
||||
<ui-switch v-model="disableRegistration">{{ $t('disable-registration') }}</ui-switch>
|
||||
<ui-switch v-model="disableLocalTimeline">{{ $t('disable-local-timeline') }}</ui-switch>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa icon="cloud"/> {{ $t('drive-config') }}</header>
|
||||
<ui-switch v-model="cacheRemoteFiles">{{ $t('cache-remote-files') }}<span slot="desc">{{ $t('cache-remote-files-desc') }}</span></ui-switch>
|
||||
<ui-input v-model="localDriveCapacityMb" type="number">{{ $t('local-drive-capacity-mb') }}<span slot="suffix">MB</span><span slot="desc">{{ $t('mb') }}</span></ui-input>
|
||||
<ui-input v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">{{ $t('remote-drive-capacity-mb') }}<span slot="suffix">MB</span><span slot="desc">{{ $t('mb') }}</span></ui-input>
|
||||
</section>
|
||||
<section class="fit-bottom">
|
||||
<header><fa :icon="faShieldAlt"/> {{ $t('recaptcha-config') }}</header>
|
||||
<ui-switch v-model="enableRecaptcha">{{ $t('enable-recaptcha') }}</ui-switch>
|
||||
<ui-info>{{ $t('recaptcha-info') }}</ui-info>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="recaptchaSiteKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>{{ $t('recaptcha-site-key') }}</ui-input>
|
||||
<ui-input v-model="recaptchaSecretKey" :disabled="!enableRecaptcha"><i slot="icon"><fa icon="key"/></i>{{ $t('recaptcha-secret-key') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faGhost"/> {{ $t('proxy-account-config') }}</header>
|
||||
<ui-info>{{ $t('proxy-account-info') }}</ui-info>
|
||||
<ui-input v-model="proxyAccount"><span slot="prefix">@</span>{{ $t('proxy-account-username') }}<span slot="desc">{{ $t('proxy-account-username-desc') }}</span></ui-input>
|
||||
<ui-info warn>{{ $t('proxy-account-warn') }}</ui-info>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="farEnvelope"/> {{ $t('email-config') }}</header>
|
||||
<ui-switch v-model="enableEmail">{{ $t('enable-email') }}<span slot="desc">{{ $t('email-config-info') }}</span></ui-switch>
|
||||
<ui-input v-model="email" type="email" :disabled="!enableEmail">{{ $t('email') }}</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpHost" :disabled="!enableEmail">{{ $t('smtp-host') }}</ui-input>
|
||||
<ui-input v-model="smtpPort" type="number" :disabled="!enableEmail">{{ $t('smtp-port') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="smtpUser" :disabled="!enableEmail">{{ $t('smtp-user') }}</ui-input>
|
||||
<ui-input v-model="smtpPass" type="password" :withPasswordToggle="true" :disabled="!enableEmail">{{ $t('smtp-pass') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-switch v-model="smtpSecure" :disabled="!enableEmail">{{ $t('smtp-secure') }}<span slot="desc">{{ $t('smtp-secure-info') }}</span></ui-switch>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faBolt"/> {{ $t('serviceworker-config') }}</header>
|
||||
<ui-switch v-model="enableServiceWorker">{{ $t('enable-serviceworker') }}<span slot="desc">{{ $t('serviceworker-info') }}</span></ui-switch>
|
||||
<ui-info>{{ $t('vapid-info') }}<br><code>npm i web-push -g<br>web-push generate-vapid-keys</code></ui-info>
|
||||
<ui-horizon-group inputs class="fit-bottom">
|
||||
<ui-input v-model="swPublicKey" :disabled="!enableServiceWorker"><i slot="icon"><fa icon="key"/></i>{{ $t('vapid-publickey') }}</ui-input>
|
||||
<ui-input v-model="swPrivateKey" :disabled="!enableServiceWorker"><i slot="icon"><fa icon="key"/></i>{{ $t('vapid-privatekey') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
</section>
|
||||
<section>
|
||||
<header>summaly Proxy</header>
|
||||
<ui-input v-model="summalyProxy">URL</ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<header><fa :icon="faUserPlus"/> {{ $t('user-recommendation-config') }}</header>
|
||||
<ui-switch v-model="enableExternalUserRecommendation">{{ $t('enable-external-user-recommendation') }}</ui-switch>
|
||||
<ui-input v-model="externalUserRecommendationEngine" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-engine') }}<span slot="desc">{{ $t('external-user-recommendation-engine-desc') }}</span></ui-input>
|
||||
<ui-input v-model="externalUserRecommendationTimeout" type="number" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-timeout') }}<span slot="suffix">ms</span><span slot="desc">{{ $t('external-user-recommendation-timeout-desc') }}</span></ui-input>
|
||||
</section>
|
||||
<section>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@disable-registration%</div>
|
||||
<div slot="title">{{ $t('invite') }}</div>
|
||||
<section>
|
||||
<input type="checkbox" v-model="disableRegistration" @change="updateMeta">
|
||||
<button class="ui" @click="invite">%i18n:@invite%</button>
|
||||
<ui-button @click="invite">{{ $t('invite') }}</ui-button>
|
||||
<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@disable-local-timeline%</div>
|
||||
<div slot="title"><fa :icon="['fab', 'twitter']"/> {{ $t('twitter-integration-config') }}</div>
|
||||
<section>
|
||||
<input type="checkbox" v-model="disableLocalTimeline" @change="updateMeta">
|
||||
<ui-switch v-model="enableTwitterIntegration">{{ $t('enable-twitter-integration') }}</ui-switch>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="twitterConsumerKey" :disabled="!enableTwitterIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('twitter-integration-consumer-key') }}</ui-input>
|
||||
<ui-input v-model="twitterConsumerSecret" :disabled="!enableTwitterIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('twitter-integration-consumer-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('twitter-integration-info', { url: `${url}/api/tw/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['fab', 'github']"/> {{ $t('github-integration-config') }}</div>
|
||||
<section>
|
||||
<ui-switch v-model="enableGithubIntegration">{{ $t('enable-github-integration') }}</ui-switch>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="githubClientId" :disabled="!enableGithubIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('github-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="githubClientSecret" :disabled="!enableGithubIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('github-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('github-integration-info', { url: `${url}/api/gh/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title"><fa :icon="['fab', 'discord']"/> {{ $t('discord-integration-config') }}</div>
|
||||
<section>
|
||||
<ui-switch v-model="enableDiscordIntegration">{{ $t('enable-discord-integration') }}</ui-switch>
|
||||
<ui-horizon-group>
|
||||
<ui-input v-model="discordClientId" :disabled="!enableDiscordIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('discord-integration-client-id') }}</ui-input>
|
||||
<ui-input v-model="discordClientSecret" :disabled="!enableDiscordIntegration"><i slot="icon"><fa icon="key"/></i>{{ $t('discord-integration-client-secret') }}</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-info>{{ $t('discord-integration-info', { url: `${url}/api/dc/cb` }) }}</ui-info>
|
||||
<ui-button @click="updateMeta">{{ $t('save') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { url, host } from '../../config';
|
||||
import { toUnicode } from 'punycode';
|
||||
import { faHeadset, faShieldAlt, faGhost, faUserPlus, faBolt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faEnvelope as farEnvelope } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/instance.vue'),
|
||||
|
||||
data() {
|
||||
return {
|
||||
url,
|
||||
host: toUnicode(host),
|
||||
maintainerName: null,
|
||||
maintainerEmail: null,
|
||||
disableRegistration: false,
|
||||
disableLocalTimeline: false,
|
||||
mascotImageUrl: null,
|
||||
bannerUrl: null,
|
||||
errorImageUrl: null,
|
||||
name: null,
|
||||
description: null,
|
||||
languages: null,
|
||||
cacheRemoteFiles: false,
|
||||
localDriveCapacityMb: null,
|
||||
remoteDriveCapacityMb: null,
|
||||
maxNoteTextLength: null,
|
||||
enableRecaptcha: false,
|
||||
recaptchaSiteKey: null,
|
||||
recaptchaSecretKey: null,
|
||||
enableTwitterIntegration: false,
|
||||
twitterConsumerKey: null,
|
||||
twitterConsumerSecret: null,
|
||||
enableGithubIntegration: false,
|
||||
githubClientId: null,
|
||||
githubClientSecret: null,
|
||||
enableDiscordIntegration: false,
|
||||
discordClientId: null,
|
||||
discordClientSecret: null,
|
||||
proxyAccount: null,
|
||||
inviteCode: null,
|
||||
enableExternalUserRecommendation: false,
|
||||
externalUserRecommendationEngine: null,
|
||||
externalUserRecommendationTimeout: null,
|
||||
summalyProxy: null,
|
||||
enableEmail: false,
|
||||
email: null,
|
||||
smtpSecure: false,
|
||||
smtpHost: null,
|
||||
smtpPort: null,
|
||||
smtpUser: null,
|
||||
smtpPass: null,
|
||||
enableServiceWorker: false,
|
||||
swPublicKey: null,
|
||||
swPrivateKey: null,
|
||||
faHeadset, faShieldAlt, faGhost, faUserPlus, farEnvelope, faBolt
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
(this as any).os.getMeta().then(meta => {
|
||||
this.$root.getMeta().then(meta => {
|
||||
this.maintainerName = meta.maintainer.name;
|
||||
this.maintainerEmail = meta.maintainer.email;
|
||||
this.disableRegistration = meta.disableRegistration;
|
||||
this.disableLocalTimeline = meta.disableLocalTimeline;
|
||||
this.mascotImageUrl = meta.mascotImageUrl;
|
||||
this.bannerUrl = meta.bannerUrl;
|
||||
this.errorImageUrl = meta.errorImageUrl;
|
||||
this.name = meta.name;
|
||||
this.description = meta.description;
|
||||
this.languages = meta.langs.join(' ');
|
||||
this.cacheRemoteFiles = meta.cacheRemoteFiles;
|
||||
this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb;
|
||||
this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb;
|
||||
this.maxNoteTextLength = meta.maxNoteTextLength;
|
||||
this.enableRecaptcha = meta.enableRecaptcha;
|
||||
this.recaptchaSiteKey = meta.recaptchaSiteKey;
|
||||
this.recaptchaSecretKey = meta.recaptchaSecretKey;
|
||||
this.proxyAccount = meta.proxyAccount;
|
||||
this.enableTwitterIntegration = meta.enableTwitterIntegration;
|
||||
this.twitterConsumerKey = meta.twitterConsumerKey;
|
||||
this.twitterConsumerSecret = meta.twitterConsumerSecret;
|
||||
this.enableGithubIntegration = meta.enableGithubIntegration;
|
||||
this.githubClientId = meta.githubClientId;
|
||||
this.githubClientSecret = meta.githubClientSecret;
|
||||
this.enableDiscordIntegration = meta.enableDiscordIntegration;
|
||||
this.discordClientId = meta.discordClientId;
|
||||
this.discordClientSecret = meta.discordClientSecret;
|
||||
this.enableExternalUserRecommendation = meta.enableExternalUserRecommendation;
|
||||
this.externalUserRecommendationEngine = meta.externalUserRecommendationEngine;
|
||||
this.externalUserRecommendationTimeout = meta.externalUserRecommendationTimeout;
|
||||
this.summalyProxy = meta.summalyProxy;
|
||||
this.enableEmail = meta.enableEmail;
|
||||
this.email = meta.email;
|
||||
this.smtpSecure = meta.smtpSecure;
|
||||
this.smtpHost = meta.smtpHost;
|
||||
this.smtpPort = meta.smtpPort;
|
||||
this.smtpUser = meta.smtpUser;
|
||||
this.smtpPass = meta.smtpPass;
|
||||
this.enableServiceWorker = meta.enableServiceWorker;
|
||||
this.swPublicKey = meta.swPublickey;
|
||||
this.swPrivateKey = meta.swPrivateKey;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
invite() {
|
||||
(this as any).api('admin/invite').then(x => {
|
||||
this.$root.api('admin/invite').then(x => {
|
||||
this.inviteCode = x.code;
|
||||
}).catch(e => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
@ -83,23 +251,55 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
updateMeta() {
|
||||
(this as any).api('admin/update-meta', {
|
||||
this.$root.api('admin/update-meta', {
|
||||
maintainerName: this.maintainerName,
|
||||
maintainerEmail: this.maintainerEmail,
|
||||
disableRegistration: this.disableRegistration,
|
||||
disableLocalTimeline: this.disableLocalTimeline,
|
||||
mascotImageUrl: this.mascotImageUrl,
|
||||
bannerUrl: this.bannerUrl,
|
||||
errorImageUrl: this.errorImageUrl,
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
langs: this.languages.split(' '),
|
||||
cacheRemoteFiles: this.cacheRemoteFiles,
|
||||
localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10),
|
||||
remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10),
|
||||
maxNoteTextLength: parseInt(this.maxNoteTextLength, 10)
|
||||
maxNoteTextLength: parseInt(this.maxNoteTextLength, 10),
|
||||
enableRecaptcha: this.enableRecaptcha,
|
||||
recaptchaSiteKey: this.recaptchaSiteKey,
|
||||
recaptchaSecretKey: this.recaptchaSecretKey,
|
||||
proxyAccount: this.proxyAccount,
|
||||
enableTwitterIntegration: this.enableTwitterIntegration,
|
||||
twitterConsumerKey: this.twitterConsumerKey,
|
||||
twitterConsumerSecret: this.twitterConsumerSecret,
|
||||
enableGithubIntegration: this.enableGithubIntegration,
|
||||
githubClientId: this.githubClientId,
|
||||
githubClientSecret: this.githubClientSecret,
|
||||
enableDiscordIntegration: this.enableDiscordIntegration,
|
||||
discordClientId: this.discordClientId,
|
||||
discordClientSecret: this.discordClientSecret,
|
||||
enableExternalUserRecommendation: this.enableExternalUserRecommendation,
|
||||
externalUserRecommendationEngine: this.externalUserRecommendationEngine,
|
||||
externalUserRecommendationTimeout: parseInt(this.externalUserRecommendationTimeout, 10),
|
||||
summalyProxy: this.summalyProxy,
|
||||
enableEmail: this.enableEmail,
|
||||
email: this.email,
|
||||
smtpSecure: this.smtpSecure,
|
||||
smtpHost: this.smtpHost,
|
||||
smtpPort: parseInt(this.smtpPort, 10),
|
||||
smtpUser: this.smtpUser,
|
||||
smtpPass: this.smtpPass,
|
||||
enableServiceWorker: this.enableServiceWorker,
|
||||
swPublicKey: this.swPublicKey,
|
||||
swPrivateKey: this.swPrivateKey
|
||||
}).then(() => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: '%i18n:@saved%'
|
||||
text: this.$t('saved')
|
||||
});
|
||||
}).catch(e => {
|
||||
this.$swal({
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e
|
||||
});
|
||||
|
84
src/client/app/admin/views/moderators.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div class="jnhmugbb">
|
||||
<ui-card>
|
||||
<div slot="title"><fa icon="plus"/> {{ $t('add-moderator.title') }}</div>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="username" type="text">
|
||||
<span slot="prefix">@</span>
|
||||
</ui-input>
|
||||
<ui-button @click="add" :disabled="changing">{{ $t('add-moderator.add') }}</ui-button>
|
||||
<ui-button @click="remove" :disabled="changing">{{ $t('add-moderator.remove') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import parseAcct from "../../../../misc/acct/parse";
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/moderators.vue'),
|
||||
|
||||
data() {
|
||||
return {
|
||||
username: '',
|
||||
changing: false
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
async add() {
|
||||
this.changing = true;
|
||||
|
||||
const process = async () => {
|
||||
const user = await this.$root.api('users/show', parseAcct(this.username));
|
||||
await this.$root.api('admin/moderators/add', { userId: user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('add-moderator.added')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.changing = false;
|
||||
},
|
||||
|
||||
async remove() {
|
||||
this.changing = true;
|
||||
|
||||
const process = async () => {
|
||||
const user = await this.$root.api('users/show', parseAcct(this.username));
|
||||
await this.$root.api('admin/moderators/remove', { userId: user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('add-moderator.removed')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.changing = false;
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.jnhmugbb
|
||||
@media (min-width 500px)
|
||||
padding 16px
|
||||
|
||||
</style>
|
@ -1,77 +1,188 @@
|
||||
<template>
|
||||
<div class="ucnffhbtogqgscfmqcymwmmupoknpfsw">
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@verify-user%</div>
|
||||
<div slot="title"><fa :icon="faTerminal"/> {{ $t('operation') }}</div>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="verifyUsername" type="text">
|
||||
<span slot="prefix">@</span>
|
||||
<ui-input v-model="target" type="text">
|
||||
<span>{{ $t('username-or-userid') }}</span>
|
||||
</ui-input>
|
||||
<ui-button @click="verifyUser" :disabled="verifying">%i18n:@verify%</ui-button>
|
||||
<ui-button @click="resetPassword"><fa :icon="faKey"/> {{ $t('reset-password') }}</ui-button>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="verifyUser" :disabled="verifying"><fa :icon="faCertificate"/> {{ $t('verify') }}</ui-button>
|
||||
<ui-button @click="unverifyUser" :disabled="unverifying">{{ $t('unverify') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group>
|
||||
<ui-button @click="suspendUser" :disabled="suspending"><fa :icon="faSnowflake"/> {{ $t('suspend') }}</ui-button>
|
||||
<ui-button @click="unsuspendUser" :disabled="unsuspending">{{ $t('unsuspend') }}</ui-button>
|
||||
</ui-horizon-group>
|
||||
<ui-button @click="showUser"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
|
||||
<ui-textarea v-if="user" :value="user | json5" readonly tall style="margin-top:16px;"></ui-textarea>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@unverify-user%</div>
|
||||
<div slot="title"><fa :icon="faUsers"/> {{ $t('users.title') }}</div>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="unverifyUsername" type="text">
|
||||
<span slot="prefix">@</span>
|
||||
</ui-input>
|
||||
<ui-button @click="unverifyUser" :disabled="unverifying">%i18n:@unverify%</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@suspend-user%</div>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="suspendUsername" type="text">
|
||||
<span slot="prefix">@</span>
|
||||
</ui-input>
|
||||
<ui-button @click="suspendUser" :disabled="suspending">%i18n:@suspend%</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
|
||||
<ui-card>
|
||||
<div slot="title">%i18n:@unsuspend-user%</div>
|
||||
<section class="fit-top">
|
||||
<ui-input v-model="unsuspendUsername" type="text">
|
||||
<span slot="prefix">@</span>
|
||||
</ui-input>
|
||||
<ui-button @click="unsuspendUser" :disabled="unsuspending">%i18n:@unsuspend%</ui-button>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-select v-model="sort">
|
||||
<span slot="label">{{ $t('users.sort.title') }}</span>
|
||||
<option value="-createdAt">{{ $t('users.sort.createdAtAsc') }}</option>
|
||||
<option value="+createdAt">{{ $t('users.sort.createdAtDesc') }}</option>
|
||||
<option value="-updatedAt">{{ $t('users.sort.updatedAtAsc') }}</option>
|
||||
<option value="+updatedAt">{{ $t('users.sort.updatedAtDesc') }}</option>
|
||||
</ui-select>
|
||||
<ui-select v-model="state">
|
||||
<span slot="label">{{ $t('users.state.title') }}</span>
|
||||
<option value="all">{{ $t('users.state.all') }}</option>
|
||||
<option value="admin">{{ $t('users.state.admin') }}</option>
|
||||
<option value="moderator">{{ $t('users.state.moderator') }}</option>
|
||||
<option value="verified">{{ $t('users.state.verified') }}</option>
|
||||
<option value="suspended">{{ $t('users.state.suspended') }}</option>
|
||||
</ui-select>
|
||||
<ui-select v-model="origin">
|
||||
<span slot="label">{{ $t('users.origin.title') }}</span>
|
||||
<option value="combined">{{ $t('users.origin.combined') }}</option>
|
||||
<option value="local">{{ $t('users.origin.local') }}</option>
|
||||
<option value="remote">{{ $t('users.origin.remote') }}</option>
|
||||
</ui-select>
|
||||
</ui-horizon-group>
|
||||
<sequential-entrance animation="entranceFromTop" delay="25">
|
||||
<div class="kofvwchc" v-for="user in users" :key="user.id">
|
||||
<div>
|
||||
<a :href="user | userPage(null, true)">
|
||||
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<header>
|
||||
<b><mk-user-name :user="user"/></b>
|
||||
<span class="username">@{{ user | acct }}</span>
|
||||
<span class="is-admin" v-if="user.isAdmin">admin</span>
|
||||
<span class="is-moderator" v-if="user.isModerator">moderator</span>
|
||||
<span class="is-verified" v-if="user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
|
||||
<span class="is-suspended" v-if="user.isSuspended" :title="$t('@.suspended-user')"><fa :icon="faSnowflake"/></span>
|
||||
</header>
|
||||
<div>
|
||||
<span>{{ $t('users.updatedAt') }}: <mk-time :time="user.updatedAt" mode="detail"/></span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ $t('users.createdAt') }}: <mk-time :time="user.createdAt" mode="detail"/></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</sequential-entrance>
|
||||
<ui-button v-if="existMore" @click="fetchUsers">{{ $t('@.load-more') }}</ui-button>
|
||||
</section>
|
||||
</ui-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from "vue";
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import parseAcct from "../../../../misc/acct/parse";
|
||||
import { faCertificate, faUsers, faTerminal, faSearch, faKey } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/users.vue'),
|
||||
|
||||
data() {
|
||||
return {
|
||||
verifyUsername: null,
|
||||
user: null,
|
||||
target: null,
|
||||
verifying: false,
|
||||
unverifyUsername: null,
|
||||
unverifying: false,
|
||||
suspendUsername: null,
|
||||
suspending: false,
|
||||
unsuspendUsername: null,
|
||||
unsuspending: false
|
||||
unsuspending: false,
|
||||
sort: '+createdAt',
|
||||
state: 'all',
|
||||
origin: 'combined',
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
users: [],
|
||||
existMore: false,
|
||||
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
sort() {
|
||||
this.users = [];
|
||||
this.offset = 0;
|
||||
this.fetchUsers();
|
||||
},
|
||||
|
||||
state() {
|
||||
this.users = [];
|
||||
this.offset = 0;
|
||||
this.fetchUsers();
|
||||
},
|
||||
|
||||
origin() {
|
||||
this.users = [];
|
||||
this.offset = 0;
|
||||
this.fetchUsers();
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.fetchUsers();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async fetchUser() {
|
||||
try {
|
||||
return await this.$root.api('users/show', this.target.startsWith('@') ? parseAcct(this.target) : { userId: this.target });
|
||||
} catch (e) {
|
||||
if (e == 'user not found') {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('user-not-found')
|
||||
});
|
||||
} else {
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async showUser() {
|
||||
const user = await this.fetchUser();
|
||||
this.$root.api('admin/show-user', { userId: user.id }).then(info => {
|
||||
this.user = info;
|
||||
});
|
||||
},
|
||||
|
||||
async resetPassword() {
|
||||
const user = await this.fetchUser();
|
||||
this.$root.api('admin/reset-password', { userId: user.id }).then(res => {
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('password-updated', { password: res.password })
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
async verifyUser() {
|
||||
this.verifying = true;
|
||||
|
||||
const process = async () => {
|
||||
const user = await (this as any).os.api('users/show', parseAcct(this.verifyUsername));
|
||||
await (this as any).os.api('admin/verify-user', { userId: user.id });
|
||||
//(this as any).os.apis.dialog({ text: '%i18n:@verified%' });
|
||||
const user = await this.fetchUser();
|
||||
await this.$root.api('admin/verify-user', { userId: user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('verified')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.verifying = false;
|
||||
@ -81,13 +192,19 @@ export default Vue.extend({
|
||||
this.unverifying = true;
|
||||
|
||||
const process = async () => {
|
||||
const user = await (this as any).os.api('users/show', parseAcct(this.unverifyUsername));
|
||||
await (this as any).os.api('admin/unverify-user', { userId: user.id });
|
||||
//(this as any).os.apis.dialog({ text: '%i18n:@unverified%' });
|
||||
const user = await this.fetchUser();
|
||||
await this.$root.api('admin/unverify-user', { userId: user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('unverified')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.unverifying = false;
|
||||
@ -97,13 +214,19 @@ export default Vue.extend({
|
||||
this.suspending = true;
|
||||
|
||||
const process = async () => {
|
||||
const user = await (this as any).os.api('users/show', parseAcct(this.suspendUsername));
|
||||
await (this as any).os.api('admin/suspend-user', { userId: user.id });
|
||||
//(this as any).os.apis.dialog({ text: '%i18n:@suspended%' });
|
||||
const user = await this.fetchUser();
|
||||
await this.$root.api('admin/suspend-user', { userId: user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('suspended')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.suspending = false;
|
||||
@ -113,16 +236,41 @@ export default Vue.extend({
|
||||
this.unsuspending = true;
|
||||
|
||||
const process = async () => {
|
||||
const user = await (this as any).os.api('users/show', parseAcct(this.unsuspendUsername));
|
||||
await (this as any).os.api('admin/unsuspend-user', { userId: user.id });
|
||||
//(this as any).os.apis.dialog({ text: '%i18n:@unsuspended%' });
|
||||
const user = await this.fetchUser();
|
||||
await this.$root.api('admin/unsuspend-user', { userId: user.id });
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('unsuspended')
|
||||
});
|
||||
};
|
||||
|
||||
await process().catch(e => {
|
||||
//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
|
||||
this.$root.dialog({
|
||||
type: 'error',
|
||||
text: e.toString()
|
||||
});
|
||||
});
|
||||
|
||||
this.unsuspending = false;
|
||||
},
|
||||
|
||||
fetchUsers() {
|
||||
this.$root.api('admin/show-users', {
|
||||
state: this.state,
|
||||
origin: this.origin,
|
||||
sort: this.sort,
|
||||
offset: this.offset,
|
||||
limit: this.limit + 1
|
||||
}).then(users => {
|
||||
if (users.length == this.limit + 1) {
|
||||
users.pop();
|
||||
this.existMore = true;
|
||||
} else {
|
||||
this.existMore = false;
|
||||
}
|
||||
this.users = this.users.concat(users);
|
||||
this.offset += this.limit;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -133,4 +281,42 @@ export default Vue.extend({
|
||||
@media (min-width 500px)
|
||||
padding 16px
|
||||
|
||||
.kofvwchc
|
||||
display flex
|
||||
padding 16px 0
|
||||
border-top solid 1px var(--faceDivider)
|
||||
|
||||
> div:first-child
|
||||
> a
|
||||
> .avatar
|
||||
width 64px
|
||||
height 64px
|
||||
|
||||
> div:last-child
|
||||
flex 1
|
||||
padding-left 16px
|
||||
|
||||
@media (max-width 500px)
|
||||
font-size 14px
|
||||
|
||||
> header
|
||||
> .username
|
||||
margin-left 8px
|
||||
opacity 0.7
|
||||
|
||||
> .is-admin
|
||||
> .is-moderator
|
||||
flex-shrink 0
|
||||
align-self center
|
||||
margin 0 0 0 .5em
|
||||
padding 1px 6px
|
||||
font-size 80%
|
||||
border-radius 3px
|
||||
background var(--noteHeaderAdminBg)
|
||||
color var(--noteHeaderAdminFg)
|
||||
|
||||
> .is-verified
|
||||
> .is-suspended
|
||||
margin 0 0 0 .5em
|
||||
color #4dabf7
|
||||
</style>
|
||||
|
@ -10,3 +10,19 @@
|
||||
opacity: 0;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
|
||||
.entranceFromTop {
|
||||
animation-duration: 0.5s;
|
||||
animation-name: entranceFromTop;
|
||||
}
|
||||
|
||||
@keyframes entranceFromTop {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-64px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,6 @@ html
|
||||
body
|
||||
overflow-wrap break-word
|
||||
|
||||
#error
|
||||
padding 32px
|
||||
color #fff
|
||||
|
||||
hr
|
||||
border solid 1px #fff
|
||||
|
||||
#nprogress
|
||||
pointer-events none
|
||||
|
||||
@ -130,29 +123,3 @@ pre
|
||||
|
||||
[data-icon]
|
||||
display inline-block
|
||||
|
||||
.swal2-container
|
||||
z-index 10000 !important
|
||||
|
||||
&.swal2-shown
|
||||
background-color rgba(0, 0, 0, 0.5) !important
|
||||
|
||||
.swal2-popup
|
||||
background var(--face) !important
|
||||
|
||||
.swal2-content
|
||||
color var(--text) !important
|
||||
|
||||
.swal2-confirm
|
||||
background-color var(--primary) !important
|
||||
border-left-color var(--primary) !important
|
||||
border-right-color var(--primary) !important
|
||||
color var(--primaryForeground) !important
|
||||
|
||||
&:hover
|
||||
background-image none !important
|
||||
background-color var(--primaryDarken5) !important
|
||||
|
||||
&:active
|
||||
background-image none !important
|
||||
background-color var(--primaryDarken5) !important
|
||||
|
@ -9,20 +9,19 @@ import './style.styl';
|
||||
|
||||
import init from '../init';
|
||||
import Index from './views/index.vue';
|
||||
import * as config from '../config';
|
||||
import NotFound from '../common/views/pages/not-found.vue';
|
||||
|
||||
/**
|
||||
* init
|
||||
*/
|
||||
init(launch => {
|
||||
document.title = `${config.name} | %i18n:common.application-authorization%`;
|
||||
|
||||
// Init router
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: '/auth/',
|
||||
routes: [
|
||||
{ path: '/:token', component: Index },
|
||||
{ path: '*', component: NotFound }
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="form">
|
||||
<header>
|
||||
<h1>%i18n:@share-access%</h1>
|
||||
<h1 v-html="$t('share-access', { name: app.name })"></h1>
|
||||
<img :src="app.iconUrl"/>
|
||||
</header>
|
||||
<div class="app">
|
||||
@ -11,32 +11,35 @@
|
||||
<p class="description">{{ app.description }}</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>%i18n:@permission-ask%</h2>
|
||||
<h2>{{ $t('permission-ask') }}</h2>
|
||||
<ul>
|
||||
<template v-for="p in app.permission">
|
||||
<li v-if="p == 'account-read'">%i18n:@account-read%</li>
|
||||
<li v-if="p == 'account-write'">%i18n:@account-write%</li>
|
||||
<li v-if="p == 'note-write'">%i18n:@note-write%</li>
|
||||
<li v-if="p == 'like-write'">%i18n:@like-write%</li>
|
||||
<li v-if="p == 'following-write'">%i18n:@following-write%</li>
|
||||
<li v-if="p == 'drive-read'">%i18n:@drive-read%</li>
|
||||
<li v-if="p == 'drive-write'">%i18n:@drive-write%</li>
|
||||
<li v-if="p == 'notification-read'">%i18n:@notification-read%</li>
|
||||
<li v-if="p == 'notification-write'">%i18n:@notification-write%</li>
|
||||
<li v-if="p == 'account-read'">{{ $t('account-read') }}</li>
|
||||
<li v-if="p == 'account-write'">{{ $t('account-write') }}</li>
|
||||
<li v-if="p == 'note-write'">{{ $t('note-write') }}</li>
|
||||
<li v-if="p == 'like-write'">{{ $t('like-write') }}</li>
|
||||
<li v-if="p == 'following-write'">{{ $t('following-write') }}</li>
|
||||
<li v-if="p == 'drive-read'">{{ $t('drive-read') }}</li>
|
||||
<li v-if="p == 'drive-write'">{{ $t('drive-write') }}</li>
|
||||
<li v-if="p == 'notification-read'">{{ $t('notification-read') }}</li>
|
||||
<li v-if="p == 'notification-write'">{{ $t('notification-write') }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<div class="action">
|
||||
<button @click="cancel">%i18n:@cancel%</button>
|
||||
<button @click="accept">%i18n:@accept%</button>
|
||||
<button @click="cancel">{{ $t('cancel') }}</button>
|
||||
<button @click="accept">{{ $t('accept') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('auth/views/form.vue'),
|
||||
props: ['session'],
|
||||
computed: {
|
||||
app(): any {
|
||||
@ -45,7 +48,7 @@ export default Vue.extend({
|
||||
},
|
||||
methods: {
|
||||
cancel() {
|
||||
(this as any).api('auth/deny', {
|
||||
this.$root.api('auth/deny', {
|
||||
token: this.session.token
|
||||
}).then(() => {
|
||||
this.$emit('denied');
|
||||
@ -53,7 +56,7 @@ export default Vue.extend({
|
||||
},
|
||||
|
||||
accept() {
|
||||
(this as any).api('auth/accept', {
|
||||
this.$root.api('auth/accept', {
|
||||
token: this.session.token
|
||||
}).then(() => {
|
||||
this.$emit('accepted');
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="index">
|
||||
<main v-if="$store.getters.isSignedIn">
|
||||
<p class="fetching" v-if="fetching">%i18n:@loading%<mk-ellipsis/></p>
|
||||
<p class="fetching" v-if="fetching">{{ $t('loading') }}<mk-ellipsis/></p>
|
||||
<x-form
|
||||
class="form"
|
||||
ref="form"
|
||||
@ -11,20 +11,20 @@
|
||||
@accepted="accepted"
|
||||
/>
|
||||
<div class="denied" v-if="state == 'denied'">
|
||||
<h1>%i18n:@denied%</h1>
|
||||
<p>%i18n:@denied-paragraph%</p>
|
||||
<h1>{{ $t('denied') }}</h1>
|
||||
<p>{{ $t('denied-paragraph') }}</p>
|
||||
</div>
|
||||
<div class="accepted" v-if="state == 'accepted'">
|
||||
<h1>{{ session.app.isAuthorized ? '%i18n:@already-authorized%' : '%i18n:@allowed%' }}</h1>
|
||||
<p v-if="session.app.callbackUrl">%i18n:@callback-url%<mk-ellipsis/></p>
|
||||
<p v-if="!session.app.callbackUrl">%i18n:@please-go-back%</p>
|
||||
<h1>{{ session.app.isAuthorized ? this.$t('already-authorized') : this.$t('allowed') }}</h1>
|
||||
<p v-if="session.app.callbackUrl">{{ $t('callback-url') }}<mk-ellipsis/></p>
|
||||
<p v-if="!session.app.callbackUrl">{{ $t('please-go-back') }}</p>
|
||||
</div>
|
||||
<div class="error" v-if="state == 'fetch-session-error'">
|
||||
<p>%i18n:@error%</p>
|
||||
<p>{{ $t('error') }}</p>
|
||||
</div>
|
||||
</main>
|
||||
<main class="signin" v-if="!$store.getters.isSignedIn">
|
||||
<h1>%i18n:@sign-in%</h1>
|
||||
<h1>{{ $t('sign-in') }}</h1>
|
||||
<mk-signin/>
|
||||
</main>
|
||||
<footer><img src="/assets/auth/icon.svg" alt="Misskey"/></footer>
|
||||
@ -33,9 +33,11 @@
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import XForm from './form.vue';
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('auth/views/index.vue'),
|
||||
components: {
|
||||
XForm
|
||||
},
|
||||
@ -55,7 +57,7 @@ export default Vue.extend({
|
||||
if (!this.$store.getters.isSignedIn) return;
|
||||
|
||||
// Fetch session
|
||||
(this as any).api('auth/session/show', {
|
||||
this.$root.api('auth/session/show', {
|
||||
token: this.token
|
||||
}).then(session => {
|
||||
this.session = session;
|
||||
@ -63,7 +65,7 @@ export default Vue.extend({
|
||||
|
||||
// 既に連携していた場合
|
||||
if (this.session.app.isAuthorized) {
|
||||
(this as any).api('auth/accept', {
|
||||
this.$root.api('auth/accept', {
|
||||
token: this.session.token
|
||||
}).then(() => {
|
||||
this.accepted();
|
||||
|
@ -3,15 +3,9 @@
|
||||
* (ENTRY POINT)
|
||||
*/
|
||||
|
||||
/**
|
||||
* ドメインに基づいて適切なスクリプトを読み込みます。
|
||||
* ユーザーの言語およびモバイル端末か否かも考慮します。
|
||||
* webpackは介さないためrequireやimportは使えません。
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
(async function() {
|
||||
// キャッシュ削除要求があれば従う
|
||||
if (localStorage.getItem('shouldFlush') == 'true') {
|
||||
refresh();
|
||||
@ -23,9 +17,9 @@
|
||||
//#region Apply theme
|
||||
const theme = localStorage.getItem('theme');
|
||||
if (theme) {
|
||||
Object.entries(JSON.parse(theme)).forEach(([k, v]) => {
|
||||
for (const [k, v] of Object.entries(JSON.parse(theme))) {
|
||||
document.documentElement.style.setProperty(`--${k}`, v.toString());
|
||||
});
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@ -47,8 +41,12 @@
|
||||
if (`${url.pathname}/`.startsWith('/dev/')) app = 'dev';
|
||||
if (`${url.pathname}/`.startsWith('/auth/')) app = 'auth';
|
||||
if (`${url.pathname}/`.startsWith('/admin/')) app = 'admin';
|
||||
if (`${url.pathname}/`.startsWith('/test/')) app = 'test';
|
||||
//#endregion
|
||||
|
||||
// Script version
|
||||
const ver = localStorage.getItem('v') || VERSION;
|
||||
|
||||
//#region Detect the user language
|
||||
let lang = null;
|
||||
|
||||
@ -67,8 +65,21 @@
|
||||
langs.includes(settings.device.lang)) {
|
||||
lang = settings.device.lang;
|
||||
}
|
||||
|
||||
window.lang = lang;
|
||||
//#endregion
|
||||
|
||||
let locale = localStorage.getItem('locale');
|
||||
const localeKey = localStorage.getItem('localeKey');
|
||||
|
||||
if (locale == null || localeKey != `${ver}.${lang}`) {
|
||||
const locale = await fetch(`/assets/locales/${lang}.json?ver=${ver}`)
|
||||
.then(response => response.json());
|
||||
|
||||
localStorage.setItem('locale', JSON.stringify(locale));
|
||||
localStorage.setItem('localeKey', `${ver}.${lang}`);
|
||||
}
|
||||
|
||||
// Detect the user agent
|
||||
const ua = navigator.userAgent.toLowerCase();
|
||||
const isMobile = /mobile|iphone|ipad|android/.test(ua);
|
||||
@ -94,9 +105,6 @@
|
||||
app = isMobile ? 'mobile' : 'desktop';
|
||||
}
|
||||
|
||||
// Script version
|
||||
const ver = localStorage.getItem('v') || VERSION;
|
||||
|
||||
// Get salt query
|
||||
const salt = localStorage.getItem('salt')
|
||||
? `?salt=${localStorage.getItem('salt')}`
|
||||
@ -106,7 +114,7 @@
|
||||
// Note: 'async' make it possible to load the script asyncly.
|
||||
// 'defer' make it possible to run the script when the dom loaded.
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('src', `/assets/${app}.${ver}.${lang}.js${salt}`);
|
||||
script.setAttribute('src', `/assets/${app}.${ver}.js${salt}`);
|
||||
script.setAttribute('async', 'true');
|
||||
script.setAttribute('defer', 'true');
|
||||
head.appendChild(script);
|
||||
@ -142,6 +150,8 @@
|
||||
function refresh() {
|
||||
localStorage.setItem('shouldFlush', 'false');
|
||||
|
||||
localStorage.removeItem('locale');
|
||||
|
||||
// Random
|
||||
localStorage.setItem('salt', Math.random().toString().substr(2, 8));
|
||||
|
||||
@ -150,7 +160,7 @@
|
||||
navigator.serviceWorker.controller.postMessage('clear');
|
||||
|
||||
navigator.serviceWorker.getRegistrations().then(registrations => {
|
||||
registrations.forEach(registration => registration.unregister());
|
||||
for (const registration of registrations) registration.unregister();
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export default function<T extends object>(data: {
|
||||
export default function <T extends object>(data: {
|
||||
name: string;
|
||||
props?: () => T;
|
||||
}) {
|
||||
@ -53,11 +53,10 @@ export default function<T extends object>(data: {
|
||||
mergeProps() {
|
||||
if (data.props) {
|
||||
const defaultProps = data.props();
|
||||
Object.keys(defaultProps).forEach(prop => {
|
||||
if (!this.props.hasOwnProperty(prop)) {
|
||||
Vue.set(this.props, prop, defaultProps[prop]);
|
||||
}
|
||||
});
|
||||
for (const prop of Object.keys(defaultProps)) {
|
||||
if (this.props.hasOwnProperty(prop)) continue;
|
||||
Vue.set(this.props, prop, defaultProps[prop]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -66,7 +65,7 @@ export default function<T extends object>(data: {
|
||||
|
||||
this.bakeProps();
|
||||
|
||||
(this as any).api('i/update_widget', {
|
||||
this.$root.api('i/update_widget', {
|
||||
id: this.id,
|
||||
data: this.props
|
||||
});
|
||||
|
@ -28,15 +28,15 @@ const getKeyMap = keymap => Object.entries(keymap).map(([patterns, callback]): a
|
||||
shift: false
|
||||
} as pattern;
|
||||
|
||||
part.trim().split('+').forEach(key => {
|
||||
key = key.trim().toLowerCase();
|
||||
const keys = part.trim().split('+').map(x => x.trim().toLowerCase());
|
||||
for (const key of keys) {
|
||||
switch (key) {
|
||||
case 'ctrl': pattern.ctrl = true; break;
|
||||
case 'alt': pattern.alt = true; break;
|
||||
case 'shift': pattern.shift = true; break;
|
||||
default: pattern.which = keyCode(key).map(k => k.toLowerCase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return pattern;
|
||||
});
|
||||
@ -77,11 +77,7 @@ export default {
|
||||
const matched = match(e, action.patterns);
|
||||
|
||||
if (matched) {
|
||||
if (el._hotkey_global) {
|
||||
if (match(e, targetReservedKeys)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (el._hotkey_global && match(e, targetReservedKeys)) return;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -1,8 +1,7 @@
|
||||
import MiOS from '../../mios';
|
||||
import { clientVersion as current } from '../../config';
|
||||
|
||||
export default async function(mios: MiOS, force = false, silent = false) {
|
||||
const meta = await mios.getMeta(force);
|
||||
export default async function($root: any, force = false, silent = false) {
|
||||
const meta = await $root.getMeta(force);
|
||||
const newer = meta.clientVersion;
|
||||
|
||||
if (newer != current) {
|
||||
@ -15,19 +14,20 @@ export default async function(mios: MiOS, force = false, silent = false) {
|
||||
navigator.serviceWorker.controller.postMessage('clear');
|
||||
}
|
||||
|
||||
navigator.serviceWorker.getRegistrations().then(registrations => {
|
||||
registrations.forEach(registration => registration.unregister());
|
||||
});
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
for (const registration of registrations) {
|
||||
registration.unregister();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
mios.apis.dialog({
|
||||
title: '%i18n:common.update-available-title%',
|
||||
text: '%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current)
|
||||
/*if (!silent) {
|
||||
$root.dialog({
|
||||
title: $root.$t('@.update-available-title'),
|
||||
text: $root.$t('@.update-available', { newer, current })
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
return newer;
|
||||
} else {
|
||||
|
@ -22,7 +22,7 @@ export default function(type, data): Notification {
|
||||
|
||||
case 'unreadMessagingMessage':
|
||||
return {
|
||||
title: '%i18n:common.notification.message-from%'.split("{}")[0] + `${getUserName(data.user)}` + '%i18n:common.notification.message-from%'.split("{}")[1] ,
|
||||
title: '%i18n:common.notification.message-from%'.split('{}')[0] + `${getUserName(data.user)}` + '%i18n:common.notification.message-from%'.split('{}')[1] ,
|
||||
body: data.text, // TODO: getMessagingMessageSummary(data),
|
||||
icon: data.user.avatarUrl
|
||||
};
|
||||
@ -30,7 +30,7 @@ export default function(type, data): Notification {
|
||||
case 'reversiInvited':
|
||||
return {
|
||||
title: '%i18n:common.notification.reversi-invited%',
|
||||
body: '%i18n:common.notification.reversi-invited-by%'.split("{}")[0] + `${getUserName(data.parent)}` + '%i18n:common.notification.reversi-invited-by%'.split("{}")[1],
|
||||
body: '%i18n:common.notification.reversi-invited-by%'.split('{}')[0] + `${getUserName(data.parent)}` + '%i18n:common.notification.reversi-invited-by%'.split('{}')[1],
|
||||
icon: data.parent.avatarUrl
|
||||
};
|
||||
|
||||
@ -38,21 +38,21 @@ export default function(type, data): Notification {
|
||||
switch (data.type) {
|
||||
case 'mention':
|
||||
return {
|
||||
title: '%i18n:common.notification.notified-by%'.split("{}")[0] + `${getUserName(data.user)}:` + '%i18n:common.notification.notified-by%'.split("{}")[1],
|
||||
title: '%i18n:common.notification.notified-by%'.split('{}')[0] + `${getUserName(data.user)}:` + '%i18n:common.notification.notified-by%'.split('{}')[1],
|
||||
body: getNoteSummary(data),
|
||||
icon: data.user.avatarUrl
|
||||
};
|
||||
|
||||
case 'reply':
|
||||
return {
|
||||
title: '%i18n:common.notification.reply-from%'.split("{}")[0] + `${getUserName(data.user)}` + '%i18n:common.notification.reply-from%'.split("{}")[1],
|
||||
title: '%i18n:common.notification.reply-from%'.split('{}')[0] + `${getUserName(data.user)}` + '%i18n:common.notification.reply-from%'.split('{}')[1],
|
||||
body: getNoteSummary(data),
|
||||
icon: data.user.avatarUrl
|
||||
};
|
||||
|
||||
case 'quote':
|
||||
return {
|
||||
title: '%i18n:common.notification.quoted-by%'.split("{}")[0] + `${getUserName(data.user)}` + '%i18n:common.notification.quoted-by%'.split("{}")[1],
|
||||
title: '%i18n:common.notification.quoted-by%'.split('{}')[0] + `${getUserName(data.user)}` + '%i18n:common.notification.quoted-by%'.split('{}')[1],
|
||||
body: getNoteSummary(data),
|
||||
icon: data.user.avatarUrl
|
||||
};
|
||||
|
25
src/client/app/common/scripts/format-uptime.ts
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
/**
|
||||
* Format like the uptime command
|
||||
*/
|
||||
export default function(sec) {
|
||||
if (!sec) return sec;
|
||||
|
||||
const day = Math.floor(sec / 86400);
|
||||
const tod = sec % 86400;
|
||||
|
||||
// Days part in string: 2 days, 1 day, null
|
||||
const d = day >= 2 ? `${day} days` : day >= 1 ? `${day} day` : null;
|
||||
|
||||
// Time part in string: 1 sec, 1 min, 1:01
|
||||
const t
|
||||
= tod < 60 ? `${Math.floor(tod)} sec`
|
||||
: tod < 3600 ? `${Math.floor(tod / 60)} min`
|
||||
: `${Math.floor(tod / 60 / 60)}:${Math.floor((tod / 60) % 60).toString().padStart(2, '0')}`;
|
||||
|
||||
let str = '';
|
||||
if (d) str += `${d}, `;
|
||||
str += t;
|
||||
|
||||
return str;
|
||||
}
|
@ -1,15 +1,12 @@
|
||||
declare const fuckAdBlock: any;
|
||||
|
||||
export default (os) => {
|
||||
export default ($root: any) => {
|
||||
require('fuckadblock');
|
||||
|
||||
function adBlockDetected() {
|
||||
os.apis.dialog({
|
||||
title: '%fa:exclamation-triangle%%i18n:common.adblock.detected%',
|
||||
text: '%i18n:common.adblock.warning%',
|
||||
actins: [{
|
||||
text: 'OK'
|
||||
}]
|
||||
$root.dialog({
|
||||
title: $root.$t('@.adblock.detected'),
|
||||
text: $root.$t('@.adblock.warning')
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ const faces = [
|
||||
'(=^・・^=)',
|
||||
'v(\'ω\')v',
|
||||
'🐡( \'-\' 🐡 )フグパンチ!!!!',
|
||||
'🖕(´・_・`)🖕',
|
||||
'✌️(´・_・`)✌️',
|
||||
'(。>﹏<。)',
|
||||
'(Δ・x・Δ)'
|
||||
];
|
||||
|
@ -1,8 +1,10 @@
|
||||
const crypto = require('crypto');
|
||||
// スクリプトサイズがデカい
|
||||
//const crypto = require('crypto');
|
||||
|
||||
export default (data: ArrayBuffer) => {
|
||||
const buf = new Buffer(data);
|
||||
const hash = crypto.createHash("md5");
|
||||
hash.update(buf);
|
||||
return hash.digest("hex");
|
||||
};
|
||||
//const buf = new Buffer(data);
|
||||
//const hash = crypto.createHash('md5');
|
||||
//hash.update(buf);
|
||||
//return hash.digest('hex');
|
||||
return '';
|
||||
};
|
||||
|
@ -1,11 +0,0 @@
|
||||
/**
|
||||
* 中央値を求めます
|
||||
* @param samples サンプル
|
||||
*/
|
||||
export default function(samples) {
|
||||
if (!samples.length) return 0;
|
||||
const numbers = samples.slice(0).sort((a, b) => a - b);
|
||||
const middle = Math.floor(numbers.length / 2);
|
||||
const isEven = numbers.length % 2 === 0;
|
||||
return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle];
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import parse from '../../../../mfm/parse';
|
||||
import { sum } from '../../../../prelude/array';
|
||||
import { sum, unique } from '../../../../prelude/array';
|
||||
import shouldMuteNote from './should-mute-note';
|
||||
import MkNoteMenu from '../views/components/note-menu.vue';
|
||||
import MkReactionPicker from '../views/components/reaction-picker.vue';
|
||||
import Ok from '../views/components/ok.vue';
|
||||
|
||||
function focus(el, fn) {
|
||||
const target = fn(el);
|
||||
@ -22,7 +22,8 @@ type Opts = {
|
||||
export default (opts: Opts = {}) => ({
|
||||
data() {
|
||||
return {
|
||||
showContent: false
|
||||
showContent: false,
|
||||
hideThisNote: false
|
||||
};
|
||||
},
|
||||
|
||||
@ -64,6 +65,10 @@ export default (opts: Opts = {}) => ({
|
||||
return this.isRenote ? this.note.renote : this.note;
|
||||
},
|
||||
|
||||
isMyNote(): boolean {
|
||||
return this.$store.getters.isSignedIn && (this.$store.state.i.id === this.appearNote.userId);
|
||||
},
|
||||
|
||||
reactionsCount(): number {
|
||||
return this.appearNote.reactionCounts
|
||||
? sum(Object.values(this.appearNote.reactionCounts))
|
||||
@ -77,18 +82,23 @@ export default (opts: Opts = {}) => ({
|
||||
urls(): string[] {
|
||||
if (this.appearNote.text) {
|
||||
const ast = parse(this.appearNote.text);
|
||||
return ast
|
||||
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
|
||||
.map(t => t.url);
|
||||
// TODO: 再帰的にURL要素がないか調べる
|
||||
return unique(ast
|
||||
.filter(t => ((t.node.type == 'url' || t.node.type == 'link') && t.node.props.url && !t.node.props.silent))
|
||||
.map(t => t.node.props.url));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.hideThisNote = shouldMuteNote(this.$store.state.i, this.$store.state.settings, this.appearNote);
|
||||
},
|
||||
|
||||
methods: {
|
||||
reply(viaKeyboard = false) {
|
||||
(this as any).apis.post({
|
||||
this.$root.$post({
|
||||
reply: this.appearNote,
|
||||
animation: !viaKeyboard,
|
||||
cb: () => {
|
||||
@ -98,7 +108,7 @@ export default (opts: Opts = {}) => ({
|
||||
},
|
||||
|
||||
renote(viaKeyboard = false) {
|
||||
(this as any).apis.post({
|
||||
this.$root.$post({
|
||||
renote: this.appearNote,
|
||||
animation: !viaKeyboard,
|
||||
cb: () => {
|
||||
@ -115,43 +125,51 @@ export default (opts: Opts = {}) => ({
|
||||
|
||||
react(viaKeyboard = false) {
|
||||
this.blur();
|
||||
(this as any).os.new(MkReactionPicker, {
|
||||
this.$root.new(MkReactionPicker, {
|
||||
source: this.$refs.reactButton,
|
||||
note: this.appearNote,
|
||||
showFocus: viaKeyboard,
|
||||
animation: !viaKeyboard,
|
||||
compact: opts.mobile,
|
||||
big: opts.mobile
|
||||
animation: !viaKeyboard
|
||||
}).$once('closed', this.focus);
|
||||
},
|
||||
|
||||
reactDirectly(reaction) {
|
||||
(this as any).api('notes/reactions/create', {
|
||||
(this.$root.api('notes/reactions/create', {
|
||||
noteId: this.appearNote.id,
|
||||
reaction: reaction
|
||||
});
|
||||
},
|
||||
|
||||
undoReact(note) {
|
||||
const oldReaction = note.myReaction;
|
||||
if (!oldReaction) return;
|
||||
this.$root.api('notes/reactions/delete', {
|
||||
noteId: note.id
|
||||
});
|
||||
},
|
||||
|
||||
favorite() {
|
||||
(this as any).api('notes/favorites/create', {
|
||||
this.$root.api('notes/favorites/create', {
|
||||
noteId: this.appearNote.id
|
||||
}).then(() => {
|
||||
(this as any).os.new(Ok);
|
||||
this.$root.dialog({
|
||||
type: 'success',
|
||||
splash: true
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
del() {
|
||||
(this as any).api('notes/delete', {
|
||||
this.$root.api('notes/delete', {
|
||||
noteId: this.appearNote.id
|
||||
});
|
||||
},
|
||||
|
||||
menu(viaKeyboard = false) {
|
||||
(this as any).os.new(MkNoteMenu, {
|
||||
this.$root.new(MkNoteMenu, {
|
||||
source: this.$refs.menuButton,
|
||||
note: this.appearNote,
|
||||
animation: !viaKeyboard,
|
||||
compact: opts.mobile,
|
||||
animation: !viaKeyboard
|
||||
}).$once('closed', this.focus);
|
||||
},
|
||||
|
||||
|
@ -26,7 +26,7 @@ export default prop => ({
|
||||
|
||||
created() {
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
this.connection = (this as any).os.stream;
|
||||
this.connection = this.$root.stream;
|
||||
}
|
||||
},
|
||||
|
||||
@ -95,6 +95,7 @@ export default prop => ({
|
||||
Vue.set(this.$_ns_target.reactionCounts, reaction, 0);
|
||||
}
|
||||
|
||||
// Increment the count
|
||||
this.$_ns_target.reactionCounts[reaction]++;
|
||||
|
||||
if (body.userId == this.$store.state.i.id) {
|
||||
@ -103,6 +104,26 @@ export default prop => ({
|
||||
break;
|
||||
}
|
||||
|
||||
case 'unreacted': {
|
||||
const reaction = body.reaction;
|
||||
|
||||
if (this.$_ns_target.reactionCounts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.$_ns_target.reactionCounts[reaction] == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Decrement the count
|
||||
if (this.$_ns_target.reactionCounts[reaction] > 0) this.$_ns_target.reactionCounts[reaction]--;
|
||||
|
||||
if (body.userId == this.$store.state.i.id) {
|
||||
Vue.set(this.$_ns_target, 'myReaction', null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'pollVoted': {
|
||||
if (body.userId == this.$store.state.i.id) return;
|
||||
const choice = body.choice;
|
||||
|
18
src/client/app/common/scripts/should-mute-note.ts
Normal file
@ -0,0 +1,18 @@
|
||||
export default function(me, settings, note) {
|
||||
const isMyNote = note.userId == me.id;
|
||||
const isPureRenote = note.renoteId != null && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
||||
|
||||
const includesMutedWords = (text: string) =>
|
||||
text
|
||||
? settings.mutedWords.some(q => q.length > 0 && !q.some(word => !text.includes(word)))
|
||||
: false;
|
||||
|
||||
return (
|
||||
(!isMyNote && note.reply && includesMutedWords(note.reply.text)) ||
|
||||
(!isMyNote && note.renote && includesMutedWords(note.renote.text)) ||
|
||||
(settings.showMyRenotes === false && isMyNote && isPureRenote) ||
|
||||
(settings.showRenotedMyNotes === false && isPureRenote && note.renote.userId == me.id) ||
|
||||
(settings.showLocalRenotes === false && isPureRenote && note.renote.user.host == null) ||
|
||||
(!isMyNote && includesMutedWords(note.text))
|
||||
);
|
||||
}
|
@ -75,12 +75,10 @@ export default class Stream extends EventEmitter {
|
||||
|
||||
// チャンネル再接続
|
||||
if (isReconnect) {
|
||||
this.sharedConnectionPools.forEach(p => {
|
||||
for (const p of this.sharedConnectionPools)
|
||||
p.connect();
|
||||
});
|
||||
this.nonSharedConnections.forEach(c => {
|
||||
for (const c of this.nonSharedConnections)
|
||||
c.connect();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,9 +111,9 @@ export default class Stream extends EventEmitter {
|
||||
connections = [this.nonSharedConnections.find(c => c.id === id)];
|
||||
}
|
||||
|
||||
connections.filter(c => c != null).forEach(c => {
|
||||
for (const c of connections.filter(c => c != null)) {
|
||||
c.emit(body.type, body.body);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.emit(type, body);
|
||||
}
|
||||
|
@ -2,17 +2,19 @@
|
||||
<span class="mk-acct">
|
||||
<span class="name">@{{ user.username }}</span>
|
||||
<span class="host" :class="{ fade: $store.state.settings.contrastedAcct }" v-if="user.host || detail || $store.state.settings.showFullAcct">@{{ user.host || host }}</span>
|
||||
<fa v-if="user.isLocked == true" class="locked" icon="lock" fixed-width/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { host } from '../../../config';
|
||||
import { toUnicode } from 'punycode';
|
||||
export default Vue.extend({
|
||||
props: ['user', 'detail'],
|
||||
data() {
|
||||
return {
|
||||
host
|
||||
host: toUnicode(host)
|
||||
};
|
||||
}
|
||||
});
|
||||
@ -22,4 +24,8 @@ export default Vue.extend({
|
||||
.mk-acct
|
||||
> .host.fade
|
||||
opacity 0.5
|
||||
|
||||
> .locked
|
||||
opacity 0.8
|
||||
margin-left 0.5em
|
||||
</style>
|
||||
|