Merge branch 'develop' into notification-read-api
This commit is contained in:
commit
a626a5a407
52 changed files with 621 additions and 452 deletions
|
@ -7,20 +7,27 @@
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## 12.x.x (unreleased)
|
## 12.96.0 (2021/11/13)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
- フォロー/フォロワーを非公開にできるように
|
- フォロー/フォロワーを非公開にできるように
|
||||||
- インスタンスプロフィールレンダリング ready
|
- インスタンスプロフィールレンダリング ready
|
||||||
- 通知のリアクションアイコンをホバーで拡大できるように
|
- 通知のリアクションアイコンをホバーで拡大できるように
|
||||||
|
- RenoteボタンをホバーでRenoteしたユーザー一覧を表示するように
|
||||||
|
- 返信の際にメンションを含めるように
|
||||||
|
- 通報があったときに管理者へEメールで通知されるように
|
||||||
- メールアドレスのバリデーションを強化
|
- メールアドレスのバリデーションを強化
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
- アカウント削除処理があると高負荷になる問題を修正
|
||||||
- クライアント: 長いメニューが画面からはみ出す問題を修正
|
- クライアント: 長いメニューが画面からはみ出す問題を修正
|
||||||
- クライアント: コントロールパネルのジョブキューに個々のジョブが表示されないのを修正
|
- クライアント: コントロールパネルのジョブキューに個々のジョブが表示されないのを修正
|
||||||
- クライアント: fix missing i18n string
|
- クライアント: fix missing i18n string
|
||||||
- fix html conversion issue with code blocks
|
- fix html conversion issue with code blocks
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- ノートにモバイルからの投稿か否かの情報を含めないように
|
||||||
|
|
||||||
## 12.95.0 (2021/10/31)
|
## 12.95.0 (2021/10/31)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
|
|
@ -797,6 +797,15 @@ unread: "Non lu"
|
||||||
filter: "Filtre"
|
filter: "Filtre"
|
||||||
controlPanel: "Panneau de contrôle"
|
controlPanel: "Panneau de contrôle"
|
||||||
manageAccounts: "Gérer les comptes"
|
manageAccounts: "Gérer les comptes"
|
||||||
|
classic: "Classique"
|
||||||
|
_emailUnavailable:
|
||||||
|
format: "Le format de cette adresse de courriel est invalide"
|
||||||
|
mx: "Ce serveur de courriels est invalide"
|
||||||
|
smtp: "Ce serveur de courriels ne répond pas"
|
||||||
|
_ffVisibility:
|
||||||
|
public: "Public"
|
||||||
|
followers: "Visible uniquement pour les abonné·e·s"
|
||||||
|
private: "Privé"
|
||||||
_signup:
|
_signup:
|
||||||
almostThere: "Bientôt fini"
|
almostThere: "Bientôt fini"
|
||||||
emailAddressInfo: "Insérez votre adresse e-mail."
|
emailAddressInfo: "Insérez votre adresse e-mail."
|
||||||
|
@ -808,13 +817,6 @@ _accountDelete:
|
||||||
requestAccountDelete: "Demander la suppression de votre compte"
|
requestAccountDelete: "Demander la suppression de votre compte"
|
||||||
started: "La procédure de suppression a commencé."
|
started: "La procédure de suppression a commencé."
|
||||||
inProgress: "Suppression en cours"
|
inProgress: "Suppression en cours"
|
||||||
_docs:
|
|
||||||
continueReading: "Lire plus"
|
|
||||||
features: "Fonctionnalités"
|
|
||||||
generalTopics: "Sujets généraux"
|
|
||||||
advancedTopics: "Sujets avancés"
|
|
||||||
admin: "Gestion"
|
|
||||||
translateWarn: "Ceci est une traduction dont le contenu peut différer du texte original."
|
|
||||||
_ad:
|
_ad:
|
||||||
back: "Retour"
|
back: "Retour"
|
||||||
reduceFrequencyOfThisAd: "Voir cette publicité moins souvent"
|
reduceFrequencyOfThisAd: "Voir cette publicité moins souvent"
|
||||||
|
|
|
@ -81,6 +81,8 @@ somethingHappened: "Terjadi kesalahan"
|
||||||
retry: "Coba lagi"
|
retry: "Coba lagi"
|
||||||
pageLoadError: "Gagal memuat halaman."
|
pageLoadError: "Gagal memuat halaman."
|
||||||
pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok perambah. Cobalah bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali."
|
pageLoadErrorDescription: "Umumnya disebabkan jaringan atau tembolok perambah. Cobalah bersihkan tembolok peramban lalu tunggu sesaat sebelum mencoba kembali."
|
||||||
|
serverIsDead: "Tidak ada respon dari server. Mohon tunggu dan coba beberapa saat lagi."
|
||||||
|
youShouldUpgradeClient: "Untuk melihat halaman ini, mohon muat ulang untuk memutakhirkan klienmu."
|
||||||
enterListName: "Masukkan nama daftar"
|
enterListName: "Masukkan nama daftar"
|
||||||
privacy: "Privasi"
|
privacy: "Privasi"
|
||||||
makeFollowManuallyApprove: "Permintaan mengikuti membutuhkan persetujuan"
|
makeFollowManuallyApprove: "Permintaan mengikuti membutuhkan persetujuan"
|
||||||
|
@ -529,6 +531,8 @@ removeAllFollowing: "Tahan semua mengikuti"
|
||||||
removeAllFollowingDescription: "Batal mengikuti semua akun dari {host}. Mohon jalankan ini ketika instansi sudah tidak ada lagi."
|
removeAllFollowingDescription: "Batal mengikuti semua akun dari {host}. Mohon jalankan ini ketika instansi sudah tidak ada lagi."
|
||||||
userSuspended: "Pengguna ini telah dibekukan."
|
userSuspended: "Pengguna ini telah dibekukan."
|
||||||
userSilenced: "Pengguna ini telah dibungkam."
|
userSilenced: "Pengguna ini telah dibungkam."
|
||||||
|
yourAccountSuspendedTitle: "Akun ini dibekukan"
|
||||||
|
yourAccountSuspendedDescription: "Akun ini dibekukan karena melanggar ketentuan penggunaan layanan server atau semacamnya. Hubungi admin apabila ingin tahu alasan lebih lanjut. Mohon untuk tidak membuat akun baru."
|
||||||
menu: "Menu"
|
menu: "Menu"
|
||||||
divider: "Pembagi"
|
divider: "Pembagi"
|
||||||
addItem: "Tambahkan item"
|
addItem: "Tambahkan item"
|
||||||
|
@ -616,6 +620,8 @@ reportAbuse: "Laporkan"
|
||||||
reportAbuseOf: "Laporkan {name}"
|
reportAbuseOf: "Laporkan {name}"
|
||||||
fillAbuseReportDescription: "Mohon isi rincian laporan. Jika laporan ini mengenai catatan yang spesifik, mohon lampirkan serta URL catatan tersebut."
|
fillAbuseReportDescription: "Mohon isi rincian laporan. Jika laporan ini mengenai catatan yang spesifik, mohon lampirkan serta URL catatan tersebut."
|
||||||
abuseReported: "Laporan kamu telah dikirimkan. Terima kasih."
|
abuseReported: "Laporan kamu telah dikirimkan. Terima kasih."
|
||||||
|
reporteeOrigin: "Yang dilaporkan"
|
||||||
|
reporterOrigin: "Pelapor"
|
||||||
send: "Kirim"
|
send: "Kirim"
|
||||||
abuseMarkAsResolved: "Tandai laporan sebagai selesai"
|
abuseMarkAsResolved: "Tandai laporan sebagai selesai"
|
||||||
openInNewTab: "Buka di tab baru"
|
openInNewTab: "Buka di tab baru"
|
||||||
|
@ -762,6 +768,7 @@ middle: "Sedang"
|
||||||
low: "Rendah"
|
low: "Rendah"
|
||||||
emailNotConfiguredWarning: "Alamat surel tidak disetel."
|
emailNotConfiguredWarning: "Alamat surel tidak disetel."
|
||||||
ratio: "Rasio"
|
ratio: "Rasio"
|
||||||
|
previewNoteText: "Tampilkan pratinjau"
|
||||||
customCss: "Custom CSS"
|
customCss: "Custom CSS"
|
||||||
customCssWarn: "Pengaturan ini seharusnya digunakan jika kamu tahu cara kerjanya. Memasukkan nilai yang tidak tepat dapat menyebabkan klien tidak berfungsi semestinya."
|
customCssWarn: "Pengaturan ini seharusnya digunakan jika kamu tahu cara kerjanya. Memasukkan nilai yang tidak tepat dapat menyebabkan klien tidak berfungsi semestinya."
|
||||||
global: "Global"
|
global: "Global"
|
||||||
|
@ -779,8 +786,40 @@ translate: "Terjemahkan"
|
||||||
translatedFrom: "Terjemahkan dari {x}"
|
translatedFrom: "Terjemahkan dari {x}"
|
||||||
accountDeletionInProgress: "Penghapusan akun sedang dalam proses"
|
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."
|
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."
|
||||||
|
aiChanMode: "Mode Ai"
|
||||||
keepCw: "Biarkan Peringatan Konten"
|
keepCw: "Biarkan Peringatan Konten"
|
||||||
|
pubSub: "Akun Pub/Sub"
|
||||||
|
lastCommunication: "Komunikasi terakhir"
|
||||||
|
resolved: "Selesai"
|
||||||
|
unresolved: "Belum selesai"
|
||||||
|
itsOn: "Aktif"
|
||||||
|
itsOff: "Nonaktif"
|
||||||
|
emailRequiredForSignup: "Membutuhkan alamat surel untuk mendaftar"
|
||||||
|
unread: "Belum dibaca"
|
||||||
|
filter: "Saring"
|
||||||
controlPanel: "Panel kontrol"
|
controlPanel: "Panel kontrol"
|
||||||
|
manageAccounts: "Kelola Akun"
|
||||||
|
makeReactionsPublic: "Tampilkan riwayat reaksi ke publik"
|
||||||
|
makeReactionsPublicDescription: "Pengaturan ini akan membuat daftar dari semua reaksi masa lalu kamu ditampilkan secara publik."
|
||||||
|
classic: "Klasik"
|
||||||
|
muteThread: "Bisukan thread"
|
||||||
|
unmuteThread: "Suarakan thread"
|
||||||
|
ffVisibility: "Visibilitas Mengikuti/Pengikut"
|
||||||
|
ffVisibilityDescription: "Mengatur siapa yang dapat melihat pengikutmu dan yang kamu ikuti."
|
||||||
|
_emailUnavailable:
|
||||||
|
used: "Alamat surel ini telah digunakan"
|
||||||
|
format: "Format tidak valid."
|
||||||
|
disposable: "Alamat surel temporer tidak dapat digunakan"
|
||||||
|
mx: "Server alamat surel ini tidak valid"
|
||||||
|
smtp: "Server alamat surel ini tidak merespon"
|
||||||
|
_ffVisibility:
|
||||||
|
public: "Terbitkan"
|
||||||
|
followers: "Tampil untuk pengikut saja"
|
||||||
|
private: "Tersembunyi"
|
||||||
|
_signup:
|
||||||
|
almostThere: "Hampir selesai"
|
||||||
|
emailAddressInfo: "Mohon masukkan alamat surel kamu."
|
||||||
|
emailSent: "Konfirmasi surel telah dikirimkan ke alamat surel kamu ({email}). Mohon klik tautan yang tercantum di dalamnya untuk menyelesaikan pembuatan akun."
|
||||||
_accountDelete:
|
_accountDelete:
|
||||||
accountDelete: "Hapus akun"
|
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."
|
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."
|
||||||
|
@ -788,13 +827,6 @@ _accountDelete:
|
||||||
requestAccountDelete: "Minta penghapusan akun"
|
requestAccountDelete: "Minta penghapusan akun"
|
||||||
started: "Penghapusan telah dimulai"
|
started: "Penghapusan telah dimulai"
|
||||||
inProgress: "Penghapusan sedang dalam proses"
|
inProgress: "Penghapusan sedang dalam proses"
|
||||||
_docs:
|
|
||||||
continueReading: "Baca lebih lanjut"
|
|
||||||
features: "Fitur"
|
|
||||||
generalTopics: "Topik umum"
|
|
||||||
advancedTopics: "Topik tingkat lanjut"
|
|
||||||
admin: "Manajemen"
|
|
||||||
translateWarn: "Ini merupakan dokumen terjemahan. Konten di dalamnya kemungkinan dapat berbeda dari yang aslinya."
|
|
||||||
_ad:
|
_ad:
|
||||||
back: "Kembali"
|
back: "Kembali"
|
||||||
reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit"
|
reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit"
|
||||||
|
@ -895,6 +927,8 @@ _mfm:
|
||||||
fontDescription: "Setel font yang ditampilkan untuk konten."
|
fontDescription: "Setel font yang ditampilkan untuk konten."
|
||||||
rainbow: "Pelangi"
|
rainbow: "Pelangi"
|
||||||
rainbowDescription: "Membuat konten muncul dalam warna pelangi."
|
rainbowDescription: "Membuat konten muncul dalam warna pelangi."
|
||||||
|
sparkle: "Kelap-kelip"
|
||||||
|
sparkleDescription: "Memberikan konten efek partikel kelap-kelip."
|
||||||
_reversi:
|
_reversi:
|
||||||
reversi: "Reversi"
|
reversi: "Reversi"
|
||||||
gameSettings: "Pengaturan permainan"
|
gameSettings: "Pengaturan permainan"
|
||||||
|
@ -1121,6 +1155,10 @@ _permissions:
|
||||||
"write:user-groups": "Sunting atau hapus grup pengguna"
|
"write:user-groups": "Sunting atau hapus grup pengguna"
|
||||||
"read:channels": "Lihat saluran"
|
"read:channels": "Lihat saluran"
|
||||||
"write:channels": "Sunting saluran"
|
"write:channels": "Sunting saluran"
|
||||||
|
"read:gallery": "Lihat galeri"
|
||||||
|
"write:gallery": "Sunting galeri"
|
||||||
|
"read:gallery-likes": "Lihat daftar postingan galeri yang disukai"
|
||||||
|
"write:gallery-likes": "Sunting daftar postingan galeri yang disukai"
|
||||||
_auth:
|
_auth:
|
||||||
shareAccess: "Apakah kamu ingin mengijinkan \"{name}\" untuk mengakses akun ini?"
|
shareAccess: "Apakah kamu ingin mengijinkan \"{name}\" untuk mengakses akun ini?"
|
||||||
shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun kamu?"
|
shareAccessAsk: "Apakah kamu ingin mengijinkan aplikasi ini untuk mengakses akun kamu?"
|
||||||
|
|
62
locales/tr-TR.yml
Normal file
62
locales/tr-TR.yml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
---
|
||||||
|
_lang_: "Türkçe"
|
||||||
|
introMisskey: "Açık kaynaklı bir dağıtılmış mikroblog hizmeti olan Misskey'e hoş geldiniz.\nMisskey, neler olup bittiğini paylaşmak ve herkese sizden bahsetmek için \"notlar\" oluşturmanıza olanak tanıyan, açık kaynaklı, dağıtılmış bir mikroblog hizmetidir.\nHerkesin notlarına kendi tepkilerinizi hızlıca eklemek için \"Tepkiler\" özelliğini de kullanabilirsiniz👍.\nYeni bir dünyayı keşfedin🚀."
|
||||||
|
monthAndDay: "{month}Ay {day}Gün"
|
||||||
|
search: "Arama"
|
||||||
|
notifications: "Bildirim"
|
||||||
|
username: "Kullanıcı Adı"
|
||||||
|
password: "Şifre"
|
||||||
|
forgotPassword: "şifremi unuttum"
|
||||||
|
ok: "TAMAM"
|
||||||
|
gotIt: "Anladım"
|
||||||
|
cancel: "İptal"
|
||||||
|
enterUsername: "Kullanıcı adınızı giriniz"
|
||||||
|
noNotes: "Notlar mevcut değil."
|
||||||
|
noNotifications: "Bildirim bulunmuyor"
|
||||||
|
settings: "Ayarlar"
|
||||||
|
basicSettings: "Temel Ayarlar"
|
||||||
|
otherSettings: "Diğer Ayarlar"
|
||||||
|
openInWindow: "Bir pencere ile aç"
|
||||||
|
profile: "Profil"
|
||||||
|
timeline: "Zaman çizelgesi"
|
||||||
|
noAccountDescription: "Bu kullanıcı henüz biyografisini yazmadı"
|
||||||
|
login: "Giriş Yap "
|
||||||
|
logout: "Çıkış Yap"
|
||||||
|
signup: "Kayıt Ol"
|
||||||
|
uploading: "Yükleniyor"
|
||||||
|
users: "Kullanıcı"
|
||||||
|
addUser: "Kullanıcı Ekle"
|
||||||
|
favorite: "Favoriler"
|
||||||
|
favorites: "Favoriler"
|
||||||
|
unfavorite: "Favorilerden Kaldır"
|
||||||
|
favorited: "Favorilerime eklendi."
|
||||||
|
alreadyFavorited: "Zaten favorilerinizde kayıtlı."
|
||||||
|
pin: "Sabitlenmiş"
|
||||||
|
unpin: "Sabitlemeyi kaldır"
|
||||||
|
copyContent: "İçeriği kopyala"
|
||||||
|
copyLink: "Bağlantıyı Kopyala"
|
||||||
|
delete: "Sil"
|
||||||
|
deleteAndEdit: "Sil ve yeniden düzenle"
|
||||||
|
deleteAndEditConfirm: "Bu notu silip yeniden düzenlemek istiyor musunuz? Bu nota ilişkin tüm Tepkiler, Yeniden Notlar ve Yanıtlar da silinecektir."
|
||||||
|
addToList: "Listeye ekle"
|
||||||
|
sendMessage: "Mesaj Gönder"
|
||||||
|
copyUsername: "Kullanıcı Adını Kopyala"
|
||||||
|
searchUser: "Kullanıcıları ara"
|
||||||
|
pinned: "Sabitlenmiş"
|
||||||
|
remove: "Sil"
|
||||||
|
smtpUser: "Kullanıcı Adı"
|
||||||
|
smtpPass: "Şifre"
|
||||||
|
user: "Kullanıcı"
|
||||||
|
_mfm:
|
||||||
|
search: "Arama"
|
||||||
|
_sfx:
|
||||||
|
notification: "Bildirim"
|
||||||
|
_widgets:
|
||||||
|
notifications: "Bildirim"
|
||||||
|
timeline: "Zaman çizelgesi"
|
||||||
|
_profile:
|
||||||
|
username: "Kullanıcı Adı"
|
||||||
|
_deck:
|
||||||
|
_columns:
|
||||||
|
notifications: "Bildirim"
|
||||||
|
tl: "Zaman çizelgesi"
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "12.95.0",
|
"version": "12.96.0",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
12
packages/backend/@types/ms.d.ts
vendored
12
packages/backend/@types/ms.d.ts
vendored
|
@ -1,12 +0,0 @@
|
||||||
declare module 'ms' {
|
|
||||||
interface IMSOptions {
|
|
||||||
long: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ms(value: string): number;
|
|
||||||
function ms(value: number, options?: IMSOptions): string;
|
|
||||||
|
|
||||||
namespace ms {} // Hack
|
|
||||||
|
|
||||||
export = ms;
|
|
||||||
}
|
|
|
@ -59,6 +59,7 @@
|
||||||
"@types/redis": "2.8.32",
|
"@types/redis": "2.8.32",
|
||||||
"@types/rename": "1.0.4",
|
"@types/rename": "1.0.4",
|
||||||
"@types/request-stats": "3.0.0",
|
"@types/request-stats": "3.0.0",
|
||||||
|
"@types/sanitize-html": "2.5.0",
|
||||||
"@types/seedrandom": "2.4.28",
|
"@types/seedrandom": "2.4.28",
|
||||||
"@types/sharp": "0.29.3",
|
"@types/sharp": "0.29.3",
|
||||||
"@types/sinonjs__fake-timers": "6.0.4",
|
"@types/sinonjs__fake-timers": "6.0.4",
|
||||||
|
@ -135,7 +136,7 @@
|
||||||
"mfm-js": "0.20.0",
|
"mfm-js": "0.20.0",
|
||||||
"misskey-js": "0.0.8",
|
"misskey-js": "0.0.8",
|
||||||
"mocha": "8.4.0",
|
"mocha": "8.4.0",
|
||||||
"ms": "2.1.3",
|
"ms": "3.0.0-canary.1",
|
||||||
"multer": "1.4.3",
|
"multer": "1.4.3",
|
||||||
"nested-property": "4.0.0",
|
"nested-property": "4.0.0",
|
||||||
"node-fetch": "2.6.1",
|
"node-fetch": "2.6.1",
|
||||||
|
@ -163,6 +164,7 @@
|
||||||
"require-all": "3.0.0",
|
"require-all": "3.0.0",
|
||||||
"rndstr": "1.0.0",
|
"rndstr": "1.0.0",
|
||||||
"s-age": "1.1.2",
|
"s-age": "1.1.2",
|
||||||
|
"sanitize-html": "2.5.3",
|
||||||
"seedrandom": "3.0.5",
|
"seedrandom": "3.0.5",
|
||||||
"sharp": "0.29.2",
|
"sharp": "0.29.2",
|
||||||
"speakeasy": "2.0.0",
|
"speakeasy": "2.0.0",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import Resolver from '@/remote/activitypub/resolver';
|
import Resolver from '@/remote/activitypub/resolver';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['federation'],
|
tags: ['federation'],
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { Note } from '@/models/entities/note';
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta';
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
import { isActor, isPost, getApId } from '@/remote/activitypub/type';
|
import { isActor, isPost, getApId } from '@/remote/activitypub/type';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['federation'],
|
tags: ['federation'],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import create from '@/services/blocking/create';
|
import create from '@/services/blocking/create';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import deleteBlocking from '@/services/blocking/delete';
|
import deleteBlocking from '@/services/blocking/delete';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import create from '@/services/drive/add-file';
|
import create from '@/services/drive/add-file';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import uploadFromUrl from '@/services/drive/upload-from-url';
|
import uploadFromUrl from '@/services/drive/upload-from-url';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { DriveFiles } from '@/models/index';
|
import { DriveFiles } from '@/models/index';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import create from '@/services/following/create';
|
import create from '@/services/following/create';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import deleteFollowing from '@/services/following/delete';
|
import deleteFollowing from '@/services/following/delete';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { ID } from '../../../../../misc/cafy-id';
|
import { ID } from '../../../../../misc/cafy-id';
|
||||||
import { DriveFiles, GalleryPosts } from '@/models/index';
|
import { DriveFiles, GalleryPosts } from '@/models/index';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import { ID } from '../../../../../misc/cafy-id';
|
import { ID } from '../../../../../misc/cafy-id';
|
||||||
import { DriveFiles, GalleryPosts } from '@/models/index';
|
import { DriveFiles, GalleryPosts } from '@/models/index';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createExportBlockingJob } from '@/queue/index';
|
import { createExportBlockingJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createExportFollowingJob } from '@/queue/index';
|
import { createExportFollowingJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createExportMuteJob } from '@/queue/index';
|
import { createExportMuteJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createExportNotesJob } from '@/queue/index';
|
import { createExportNotesJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createExportUserListsJob } from '@/queue/index';
|
import { createExportUserListsJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
secure: true,
|
secure: true,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createImportBlockingJob } from '@/queue/index';
|
import { createImportBlockingJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { DriveFiles } from '@/models/index';
|
import { DriveFiles } from '@/models/index';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createImportFollowingJob } from '@/queue/index';
|
import { createImportFollowingJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { DriveFiles } from '@/models/index';
|
import { DriveFiles } from '@/models/index';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createImportMutingJob } from '@/queue/index';
|
import { createImportMutingJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { DriveFiles } from '@/models/index';
|
import { DriveFiles } from '@/models/index';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { createImportUserListsJob } from '@/queue/index';
|
import { createImportUserListsJob } from '@/queue/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { DriveFiles } from '@/models/index';
|
import { DriveFiles } from '@/models/index';
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { publishMainStream } from '@/services/stream';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import rndstr from 'rndstr';
|
import rndstr from 'rndstr';
|
||||||
import config from '@/config/index';
|
import config from '@/config/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import * as bcrypt from 'bcryptjs';
|
import * as bcrypt from 'bcryptjs';
|
||||||
import { Users, UserProfiles } from '@/models/index';
|
import { Users, UserProfiles } from '@/models/index';
|
||||||
import { sendEmail } from '@/services/send-email';
|
import { sendEmail } from '@/services/send-email';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { ApiError } from '../../../error';
|
import { ApiError } from '../../../error';
|
||||||
import { MessagingMessages } from '@/models/index';
|
import { MessagingMessages } from '@/models/index';
|
||||||
import { deleteMessage } from '@/services/messages/delete';
|
import { deleteMessage } from '@/services/messages/delete';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { length } from 'stringz';
|
import { length } from 'stringz';
|
||||||
import create from '@/services/note/create';
|
import create from '@/services/note/create';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import deleteNote from '@/services/note/delete';
|
import deleteNote from '@/services/note/delete';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { getNote } from '../../common/getters';
|
import { getNote } from '../../common/getters';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { Users } from '@/models/index';
|
import { Users } from '@/models/index';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../../define';
|
import define from '../../../define';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import deleteReaction from '@/services/note/reaction/delete';
|
import deleteReaction from '@/services/note/reaction/delete';
|
||||||
import { getNote } from '../../../common/getters';
|
import { getNote } from '../../../common/getters';
|
||||||
import { ApiError } from '../../../error';
|
import { ApiError } from '../../../error';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import $ from 'cafy';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import deleteNote from '@/services/note/delete';
|
import deleteNote from '@/services/note/delete';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { getNote } from '../../common/getters';
|
import { getNote } from '../../common/getters';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { Notes, Users } from '@/models/index';
|
import { Notes, Users } from '@/models/index';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import { Pages, DriveFiles } from '@/models/index';
|
import { Pages, DriveFiles } from '@/models/index';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { ApiError } from '../../error';
|
import { ApiError } from '../../error';
|
||||||
import { Pages, DriveFiles } from '@/models/index';
|
import { Pages, DriveFiles } from '@/models/index';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { publishMainStream } from '@/services/stream';
|
||||||
import define from '../define';
|
import define from '../define';
|
||||||
import rndstr from 'rndstr';
|
import rndstr from 'rndstr';
|
||||||
import config from '@/config/index';
|
import config from '@/config/index';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import { Users, UserProfiles, PasswordResetRequests } from '@/models/index';
|
import { Users, UserProfiles, PasswordResetRequests } from '@/models/index';
|
||||||
import { sendEmail } from '@/services/send-email';
|
import { sendEmail } from '@/services/send-email';
|
||||||
import { ApiError } from '../error';
|
import { ApiError } from '../error';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { Users, Followings } from '@/models/index';
|
import { Users, Followings } from '@/models/index';
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import $ from 'cafy';
|
import $ from 'cafy';
|
||||||
|
import * as sanitizeHtml from 'sanitize-html';
|
||||||
import { ID } from '@/misc/cafy-id';
|
import { ID } from '@/misc/cafy-id';
|
||||||
import define from '../../define';
|
import define from '../../define';
|
||||||
import { publishAdminStream } from '@/services/stream';
|
import { publishAdminStream } from '@/services/stream';
|
||||||
|
@ -6,6 +7,8 @@ import { ApiError } from '../../error';
|
||||||
import { getUser } from '../../common/getters';
|
import { getUser } from '../../common/getters';
|
||||||
import { AbuseUserReports, Users } from '@/models/index';
|
import { AbuseUserReports, Users } from '@/models/index';
|
||||||
import { genId } from '@/misc/gen-id';
|
import { genId } from '@/misc/gen-id';
|
||||||
|
import { sendEmail } from '@/services/send-email';
|
||||||
|
import { fetchMeta } from '@/misc/fetch-meta';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['users'],
|
tags: ['users'],
|
||||||
|
@ -26,23 +29,24 @@ export const meta = {
|
||||||
noSuchUser: {
|
noSuchUser: {
|
||||||
message: 'No such user.',
|
message: 'No such user.',
|
||||||
code: 'NO_SUCH_USER',
|
code: 'NO_SUCH_USER',
|
||||||
id: '1acefcb5-0959-43fd-9685-b48305736cb5'
|
id: '1acefcb5-0959-43fd-9685-b48305736cb5',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotReportYourself: {
|
cannotReportYourself: {
|
||||||
message: 'Cannot report yourself.',
|
message: 'Cannot report yourself.',
|
||||||
code: 'CANNOT_REPORT_YOURSELF',
|
code: 'CANNOT_REPORT_YOURSELF',
|
||||||
id: '1e13149e-b1e8-43cf-902e-c01dbfcb202f'
|
id: '1e13149e-b1e8-43cf-902e-c01dbfcb202f',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotReportAdmin: {
|
cannotReportAdmin: {
|
||||||
message: 'Cannot report the admin.',
|
message: 'Cannot report the admin.',
|
||||||
code: 'CANNOT_REPORT_THE_ADMIN',
|
code: 'CANNOT_REPORT_THE_ADMIN',
|
||||||
id: '35e166f5-05fb-4f87-a2d5-adb42676d48f'
|
id: '35e166f5-05fb-4f87-a2d5-adb42676d48f',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default define(meta, async (ps, me) => {
|
export default define(meta, async (ps, me) => {
|
||||||
// Lookup user
|
// Lookup user
|
||||||
const user = await getUser(ps.userId).catch(e => {
|
const user = await getUser(ps.userId).catch(e => {
|
||||||
|
@ -72,10 +76,10 @@ export default define(meta, async (ps, me) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const moderators = await Users.find({
|
const moderators = await Users.find({
|
||||||
where: [{
|
where: [{
|
||||||
isAdmin: true
|
isAdmin: true,
|
||||||
}, {
|
}, {
|
||||||
isModerator: true
|
isModerator: true,
|
||||||
}]
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const moderator of moderators) {
|
for (const moderator of moderators) {
|
||||||
|
@ -83,8 +87,15 @@ export default define(meta, async (ps, me) => {
|
||||||
id: report.id,
|
id: report.id,
|
||||||
targetUserId: report.targetUserId,
|
targetUserId: report.targetUserId,
|
||||||
reporterId: report.reporterId,
|
reporterId: report.reporterId,
|
||||||
comment: report.comment
|
comment: report.comment,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const meta = await fetchMeta();
|
||||||
|
if (meta.email) {
|
||||||
|
sendEmail(meta.email, 'New abuse report',
|
||||||
|
sanitizeHtml(ps.comment),
|
||||||
|
sanitizeHtml(ps.comment));
|
||||||
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
import * as ms from 'ms';
|
import ms from 'ms';
|
||||||
import * as Koa from 'koa';
|
import * as Koa from 'koa';
|
||||||
import * as Router from '@koa/router';
|
import * as Router from '@koa/router';
|
||||||
import * as send from 'koa-send';
|
import * as send from 'koa-send';
|
||||||
|
|
|
@ -21,8 +21,8 @@ export async function sendEmail(to: string, subject: string, html: string, text:
|
||||||
proxy: config.proxySmtp,
|
proxy: config.proxySmtp,
|
||||||
auth: enableAuth ? {
|
auth: enableAuth ? {
|
||||||
user: meta.smtpUser,
|
user: meta.smtpUser,
|
||||||
pass: meta.smtpPass
|
pass: meta.smtpPass,
|
||||||
} : undefined
|
} : undefined,
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -33,86 +33,85 @@ export async function sendEmail(to: string, subject: string, html: string, text:
|
||||||
subject: subject,
|
subject: subject,
|
||||||
text: text,
|
text: text,
|
||||||
html: `<!doctype html>
|
html: `<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>${ subject }</title>
|
<title>${ subject }</title>
|
||||||
<style>
|
<style>
|
||||||
html {
|
html {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #86b300;
|
color: #86b300;
|
||||||
}
|
}
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #555;
|
color: #555;
|
||||||
}
|
}
|
||||||
main > header {
|
main > header {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
background: #86b300;
|
background: #86b300;
|
||||||
}
|
}
|
||||||
main > header > img {
|
main > header > img {
|
||||||
max-width: 128px;
|
max-width: 128px;
|
||||||
max-height: 28px;
|
max-height: 28px;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
main > article {
|
main > article {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
}
|
}
|
||||||
main > article > h1 {
|
main > article > h1 {
|
||||||
margin: 0 0 1em 0;
|
margin: 0 0 1em 0;
|
||||||
}
|
}
|
||||||
main > footer {
|
main > footer {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
border-top: solid 1px #eee;
|
border-top: solid 1px #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin: 16px auto 0 auto;
|
margin: 16px auto 0 auto;
|
||||||
padding: 0 32px;
|
padding: 0 32px;
|
||||||
}
|
}
|
||||||
nav > a {
|
nav > a {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<header>
|
<header>
|
||||||
<img src="${ meta.logoImageUrl || meta.iconUrl || iconUrl }"/>
|
<img src="${ meta.logoImageUrl || meta.iconUrl || iconUrl }"/>
|
||||||
</header>
|
</header>
|
||||||
<article>
|
<article>
|
||||||
<h1>${ subject }</h1>
|
<h1>${ subject }</h1>
|
||||||
<div>${ html }</div>
|
<div>${ html }</div>
|
||||||
</article>
|
</article>
|
||||||
<footer>
|
<footer>
|
||||||
<a href="${ emailSettingUrl }">${ 'Email setting' }</a>
|
<a href="${ emailSettingUrl }">${ 'Email setting' }</a>
|
||||||
</footer>
|
</footer>
|
||||||
</main>
|
</main>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="${ config.url }">${ config.host }</a>
|
<a href="${ config.url }">${ config.host }</a>
|
||||||
</nav>
|
</nav>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>`,
|
||||||
`
|
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info('Message sent: %s', info.messageId);
|
logger.info('Message sent: %s', info.messageId);
|
||||||
|
|
|
@ -769,6 +769,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/rsvp/-/rsvp-4.0.4.tgz#55e93e7054027f1ad4b4ebc1e60e59eb091e2d32"
|
resolved "https://registry.yarnpkg.com/@types/rsvp/-/rsvp-4.0.4.tgz#55e93e7054027f1ad4b4ebc1e60e59eb091e2d32"
|
||||||
integrity sha512-J3Ol++HCC7/hwZhanDvggFYU/GtxHxE/e7cGRWxR04BF7Tt3TqJZ84BkzQgDxmX0uu8IagiyfmfoUlBACh2Ilg==
|
integrity sha512-J3Ol++HCC7/hwZhanDvggFYU/GtxHxE/e7cGRWxR04BF7Tt3TqJZ84BkzQgDxmX0uu8IagiyfmfoUlBACh2Ilg==
|
||||||
|
|
||||||
|
"@types/sanitize-html@2.5.0":
|
||||||
|
version "2.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-2.5.0.tgz#bfef58fbcf2674b20ffcc23c3506faa68c3a13e3"
|
||||||
|
integrity sha512-PeFIEZsO9m1+ACJlXUaimgrR+5DEDiIXhz7Hso307jmq5Yz0lb5kDp8LiTr5dMMMliC/jNNx/qds7Zoxa4zexw==
|
||||||
|
dependencies:
|
||||||
|
htmlparser2 "^6.0.0"
|
||||||
|
|
||||||
"@types/seedrandom@2.4.28":
|
"@types/seedrandom@2.4.28":
|
||||||
version "2.4.28"
|
version "2.4.28"
|
||||||
resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f"
|
resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f"
|
||||||
|
@ -2631,6 +2638,11 @@ deep-is@^0.1.3, deep-is@~0.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||||
|
|
||||||
|
deepmerge@^4.2.2:
|
||||||
|
version "4.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||||
|
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||||
|
|
||||||
defer-to-connect@^2.0.0:
|
defer-to-connect@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1"
|
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1"
|
||||||
|
@ -2831,7 +2843,7 @@ domutils@^1.5.1:
|
||||||
dom-serializer "0"
|
dom-serializer "0"
|
||||||
domelementtype "1"
|
domelementtype "1"
|
||||||
|
|
||||||
domutils@^2.6.0:
|
domutils@^2.5.2, domutils@^2.6.0:
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||||
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
||||||
|
@ -3889,6 +3901,16 @@ htmlparser2@^3.9.1:
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
readable-stream "^3.1.1"
|
readable-stream "^3.1.1"
|
||||||
|
|
||||||
|
htmlparser2@^6.0.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||||
|
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.0.1"
|
||||||
|
domhandler "^4.0.0"
|
||||||
|
domutils "^2.5.2"
|
||||||
|
entities "^2.0.0"
|
||||||
|
|
||||||
http-assert@^1.3.0:
|
http-assert@^1.3.0:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878"
|
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878"
|
||||||
|
@ -4358,6 +4380,11 @@ is-plain-obj@^2.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
|
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
|
||||||
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
|
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
|
||||||
|
|
||||||
|
is-plain-object@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
|
||||||
|
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
|
||||||
|
|
||||||
is-potential-custom-element-name@^1.0.1:
|
is-potential-custom-element-name@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
|
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
|
||||||
|
@ -5421,6 +5448,11 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
|
ms@3.0.0-canary.1:
|
||||||
|
version "3.0.0-canary.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-3.0.0-canary.1.tgz#c7b34fbce381492fd0b345d1cf56e14d67b77b80"
|
||||||
|
integrity sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==
|
||||||
|
|
||||||
multer@1.4.3:
|
multer@1.4.3:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.3.tgz#4db352d6992e028ac0eacf7be45c6efd0264297b"
|
resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.3.tgz#4db352d6992e028ac0eacf7be45c6efd0264297b"
|
||||||
|
@ -5466,6 +5498,11 @@ nanoid@^3.1.23:
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
|
||||||
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
|
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
|
||||||
|
|
||||||
|
nanoid@^3.1.30:
|
||||||
|
version "3.1.30"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
|
||||||
|
integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
|
||||||
|
|
||||||
napi-build-utils@^1.0.1:
|
napi-build-utils@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
||||||
|
@ -5935,6 +5972,11 @@ parse-passwd@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
|
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
|
||||||
integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
|
integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
|
||||||
|
|
||||||
|
parse-srcset@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1"
|
||||||
|
integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=
|
||||||
|
|
||||||
parse5-htmlparser2-tree-adapter@^6.0.0:
|
parse5-htmlparser2-tree-adapter@^6.0.0:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
||||||
|
@ -6366,6 +6408,15 @@ postcss@^8.2.15:
|
||||||
nanoid "^3.1.23"
|
nanoid "^3.1.23"
|
||||||
source-map-js "^0.6.2"
|
source-map-js "^0.6.2"
|
||||||
|
|
||||||
|
postcss@^8.3.11:
|
||||||
|
version "8.3.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858"
|
||||||
|
integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.1.30"
|
||||||
|
picocolors "^1.0.0"
|
||||||
|
source-map-js "^0.6.2"
|
||||||
|
|
||||||
postgres-array@~2.0.0:
|
postgres-array@~2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
||||||
|
@ -7044,6 +7095,18 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
|
||||||
|
sanitize-html@2.5.3:
|
||||||
|
version "2.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.5.3.tgz#91aa3dc760b072cdf92f9c6973747569b1ba1cd8"
|
||||||
|
integrity sha512-DGATXd1fs/Rm287/i5FBKVYSBBUL0iAaztOA1/RFhEs4yqo39/X52i/q/CwsfCUG5cilmXSBmnQmyWfnKhBlOg==
|
||||||
|
dependencies:
|
||||||
|
deepmerge "^4.2.2"
|
||||||
|
escape-string-regexp "^4.0.0"
|
||||||
|
htmlparser2 "^6.0.0"
|
||||||
|
is-plain-object "^5.0.0"
|
||||||
|
parse-srcset "^1.0.2"
|
||||||
|
postcss "^8.3.11"
|
||||||
|
|
||||||
sax@1.2.1:
|
sax@1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
|
||||||
|
|
|
@ -70,7 +70,6 @@
|
||||||
"cssnano": "5.0.10",
|
"cssnano": "5.0.10",
|
||||||
"date-fns": "2.25.0",
|
"date-fns": "2.25.0",
|
||||||
"dateformat": "4.5.1",
|
"dateformat": "4.5.1",
|
||||||
"deep-email-validator": "0.1.18",
|
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eslint": "8.2.0",
|
"eslint": "8.2.0",
|
||||||
"eslint-plugin-vue": "8.0.3",
|
"eslint-plugin-vue": "8.0.3",
|
||||||
|
|
|
@ -94,12 +94,7 @@
|
||||||
<template v-else><i class="fas fa-reply"></i></template>
|
<template v-else><i class="fas fa-reply"></i></template>
|
||||||
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton">
|
<XRenoteButton class="button" :note="appearNote" :count="appearNote.renoteCount" ref="renoteButton"/>
|
||||||
<i class="fas fa-retweet"></i><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
|
||||||
</button>
|
|
||||||
<button v-else class="button _button">
|
|
||||||
<i class="fas fa-ban"></i>
|
|
||||||
</button>
|
|
||||||
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
|
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -136,6 +131,7 @@ import XReactionsViewer from './reactions-viewer.vue';
|
||||||
import XMediaList from './media-list.vue';
|
import XMediaList from './media-list.vue';
|
||||||
import XCwButton from './cw-button.vue';
|
import XCwButton from './cw-button.vue';
|
||||||
import XPoll from './poll.vue';
|
import XPoll from './poll.vue';
|
||||||
|
import XRenoteButton from './renote-button.vue';
|
||||||
import { pleaseLogin } from '@/scripts/please-login';
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
import { focusPrev, focusNext } from '@/scripts/focus';
|
import { focusPrev, focusNext } from '@/scripts/focus';
|
||||||
import { url } from '@/config';
|
import { url } from '@/config';
|
||||||
|
@ -157,6 +153,7 @@ export default defineComponent({
|
||||||
XMediaList,
|
XMediaList,
|
||||||
XCwButton,
|
XCwButton,
|
||||||
XPoll,
|
XPoll,
|
||||||
|
XRenoteButton,
|
||||||
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
|
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
|
||||||
MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')),
|
MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')),
|
||||||
},
|
},
|
||||||
|
@ -197,7 +194,7 @@ export default defineComponent({
|
||||||
return {
|
return {
|
||||||
'r': () => this.reply(true),
|
'r': () => this.reply(true),
|
||||||
'e|a|plus': () => this.react(true),
|
'e|a|plus': () => this.react(true),
|
||||||
'q': () => this.renote(true),
|
'q': () => this.$refs.renoteButton.renote(true),
|
||||||
'f|b': this.favorite,
|
'f|b': this.favorite,
|
||||||
'delete|ctrl+d': this.del,
|
'delete|ctrl+d': this.del,
|
||||||
'ctrl+q': this.renoteDirectly,
|
'ctrl+q': this.renoteDirectly,
|
||||||
|
@ -238,10 +235,6 @@ export default defineComponent({
|
||||||
return this.$i && (this.$i.id === this.note.userId);
|
return this.$i && (this.$i.id === this.note.userId);
|
||||||
},
|
},
|
||||||
|
|
||||||
canRenote(): boolean {
|
|
||||||
return ['public', 'home'].includes(this.appearNote.visibility) || this.isMyNote;
|
|
||||||
},
|
|
||||||
|
|
||||||
reactionsCount(): number {
|
reactionsCount(): number {
|
||||||
return this.appearNote.reactions
|
return this.appearNote.reactions
|
||||||
? sum(Object.values(this.appearNote.reactions))
|
? sum(Object.values(this.appearNote.reactions))
|
||||||
|
@ -459,30 +452,6 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renote(viaKeyboard = false) {
|
|
||||||
pleaseLogin();
|
|
||||||
this.blur();
|
|
||||||
os.popupMenu([{
|
|
||||||
text: this.$ts.renote,
|
|
||||||
icon: 'fas fa-retweet',
|
|
||||||
action: () => {
|
|
||||||
os.api('notes/create', {
|
|
||||||
renoteId: this.appearNote.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
text: this.$ts.quote,
|
|
||||||
icon: 'fas fa-quote-right',
|
|
||||||
action: () => {
|
|
||||||
os.post({
|
|
||||||
renote: this.appearNote,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}], this.$refs.renoteButton, {
|
|
||||||
viaKeyboard
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
renoteDirectly() {
|
renoteDirectly() {
|
||||||
os.apiWithDialog('notes/create', {
|
os.apiWithDialog('notes/create', {
|
||||||
renoteId: this.appearNote.id
|
renoteId: this.appearNote.id
|
||||||
|
|
|
@ -78,12 +78,7 @@
|
||||||
<template v-else><i class="fas fa-reply"></i></template>
|
<template v-else><i class="fas fa-reply"></i></template>
|
||||||
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton">
|
<XRenoteButton class="button" :note="appearNote" :count="appearNote.renoteCount" ref="renoteButton"/>
|
||||||
<i class="fas fa-retweet"></i><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
|
||||||
</button>
|
|
||||||
<button v-else class="button _button">
|
|
||||||
<i class="fas fa-ban"></i>
|
|
||||||
</button>
|
|
||||||
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
|
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -119,6 +114,7 @@ import XReactionsViewer from './reactions-viewer.vue';
|
||||||
import XMediaList from './media-list.vue';
|
import XMediaList from './media-list.vue';
|
||||||
import XCwButton from './cw-button.vue';
|
import XCwButton from './cw-button.vue';
|
||||||
import XPoll from './poll.vue';
|
import XPoll from './poll.vue';
|
||||||
|
import XRenoteButton from './renote-button.vue';
|
||||||
import { pleaseLogin } from '@/scripts/please-login';
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
import { focusPrev, focusNext } from '@/scripts/focus';
|
import { focusPrev, focusNext } from '@/scripts/focus';
|
||||||
import { url } from '@/config';
|
import { url } from '@/config';
|
||||||
|
@ -139,6 +135,7 @@ export default defineComponent({
|
||||||
XMediaList,
|
XMediaList,
|
||||||
XCwButton,
|
XCwButton,
|
||||||
XPoll,
|
XPoll,
|
||||||
|
XRenoteButton,
|
||||||
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
|
MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')),
|
||||||
MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')),
|
MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')),
|
||||||
},
|
},
|
||||||
|
@ -184,7 +181,7 @@ export default defineComponent({
|
||||||
return {
|
return {
|
||||||
'r': () => this.reply(true),
|
'r': () => this.reply(true),
|
||||||
'e|a|plus': () => this.react(true),
|
'e|a|plus': () => this.react(true),
|
||||||
'q': () => this.renote(true),
|
'q': () => this.$refs.renoteButton.renote(true),
|
||||||
'f|b': this.favorite,
|
'f|b': this.favorite,
|
||||||
'delete|ctrl+d': this.del,
|
'delete|ctrl+d': this.del,
|
||||||
'ctrl+q': this.renoteDirectly,
|
'ctrl+q': this.renoteDirectly,
|
||||||
|
@ -225,10 +222,6 @@ export default defineComponent({
|
||||||
return this.$i && (this.$i.id === this.note.userId);
|
return this.$i && (this.$i.id === this.note.userId);
|
||||||
},
|
},
|
||||||
|
|
||||||
canRenote(): boolean {
|
|
||||||
return ['public', 'home'].includes(this.appearNote.visibility) || this.isMyNote;
|
|
||||||
},
|
|
||||||
|
|
||||||
reactionsCount(): number {
|
reactionsCount(): number {
|
||||||
return this.appearNote.reactions
|
return this.appearNote.reactions
|
||||||
? sum(Object.values(this.appearNote.reactions))
|
? sum(Object.values(this.appearNote.reactions))
|
||||||
|
@ -435,30 +428,6 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renote(viaKeyboard = false) {
|
|
||||||
pleaseLogin();
|
|
||||||
this.blur();
|
|
||||||
os.popupMenu([{
|
|
||||||
text: this.$ts.renote,
|
|
||||||
icon: 'fas fa-retweet',
|
|
||||||
action: () => {
|
|
||||||
os.api('notes/create', {
|
|
||||||
renoteId: this.appearNote.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
text: this.$ts.quote,
|
|
||||||
icon: 'fas fa-quote-right',
|
|
||||||
action: () => {
|
|
||||||
os.post({
|
|
||||||
renote: this.appearNote,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}], this.$refs.renoteButton, {
|
|
||||||
viaKeyboard
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
renoteDirectly() {
|
renoteDirectly() {
|
||||||
os.apiWithDialog('notes/create', {
|
os.apiWithDialog('notes/create', {
|
||||||
renoteId: this.appearNote.id
|
renoteId: this.appearNote.id
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
|
import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
|
||||||
|
import * as misskey from 'misskey-js';
|
||||||
import { getNoteSummary } from '@/scripts/get-note-summary';
|
import { getNoteSummary } from '@/scripts/get-note-summary';
|
||||||
import XReactionIcon from './reaction-icon.vue';
|
import XReactionIcon from './reaction-icon.vue';
|
||||||
import MkFollowButton from './follow-button.vue';
|
import MkFollowButton from './follow-button.vue';
|
||||||
|
@ -77,6 +78,7 @@ import notePage from '@/filters/note';
|
||||||
import { userPage } from '@/filters/user';
|
import { userPage } from '@/filters/user';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -105,7 +107,7 @@ export default defineComponent({
|
||||||
const reactionRef = ref(null);
|
const reactionRef = ref(null);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let readObserver: IntersectionObserver = null;
|
let readObserver: IntersectionObserver | null = null;
|
||||||
let connection = null;
|
let connection = null;
|
||||||
|
|
||||||
if (!props.notification.isRead) {
|
if (!props.notification.isRead) {
|
||||||
|
@ -152,50 +154,17 @@ export default defineComponent({
|
||||||
os.api('users/groups/invitations/reject', { invitationId: props.notification.invitation.id });
|
os.api('users/groups/invitations/reject', { invitationId: props.notification.invitation.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
let isReactionHovering = false;
|
const { onMouseover: onReactionMouseover, onMouseleave: onReactionMouseleave } = useTooltip((showing) => {
|
||||||
let reactionTooltipTimeoutId;
|
|
||||||
|
|
||||||
const onReactionMouseover = () => {
|
|
||||||
if (isReactionHovering) return;
|
|
||||||
isReactionHovering = true;
|
|
||||||
reactionTooltipTimeoutId = setTimeout(openReactionTooltip, 300);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onReactionMouseleave = () => {
|
|
||||||
if (!isReactionHovering) return;
|
|
||||||
isReactionHovering = false;
|
|
||||||
clearTimeout(reactionTooltipTimeoutId);
|
|
||||||
closeReactionTooltip();
|
|
||||||
};
|
|
||||||
|
|
||||||
let changeReactionTooltipShowingState: () => void;
|
|
||||||
|
|
||||||
const openReactionTooltip = () => {
|
|
||||||
closeReactionTooltip();
|
|
||||||
if (!isReactionHovering) return;
|
|
||||||
|
|
||||||
const showing = ref(true);
|
|
||||||
os.popup(XReactionTooltip, {
|
os.popup(XReactionTooltip, {
|
||||||
showing,
|
showing,
|
||||||
reaction: props.notification.reaction ? props.notification.reaction.replace(/^:(\w+):$/, ':$1@.:') : props.notification.reaction,
|
reaction: props.notification.reaction ? props.notification.reaction.replace(/^:(\w+):$/, ':$1@.:') : props.notification.reaction,
|
||||||
emojis: props.notification.note.emojis,
|
emojis: props.notification.note.emojis,
|
||||||
source: reactionRef.value.$el,
|
source: reactionRef.value.$el,
|
||||||
}, {}, 'closed');
|
}, {}, 'closed');
|
||||||
|
});
|
||||||
changeReactionTooltipShowingState = () => {
|
|
||||||
showing.value = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeReactionTooltip = () => {
|
|
||||||
if (changeReactionTooltipShowingState != null) {
|
|
||||||
changeReactionTooltipShowingState();
|
|
||||||
changeReactionTooltipShowingState = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getNoteSummary: (text: string) => getNoteSummary(text, i18n.locale),
|
getNoteSummary: (note: misskey.entities.Note) => getNoteSummary(note),
|
||||||
followRequestDone,
|
followRequestDone,
|
||||||
groupInviteDone,
|
groupInviteDone,
|
||||||
notePage,
|
notePage,
|
||||||
|
|
|
@ -278,8 +278,8 @@ export default defineComponent({
|
||||||
this.text += ' ';
|
this.text += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.reply && this.reply.user.host != null) {
|
if (this.reply && (this.reply.user.username != this.$i.username || (this.reply.user.host != null && this.reply.user.host != host))) {
|
||||||
this.text = `@${this.reply.user.username}@${toASCII(this.reply.user.host)} `;
|
this.text = `@${this.reply.user.username}${this.reply.user.host != null ? '@' + toASCII(this.reply.user.host) : ''} `;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.reply && this.reply.text != null) {
|
if (this.reply && this.reply.text != null) {
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
<template v-if="users.length <= 10">
|
<template v-if="users.length <= 10">
|
||||||
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
|
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
|
||||||
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
|
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
|
||||||
|
<br/>
|
||||||
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
|
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
|
||||||
</b>
|
</b>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="10 < users.length">
|
<template v-if="10 < users.length">
|
||||||
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
|
<b v-for="u in users" :key="u.id" style="margin-right: 12px;">
|
||||||
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
|
<MkAvatar :user="u" style="width: 24px; height: 24px; margin-right: 2px;"/>
|
||||||
|
<br/>
|
||||||
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
|
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
|
||||||
</b>
|
</b>
|
||||||
<span slot="omitted">+{{ count - 10 }}</span>
|
<span slot="omitted">+{{ count - 10 }}</span>
|
||||||
|
@ -64,7 +66,6 @@ export default defineComponent({
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
> .reaction {
|
> .reaction {
|
||||||
flex: 1;
|
|
||||||
max-width: 100px;
|
max-width: 100px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
@ -80,12 +81,13 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
> .users {
|
> .users {
|
||||||
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
border-left: solid 0.5px var(--divider);
|
border-left: solid 0.5px var(--divider);
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<button
|
<button
|
||||||
class="hkzvhatu _button"
|
class="hkzvhatu _button"
|
||||||
:class="{ reacted: note.myReaction == reaction, canToggle }"
|
:class="{ reacted: note.myReaction == reaction, canToggle }"
|
||||||
@click="toggleReaction(reaction)"
|
@click="toggleReaction()"
|
||||||
v-if="count > 0"
|
v-if="count > 0"
|
||||||
@touchstart.passive="onMouseover"
|
@touchstart.passive="onMouseover"
|
||||||
@mouseover="onMouseover"
|
@mouseover="onMouseover"
|
||||||
@mouseleave="onMouseleave"
|
@mouseleave="onMouseleave"
|
||||||
@touchend="onMouseleave"
|
@touchend="onMouseleave"
|
||||||
ref="reaction"
|
ref="buttonRef"
|
||||||
v-particle="canToggle"
|
v-particle="canToggle"
|
||||||
>
|
>
|
||||||
<XReactionIcon :reaction="reaction" :custom-emojis="note.emojis"/>
|
<XReactionIcon :reaction="reaction" :custom-emojis="note.emojis"/>
|
||||||
|
@ -17,15 +17,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from 'vue';
|
import { computed, defineComponent, onMounted, ref, watch } from 'vue';
|
||||||
import XDetails from '@/components/reactions-viewer.details.vue';
|
import XDetails from '@/components/reactions-viewer.details.vue';
|
||||||
import XReactionIcon from '@/components/reaction-icon.vue';
|
import XReactionIcon from '@/components/reaction-icon.vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XReactionIcon
|
XReactionIcon
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
reaction: {
|
reaction: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -44,101 +47,78 @@ export default defineComponent({
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
close: null,
|
|
||||||
detailsTimeoutId: null,
|
|
||||||
isHovering: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
canToggle(): boolean {
|
|
||||||
return !this.reaction.match(/@\w/) && this.$i;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
count(newCount, oldCount) {
|
|
||||||
if (oldCount < newCount) this.anime();
|
|
||||||
if (this.close != null) this.openDetails();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (!this.isInitial) this.anime();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggleReaction() {
|
|
||||||
if (!this.canToggle) return;
|
|
||||||
|
|
||||||
const oldReaction = this.note.myReaction;
|
setup(props) {
|
||||||
|
const buttonRef = ref<HTMLElement>();
|
||||||
|
|
||||||
|
const canToggle = computed(() => !props.reaction.match(/@\w/) && $i);
|
||||||
|
|
||||||
|
const toggleReaction = () => {
|
||||||
|
if (!canToggle.value) return;
|
||||||
|
|
||||||
|
const oldReaction = props.note.myReaction;
|
||||||
if (oldReaction) {
|
if (oldReaction) {
|
||||||
os.api('notes/reactions/delete', {
|
os.api('notes/reactions/delete', {
|
||||||
noteId: this.note.id
|
noteId: props.note.id
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (oldReaction !== this.reaction) {
|
if (oldReaction !== props.reaction) {
|
||||||
os.api('notes/reactions/create', {
|
os.api('notes/reactions/create', {
|
||||||
noteId: this.note.id,
|
noteId: props.note.id,
|
||||||
reaction: this.reaction
|
reaction: props.reaction
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
os.api('notes/reactions/create', {
|
os.api('notes/reactions/create', {
|
||||||
noteId: this.note.id,
|
noteId: props.note.id,
|
||||||
reaction: this.reaction
|
reaction: props.reaction
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
onMouseover() {
|
|
||||||
if (this.isHovering) return;
|
|
||||||
this.isHovering = true;
|
|
||||||
this.detailsTimeoutId = setTimeout(this.openDetails, 300);
|
|
||||||
},
|
|
||||||
onMouseleave() {
|
|
||||||
if (!this.isHovering) return;
|
|
||||||
this.isHovering = false;
|
|
||||||
clearTimeout(this.detailsTimeoutId);
|
|
||||||
this.closeDetails();
|
|
||||||
},
|
|
||||||
openDetails() {
|
|
||||||
os.api('notes/reactions', {
|
|
||||||
noteId: this.note.id,
|
|
||||||
type: this.reaction,
|
|
||||||
limit: 11
|
|
||||||
}).then((reactions: any[]) => {
|
|
||||||
const users = reactions
|
|
||||||
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
|
|
||||||
.map(x => x.user);
|
|
||||||
|
|
||||||
this.closeDetails();
|
const anime = () => {
|
||||||
if (!this.isHovering) return;
|
|
||||||
|
|
||||||
const showing = ref(true);
|
|
||||||
os.popup(XDetails, {
|
|
||||||
showing,
|
|
||||||
reaction: this.reaction,
|
|
||||||
emojis: this.note.emojis,
|
|
||||||
users,
|
|
||||||
count: this.count,
|
|
||||||
source: this.$refs.reaction
|
|
||||||
}, {}, 'closed');
|
|
||||||
|
|
||||||
this.close = () => {
|
|
||||||
showing.value = false;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
|
||||||
closeDetails() {
|
|
||||||
if (this.close != null) {
|
|
||||||
this.close();
|
|
||||||
this.close = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
anime() {
|
|
||||||
if (document.hidden) return;
|
if (document.hidden) return;
|
||||||
|
|
||||||
// TODO
|
// TODO: 新しくリアクションが付いたことが視覚的に分かりやすいアニメーション
|
||||||
},
|
};
|
||||||
}
|
|
||||||
|
watch(() => props.count, (newCount, oldCount) => {
|
||||||
|
if (oldCount < newCount) anime();
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!props.isInitial) anime();
|
||||||
|
});
|
||||||
|
|
||||||
|
const { onMouseover, onMouseleave } = useTooltip(async (showing) => {
|
||||||
|
const reactions = await os.api('notes/reactions', {
|
||||||
|
noteId: props.note.id,
|
||||||
|
type: props.reaction,
|
||||||
|
limit: 11
|
||||||
|
});
|
||||||
|
|
||||||
|
const users = reactions
|
||||||
|
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
|
||||||
|
.map(x => x.user);
|
||||||
|
|
||||||
|
os.popup(XDetails, {
|
||||||
|
showing,
|
||||||
|
reaction: props.reaction,
|
||||||
|
emojis: props.note.emojis,
|
||||||
|
users,
|
||||||
|
count: props.count,
|
||||||
|
source: buttonRef.value
|
||||||
|
}, {}, 'closed');
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
buttonRef,
|
||||||
|
canToggle,
|
||||||
|
toggleReaction,
|
||||||
|
onMouseover,
|
||||||
|
onMouseleave,
|
||||||
|
};
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
121
packages/client/src/components/renote-button.vue
Normal file
121
packages/client/src/components/renote-button.vue
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
<template>
|
||||||
|
<button v-if="canRenote"
|
||||||
|
class="eddddedb _button canRenote"
|
||||||
|
@click="renote()"
|
||||||
|
@touchstart.passive="onMouseover"
|
||||||
|
@mouseover="onMouseover"
|
||||||
|
@mouseleave="onMouseleave"
|
||||||
|
@touchend="onMouseleave"
|
||||||
|
ref="buttonRef"
|
||||||
|
>
|
||||||
|
<i class="fas fa-retweet"></i>
|
||||||
|
<p class="count" v-if="count > 0">{{ count }}</p>
|
||||||
|
</button>
|
||||||
|
<button v-else class="eddddedb _button">
|
||||||
|
<i class="fas fa-ban"></i>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, ref } from 'vue';
|
||||||
|
import XDetails from '@/components/renote.details.vue';
|
||||||
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
|
import * as os from '@/os';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
count: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
note: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props) {
|
||||||
|
const buttonRef = ref<HTMLElement>();
|
||||||
|
|
||||||
|
const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i.id);
|
||||||
|
|
||||||
|
const { onMouseover, onMouseleave } = useTooltip(async (showing) => {
|
||||||
|
const renotes = await os.api('notes/renotes', {
|
||||||
|
noteId: props.note.id,
|
||||||
|
limit: 11
|
||||||
|
});
|
||||||
|
|
||||||
|
const users = renotes
|
||||||
|
.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
|
||||||
|
.map(x => x.user);
|
||||||
|
|
||||||
|
if (users.length < 1) return;
|
||||||
|
|
||||||
|
os.popup(XDetails, {
|
||||||
|
showing,
|
||||||
|
users,
|
||||||
|
count: props.count,
|
||||||
|
source: buttonRef.value
|
||||||
|
}, {}, 'closed');
|
||||||
|
});
|
||||||
|
|
||||||
|
const renote = (viaKeyboard = false) => {
|
||||||
|
pleaseLogin();
|
||||||
|
os.popupMenu([{
|
||||||
|
text: i18n.locale.renote,
|
||||||
|
icon: 'fas fa-retweet',
|
||||||
|
action: () => {
|
||||||
|
os.api('notes/create', {
|
||||||
|
renoteId: props.note.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: i18n.locale.quote,
|
||||||
|
icon: 'fas fa-quote-right',
|
||||||
|
action: () => {
|
||||||
|
os.post({
|
||||||
|
renote: props.note,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}], buttonRef.value, {
|
||||||
|
viaKeyboard
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
buttonRef,
|
||||||
|
canRenote,
|
||||||
|
renote,
|
||||||
|
onMouseover,
|
||||||
|
onMouseleave,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.eddddedb {
|
||||||
|
display: inline-block;
|
||||||
|
height: 32px;
|
||||||
|
margin: 2px;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:not(.canRenote) {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.renoted {
|
||||||
|
background: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .count {
|
||||||
|
display: inline;
|
||||||
|
margin-left: 8px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
46
packages/client/src/components/renote.details.vue
Normal file
46
packages/client/src/components/renote.details.vue
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<MkTooltip :source="source" ref="tooltip" @closed="$emit('closed')" :max-width="340">
|
||||||
|
<div class="renoteTooltip">
|
||||||
|
<b v-for="u in users" :key="u.id">
|
||||||
|
<MkAvatar :user="u" style="width: 24px; height: 24px;"/><br/>
|
||||||
|
<MkUserName :user="u" :nowrap="false" style="line-height: 24px;"/>
|
||||||
|
</b>
|
||||||
|
<span v-if="users.length < count" slot="omitted">+{{ count - users.length }}</span>
|
||||||
|
</div>
|
||||||
|
</MkTooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import MkTooltip from './ui/tooltip.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
MkTooltip,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
users: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
count: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
source: {
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['closed'],
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.renoteTooltip {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
44
packages/client/src/scripts/use-tooltip.ts
Normal file
44
packages/client/src/scripts/use-tooltip.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import { Ref, ref } from 'vue';
|
||||||
|
|
||||||
|
export function useTooltip(onShow: (showing: Ref<boolean>) => void) {
|
||||||
|
let isHovering = false;
|
||||||
|
let timeoutId: number;
|
||||||
|
|
||||||
|
let changeShowingState: (() => void) | null;
|
||||||
|
|
||||||
|
const open = () => {
|
||||||
|
close();
|
||||||
|
if (!isHovering) return;
|
||||||
|
|
||||||
|
const showing = ref(true);
|
||||||
|
onShow(showing);
|
||||||
|
changeShowingState = () => {
|
||||||
|
showing.value = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
if (changeShowingState != null) {
|
||||||
|
changeShowingState();
|
||||||
|
changeShowingState = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseover = () => {
|
||||||
|
if (isHovering) return;
|
||||||
|
isHovering = true;
|
||||||
|
timeoutId = window.setTimeout(open, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseleave = () => {
|
||||||
|
if (!isHovering) return;
|
||||||
|
isHovering = false;
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onMouseover,
|
||||||
|
onMouseleave,
|
||||||
|
};
|
||||||
|
}
|
|
@ -206,8 +206,8 @@ export default defineComponent({
|
||||||
this.text += ' ';
|
this.text += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.reply && this.reply.user.host != null) {
|
if (this.reply && (this.reply.user.username != this.$i.username || (this.reply.user.host != null && this.reply.user.host != host))) {
|
||||||
this.text = `@${this.reply.user.username}@${toASCII(this.reply.user.host)} `;
|
this.text = `@${this.reply.user.username}${this.reply.user.host != null ? '@' + toASCII(this.reply.user.host) : ''} `;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.reply && this.reply.text != null) {
|
if (this.reply && this.reply.text != null) {
|
||||||
|
|
|
@ -397,11 +397,6 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
|
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
|
||||||
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
|
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
|
||||||
|
|
||||||
"@types/disposable-email-domains@^1.0.1":
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/disposable-email-domains/-/disposable-email-domains-1.0.2.tgz#0280f6b38fa7f14e54b056a434135ecd254483b1"
|
|
||||||
integrity sha512-SDKwyYTjk3y5aZBxxc38yRecpJPjsqn57STz1bNxYYlv4k11bBe7QB8w4llXDTmQXKT1mFvgGmJv+8Zdu3YmJw==
|
|
||||||
|
|
||||||
"@types/escape-regexp@0.0.0":
|
"@types/escape-regexp@0.0.0":
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3"
|
resolved "https://registry.yarnpkg.com/@types/escape-regexp/-/escape-regexp-0.0.0.tgz#bff0225f9ef30d0dbdbe0e2a24283ee5342990c3"
|
||||||
|
@ -1479,13 +1474,6 @@ aws4@^1.8.0:
|
||||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
|
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
|
||||||
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
|
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
|
||||||
|
|
||||||
axios@^0.19.2:
|
|
||||||
version "0.19.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
|
||||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
|
||||||
dependencies:
|
|
||||||
follow-redirects "1.5.10"
|
|
||||||
|
|
||||||
axios@^0.21.1:
|
axios@^0.21.1:
|
||||||
version "0.21.1"
|
version "0.21.1"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
|
||||||
|
@ -1628,13 +1616,6 @@ browserslist@^4.16.6:
|
||||||
escalade "^3.1.1"
|
escalade "^3.1.1"
|
||||||
node-releases "^1.1.71"
|
node-releases "^1.1.71"
|
||||||
|
|
||||||
bs-logger@0.x:
|
|
||||||
version "0.2.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8"
|
|
||||||
integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
|
|
||||||
dependencies:
|
|
||||||
fast-json-stable-stringify "2.x"
|
|
||||||
|
|
||||||
buffer-alloc-unsafe@^1.1.0:
|
buffer-alloc-unsafe@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||||
|
@ -1663,11 +1644,6 @@ buffer-fill@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
||||||
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
||||||
|
|
||||||
buffer-from@1.x:
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
|
||||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
|
||||||
|
|
||||||
buffer-from@^1.0.0, buffer-from@^1.1.1:
|
buffer-from@^1.0.0, buffer-from@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||||
|
@ -2350,13 +2326,6 @@ debug@4.3.2, debug@^4.3.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "2.1.2"
|
ms "2.1.2"
|
||||||
|
|
||||||
debug@=3.1.0:
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
|
||||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
|
||||||
dependencies:
|
|
||||||
ms "2.0.0"
|
|
||||||
|
|
||||||
debug@^3.1.0:
|
debug@^3.1.0:
|
||||||
version "3.2.7"
|
version "3.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||||
|
@ -2388,18 +2357,6 @@ decompress-response@^6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-response "^3.1.0"
|
mimic-response "^3.1.0"
|
||||||
|
|
||||||
deep-email-validator@0.1.18:
|
|
||||||
version "0.1.18"
|
|
||||||
resolved "https://registry.yarnpkg.com/deep-email-validator/-/deep-email-validator-0.1.18.tgz#a072a93f28e11863cc6b9ca3ae964e0e45b3ece8"
|
|
||||||
integrity sha512-eo2WEUidQvppg6Qdek8iwOqmXvaxRJ2D2VJKbIOwUgLZNFveDDdJMBsFc+yq0S+lILEUcmzrJRrCWbyoe7QUzQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/disposable-email-domains" "^1.0.1"
|
|
||||||
axios "^0.19.2"
|
|
||||||
disposable-email-domains "^1.0.53"
|
|
||||||
lodash "^4.17.15"
|
|
||||||
mailcheck "^1.1.1"
|
|
||||||
ts-jest "^25.2.1"
|
|
||||||
|
|
||||||
deep-is@^0.1.3:
|
deep-is@^0.1.3:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||||
|
@ -2454,11 +2411,6 @@ dir-glob@^3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
|
|
||||||
disposable-email-domains@^1.0.53:
|
|
||||||
version "1.0.58"
|
|
||||||
resolved "https://registry.yarnpkg.com/disposable-email-domains/-/disposable-email-domains-1.0.58.tgz#ac9c879c02c4f0898bfb6c0c80b959c0b0b7bc51"
|
|
||||||
integrity sha512-frnNCPqTjk6t/sosPoco6EIFHbP9SazHQkeltJNfZeUyNgewaVf+kFjEfVkVDVd436Vln43YElJPb8JozhBs7Q==
|
|
||||||
|
|
||||||
doctrine@^3.0.0:
|
doctrine@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||||
|
@ -3013,7 +2965,7 @@ fast-glob@^3.1.1:
|
||||||
micromatch "^4.0.2"
|
micromatch "^4.0.2"
|
||||||
picomatch "^2.2.1"
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
|
fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||||
|
@ -3134,13 +3086,6 @@ flatted@^3.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067"
|
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067"
|
||||||
integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==
|
integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==
|
||||||
|
|
||||||
follow-redirects@1.5.10:
|
|
||||||
version "1.5.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
|
||||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
|
||||||
dependencies:
|
|
||||||
debug "=3.1.0"
|
|
||||||
|
|
||||||
follow-redirects@^1.10.0:
|
follow-redirects@^1.10.0:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
|
||||||
|
@ -3952,7 +3897,7 @@ json5-loader@4.0.1:
|
||||||
loader-utils "^2.0.0"
|
loader-utils "^2.0.0"
|
||||||
schema-utils "^3.0.0"
|
schema-utils "^3.0.0"
|
||||||
|
|
||||||
json5@2.2.0, json5@2.x:
|
json5@2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
||||||
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
|
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
|
||||||
|
@ -4153,7 +4098,7 @@ lodash.isfinite@^3.3.2:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
|
resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
|
||||||
integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=
|
integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=
|
||||||
|
|
||||||
lodash.memoize@4.x, lodash.memoize@^4.1.2:
|
lodash.memoize@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
@ -4173,7 +4118,7 @@ lodash.uniq@^4.5.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||||
|
|
||||||
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21:
|
lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
@ -4222,12 +4167,7 @@ magic-string@^0.25.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
sourcemap-codec "^1.4.4"
|
sourcemap-codec "^1.4.4"
|
||||||
|
|
||||||
mailcheck@^1.1.1:
|
make-error@^1.1.1:
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/mailcheck/-/mailcheck-1.1.1.tgz#d87cf6ba0b64ba512199dbf93f1489f479591e34"
|
|
||||||
integrity sha1-2Hz2ugtkulEhmdv5PxSJ9HlZHjQ=
|
|
||||||
|
|
||||||
make-error@1.x, make-error@^1.1.1:
|
|
||||||
version "1.3.6"
|
version "1.3.6"
|
||||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||||
|
@ -4279,14 +4219,6 @@ mfm-js@0.20.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
twemoji-parser "13.1.x"
|
twemoji-parser "13.1.x"
|
||||||
|
|
||||||
micromatch@4.x:
|
|
||||||
version "4.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
|
||||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
|
||||||
dependencies:
|
|
||||||
braces "^3.0.1"
|
|
||||||
picomatch "^2.2.3"
|
|
||||||
|
|
||||||
micromatch@^4.0.0, micromatch@^4.0.2:
|
micromatch@^4.0.0, micromatch@^4.0.2:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
|
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
|
||||||
|
@ -4353,7 +4285,7 @@ misskey-js@0.0.10:
|
||||||
eventemitter3 "^4.0.7"
|
eventemitter3 "^4.0.7"
|
||||||
reconnecting-websocket "^4.4.0"
|
reconnecting-websocket "^4.4.0"
|
||||||
|
|
||||||
mkdirp@0.x, mkdirp@~0.5.1:
|
mkdirp@~0.5.1:
|
||||||
version "0.5.5"
|
version "0.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||||
|
@ -4754,11 +4686,6 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1:
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||||
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
||||||
|
|
||||||
picomatch@^2.2.3:
|
|
||||||
version "2.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
|
||||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
|
||||||
|
|
||||||
pify@^2.2.0:
|
pify@^2.2.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||||
|
@ -5605,11 +5532,6 @@ seedrandom@3.0.5:
|
||||||
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
|
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
|
||||||
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
|
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
|
||||||
|
|
||||||
semver@6.x:
|
|
||||||
version "6.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
|
||||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
|
||||||
|
|
||||||
semver@^7.2.1, semver@^7.3.2, semver@^7.3.4:
|
semver@^7.2.1, semver@^7.3.2, semver@^7.3.4:
|
||||||
version "7.3.4"
|
version "7.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
|
||||||
|
@ -6114,22 +6036,6 @@ tree-kill@^1.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
|
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
|
||||||
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
|
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
|
||||||
|
|
||||||
ts-jest@^25.2.1:
|
|
||||||
version "25.5.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.5.1.tgz#2913afd08f28385d54f2f4e828be4d261f4337c7"
|
|
||||||
integrity sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw==
|
|
||||||
dependencies:
|
|
||||||
bs-logger "0.x"
|
|
||||||
buffer-from "1.x"
|
|
||||||
fast-json-stable-stringify "2.x"
|
|
||||||
json5 "2.x"
|
|
||||||
lodash.memoize "4.x"
|
|
||||||
make-error "1.x"
|
|
||||||
micromatch "4.x"
|
|
||||||
mkdirp "0.x"
|
|
||||||
semver "6.x"
|
|
||||||
yargs-parser "18.x"
|
|
||||||
|
|
||||||
ts-loader@9.2.6:
|
ts-loader@9.2.6:
|
||||||
version "9.2.6"
|
version "9.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74"
|
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74"
|
||||||
|
@ -6734,14 +6640,6 @@ yaml@^1.10.2:
|
||||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||||
|
|
||||||
yargs-parser@18.x:
|
|
||||||
version "18.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
|
|
||||||
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
|
|
||||||
dependencies:
|
|
||||||
camelcase "^5.0.0"
|
|
||||||
decamelize "^1.2.0"
|
|
||||||
|
|
||||||
yargs-parser@20.2.4, yargs-parser@^20.2.2:
|
yargs-parser@20.2.4, yargs-parser@^20.2.2:
|
||||||
version "20.2.4"
|
version "20.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
|
||||||
|
|
Loading…
Reference in a new issue