Compare commits
57 Commits
Author | SHA1 | Date | |
---|---|---|---|
944250f7fd | |||
ab0253ab07 | |||
758e054c92 | |||
187b44c7f3 | |||
587ea5b424 | |||
1a883f4f05 | |||
540e6e4f99 | |||
baf3d8f3ee | |||
7a66c9b5f3 | |||
15cd563612 | |||
e2556189de | |||
9236a8fd6c | |||
303c5abfb4 | |||
fc65190ef7 | |||
f47a564819 | |||
fa0814f939 | |||
ddd931a0a3 | |||
46010187c3 | |||
877bd52ed7 | |||
d964c5f27f | |||
d35b02fa23 | |||
21ece52a9f | |||
c2ae160d23 | |||
9c74c5c5dc | |||
2e80cebc11 | |||
f418eaecf9 | |||
901436a095 | |||
a905188e95 | |||
a21070c01b | |||
5d0ee544f4 | |||
e52a9e0a65 | |||
67bf6ff3ce | |||
000bee6327 | |||
19a232cad7 | |||
a744f75eb9 | |||
5cf07fc50f | |||
1143606bc8 | |||
09f4885f89 | |||
dfd92efa89 | |||
c3fcfad910 | |||
652588abed | |||
2b4d5b73b9 | |||
c08d959b59 | |||
7783c1e0e1 | |||
6afa67089a | |||
26928ab407 | |||
4f04421cb3 | |||
4d1c723496 | |||
ae5d537197 | |||
2d21685d22 | |||
d4c0d85cbc | |||
781b57585b | |||
a0b036a119 | |||
c6afc61c94 | |||
4168addbb2 | |||
600394458c | |||
f33785a09c |
@ -1,49 +0,0 @@
|
||||
version: 2.1
|
||||
|
||||
executors:
|
||||
docker:
|
||||
working_directory: /tmp/workspace
|
||||
docker:
|
||||
- image: docker:latest
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
parameters:
|
||||
with_deploy:
|
||||
type: boolean
|
||||
default: false
|
||||
executor: docker
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker:
|
||||
version: 19.03.13
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
docker build -t misskey/misskey .
|
||||
- when:
|
||||
condition: <<parameters.with_deploy>>
|
||||
steps:
|
||||
- run:
|
||||
name: Deploy
|
||||
command: |
|
||||
if [ "$DOCKERHUB_USERNAME$DOCKERHUB_PASSWORD" ]
|
||||
then
|
||||
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 -a misskey/misskey
|
||||
else
|
||||
echo -e '\033[0;33mAborted deploying to Docker Hub\033[0;39m'
|
||||
fi
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
docker:
|
||||
jobs:
|
||||
- docker:
|
||||
name: auto-build
|
||||
with_deploy: true
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
@ -1,12 +0,0 @@
|
||||
url: 'http://misskey.local'
|
||||
port: 8080
|
||||
db:
|
||||
host: localhost
|
||||
port: 5432
|
||||
db: test-misskey
|
||||
user: postgres
|
||||
pass: ''
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
id: aid
|
38
.github/CODEOWNERS
vendored
38
.github/CODEOWNERS
vendored
@ -1,38 +0,0 @@
|
||||
# PATH OWNERS
|
||||
/.autogen/ @acid-chicken
|
||||
/.circleci/ @syuilo @acid-chicken
|
||||
/.config/ @syuilo @AyaMorisawa @mei23 @acid-chicken @rinsuki
|
||||
# /.config/mongo_initdb_example.js @khws4v1
|
||||
/.github/ @syuilo @AyaMorisawa @acid-chicken
|
||||
/.vscode/ @acid-chicken
|
||||
/assets/ @syuilo # @tamaina
|
||||
/docs/ @syuilo
|
||||
/docs/*.en.md @AyaMorisawa # @skid9000
|
||||
# /docs/*.fr.md @BoFFire
|
||||
# /docs/docker.*.md @khws4v1
|
||||
/locales/ @syuilo
|
||||
/src/ @syuilo @AyaMorisawa @mei23 @acid-chicken @rinsuki
|
||||
# /src/crypto_key.cc @akihikodaki
|
||||
# /src/crypto_key.d.ts @akihikodaki
|
||||
/.dockerignore @syuilo # @khws4v1
|
||||
/.editorconfig @syuilo @AyaMorisawa
|
||||
/.eslintrc @syuilo
|
||||
/.gitattributes @syuilo
|
||||
/.gitignore @syuilo
|
||||
/.npmrc @syuilo
|
||||
/.vsls.json @AyaMorisawa
|
||||
/CHANGELOG.md @syuilo
|
||||
/CODE_OF_CONDUCT.md @syuilo
|
||||
/CONTRIBUTING.md @syuilo
|
||||
/Dockerfile @syuilo @AyaMorisawa @acid-chicken # @khws4v1
|
||||
/LICENSE @syuilo
|
||||
/README.md @syuilo @AyaMorisawa @acid-chicken # @nikhiljha
|
||||
# /binding.gyp @akihikodaki
|
||||
/crowdin.yml @syuilo
|
||||
# /docker-compose.yml @khws4v1
|
||||
/gulpfile.ts @syuilo @AyaMorisawa
|
||||
/jsconfig.json @syuilo @AyaMorisawa
|
||||
/package.json @syuilo @AyaMorisawa
|
||||
/tsconfig.json @syuilo @AyaMorisawa
|
||||
/tslint.json @syuilo @AyaMorisawa
|
||||
/webpack.config.ts @syuilo @AyaMorisawa
|
21
.github/workflows/lint.yml
vendored
Normal file
21
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12.x
|
||||
- run: yarn install
|
||||
- run: yarn lint
|
@ -1,4 +1,5 @@
|
||||
name: Node.js CI
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@ -7,12 +8,12 @@ on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
mocha:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x, 16.x]
|
||||
node-version: [16.x]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
@ -44,16 +45,43 @@ jobs:
|
||||
- name: Build
|
||||
run: yarn build
|
||||
- name: Test
|
||||
run: yarn test
|
||||
run: yarn mocha
|
||||
|
||||
lint:
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:12.2-alpine
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:4.0-alpine
|
||||
ports:
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v1
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12.x
|
||||
- run: yarn install
|
||||
- run: yarn lint
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
- name: Check yarn.lock
|
||||
run: git diff --exit-code yarn.lock
|
||||
- name: Copy Configure
|
||||
run: cp test/test.yml .config
|
||||
- name: Build
|
||||
run: yarn build
|
||||
- name: Test
|
||||
run: yarn e2e
|
43
CHANGELOG.md
43
CHANGELOG.md
@ -7,6 +7,49 @@
|
||||
|
||||
-->
|
||||
|
||||
## 12.95.0 (2021/10/31)
|
||||
|
||||
### Improvements
|
||||
- スレッドミュート機能
|
||||
|
||||
### Bugfixes
|
||||
- リレー向けのActivityが一部実装で除外されてしまうことがあるのを修正
|
||||
- 削除したノートやユーザーがリモートから参照されると復活することがあるのを修正
|
||||
- クライアント: ページ編集時のドロップダウンメニューなどが動作しない問題を修正
|
||||
- クライアント: コントロールパネルのカスタム絵文字タブが切り替わらないように見える問題を修正
|
||||
- API: ユーザー情報の hasUnreadChannel が常に false になっている問題を修正
|
||||
|
||||
## 12.94.1 (2021/10/25)
|
||||
|
||||
### Improvements
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: ユーザーページのナビゲーションが失敗する問題を修正
|
||||
|
||||
## 12.94.0 (2021/10/25)
|
||||
|
||||
### Improvements
|
||||
- クライアント: 画像ビューアを強化
|
||||
- クライアント: メンションにユーザーのアバターを表示するように
|
||||
- クライアント: デザインの調整
|
||||
- クライアント: twemojiをセルフホスティングするように
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: CWで画像が隠されたとき、画像の高さがおかしいことになる問題を修正
|
||||
|
||||
### NOTE
|
||||
- このバージョンから、iOS 15未満のサポートがされなくなります。対象のバージョンをお使いの方は、iOSのバージョンアップを行ってください。
|
||||
|
||||
## 12.93.2 (2021/10/23)
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: ウィジェットを追加できない問題を修正
|
||||
|
||||
## 12.93.1 (2021/10/23)
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: 通知上でローカルのリアクションが表示されないのを修正
|
||||
|
||||
## 12.93.0 (2021/10/23)
|
||||
|
||||
### Improvements
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://circleci.com/gh/misskey-dev/misskey)
|
||||
[](https://david-dm.org/misskey-dev/misskey)
|
||||
[](http://makeapullrequest.com)
|
||||
[](https://github.com/humanetech-community/awesome-humane-tech)
|
||||
|
BIN
assets/user-unknown.png
Normal file
BIN
assets/user-unknown.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
@ -1,3 +1,3 @@
|
||||
{
|
||||
"baseUrl": "http://localhost"
|
||||
"baseUrl": "http://localhost:61812"
|
||||
}
|
||||
|
@ -128,7 +128,8 @@ describe('After user signup', () => {
|
||||
cy.get('[data-cy-signin-username] input').type('alice');
|
||||
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
|
||||
|
||||
cy.contains('アカウントが凍結されています');
|
||||
// TODO: cypressにブラウザの言語指定できる機能が実装され次第英語のみテストするようにする
|
||||
cy.contains(/アカウントが凍結されています|This account has been suspended due to/gi);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
_lang_: "العربية"
|
||||
headlineMisskey: "شبكة مرتبطة بالملاحظات"
|
||||
introMisskey: "اهلا بك! ميسكي هو منصة تدوين مصغر لا مركزية ومفتوحة المصدر.\nيمكنك مشاركة \"ملاحظات\" عن ما يجري حولك، وإخبار الجميع عن نفسك 📡\nتسمح لك \"الانفعالات\" بتعبير عن شعورك حول ملاحظات الآخرين 👍\nاكتشف عالمًا جديدًا 🚀"
|
||||
monthAndDay: "{day}/{month}"
|
||||
search: "البحث"
|
||||
@ -12,6 +13,7 @@ ok: " حسناً"
|
||||
gotIt: "فهِمت"
|
||||
cancel: " إلغاء"
|
||||
enterUsername: "أدخِل إسم مسخدم"
|
||||
renotedBy: "أعاد {user} نشر ملاحظة"
|
||||
noNotes: "لم يتم العثور على أية ملاحظات"
|
||||
noNotifications: "ليس هناك أية اشعارات"
|
||||
instance: "مثيل الخادم"
|
||||
@ -26,7 +28,7 @@ login: "لِج"
|
||||
loggingIn: "جارٍ تسجيل الدخول"
|
||||
logout: "الخروج"
|
||||
signup: "أنشئ حسابًا"
|
||||
uploading: "عملية الإرسال جارية"
|
||||
uploading: "يرفع..."
|
||||
save: "حفظ"
|
||||
users: "المستخدمون"
|
||||
addUser: "اضافة مستخدم"
|
||||
@ -37,7 +39,7 @@ favorited: "تمت الإضافة إلى المفضلة."
|
||||
alreadyFavorited: "تمت إضافته بالفعل إلى المفضلة."
|
||||
cantFavorite: "تعذرت الإضافة إلى المفضلة."
|
||||
pin: "دبّسها على الصفحة الشخصية"
|
||||
unpin: "ألغ تثبيتها من ملفك الشخصي"
|
||||
unpin: "ألغ تدبيسها من ملفك الشخصي"
|
||||
copyContent: "انسخ المحتوى"
|
||||
copyLink: "انسخ الرابط"
|
||||
delete: "حذف"
|
||||
@ -63,13 +65,14 @@ files: "الملفات"
|
||||
download: "تنزيل"
|
||||
driveFileDeleteConfirm: "أمتأكد من حذف ملف {name}؟ كل الملاحظات المُرفق بها هذا الملف ستحذف."
|
||||
unfollowConfirm: "أمتأكد من إلغاء متابعة {name}؟"
|
||||
exportRequested: "قد تستغرق عملية التصدير بعض الوقت. بمجرد الانتهاء ستتم إضافة الملف الناتج إلى قرص التخزين."
|
||||
importRequested: "يستغرق الاستيراد بعض الوقت"
|
||||
lists: "القوائم"
|
||||
noLists: "ليس لديك أية قائمة"
|
||||
note: "ملاحظة"
|
||||
notes: "الملاحظات"
|
||||
following: "المتابَعون"
|
||||
followers: "المتابِعين"
|
||||
followers: "المتابِعون"
|
||||
followsYou: "يتابعك"
|
||||
createList: "إنشاء قائمة"
|
||||
manageLists: "إدارة القوائم"
|
||||
@ -77,10 +80,12 @@ error: "خطأ"
|
||||
somethingHappened: "حدث خطأ"
|
||||
retry: "حاول مجددًا"
|
||||
pageLoadError: "فشل تحميل الصفحة"
|
||||
pageLoadErrorDescription: "عادة ما يكون السبب خطأ في الشبكة أو التخزين المؤقت للمتصفح. امسح التخزين المؤقت ثم أعد المحاولة لاحقًا."
|
||||
serverIsDead: "الخادم لا يستجيب، حاول بعد قليل"
|
||||
youShouldUpgradeClient: "حدّث الصفحة لعرضها."
|
||||
enterListName: "اسم القائمة"
|
||||
privacy: "الخصوصية"
|
||||
makeFollowManuallyApprove: "القبول يدويا طلبات الإشتراك"
|
||||
makeFollowManuallyApprove: "قبول طلبات الإشتراك يدويا"
|
||||
defaultNoteVisibility: "مدى الرؤية الافتراضي"
|
||||
follow: "تابِع"
|
||||
followRequest: "طلب اشتراك"
|
||||
@ -88,7 +93,11 @@ followRequests: "طلبات الإشتراك"
|
||||
unfollow: "إلغاء الاشتراك"
|
||||
followRequestPending: "طلبات الإشتراك المعلّقة"
|
||||
enterEmoji: "أدخل إيموجي"
|
||||
renote: "أعد النشر"
|
||||
unrenote: "إلغاء مشاركة الملاحظة"
|
||||
renoted: "أُعيد نشره"
|
||||
cantRenote: "لا يمكن إعادة نشر الملاحظة"
|
||||
cantReRenote: "لا يمكنك إعادة نشر ملاحظة معاد نشرها"
|
||||
quote: "اقتبس"
|
||||
pinnedNote: "ملاحظة مدبسة"
|
||||
pinned: "دبّسها على الصفحة الشخصية"
|
||||
@ -97,9 +106,12 @@ clickToShow: "اضغط للعرض"
|
||||
sensitive: "محتوى حساس"
|
||||
add: "إضافة"
|
||||
reaction: "تفاعل"
|
||||
reactionSettingDescription: "اختر التفاعلات المفضلة التي تريد تثبيتها في منتقي التفاعلات."
|
||||
reactionSettingDescription2: "اسحب لإعادة التنظيم ، انقر للحذف ، استخدم \"+\" للإضافة."
|
||||
rememberNoteVisibility: "تذكر إعدادت مدى رؤية الملاحظات"
|
||||
attachCancel: "أزل المرفق"
|
||||
markAsSensitive: "علّمه كمحتوى حساس"
|
||||
unmarkAsSensitive: "ألغ تعيينه كمحتوى حساس"
|
||||
enterFileName: "ادخل اسم الملف"
|
||||
mute: "اكتم"
|
||||
unmute: "إلغاء الكتم"
|
||||
@ -109,7 +121,12 @@ suspend: "علِق"
|
||||
unsuspend: "ألغ التعليق"
|
||||
blockConfirm: "أمتأكد من حجب هذا الحساب؟"
|
||||
unblockConfirm: "أمتأكد من إلغاء حجب هذا الحساب؟"
|
||||
suspendConfirm: "أمتأكد من تعليق الحساب؟"
|
||||
unsuspendConfirm: "أمتأكد من إلغاء تعليق؟"
|
||||
selectList: "اختر قائمة"
|
||||
selectAntenna: "اختر هوائيًا"
|
||||
selectWidget: "اختر ودجة"
|
||||
editWidgets: "عدّل الودجات"
|
||||
editWidgetsExit: "تم"
|
||||
customEmojis: "إيموجي مخصص"
|
||||
emoji: "الوجوه التعبيرية"
|
||||
@ -119,7 +136,12 @@ emojiUrl: "رابط الوجه التعبيري"
|
||||
addEmoji: "إضافة إيموجي"
|
||||
settingGuide: "الإعدادات المستحسنة"
|
||||
cacheRemoteFiles: "خزن مؤقتا الملفات البعيدة"
|
||||
flagAsBot: "علّمه كحساب آلي"
|
||||
flagAsBotDescription: "فعّل هذا الخيار إذا كان هذا الحساب يُدار عبر برمجية. إذا فُعل فسيكون بمثابة علامة للمطورين الآخرين لتجنب سلاسل لا متناعية من التفاعل بين حسابات الآلية وضبط أنظمة ميسكي للتعامل مع هذا الحساب كروبوت."
|
||||
flagAsCat: "علّم هذا الحساب كحساب قط"
|
||||
flagAsCatDescription: "فعّل هذا الخيار لوضع علامة على الحساب لتوضيح أنه حساب قط."
|
||||
autoAcceptFollowed: "اقبل طلبات المتابعة تلقائيا من الحسابات المتابَعة"
|
||||
addAccount: "أضف حساباً"
|
||||
loginFailed: "فشل الولوج"
|
||||
showOnRemote: "رؤيته على مثيل الخادم البُعدي"
|
||||
general: "الرئيسية"
|
||||
@ -136,8 +158,10 @@ recipient: "المرسَل إليه·ها"
|
||||
annotation: "التعليقات"
|
||||
federation: "الفديرالية"
|
||||
instances: "مثيل الخادم"
|
||||
registeredAt: "مسجل في"
|
||||
latestRequestSentAt: "آخر طلب أرسِل في"
|
||||
latestRequestReceivedAt: "آخر طلب تُلقي في"
|
||||
latestStatus: "الحالات الأخيرة"
|
||||
storageUsage: "مساحة التخزين المستخدمة"
|
||||
charts: "المنحنيات البيانية"
|
||||
perHour: "في الساعة"
|
||||
@ -157,6 +181,11 @@ disk: "قرص التخزين"
|
||||
instanceInfo: "معلومات مثيل الخادم"
|
||||
statistics: "الإحصائيات"
|
||||
clearQueue: "تفريغ قائمة الإنتظار"
|
||||
clearQueueConfirmTitle: "أتريد مسح الطابور؟"
|
||||
clearCachedFiles: "امسح التخزين المؤقت"
|
||||
clearCachedFilesConfirm: "أتريد حذف التخزين المؤقت للملفات البعيدة؟"
|
||||
blockedInstances: "المثلاء المحجوبون"
|
||||
blockedInstancesDescription: "قائمة بالمثلاء التي تريد حظرها بحيث كل نطاق في سطر لوحده. بعد إدراجهم لن يتمكنوا من التفاعل مع هذا المثيل."
|
||||
muteAndBlock: "تم كتمها / تم حجبها"
|
||||
mutedUsers: "الحسابات التي تم كتمها"
|
||||
blockedUsers: "الحسابات التي تم حظرها"
|
||||
@ -183,7 +212,7 @@ usernameOrUserId: "اسم المستخدم أو معرّفه"
|
||||
noSuchUser: "لم يُعثَر على المستخدم"
|
||||
lookup: "البحث"
|
||||
announcements: "الإعلانات"
|
||||
imageUrl: "عنوان URL للصورة"
|
||||
imageUrl: "رابط الصورة"
|
||||
remove: "حذف"
|
||||
removed: "تم حذفه بنجاح"
|
||||
removeAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
||||
@ -191,11 +220,11 @@ deleteAreYouSure: "متأكد من أنك تريد حذف {x}؟"
|
||||
resetAreYouSure: "هل تريد إعادة التعيين؟"
|
||||
saved: "تم حفظه"
|
||||
messaging: "المحادثة"
|
||||
upload: "تحميل"
|
||||
upload: "ارفع"
|
||||
fromDrive: "من المخزن"
|
||||
fromUrl: "من عنوان URL"
|
||||
uploadFromUrl: "التحميل عبر URL"
|
||||
uploadFromUrlDescription: "رابط الملف المراد تحميله "
|
||||
fromUrl: "عبر رابط"
|
||||
uploadFromUrl: "ارفع عبر رابط"
|
||||
uploadFromUrlDescription: "رابط الملف المراد رفعه"
|
||||
uploadFromUrlRequested: "الرفع مطلوب"
|
||||
uploadFromUrlMayTakeTime: "سيستغرق بعض الوقت لاتمام الرفع "
|
||||
explore: "استكشاف"
|
||||
@ -240,7 +269,7 @@ unableToDelete: "لا يمكن حذفه"
|
||||
inputNewFileName: "ادخل الإسم الجديد للملف"
|
||||
inputNewFolderName: "ادخل الإسم الجديد للمجلد"
|
||||
hasChildFilesOrFolders: "الان الملف غير فارغ. لا يمكن حذفه"
|
||||
copyUrl: "انسخ عنوان URL"
|
||||
copyUrl: "انسخ الرابط"
|
||||
rename: "إعادة التسمية"
|
||||
avatar: "الصورة الرمزية"
|
||||
banner: "الصورة الرأسية"
|
||||
@ -259,7 +288,7 @@ instanceName: "اسم مثيل الخادم"
|
||||
instanceDescription: "وصف مثيل الخادم"
|
||||
maintainerName: "المدير"
|
||||
maintainerEmail: "عنوان بريد المدير الإلكتروني"
|
||||
tosUrl: "عنوان URL لشروط الخدمة"
|
||||
tosUrl: "رابط صفحة شروط الخدمة"
|
||||
thisYear: "هذا العام"
|
||||
thisMonth: "هذا الشهر"
|
||||
today: "اليوم"
|
||||
@ -281,10 +310,10 @@ iconUrl: "رابط الأيقونة"
|
||||
bannerUrl: "رابط صورة اللافتة"
|
||||
backgroundImageUrl: "رابط صورة الخلفية"
|
||||
basicInfo: "المعلومات الأساسية "
|
||||
pinnedUsers: "المستخدمون المثبتون"
|
||||
pinnedUsersDescription: "قائمة المستخدمين المثبتين في لسان \"استكشف\" ، اجعل كل اسم مستخدم في سطر لوحده."
|
||||
pinnedPages: "الصفحات المثبتة"
|
||||
pinnedPagesDescription: "أدخل مسار الصفحات التي تريد تثبيتها في أعلى هذا الموقع، اجعل كل مسار في سطر لوحده."
|
||||
pinnedUsers: "المستخدمون المدبسون"
|
||||
pinnedUsersDescription: "قائمة المستخدمين المدبسين في لسان \"استكشف\" ، اجعل كل اسم مستخدم في سطر لوحده."
|
||||
pinnedPages: "الصفحات المدبسة"
|
||||
pinnedPagesDescription: "أدخل مسار الصفحات التي تريد تدبيسها في أعلى هذا الموقع، اجعل كل مسار في سطر لوحده."
|
||||
pinnedNotes: "ملاحظة مدبسة"
|
||||
hcaptchaSiteKey: "مفتاح الموقع"
|
||||
hcaptchaSecretKey: "المفتاح السري"
|
||||
@ -302,9 +331,11 @@ withFileAntenna: "ملاحظات تحوي ملفات فقط"
|
||||
caseSensitive: "حساسية حالة الأحرف"
|
||||
withReplies: "بالردود"
|
||||
notesAndReplies: "الملاحظات والردود"
|
||||
withFiles: "بالمرفقات"
|
||||
withFiles: "ذات مرفقات"
|
||||
silence: "اكتم"
|
||||
silenceConfirm: "أمتأكد من كتم هذا المستخدم؟"
|
||||
unsilence: "إلغاء الكتم"
|
||||
unsilenceConfirm: "أمتأكد من إلغاء كتم هذا المستخدم؟"
|
||||
popularUsers: "المستخدمون الشائعون"
|
||||
recentlyUpdatedUsers: "أصحاب النشاطات الأخيرة"
|
||||
recentlyRegisteredUsers: "المستخدمون المنضمون حديثًا"
|
||||
@ -331,14 +362,20 @@ newPasswordIs: "كلمتك السرية الجديدة هي {password}"
|
||||
reduceUiAnimation: "قلص تأثيرات الواجهة"
|
||||
share: "شارِك"
|
||||
notFound: "غير موجود"
|
||||
notFoundDescription: "تعذر العثور على صفحة يقود إليها هذا الرابط."
|
||||
uploadFolder: "المجلد الافتراضي للرفع"
|
||||
cacheClear: "مسح ذاكرة التخزين المؤقت"
|
||||
markAsReadAllNotifications: "وضع جميع الإشعارات كأنها مقروءة"
|
||||
markAsReadAllUnreadNotes: "علّم جميع الملاحظات كمقروءة"
|
||||
markAsReadAllTalkMessages: "علّم جميع الرسائل كمقروءة"
|
||||
help: "المساعدة"
|
||||
inputMessageHere: "اكتب رسالتك هنا"
|
||||
close: "اغلق"
|
||||
group: "الفريق"
|
||||
groups: "الفِرَق"
|
||||
createGroup: "انشئ فريقًا"
|
||||
ownedGroups: "مجموعات المالك"
|
||||
joinedGroups: "المجموعات المنضم إليها"
|
||||
invites: "دعوة"
|
||||
groupName: "اسم الفريق"
|
||||
members: "الأعضاء"
|
||||
@ -352,13 +389,18 @@ next: "التالية"
|
||||
retype: "أعد الكتابة"
|
||||
noteOf: "ملاحظات {user}"
|
||||
inviteToGroup: "دعوة إلى فريق"
|
||||
maxNoteTextLength: "حد عدد المحارف لكل ملاحظة"
|
||||
quoteAttached: "اِقتُبسَ"
|
||||
noMessagesYet: "ليس هناك رسائل بعد"
|
||||
newMessageExists: "لقد تلقيت رسالة جديدة"
|
||||
onlyOneFileCanBeAttached: "يمكنك إرفاق ملف واحد بالرسالة"
|
||||
signinRequired: "رجاءً لِج"
|
||||
invitations: "دعوة"
|
||||
invitationCode: "رمز الدعوة"
|
||||
checking: "التحقق جارٍ"
|
||||
available: "متوفر"
|
||||
unavailable: "غير متوفر"
|
||||
usernameInvalidFormat: "يمكنك استخدام A-z، a-z، 0-9، _"
|
||||
tooShort: "قصير جدًا"
|
||||
tooLong: "طويل جدًا"
|
||||
weakPassword: "الكلمة السرية ضعيفة"
|
||||
@ -367,11 +409,15 @@ strongPassword: "الكلمة السرية قوية"
|
||||
passwordMatched: "التطابق صحيح!"
|
||||
passwordNotMatched: "غير متطابقتان"
|
||||
signinWith: "الولوج عبر {x}"
|
||||
signinFailed: "فشل الولوج، خطأ في اسم المستخدم أو كلمة المرور."
|
||||
or: "أو"
|
||||
language: "اللغة"
|
||||
uiLanguage: "لغة واجهة المستخدم"
|
||||
groupInvited: "دُعيت إلى مجموعة"
|
||||
aboutX: "عن {x}"
|
||||
useOsNativeEmojis: "استخدم الإيموجيات الخاصة بنظام التشغيل"
|
||||
youHaveNoGroups: "لا تمتلك أية فِرَق"
|
||||
joinOrCreateGroup: "احصل على دعوة لمجموعة أو أنشئ واحدة."
|
||||
noHistory: "السجل فارغ"
|
||||
signinHistory: "تاريخ تسجيل الدخول"
|
||||
doing: "انتظر لحظة"
|
||||
@ -379,8 +425,10 @@ category: "الفئات"
|
||||
tags: "الوسوم"
|
||||
docSource: "مصدر هذا المستند"
|
||||
createAccount: "أنشئ حسابًا"
|
||||
existingAccount: "الحسابات الموجودة"
|
||||
regenerate: "أعِد التوليد"
|
||||
fontSize: "حجم الخط"
|
||||
noFollowRequests: "ليس لديك طلبات متابعة معلقة"
|
||||
openImageInNewTab: "إفتح الصورة بصفحة جديدة"
|
||||
dashboard: "لوحة التحكم"
|
||||
local: "المحلي"
|
||||
@ -421,13 +469,17 @@ nothing: "لا يوجد شيء هنا"
|
||||
lastUsedDate: "آخر استخدام"
|
||||
state: "الحالة"
|
||||
sort: "ترتيب حسب"
|
||||
ascendingOrder: "تصاعدي"
|
||||
descendingOrder: "تنازلي"
|
||||
output: "الخارجة"
|
||||
updateRemoteUser: "تحديث المعلومات عن المستخدم البعيد"
|
||||
deleteAllFiles: "حذف كافة الملفات"
|
||||
deleteAllFilesConfirm: "أتريد حذف كل الملفات؟"
|
||||
removeAllFollowing: "ألغ متابعة كل المتابِعين"
|
||||
removeAllFollowing: "ألغ متابعة كل المتابَعين"
|
||||
userSuspended: "تم تعليق هذا المستخدم."
|
||||
userSilenced: "تم إسكات هذا المستخدم."
|
||||
yourAccountSuspendedTitle: "هذا الحساب معلق"
|
||||
menu: "القائمة"
|
||||
addItem: "إضافة عنصر"
|
||||
rooms: "الغرفة"
|
||||
relays: "المُرَحلات"
|
||||
@ -435,9 +487,15 @@ addRelay: "إضافة مُرحّل"
|
||||
addedRelays: "المرحلات التي تم إضافتها"
|
||||
deletedNote: "ملاحظة محذوفة"
|
||||
invisibleNote: "ملاحظة مخفية"
|
||||
enableInfiniteScroll: "فعّل التمرير المتواصل"
|
||||
visibility: "الظهور"
|
||||
poll: "استطلاع رأي"
|
||||
useCw: "إخفاء المحتوى"
|
||||
enablePlayer: "افتح مشغل الفيديو"
|
||||
disablePlayer: "أغلق مشغل الفيديو"
|
||||
themeEditor: "مصمم القوالب"
|
||||
description: "الوصف"
|
||||
leaveConfirm: "لديك تغييرات غير محفوظة. أتريد المتابعة دون حفظها؟"
|
||||
manage: "إدارة "
|
||||
plugins: "الإضافات"
|
||||
width: "العرض"
|
||||
@ -445,12 +503,14 @@ height: "الإرتفاع"
|
||||
large: "كبير"
|
||||
medium: "متوسط"
|
||||
small: "صغير"
|
||||
generateAccessToken: "ولّد رمز الوصول"
|
||||
permission: "أذونات"
|
||||
enableAll: "تشغيل الكل"
|
||||
disableAll: "تعطيل الكل"
|
||||
tokenRequested: "منح حق الوصول إلى الحساب"
|
||||
notificationType: "أنواع الإشعارات"
|
||||
edit: "التعديل"
|
||||
emailServer: "خادم البريد الإلكتروني"
|
||||
email: "البريد الإلكتروني "
|
||||
emailAddress: "عنوان البريد الالكتروني"
|
||||
smtpHost: "المضيف"
|
||||
@ -461,6 +521,12 @@ makeActive: "تفعيل"
|
||||
display: "المظهر"
|
||||
copy: "نسخ"
|
||||
metrics: "المقاييس"
|
||||
channel: "القنوات"
|
||||
create: "أنشئ"
|
||||
notificationSetting: "إعدادات التنبيهات"
|
||||
notificationSettingDesc: "اختر نوع التنبيهات المراد عرضها"
|
||||
other: "منوعات"
|
||||
regenerateLoginToken: "أعد توليد الرمز"
|
||||
fileIdOrUrl: "معرف الملف أو رابط"
|
||||
chatOpenBehavior: "سلوك نفاذة المحادثة عند فتحها"
|
||||
behavior: "السلوك"
|
||||
@ -468,7 +534,7 @@ sample: "مثال"
|
||||
abuseReports: "البلاغات"
|
||||
reportAbuse: "البلاغات"
|
||||
reportAbuseOf: "أبلغ عن {name}"
|
||||
fillAbuseReportDescription: "أكتب بالتفصيل سبب الإبلاغ، إذا كنت تبلغ عن ملاحظة أرفق رابط لها."
|
||||
fillAbuseReportDescription: "أكتب بالتفصيل سبب البلاغ، إذا كنت تبلغ عن ملاحظة أرفق رابط لها."
|
||||
abuseReported: "أُرسل البلاغ، شكرًا لك"
|
||||
send: "أرسل"
|
||||
abuseMarkAsResolved: "علّم البلاغ كمحلول"
|
||||
@ -486,7 +552,9 @@ manageAccessTokens: "إدارة رموز الوصول"
|
||||
accountInfo: "معلومات الحساب"
|
||||
notesCount: "عدد الملاحظات"
|
||||
repliesCount: "عدد الردود المرسلة"
|
||||
renotesCount: "عدد الملاحظات المعاد نشرها (المرسلة)"
|
||||
repliedCount: "عدد الردود المستلمة"
|
||||
renotedCount: "عدد الملاحظات المعاد نشرها (المستلمة)"
|
||||
followingCount: "عدد الحسابات المتابَعة"
|
||||
followersCount: "عدد المتابِعين"
|
||||
sentReactionsCount: "عدد الانفعالات المرسلة"
|
||||
@ -495,32 +563,141 @@ pollVotesCount: "عدد الاستطلاعات المرسلة"
|
||||
pollVotedCount: "عدد الاستطلاعات المستلمة"
|
||||
yes: "نعم"
|
||||
no: "لا"
|
||||
driveFilesCount: "عدد الملفات في قرص التخزين"
|
||||
useSystemFont: "استخدم الخط الافتراضية للنظام"
|
||||
experimentalFeatures: "ميّزات اختبارية"
|
||||
developer: "المطور"
|
||||
clearCache: "امسح التخزين المؤقت"
|
||||
currentVersion: "الإصدار الحالي"
|
||||
latestVersion: "آخر نسخة مستقرة"
|
||||
usageAmount: "الإستخدام"
|
||||
capacity: "السعة"
|
||||
inUse: "مستخدم"
|
||||
useReactionPickerForContextMenu: "افتح منتقي التفاعلات عند التقر بالزر الأيمن"
|
||||
typingUsers: "{users} يكتب(ون)..."
|
||||
jumpToSpecifiedDate: "انتقل إلى التاريخ المحدد"
|
||||
showingPastTimeline: "أنت تستعرض حاليًا خيطًا زمنيًا قديمًا"
|
||||
markAllAsRead: "علّم الكل كمقروء"
|
||||
goBack: "رجوع"
|
||||
unlikeConfirm: "أتريد إلغاء إعجابك؟"
|
||||
fullView: "ملء الشاشة"
|
||||
quitFullView: "اخرج من وضع ملء للشاشة"
|
||||
addDescription: "أضف وصفًا"
|
||||
info: "عن"
|
||||
userInfo: "معلومات المستخدم"
|
||||
unknown: "مجهول"
|
||||
onlineStatus: "الحالة"
|
||||
hideOnlineStatus: "اخف الحالة"
|
||||
online: "متصل"
|
||||
active: "نشط"
|
||||
offline: "غير متصل"
|
||||
notRecommended: "غير مستحسن"
|
||||
botProtection: "الحماية من الحسابات الآلية"
|
||||
instanceBlocking: "المثيلات المحجوبة"
|
||||
selectAccount: "اختر حسابًا"
|
||||
enabled: "مفعّل"
|
||||
disabled: "معطّل"
|
||||
quickAction: "الإجراءات السّريعة"
|
||||
user: "المستخدمون"
|
||||
administration: "إدارة "
|
||||
accounts: "الحسابات"
|
||||
switch: "بدّل"
|
||||
noBotProtectionWarning: "لم تضبط الحماية من الحسابات الآلية"
|
||||
configure: "اضبط"
|
||||
postToGallery: "انشر في المعرض"
|
||||
gallery: "المعرض"
|
||||
recentPosts: "المشاركات الحديثة"
|
||||
shareWithNote: "شاركه في ملاحظة"
|
||||
ads: "الإعلانات"
|
||||
expiration: "ينتهي استطلاع الرأي في"
|
||||
priority: "الأولوية"
|
||||
high: "عالية"
|
||||
middle: "متوسط"
|
||||
low: "منخفضة"
|
||||
emailNotConfiguredWarning: "لم تعيّن بريدًا إلكترونيًا"
|
||||
ratio: "النسبة"
|
||||
previewNoteText: "اعرض معاينة"
|
||||
customCss: "CSS مخصصة"
|
||||
global: "الشامل"
|
||||
squareAvatars: "اعرض شكل الصور الرمزية كمربعات"
|
||||
sent: "أرسل"
|
||||
received: "اُستلم"
|
||||
searchResult: "نتائج البحث"
|
||||
hashtags: "الوسوم"
|
||||
learnMore: "راجع المزيد"
|
||||
misskeyUpdated: "حُدث ميسكي!"
|
||||
whatIsNew: "اعرض التغييرات"
|
||||
translate: "ترجم"
|
||||
translatedFrom: "تُرجم من {x}"
|
||||
accountDeletionInProgress: "حذف الحساب جارٍ"
|
||||
usernameInfo: "الاسم الذي يميزك عن بافي مستخدمي هذا الخادم، يمكنك استخدام الحروف اللاتينية (a~z, A~Z) والأرقام (0~9) والشرطة السفلية (_). لا يمكنك تغييره بعد تسجيله."
|
||||
lastCommunication: "آخر تواصل"
|
||||
itsOn: "مفعّل"
|
||||
itsOff: "معطّل"
|
||||
emailRequiredForSignup: "عنوان البريد الإلكتروني إلزامي للتسجيل"
|
||||
filter: "رشّح"
|
||||
controlPanel: "لوحة التحكم"
|
||||
manageAccounts: "إدارة الحسابات"
|
||||
makeReactionsPublic: "اجعل سجل التفاعلات علنيًا"
|
||||
makeReactionsPublicDescription: "هذا سيجعل قائمة تفاعلاتك مرئية للعلن."
|
||||
classic: "تقليدي"
|
||||
_docs:
|
||||
admin: "إدارة "
|
||||
_gallery:
|
||||
unlike: "أزل الإعجاب"
|
||||
_email:
|
||||
_follow:
|
||||
title: "يتابعك"
|
||||
_registry:
|
||||
keys: "المفاتيح"
|
||||
domain: "النّطاق"
|
||||
createKey: "أنشئ مفتاحًا"
|
||||
_aboutMisskey:
|
||||
about: "ميسكي هو برمجية مفتوحة المصدر يطورها syuilo منذ 2014."
|
||||
contributors: "المساهم الرئيسي"
|
||||
allContributors: "كل المساهمين"
|
||||
source: "الشفرة المصدرية"
|
||||
translation: "ترجم ميسكي"
|
||||
donate: "تبرع لميسكي"
|
||||
morePatrons: "نحن نقدر الدعم الذي قدمه العديد من الأشخاص الذين لم نذكرهم. شكرًا لكم 🥰"
|
||||
patrons: "الداعمون"
|
||||
_nsfw:
|
||||
force: "اخف كل الوسائط"
|
||||
_mfm:
|
||||
mention: "أشر الى"
|
||||
hashtag: "الوسوم"
|
||||
url: "الرابط"
|
||||
urlDescription: "يمكن عرض الروابط"
|
||||
link: "رابط"
|
||||
bold: "عريض"
|
||||
small: "صغير"
|
||||
quote: "اقتبس"
|
||||
emoji: "إيموجي مخصص"
|
||||
search: "البحث"
|
||||
_reversi:
|
||||
gameSettings: "إعدادات اللعبة"
|
||||
chooseBoard: "اختر اللوح"
|
||||
blackOrWhite: "أسود/أبيض"
|
||||
blackIs: "{name} سيلعب بالأسود"
|
||||
botSettings: "خيارات الحسابات الآلية"
|
||||
waitingBoth: "استعد"
|
||||
ready: "جاهز"
|
||||
cancelReady: "ألغ الجهوزية"
|
||||
opponentTurn: "دور الخصم"
|
||||
myTurn: "دورك"
|
||||
turnOf: "دور {name}"
|
||||
pastTurnOf: "دور {name}"
|
||||
surrender: "استسلم"
|
||||
drawn: "تعادل"
|
||||
won: "فاز {name}"
|
||||
black: "أسود"
|
||||
white: "أبيض"
|
||||
total: "المجموع"
|
||||
turnCount: "الدور {count}"
|
||||
myGames: "جولاتي"
|
||||
allGames: "كل الجولات"
|
||||
ended: "انتهت"
|
||||
playing: "يُلعب الآن"
|
||||
_channel:
|
||||
featured: "المتداوَلة"
|
||||
_menuDisplay:
|
||||
@ -530,11 +707,15 @@ _theme:
|
||||
install: "تنصيب قالب"
|
||||
manage: "إدارة القوالب"
|
||||
code: "شيفرة القالب"
|
||||
description: "الوصف"
|
||||
installed: "تم تنصيب {name}"
|
||||
make: "إنشاء قالب"
|
||||
alpha: "الشفافية"
|
||||
keys:
|
||||
link: "رابط"
|
||||
hashtag: "وسم"
|
||||
mention: "أشر الى"
|
||||
renote: "أعد النشر"
|
||||
messageBg: "خلفية المحادثة"
|
||||
_sfx:
|
||||
note: "الملاحظات"
|
||||
@ -560,11 +741,35 @@ _time:
|
||||
_tutorial:
|
||||
title: "كيف تستخدم Misskey"
|
||||
step1_1: "مرحبًا!"
|
||||
step1_2: "تدعى هذه الصفحة 'الخيط الزمني' وهي تحوي ملاحظات الأشخاص الذي تتابعهم مرتبة حسب تاريخ نشرها."
|
||||
step1_3: "خيطك الزمني فارغ حاليًا بما أنك لا تتابع أي شخص ولم تنشر أي ملاحظة."
|
||||
step2_1: "لننهي إعداد ملفك الشخصي قبل كتابة ملاحظة أو متابعة أشخاص."
|
||||
step3_1: "هل أنهيت إعداد حسابك؟"
|
||||
step3_2: "إذا تاليًا للنشر ملاحظة. أنقر على أيقونة القلم في أعلى الشاشة"
|
||||
step5_3: "لمتابعة مستخدمين ادخل ملفهم الشخصي بالنقر على صورتهم الشخصية ثم اضغط زر 'تابع'."
|
||||
_2fa:
|
||||
registerKey: "تسجيل مفتاح أمان جديد"
|
||||
_permissions:
|
||||
"read:account": "اعرض معلومات حسابك"
|
||||
"write:account": "تعديل معلومات حسابك"
|
||||
"read:blocks": "اعرض قائمة المستخدمين المحجوبين"
|
||||
"write:blocks": "عدّل قائمة المستخدمين المحجوبين"
|
||||
"read:drive": "تصفح قرص التخزين"
|
||||
"write:drive": "احذف أو عدّل محتويات قرص التخزين"
|
||||
"read:favorites": "اعرض المفضلة"
|
||||
"write:favorites": "عدّل المفضلة"
|
||||
"read:notifications": "اظهر الإشعارات"
|
||||
"read:reactions": "اعرض تفاعلاتك"
|
||||
"write:reactions": "عدّل تفاعلاتك"
|
||||
"write:votes": "صوّت"
|
||||
"read:pages": "اعرض صفحاتك"
|
||||
"write:pages": "عدّل أو احذف صفحاتك"
|
||||
"read:user-groups": "اعرض مجموعات المستخدمين"
|
||||
"write:user-groups": "عدّل أو احذف مجموعات المستخدمين"
|
||||
"read:gallery": "اعرض المعرض"
|
||||
"write:gallery": "عدّل المعرض"
|
||||
_auth:
|
||||
shareAccess: "أتريد التفويض لـ \"{name}\" بالوصول لحسابك؟"
|
||||
_weekday:
|
||||
sunday: "الأحد"
|
||||
monday: "الإثنين"
|
||||
@ -615,39 +820,74 @@ _poll:
|
||||
_visibility:
|
||||
public: "للعامة"
|
||||
home: "الرئيسي"
|
||||
followers: "المتابِعين"
|
||||
followers: "المتابِعون"
|
||||
specified: "مباشرة"
|
||||
localOnly: "المحلي فقط"
|
||||
_postForm:
|
||||
replyPlaceholder: "رد على هذه الملاحظة…"
|
||||
quotePlaceholder: "اقتبس هذه الملاحظة…"
|
||||
channelPlaceholder: "انشر في قناة..."
|
||||
_placeholders:
|
||||
c: "ما الذي تفكر فيه؟"
|
||||
d: "ما الذي تريد قوله؟"
|
||||
e: "أكتب..."
|
||||
_profile:
|
||||
name: "الإسم"
|
||||
username: "اسم المستخدم"
|
||||
description: "السيرة"
|
||||
youCanIncludeHashtags: "يمكنك أيضًا إضافة وسوم إلى نبذتك التعريفية."
|
||||
metadata: "معلومات إضافية"
|
||||
metadataEdit: "عدّل المعلومات الإضافية"
|
||||
metadataDescription: "يُمكنك عرض 4 حقول معلومات في ملفك الشخصي"
|
||||
metadataLabel: "التسمية"
|
||||
metadataContent: "المحتوى"
|
||||
changeAvatar: "غيّر الصورة الرمزية"
|
||||
changeBanner: "غيّر اللافتة"
|
||||
_exportOrImport:
|
||||
allNotes: "كل الملاحظات"
|
||||
followingList: "المتابَعون"
|
||||
muteList: "اكتم"
|
||||
blockingList: "احجب"
|
||||
muteList: "المستخدمون المكتومون"
|
||||
blockingList: "المستخدمون المحجوبون"
|
||||
userLists: "القوائم"
|
||||
_charts:
|
||||
usersTotal: "مجموع عدد المستخدمين والمستخدمات"
|
||||
activeUsers: "المستخدمون النشطون"
|
||||
notesTotal: "إجمالي الملاحظات"
|
||||
_timelines:
|
||||
home: "الرئيسي"
|
||||
local: "المحلي"
|
||||
social: "الاجتماعي"
|
||||
global: "الشامل"
|
||||
_rooms:
|
||||
leaveConfirm: "لديك تغييرات غير محفوظة. أتريد المتابعة دون حفظها؟"
|
||||
chooseImage: "اختر صورة"
|
||||
roomType: "نوع الغرفة"
|
||||
_roomType:
|
||||
default: "افتراضي"
|
||||
washitsu: "الأسلوب الياباني"
|
||||
_furnitures:
|
||||
milk: "علبة حليب"
|
||||
bed: "سرير"
|
||||
low-table: "طاولة قصيرة"
|
||||
desk: "مكتب"
|
||||
chair: "كرسي"
|
||||
chair2: "كرسي 2"
|
||||
pc: "حاسوب"
|
||||
monitor: "شاشة التحكم"
|
||||
banknote: "أوراق نقدية"
|
||||
_pages:
|
||||
viewPage: "اعرض صفحاتك"
|
||||
like: "أعجبني"
|
||||
unlike: "أزل الإعجاب"
|
||||
my: "صفحاتي"
|
||||
blocks:
|
||||
image: "الصور"
|
||||
_post:
|
||||
text: "المحتوى"
|
||||
_button:
|
||||
_action:
|
||||
_dialog:
|
||||
content: "المحتوى"
|
||||
script:
|
||||
categories:
|
||||
list: "القوائم"
|
||||
@ -676,9 +916,11 @@ _notification:
|
||||
youGotMessagingMessageFromUser: "لقد تلقيت رسالة مِن {name}"
|
||||
youGotMessagingMessageFromGroup: "لقد أرسِلَت رسالة إلى الفريق {name}"
|
||||
youWereFollowed: "يتابعك"
|
||||
youWereInvitedToGroup: "دُعيت إلى مجموعة"
|
||||
_types:
|
||||
follow: "المتابَعون"
|
||||
mention: "أشر الى"
|
||||
renote: "أعد النشر"
|
||||
quote: "اقتبس"
|
||||
reaction: "تفاعل"
|
||||
_deck:
|
||||
|
@ -795,10 +795,12 @@ itsOff: "Ausgeschaltet"
|
||||
emailRequiredForSignup: "Angaben einer Email-Adresse als benötigt markieren"
|
||||
unread: "Ungelesen"
|
||||
filter: "Filter"
|
||||
controllPanel: "Systemsteuerung"
|
||||
manageAccounts: "Benutzerkonten verwalten"
|
||||
makeReactionsPublic: "Reaktionsverlauf veröffentlichen"
|
||||
makeReactionsPublicDescription: "Jeder wird die Liste deiner gesendeten Reaktionen einsehen können."
|
||||
classic: "Classic"
|
||||
muteThread: "Thread stummschalten"
|
||||
unmuteThread: "Threadstummschaltung aufheben"
|
||||
_signup:
|
||||
almostThere: "Fast geschafft"
|
||||
emailAddressInfo: "Bitte gib deine Email-Adresse ein."
|
||||
|
@ -795,10 +795,13 @@ itsOff: "Disabled"
|
||||
emailRequiredForSignup: "Require email address for sign-up"
|
||||
unread: "Unread"
|
||||
filter: "Filter"
|
||||
controllPanel: "Control Panel"
|
||||
controlPanel: "Control Panel"
|
||||
manageAccounts: "Manage Accounts"
|
||||
makeReactionsPublic: "Set reaction history to public"
|
||||
makeReactionsPublicDescription: "This will make the list of all your past reactions publicly visible."
|
||||
classic: "Classic"
|
||||
muteThread: "Mute thread"
|
||||
unmuteThread: "Unmute thread"
|
||||
_signup:
|
||||
almostThere: "Almost there"
|
||||
emailAddressInfo: "Please enter your email address."
|
||||
|
@ -542,7 +542,8 @@ troubleshooting: "Problemsolvi"
|
||||
learnMore: "Lernu pli"
|
||||
translate: "Traduki"
|
||||
translatedFrom: "Tradukita el {x}"
|
||||
controllPanel: "Ŝaltpodio"
|
||||
controlPanel: "Ŝaltpodio"
|
||||
classic: "Klasika"
|
||||
_docs:
|
||||
continueReading: "Legi plu"
|
||||
features: "Funkcioj"
|
||||
|
@ -795,7 +795,7 @@ itsOff: "Désactivé"
|
||||
emailRequiredForSignup: "Une adresse e-mail est nécessaire pour créer un compte"
|
||||
unread: "Non lu"
|
||||
filter: "Filtre"
|
||||
controllPanel: "Panneau de contrôle"
|
||||
controlPanel: "Panneau de contrôle"
|
||||
manageAccounts: "Gérer les comptes"
|
||||
_signup:
|
||||
almostThere: "Bientôt fini"
|
||||
|
@ -780,7 +780,7 @@ translatedFrom: "Terjemahkan dari {x}"
|
||||
accountDeletionInProgress: "Penghapusan akun sedang dalam proses"
|
||||
usernameInfo: "Nama yang mengidentifikasikan akun kamu dari yang lain pada server ini. Kamu dapat menggunakan alfabet (a~z, A~Z), digit (0~9) atau garis bawah (_). Username tidak dapat diubah setelahnya."
|
||||
keepCw: "Biarkan Peringatan Konten"
|
||||
controllPanel: "Panel kontrol"
|
||||
controlPanel: "Panel kontrol"
|
||||
_accountDelete:
|
||||
accountDelete: "Hapus akun"
|
||||
mayTakeTime: "Karena penghapusan akun merupakan proses yang berat dan intensif, kemungkinan dapat membutuhkan waktu untuk menyelesaikan tergantung daripada berapa banyak konten yang kamu buat dan berapa banyak berkas yang telah kamu unggah."
|
||||
|
@ -795,10 +795,13 @@ itsOff: "オフになっています"
|
||||
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
|
||||
unread: "未読"
|
||||
filter: "フィルタ"
|
||||
controllPanel: "コントロールパネル"
|
||||
controlPanel: "コントロールパネル"
|
||||
manageAccounts: "アカウントを管理"
|
||||
makeReactionsPublic: "リアクション一覧を公開する"
|
||||
makeReactionsPublicDescription: "あなたがしたリアクション一覧を誰でも見れるようにします。"
|
||||
classic: "クラシック"
|
||||
muteThread: "スレッドをミュート"
|
||||
unmuteThread: "スレッドのミュートを解除"
|
||||
|
||||
_signup:
|
||||
almostThere: "ほとんど完了です"
|
||||
|
@ -787,7 +787,7 @@ pubSub: "Pub/Sub 계정"
|
||||
lastCommunication: "마지막 통신"
|
||||
resolved: "해결됨"
|
||||
unresolved: "해결되지 않음"
|
||||
controllPanel: "제어판"
|
||||
controlPanel: "제어판"
|
||||
_accountDelete:
|
||||
accountDelete: "계정 삭제"
|
||||
mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다."
|
||||
|
@ -784,7 +784,7 @@ accountDeletionInProgress: "В настоящее время выполняет
|
||||
usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже."
|
||||
aiChanMode: "ИИ режим"
|
||||
keepCw: "Сохраняйте Предупреждения о содержимом"
|
||||
controllPanel: "Панель управления"
|
||||
controlPanel: "Панель управления"
|
||||
manageAccounts: "Управление аккаунтом"
|
||||
_docs:
|
||||
continueReading: "Читать подробнее"
|
||||
|
@ -795,8 +795,9 @@ itsOff: "已关闭"
|
||||
emailRequiredForSignup: "注册账户需要电子邮件地址"
|
||||
unread: "未读"
|
||||
filter: "筛选"
|
||||
controllPanel: "控制面板"
|
||||
controlPanel: "控制面板"
|
||||
manageAccounts: "管理账户"
|
||||
classic: "经典"
|
||||
_signup:
|
||||
almostThere: "即将完成"
|
||||
emailAddressInfo: "请输入您所使用的电子邮件地址"
|
||||
|
26
migration/1635500777168-note-thread-mute.ts
Normal file
26
migration/1635500777168-note-thread-mute.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class noteThreadMute1635500777168 implements MigrationInterface {
|
||||
name = 'noteThreadMute1635500777168'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE "note_thread_muting" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" character varying(32) NOT NULL, "threadId" character varying(256) NOT NULL, CONSTRAINT "PK_ec5936d94d1a0369646d12a3a47" PRIMARY KEY ("id"))`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_29c11c7deb06615076f8c95b80" ON "note_thread_muting" ("userId") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_c426394644267453e76f036926" ON "note_thread_muting" ("threadId") `);
|
||||
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ae7aab18a2641d3e5f25e0c4ea" ON "note_thread_muting" ("userId", "threadId") `);
|
||||
await queryRunner.query(`ALTER TABLE "note" ADD "threadId" character varying(256)`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_d4ebdef929896d6dc4a3c5bb48" ON "note" ("threadId") `);
|
||||
await queryRunner.query(`ALTER TABLE "note_thread_muting" ADD CONSTRAINT "FK_29c11c7deb06615076f8c95b80a" 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 "note_thread_muting" DROP CONSTRAINT "FK_29c11c7deb06615076f8c95b80a"`);
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_d4ebdef929896d6dc4a3c5bb48"`);
|
||||
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "threadId"`);
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_ae7aab18a2641d3e5f25e0c4ea"`);
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_c426394644267453e76f036926"`);
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_29c11c7deb06615076f8c95b80"`);
|
||||
await queryRunner.query(`DROP TABLE "note_thread_muting"`);
|
||||
}
|
||||
|
||||
}
|
59
package.json
59
package.json
@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
||||
"version": "12.93.0",
|
||||
"version": "12.95.0",
|
||||
"codename": "indigo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -29,8 +28,9 @@
|
||||
"lint": "tslint 'src/**/*.ts'",
|
||||
"cy:open": "cypress open",
|
||||
"cy:run": "cypress run",
|
||||
"e2e": "start-server-and-test start:test http://localhost cy:run",
|
||||
"test": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
||||
"e2e": "start-server-and-test start:test http://localhost:61812 cy:run",
|
||||
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
|
||||
"test": "npm run mocha",
|
||||
"format": "gulp format"
|
||||
},
|
||||
"resolutions": {
|
||||
@ -38,6 +38,7 @@
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordapp/twemoji": "13.1.0",
|
||||
"@elastic/elasticsearch": "7.11.0",
|
||||
"@koa/cors": "3.1.0",
|
||||
"@koa/multer": "3.0.0",
|
||||
@ -51,18 +52,15 @@
|
||||
"@types/cbor": "6.0.0",
|
||||
"@types/dateformat": "3.0.1",
|
||||
"@types/escape-regexp": "0.0.0",
|
||||
"@types/glob": "7.1.4",
|
||||
"@types/glob": "7.2.0",
|
||||
"@types/gulp": "4.0.9",
|
||||
"@types/gulp-rename": "2.0.1",
|
||||
"@types/is-url": "1.2.30",
|
||||
"@types/js-yaml": "4.0.3",
|
||||
"@types/js-yaml": "4.0.4",
|
||||
"@types/jsdom": "16.2.13",
|
||||
"@types/jsonld": "1.5.6",
|
||||
"@types/katex": "0.11.1",
|
||||
"@types/koa": "2.13.4",
|
||||
"@types/koa__cors": "3.0.3",
|
||||
"@types/koa__multer": "2.0.3",
|
||||
"@types/koa__router": "8.0.8",
|
||||
"@types/koa-bodyparser": "4.3.3",
|
||||
"@types/koa-cors": "0.0.2",
|
||||
"@types/koa-favicon": "2.0.21",
|
||||
@ -70,15 +68,18 @@
|
||||
"@types/koa-mount": "4.0.1",
|
||||
"@types/koa-send": "4.1.3",
|
||||
"@types/koa-views": "7.0.0",
|
||||
"@types/koa__cors": "3.0.3",
|
||||
"@types/koa__multer": "2.0.4",
|
||||
"@types/koa__router": "8.0.8",
|
||||
"@types/markdown-it": "12.2.3",
|
||||
"@types/matter-js": "0.17.5",
|
||||
"@types/matter-js": "0.17.6",
|
||||
"@types/mocha": "8.2.3",
|
||||
"@types/node": "16.10.3",
|
||||
"@types/node": "16.11.4",
|
||||
"@types/node-fetch": "2.5.12",
|
||||
"@types/nodemailer": "6.4.4",
|
||||
"@types/nprogress": "0.2.0",
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/parse5": "6.0.1",
|
||||
"@types/parse5": "6.0.2",
|
||||
"@types/parsimmon": "1.10.6",
|
||||
"@types/portscanner": "2.1.1",
|
||||
"@types/pug": "2.0.5",
|
||||
@ -96,21 +97,20 @@
|
||||
"@types/speakeasy": "2.0.6",
|
||||
"@types/throttle-debounce": "2.1.0",
|
||||
"@types/tinycolor2": "1.4.3",
|
||||
"@types/tmp": "0.2.1",
|
||||
"@types/tmp": "0.2.2",
|
||||
"@types/uuid": "8.3.1",
|
||||
"@types/web-push": "3.3.2",
|
||||
"@types/webpack": "5.28.0",
|
||||
"@types/webpack-stream": "3.2.12",
|
||||
"@types/websocket": "1.0.4",
|
||||
"@types/ws": "8.2.0",
|
||||
"@typescript-eslint/parser": "5.0.0",
|
||||
"@typescript-eslint/parser": "5.1.0",
|
||||
"@vue/compiler-sfc": "3.2.20",
|
||||
"abort-controller": "3.0.0",
|
||||
"apexcharts": "3.28.3",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.4",
|
||||
"autwh": "0.1.0",
|
||||
"aws-sdk": "2.1003.0",
|
||||
"aws-sdk": "2.1013.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"blurhash": "1.1.4",
|
||||
"broadcast-channel": "4.2.0",
|
||||
@ -119,7 +119,7 @@
|
||||
"cafy": "15.2.1",
|
||||
"cbor": "8.0.2",
|
||||
"chalk": "4.1.2",
|
||||
"chart.js": "3.5.1",
|
||||
"chart.js": "3.6.0",
|
||||
"chartjs-adapter-date-fns": "2.0.0",
|
||||
"chartjs-plugin-zoom": "1.1.1",
|
||||
"cli-highlight": "2.1.11",
|
||||
@ -132,8 +132,8 @@
|
||||
"date-fns": "2.25.0",
|
||||
"dateformat": "4.5.1",
|
||||
"escape-regexp": "0.0.1",
|
||||
"eslint": "8.0.1",
|
||||
"eslint-plugin-vue": "7.19.1",
|
||||
"eslint": "8.1.0",
|
||||
"eslint-plugin-vue": "7.20.0",
|
||||
"eventemitter3": "4.0.7",
|
||||
"feed": "4.2.2",
|
||||
"file-type": "16.5.3",
|
||||
@ -159,7 +159,7 @@
|
||||
"jsonld": "5.2.0",
|
||||
"jsrsasign": "8.0.20",
|
||||
"katex": "0.13.18",
|
||||
"koa": "2.13.3",
|
||||
"koa": "2.13.4",
|
||||
"koa-bodyparser": "4.3.0",
|
||||
"koa-favicon": "2.1.0",
|
||||
"koa-json-body": "5.3.0",
|
||||
@ -173,7 +173,7 @@
|
||||
"markdown-it-anchor": "7.1.0",
|
||||
"matter-js": "0.17.1",
|
||||
"mfm-js": "0.20.0",
|
||||
"misskey-js": "0.0.6",
|
||||
"misskey-js": "0.0.8",
|
||||
"mocha": "8.4.0",
|
||||
"ms": "2.1.3",
|
||||
"multer": "1.4.3",
|
||||
@ -183,8 +183,9 @@
|
||||
"os-utils": "0.0.14",
|
||||
"parse5": "6.0.1",
|
||||
"pg": "8.7.1",
|
||||
"photoswipe": "git://github.com/dimsemenov/photoswipe#v5-beta",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss": "8.3.9",
|
||||
"postcss": "8.3.11",
|
||||
"postcss-loader": "6.2.0",
|
||||
"prismjs": "1.25.0",
|
||||
"private-ip": "2.3.0",
|
||||
@ -206,17 +207,17 @@
|
||||
"rimraf": "3.0.2",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"sass": "1.43.2",
|
||||
"sass": "1.43.3",
|
||||
"sass-loader": "12.2.0",
|
||||
"seedrandom": "3.0.5",
|
||||
"sharp": "0.29.1",
|
||||
"sharp": "0.29.2",
|
||||
"speakeasy": "2.0.0",
|
||||
"strict-event-emitter-types": "2.0.0",
|
||||
"stringz": "2.1.0",
|
||||
"style-loader": "3.3.0",
|
||||
"style-loader": "3.3.1",
|
||||
"summaly": "2.4.1",
|
||||
"syslog-pro": "1.0.0",
|
||||
"systeminformation": "5.9.7",
|
||||
"systeminformation": "5.9.8",
|
||||
"syuilo-password-strength": "0.0.1",
|
||||
"textarea-caret": "3.1.0",
|
||||
"three": "0.117.1",
|
||||
@ -224,7 +225,7 @@
|
||||
"tinycolor2": "1.4.2",
|
||||
"tmp": "0.2.1",
|
||||
"ts-loader": "9.2.6",
|
||||
"ts-node": "10.3.0",
|
||||
"ts-node": "10.4.0",
|
||||
"tsc-alias": "1.3.10",
|
||||
"tsconfig-paths": "3.11.0",
|
||||
"tslint": "6.1.3",
|
||||
@ -244,8 +245,8 @@
|
||||
"vue-svg-loader": "0.17.0-beta.2",
|
||||
"vuedraggable": "4.0.1",
|
||||
"web-push": "3.4.5",
|
||||
"webpack": "5.58.2",
|
||||
"webpack-cli": "4.9.0",
|
||||
"webpack": "5.59.1",
|
||||
"webpack-cli": "4.9.1",
|
||||
"websocket": "1.0.34",
|
||||
"ws": "8.2.3",
|
||||
"xev": "2.0.1"
|
||||
|
@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<canvas ref="chartEl"></canvas>
|
||||
<div class="cbbedffa">
|
||||
<canvas ref="chartEl"></canvas>
|
||||
<div v-if="fetching" class="fetching">
|
||||
<MkLoading/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -84,6 +89,16 @@ export default defineComponent({
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
stacked: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
aspectRatio: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
@ -152,7 +167,7 @@ export default defineComponent({
|
||||
})),
|
||||
},
|
||||
options: {
|
||||
aspectRatio: 2.5,
|
||||
aspectRatio: props.aspectRatio || 2.5,
|
||||
layout: {
|
||||
padding: {
|
||||
left: 16,
|
||||
@ -169,7 +184,6 @@ export default defineComponent({
|
||||
unit: props.span === 'day' ? 'month' : 'day',
|
||||
},
|
||||
grid: {
|
||||
display: props.detailed,
|
||||
color: gridColor,
|
||||
borderColor: 'rgb(0, 0, 0, 0)',
|
||||
},
|
||||
@ -185,6 +199,7 @@ export default defineComponent({
|
||||
},
|
||||
y: {
|
||||
position: 'left',
|
||||
stacked: props.stacked,
|
||||
grid: {
|
||||
color: gridColor,
|
||||
borderColor: 'rgb(0, 0, 0, 0)',
|
||||
@ -199,6 +214,7 @@ export default defineComponent({
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: props.detailed,
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
boxWidth: 16,
|
||||
@ -578,6 +594,30 @@ export default defineComponent({
|
||||
};
|
||||
};
|
||||
|
||||
const fetchPerUserNotesChart = async (): Promise<typeof data> => {
|
||||
const raw = await os.api('charts/user/notes', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
||||
return {
|
||||
series: [...(props.args.withoutAll ? [] : [{
|
||||
name: 'All',
|
||||
type: 'line',
|
||||
borderDash: [5, 5],
|
||||
data: format(sum(raw.inc, negate(raw.dec))),
|
||||
}]), {
|
||||
name: 'Renotes',
|
||||
type: 'area',
|
||||
data: format(raw.diffs.renote),
|
||||
}, {
|
||||
name: 'Replies',
|
||||
type: 'area',
|
||||
data: format(raw.diffs.reply),
|
||||
}, {
|
||||
name: 'Normal',
|
||||
type: 'area',
|
||||
data: format(raw.diffs.normal),
|
||||
}],
|
||||
};
|
||||
};
|
||||
|
||||
const fetchAndRender = async () => {
|
||||
const fetchData = () => {
|
||||
switch (props.src) {
|
||||
@ -606,6 +646,8 @@ export default defineComponent({
|
||||
case 'instance-drive-usage-total': return fetchInstanceDriveUsageChart(true);
|
||||
case 'instance-drive-files': return fetchInstanceDriveFilesChart(false);
|
||||
case 'instance-drive-files-total': return fetchInstanceDriveFilesChart(true);
|
||||
|
||||
case 'per-user-notes': return fetchPerUserNotesChart();
|
||||
}
|
||||
};
|
||||
fetching.value = true;
|
||||
@ -622,7 +664,28 @@ export default defineComponent({
|
||||
|
||||
return {
|
||||
chartEl,
|
||||
fetching,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cbbedffa {
|
||||
position: relative;
|
||||
|
||||
> .fetching {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-webkit-backdrop-filter: var(--blur, blur(12px));
|
||||
backdrop-filter: var(--blur, blur(12px));
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: wait;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -7,21 +7,21 @@
|
||||
>
|
||||
<template #header>{{ $ts.forgotPassword }}</template>
|
||||
|
||||
<form class="_monolithic_" @submit.prevent="onSubmit" v-if="$instance.enableEmail">
|
||||
<div class="_section">
|
||||
<MkInput v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required>
|
||||
<form class="bafeceda" @submit.prevent="onSubmit" v-if="$instance.enableEmail">
|
||||
<div class="main _formRoot">
|
||||
<MkInput class="_formBlock" v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required>
|
||||
<template #label>{{ $ts.username }}</template>
|
||||
<template #prefix>@</template>
|
||||
</MkInput>
|
||||
|
||||
<MkInput v-model="email" type="email" spellcheck="false" required>
|
||||
<MkInput class="_formBlock" v-model="email" type="email" spellcheck="false" required>
|
||||
<template #label>{{ $ts.emailAddress }}</template>
|
||||
<template #caption>{{ $ts._forgotPassword.enterEmail }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkButton type="submit" :disabled="processing" primary style="margin: 0 auto;">{{ $ts.send }}</MkButton>
|
||||
<MkButton class="_formBlock" type="submit" :disabled="processing" primary style="margin: 0 auto;">{{ $ts.send }}</MkButton>
|
||||
</div>
|
||||
<div class="_section">
|
||||
<div class="sub">
|
||||
<MkA to="/about" class="_link">{{ $ts._forgotPassword.ifNoEmail }}</MkA>
|
||||
</div>
|
||||
</form>
|
||||
@ -69,3 +69,16 @@ export default defineComponent({
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bafeceda {
|
||||
> .main {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
> .sub {
|
||||
border-top: solid 0.5px var(--divider);
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -24,7 +24,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs, VNode } from 'vue';
|
||||
import MkButton from '@client/components/ui/button.vue';
|
||||
import * as os from '@client/os';
|
||||
|
||||
@ -140,33 +140,36 @@ export default defineComponent({
|
||||
const menu = [];
|
||||
let options = context.slots.default();
|
||||
|
||||
for (const optionOrOptgroup of options) {
|
||||
if (optionOrOptgroup.type === 'optgroup') {
|
||||
const optgroup = optionOrOptgroup;
|
||||
const pushOption = (option: VNode) => {
|
||||
menu.push({
|
||||
text: option.children,
|
||||
active: v.value === option.props.value,
|
||||
action: () => {
|
||||
v.value = option.props.value;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const scanOptions = (options: VNode[]) => {
|
||||
for (const vnode of options) {
|
||||
if (vnode.type === 'optgroup') {
|
||||
const optgroup = vnode;
|
||||
menu.push({
|
||||
type: 'label',
|
||||
text: optgroup.props.label,
|
||||
});
|
||||
for (const option of optgroup.children) {
|
||||
menu.push({
|
||||
text: option.children,
|
||||
active: v.value === option.props.value,
|
||||
action: () => {
|
||||
v.value = option.props.value;
|
||||
},
|
||||
});
|
||||
}
|
||||
scanOptions(optgroup.children);
|
||||
} else if (Array.isArray(vnode.children)) { // 何故かフラグメントになってくることがある
|
||||
const fragment = vnode;
|
||||
scanOptions(fragment.children);
|
||||
} else {
|
||||
const option = optionOrOptgroup;
|
||||
menu.push({
|
||||
text: option.children,
|
||||
active: v.value === option.props.value,
|
||||
action: () => {
|
||||
v.value = option.props.value;
|
||||
},
|
||||
});
|
||||
const option = vnode;
|
||||
pushOption(option);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
scanOptions(options);
|
||||
|
||||
os.popupMenu(menu, container.value, {
|
||||
width: container.value.offsetWidth,
|
||||
|
@ -2,8 +2,8 @@
|
||||
<div class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick" ref="el">
|
||||
<template v-if="info">
|
||||
<div class="titleContainer" @click="showTabsPopup" v-if="!hideTitle">
|
||||
<i v-if="info.icon" class="icon" :class="info.icon"></i>
|
||||
<MkAvatar v-else-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true" :show-indicator="true"/>
|
||||
<MkAvatar v-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true" :show-indicator="true"/>
|
||||
<i v-else-if="info.icon" class="icon" :class="info.icon"></i>
|
||||
|
||||
<div class="title">
|
||||
<MkUserName v-if="info.userName" :user="info.userName" :nowrap="false" class="title"/>
|
||||
@ -162,11 +162,6 @@ export default defineComponent({
|
||||
onUnmounted(() => {
|
||||
ro.disconnect();
|
||||
});
|
||||
setTimeout(() => {
|
||||
const currentStickyTop = getComputedStyle(el.value.parentElement).getPropertyValue('--stickyTop') || '0px';
|
||||
el.value.style.setProperty('--stickyTop', currentStickyTop);
|
||||
el.value.parentElement.style.setProperty('--stickyTop', `calc(${currentStickyTop} + ${el.value.offsetHeight}px)`);
|
||||
}, 100); // レンダリング順序の関係で親のstickyTopの設定が少し遅れることがあるため
|
||||
}
|
||||
});
|
||||
|
||||
|
74
src/client/components/global/sticky-container.vue
Normal file
74
src/client/components/global/sticky-container.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div ref="rootEl">
|
||||
<slot name="header"></slot>
|
||||
<div ref="bodyEl">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, onUnmounted, ref } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
autoSticky: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, context) {
|
||||
const rootEl = ref<HTMLElement>(null);
|
||||
const bodyEl = ref<HTMLElement>(null);
|
||||
|
||||
const calc = () => {
|
||||
const currentStickyTop = getComputedStyle(rootEl.value).getPropertyValue('--stickyTop') || '0px';
|
||||
|
||||
const header = rootEl.value.children[0];
|
||||
if (header === bodyEl.value) {
|
||||
bodyEl.value.style.setProperty('--stickyTop', currentStickyTop);
|
||||
} else {
|
||||
bodyEl.value.style.setProperty('--stickyTop', `calc(${currentStickyTop} + ${header.offsetHeight}px)`);
|
||||
|
||||
if (props.autoSticky) {
|
||||
header.style.setProperty('--stickyTop', currentStickyTop);
|
||||
header.style.position = 'sticky';
|
||||
header.style.top = 'var(--stickyTop)';
|
||||
header.style.zIndex = '1';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
calc();
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
setTimeout(() => {
|
||||
calc();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
observer.observe(rootEl.value, {
|
||||
attributes: false,
|
||||
childList: true,
|
||||
subtree: false,
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
observer.disconnect();
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
rootEl,
|
||||
bodyEl,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
||||
</style>
|
@ -10,7 +10,12 @@ import { defineComponent } from 'vue';
|
||||
import * as os from '@client/os';
|
||||
|
||||
export default defineComponent({
|
||||
props: ['q'],
|
||||
props: {
|
||||
q: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: null,
|
||||
@ -21,10 +26,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
const engine = this.$store.state.webSearchEngine ||
|
||||
'https://www.google.com/search?q={{query}}';
|
||||
const url = engine.replace('{{query}}', this.query)
|
||||
window.open(url, '_blank');
|
||||
window.open(`https://www.google.com/search?q=${this.query}`, '_blank');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -15,6 +15,7 @@ import error from './global/error.vue';
|
||||
import ad from './global/ad.vue';
|
||||
import header from './global/header.vue';
|
||||
import spacer from './global/spacer.vue';
|
||||
import stickyContainer from './global/sticky-container.vue';
|
||||
|
||||
export default function(app: App) {
|
||||
app.component('I18n', i18n);
|
||||
@ -32,4 +33,5 @@ export default function(app: App) {
|
||||
app.component('MkAd', ad);
|
||||
app.component('MkHeader', header);
|
||||
app.component('MkSpacer', spacer);
|
||||
app.component('MkStickyContainer', stickyContainer);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
<a
|
||||
:href="image.url"
|
||||
:title="image.name"
|
||||
@click.prevent="onClick"
|
||||
>
|
||||
<ImgWithBlurhash :hash="image.blurhash" :src="url" :alt="image.comment" :title="image.comment" :cover="false"/>
|
||||
<div class="gif" v-if="image.type === 'image/gif'">GIF</div>
|
||||
@ -73,17 +72,6 @@ export default defineComponent({
|
||||
immediate: true,
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
if (this.$store.state.imageNewTab) {
|
||||
window.open(this.image.url, '_blank');
|
||||
} else {
|
||||
os.popup(ImageViewer, {
|
||||
image: this.image
|
||||
}, {}, 'closed');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="mk-media-list">
|
||||
<div class="hoawjimk">
|
||||
<XBanner v-for="media in mediaList.filter(media => !previewable(media))" :media="media" :key="media.id"/>
|
||||
<div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container" ref="gridOuter">
|
||||
<div :data-count="mediaList.filter(media => previewable(media)).length" :style="gridInnerStyle">
|
||||
<div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container">
|
||||
<div :data-count="mediaList.filter(media => previewable(media)).length" ref="gallery">
|
||||
<template v-for="media in mediaList">
|
||||
<XVideo :video="media" :key="media.id" v-if="media.type.startsWith('video')"/>
|
||||
<XImage :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/>
|
||||
<XImage class="image" :data-id="media.id" :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@ -13,11 +13,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, onMounted, PropType, ref } from 'vue';
|
||||
import * as misskey from 'misskey-js';
|
||||
import PhotoSwipeLightbox from 'photoswipe/dist/photoswipe-lightbox.esm.js';
|
||||
import PhotoSwipe from 'photoswipe/dist/photoswipe.esm.js';
|
||||
import 'photoswipe/dist/photoswipe.css';
|
||||
import XBanner from './media-banner.vue';
|
||||
import XImage from './media-image.vue';
|
||||
import XVideo from './media-video.vue';
|
||||
import * as os from '@client/os';
|
||||
import { defaultStore } from '@client/store';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -27,63 +32,63 @@ export default defineComponent({
|
||||
},
|
||||
props: {
|
||||
mediaList: {
|
||||
required: true
|
||||
type: Array as PropType<misskey.entities.DriveFile[]>,
|
||||
required: true,
|
||||
},
|
||||
raw: {
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
gridInnerStyle: {},
|
||||
sizeWaiting: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.size();
|
||||
window.addEventListener('resize', this.size);
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.size);
|
||||
},
|
||||
activated() {
|
||||
this.size();
|
||||
},
|
||||
methods: {
|
||||
previewable(file) {
|
||||
return file.type.startsWith('video') || file.type.startsWith('image');
|
||||
},
|
||||
size() {
|
||||
// for Safari bug
|
||||
if (this.sizeWaiting) return;
|
||||
setup(props) {
|
||||
const gallery = ref(null);
|
||||
|
||||
this.sizeWaiting = true;
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
this.sizeWaiting = false;
|
||||
|
||||
if (this.$refs.gridOuter) {
|
||||
let height = 287;
|
||||
const parent = this.$parent.$el;
|
||||
|
||||
if (this.$refs.gridOuter.clientHeight) {
|
||||
height = this.$refs.gridOuter.clientHeight;
|
||||
} else if (parent) {
|
||||
height = parent.getBoundingClientRect().width * 9 / 16;
|
||||
}
|
||||
|
||||
this.gridInnerStyle = { height: `${height}px` };
|
||||
} else {
|
||||
this.gridInnerStyle = {};
|
||||
}
|
||||
onMounted(() => {
|
||||
const lightbox = new PhotoSwipeLightbox({
|
||||
dataSource: props.mediaList.filter(media => media.type.startsWith('image')).map(media => ({
|
||||
src: media.url,
|
||||
w: media.properties.width,
|
||||
h: media.properties.height,
|
||||
alt: media.name,
|
||||
})),
|
||||
gallery: gallery.value,
|
||||
children: '.image',
|
||||
thumbSelector: '.image',
|
||||
pswpModule: PhotoSwipe
|
||||
});
|
||||
}
|
||||
|
||||
lightbox.on('itemData', (e) => {
|
||||
const { itemData } = e;
|
||||
|
||||
// element is children
|
||||
const { element } = itemData;
|
||||
|
||||
const id = element.dataset.id;
|
||||
const file = props.mediaList.find(media => media.id === id);
|
||||
|
||||
itemData.src = file.url;
|
||||
itemData.w = Number(file.properties.width);
|
||||
itemData.h = Number(file.properties.height);
|
||||
itemData.msrc = file.thumbnailUrl;
|
||||
itemData.thumbCropped = true;
|
||||
});
|
||||
|
||||
lightbox.init();
|
||||
});
|
||||
|
||||
const previewable = (file: misskey.entities.DriveFile): boolean => {
|
||||
return file.type.startsWith('video') || file.type.startsWith('image');
|
||||
};
|
||||
|
||||
return {
|
||||
previewable,
|
||||
gallery,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mk-media-list {
|
||||
.hoawjimk {
|
||||
> .gird-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
@ -11,6 +11,7 @@
|
||||
:title="video.name"
|
||||
preload="none"
|
||||
controls
|
||||
@contextmenu.stop
|
||||
>
|
||||
<source
|
||||
:src="video.url"
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<MkA class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" v-if="url.startsWith('/')">
|
||||
<span class="me" v-if="isMe">{{ $ts.you }}</span>
|
||||
<MkA v-if="url.startsWith('/')" class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" :style="{ background: bg }">
|
||||
<img class="icon" :src="`/avatar/@${username}@${host}`" alt="">
|
||||
<span class="main">
|
||||
<span class="username">@{{ username }}</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>
|
||||
<a v-else class="ldlomzub" :href="url" target="_blank" rel="noopener" :style="{ background: bg }">
|
||||
<span class="main">
|
||||
<span class="username">@{{ username }}</span>
|
||||
<span class="host">@{{ toUnicode(host) }}</span>
|
||||
@ -16,10 +16,11 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { toUnicode } from 'punycode/';
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
import { toUnicode } from 'punycode';
|
||||
import { host as localHost } from '@client/config';
|
||||
import { wellKnownServices } from '../../well-known-services';
|
||||
import * as os from '@client/os';
|
||||
import { $i } from '@client/account';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -32,48 +33,48 @@ export default defineComponent({
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
setup(props) {
|
||||
const canonical = props.host === localHost ? `@${props.username}` : `@${props.username}@${toUnicode(props.host)}`;
|
||||
|
||||
const wellKnown = wellKnownServices.find(x => x[0] === props.host);
|
||||
const url = wellKnown ? wellKnown[1](props.username) : `/${canonical}`;
|
||||
|
||||
const isMe = $i && (
|
||||
`@${props.username}@${toUnicode(props.host)}` === `@${$i.username}@${toUnicode(localHost)}`.toLowerCase()
|
||||
);
|
||||
|
||||
const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention'));
|
||||
bg.setAlpha(0.20);
|
||||
|
||||
return {
|
||||
localHost
|
||||
localHost,
|
||||
isMe,
|
||||
url,
|
||||
canonical,
|
||||
toUnicode,
|
||||
bg: bg.toRgbString(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
url(): string {
|
||||
const wellKnown = wellKnownServices.find(x => x[0] === this.host);
|
||||
if (wellKnown) {
|
||||
return wellKnown[1](this.username);
|
||||
} else {
|
||||
return `/${this.canonical}`;
|
||||
}
|
||||
},
|
||||
canonical(): string {
|
||||
return this.host === localHost ? `@${this.username}` : `@${this.username}@${toUnicode(this.host)}`;
|
||||
},
|
||||
isMe(): boolean {
|
||||
return this.$i && (
|
||||
`@${this.username}@${toUnicode(this.host)}` === `@${this.$i.username}@${toUnicode(localHost)}`.toLowerCase()
|
||||
);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toUnicode
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ldlomzub {
|
||||
display: inline-block;
|
||||
padding: 4px 8px 4px 4px;
|
||||
border-radius: 999px;
|
||||
color: var(--mention);
|
||||
|
||||
&.isMe {
|
||||
color: var(--mentionMe);
|
||||
}
|
||||
|
||||
> .me {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
font-size: 70%;
|
||||
vertical-align: top;
|
||||
> .icon {
|
||||
width: 1.5em;
|
||||
margin: 0 0.2em 0 0;
|
||||
vertical-align: bottom;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
> .main {
|
||||
|
@ -10,10 +10,13 @@
|
||||
</span>
|
||||
<button class="_button" @click="$refs.modal.close()"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
<div class="body _fitSide_">
|
||||
<div class="body">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template>
|
||||
<keep-alive>
|
||||
<component :is="component" v-bind="props" :ref="changePage"/>
|
||||
</keep-alive>
|
||||
</MkStickyContainer>
|
||||
</div>
|
||||
</div>
|
||||
</MkModal>
|
||||
|
@ -601,6 +601,12 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
|
||||
toggleThreadMute(mute: boolean) {
|
||||
os.apiWithDialog(mute ? 'notes/thread-muting/create' : 'notes/thread-muting/delete', {
|
||||
noteId: this.appearNote.id
|
||||
});
|
||||
},
|
||||
|
||||
getMenu() {
|
||||
let menu;
|
||||
if (this.$i) {
|
||||
@ -657,6 +663,15 @@ export default defineComponent({
|
||||
text: this.$ts.watch,
|
||||
action: () => this.toggleWatch(true)
|
||||
}) : undefined,
|
||||
statePromise.then(state => state.isMutedThread ? {
|
||||
icon: 'fas fa-comment-slash',
|
||||
text: this.$ts.unmuteThread,
|
||||
action: () => this.toggleThreadMute(false)
|
||||
} : {
|
||||
icon: 'fas fa-comment-slash',
|
||||
text: this.$ts.muteThread,
|
||||
action: () => this.toggleThreadMute(true)
|
||||
}),
|
||||
this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
|
||||
icon: 'fas fa-thumbtack',
|
||||
text: this.$ts.unpin,
|
||||
|
@ -576,6 +576,12 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
|
||||
toggleThreadMute(mute: boolean) {
|
||||
os.apiWithDialog(mute ? 'notes/thread-muting/create' : 'notes/thread-muting/delete', {
|
||||
noteId: this.appearNote.id
|
||||
});
|
||||
},
|
||||
|
||||
getMenu() {
|
||||
let menu;
|
||||
if (this.$i) {
|
||||
@ -632,6 +638,15 @@ export default defineComponent({
|
||||
text: this.$ts.watch,
|
||||
action: () => this.toggleWatch(true)
|
||||
}) : undefined,
|
||||
statePromise.then(state => state.isMutedThread ? {
|
||||
icon: 'fas fa-comment-slash',
|
||||
text: this.$ts.unmuteThread,
|
||||
action: () => this.toggleThreadMute(false)
|
||||
} : {
|
||||
icon: 'fas fa-comment-slash',
|
||||
text: this.$ts.muteThread,
|
||||
action: () => this.toggleThreadMute(true)
|
||||
}),
|
||||
this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
|
||||
icon: 'fas fa-thumbtack',
|
||||
text: this.$ts.unpin,
|
||||
|
@ -13,7 +13,8 @@
|
||||
<i v-else-if="notification.type === 'mention'" class="fas fa-at"></i>
|
||||
<i v-else-if="notification.type === 'quote'" class="fas fa-quote-left"></i>
|
||||
<i v-else-if="notification.type === 'pollVote'" class="fas fa-poll-h"></i>
|
||||
<XReactionIcon v-else-if="notification.type === 'reaction'" :reaction="notification.reaction" :custom-emojis="notification.note.emojis" :no-style="true"/>
|
||||
<!-- notification.reaction が null になることはまずないが、ここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
|
||||
<XReactionIcon v-else-if="notification.type === 'reaction'" :reaction="notification.reaction ? notification.reaction.replace(/^:(\w+):$/, ':$1@.:') : notification.reaction" :custom-emojis="notification.note.emojis" :no-style="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tail">
|
||||
|
@ -16,8 +16,11 @@
|
||||
<template #headerLeft>
|
||||
<button v-if="history.length > 0" class="_button" @click="back()" v-tooltip="$ts.goBack"><i class="fas fa-arrow-left"></i></button>
|
||||
</template>
|
||||
<div class="yrolvcoq _fitSide_">
|
||||
<div class="yrolvcoq">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template>
|
||||
<component :is="component" v-bind="props" :ref="changePage"/>
|
||||
</MkStickyContainer>
|
||||
</div>
|
||||
</XWindow>
|
||||
</template>
|
||||
|
@ -79,6 +79,7 @@ export default defineComponent({
|
||||
pointRadius: 0,
|
||||
tension: 0,
|
||||
borderWidth: 2,
|
||||
borderJoinStyle: 'round',
|
||||
borderColor: '#00E396',
|
||||
backgroundColor: alpha('#00E396', 0.1),
|
||||
data: []
|
||||
@ -87,6 +88,7 @@ export default defineComponent({
|
||||
pointRadius: 0,
|
||||
tension: 0,
|
||||
borderWidth: 2,
|
||||
borderJoinStyle: 'round',
|
||||
borderColor: '#00BCD4',
|
||||
backgroundColor: alpha('#00BCD4', 0.1),
|
||||
data: []
|
||||
@ -95,17 +97,21 @@ export default defineComponent({
|
||||
pointRadius: 0,
|
||||
tension: 0,
|
||||
borderWidth: 2,
|
||||
borderJoinStyle: 'round',
|
||||
borderColor: '#FFB300',
|
||||
backgroundColor: alpha('#FFB300', 0.1),
|
||||
yAxisID: 'y2',
|
||||
data: []
|
||||
}, {
|
||||
label: 'Delayed',
|
||||
pointRadius: 0,
|
||||
tension: 0,
|
||||
borderWidth: 2,
|
||||
borderJoinStyle: 'round',
|
||||
borderColor: '#E53935',
|
||||
borderDash: [5, 5],
|
||||
fill: false,
|
||||
yAxisID: 'y2',
|
||||
data: []
|
||||
}],
|
||||
},
|
||||
@ -122,15 +128,29 @@ export default defineComponent({
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
display: false,
|
||||
display: true,
|
||||
color: gridColor,
|
||||
borderColor: 'rgb(0, 0, 0, 0)',
|
||||
},
|
||||
ticks: {
|
||||
display: false,
|
||||
maxTicksLimit: 10
|
||||
},
|
||||
},
|
||||
y: {
|
||||
min: 0,
|
||||
stack: 'queue',
|
||||
stackWeight: 2,
|
||||
grid: {
|
||||
color: gridColor,
|
||||
borderColor: 'rgb(0, 0, 0, 0)',
|
||||
},
|
||||
},
|
||||
y2: {
|
||||
min: 0,
|
||||
offset: true,
|
||||
stack: 'queue',
|
||||
stackWeight: 1,
|
||||
grid: {
|
||||
color: gridColor,
|
||||
borderColor: 'rgb(0, 0, 0, 0)',
|
||||
|
@ -1,10 +1,11 @@
|
||||
<template>
|
||||
<MkTooltip :source="source" ref="tooltip" @closed="$emit('closed')">
|
||||
<MkTooltip :source="source" ref="tooltip" @closed="$emit('closed')" :max-width="340">
|
||||
<div class="bqxuuuey">
|
||||
<div class="info">
|
||||
<div>{{ reaction.replace('@.', '') }}</div>
|
||||
<div class="reaction">
|
||||
<XReactionIcon :reaction="reaction" :custom-emojis="emojis" class="icon" :no-style="true"/>
|
||||
<div class="name">{{ reaction.replace('@.', '') }}</div>
|
||||
</div>
|
||||
<div class="users">
|
||||
<template v-if="users.length <= 10">
|
||||
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
|
||||
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
|
||||
@ -19,6 +20,7 @@
|
||||
<span slot="omitted">+{{ count - 10 }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</MkTooltip>
|
||||
</template>
|
||||
|
||||
@ -59,8 +61,11 @@ export default defineComponent({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bqxuuuey {
|
||||
> .info {
|
||||
padding: 0 0 8px 0;
|
||||
display: flex;
|
||||
|
||||
> .reaction {
|
||||
flex: 1;
|
||||
max-width: 100px;
|
||||
text-align: center;
|
||||
|
||||
> .icon {
|
||||
@ -68,6 +73,19 @@ export default defineComponent({
|
||||
width: 60px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
> .name {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
|
||||
> .users {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 0.9em;
|
||||
border-left: solid 0.5px var(--divider);
|
||||
padding-left: 10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -177,6 +177,7 @@ export default defineComponent({
|
||||
> span {
|
||||
font-size: 0.9em;
|
||||
line-height: 32px;
|
||||
margin: 0 0 0 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -153,10 +153,4 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._fitSide_ .ssazuxis {
|
||||
> header {
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -42,8 +42,4 @@ export default defineComponent({
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
._fitSide_ .fpezltsf {
|
||||
border-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -50,9 +50,6 @@ export default defineComponent({
|
||||
border-top: solid 0.5px var(--divider);
|
||||
}
|
||||
|
||||
margin-left: 16px;
|
||||
margin-right: 16px;
|
||||
|
||||
> .title {
|
||||
font-size: 0.9em;
|
||||
opacity: 0.7;
|
||||
@ -120,7 +117,7 @@ export default defineComponent({
|
||||
|
||||
> .items {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
|
||||
grid-gap: 8px;
|
||||
padding: 0 16px;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<transition name="tooltip" appear @after-leave="$emit('closed')">
|
||||
<div class="buebdbiu _acrylic _shadow" v-show="showing" ref="content">
|
||||
<div class="buebdbiu _acrylic _shadow" v-show="showing" ref="content" :style="{ maxWidth: maxWidth + 'px' }">
|
||||
<slot>{{ text }}</slot>
|
||||
</div>
|
||||
</transition>
|
||||
@ -21,7 +21,12 @@ export default defineComponent({
|
||||
text: {
|
||||
type: String,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
maxWidth: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 250,
|
||||
},
|
||||
},
|
||||
|
||||
emits: ['closed'],
|
||||
@ -75,11 +80,12 @@ export default defineComponent({
|
||||
.buebdbiu {
|
||||
position: absolute;
|
||||
z-index: 11000;
|
||||
max-width: 240px;
|
||||
font-size: 0.8em;
|
||||
padding: 8px 12px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
border: solid 0.5px var(--divider);
|
||||
pointer-events: none;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="title">{{ $ts.misskeyUpdated }}</div>
|
||||
<div class="version">✨{{ version }}🚀</div>
|
||||
<MkButton full @click="whatIsNew">{{ $ts.whatIsNew }}</MkButton>
|
||||
<MkButton primary full @click="$refs.modal.close()">{{ $ts.gotIt }}</MkButton>
|
||||
<MkButton class="gotIt" primary full @click="$refs.modal.close()">{{ $ts.gotIt }}</MkButton>
|
||||
</div>
|
||||
</MkModal>
|
||||
</template>
|
||||
@ -54,5 +54,9 @@ export default defineComponent({
|
||||
> .version {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
> .gotIt {
|
||||
margin: 8px 0 0 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -37,6 +37,8 @@ import { isMobile } from '@client/scripts/is-mobile';
|
||||
import { initializeSw } from '@client/scripts/initialize-sw';
|
||||
import { reloadChannel } from '@client/scripts/unison-reload';
|
||||
import { reactionPicker } from '@client/scripts/reaction-picker';
|
||||
import { getUrlWithoutLoginId } from '@client/scripts/login-id';
|
||||
import { getAccountFromId } from '@client/scripts/get-account-from-id';
|
||||
|
||||
console.info(`Misskey v${version}`);
|
||||
|
||||
@ -116,6 +118,25 @@ const html = document.documentElement;
|
||||
html.setAttribute('lang', lang);
|
||||
//#endregion
|
||||
|
||||
//#region loginId
|
||||
const params = new URLSearchParams(location.search);
|
||||
const loginId = params.get('loginId');
|
||||
|
||||
if (loginId) {
|
||||
const target = getUrlWithoutLoginId(location.href);
|
||||
|
||||
if (!$i || $i.id !== loginId) {
|
||||
const account = await getAccountFromId(loginId);
|
||||
if (account) {
|
||||
await login(account.token, target);
|
||||
}
|
||||
}
|
||||
|
||||
history.replaceState({ misskey: 'loginId' }, '', target);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Fetch user
|
||||
if ($i && $i.token) {
|
||||
if (_DEV_) {
|
||||
@ -166,8 +187,8 @@ const app = createApp(await (
|
||||
ui === 'deck' ? import('@client/ui/deck.vue') :
|
||||
ui === 'desktop' ? import('@client/ui/desktop.vue') :
|
||||
ui === 'chat' ? import('@client/ui/chat/index.vue') :
|
||||
ui === 'pope' ? import('@client/ui/universal.vue') :
|
||||
import('@client/ui/default.vue')
|
||||
ui === 'classic' ? import('@client/ui/classic.vue') :
|
||||
import('@client/ui/universal.vue')
|
||||
).then(x => x.default));
|
||||
|
||||
if (_DEV_) {
|
||||
|
@ -2,6 +2,7 @@ import { computed, ref } from 'vue';
|
||||
import { search } from '@client/scripts/search';
|
||||
import * as os from '@client/os';
|
||||
import { i18n } from '@client/i18n';
|
||||
import { ui } from '@client/config';
|
||||
import { $i } from './account';
|
||||
import { unisonReload } from '@client/scripts/unison-reload';
|
||||
import { router } from './router';
|
||||
@ -184,35 +185,40 @@ export const menuDef = {
|
||||
action: (ev) => {
|
||||
os.popupMenu([{
|
||||
text: i18n.locale.default,
|
||||
active: ui === 'default' || ui === null,
|
||||
action: () => {
|
||||
localStorage.setItem('ui', 'default');
|
||||
unisonReload();
|
||||
}
|
||||
}, {
|
||||
text: i18n.locale.deck,
|
||||
active: ui === 'deck',
|
||||
action: () => {
|
||||
localStorage.setItem('ui', 'deck');
|
||||
unisonReload();
|
||||
}
|
||||
}, {
|
||||
text: 'pope',
|
||||
text: i18n.locale.classic,
|
||||
active: ui === 'classic',
|
||||
action: () => {
|
||||
localStorage.setItem('ui', 'pope');
|
||||
localStorage.setItem('ui', 'classic');
|
||||
unisonReload();
|
||||
}
|
||||
}, {
|
||||
text: 'Chat (β)',
|
||||
active: ui === 'chat',
|
||||
action: () => {
|
||||
localStorage.setItem('ui', 'chat');
|
||||
unisonReload();
|
||||
}
|
||||
}, {
|
||||
}, /*{
|
||||
text: i18n.locale.desktop + ' (β)',
|
||||
active: ui === 'desktop',
|
||||
action: () => {
|
||||
localStorage.setItem('ui', 'desktop');
|
||||
unisonReload();
|
||||
}
|
||||
}], ev.currentTarget || ev.target);
|
||||
}*/], ev.currentTarget || ev.target);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="uqshojas">
|
||||
<div class="uqshojas">
|
||||
<section class="_card _gap ads" v-for="ad in ads">
|
||||
<div class="_content ad">
|
||||
<MkAd v-if="ad.url" :specify="ad"/>
|
||||
@ -39,7 +37,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -68,11 +65,6 @@ export default defineComponent({
|
||||
title: this.$ts.ads,
|
||||
icon: 'fas fa-audio-description',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.ads,
|
||||
icon: 'fas fa-audio-description',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
asFullButton: true,
|
||||
icon: 'fas fa-plus',
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="ztgjmzrw">
|
||||
<div class="ztgjmzrw">
|
||||
<section class="_card _gap announcements" v-for="announcement in announcements">
|
||||
<div class="_content announcement">
|
||||
<MkInput v-model="announcement.title">
|
||||
@ -21,7 +18,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -48,11 +44,6 @@ export default defineComponent({
|
||||
title: this.$ts.announcements,
|
||||
icon: 'fas fa-broadcast-tower',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.announcements,
|
||||
icon: 'fas fa-broadcast-tower',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
asFullButton: true,
|
||||
icon: 'fas fa-plus',
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div class="ogwlenmc">
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="local" v-if="tab === 'local'">
|
||||
<MkInput v-model="query" :debounce="true" type="search" style="margin: var(--margin);">
|
||||
<template #prefix><i class="fas fa-search"></i></template>
|
||||
@ -50,7 +48,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { computed, defineComponent, toRef } from 'vue';
|
||||
import MkButton from '@client/components/ui/button.vue';
|
||||
import MkInput from '@client/components/form/input.vue';
|
||||
import MkPagination from '@client/components/ui/pagination.vue';
|
||||
@ -71,12 +69,7 @@ export default defineComponent({
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.customEmojis,
|
||||
icon: 'fas fa-laugh',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: computed(() => ({
|
||||
[symbols.PAGE_INFO]: computed(() => ({
|
||||
title: this.$ts.customEmojis,
|
||||
icon: 'fas fa-laugh',
|
||||
bg: 'var(--bg)',
|
||||
@ -119,7 +112,7 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
this.$emit('info', toRef(this, symbols.PAGE_INFO));
|
||||
},
|
||||
|
||||
methods: {
|
||||
@ -175,6 +168,10 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.ogwlenmc {
|
||||
> .local {
|
||||
.empty {
|
||||
margin: var(--margin);
|
||||
}
|
||||
|
||||
.ldhfsamy {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
|
||||
@ -217,6 +214,10 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
> .remote {
|
||||
.empty {
|
||||
margin: var(--margin);
|
||||
}
|
||||
|
||||
.ldhfsamy {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
|
||||
|
@ -3,7 +3,9 @@
|
||||
<div class="nav" v-if="!narrow || page == null">
|
||||
<MkHeader :info="header"></MkHeader>
|
||||
|
||||
<MkSpacer :content-max="700">
|
||||
<div class="lxpfedzu">
|
||||
<div class="banner">
|
||||
<img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
|
||||
</div>
|
||||
|
||||
@ -12,14 +14,19 @@
|
||||
|
||||
<MkSuperMenu :def="menuDef" :grid="page == null"></MkSuperMenu>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
<div class="main">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="childInfo && !childInfo.hideHeader" :info="childInfo"/></template>
|
||||
<component :is="component" :key="page" @info="onInfo" v-bind="pageProps"/>
|
||||
</MkStickyContainer>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { computed, defineAsyncComponent, defineComponent, isRef, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { i18n } from '@client/i18n';
|
||||
import MkSuperMenu from '@client/components/ui/super-menu.vue';
|
||||
import FormGroup from '@client/components/debobigego/group.vue';
|
||||
@ -41,6 +48,10 @@ export default defineComponent({
|
||||
MkInfo,
|
||||
},
|
||||
|
||||
provide: {
|
||||
shouldOmitHeaderTitle: false,
|
||||
},
|
||||
|
||||
props: {
|
||||
initialPage: {
|
||||
type: String,
|
||||
@ -50,17 +61,25 @@ export default defineComponent({
|
||||
|
||||
setup(props, context) {
|
||||
const indexInfo = {
|
||||
title: i18n.locale.instance,
|
||||
title: i18n.locale.controlPanel,
|
||||
icon: 'fas fa-cog',
|
||||
bg: 'var(--bg)',
|
||||
hideHeader: true,
|
||||
};
|
||||
const INFO = ref(indexInfo);
|
||||
const childInfo = ref(null);
|
||||
const page = ref(props.initialPage);
|
||||
const narrow = ref(false);
|
||||
const view = ref(null);
|
||||
const el = ref(null);
|
||||
const onInfo = (viewInfo) => {
|
||||
INFO.value = viewInfo;
|
||||
if (isRef(viewInfo)) {
|
||||
watch(viewInfo, () => {
|
||||
childInfo.value = viewInfo.value;
|
||||
}, { immediate: true });
|
||||
} else {
|
||||
childInfo.value = viewInfo;
|
||||
}
|
||||
};
|
||||
const pageProps = ref({});
|
||||
|
||||
@ -306,7 +325,7 @@ export default defineComponent({
|
||||
[symbols.PAGE_INFO]: INFO,
|
||||
menuDef,
|
||||
header: {
|
||||
title: i18n.locale.controllPanel,
|
||||
title: i18n.locale.controlPanel,
|
||||
},
|
||||
noMaintainerInformation,
|
||||
noBotProtection,
|
||||
@ -315,6 +334,7 @@ export default defineComponent({
|
||||
view,
|
||||
el,
|
||||
onInfo,
|
||||
childInfo,
|
||||
pageProps,
|
||||
component,
|
||||
invite,
|
||||
@ -343,18 +363,16 @@ export default defineComponent({
|
||||
> .main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
--baseContentWidth: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
> .nav {
|
||||
.lxpfedzu {
|
||||
> .info {
|
||||
margin: 16px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lxpfedzu {
|
||||
> .banner {
|
||||
margin: 16px;
|
||||
|
||||
> .icon {
|
||||
@ -363,5 +381,8 @@ export default defineComponent({
|
||||
height: 42px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="edbbcaef" v-size="{ max: [880] }">
|
||||
<div class="edbbcaef" v-size="{ max: [740] }">
|
||||
<div v-if="stats" class="cfcdecdf" style="margin: var(--margin)">
|
||||
<div class="number _panel">
|
||||
<div class="label">Users</div>
|
||||
@ -65,7 +62,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -107,10 +103,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-tachometer-alt',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.dashboard,
|
||||
icon: 'fas fa-tachometer-alt',
|
||||
},
|
||||
version,
|
||||
vueVersion,
|
||||
url,
|
||||
@ -225,12 +217,14 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
&.max-width_800px {
|
||||
&.max-width_740px {
|
||||
> .queue {
|
||||
display: block;
|
||||
|
||||
> .deliver,
|
||||
> .inbox {
|
||||
width: 100%;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: var(--margin);
|
||||
margin-left: 0;
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div class="lknzcolw">
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="users">
|
||||
<div class="inputs">
|
||||
<MkSelect v-model="sort" style="flex: 1;">
|
||||
@ -90,11 +88,6 @@ export default defineComponent({
|
||||
title: this.$ts.users,
|
||||
icon: 'fas fa-users',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.users,
|
||||
icon: 'fas fa-users',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
icon: 'fas fa-search',
|
||||
text: this.$ts.search,
|
||||
@ -109,7 +102,7 @@ export default defineComponent({
|
||||
icon: 'fas fa-search',
|
||||
text: this.$ts.lookup,
|
||||
handler: this.lookupUser
|
||||
}]
|
||||
}],
|
||||
},
|
||||
sort: '+createdAt',
|
||||
state: 'all',
|
||||
|
@ -1,9 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="_section">
|
||||
<MkSpacer :content-max="800">
|
||||
<MkPagination :pagination="pagination" #default="{items}" class="ruryvtyk _content">
|
||||
<section class="_card announcement _gap" v-for="(announcement, i) in items" :key="announcement.id">
|
||||
<section class="_card announcement" v-for="(announcement, i) in items" :key="announcement.id">
|
||||
<div class="_title"><span v-if="$i && !announcement.isRead">🆕 </span>{{ announcement.title }}</div>
|
||||
<div class="_content">
|
||||
<Mfm :text="announcement.text"/>
|
||||
@ -14,8 +12,7 @@
|
||||
</div>
|
||||
</section>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -38,11 +35,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-broadcast-tower',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.announcements,
|
||||
icon: 'fas fa-broadcast-tower',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'announcements',
|
||||
limit: 10,
|
||||
@ -66,6 +58,10 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.ruryvtyk {
|
||||
> .announcement {
|
||||
&:not(:last-child) {
|
||||
margin-bottom: var(--margin);
|
||||
}
|
||||
|
||||
> ._content {
|
||||
> img {
|
||||
display: block;
|
||||
|
@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div :class="$style.root">
|
||||
<div :class="$style.root">
|
||||
<XCategory v-if="tab === 'category'"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -25,11 +22,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-laugh',
|
||||
bg: 'var(--bg)',
|
||||
})),
|
||||
header: computed(() => ({
|
||||
title: this.$ts.customEmojis,
|
||||
icon: 'fas fa-laugh',
|
||||
bg: 'var(--bg)',
|
||||
})),
|
||||
tab: 'category',
|
||||
}
|
||||
},
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<MkSpacer :content-max="1200">
|
||||
<div class="lznhrdub">
|
||||
<div v-if="tab === 'local'">
|
||||
@ -110,13 +108,7 @@ export default defineComponent({
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.explore,
|
||||
icon: 'fas fa-hashtag',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
tab: 'local',
|
||||
header: computed(() => ({
|
||||
[symbols.PAGE_INFO]: computed(() => ({
|
||||
title: this.$ts.explore,
|
||||
icon: 'fas fa-hashtag',
|
||||
bg: 'var(--bg)',
|
||||
@ -134,6 +126,7 @@ export default defineComponent({
|
||||
onClick: () => { this.tab = 'search'; },
|
||||
},]
|
||||
})),
|
||||
tab: 'local',
|
||||
pinnedUsers: { endpoint: 'pinned-users' },
|
||||
popularUsers: { endpoint: 'users', limit: 10, noPaging: true, params: {
|
||||
state: 'alive',
|
||||
|
@ -1,11 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="jmelgwjh">
|
||||
<div class="jmelgwjh">
|
||||
<div class="body">
|
||||
<XNotes class="notes" :pagination="pagination" :detail="true" :prop="'note'" @before="before()" @after="after()"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -28,11 +25,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-star',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.favorites,
|
||||
icon: 'fas fa-star',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'i/favorites',
|
||||
limit: 10,
|
||||
|
@ -1,10 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="_section">
|
||||
<XNotes class="_content" ref="notes" :pagination="pagination" @before="before" @after="after"/>
|
||||
</div>
|
||||
</div>
|
||||
<MkSpacer :content-max="800">
|
||||
<XNotes ref="notes" :pagination="pagination" @before="before" @after="after"/>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -25,11 +22,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-fire-alt',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.featured,
|
||||
icon: 'fas fa-fire-alt',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'notes/featured',
|
||||
limit: 10,
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="taeiyria">
|
||||
<div class="taeiyria">
|
||||
<div class="query">
|
||||
<MkInput v-model="host" :debounce="true" class="">
|
||||
<template #prefix><i class="fas fa-search"></i></template>
|
||||
@ -92,7 +90,6 @@
|
||||
</MkA>
|
||||
</div>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -122,11 +119,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-globe',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.federation,
|
||||
icon: 'fas fa-globe',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
host: '',
|
||||
state: 'federating',
|
||||
sort: '+pubSub',
|
||||
|
@ -1,10 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="_section">
|
||||
<XNotes class="_content" :pagination="pagination" @before="before()" @after="after()"/>
|
||||
</div>
|
||||
</div>
|
||||
<MkSpacer :content-max="800">
|
||||
<XNotes :pagination="pagination" @before="before()" @after="after()"/>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -25,11 +22,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-at',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.mentions,
|
||||
icon: 'fas fa-at',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'notes/mentions',
|
||||
limit: 10,
|
||||
|
@ -1,10 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div>
|
||||
<MkSpacer :content-max="800">
|
||||
<XNotes :pagination="pagination" @before="before()" @after="after()"/>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -25,11 +22,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-envelope',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.directNotes,
|
||||
icon: 'fas fa-envelope',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'notes/mentions',
|
||||
limit: 10,
|
||||
|
@ -1,8 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="yweeujhr _root" v-size="{ max: [400] }">
|
||||
<MkSpacer :content-max="800">
|
||||
<div class="yweeujhr" v-size="{ max: [400] }">
|
||||
<MkButton @click="start" primary class="start"><i class="fas fa-plus"></i> {{ $ts.startMessaging }}</MkButton>
|
||||
|
||||
<div class="history" v-if="messages.length > 0">
|
||||
@ -37,7 +35,7 @@
|
||||
</div>
|
||||
<MkLoading v-if="fetching"/>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -60,11 +58,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-comments',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.messaging,
|
||||
icon: 'fas fa-comments',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
fetching: true,
|
||||
moreFetching: false,
|
||||
messages: [],
|
||||
@ -177,7 +170,7 @@ export default defineComponent({
|
||||
.yweeujhr {
|
||||
|
||||
> .start {
|
||||
margin: var(--margin) auto var(--margin) auto;
|
||||
margin: 0 auto var(--margin) auto;
|
||||
}
|
||||
|
||||
> .history {
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="qkcjvfiv">
|
||||
<div class="qkcjvfiv">
|
||||
<MkButton @click="create" primary class="add"><i class="fas fa-plus"></i> {{ $ts.createList }}</MkButton>
|
||||
|
||||
<MkPagination :pagination="pagination" #default="{items}" class="lists _content" ref="list">
|
||||
@ -10,7 +8,6 @@
|
||||
<MkAvatars :user-ids="list.userIds"/>
|
||||
</MkA>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -35,15 +32,10 @@ export default defineComponent({
|
||||
title: this.$ts.manageLists,
|
||||
icon: 'fas fa-list-ul',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.manageLists,
|
||||
icon: 'fas fa-list-ul',
|
||||
bg: 'var(--bg)',
|
||||
action: {
|
||||
icon: 'fas fa-plus',
|
||||
handler: this.create
|
||||
}
|
||||
},
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'users/lists/list',
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader v-if="header" :info="header"/>
|
||||
<div class="mk-list-page">
|
||||
<div class="mk-list-page">
|
||||
<transition name="zoom" mode="out-in">
|
||||
<div v-if="list" class="_section">
|
||||
<div class="_content">
|
||||
@ -31,7 +29,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -53,10 +50,6 @@ export default defineComponent({
|
||||
title: this.list.name,
|
||||
icon: 'fas fa-list-ul',
|
||||
} : null),
|
||||
header: computed(() => this.list ? {
|
||||
title: this.list.name,
|
||||
icon: 'fas fa-list-ul',
|
||||
} : null),
|
||||
list: null,
|
||||
users: [],
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="fcuexfpr">
|
||||
<div class="_root">
|
||||
<MkSpacer :content-max="800">
|
||||
<div class="fcuexfpr">
|
||||
<transition name="fade" mode="out-in">
|
||||
<div v-if="note" class="note">
|
||||
<div class="_gap" v-if="showNext">
|
||||
@ -34,7 +34,7 @@
|
||||
<MkLoading v-else/>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -153,7 +153,6 @@ export default defineComponent({
|
||||
.fcuexfpr {
|
||||
background: var(--bg);
|
||||
|
||||
> ._root {
|
||||
> .note {
|
||||
> .main {
|
||||
> .load {
|
||||
@ -206,6 +205,5 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,12 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<MkSpacer :content-max="800">
|
||||
<MkSpacer :content-max="800">
|
||||
<div class="clupoqwt">
|
||||
<XNotifications class="notifications" @before="before" @after="after" :include-types="includeTypes" :unread-only="tab === 'unread'"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -24,14 +21,7 @@ export default defineComponent({
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.notifications,
|
||||
icon: 'fas fa-bell',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
tab: 'all',
|
||||
includeTypes: null,
|
||||
header: computed(() => ({
|
||||
[symbols.PAGE_INFO]: computed(() => ({
|
||||
title: this.$ts.notifications,
|
||||
icon: 'fas fa-bell',
|
||||
bg: 'var(--bg)',
|
||||
@ -57,6 +47,8 @@ export default defineComponent({
|
||||
onClick: () => { this.tab = 'unread'; },
|
||||
},]
|
||||
})),
|
||||
tab: 'all',
|
||||
includeTypes: null,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="_root">
|
||||
<div class="jqqmcavi" style="margin: 16px;">
|
||||
<MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="fas fa-external-link-square-alt"></i> {{ $ts._pages.viewPage }}</MkButton>
|
||||
<MkButton inline @click="save" primary class="button" v-if="!readonly"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
|
||||
@ -78,7 +75,6 @@
|
||||
<MkTextarea class="_code" v-model="script"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -131,21 +127,6 @@ export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: computed(() => {
|
||||
let title = this.$ts._pages.newPage;
|
||||
if (this.initPageId) {
|
||||
title = this.$ts._pages.editPage;
|
||||
}
|
||||
else if (this.initPageName && this.initUser) {
|
||||
title = this.$ts._pages.readPage;
|
||||
}
|
||||
return {
|
||||
title: title,
|
||||
icon: 'fas fa-pencil-alt',
|
||||
bg: 'var(--bg)',
|
||||
};
|
||||
}),
|
||||
tab: 'settings',
|
||||
header: computed(() => {
|
||||
let title = this.$ts._pages.newPage;
|
||||
if (this.initPageId) {
|
||||
title = this.$ts._pages.editPage;
|
||||
@ -177,9 +158,10 @@ export default defineComponent({
|
||||
title: this.$ts.script,
|
||||
icon: 'fas fa-code',
|
||||
onClick: () => { this.tab = 'script'; },
|
||||
}]
|
||||
}],
|
||||
};
|
||||
}),
|
||||
tab: 'settings',
|
||||
author: this.$i,
|
||||
readonly: false,
|
||||
page: null,
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<div class="_root">
|
||||
<transition name="fade" mode="out-in">
|
||||
<div v-if="page" class="xcukqgmh" :key="page.id" v-size="{ max: [450] }">
|
||||
<div class="_block main">
|
||||
@ -59,7 +56,6 @@
|
||||
<MkError v-else-if="error" @retry="fetch()"/>
|
||||
<MkLoading v-else/>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -101,10 +97,6 @@ export default defineComponent({
|
||||
[symbols.PAGE_INFO]: computed(() => this.page ? {
|
||||
title: computed(() => this.page.title || this.page.name),
|
||||
avatar: this.page.user,
|
||||
} : null),
|
||||
header: computed(() => this.page ? {
|
||||
title: computed(() => this.page.title || this.page.name),
|
||||
avatar: this.page.user,
|
||||
path: `/@${this.page.user.username}/pages/${this.page.name}`,
|
||||
share: {
|
||||
title: this.page.title || this.page.name,
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
|
||||
<MkSpacer>
|
||||
<MkSpacer>
|
||||
<!-- TODO: MkHeaderに統合 -->
|
||||
<MkTab v-model="tab" v-if="$i">
|
||||
<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._pages.featured }}</option>
|
||||
@ -30,8 +27,7 @@
|
||||
</MkPagination>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -52,11 +48,6 @@ export default defineComponent({
|
||||
title: this.$ts.pages,
|
||||
icon: 'fas fa-sticky-note',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
header: {
|
||||
title: this.$ts.pages,
|
||||
icon: 'fas fa-sticky-note',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
icon: 'fas fa-plus',
|
||||
text: this.$ts.create,
|
||||
|
@ -1,11 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<div class="_section">
|
||||
<div class="_section">
|
||||
<div class="_content">
|
||||
<XNotes ref="notes" :pagination="pagination" @before="before" @after="after"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -26,10 +23,6 @@ export default defineComponent({
|
||||
title: computed(() => this.$t('searchWith', { q: this.$route.query.q })),
|
||||
icon: 'fas fa-search',
|
||||
},
|
||||
header: {
|
||||
title: computed(() => this.$t('searchWith', { q: this.$route.query.q })),
|
||||
icon: 'fas fa-search',
|
||||
},
|
||||
pagination: {
|
||||
endpoint: 'notes/search',
|
||||
limit: 10,
|
||||
|
@ -35,7 +35,6 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
import ApexCharts from 'apexcharts';
|
||||
import FormButton from '@client/components/debobigego/button.vue';
|
||||
import FormGroup from '@client/components/debobigego/group.vue';
|
||||
import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
|
||||
@ -44,6 +43,8 @@ import * as os from '@client/os';
|
||||
import bytes from '@client/filters/bytes';
|
||||
import * as symbols from '@client/symbols';
|
||||
|
||||
// TODO: render chart
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
@ -117,104 +118,6 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
|
||||
renderChart() {
|
||||
os.api('charts/user/drive', {
|
||||
userId: this.$i.id,
|
||||
span: 'day',
|
||||
limit: 21
|
||||
}).then(stats => {
|
||||
const addition = [];
|
||||
const deletion = [];
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
for (let i = 0; i < 21; i++) {
|
||||
const x = new Date(y, m, d - i);
|
||||
addition.push([
|
||||
x,
|
||||
stats.incSize[i]
|
||||
]);
|
||||
deletion.push([
|
||||
x,
|
||||
-stats.decSize[i]
|
||||
]);
|
||||
}
|
||||
const chart = new ApexCharts(this.$refs.chart, {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
stacked: true,
|
||||
height: 150,
|
||||
toolbar: {
|
||||
show: false
|
||||
},
|
||||
zoom: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '80%'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
clipMarkers: false,
|
||||
borderColor: 'rgba(0, 0, 0, 0.1)',
|
||||
xaxis: {
|
||||
lines: {
|
||||
show: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
shared: true,
|
||||
intersect: false,
|
||||
theme: this.$store.state.darkMode ? 'dark' : 'light',
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
series: [{
|
||||
name: 'Additions',
|
||||
data: addition
|
||||
}, {
|
||||
name: 'Deletions',
|
||||
data: deletion
|
||||
}],
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
labels: {
|
||||
style: {
|
||||
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--fg')).toRgbString()
|
||||
}
|
||||
},
|
||||
axisBorder: {
|
||||
color: 'rgba(0, 0, 0, 0.1)'
|
||||
},
|
||||
axisTicks: {
|
||||
color: 'rgba(0, 0, 0, 0.1)'
|
||||
},
|
||||
crosshairs: {
|
||||
width: 1,
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: v => bytes(v, 0),
|
||||
style: {
|
||||
colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--fg')).toRgbString()
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
chart.render();
|
||||
});
|
||||
},
|
||||
|
||||
bytes
|
||||
}
|
||||
});
|
||||
|
@ -1,10 +1,14 @@
|
||||
<template>
|
||||
<div class="vvcocwet" :class="{ wide: !narrow }" ref="el">
|
||||
<div class="nav" v-if="!narrow || page == null">
|
||||
<MkSpacer :content-max="700">
|
||||
<div class="baaadecd">
|
||||
<div class="title">{{ $ts.settings }}</div>
|
||||
<MkInfo v-if="emailNotConfigured" warn class="info">{{ $ts.emailNotConfiguredWarning }} <MkA to="/settings/email" class="_link">{{ $ts.configure }}</MkA></MkInfo>
|
||||
<MkSuperMenu :def="menuDef" :grid="page == null"></MkSuperMenu>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
<div class="main">
|
||||
<component :is="component" :key="page" v-bind="pageProps"/>
|
||||
</div>
|
||||
@ -41,6 +45,7 @@ export default defineComponent({
|
||||
title: i18n.locale.settings,
|
||||
icon: 'fas fa-cog',
|
||||
bg: 'var(--bg)',
|
||||
hideHeader: true,
|
||||
};
|
||||
const INFO = ref(indexInfo);
|
||||
const page = ref(props.initialPage);
|
||||
@ -271,6 +276,7 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.vvcocwet {
|
||||
> .nav {
|
||||
.baaadecd {
|
||||
> .title {
|
||||
margin: 16px;
|
||||
font-size: 1.5em;
|
||||
@ -290,6 +296,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.wide {
|
||||
display: flex;
|
||||
@ -302,8 +309,10 @@ export default defineComponent({
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
|
||||
.baaadecd {
|
||||
> .title {
|
||||
margin: 24px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,7 +320,6 @@ export default defineComponent({
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
--baseContentWidth: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div v-hotkey.global="keymap">
|
||||
<MkHeader :info="header"/>
|
||||
<div class="cmuxhskf" v-size="{ min: [800] }">
|
||||
<div class="cmuxhskf" v-size="{ min: [800] }" v-hotkey.global="keymap">
|
||||
<XTutorial v-if="$store.reactiveState.tutorial.value != -1" class="tutorial _block"/>
|
||||
<XPostForm v-if="$store.reactiveState.showFixedPostForm.value" class="post-form _block" fixed/>
|
||||
|
||||
@ -16,7 +14,6 @@
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -46,11 +43,6 @@ export default defineComponent({
|
||||
title: this.$ts.timeline,
|
||||
icon: this.src === 'local' ? 'fas fa-comments' : this.src === 'social' ? 'fas fa-share-alt' : this.src === 'global' ? 'fas fa-globe' : 'fas fa-home',
|
||||
bg: 'var(--bg)',
|
||||
})),
|
||||
header: computed(() => ({
|
||||
title: this.$ts.timeline,
|
||||
icon: this.src === 'local' ? 'fas fa-comments' : this.src === 'social' ? 'fas fa-share-alt' : this.src === 'global' ? 'fas fa-globe' : 'fas fa-home',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
icon: 'fas fa-list-ul',
|
||||
text: this.$ts.lists,
|
||||
@ -92,7 +84,7 @@ export default defineComponent({
|
||||
icon: 'fas fa-globe',
|
||||
iconOnly: true,
|
||||
onClick: () => { this.src = 'global'; this.saveSrc(); },
|
||||
}]
|
||||
}],
|
||||
})),
|
||||
};
|
||||
},
|
||||
|
@ -3,20 +3,21 @@
|
||||
<template #header><i class="fas fa-chart-bar" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template>
|
||||
|
||||
<div style="padding: 8px;">
|
||||
<div ref="chart"></div>
|
||||
<MkChart src="per-user-notes" :args="{ user, withoutAll: true }" span="day" :limit="limit" :stacked="true" :detailed="false" :aspect-ratio="6"/>
|
||||
</div>
|
||||
</MkContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import ApexCharts from 'apexcharts';
|
||||
import * as os from '@client/os';
|
||||
import MkContainer from '@client/components/ui/container.vue';
|
||||
import MkChart from '@client/components/chart.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkContainer,
|
||||
MkChart,
|
||||
},
|
||||
props: {
|
||||
user: {
|
||||
@ -29,96 +30,5 @@ export default defineComponent({
|
||||
default: 40
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fetching: true,
|
||||
data: [],
|
||||
peak: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
os.api('charts/user/notes', {
|
||||
userId: this.user.id,
|
||||
span: 'day',
|
||||
limit: this.limit
|
||||
}).then(stats => {
|
||||
const normal = [];
|
||||
const reply = [];
|
||||
const renote = [];
|
||||
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = now.getMonth();
|
||||
const d = now.getDate();
|
||||
|
||||
for (let i = 0; i < this.limit; i++) {
|
||||
const x = new Date(y, m, d - i);
|
||||
normal.push([
|
||||
x,
|
||||
stats.diffs.normal[i]
|
||||
]);
|
||||
reply.push([
|
||||
x,
|
||||
stats.diffs.reply[i]
|
||||
]);
|
||||
renote.push([
|
||||
x,
|
||||
stats.diffs.renote[i]
|
||||
]);
|
||||
}
|
||||
|
||||
const chart = new ApexCharts(this.$refs.chart, {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
stacked: true,
|
||||
height: 100,
|
||||
sparkline: {
|
||||
enabled: true
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40%'
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
grid: {
|
||||
clipMarkers: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
right: 8,
|
||||
bottom: 0,
|
||||
left: 8
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
shared: true,
|
||||
intersect: false,
|
||||
theme: this.$store.state.darkMode ? 'dark' : 'light',
|
||||
},
|
||||
series: [{
|
||||
name: 'Normal',
|
||||
data: normal
|
||||
}, {
|
||||
name: 'Reply',
|
||||
data: reply
|
||||
}, {
|
||||
name: 'Renote',
|
||||
data: renote
|
||||
}],
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
crosshairs: {
|
||||
width: 1,
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
chart.render();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -65,11 +65,4 @@ export default defineComponent({
|
||||
background: var(--bg);
|
||||
}
|
||||
}
|
||||
|
||||
._fitSide_ .yrzkoczt {
|
||||
> .tab {
|
||||
padding-left: var(--margin);
|
||||
padding-right: var(--margin);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<MkHeader :info="header"/>
|
||||
<transition name="fade" mode="out-in">
|
||||
<transition name="fade" mode="out-in">
|
||||
<div class="ftskorzw wide" v-if="user && narrow === false">
|
||||
<MkRemoteCaution v-if="user.host != null" :href="user.url"/>
|
||||
|
||||
@ -81,7 +80,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ftskorzw narrow _root" v-else-if="user && narrow === true" v-size="{ max: [500] }">
|
||||
<MkSpacer v-else-if="user && narrow === true" :content-max="800">
|
||||
<div class="ftskorzw narrow" v-size="{ max: [500] }">
|
||||
<!-- TODO -->
|
||||
<!-- <div class="punished" v-if="user.isSuspended"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i> {{ $ts.userSuspended }}</div> -->
|
||||
<!-- <div class="punished" v-if="user.isSilenced"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i> {{ $ts.userSilenced }}</div> -->
|
||||
@ -173,7 +173,7 @@
|
||||
</div>
|
||||
<MkInfo v-else-if="$i && $i.id === user.id">{{ $ts.userPagePinTip }}</MkInfo>
|
||||
<XPhotos :user="user" :key="user.id"/>
|
||||
<XActivity :user="user" :key="user.id"/>
|
||||
<XActivity :user="user" :key="user.id" style="margin-top: var(--margin);"/>
|
||||
</div>
|
||||
<div>
|
||||
<XUserTimeline :user="user"/>
|
||||
@ -187,9 +187,10 @@
|
||||
<XGallery v-else-if="page === 'gallery'" :user="user" class="_gap"/>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
<MkError v-else-if="error" @retry="fetch()"/>
|
||||
<MkLoading v-else/>
|
||||
</transition>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -248,14 +249,6 @@ export default defineComponent({
|
||||
return {
|
||||
[symbols.PAGE_INFO]: computed(() => this.user ? {
|
||||
icon: 'fas fa-user',
|
||||
title: this.user.name ? `${this.user.name} (@${this.user.username})` : `@${this.user.username}`,
|
||||
path: `/@${this.user.username}`,
|
||||
share: {
|
||||
title: this.user.name,
|
||||
},
|
||||
bg: 'var(--bg)',
|
||||
} : null),
|
||||
header: computed(() => this.user ? {
|
||||
title: this.user.name ? `${this.user.name} (@${this.user.username})` : `@${this.user.username}`,
|
||||
subtitle: `@${getAcct(this.user)}`,
|
||||
userName: this.user,
|
||||
@ -290,7 +283,7 @@ export default defineComponent({
|
||||
title: this.$ts.gallery,
|
||||
icon: 'fas fa-icons',
|
||||
onClick: () => { this.$router.push('/@' + getAcct(this.user) + '/gallery'); },
|
||||
}]
|
||||
}],
|
||||
} : null),
|
||||
user: null,
|
||||
error: null,
|
||||
@ -833,16 +826,4 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._fitSide_ .ftskorzw.narrow {
|
||||
> .profile {
|
||||
> .warn {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> .main {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
11
src/client/scripts/login-id.ts
Normal file
11
src/client/scripts/login-id.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export function getUrlWithLoginId(url: string, loginId: string) {
|
||||
const u = new URL(url, origin);
|
||||
u.searchParams.append('loginId', loginId);
|
||||
return u.toString();
|
||||
}
|
||||
|
||||
export function getUrlWithoutLoginId(url: string) {
|
||||
const u = new URL(url);
|
||||
u.searchParams.delete('loginId');
|
||||
return u.toString();
|
||||
}
|
@ -144,7 +144,7 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||
},
|
||||
useBlurEffect: {
|
||||
where: 'device',
|
||||
default: false
|
||||
default: true
|
||||
},
|
||||
showFixedPostForm: {
|
||||
where: 'device',
|
||||
|
@ -1,7 +1,6 @@
|
||||
@charset "utf-8";
|
||||
|
||||
:root {
|
||||
--baseContentWidth: 760px;
|
||||
--radius: 12px;
|
||||
--marginFull: 16px;
|
||||
--marginHalf: 10px;
|
||||
@ -350,21 +349,6 @@ hr {
|
||||
}
|
||||
|
||||
// TODO: 廃止
|
||||
._root {
|
||||
box-sizing: border-box;
|
||||
margin: var(--root-margin, 32px) auto;
|
||||
max-width: min(var(--baseContentWidth), calc(100% - (var(--root-margin, 32px) * 2)));
|
||||
|
||||
// 子marginが突き抜けるのを防ぐため
|
||||
// https://stackoverflow.com/questions/1762539/margin-on-child-element-moves-parent-element
|
||||
padding-top: 1px;
|
||||
margin-top: calc(var(--root-margin, 32px) - 1px);
|
||||
|
||||
@media (max-width: 500px) {
|
||||
--root-margin: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
._monolithic_ {
|
||||
._section:not(:empty) {
|
||||
box-sizing: border-box;
|
||||
@ -380,33 +364,6 @@ hr {
|
||||
}
|
||||
}
|
||||
|
||||
._fitSide_ {
|
||||
--root-margin: 0px;
|
||||
--baseContentWidth: 100%;
|
||||
--panelBorder: none;
|
||||
|
||||
._block {
|
||||
//border-top: solid 0.5px var(--divider);
|
||||
//border-bottom: solid 0.5px var(--divider);
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
._isolated {
|
||||
margin: var(--margin);
|
||||
}
|
||||
|
||||
._block._isolated {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
._root {
|
||||
--root-margin: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._narrow_ ._card {
|
||||
> ._title {
|
||||
padding: 16px;
|
||||
|
@ -15,5 +15,6 @@
|
||||
navBg: '#fff',
|
||||
panel: '#fff',
|
||||
panelHeaderDivider: '@divider',
|
||||
mentionMe: 'rgb(0, 179, 70)',
|
||||
},
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
</template>
|
||||
<div class="divider"></div>
|
||||
<MkA v-if="$i.isAdmin || $i.isModerator" class="item" active-class="active" to="/admin" v-click-anime>
|
||||
<i class="fas fa-server fa-fw"></i><span class="text">{{ $ts.instance }}</span>
|
||||
<i class="fas fa-door-open fa-fw"></i><span class="text">{{ $ts.controlPanel }}</span>
|
||||
</MkA>
|
||||
<button class="item _button" @click="more" v-click-anime>
|
||||
<i class="fa fa-ellipsis-h fa-fw"></i><span class="text">{{ $ts.more }}</span>
|
||||
@ -35,7 +35,7 @@
|
||||
<MkA class="item" active-class="active" to="/settings" v-click-anime>
|
||||
<i class="fas fa-cog fa-fw"></i><span class="text">{{ $ts.settings }}</span>
|
||||
</MkA>
|
||||
<button class="item _button post" @click="post">
|
||||
<button class="item _button post" @click="post" data-cy-open-post-form>
|
||||
<i class="fas fa-pencil-alt fa-fw"></i><span class="text">{{ $ts.note }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<header class="header" @contextmenu.prevent.stop="onContextmenu">
|
||||
<MkHeader class="title" :info="pageInfo" :center="false"/>
|
||||
</header>
|
||||
<component :is="component" v-bind="props" :ref="changePage" class="body _fitSide_"/>
|
||||
<component :is="component" v-bind="props" :ref="changePage" class="body"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -13,8 +13,8 @@
|
||||
</component>
|
||||
</template>
|
||||
<div class="divider"></div>
|
||||
<MkA v-if="$i.isAdmin || $i.isModerator" class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null" v-click-anime v-tooltip="$ts.instance">
|
||||
<i class="fas fa-server fa-fw"></i>
|
||||
<MkA v-if="$i.isAdmin || $i.isModerator" class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null" v-click-anime v-tooltip="$ts.controlPanel">
|
||||
<i class="fas fa-door-open fa-fw"></i>
|
||||
</MkA>
|
||||
<button class="item _button" @click="more" v-click-anime>
|
||||
<i class="fas fa-ellipsis-h fa-fw"></i>
|
@ -21,7 +21,7 @@
|
||||
</template>
|
||||
<div class="divider"></div>
|
||||
<MkA v-if="$i.isAdmin || $i.isModerator" class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null" v-click-anime>
|
||||
<i class="fas fa-server fa-fw"></i><span class="text">{{ $ts.instance }}</span>
|
||||
<i class="fas fa-door-open fa-fw"></i><span class="text">{{ $ts.controlPanel }}</span>
|
||||
</MkA>
|
||||
<button class="item _button" @click="more" v-click-anime>
|
||||
<i class="fas fa-ellipsis-h fa-fw"></i><span class="text">{{ $ts.more }}</span>
|
@ -13,7 +13,9 @@
|
||||
</template>
|
||||
|
||||
<main class="main" @contextmenu.stop="onContextmenu" :style="{ background: pageInfo?.bg }">
|
||||
<div class="content" :class="{ _fitSide_: !fullView }">
|
||||
<div class="content">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template>
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
|
||||
<keep-alive :include="['timeline']">
|
||||
@ -21,6 +23,7 @@
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</MkStickyContainer>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@ -61,7 +64,7 @@
|
||||
import { defineComponent, defineAsyncComponent, markRaw } from 'vue';
|
||||
import { instanceName } from '@client/config';
|
||||
import { StickySidebar } from '@client/scripts/sticky-sidebar';
|
||||
import XSidebar from './default.sidebar.vue';
|
||||
import XSidebar from './classic.sidebar.vue';
|
||||
import XDrawerSidebar from '@client/ui/_common_/sidebar.vue';
|
||||
import XCommon from './_common_/common.vue';
|
||||
import * as os from '@client/os';
|
||||
@ -76,8 +79,8 @@ export default defineComponent({
|
||||
XCommon,
|
||||
XSidebar,
|
||||
XDrawerSidebar,
|
||||
XHeaderMenu: defineAsyncComponent(() => import('./default.header.vue')),
|
||||
XWidgets: defineAsyncComponent(() => import('./default.widgets.vue')),
|
||||
XHeaderMenu: defineAsyncComponent(() => import('./classic.header.vue')),
|
||||
XWidgets: defineAsyncComponent(() => import('./classic.widgets.vue')),
|
||||
},
|
||||
|
||||
provide() {
|
@ -7,13 +7,16 @@
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<router-view v-slot="{ Component }" class="_fitSide_">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template>
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition>
|
||||
<keep-alive :include="['timeline']">
|
||||
<component :is="Component" :ref="changePage" @contextmenu.stop="onContextmenu"/>
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</MkStickyContainer>
|
||||
</XColumn>
|
||||
</template>
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
<div class="contents" ref="contents" @contextmenu.stop="onContextmenu" :style="{ background: pageInfo?.bg }">
|
||||
<main ref="main">
|
||||
<div class="content">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template>
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition :name="$store.state.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
|
||||
<keep-alive :include="['timeline']">
|
||||
@ -12,6 +14,7 @@
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</MkStickyContainer>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
</main>
|
||||
@ -55,7 +58,7 @@ import { instanceName } from '@client/config';
|
||||
import { StickySidebar } from '@client/scripts/sticky-sidebar';
|
||||
import XSidebar from '@client/ui/_common_/sidebar.vue';
|
||||
import XCommon from './_common_/common.vue';
|
||||
import XSide from './default.side.vue';
|
||||
import XSide from './classic.side.vue';
|
||||
import * as os from '@client/os';
|
||||
import { menuDef } from '@client/menu';
|
||||
import * as symbols from '@client/symbols';
|
||||
|
@ -3,7 +3,7 @@
|
||||
<template #header><i class="fas fa-bell"></i>{{ $ts.notifications }}</template>
|
||||
<template #func><button @click="configure()" class="_button"><i class="fas fa-cog"></i></button></template>
|
||||
|
||||
<div class="_fitSide_">
|
||||
<div>
|
||||
<XNotifications :include-types="props.includingTypes"/>
|
||||
</div>
|
||||
</MkContainer>
|
||||
|
@ -17,6 +17,7 @@ import { PollVote } from '@/models/entities/poll-vote';
|
||||
import { Note } from '@/models/entities/note';
|
||||
import { NoteReaction } from '@/models/entities/note-reaction';
|
||||
import { NoteWatching } from '@/models/entities/note-watching';
|
||||
import { NoteThreadMuting } from '@/models/entities/note-thread-muting';
|
||||
import { NoteUnread } from '@/models/entities/note-unread';
|
||||
import { Notification } from '@/models/entities/notification';
|
||||
import { Meta } from '@/models/entities/meta';
|
||||
@ -138,6 +139,7 @@ export const entities = [
|
||||
NoteFavorite,
|
||||
NoteReaction,
|
||||
NoteWatching,
|
||||
NoteThreadMuting,
|
||||
NoteUnread,
|
||||
Page,
|
||||
PageLike,
|
||||
|
@ -33,7 +33,7 @@
|
||||
<dd>Renote先のUrl(リモートのノートオブジェクトを指定)</dd>
|
||||
</dl>
|
||||
|
||||
### 公開範囲
|
||||
### الظهور
|
||||
※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する
|
||||
|
||||
<dl>
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
**ストリームでのやり取りはすべてJSONです。**
|
||||
|
||||
## チャンネル
|
||||
## القنوات
|
||||
MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。
|
||||
|
||||
ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="info">ℹ️ コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。</div>
|
||||
<div class="info">ℹ️ テキストボックス内で<kbd class="key">Ctrl + Enter</kbd>を押すことでも投稿できます。</div>
|
||||
|
||||
## Renote
|
||||
## أعد النشر
|
||||
既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じノートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。
|
||||
<div class="warn">⚠️ 公開範囲がフォロワーやダイレクトのノートはRenoteできません</div>
|
||||
|
||||
@ -21,7 +21,7 @@ Renoteを削除するには、Renoteの時刻表示の隣にある「...」を
|
||||
## CW
|
||||
Contents Warningの略で、ノートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。
|
||||
|
||||
## 公開範囲
|
||||
## الظهور
|
||||
ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。
|
||||
|
||||
### للعامة
|
||||
|
@ -34,7 +34,7 @@ Misskeyに関する用語集です。
|
||||
## NSFW
|
||||
(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。
|
||||
|
||||
## Renote
|
||||
## أعد النشر
|
||||
(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note)
|
||||
|
||||
## STL
|
||||
|
@ -4,7 +4,7 @@
|
||||
- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー
|
||||
- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム
|
||||
|
||||
## アカウント
|
||||
## الحسابات
|
||||
- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot
|
||||
|
||||
## ライブラリ
|
||||
|
@ -1,24 +1,24 @@
|
||||
# キーボードショートカット
|
||||
# Keyboard shortcuts
|
||||
|
||||
## Global
|
||||
これらのショートカットは基本的にどこでも使えます。
|
||||
These shortcuts are usually available anywhere.
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
|
||||
<tr><th>Shortcut</th><th>Effect</th><th>Why this key?</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>新規投稿</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
|
||||
<tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
|
||||
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>通知を表示/隠す</td><td><b>N</b>otifications</td></tr>
|
||||
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>Create a note</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
|
||||
<tr><td><kbd class="key">T</kbd></td><td>Focus the latest note</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
|
||||
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>Show/hide notifications</td><td><b>N</b>otifications</td></tr>
|
||||
<tr><td><kbd class="key">S</kbd></td><td>Search</td><td><b>S</b>earch</td></tr>
|
||||
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>ヘルプを表示</td><td><b>H</b>elp</td></tr>
|
||||
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>Show help</td><td><b>H</b>elp</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 投稿にフォーカスされた状態
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
|
||||
<tr><th>Shortcut</th><th>Effect</th><th>Why this key?</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">↑</kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr>
|
||||
@ -39,12 +39,12 @@
|
||||
## Renoteフォーム
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
|
||||
<tr><th>Shortcut</th><th>Effect</th><th>Why this key?</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">Enter</kbd></td><td>Renoteする</td><td>-</td></tr>
|
||||
<tr><td><kbd class="key">Q</kbd></td><td>フォームを展開する</td><td><b>Q</b>uote</td></tr>
|
||||
<tr><td><kbd class="key">Esc</kbd></td><td>フォームを閉じる</td><td>-</td></tr>
|
||||
<tr><td><kbd class="key">Enter</kbd></td><td>Renote</td><td>-</td></tr>
|
||||
<tr><td><kbd class="key">Q</kbd></td><td>Expand form</td><td><b>Q</b>uote</td></tr>
|
||||
<tr><td><kbd class="key">Esc</kbd></td><td>Close form</td><td>-</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
デフォルトで「👍」にフォーカスが当たっている状態です。
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
|
||||
<tr><th>Shortcut</th><th>Effect</th><th>Why this key?</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><kbd class="key">↑</kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr>
|
||||
|
@ -1,9 +1,9 @@
|
||||
# Pages
|
||||
|
||||
## Variables
|
||||
変数を使うことで動的なページを作成できます。テキスト内で <b>{ 変数名 }</b> と書くとそこに変数の値を埋め込めます。例えば <b>Hello { thing } world!</b> というテキストで、変数(thing)の値が <b>ai</b> だった場合、テキストは <b>Hello ai world!</b> になります。
|
||||
Use variables to create dynamic pages. Put <b>{ variable-name }</b> in your content to embed the value. For example, if a variable named "thing" has the value <b>ai</b>, the string <b>Hello { thing } world!</b> turns into <b>Hello ai world!</b>.
|
||||
|
||||
変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から <b>A、B、C</b> と3つの変数を定義したとき、<b>C</b>の中で<b>A</b>や<b>B</b>を参照することはできますが、<b>A</b>の中で<b>B</b>や<b>C</b>を参照することはできません。
|
||||
Variables are evaluated from top to bottom, so referencing variables before declaring is not possible. For example, when declaring the three variables <b>A, B, C</b> in this order, you can use <b>A</b> or <b>B</b> in <b>C</b>, but you cannot use <b>B</b> or <b>C</b> in <b>A</b>.
|
||||
|
||||
ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user