Compare commits
261 Commits
Author | SHA1 | Date | |
---|---|---|---|
d153d3b761 | |||
60561578d8 | |||
b8bc96c181 | |||
005d6b4ccf | |||
f972fb6920 | |||
77078f2ce2 | |||
dae6d60163 | |||
264d6afe5d | |||
52c1d87fa2 | |||
dccafca58d | |||
52c12f96d5 | |||
114a9fbdb2 | |||
20e67e7edd | |||
889b52e813 | |||
6c975275f8 | |||
1286dee1ab | |||
fee953b0df | |||
26e7454f0e | |||
edbaa07867 | |||
f7ebf14501 | |||
d00928cf3f | |||
b3a198cae6 | |||
8b87d56a5a | |||
62ac3400da | |||
d54f71774e | |||
a47358f590 | |||
8f2cf066b6 | |||
e3e5a4272b | |||
2dcb3af70f | |||
3a19e9f80e | |||
c6fe798092 | |||
e74a47916d | |||
761071e1ce | |||
9e3610d513 | |||
393ac6c203 | |||
b7a79d25b0 | |||
486f045751 | |||
d6e3ec3218 | |||
078b043cae | |||
296cbc2e5a | |||
a74beaac36 | |||
79f8eb910f | |||
c91eef0030 | |||
7bf9d726d0 | |||
1946ff8ed4 | |||
b4d85d4f69 | |||
a03702d2bd | |||
71d7de4989 | |||
35d9e13dbb | |||
b427842679 | |||
4ae172be57 | |||
e6705b1a65 | |||
bc22cabdb5 | |||
7128b9f16a | |||
8c0490fef1 | |||
882a81636d | |||
24b9be76ba | |||
e763c6e661 | |||
899e2c73d7 | |||
10cb15b000 | |||
873d4bd707 | |||
97dea72c94 | |||
7d49f260b8 | |||
3055e6d8c7 | |||
2c93246860 | |||
360c820b9d | |||
87847c6ed5 | |||
4874f54d4d | |||
ff73efcc08 | |||
4ee64cbd9e | |||
0c40a86fca | |||
f92eed0549 | |||
69ed8cc409 | |||
4fff1279db | |||
d80699e454 | |||
deee1dbf53 | |||
067588845b | |||
b177b0cafc | |||
5679777010 | |||
a70c24cd1e | |||
357f3dd258 | |||
d815838762 | |||
4ceef78599 | |||
d5811633ea | |||
32265da72c | |||
ef94236e7f | |||
2924f0e434 | |||
1e419a9e1f | |||
097ece9dc9 | |||
6b6483c9fc | |||
22049b10ff | |||
de86644cb6 | |||
657aac5bc5 | |||
7ae3640d1a | |||
6fb42857c6 | |||
abf21349cd | |||
ed17af8339 | |||
67f391f6d4 | |||
c6b25f317e | |||
d91fa1a37a | |||
6c3f052996 | |||
33b0c87fb1 | |||
5c490e7521 | |||
54961235a4 | |||
17eca2a18f | |||
137f3ee609 | |||
498f6e9be2 | |||
a5e841f59c | |||
9adab1e85e | |||
4288a843cb | |||
1669f5b265 | |||
1157298eb8 | |||
948a65bf39 | |||
20c076b369 | |||
b67ed64116 | |||
1da3777bfb | |||
ea6aa40b09 | |||
b002651194 | |||
1452512daf | |||
0e7778bebf | |||
698fbdf88b | |||
7b738deabf | |||
3c65e7b76e | |||
3fc427b699 | |||
03667e1fe6 | |||
5cfd000a7d | |||
fa66eac096 | |||
70eb75b7e6 | |||
2f6187a26a | |||
167da988da | |||
6935e647a6 | |||
743eca4a95 | |||
78598a92f9 | |||
94598ab555 | |||
c5bdee086d | |||
c6cfc3f908 | |||
84b488a912 | |||
ec4d5857d8 | |||
4576641105 | |||
572e475b39 | |||
882a30fabe | |||
feec35bf4f | |||
c9fea5a7a0 | |||
00f3a1e1ec | |||
5a8cc7851b | |||
9d81d06853 | |||
4fce5d8066 | |||
329e367bda | |||
ce056bf936 | |||
c6ab5faba6 | |||
6ce0804b43 | |||
a7a6563281 | |||
0a084a3363 | |||
beeb8de6da | |||
e73297f260 | |||
b408ef5ba5 | |||
50539099ab | |||
9a3a77cff0 | |||
cdc07945af | |||
9f9194ab5c | |||
136a087ae7 | |||
b9e91afa26 | |||
f943e39c89 | |||
75bdbff36d | |||
43930e6a84 | |||
57d0c19a98 | |||
66a11378d2 | |||
62b680cadd | |||
1e1ac13999 | |||
d27c454674 | |||
3263eaec32 | |||
de4e9a857c | |||
d838876ab1 | |||
03336f01b5 | |||
d212d693a4 | |||
d17fcd8e48 | |||
49b3ee36bd | |||
100d7adc3d | |||
68b1fea6bb | |||
4de6e1e28a | |||
84f8c34e90 | |||
77567cf114 | |||
3cf8e1917c | |||
84cbabec29 | |||
b88c65ab67 | |||
10782822de | |||
5457172aa5 | |||
d20a2c7080 | |||
c01098de16 | |||
0b14a57d55 | |||
405d104208 | |||
83e3316f06 | |||
2037d4c21d | |||
6cabf052b1 | |||
359e1b2e6e | |||
7b553b13ac | |||
79872ec3e8 | |||
e9df7265fa | |||
1ade89be35 | |||
3356f7113f | |||
e6495ea6e2 | |||
629991443a | |||
6848f05ea5 | |||
e58dd71829 | |||
1afa2f1202 | |||
f322cb444a | |||
69c3c4e3dc | |||
488e6feed9 | |||
40891aca48 | |||
cd0e557991 | |||
679f8ad614 | |||
00c647c736 | |||
1ac6af6ad1 | |||
a5d7099a3c | |||
e9c8a0f5d5 | |||
adcda0889e | |||
95cbcdd379 | |||
a5e8eb4b7b | |||
ed440f80f3 | |||
4e2ef94107 | |||
de690e0622 | |||
062e1a4940 | |||
cc3779b197 | |||
92dc34b51a | |||
f8ee615640 | |||
5dde8b4bdc | |||
2c70055a87 | |||
db8ab8b890 | |||
28da5c5a31 | |||
b345aad52c | |||
aa5af89dfc | |||
9a3a74db34 | |||
328619f1fc | |||
121e12785f | |||
cc3f0737a2 | |||
bc3714139f | |||
9200379997 | |||
0ee664db2b | |||
86487e6f66 | |||
adc2bcc59b | |||
21a54f559a | |||
145e16c266 | |||
68f4edd0ee | |||
7fd6a134d1 | |||
0db8d566e2 | |||
c6f6291fc0 | |||
c2d79450ea | |||
d58ae601f7 | |||
3ad73ad7d9 | |||
f0c4df1cc5 | |||
839784bc8c | |||
b758ec96ef | |||
2f8ceb9d22 | |||
e05ae5ebc2 | |||
ebc43be4b3 | |||
8543278ce3 | |||
9a98de7bd8 | |||
e1d69fb4ad | |||
946f9b4a2b | |||
9a270e59a4 | |||
2112fb3896 |
@ -32,7 +32,7 @@ jobs:
|
||||
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
|
||||
docker push -a misskey/misskey
|
||||
else
|
||||
echo -e '\033[0;33mAborted deploying to Docker Hub\033[0;39m'
|
||||
fi
|
||||
|
@ -62,6 +62,8 @@ Organize and store your files! Want to post a picture you have already uploaded?
|
||||
|
||||
...and more! Experience Misskey with your own eyes at [misskey.io](https://misskey.io/) or join one of the [other instances](https://joinmisskey.github.io/) that are available.
|
||||
|
||||
To recive updates of this repo, follow [@repo@misskey.io](https://misskey.io/@repo) on fediverse.
|
||||
|
||||
Screen shots
|
||||
----------------------------------------------------------------
|
||||
### Profile page
|
||||
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 9.1 KiB |
@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(0.413372,0,0,0.469741,64.564,40.5821)">
|
||||
<rect x="-156.189" y="-86.393" width="619.297" height="544.981" style="fill:rgb(27,30,31);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.898356,0,0,0.898356,-130.722,-120.968)">
|
||||
<g transform="matrix(0.5,0.866025,-0.866025,0.5,288,-166.277)">
|
||||
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-96,166.277)">
|
||||
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.5,-0.866025,0.866025,0.5,-96,498.831)">
|
||||
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653Z" style="fill:white;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-95.9902,55.4086)">
|
||||
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653ZM385.681,139.653C385.332,139.049 384.688,138.677 383.99,138.677C383.293,138.677 382.648,139.049 382.299,139.653C378.289,146.599 373.342,155.168 369.8,161.303C368.017,164.391 368.017,168.196 369.8,171.285C373.339,177.414 378.28,185.972 382.288,192.915C382.639,193.523 383.288,193.898 383.99,193.898C384.692,193.898 385.341,193.523 385.692,192.915C389.701,185.972 394.642,177.414 398.181,171.284C399.964,168.196 399.964,164.391 398.181,161.303L385.681,139.653Z" style="fill:rgb(150,208,74);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.5,-0.866025,0.866025,0.5,-2.64322e-11,554.256)">
|
||||
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653ZM385.681,139.653C385.332,139.049 384.688,138.677 383.99,138.677C383.293,138.677 382.648,139.049 382.299,139.653C378.289,146.599 373.342,155.168 369.8,161.303C368.017,164.391 368.017,168.196 369.8,171.285C373.339,177.414 378.28,185.972 382.288,192.915C382.639,193.523 383.288,193.898 383.99,193.898C384.692,193.898 385.341,193.523 385.692,192.915C389.701,185.972 394.642,177.414 398.181,171.284C399.964,168.196 399.964,164.391 398.181,161.303L385.681,139.653Z" style="fill:rgb(150,208,74);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.5,0.866025,-0.866025,0.5,192,-110.851)">
|
||||
<path d="M390.877,136.653C389.457,134.193 386.831,132.677 383.99,132.677C381.149,132.677 378.524,134.193 377.103,136.653C373.093,143.599 368.146,152.168 364.604,158.303C361.749,163.248 361.749,169.34 364.604,174.285C368.142,180.414 373.084,188.972 377.092,195.915C378.515,198.379 381.144,199.898 383.99,199.898C386.836,199.898 389.466,198.379 390.889,195.915C394.897,188.972 399.838,180.414 403.377,174.284C406.232,169.34 406.232,163.248 403.377,158.303C399.835,152.168 394.888,143.599 390.877,136.653ZM385.681,139.653C385.332,139.049 384.688,138.677 383.99,138.677C383.293,138.677 382.648,139.049 382.299,139.653C378.289,146.599 373.342,155.168 369.8,161.303C368.017,164.391 368.017,168.196 369.8,171.285C373.339,177.414 378.28,185.972 382.288,192.915C382.639,193.523 383.288,193.898 383.99,193.898C384.692,193.898 385.341,193.523 385.692,192.915C389.701,185.972 394.642,177.414 398.181,171.284C399.964,168.196 399.964,164.391 398.181,161.303L385.681,139.653Z" style="fill:rgb(150,208,74);"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
BIN
assets/mi-white.afdesign
Normal file
BIN
assets/mi.afdesign
Normal file
@ -1,3 +1,7 @@
|
||||
files:
|
||||
- source: /locales/ja-JP.yml
|
||||
translation: /locales/%locale%.yml
|
||||
update_option: update_as_unapproved
|
||||
- source: /src/docs/ja-JP/*.md
|
||||
translation: /src/docs/%locale%/%original_file_name%
|
||||
update_option: update_as_unapproved
|
||||
|
27
gulpfile.ts
@ -7,6 +7,9 @@ import * as gulp from 'gulp';
|
||||
import * as ts from 'gulp-typescript';
|
||||
import * as rimraf from 'rimraf';
|
||||
import * as rename from 'gulp-rename';
|
||||
import * as replace from 'gulp-replace';
|
||||
const terser = require('gulp-terser');
|
||||
const cssnano = require('gulp-cssnano');
|
||||
|
||||
const locales: { [x: string]: any } = require('./locales');
|
||||
const meta = require('./package.json');
|
||||
@ -25,6 +28,10 @@ gulp.task('build:copy:views', () =>
|
||||
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
|
||||
);
|
||||
|
||||
gulp.task('build:copy:fonts', () =>
|
||||
gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/'))
|
||||
);
|
||||
|
||||
gulp.task('build:copy:locales', cb => {
|
||||
fs.mkdirSync('./built/client/assets/locales', { recursive: true });
|
||||
|
||||
@ -37,11 +44,23 @@ gulp.task('build:copy:locales', cb => {
|
||||
cb();
|
||||
});
|
||||
|
||||
gulp.task('build:copy:fonts', () =>
|
||||
gulp.src('./node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/client/assets/fonts/'))
|
||||
);
|
||||
gulp.task('build:client:script', () => {
|
||||
return gulp.src(['./src/server/web/boot.js'])
|
||||
.pipe(replace('VERSION', JSON.stringify(meta.version)))
|
||||
.pipe(replace('LANGS', JSON.stringify(Object.keys(locales))))
|
||||
.pipe(terser({
|
||||
toplevel: true
|
||||
}))
|
||||
.pipe(gulp.dest('./built/server/web/'));
|
||||
});
|
||||
|
||||
gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:locales', 'build:copy:fonts', () =>
|
||||
gulp.task('build:client:style', () => {
|
||||
return gulp.src(['./src/server/web/style.css'])
|
||||
.pipe(cssnano())
|
||||
.pipe(gulp.dest('./built/server/web/'));
|
||||
});
|
||||
|
||||
gulp.task('build:copy', gulp.parallel('build:copy:locales', 'build:copy:views', 'build:client:script', 'build:client:style', 'build:copy:fonts', () =>
|
||||
gulp.src([
|
||||
'./src/emojilist.json',
|
||||
'./src/server/web/views/**/*',
|
||||
|
@ -45,6 +45,7 @@ copyUsername: "انسخ اسم المستخدم"
|
||||
searchUser: "ابحث عن مستخدمين"
|
||||
reply: "رد"
|
||||
loadMore: "عرض المزيد"
|
||||
showMore: "عرض المزيد"
|
||||
youGotNewFollower: "يتابعك"
|
||||
receiveFollowRequest: "تلقيت طلب متابعة"
|
||||
followRequestAccepted: "قُبل طلب المتابعة"
|
||||
@ -175,16 +176,23 @@ remove: "حذف"
|
||||
removed: "تم حذفه بنجاح"
|
||||
removeAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
||||
deleteAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
||||
resetAreYouSure: "هل تريد إعادة التعيين؟"
|
||||
saved: "تم حفظه"
|
||||
messaging: "الدردشة"
|
||||
upload: "تحميل"
|
||||
fromDrive: "من المخزن"
|
||||
fromUrl: "من عنوان URL"
|
||||
uploadFromUrl: "التحميل عبر URL"
|
||||
uploadFromUrlDescription: "رابط الملف المراد تحميله "
|
||||
uploadFromUrlRequested: "الرفع مطلوب"
|
||||
uploadFromUrlMayTakeTime: "سيستغرق بعض الوقت لاتمام الرفع "
|
||||
explore: "استكشاف"
|
||||
games: "ألعاب Misskey"
|
||||
messageRead: "مقروءة"
|
||||
noMoreHistory: "لا يوجد المزيد من التاريخ"
|
||||
startMessaging: "ابدأ الدردشة"
|
||||
nUsersRead: "تمت القراءة من {n}"
|
||||
agreeTo: "اوافق على {0}"
|
||||
tos: "شروط الخدمة"
|
||||
start: "البداية"
|
||||
home: "الرئيسي"
|
||||
@ -201,6 +209,7 @@ light: "فاتح"
|
||||
dark: "داكن"
|
||||
lightThemes: "الحلة الفاتحة"
|
||||
darkThemes: "الحلة الداكنة"
|
||||
syncDeviceDarkMode: "مطابقة الوضع المضلمومع اعدادات الجهاز"
|
||||
drive: "قرص التخرين"
|
||||
fileName: "اسم الملف"
|
||||
selectFile: "اختر ملفًا"
|
||||
@ -218,14 +227,17 @@ emptyFolder: "هذا المجلد فارغ"
|
||||
unableToDelete: "لا يمكن حذفه"
|
||||
inputNewFileName: "ادخل الإسم الجديد للملف"
|
||||
inputNewFolderName: "ادخل الإسم الجديد للمجلد"
|
||||
hasChildFilesOrFolders: "الان الملف غير فارغ. لا يمكن حذفه"
|
||||
copyUrl: "انسخ عنوان URL"
|
||||
rename: "إعادة التسمية"
|
||||
avatar: "الصورة الرمزية"
|
||||
banner: "الصورة الرأسية"
|
||||
nsfw: "محتوى حساس"
|
||||
whenServerDisconnected: "عند فقدان الاتصال بالخادم"
|
||||
disconnectedFromServer: "قُطِع الإتصال بالخادم"
|
||||
reload: "انعش"
|
||||
doNothing: "تجاهل"
|
||||
reloadConfirm: "هل ترغب في تحديث الجدول الزمني؟"
|
||||
watch: "راقب"
|
||||
unwatch: "إلغاء المراقبة"
|
||||
accept: "السماح"
|
||||
@ -243,10 +255,12 @@ dayX: "{day}"
|
||||
monthX: "{month}"
|
||||
yearX: "{year}"
|
||||
pages: "الصفحات"
|
||||
integration: "دمج"
|
||||
connectSerice: "أوصل"
|
||||
disconnectSerice: "قطع الاتصال"
|
||||
enableLocalTimeline: "تفعيل الخيط المحلي"
|
||||
enableGlobalTimeline: "تفعيل الخيط الزمني الشامل"
|
||||
disablingTimelinesInfo: "سيتمكن المسؤولون ومن تعديل دائمًا و من الوصول إلى جميع المخططات الزمنية ، حتى إذا لم يتم تمكينها."
|
||||
registration: "إنشاء حساب"
|
||||
enableRegistration: "تفعيل إنشاء الحسابات الجديدة"
|
||||
invite: "دعوة"
|
||||
@ -288,6 +302,8 @@ resetPassword: "أعد تعيين كلمتك السرية"
|
||||
newPasswordIs: "كلمتك السرية الجديدة هي {password}"
|
||||
share: "شارِك"
|
||||
notFound: "غير موجود"
|
||||
cacheClear: "مسح ذاكرة التخزين المؤقت"
|
||||
markAsReadAllNotifications: "وضع جميع الإشعارات كأنها مقروءة"
|
||||
help: "المساعدة"
|
||||
inputMessageHere: "اكتب رسالتك هنا"
|
||||
close: "اغلق"
|
||||
@ -328,6 +344,7 @@ aboutX: "عن {x}"
|
||||
useOsNativeEmojis: "استخدم الإيموجيات الخاصة بنظام التشغيل"
|
||||
youHaveNoGroups: "لا تمتلك أية فِرَق"
|
||||
noHistory: "السجل فارغ"
|
||||
signinHistory: "تاريخ تسجيل الدخول"
|
||||
doing: "انتظر لحظة"
|
||||
category: "الفئات"
|
||||
tags: "الوسوم"
|
||||
@ -336,6 +353,7 @@ createAccount: "أنشئ حسابًا"
|
||||
existingAcount: "الحسابات الموجودة"
|
||||
regenerate: "أعِد التوليد"
|
||||
fontSize: "حجم الخط"
|
||||
openImageInNewTab: "إفتح الصورة بصفحة جديدة"
|
||||
dashboard: "لوحة التحكم"
|
||||
local: "المحلي"
|
||||
remote: "بُعدي"
|
||||
@ -364,6 +382,9 @@ state: "الحالة"
|
||||
sort: "ترتيب حسب"
|
||||
output: "الخارجة"
|
||||
updateRemoteUser: "تحديث المعلومات عن المستخدم البعيد"
|
||||
deleteAllFiles: "حذف كافة الملفات"
|
||||
userSuspended: "تم تعليق هذا المستخدم."
|
||||
userSilenced: "تم إسكات هذا المستخدم."
|
||||
sidebar: "الشريط الجانبي"
|
||||
addItem: "إضافة عنصر"
|
||||
rooms: "الغرفة"
|
||||
@ -373,13 +394,32 @@ addedRelays: "المرحلات التي تم إضافتها"
|
||||
deletedNote: "ملاحظة محذوفة"
|
||||
invisibleNote: "ملاحظة مخفية"
|
||||
poll: "استطلاع رأي"
|
||||
useCw: "إخفاء المحتوى"
|
||||
themeEditor: "مصمم القوالب"
|
||||
manage: "إدارة "
|
||||
plugins: "الإضافات"
|
||||
pluginInstallWarn: "يرجى تنصيب إضافات ذات مصدر موثوق منه فقط."
|
||||
width: "العرض"
|
||||
height: "الإرتفاع"
|
||||
large: "كبير"
|
||||
medium: "متوسط"
|
||||
small: "صغير"
|
||||
permission: "أذونات"
|
||||
enableAll: "تشغيل الكل"
|
||||
disableAll: "تعطيل الكل"
|
||||
tokenRequested: "منح حق الوصول إلى الحساب"
|
||||
notificationType: "أنواع الإشعارات"
|
||||
edit: "التعديل"
|
||||
email: "البريد الإلكتروني "
|
||||
emailAddress: "عنوان البريد الالكتروني"
|
||||
smtpHost: "المضيف"
|
||||
smtpPort: "المنفذ"
|
||||
smtpUser: "اسم المستخدم"
|
||||
smtpPass: "الكلمة السرية"
|
||||
makeActive: "تفعيل"
|
||||
display: "المظهر"
|
||||
copy: "نسخ"
|
||||
metrics: "المقاييس"
|
||||
public: "للعامة"
|
||||
_mfm:
|
||||
mention: "أشر الى"
|
||||
@ -453,6 +493,7 @@ _widgets:
|
||||
activity: "النشاط"
|
||||
photos: "الصور"
|
||||
federation: "الفديرالية"
|
||||
jobQueue: "قائمة الانتظار"
|
||||
_cw:
|
||||
hide: "إخفاء"
|
||||
show: "عرض المزيد"
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
_lang_: "Deutsch"
|
||||
headlineMisskey: "Durch Notizen verbundenes Netzwerk"
|
||||
introMisskey: "Willkommen! Misskey ist eine dezentralisierte Open-Source Microblogging-Platform.\nVerfasse \"Notizen\" um mitzuteilen, was gerade passiert oder um Ereignisse mit Anderen zu teilen. 📡\nMit \"Reaktionen\" kannst du außerdem schnell deine Gefühle über Notizen anderer Benutzer zum Ausdruck bringen. 👍\nLass uns eine neue Welt erforschen! 🚀"
|
||||
monthAndDay: "{day}/{month}"
|
||||
search: "Suchen"
|
||||
@ -33,6 +34,9 @@ addUser: "Benutzer hinzufügen"
|
||||
favorite: "Zu Favoriten hinzufügen"
|
||||
favorites: "Favoriten"
|
||||
unfavorite: "Aus Favoriten entfernen"
|
||||
favorited: "Zu Favoriten hinzugefügt."
|
||||
alreadyFavorited: "Bereits zu den Favoriten hinzugefügt."
|
||||
cantFavorite: "Hinzufügen zu Favoriten fehlgeschlagen."
|
||||
pin: "Anheften"
|
||||
unpin: "Lösen"
|
||||
copyContent: "Inhalt kopieren"
|
||||
@ -46,6 +50,7 @@ copyUsername: "Benutzernamen kopieren"
|
||||
searchUser: "Benutzersuche"
|
||||
reply: "Antworten"
|
||||
loadMore: "Mehr anzeigen"
|
||||
showMore: "Mehr anzeigen"
|
||||
youGotNewFollower: "Du hast einen neuen Follower"
|
||||
receiveFollowRequest: "Follow-Anfrage erhalten"
|
||||
followRequestAccepted: "Follow-Anfrage akzeptiert"
|
||||
@ -87,6 +92,9 @@ followRequestPending: "Ausstehende Follow-Anfrage"
|
||||
enterEmoji: "Gib ein Emoji ein"
|
||||
renote: "Renote"
|
||||
unrenote: "Renote zurücknehmen"
|
||||
renoted: "Renote getätigt."
|
||||
cantRenote: "Renote dieses Beitrags nicht möglich."
|
||||
cantReRenote: "Renote einer Renote nicht möglich."
|
||||
quote: "Zitieren"
|
||||
pinnedNote: "Angepinnte Notiz"
|
||||
you: "Du"
|
||||
@ -176,7 +184,7 @@ clearCachedFiles: "Cache leeren"
|
||||
clearCachedFilesConfirm: "Sollen alle im Cache gespeicherten Dateien von anderen Instanzen wirklich gelöscht werden?"
|
||||
blockedInstances: "Blockierte Instanzen"
|
||||
blockedInstancesDescription: "Gib den Hostnamen der Instanz an, die blockiert werden soll. Blockierte Instanzen können nicht mehr mit dieser kommunizieren."
|
||||
muteAndBlock: "Stummgeschaltet / Blockiert"
|
||||
muteAndBlock: "Stummschaltungen / Blockierungen"
|
||||
mutedUsers: "Stummgeschaltete Benutzer"
|
||||
blockedUsers: "Blockierte Benutzer"
|
||||
noUsers: "Keine Benutzer"
|
||||
@ -310,7 +318,7 @@ enableRegistration: "Registration neuer Benutzer erlauben"
|
||||
invite: "Einladen"
|
||||
proxyRemoteFiles: "Dateien anderer Instanzen durch Proxy leiten"
|
||||
proxyRemoteFilesDescription: "Wenn diese Einstellung aktiviert ist, dann werden Dateien von anderen Instanzen, welche entweder nicht lokal gespeichert sind oder durch Überschreiten des Speicherlimits gelöscht wurden, durch einen Proxy geleitet. Hierbei wird auch ein Vorschaubild generiert. \n Dies hat keinen Effekt auf den Speicherplatz des Servers."
|
||||
driveCapacityPerLocalAccount: "Drivekapazität pro lokales Benutzerkonto"
|
||||
driveCapacityPerLocalAccount: "Drive-Kapazität pro lokales Benutzerkonto"
|
||||
driveCapacityPerRemoteAccount: "Drive-Kapazität pro Benutzer anderer Instanzen"
|
||||
inMb: "In Megabytes"
|
||||
iconUrl: "Icon-URL"
|
||||
@ -485,7 +493,7 @@ showFixedPostForm: "Bereich zum Schreiben neuer Notizen am Anfang der Chronik an
|
||||
newNoteRecived: "Es gibt neue Notizen"
|
||||
sounds: "Töne"
|
||||
listen: "Anhören"
|
||||
none: "Keine"
|
||||
none: "Nichts"
|
||||
showInPage: "In Seite anzeigen"
|
||||
popout: "Pop-Up"
|
||||
volume: "Lautstärke"
|
||||
@ -530,7 +538,7 @@ invisibleNote: "Private Notiz"
|
||||
enableInfiniteScroll: "Automatisch mehr Notizen laden"
|
||||
visibility: "Sichtbarkeit"
|
||||
poll: "Umfrage"
|
||||
useCw: "Inhalt verstecken"
|
||||
useCw: "Inhalt verdecken"
|
||||
enablePlayer: "Video-Player öffnen"
|
||||
disablePlayer: "Video-Player schließen"
|
||||
expandTweet: "Tweet ausklappen"
|
||||
@ -556,7 +564,7 @@ enableAll: "Alle aktivieren"
|
||||
disableAll: "Alle deaktivieren"
|
||||
tokenRequested: "Benutzerkontozugriff gewähren"
|
||||
pluginTokenRequestedDescription: "Dieses Plugin wird die hier konfigurierten Berechtigungen verwenden können."
|
||||
notificationType: "Benachrichtigungstyp"
|
||||
notificationType: "Benachrichtigungsart"
|
||||
edit: "Bearbeiten"
|
||||
useStarForReactionFallback: "Verwende ★ falls das Reaktions-Emoji unbekannt ist"
|
||||
emailConfig: "Email-Server Konfiguration"
|
||||
@ -619,7 +627,7 @@ createNew: "Neu erstellen"
|
||||
optional: "Optional"
|
||||
createNewClip: "Neuen Clip erstellen"
|
||||
public: "Öffentlich"
|
||||
i18nInfo: "Misskey wird durch freiwillige Helfer in viele verschiedene Sprachen übersetzt. Unter {link} kannst du mithelfen."
|
||||
i18nInfo: "Misskey wird durch freiwillige Helfer in viele verschiedene Sprachen übersetzt. Auf {link} kannst du mithelfen."
|
||||
manageAccessTokens: "Zugriffstoken verwalten"
|
||||
accountInfo: "Benutzerkonto-Informationen"
|
||||
notesCount: "Anzahl von Notizen"
|
||||
@ -655,6 +663,41 @@ useSystemFont: "Standardschriftart des Systems verwenden"
|
||||
clips: "Clips"
|
||||
experimentalFeatures: "Experimentelle Funktionalitäten"
|
||||
developer: "Entwickler"
|
||||
makeExplorable: "Benutzerkonto in \"Erkunden\" sichtbar machen"
|
||||
makeExplorableDescription: "Wenn diese Option deaktiviert ist, ist dein Benutzerkonto nicht im \"Erkunden\"-Bereich sichtbar."
|
||||
showGapBetweenNotesInTimeline: "Abstände zwischen Notizen auf der Chronik anzeigen"
|
||||
duplicate: "Duplizieren"
|
||||
left: "Links"
|
||||
center: "Mitte"
|
||||
wide: "Breit"
|
||||
narrow: "Schmal"
|
||||
reloadToApplySetting: "Diese Einstellung tritt nach einer Aktualisierung der Seite in Kraft. Jetzt aktualisieren?"
|
||||
showTitlebar: "Titelleiste anzeigen"
|
||||
clearCache: "Cache leeren"
|
||||
onlineUsersCount: "{n} Benutzer sind online"
|
||||
nUsers: "{n} Benutzer"
|
||||
nNotes: "{n} Notizen"
|
||||
sendErrorReports: "Fehlerberichte senden"
|
||||
sendErrorReportsDescription: "Ist diese Option aktiviert, so werden beim Auftreten von Fehlern detaillierte Fehlerinformationen an Misskey weitergegeben, was zur Verbesserung der Qualität von Misskey beiträgt."
|
||||
myTheme: "Mein Farbthema"
|
||||
backgroundColor: "Hintergrund"
|
||||
accentColor: "Akzentfarbe"
|
||||
textColor: "Text"
|
||||
saveAs: "Speichern als…"
|
||||
advanced: "Fortgeschritten"
|
||||
value: "Wert"
|
||||
updatedAt: "Zuletzt geändert am"
|
||||
saveConfirm: "Änderungen speichern?"
|
||||
deleteConfirm: "Wirklich löschen?"
|
||||
invalidValue: "Ungültiger Wert."
|
||||
registry: "Registry"
|
||||
closeAccount: "Benutzerkonto schließen"
|
||||
_registry:
|
||||
scope: "Scope"
|
||||
key: "Schlüssel"
|
||||
keys: "Schlüssel"
|
||||
domain: "Domain"
|
||||
createKey: "Schlüssel erstellen"
|
||||
_aboutMisskey:
|
||||
about: "Misskey ist Open-Source-Software die von syuilo seit 2014 entwickelt wird."
|
||||
contributors: "Hauptmitwirkende"
|
||||
@ -677,7 +720,7 @@ _mfm:
|
||||
hashtag: "Hashtag"
|
||||
hashtagDescription: "Mit einer Raute und Text kann ein Hashtag angegeben werden."
|
||||
url: "URL"
|
||||
urlDescription: "URLs können angezeigt werden."
|
||||
urlDescription: "Zeigt URLs an."
|
||||
link: "Link"
|
||||
linkDescription: "Ein spezifizierter Textabschnitt kann als URL angezeigt werden."
|
||||
bold: "Fett"
|
||||
@ -716,6 +759,16 @@ _mfm:
|
||||
twitchDescription: "Verleiht eine sehr stark zuckende Animation."
|
||||
spin: "Animation (Rotieren)"
|
||||
spinDescription: "Verleiht eine rotierende Animation."
|
||||
x2: "Groß"
|
||||
x2Description: "Lässt Inhalte größer angezeigt werden."
|
||||
x3: "Sehr groß"
|
||||
x3Description: "Lässt Inhalte noch größer angezeigt werden."
|
||||
x4: "Am größten"
|
||||
x4Description: "Lässt Inhalte noch größer als größer als groß angezeigt werden."
|
||||
blur: "Weichzeichner"
|
||||
blurDescription: "Inhalte durch Weihzeichnung verschwimmen lassen. Durch das Bewegen des Mauszeigers auf den Inhalt wird er klar angezeigt."
|
||||
font: "Schriftart"
|
||||
fontDescription: "Setzt die Schriftart des Inhaltes fest."
|
||||
_reversi:
|
||||
reversi: "Reversi"
|
||||
gameSettings: "Spieleinstellungen"
|
||||
@ -800,7 +853,7 @@ _theme:
|
||||
refConst: "Konstante referenzieren"
|
||||
key: "Schlüssel"
|
||||
func: "Funktionen"
|
||||
funcKind: "Funktionstyp"
|
||||
funcKind: "Funktionsart"
|
||||
argument: "Parameter"
|
||||
basedProp: "Referenzierte Eigenschaft"
|
||||
alpha: "Transparenz"
|
||||
@ -837,9 +890,9 @@ _theme:
|
||||
infoFg: "Text von Informationen"
|
||||
infoWarnBg: "Hintergrund von Warnungen"
|
||||
infoWarnFg: "Text von Informationen"
|
||||
cwBg: "Hintergrund von versteckten Inhalten"
|
||||
cwFg: "Text von versteckten Inhalten"
|
||||
cwHoverBg: "Hintergrund von versteckten Inhalten (Mouseover)"
|
||||
cwBg: "Hintergrund von verdeckten Inhalten"
|
||||
cwFg: "Text von verdeckten Inhalten"
|
||||
cwHoverBg: "Hintergrund von verdeckten Inhalten (Mouseover)"
|
||||
toastBg: "Hintergrund von Benachrichtigungen"
|
||||
toastFg: "Text von Benachrichtigungen"
|
||||
buttonBg: "Hintergrund von Schaltflächen"
|
||||
@ -974,6 +1027,11 @@ _widgets:
|
||||
digitalClock: "Digitaluhr"
|
||||
federation: "Föderation"
|
||||
postForm: "Neue Notiz anfertigen"
|
||||
slideshow: "Diashow"
|
||||
button: "Knopf"
|
||||
onlineUsers: "Benutzer Online"
|
||||
jobQueue: "Job-Warteschlange"
|
||||
serverMetric: "Servermetriken"
|
||||
_cw:
|
||||
hide: "Ausblenden"
|
||||
show: "Mehr anzeigen"
|
||||
@ -1083,7 +1141,7 @@ _rooms:
|
||||
clearConfirm: "Möchtest du wirklich alle Möbel entfernen?"
|
||||
leaveConfirm: "Es gibt ungespeicherte Änderungen. Möchtest du wirklich gehen?"
|
||||
chooseImage: "Bild auswählen"
|
||||
roomType: "Raumtyp"
|
||||
roomType: "Raumart"
|
||||
carpetColor: "Teppichfarbe"
|
||||
_roomType:
|
||||
default: "Standard"
|
||||
@ -1456,14 +1514,18 @@ _notification:
|
||||
_deck:
|
||||
alwaysShowMainColumn: "Hauptspalte immer zeigen"
|
||||
columnAlign: "Spalten ausrichten"
|
||||
columnMargin: "Spaltenabstand"
|
||||
columnHeaderHeight: "Spaltenkopfhöhe"
|
||||
addColumn: "Spalte hinzufügen"
|
||||
swapLeft: "Nach links verschieben"
|
||||
swapRight: "Nach rechts verschieben"
|
||||
swapUp: "Nach oben verschieben"
|
||||
swapDown: "Nach unten verschieben"
|
||||
stackLeft: "Nach links stapeln"
|
||||
stackLeft: "Auf linke Spalte stapeln"
|
||||
popRight: "Nach rechts vom Stapel nehmen"
|
||||
profile: "Profil"
|
||||
_columns:
|
||||
main: "Hauptspalte"
|
||||
widgets: "Widgets"
|
||||
notifications: "Benachrichtigungen"
|
||||
tl: "Chronik"
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
_lang_: "English"
|
||||
headlineMisskey: "Network connected by notes"
|
||||
introMisskey: "Welcome! Misskey is an open source, and also a decentralized microblogging service.\nCreate \"notes\" to share what is happening now, or to share it with everyone around you 📡\nWith \"reactions\", you can also quickly express your feelings about everyone's notes 👍\nLet's explore a new world 🚀"
|
||||
monthAndDay: "{month}/{day}"
|
||||
search: "Search"
|
||||
@ -33,6 +34,9 @@ addUser: "Add a user"
|
||||
favorite: "Favorite"
|
||||
favorites: "Favorites"
|
||||
unfavorite: "Unfavorite"
|
||||
favorited: "Added to favorites."
|
||||
alreadyFavorited: "Already added to favorites."
|
||||
cantFavorite: "Couldn't add to favorites."
|
||||
pin: "Pin to profile"
|
||||
unpin: "Unpin from profile"
|
||||
copyContent: "Copy contents"
|
||||
@ -46,6 +50,7 @@ copyUsername: "Copy username"
|
||||
searchUser: "User search"
|
||||
reply: "Reply"
|
||||
loadMore: "Load more"
|
||||
showMore: "Load more"
|
||||
youGotNewFollower: "Followed you"
|
||||
receiveFollowRequest: "Follow request received"
|
||||
followRequestAccepted: "Follow request accepted"
|
||||
@ -63,7 +68,7 @@ exportRequested: "You have requested an export. This may take a while. After the
|
||||
importRequested: "You requested an import. This may take a while."
|
||||
lists: "Lists"
|
||||
noLists: "You don't have any lists"
|
||||
note: "Notes"
|
||||
note: "Note"
|
||||
notes: "Notes"
|
||||
following: "Following"
|
||||
followers: "Followers"
|
||||
@ -74,7 +79,7 @@ error: "Error"
|
||||
somethingHappened: "An error occurred"
|
||||
retry: "Retry"
|
||||
pageLoadError: "Failed to load page"
|
||||
pageLoadErrorDescription: "This is normally caused by network errors or the browser's cache. Try clearung the cache and then try again after waiting a little while."
|
||||
pageLoadErrorDescription: "This is normally caused by network errors or the browser's cache. Try clearing the cache and then try again after waiting a little while."
|
||||
enterListName: "List name"
|
||||
privacy: "Privacy"
|
||||
makeFollowManuallyApprove: "Follow requests require approval"
|
||||
@ -87,6 +92,9 @@ followRequestPending: "Pending follow request"
|
||||
enterEmoji: "Enter an emoji"
|
||||
renote: "Renote"
|
||||
unrenote: "Unrenote"
|
||||
renoted: "Renoted."
|
||||
cantRenote: "This post can't be renoted."
|
||||
cantReRenote: "A renote can't be renoted."
|
||||
quote: "Quote"
|
||||
pinnedNote: "Pinned note"
|
||||
you: "You"
|
||||
@ -245,7 +253,7 @@ birthday: "Birthday"
|
||||
yearsOld: "{age} years old"
|
||||
registeredDate: "Joined on"
|
||||
location: "Location"
|
||||
theme: "Theme"
|
||||
theme: "Themes"
|
||||
themeForLightMode: "Theme to use in Light Mode"
|
||||
themeForDarkMode: "Theme to use in Dark Mode"
|
||||
light: "Light"
|
||||
@ -306,7 +314,7 @@ enableLocalTimeline: "Enable local timeline"
|
||||
enableGlobalTimeline: "Enable global timeline"
|
||||
disablingTimelinesInfo: "Admins and Mods will always have access to all timelines, even if they are not enabled."
|
||||
registration: "Register"
|
||||
enableRegistration: "Enable new user registeration"
|
||||
enableRegistration: "Enable new user registration"
|
||||
invite: "Invite"
|
||||
proxyRemoteFiles: "Proxy remote files"
|
||||
proxyRemoteFilesDescription: "If enabled, remote files that (1) are not stored locally or (2) got deleted from exceeding storage limit will be locally proxied (with thumbnails). This does not affect the server's storage."
|
||||
@ -655,6 +663,41 @@ useSystemFont: "Use the system's default font"
|
||||
clips: "Clips"
|
||||
experimentalFeatures: "Experimental features"
|
||||
developer: "Developer"
|
||||
makeExplorable: "Make account visible in \"Explore\""
|
||||
makeExplorableDescription: "If you turn this off, your account will not show up in the \"Explore\" section."
|
||||
showGapBetweenNotesInTimeline: "Show a gap between posts on the timeline"
|
||||
duplicate: "Duplicate"
|
||||
left: "Left"
|
||||
center: "Center"
|
||||
wide: "Wide"
|
||||
narrow: "Narrow"
|
||||
reloadToApplySetting: "This setting will be applied upon page reload. Reload now?"
|
||||
showTitlebar: "Show title bar"
|
||||
clearCache: "Clear cache"
|
||||
onlineUsersCount: "{n} people are online"
|
||||
nUsers: "{n} Users"
|
||||
nNotes: "{n} Notes"
|
||||
sendErrorReports: "Send error reports"
|
||||
sendErrorReportsDescription: "When turned on, detailed error information will be shared with Misskey when a problem occurs, helping to improve the quality of Misskey."
|
||||
myTheme: "My theme"
|
||||
backgroundColor: "Background"
|
||||
accentColor: "Accent"
|
||||
textColor: "Text"
|
||||
saveAs: "Save as..."
|
||||
advanced: "Advanced"
|
||||
value: "Value"
|
||||
updatedAt: "Updated at"
|
||||
saveConfirm: "Save changes?"
|
||||
deleteConfirm: "Really delete?"
|
||||
invalidValue: "Invalid value."
|
||||
registry: "Registry"
|
||||
closeAccount: "Close account"
|
||||
_registry:
|
||||
scope: "Scope"
|
||||
key: "Key"
|
||||
keys: "Keys"
|
||||
domain: "Domain"
|
||||
createKey: "Create key"
|
||||
_aboutMisskey:
|
||||
about: "Misskey is open-source software being developed by syuilo since 2014."
|
||||
contributors: "Main contributors"
|
||||
@ -716,6 +759,16 @@ _mfm:
|
||||
twitchDescription: "Infuses a strongly twitching animation."
|
||||
spin: "Animation (Spin)"
|
||||
spinDescription: "Infuses a spinning animation."
|
||||
x2: "Big"
|
||||
x2Description: "Displays content bigger."
|
||||
x3: "Very big"
|
||||
x3Description: "Displays content even bigger."
|
||||
x4: "Extremely big"
|
||||
x4Description: "Displays content even bigger than bigger than big."
|
||||
blur: "Blur"
|
||||
blurDescription: "Content can be blurred via this effect. It will be clearly displayed by hovering your cursor above it."
|
||||
font: "Font"
|
||||
fontDescription: "Sets the font to display contents in."
|
||||
_reversi:
|
||||
reversi: "Reversi"
|
||||
gameSettings: "Game settings"
|
||||
@ -974,6 +1027,11 @@ _widgets:
|
||||
digitalClock: "Digital clock"
|
||||
federation: "Federation"
|
||||
postForm: "Compose a note"
|
||||
slideshow: "Slideshow"
|
||||
button: "Button"
|
||||
onlineUsers: "Online users"
|
||||
jobQueue: "Job Queue"
|
||||
serverMetric: "Server metrics"
|
||||
_cw:
|
||||
hide: "Hide"
|
||||
show: "Load more"
|
||||
@ -1456,14 +1514,18 @@ _notification:
|
||||
_deck:
|
||||
alwaysShowMainColumn: "Always show main column"
|
||||
columnAlign: "Align columns"
|
||||
columnMargin: "Margin between columns"
|
||||
columnHeaderHeight: " Column header height"
|
||||
addColumn: "Add column"
|
||||
swapLeft: "Swap to left"
|
||||
swapRight: "Swap to right"
|
||||
swapUp: "Swap with above"
|
||||
swapDown: "Swap with below"
|
||||
stackLeft: "Stack on the left"
|
||||
stackLeft: "Stack on left column"
|
||||
popRight: "Pop to the right"
|
||||
profile: "Profile"
|
||||
_columns:
|
||||
main: "Main"
|
||||
widgets: "Widgets"
|
||||
notifications: "Notifications"
|
||||
tl: "Timeline"
|
||||
|
@ -33,6 +33,9 @@ addUser: "Agregar usuario"
|
||||
favorite: "Favorito"
|
||||
favorites: "Favoritos"
|
||||
unfavorite: "Quitar de favoritos"
|
||||
favorited: "Añadido a favoritos"
|
||||
alreadyFavorited: "Ya había sido añadido a favoritos"
|
||||
cantFavorite: "No fue añadido a favoritos"
|
||||
pin: "Fijar"
|
||||
unpin: "Desfijar"
|
||||
copyContent: "Copiar contenido"
|
||||
@ -46,6 +49,7 @@ copyUsername: "Copiar nombre de usuario"
|
||||
searchUser: "Búsqueda de usuarios"
|
||||
reply: "Responder"
|
||||
loadMore: "Ver más"
|
||||
showMore: "Ver más"
|
||||
youGotNewFollower: "te ha seguido"
|
||||
receiveFollowRequest: "Recibiste una solicitud de seguimiento"
|
||||
followRequestAccepted: "La solicitud de seguimiento fue aceptada"
|
||||
@ -87,6 +91,9 @@ followRequestPending: "Solicitudes de seguimiento pendientes"
|
||||
enterEmoji: "Ingresar emojis"
|
||||
renote: "Renotar"
|
||||
unrenote: "Quitar renota"
|
||||
renoted: "Renotado"
|
||||
cantRenote: "No se puede renotar este post"
|
||||
cantReRenote: "No se puede renotar una renota"
|
||||
quote: "Citar"
|
||||
pinnedNote: "Nota fijada"
|
||||
you: "Tú"
|
||||
@ -95,6 +102,7 @@ sensitive: "Marcado como sensible"
|
||||
add: "Agregar"
|
||||
reaction: "Reacción"
|
||||
reactionSettingDescription: "Asigne sus reacción favoritas que desean anclar en el selector de reacciones."
|
||||
reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete la tecla + para añadir."
|
||||
rememberNoteVisibility: "Recordar visibilidad"
|
||||
attachCancel: "Quitar adjunto"
|
||||
markAsSensitive: "Marcar como sensible"
|
||||
@ -124,7 +132,9 @@ settingGuide: "Configuración sugerida"
|
||||
cacheRemoteFiles: "Mantener en cache los archivos remotos"
|
||||
cacheRemoteFilesDescription: "Si desactiva esta configuración, Los archivos remotos se cargarán desde el link directo sin usar la caché. Con eso se puede ahorrar almacenamiento del servidor, pero eso aumentará el tráfico al no crear miniaturas."
|
||||
flagAsBot: "Esta cuenta es un bot"
|
||||
flagAsBotDescription: "En caso de que esta cuenta fuera usada por un programa, active esta opción. Al hacerlo, esta opción servirá para otros desarrolladores para evitar cadenas infinitas de reacciones, y ajustará los sistemas internos de Misskey para que trate a esta cuenta como un bot."
|
||||
flagAsCat: "Esta cuenta es un gato"
|
||||
flagAsCatDescription: "En caso de que declare que esta cuenta es de un gato, active esta opción."
|
||||
autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los usuarios que sigues"
|
||||
addAcount: "Agregar cuenta"
|
||||
loginFailed: "Error al iniciar sesión."
|
||||
@ -215,6 +225,7 @@ remove: "Borrar"
|
||||
removed: "Borrado"
|
||||
removeAreYouSure: "¿Desea borrar \"{x}\"?"
|
||||
deleteAreYouSure: "¿Desea borrar \"{x}\"?"
|
||||
resetAreYouSure: "¿Desea reestablecer?"
|
||||
saved: "Guardado"
|
||||
messaging: "Chat"
|
||||
upload: "Subir"
|
||||
@ -314,6 +325,9 @@ bannerUrl: "URL de la imagen del banner"
|
||||
basicInfo: "Información básica"
|
||||
pinnedUsers: "Usuarios fijados"
|
||||
pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\" separados por una linea nueva"
|
||||
pinnedPages: "Páginas fijadas"
|
||||
pinnedPagesDescription: "Describa las rutas de las páginas que desea fijar a la página principal de la instancia, separadas por lineas nuevas"
|
||||
pinnedClipId: "Id del clip fijado"
|
||||
pinnedNotes: "Nota fijada"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Habilitar hCaptcha"
|
||||
@ -429,6 +443,7 @@ useOsNativeEmojis: "Usa los emojis nativos de la plataforma"
|
||||
youHaveNoGroups: "Sin grupos"
|
||||
joinOrCreateGroup: "Obtenga una invitación para unirse al grupos o puede crear su propio grupo."
|
||||
noHistory: "No hay datos en el historial"
|
||||
signinHistory: "Historial de ingresos"
|
||||
disableAnimatedMfm: "Deshabilitar MFM que tiene animaciones"
|
||||
doing: "Voy en camino"
|
||||
category: "Categoría"
|
||||
@ -481,6 +496,7 @@ none: "Ninguna"
|
||||
showInPage: "Mostrar en la página"
|
||||
popout: "Popout"
|
||||
volume: "Volumen"
|
||||
masterVolume: "Volumen principal"
|
||||
details: "Detalles"
|
||||
chooseEmoji: "Elije un emoji"
|
||||
unableToProcess: "La operación no se puede llevar a cabo"
|
||||
@ -538,6 +554,9 @@ useBlurEffectForModal: "Usar efecto borroso en modales"
|
||||
useFullReactionPicker: "Reacción"
|
||||
width: "Ancho"
|
||||
height: "Altura"
|
||||
large: "Grande"
|
||||
medium: "Mediano"
|
||||
small: "Pequeño"
|
||||
generateAccessToken: "Generar token de acceso"
|
||||
permission: "Permisos"
|
||||
enableAll: "Activar todo"
|
||||
@ -550,6 +569,8 @@ useStarForReactionFallback: "En caso de que los emojis de reacciones no sean cla
|
||||
emailConfig: "Configuración del servidor de correos"
|
||||
enableEmail: "Activar el envío de correos electrónicos"
|
||||
emailConfigInfo: "Usar en caso de validación de correo electrónico y pedido de contraseña"
|
||||
email: "Correo"
|
||||
emailAddress: "Correo electrónico"
|
||||
smtpConfig: "Configuración del servidor SMTP"
|
||||
smtpHost: "Host"
|
||||
smtpPort: "Puerto"
|
||||
@ -581,6 +602,7 @@ regenerateLoginTokenDescription: "Regenerar el token usado internamente durante
|
||||
setMultipleBySeparatingWithSpace: "Puedes añadir mas de uno, separado por espacios."
|
||||
fileIdOrUrl: "Id del archivo o URL"
|
||||
chatOpenBehavior: "Comportamiento al abrir el chat"
|
||||
behavior: "Comportamiento"
|
||||
sample: "Muestra"
|
||||
abuseReports: "Reportes"
|
||||
reportAbuse: "Reportar"
|
||||
@ -599,7 +621,40 @@ random: "Aleatorio"
|
||||
system: "Sistema"
|
||||
switchUi: "Cambiar interfaz de usuario"
|
||||
desktop: "Escritorio"
|
||||
clip: "Clip"
|
||||
createNew: "Crear"
|
||||
optional: "Opcional"
|
||||
createNewClip: "Crear clip nuevo"
|
||||
public: "Público"
|
||||
i18nInfo: "Misskey está siendo traducido a varios idiomas gracias a voluntarios. Se puede colaborar traduciendo en {link}"
|
||||
manageAccessTokens: "Administrar tokens de acceso"
|
||||
accountInfo: "Información de la Cuenta"
|
||||
notesCount: "Cantidad de notas"
|
||||
repliesCount: "Cantidad de respuestas hechas"
|
||||
renotesCount: "Cantidad de renotas hechas"
|
||||
repliedCount: "Cantidad de respuestas recibidas"
|
||||
renotedCount: "Cantidad de renotas recibidas"
|
||||
followingCount: "Cantidad de seguidos"
|
||||
followersCount: "Cantidad de seguidores"
|
||||
sentReactionsCount: "Cantidad de reacciones hechas"
|
||||
receivedReactionsCount: "Cantidad de reacciones recibidas"
|
||||
pollVotesCount: "Cantidad de votaciones hechas"
|
||||
pollVotedCount: "Cantidad de votaciones recibidas"
|
||||
yes: "Si"
|
||||
no: "No"
|
||||
driveFilesCount: "Cantidad de archivos en el drive"
|
||||
driveUsage: "Uso del drive"
|
||||
noCrawle: "Rechazar indexación del crawler"
|
||||
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc."
|
||||
clips: "Clip"
|
||||
clearCache: "Limpiar caché"
|
||||
backgroundColor: "Fondo"
|
||||
accentColor: "Acento"
|
||||
textColor: "Texto"
|
||||
value: "Valores"
|
||||
_registry:
|
||||
key: "Clave"
|
||||
keys: "Clave"
|
||||
_mfm:
|
||||
cheatSheet: "Hoja de referencia de MFM"
|
||||
intro: "MFM es un lenguaje de marcado dedicado que se puede usar en varios lugares dentro de Misskey. Aquí puede ver una lista de sintaxis disponibles en MFM."
|
||||
@ -617,6 +672,7 @@ _mfm:
|
||||
search: "Buscar"
|
||||
flip: "Echar de un capirotazo"
|
||||
flipDescription: "Voltea el contenido hacia arriba / abajo o hacia la izquierda / derecha."
|
||||
font: "Fuente"
|
||||
_reversi:
|
||||
reversi: "Reversi"
|
||||
gameSettings: "Configuración del juego"
|
||||
@ -871,6 +927,8 @@ _widgets:
|
||||
digitalClock: "Reloj digital"
|
||||
federation: "Federación"
|
||||
postForm: "Formulario"
|
||||
button: "Botón"
|
||||
jobQueue: "Cola de trabajos"
|
||||
_cw:
|
||||
hide: "Ocultar"
|
||||
show: "Ver más"
|
||||
|
@ -46,6 +46,7 @@ copyUsername: "Copier le nom d’utilisateur·rice"
|
||||
searchUser: "Chercher un·e utilisateur·rice"
|
||||
reply: "Répondre"
|
||||
loadMore: "Afficher plus …"
|
||||
showMore: "Afficher plus …"
|
||||
youGotNewFollower: "Vous suit"
|
||||
receiveFollowRequest: "Demande d’abonnement reçue"
|
||||
followRequestAccepted: "La demande d’abonnement a été acceptée"
|
||||
@ -577,6 +578,13 @@ fileIdOrUrl: "ID du fichier ou URL"
|
||||
chatOpenBehavior: "Comportement de la fenêtre de discussion lors de son ouverture"
|
||||
random: "Aléatoire"
|
||||
public: "Public"
|
||||
clearCache: "Vider le cache"
|
||||
backgroundColor: "Arrière-plan"
|
||||
textColor: "Texte"
|
||||
value: "Valeur"
|
||||
_registry:
|
||||
key: "Clé "
|
||||
keys: "Clé "
|
||||
_mfm:
|
||||
mention: "Mentionner"
|
||||
hashtag: "Hashtags"
|
||||
@ -585,6 +593,7 @@ _mfm:
|
||||
quote: "Citer"
|
||||
emoji: "Émojis personnalisés"
|
||||
search: "Rechercher"
|
||||
font: "Police de caractères"
|
||||
_reversi:
|
||||
total: "Total"
|
||||
_serverDisconnectedBehavior:
|
||||
@ -762,6 +771,8 @@ _widgets:
|
||||
digitalClock: "Horloge numérique"
|
||||
federation: "Fédération"
|
||||
postForm: "Formulaire à publier"
|
||||
button: "Bouton"
|
||||
jobQueue: "File d’attente"
|
||||
_cw:
|
||||
hide: "Masquer"
|
||||
show: "Afficher plus …"
|
||||
|
1
locales/ht-HT.yml
Normal file
@ -0,0 +1 @@
|
||||
---
|
219
locales/id-ID.yml
Normal file
@ -0,0 +1,219 @@
|
||||
---
|
||||
_lang_: "Bahasa Jepang"
|
||||
monthAndDay: "{day} {month}"
|
||||
search: "Pencarian"
|
||||
notifications: "Notifikasi"
|
||||
username: "Nama Pengguna"
|
||||
password: "Kata sandi"
|
||||
ok: "OK"
|
||||
gotIt: "Saya mengerti"
|
||||
cancel: "Batalkan"
|
||||
enterUsername: "Masukkan nama pengguna"
|
||||
renotedBy: "direnote oleh {user}"
|
||||
noNotes: "Tidak ada notes"
|
||||
noNotifications: "Tidak ada notifikasi"
|
||||
settings: "Pengaturan"
|
||||
basicSettings: "Pengaturan umum"
|
||||
otherSettings: "Pengaturan lainnya"
|
||||
openInWindow: "Buka di jendela"
|
||||
profile: "Profil"
|
||||
timeline: "Linimasa"
|
||||
noAccountDescription: "Pengguna ini belum menulis bio"
|
||||
login: "Masuk"
|
||||
loggingIn: "Sedang masuk"
|
||||
logout: "Keluar"
|
||||
signup: "Daftar"
|
||||
uploading: "Sedang mengunggah"
|
||||
save: "Simpan"
|
||||
users: "Pengguna"
|
||||
addUser: "Tambah pengguna"
|
||||
favorite: "Favorit"
|
||||
favorites: "Favorit"
|
||||
unfavorite: "Hapus favorit"
|
||||
favorited: "Ditambahkan ke favorit"
|
||||
alreadyFavorited: "Telah ditambahkan ke favorit"
|
||||
cantFavorite: "Tidak dapat menambahkan ke favorit"
|
||||
pin: "Sematkan ke profil"
|
||||
unpin: "Lepas sematan dari profil"
|
||||
copyContent: "Salin konten"
|
||||
copyLink: "Salin tautan"
|
||||
delete: "Hapus"
|
||||
deleteAndEdit: "Hapus dan sunting"
|
||||
addToList: "Tambahkan ke daftar"
|
||||
sendMessage: "Kirim pesan"
|
||||
copyUsername: "Salin nama pengguna"
|
||||
searchUser: "Cari pengguna"
|
||||
reply: "Balas"
|
||||
cantReRenote: "Renote tidak dapat direnote"
|
||||
quote: "Kutip"
|
||||
pinnedNote: "Note yang disematkan"
|
||||
you: "Anda"
|
||||
clickToShow: "Klik untuk melihat"
|
||||
sensitive: "Konten sensitif"
|
||||
add: "Tambahkan"
|
||||
reaction: "Reaksi"
|
||||
reactionSettingDescription: "Masukkan reaksi favorit yang ingin anda sematkan pada bilah reaksi"
|
||||
reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus, tekan \"+\" untuk menambahkan"
|
||||
rememberNoteVisibility: "Ingat pengaturan visibilitas note"
|
||||
attachCancel: "Hapus lampiran"
|
||||
markAsSensitive: "Tandai sebagai konten sensitif"
|
||||
unmarkAsSensitive: "Hapus tanda konten sensitif"
|
||||
enterFileName: "Masukkan nama berkas"
|
||||
mute: "Bisukan"
|
||||
unmute: "Hapus bisukan"
|
||||
block: "Blokir"
|
||||
unblock: "Buka blokir"
|
||||
suspend: "Bekukan"
|
||||
unsuspend: "Buka pembekuan"
|
||||
blockConfirm: "Apakah anda yakin ingin memblokir akun ini?"
|
||||
unblockConfirm: "Apakah anda yakin ingin membuka blokir akun ini?"
|
||||
suspendConfirm: "Apakah anda yakin ingin membekukan akun ini?"
|
||||
unsuspendConfirm: "Apakah anda yakin ingin membuka pembekuan akun ini?"
|
||||
selectList: "Pilih daftar"
|
||||
selectAntenna: "Pilih Antena"
|
||||
selectWidget: "Pilih gawit"
|
||||
editWidgets: "Sunting gawit"
|
||||
editWidgetsExit: "Selesai"
|
||||
customEmojis: "Emoji kustom"
|
||||
emoji: "Emoji"
|
||||
emojiName: "Nama emoji"
|
||||
emojiUrl: "URL Emoji"
|
||||
addEmoji: "Tambahkan emoji"
|
||||
settingGuide: "Pengaturan rekomendasi"
|
||||
cacheRemoteFiles: "Tembolokkan berkas remote"
|
||||
flagAsBot: "Atur akun ini sebagai Bot"
|
||||
flagAsCat: "Atur akun ini sebagai kucing"
|
||||
autoAcceptFollowed: "Setujui otomatis permintaan mengikuti dari pengguna yang anda ikuti"
|
||||
addAcount: "Tambahkan akun"
|
||||
loginFailed: "Gagal untuk masuk"
|
||||
showOnRemote: "Lihat profil asli"
|
||||
general: "Umum"
|
||||
wallpaper: "Wallpaper"
|
||||
setWallpaper: "Atur wallpaper"
|
||||
removeWallpaper: "Hapus wallpaper"
|
||||
intro: "Instalasi Misskey telah selesai! Mohon untuk membuat pengguna admin."
|
||||
done: "Selesai"
|
||||
processing: "Memproses"
|
||||
preview: "Pratinjau"
|
||||
default: "Bawaan"
|
||||
noCustomEmojis: "Tidak ada emoji kustom"
|
||||
federating: "memfederasi"
|
||||
blocked: "Diblokir"
|
||||
all: "Semua"
|
||||
subscribing: "Berlangganan"
|
||||
publishing: "Sedang menyiarkan langsung"
|
||||
notResponding: "Tidak ada respon"
|
||||
instanceFollowing: "Mengikuti instance"
|
||||
instanceFollowers: "Pengikut instance"
|
||||
instanceUsers: "Pengguna pada instance ini"
|
||||
changePassword: "Ubah kata sandi"
|
||||
security: "Keamanan"
|
||||
retypedNotMatch: "Input tidak sama"
|
||||
currentPassword: "Kata sandi saat ini"
|
||||
newPassword: "Kata sandi baru"
|
||||
newPasswordRetype: "Ulangi kata sandi baru"
|
||||
attachFile: "Lampirkan berkas"
|
||||
more: "Lagi !"
|
||||
featured: "Sorotan"
|
||||
usernameOrUserId: "Nama pengguna atau User ID"
|
||||
noSuchUser: "Pengguna tidak ditemukan"
|
||||
lookup: "Mencari"
|
||||
announcements: "Pengumuman"
|
||||
imageUrl: "URL Gambar"
|
||||
remove: "Hapus"
|
||||
removed: "Telah dihapus"
|
||||
removeAreYouSure: "Apakah anda yakin ingin menghapus \"{x}\"?"
|
||||
deleteAreYouSure: "Apakah anda yakin ingin menghapus \"{x}\"?"
|
||||
saved: "Telah disimpan"
|
||||
messaging: "Pesan"
|
||||
upload: "Unggah"
|
||||
fromDrive: "Dari Drive"
|
||||
fromUrl: "Dari URL"
|
||||
uploadFromUrl: "Unggah dari URL"
|
||||
uploadFromUrlDescription: "URL berkas yang ingin anda unggah"
|
||||
uploadFromUrlRequested: "Pengunggahan telah diminta"
|
||||
uploadFromUrlMayTakeTime: "Membutuhkan beberapa waktu hingga pengunggahan selesai"
|
||||
explore: "Jelajahi"
|
||||
games: "Permainan Misskey"
|
||||
messageRead: "Telah dibaca"
|
||||
noMoreHistory: "Tidak ada sejarah lagi"
|
||||
startMessaging: "Mulai mengirim pesan"
|
||||
nUsersRead: "Dibaca oleh {n}"
|
||||
nsfw: "Konten sensitif"
|
||||
watch: "Tonton"
|
||||
unwatch: "Batal tonton"
|
||||
accept: "Terima"
|
||||
reject: "Tolak"
|
||||
normal: "Normal"
|
||||
instanceName: "Nama instance"
|
||||
instanceDescription: "Tentang instance"
|
||||
maintainerName: "Pengelola"
|
||||
maintainerEmail: "Surel pengelola"
|
||||
tosUrl: "URL Syarat dan Ketentuan"
|
||||
thisYear: "Tahun ini"
|
||||
thisMonth: "Bulan ini"
|
||||
today: "Hari ini"
|
||||
dayX: "{day}"
|
||||
monthX: "{month}"
|
||||
yearX: "{year}"
|
||||
pages: "Halaman"
|
||||
integration: "Integrasi"
|
||||
connectSerice: "Sambungkan"
|
||||
disconnectSerice: "Putuskan"
|
||||
enableLocalTimeline: "Nyalakan linimasa lokal"
|
||||
enableGlobalTimeline: "Nyalakan linimasa global"
|
||||
registration: "Pendaftaran"
|
||||
enableRegistration: "Nyalakan pendaftaran pengguna baru"
|
||||
invite: "Undang"
|
||||
proxyRemoteFiles: "Proksi berkas remote"
|
||||
driveCapacityPerLocalAccount: "Kapasitas drive per pengguna lokal"
|
||||
driveCapacityPerRemoteAccount: "Kapasitas drive per pengguna remote"
|
||||
inMb: "dalam Megabytes"
|
||||
iconUrl: "URL Gambar ikon"
|
||||
bannerUrl: "URL Banner"
|
||||
basicInfo: "Informasi Umum"
|
||||
pinnedUsers: "Pengguna yang disematkan"
|
||||
pinnedPages: "Halaman yang disematkan"
|
||||
pinnedNotes: "Note yang disematkan"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Nyalakan hCaptcha"
|
||||
hcaptchaSiteKey: "Site Key"
|
||||
hcaptchaSecretKey: "Secret Key"
|
||||
recaptcha: "reCAPTCHA"
|
||||
enableRecaptcha: "Nyalakan reCAPTCHA"
|
||||
recaptchaSiteKey: "Site key"
|
||||
recaptchaSecretKey: "Secret Key"
|
||||
antennas: "Antena"
|
||||
manageAntennas: "Pengelola Antena"
|
||||
notFound: "Tidak dapat ditemukan"
|
||||
invites: "Undang"
|
||||
invitations: "Undang"
|
||||
smtpUser: "Nama Pengguna"
|
||||
smtpPass: "Kata sandi"
|
||||
_mfm:
|
||||
quote: "Kutip"
|
||||
emoji: "Emoji kustom"
|
||||
search: "Pencarian"
|
||||
_sfx:
|
||||
notification: "Notifikasi"
|
||||
chat: "Pesan"
|
||||
_widgets:
|
||||
notifications: "Notifikasi"
|
||||
timeline: "Linimasa"
|
||||
_profile:
|
||||
username: "Nama Pengguna"
|
||||
_exportOrImport:
|
||||
muteList: "Bisukan"
|
||||
blockingList: "Blokir"
|
||||
_rooms:
|
||||
_roomType:
|
||||
default: "Bawaan"
|
||||
_notification:
|
||||
_types:
|
||||
quote: "Kutip"
|
||||
reaction: "Reaksi"
|
||||
_deck:
|
||||
_columns:
|
||||
notifications: "Notifikasi"
|
||||
tl: "Linimasa"
|
||||
antenna: "Antena"
|
1
locales/it-IT.yml
Normal file
@ -0,0 +1 @@
|
||||
---
|
@ -1,5 +1,6 @@
|
||||
_lang_: "日本語"
|
||||
|
||||
headlineMisskey: "ノートでつながるネットワーク"
|
||||
introMisskey: "ようこそ!Misskeyは、オープンソースの分散型マイクロブログサービスです。\n「ノート」を作成して、いま起こっていることを共有したり、あなたについて皆に発信しよう📡\n「リアクション」機能で、皆のノートに素早く反応を追加することもできます👍\n新しい世界を探検しよう🚀"
|
||||
monthAndDay: "{month}月 {day}日"
|
||||
search: "検索"
|
||||
@ -33,6 +34,9 @@ addUser: "ユーザーを追加"
|
||||
favorite: "お気に入り"
|
||||
favorites: "お気に入り"
|
||||
unfavorite: "お気に入り解除"
|
||||
favorited: "お気に入りに登録しました。"
|
||||
alreadyFavorited: "既にお気に入りに登録されています。"
|
||||
cantFavorite: "お気に入りに登録できませんでした。"
|
||||
pin: "ピン留め"
|
||||
unpin: "ピン留め解除"
|
||||
copyContent: "内容をコピー"
|
||||
@ -46,6 +50,7 @@ copyUsername: "ユーザー名をコピー"
|
||||
searchUser: "ユーザーを検索"
|
||||
reply: "返信"
|
||||
loadMore: "もっと見る"
|
||||
showMore: "もっと見る"
|
||||
youGotNewFollower: "フォローされました"
|
||||
receiveFollowRequest: "フォローリクエストされました"
|
||||
followRequestAccepted: "フォローが承認されました"
|
||||
@ -87,6 +92,9 @@ followRequestPending: "フォロー許可待ち"
|
||||
enterEmoji: "絵文字を入力"
|
||||
renote: "Renote"
|
||||
unrenote: "Renote解除"
|
||||
renoted: "Renoteしました。"
|
||||
cantRenote: "この投稿はRenoteできません。"
|
||||
cantReRenote: "RenoteをRenoteすることはできません。"
|
||||
quote: "引用"
|
||||
pinnedNote: "ピン留めされたノート"
|
||||
you: "あなた"
|
||||
@ -655,6 +663,42 @@ useSystemFont: "システムのデフォルトのフォントを使う"
|
||||
clips: "クリップ"
|
||||
experimentalFeatures: "実験的機能"
|
||||
developer: "開発者"
|
||||
makeExplorable: "アカウントを見つけやすくする"
|
||||
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。"
|
||||
showGapBetweenNotesInTimeline: "タイムラインのノートを離して表示"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "中央"
|
||||
wide: "広い"
|
||||
narrow: "狭い"
|
||||
reloadToApplySetting: "設定はページリロード後に反映されます。今すぐリロードしますか?"
|
||||
showTitlebar: "タイトルバーを表示する"
|
||||
clearCache: "キャッシュをクリア"
|
||||
onlineUsersCount: "{n}人がオンライン"
|
||||
nUsers: "{n}ユーザー"
|
||||
nNotes: "{n}ノート"
|
||||
sendErrorReports: "エラーリポートを送信"
|
||||
sendErrorReportsDescription: "オンにすると、問題が発生したときにエラーの詳細情報がMisskeyに共有され、ソフトウェアの品質向上に役立てることができます。"
|
||||
myTheme: "マイテーマ"
|
||||
backgroundColor: "背景"
|
||||
accentColor: "アクセント"
|
||||
textColor: "文字"
|
||||
saveAs: "名前を付けて保存"
|
||||
advanced: "高度"
|
||||
value: "値"
|
||||
updatedAt: "更新日時"
|
||||
saveConfirm: "保存しますか?"
|
||||
deleteConfirm: "削除しますか?"
|
||||
invalidValue: "有効な値ではありません。"
|
||||
registry: "レジストリ"
|
||||
closeAccount: "アカウントを閉鎖する"
|
||||
|
||||
_registry:
|
||||
scope: "スコープ"
|
||||
key: "キー"
|
||||
keys: "キー"
|
||||
domain: "ドメイン"
|
||||
createKey: "キーを作成"
|
||||
|
||||
_aboutMisskey:
|
||||
about: "Misskeyはsyuiloによって2014年から開発されている、オープンソースのソフトウェアです。"
|
||||
@ -714,11 +758,21 @@ _mfm:
|
||||
bounce: "アニメーション(バウンド)"
|
||||
bounceDescription: "ぽよんぽよん弾むようなアニメーションを与えます。"
|
||||
shake: "アニメーション(ぶるぶる)"
|
||||
shakeDescription: "ぶるぶるするアニメーションを与えます。"
|
||||
shakeDescription: "ぶるぶる震えるアニメーションを与えます。"
|
||||
twitch: "アニメーション(ブレ)"
|
||||
twitchDescription: "激しくブレるアニメーションを与えます。"
|
||||
spin: "アニメーション(回転)"
|
||||
spinDescription: "回転するアニメーションを与えます。"
|
||||
x2: "大きく"
|
||||
x2Description: "内容を大きく表示します。"
|
||||
x3: "とても大きく"
|
||||
x3Description: "内容をとても大きく表示します。"
|
||||
x4: "究極に大きく"
|
||||
x4Description: "内容を究極に大きく表示します。"
|
||||
blur: "ぼかし"
|
||||
blurDescription: "内容をぼかすことができます。ポインターを上に乗せるとはっきり見えるようになります。"
|
||||
font: "フォント"
|
||||
fontDescription: "内容のフォントを指定することができます。"
|
||||
|
||||
_reversi:
|
||||
reversi: "リバーシ"
|
||||
@ -995,6 +1049,11 @@ _widgets:
|
||||
digitalClock: "デジタル時計"
|
||||
federation: "連合"
|
||||
postForm: "投稿フォーム"
|
||||
slideshow: "スライドショー"
|
||||
button: "ボタン"
|
||||
onlineUsers: "オンラインユーザー"
|
||||
jobQueue: "ジョブキュー"
|
||||
serverMetric: "サーバーメトリクス"
|
||||
|
||||
_cw:
|
||||
hide: "隠す"
|
||||
@ -1504,6 +1563,8 @@ _notification:
|
||||
_deck:
|
||||
alwaysShowMainColumn: "常にメインカラムを表示"
|
||||
columnAlign: "カラムの寄せ"
|
||||
columnMargin: "カラム間のマージン"
|
||||
columnHeaderHeight: "カラムのヘッダー幅"
|
||||
addColumn: "カラムを追加"
|
||||
swapLeft: "左に移動"
|
||||
swapRight: "右に移動"
|
||||
@ -1511,8 +1572,10 @@ _deck:
|
||||
swapDown: "下に移動"
|
||||
stackLeft: "左に重ねる"
|
||||
popRight: "右に出す"
|
||||
profile: "プロファイル"
|
||||
|
||||
_columns:
|
||||
main: "メイン"
|
||||
widgets: "ウィジェット"
|
||||
notifications: "通知"
|
||||
tl: "タイムライン"
|
||||
|
@ -33,6 +33,9 @@ addUser: "ユーザーを追加や"
|
||||
favorite: "お気に入り"
|
||||
favorites: "お気に入り"
|
||||
unfavorite: "やっぱ気に入らん"
|
||||
favorited: "お気に入りに登録したで"
|
||||
alreadyFavorited: "もうお気に入りに入れとるがな。"
|
||||
cantFavorite: "アカン、お気に入り登録できへんかったで。"
|
||||
pin: "ピン留めしとく"
|
||||
unpin: "やっぱピン留めせん"
|
||||
copyContent: "内容をコピー"
|
||||
@ -46,6 +49,7 @@ copyUsername: "ユーザー名をコピー"
|
||||
searchUser: "ユーザーを検索"
|
||||
reply: "返す"
|
||||
loadMore: "もっとあるやろ!"
|
||||
showMore: "もっとあるやろ!"
|
||||
youGotNewFollower: "フォローされたで"
|
||||
receiveFollowRequest: "フォローリクエストされたで"
|
||||
followRequestAccepted: "フォローが承認されたで"
|
||||
@ -87,6 +91,9 @@ followRequestPending: "フォロー許してくれるん待っとる"
|
||||
enterEmoji: "絵文字を入れてや"
|
||||
renote: "Renote"
|
||||
unrenote: "Renoteやめる"
|
||||
renoted: "Renoteしたで。"
|
||||
cantRenote: "この投稿はRenoteできへんらしい。"
|
||||
cantReRenote: "すまん、今このRenoteにRenoteはできへんのや。"
|
||||
quote: "引用"
|
||||
pinnedNote: "ピン留めされとるノート"
|
||||
you: "あんた"
|
||||
@ -95,6 +102,7 @@ sensitive: "ちょっとアカンやつやで"
|
||||
add: "増やす"
|
||||
reaction: "リアクション"
|
||||
reactionSettingDescription: "リアクションピッカーに出しとくリアクションを選んでや。"
|
||||
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押すと追加できるで。"
|
||||
rememberNoteVisibility: "公開範囲覚えといて"
|
||||
attachCancel: "やっぱ添付やめてくれん?"
|
||||
markAsSensitive: "ちょっとこれはアカン"
|
||||
@ -124,7 +132,9 @@ settingGuide: "ええ感じの設定"
|
||||
cacheRemoteFiles: "リモートのファイルをキャッシュする"
|
||||
cacheRemoteFilesDescription: "この設定を切っとくと、リモートファイルをキャッシュせず直リンクするようになってしまうんやで? サーバーのストレージは節約できるんやけど、かわりにサムネイルが作られんくなるから通信量が増えるで?"
|
||||
flagAsBot: "Botやで"
|
||||
flagAsBotDescription: "もしこのアカウントがプログラムによって運用されるんやったら、このフラグをオンにしてたのむで。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Misskeyのシステム上での扱いがBotに合ったもんになるんやで。"
|
||||
flagAsCat: "Catやで"
|
||||
flagAsCatDescription: "ワレ、猫ちゃんならこのフラグをつけてみ?"
|
||||
autoAcceptFollowed: "フォローしとるユーザーからのフォローリクエストには勝手に許可しとくで。"
|
||||
addAcount: "アカウント追加"
|
||||
loginFailed: "ログインに失敗してしもうた…"
|
||||
@ -215,6 +225,7 @@ remove: "ほかす"
|
||||
removed: "削除したで!"
|
||||
removeAreYouSure: "「{x}」はなおしてしもてええか?"
|
||||
deleteAreYouSure: "「{x}」はなおしてしもてええか?"
|
||||
resetAreYouSure: "リセットしてええん?"
|
||||
saved: "保存したで!"
|
||||
messaging: "チャット"
|
||||
upload: "アップロード"
|
||||
@ -314,6 +325,7 @@ bannerUrl: "バナー画像のURL"
|
||||
basicInfo: "基本情報"
|
||||
pinnedUsers: "ピン留めしたユーザー"
|
||||
pinnedUsersDescription: "「みつける」ページとかにピン留めしたいユーザーをここに書けばええんやで。他ん人との名前は改行で区切ればええんやで。"
|
||||
pinnedPages: "ピン留めページ"
|
||||
pinnedNotes: "ピン留めされとるノート"
|
||||
hcaptcha: "hCaptcha(キャプチャ)"
|
||||
enableHcaptcha: "hCaptcha(キャプチャ)をつけとく"
|
||||
@ -404,12 +416,46 @@ quoteQuestion: "引用として添付してもええか?"
|
||||
noMessagesYet: "まだチャットはあらへんで"
|
||||
newMessageExists: "新しいメッセージがきたで"
|
||||
onlyOneFileCanBeAttached: "すまん、メッセージに添付できるファイルはひとつだけなんや。"
|
||||
signinRequired: "ログインしてくれへん?"
|
||||
invitations: "来てや"
|
||||
invitationCode: "招待コード"
|
||||
checking: "確認しとるで"
|
||||
available: "利用できる\n"
|
||||
unavailable: "利用できん"
|
||||
usernameInvalidFormat: "a~z、A~Z、0~9、_が使えるで"
|
||||
tooShort: "短すぎやろ!"
|
||||
tooLong: "長すぎやろ!"
|
||||
weakPassword: "弱いパスワード"
|
||||
normalPassword: "普通のパスワード"
|
||||
strongPassword: "ええ感じのパスワード"
|
||||
passwordMatched: "よし!一致や!"
|
||||
passwordNotMatched: "一致しとらんで?"
|
||||
signinWith: "{x}でログイン"
|
||||
or: "それか"
|
||||
uiLanguage: "UIの表示言語"
|
||||
groupInvited: "グループに招待されとるで"
|
||||
aboutX: "{x}について"
|
||||
useOsNativeEmojis: "OSネイティブの絵文字を使う"
|
||||
youHaveNoGroups: "グループがあらへんねぇ。"
|
||||
noHistory: "履歴はあらへんねぇ。"
|
||||
signinHistory: "ログイン履歴"
|
||||
doing: "やっとるがな"
|
||||
category: "カテゴリ"
|
||||
tags: "タグ"
|
||||
docSource: "このドキュメントのソース"
|
||||
createAccount: "アカウントを作成"
|
||||
existingAcount: "既存のアカウント"
|
||||
regenerate: "再生成"
|
||||
fontSize: "フォントサイズ"
|
||||
noFollowRequests: "フォロー申請はあらへんで"
|
||||
openImageInNewTab: "画像を新しいタブで開く"
|
||||
dashboard: "ダッシュボード"
|
||||
local: "ローカル"
|
||||
remote: "リモート"
|
||||
smtpHost: "ホスト"
|
||||
smtpUser: "ユーザー名"
|
||||
smtpPass: "パスワード"
|
||||
clearCache: "キャッシュにさいなら"
|
||||
_mfm:
|
||||
mention: "メンション"
|
||||
quote: "引用"
|
||||
@ -453,6 +499,7 @@ _widgets:
|
||||
timeline: "タイムライン"
|
||||
activity: "アクティビティ"
|
||||
federation: "連合"
|
||||
jobQueue: "ジョブキュー"
|
||||
_cw:
|
||||
show: "もっとあるやろ!"
|
||||
_poll:
|
||||
@ -501,6 +548,7 @@ _pages:
|
||||
array: "リスト"
|
||||
_notification:
|
||||
youWereFollowed: "フォローされたで"
|
||||
youWereInvitedToGroup: "グループに招待されとるで"
|
||||
_types:
|
||||
follow: "フォロー"
|
||||
mention: "メンション"
|
||||
|
@ -13,6 +13,7 @@ delete: "Kkes"
|
||||
addToList: "Rnu ɣer tebdart"
|
||||
reply: "Err"
|
||||
loadMore: "Wali ugar"
|
||||
showMore: "Wali ugar"
|
||||
youGotNewFollower: "Yeṭṭafaṛ-ik·em-id"
|
||||
mention: "Bder"
|
||||
import: "Kter"
|
||||
@ -38,6 +39,7 @@ smtpPass: "Awal uffir"
|
||||
_mfm:
|
||||
mention: "Bder"
|
||||
search: "Nadi"
|
||||
font: "Tasefsit"
|
||||
_theme:
|
||||
keys:
|
||||
mention: "Bder"
|
||||
|
@ -40,6 +40,7 @@ sendMessage: "ಸಂದೇಶ ಕಳುಹಿಸು"
|
||||
copyUsername: "ಬಳಕೆಹೆಸರು ನಕಲಿಸು"
|
||||
reply: "ಉತ್ತರಿಸು"
|
||||
loadMore: "ಇನ್ನಷ್ಟು ನೋಡು"
|
||||
showMore: "ಇನ್ನಷ್ಟು ನೋಡು"
|
||||
youGotNewFollower: "ಹಿಂಬಾಲಿಸಿದರು"
|
||||
receiveFollowRequest: "ಹಿಂಬಾಲನೆ ವಿನಂತಿ ಬಂದಿದೆ"
|
||||
followRequestAccepted: "ಹಿಂಬಾಲನೆ ವಿನಂತಿ ಸ್ವೀಕರಿಸಲಾಯಿತು"
|
||||
|
@ -46,6 +46,7 @@ copyUsername: "유저명 복사"
|
||||
searchUser: "사용자 검색"
|
||||
reply: "답글"
|
||||
loadMore: "더 보기"
|
||||
showMore: "더 보기"
|
||||
youGotNewFollower: "새로운 팔로워가 있습니다"
|
||||
receiveFollowRequest: "새로운 팔로우 요청이 있습니다"
|
||||
followRequestAccepted: "팔로우가 수락되었습니다"
|
||||
@ -612,6 +613,11 @@ lockedAccountInfo: "팔로우를 승인으로 승인받더라도 노트의 공
|
||||
alwaysMarkSensitive: "미디어를 항상 열람 주의로 설정"
|
||||
emailVerified: "메일 주소가 확인되었습니다."
|
||||
clips: "클립"
|
||||
clearCache: "캐시 비우기"
|
||||
value: "값"
|
||||
_registry:
|
||||
key: "키"
|
||||
keys: "키"
|
||||
_nsfw:
|
||||
ignore: "열람 주의 미디어 항상 표시"
|
||||
_mfm:
|
||||
@ -642,6 +648,7 @@ _mfm:
|
||||
flip: "플립"
|
||||
flipDescription: "내용을 상하 또는 좌우로 반전시킵니다."
|
||||
jump: "애니메이션(점프)"
|
||||
font: "폰트"
|
||||
_reversi:
|
||||
reversi: "리버시"
|
||||
gameSettings: "대국 설정"
|
||||
@ -834,6 +841,8 @@ _widgets:
|
||||
digitalClock: "디지털 시계"
|
||||
federation: "연합"
|
||||
postForm: "글 입력란"
|
||||
button: "버튼"
|
||||
jobQueue: "작업 대기열"
|
||||
_cw:
|
||||
hide: "숨기기"
|
||||
show: "더 보기"
|
||||
|
1159
locales/pl-PL.yml
@ -1,2 +1,31 @@
|
||||
---
|
||||
_lang_: "Português"
|
||||
monthAndDay: "{day}/{month}"
|
||||
search: "Pesquisar"
|
||||
notifications: "Notificações"
|
||||
username: "Nome de usuário"
|
||||
password: "Senha"
|
||||
ok: "OK"
|
||||
cancel: "Cancelar"
|
||||
enterUsername: "Digite o nome de usuário"
|
||||
renotedBy: "Repostado por {user}"
|
||||
settings: "Configurações"
|
||||
basicSettings: "Configurações básicas"
|
||||
otherSettings: "Outras configurações"
|
||||
profile: "Perfil"
|
||||
timeline: "Timeline"
|
||||
smtpUser: "Nome de usuário"
|
||||
smtpPass: "Senha"
|
||||
_mfm:
|
||||
search: "Pesquisar"
|
||||
_sfx:
|
||||
notification: "Notificações"
|
||||
_widgets:
|
||||
notifications: "Notificações"
|
||||
timeline: "Timeline"
|
||||
_profile:
|
||||
username: "Nome de usuário"
|
||||
_deck:
|
||||
_columns:
|
||||
notifications: "Notificações"
|
||||
tl: "Timeline"
|
||||
|
@ -33,6 +33,9 @@ addUser: "Добавить пользователя"
|
||||
favorite: "В избранное"
|
||||
favorites: "Избранное"
|
||||
unfavorite: "Убрать из избранного"
|
||||
favorited: "Добавлено в избранное."
|
||||
alreadyFavorited: "Уже есть в избранном."
|
||||
cantFavorite: "Не удалось добавить в избранное."
|
||||
pin: "Закрепить в профиле"
|
||||
unpin: "Открепить от профиля"
|
||||
copyContent: "Скопировать содержимое"
|
||||
@ -46,6 +49,7 @@ copyUsername: "Скопировать имя пользователя"
|
||||
searchUser: "Поиск людей"
|
||||
reply: "Ответить"
|
||||
loadMore: "Показать еще"
|
||||
showMore: "Показать еще"
|
||||
youGotNewFollower: "Новый подписчик"
|
||||
receiveFollowRequest: "Получен запрос на подписку"
|
||||
followRequestAccepted: "Запрос на подписку принят"
|
||||
@ -87,6 +91,9 @@ followRequestPending: "Нерассмотренный запрос на подп
|
||||
enterEmoji: "Введите эмодзи"
|
||||
renote: "Репост"
|
||||
unrenote: "Отмена репоста"
|
||||
renoted: "Репост совершён."
|
||||
cantRenote: "Это нельзя репостить."
|
||||
cantReRenote: "Невозможно репостить репост."
|
||||
quote: "Цитата"
|
||||
pinnedNote: "Закреплённая заметка"
|
||||
you: "Вы"
|
||||
@ -95,6 +102,7 @@ sensitive: "Содержимое не для всех"
|
||||
add: "Добавить"
|
||||
reaction: "Реакции"
|
||||
reactionSettingDescription: "Подберите, что будет у вас в палитре реакций"
|
||||
reactionSettingDescription2: "Расставляйте перетаскиванием, удаляйте нажатием, добавляйте кнопкой «+»."
|
||||
rememberNoteVisibility: "Запоминать видимость заметок"
|
||||
attachCancel: "Удалить вложение"
|
||||
markAsSensitive: "Отметить как «не для всех»"
|
||||
@ -319,6 +327,7 @@ pinnedUsers: "Прикреплённый пользователь"
|
||||
pinnedUsersDescription: "Перечислите по одному имени пользователя в строке. Пользователи, перечисленные здесь, будут привязаны к закладке \"Изучение\"."
|
||||
pinnedPages: "Закрепленные страницы"
|
||||
pinnedPagesDescription: "Если хотите закрепить страницы на главной сайта, сюда можно добавить пути к ним, каждый в отдельной строке."
|
||||
pinnedClipId: "Идентификатор закреплённой памятки"
|
||||
pinnedNotes: "Закреплённая заметка"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Включить hCaptcha"
|
||||
@ -653,6 +662,25 @@ useSystemFont: "Использовать шрифт, предлагаемый с
|
||||
clips: "Памятки"
|
||||
experimentalFeatures: "Экспериментальные функции"
|
||||
developer: "Разработчик"
|
||||
makeExplorable: "Опубликовать профиль в «Обзоре»."
|
||||
makeExplorableDescription: "Если выключить, ваш профиль не будет показан в разделе «Обзор»."
|
||||
showGapBetweenNotesInTimeline: "Показывать разделитель между заметками в ленте"
|
||||
duplicate: "Дубликат"
|
||||
left: "Влево"
|
||||
center: "По центру"
|
||||
reloadToApplySetting: "Это настройка вступает в силу при загрузке страницы. Перезагрузить сейчас?"
|
||||
showTitlebar: "Показать заголовок"
|
||||
clearCache: "Очистить кэш"
|
||||
onlineUsersCount: "Пользователей сейчас в сети: {n}"
|
||||
nUsers: "Пользователей: {n}"
|
||||
nNotes: "Заметок: {n}"
|
||||
backgroundColor: "Фон"
|
||||
accentColor: "Акцент"
|
||||
textColor: "Текст"
|
||||
value: "Значения"
|
||||
_registry:
|
||||
key: "Ключ"
|
||||
keys: "Ключ"
|
||||
_aboutMisskey:
|
||||
about: "Misskey — программа с открытым исходным кодом, которую разрабатывает syuilo с 2014 года."
|
||||
contributors: "Основные соавторы"
|
||||
@ -714,6 +742,7 @@ _mfm:
|
||||
twitchDescription: "Заставляет трястись как одержимого"
|
||||
spin: "Вращение"
|
||||
spinDescription: "Так можно крутить содержимое в разных направлениях."
|
||||
font: "Шрифт"
|
||||
_reversi:
|
||||
reversi: "Реверси"
|
||||
gameSettings: "Настройки игры"
|
||||
@ -972,6 +1001,10 @@ _widgets:
|
||||
digitalClock: "Цифровые часы"
|
||||
federation: "Федерация"
|
||||
postForm: "Форма отправки"
|
||||
slideshow: "Показ слайдов"
|
||||
button: "Кнопка"
|
||||
onlineUsers: "Пользователи сейчас с сети"
|
||||
jobQueue: "Очередь заданий"
|
||||
_cw:
|
||||
hide: "Спрятать"
|
||||
show: "Показать еще"
|
||||
@ -1454,6 +1487,8 @@ _notification:
|
||||
_deck:
|
||||
alwaysShowMainColumn: "Всегда показывать главную колонку"
|
||||
columnAlign: "Выравнивание колонок"
|
||||
columnMargin: "Расстояние между колонками"
|
||||
columnHeaderHeight: "Высота заголовка колонки"
|
||||
addColumn: "Добавить колонку"
|
||||
swapLeft: "Переставить левее"
|
||||
swapRight: "Переставить правее"
|
||||
@ -1462,6 +1497,7 @@ _deck:
|
||||
stackLeft: "В столбик влево"
|
||||
popRight: "Из столбика вправо"
|
||||
_columns:
|
||||
main: "Основная"
|
||||
widgets: "Виджеты"
|
||||
notifications: "Уведомления"
|
||||
tl: "Лента"
|
||||
|
1
locales/th-TH.yml
Normal file
@ -0,0 +1 @@
|
||||
---
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
_lang_: "中文(简体)"
|
||||
headlineMisskey: "通过帖子连接在一起的网络"
|
||||
introMisskey: "欢迎!Misskey是一个开源的、去中心化的“微博客”服务。\n通过编写「帖文」来和大家分享你的以及你周围的事情吧!📡\n通过「回应」功能,可以让你快速地对大家的帖文表达反馈👍\n来探索新的世界吧!🚀"
|
||||
monthAndDay: "{month}月 {day}日"
|
||||
search: "搜索"
|
||||
@ -11,7 +12,7 @@ ok: "OK"
|
||||
gotIt: "我明白了"
|
||||
cancel: "取消"
|
||||
enterUsername: "输入用户名"
|
||||
renotedBy: "{user} 转贴了"
|
||||
renotedBy: "{user} 转发了"
|
||||
noNotes: "没有帖文"
|
||||
noNotifications: "无通知"
|
||||
instance: "实例"
|
||||
@ -33,6 +34,9 @@ addUser: "添加用户"
|
||||
favorite: "收藏"
|
||||
favorites: "收藏"
|
||||
unfavorite: "取消收藏"
|
||||
favorited: "已加入收藏夹。"
|
||||
alreadyFavorited: "收藏夹中已存在。"
|
||||
cantFavorite: "无法添加到收藏夹。"
|
||||
pin: "置顶"
|
||||
unpin: "取消置顶"
|
||||
copyContent: "复制内容"
|
||||
@ -46,6 +50,7 @@ copyUsername: "复制用户名"
|
||||
searchUser: "搜索用户"
|
||||
reply: "回复"
|
||||
loadMore: "查看更多"
|
||||
showMore: "查看更多"
|
||||
youGotNewFollower: "你有新的关注者"
|
||||
receiveFollowRequest: "您收到了关注请求"
|
||||
followRequestAccepted: "您的关注请求被通过了"
|
||||
@ -87,6 +92,9 @@ followRequestPending: "发送关注申请"
|
||||
enterEmoji: "输入表情符号"
|
||||
renote: "转发"
|
||||
unrenote: "取消转发"
|
||||
renoted: "已转发。"
|
||||
cantRenote: "该帖子无法转发。"
|
||||
cantReRenote: "转发无法被再次转发。"
|
||||
quote: "引用"
|
||||
pinnedNote: "已置顶的帖子"
|
||||
you: "您"
|
||||
@ -103,12 +111,12 @@ unmarkAsSensitive: "取消标记为敏感内容"
|
||||
enterFileName: "请输入文件名"
|
||||
mute: "屏蔽"
|
||||
unmute: "解除屏蔽"
|
||||
block: "屏蔽"
|
||||
unblock: "取消屏蔽"
|
||||
block: "拉黑"
|
||||
unblock: "取消拉黑"
|
||||
suspend: "冻结"
|
||||
unsuspend: "解除冻结"
|
||||
blockConfirm: "确定要屏蔽吗?"
|
||||
unblockConfirm: "确定要解除屏蔽吗?"
|
||||
blockConfirm: "确定要拉黑吗?"
|
||||
unblockConfirm: "确定要解除拉黑吗?"
|
||||
suspendConfirm: "要冻结吗?"
|
||||
unsuspendConfirm: "要解除冻结吗?"
|
||||
selectList: "选择列表"
|
||||
@ -116,7 +124,7 @@ selectAntenna: "天线选择"
|
||||
selectWidget: "选择小工具"
|
||||
editWidgets: "编辑小工具"
|
||||
editWidgetsExit: "完成编辑"
|
||||
customEmojis: "自定义Emoji"
|
||||
customEmojis: "自定义表情符号"
|
||||
emoji: "表情符号"
|
||||
emojiName: "表情符号名称"
|
||||
emojiUrl: "表情符号地址"
|
||||
@ -177,8 +185,8 @@ clearCachedFilesConfirm: "确定要清除缓存文件?"
|
||||
blockedInstances: "被阻拦的实例"
|
||||
blockedInstancesDescription: "设定要阻拦的实例,以换行来进行分割。被阻拦的实例将无法与本实例进行交换通讯。"
|
||||
muteAndBlock: "屏蔽/拉黑"
|
||||
mutedUsers: "禁言用户"
|
||||
blockedUsers: "已屏蔽用户"
|
||||
mutedUsers: "已屏蔽用户"
|
||||
blockedUsers: "被拉黑的用户"
|
||||
noUsers: "无用户"
|
||||
editProfile: "编辑资料"
|
||||
noteDeleteConfirm: "要删除该帖子吗?"
|
||||
@ -191,7 +199,7 @@ default: "默认"
|
||||
noCustomEmojis: "没有自定义表情符号"
|
||||
noJobs: "没有任务"
|
||||
federating: "联合中"
|
||||
blocked: "已拦截"
|
||||
blocked: "已拉黑"
|
||||
suspended: "停止推流"
|
||||
all: "全部"
|
||||
subscribing: "已订阅"
|
||||
@ -533,7 +541,7 @@ poll: "调查问卷"
|
||||
useCw: "隐藏内容"
|
||||
enablePlayer: "打开播放器"
|
||||
disablePlayer: "关闭播放器"
|
||||
expandTweet: "展开推文"
|
||||
expandTweet: "展开贴文"
|
||||
themeEditor: "主题编辑器"
|
||||
description: "描述"
|
||||
author: "作者"
|
||||
@ -633,8 +641,8 @@ sentReactionsCount: "发送反应数"
|
||||
receivedReactionsCount: "收到反应数"
|
||||
pollVotesCount: "发起投票数"
|
||||
pollVotedCount: "已投票数"
|
||||
yes: "确定"
|
||||
no: "取消"
|
||||
yes: "是"
|
||||
no: "否"
|
||||
driveFilesCount: "磁盘文件数"
|
||||
driveUsage: "磁盘空间用量"
|
||||
noCrawle: "拒绝搜索器的索引"
|
||||
@ -655,6 +663,41 @@ useSystemFont: "使用系统默认字体"
|
||||
clips: "片段"
|
||||
experimentalFeatures: "实验性功能"
|
||||
developer: "开发者"
|
||||
makeExplorable: "使账号可见。"
|
||||
makeExplorableDescription: "关闭时,账号不会显示在\"发现\"中。"
|
||||
showGapBetweenNotesInTimeline: "时间线上的帖子分开显示。"
|
||||
duplicate: "复制"
|
||||
left: "左"
|
||||
center: "中央"
|
||||
wide: "宽"
|
||||
narrow: "窄"
|
||||
reloadToApplySetting: "页面刷新后设置才会生效。是否现在刷新页面?"
|
||||
showTitlebar: "显示标题栏"
|
||||
clearCache: "清除缓存"
|
||||
onlineUsersCount: "{n}人在线"
|
||||
nUsers: "{n}用户"
|
||||
nNotes: "{n}帖子"
|
||||
sendErrorReports: "发送错误报告"
|
||||
sendErrorReportsDescription: "启用后,如果出现问题,可以与Misskey共享详细的错误信息,从而帮助提高软件的质量。"
|
||||
myTheme: "我的主题"
|
||||
backgroundColor: "背景"
|
||||
accentColor: "强调色"
|
||||
textColor: "文本"
|
||||
saveAs: "另存为"
|
||||
advanced: "高级"
|
||||
value: "值"
|
||||
updatedAt: "更新时间"
|
||||
saveConfirm: "确定保存?"
|
||||
deleteConfirm: "确定删除?"
|
||||
invalidValue: "无效值。"
|
||||
registry: "注册表"
|
||||
closeAccount: "关闭账户"
|
||||
_registry:
|
||||
scope: "范围"
|
||||
key: "主要"
|
||||
keys: "主要"
|
||||
domain: "域"
|
||||
createKey: "创建键"
|
||||
_aboutMisskey:
|
||||
about: "Misskey是由syuilo于2014年开发的开源软件。"
|
||||
contributors: "主要贡献者"
|
||||
@ -716,6 +759,16 @@ _mfm:
|
||||
twitchDescription: "显示强烈颤抖的动画效果。"
|
||||
spin: "动画(回转)"
|
||||
spinDescription: "显示回转的动画效果。"
|
||||
x2: "大"
|
||||
x2Description: "以大尺寸显示内容。"
|
||||
x3: "非常大"
|
||||
x3Description: "以更大尺寸显示内容。"
|
||||
x4: "最大"
|
||||
x4Description: "以最大尺寸显示内容。"
|
||||
blur: "模糊"
|
||||
blurDescription: "产生模糊效果。将鼠标指针放在上面即可将内容显示出来。"
|
||||
font: "字体"
|
||||
fontDescription: "可以设置内容所使用的字体。"
|
||||
_reversi:
|
||||
reversi: "黑白棋"
|
||||
gameSettings: "对局设置"
|
||||
@ -775,7 +828,7 @@ _wordMute:
|
||||
muteWords: "禁用词"
|
||||
muteWordsDescription: "使用空格分隔表示AND逻辑,使用换行符分隔表示OR逻辑。"
|
||||
muteWordsDescription2: "将关键字用斜线括起来表示正则表达式。"
|
||||
softDescription: "隐藏时间轴中指定条件的帖文。"
|
||||
softDescription: "隐藏时间线中指定条件的帖文。"
|
||||
hardDescription: "防止将具有指定条件的帖文添加到时间线。 即使您更改条件,未添加的帖文也会被排除在外。"
|
||||
soft: "软屏蔽"
|
||||
hard: "硬屏蔽"
|
||||
@ -974,6 +1027,11 @@ _widgets:
|
||||
digitalClock: "数字时钟"
|
||||
federation: "联邦宇宙"
|
||||
postForm: "投稿窗口"
|
||||
slideshow: "幻灯片展示"
|
||||
button: "按钮"
|
||||
onlineUsers: "在线用户"
|
||||
jobQueue: "作业队列"
|
||||
serverMetric: "服务器指标"
|
||||
_cw:
|
||||
hide: "隐藏"
|
||||
show: "查看更多"
|
||||
@ -1039,7 +1097,7 @@ _exportOrImport:
|
||||
allNotes: "所有帖子"
|
||||
followingList: "关注中"
|
||||
muteList: "屏蔽"
|
||||
blockingList: "屏蔽"
|
||||
blockingList: "拉黑"
|
||||
userLists: "列表"
|
||||
_charts:
|
||||
federationInstancesIncDec: "联合:增加/减少"
|
||||
@ -1456,6 +1514,8 @@ _notification:
|
||||
_deck:
|
||||
alwaysShowMainColumn: "总是显示主列"
|
||||
columnAlign: "列对齐"
|
||||
columnMargin: "列间距"
|
||||
columnHeaderHeight: "列标题高度"
|
||||
addColumn: "添加列"
|
||||
swapLeft: "向左移动"
|
||||
swapRight: "向右移动"
|
||||
@ -1463,7 +1523,9 @@ _deck:
|
||||
swapDown: "向下移动"
|
||||
stackLeft: "向左折叠"
|
||||
popRight: "向右弹出"
|
||||
profile: "个人资料"
|
||||
_columns:
|
||||
main: "主列"
|
||||
widgets: "小工具"
|
||||
notifications: "通知"
|
||||
tl: "时间线"
|
||||
|
@ -1,18 +1,18 @@
|
||||
---
|
||||
_lang_: "繁體中文"
|
||||
introMisskey: "歡迎! Misskey是一個開源的去中心化的社群網站。\n通過「貼文」來分享現在發生的事情吧! 📡\n「反應」功能,可以讓你快速的對大家的「帖子」來表達感情👍\n一起來探索新的世界吧! 🚀"
|
||||
introMisskey: "歡迎! Misskey是一個開源且去中心化的社群網絡。\n通過「箋文」分享周邊新鮮事,並告訴其他人您的想法!📡\n透過「情感」功能,對大家的箋文表達情感!👍\n一起來探索這個新的世界吧!🚀"
|
||||
monthAndDay: "{month}月 {day}日"
|
||||
search: "搜尋"
|
||||
notifications: "通知"
|
||||
username: "使用者名稱"
|
||||
password: "密碼"
|
||||
fetchingAsApObject: "從 Fediverse 查詢中..."
|
||||
fetchingAsApObject: "從聯邦宇宙取得中..."
|
||||
ok: "OK"
|
||||
gotIt: "知道了"
|
||||
cancel: "取消"
|
||||
enterUsername: "輸入使用者名稱"
|
||||
renotedBy: "{user} 轉發了"
|
||||
noNotes: "貼文不可用。"
|
||||
noNotes: "箋文不可用。"
|
||||
noNotifications: "沒有通知"
|
||||
instance: "實例"
|
||||
settings: "設定"
|
||||
@ -31,40 +31,44 @@ save: "儲存"
|
||||
users: "使用者"
|
||||
addUser: "新增使用者"
|
||||
favorite: "收藏"
|
||||
favorites: "已加星號"
|
||||
favorites: "已收藏"
|
||||
unfavorite: "取消收藏"
|
||||
favorited: "已添加至收藏夾"
|
||||
alreadyFavorited: "已經有添加入收藏夾過了"
|
||||
cantFavorite: "無法添加至收藏夾"
|
||||
pin: "置頂"
|
||||
unpin: "取消置頂"
|
||||
copyContent: "複製內容"
|
||||
copyLink: "複製連結"
|
||||
delete: "刪除"
|
||||
deleteAndEdit: "刪除並編輯"
|
||||
deleteAndEditConfirm: "要刪除並再次編輯嗎?此貼文的所有反應,轉發和回覆也將會消失。"
|
||||
addToList: "添加至清單"
|
||||
deleteAndEditConfirm: "要刪除並再次編輯嗎?此箋文的所有情感、轉發和回覆也將會消失。"
|
||||
addToList: "新增至清單"
|
||||
sendMessage: "發送訊息"
|
||||
copyUsername: "複製用戶名"
|
||||
searchUser: "搜尋用戶"
|
||||
reply: "回覆"
|
||||
loadMore: "瀏覽更多"
|
||||
loadMore: "載入更多"
|
||||
showMore: "載入更多"
|
||||
youGotNewFollower: "您有新的追隨者"
|
||||
receiveFollowRequest: "收到追隨請求"
|
||||
receiveFollowRequest: "您有新的追隨請求"
|
||||
followRequestAccepted: "追隨請求已接受"
|
||||
mention: "提及"
|
||||
mentions: "提及"
|
||||
directNotes: "私信"
|
||||
importAndExport: "匯入 / 匯出"
|
||||
directNotes: "指定使用者發佈"
|
||||
importAndExport: "匯入與匯出"
|
||||
import: "匯入"
|
||||
export: "匯出"
|
||||
files: "檔案"
|
||||
download: "下載"
|
||||
driveFileDeleteConfirm: "確定要刪除檔案「{name}」嗎?使用此附件的貼文也會跟著消失。"
|
||||
unfollowConfirm: "確定要取消對{name}的追隨嗎?"
|
||||
driveFileDeleteConfirm: "確定要刪除檔案「{name}」嗎?使用此附件的箋文也會跟著消失。\n"
|
||||
unfollowConfirm: "確定要取消追隨{name}嗎?"
|
||||
exportRequested: "已請求匯出。這可能會花一點時間。結束後檔案將會被放到雲端裡。"
|
||||
importRequested: "已請求匯入。這可能會花一點時間"
|
||||
lists: "清單"
|
||||
noLists: "沒有清單"
|
||||
note: "貼文"
|
||||
notes: "筆記"
|
||||
noLists: "你沒有任何清單"
|
||||
note: "箋文"
|
||||
notes: "箋文"
|
||||
following: "追隨中"
|
||||
followers: "追隨者"
|
||||
followsYou: "追隨你的人"
|
||||
@ -74,27 +78,32 @@ error: "錯誤"
|
||||
somethingHappened: "發生錯誤"
|
||||
retry: "重試"
|
||||
pageLoadError: "載入頁面失敗"
|
||||
pageLoadErrorDescription: "這通常是因為網路錯誤或是瀏覽器快取殘留的原因。請先清除瀏覽器快取,稍後再重試"
|
||||
enterListName: "輸入清單名稱"
|
||||
privacy: "隱私"
|
||||
makeFollowManuallyApprove: "手動審核追隨請求"
|
||||
defaultNoteVisibility: "預設的筆記隱私權"
|
||||
defaultNoteVisibility: "預設可見性"
|
||||
follow: "追隨"
|
||||
followRequest: "追隨請求"
|
||||
followRequests: "追隨請求"
|
||||
unfollow: "取消追隨"
|
||||
followRequestPending: "追隨許可批准中"
|
||||
enterEmoji: "輸入表情符號"
|
||||
renote: "轉發貼文"
|
||||
unrenote: "取消轉發貼文"
|
||||
renote: "轉箋"
|
||||
unrenote: "取消轉箋"
|
||||
renoted: "轉發成功"
|
||||
cantRenote: "無法轉發此箋文。"
|
||||
cantReRenote: "無法轉發之前已經轉發過的內容"
|
||||
quote: "引用"
|
||||
pinnedNote: "已置頂的貼文"
|
||||
pinnedNote: "已置頂的箋文"
|
||||
you: "您"
|
||||
clickToShow: "按一下以顯示"
|
||||
sensitive: "敏感內容"
|
||||
add: "新增"
|
||||
reaction: "反應"
|
||||
reaction: "情感"
|
||||
reactionSettingDescription: "置頂「反應」表情符號\n"
|
||||
rememberNoteVisibility: "記住筆記隱私設定"
|
||||
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
|
||||
rememberNoteVisibility: "記住箋文可見性"
|
||||
attachCancel: "移除附件"
|
||||
markAsSensitive: "標記為敏感內容"
|
||||
unmarkAsSensitive: "取消標記為敏感內容"
|
||||
@ -104,7 +113,7 @@ unmute: "解除靜音"
|
||||
block: "封鎖"
|
||||
unblock: "解除封鎖"
|
||||
suspend: "凍結"
|
||||
unsuspend: "解凍"
|
||||
unsuspend: "解除凍結"
|
||||
blockConfirm: "確定要封鎖此用戶?"
|
||||
unblockConfirm: "確定解除封鎖此用戶?"
|
||||
suspendConfirm: "確定凍結此帳號?"
|
||||
@ -113,7 +122,7 @@ selectList: "選擇清單"
|
||||
selectAntenna: "選擇天線"
|
||||
selectWidget: "選擇小工具"
|
||||
editWidgets: "編輯小工具"
|
||||
editWidgetsExit: "停止編輯"
|
||||
editWidgetsExit: "完成"
|
||||
customEmojis: "自訂表情符號"
|
||||
emoji: "表情符號"
|
||||
emojiName: "表情符號名稱"
|
||||
@ -121,11 +130,13 @@ emojiUrl: "表情符號URL"
|
||||
addEmoji: "新增表情符號"
|
||||
settingGuide: "推薦設定"
|
||||
cacheRemoteFiles: "緩存非遠程檔案"
|
||||
cacheRemoteFilesDescription: "禁用此設定會停止遠端檔案的緩存,從而節省儲存空間。但資料會因直接連線從而產生額外連接數據。"
|
||||
cacheRemoteFilesDescription: "禁用此設定會停止遠端檔案的緩存,從而節省儲存空間,但資料會因直接連線從而產生額外連接數據。"
|
||||
flagAsBot: "此使用者是機器人"
|
||||
flagAsBotDescription: "如果本帳戶是由程式控制,請啟用此選項。啟用後,會作為標示幫助其他開發者防止機器人之間產生無限互動的行為,並會調整Misskey內部系統將本帳戶識別為機器人"
|
||||
flagAsCat: "此使用者是貓"
|
||||
autoAcceptFollowed: "自動許可追隨"
|
||||
addAcount: "新增帳號"
|
||||
flagAsCatDescription: "如果想將本帳戶標示為一隻貓,請開啟此標示"
|
||||
autoAcceptFollowed: "自動追隨中使用者的追隨請求"
|
||||
addAcount: "新增帳戶"
|
||||
loginFailed: "登入失敗"
|
||||
showOnRemote: "轉到所在實例顯示"
|
||||
general: "一般"
|
||||
@ -133,15 +144,15 @@ wallpaper: "桌布"
|
||||
setWallpaper: "設定桌布"
|
||||
removeWallpaper: "移除桌布"
|
||||
searchWith: "搜尋: {q}"
|
||||
youHaveNoLists: "沒有任何清單"
|
||||
followConfirm: "你真的要關注{name}嗎?"
|
||||
youHaveNoLists: "你沒有任何清單"
|
||||
followConfirm: "你真的要追隨{name}嗎?"
|
||||
proxyAccount: "代理帳號"
|
||||
proxyAccountDescription: "代理帳號是在某些情況下充當其他服務器用戶的帳號。例如,當用戶將一個來自其他服務器的帳號放在列表中時,由於沒有其他用戶關注該帳號,該指令不會傳送到該服務器上,因此會由代理帳戶關注。"
|
||||
host: "主機"
|
||||
selectUser: "選取使用者"
|
||||
recipient: "發送至"
|
||||
recipient: "收件人"
|
||||
annotation: "註解"
|
||||
federation: "聯邦宇宙"
|
||||
federation: "站台聯邦"
|
||||
instances: "實例"
|
||||
registeredAt: "初次觀測"
|
||||
latestRequestSentAt: "上次發送的請求"
|
||||
@ -155,7 +166,7 @@ blockThisInstance: "封鎖此實例"
|
||||
operations: "操作"
|
||||
software: "軟體"
|
||||
version: "版本"
|
||||
metadata: "元資料(Metadata)"
|
||||
metadata: "元資料"
|
||||
withNFiles: "{n}個檔案"
|
||||
monitor: "監視器"
|
||||
jobQueue: "佇列"
|
||||
@ -171,13 +182,13 @@ clearCachedFiles: "清除快取資料"
|
||||
clearCachedFilesConfirm: "確定要清除緩存資料嗎?"
|
||||
blockedInstances: "已封鎖的實例"
|
||||
blockedInstancesDescription: "請逐行輸入需要封鎖的實例。已封鎖的實例將無法與本實例進行通訊。"
|
||||
muteAndBlock: "靜音/封鎖"
|
||||
muteAndBlock: "靜音和封鎖"
|
||||
mutedUsers: "已靜音用戶"
|
||||
blockedUsers: "已封鎖用戶"
|
||||
noUsers: "無用戶"
|
||||
noUsers: "沒有任何使用者"
|
||||
editProfile: "編輯個人檔案"
|
||||
noteDeleteConfirm: "確定刪除此貼文嗎?"
|
||||
pinLimitExceeded: "不能再置頂更多的貼文了"
|
||||
noteDeleteConfirm: "確定刪除此箋文嗎?"
|
||||
pinLimitExceeded: "不能置頂更多箋文了"
|
||||
intro: "Misskey 部署完成!請開設管理員帳號!"
|
||||
done: "完成"
|
||||
processing: "處理中"
|
||||
@ -190,30 +201,31 @@ blocked: "已封鎖"
|
||||
suspended: "已凍結"
|
||||
all: "全部"
|
||||
subscribing: "訂閱中"
|
||||
publishing: "現正直播"
|
||||
publishing: "直播中"
|
||||
notResponding: "沒有回應"
|
||||
instanceFollowing: "追蹤實例"
|
||||
instanceFollowers: "追蹤實例"
|
||||
instanceUsers: "用戶"
|
||||
changePassword: "修改密碼"
|
||||
security: "安全性"
|
||||
retypedNotMatch: "不相符的輸入內容"
|
||||
currentPassword: "現在的密碼"
|
||||
newPassword: "新的密碼"
|
||||
newPasswordRetype: "新的密碼(再輸入一次)"
|
||||
retypedNotMatch: "兩次輸入不一致。"
|
||||
currentPassword: "目前密碼"
|
||||
newPassword: "新密碼"
|
||||
newPasswordRetype: "確認密碼"
|
||||
attachFile: "添加附件"
|
||||
more: "更多!"
|
||||
featured: "精選"
|
||||
usernameOrUserId: "使用者名稱或使用者 ID"
|
||||
usernameOrUserId: "使用者名稱或用戶ID"
|
||||
noSuchUser: "使用者不存在"
|
||||
lookup: "查詢"
|
||||
announcements: "公告"
|
||||
imageUrl: "圖片URL"
|
||||
remove: "刪除"
|
||||
removed: "成功移除"
|
||||
removed: "已刪除"
|
||||
removeAreYouSure: "確定要刪掉「{x}」嗎?"
|
||||
deleteAreYouSure: "確定要刪掉「{x}」嗎?"
|
||||
saved: "已保存"
|
||||
resetAreYouSure: "確定要重設嗎?"
|
||||
saved: "已儲存"
|
||||
messaging: "傳送訊息"
|
||||
upload: "上傳"
|
||||
fromDrive: "從雲端"
|
||||
@ -258,9 +270,9 @@ folderName: "資料夾名稱"
|
||||
createFolder: "新增資料夾"
|
||||
renameFolder: "重新命名資料夾"
|
||||
deleteFolder: "刪除資料夾"
|
||||
addFile: "添加檔案"
|
||||
addFile: "添加附件"
|
||||
emptyDrive: "雲端硬碟為空"
|
||||
emptyFolder: "空的資料夾"
|
||||
emptyFolder: "資料夾為空"
|
||||
unableToDelete: "無法刪除"
|
||||
inputNewFileName: "輸入檔案名稱"
|
||||
inputNewFolderName: "輸入新資料夾的名稱"
|
||||
@ -268,7 +280,7 @@ circularReferenceFolder: "目標文件夾是您要移動的文件夾的子文件
|
||||
hasChildFilesOrFolders: "此文件夾不是空的,無法刪除。"
|
||||
copyUrl: "複製URL"
|
||||
rename: "重新命名"
|
||||
avatar: "頭像"
|
||||
avatar: "大頭貼"
|
||||
banner: "橫幅"
|
||||
nsfw: "敏感內容"
|
||||
whenServerDisconnected: "與服務器的連接中斷時"
|
||||
@ -282,14 +294,14 @@ accept: "接受"
|
||||
reject: "拒絕"
|
||||
normal: "正常"
|
||||
instanceName: "實例名稱"
|
||||
instanceDescription: "實例描述"
|
||||
instanceDescription: "實例說明"
|
||||
maintainerName: "管理員名稱"
|
||||
maintainerEmail: "管理員信箱"
|
||||
maintainerEmail: "管理員郵箱"
|
||||
tosUrl: "服務條款URL"
|
||||
thisYear: "今年"
|
||||
thisYear: "本年"
|
||||
thisMonth: "本月"
|
||||
today: "本日"
|
||||
dayX: "{day}天"
|
||||
dayX: "{day}日"
|
||||
monthX: "{month}月"
|
||||
yearX: "{year}年"
|
||||
pages: "頁面"
|
||||
@ -312,7 +324,9 @@ bannerUrl: "橫幅圖片URL"
|
||||
basicInfo: "基本資訊"
|
||||
pinnedUsers: "置頂用戶"
|
||||
pinnedUsersDescription: "在「發現」頁面中使用換行標記想要置頂的用戶。"
|
||||
pinnedNotes: "已置頂的貼文"
|
||||
pinnedPages: "釘選頁面"
|
||||
pinnedPagesDescription: "輸入要固定至實例首頁的頁面路徑,以換行符分隔。"
|
||||
pinnedNotes: "已置頂的箋文"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "啟用 hCaptcha"
|
||||
hcaptchaSiteKey: "網站金鑰"
|
||||
@ -329,14 +343,15 @@ antennaSource: "接收來源"
|
||||
antennaKeywords: "包含關鍵字"
|
||||
antennaExcludeKeywords: "排除關鍵字"
|
||||
antennaKeywordsDescription: "用空格分隔指定AND、用換行符分隔指定OR"
|
||||
notifyAntenna: "通知我有新的貼文"
|
||||
notifyAntenna: "通知有新箋文"
|
||||
withFileAntenna: "僅帶有附件的箋文"
|
||||
serviceworker: "ServiceWorker"
|
||||
enableServiceworker: "開啟 ServiceWorker"
|
||||
antennaUsersDescription: "指定用換行符分隔的用戶名"
|
||||
caseSensitive: "區分大小寫"
|
||||
withReplies: "包含回覆"
|
||||
connectedTo: "您的帳號已連接到以下社交帳號"
|
||||
notesAndReplies: "貼文與回覆"
|
||||
notesAndReplies: "箋文與回覆"
|
||||
withFiles: "附件"
|
||||
silence: "禁言"
|
||||
silenceConfirm: "確定要禁言此用戶嗎?"
|
||||
@ -353,7 +368,7 @@ userList: "清單"
|
||||
about: "資訊"
|
||||
aboutMisskey: "關於 Misskey"
|
||||
administrator: "管理員"
|
||||
token: "令牌"
|
||||
token: "權杖"
|
||||
twoStepAuthentication: "雙重身份驗證"
|
||||
moderator: "板主"
|
||||
nUsersMentioned: "提到了{n}"
|
||||
@ -372,7 +387,7 @@ notFoundDescription: "找不到與指定URL回應的頁面"
|
||||
uploadFolder: "預設上傳資料夾"
|
||||
cacheClear: "清除快取"
|
||||
markAsReadAllNotifications: "標記所有通知為已讀"
|
||||
markAsReadAllUnreadNotes: "標記所有貼文為已讀"
|
||||
markAsReadAllUnreadNotes: "標記所有箋文為已讀"
|
||||
markAsReadAllTalkMessages: "標記所有訊息為已讀"
|
||||
help: "幫助"
|
||||
inputMessageHere: "在此輸入訊息"
|
||||
@ -393,9 +408,9 @@ text: "文字"
|
||||
enable: "啟用"
|
||||
next: "下一步"
|
||||
retype: "重新輸入"
|
||||
noteOf: "{user}的貼文"
|
||||
noteOf: "{user}的箋文"
|
||||
inviteToGroup: "邀請至群組"
|
||||
maxNoteTextLength: "貼文的字數限制"
|
||||
maxNoteTextLength: "箋文的字數限制"
|
||||
quoteAttached: "引用"
|
||||
quoteQuestion: "是否要引用?"
|
||||
noMessagesYet: "沒有訊息"
|
||||
@ -426,6 +441,7 @@ useOsNativeEmojis: "使用OS原生表情符號"
|
||||
youHaveNoGroups: "找不到群組"
|
||||
joinOrCreateGroup: "請加入現有群組,或創建新群組。"
|
||||
noHistory: "沒有歷史紀錄"
|
||||
signinHistory: "登錄歷史"
|
||||
disableAnimatedMfm: "禁用MFM動畫"
|
||||
doing: "正在進行"
|
||||
category: "類別"
|
||||
@ -435,7 +451,9 @@ createAccount: "建立帳戶"
|
||||
existingAcount: "現有帳戶"
|
||||
regenerate: "再生"
|
||||
fontSize: "字體大小"
|
||||
noFollowRequests: "沒有要求跟隨您的申請"
|
||||
openImageInNewTab: "於新分頁中開啟圖片"
|
||||
dashboard: "儀表板"
|
||||
local: "本地"
|
||||
remote: "遠端"
|
||||
total: "合計"
|
||||
@ -444,10 +462,10 @@ dayOverDayChanges: "與前一日相比"
|
||||
appearance: "外觀"
|
||||
clientSettings: "用戶端設定"
|
||||
accountSettings: "帳號設定"
|
||||
promotion: "推廣貼文"
|
||||
promotion: "推廣"
|
||||
promote: "推廣"
|
||||
numberOfDays: "有效天數"
|
||||
hideThisNote: "隱藏此貼文"
|
||||
hideThisNote: "隱藏此箋文"
|
||||
showFeaturedNotesInTimeline: "在時間軸上顯示熱門推薦"
|
||||
objectStorageBaseUrl: "Base URL"
|
||||
objectStorageBucket: "儲存空間(Bucket)"
|
||||
@ -457,12 +475,18 @@ objectStorageEndpointDesc: "如要使用AWS S3,請留空。否則請根據伺
|
||||
objectStorageRegion: "地域(Region)"
|
||||
objectStorageUseSSL: "使用SSL"
|
||||
objectStorageUseProxy: "使用網路代理"
|
||||
objectStorageSetPublicRead: "上載時設定為\"public-read\""
|
||||
serverLogs: "伺服器日誌"
|
||||
deleteAll: "刪除所有記錄"
|
||||
showFixedPostForm: "於時間軸頁頂顯示「發送箋文」方框"
|
||||
newNoteRecived: "發現新的箋文"
|
||||
sounds: "音效"
|
||||
listen: "聆聽"
|
||||
none: "無"
|
||||
showInPage: "在頁面中顯示"
|
||||
popout: "彈出型窗口"
|
||||
volume: "音量"
|
||||
masterVolume: "主音量"
|
||||
details: "詳細資訊"
|
||||
chooseEmoji: "選擇您的表情符號\n"
|
||||
unableToProcess: "操作無法完成"
|
||||
@ -480,10 +504,12 @@ descendingOrder: "降冪"
|
||||
scratchpad: "暫存記憶體"
|
||||
output: "輸出"
|
||||
script: "腳本"
|
||||
disablePagesScript: "停用頁面的AiScript腳本"
|
||||
updateRemoteUser: "更新非本地用戶資料"
|
||||
deleteAllFiles: "刪除所有檔案"
|
||||
deleteAllFilesConfirm: "要删除所有檔案吗?"
|
||||
removeAllFollowing: "解除所有追隨"
|
||||
removeAllFollowingDescription: "解除{host}所有的跟隨。在實例不再存在時執行。"
|
||||
userSuspended: "該用戶已被凍結"
|
||||
userSilenced: "該用戶已被禁言。"
|
||||
sidebar: "側邊列"
|
||||
@ -495,10 +521,10 @@ addRelay: "添加中繼"
|
||||
inboxUrl: "私信URL"
|
||||
addedRelays: "已添加的中繼"
|
||||
serviceworkerInfo: "您需要啟用推送通知"
|
||||
deletedNote: "已删除的貼文"
|
||||
deletedNote: "已删除的箋文"
|
||||
invisibleNote: "隱藏的帖子"
|
||||
enableInfiniteScroll: "啟用自動滾動頁面模式"
|
||||
visibility: "公開範圍"
|
||||
visibility: "可見性"
|
||||
poll: "投票"
|
||||
useCw: "隱藏內容"
|
||||
enablePlayer: "打開播放器"
|
||||
@ -513,8 +539,13 @@ plugins: "插件"
|
||||
pluginInstallWarn: "請不要安裝來源不明的插件。"
|
||||
deck: "多欄模式"
|
||||
undeck: "取消多欄模式"
|
||||
useBlurEffectForModal: "在模態框使用模糊效果"
|
||||
useFullReactionPicker: "使用大尺寸的情感選擇欄"
|
||||
width: "寬度"
|
||||
height: "高度"
|
||||
large: "大"
|
||||
medium: "中"
|
||||
small: "小"
|
||||
permission: "權限"
|
||||
enableAll: "啟用全部"
|
||||
disableAll: "停用全部"
|
||||
@ -525,6 +556,8 @@ useStarForReactionFallback: "以★代替未知的表情符號"
|
||||
emailConfig: "電子郵件伺服器設定"
|
||||
enableEmail: "啟用發送電郵功能"
|
||||
emailConfigInfo: "用於確認電郵地址及密碼重置"
|
||||
email: "電子郵件"
|
||||
emailAddress: "電郵地址"
|
||||
smtpConfig: "SMTP伺服器設定"
|
||||
smtpHost: "主機"
|
||||
smtpPort: "端口"
|
||||
@ -533,6 +566,8 @@ smtpPass: "密碼"
|
||||
emptyToDisableSmtpAuth: "留空使用者名稱和密碼以禁用SMTP驗證。"
|
||||
testEmail: "郵件測試發送"
|
||||
wordMute: "靜音文字"
|
||||
userSaysSomething: "{name}說了什麼"
|
||||
makeActive: "啟用"
|
||||
display: "檢視"
|
||||
copy: "複製"
|
||||
metrics: "指標"
|
||||
@ -543,67 +578,201 @@ database: "資料庫"
|
||||
channel: "頻道"
|
||||
create: "新增"
|
||||
notificationSetting: "通知設定"
|
||||
notificationSettingDesc: "選擇顯示通知的類型"
|
||||
useGlobalSetting: "使用全域設定"
|
||||
other: "其他"
|
||||
regenerateLoginTokenDescription: "再生用於登入的內部權杖。一般情況下是不需要這樣做的。一旦再生,所有裝置將會被登出。"
|
||||
fileIdOrUrl: "文檔ID或者URL"
|
||||
chatOpenBehavior: "開啟聊天窗口時的行為"
|
||||
behavior: "行為"
|
||||
sample: "範例 "
|
||||
abuseReports: "檢舉"
|
||||
reportAbuse: "檢舉"
|
||||
reportAbuseOf: "檢舉{name}"
|
||||
fillAbuseReportDescription: "請填寫檢舉的詳細理由。可以的話,請附上針對的URL網址。"
|
||||
abuseReported: "內容已經發送。感謝您的報告。"
|
||||
send: "發送"
|
||||
abuseMarkAsResolved: "處理完畢"
|
||||
openInNewTab: "在新分頁中開啟"
|
||||
openInSideView: "在側欄中開啟"
|
||||
editTheseSettingsMayBreakAccount: "修改這些設定可能會毀壞您的帳戶"
|
||||
instanceTicker: "箋文的實例來源"
|
||||
waitingFor: "等待{x}"
|
||||
random: "隨機"
|
||||
system: "系統"
|
||||
switchUi: "切換界面"
|
||||
desktop: "桌面"
|
||||
clip: "片段"
|
||||
createNew: "新建"
|
||||
optional: "可選"
|
||||
public: "公開"
|
||||
i18nInfo: "Misskey已經被志願者們翻譯成各種語言版本,如果想要幫忙的話,可以進入{link}幫助翻譯。"
|
||||
manageAccessTokens: "管理存取權杖"
|
||||
accountInfo: "帳戶資訊"
|
||||
notesCount: "箋文數量"
|
||||
repliesCount: "回覆數量\n"
|
||||
renotesCount: "轉發數量"
|
||||
repliedCount: "回覆數量"
|
||||
renotedCount: "轉發次數"
|
||||
followingCount: "正在跟隨的用戶數量"
|
||||
followersCount: "跟隨者數量"
|
||||
sentReactionsCount: "情感發送次數"
|
||||
receivedReactionsCount: "情感收到次數"
|
||||
yes: "確定"
|
||||
no: "取消"
|
||||
driveFilesCount: "雲端硬碟檔案數量"
|
||||
driveUsage: "雲端硬碟使用量"
|
||||
noCrawleDescription: "請求網路搜尋引擎不要索引你的個人資料頁、箋文及頁面等。"
|
||||
lockedAccountInfo: "即使你通過了追隨者請求,除非你將箋文的可見性設定為 「追隨者」,否則任何人都能看見你的箋文。"
|
||||
loadRawImages: "以原始圖像質量顯示附件圖像的縮略圖"
|
||||
disableShowingAnimatedImages: "不播放動態圖像"
|
||||
notSet: "未設定"
|
||||
emailVerified: "已成功驗證您的電郵"
|
||||
noteFavoritesCount: "收藏箋文的數目"
|
||||
pageLikesCount: "頁面被喜歡次數"
|
||||
pageLikedCount: "頁面被喜歡次數"
|
||||
contact: "聯絡人"
|
||||
useSystemFont: "使用系統默認的字型"
|
||||
clips: "標籤"
|
||||
experimentalFeatures: "測試中的功能"
|
||||
developer: "開發者"
|
||||
makeExplorable: "讓自己的帳戶能夠在“探索”版面顯示"
|
||||
makeExplorableDescription: "如果關閉,帳戶將不會被顯示在\"探索\"版面中。"
|
||||
showGapBetweenNotesInTimeline: "分開顯示時間線上的箋文。"
|
||||
duplicate: "複製"
|
||||
left: "左"
|
||||
center: "向中央"
|
||||
wide: "寬"
|
||||
narrow: "窄"
|
||||
reloadToApplySetting: "設定將會在頁面重新載入之後生效。要現在就重載頁面嗎?"
|
||||
showTitlebar: "顯示標題列"
|
||||
clearCache: "清除快取資料"
|
||||
onlineUsersCount: "{n}人正在線上"
|
||||
nUsers: "{n}用戶"
|
||||
nNotes: "{n}箋文"
|
||||
backgroundColor: "背景"
|
||||
textColor: "文本"
|
||||
advanced: "進階"
|
||||
value: "數值 "
|
||||
_aboutMisskey:
|
||||
about: "Misskey是由syuilo於2014年開發的開源軟件。"
|
||||
contributors: "主要貢獻者"
|
||||
allContributors: "全體貢獻人員"
|
||||
source: "原始碼"
|
||||
translation: "翻譯Misskey"
|
||||
donate: "捐贈給Misskey"
|
||||
morePatrons: "感謝你們的支持、 幫助。 🥰"
|
||||
patrons: "贊助者"
|
||||
_nsfw:
|
||||
respect: "隱藏敏感內容"
|
||||
ignore: "不隱藏敏感內容"
|
||||
force: "隱藏所有內容"
|
||||
_mfm:
|
||||
cheatSheet: "MFM代碼小抄"
|
||||
intro: "MFM是Misskey專用的標記語言,可以在Misskey中的各個位置使用。 您可以這裏看到MFM可用語法列表。"
|
||||
mention: "提及"
|
||||
hashtag: "#tag"
|
||||
url: "URL"
|
||||
link: "鏈接"
|
||||
bold: "粗體"
|
||||
small: "縮小"
|
||||
center: "置中"
|
||||
inlineMath: "數學公式(內嵌)"
|
||||
inlineMathDescription: "顯示內嵌的KaTex數學公式。"
|
||||
blockMath: "數學公式(方塊)"
|
||||
quote: "引用"
|
||||
emoji: "自訂表情符號"
|
||||
search: "搜尋"
|
||||
flip: "翻轉"
|
||||
flipDescription: "將內容上下或左右翻轉。"
|
||||
jelly: "動畫(果凍)"
|
||||
jellyDescription: "顯示果凍一樣的動畫效果。"
|
||||
bounce: "動畫(反彈)"
|
||||
shake: "動畫(搖晃)"
|
||||
twitch: "動畫(顫抖)"
|
||||
spin: "動畫(旋轉)"
|
||||
spinDescription: "顯示旋轉的動畫效果。"
|
||||
x2: "大"
|
||||
x3: "較大"
|
||||
x3Description: "放大顯示內容。"
|
||||
x4: "最大"
|
||||
x4Description: "將顯示內容放至最大。"
|
||||
blur: "模糊"
|
||||
font: "字型"
|
||||
fontDescription: "可設置顯示內容所使用的字型"
|
||||
_reversi:
|
||||
reversi: "黑白棋"
|
||||
gameSettings: "對弈設定"
|
||||
chooseBoard: "選擇棋盤"
|
||||
blackOrWhite: "黑棋/白棋"
|
||||
blackIs: "{name}在玩黑棋"
|
||||
rules: "規則"
|
||||
botSettings: "機器人設定"
|
||||
thisGameIsStartedSoon: "遊戲即將開始"
|
||||
waitingForOther: "等待對手準備"
|
||||
waitingForMe: "等待您的準備"
|
||||
waitingBoth: "請準備"
|
||||
ready: "已就緒"
|
||||
cancelReady: "重新準備"
|
||||
opponentTurn: "對手回合"
|
||||
myTurn: "你的回合"
|
||||
turnOf: "{name}的回合"
|
||||
pastTurnOf: "{name}的回合"
|
||||
surrender: "認輸"
|
||||
surrendered: "對手認輸"
|
||||
drawn: "平局"
|
||||
won: "{name}獲勝"
|
||||
black: "黑"
|
||||
white: "白"
|
||||
total: "合計"
|
||||
turnCount: "{count}回合"
|
||||
myGames: "我的對弈"
|
||||
allGames: "所有對弈"
|
||||
ended: "已結束"
|
||||
playing: "正在對弈"
|
||||
_instanceTicker:
|
||||
none: "隱藏"
|
||||
remote: "向遠端使用者顯示"
|
||||
always: "總是顯示"
|
||||
_serverDisconnectedBehavior:
|
||||
reload: "自動重載"
|
||||
dialog: "以對話框警告"
|
||||
quiet: "適當地警告"
|
||||
dialog: "彈出式警告"
|
||||
quiet: "非侵入式警告"
|
||||
_channel:
|
||||
create: "建立頻道"
|
||||
edit: "編輯頻道"
|
||||
setBanner: "設定橫幅"
|
||||
removeBanner: "移除封面圖"
|
||||
featured: "流行"
|
||||
featured: "發燒內容"
|
||||
owned: "管理中"
|
||||
following: "關注中"
|
||||
usersCount: "有{n}人參與"
|
||||
notesCount: "有{n}個帖子"
|
||||
_sidebar:
|
||||
full: "全部"
|
||||
icon: "頭像"
|
||||
hide: "隱藏"
|
||||
_wordMute:
|
||||
muteWords: "加入靜音文字"
|
||||
mutedNotes: "已靜音的貼文"
|
||||
softDescription: "隱藏時間軸中指定條件的箋文。"
|
||||
mutedNotes: "已靜音的箋文"
|
||||
_theme:
|
||||
explore: "取得佈景主題"
|
||||
install: "安裝佈景主題"
|
||||
manage: "佈景主題管理員"
|
||||
code: "主題代碼"
|
||||
installed: "{name}已安裝"
|
||||
installedThemes: "已經安裝的主題"
|
||||
builtinThemes: "標準主題"
|
||||
alreadyInstalled: "此主題已經安裝"
|
||||
invalid: "主題格式錯誤"
|
||||
make: "製作主題"
|
||||
base: "基於"
|
||||
constant: "常數"
|
||||
defaultValue: "預設值"
|
||||
color: "顏色"
|
||||
func: "函数"
|
||||
funcKind: "功能類型"
|
||||
argument: "引數"
|
||||
alpha: "透明度"
|
||||
darken: "暗度"
|
||||
@ -612,21 +781,38 @@ _theme:
|
||||
bg: "背景"
|
||||
fg: "文本"
|
||||
shadow: "陰影"
|
||||
navIndicator: "側邊欄指示符"
|
||||
link: "鏈接"
|
||||
hashtag: "#tag"
|
||||
mention: "提及"
|
||||
mentionMe: "提及我"
|
||||
renote: "轉發貼文"
|
||||
renote: "轉發箋文"
|
||||
divider: "分割線"
|
||||
scrollbarHandle: "滾動條"
|
||||
scrollbarHandleHover: "滾動條 (漂浮)"
|
||||
dateLabelFg: "日期標籤文字"
|
||||
infoBg: "資訊背景"
|
||||
infoFg: "資訊內容"
|
||||
infoWarnBg: "警告背景"
|
||||
infoWarnFg: "警告字元"
|
||||
cwBg: "CW 按鈕背景"
|
||||
cwFg: "CW 按鈕文本"
|
||||
cwHoverBg: "CW 按鈕背景 (漂浮)"
|
||||
buttonBg: "按鈕背景"
|
||||
buttonHoverBg: "按鈕背景 (漂浮)"
|
||||
inputBorder: "輸入框邊框"
|
||||
listItemHoverBg: "列表物品背景 (漂浮)"
|
||||
driveFolderBg: "雲端硬碟文件夾背景"
|
||||
messageBg: "私信背景"
|
||||
accentDarken: "強調色(偏暗)"
|
||||
accentLighten: "強調色(明亮)"
|
||||
fgHighlighted: "高亮顯示文本"
|
||||
_sfx:
|
||||
note: "貼文"
|
||||
noteMy: "我的貼文"
|
||||
note: "箋文"
|
||||
noteMy: "我的箋文"
|
||||
notification: "通知"
|
||||
chat: "傳送訊息"
|
||||
antenna: "天線接收"
|
||||
channel: "頻道通知"
|
||||
_ago:
|
||||
unknown: "未知"
|
||||
@ -643,32 +829,37 @@ _time:
|
||||
second: "秒"
|
||||
minute: "分鐘"
|
||||
hour: "小時"
|
||||
day: "天"
|
||||
day: "日"
|
||||
_tutorial:
|
||||
title: "Misskey使用方法"
|
||||
step1_1: "歡迎!"
|
||||
step1_2: "此為「時間軸」頁面,它會按照時間順序顯示你「追隨」的人的「貼文」"
|
||||
step1_3: "由於你沒有發布任何筆記,也沒有追隨任何人,所以你的時間軸目前是空的。"
|
||||
step1_2: "此為「時間軸」頁面,它會按照時間順序顯示你「追隨」的人發出的「箋文」"
|
||||
step1_3: "由於你沒有發佈任何箋文,也沒有追隨任何人,所以你的時間軸目前是空的。"
|
||||
step2_1: "在發文或追隨其他人之前先讓我們設定一下個人資料吧。"
|
||||
step2_2: "提供一些關於自己的資訊來讓其他人更有追隨你的意願。"
|
||||
step3_1: "個人資料都打理好了嗎?"
|
||||
step3_2: "下一步讓我們來試試看發個文,按一下畫面上的鉛筆圖示來開始"
|
||||
step3_3: "輸入完內容後,按視窗右上角的按鈕來發文"
|
||||
step3_4: "不知道該寫什麼內容嗎?試試看「開始使用Misskey了」如何。"
|
||||
step4_1: "筆記發出去了嗎?"
|
||||
step4_2: "如果你的貼文有顯示在時間軸上,就代表已經發文成功。"
|
||||
step4_1: "箋文發出去了嗎?"
|
||||
step4_2: "如果你的箋文出現在時間軸上,就代表發文成功。"
|
||||
step5_1: "現在試試看追隨其他人來讓你的時間軸變得更生動吧。"
|
||||
step5_2: "你可以在{featured}上看到受歡迎的貼文,你也可以選擇從列表中追隨你喜歡的人,或者在{explore}上找到熱門使用者。"
|
||||
step5_2: "你會在{featured}上看到受歡迎的箋文,你也可以從列表中追隨你喜歡的人,或者在{explore}上找到熱門使用者。"
|
||||
step5_3: "想要追隨其他人,只要點擊他們的頭像並按「追隨」即可。"
|
||||
step5_4: "如果使用者的名字旁有鎖頭的圖示,代表他們需要手動核准你的追隨請求。"
|
||||
step6_1: "現在你可以在時間軸上看到其他用戶的貼文"
|
||||
step6_2: "你也可以在其他人的貼文上進行「反應」來表達簡單的回覆。"
|
||||
step6_3: "在他人的貼文按下「+」的圖示即可選擇想要的表情符號來進行「反應」。"
|
||||
step6_1: "現在你可以在時間軸上看到其他用戶的箋文。"
|
||||
step6_2: "你也可以對別人的箋文作出「情感」,作出簡單的回覆。"
|
||||
step7_1: "以上為Misskey的基本操作說明,教學在此告一段落。辛苦了。"
|
||||
step7_2: "歡迎到{help}來瞭解更多Misskey相關介紹。"
|
||||
step7_3: "那麼,祝您在Misskey玩的開心~ 🚀"
|
||||
_2fa:
|
||||
alreadyRegistered: "此設備已經被註冊過了"
|
||||
registerDevice: "註冊裝置"
|
||||
step1: "首先,在您的設備上安裝二步驗證程式,例如{a}或{b}。"
|
||||
step2: "然後,掃描熒幕上的QR code。"
|
||||
_permissions:
|
||||
"read:account": "查看帳戶信息"
|
||||
"write:account": "更改帳戶信息"
|
||||
"read:blocks": "已封鎖用戶名單"
|
||||
"write:blocks": "編輯已封鎖用戶名單"
|
||||
"read:drive": "存取雲端硬碟\n"
|
||||
@ -680,11 +871,11 @@ _permissions:
|
||||
"write:messaging": "撰寫或刪除私人訊息"
|
||||
"read:mutes": "顯示已靜音列表"
|
||||
"write:mutes": "編輯已靜音列表"
|
||||
"write:notes": "撰寫或刪除貼文"
|
||||
"write:notes": "撰寫或刪除箋文"
|
||||
"read:notifications": "查看通知"
|
||||
"write:notifications": "編輯通知"
|
||||
"read:reactions": "查看反應"
|
||||
"write:reactions": "編輯反應"
|
||||
"read:reactions": "查看情感"
|
||||
"write:reactions": "編輯情感"
|
||||
"write:votes": "投票"
|
||||
"read:pages": "顯示頁面"
|
||||
"write:pages": "編輯頁面"
|
||||
@ -696,12 +887,17 @@ _permissions:
|
||||
"write:channels": "編輯頻道"
|
||||
_auth:
|
||||
shareAccess: "要授權「“{name}”」存取您的帳戶嗎?"
|
||||
shareAccessAsk: "您確定要授權這個應用程式使用您的帳戶嗎?"
|
||||
permissionAsk: "此應用程式需要以下權限"
|
||||
pleaseGoBack: "請返回至應用程式"
|
||||
callback: "回到應用程式"
|
||||
denied: "拒絕訪問"
|
||||
_antennaSources:
|
||||
all: "全部貼文"
|
||||
homeTimeline: "來自已追隨使用者的貼文"
|
||||
users: "來自特定使用者的貼文"
|
||||
userList: "來自特定清單中的貼文"
|
||||
userGroup: "來自特定群組的貼文"
|
||||
all: "全部箋文"
|
||||
homeTimeline: "來自已追隨使用者的箋文"
|
||||
users: "來自特定使用者的箋文"
|
||||
userList: "來自特定清單中的箋文"
|
||||
userGroup: "來自特定群組的箋文"
|
||||
_weekday:
|
||||
sunday: "週日"
|
||||
monday: "週一"
|
||||
@ -715,13 +911,18 @@ _widgets:
|
||||
notifications: "通知"
|
||||
timeline: "時間軸"
|
||||
calendar: "行事曆"
|
||||
trends: "發燒貼文"
|
||||
trends: "發燒箋文"
|
||||
clock: "時鐘"
|
||||
rss: "RSS閱讀器"
|
||||
activity: "動態"
|
||||
photos: "照片"
|
||||
digitalClock: "電子時鐘"
|
||||
federation: "聯邦宇宙"
|
||||
postForm: "發佈窗口"
|
||||
slideshow: "幻燈片"
|
||||
button: "按鈕"
|
||||
onlineUsers: "在線上的用戶"
|
||||
jobQueue: "佇列"
|
||||
_cw:
|
||||
hide: "隱藏"
|
||||
show: "瀏覽更多"
|
||||
@ -729,6 +930,8 @@ _cw:
|
||||
files: "{count} 個檔案"
|
||||
_poll:
|
||||
noOnlyOneChoice: "至少需要兩個選項。"
|
||||
choiceN: "選擇{n}"
|
||||
noMore: "沒辦法再添加選項了"
|
||||
expiration: "期限"
|
||||
infinite: "無期限"
|
||||
at: "結束時間"
|
||||
@ -742,6 +945,7 @@ _poll:
|
||||
voted: "已投票"
|
||||
closed: "已結束"
|
||||
remainingDays: "{d}天{h}小時後結束"
|
||||
remainingHours: "{h}小時{m}分後結束"
|
||||
_visibility:
|
||||
public: "公開"
|
||||
home: "首頁"
|
||||
@ -751,8 +955,8 @@ _visibility:
|
||||
localOnly: "僅限本地"
|
||||
localOnlyDescription: "對遠端使用者隱藏"
|
||||
_postForm:
|
||||
replyPlaceholder: "回覆此貼文..."
|
||||
quotePlaceholder: "引用此貼文..."
|
||||
replyPlaceholder: "回覆此箋文..."
|
||||
quotePlaceholder: "引用此箋文..."
|
||||
channelPlaceholder: "發佈到頻道"
|
||||
_placeholders:
|
||||
a: "今天過得如何?"
|
||||
@ -766,10 +970,12 @@ _profile:
|
||||
username: "使用者名稱"
|
||||
description: "關於我"
|
||||
youCanIncludeHashtags: "你也可以在「關於我」中加上 #tag"
|
||||
metadata: "進階資訊"
|
||||
metadataEdit: "編輯進階資訊"
|
||||
metadataLabel: "標籤"
|
||||
metadataContent: "内容"
|
||||
_exportOrImport:
|
||||
allNotes: "全部貼文"
|
||||
allNotes: "所有箋文"
|
||||
followingList: "追隨中"
|
||||
muteList: "靜音"
|
||||
blockingList: "封鎖"
|
||||
@ -778,10 +984,10 @@ _charts:
|
||||
usersIncDec: "使用者増減"
|
||||
usersTotal: "使用者合共"
|
||||
activeUsers: "活躍使用者"
|
||||
notesIncDec: "貼文増減"
|
||||
localNotesIncDec: "本地貼文増減"
|
||||
remoteNotesIncDec: "非本地貼文的數目增减"
|
||||
notesTotal: "貼文合共"
|
||||
notesIncDec: "箋文増減"
|
||||
localNotesIncDec: "本地箋文増減"
|
||||
remoteNotesIncDec: "遠端箋文數目增减"
|
||||
notesTotal: "箋文合共"
|
||||
filesIncDec: "檔案増減"
|
||||
filesTotal: "累計檔案"
|
||||
storageUsageIncDec: "儲存空間的増減"
|
||||
@ -790,8 +996,8 @@ _instanceCharts:
|
||||
requests: "請求"
|
||||
users: "使用者増減"
|
||||
usersTotal: "總計使用者"
|
||||
notes: "貼文増減"
|
||||
notesTotal: "累計貼文"
|
||||
notes: "箋文増減"
|
||||
notesTotal: "累計箋文"
|
||||
ff: "追隨/追隨者的増減"
|
||||
ffTotal: "追隨/追隨者累計"
|
||||
cacheSize: "增加或減少快取用量"
|
||||
@ -839,12 +1045,23 @@ _rooms:
|
||||
book: "讀物"
|
||||
book2: "讀物2"
|
||||
piano: "鋼琴"
|
||||
server: "伺服器"
|
||||
moon: "月亮"
|
||||
corkboard: "木栓板"
|
||||
mousepad: "滑鼠墊"
|
||||
monitor: "監視器"
|
||||
keyboard: "鍵盤"
|
||||
carpet-stripe: "條紋地毯"
|
||||
mat: "地毯"
|
||||
wall-clock: "壁鐘"
|
||||
photoframe: "相框"
|
||||
cube: "立方體"
|
||||
tv: "電視"
|
||||
pinguin: "企鵝蠟像"
|
||||
poster-h: "海報(橫向)"
|
||||
poster-v: "海報(直向)"
|
||||
sofa: " 沙發"
|
||||
spiral: "螺旋式樓梯"
|
||||
bin: "垃圾箱"
|
||||
cup-noodle: "杯面"
|
||||
holo-display: "投影機"
|
||||
@ -854,9 +1071,14 @@ _rooms:
|
||||
_pages:
|
||||
newPage: "建立頁面"
|
||||
editPage: "編輯頁面"
|
||||
readPage: "正檢視原始碼"
|
||||
created: "頁面已建立"
|
||||
updated: "頁面已更新"
|
||||
deleted: "頁面已被刪除"
|
||||
pageSetting: "頁面設定"
|
||||
nameAlreadyExists: "指定的頁面URL已經存在"
|
||||
invalidNameTitle: "指定的頁面URL無效"
|
||||
invalidNameText: "請確定是否為非空白"
|
||||
editThisPage: "編輯此頁面"
|
||||
viewSource: "檢視原始碼"
|
||||
viewPage: "顯示頁面"
|
||||
@ -864,14 +1086,28 @@ _pages:
|
||||
unlike: "收回喜歡"
|
||||
my: "我的頁面"
|
||||
liked: "已喜歡的頁面"
|
||||
featured: "人氣"
|
||||
inspector: "面板檢查"
|
||||
contents: "內容"
|
||||
content: "頁面方塊"
|
||||
variables: "變數"
|
||||
title: "標題"
|
||||
url: "頁面網址"
|
||||
summary: "頁面摘要"
|
||||
alignCenter: "置中"
|
||||
hideTitleWhenPinned: "被置頂於個人資料時隱藏頁面標題"
|
||||
font: "字型"
|
||||
fontSerif: "襯線體"
|
||||
fontSansSerif: "無襯線體"
|
||||
eyeCatchingImageSet: "設定封面影像"
|
||||
eyeCatchingImageRemove: "刪除封面影像"
|
||||
chooseBlock: "新增方塊"
|
||||
selectType: "選擇類型"
|
||||
enterVariableName: "請輸入變數名稱"
|
||||
variableNameIsAlreadyUsed: "變數名稱已被佔用"
|
||||
contentBlocks: "內容"
|
||||
inputBlocks: "輸入"
|
||||
specialBlocks: "特殊"
|
||||
blocks:
|
||||
text: "文本"
|
||||
textarea: "文字區域"
|
||||
@ -881,6 +1117,7 @@ _pages:
|
||||
if: "如果"
|
||||
_if:
|
||||
variable: "變數"
|
||||
post: "發佈窗口"
|
||||
_post:
|
||||
text: "内容"
|
||||
canvasId: "畫布ID"
|
||||
@ -904,6 +1141,10 @@ _pages:
|
||||
id: "畫布ID"
|
||||
width: "寬度"
|
||||
height: "高度"
|
||||
note: "嵌式箋文"
|
||||
_note:
|
||||
id: "箋文ID"
|
||||
detailed: "顯示詳細內容"
|
||||
switch: "開關"
|
||||
_switch:
|
||||
name: "變數名稱"
|
||||
@ -936,6 +1177,7 @@ _pages:
|
||||
default: "預設值"
|
||||
script:
|
||||
categories:
|
||||
flow: "控制"
|
||||
logical: "邏輯運算"
|
||||
operation: "計算"
|
||||
comparison: "對比"
|
||||
@ -951,6 +1193,7 @@ _pages:
|
||||
textList: "文本列表"
|
||||
_strLen:
|
||||
arg1: "文本"
|
||||
strPick: "提取字元"
|
||||
_strPick:
|
||||
arg1: "文本"
|
||||
arg2: "字元位置"
|
||||
@ -960,6 +1203,7 @@ _pages:
|
||||
arg1: "本文"
|
||||
_join:
|
||||
arg1: "清單"
|
||||
arg2: "分隔字元"
|
||||
add: "加"
|
||||
_add:
|
||||
arg1: "A"
|
||||
@ -976,6 +1220,7 @@ _pages:
|
||||
_divide:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
mod: "餘數"
|
||||
_mod:
|
||||
arg1: "A"
|
||||
arg2: "B"
|
||||
@ -1070,7 +1315,6 @@ _pages:
|
||||
aiScriptVar: "AiScript的變數"
|
||||
fn: "函数"
|
||||
_fn:
|
||||
slots: "欄位"
|
||||
arg1: "輸出"
|
||||
_for:
|
||||
arg1: "重複次數"
|
||||
@ -1087,9 +1331,14 @@ _relayStatus:
|
||||
accepted: "已通過核准"
|
||||
rejected: "已拒絕"
|
||||
_notification:
|
||||
youRenoted: "{name} 轉發了你的貼文"
|
||||
youGotMention: "{name}提及到您"
|
||||
youGotReply: "{name}回覆了您"
|
||||
youGotQuote: "{name}引用了您"
|
||||
youRenoted: "{name} 轉發了你的箋文"
|
||||
youGotPoll: "{name}已投票"
|
||||
youGotMessagingMessageFromUser: "{name}發送給您的訊息"
|
||||
youWereFollowed: "您有新的追隨者"
|
||||
youReceivedFollowRequest: "您有新的追隨請求"
|
||||
yourFollowRequestAccepted: "您的追隨請求已通過"
|
||||
youWereInvitedToGroup: "您有新的群組邀請"
|
||||
_types:
|
||||
@ -1097,15 +1346,19 @@ _notification:
|
||||
follow: "追隨中"
|
||||
mention: "提及"
|
||||
reply: "回覆"
|
||||
renote: "轉發貼文"
|
||||
renote: "轉發箋文"
|
||||
quote: "引用"
|
||||
reaction: "反應"
|
||||
reaction: "情感"
|
||||
pollVote: "統計已投票數"
|
||||
receiveFollowRequest: "已收到追隨請求"
|
||||
followRequestAccepted: "追隨請求已接受"
|
||||
groupInvited: "加入社群邀請"
|
||||
app: "應用程式通知"
|
||||
_deck:
|
||||
alwaysShowMainColumn: "總是顯示主欄"
|
||||
columnAlign: "對齊欄位"
|
||||
columnMargin: "列之間的邊距"
|
||||
columnHeaderHeight: "欄位標題高度"
|
||||
addColumn: "新增欄位"
|
||||
swapLeft: "向左移動"
|
||||
swapRight: "向右移動"
|
||||
@ -1113,7 +1366,9 @@ _deck:
|
||||
swapDown: "往下移動"
|
||||
stackLeft: "向左折疊"
|
||||
popRight: "向右彈出"
|
||||
profile: "個人檔案"
|
||||
_columns:
|
||||
main: "主列"
|
||||
widgets: "小工具"
|
||||
notifications: "通知"
|
||||
tl: "時間軸"
|
||||
|
18
migration/1607353487793-isExplorable.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class isExplorable1607353487793 implements MigrationInterface {
|
||||
name = 'isExplorable1607353487793'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "user" ADD "isExplorable" boolean NOT NULL DEFAULT true`);
|
||||
await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_d5a1b83c7cab66f167e6888188" ON "user" ("isExplorable") `);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "IDX_d5a1b83c7cab66f167e6888188"`);
|
||||
await queryRunner.query(`COMMENT ON COLUMN "user"."isExplorable" IS 'Whether the User is explorable.'`);
|
||||
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isExplorable"`);
|
||||
}
|
||||
|
||||
}
|
22
migration/1610277136869-registry.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class registry1610277136869 implements MigrationInterface {
|
||||
name = 'registry1610277136869'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE "registry_item" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "key" character varying(1024) NOT NULL, "scope" character varying(1024) array NOT NULL DEFAULT '{}'::varchar[], "domain" character varying(512), CONSTRAINT "PK_64b3f7e6008b4d89b826cd3af95" PRIMARY KEY ("id")); COMMENT ON COLUMN "registry_item"."createdAt" IS 'The created date of the RegistryItem.'; COMMENT ON COLUMN "registry_item"."updatedAt" IS 'The updated date of the RegistryItem.'; COMMENT ON COLUMN "registry_item"."userId" IS 'The owner ID.'; COMMENT ON COLUMN "registry_item"."key" IS 'The key of the RegistryItem.'`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_fb9d21ba0abb83223263df6bcb" ON "registry_item" ("userId") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_22baca135bb8a3ea1a83d13df3" ON "registry_item" ("scope") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_0a72bdfcdb97c0eca11fe7ecad" ON "registry_item" ("domain") `);
|
||||
await queryRunner.query(`ALTER TABLE "registry_item" ADD CONSTRAINT "FK_fb9d21ba0abb83223263df6bcb3" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "registry_item" DROP CONSTRAINT "FK_fb9d21ba0abb83223263df6bcb3"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_0a72bdfcdb97c0eca11fe7ecad"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_22baca135bb8a3ea1a83d13df3"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_fb9d21ba0abb83223263df6bcb"`);
|
||||
await queryRunner.query(`DROP TABLE "registry_item"`);
|
||||
}
|
||||
|
||||
}
|
16
migration/1610277585759-registry2.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class registry21610277585759 implements MigrationInterface {
|
||||
name = 'registry21610277585759'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "registry_item" ADD "value" jsonb NOT NULL DEFAULT '{}'`);
|
||||
await queryRunner.query(`COMMENT ON COLUMN "registry_item"."value" IS 'The value of the RegistryItem.'`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`COMMENT ON COLUMN "registry_item"."value" IS 'The value of the RegistryItem.'`);
|
||||
await queryRunner.query(`ALTER TABLE "registry_item" DROP COLUMN "value"`);
|
||||
}
|
||||
|
||||
}
|
14
migration/1610283021566-registry3.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class registry31610283021566 implements MigrationInterface {
|
||||
name = 'registry31610283021566'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "value" DROP NOT NULL`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "registry_item" ALTER COLUMN "value" SET NOT NULL`);
|
||||
}
|
||||
|
||||
}
|
98
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
||||
"version": "12.62.0",
|
||||
"version": "12.67.1",
|
||||
"codename": "indigo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -41,10 +41,12 @@
|
||||
"@fortawesome/free-brands-svg-icons": "5.15.1",
|
||||
"@fortawesome/free-regular-svg-icons": "5.15.1",
|
||||
"@fortawesome/free-solid-svg-icons": "5.15.1",
|
||||
"@fortawesome/vue-fontawesome": "3.0.0-2",
|
||||
"@fortawesome/vue-fontawesome": "3.0.0-3",
|
||||
"@koa/cors": "3.1.0",
|
||||
"@koa/multer": "3.0.0",
|
||||
"@koa/router": "9.0.1",
|
||||
"@sentry/browser": "5.29.2",
|
||||
"@sentry/tracing": "5.29.2",
|
||||
"@sinonjs/fake-timers": "6.0.1",
|
||||
"@syuilo/aiscript": "0.11.1",
|
||||
"@types/bcryptjs": "2.4.2",
|
||||
@ -62,7 +64,7 @@
|
||||
"@types/jsdom": "16.2.5",
|
||||
"@types/jsonld": "1.5.1",
|
||||
"@types/katex": "0.11.0",
|
||||
"@types/koa": "2.11.3",
|
||||
"@types/koa": "2.11.6",
|
||||
"@types/koa-bodyparser": "4.3.0",
|
||||
"@types/koa-cors": "0.0.0",
|
||||
"@types/koa-favicon": "2.0.19",
|
||||
@ -70,31 +72,33 @@
|
||||
"@types/koa-mount": "4.0.0",
|
||||
"@types/koa-send": "4.1.2",
|
||||
"@types/koa-views": "2.0.4",
|
||||
"@types/koa__cors": "3.0.1",
|
||||
"@types/koa__cors": "3.0.2",
|
||||
"@types/koa__multer": "2.0.2",
|
||||
"@types/koa__router": "8.0.2",
|
||||
"@types/markdown-it": "10.0.3",
|
||||
"@types/matter-js": "0.14.8",
|
||||
"@types/mocha": "7.0.2",
|
||||
"@types/node": "14.0.22",
|
||||
"@types/node": "14.14.13",
|
||||
"@types/node-fetch": "2.5.7",
|
||||
"@types/nodemailer": "6.4.0",
|
||||
"@types/nprogress": "0.2.0",
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/parse5": "5.0.3",
|
||||
"@types/parsimmon": "1.10.5",
|
||||
"@types/parsimmon": "1.10.6",
|
||||
"@types/portscanner": "2.1.0",
|
||||
"@types/pug": "2.0.4",
|
||||
"@types/qrcode": "1.3.5",
|
||||
"@types/random-seed": "0.3.3",
|
||||
"@types/ratelimiter": "3.4.0",
|
||||
"@types/ratelimiter": "3.4.1",
|
||||
"@types/redis": "2.8.28",
|
||||
"@types/rename": "1.0.2",
|
||||
"@types/request-stats": "3.0.0",
|
||||
"@types/rimraf": "3.0.0",
|
||||
"@types/seedrandom": "2.4.28",
|
||||
"@types/sharp": "0.26.0",
|
||||
"@types/sharp": "0.26.1",
|
||||
"@types/sinonjs__fake-timers": "6.0.1",
|
||||
"@types/speakeasy": "2.0.5",
|
||||
"@types/throttle-debounce": "2.1.0",
|
||||
"@types/tinycolor2": "1.4.2",
|
||||
"@types/tmp": "0.2.0",
|
||||
"@types/uuid": "8.3.0",
|
||||
@ -103,17 +107,17 @@
|
||||
"@types/webpack-stream": "3.2.11",
|
||||
"@types/websocket": "1.0.1",
|
||||
"@types/ws": "7.4.0",
|
||||
"@typescript-eslint/parser": "4.6.1",
|
||||
"@vue/compiler-sfc": "3.0.3",
|
||||
"@typescript-eslint/parser": "4.10.0",
|
||||
"@vue/compiler-sfc": "3.0.5",
|
||||
"abort-controller": "3.0.0",
|
||||
"apexcharts": "3.22.2",
|
||||
"apexcharts": "3.23.1",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.2",
|
||||
"autwh": "0.1.0",
|
||||
"aws-sdk": "2.787.0",
|
||||
"aws-sdk": "2.809.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"blurhash": "1.1.3",
|
||||
"bull": "3.18.1",
|
||||
"bull": "3.20.0",
|
||||
"cafy": "15.2.1",
|
||||
"cbor": "5.1.0",
|
||||
"chalk": "4.1.0",
|
||||
@ -121,28 +125,30 @@
|
||||
"cli-highlight": "2.1.9",
|
||||
"commander": "4.1.1",
|
||||
"content-disposition": "0.5.3",
|
||||
"core-js": "3.7.0",
|
||||
"core-js": "3.8.1",
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "5.0.1",
|
||||
"cssnano": "4.1.10",
|
||||
"dateformat": "3.0.3",
|
||||
"dateformat": "4.3.1",
|
||||
"deep-entries": "3.1.0",
|
||||
"diskusage": "1.1.3",
|
||||
"double-ended-queue": "2.1.0-0",
|
||||
"escape-regexp": "0.0.1",
|
||||
"eslint": "7.14.0",
|
||||
"eslint-plugin-vue": "7.1.0",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-plugin-vue": "7.4.1",
|
||||
"eventemitter3": "4.0.7",
|
||||
"feed": "4.2.1",
|
||||
"fibers": "5.0.0",
|
||||
"file-type": "16.0.1",
|
||||
"file-type": "16.1.0",
|
||||
"fluent-ffmpeg": "2.1.2",
|
||||
"glob": "7.1.6",
|
||||
"got": "11.8.0",
|
||||
"got": "11.8.1",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-cssnano": "2.1.3",
|
||||
"gulp-rename": "2.0.0",
|
||||
"gulp-replace": "1.0.0",
|
||||
"gulp-sourcemaps": "2.6.5",
|
||||
"gulp-terser": "2.0.1",
|
||||
"gulp-tslint": "8.1.4",
|
||||
"gulp-typescript": "6.0.0-alpha.1",
|
||||
"hard-source-webpack-plugin": "0.13.1",
|
||||
@ -151,7 +157,6 @@
|
||||
"http-proxy-agent": "4.0.1",
|
||||
"http-signature": "1.3.5",
|
||||
"https-proxy-agent": "5.0.0",
|
||||
"idb-keyval": "3.2.0",
|
||||
"insert-text-at-cursor": "0.3.0",
|
||||
"is-root": "2.1.0",
|
||||
"is-svg": "4.2.1",
|
||||
@ -162,7 +167,7 @@
|
||||
"jsonld": "3.2.0",
|
||||
"jsrsasign": "8.0.20",
|
||||
"katex": "0.12.0",
|
||||
"koa": "2.13.0",
|
||||
"koa": "2.13.1",
|
||||
"koa-bodyparser": "4.3.0",
|
||||
"koa-favicon": "2.1.0",
|
||||
"koa-json-body": "5.3.0",
|
||||
@ -175,13 +180,14 @@
|
||||
"lookup-dns-cache": "2.1.0",
|
||||
"markdown-it": "11.0.1",
|
||||
"markdown-it-anchor": "6.0.1",
|
||||
"matter-js": "0.14.2",
|
||||
"mocha": "8.2.1",
|
||||
"moji": "0.5.1",
|
||||
"ms": "2.1.2",
|
||||
"ms": "2.1.3",
|
||||
"multer": "1.4.2",
|
||||
"nested-property": "4.0.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"nodemailer": "6.4.16",
|
||||
"nodemailer": "6.4.17",
|
||||
"object-assign-deep": "0.4.0",
|
||||
"os-utils": "0.0.14",
|
||||
"p-cancelable": "2.0.0",
|
||||
@ -189,9 +195,9 @@
|
||||
"parsimmon": "1.16.0",
|
||||
"pg": "8.5.1",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss": "8.1.14",
|
||||
"postcss": "8.2.4",
|
||||
"postcss-loader": "4.1.0",
|
||||
"prismjs": "1.22.0",
|
||||
"prismjs": "1.23.0",
|
||||
"probe-image-size": "6.0.0",
|
||||
"promise-limit": "2.7.0",
|
||||
"promise-sequential": "1.1.1",
|
||||
@ -201,7 +207,7 @@
|
||||
"qrcode": "1.4.4",
|
||||
"random-seed": "0.3.0",
|
||||
"ratelimiter": "3.4.1",
|
||||
"re2": "1.15.8",
|
||||
"re2": "1.15.9",
|
||||
"recaptcha-promise": "1.0.0",
|
||||
"reconnecting-websocket": "4.4.0",
|
||||
"redis": "3.0.2",
|
||||
@ -214,54 +220,52 @@
|
||||
"rimraf": "3.0.2",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"sass": "1.29.0",
|
||||
"sass-loader": "10.1.0",
|
||||
"sass": "1.32.4",
|
||||
"sass-loader": "10.1.1",
|
||||
"seedrandom": "3.0.5",
|
||||
"sharp": "0.26.2",
|
||||
"sharp": "0.27.0",
|
||||
"speakeasy": "2.0.0",
|
||||
"stringz": "2.1.0",
|
||||
"style-loader": "2.0.0",
|
||||
"summaly": "2.4.0",
|
||||
"syslog-pro": "1.0.0",
|
||||
"systeminformation": "4.30.7",
|
||||
"systeminformation": "4.34.6",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"textarea-caret": "3.1.0",
|
||||
"three": "0.117.1",
|
||||
"throttle-debounce": "3.0.1",
|
||||
"tinycolor2": "1.4.2",
|
||||
"tmp": "0.2.1",
|
||||
"ts-loader": "8.0.9",
|
||||
"ts-node": "9.1.0",
|
||||
"ts-loader": "8.0.14",
|
||||
"ts-node": "9.1.1",
|
||||
"tslint": "6.1.3",
|
||||
"tslint-sonarts": "1.9.0",
|
||||
"typeorm": "0.2.29",
|
||||
"typescript": "4.0.5",
|
||||
"typeorm": "0.2.30",
|
||||
"typescript": "4.1.3",
|
||||
"ulid": "2.3.0",
|
||||
"url-loader": "4.1.1",
|
||||
"uuid": "8.3.1",
|
||||
"uuid": "8.3.2",
|
||||
"v-debounce": "0.1.2",
|
||||
"vanilla-tilt": "1.7.0",
|
||||
"vue": "3.0.3",
|
||||
"vue-color": "2.7.1",
|
||||
"vue-i18n": "9.0.0-beta.7",
|
||||
"vue": "3.0.5",
|
||||
"vue-color": "2.8.1",
|
||||
"vue-json-pretty": "1.7.1",
|
||||
"vue-loader": "16.0.0",
|
||||
"vue-prism-editor": "2.0.0-alpha.2",
|
||||
"vue-router": "4.0.0-rc.6",
|
||||
"vue-router": "4.0.1",
|
||||
"vue-style-loader": "4.1.2",
|
||||
"vuedraggable": "4.0.1",
|
||||
"vuex": "4.0.0-rc.2",
|
||||
"vuex-persistedstate": "3.1.0",
|
||||
"web-push": "3.4.4",
|
||||
"webpack": "5.9.0",
|
||||
"webpack-cli": "4.2.0",
|
||||
"websocket": "1.0.32",
|
||||
"ws": "7.4.0",
|
||||
"webpack": "5.13.0",
|
||||
"webpack-cli": "4.3.1",
|
||||
"websocket": "1.0.33",
|
||||
"ws": "7.4.2",
|
||||
"xev": "2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "4.2.11",
|
||||
"@types/chai": "4.2.14",
|
||||
"@types/fluent-ffmpeg": "2.1.16",
|
||||
"chai": "4.2.0",
|
||||
"cross-env": "7.0.2"
|
||||
"cross-env": "7.0.3"
|
||||
}
|
||||
}
|
||||
|
2
src/client/@types/global.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
declare const _LANGS_: string[];
|
||||
declare const _LANGS_: string[][];
|
||||
declare const _VERSION_: string;
|
||||
declare const _ENV_: string;
|
||||
declare const _DEV_: boolean;
|
||||
|
4
src/client/@types/vue.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
declare module '*.vue' {
|
||||
import { defineComponent } from 'vue';
|
||||
const component: ReturnType<typeof defineComponent>;
|
||||
import type { DefineComponent } from 'vue';
|
||||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
|
12
src/client/@types/vuex-shim.d.ts
vendored
@ -1,12 +0,0 @@
|
||||
import { ComponentCustomProperties } from 'vue';
|
||||
import { Store } from 'vuex';
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface State {
|
||||
}
|
||||
|
||||
interface ComponentCustomProperties {
|
||||
$store: Store<State>;
|
||||
}
|
||||
}
|
85
src/client/account.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { reactive } from 'vue';
|
||||
import { apiUrl } from '@/config';
|
||||
import { waiting } from '@/os';
|
||||
|
||||
// TODO: 他のタブと永続化されたstateを同期
|
||||
|
||||
type Account = {
|
||||
id: string;
|
||||
token: string;
|
||||
};
|
||||
|
||||
const data = localStorage.getItem('account');
|
||||
|
||||
// TODO: 外部からはreadonlyに
|
||||
export const $i = data ? reactive(JSON.parse(data) as Account) : null;
|
||||
|
||||
export function signout() {
|
||||
localStorage.removeItem('account');
|
||||
document.cookie = `igi=; path=/`;
|
||||
location.href = '/';
|
||||
}
|
||||
|
||||
export function getAccounts() {
|
||||
const accountsData = localStorage.getItem('accounts');
|
||||
const accounts: { id: Account['id'], token: Account['token'] }[] = accountsData ? JSON.parse(accountsData) : [];
|
||||
return accounts;
|
||||
}
|
||||
|
||||
export function addAccount(id: Account['id'], token: Account['token']) {
|
||||
const accounts = getAccounts();
|
||||
if (!accounts.some(x => x.id === id)) {
|
||||
localStorage.setItem('accounts', JSON.stringify(accounts.concat([{ id, token }])));
|
||||
}
|
||||
}
|
||||
|
||||
function fetchAccount(token): Promise<Account> {
|
||||
return new Promise((done, fail) => {
|
||||
// Fetch user
|
||||
fetch(`${apiUrl}/i`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
i: token
|
||||
})
|
||||
})
|
||||
.then(res => {
|
||||
// When failed to authenticate user
|
||||
if (res.status !== 200 && res.status < 500) {
|
||||
return signout();
|
||||
}
|
||||
|
||||
// Parse response
|
||||
res.json().then(i => {
|
||||
i.token = token;
|
||||
done(i);
|
||||
});
|
||||
})
|
||||
.catch(fail);
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAccount(data) {
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
$i[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
export function refreshAccount() {
|
||||
fetchAccount($i.token).then(updateAccount);
|
||||
}
|
||||
|
||||
export async function login(token: Account['token']) {
|
||||
waiting();
|
||||
if (_DEV_) console.log('logging as token ', token);
|
||||
const me = await fetchAccount(token);
|
||||
localStorage.setItem('account', JSON.stringify(me));
|
||||
addAccount(me.id, token);
|
||||
location.reload();
|
||||
}
|
||||
|
||||
// このファイルに書きたくないけどここに書かないと何故かVeturが認識しない
|
||||
declare module '@vue/runtime-core' {
|
||||
interface ComponentCustomProperties {
|
||||
$i: typeof $i;
|
||||
}
|
||||
}
|
BIN
src/client/assets/about-icon.png
Normal file
After Width: | Height: | Size: 20 KiB |
7
src/client/assets/misskey.svg
Normal file
After Width: | Height: | Size: 9.2 KiB |
@ -1,34 +0,0 @@
|
||||
// 常にメモリにロードしておく必要がないような設定情報を保管するストレージ
|
||||
|
||||
const PREFIX = 'miux:';
|
||||
|
||||
export const defaultDeviceSettings = {
|
||||
sound_masterVolume: 0.3,
|
||||
sound_note: { type: 'syuilo/down', volume: 1 },
|
||||
sound_noteMy: { type: 'syuilo/up', volume: 1 },
|
||||
sound_notification: { type: 'syuilo/pope2', volume: 1 },
|
||||
sound_chat: { type: 'syuilo/pope1', volume: 1 },
|
||||
sound_chatBg: { type: 'syuilo/waon', volume: 1 },
|
||||
sound_antenna: { type: 'syuilo/triple', volume: 1 },
|
||||
sound_channel: { type: 'syuilo/square-pico', volume: 1 },
|
||||
sound_reversiPutBlack: { type: 'syuilo/kick', volume: 0.3 },
|
||||
sound_reversiPutWhite: { type: 'syuilo/snare', volume: 0.3 },
|
||||
};
|
||||
|
||||
export const device = {
|
||||
get<T extends keyof typeof defaultDeviceSettings>(key: T): typeof defaultDeviceSettings[T] {
|
||||
// TODO: indexedDBにする
|
||||
// ただしその際はnullチェックではなくキー存在チェックにしないとダメ
|
||||
// (indexedDBはnullを保存できるため、ユーザーが意図してnullを格納した可能性がある)
|
||||
const value = localStorage.getItem(PREFIX + key);
|
||||
if (value == null) {
|
||||
return defaultDeviceSettings[key];
|
||||
} else {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
},
|
||||
|
||||
set(key: keyof typeof defaultDeviceSettings, value: any): any {
|
||||
localStorage.setItem(PREFIX + key, JSON.stringify(value));
|
||||
},
|
||||
};
|
@ -2,24 +2,24 @@
|
||||
<XWindow ref="window" :initial-width="400" :initial-height="500" :can-resize="true" @closed="$emit('closed')">
|
||||
<template #header>
|
||||
<Fa :icon="faExclamationCircle" style="margin-right: 0.5em;"/>
|
||||
<i18n-t keypath="reportAbuseOf" tag="span">
|
||||
<I18n :src="$ts.reportAbuseOf" tag="span">
|
||||
<template #name>
|
||||
<b><MkAcct :user="user"/></b>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</I18n>
|
||||
</template>
|
||||
<div class="dpvffvvy">
|
||||
<div class="_section">
|
||||
<div class="_content">
|
||||
<MkTextarea v-model:value="comment">
|
||||
<span>{{ $t('details') }}</span>
|
||||
<template #desc>{{ $t('fillAbuseReportDescription') }}</template>
|
||||
<span>{{ $ts.details }}</span>
|
||||
<template #desc>{{ $ts.fillAbuseReportDescription }}</template>
|
||||
</MkTextarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_section">
|
||||
<div class="_content">
|
||||
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $t('send') }}</MkButton>
|
||||
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $ts.send }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,7 +69,7 @@ export default defineComponent({
|
||||
}, undefined, res => {
|
||||
os.dialog({
|
||||
type: 'success',
|
||||
text: this.$t('abuseReported')
|
||||
text: this.$ts.abuseReported
|
||||
});
|
||||
this.$refs.window.close();
|
||||
});
|
||||
|
@ -116,16 +116,6 @@ export default defineComponent({
|
||||
}
|
||||
};
|
||||
update();
|
||||
|
||||
this.$store.subscribe((mutation, state) => {
|
||||
if (mutation.type !== 'device/set') return;
|
||||
|
||||
if (mutation?.payload?.key !== 'theme') return;
|
||||
|
||||
setTimeout(() => {
|
||||
this.computedStyle = getComputedStyle(document.documentElement);
|
||||
}, 250);
|
||||
});
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
|
@ -8,7 +8,7 @@
|
||||
</span>
|
||||
<span class="username">@{{ acct(user) }}</span>
|
||||
</li>
|
||||
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $t('selectUser') }}</li>
|
||||
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $ts.selectUser }}</li>
|
||||
</ol>
|
||||
<ol class="hashtags" ref="suggests" v-if="hashtags.length > 0">
|
||||
<li v-for="hashtag in hashtags" @click="complete(type, hashtag)" @keydown="onKeydown" tabindex="-1">
|
||||
@ -17,8 +17,8 @@
|
||||
</ol>
|
||||
<ol class="emojis" ref="suggests" v-if="emojis.length > 0">
|
||||
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
|
||||
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
|
||||
<span class="emoji" v-else-if="!useOsNativeEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span>
|
||||
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
|
||||
<span class="emoji" v-else-if="!$store.state.useOsNativeEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span>
|
||||
<span class="emoji" v-else>{{ emoji.emoji }}</span>
|
||||
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
|
||||
<span class="alias" v-if="emoji.aliasOf">({{ emoji.aliasOf }})</span>
|
||||
@ -128,12 +128,6 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
useOsNativeEmojis(): boolean {
|
||||
return this.$store.state.device.useOsNativeEmojis;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
showing() {
|
||||
if (!this.showing) {
|
||||
@ -151,7 +145,7 @@ export default defineComponent({
|
||||
this.setPosition();
|
||||
|
||||
//#region Construct Emoji DB
|
||||
const customEmojis = this.$store.state.instance.meta.emojis;
|
||||
const customEmojis = this.$instance.emojis;
|
||||
const emojiDefinitions: EmojiDef[] = [];
|
||||
|
||||
for (const x of customEmojis) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<span v-if="!available">{{ $t('waiting') }}<MkEllipsis/></span>
|
||||
<span v-if="!available">{{ $ts.waiting }}<MkEllipsis/></span>
|
||||
<div ref="captcha"></div>
|
||||
</div>
|
||||
</template>
|
||||
@ -28,7 +28,6 @@ declare global {
|
||||
interface Window extends CaptchaContainer {
|
||||
}
|
||||
}
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -101,7 +100,7 @@ export default defineComponent({
|
||||
if (this.captcha.render && this.$refs.captcha instanceof Element) {
|
||||
this.captcha.render(this.$refs.captcha, {
|
||||
sitekey: this.sitekey,
|
||||
theme: this.$store.state.device.darkMode ? 'dark' : 'light',
|
||||
theme: this.$store.state.darkMode ? 'dark' : 'light',
|
||||
callback: this.callback,
|
||||
'expired-callback': this.callback,
|
||||
'error-callback': this.callback,
|
||||
|
@ -6,14 +6,14 @@
|
||||
>
|
||||
<template v-if="!wait">
|
||||
<template v-if="isFollowing">
|
||||
<span v-if="full">{{ $t('unfollow') }}</span><Fa :icon="faMinus"/>
|
||||
<span v-if="full">{{ $ts.unfollow }}</span><Fa :icon="faMinus"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-if="full">{{ $t('follow') }}</span><Fa :icon="faPlus"/>
|
||||
<span v-if="full">{{ $ts.follow }}</span><Fa :icon="faPlus"/>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse fixed-width/>
|
||||
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse fixed-width/>
|
||||
</template>
|
||||
</button>
|
||||
</template>
|
||||
|
@ -6,19 +6,19 @@
|
||||
<div class="status">
|
||||
<div>
|
||||
<Fa :icon="faUsers" fixed-width/>
|
||||
<i18n-t keypath="_channel.usersCount" tag="span" style="margin-left: 4px;">
|
||||
<I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;">
|
||||
<template #n>
|
||||
<b>{{ channel.usersCount }}</b>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</I18n>
|
||||
</div>
|
||||
<div>
|
||||
<Fa :icon="faPencilAlt" fixed-width/>
|
||||
<i18n-t keypath="_channel.notesCount" tag="span" style="margin-left: 4px;">
|
||||
<I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;">
|
||||
<template #n>
|
||||
<b>{{ channel.notesCount }}</b>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</I18n>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -27,7 +27,7 @@
|
||||
</article>
|
||||
<footer>
|
||||
<span v-if="channel.lastNotedAt">
|
||||
{{ $t('updatedAt') }}: <MkTime :time="channel.lastNotedAt"/>
|
||||
{{ $ts.updatedAt }}: <MkTime :time="channel.lastNotedAt"/>
|
||||
</span>
|
||||
</footer>
|
||||
</MkA>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<button class="nrvgflfu _button" @click="toggle">
|
||||
<b>{{ value ? $t('_cw.hide') : $t('_cw.show') }}</b>
|
||||
<b>{{ value ? $ts._cw.hide : $ts._cw.show }}</b>
|
||||
<span v-if="!value">{{ label }}</span>
|
||||
</button>
|
||||
</template>
|
||||
@ -27,7 +27,7 @@ export default defineComponent({
|
||||
return concat([
|
||||
this.note.text ? [this.$t('_cw.chars', { count: length(this.note.text) })] : [],
|
||||
this.note.files && this.note.files.length !== 0 ? [this.$t('_cw.files', { count: this.note.files.length }) ] : [],
|
||||
this.note.poll != null ? [this.$t('poll')] : []
|
||||
this.note.poll != null ? [this.$ts.poll] : []
|
||||
] as string[][]).join(' / ');
|
||||
}
|
||||
},
|
||||
|
@ -1,20 +1,7 @@
|
||||
<template>
|
||||
<transition-group class="sqadhkmv _list_" name="list" tag="div" :data-direction="direction" :data-reversed="reversed ? 'true' : 'false'">
|
||||
<template v-for="(item, i) in items">
|
||||
<slot :item="item"></slot>
|
||||
<div class="separator" v-if="showDate(i, item)" :key="item.id + '_date'">
|
||||
<p class="date">
|
||||
<span><Fa class="icon" :icon="faAngleUp"/>{{ getDateText(item.createdAt) }}</span>
|
||||
<span>{{ getDateText(items[i + 1].createdAt) }}<Fa class="icon" :icon="faAngleDown"/></span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</transition-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, h, TransitionGroup } from 'vue';
|
||||
import { faAngleUp, faAngleDown } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -34,36 +21,72 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
faAngleUp, faAngleDown
|
||||
};
|
||||
methods: {
|
||||
focus() {
|
||||
this.$slots.default[0].elm.focus();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getDateText(time: string) {
|
||||
render() {
|
||||
const getDateText = (time: string) => {
|
||||
const date = new Date(time).getDate();
|
||||
const month = new Date(time).getMonth() + 1;
|
||||
return this.$t('monthAndDay', {
|
||||
month: month.toString(),
|
||||
day: date.toString()
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
showDate(i, item) {
|
||||
return (
|
||||
return h(this.$store.state.animation ? TransitionGroup : 'div', this.$store.state.animation ? {
|
||||
class: 'sqadhkmv _list_',
|
||||
name: 'list',
|
||||
tag: 'div',
|
||||
'data-direction': this.direction,
|
||||
'data-reversed': this.reversed ? 'true' : 'false',
|
||||
} : {
|
||||
class: 'sqadhkmv _list_',
|
||||
}, this.items.map((item, i) => {
|
||||
const el = this.$slots.default({
|
||||
item: item
|
||||
})[0];
|
||||
if (el.key == null && item.id) el.key = item.id;
|
||||
|
||||
if (
|
||||
i != this.items.length - 1 &&
|
||||
new Date(item.createdAt).getDate() != new Date(this.items[i + 1].createdAt).getDate() &&
|
||||
!item._prId_ &&
|
||||
!this.items[i + 1]._prId_ &&
|
||||
!item._featuredId_ &&
|
||||
!this.items[i + 1]._featuredId_);
|
||||
},
|
||||
!this.items[i + 1]._featuredId_
|
||||
) {
|
||||
const separator = h('div', {
|
||||
class: 'separator',
|
||||
key: item.id + ':separator',
|
||||
}, h('p', {
|
||||
class: 'date'
|
||||
}, [
|
||||
h('span', [
|
||||
h(FontAwesomeIcon, {
|
||||
class: 'icon',
|
||||
icon: faAngleUp,
|
||||
}),
|
||||
getDateText(item.createdAt)
|
||||
]),
|
||||
h('span', [
|
||||
getDateText(this.items[i + 1].createdAt),
|
||||
h(FontAwesomeIcon, {
|
||||
class: 'icon',
|
||||
icon: faAngleDown,
|
||||
})
|
||||
])
|
||||
]));
|
||||
|
||||
focus() {
|
||||
this.$slots.default[0].elm.focus();
|
||||
}
|
||||
}
|
||||
return [el, separator];
|
||||
} else {
|
||||
return el;
|
||||
}
|
||||
}));
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -97,7 +120,7 @@ export default defineComponent({
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style lang="scss">
|
||||
.sqadhkmv {
|
||||
> .separator {
|
||||
text-align: center;
|
||||
|
@ -26,8 +26,8 @@
|
||||
</template>
|
||||
</MkSelect>
|
||||
<div class="buttons" v-if="(showOkButton || showCancelButton) && !actions">
|
||||
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $t('ok') : $t('gotIt') }}</MkButton>
|
||||
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $t('cancel') }}</MkButton>
|
||||
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $ts.ok : $ts.gotIt }}</MkButton>
|
||||
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $ts.cancel }}</MkButton>
|
||||
</div>
|
||||
<div class="buttons" v-if="actions">
|
||||
<MkButton v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</MkButton>
|
||||
|
@ -27,6 +27,7 @@ import {
|
||||
faFilm
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import ImgWithBlurhash from './img-with-blurhash.vue';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -89,12 +90,12 @@ export default defineComponent({
|
||||
},
|
||||
mounted() {
|
||||
const audioTag = this.$refs.volumectrl as HTMLAudioElement;
|
||||
if (audioTag) audioTag.volume = this.$store.state.device.mediaVolume;
|
||||
if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume');
|
||||
},
|
||||
methods: {
|
||||
volumechange() {
|
||||
const audioTag = this.$refs.volumectrl as HTMLAudioElement;
|
||||
this.$store.commit('device/set', { key: 'mediaVolume', value: audioTag.volume });
|
||||
ColdDeviceStorage.set('mediaVolume', audioTag.volume);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -10,7 +10,7 @@
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<template #header>
|
||||
{{ multiple ? ((type === 'file') ? $t('selectFiles') : $t('selectFolders')) : ((type === 'file') ? $t('selectFile') : $t('selectFolder')) }}
|
||||
{{ multiple ? ((type === 'file') ? $ts.selectFiles : $ts.selectFolders) : ((type === 'file') ? $ts.selectFile : $ts.selectFolder) }}
|
||||
<span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ number(selected.length) }})</span>
|
||||
</template>
|
||||
<XDrive :multiple="multiple" @changeSelection="onChangeSelection" @selected="ok()" :select="type"/>
|
||||
|
@ -6,7 +6,7 @@
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<template #header>
|
||||
{{ $t('drive') }}
|
||||
{{ $ts.drive }}
|
||||
</template>
|
||||
<XDrive :initial-folder="initialFolder"/>
|
||||
</XWindow>
|
||||
|
@ -8,17 +8,17 @@
|
||||
@dragend="onDragend"
|
||||
:title="title"
|
||||
>
|
||||
<div class="label" v-if="$store.state.i.avatarId == file.id">
|
||||
<div class="label" v-if="$i.avatarId == file.id">
|
||||
<img src="/assets/label.svg"/>
|
||||
<p>{{ $t('avatar') }}</p>
|
||||
<p>{{ $ts.avatar }}</p>
|
||||
</div>
|
||||
<div class="label" v-if="$store.state.i.bannerId == file.id">
|
||||
<div class="label" v-if="$i.bannerId == file.id">
|
||||
<img src="/assets/label.svg"/>
|
||||
<p>{{ $t('banner') }}</p>
|
||||
<p>{{ $ts.banner }}</p>
|
||||
</div>
|
||||
<div class="label red" v-if="file.isSensitive">
|
||||
<img src="/assets/label-red.svg"/>
|
||||
<p>{{ $t('nsfw') }}</p>
|
||||
<p>{{ $ts.nsfw }}</p>
|
||||
</div>
|
||||
|
||||
<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/>
|
||||
@ -36,7 +36,7 @@ import { faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons';
|
||||
import { faDownload, faLink, faICursor, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import MkDriveFileThumbnail from './drive-file-thumbnail.vue';
|
||||
import bytes from '../filters/bytes';
|
||||
import bytes from '@/filters/bytes';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
@ -82,26 +82,26 @@ export default defineComponent({
|
||||
methods: {
|
||||
getMenu() {
|
||||
return [{
|
||||
text: this.$t('rename'),
|
||||
text: this.$ts.rename,
|
||||
icon: faICursor,
|
||||
action: this.rename
|
||||
}, {
|
||||
text: this.file.isSensitive ? this.$t('unmarkAsSensitive') : this.$t('markAsSensitive'),
|
||||
text: this.file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive,
|
||||
icon: this.file.isSensitive ? faEye : faEyeSlash,
|
||||
action: this.toggleSensitive
|
||||
}, null, {
|
||||
text: this.$t('copyUrl'),
|
||||
text: this.$ts.copyUrl,
|
||||
icon: faLink,
|
||||
action: this.copyUrl
|
||||
}, {
|
||||
type: 'a',
|
||||
href: this.file.url,
|
||||
target: '_blank',
|
||||
text: this.$t('download'),
|
||||
text: this.$ts.download,
|
||||
icon: faDownload,
|
||||
download: this.file.name
|
||||
}, null, {
|
||||
text: this.$t('delete'),
|
||||
text: this.$ts.delete,
|
||||
icon: faTrashAlt,
|
||||
danger: true,
|
||||
action: this.deleteFile
|
||||
@ -137,9 +137,9 @@ export default defineComponent({
|
||||
|
||||
rename() {
|
||||
os.dialog({
|
||||
title: this.$t('renameFile'),
|
||||
title: this.$ts.renameFile,
|
||||
input: {
|
||||
placeholder: this.$t('inputNewFileName'),
|
||||
placeholder: this.$ts.inputNewFileName,
|
||||
default: this.file.name,
|
||||
allowEmpty: false
|
||||
}
|
||||
|
@ -19,8 +19,8 @@
|
||||
<template v-if="!hover"><Fa :icon="faFolder" fixed-width/></template>
|
||||
{{ folder.name }}
|
||||
</p>
|
||||
<p class="upload" v-if="$store.state.settings.uploadFolder == folder.id">
|
||||
{{ $t('uploadFolder') }}
|
||||
<p class="upload" v-if="$store.state.uploadFolder == folder.id">
|
||||
{{ $ts.uploadFolder }}
|
||||
</p>
|
||||
<button v-if="selectMode" class="checkbox _button" :class="{ checked: isSelected }" @click.prevent.stop="checkboxClicked"></button>
|
||||
</div>
|
||||
@ -155,14 +155,14 @@ export default defineComponent({
|
||||
switch (err) {
|
||||
case 'detected-circular-definition':
|
||||
os.dialog({
|
||||
title: this.$t('unableToProcess'),
|
||||
text: this.$t('circularReferenceFolder')
|
||||
title: this.$ts.unableToProcess,
|
||||
text: this.$ts.circularReferenceFolder
|
||||
});
|
||||
break;
|
||||
default:
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('somethingHappened')
|
||||
text: this.$ts.somethingHappened
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -195,9 +195,9 @@ export default defineComponent({
|
||||
|
||||
rename() {
|
||||
os.dialog({
|
||||
title: this.$t('renameFolder'),
|
||||
title: this.$ts.renameFolder,
|
||||
input: {
|
||||
placeholder: this.$t('inputNewFolderName'),
|
||||
placeholder: this.$ts.inputNewFolderName,
|
||||
default: this.folder.name
|
||||
}
|
||||
}).then(({ canceled, result: name }) => {
|
||||
@ -213,40 +213,34 @@ export default defineComponent({
|
||||
os.api('drive/folders/delete', {
|
||||
folderId: this.folder.id
|
||||
}).then(() => {
|
||||
if (this.$store.state.settings.uploadFolder === this.folder.id) {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'uploadFolder',
|
||||
value: null
|
||||
});
|
||||
if (this.$store.state.uploadFolder === this.folder.id) {
|
||||
this.$store.set('uploadFolder', null);
|
||||
}
|
||||
}).catch(err => {
|
||||
switch(err.id) {
|
||||
case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
title: this.$t('unableToDelete'),
|
||||
text: this.$t('hasChildFilesOrFolders')
|
||||
title: this.$ts.unableToDelete,
|
||||
text: this.$ts.hasChildFilesOrFolders
|
||||
});
|
||||
break;
|
||||
default:
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('unableToDelete')
|
||||
text: this.$ts.unableToDelete
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setAsUploadFolder() {
|
||||
this.$store.dispatch('settings/set', {
|
||||
key: 'uploadFolder',
|
||||
value: this.folder.id
|
||||
});
|
||||
this.$store.set('uploadFolder', this.folder.id);
|
||||
},
|
||||
|
||||
onContextmenu(e) {
|
||||
os.contextMenu([{
|
||||
text: this.$t('openInWindow'),
|
||||
text: this.$ts.openInWindow,
|
||||
icon: faWindowRestore,
|
||||
action: () => {
|
||||
os.popup(import('./drive-window.vue'), {
|
||||
@ -255,11 +249,11 @@ export default defineComponent({
|
||||
}, 'closed');
|
||||
}
|
||||
}, null, {
|
||||
text: this.$t('rename'),
|
||||
text: this.$ts.rename,
|
||||
icon: faICursor,
|
||||
action: this.rename
|
||||
}, null, {
|
||||
text: this.$t('delete'),
|
||||
text: this.$ts.delete,
|
||||
icon: faTrashAlt,
|
||||
danger: true,
|
||||
action: this.deleteFolder
|
||||
|
@ -8,7 +8,7 @@
|
||||
@drop.stop="onDrop"
|
||||
>
|
||||
<i v-if="folder == null"><Fa :icon="faCloud"/></i>
|
||||
<span>{{ folder == null ? $t('drive') : folder.name }}</span>
|
||||
<span>{{ folder == null ? $ts.drive : folder.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -17,25 +17,25 @@
|
||||
@dragenter="onDragenter"
|
||||
@dragleave="onDragleave"
|
||||
@drop.prevent.stop="onDrop"
|
||||
@contextmenu="onContextmenu"
|
||||
@contextmenu.stop="onContextmenu"
|
||||
>
|
||||
<div class="contents" ref="contents">
|
||||
<div class="folders" ref="foldersContainer" v-show="folders.length > 0">
|
||||
<XFolder v-for="f in folders" :key="f.id" class="folder" :folder="f" :select-mode="select === 'folder'" :is-selected="selectedFolders.some(x => x.id === f.id)" @chosen="chooseFolder"/>
|
||||
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
|
||||
<div class="padding" v-for="(n, i) in 16" :key="i"></div>
|
||||
<MkButton ref="moreFolders" v-if="moreFolders">{{ $t('loadMore') }}</MkButton>
|
||||
<MkButton ref="moreFolders" v-if="moreFolders">{{ $ts.loadMore }}</MkButton>
|
||||
</div>
|
||||
<div class="files" ref="filesContainer" v-show="files.length > 0">
|
||||
<XFile v-for="file in files" :key="file.id" class="file" :file="file" :select-mode="select === 'file'" :is-selected="selectedFiles.some(x => x.id === file.id)" @chosen="chooseFile"/>
|
||||
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
|
||||
<div class="padding" v-for="(n, i) in 16" :key="i"></div>
|
||||
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $t('loadMore') }}</MkButton>
|
||||
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $ts.loadMore }}</MkButton>
|
||||
</div>
|
||||
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
|
||||
<p v-if="draghover">{{ $t('empty-draghover') }}</p>
|
||||
<p v-if="!draghover && folder == null"><strong>{{ $t('emptyDrive') }}</strong><br/>{{ $t('empty-drive-description') }}</p>
|
||||
<p v-if="!draghover && folder != null">{{ $t('emptyFolder') }}</p>
|
||||
<p v-if="!draghover && folder == null"><strong>{{ $ts.emptyDrive }}</strong><br/>{{ $t('empty-drive-description') }}</p>
|
||||
<p v-if="!draghover && folder != null">{{ $ts.emptyFolder }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<MkLoading v-if="fetching"/>
|
||||
@ -136,7 +136,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.$store.state.device.enableInfiniteScroll && this.$refs.loadMoreFiles) {
|
||||
if (this.$store.state.enableInfiniteScroll && this.$refs.loadMoreFiles) {
|
||||
this.$nextTick(() => {
|
||||
this.ilFilesObserver.observe((this.$refs.loadMoreFiles as Vue).$el)
|
||||
});
|
||||
@ -159,7 +159,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
activated() {
|
||||
if (this.$store.state.device.enableInfiniteScroll) {
|
||||
if (this.$store.state.enableInfiniteScroll) {
|
||||
this.$nextTick(() => {
|
||||
this.ilFilesObserver.observe((this.$refs.loadMoreFiles as Vue).$el)
|
||||
});
|
||||
@ -277,14 +277,14 @@ export default defineComponent({
|
||||
switch (err) {
|
||||
case 'detected-circular-definition':
|
||||
os.dialog({
|
||||
title: this.$t('unableToProcess'),
|
||||
text: this.$t('circularReferenceFolder')
|
||||
title: this.$ts.unableToProcess,
|
||||
text: this.$ts.circularReferenceFolder
|
||||
});
|
||||
break;
|
||||
default:
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('somethingHappened')
|
||||
text: this.$ts.somethingHappened
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -298,9 +298,9 @@ export default defineComponent({
|
||||
|
||||
urlUpload() {
|
||||
os.dialog({
|
||||
title: this.$t('uploadFromUrl'),
|
||||
title: this.$ts.uploadFromUrl,
|
||||
input: {
|
||||
placeholder: this.$t('uploadFromUrlDescription')
|
||||
placeholder: this.$ts.uploadFromUrlDescription
|
||||
}
|
||||
}).then(({ canceled, result: url }) => {
|
||||
if (canceled) return;
|
||||
@ -310,17 +310,17 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
os.dialog({
|
||||
title: this.$t('uploadFromUrlRequested'),
|
||||
text: this.$t('uploadFromUrlMayTakeTime')
|
||||
title: this.$ts.uploadFromUrlRequested,
|
||||
text: this.$ts.uploadFromUrlMayTakeTime
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
createFolder() {
|
||||
os.dialog({
|
||||
title: this.$t('createFolder'),
|
||||
title: this.$ts.createFolder,
|
||||
input: {
|
||||
placeholder: this.$t('folderName')
|
||||
placeholder: this.$ts.folderName
|
||||
}
|
||||
}).then(({ canceled, result: name }) => {
|
||||
if (canceled) return;
|
||||
@ -335,9 +335,9 @@ export default defineComponent({
|
||||
|
||||
renameFolder(folder) {
|
||||
os.dialog({
|
||||
title: this.$t('renameFolder'),
|
||||
title: this.$ts.renameFolder,
|
||||
input: {
|
||||
placeholder: this.$t('inputNewFolderName'),
|
||||
placeholder: this.$ts.inputNewFolderName,
|
||||
default: folder.name
|
||||
}
|
||||
}).then(({ canceled, result: name }) => {
|
||||
@ -363,14 +363,14 @@ export default defineComponent({
|
||||
case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
title: this.$t('unableToDelete'),
|
||||
text: this.$t('hasChildFilesOrFolders')
|
||||
title: this.$ts.unableToDelete,
|
||||
text: this.$ts.hasChildFilesOrFolders
|
||||
});
|
||||
break;
|
||||
default:
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('unableToDelete')
|
||||
text: this.$ts.unableToDelete
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -602,29 +602,29 @@ export default defineComponent({
|
||||
|
||||
getMenu() {
|
||||
return [{
|
||||
text: this.$t('addFile'),
|
||||
text: this.$ts.addFile,
|
||||
type: 'label'
|
||||
}, {
|
||||
text: this.$t('upload'),
|
||||
text: this.$ts.upload,
|
||||
icon: faUpload,
|
||||
action: () => { this.selectLocalFile(); }
|
||||
}, {
|
||||
text: this.$t('fromUrl'),
|
||||
text: this.$ts.fromUrl,
|
||||
icon: faLink,
|
||||
action: () => { this.urlUpload(); }
|
||||
}, null, {
|
||||
text: this.folder ? this.folder.name : this.$t('drive'),
|
||||
text: this.folder ? this.folder.name : this.$ts.drive,
|
||||
type: 'label'
|
||||
}, this.folder ? {
|
||||
text: this.$t('renameFolder'),
|
||||
text: this.$ts.renameFolder,
|
||||
icon: faICursor,
|
||||
action: () => { this.renameFolder(this.folder); }
|
||||
} : undefined, this.folder ? {
|
||||
text: this.$t('deleteFolder'),
|
||||
text: this.$ts.deleteFolder,
|
||||
icon: faTrashAlt,
|
||||
action: () => { this.deleteFolder(this.folder); }
|
||||
} : undefined, {
|
||||
text: this.$t('createFolder'),
|
||||
text: this.$ts.createFolder,
|
||||
icon: faFolderPlus,
|
||||
action: () => { this.createFolder(); }
|
||||
}];
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="omfetrab _popup" :class="['w' + width, 'h' + height, { big }]">
|
||||
<input ref="search" class="search" :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$t('search')" @paste.stop="paste" @keyup.enter="done()">
|
||||
<div class="emojis">
|
||||
<input ref="search" class="search" :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$ts.search" @paste.stop="paste" @keyup.enter="done()">
|
||||
<div class="emojis" ref="emojis">
|
||||
<section class="result">
|
||||
<div v-if="searchResultCustom.length > 0">
|
||||
<button v-for="emoji in searchResultCustom"
|
||||
@ -13,7 +13,7 @@
|
||||
tabindex="0"
|
||||
>
|
||||
<MkEmoji v-if="emoji.char != null" :emoji="emoji.char"/>
|
||||
<img v-else :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
|
||||
<img v-else :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="searchResultUnicode.length > 0">
|
||||
@ -43,9 +43,9 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header class="_acrylic"><Fa :icon="faClock" fixed-width/> {{ $t('recentUsed') }}</header>
|
||||
<header class="_acrylic"><Fa :icon="faClock" fixed-width/> {{ $ts.recentUsed }}</header>
|
||||
<div>
|
||||
<button v-for="emoji in $store.state.device.recentlyUsedEmojis"
|
||||
<button v-for="emoji in $store.state.recentlyUsedEmojis"
|
||||
class="_button"
|
||||
@click="chosen(emoji, $event)"
|
||||
:key="emoji"
|
||||
@ -59,7 +59,7 @@
|
||||
</div>
|
||||
|
||||
<section v-for="category in customEmojiCategories" :key="'custom:' + category" class="custom">
|
||||
<header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $t('other') }}</header>
|
||||
<header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $ts.other }}</header>
|
||||
<div v-if="visibleCategories[category]">
|
||||
<button v-for="emoji in customEmojis.filter(e => e.category === category)"
|
||||
class="_button"
|
||||
@ -67,7 +67,7 @@
|
||||
@click="chosen(emoji, $event)"
|
||||
:key="emoji.name"
|
||||
>
|
||||
<img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
|
||||
<img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
@ -100,6 +100,7 @@ import MkModal from '@/components/ui/modal.vue';
|
||||
import Particle from '@/components/particle.vue';
|
||||
import * as os from '@/os';
|
||||
import { isDeviceTouch } from '../scripts/is-device-touch';
|
||||
import { emojiCategories } from '@/instance';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -125,12 +126,12 @@ export default defineComponent({
|
||||
return {
|
||||
emojilist: markRaw(emojilist),
|
||||
getStaticImageUrl,
|
||||
pinned: this.$store.state.settings.reactions,
|
||||
width: this.asReactionPicker ? this.$store.state.device.reactionPickerWidth : 3,
|
||||
height: this.asReactionPicker ? this.$store.state.device.reactionPickerHeight : 2,
|
||||
pinned: this.$store.state.reactions,
|
||||
width: this.asReactionPicker ? this.$store.state.reactionPickerWidth : 3,
|
||||
height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2,
|
||||
big: this.asReactionPicker ? isDeviceTouch : false,
|
||||
customEmojiCategories: this.$store.getters['instance/emojiCategories'],
|
||||
customEmojis: this.$store.state.instance.meta.emojis,
|
||||
customEmojiCategories: emojiCategories,
|
||||
customEmojis: this.$instance.emojis,
|
||||
visibleCategories: {},
|
||||
q: null,
|
||||
searchResultCustom: [],
|
||||
@ -179,6 +180,8 @@ export default defineComponent({
|
||||
|
||||
watch: {
|
||||
q() {
|
||||
this.$refs.emojis.scrollTop = 0;
|
||||
|
||||
if (this.q == null || this.q === '') {
|
||||
this.searchResultCustom = [];
|
||||
this.searchResultUnicode = [];
|
||||
@ -346,10 +349,10 @@ export default defineComponent({
|
||||
|
||||
// 最近使った絵文字更新
|
||||
if (!this.pinned.includes(key)) {
|
||||
let recents = this.$store.state.device.recentlyUsedEmojis;
|
||||
let recents = this.$store.state.recentlyUsedEmojis;
|
||||
recents = recents.filter((e: any) => e !== key);
|
||||
recents.unshift(key);
|
||||
this.$store.commit('device/set', { key: 'recentlyUsedEmojis', value: recents.splice(0, 16) });
|
||||
this.$store.set('recentlyUsedEmojis', recents.splice(0, 16));
|
||||
}
|
||||
},
|
||||
|
||||
|
34
src/client/components/featured-photos.vue
Normal file
@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div class="xfbouadm" v-if="meta" :style="{ backgroundImage: `url(${ meta.backgroundImageUrl })` }">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
meta: null,
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
os.api('meta', { detail: true }).then(meta => {
|
||||
this.meta = meta;
|
||||
});
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.xfbouadm {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
@ -6,23 +6,23 @@
|
||||
>
|
||||
<template v-if="!wait">
|
||||
<template v-if="hasPendingFollowRequestFromYou && user.isLocked">
|
||||
<span v-if="full">{{ $t('followRequestPending') }}</span><Fa :icon="faHourglassHalf"/>
|
||||
<span v-if="full">{{ $ts.followRequestPending }}</span><Fa :icon="faHourglassHalf"/>
|
||||
</template>
|
||||
<template v-else-if="hasPendingFollowRequestFromYou && !user.isLocked"> <!-- つまりリモートフォローの場合。 -->
|
||||
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse/>
|
||||
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse/>
|
||||
</template>
|
||||
<template v-else-if="isFollowing">
|
||||
<span v-if="full">{{ $t('unfollow') }}</span><Fa :icon="faMinus"/>
|
||||
<span v-if="full">{{ $ts.unfollow }}</span><Fa :icon="faMinus"/>
|
||||
</template>
|
||||
<template v-else-if="!isFollowing && user.isLocked">
|
||||
<span v-if="full">{{ $t('followRequest') }}</span><Fa :icon="faPlus"/>
|
||||
<span v-if="full">{{ $ts.followRequest }}</span><Fa :icon="faPlus"/>
|
||||
</template>
|
||||
<template v-else-if="!isFollowing && !user.isLocked">
|
||||
<span v-if="full">{{ $t('follow') }}</span><Fa :icon="faPlus"/>
|
||||
<span v-if="full">{{ $ts.follow }}</span><Fa :icon="faPlus"/>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse fixed-width/>
|
||||
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse fixed-width/>
|
||||
</template>
|
||||
</button>
|
||||
</template>
|
||||
|
@ -15,15 +15,15 @@
|
||||
<FormBase class="xkpnjxcv">
|
||||
<template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
|
||||
<FormInput v-if="form[item].type === 'number'" v-model:value="values[item]" type="number" :step="form[item].step || 1">
|
||||
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
|
||||
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
|
||||
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
|
||||
</FormInput>
|
||||
<FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model:value="values[item]" type="text">
|
||||
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
|
||||
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
|
||||
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
|
||||
</FormInput>
|
||||
<FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model:value="values[item]">
|
||||
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
|
||||
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
|
||||
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
|
||||
</FormTextarea>
|
||||
<FormSwitch v-else-if="form[item].type === 'boolean'" v-model:value="values[item]">
|
||||
@ -31,11 +31,11 @@
|
||||
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
|
||||
</FormSwitch>
|
||||
<FormSelect v-else-if="form[item].type === 'enum'" v-model:value="values[item]">
|
||||
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span></template>
|
||||
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
|
||||
<option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option>
|
||||
</FormSelect>
|
||||
<FormRange v-else-if="form[item].type === 'range'" v-model:value="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
|
||||
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span></template>
|
||||
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
|
||||
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
|
||||
</FormRange>
|
||||
<FormButton v-else-if="form[item].type === 'button'" @click="form[item].action($event, values)">
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
&._formClickable {
|
||||
&:hover {
|
||||
background: var(--panelHighlight);
|
||||
//background: var(--panelHighlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@
|
||||
._formLabel {
|
||||
font-size: 80%;
|
||||
padding: 0 16px 8px 16px;
|
||||
opacity: 0.8;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
@ -21,6 +22,7 @@
|
||||
._formCaption {
|
||||
font-size: 80%;
|
||||
padding: 8px 16px 0 16px;
|
||||
opacity: 0.8;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
@ -44,7 +44,7 @@
|
||||
</datalist>
|
||||
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
|
||||
</div>
|
||||
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
|
||||
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
|
||||
<div class="_formCaption"><slot name="desc"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<slot name="empty"></slot>
|
||||
</div>
|
||||
<FormButton v-show="more" class="button" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary>
|
||||
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
|
||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||
</FormButton>
|
||||
</FormGroup>
|
||||
|
@ -14,7 +14,7 @@
|
||||
@blur="focused = false"
|
||||
></textarea>
|
||||
</div>
|
||||
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
|
||||
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
|
||||
<div class="_formCaption"><slot name="desc"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -10,8 +10,9 @@ import { faExpandAlt, faColumns, faExternalLinkAlt, faLink, faWindowMaximize } f
|
||||
import * as os from '@/os';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import { router } from '@/router';
|
||||
import { ui, url } from '@/config';
|
||||
import { url } from '@/config';
|
||||
import { popout } from '@/scripts/popout';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
|
||||
export default defineComponent({
|
||||
inject: {
|
||||
@ -57,31 +58,31 @@ export default defineComponent({
|
||||
text: this.to,
|
||||
}, {
|
||||
icon: faWindowMaximize,
|
||||
text: this.$t('openInWindow'),
|
||||
text: this.$ts.openInWindow,
|
||||
action: () => {
|
||||
os.pageWindow(this.to);
|
||||
}
|
||||
}, this.sideViewHook ? {
|
||||
icon: faColumns,
|
||||
text: this.$t('openInSideView'),
|
||||
text: this.$ts.openInSideView,
|
||||
action: () => {
|
||||
this.sideViewHook(this.to);
|
||||
}
|
||||
} : undefined, {
|
||||
icon: faExpandAlt,
|
||||
text: this.$t('showInPage'),
|
||||
text: this.$ts.showInPage,
|
||||
action: () => {
|
||||
this.$router.push(this.to);
|
||||
}
|
||||
}, null, {
|
||||
icon: faExternalLinkAlt,
|
||||
text: this.$t('openInNewTab'),
|
||||
text: this.$ts.openInNewTab,
|
||||
action: () => {
|
||||
window.open(this.to, '_blank');
|
||||
}
|
||||
}, {
|
||||
icon: faLink,
|
||||
text: this.$t('copyLink'),
|
||||
text: this.$ts.copyLink,
|
||||
action: () => {
|
||||
copyToClipboard(`${url}${this.to}`);
|
||||
}
|
||||
@ -98,8 +99,8 @@ export default defineComponent({
|
||||
|
||||
nav() {
|
||||
if (this.to.startsWith('/my/messaging')) {
|
||||
if (this.$store.state.device.chatOpenBehavior === 'window') return this.window();
|
||||
if (this.$store.state.device.chatOpenBehavior === 'popout') return this.popout();
|
||||
if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return this.window();
|
||||
if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return this.popout();
|
||||
}
|
||||
|
||||
if (this.behavior) {
|
||||
@ -111,15 +112,9 @@ export default defineComponent({
|
||||
if (this.navHook) {
|
||||
this.navHook(this.to);
|
||||
} else {
|
||||
if (this.$store.state.device.defaultSideView && this.sideViewHook && this.to !== '/') {
|
||||
if (this.$store.state.defaultSideView && this.sideViewHook && this.to !== '/') {
|
||||
return this.sideViewHook(this.to);
|
||||
}
|
||||
if (this.$store.state.device.deckNavWindow && (ui === 'deck') && this.to !== '/') {
|
||||
return this.window();
|
||||
}
|
||||
if (ui === 'desktop') {
|
||||
return this.window();
|
||||
}
|
||||
|
||||
if (this.$router.currentRoute.value.path === this.to) {
|
||||
window.scroll({ top: 0, behavior: 'smooth' });
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<span class="mk-acct" v-once>
|
||||
<span class="name">@{{ user.username }}</span>
|
||||
<span class="host" v-if="user.host || detail || $store.state.settings.showFullAcct">@{{ user.host || host }}</span>
|
||||
<span class="host" v-if="user.host || detail || $store.state.showFullAcct">@{{ user.host || host }}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<span class="eiwwqkts" :class="{ cat }" :title="acct(user)" v-if="disableLink" v-user-preview="disablePreview ? undefined : user.id" @click="onClick">
|
||||
<img class="inner" :src="url"/>
|
||||
<img class="inner" :src="url" decoding="async"/>
|
||||
</span>
|
||||
<MkA class="eiwwqkts" :class="{ cat }" :to="userPage(user)" :title="acct(user)" :target="target" v-else v-user-preview="disablePreview ? undefined : user.id">
|
||||
<img class="inner" :src="url"/>
|
||||
<img class="inner" :src="url" decoding="async"/>
|
||||
</MkA>
|
||||
</template>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
|
||||
import { extractAvgColorFromBlurhash } from '@/scripts/extract-avg-color-from-blurhash';
|
||||
import { acct, userPage } from '../filters/user';
|
||||
import { acct, userPage } from '@/filters/user';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -38,7 +38,7 @@ export default defineComponent({
|
||||
return this.user.isCat;
|
||||
},
|
||||
url(): string {
|
||||
return this.$store.state.device.disableShowingAnimatedImages
|
||||
return this.$store.state.disableShowingAnimatedImages
|
||||
? getStaticImageUrl(this.user.avatarUrl)
|
||||
: this.user.avatarUrl;
|
||||
},
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<img v-if="customEmoji" class="mk-emoji custom" :class="{ normal, noStyle }" :src="url" :alt="alt" :title="alt"/>
|
||||
<img v-else-if="char && !useOsNativeEmojis" class="mk-emoji" :src="url" :alt="alt" :title="alt"/>
|
||||
<img v-if="customEmoji" class="mk-emoji custom" :class="{ normal, noStyle }" :src="url" :alt="alt" :title="alt" decoding="async"/>
|
||||
<img v-else-if="char && !useOsNativeEmojis" class="mk-emoji" :src="url" :alt="alt" :title="alt" decoding="async"/>
|
||||
<span v-else-if="char && useOsNativeEmojis">{{ char }}</span>
|
||||
<span v-else>{{ emoji }}</span>
|
||||
</template>
|
||||
@ -8,7 +8,7 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
|
||||
import { twemojiSvgBase } from '../../misc/twemoji-base';
|
||||
import { twemojiSvgBase } from '@/../misc/twemoji-base';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -54,13 +54,13 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
useOsNativeEmojis(): boolean {
|
||||
return this.$store.state.device.useOsNativeEmojis && !this.isReaction;
|
||||
return this.$store.state.useOsNativeEmojis && !this.isReaction;
|
||||
},
|
||||
|
||||
ce() {
|
||||
let ce = [];
|
||||
if (this.customEmojis) ce = ce.concat(this.customEmojis);
|
||||
if (this.$store.state.instance.meta && this.$store.state.instance.meta.emojis) ce = ce.concat(this.$store.state.instance.meta.emojis);
|
||||
if (this.$instance && this.$instance.emojis) ce = ce.concat(this.$instance.emojis);
|
||||
return ce;
|
||||
}
|
||||
},
|
||||
@ -72,7 +72,7 @@ export default defineComponent({
|
||||
const customEmoji = this.ce.find(x => x.name === this.emoji.substr(1, this.emoji.length - 2));
|
||||
if (customEmoji) {
|
||||
this.customEmoji = customEmoji;
|
||||
this.url = this.$store.state.device.disableShowingAnimatedImages
|
||||
this.url = this.$store.state.disableShowingAnimatedImages
|
||||
? getStaticImageUrl(customEmoji.url)
|
||||
: customEmoji.url;
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<transition :name="$store.state.device.animation ? 'zoom' : ''" appear>
|
||||
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
|
||||
<div class="mjndxjcg">
|
||||
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
|
||||
<p><Fa :icon="faExclamationTriangle"/> {{ $t('somethingHappened') }}</p>
|
||||
<MkButton @click="() => $emit('retry')" class="button">{{ $t('retry') }}</MkButton>
|
||||
<p><Fa :icon="faExclamationTriangle"/> {{ $ts.somethingHappened }}</p>
|
||||
<MkButton @click="() => $emit('retry')" class="button">{{ $ts.retry }}</MkButton>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
@ -11,7 +11,7 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||
import MkButton from './ui/button.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
42
src/client/components/global/i18n.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { h, defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
tag: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'span',
|
||||
},
|
||||
textTag: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
render() {
|
||||
let str = this.src;
|
||||
const parsed = [] as (string | { arg: string; })[];
|
||||
while (true) {
|
||||
const nextBracketOpen = str.indexOf('{');
|
||||
const nextBracketClose = str.indexOf('}');
|
||||
|
||||
if (nextBracketOpen === -1) {
|
||||
parsed.push(str);
|
||||
break;
|
||||
} else {
|
||||
if (nextBracketOpen > 0) parsed.push(str.substr(0, nextBracketOpen));
|
||||
parsed.push({
|
||||
arg: str.substring(nextBracketOpen + 1, nextBracketClose)
|
||||
});
|
||||
}
|
||||
|
||||
str = str.substr(nextBracketClose + 1);
|
||||
}
|
||||
|
||||
return h(this.tag, parsed.map(x => typeof x === 'string' ? (this.textTag ? h(this.textTag, x) : x) : this.$slots[x.arg]()));
|
||||
}
|
||||
});
|
@ -4,7 +4,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import MfmCore from './mfm';
|
||||
import MfmCore from '@/components/mfm';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -14,6 +14,15 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
._mfm_blur_ {
|
||||
filter: blur(6px);
|
||||
transition: filter 0.3s;
|
||||
|
||||
&:hover {
|
||||
filter: blur(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes mfm-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
@ -44,9 +44,9 @@ export default defineComponent({
|
||||
ago >= 3600 ? this.$t('_ago.hoursAgo', { n: (~~(ago / 3600)).toString() }) :
|
||||
ago >= 60 ? this.$t('_ago.minutesAgo', { n: (~~(ago / 60)).toString() }) :
|
||||
ago >= 10 ? this.$t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() }) :
|
||||
ago >= -1 ? this.$t('_ago.justNow') :
|
||||
ago < -1 ? this.$t('_ago.future') :
|
||||
this.$t('_ago.unknown'));
|
||||
ago >= -1 ? this.$ts._ago.justNow :
|
||||
ago < -1 ? this.$ts._ago.future :
|
||||
this.$ts._ago.unknown);
|
||||
}
|
||||
},
|
||||
created() {
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="mk-google">
|
||||
<input type="search" v-model="query" :placeholder="q">
|
||||
<button @click="search"><Fa :icon="faSearch"/> {{ $t('search') }}</button>
|
||||
<button @click="search"><Fa :icon="faSearch"/> {{ $ts.search }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -23,7 +23,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
const engine = this.$store.state.settings.webSearchEngine ||
|
||||
const engine = this.$store.state.webSearchEngine ||
|
||||
'https://www.google.com/search?q={{query}}';
|
||||
const url = engine.replace('{{query}}', this.query)
|
||||
window.open(url, '_blank');
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { App } from 'vue';
|
||||
|
||||
import mfm from './misskey-flavored-markdown.vue';
|
||||
import a from './ui/a.vue';
|
||||
import acct from './acct.vue';
|
||||
import avatar from './avatar.vue';
|
||||
import emoji from './emoji.vue';
|
||||
import userName from './user-name.vue';
|
||||
import ellipsis from './ellipsis.vue';
|
||||
import time from './time.vue';
|
||||
import url from './url.vue';
|
||||
import loading from './loading.vue';
|
||||
import error from './error.vue';
|
||||
import mfm from './global/misskey-flavored-markdown.vue';
|
||||
import a from './global/a.vue';
|
||||
import acct from './global/acct.vue';
|
||||
import avatar from './global/avatar.vue';
|
||||
import emoji from './global/emoji.vue';
|
||||
import userName from './global/user-name.vue';
|
||||
import ellipsis from './global/ellipsis.vue';
|
||||
import time from './global/time.vue';
|
||||
import url from './global/url.vue';
|
||||
import i18n from './global/i18n';
|
||||
import loading from './global/loading.vue';
|
||||
import error from './global/error.vue';
|
||||
|
||||
export default function(app: App) {
|
||||
app.component('Mfm', mfm);
|
||||
@ -24,4 +25,5 @@ export default function(app: App) {
|
||||
app.component('MkUrl', url);
|
||||
app.component('MkLoading', loading);
|
||||
app.component('MkError', error);
|
||||
app.component('I18n', i18n);
|
||||
}
|
||||
|
@ -3,80 +3,80 @@
|
||||
<div class="stats" v-if="info">
|
||||
<div class="_panel">
|
||||
<div>
|
||||
<b><Fa :icon="faUser"/>{{ $t('users') }}</b>
|
||||
<small>{{ $t('local') }}</small>
|
||||
<b><Fa :icon="faUser"/>{{ $ts.users }}</b>
|
||||
<small>{{ $ts.local }}</small>
|
||||
</div>
|
||||
<div>
|
||||
<dl class="total">
|
||||
<dt>{{ $t('total') }}</dt>
|
||||
<dt>{{ $ts.total }}</dt>
|
||||
<dd>{{ number(info.originalUsersCount) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: usersLocalDoD > 0 }">
|
||||
<dt>{{ $t('dayOverDayChanges') }}</dt>
|
||||
<dt>{{ $ts.dayOverDayChanges }}</dt>
|
||||
<dd>{{ number(usersLocalDoD) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: usersLocalWoW > 0 }">
|
||||
<dt>{{ $t('weekOverWeekChanges') }}</dt>
|
||||
<dt>{{ $ts.weekOverWeekChanges }}</dt>
|
||||
<dd>{{ number(usersLocalWoW) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_panel">
|
||||
<div>
|
||||
<b><Fa :icon="faUser"/>{{ $t('users') }}</b>
|
||||
<small>{{ $t('remote') }}</small>
|
||||
<b><Fa :icon="faUser"/>{{ $ts.users }}</b>
|
||||
<small>{{ $ts.remote }}</small>
|
||||
</div>
|
||||
<div>
|
||||
<dl class="total">
|
||||
<dt>{{ $t('total') }}</dt>
|
||||
<dt>{{ $ts.total }}</dt>
|
||||
<dd>{{ number((info.usersCount - info.originalUsersCount)) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: usersRemoteDoD > 0 }">
|
||||
<dt>{{ $t('dayOverDayChanges') }}</dt>
|
||||
<dt>{{ $ts.dayOverDayChanges }}</dt>
|
||||
<dd>{{ number(usersRemoteDoD) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: usersRemoteWoW > 0 }">
|
||||
<dt>{{ $t('weekOverWeekChanges') }}</dt>
|
||||
<dt>{{ $ts.weekOverWeekChanges }}</dt>
|
||||
<dd>{{ number(usersRemoteWoW) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_panel">
|
||||
<div>
|
||||
<b><Fa :icon="faPencilAlt"/>{{ $t('notes') }}</b>
|
||||
<small>{{ $t('local') }}</small>
|
||||
<b><Fa :icon="faPencilAlt"/>{{ $ts.notes }}</b>
|
||||
<small>{{ $ts.local }}</small>
|
||||
</div>
|
||||
<div>
|
||||
<dl class="total">
|
||||
<dt>{{ $t('total') }}</dt>
|
||||
<dt>{{ $ts.total }}</dt>
|
||||
<dd>{{ number(info.originalNotesCount) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: notesLocalDoD > 0 }">
|
||||
<dt>{{ $t('dayOverDayChanges') }}</dt>
|
||||
<dt>{{ $ts.dayOverDayChanges }}</dt>
|
||||
<dd>{{ number(notesLocalDoD) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: notesLocalWoW > 0 }">
|
||||
<dt>{{ $t('weekOverWeekChanges') }}</dt>
|
||||
<dt>{{ $ts.weekOverWeekChanges }}</dt>
|
||||
<dd>{{ number(notesLocalWoW) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_panel">
|
||||
<div>
|
||||
<b><Fa :icon="faPencilAlt"/>{{ $t('notes') }}</b>
|
||||
<small>{{ $t('remote') }}</small>
|
||||
<b><Fa :icon="faPencilAlt"/>{{ $ts.notes }}</b>
|
||||
<small>{{ $ts.remote }}</small>
|
||||
</div>
|
||||
<div>
|
||||
<dl class="total">
|
||||
<dt>{{ $t('total') }}</dt>
|
||||
<dt>{{ $ts.total }}</dt>
|
||||
<dd>{{ number((info.notesCount - info.originalNotesCount)) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: notesRemoteDoD > 0 }">
|
||||
<dt>{{ $t('dayOverDayChanges') }}</dt>
|
||||
<dt>{{ $ts.dayOverDayChanges }}</dt>
|
||||
<dd>{{ number(notesRemoteDoD) }}</dd>
|
||||
</dl>
|
||||
<dl class="diff" :class="{ inc: notesRemoteWoW > 0 }">
|
||||
<dt>{{ $t('weekOverWeekChanges') }}</dt>
|
||||
<dt>{{ $ts.weekOverWeekChanges }}</dt>
|
||||
<dd>{{ number(notesRemoteWoW) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
@ -84,35 +84,35 @@
|
||||
</div>
|
||||
|
||||
<section class="_card">
|
||||
<div class="_title" style="position: relative;"><Fa :icon="faChartBar"/> {{ $t('statistics') }}<button @click="fetchChart" class="_button" style="position: absolute; right: 0; bottom: 0; top: 0; padding: inherit;"><Fa :icon="faSync"/></button></div>
|
||||
<div class="_title" style="position: relative;"><Fa :icon="faChartBar"/> {{ $ts.statistics }}<button @click="fetchChart" class="_button" style="position: absolute; right: 0; bottom: 0; top: 0; padding: inherit;"><Fa :icon="faSync"/></button></div>
|
||||
<div class="_content" style="margin-top: -8px;">
|
||||
<div class="selects" style="display: flex;">
|
||||
<MkSelect v-model:value="chartSrc" style="margin: 0; flex: 1;">
|
||||
<optgroup :label="$t('federation')">
|
||||
<option value="federation-instances">{{ $t('_charts.federationInstancesIncDec') }}</option>
|
||||
<option value="federation-instances-total">{{ $t('_charts.federationInstancesTotal') }}</option>
|
||||
<optgroup :label="$ts.federation">
|
||||
<option value="federation-instances">{{ $ts._charts.federationInstancesIncDec }}</option>
|
||||
<option value="federation-instances-total">{{ $ts._charts.federationInstancesTotal }}</option>
|
||||
</optgroup>
|
||||
<optgroup :label="$t('users')">
|
||||
<option value="users">{{ $t('_charts.usersIncDec') }}</option>
|
||||
<option value="users-total">{{ $t('_charts.usersTotal') }}</option>
|
||||
<option value="active-users">{{ $t('_charts.activeUsers') }}</option>
|
||||
<optgroup :label="$ts.users">
|
||||
<option value="users">{{ $ts._charts.usersIncDec }}</option>
|
||||
<option value="users-total">{{ $ts._charts.usersTotal }}</option>
|
||||
<option value="active-users">{{ $ts._charts.activeUsers }}</option>
|
||||
</optgroup>
|
||||
<optgroup :label="$t('notes')">
|
||||
<option value="notes">{{ $t('_charts.notesIncDec') }}</option>
|
||||
<option value="local-notes">{{ $t('_charts.localNotesIncDec') }}</option>
|
||||
<option value="remote-notes">{{ $t('_charts.remoteNotesIncDec') }}</option>
|
||||
<option value="notes-total">{{ $t('_charts.notesTotal') }}</option>
|
||||
<optgroup :label="$ts.notes">
|
||||
<option value="notes">{{ $ts._charts.notesIncDec }}</option>
|
||||
<option value="local-notes">{{ $ts._charts.localNotesIncDec }}</option>
|
||||
<option value="remote-notes">{{ $ts._charts.remoteNotesIncDec }}</option>
|
||||
<option value="notes-total">{{ $ts._charts.notesTotal }}</option>
|
||||
</optgroup>
|
||||
<optgroup :label="$t('drive')">
|
||||
<option value="drive-files">{{ $t('_charts.filesIncDec') }}</option>
|
||||
<option value="drive-files-total">{{ $t('_charts.filesTotal') }}</option>
|
||||
<option value="drive">{{ $t('_charts.storageUsageIncDec') }}</option>
|
||||
<option value="drive-total">{{ $t('_charts.storageUsageTotal') }}</option>
|
||||
<optgroup :label="$ts.drive">
|
||||
<option value="drive-files">{{ $ts._charts.filesIncDec }}</option>
|
||||
<option value="drive-files-total">{{ $ts._charts.filesTotal }}</option>
|
||||
<option value="drive">{{ $ts._charts.storageUsageIncDec }}</option>
|
||||
<option value="drive-total">{{ $ts._charts.storageUsageTotal }}</option>
|
||||
</optgroup>
|
||||
</MkSelect>
|
||||
<MkSelect v-model:value="chartSpan" style="margin: 0;">
|
||||
<option value="hour">{{ $t('perHour') }}</option>
|
||||
<option value="day">{{ $t('perDay') }}</option>
|
||||
<option value="hour">{{ $ts.perHour }}</option>
|
||||
<option value="day">{{ $ts.perDay }}</option>
|
||||
</MkSelect>
|
||||
</div>
|
||||
<canvas ref="chart"></canvas>
|
||||
@ -278,7 +278,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
// TODO: var(--panel)の色が暗いか明るいかで判定する
|
||||
const gridColor = this.$store.state.device.darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)';
|
||||
const gridColor = this.$store.state.darkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)';
|
||||
|
||||
Chart.defaults.global.defaultFontColor = getComputedStyle(document.documentElement).getPropertyValue('--fg');
|
||||
this.chartInstance = markRaw(new Chart(this.$refs.chart, {
|
||||
|
@ -18,7 +18,7 @@
|
||||
<div class="sub">
|
||||
<MkA to="/docs" @click.passive="close()">
|
||||
<Fa :icon="faQuestionCircle" class="icon"/>
|
||||
<div class="text">{{ $t('help') }}</div>
|
||||
<div class="text">{{ $ts.help }}</div>
|
||||
</MkA>
|
||||
<MkA to="/about" @click.passive="close()">
|
||||
<Fa :icon="faInfoCircle" class="icon"/>
|
||||
@ -26,7 +26,7 @@
|
||||
</MkA>
|
||||
<MkA to="/about-misskey" @click.passive="close()">
|
||||
<Fa :icon="faInfoCircle" class="icon"/>
|
||||
<div class="text">{{ $t('aboutMisskey') }}</div>
|
||||
<div class="text">{{ $ts.aboutMisskey }}</div>
|
||||
</MkA>
|
||||
</div>
|
||||
</div>
|
||||
@ -58,14 +58,14 @@ export default defineComponent({
|
||||
|
||||
computed: {
|
||||
menu(): string[] {
|
||||
return this.$store.state.deviceUser.menu;
|
||||
return this.$store.state.menu;
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.items = Object.keys(this.menuDef).filter(k => !this.menu.includes(k)).map(k => this.menuDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({
|
||||
type: def.to ? 'link' : 'button',
|
||||
text: this.$t(def.title),
|
||||
text: this.$ts[def.title],
|
||||
icon: def.icon,
|
||||
to: def.to,
|
||||
action: def.action,
|
||||
|
@ -2,8 +2,8 @@
|
||||
<div class="mk-media-banner">
|
||||
<div class="sensitive" v-if="media.isSensitive && hide" @click="hide = false">
|
||||
<span class="icon"><Fa :icon="faExclamationTriangle"/></span>
|
||||
<b>{{ $t('sensitive') }}</b>
|
||||
<span>{{ $t('clickToShow') }}</span>
|
||||
<b>{{ $ts.sensitive }}</b>
|
||||
<span>{{ $ts.clickToShow }}</span>
|
||||
</div>
|
||||
<div class="audio" v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'">
|
||||
<audio class="audio"
|
||||
@ -29,6 +29,7 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -45,12 +46,12 @@ export default defineComponent({
|
||||
},
|
||||
mounted() {
|
||||
const audioTag = this.$refs.audio as HTMLAudioElement;
|
||||
if (audioTag) audioTag.volume = this.$store.state.device.mediaVolume;
|
||||
if (audioTag) audioTag.volume = ColdDeviceStorage.get('mediaVolume');
|
||||
},
|
||||
methods: {
|
||||
volumechange() {
|
||||
const audioTag = this.$refs.audio as HTMLAudioElement;
|
||||
this.$store.commit('device/set', { key: 'mediaVolume', value: audioTag.volume });
|
||||
ColdDeviceStorage.set('mediaVolume', audioTag.volume);
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -3,8 +3,8 @@
|
||||
<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.name"/>
|
||||
<div class="text">
|
||||
<div>
|
||||
<b><Fa :icon="faExclamationTriangle"/> {{ $t('sensitive') }}</b>
|
||||
<span>{{ $t('clickToShow') }}</span>
|
||||
<b><Fa :icon="faExclamationTriangle"/> {{ $ts.sensitive }}</b>
|
||||
<span>{{ $ts.clickToShow }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,13 +52,11 @@ export default defineComponent({
|
||||
},
|
||||
computed: {
|
||||
url(): any {
|
||||
let url = this.$store.state.device.disableShowingAnimatedImages
|
||||
let url = this.$store.state.disableShowingAnimatedImages
|
||||
? getStaticImageUrl(this.image.thumbnailUrl)
|
||||
: this.image.thumbnailUrl;
|
||||
|
||||
if (this.$store.state.device.loadRemoteMedia) {
|
||||
url = null;
|
||||
} else if (this.raw || this.$store.state.device.loadRawImages) {
|
||||
if (this.raw || this.$store.state.loadRawImages) {
|
||||
url = this.image.url;
|
||||
}
|
||||
|
||||
@ -68,7 +66,7 @@ export default defineComponent({
|
||||
created() {
|
||||
// Plugin:register_note_view_interruptor を使って書き換えられる可能性があるためwatchする
|
||||
this.$watch('image', () => {
|
||||
this.hide = (this.$store.state.device.nsfw === 'force') ? true : this.image.isSensitive && (this.$store.state.device.nsfw !== 'ignore');
|
||||
this.hide = (this.$store.state.nsfw === 'force') ? true : this.image.isSensitive && (this.$store.state.nsfw !== 'ignore');
|
||||
if (this.image.blurhash) {
|
||||
this.color = extractAvgColorFromBlurhash(this.image.blurhash);
|
||||
}
|
||||
@ -79,7 +77,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
if (this.$store.state.device.imageNewTab) {
|
||||
if (this.$store.state.imageNewTab) {
|
||||
window.open(this.image.url, '_blank');
|
||||
} else {
|
||||
os.popup(ImageViewer, {
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="icozogqfvdetwohsdglrbswgrejoxbdj" v-if="hide" @click="hide = false">
|
||||
<div>
|
||||
<b><Fa :icon="faExclamationTriangle"/> {{ $t('sensitive') }}</b>
|
||||
<span>{{ $t('clickToShow') }}</span>
|
||||
<b><Fa :icon="faExclamationTriangle"/> {{ $ts.sensitive }}</b>
|
||||
<span>{{ $ts.clickToShow }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kkjnbbplepmiyuadieoenjgutgcmtsvu" v-else>
|
||||
@ -48,7 +48,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.hide = (this.$store.state.device.nsfw === 'force') ? true : this.video.isSensitive && (this.$store.state.device.nsfw !== 'ignore');
|
||||
this.hide = (this.$store.state.nsfw === 'force') ? true : this.video.isSensitive && (this.$store.state.nsfw !== 'ignore');
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<MkA class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" v-if="url.startsWith('/')">
|
||||
<span class="me" v-if="isMe">{{ $t('you') }}</span>
|
||||
<span class="me" v-if="isMe">{{ $ts.you }}</span>
|
||||
<span class="main">
|
||||
<span class="username">@{{ username }}</span>
|
||||
<span class="host" v-if="(host != localHost) || $store.state.settings.showFullAcct">@{{ toUnicode(host) }}</span>
|
||||
<span class="host" v-if="(host != localHost) || $store.state.showFullAcct">@{{ toUnicode(host) }}</span>
|
||||
</span>
|
||||
</MkA>
|
||||
<a class="ldlomzub" :href="url" target="_blank" rel="noopener" v-else>
|
||||
@ -50,8 +50,8 @@ export default defineComponent({
|
||||
return this.host === localHost ? `@${this.username}` : `@${this.username}@${toUnicode(this.host)}`;
|
||||
},
|
||||
isMe(): boolean {
|
||||
return this.$store.getters.isSignedIn && (
|
||||
`@${this.username}@${toUnicode(this.host)}` === `@${this.$store.state.i.username}@${toUnicode(localHost)}`.toLowerCase()
|
||||
return this.$i && (
|
||||
`@${this.username}@${toUnicode(this.host)}` === `@${this.$i.username}@${toUnicode(localHost)}`.toLowerCase()
|
||||
);
|
||||
}
|
||||
},
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { VNode, defineComponent, h } from 'vue';
|
||||
import { MfmForest } from '../../mfm/prelude';
|
||||
import { parse, parsePlain } from '../../mfm/parse';
|
||||
import MkUrl from './url.vue';
|
||||
import MkLink from './link.vue';
|
||||
import MkMention from './mention.vue';
|
||||
import MkEmoji from './emoji.vue';
|
||||
import { concat } from '../../prelude/array';
|
||||
import MkFormula from './formula.vue';
|
||||
import MkCode from './code.vue';
|
||||
import MkGoogle from './google.vue';
|
||||
import MkA from './ui/a.vue';
|
||||
import { MfmForest } from '@/../mfm/prelude';
|
||||
import { parse, parsePlain } from '@/../mfm/parse';
|
||||
import MkUrl from '@/components/global/url.vue';
|
||||
import MkLink from '@/components/link.vue';
|
||||
import MkMention from '@/components/mention.vue';
|
||||
import MkEmoji from '@/components/global/emoji.vue';
|
||||
import { concat } from '@/../prelude/array';
|
||||
import MkFormula from '@/components/formula.vue';
|
||||
import MkCode from '@/components/code.vue';
|
||||
import MkGoogle from '@/components/google.vue';
|
||||
import MkA from '@/components/global/a.vue';
|
||||
import { host } from '@/config';
|
||||
|
||||
export default defineComponent({
|
||||
@ -48,6 +48,11 @@ export default defineComponent({
|
||||
|
||||
const ast = (this.plain ? parsePlain : parse)(this.text);
|
||||
|
||||
const validTime = (t: string | null | undefined) => {
|
||||
if (t == null) return null;
|
||||
return t.match(/^[0-9.]+s$/) ? t : null;
|
||||
};
|
||||
|
||||
const genEl = (ast: MfmForest) => concat(ast.map((token): VNode[] => {
|
||||
switch (token.node.type) {
|
||||
case 'text': {
|
||||
@ -82,22 +87,22 @@ export default defineComponent({
|
||||
let style;
|
||||
switch (token.node.props.name) {
|
||||
case 'tada': {
|
||||
style = `font-size: 150%;` + (this.$store.state.device.animatedMfm ? 'animation: tada 1s linear infinite both;' : '');
|
||||
style = `font-size: 150%;` + (this.$store.state.animatedMfm ? 'animation: tada 1s linear infinite both;' : '');
|
||||
break;
|
||||
}
|
||||
case 'jelly': {
|
||||
const speed = token.node.props.args.speed || '1s';
|
||||
style = (this.$store.state.device.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : '');
|
||||
const speed = validTime(token.node.props.args.speed) || '1s';
|
||||
style = (this.$store.state.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : '');
|
||||
break;
|
||||
}
|
||||
case 'twitch': {
|
||||
const speed = token.node.props.args.speed || '0.5s';
|
||||
style = this.$store.state.device.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : '';
|
||||
const speed = validTime(token.node.props.args.speed) || '0.5s';
|
||||
style = this.$store.state.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : '';
|
||||
break;
|
||||
}
|
||||
case 'shake': {
|
||||
const speed = token.node.props.args.speed || '0.5s';
|
||||
style = this.$store.state.device.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : '';
|
||||
const speed = validTime(token.node.props.args.speed) || '0.5s';
|
||||
style = this.$store.state.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : '';
|
||||
break;
|
||||
}
|
||||
case 'spin': {
|
||||
@ -109,16 +114,16 @@ export default defineComponent({
|
||||
token.node.props.args.x ? 'mfm-spinX' :
|
||||
token.node.props.args.y ? 'mfm-spinY' :
|
||||
'mfm-spin';
|
||||
const speed = token.node.props.args.speed || '1.5s';
|
||||
style = this.$store.state.device.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : '';
|
||||
const speed = validTime(token.node.props.args.speed) || '1.5s';
|
||||
style = this.$store.state.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : '';
|
||||
break;
|
||||
}
|
||||
case 'jump': {
|
||||
style = this.$store.state.device.animatedMfm ? 'animation: mfm-jump 0.75s linear infinite;' : '';
|
||||
style = this.$store.state.animatedMfm ? 'animation: mfm-jump 0.75s linear infinite;' : '';
|
||||
break;
|
||||
}
|
||||
case 'bounce': {
|
||||
style = this.$store.state.device.animatedMfm ? 'animation: mfm-bounce 0.75s linear infinite; transform-origin: center bottom;' : '';
|
||||
style = this.$store.state.animatedMfm ? 'animation: mfm-bounce 0.75s linear infinite; transform-origin: center bottom;' : '';
|
||||
break;
|
||||
}
|
||||
case 'flip': {
|
||||
@ -129,6 +134,35 @@ export default defineComponent({
|
||||
style = `transform: ${transform};`;
|
||||
break;
|
||||
}
|
||||
case 'x2': {
|
||||
style = `font-size: 200%;`;
|
||||
break;
|
||||
}
|
||||
case 'x3': {
|
||||
style = `font-size: 400%;`;
|
||||
break;
|
||||
}
|
||||
case 'x4': {
|
||||
style = `font-size: 600%;`;
|
||||
break;
|
||||
}
|
||||
case 'font': {
|
||||
const family =
|
||||
token.node.props.args.serif ? 'serif' :
|
||||
token.node.props.args.monospace ? 'monospace' :
|
||||
token.node.props.args.cursive ? 'cursive' :
|
||||
token.node.props.args.fantasy ? 'fantasy' :
|
||||
token.node.props.args.emoji ? 'emoji' :
|
||||
token.node.props.args.math ? 'math' :
|
||||
null;
|
||||
if (family) style = `font-family: ${family};`;
|
||||
break;
|
||||
}
|
||||
case 'blur': {
|
||||
return h('span', {
|
||||
class: '_mfm_blur_',
|
||||
}, genEl(token.children));
|
||||
}
|
||||
}
|
||||
if (style == null) {
|
||||
return h('span', {}, ['[', token.node.props.name, ...genEl(token.children), ']']);
|
||||
|
1190
src/client/components/note-detailed.vue
Normal file
@ -6,7 +6,7 @@
|
||||
<XNoteHeader class="header" :note="note" :mini="true"/>
|
||||
<div class="body">
|
||||
<p v-if="note.cw != null" class="cw">
|
||||
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$store.state.i" :custom-emojis="note.emojis" />
|
||||
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" />
|
||||
<XCwButton v-model:value="showContent" :note="note"/>
|
||||
</p>
|
||||
<div class="content" v-show="note.cw == null || showContent">
|
||||
|
@ -8,21 +8,20 @@
|
||||
v-hotkey="keymap"
|
||||
v-size="{ max: [500, 450, 350, 300] }"
|
||||
>
|
||||
<XSub v-for="note in conversation" class="reply-to-more" :key="note.id" :note="note"/>
|
||||
<XSub :note="appearNote.reply" class="reply-to" v-if="appearNote.reply"/>
|
||||
<div class="info" v-if="pinned"><Fa :icon="faThumbtack"/> {{ $t('pinnedNote') }}</div>
|
||||
<div class="info" v-if="appearNote._prId_"><Fa :icon="faBullhorn"/> {{ $t('promotion') }}<button class="_textButton hide" @click="readPromo()">{{ $t('hideThisNote') }} <Fa :icon="faTimes"/></button></div>
|
||||
<div class="info" v-if="appearNote._featuredId_"><Fa :icon="faBolt"/> {{ $t('featured') }}</div>
|
||||
<div class="info" v-if="pinned"><Fa :icon="faThumbtack"/> {{ $ts.pinnedNote }}</div>
|
||||
<div class="info" v-if="appearNote._prId_"><Fa :icon="faBullhorn"/> {{ $ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ $ts.hideThisNote }} <Fa :icon="faTimes"/></button></div>
|
||||
<div class="info" v-if="appearNote._featuredId_"><Fa :icon="faBolt"/> {{ $ts.featured }}</div>
|
||||
<div class="renote" v-if="isRenote">
|
||||
<MkAvatar class="avatar" :user="note.user"/>
|
||||
<Fa :icon="faRetweet"/>
|
||||
<i18n-t keypath="renotedBy" tag="span">
|
||||
<I18n :src="$ts.renotedBy" tag="span">
|
||||
<template #user>
|
||||
<MkA class="name" :to="userPage(note.user)" v-user-preview="note.userId">
|
||||
<MkUserName :user="note.user"/>
|
||||
</MkA>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</I18n>
|
||||
<div class="info">
|
||||
<button class="_button time" @click="showRenoteMenu()" ref="renoteTime">
|
||||
<Fa class="dropdownIcon" v-if="isMyRenote" :icon="faEllipsisH"/>
|
||||
@ -36,29 +35,32 @@
|
||||
<span class="localOnly" v-if="note.localOnly"><Fa :icon="faBiohazard"/></span>
|
||||
</div>
|
||||
</div>
|
||||
<article class="article" @contextmenu="onContextmenu">
|
||||
<article class="article" @contextmenu.stop="onContextmenu">
|
||||
<MkAvatar class="avatar" :user="appearNote.user"/>
|
||||
<div class="main">
|
||||
<XNoteHeader class="header" :note="appearNote" :mini="true"/>
|
||||
<MkInstanceTicker v-if="showTicker" class="ticker" :instance="appearNote.user.instance"/>
|
||||
<div class="body">
|
||||
<p v-if="appearNote.cw != null" class="cw">
|
||||
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
|
||||
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
||||
<XCwButton v-model:value="showContent" :note="appearNote"/>
|
||||
</p>
|
||||
<div class="content" v-show="appearNote.cw == null || showContent">
|
||||
<div class="content" :class="{ collapsed }" v-show="appearNote.cw == null || showContent">
|
||||
<div class="text">
|
||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
|
||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
|
||||
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><Fa :icon="faReply"/></MkA>
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
||||
<a class="rp" v-if="appearNote.renote != null">RN:</a>
|
||||
</div>
|
||||
<div class="files" v-if="appearNote.files.length > 0">
|
||||
<XMediaList :media-list="appearNote.files"/>
|
||||
</div>
|
||||
<XPoll v-if="appearNote.poll" :note="appearNote" ref="pollViewer" class="poll"/>
|
||||
<MkUrlPreview v-for="url in urls" :url="url" :key="url" :compact="true" :detail="detail" class="url-preview"/>
|
||||
<MkUrlPreview v-for="url in urls" :url="url" :key="url" :compact="true" :detail="false" class="url-preview"/>
|
||||
<div class="renote" v-if="appearNote.renote"><XNotePreview :note="appearNote.renote"/></div>
|
||||
<button v-if="collapsed" class="fade _button" @click="collapsed = false">
|
||||
<span>{{ $ts.showMore }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><Fa :icon="faSatelliteDish"/> {{ appearNote.channel.name }}</MkA>
|
||||
</div>
|
||||
@ -87,16 +89,15 @@
|
||||
</footer>
|
||||
</div>
|
||||
</article>
|
||||
<XSub v-for="note in replies" :key="note.id" :note="note" class="reply" :detail="true"/>
|
||||
</div>
|
||||
<div v-else class="_panel muted" @click="muted = false">
|
||||
<i18n-t keypath="userSaysSomething" tag="small">
|
||||
<I18n :src="$ts.userSaysSomething" tag="small">
|
||||
<template #name>
|
||||
<MkA class="name" :to="userPage(appearNote.user)" v-user-preview="appearNote.userId">
|
||||
<MkUserName :user="appearNote.user"/>
|
||||
</MkA>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</I18n>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -154,11 +155,6 @@ export default defineComponent({
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
detail: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
pinned: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
@ -171,9 +167,9 @@ export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
connection: null,
|
||||
conversation: [],
|
||||
replies: [],
|
||||
showContent: false,
|
||||
collapsed: false,
|
||||
isDeleted: false,
|
||||
muted: false,
|
||||
faEdit, faBolt, faTimes, faBullhorn, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faBiohazard, faPlug, faSatelliteDish
|
||||
@ -182,7 +178,7 @@ export default defineComponent({
|
||||
|
||||
computed: {
|
||||
rs() {
|
||||
return this.$store.state.settings.reactions;
|
||||
return this.$store.state.reactions;
|
||||
},
|
||||
keymap(): any {
|
||||
return {
|
||||
@ -222,11 +218,11 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
isMyNote(): boolean {
|
||||
return this.$store.getters.isSignedIn && (this.$store.state.i.id === this.appearNote.userId);
|
||||
return this.$i && (this.$i.id === this.appearNote.userId);
|
||||
},
|
||||
|
||||
isMyRenote(): boolean {
|
||||
return this.$store.getters.isSignedIn && (this.$store.state.i.id === this.note.userId);
|
||||
return this.$i && (this.$i.id === this.note.userId);
|
||||
},
|
||||
|
||||
canRenote(): boolean {
|
||||
@ -262,17 +258,23 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
showTicker() {
|
||||
if (this.$store.state.device.instanceTicker === 'always') return true;
|
||||
if (this.$store.state.device.instanceTicker === 'remote' && this.appearNote.user.instance) return true;
|
||||
if (this.$store.state.instanceTicker === 'always') return true;
|
||||
if (this.$store.state.instanceTicker === 'remote' && this.appearNote.user.instance) return true;
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
async created() {
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
if (this.$i) {
|
||||
this.connection = os.stream;
|
||||
}
|
||||
|
||||
this.collapsed = this.appearNote.cw == null && this.appearNote.text && (
|
||||
(this.appearNote.text.split('\n').length > 9) ||
|
||||
(this.appearNote.text.length > 500)
|
||||
);
|
||||
this.muted = await checkWordMute(this.appearNote, this.$i, this.$store.state.mutedWords);
|
||||
|
||||
// plugin
|
||||
if (noteViewInterruptors.length > 0) {
|
||||
let result = this.note;
|
||||
@ -281,31 +283,12 @@ export default defineComponent({
|
||||
}
|
||||
this.$emit('update:note', Object.freeze(result));
|
||||
}
|
||||
|
||||
this.muted = await checkWordMute(this.appearNote, this.$store.state.i, this.$store.state.settings.mutedWords);
|
||||
|
||||
if (this.detail) {
|
||||
os.api('notes/children', {
|
||||
noteId: this.appearNote.id,
|
||||
limit: 30
|
||||
}).then(replies => {
|
||||
this.replies = replies;
|
||||
});
|
||||
|
||||
if (this.appearNote.replyId) {
|
||||
os.api('notes/conversation', {
|
||||
noteId: this.appearNote.replyId
|
||||
}).then(conversation => {
|
||||
this.conversation = conversation.reverse();
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.capture(true);
|
||||
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
if (this.$i) {
|
||||
this.connection.on('_connected_', this.onStreamConnected);
|
||||
}
|
||||
},
|
||||
@ -313,7 +296,7 @@ export default defineComponent({
|
||||
beforeUnmount() {
|
||||
this.decapture(true);
|
||||
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
if (this.$i) {
|
||||
this.connection.off('_connected_', this.onStreamConnected);
|
||||
}
|
||||
},
|
||||
@ -340,14 +323,14 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
capture(withHandler = false) {
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
if (this.$i) {
|
||||
this.connection.send(document.body.contains(this.$el) ? 'sn' : 's', { id: this.appearNote.id });
|
||||
if (withHandler) this.connection.on('noteUpdated', this.onStreamNoteUpdated);
|
||||
}
|
||||
},
|
||||
|
||||
decapture(withHandler = false) {
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
if (this.$i) {
|
||||
this.connection.send('un', {
|
||||
id: this.appearNote.id
|
||||
});
|
||||
@ -389,7 +372,7 @@ export default defineComponent({
|
||||
[reaction]: currentCount + 1
|
||||
};
|
||||
|
||||
if (body.userId === this.$store.state.i.id) {
|
||||
if (body.userId === this.$i.id) {
|
||||
n.myReaction = reaction;
|
||||
}
|
||||
|
||||
@ -414,7 +397,7 @@ export default defineComponent({
|
||||
[reaction]: Math.max(0, currentCount - 1)
|
||||
};
|
||||
|
||||
if (body.userId === this.$store.state.i.id) {
|
||||
if (body.userId === this.$i.id) {
|
||||
n.myReaction = null;
|
||||
}
|
||||
|
||||
@ -434,7 +417,7 @@ export default defineComponent({
|
||||
choices[choice] = {
|
||||
...choices[choice],
|
||||
votes: choices[choice].votes + 1,
|
||||
...(body.userId === this.$store.state.i.id ? {
|
||||
...(body.userId === this.$i.id ? {
|
||||
isVoted: true
|
||||
} : {})
|
||||
};
|
||||
@ -469,7 +452,7 @@ export default defineComponent({
|
||||
pleaseLogin();
|
||||
this.blur();
|
||||
os.modalMenu([{
|
||||
text: this.$t('renote'),
|
||||
text: this.$ts.renote,
|
||||
icon: faRetweet,
|
||||
action: () => {
|
||||
os.api('notes/create', {
|
||||
@ -477,7 +460,7 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
}, {
|
||||
text: this.$t('quote'),
|
||||
text: this.$ts.quote,
|
||||
icon: faQuoteRight,
|
||||
action: () => {
|
||||
os.post({
|
||||
@ -490,8 +473,25 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
renoteDirectly() {
|
||||
os.api('notes/create', {
|
||||
os.apiWithDialog('notes/create', {
|
||||
renoteId: this.appearNote.id
|
||||
}, undefined, (res: any) => {
|
||||
os.dialog({
|
||||
type: 'success',
|
||||
text: this.$ts.renoted,
|
||||
});
|
||||
}, (e: Error) => {
|
||||
if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$ts.cantRenote,
|
||||
});
|
||||
} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$ts.cantReRenote,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@ -533,13 +533,30 @@ export default defineComponent({
|
||||
pleaseLogin();
|
||||
os.apiWithDialog('notes/favorites/create', {
|
||||
noteId: this.appearNote.id
|
||||
}, undefined, (res: any) => {
|
||||
os.dialog({
|
||||
type: 'success',
|
||||
text: this.$ts.favorited,
|
||||
});
|
||||
}, (e: Error) => {
|
||||
if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$ts.alreadyFavorited,
|
||||
});
|
||||
} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$ts.cantFavorite,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
del() {
|
||||
os.dialog({
|
||||
type: 'warning',
|
||||
text: this.$t('noteDeleteConfirm'),
|
||||
text: this.$ts.noteDeleteConfirm,
|
||||
showCancelButton: true
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
@ -553,7 +570,7 @@ export default defineComponent({
|
||||
delEdit() {
|
||||
os.dialog({
|
||||
type: 'warning',
|
||||
text: this.$t('deleteAndEditConfirm'),
|
||||
text: this.$ts.deleteAndEditConfirm,
|
||||
showCancelButton: true
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
@ -580,22 +597,22 @@ export default defineComponent({
|
||||
|
||||
getMenu() {
|
||||
let menu;
|
||||
if (this.$store.getters.isSignedIn) {
|
||||
if (this.$i) {
|
||||
const statePromise = os.api('notes/state', {
|
||||
noteId: this.appearNote.id
|
||||
});
|
||||
|
||||
menu = [{
|
||||
icon: faCopy,
|
||||
text: this.$t('copyContent'),
|
||||
text: this.$ts.copyContent,
|
||||
action: this.copyContent
|
||||
}, {
|
||||
icon: faLink,
|
||||
text: this.$t('copyLink'),
|
||||
text: this.$ts.copyLink,
|
||||
action: this.copyLink
|
||||
}, (this.appearNote.url || this.appearNote.uri) ? {
|
||||
icon: faExternalLinkSquareAlt,
|
||||
text: this.$t('showOnRemote'),
|
||||
text: this.$ts.showOnRemote,
|
||||
action: () => {
|
||||
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
|
||||
}
|
||||
@ -603,50 +620,50 @@ export default defineComponent({
|
||||
null,
|
||||
statePromise.then(state => state.isFavorited ? {
|
||||
icon: faStar,
|
||||
text: this.$t('unfavorite'),
|
||||
text: this.$ts.unfavorite,
|
||||
action: () => this.toggleFavorite(false)
|
||||
} : {
|
||||
icon: faStar,
|
||||
text: this.$t('favorite'),
|
||||
text: this.$ts.favorite,
|
||||
action: () => this.toggleFavorite(true)
|
||||
}),
|
||||
{
|
||||
icon: faPaperclip,
|
||||
text: this.$t('clip'),
|
||||
text: this.$ts.clip,
|
||||
action: () => this.clip()
|
||||
},
|
||||
(this.appearNote.userId != this.$store.state.i.id) ? statePromise.then(state => state.isWatching ? {
|
||||
(this.appearNote.userId != this.$i.id) ? statePromise.then(state => state.isWatching ? {
|
||||
icon: faEyeSlash,
|
||||
text: this.$t('unwatch'),
|
||||
text: this.$ts.unwatch,
|
||||
action: () => this.toggleWatch(false)
|
||||
} : {
|
||||
icon: faEye,
|
||||
text: this.$t('watch'),
|
||||
text: this.$ts.watch,
|
||||
action: () => this.toggleWatch(true)
|
||||
}) : undefined,
|
||||
this.appearNote.userId == this.$store.state.i.id ? (this.$store.state.i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
|
||||
this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
|
||||
icon: faThumbtack,
|
||||
text: this.$t('unpin'),
|
||||
text: this.$ts.unpin,
|
||||
action: () => this.togglePin(false)
|
||||
} : {
|
||||
icon: faThumbtack,
|
||||
text: this.$t('pin'),
|
||||
text: this.$ts.pin,
|
||||
action: () => this.togglePin(true)
|
||||
} : undefined,
|
||||
...(this.$store.state.i.isModerator || this.$store.state.i.isAdmin ? [
|
||||
...(this.$i.isModerator || this.$i.isAdmin ? [
|
||||
null,
|
||||
{
|
||||
icon: faBullhorn,
|
||||
text: this.$t('promote'),
|
||||
text: this.$ts.promote,
|
||||
action: this.promote
|
||||
}]
|
||||
: []
|
||||
),
|
||||
...(this.appearNote.userId != this.$store.state.i.id ? [
|
||||
...(this.appearNote.userId != this.$i.id ? [
|
||||
null,
|
||||
{
|
||||
icon: faExclamationCircle,
|
||||
text: this.$t('reportAbuse'),
|
||||
text: this.$ts.reportAbuse,
|
||||
action: () => {
|
||||
const u = `${url}/notes/${this.appearNote.id}`;
|
||||
os.popup(import('@/components/abuse-report-window.vue'), {
|
||||
@ -657,16 +674,16 @@ export default defineComponent({
|
||||
}]
|
||||
: []
|
||||
),
|
||||
...(this.appearNote.userId == this.$store.state.i.id || this.$store.state.i.isModerator || this.$store.state.i.isAdmin ? [
|
||||
...(this.appearNote.userId == this.$i.id || this.$i.isModerator || this.$i.isAdmin ? [
|
||||
null,
|
||||
this.appearNote.userId == this.$store.state.i.id ? {
|
||||
this.appearNote.userId == this.$i.id ? {
|
||||
icon: faEdit,
|
||||
text: this.$t('deleteAndEdit'),
|
||||
text: this.$ts.deleteAndEdit,
|
||||
action: this.delEdit
|
||||
} : undefined,
|
||||
{
|
||||
icon: faTrashAlt,
|
||||
text: this.$t('delete'),
|
||||
text: this.$ts.delete,
|
||||
danger: true,
|
||||
action: this.del
|
||||
}]
|
||||
@ -676,15 +693,15 @@ export default defineComponent({
|
||||
} else {
|
||||
menu = [{
|
||||
icon: faCopy,
|
||||
text: this.$t('copyContent'),
|
||||
text: this.$ts.copyContent,
|
||||
action: this.copyContent
|
||||
}, {
|
||||
icon: faLink,
|
||||
text: this.$t('copyLink'),
|
||||
text: this.$ts.copyLink,
|
||||
action: this.copyLink
|
||||
}, (this.appearNote.url || this.appearNote.uri) ? {
|
||||
icon: faExternalLinkSquareAlt,
|
||||
text: this.$t('showOnRemote'),
|
||||
text: this.$ts.showOnRemote,
|
||||
action: () => {
|
||||
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
|
||||
}
|
||||
@ -726,7 +743,7 @@ export default defineComponent({
|
||||
showRenoteMenu(viaKeyboard = false) {
|
||||
if (!this.isMyRenote) return;
|
||||
os.modalMenu([{
|
||||
text: this.$t('unrenote'),
|
||||
text: this.$ts.unrenote,
|
||||
icon: faTrashAlt,
|
||||
danger: true,
|
||||
action: () => {
|
||||
@ -761,7 +778,7 @@ export default defineComponent({
|
||||
if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
|
||||
os.dialog({
|
||||
type: 'error',
|
||||
text: this.$t('pinLimitExceeded')
|
||||
text: this.$ts.pinLimitExceeded
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -771,22 +788,22 @@ export default defineComponent({
|
||||
const clips = await os.api('clips/list');
|
||||
os.modalMenu([{
|
||||
icon: faPlus,
|
||||
text: this.$t('createNew'),
|
||||
text: this.$ts.createNew,
|
||||
action: async () => {
|
||||
const { canceled, result } = await os.form(this.$t('createNewClip'), {
|
||||
const { canceled, result } = await os.form(this.$ts.createNewClip, {
|
||||
name: {
|
||||
type: 'string',
|
||||
label: this.$t('name')
|
||||
label: this.$ts.name
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
multiline: true,
|
||||
label: this.$t('description')
|
||||
label: this.$ts.description
|
||||
},
|
||||
isPublic: {
|
||||
type: 'boolean',
|
||||
label: this.$t('public'),
|
||||
label: this.$ts.public,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
@ -807,7 +824,7 @@ export default defineComponent({
|
||||
|
||||
async promote() {
|
||||
const { canceled, result: days } = await os.dialog({
|
||||
title: this.$t('numberOfDays'),
|
||||
title: this.$ts.numberOfDays,
|
||||
input: { type: 'number' }
|
||||
});
|
||||
|
||||
@ -847,6 +864,14 @@ export default defineComponent({
|
||||
overflow: hidden;
|
||||
contain: content;
|
||||
|
||||
// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、
|
||||
// 下の方までスクロールすると上のノートの高さがここで決め打ちされたものに変化し、表示しているノートの位置が変わってしまう
|
||||
// ノートがマウントされたときに自身の高さを取得し contain-intrinsic-size を設定しなおせばほぼ解決できそうだが、
|
||||
// 今度はその処理自体がパフォーマンス低下の原因にならないか懸念される。また、被リアクションでも高さは変化するため、やはり多少のズレは生じる
|
||||
// 一度レンダリングされた要素はブラウザがよしなにサイズを覚えておいてくれるような実装になるまで待った方が良さそう(なるのか?)
|
||||
//content-visibility: auto;
|
||||
//contain-intrinsic-size: 0 128px;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
|
||||
@ -901,10 +926,6 @@ export default defineComponent({
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
> .reply-to-more {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
> .renote {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -996,6 +1017,37 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
> .content {
|
||||
&.collapsed {
|
||||
position: relative;
|
||||
max-height: 9em;
|
||||
overflow: hidden;
|
||||
|
||||
> .fade {
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
background: linear-gradient(0deg, var(--panel), var(--X15));
|
||||
|
||||
> span {
|
||||
display: inline-block;
|
||||
background: var(--panel);
|
||||
padding: 6px 10px;
|
||||
font-size: 0.8em;
|
||||
border-radius: 999px;
|
||||
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> span {
|
||||
background: var(--panelHighlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .text {
|
||||
overflow-wrap: break-word;
|
||||
|
||||
|
@ -2,25 +2,25 @@
|
||||
<div class="_list_">
|
||||
<div class="_fullinfo" v-if="empty">
|
||||
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
||||
<div>{{ $t('noNotes') }}</div>
|
||||
<div>{{ $ts.noNotes }}</div>
|
||||
</div>
|
||||
|
||||
<MkError v-if="error" @retry="init()"/>
|
||||
|
||||
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
|
||||
<button class="_loadMore" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
|
||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
|
||||
<XNote :note="note" @update:note="updated(note, $event)" :detail="detail" :key="note._featuredId_ || note._prId_ || note.id"/>
|
||||
<XNote :note="note" @update:note="updated(note, $event)" :key="note._featuredId_ || note._prId_ || note.id"/>
|
||||
</XList>
|
||||
|
||||
<div v-show="more && !reversed" style="margin-top: var(--margin);">
|
||||
<button class="_loadMore" v-appear="$store.state.device.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
|
||||
<button class="_loadMore" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||
</button>
|
||||
</div>
|
||||
@ -55,12 +55,6 @@ export default defineComponent({
|
||||
required: true
|
||||
},
|
||||
|
||||
detail: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
|
||||
prop: {
|
||||
type: String,
|
||||
required: false
|
||||
|
@ -8,17 +8,17 @@
|
||||
@close="$refs.dialog.close()"
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<template #header>{{ $t('notificationSetting') }}</template>
|
||||
<template #header>{{ $ts.notificationSetting }}</template>
|
||||
<div v-if="showGlobalToggle" class="_section">
|
||||
<MkSwitch v-model:value="useGlobalSetting">
|
||||
{{ $t('useGlobalSetting') }}
|
||||
<template #desc>{{ $t('useGlobalSettingDesc') }}</template>
|
||||
{{ $ts.useGlobalSetting }}
|
||||
<template #desc>{{ $ts.useGlobalSettingDesc }}</template>
|
||||
</MkSwitch>
|
||||
</div>
|
||||
<div v-if="!useGlobalSetting" class="_section">
|
||||
<MkInfo>{{ $t('notificationSettingDesc') }}</MkInfo>
|
||||
<MkButton inline @click="disableAll">{{ $t('disableAll') }}</MkButton>
|
||||
<MkButton inline @click="enableAll">{{ $t('enableAll') }}</MkButton>
|
||||
<MkInfo>{{ $ts.notificationSettingDesc }}</MkInfo>
|
||||
<MkButton inline @click="disableAll">{{ $ts.disableAll }}</MkButton>
|
||||
<MkButton inline @click="enableAll">{{ $ts.enableAll }}</MkButton>
|
||||
<MkSwitch v-for="type in notificationTypes" :key="type" v-model:value="typesMap[type]">{{ $t(`_notification._types.${type}`) }}</MkSwitch>
|
||||
</div>
|
||||
</XModalWindow>
|
||||
|
@ -46,10 +46,10 @@
|
||||
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
|
||||
<Fa :icon="faQuoteRight"/>
|
||||
</MkA>
|
||||
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $t('youGotNewFollower') }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
|
||||
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $t('followRequestAccepted') }}</span>
|
||||
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $t('receiveFollowRequest') }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $t('accept') }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $t('reject') }}</button></div></span>
|
||||
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $t('groupInvited') }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $t('accept') }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $t('reject') }}</button></div></span>
|
||||
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
|
||||
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $ts.followRequestAccepted }}</span>
|
||||
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $ts.receiveFollowRequest }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $ts.reject }}</button></div></span>
|
||||
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $ts.reject }}</button></div></span>
|
||||
<span v-if="notification.type === 'app'" class="text">
|
||||
<Mfm :text="notification.body" :nowrap="!full"/>
|
||||
</span>
|
||||
@ -61,12 +61,12 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import { faIdCardAlt, faPlus, faQuoteLeft, faQuoteRight, faRetweet, faReply, faAt, faCheck, faPollH } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faClock } from '@fortawesome/free-regular-svg-icons';
|
||||
import noteSummary from '../../misc/get-note-summary';
|
||||
import { getNoteSummary } from '../../misc/get-note-summary';
|
||||
import XReactionIcon from './reaction-icon.vue';
|
||||
import MkFollowButton from './follow-button.vue';
|
||||
import notePage from '../filters/note';
|
||||
import { userPage } from '../filters/user';
|
||||
import { locale } from '../i18n';
|
||||
import { i18n } from '@/i18n';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
@ -91,7 +91,7 @@ export default defineComponent({
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
getNoteSummary: (text: string) => noteSummary(text, locale),
|
||||
getNoteSummary: (text: string) => getNoteSummary(text, i18n.locale),
|
||||
followRequestDone: false,
|
||||
groupInviteDone: false,
|
||||
connection: null,
|
||||
|
@ -5,12 +5,12 @@
|
||||
<XNotification v-else :notification="notification" :with-time="true" :full="true" class="_panel notification" :key="notification.id"/>
|
||||
</XList>
|
||||
|
||||
<button class="_loadMore" v-appear="$store.state.device.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" v-show="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
|
||||
<button class="_loadMore" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" v-show="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||
</button>
|
||||
|
||||
<p class="empty" v-if="empty">{{ $t('noNotifications') }}</p>
|
||||
<p class="empty" v-if="empty">{{ $ts.noNotifications }}</p>
|
||||
|
||||
<MkError v-if="error" @retry="init()"/>
|
||||
</div>
|
||||
@ -59,7 +59,7 @@ export default defineComponent({
|
||||
|
||||
computed: {
|
||||
allIncludeTypes() {
|
||||
return this.includeTypes ?? notificationTypes.filter(x => !this.$store.state.i.mutingNotificationTypes.includes(x));
|
||||
return this.includeTypes ?? notificationTypes.filter(x => !this.$i.mutingNotificationTypes.includes(x));
|
||||
}
|
||||
},
|
||||
|
||||
@ -70,9 +70,9 @@ export default defineComponent({
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $store.state.i が更新されると、
|
||||
// TODO: vue/vuexのバグか仕様かは不明なものの、プロフィール更新するなどして $i が更新されると、
|
||||
// mutingNotificationTypes に変化が無くてもこのハンドラーが呼び出され無駄なリロードが発生するのを直す
|
||||
'$store.state.i.mutingNotificationTypes': {
|
||||
'$i.mutingNotificationTypes': {
|
||||
handler() {
|
||||
if (this.includeTypes === null) {
|
||||
this.reload();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<XWindow ref="window"
|
||||
:initial-width="700"
|
||||
:initial-width="500"
|
||||
:initial-height="500"
|
||||
:can-resize="true"
|
||||
:close-right="true"
|
||||
@ -90,29 +90,29 @@ export default defineComponent({
|
||||
text: this.path,
|
||||
}, {
|
||||
icon: faExpandAlt,
|
||||
text: this.$t('showInPage'),
|
||||
text: this.$ts.showInPage,
|
||||
action: this.expand
|
||||
}, this.sideViewHook ? {
|
||||
icon: faColumns,
|
||||
text: this.$t('openInSideView'),
|
||||
text: this.$ts.openInSideView,
|
||||
action: () => {
|
||||
this.sideViewHook(this.path);
|
||||
this.$refs.window.close();
|
||||
}
|
||||
} : undefined, {
|
||||
icon: faExternalLinkAlt,
|
||||
text: this.$t('popout'),
|
||||
text: this.$ts.popout,
|
||||
action: this.popout
|
||||
}, null, {
|
||||
icon: faExternalLinkAlt,
|
||||
text: this.$t('openInNewTab'),
|
||||
text: this.$ts.openInNewTab,
|
||||
action: () => {
|
||||
window.open(this.url, '_blank');
|
||||
this.$refs.window.close();
|
||||
}
|
||||
}, {
|
||||
icon: faLink,
|
||||
text: this.$t('copyLink'),
|
||||
text: this.$ts.copyLink,
|
||||
action: () => {
|
||||
copyToClipboard(this.url);
|
||||
}
|
||||
|
@ -1,17 +1,20 @@
|
||||
<template>
|
||||
<div class="voxdxuby">
|
||||
<XNote v-if="note" v-model:note="note" :key="note.id" :detail="value.detailed"/>
|
||||
<XNote v-if="note && !value.detailed" v-model:note="note" :key="note.id + ':normal'"/>
|
||||
<XNoteDetailed v-if="note && value.detailed" v-model:note="note" :key="note.id + ':detail'"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import XNote from '@/components/note.vue';
|
||||
import XNoteDetailed from '@/components/note-detailed.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XNote
|
||||
XNote,
|
||||
XNoteDetailed,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
|
@ -49,9 +49,9 @@ export default defineComponent({
|
||||
canvas.toBlob(blob => {
|
||||
const data = new FormData();
|
||||
data.append('file', blob);
|
||||
data.append('i', this.$store.state.i.token);
|
||||
if (this.$store.state.settings.uploadFolder) {
|
||||
data.append('folderId', this.$store.state.settings.uploadFolder);
|
||||
data.append('i', this.$i.token);
|
||||
if (this.$store.state.uploadFolder) {
|
||||
data.append('folderId', this.$store.state.uploadFolder);
|
||||
}
|
||||
|
||||
fetch(apiUrl + '/drive/files/create', {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>{{ hpml.interpolate(value.title) }}</div>
|
||||
<MkRadio v-for="x in value.values" v-model:value="v" :value="x" :key="x">{{ x }}</MkRadio>
|
||||
<MkRadio v-for="x in value.values" v-model="v" :value="x" :key="x">{{ x }}</MkRadio>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="mrdgzndn">
|
||||
<Mfm :text="text" :is-note="false" :i="$store.state.i" :key="text"/>
|
||||
<Mfm :text="text" :is-note="false" :i="$i" :key="text"/>
|
||||
<MkUrlPreview v-for="url in urls" :url="url" :key="url" class="url"/>
|
||||
</div>
|
||||
</template>
|
||||
|