Merge branch 'develop'

This commit is contained in:
syuilo 2021-11-19 20:39:59 +09:00
commit 88cdbc2ad6
368 changed files with 4160 additions and 2663 deletions

View file

@ -17,5 +17,9 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
with: with:
node-version: 12.x node-version: 12.x
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- run: yarn install - run: yarn install
- run: yarn lint - run: yarn lint

View file

@ -75,6 +75,10 @@ jobs:
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- name: Install dependencies - name: Install dependencies
run: yarn install run: yarn install
- name: Check yarn.lock - name: Check yarn.lock

View file

@ -3,7 +3,7 @@
"editorconfig.editorconfig", "editorconfig.editorconfig",
"eg2.vscode-npm-script", "eg2.vscode-npm-script",
"ms-vscode.typescript-javascript-grammar", "ms-vscode.typescript-javascript-grammar",
"ms-vscode.vscode-typescript-tslint-plugin", "dbaeumer.vscode-eslint",
"johnsoncodehk.volar", "johnsoncodehk.volar",
"sysoev.language-stylus" "sysoev.language-stylus"
] ]

View file

@ -7,6 +7,18 @@
--> -->
## 12.97.0 (2021/11/19)
### Improvements
- クライアント: 返信先やRenoteに対しても自動折りたたみされるように
- クライアント: 長いスレッドの表示を改善
- クライアント: 翻訳にもMFMを適用し、元の文章の改行などを保持するように
- クライアント: アカウント削除に確認ダイアログを出すように
### Bugfixes
- クライアント: ユーザー検索の「全て」が動作しない問題を修正
- クライアント: リアクション一覧、Renote一覧ツールチップのスタイルを修正
## 12.96.1 (2021/11/13) ## 12.96.1 (2021/11/13)
### Improvements ### Improvements
- npm scriptの互換性を向上 - npm scriptの互換性を向上

View file

@ -49,6 +49,11 @@ If your language is not listed in Crowdin, please open an issue.
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg) ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
## Development
During development, it is useful to use the `npm run dev` command.
This command monitors the server-side and client-side source files and automatically builds them if they are modified.
In addition, it will also automatically start the Misskey server process.
## Testing ## Testing
- Test codes are located in [`/test`](/test). - Test codes are located in [`/test`](/test).

View file

@ -29,7 +29,6 @@ COPY --from=builder /misskey/built ./built
COPY --from=builder /misskey/packages/backend/node_modules ./packages/backend/node_modules COPY --from=builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
COPY --from=builder /misskey/packages/backend/built ./packages/backend/built COPY --from=builder /misskey/packages/backend/built ./packages/backend/built
COPY --from=builder /misskey/packages/client/node_modules ./packages/client/node_modules COPY --from=builder /misskey/packages/client/node_modules ./packages/client/node_modules
COPY --from=builder /misskey/packages/client/built ./packages/client/built
COPY . ./ COPY . ./
CMD ["npm", "run", "migrateandstart"] CMD ["npm", "run", "migrateandstart"]

View file

@ -57,6 +57,6 @@ gulp.task('default', gulp.task('build'));
gulp.task('watch', () => { gulp.task('watch', () => {
gulp.watch([ gulp.watch([
'./packages/**/*', './packages/*/src/**/*',
], { ignoreInitial: false }, gulp.task('build')); ], { ignoreInitial: false }, gulp.task('build'));
}); });

File diff suppressed because it is too large Load diff

View file

@ -52,6 +52,7 @@ searchUser: "Vyhledat uživatele"
reply: "Odpovědět" reply: "Odpovědět"
loadMore: "Zobrazit více" loadMore: "Zobrazit více"
showMore: "Zobrazit více" showMore: "Zobrazit více"
youGotNewFollower: "Máte nového následovníka"
mention: "Zmínění" mention: "Zmínění"
mentions: "Zmínění" mentions: "Zmínění"
importAndExport: "Import a export" importAndExport: "Import a export"
@ -163,6 +164,7 @@ clearQueue: "Vyčistit frontu"
clearQueueConfirmTitle: "Jste si jisti že zrušit všechny úlohy ve frontě?" clearQueueConfirmTitle: "Jste si jisti že zrušit všechny úlohy ve frontě?"
clearCachedFiles: "Vyprázdnit mezipaměť" clearCachedFiles: "Vyprázdnit mezipaměť"
blockedInstances: "Blokované instance" blockedInstances: "Blokované instance"
noUsers: "Žádní uživatelé"
editProfile: "Upravit můj profil" editProfile: "Upravit můj profil"
pinLimitExceeded: "Nemůžete připnout další poznámky." pinLimitExceeded: "Nemůžete připnout další poznámky."
intro: "Instalace Misskey byla dokončena! Prosím vytvořte admina." intro: "Instalace Misskey byla dokončena! Prosím vytvořte admina."
@ -170,6 +172,7 @@ done: "Hotovo"
processing: "Zpracovávám" processing: "Zpracovávám"
preview: "Náhled" preview: "Náhled"
default: "Výchozí" default: "Výchozí"
noCustomEmojis: "Bez Emoji"
blocked: "Blokováno" blocked: "Blokováno"
suspended: "Suspendováno" suspended: "Suspendováno"
all: "Vše" all: "Vše"
@ -402,6 +405,9 @@ smtpPass: "Heslo"
clearCache: "Vyprázdnit mezipaměť" clearCache: "Vyprázdnit mezipaměť"
info: "Informace" info: "Informace"
user: "Uživatelé" user: "Uživatelé"
_email:
_follow:
title: "Máte nového následovníka"
_mfm: _mfm:
mention: "Zmínění" mention: "Zmínění"
quote: "Citovat" quote: "Citovat"
@ -464,6 +470,7 @@ _pages:
types: types:
array: "Seznamy" array: "Seznamy"
_notification: _notification:
youWereFollowed: "Máte nového následovníka"
youWereInvitedToGroup: "Pozvat do skupiny" youWereInvitedToGroup: "Pozvat do skupiny"
_types: _types:
follow: "Sledovaní" follow: "Sledovaní"

View file

@ -620,6 +620,8 @@ reportAbuse: "Melden"
reportAbuseOf: "{name} melden" reportAbuseOf: "{name} melden"
fillAbuseReportDescription: "Bitte gib zusätzliche Informationen zu dieser Meldung an. Falls es sich um eine spezielle Notiz handelt, bitte gib dessen URL an." fillAbuseReportDescription: "Bitte gib zusätzliche Informationen zu dieser Meldung an. Falls es sich um eine spezielle Notiz handelt, bitte gib dessen URL an."
abuseReported: "Die Meldung wurde versendet. Vielen Dank." abuseReported: "Die Meldung wurde versendet. Vielen Dank."
reporteeOrigin: "Herkunft des Gemeldeten"
reporterOrigin: "Herkunft des Meldenden"
send: "Senden" send: "Senden"
abuseMarkAsResolved: "Meldung als gelöst markieren" abuseMarkAsResolved: "Meldung als gelöst markieren"
openInNewTab: "In neuem Tab öffnen" openInNewTab: "In neuem Tab öffnen"
@ -795,12 +797,27 @@ itsOff: "Ausgeschaltet"
emailRequiredForSignup: "Angaben einer Email-Adresse als benötigt markieren" emailRequiredForSignup: "Angaben einer Email-Adresse als benötigt markieren"
unread: "Ungelesen" unread: "Ungelesen"
filter: "Filter" filter: "Filter"
controlPanel: "Systemsteuerung"
manageAccounts: "Benutzerkonten verwalten" manageAccounts: "Benutzerkonten verwalten"
makeReactionsPublic: "Reaktionsverlauf veröffentlichen" makeReactionsPublic: "Reaktionsverlauf veröffentlichen"
makeReactionsPublicDescription: "Jeder wird die Liste deiner gesendeten Reaktionen einsehen können." makeReactionsPublicDescription: "Jeder wird die Liste deiner gesendeten Reaktionen einsehen können."
classic: "Classic" classic: "Classic"
muteThread: "Thread stummschalten" muteThread: "Thread stummschalten"
unmuteThread: "Threadstummschaltung aufheben" unmuteThread: "Threadstummschaltung aufheben"
ffVisibility: "Sichtbarkeit von Gefolgten/Followern"
ffVisibilityDescription: "Konfiguriere wer sehen kann, wem du folgst sowie wer dir folgt."
continueThread: "Weiteren Threadverlauf anzeigen"
deleteAccountConfirm: "Dein Benutzerkonto wird unwiderruflich gelöscht. Trotzdem fortfahren?"
_emailUnavailable:
used: "Diese Email-Adresse wird bereits verwendet"
format: "Das Format dieser Email-Adresse ist ungültig"
disposable: "Wegwerf-Email-Adressen können nicht verwendet werden"
mx: "Dieser Email-Server ist ungültig"
smtp: "Dieser Email-Server antwortet nicht"
_ffVisibility:
public: "Öffentlich"
followers: "Nur für Follower sichtbar"
private: "Privat"
_signup: _signup:
almostThere: "Fast geschafft" almostThere: "Fast geschafft"
emailAddressInfo: "Bitte gib deine Email-Adresse ein." emailAddressInfo: "Bitte gib deine Email-Adresse ein."
@ -812,13 +829,6 @@ _accountDelete:
requestAccountDelete: "Löschung des Benutzerkontos anfordern" requestAccountDelete: "Löschung des Benutzerkontos anfordern"
started: "Löschung wurde eingeleitet." started: "Löschung wurde eingeleitet."
inProgress: "Löschung in Bearbeitung" inProgress: "Löschung in Bearbeitung"
_docs:
continueReading: "Mehr lesen"
features: "Funktionen"
generalTopics: "Allgemeine Themen"
advancedTopics: "Erweiterte Themen"
admin: "Administration"
translateWarn: "Dies ist ein übersetztes Dokument. Es kann zu Unterschieden mit dem Original kommen."
_ad: _ad:
back: "Zurück" back: "Zurück"
reduceFrequencyOfThisAd: "Diese Werbung weniger anzeigen" reduceFrequencyOfThisAd: "Diese Werbung weniger anzeigen"

View file

@ -620,6 +620,8 @@ reportAbuse: "Report"
reportAbuseOf: "Report {name}" reportAbuseOf: "Report {name}"
fillAbuseReportDescription: "Please fill in details regarding this report. If it is about a specific note, please include its URL." fillAbuseReportDescription: "Please fill in details regarding this report. If it is about a specific note, please include its URL."
abuseReported: "Your report has been sent. Thank you very much." abuseReported: "Your report has been sent. Thank you very much."
reporteeOrigin: "Reportee Origin"
reporterOrigin: "Reporter Origin"
send: "Send" send: "Send"
abuseMarkAsResolved: "Mark report as resolved" abuseMarkAsResolved: "Mark report as resolved"
openInNewTab: "Open in new tab" openInNewTab: "Open in new tab"
@ -802,6 +804,20 @@ makeReactionsPublicDescription: "This will make the list of all your past reacti
classic: "Classic" classic: "Classic"
muteThread: "Mute thread" muteThread: "Mute thread"
unmuteThread: "Unmute thread" unmuteThread: "Unmute thread"
ffVisibility: "Follows/Followers Visibility"
ffVisibilityDescription: "Allows you to configure who can see who you follow and who follows you."
continueThread: "View thread continuation"
deleteAccountConfirm: "This will irreversibly delete your account. Proceed?"
_emailUnavailable:
used: "This email address is already being used"
format: "The format of this email address is invalid"
disposable: "Disposable email addresses may not be used"
mx: "This email server is invalid"
smtp: "This email server is not responding"
_ffVisibility:
public: "Public"
followers: "Visible to followers only"
private: "Private"
_signup: _signup:
almostThere: "Almost there" almostThere: "Almost there"
emailAddressInfo: "Please enter your email address." emailAddressInfo: "Please enter your email address."
@ -813,13 +829,6 @@ _accountDelete:
requestAccountDelete: "Request account deletion" requestAccountDelete: "Request account deletion"
started: "Deletion has been started." started: "Deletion has been started."
inProgress: "Deletion is currently in progress" inProgress: "Deletion is currently in progress"
_docs:
continueReading: "Read more"
features: "Features"
generalTopics: "General topics"
advancedTopics: "Advanced Topics"
admin: "Administration"
translateWarn: "This is a translated document. Its contents may differ from the original."
_ad: _ad:
back: "Back" back: "Back"
reduceFrequencyOfThisAd: "Show this ad less" reduceFrequencyOfThisAd: "Show this ad less"

View file

@ -2,7 +2,7 @@
_lang_: "Esperanto" _lang_: "Esperanto"
headlineMisskey: "Jen la reto konektata de notoj" headlineMisskey: "Jen la reto konektata de notoj"
introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por paroli vian penson al iuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri ies noto en Fediverso. 👍\nBonvole esploru novan mondon. 🚀" introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por paroli vian penson al iuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri ies noto en Fediverso. 👍\nBonvole esploru novan mondon. 🚀"
monthAndDay: "{{day}}/{{month}}" monthAndDay: "La {day}a de la {month}a"
search: "Serĉi" search: "Serĉi"
notifications: "Sciigoj" notifications: "Sciigoj"
username: "Uzantnomo" username: "Uzantnomo"
@ -23,7 +23,7 @@ otherSettings: "Aliaj agordoj"
openInWindow: "Malfermi en fenestro" openInWindow: "Malfermi en fenestro"
profile: "Profilo" profile: "Profilo"
timeline: "Templinio" timeline: "Templinio"
noAccountDescription: "Neniu priskribo" noAccountDescription: "Neniu sinprezento"
login: "Ensaluti" login: "Ensaluti"
loggingIn: "Ensalutado…" loggingIn: "Ensalutado…"
logout: "Elsaluti" logout: "Elsaluti"
@ -36,15 +36,15 @@ favorite: "Preferi"
favorites: "Preferaĵoj" favorites: "Preferaĵoj"
unfavorite: "Malpreferi" unfavorite: "Malpreferi"
favorited: "Aldonita al via listo de preferaĵoj." favorited: "Aldonita al via listo de preferaĵoj."
alreadyFavorited: "Ĝi jam estis aldonita al via listo de preferaĵoj." alreadyFavorited: "Jam aldonita al via listo de preferaĵoj."
cantFavorite: "Ne aldonita al via listo de preferaĵoj." cantFavorite: "Ĝi ne povis esti aldonita al via listo de preferaĵoj."
pin: "Alpingli" pin: "Alpingli"
unpin: "Depingli" unpin: "Depingli"
copyContent: "Kopii enhavon" copyContent: "Kopii enhavon"
copyLink: "Kopii ligilon" copyLink: "Kopii ligilon"
delete: "Forviŝi" delete: "Forviŝi"
deleteAndEdit: "Redakti foriginte" deleteAndEdit: "Forviŝi kaj redakti"
deleteAndEditConfirm: "Ĉu vi certas, ke vi volas forigi kaj redakti la noton? Tio forviŝos reagojn, plusendojn, kaj respondojn ĉiujn de ĝi." deleteAndEditConfirm: "Ĉu vi certas ke vi volas redakti forviŝinte la noton? Tio forviŝos ankaŭ ĉiujn reagojn, plusendojn, kaj respondojn apartenantajn al ĝi."
addToList: "Aldoni al listo" addToList: "Aldoni al listo"
sendMessage: "Sendi mesaĝon" sendMessage: "Sendi mesaĝon"
copyUsername: "Kopii uzantnomon" copyUsername: "Kopii uzantnomon"
@ -56,7 +56,7 @@ youGotNewFollower: "eksekvis vin"
receiveFollowRequest: "Peto de sekvado estas ricevita" receiveFollowRequest: "Peto de sekvado estas ricevita"
followRequestAccepted: "La peto de sekvado akceptita" followRequestAccepted: "La peto de sekvado akceptita"
mention: "Mencioj" mention: "Mencioj"
mentions: "Al vi" mentions: "Mencioj"
directNotes: "Rekte senditaj" directNotes: "Rekte senditaj"
importAndExport: "Importi/eksporti" importAndExport: "Importi/eksporti"
import: "Importi" import: "Importi"
@ -79,11 +79,13 @@ somethingHappened: "Problemo okazis"
retry: "Provi denove" retry: "Provi denove"
enterListName: "Entajpu nomon de la listo" enterListName: "Entajpu nomon de la listo"
privacy: "Privateco" privacy: "Privateco"
makeFollowManuallyApprove: "Eksekvi vin devas peti al vi"
defaultNoteVisibility: "Implicitaĵo de videbleco" defaultNoteVisibility: "Implicitaĵo de videbleco"
follow: "Sekvi" follow: "Sekvi"
followRequest: "Peti de sekvado" followRequest: "Peti de sekvado"
followRequests: "Petoj de sekvado" followRequests: "Petoj de sekvado"
unfollow: "Ne plu sekvi" unfollow: "Ne plu sekvi"
followRequestPending: "Atendado akcepti vian peton de eksekvado"
enterEmoji: "Entajpu emoĵion" enterEmoji: "Entajpu emoĵion"
renote: "Plusendi la noton" renote: "Plusendi la noton"
unrenote: "Malfari plusendadon" unrenote: "Malfari plusendadon"
@ -98,11 +100,12 @@ clickToShow: "Klaku por malkaŝu"
sensitive: "Enhavo ne estas deca por laborejo (NSFW)" sensitive: "Enhavo ne estas deca por laborejo (NSFW)"
add: "Aldoni" add: "Aldoni"
reaction: "Reagoj" reaction: "Reagoj"
rememberNoteVisibility: "Rememoru videblecon de la noto laste sendita " reactionSettingDescription: "Agordi la reagojn kiujn vi volas prefere montrigi ĉe la elektilo de reagoj"
rememberNoteVisibility: "Rememori la agordon de videbleco de la noto laste sendita "
attachCancel: "Deigi aldonaĵon" attachCancel: "Deigi aldonaĵon"
markAsSensitive: "Troviĝi NSFW" markAsSensitive: "Troviĝi NSFW"
unmarkAsSensitive: "Ne troviĝi NSFW" unmarkAsSensitive: "Ne troviĝi NSFW"
enterFileName: "Entajpu nomon de dosiero" enterFileName: "Entajpu nomon de la dosiero"
mute: "Silentigi" mute: "Silentigi"
unmute: "Malsilentigi" unmute: "Malsilentigi"
block: "Bloki" block: "Bloki"
@ -127,7 +130,7 @@ addEmoji: "Aldoni emoĵion"
settingGuide: "Agordaj rekomendoj" settingGuide: "Agordaj rekomendoj"
cacheRemoteFiles: "Stapli transajn dosierojn" cacheRemoteFiles: "Stapli transajn dosierojn"
flagAsBot: "Agordo por robota uzanto" flagAsBot: "Agordo por robota uzanto"
flagAsCat: "Agordo de katiĝa uzanto" flagAsCat: "Agi kat-iĝon"
addAccount: "Aldoni konton" addAccount: "Aldoni konton"
showOnRemote: "Vidi ĉe la surloka nodo" showOnRemote: "Vidi ĉe la surloka nodo"
general: "Ĝenerala" general: "Ĝenerala"
@ -141,13 +144,14 @@ host: "Gastigo"
selectUser: "Elekti uzanton" selectUser: "Elekti uzanton"
recipient: "Ricevonto" recipient: "Ricevonto"
annotation: "Komentarioj" annotation: "Komentarioj"
federation: "Kunfederaĵo" federation: "Federaĵo"
instances: "Nodoj" instances: "Nodoj"
latestRequestSentAt: "Lastatempa sendo" latestRequestSentAt: "Lastatempa sendo"
latestRequestReceivedAt: "Lastatempa ricevo" latestRequestReceivedAt: "Lastatempa ricevo"
latestStatus: "Laŭstato" latestStatus: "Laŭstato"
perHour: "Po horo" charts: "Diagramoj"
perDay: "Po tago" perHour: "por horo"
perDay: "por tago"
blockThisInstance: "Bloki la nodon" blockThisInstance: "Bloki la nodon"
operations: "Agoj" operations: "Agoj"
software: "Programaro" software: "Programaro"
@ -156,36 +160,37 @@ metadata: "Metadatumoj"
withNFiles: "{n} dosiero(j)" withNFiles: "{n} dosiero(j)"
monitor: "Monitoro" monitor: "Monitoro"
network: "Reto" network: "Reto"
disk: "Diskilo" disk: "Disko"
instanceInfo: "Informoj pri la nodo" instanceInfo: "Informoj pri la nodo"
statistics: "Statistikoj" statistics: "Statistikoj"
clearCachedFiles: "Malplenigi la staplon" clearCachedFiles: "Malplenigi la staplon"
clearCachedFilesConfirm: "Ĉu vi certas, ke vi volas forviŝi ĉiujn transajn dosierojn en la staplo?" clearCachedFilesConfirm: "Ĉu vi certas, ke vi volas forviŝi ĉiujn transajn dosierojn en la staplo?"
blockedInstances: "Blokitaj nodoj" blockedInstances: "Blokitaj nodoj"
muteAndBlock: "Silentigitoj kaj blokitoj"
mutedUsers: "Silentigitaj uzantoj" mutedUsers: "Silentigitaj uzantoj"
blockedUsers: "Blokitaj uzantoj" blockedUsers: "Blokitaj uzantoj"
noUsers: "Sen uzantoj" noUsers: "Neniu uzanto"
editProfile: "Redakti profilon" editProfile: "Redakti profilon"
noteDeleteConfirm: "Ĉu vi certas ke vi volas forviŝi la noton?" noteDeleteConfirm: "Ĉu vi certas ke vi volas forviŝi la noton?"
pinLimitExceeded: "Vi povas alpingli ne pli noton." pinLimitExceeded: "Vi ne povas alpingli pli"
done: "Fini" done: "Fini"
processing: "Prilaborado…" processing: "Prilaborado…"
preview: "Antaŭmontro" preview: "Antaŭmontro"
default: "Defaŭlta"
noCustomEmojis: "Neniu emoĵio" noCustomEmojis: "Neniu emoĵio"
federating: "Nun kunfederanta" noJobs: "Neniu laboro"
blocked: "Blokita" federating: "Federantaj"
suspended: "Suspendita" blocked: "Blokitaj"
suspended: "Suspenditaj"
all: "Ĉiuj" all: "Ĉiuj"
subscribing: "Abonata" subscribing: "Abonitaj"
publishing: "Al kiu dissendas" publishing: "Abonintaj"
notResponding: "Alvokato ne disponeblas" notResponding: "Alvokato ne disponeblas"
instanceFollowing: "Sekvatoj en la nodo" instanceFollowing: "Sekvatoj en la nodo"
instanceFollowers: "Sekvantoj el la nodo" instanceFollowers: "Sekvantoj el la nodo"
instanceUsers: "Uzantoj de tiu ĉi nodo" instanceUsers: "Uzantoj de la nodo"
changePassword: "Ŝanĝi pasvorton" changePassword: "Ŝanĝi pasvorton"
security: "Sekureco" security: "Sekureco"
retypedNotMatch: "Enigitoj ne estas konformaj." retypedNotMatch: "La enigitoj ne estas konformaj."
currentPassword: "Aktuala pasvorto" currentPassword: "Aktuala pasvorto"
newPassword: "Nova pasvorto" newPassword: "Nova pasvorto"
newPasswordRetype: "Reentajpu la novan pasvorton" newPasswordRetype: "Reentajpu la novan pasvorton"
@ -193,38 +198,47 @@ attachFile: "Aldoni dosieron"
more: "Plu!" more: "Plu!"
featured: "Maksimumi" featured: "Maksimumi"
usernameOrUserId: "Uzantnomo aŭ identigilo de uzanto" usernameOrUserId: "Uzantnomo aŭ identigilo de uzanto"
noSuchUser: "Neniuj uzantoj trovitaj." noSuchUser: "Neniuj uzantoj trovitaj"
lookup: "Informpeti" lookup: "Informpeti"
announcements: "Novaĵoj" announcements: "Novaĵoj"
imageUrl: "URL de bildo" imageUrl: "URL de la bildo"
remove: "Forigi" remove: "Forigi"
removed: "Forviŝis" removed: "Forigita"
removeAreYouSure: "Ĉu vi certas ke vi volas forigi \"{x}\"'(o)n?" removeAreYouSure: "Ĉu vi certas ke vi volas forigi \"{x}\"'(o)n?"
deleteAreYouSure: "Ĉu vi certas ke vi volas forviŝi \"{x}\"'(o)n?" deleteAreYouSure: "Ĉu vi certas ke vi volas forviŝi \"{x}\"'(o)n?"
resetAreYouSure: "Ĉu vi certas restarigi?"
saved: "Konservita" saved: "Konservita"
messaging: "Retbabili" messaging: "Retbabili"
upload: "Alŝuti" upload: "Alŝuti"
fromDrive: "De la disko" fromDrive: "De la disko"
fromUrl: "De URL" fromUrl: "De URL"
uploadFromUrl: "Alŝuti de URL" uploadFromUrl: "Alŝuti de URL"
uploadFromUrlDescription: "URL de dosiero kiun vi volas alŝuti" uploadFromUrlDescription: "URL de la dosiero kiun vi volas alŝuti"
uploadFromUrlRequested: "La alŝutado estis patita"
explore: "Esplori" explore: "Esplori"
games: "Miskiaj Ludoj" games: "Miskiaj Ludoj"
messageRead: "Legita" messageRead: "Legita"
noMoreHistory: "Ne plu de la historio"
startMessaging: "Komenci babiladon" startMessaging: "Komenci babiladon"
nUsersRead: "Legita de {n} homoj" nUsersRead: "Legita de {n} homoj"
agreeTo: "Mi akceptas {0}'(o)n"
tos: "Kondiĉoj de uzado" tos: "Kondiĉoj de uzado"
start: "Komenciĝi" start: "Komenciĝi"
home: "Hejma" home: "Hejma"
remoteUserCaution: "Ĉi tiuj infomoj ne estas tute ekzaktaj pro transa uzanto." remoteUserCaution: "Ĉi tiuj infomoj estas ne tute ekzaktaj pro transa uzanto."
activity: "Aktiveco" activity: "Aktiveco"
images: "Bildoj" images: "Bildoj"
birthday: "Naskiĝdato" birthday: "Naskiĝdato"
yearsOld: "{age} jaroj aĝa"
registeredDate: "Dato de registriĝo" registeredDate: "Dato de registriĝo"
location: "Loko" location: "Loko"
theme: "Koloraro" theme: "Koloraro"
themeForLightMode: "Luma kolararo en la luma modo"
themeForDarkMode: "Malluma kolararo en la malluma modo"
light: "Luma" light: "Luma"
dark: "Malluma" dark: "Malluma"
lightThemes: "Luma koloraro"
darkThemes: "Malluma koloraro"
drive: "Disko" drive: "Disko"
fileName: "Dosiernomo" fileName: "Dosiernomo"
selectFile: "Elekti dosieron" selectFile: "Elekti dosieron"
@ -240,15 +254,18 @@ addFile: "Aldoni dosieron"
emptyDrive: "La disko malplenas" emptyDrive: "La disko malplenas"
emptyFolder: "La dosierujo malplenas" emptyFolder: "La dosierujo malplenas"
unableToDelete: "Ne forigebla" unableToDelete: "Ne forigebla"
inputNewFileName: "Entajpu nova nomon de la dosiero" inputNewFileName: "Entajpu novan nomon de la dosiero"
inputNewFolderName: "Entajpu nova nomon de la dosierujo" inputNewDescription: "Entajpu novan priskribon"
inputNewFolderName: "Entajpu novan nomon de la dosierujo"
hasChildFilesOrFolders: "La dosierujo ne estas forviŝebla, ĉar ĝi ne malplenas." hasChildFilesOrFolders: "La dosierujo ne estas forviŝebla, ĉar ĝi ne malplenas."
copyUrl: "Kopii URL" copyUrl: "Kopii URL"
rename: "Alinomi" rename: "Alinomi"
avatar: "Ikono" avatar: "Ikono"
banner: "Standardo" banner: "Standardo"
nsfw: "Enhavo ne estas deca por laborejo (NSFW)" nsfw: "Enhavo ne estas deca por laborejo (NSFW)"
disconnectedFromServer: "Malkonektita de servilo"
reload: "Reŝargi" reload: "Reŝargi"
doNothing: "Ignori"
watch: "Observi" watch: "Observi"
unwatch: "Malobservi" unwatch: "Malobservi"
accept: "Permesi" accept: "Permesi"
@ -265,6 +282,7 @@ dayX: "{day}a"
monthX: "La {month}a monato" monthX: "La {month}a monato"
yearX: "La jaro {year}" yearX: "La jaro {year}"
pages: "Paĝoj" pages: "Paĝoj"
integration: "Integri"
connectService: "Konekti" connectService: "Konekti"
disconnectService: "Farkonektiĝi" disconnectService: "Farkonektiĝi"
enableLocalTimeline: "Ebligi lokan templinion" enableLocalTimeline: "Ebligi lokan templinion"
@ -281,6 +299,8 @@ basicInfo: "Baza informo"
pinnedUsers: "Alpinglita uzanto" pinnedUsers: "Alpinglita uzanto"
pinnedPages: "Alpinglitaj paĝoj" pinnedPages: "Alpinglitaj paĝoj"
pinnedNotes: "Alpinglita noto" pinnedNotes: "Alpinglita noto"
hcaptcha: "hCaptcha"
enableHcaptcha: "Ebligi hCaptcha"
hcaptchaSiteKey: "Reteja ŝlosilo" hcaptchaSiteKey: "Reteja ŝlosilo"
hcaptchaSecretKey: "Sekreta ŝlosilo" hcaptchaSecretKey: "Sekreta ŝlosilo"
recaptcha: "reCAPTCHA" recaptcha: "reCAPTCHA"
@ -290,6 +310,7 @@ recaptchaSecretKey: "Sekreta ŝlosilo"
antennas: "Antenoj" antennas: "Antenoj"
manageAntennas: "Administri antenojn" manageAntennas: "Administri antenojn"
name: "Nomo" name: "Nomo"
antennaSource: "Fonto de la anteno"
notifyAntenna: "Oni sciigos novajn notojn" notifyAntenna: "Oni sciigos novajn notojn"
withFileAntenna: "Nur kun aldonaĵo" withFileAntenna: "Nur kun aldonaĵo"
withReplies: "Inkluzive respondoj" withReplies: "Inkluzive respondoj"
@ -311,6 +332,7 @@ userList: "Listoj"
about: "Informoj" about: "Informoj"
aboutMisskey: "Pri Misskey" aboutMisskey: "Pri Misskey"
administrator: "Administranto" administrator: "Administranto"
token: "Ĵetono"
twoStepAuthentication: "Dua-faktora aŭtentiko" twoStepAuthentication: "Dua-faktora aŭtentiko"
moderator: "Kontrolisto" moderator: "Kontrolisto"
nUsersMentioned: "{n} uzanto(j) menciis" nUsersMentioned: "{n} uzanto(j) menciis"
@ -331,6 +353,8 @@ close: "Fermi"
group: "Grupo" group: "Grupo"
groups: "Grupoj" groups: "Grupoj"
createGroup: "Krei grupon" createGroup: "Krei grupon"
ownedGroups: "Administrataj grupoj"
joinedGroups: "La grupoj kiujn la uzanto aliĝis"
invites: "Inviti" invites: "Inviti"
groupName: "Grupa nomo" groupName: "Grupa nomo"
members: "Membroj" members: "Membroj"
@ -390,6 +414,7 @@ showInPage: "Vidi en paĝo"
popout: "Superigi" popout: "Superigi"
volume: "Laŭteco" volume: "Laŭteco"
masterVolume: "Baza laŭteco" masterVolume: "Baza laŭteco"
details: "Detaloj"
chooseEmoji: "Elekti emoĵion" chooseEmoji: "Elekti emoĵion"
recentUsed: "Lastatempaj uzitaj" recentUsed: "Lastatempaj uzitaj"
install: "Instali" install: "Instali"
@ -400,11 +425,13 @@ installedDate: "Dato de instalado"
lastUsedDate: "Lastfoje uzita je" lastUsedDate: "Lastfoje uzita je"
state: "Stato" state: "Stato"
sort: "Ordigado" sort: "Ordigado"
scratchpad: "Malneta redaktilo"
output: "Elmeto" output: "Elmeto"
script: "Skripto" script: "Skripto"
disablePagesScript: "Malebligi AiScripto en la paĝoj" disablePagesScript: "Malebligi AiScripto en la paĝoj"
deleteAllFiles: "Forviŝi ĉiujn dosierojn" deleteAllFiles: "Forviŝi ĉiujn dosierojn"
deleteAllFilesConfirm: "Ĉu vi certas, ke vi volas forviŝi ĉiujn dosierojn?" deleteAllFilesConfirm: "Ĉu vi certas, ke vi volas forviŝi ĉiujn dosierojn?"
removeAllFollowing: "Ĉesi sekvi ĉiujn sekvatojn"
userSuspended: "Ĉi tiu uzanto estas flostigita." userSuspended: "Ĉi tiu uzanto estas flostigita."
userSilenced: "Ĉi tiu uzanto estas mutigita." userSilenced: "Ĉi tiu uzanto estas mutigita."
menu: "Menuo" menu: "Menuo"
@ -512,7 +539,7 @@ editCode: "Redakti kodon"
emailNotification: "Sciigoj per retpoŝto" emailNotification: "Sciigoj per retpoŝto"
inChannelSearch: "Serĉi en kanalo" inChannelSearch: "Serĉi en kanalo"
useReactionPickerForContextMenu: "Malfermi reago-elektilon per dekstro-klaki" useReactionPickerForContextMenu: "Malfermi reago-elektilon per dekstro-klaki"
typingUsers: "{users} nun entajpas…" typingUsers: "{users} nun skribas…"
clear: "Vakigi" clear: "Vakigi"
goBack: "Reiri antaŭ" goBack: "Reiri antaŭ"
addDescription: "Priskribi" addDescription: "Priskribi"
@ -544,12 +571,12 @@ translate: "Traduki"
translatedFrom: "Tradukita el {x}" translatedFrom: "Tradukita el {x}"
controlPanel: "Ŝaltpodio" controlPanel: "Ŝaltpodio"
classic: "Klasika" classic: "Klasika"
_docs: _signup:
continueReading: "Legi plu" emailAddressInfo: "Entajpu vian retpoŝton"
features: "Funkcioj"
admin: "Administro"
_ad: _ad:
back: "Nuligi" back: "Nuligi"
_forgotPassword:
enterEmail: "Entajpu la retpoŝton kiun vi registrigis al via konto. Ligilo por restarigi pasvorton estos sendita al la retpoŝto."
_gallery: _gallery:
liked: "Ŝatitaj notoj" liked: "Ŝatitaj notoj"
like: "Ŝati" like: "Ŝati"
@ -648,7 +675,7 @@ _ago:
secondsAgo: "Antaŭ {n} sekundo(j)" secondsAgo: "Antaŭ {n} sekundo(j)"
minutesAgo: "Antaŭ {n} minutoj" minutesAgo: "Antaŭ {n} minutoj"
hoursAgo: "Antaŭ {n} horo(j)" hoursAgo: "Antaŭ {n} horo(j)"
daysAgo: "Antaŭ {n} tagoj" daysAgo: "Antaŭ {n} tago(j)"
weeksAgo: "Antaŭ {n} semajnoj" weeksAgo: "Antaŭ {n} semajnoj"
monthsAgo: "Antaŭ {n} monatoj" monthsAgo: "Antaŭ {n} monatoj"
yearsAgo: "Antaŭ {n} jaroj" yearsAgo: "Antaŭ {n} jaroj"
@ -702,7 +729,7 @@ _widgets:
timeline: "Templinio" timeline: "Templinio"
clock: "Horloĝo" clock: "Horloĝo"
activity: "Aktiveco" activity: "Aktiveco"
federation: "Kunfederaĵo" federation: "Federaĵo"
slideshow: "Bildoprezento" slideshow: "Bildoprezento"
button: "Butono" button: "Butono"
onlineUsers: "Surkonektita uzanto" onlineUsers: "Surkonektita uzanto"
@ -761,6 +788,8 @@ _timelines:
_rooms: _rooms:
translate: "Movi" translate: "Movi"
chooseImage: "Elekti bildon" chooseImage: "Elekti bildon"
_roomType:
default: "Defaŭlta"
_furnitures: _furnitures:
bed: "Lito" bed: "Lito"
low-table: "Malaltotablo" low-table: "Malaltotablo"
@ -790,10 +819,12 @@ _pages:
featured: "Ravaĵoj" featured: "Ravaĵoj"
contents: "Enhavo" contents: "Enhavo"
content: "Paĝo en bloko" content: "Paĝo en bloko"
title: "Temlinio"
url: "URL de paĝo" url: "URL de paĝo"
alignCenter: "Centrigi" alignCenter: "Centrigi"
chooseBlock: "Aldoni blokon" chooseBlock: "Aldoni blokon"
contentBlocks: "Enhavo" contentBlocks: "Enhavo"
inputBlocks: "Enigo"
blocks: blocks:
text: "Teksto" text: "Teksto"
textarea: "Areo de teksto" textarea: "Areo de teksto"
@ -802,7 +833,11 @@ _pages:
_post: _post:
canvasId: "Kanvasa identigilo" canvasId: "Kanvasa identigilo"
textInput: "Enmeto el teksto" textInput: "Enmeto el teksto"
_textInput:
text: "Titolo"
textareaInput: "Enmeto el teksto en multaj linioj" textareaInput: "Enmeto el teksto en multaj linioj"
_textareaInput:
text: "Titolo"
numberInput: "Nombra enmeto" numberInput: "Nombra enmeto"
_numberInput: _numberInput:
text: "Titolo" text: "Titolo"
@ -810,6 +845,8 @@ _pages:
id: "Kanvasa identigilo" id: "Kanvasa identigilo"
_note: _note:
id: "Identigilo de noto" id: "Identigilo de noto"
_switch:
text: "Titolo"
_counter: _counter:
text: "Titolo" text: "Titolo"
_button: _button:
@ -817,6 +854,8 @@ _pages:
_action: _action:
_pushEvent: _pushEvent:
event: "Nomo de la evento" event: "Nomo de la evento"
_radioButton:
title: "Titolo"
script: script:
categories: categories:
text: "Manipulo de teksto" text: "Manipulo de teksto"
@ -862,6 +901,9 @@ _pages:
stringArray: "List de teksto" stringArray: "List de teksto"
emptySlot: "Malplena junto" emptySlot: "Malplena junto"
argVariables: "Eniga junto" argVariables: "Eniga junto"
_relayStatus:
requesting: "Atendado de aprobon"
accepted: "Konfirmita"
_notification: _notification:
fileUploaded: "La dosiero sukcese alŝutiĝis." fileUploaded: "La dosiero sukcese alŝutiĝis."
youGotMention: "{name} mencis" youGotMention: "{name} mencis"
@ -891,5 +933,5 @@ _deck:
tl: "Templinio" tl: "Templinio"
antenna: "Antenoj" antenna: "Antenoj"
list: "Listoj" list: "Listoj"
mentions: "Al vi" mentions: "Mencioj"
direct: "Rekte" direct: "Rekte"

View file

@ -739,8 +739,6 @@ resolved: "Resuelto"
unresolved: "Sin resolver" unresolved: "Sin resolver"
_accountDelete: _accountDelete:
accountDelete: "Eliminar Cuenta" accountDelete: "Eliminar Cuenta"
_docs:
admin: "Administrar"
_ad: _ad:
back: "Deseleccionar" back: "Deseleccionar"
_gallery: _gallery:

View file

@ -745,10 +745,8 @@ global: "Federata"
sent: "Inviare" sent: "Inviare"
hashtags: "Hashtag" hashtags: "Hashtag"
troubleshooting: "Risoluzione problemi" troubleshooting: "Risoluzione problemi"
_docs: _ffVisibility:
continueReading: "Leggi di più" public: "Pubblico"
features: "Funzionalità"
admin: "Gestione"
_ad: _ad:
back: "Indietro" back: "Indietro"
reduceFrequencyOfThisAd: "Visualizza questa pubblicità meno spesso" reduceFrequencyOfThisAd: "Visualizza questa pubblicità meno spesso"

View file

@ -806,6 +806,8 @@ muteThread: "スレッドをミュート"
unmuteThread: "スレッドのミュートを解除" unmuteThread: "スレッドのミュートを解除"
ffVisibility: "つながりの公開範囲" ffVisibility: "つながりの公開範囲"
ffVisibilityDescription: "自分のフォロー/フォロワー情報の公開範囲を設定できます。" ffVisibilityDescription: "自分のフォロー/フォロワー情報の公開範囲を設定できます。"
continueThread: "さらにスレッドを見る"
deleteAccountConfirm: "アカウントが削除されます。よろしいですか?"
_emailUnavailable: _emailUnavailable:
used: "既に使用されています" used: "既に使用されています"

View file

@ -653,8 +653,6 @@ low: "低い"
global: "グローバル" global: "グローバル"
sent: "送信" sent: "送信"
hashtags: "ハッシュタグ" hashtags: "ハッシュタグ"
_docs:
admin: "管理"
_ad: _ad:
back: "戻る" back: "戻る"
_gallery: _gallery:

View file

@ -788,6 +788,8 @@ lastCommunication: "마지막 통신"
resolved: "해결됨" resolved: "해결됨"
unresolved: "해결되지 않음" unresolved: "해결되지 않음"
controlPanel: "제어판" controlPanel: "제어판"
_ffVisibility:
public: "게시"
_accountDelete: _accountDelete:
accountDelete: "계정 삭제" accountDelete: "계정 삭제"
mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다." mayTakeTime: "계정 삭제는 서버에 부하를 가하기 때문에, 작성한 콘텐츠나 업로드한 파일의 수가 많으면 완료까지 시간이 걸릴 수 있습니다."
@ -795,13 +797,6 @@ _accountDelete:
requestAccountDelete: "계정 삭제 요청" requestAccountDelete: "계정 삭제 요청"
started: "삭제 작업이 시작되었습니다." started: "삭제 작업이 시작되었습니다."
inProgress: "삭제 진행 중" inProgress: "삭제 진행 중"
_docs:
continueReading: "계속 읽기"
features: "기능"
generalTopics: "일반 주제"
advancedTopics: "심화 주제"
admin: "관리"
translateWarn: "이 문서는 번역되었기 때문에 원본과는 내용이 다를 수 있습니다."
_ad: _ad:
back: "뒤로" back: "뒤로"
reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기" reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기"

View file

@ -1,3 +1,5 @@
--- ---
_lang_: "Nederlands" _lang_: "Nederlands"
headlineMisskey: "Netwerk verbonden door notities" headlineMisskey: "Netwerk verbonden door notities"
muteThread: "Discussies dempen "
unmuteThread: "Dempen van discussie ongedaan maken"

View file

@ -738,8 +738,8 @@ ratio: "Stosunek"
global: "Globalna" global: "Globalna"
sent: "Wyślij" sent: "Wyślij"
hashtags: "Hashtag" hashtags: "Hashtag"
_docs: _ffVisibility:
admin: "Zarządzanie" public: "Publikuj"
_ad: _ad:
back: "Wróć" back: "Wróć"
reduceFrequencyOfThisAd: "Pokazuj tę reklamę rzadziej" reduceFrequencyOfThisAd: "Pokazuj tę reklamę rzadziej"

View file

@ -620,6 +620,8 @@ reportAbuse: "Жалоба"
reportAbuseOf: "Пожаловаться на пользователя {name}" reportAbuseOf: "Пожаловаться на пользователя {name}"
fillAbuseReportDescription: "Опишите, пожалуйста, причину жалобы подробнее. Если речь о конкретной заметке, будьте добры приложить ссылку на неё." fillAbuseReportDescription: "Опишите, пожалуйста, причину жалобы подробнее. Если речь о конкретной заметке, будьте добры приложить ссылку на неё."
abuseReported: "Жалоба отправлена. Большое спасибо за информацию." abuseReported: "Жалоба отправлена. Большое спасибо за информацию."
reporteeOrigin: "Куда сообщать"
reporterOrigin: "Сообщено"
send: "Отправить" send: "Отправить"
abuseMarkAsResolved: "Отметить жалобу как решённую" abuseMarkAsResolved: "Отметить жалобу как решённую"
openInNewTab: "Открыть в новой вкладке" openInNewTab: "Открыть в новой вкладке"
@ -766,6 +768,7 @@ middle: "Средне"
low: "Низкий" low: "Низкий"
emailNotConfiguredWarning: "Не указан адрес электронной почты" emailNotConfiguredWarning: "Не указан адрес электронной почты"
ratio: "Соотношение" ratio: "Соотношение"
previewNoteText: "Предварительный просмотр текста"
customCss: "Индивидуальный CSS" customCss: "Индивидуальный CSS"
customCssWarn: "Используйте эту настройку только если знаете, что делаете. Ошибки здесь чреваты тем, что сайт перестанет нормально работать у вас." customCssWarn: "Используйте эту настройку только если знаете, что делаете. Ошибки здесь чреваты тем, что сайт перестанет нормально работать у вас."
global: "Всеобщая" global: "Всеобщая"
@ -780,19 +783,43 @@ learnMore: "Подробнее"
misskeyUpdated: "Misskey обновился!" misskeyUpdated: "Misskey обновился!"
whatIsNew: "Что новенького?" whatIsNew: "Что новенького?"
translate: "Перевод" translate: "Перевод"
translatedFrom: "{x}Перевод с английского"
accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи" accountDeletionInProgress: "В настоящее время выполняется удаление учетной записи"
usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже." usernameInfo: "Имя, которое отличает вашу учетную запись от других на этом сервере. Вы можете использовать алфавит (a~z, A~Z), цифры (0~9) или символы подчеркивания (_). Имена пользователей не могут быть изменены позже."
aiChanMode: "ИИ режим" aiChanMode: "ИИ режим"
keepCw: "Сохраняйте Предупреждения о содержимом" keepCw: "Сохраняйте Предупреждения о содержимом"
lastCommunication: "Последнее сообщение"
resolved: "Решен"
unresolved: "Неразрешенные"
itsOff: "Он выключен!"
emailRequiredForSignup: "Требуется адрес электронной почты для регистрации аккаунта"
unread: "Непрочитанное"
filter: "Фильтры"
controlPanel: "Панель управления" controlPanel: "Панель управления"
manageAccounts: "Управление аккаунтом" manageAccounts: "Управление аккаунтом"
_docs: makeReactionsPublic: "Опубликовать список реакций"
continueReading: "Читать подробнее" makeReactionsPublicDescription: "Список сделанных вами реакций доступен для просмотра всем желающим."
features: "Возможности" classic: "Классика"
generalTopics: "Основные темы" unmuteThread: "Отключить звук"
advancedTopics: "Дополнительные темы" ffVisibilityDescription: "Вы можете установить объем вашей следующей/последней информации."
admin: "Управление" _emailUnavailable:
translateWarn: "Это перевод документа. Он может неточно отражать содержимое оригинала." used: "Уже используется"
format: "Неправильный формат"
smtp: "Почтовый сервер не отвечает"
_ffVisibility:
public: "Опубликовать"
private: "Частный"
_signup:
almostThere: "Почти готово!"
emailAddressInfo: "Пожалуйста, введите адрес электронной почты, который вы используете."
emailSent: "На указанный вами адрес электронной почты ({email}) было отправлено письмо с подтверждением. Перейдите по ссылке в электронном письме, чтобы завершить создание учетной записи."
_accountDelete:
accountDelete: "Удалить свой аккаунт"
mayTakeTime: "Удаление учетной записи - это тяжелый процесс, который может занять много времени, если у вас создано много контента или загружено много файлов."
sendEmail: "Мы отправим уведомление на зарегистрированный вами адрес электронной почты, когда ваша учетная запись будет удалена."
requestAccountDelete: "Запросить удаление вашей учетной записи"
started: "Процесс удаления начался."
inProgress: "Удаление в процессе"
_ad: _ad:
back: "Выход" back: "Выход"
reduceFrequencyOfThisAd: "Реже показывать эту рекламу" reduceFrequencyOfThisAd: "Реже показывать эту рекламу"
@ -893,6 +920,8 @@ _mfm:
fontDescription: "Так можно писать произвольным шрифтом." fontDescription: "Так можно писать произвольным шрифтом."
rainbow: "Радуга" rainbow: "Радуга"
rainbowDescription: "Заставлять содержимое отображаться в цветах радуги." rainbowDescription: "Заставлять содержимое отображаться в цветах радуги."
sparkle: "Блеск"
sparkleDescription: "Добавьте эффект искрящихся частиц."
_reversi: _reversi:
reversi: "Реверси" reversi: "Реверси"
gameSettings: "Настройки игры" gameSettings: "Настройки игры"
@ -1119,6 +1148,10 @@ _permissions:
"write:user-groups": "Изменять и удалять группы пользователей" "write:user-groups": "Изменять и удалять группы пользователей"
"read:channels": "Смотреть каналы" "read:channels": "Смотреть каналы"
"write:channels": "Изменять каналы" "write:channels": "Изменять каналы"
"read:gallery": "Смотреть галерею"
"write:gallery": "Работа с галереей"
"read:gallery-likes": "Посмотреть галерею лайков"
"write:gallery-likes": "Манипулируйте понравившейся галереей"
_auth: _auth:
shareAccess: "Дать доступ для «{name}» к вашей учётной записи?" shareAccess: "Дать доступ для «{name}» к вашей учётной записи?"
shareAccessAsk: "Уверены, что хотите дать приложению доступ к своей учётной записи?" shareAccessAsk: "Уверены, что хотите дать приложению доступ к своей учётной записи?"

View file

@ -692,8 +692,6 @@ middle: "Середній"
global: "Глобальна" global: "Глобальна"
sent: "Відправити" sent: "Відправити"
hashtags: "Хештеґ" hashtags: "Хештеґ"
_docs:
admin: "Управління"
_ad: _ad:
back: "Назад" back: "Назад"
_gallery: _gallery:

View file

@ -1,20 +1,20 @@
--- ---
_lang_: "中文(简体)" _lang_: "中文(简体)"
headlineMisskey: "通过帖子连接在一起的网络" headlineMisskey: "通过帖子连接在一起的网络"
introMisskey: "欢迎Misskey是一个开源的、去中心化的“微博客”服务。\n通过编写「帖」来和大家分享你的以及你周围的事情吧!📡\n通过「回应」功能可以让你快速地对大家的帖表达反馈👍\n来探索新的世界吧🚀" introMisskey: "欢迎Misskey是一个开源的、去中心化的“微博客”服务。\n通过编写「帖」来和大家分享你的以及你周围的事情吧!📡\n通过「回应」功能可以让你快速地对大家的帖表达反馈👍\n来探索新的世界吧🚀"
monthAndDay: "{month}月 {day}日" monthAndDay: "{month}月 {day}日"
search: "搜索" search: "搜索"
notifications: "通知" notifications: "通知"
username: "用户名" username: "用户名"
password: "密码" password: "密码"
forgotPassword: "重置密码" forgotPassword: "忘记密码"
fetchingAsApObject: "联合查询" fetchingAsApObject: "联合查询"
ok: "OK" ok: "OK"
gotIt: "我明白了" gotIt: "我明白了"
cancel: "取消" cancel: "取消"
enterUsername: "输入用户名" enterUsername: "输入用户名"
renotedBy: "{user} 转发了" renotedBy: "由 {user} 转推"
noNotes: "没有帖" noNotes: "没有帖"
noNotifications: "无通知" noNotifications: "无通知"
instance: "实例" instance: "实例"
settings: "设置" settings: "设置"
@ -124,9 +124,9 @@ unblockConfirm: "确定要解除拉黑吗?"
suspendConfirm: "要冻结吗?" suspendConfirm: "要冻结吗?"
unsuspendConfirm: "要解除冻结吗?" unsuspendConfirm: "要解除冻结吗?"
selectList: "选择列表" selectList: "选择列表"
selectAntenna: "天线选择" selectAntenna: "选择天线"
selectWidget: "选择小工具" selectWidget: "选择小工具"
editWidgets: "编辑小工具" editWidgets: "编辑部件"
editWidgetsExit: "完成编辑" editWidgetsExit: "完成编辑"
customEmojis: "自定义表情符号" customEmojis: "自定义表情符号"
emoji: "表情符号" emoji: "表情符号"
@ -139,9 +139,9 @@ cacheRemoteFiles: "远程文件缓存"
cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程实例载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。" cacheRemoteFilesDescription: "当禁用此设定时远程文件将直接从远程实例载入。禁用后会减小储存空间需求,但是会增加流量,因为缩略图不会被生成。"
flagAsBot: "这是一个机器人账号" flagAsBot: "这是一个机器人账号"
flagAsBotDescription: "如果此帐户由程序控制请启用此项。启用后此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为并让Misskey的内部系统将此帐户识别为机器人。" flagAsBotDescription: "如果此帐户由程序控制请启用此项。启用后此标志可以帮助其他开发人员防止机器人之间产生无限互动的行为并让Misskey的内部系统将此帐户识别为机器人。"
flagAsCat: "这个账户是一只猫" flagAsCat: "将这个账户设定为一只猫"
flagAsCatDescription: "如果您想表明此帐户是一只猫,请打开此标志。\n开启后会在您的头像上出现猫耳朵并将你的帖子中的「na」替换为「nya」日文同理。" flagAsCatDescription: "如果您想表明此帐户是一只猫,请打开此标志。"
autoAcceptFollowed: "自动允许关注者的关注" autoAcceptFollowed: "自动允许关注"
addAccount: "添加账户" addAccount: "添加账户"
loginFailed: "登录失败" loginFailed: "登录失败"
showOnRemote: "转到所在实例显示" showOnRemote: "转到所在实例显示"
@ -620,6 +620,8 @@ reportAbuse: "举报"
reportAbuseOf: "举报{name}" reportAbuseOf: "举报{name}"
fillAbuseReportDescription: "请填写举报的详细原因。如果有对方发的帖子请同时填写URL地址。" fillAbuseReportDescription: "请填写举报的详细原因。如果有对方发的帖子请同时填写URL地址。"
abuseReported: "内容已发送。感谢您的报告。" abuseReported: "内容已发送。感谢您的报告。"
reporteeOrigin: "举报来源"
reporterOrigin: "举报者来源"
send: "发送" send: "发送"
abuseMarkAsResolved: "处理完毕" abuseMarkAsResolved: "处理完毕"
openInNewTab: "在新标签页中打开" openInNewTab: "在新标签页中打开"
@ -797,7 +799,25 @@ unread: "未读"
filter: "筛选" filter: "筛选"
controlPanel: "控制面板" controlPanel: "控制面板"
manageAccounts: "管理账户" manageAccounts: "管理账户"
makeReactionsPublic: "将回应设置为公开"
makeReactionsPublicDescription: "将您发表过的回应设置成公开可见。"
classic: "经典" classic: "经典"
muteThread: "屏蔽帖子列表"
unmuteThread: "取消屏蔽帖子列表"
ffVisibility: "连接的可见范围"
ffVisibilityDescription: "您可以设置您的关注/关注者信息的公开范围"
continueThread: "查看更多帖子"
deleteAccountConfirm: "将要删除账户。是否确认?"
_emailUnavailable:
used: "已经被使用过"
format: "无效的格式"
disposable: "不是永久可用的地址"
mx: "邮件服务器不正确"
smtp: "邮件服务器没有响应"
_ffVisibility:
public: "发布"
followers: "只有关注你的用户能看到"
private: "私密"
_signup: _signup:
almostThere: "即将完成" almostThere: "即将完成"
emailAddressInfo: "请输入您所使用的电子邮件地址" emailAddressInfo: "请输入您所使用的电子邮件地址"
@ -809,13 +829,6 @@ _accountDelete:
requestAccountDelete: "请求删除账户" requestAccountDelete: "请求删除账户"
started: "账户删除过程已开始。" started: "账户删除过程已开始。"
inProgress: "正在删除" inProgress: "正在删除"
_docs:
continueReading: "继续阅读"
features: "特性"
generalTopics: "通常提示"
advancedTopics: "进阶提示"
admin: "管理"
translateWarn: "本文档是翻译后的文档。内容可能与原文有所不同。"
_ad: _ad:
back: "返回" back: "返回"
reduceFrequencyOfThisAd: "减少此广告的频率" reduceFrequencyOfThisAd: "减少此广告的频率"

View file

@ -754,8 +754,8 @@ ratio: "%"
global: "公開" global: "公開"
sent: "發送" sent: "發送"
hashtags: "#tag" hashtags: "#tag"
_docs: _ffVisibility:
admin: "管理" public: "發佈"
_ad: _ad:
back: "返回" back: "返回"
reduceFrequencyOfThisAd: "降低此廣告的頻率 " reduceFrequencyOfThisAd: "降低此廣告的頻率 "

View file

@ -17,10 +17,8 @@
"migrate": "cd packages/backend && npx typeorm migration:run", "migrate": "cd packages/backend && npx typeorm migration:run",
"migrateandstart": "npm run migrate && npm run start", "migrateandstart": "npm run migrate && npm run start",
"gulp": "gulp build", "gulp": "gulp build",
"watch": "concurrently \"npm:watch-*\"", "watch": "npm run dev",
"watch-webpack": "webpack --watch", "dev": "node ./scripts/dev.js",
"watch-ts": "tsc -w -p packages/tsconfig.json && tsc-alias -w -p packages/tsconfig.json",
"watch-gulp": "gulp watch",
"lint": "node ./scripts/lint.js", "lint": "node ./scripts/lint.js",
"cy:open": "cypress open", "cy:open": "cypress open",
"cy:run": "cypress run", "cy:run": "cypress run",
@ -40,13 +38,16 @@
"gulp-cssnano": "2.1.3", "gulp-cssnano": "2.1.3",
"gulp-rename": "2.0.0", "gulp-rename": "2.0.0",
"gulp-replace": "1.1.3", "gulp-replace": "1.1.3",
"gulp-terser": "2.1.0" "gulp-terser": "2.1.0",
"js-yaml": "4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@redocly/openapi-core": "1.0.0-beta.54", "@redocly/openapi-core": "1.0.0-beta.54",
"@types/fluent-ffmpeg": "2.1.17", "@types/fluent-ffmpeg": "2.1.17",
"@typescript-eslint/parser": "5.4.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"cypress": "9.0.0", "cypress": "9.0.0",
"start-server-and-test": "1.14.0" "start-server-and-test": "1.14.0",
"typescript": "4.5.2"
} }
} }

View file

@ -1,64 +1,9 @@
module.exports = { module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: { parserOptions: {
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
project: ['./tsconfig.json'], project: ['./tsconfig.json'],
}, },
plugins: [
'@typescript-eslint',
'import'
],
extends: [ extends: [
'eslint:recommended', '../shared/.eslintrc.js',
'plugin:@typescript-eslint/recommended',
'plugin:import/recommended',
'plugin:import/typescript'
], ],
rules: {
'indent': ['warn', 'tab', {
'SwitchCase': 1,
'MemberExpression': 'off',
'flatTernaryExpressions': true,
'ArrayExpression': 'first',
'ObjectExpression': 'first',
}],
'eol-last': ['error', 'always'],
'semi': ['error', 'always'],
'quotes': ['warn', 'single'],
'comma-dangle': ['warn', 'always-multiline'],
'keyword-spacing': ['error', {
'before': true,
'after': true,
}],
/* TODO: path alias使warn
'no-restricted-imports': ['warn', {
'patterns': [
]
}],
*/
'no-multi-spaces': ['error'],
'no-var': ['error'],
'prefer-arrow-callback': ['error'],
'no-throw-literal': ['warn'],
'no-param-reassign': ['warn'],
'no-constant-condition': ['warn'],
'no-empty-pattern': ['warn'],
'no-async-promise-executor': ['off'],
'no-useless-escape': ['off'],
'no-multi-spaces': ['warn'],
'no-control-regex': ['warn'],
'no-empty': ['warn'],
'no-inner-declarations': ['off'],
'no-sparse-arrays': ['off'],
'@typescript-eslint/no-var-requires': ['warn'],
'@typescript-eslint/no-inferrable-types': ['warn'],
'@typescript-eslint/no-empty-function': ['off'],
'@typescript-eslint/no-non-null-assertion': ['off'],
'@typescript-eslint/no-misused-promises': ['error', {
'checksVoidReturn': false,
}],
'import/no-unresolved': ['off'],
'import/no-default-export': ['warn'],
},
}; };

View file

@ -0,0 +1,6 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib",
"path-intellisense.mappings": {
"@": "${workspaceRoot}/packages/backend/src/"
}
}

View file

@ -4,7 +4,7 @@
"scripts": { "scripts": {
"init": "npm run migrate", "init": "npm run migrate",
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json", "build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
"watch": "tsc -w -p tsconfig.json && tsc-alias -w -p tsconfig.json", "watch": "node watch.mjs",
"lint": "eslint --quiet src/**/*.ts", "lint": "eslint --quiet src/**/*.ts",
"mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha", "mocha": "cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
"test": "npm run mocha" "test": "npm run mocha"
@ -179,7 +179,7 @@
"tmp": "0.2.1", "tmp": "0.2.1",
"ts-loader": "9.2.6", "ts-loader": "9.2.6",
"ts-node": "10.4.0", "ts-node": "10.4.0",
"tsc-alias": "1.3.10", "tsc-alias": "1.4.1",
"tsconfig-paths": "3.11.0", "tsconfig-paths": "3.11.0",
"twemoji-parser": "13.1.0", "twemoji-parser": "13.1.0",
"typeorm": "0.2.39", "typeorm": "0.2.39",
@ -194,6 +194,7 @@
"devDependencies": { "devDependencies": {
"@redocly/openapi-core": "1.0.0-beta.54", "@redocly/openapi-core": "1.0.0-beta.54",
"@types/fluent-ffmpeg": "2.1.17", "@types/fluent-ffmpeg": "2.1.17",
"cross-env": "7.0.3" "cross-env": "7.0.3",
"execa": "6.0.0"
} }
} }

View file

@ -82,8 +82,7 @@ export default class Reversi {
//#endregion //#endregion
// ゲームが始まった時点で片方の色の石しかないか、始まった時点で勝敗が決定するようなマップの場合がある // ゲームが始まった時点で片方の色の石しかないか、始まった時点で勝敗が決定するようなマップの場合がある
if (!this.canPutSomewhere(BLACK)) if (!this.canPutSomewhere(BLACK)) this.turn = this.canPutSomewhere(WHITE) ? WHITE : null;
this.turn = this.canPutSomewhere(WHITE) ? WHITE : null;
} }
/** /**
@ -226,11 +225,12 @@ export default class Reversi {
// 座標が指し示す位置がボード外に出たとき // 座標が指し示す位置がボード外に出たとき
if (this.opts.loopedBoard && this.transformXyToPos( if (this.opts.loopedBoard && this.transformXyToPos(
(x = ((x % this.mapWidth) + this.mapWidth) % this.mapWidth), (x = ((x % this.mapWidth) + this.mapWidth) % this.mapWidth),
(y = ((y % this.mapHeight) + this.mapHeight) % this.mapHeight)) === initPos) (y = ((y % this.mapHeight) + this.mapHeight) % this.mapHeight)) === initPos) {
// 盤面の境界でループし、自分が石を置く位置に戻ってきたとき、挟めるようにしている (ref: Test4のマップ) // 盤面の境界でループし、自分が石を置く位置に戻ってきたとき、挟めるようにしている (ref: Test4のマップ)
return found; return found;
else if (x === -1 || y === -1 || x === this.mapWidth || y === this.mapHeight) } else if (x === -1 || y === -1 || x === this.mapWidth || y === this.mapHeight) {
return []; // 挟めないことが確定 (盤面外に到達) return []; // 挟めないことが確定 (盤面外に到達)
}
const pos = this.transformXyToPos(x, y); const pos = this.transformXyToPos(x, y);
if (this.mapDataGet(pos) === 'null') return []; // 挟めないことが確定 (配置不可能なマスに到達) if (this.mapDataGet(pos) === 'null') return []; // 挟めないことが確定 (配置不可能なマスに到達)

View file

@ -54,7 +54,7 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
const queryOrNull = async () => (await Emojis.findOne({ const queryOrNull = async () => (await Emojis.findOne({
name, name,
host host,
})) || null; })) || null;
const emoji = await cache.fetch(`${name} ${host}`, queryOrNull); const emoji = await cache.fetch(`${name} ${host}`, queryOrNull);
@ -62,7 +62,7 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
if (emoji == null) return null; if (emoji == null) return null;
const isLocal = emoji.host == null; const isLocal = emoji.host == null;
const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({url: emoji.url})}`; const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({ url: emoji.url })}`;
return { return {
name: emojiName, name: emojiName,
@ -111,12 +111,12 @@ export async function prefetchEmojis(emojis: { name: string; host: string | null
for (const host of hosts) { for (const host of hosts) {
emojisQuery.push({ emojisQuery.push({
name: In(notCachedEmojis.filter(e => e.host === host).map(e => e.name)), name: In(notCachedEmojis.filter(e => e.host === host).map(e => e.name)),
host: host host: host,
}); });
} }
const _emojis = emojisQuery.length > 0 ? await Emojis.find({ const _emojis = emojisQuery.length > 0 ? await Emojis.find({
where: emojisQuery, where: emojisQuery,
select: ['name', 'host', 'url'] select: ['name', 'host', 'url'],
}) : []; }) : [];
for (const emoji of _emojis) { for (const emoji of _emojis) {
cache.set(`${emoji.name} ${emoji.host}`, emoji); cache.set(`${emoji.name} ${emoji.host}`, emoji);

View file

@ -1,3 +1,4 @@
/* eslint-disable key-spacing */
import { emojiRegex } from './emoji-regex'; import { emojiRegex } from './emoji-regex';
import { fetchMeta } from './fetch-meta'; import { fetchMeta } from './fetch-meta';
import { Emojis } from '@/models/index'; import { Emojis } from '@/models/index';

View file

@ -19,7 +19,7 @@ export function createSignedPost(args: { key: PrivateKey, url: string, body: str
const request: Request = { const request: Request = {
url: u.href, url: u.href,
method: 'POST', method: 'POST',
headers: objectAssignWithLcKey({ headers: objectAssignWithLcKey({
'Date': new Date().toUTCString(), 'Date': new Date().toUTCString(),
'Host': u.hostname, 'Host': u.hostname,
'Content-Type': 'application/activity+json', 'Content-Type': 'application/activity+json',
@ -43,7 +43,7 @@ export function createSignedGet(args: { key: PrivateKey, url: string, additional
const request: Request = { const request: Request = {
url: u.href, url: u.href,
method: 'GET', method: 'GET',
headers: objectAssignWithLcKey({ headers: objectAssignWithLcKey({
'Accept': 'application/activity+json, application/ld+json', 'Accept': 'application/activity+json, application/ld+json',
'Date': new Date().toUTCString(), 'Date': new Date().toUTCString(),
'Host': new URL(args.url).hostname, 'Host': new URL(args.url).hostname,
@ -66,7 +66,7 @@ function signToRequest(request: Request, key: PrivateKey, includeHeaders: string
const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`; const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
request.headers = objectAssignWithLcKey(request.headers, { request.headers = objectAssignWithLcKey(request.headers, {
Signature: signatureHeader Signature: signatureHeader,
}); });
return { return {

File diff suppressed because it is too large Load diff

View file

@ -163,7 +163,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
uri: person.id, uri: person.id,
tags, tags,
isBot, isBot,
isCat: (person as any).isCat === true isCat: (person as any).isCat === true,
})) as IRemoteUser; })) as IRemoteUser;
await transactionalEntityManager.save(new UserProfile({ await transactionalEntityManager.save(new UserProfile({
@ -173,14 +173,14 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
fields, fields,
birthday: bday ? bday[0] : null, birthday: bday ? bday[0] : null,
location: person['vcard:Address'] || null, location: person['vcard:Address'] || null,
userHost: host userHost: host,
})); }));
if (person.publicKey) { if (person.publicKey) {
await transactionalEntityManager.save(new UserPublickey({ await transactionalEntityManager.save(new UserPublickey({
userId: user.id, userId: user.id,
keyId: person.publicKey.id, keyId: person.publicKey.id,
keyPem: person.publicKey.publicKeyPem keyPem: person.publicKey.publicKeyPem,
})); }));
} }
}); });
@ -189,7 +189,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
if (isDuplicateKeyValueError(e)) { if (isDuplicateKeyValueError(e)) {
// /users/@a => /users/:id のように入力がaliasなときにエラーになることがあるのを対応 // /users/@a => /users/:id のように入力がaliasなときにエラーになることがあるのを対応
const u = await Users.findOne({ const u = await Users.findOne({
uri: person.id uri: person.id,
}); });
if (u) { if (u) {
@ -218,11 +218,11 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
//#region アバターとヘッダー画像をフェッチ //#region アバターとヘッダー画像をフェッチ
const [avatar, banner] = await Promise.all([ const [avatar, banner] = await Promise.all([
person.icon, person.icon,
person.image person.image,
].map(img => ].map(img =>
img == null img == null
? Promise.resolve(null) ? Promise.resolve(null)
: resolveImage(user!, img).catch(() => null) : resolveImage(user!, img).catch(() => null),
)); ));
const avatarId = avatar ? avatar.id : null; const avatarId = avatar ? avatar.id : null;
@ -258,7 +258,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
const emojiNames = emojis.map(emoji => emoji.name); const emojiNames = emojis.map(emoji => emoji.name);
await Users.update(user!.id, { await Users.update(user!.id, {
emojis: emojiNames emojis: emojiNames,
}); });
//#endregion //#endregion
@ -301,11 +301,11 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
// アバターとヘッダー画像をフェッチ // アバターとヘッダー画像をフェッチ
const [avatar, banner] = await Promise.all([ const [avatar, banner] = await Promise.all([
person.icon, person.icon,
person.image person.image,
].map(img => ].map(img =>
img == null img == null
? Promise.resolve(null) ? Promise.resolve(null)
: resolveImage(exist, img).catch(() => null) : resolveImage(exist, img).catch(() => null),
)); ));
// カスタム絵文字取得 // カスタム絵文字取得
@ -355,7 +355,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
if (person.publicKey) { if (person.publicKey) {
await UserPublickeys.update({ userId: exist.id }, { await UserPublickeys.update({ userId: exist.id }, {
keyId: person.publicKey.id, keyId: person.publicKey.id,
keyPem: person.publicKey.publicKeyPem keyPem: person.publicKey.publicKeyPem,
}); });
} }
@ -372,9 +372,9 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
// 該当ユーザーが既にフォロワーになっていた場合はFollowingもアップデートする // 該当ユーザーが既にフォロワーになっていた場合はFollowingもアップデートする
await Followings.update({ await Followings.update({
followerId: exist.id followerId: exist.id,
}, { }, {
followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined) followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined),
}); });
await updateFeatured(exist.id).catch(err => logger.error(err)); await updateFeatured(exist.id).catch(err => logger.error(err));
@ -411,8 +411,9 @@ const services: {
}; };
const $discord = (id: string, name: string) => { const $discord = (id: string, name: string) => {
if (typeof name !== 'string') if (typeof name !== 'string') {
name = 'unknown#0000'; name = 'unknown#0000';
}
const [username, discriminator] = name.split('#'); const [username, discriminator] = name.split('#');
return { id, username, discriminator }; return { id, username, discriminator };
}; };
@ -420,13 +421,15 @@ const $discord = (id: string, name: string) => {
function addService(target: { [x: string]: any }, source: IApPropertyValue) { function addService(target: { [x: string]: any }, source: IApPropertyValue) {
const service = services[source.name]; const service = services[source.name];
if (typeof source.value !== 'string') if (typeof source.value !== 'string') {
source.value = 'unknown'; source.value = 'unknown';
}
const [id, username] = source.value.split('@'); const [id, username] = source.value.split('@');
if (service) if (service) {
target[source.name.split(':')[2]] = service(id, username); target[source.name.split(':')[2]] = service(id, username);
}
} }
export function analyzeAttachments(attachments: IObject | IObject[] | undefined) { export function analyzeAttachments(attachments: IObject | IObject[] | undefined) {
@ -443,7 +446,7 @@ export function analyzeAttachments(attachments: IObject | IObject[] | undefined)
} else { } else {
fields.push({ fields.push({
name: attachment.name, name: attachment.name,
value: fromHtml(attachment.value) value: fromHtml(attachment.value),
}); });
} }
} }
@ -487,7 +490,7 @@ export async function updateFeatured(userId: User['id']) {
id: genId(new Date(Date.now() + td)), id: genId(new Date(Date.now() + td)),
createdAt: new Date(), createdAt: new Date(),
userId: user.id, userId: user.id,
noteId: note!.id noteId: note!.id,
}); });
} }
}); });

View file

@ -8,7 +8,7 @@ export default async function renderQuestion(user: { id: User['id'] }, note: Not
type: 'Question', type: 'Question',
id: `${config.url}/questions/${note.id}`, id: `${config.url}/questions/${note.id}`,
actor: `${config.url}/users/${user.id}`, actor: `${config.url}/users/${user.id}`,
content: note.text || '', content: note.text || '',
[poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({ [poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({
name: text, name: text,
_misskey_votes: poll.votes[i], _misskey_votes: poll.votes[i],

View file

@ -6,7 +6,7 @@ const ECC_PRELUDE = Buffer.from([0x04]);
const NULL_BYTE = Buffer.from([0]); const NULL_BYTE = Buffer.from([0]);
const PEM_PRELUDE = Buffer.from( const PEM_PRELUDE = Buffer.from(
'3059301306072a8648ce3d020106082a8648ce3d030107034200', '3059301306072a8648ce3d020106082a8648ce3d030107034200',
'hex' 'hex',
); );
// Android Safetynet attestations are signed with this cert: // Android Safetynet attestations are signed with this cert:
@ -68,7 +68,7 @@ function verifyCertificateChain(certificates: string[]) {
const signatureHex = certificate.getSignatureValueHex(); const signatureHex = certificate.getSignatureValueHex();
// Verify against CA // Verify against CA
const Signature = new jsrsasign.KJUR.crypto.Signature({alg: algorithm}); const Signature = new jsrsasign.KJUR.crypto.Signature({ alg: algorithm });
Signature.init(CACert); Signature.init(CACert);
Signature.updateHex(certStruct); Signature.updateHex(certStruct);
valid = valid && !!Signature.verify(signatureHex); // true if CA signed the certificate valid = valid && !!Signature.verify(signatureHex); // true if CA signed the certificate
@ -134,7 +134,7 @@ export function verifyLogin({
const verificationData = Buffer.concat( const verificationData = Buffer.concat(
[authenticatorData, hash(clientDataJSON)], [authenticatorData, hash(clientDataJSON)],
32 + authenticatorData.length 32 + authenticatorData.length,
); );
return crypto return crypto
@ -145,7 +145,7 @@ export function verifyLogin({
export const procedures = { export const procedures = {
none: { none: {
verify({publicKey}: {publicKey: Map<number, Buffer>}) { verify({ publicKey }: {publicKey: Map<number, Buffer>}) {
const negTwo = publicKey.get(-2); const negTwo = publicKey.get(-2);
if (!negTwo || negTwo.length != 32) { if (!negTwo || negTwo.length != 32) {
@ -158,14 +158,14 @@ export const procedures = {
const publicKeyU2F = Buffer.concat( const publicKeyU2F = Buffer.concat(
[ECC_PRELUDE, negTwo, negThree], [ECC_PRELUDE, negTwo, negThree],
1 + 32 + 32 1 + 32 + 32,
); );
return { return {
publicKey: publicKeyU2F, publicKey: publicKeyU2F,
valid: true valid: true,
}; };
} },
}, },
'android-key': { 'android-key': {
verify({ verify({
@ -174,7 +174,7 @@ export const procedures = {
clientDataHash, clientDataHash,
publicKey, publicKey,
rpIdHash, rpIdHash,
credentialId credentialId,
}: { }: {
attStmt: any, attStmt: any,
authenticatorData: Buffer, authenticatorData: Buffer,
@ -189,7 +189,7 @@ export const procedures = {
const verificationData = Buffer.concat([ const verificationData = Buffer.concat([
authenticatorData, authenticatorData,
clientDataHash clientDataHash,
]); ]);
const attCert: Buffer = attStmt.x5c[0]; const attCert: Buffer = attStmt.x5c[0];
@ -206,7 +206,7 @@ export const procedures = {
const publicKeyData = Buffer.concat( const publicKeyData = Buffer.concat(
[ECC_PRELUDE, negTwo, negThree], [ECC_PRELUDE, negTwo, negThree],
1 + 32 + 32 1 + 32 + 32,
); );
if (!attCert.equals(publicKeyData)) { if (!attCert.equals(publicKeyData)) {
@ -222,9 +222,9 @@ export const procedures = {
return { return {
valid: isValid, valid: isValid,
publicKey: publicKeyData publicKey: publicKeyData,
}; };
} },
}, },
// what a stupid attestation // what a stupid attestation
'android-safetynet': { 'android-safetynet': {
@ -234,7 +234,7 @@ export const procedures = {
clientDataHash, clientDataHash,
publicKey, publicKey,
rpIdHash, rpIdHash,
credentialId credentialId,
}: { }: {
attStmt: any, attStmt: any,
authenticatorData: Buffer, authenticatorData: Buffer,
@ -244,14 +244,14 @@ export const procedures = {
credentialId: Buffer, credentialId: Buffer,
}) { }) {
const verificationData = hash( const verificationData = hash(
Buffer.concat([authenticatorData, clientDataHash]) Buffer.concat([authenticatorData, clientDataHash]),
); );
const jwsParts = attStmt.response.toString('utf-8').split('.'); const jwsParts = attStmt.response.toString('utf-8').split('.');
const header = JSON.parse(base64URLDecode(jwsParts[0]).toString('utf-8')); const header = JSON.parse(base64URLDecode(jwsParts[0]).toString('utf-8'));
const response = JSON.parse( const response = JSON.parse(
base64URLDecode(jwsParts[1]).toString('utf-8') base64URLDecode(jwsParts[1]).toString('utf-8'),
); );
const signature = jwsParts[2]; const signature = jwsParts[2];
@ -273,7 +273,7 @@ export const procedures = {
const signatureBase = Buffer.from( const signatureBase = Buffer.from(
jwsParts[0] + '.' + jwsParts[1], jwsParts[0] + '.' + jwsParts[1],
'utf-8' 'utf-8',
); );
const valid = crypto const valid = crypto
@ -293,13 +293,13 @@ export const procedures = {
const publicKeyData = Buffer.concat( const publicKeyData = Buffer.concat(
[ECC_PRELUDE, negTwo, negThree], [ECC_PRELUDE, negTwo, negThree],
1 + 32 + 32 1 + 32 + 32,
); );
return { return {
valid, valid,
publicKey: publicKeyData publicKey: publicKeyData,
}; };
} },
}, },
packed: { packed: {
verify({ verify({
@ -308,7 +308,7 @@ export const procedures = {
clientDataHash, clientDataHash,
publicKey, publicKey,
rpIdHash, rpIdHash,
credentialId credentialId,
}: { }: {
attStmt: any, attStmt: any,
authenticatorData: Buffer, authenticatorData: Buffer,
@ -319,7 +319,7 @@ export const procedures = {
}) { }) {
const verificationData = Buffer.concat([ const verificationData = Buffer.concat([
authenticatorData, authenticatorData,
clientDataHash clientDataHash,
]); ]);
if (attStmt.x5c) { if (attStmt.x5c) {
@ -342,12 +342,12 @@ export const procedures = {
const publicKeyData = Buffer.concat( const publicKeyData = Buffer.concat(
[ECC_PRELUDE, negTwo, negThree], [ECC_PRELUDE, negTwo, negThree],
1 + 32 + 32 1 + 32 + 32,
); );
return { return {
valid: validSignature, valid: validSignature,
publicKey: publicKeyData publicKey: publicKeyData,
}; };
} else if (attStmt.ecdaaKeyId) { } else if (attStmt.ecdaaKeyId) {
// https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html#ecdaa-verify-operation // https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html#ecdaa-verify-operation
@ -357,7 +357,7 @@ export const procedures = {
throw new Error('self attestation is not supported'); throw new Error('self attestation is not supported');
} }
} },
}, },
'fido-u2f': { 'fido-u2f': {
@ -367,7 +367,7 @@ export const procedures = {
clientDataHash, clientDataHash,
publicKey, publicKey,
rpIdHash, rpIdHash,
credentialId credentialId,
}: { }: {
attStmt: any, attStmt: any,
authenticatorData: Buffer, authenticatorData: Buffer,
@ -397,7 +397,7 @@ export const procedures = {
const publicKeyU2F = Buffer.concat( const publicKeyU2F = Buffer.concat(
[ECC_PRELUDE, negTwo, negThree], [ECC_PRELUDE, negTwo, negThree],
1 + 32 + 32 1 + 32 + 32,
); );
const verificationData = Buffer.concat([ const verificationData = Buffer.concat([
@ -405,7 +405,7 @@ export const procedures = {
rpIdHash, rpIdHash,
clientDataHash, clientDataHash,
credentialId, credentialId,
publicKeyU2F publicKeyU2F,
]); ]);
const validSignature = crypto const validSignature = crypto
@ -415,8 +415,8 @@ export const procedures = {
return { return {
valid: validSignature, valid: validSignature,
publicKey: publicKeyU2F publicKey: publicKeyU2F,
}; };
} },
} },
}; };

View file

@ -244,8 +244,9 @@ export default define(meta, async (ps, user) => {
if (ps.poll) { if (ps.poll) {
if (typeof ps.poll.expiresAt === 'number') { if (typeof ps.poll.expiresAt === 'number') {
if (ps.poll.expiresAt < Date.now()) if (ps.poll.expiresAt < Date.now()) {
throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll);
}
} else if (typeof ps.poll.expiredAfter === 'number') { } else if (typeof ps.poll.expiredAfter === 'number') {
ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
} }

View file

@ -112,8 +112,9 @@ export default define(meta, async (ps, user) => {
if (exist.length) { if (exist.length) {
if (poll.multiple) { if (poll.multiple) {
if (exist.some(x => x.choice == ps.choice)) if (exist.some(x => x.choice == ps.choice)) {
throw new ApiError(meta.errors.alreadyVoted); throw new ApiError(meta.errors.alreadyVoted);
}
} else { } else {
throw new ApiError(meta.errors.alreadyVoted); throw new ApiError(meta.errors.alreadyVoted);
} }

View file

@ -42,7 +42,7 @@ router.get('/disconnect/github', async ctx => {
const user = await Users.findOneOrFail({ const user = await Users.findOneOrFail({
host: null, host: null,
token: userToken token: userToken,
}); });
const profile = await UserProfiles.findOneOrFail(user.id); const profile = await UserProfiles.findOneOrFail(user.id);
@ -58,7 +58,7 @@ router.get('/disconnect/github', async ctx => {
// Publish i updated event // Publish i updated event
publishMainStream(user.id, 'meUpdated', await Users.pack(user, user, { publishMainStream(user.id, 'meUpdated', await Users.pack(user, user, {
detail: true, detail: true,
includeSecrets: true includeSecrets: true,
})); }));
}); });
@ -209,12 +209,13 @@ router.get('/gh/cb', async ctx => {
code, code,
{ redirect_uri }, { redirect_uri },
(err, accessToken, refresh, result) => { (err, accessToken, refresh, result) => {
if (err) if (err) {
rej(err); rej(err);
else if (result.error) } else if (result.error) {
rej(result.error); rej(result.error);
else } else {
res({ accessToken }); res({ accessToken });
}
})); }));
const { login, id } = await getJson('https://api.github.com/user', 'application/vnd.github.v3+json', 10 * 1000, { const { login, id } = await getJson('https://api.github.com/user', 'application/vnd.github.v3+json', 10 * 1000, {

View file

@ -45,8 +45,6 @@
localStorage.setItem('lang', lang); localStorage.setItem('lang', lang);
localStorage.setItem('locale', await res.text()); localStorage.setItem('locale', await res.text());
localStorage.setItem('localeVersion', v); localStorage.setItem('localeVersion', v);
} else if (localeOutdated) {
// nop
} else { } else {
await checkUpdate(); await checkUpdate();
renderError('LOCALE_FETCH_FAILED'); renderError('LOCALE_FETCH_FAILED');

View file

@ -41,8 +41,8 @@ router.get('/.well-known/host-meta', async ctx => {
ctx.set('Content-Type', xrd); ctx.set('Content-Type', xrd);
ctx.body = XRD({ element: 'Link', attributes: { ctx.body = XRD({ element: 'Link', attributes: {
type: xrd, type: xrd,
template: `${config.url}${webFingerPath}?resource={uri}` template: `${config.url}${webFingerPath}?resource={uri}`,
}}); } });
}); });
router.get('/.well-known/host-meta.json', async ctx => { router.get('/.well-known/host-meta.json', async ctx => {
@ -51,8 +51,8 @@ router.get('/.well-known/host-meta.json', async ctx => {
links: [{ links: [{
rel: 'lrdd', rel: 'lrdd',
type: jrd, type: jrd,
template: `${config.url}${webFingerPath}?resource={uri}` template: `${config.url}${webFingerPath}?resource={uri}`,
}] }],
}; };
}); });

View file

@ -0,0 +1,23 @@
import { execa } from 'execa';
(async () => {
// なぜかchokidarが動かない影響で、watchされない
/*
execa('tsc-alias', ['-w', '-p', 'tsconfig.json'], {
stdout: process.stdout,
stderr: process.stderr,
});
*/
setInterval(() => {
execa('tsc-alias', ['-p', 'tsconfig.json'], {
stdout: process.stdout,
stderr: process.stderr,
});
}, 3000);
execa('tsc', ['-w', '-p', 'tsconfig.json'], {
stdout: process.stdout,
stderr: process.stderr,
});
})();

View file

@ -111,22 +111,6 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==
"@jfonx/console-utils@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@jfonx/console-utils/-/console-utils-1.0.3.tgz#cbb7f911e4191a4a2fe1ba4807d29f100b5d099f"
integrity sha512-/XbnqjWc7yNZVLAJJO9rimfIz9DYte+cj3EF9hwhIv7vw6ok2t3cjl0huYsmD89srKH03vWjeqAcIH86CuYj3g==
dependencies:
colors "^1.3.3"
"@jfonx/file-utils@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@jfonx/file-utils/-/file-utils-3.0.1.tgz#8d3d6e931a283420fe29802ea71c28dd397cd8d3"
integrity sha512-qwH0CuzWmghtTHGMyuPHj6SJPQgWeiXFJBfrxCWMbzxVCa3aLZPEfzSdlSnC/UABsk6feRkNdHXw59rVshNPqw==
dependencies:
"@jfonx/console-utils" "^1.0.3"
comment-json "^4.1.0"
find-up "^4.1.0"
"@koa/cors@3.1.0": "@koa/cors@3.1.0":
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.1.0.tgz#618bb073438cfdbd3ebd0e648a76e33b84f3a3b2" resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.1.0.tgz#618bb073438cfdbd3ebd0e648a76e33b84f3a3b2"
@ -1380,11 +1364,6 @@ array-includes@^3.1.4:
get-intrinsic "^1.1.1" get-intrinsic "^1.1.1"
is-string "^1.0.7" is-string "^1.0.7"
array-timsort@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926"
integrity sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==
array-union@^2.1.0: array-union@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
@ -2007,7 +1986,7 @@ cheerio@^0.22.0:
lodash.reject "^4.4.0" lodash.reject "^4.4.0"
lodash.some "^4.4.0" lodash.some "^4.4.0"
chokidar@3.5.1, chokidar@^3.3.1, chokidar@^3.5.0: chokidar@3.5.1, chokidar@^3.3.1, chokidar@^3.5.2:
version "3.3.1" version "3.3.1"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450"
integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==
@ -2166,7 +2145,7 @@ colorette@^1.2.0, colorette@^1.2.1, colorette@^1.2.2:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
colors@^1.1.2, colors@^1.3.3, colors@^1.4.0: colors@^1.1.2, colors@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
@ -2183,26 +2162,15 @@ commander@^2.19.0, commander@^2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
commander@^7.2.0: commander@^7.2.0:
version "7.2.0" version "7.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
comment-json@^4.1.0: commander@^8.2.0:
version "4.1.1" version "8.3.0"
resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.1.1.tgz#49df4948704bebb1cc0ffa6910e25669b668b7c5" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
integrity sha512-v8gmtPvxhBlhdRBLwdHSjGy9BgA23t9H1FctdQKyUrErPjSrJcdDMqBq9B4Irtm7w3TNYLQJNH6ARKnpyag1sA== integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
dependencies:
array-timsort "^1.0.3"
core-util-is "^1.0.2"
esprima "^4.0.1"
has-own-prop "^2.0.0"
repeat-string "^1.6.1"
compare-versions@3.6.0: compare-versions@3.6.0:
version "3.6.0" version "3.6.0"
@ -2305,11 +2273,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
core-util-is@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
crc-32@1.2.0: crc-32@1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
@ -2338,7 +2301,7 @@ cross-env@7.0.3:
dependencies: dependencies:
cross-spawn "^7.0.1" cross-spawn "^7.0.1"
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2: cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@ -3295,6 +3258,21 @@ events@^3.2.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
execa@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-6.0.0.tgz#598b46f09ae44f5d8097a30cfb1681d0f0371503"
integrity sha512-m4wU9j4Z9nXXoqT8RSfl28JSwmMNLFF69OON8H/lL3NeU0tNpGz313bcOfYoBBHokB0dC2tMl3VUcKgHELhL2Q==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.1"
human-signals "^3.0.1"
is-stream "^3.0.0"
merge-stream "^2.0.0"
npm-run-path "^5.0.1"
onetime "^6.0.0"
signal-exit "^3.0.5"
strip-final-newline "^3.0.0"
execa@^4.0.0: execa@^4.0.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
@ -3435,7 +3413,7 @@ fill-range@^7.0.1:
dependencies: dependencies:
to-regex-range "^5.0.1" to-regex-range "^5.0.1"
find-node-modules@^2.1.0: find-node-modules@^2.1.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.2.tgz#57565a3455baf671b835bc6b2134a9b938b9c53c" resolved "https://registry.yarnpkg.com/find-node-modules/-/find-node-modules-2.1.2.tgz#57565a3455baf671b835bc6b2134a9b938b9c53c"
integrity sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug== integrity sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug==
@ -3465,14 +3443,6 @@ find-up@^3.0.0:
dependencies: dependencies:
locate-path "^3.0.0" locate-path "^3.0.0"
find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
dependencies:
locate-path "^5.0.0"
path-exists "^4.0.0"
findup-sync@^4.0.0: findup-sync@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0"
@ -3637,6 +3607,11 @@ get-stream@^5.0.0, get-stream@^5.1.0:
dependencies: dependencies:
pump "^3.0.0" pump "^3.0.0"
get-stream@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
get-symbol-description@^1.0.0: get-symbol-description@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6"
@ -3734,7 +3709,7 @@ globals@^13.9.0:
dependencies: dependencies:
type-fest "^0.20.2" type-fest "^0.20.2"
globby@^11.0.2, globby@^11.0.4: globby@^11.0.4:
version "11.0.4" version "11.0.4"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
@ -3816,11 +3791,6 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-own-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af"
integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==
has-symbols@^1.0.0, has-symbols@^1.0.1: has-symbols@^1.0.0, has-symbols@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
@ -4007,6 +3977,11 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
human-signals@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5"
integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==
humanize-ms@^1.2.1: humanize-ms@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
@ -4425,6 +4400,11 @@ is-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
is-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac"
integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
is-string@^1.0.5, is-string@^1.0.7: is-string@^1.0.5, is-string@^1.0.7:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
@ -5008,13 +4988,6 @@ locate-path@^3.0.0:
p-locate "^3.0.0" p-locate "^3.0.0"
path-exists "^3.0.0" path-exists "^3.0.0"
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
dependencies:
p-locate "^4.1.0"
locate-path@^6.0.0: locate-path@^6.0.0:
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
@ -5266,6 +5239,11 @@ mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
mimic-fn@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc"
integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
mimic-response@^1.0.0: mimic-response@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
@ -5467,6 +5445,11 @@ multer@1.4.3:
type-is "^1.6.4" type-is "^1.6.4"
xtend "^4.0.0" xtend "^4.0.0"
mylas@^2.1.4:
version "2.1.5"
resolved "https://registry.yarnpkg.com/mylas/-/mylas-2.1.5.tgz#7ccf41ec5a93ab2d63fc3678abf1942c0e7bdeb1"
integrity sha512-7ZyrJux1lipSR45IxDvWz7zJOXWTazTFCqD4/p8XBF4O+mtJwf7QpMWTH+jE4lV9O2I38xcpS0KTIp7GwhUTmA==
mz@^2.4.0, mz@^2.7.0: mz@^2.4.0, mz@^2.7.0:
version "2.7.0" version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
@ -5657,6 +5640,13 @@ npm-run-path@^4.0.0:
dependencies: dependencies:
path-key "^3.0.0" path-key "^3.0.0"
npm-run-path@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.0.1.tgz#748dd68ed7de377bb1f7132c7dafe657be5ab400"
integrity sha512-ybBJQUSyFwEEhqO2lXmyKOl9ucHtyZBWVM0h0FiMfT/+WKxCUZFa95qAR2X3w/w6oigN3B0b2UNHZbD+kdfD5w==
dependencies:
path-key "^4.0.0"
npmlog@^4.0.1, npmlog@^4.1.2: npmlog@^4.0.1, npmlog@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
@ -5784,6 +5774,13 @@ onetime@^5.1.0:
dependencies: dependencies:
mimic-fn "^2.1.0" mimic-fn "^2.1.0"
onetime@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4"
integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
dependencies:
mimic-fn "^4.0.0"
only@~0.0.2: only@~0.0.2:
version "0.0.2" version "0.0.2"
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
@ -5877,7 +5874,7 @@ p-limit@^1.1.0:
dependencies: dependencies:
p-try "^1.0.0" p-try "^1.0.0"
p-limit@^2.0.0, p-limit@^2.2.0: p-limit@^2.0.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
@ -5912,13 +5909,6 @@ p-locate@^3.0.0:
dependencies: dependencies:
p-limit "^2.0.0" p-limit "^2.0.0"
p-locate@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
dependencies:
p-limit "^2.2.0"
p-locate@^5.0.0: p-locate@^5.0.0:
version "5.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
@ -6024,6 +6014,11 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-key@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18"
integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
path-parse@^1.0.6: path-parse@^1.0.6:
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
@ -6907,11 +6902,6 @@ rename@1.0.4:
dependencies: dependencies:
debug "^2.5.2" debug "^2.5.2"
repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
request-promise-core@1.1.4: request-promise-core@1.1.4:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f"
@ -7252,6 +7242,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
signal-exit@^3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af"
integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==
simple-concat@^1.0.0: simple-concat@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6"
@ -7572,6 +7567,11 @@ strip-final-newline@^2.0.0:
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
strip-final-newline@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd"
integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
@ -7915,17 +7915,16 @@ ts-node@10.4.0:
make-error "^1.1.1" make-error "^1.1.1"
yn "3.1.1" yn "3.1.1"
tsc-alias@1.3.10: tsc-alias@1.4.1:
version "1.3.10" version "1.4.1"
resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.3.10.tgz#6ccf81c644092387ab9be3a3a75549a95eeffd80" resolved "https://registry.yarnpkg.com/tsc-alias/-/tsc-alias-1.4.1.tgz#6a6075dd94267d9befdad1431f410bd0b8819805"
integrity sha512-7SF56qiV7Oh/bON+XjF/uAzEFqbmwCuEIHQyoTyVJAK80WnxaIyhO9TBwD/x8InIMU8lnvExQBOrgKkRPsHH+w== integrity sha512-nHTR8qvM/LiYI8Fx6UrzAQXRngAuE2PEK+n9uXmQY6fN+oLZhweNFkCLbyxKDmlLfYnclSuaR+dSuvRd7FUu8Q==
dependencies: dependencies:
"@jfonx/console-utils" "^1.0.3" chokidar "^3.5.2"
"@jfonx/file-utils" "^3.0.1" commander "^8.2.0"
chokidar "^3.5.0" find-node-modules "^2.1.2"
commander "^6.2.1" globby "^11.0.4"
find-node-modules "^2.1.0" mylas "^2.1.4"
globby "^11.0.2"
normalize-path "^3.0.0" normalize-path "^3.0.0"
tsconfig-paths@3.11.0, tsconfig-paths@^3.11.0: tsconfig-paths@3.11.0, tsconfig-paths@^3.11.0:

View file

@ -1,32 +0,0 @@
{
"env": {
"node": false
},
"extends": [
"eslint:recommended",
"plugin:vue/recommended"
],
"rules": {
"vue/require-v-for-key": 0,
"vue/max-attributes-per-line": 0,
"vue/html-indent": 0,
"vue/html-self-closing": 0,
"vue/no-unused-vars": 0,
"vue/attributes-order": 0,
"vue/require-prop-types": 0,
"vue/require-default-prop": 0,
"vue/html-closing-bracket-spacing": 0,
"vue/singleline-html-element-content-newline": 0,
"vue/no-v-html": 0
},
"globals": {
"_DEV_": false,
"_LANGS_": false,
"_VERSION_": false,
"_ENV_": false,
"_PERF_PREFIX_": false,
"_DATA_TRANSFER_DRIVE_FILE_": false,
"_DATA_TRANSFER_DRIVE_FOLDER_": false,
"_DATA_TRANSFER_DECK_COLUMN_": false
}
}

View file

@ -0,0 +1,61 @@
module.exports = {
root: true,
env: {
"node": false
},
parser: "vue-eslint-parser",
parserOptions: {
"parser": "@typescript-eslint/parser",
tsconfigRootDir: __dirname,
//project: ['./tsconfig.json'],
},
extends: [
//"../shared/.eslintrc.js",
"plugin:vue/vue3-recommended"
],
rules: {
"vue/attributes-order": ["error", {
"alphabetical": false
}],
"vue/no-use-v-if-with-v-for": ["error", {
"allowUsingIterationVar": false
}],
"vue/no-ref-as-operand": "error",
"vue/no-multi-spaces": ["error", {
"ignoreProperties": false
}],
"vue/no-v-html": "error",
"vue/order-in-components": "error",
"vue/html-indent": ["warn", "tab", {
"attribute": 1,
"baseIndent": 0,
"closeBracket": 0,
"alignAttributesVertically": true,
"ignores": []
}],
"vue/html-closing-bracket-spacing": ["warn", {
"startTag": "never",
"endTag": "never",
"selfClosingTag": "never"
}],
"vue/multi-word-component-names": "warn",
"vue/require-v-for-key": "warn",
"vue/no-unused-components": "warn",
"vue/valid-v-for": "warn",
"vue/return-in-computed-property": "warn",
"vue/max-attributes-per-line": "off",
"vue/html-self-closing": "off",
"vue/singleline-html-element-content-newline": "off",
},
globals: {
"require": false,
"_DEV_": false,
"_LANGS_": false,
"_VERSION_": false,
"_ENV_": false,
"_PERF_PREFIX_": false,
"_DATA_TRANSFER_DRIVE_FILE_": false,
"_DATA_TRANSFER_DRIVE_FOLDER_": false,
"_DATA_TRANSFER_DECK_COLUMN_": false
}
}

11
packages/client/.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib",
"path-intellisense.mappings": {
"@": "${workspaceRoot}/packages/client/src/"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"vue"
]
}

View file

@ -2,7 +2,8 @@
"private": true, "private": true,
"scripts": { "scripts": {
"watch": "webpack --watch", "watch": "webpack --watch",
"build": "webpack" "build": "webpack",
"lint": "eslint --quiet src/**/*.{ts,vue}"
}, },
"resolutions": { "resolutions": {
"chokidar": "^3.3.1", "chokidar": "^3.3.1",
@ -72,7 +73,7 @@
"dateformat": "4.5.1", "dateformat": "4.5.1",
"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.1.1",
"eventemitter3": "4.0.7", "eventemitter3": "4.0.7",
"feed": "4.2.2", "feed": "4.2.2",
"glob": "7.2.0", "glob": "7.2.0",
@ -106,6 +107,7 @@
"punycode": "2.1.1", "punycode": "2.1.1",
"pureimage": "0.3.5", "pureimage": "0.3.5",
"qrcode": "1.4.4", "qrcode": "1.4.4",
"querystring": "0.2.1",
"random-seed": "0.3.0", "random-seed": "0.3.0",
"ratelimiter": "3.4.1", "ratelimiter": "3.4.1",
"reflect-metadata": "0.1.13", "reflect-metadata": "0.1.13",
@ -151,8 +153,10 @@
"devDependencies": { "devDependencies": {
"@redocly/openapi-core": "1.0.0-beta.54", "@redocly/openapi-core": "1.0.0-beta.54",
"@types/fluent-ffmpeg": "2.1.17", "@types/fluent-ffmpeg": "2.1.17",
"@typescript-eslint/eslint-plugin": "5.4.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"cypress": "8.5.0", "cypress": "8.5.0",
"eslint-plugin-import": "2.25.3",
"start-server-and-test": "1.14.0" "start-server-and-test": "1.14.0"
} }
} }

View file

@ -16,7 +16,7 @@
</MkTextarea> </MkTextarea>
</div> </div>
<div class="_section"> <div class="_section">
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $ts.send }}</MkButton> <MkButton primary full :disabled="comment.length === 0" @click="send">{{ $ts.send }}</MkButton>
</div> </div>
</div> </div>
</XWindow> </XWindow>
@ -61,7 +61,7 @@ export default defineComponent({
userId: this.user.id, userId: this.user.id,
comment: this.comment, comment: this.comment,
}, undefined, res => { }, undefined, res => {
os.dialog({ os.alert({
type: 'success', type: 'success',
text: this.$ts.abuseReported text: this.$ts.abuseReported
}); });

View file

@ -1,11 +1,11 @@
<template> <template>
<svg class="mbcofsoe" viewBox="0 0 10 10" preserveAspectRatio="none"> <svg class="mbcofsoe" viewBox="0 0 10 10" preserveAspectRatio="none">
<circle v-for="(angle, i) in graduations" <circle v-for="(angle, i) in graduations"
:key="i"
:cx="5 + (Math.sin(angle) * (5 - graduationsPadding))" :cx="5 + (Math.sin(angle) * (5 - graduationsPadding))"
:cy="5 - (Math.cos(angle) * (5 - graduationsPadding))" :cy="5 - (Math.cos(angle) * (5 - graduationsPadding))"
:r="i % 5 == 0 ? 0.125 : 0.05" :r="i % 5 == 0 ? 0.125 : 0.05"
:fill="i % 5 == 0 ? majorGraduationColor : minorGraduationColor" :fill="i % 5 == 0 ? majorGraduationColor : minorGraduationColor"
:key="i"
/> />
<line <line

View file

@ -1,31 +1,31 @@
<template> <template>
<div class="swhvrteh _popup _shadow" @contextmenu.prevent="() => {}"> <div class="swhvrteh _popup _shadow" @contextmenu.prevent="() => {}">
<ol class="users" ref="suggests" v-if="type === 'user'"> <ol v-if="type === 'user'" ref="suggests" class="users">
<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1" class="user"> <li v-for="user in users" tabindex="-1" class="user" @click="complete(type, user)" @keydown="onKeydown">
<img class="avatar" :src="user.avatarUrl"/> <img class="avatar" :src="user.avatarUrl"/>
<span class="name"> <span class="name">
<MkUserName :user="user" :key="user.id"/> <MkUserName :key="user.id" :user="user"/>
</span> </span>
<span class="username">@{{ acct(user) }}</span> <span class="username">@{{ acct(user) }}</span>
</li> </li>
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $ts.selectUser }}</li> <li tabindex="-1" class="choose" @click="chooseUser()" @keydown="onKeydown">{{ $ts.selectUser }}</li>
</ol> </ol>
<ol class="hashtags" ref="suggests" v-else-if="hashtags.length > 0"> <ol v-else-if="hashtags.length > 0" ref="suggests" class="hashtags">
<li v-for="hashtag in hashtags" @click="complete(type, hashtag)" @keydown="onKeydown" tabindex="-1"> <li v-for="hashtag in hashtags" tabindex="-1" @click="complete(type, hashtag)" @keydown="onKeydown">
<span class="name">{{ hashtag }}</span> <span class="name">{{ hashtag }}</span>
</li> </li>
</ol> </ol>
<ol class="emojis" ref="suggests" v-else-if="emojis.length > 0"> <ol v-else-if="emojis.length > 0" ref="suggests" class="emojis">
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1"> <li v-for="emoji in emojis" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span> <span v-if="emoji.isCustomEmoji" class="emoji"><img :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else-if="!$store.state.useOsNativeEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span> <span v-else-if="!$store.state.useOsNativeEmojis" class="emoji"><img :src="emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else>{{ emoji.emoji }}</span> <span v-else class="emoji">{{ emoji.emoji }}</span>
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span> <span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
<span class="alias" v-if="emoji.aliasOf">({{ emoji.aliasOf }})</span> <span v-if="emoji.aliasOf" class="alias">({{ emoji.aliasOf }})</span>
</li> </li>
</ol> </ol>
<ol class="mfmTags" ref="suggests" v-else-if="mfmTags.length > 0"> <ol v-else-if="mfmTags.length > 0" ref="suggests" class="mfmTags">
<li v-for="tag in mfmTags" @click="complete(type, tag)" @keydown="onKeydown" tabindex="-1"> <li v-for="tag in mfmTags" tabindex="-1" @click="complete(type, tag)" @keydown="onKeydown">
<span class="tag">{{ tag }}</span> <span class="tag">{{ tag }}</span>
</li> </li>
</ol> </ol>

View file

@ -1,8 +1,8 @@
<template> <template>
<button class="hdcaacmi _button" <button class="hdcaacmi _button"
:class="{ wait, active: isFollowing, full }" :class="{ wait, active: isFollowing, full }"
@click="onClick"
:disabled="wait" :disabled="wait"
@click="onClick"
> >
<template v-if="!wait"> <template v-if="!wait">
<template v-if="isFollowing"> <template v-if="isFollowing">

View file

@ -44,6 +44,11 @@ export default defineComponent({
}, },
}, },
data() {
return {
};
},
computed: { computed: {
bannerStyle() { bannerStyle() {
if (this.channel.bannerUrl) { if (this.channel.bannerUrl) {
@ -53,11 +58,6 @@ export default defineComponent({
} }
} }
}, },
data() {
return {
};
},
}); });
</script> </script>

View file

@ -1,6 +1,6 @@
<template> <template>
<code v-if="inline" v-html="html" :class="`language-${prismLang}`"></code> <code v-if="inline" :class="`language-${prismLang}`" v-html="html"></code>
<pre v-else :class="`language-${prismLang}`"><code v-html="html" :class="`language-${prismLang}`"></code></pre> <pre v-else :class="`language-${prismLang}`"><code :class="`language-${prismLang}`" v-html="html"></code></pre>
</template> </template>
<script lang="ts"> <script lang="ts">

View file

@ -31,10 +31,6 @@ export default defineComponent({
}, },
methods: { methods: {
focus() {
this.$slots.default[0].elm.focus();
},
getDateText(time: string) { getDateText(time: string) {
const date = new Date(time).getDate(); const date = new Date(time).getDate();
const month = new Date(time).getMonth() + 1; const month = new Date(time).getMonth() + 1;

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="rbusrurv" :class="{ wide: forceWide }" v-size="{ max: [400] }"> <div v-size="{ max: [400] }" class="rbusrurv" :class="{ wide: forceWide }">
<slot></slot> <slot></slot>
</div> </div>
</template> </template>

View file

@ -1,7 +1,7 @@
<template> <template>
<div class="vrtktovg _debobigegoItem _debobigegoNoConcat" v-size="{ max: [500] }" v-sticky-container> <div v-size="{ max: [500] }" v-sticky-container class="vrtktovg _debobigegoItem _debobigegoNoConcat">
<div class="_debobigegoLabel"><slot name="label"></slot></div> <div class="_debobigegoLabel"><slot name="label"></slot></div>
<div class="main _debobigego_group" ref="child"> <div ref="child" class="main _debobigego_group">
<slot></slot> <slot></slot>
</div> </div>
<div class="_debobigegoCaption"><slot name="caption"></slot></div> <div class="_debobigegoCaption"><slot name="caption"></slot></div>

View file

@ -2,12 +2,12 @@
<FormGroup class="_debobigegoItem"> <FormGroup class="_debobigegoItem">
<template #label><slot></slot></template> <template #label><slot></slot></template>
<div class="ztzhwixg _debobigegoItem" :class="{ inline, disabled }"> <div class="ztzhwixg _debobigegoItem" :class="{ inline, disabled }">
<div class="icon" ref="icon"><slot name="icon"></slot></div> <div ref="icon" class="icon"><slot name="icon"></slot></div>
<div class="input _debobigegoPanel"> <div class="input _debobigegoPanel">
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> <div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
<input ref="inputEl" <input ref="inputEl"
:type="type"
v-model="v" v-model="v"
:type="type"
:disabled="disabled" :disabled="disabled"
:required="required" :required="required"
:readonly="readonly" :readonly="readonly"
@ -16,21 +16,21 @@
:autocomplete="autocomplete" :autocomplete="autocomplete"
:spellcheck="spellcheck" :spellcheck="spellcheck"
:step="step" :step="step"
:list="id"
@focus="focused = true" @focus="focused = true"
@blur="focused = false" @blur="focused = false"
@keydown="onKeydown($event)" @keydown="onKeydown($event)"
@input="onInput" @input="onInput"
:list="id"
> >
<datalist :id="id" v-if="datalist"> <datalist v-if="datalist" :id="id">
<option v-for="data in datalist" :value="data"/> <option v-for="data in datalist" :value="data"/>
</datalist> </datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div> <div ref="suffixEl" class="suffix"><slot name="suffix"></slot></div>
</div> </div>
</div> </div>
<template #caption><slot name="desc"></slot></template> <template #caption><slot name="desc"></slot></template>
<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> <FormButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
</FormGroup> </FormGroup>
</template> </template>

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="qmfkfnzi _debobigegoItem"> <div class="qmfkfnzi _debobigegoItem">
<a class="main _button _debobigegoPanel _debobigegoClickable" :href="to" target="_blank" v-if="external"> <a v-if="external" class="main _button _debobigegoPanel _debobigegoClickable" :href="to" target="_blank">
<span class="icon"><slot name="icon"></slot></span> <span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot></slot></span> <span class="text"><slot></slot></span>
<span class="right"> <span class="right">
@ -8,7 +8,7 @@
<i class="fas fa-external-link-alt icon"></i> <i class="fas fa-external-link-alt icon"></i>
</span> </span>
</a> </a>
<MkA class="main _button _debobigegoPanel _debobigegoClickable" :class="{ active }" :to="to" :behavior="behavior" v-else> <MkA v-else class="main _button _debobigegoPanel _debobigegoClickable" :class="{ active }" :to="to" :behavior="behavior">
<span class="icon"><slot name="icon"></slot></span> <span class="icon"><slot name="icon"></slot></span>
<span class="text"><slot></slot></span> <span class="text"><slot></slot></span>
<span class="right"> <span class="right">

View file

@ -3,8 +3,8 @@
<template #label><slot></slot></template> <template #label><slot></slot></template>
<div class="drooglns _debobigegoItem" :class="{ tall }"> <div class="drooglns _debobigegoItem" :class="{ tall }">
<div class="input _debobigegoPanel"> <div class="input _debobigegoPanel">
<textarea class="_monospace" <textarea v-model="v"
v-model="v" class="_monospace"
readonly readonly
:spellcheck="false" :spellcheck="false"
></textarea> ></textarea>

View file

@ -2,10 +2,10 @@
<FormGroup class="uljviswt _debobigegoItem"> <FormGroup class="uljviswt _debobigegoItem">
<template #label><slot name="label"></slot></template> <template #label><slot name="label"></slot></template>
<slot :items="items"></slot> <slot :items="items"></slot>
<div class="empty" v-if="empty" key="_empty_"> <div v-if="empty" key="_empty_" class="empty">
<slot name="empty"></slot> <slot name="empty"></slot>
</div> </div>
<FormButton v-show="more" class="button" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary> <FormButton v-show="more" class="button" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary @click="fetchMore">
<template v-if="!moreFetching">{{ $ts.loadMore }}</template> <template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template> <template v-if="moreFetching"><MkLoading inline/></template>
</FormButton> </FormButton>

View file

@ -3,9 +3,9 @@
<div class="_debobigegoLabel"><slot name="label"></slot></div> <div class="_debobigegoLabel"><slot name="label"></slot></div>
<div class="_debobigegoPanel main"> <div class="_debobigegoPanel main">
<input <input
type="range"
ref="input" ref="input"
v-model="v" v-model="v"
type="range"
:disabled="disabled" :disabled="disabled"
:min="min" :min="min"
:max="max" :max="max"

View file

@ -1,9 +1,9 @@
<template> <template>
<div class="yrtfrpux _debobigegoItem" :class="{ disabled, inline }"> <div class="yrtfrpux _debobigegoItem" :class="{ disabled, inline }">
<div class="_debobigegoLabel"><slot name="label"></slot></div> <div class="_debobigegoLabel"><slot name="label"></slot></div>
<div class="icon" ref="icon"><slot name="icon"></slot></div> <div ref="icon" class="icon"><slot name="icon"></slot></div>
<div class="input _debobigegoPanel _debobigegoClickable" @click="focus"> <div class="input _debobigegoPanel _debobigegoClickable" @click="focus">
<div class="prefix" ref="prefix"><slot name="prefix"></slot></div> <div ref="prefix" class="prefix"><slot name="prefix"></slot></div>
<select ref="input" <select ref="input"
v-model="v" v-model="v"
:required="required" :required="required"

View file

@ -1,6 +1,6 @@
<template> <template>
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div class="_debobigegoItem" v-if="pending"> <div v-if="pending" class="_debobigegoItem">
<div class="_debobigegoPanel"> <div class="_debobigegoPanel">
<MkLoading/> <MkLoading/>
</div> </div>
@ -8,10 +8,10 @@
<div v-else-if="resolved" class="_debobigegoItem"> <div v-else-if="resolved" class="_debobigegoItem">
<slot :result="result"></slot> <slot :result="result"></slot>
</div> </div>
<div class="_debobigegoItem" v-else> <div v-else class="_debobigegoItem">
<div class="_debobigegoPanel eiurkvay"> <div class="_debobigegoPanel eiurkvay">
<div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div> <div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div>
<MkButton inline @click="retry" class="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton> <MkButton inline class="retry" @click="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton>
</div> </div>
</div> </div>
</transition> </transition>

View file

@ -7,12 +7,12 @@
@click.prevent="toggle" @click.prevent="toggle"
> >
<input <input
type="checkbox"
ref="input" ref="input"
type="checkbox"
:disabled="disabled" :disabled="disabled"
@keydown.enter="toggle" @keydown.enter="toggle"
> >
<span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff"> <span v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button">
<span class="handle"></span> <span class="handle"></span>
</span> </span>
<span class="label"> <span class="label">

View file

@ -3,8 +3,8 @@
<template #label><slot></slot></template> <template #label><slot></slot></template>
<div class="rivhosbp _debobigegoItem" :class="{ tall, pre }"> <div class="rivhosbp _debobigegoItem" :class="{ tall, pre }">
<div class="input _debobigegoPanel"> <div class="input _debobigegoPanel">
<textarea ref="input" :class="{ code, _monospace: code }" <textarea ref="input" v-model="v"
v-model="v" :class="{ code, _monospace: code }"
:required="required" :required="required"
:readonly="readonly" :readonly="readonly"
:pattern="pattern" :pattern="pattern"
@ -18,7 +18,7 @@
</div> </div>
<template #caption><slot name="desc"></slot></template> <template #caption><slot name="desc"></slot></template>
<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton> <FormButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
</FormGroup> </FormGroup>
</template> </template>

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="wthhikgt _debobigegoItem" v-size="{ max: [500] }"> <div v-size="{ max: [500] }" class="wthhikgt _debobigegoItem">
<slot></slot> <slot></slot>
</div> </div>
</template> </template>

View file

@ -1,10 +1,10 @@
<template> <template>
<MkModal ref="modal" @click="done(true)" @closed="$emit('closed')"> <MkModal ref="modal" @click="done(true)" @closed="$emit('closed')">
<div class="mk-dialog"> <div class="mk-dialog">
<div class="icon" v-if="icon"> <div v-if="icon" class="icon">
<i :class="icon"></i> <i :class="icon"></i>
</div> </div>
<div class="icon" v-else-if="!input && !select" :class="type"> <div v-else-if="!input && !select" class="icon" :class="type">
<i v-if="type === 'success'" class="fas fa-check"></i> <i v-if="type === 'success'" class="fas fa-check"></i>
<i v-else-if="type === 'error'" class="fas fa-times-circle"></i> <i v-else-if="type === 'error'" class="fas fa-times-circle"></i>
<i v-else-if="type === 'warning'" class="fas fa-exclamation-triangle"></i> <i v-else-if="type === 'warning'" class="fas fa-exclamation-triangle"></i>
@ -13,7 +13,7 @@
<i v-else-if="type === 'waiting'" class="fas fa-spinner fa-pulse"></i> <i v-else-if="type === 'waiting'" class="fas fa-spinner fa-pulse"></i>
</div> </div>
<header v-if="title"><Mfm :text="title"/></header> <header v-if="title"><Mfm :text="title"/></header>
<div class="body" v-if="text"><Mfm :text="text"/></div> <div v-if="text" class="body"><Mfm :text="text"/></div>
<MkInput v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></MkInput> <MkInput v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder" @keydown="onInputKeydown"></MkInput>
<MkSelect v-if="select" v-model="selectedValue" autofocus> <MkSelect v-if="select" v-model="selectedValue" autofocus>
<template v-if="select.items"> <template v-if="select.items">
@ -25,12 +25,12 @@
</optgroup> </optgroup>
</template> </template>
</MkSelect> </MkSelect>
<div class="buttons" v-if="(showOkButton || showCancelButton) && !actions"> <div v-if="(showOkButton || showCancelButton) && !actions" class="buttons">
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $ts.ok : $ts.gotIt }}</MkButton> <MkButton v-if="showOkButton" inline primary :autofocus="!input && !select" @click="ok">{{ (showCancelButton || input || select) ? $ts.ok : $ts.gotIt }}</MkButton>
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $ts.cancel }}</MkButton> <MkButton v-if="showCancelButton || input || select" inline @click="cancel">{{ $ts.cancel }}</MkButton>
</div> </div>
<div class="buttons" v-if="actions"> <div v-if="actions" class="buttons">
<MkButton v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</MkButton> <MkButton v-for="action in actions" :key="action.text" inline :primary="action.primary" @click="() => { action.callback(); close(); }">{{ action.text }}</MkButton>
</div> </div>
</div> </div>
</MkModal> </MkModal>

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="zdjebgpv" ref="thumbnail"> <div ref="thumbnail" class="zdjebgpv">
<ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.name" :title="file.name" :style="`object-fit: ${ fit }`"/> <ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.name" :title="file.name" :style="`object-fit: ${ fit }`"/>
<i v-else-if="is === 'image'" class="fas fa-file-image icon"></i> <i v-else-if="is === 'image'" class="fas fa-file-image icon"></i>
<i v-else-if="is === 'video'" class="fas fa-file-video icon"></i> <i v-else-if="is === 'video'" class="fas fa-file-video icon"></i>

View file

@ -13,7 +13,7 @@
{{ multiple ? ((type === 'file') ? $ts.selectFiles : $ts.selectFolders) : ((type === 'file') ? $ts.selectFile : $ts.selectFolder) }} {{ multiple ? ((type === 'file') ? $ts.selectFiles : $ts.selectFolders) : ((type === 'file') ? $ts.selectFile : $ts.selectFolder) }}
<span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ number(selected.length) }})</span> <span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ number(selected.length) }})</span>
</template> </template>
<XDrive :multiple="multiple" @changeSelection="onChangeSelection" @selected="ok()" :select="type"/> <XDrive :multiple="multiple" :select="type" @changeSelection="onChangeSelection" @selected="ok()"/>
</XModalWindow> </XModalWindow>
</template> </template>

View file

@ -1,22 +1,22 @@
<template> <template>
<div class="ncvczrfv" <div class="ncvczrfv"
:class="{ isSelected }" :class="{ isSelected }"
draggable="true"
:title="title"
@click="onClick" @click="onClick"
@contextmenu.stop="onContextmenu" @contextmenu.stop="onContextmenu"
draggable="true"
@dragstart="onDragstart" @dragstart="onDragstart"
@dragend="onDragend" @dragend="onDragend"
:title="title"
> >
<div class="label" v-if="$i.avatarId == file.id"> <div v-if="$i.avatarId == file.id" class="label">
<img src="/client-assets/label.svg"/> <img src="/client-assets/label.svg"/>
<p>{{ $ts.avatar }}</p> <p>{{ $ts.avatar }}</p>
</div> </div>
<div class="label" v-if="$i.bannerId == file.id"> <div v-if="$i.bannerId == file.id" class="label">
<img src="/client-assets/label.svg"/> <img src="/client-assets/label.svg"/>
<p>{{ $ts.banner }}</p> <p>{{ $ts.banner }}</p>
</div> </div>
<div class="label red" v-if="file.isSensitive"> <div v-if="file.isSensitive" class="label red">
<img src="/client-assets/label-red.svg"/> <img src="/client-assets/label-red.svg"/>
<p>{{ $ts.nsfw }}</p> <p>{{ $ts.nsfw }}</p>
</div> </div>
@ -25,7 +25,7 @@
<p class="name"> <p class="name">
<span>{{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }}</span> <span>{{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }}</span>
<span class="ext" v-if="file.name.lastIndexOf('.') != -1">{{ file.name.substr(file.name.lastIndexOf('.')) }}</span> <span v-if="file.name.lastIndexOf('.') != -1" class="ext">{{ file.name.substr(file.name.lastIndexOf('.')) }}</span>
</p> </p>
</div> </div>
</template> </template>
@ -138,13 +138,11 @@ export default defineComponent({
}, },
rename() { rename() {
os.dialog({ os.inputText({
title: this.$ts.renameFile, title: this.$ts.renameFile,
input: { placeholder: this.$ts.inputNewFileName,
placeholder: this.$ts.inputNewFileName, default: this.file.name,
default: this.file.name, allowEmpty: false
allowEmpty: false
}
}).then(({ canceled, result: name }) => { }).then(({ canceled, result: name }) => {
if (canceled) return; if (canceled) return;
os.api('drive/files/update', { os.api('drive/files/update', {
@ -191,10 +189,9 @@ export default defineComponent({
}, },
async deleteFile() { async deleteFile() {
const { canceled } = await os.dialog({ const { canceled } = await os.confirm({
type: 'warning', type: 'warning',
text: this.$t('driveFileDeleteConfirm', { name: this.file.name }), text: this.$t('driveFileDeleteConfirm', { name: this.file.name }),
showCancelButton: true
}); });
if (canceled) return; if (canceled) return;

View file

@ -1,6 +1,8 @@
<template> <template>
<div class="rghtznwe" <div class="rghtznwe"
:class="{ draghover }" :class="{ draghover }"
draggable="true"
:title="title"
@click="onClick" @click="onClick"
@contextmenu.stop="onContextmenu" @contextmenu.stop="onContextmenu"
@mouseover="onMouseover" @mouseover="onMouseover"
@ -9,17 +11,15 @@
@dragenter.prevent="onDragenter" @dragenter.prevent="onDragenter"
@dragleave="onDragleave" @dragleave="onDragleave"
@drop.prevent.stop="onDrop" @drop.prevent.stop="onDrop"
draggable="true"
@dragstart="onDragstart" @dragstart="onDragstart"
@dragend="onDragend" @dragend="onDragend"
:title="title"
> >
<p class="name"> <p class="name">
<template v-if="hover"><i class="fas fa-folder-open fa-fw"></i></template> <template v-if="hover"><i class="fas fa-folder-open fa-fw"></i></template>
<template v-if="!hover"><i class="fas fa-folder fa-fw"></i></template> <template v-if="!hover"><i class="fas fa-folder fa-fw"></i></template>
{{ folder.name }} {{ folder.name }}
</p> </p>
<p class="upload" v-if="$store.state.uploadFolder == folder.id"> <p v-if="$store.state.uploadFolder == folder.id" class="upload">
{{ $ts.uploadFolder }} {{ $ts.uploadFolder }}
</p> </p>
<button v-if="selectMode" class="checkbox _button" :class="{ checked: isSelected }" @click.prevent.stop="checkboxClicked"></button> <button v-if="selectMode" class="checkbox _button" :class="{ checked: isSelected }" @click.prevent.stop="checkboxClicked"></button>
@ -151,13 +151,13 @@ export default defineComponent({
}).catch(err => { }).catch(err => {
switch (err) { switch (err) {
case 'detected-circular-definition': case 'detected-circular-definition':
os.dialog({ os.alert({
title: this.$ts.unableToProcess, title: this.$ts.unableToProcess,
text: this.$ts.circularReferenceFolder text: this.$ts.circularReferenceFolder
}); });
break; break;
default: default:
os.dialog({ os.alert({
type: 'error', type: 'error',
text: this.$ts.somethingHappened text: this.$ts.somethingHappened
}); });
@ -191,12 +191,10 @@ export default defineComponent({
}, },
rename() { rename() {
os.dialog({ os.inputText({
title: this.$ts.renameFolder, title: this.$ts.renameFolder,
input: { placeholder: this.$ts.inputNewFolderName,
placeholder: this.$ts.inputNewFolderName, default: this.folder.name
default: this.folder.name
}
}).then(({ canceled, result: name }) => { }).then(({ canceled, result: name }) => {
if (canceled) return; if (canceled) return;
os.api('drive/folders/update', { os.api('drive/folders/update', {
@ -216,14 +214,14 @@ export default defineComponent({
}).catch(err => { }).catch(err => {
switch(err.id) { switch(err.id) {
case 'b0fc8a17-963c-405d-bfbc-859a487295e1': case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
os.dialog({ os.alert({
type: 'error', type: 'error',
title: this.$ts.unableToDelete, title: this.$ts.unableToDelete,
text: this.$ts.hasChildFilesOrFolders text: this.$ts.hasChildFilesOrFolders
}); });
break; break;
default: default:
os.dialog({ os.alert({
type: 'error', type: 'error',
text: this.$ts.unableToDelete text: this.$ts.unableToDelete
}); });

View file

@ -7,33 +7,33 @@
<span class="separator"><i class="fas fa-angle-right"></i></span> <span class="separator"><i class="fas fa-angle-right"></i></span>
<XNavFolder :folder="f"/> <XNavFolder :folder="f"/>
</template> </template>
<span class="separator" v-if="folder != null"><i class="fas fa-angle-right"></i></span> <span v-if="folder != null" class="separator"><i class="fas fa-angle-right"></i></span>
<span class="folder current" v-if="folder != null">{{ folder.name }}</span> <span v-if="folder != null" class="folder current">{{ folder.name }}</span>
</div> </div>
<button @click="showMenu" class="menu _button"><i class="fas fa-ellipsis-h"></i></button> <button class="menu _button" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
</nav> </nav>
<div class="main" :class="{ uploading: uploadings.length > 0, fetching }" <div ref="main" class="main"
ref="main" :class="{ uploading: uploadings.length > 0, fetching }"
@dragover.prevent.stop="onDragover" @dragover.prevent.stop="onDragover"
@dragenter="onDragenter" @dragenter="onDragenter"
@dragleave="onDragleave" @dragleave="onDragleave"
@drop.prevent.stop="onDrop" @drop.prevent.stop="onDrop"
@contextmenu.stop="onContextmenu" @contextmenu.stop="onContextmenu"
> >
<div class="contents" ref="contents"> <div ref="contents" class="contents">
<div class="folders" ref="foldersContainer" v-show="folders.length > 0"> <div v-show="folders.length > 0" ref="foldersContainer" class="folders">
<XFolder v-for="(f, i) in folders" :key="f.id" class="folder" :folder="f" :select-mode="select === 'folder'" :is-selected="selectedFolders.some(x => x.id === f.id)" @chosen="chooseFolder" v-anim="i"/> <XFolder v-for="(f, i) in folders" :key="f.id" v-anim="i" class="folder" :folder="f" :select-mode="select === 'folder'" :is-selected="selectedFolders.some(x => x.id === f.id)" @chosen="chooseFolder"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid --> <!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="(n, i) in 16" :key="i"></div> <div v-for="(n, i) in 16" :key="i" class="padding"></div>
<MkButton ref="moreFolders" v-if="moreFolders">{{ $ts.loadMore }}</MkButton> <MkButton v-if="moreFolders" ref="moreFolders">{{ $ts.loadMore }}</MkButton>
</div> </div>
<div class="files" ref="filesContainer" v-show="files.length > 0"> <div v-show="files.length > 0" ref="filesContainer" class="files">
<XFile v-for="(file, i) in files" :key="file.id" class="file" :file="file" :select-mode="select === 'file'" :is-selected="selectedFiles.some(x => x.id === file.id)" @chosen="chooseFile" v-anim="i"/> <XFile v-for="(file, i) in files" :key="file.id" v-anim="i" class="file" :file="file" :select-mode="select === 'file'" :is-selected="selectedFiles.some(x => x.id === file.id)" @chosen="chooseFile"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid --> <!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="(n, i) in 16" :key="i"></div> <div v-for="(n, i) in 16" :key="i" class="padding"></div>
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $ts.loadMore }}</MkButton> <MkButton v-show="moreFiles" ref="loadMoreFiles" @click="fetchMoreFiles">{{ $ts.loadMore }}</MkButton>
</div> </div>
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching"> <div v-if="files.length == 0 && folders.length == 0 && !fetching" class="empty">
<p v-if="draghover">{{ $t('empty-draghover') }}</p> <p v-if="draghover">{{ $t('empty-draghover') }}</p>
<p v-if="!draghover && folder == null"><strong>{{ $ts.emptyDrive }}</strong><br/>{{ $t('empty-drive-description') }}</p> <p v-if="!draghover && folder == null"><strong>{{ $ts.emptyDrive }}</strong><br/>{{ $t('empty-drive-description') }}</p>
<p v-if="!draghover && folder != null">{{ $ts.emptyFolder }}</p> <p v-if="!draghover && folder != null">{{ $ts.emptyFolder }}</p>
@ -41,7 +41,7 @@
</div> </div>
<MkLoading v-if="fetching"/> <MkLoading v-if="fetching"/>
</div> </div>
<div class="dropzone" v-if="draghover"></div> <div v-if="draghover" class="dropzone"></div>
<input ref="fileInput" type="file" accept="*/*" multiple="multiple" tabindex="-1" @change="onChangeFileInput"/> <input ref="fileInput" type="file" accept="*/*" multiple="multiple" tabindex="-1" @change="onChangeFileInput"/>
</div> </div>
</template> </template>
@ -274,13 +274,13 @@ export default defineComponent({
}).catch(err => { }).catch(err => {
switch (err) { switch (err) {
case 'detected-circular-definition': case 'detected-circular-definition':
os.dialog({ os.alert({
title: this.$ts.unableToProcess, title: this.$ts.unableToProcess,
text: this.$ts.circularReferenceFolder text: this.$ts.circularReferenceFolder
}); });
break; break;
default: default:
os.dialog({ os.alert({
type: 'error', type: 'error',
text: this.$ts.somethingHappened text: this.$ts.somethingHappened
}); });
@ -295,11 +295,10 @@ export default defineComponent({
}, },
urlUpload() { urlUpload() {
os.dialog({ os.inputText({
title: this.$ts.uploadFromUrl, title: this.$ts.uploadFromUrl,
input: { type: 'url',
placeholder: this.$ts.uploadFromUrlDescription placeholder: this.$ts.uploadFromUrlDescription
}
}).then(({ canceled, result: url }) => { }).then(({ canceled, result: url }) => {
if (canceled) return; if (canceled) return;
os.api('drive/files/upload-from-url', { os.api('drive/files/upload-from-url', {
@ -307,7 +306,7 @@ export default defineComponent({
folderId: this.folder ? this.folder.id : undefined folderId: this.folder ? this.folder.id : undefined
}); });
os.dialog({ os.alert({
title: this.$ts.uploadFromUrlRequested, title: this.$ts.uploadFromUrlRequested,
text: this.$ts.uploadFromUrlMayTakeTime text: this.$ts.uploadFromUrlMayTakeTime
}); });
@ -315,11 +314,9 @@ export default defineComponent({
}, },
createFolder() { createFolder() {
os.dialog({ os.inputText({
title: this.$ts.createFolder, title: this.$ts.createFolder,
input: { placeholder: this.$ts.folderName
placeholder: this.$ts.folderName
}
}).then(({ canceled, result: name }) => { }).then(({ canceled, result: name }) => {
if (canceled) return; if (canceled) return;
os.api('drive/folders/create', { os.api('drive/folders/create', {
@ -332,12 +329,10 @@ export default defineComponent({
}, },
renameFolder(folder) { renameFolder(folder) {
os.dialog({ os.inputText({
title: this.$ts.renameFolder, title: this.$ts.renameFolder,
input: { placeholder: this.$ts.inputNewFolderName,
placeholder: this.$ts.inputNewFolderName, default: folder.name
default: folder.name
}
}).then(({ canceled, result: name }) => { }).then(({ canceled, result: name }) => {
if (canceled) return; if (canceled) return;
os.api('drive/folders/update', { os.api('drive/folders/update', {
@ -359,14 +354,14 @@ export default defineComponent({
}).catch(err => { }).catch(err => {
switch(err.id) { switch(err.id) {
case 'b0fc8a17-963c-405d-bfbc-859a487295e1': case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
os.dialog({ os.alert({
type: 'error', type: 'error',
title: this.$ts.unableToDelete, title: this.$ts.unableToDelete,
text: this.$ts.hasChildFilesOrFolders text: this.$ts.hasChildFilesOrFolders
}); });
break; break;
default: default:
os.dialog({ os.alert({
type: 'error', type: 'error',
text: this.$ts.unableToDelete text: this.$ts.unableToDelete
}); });

View file

@ -1,6 +1,6 @@
<template> <template>
<MkPopup ref="popup" :manual-showing="manualShowing" :src="src" :front="true" @click="$refs.popup.close()" @opening="opening" @close="$emit('close')" @closed="$emit('closed')" #default="{point}"> <MkPopup ref="popup" #default="{point}" :manual-showing="manualShowing" :src="src" :front="true" @click="$refs.popup.close()" @opening="opening" @close="$emit('close')" @closed="$emit('closed')">
<MkEmojiPicker class="ryghynhb _popup _shadow" :class="{ pointer: point === 'top' }" :show-pinned="showPinned" :as-reaction-picker="asReactionPicker" @chosen="chosen" ref="picker"/> <MkEmojiPicker ref="picker" class="ryghynhb _popup _shadow" :class="{ pointer: point === 'top' }" :show-pinned="showPinned" :as-reaction-picker="asReactionPicker" @chosen="chosen"/>
</MkPopup> </MkPopup>
</template> </template>

View file

@ -5,9 +5,9 @@
</header> </header>
<div v-if="shown"> <div v-if="shown">
<button v-for="emoji in emojis" <button v-for="emoji in emojis"
:key="emoji"
class="_button" class="_button"
@click="chosen(emoji, $event)" @click="chosen(emoji, $event)"
:key="emoji"
> >
<MkEmoji :emoji="emoji" :normal="true"/> <MkEmoji :emoji="emoji" :normal="true"/>
</button> </button>

View file

@ -1,15 +1,15 @@
<template> <template>
<div class="omfetrab" :class="['w' + width, 'h' + height, { big }]"> <div class="omfetrab" :class="['w' + width, 'h' + height, { big }]">
<input ref="search" class="search" data-prevent-emoji-insert :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$ts.search" @paste.stop="paste" @keyup.enter="done()"> <input ref="search" v-model.trim="q" class="search" data-prevent-emoji-insert :class="{ filled: q != null && q != '' }" :placeholder="$ts.search" @paste.stop="paste" @keyup.enter="done()">
<div class="emojis" ref="emojis"> <div ref="emojis" class="emojis">
<section class="result"> <section class="result">
<div v-if="searchResultCustom.length > 0"> <div v-if="searchResultCustom.length > 0">
<button v-for="emoji in searchResultCustom" <button v-for="emoji in searchResultCustom"
:key="emoji"
class="_button" class="_button"
:title="emoji.name" :title="emoji.name"
@click="chosen(emoji, $event)"
:key="emoji"
tabindex="0" tabindex="0"
@click="chosen(emoji, $event)"
> >
<MkEmoji v-if="emoji.char != null" :emoji="emoji.char"/> <MkEmoji v-if="emoji.char != null" :emoji="emoji.char"/>
<img v-else :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/> <img v-else :src="$store.state.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url"/>
@ -17,25 +17,25 @@
</div> </div>
<div v-if="searchResultUnicode.length > 0"> <div v-if="searchResultUnicode.length > 0">
<button v-for="emoji in searchResultUnicode" <button v-for="emoji in searchResultUnicode"
:key="emoji.name"
class="_button" class="_button"
:title="emoji.name" :title="emoji.name"
@click="chosen(emoji, $event)"
:key="emoji.name"
tabindex="0" tabindex="0"
@click="chosen(emoji, $event)"
> >
<MkEmoji :emoji="emoji.char"/> <MkEmoji :emoji="emoji.char"/>
</button> </button>
</div> </div>
</section> </section>
<div class="index" v-if="tab === 'index'"> <div v-if="tab === 'index'" class="index">
<section v-if="showPinned"> <section v-if="showPinned">
<div> <div>
<button v-for="emoji in pinned" <button v-for="emoji in pinned"
class="_button"
@click="chosen(emoji, $event)"
tabindex="0"
:key="emoji" :key="emoji"
class="_button"
tabindex="0"
@click="chosen(emoji, $event)"
> >
<MkEmoji :emoji="emoji" :normal="true"/> <MkEmoji :emoji="emoji" :normal="true"/>
</button> </button>
@ -46,9 +46,9 @@
<header class="_acrylic"><i class="far fa-clock fa-fw"></i> {{ $ts.recentUsed }}</header> <header class="_acrylic"><i class="far fa-clock fa-fw"></i> {{ $ts.recentUsed }}</header>
<div> <div>
<button v-for="emoji in $store.state.recentlyUsedEmojis" <button v-for="emoji in $store.state.recentlyUsedEmojis"
:key="emoji"
class="_button" class="_button"
@click="chosen(emoji, $event)" @click="chosen(emoji, $event)"
:key="emoji"
> >
<MkEmoji :emoji="emoji" :normal="true"/> <MkEmoji :emoji="emoji" :normal="true"/>
</button> </button>

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="xfbouadm" v-if="meta" :style="{ backgroundImage: `url(${ meta.backgroundImageUrl })` }"></div> <div v-if="meta" class="xfbouadm" :style="{ backgroundImage: `url(${ meta.backgroundImageUrl })` }"></div>
</template> </template>
<script lang="ts"> <script lang="ts">

View file

@ -1,8 +1,8 @@
<template> <template>
<button class="kpoogebi _button" <button class="kpoogebi _button"
:class="{ wait, active: isFollowing || hasPendingFollowRequestFromYou, full, large }" :class="{ wait, active: isFollowing || hasPendingFollowRequestFromYou, full, large }"
@click="onClick"
:disabled="wait" :disabled="wait"
@click="onClick"
> >
<template v-if="!wait"> <template v-if="!wait">
<template v-if="hasPendingFollowRequestFromYou && user.isLocked"> <template v-if="hasPendingFollowRequestFromYou && user.isLocked">
@ -94,10 +94,9 @@ export default defineComponent({
try { try {
if (this.isFollowing) { if (this.isFollowing) {
const { canceled } = await os.dialog({ const { canceled } = await os.confirm({
type: 'warning', type: 'warning',
text: this.$t('unfollowConfirm', { name: this.user.name || this.user.username }), text: this.$t('unfollowConfirm', { name: this.user.name || this.user.username }),
showCancelButton: true
}); });
if (canceled) return; if (canceled) return;

View file

@ -7,14 +7,14 @@
> >
<template #header>{{ $ts.forgotPassword }}</template> <template #header>{{ $ts.forgotPassword }}</template>
<form class="bafeceda" @submit.prevent="onSubmit" v-if="$instance.enableEmail"> <form v-if="$instance.enableEmail" class="bafeceda" @submit.prevent="onSubmit">
<div class="main _formRoot"> <div class="main _formRoot">
<MkInput class="_formBlock" v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required> <MkInput v-model="username" class="_formBlock" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required>
<template #label>{{ $ts.username }}</template> <template #label>{{ $ts.username }}</template>
<template #prefix>@</template> <template #prefix>@</template>
</MkInput> </MkInput>
<MkInput class="_formBlock" v-model="email" type="email" spellcheck="false" required> <MkInput v-model="email" class="_formBlock" type="email" spellcheck="false" required>
<template #label>{{ $ts.emailAddress }}</template> <template #label>{{ $ts.emailAddress }}</template>
<template #caption>{{ $ts._forgotPassword.enterEmail }}</template> <template #caption>{{ $ts._forgotPassword.enterEmail }}</template>
</MkInput> </MkInput>

View file

@ -32,11 +32,11 @@
</FormSwitch> </FormSwitch>
<FormSelect v-else-if="form[item].type === 'enum'" v-model="values[item]"> <FormSelect v-else-if="form[item].type === 'enum'" v-model="values[item]">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option> <option v-for="item in form[item].enum" :key="item.value" :value="item.value">{{ item.label }}</option>
</FormSelect> </FormSelect>
<FormRadios v-else-if="form[item].type === 'radio'" v-model="values[item]"> <FormRadios v-else-if="form[item].type === 'radio'" v-model="values[item]">
<template #desc><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template #desc><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<option v-for="item in form[item].options" :value="item.value" :key="item.value">{{ item.label }}</option> <option v-for="item in form[item].options" :key="item.value" :value="item.value">{{ item.label }}</option>
</FormRadios> </FormRadios>
<FormRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step"> <FormRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>

View file

@ -2,10 +2,10 @@
<div class="matxzzsk"> <div class="matxzzsk">
<div class="label" @click="focus"><slot name="label"></slot></div> <div class="label" @click="focus"><slot name="label"></slot></div>
<div class="input" :class="{ inline, disabled, focused }"> <div class="input" :class="{ inline, disabled, focused }">
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> <div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
<input ref="inputEl" <input ref="inputEl"
:type="type"
v-model="v" v-model="v"
:type="type"
:disabled="disabled" :disabled="disabled"
:required="required" :required="required"
:readonly="readonly" :readonly="readonly"
@ -14,20 +14,20 @@
:autocomplete="autocomplete" :autocomplete="autocomplete"
:spellcheck="spellcheck" :spellcheck="spellcheck"
:step="step" :step="step"
:list="id"
@focus="focused = true" @focus="focused = true"
@blur="focused = false" @blur="focused = false"
@keydown="onKeydown($event)" @keydown="onKeydown($event)"
@input="onInput" @input="onInput"
:list="id"
> >
<datalist :id="id" v-if="datalist"> <datalist v-if="datalist" :id="id">
<option v-for="data in datalist" :value="data"/> <option v-for="data in datalist" :value="data"/>
</datalist> </datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div> <div ref="suffixEl" class="suffix"><slot name="suffix"></slot></div>
</div> </div>
<div class="caption"><slot name="caption"></slot></div> <div class="caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton> <MkButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</div> </div>
</template> </template>

View file

@ -3,9 +3,9 @@
<div class="icon"><slot name="icon"></slot></div> <div class="icon"><slot name="icon"></slot></div>
<span class="label"><slot name="label"></slot></span> <span class="label"><slot name="label"></slot></span>
<input <input
type="range"
ref="input" ref="input"
v-model="v" v-model="v"
type="range"
:disabled="disabled" :disabled="disabled"
:min="min" :min="min"
:max="max" :max="max"

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="vrtktovh" v-size="{ max: [500] }" v-sticky-container> <div v-size="{ max: [500] }" v-sticky-container class="vrtktovh">
<div class="label"><slot name="label"></slot></div> <div class="label"><slot name="label"></slot></div>
<div class="main"> <div class="main">
<slot></slot> <slot></slot>

View file

@ -1,10 +1,10 @@
<template> <template>
<div class="vblkjoeq"> <div class="vblkjoeq">
<div class="label" @click="focus"><slot name="label"></slot></div> <div class="label" @click="focus"><slot name="label"></slot></div>
<div class="input" :class="{ inline, disabled, focused }" @click.prevent="onClick" ref="container"> <div ref="container" class="input" :class="{ inline, disabled, focused }" @click.prevent="onClick">
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div> <div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
<select class="select" ref="inputEl" <select ref="inputEl" v-model="v"
v-model="v" class="select"
:disabled="disabled" :disabled="disabled"
:required="required" :required="required"
:readonly="readonly" :readonly="readonly"
@ -15,11 +15,11 @@
> >
<slot></slot> <slot></slot>
</select> </select>
<div class="suffix" ref="suffixEl"><i class="fas fa-chevron-down"></i></div> <div ref="suffixEl" class="suffix"><i class="fas fa-chevron-down"></i></div>
</div> </div>
<div class="caption"><slot name="caption"></slot></div> <div class="caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton> <MkButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</div> </div>
</template> </template>

View file

@ -8,12 +8,12 @@
@click.prevent="toggle" @click.prevent="toggle"
> >
<input <input
type="checkbox"
ref="input" ref="input"
type="checkbox"
:disabled="disabled" :disabled="disabled"
@keydown.enter="toggle" @keydown.enter="toggle"
> >
<span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff"> <span v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button">
<span class="handle"></span> <span class="handle"></span>
</span> </span>
<span class="label"> <span class="label">

View file

@ -3,8 +3,8 @@
<div class="label" @click="focus"><slot name="label"></slot></div> <div class="label" @click="focus"><slot name="label"></slot></div>
<div class="input" :class="{ disabled, focused, tall, pre }"> <div class="input" :class="{ disabled, focused, tall, pre }">
<textarea ref="inputEl" <textarea ref="inputEl"
:class="{ code, _monospace: code }"
v-model="v" v-model="v"
:class="{ code, _monospace: code }"
:disabled="disabled" :disabled="disabled"
:required="required" :required="required"
:readonly="readonly" :readonly="readonly"
@ -20,7 +20,7 @@
</div> </div>
<div class="caption"><slot name="caption"></slot></div> <div class="caption"><slot name="caption"></slot></div>
<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton> <MkButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
</div> </div>
</template> </template>

View file

@ -1,7 +1,7 @@
<template> <template>
<span class="mk-acct"> <span class="mk-acct">
<span class="name">@{{ user.username }}</span> <span class="name">@{{ user.username }}</span>
<span class="host" v-if="user.host || detail || $store.state.showFullAcct">@{{ user.host || host }}</span> <span v-if="user.host || detail || $store.state.showFullAcct" class="host">@{{ user.host || host }}</span>
</span> </span>
</template> </template>

View file

@ -1,12 +1,12 @@
<template> <template>
<div class="qiivuoyo" v-if="ad"> <div v-if="ad" class="qiivuoyo">
<div class="main" :class="ad.place" v-if="!showMenu"> <div v-if="!showMenu" class="main" :class="ad.place">
<a :href="ad.url" target="_blank"> <a :href="ad.url" target="_blank">
<img :src="ad.imageUrl"> <img :src="ad.imageUrl">
<button class="_button menu" @click.prevent.stop="toggleMenu"><span class="fas fa-info-circle"></span></button> <button class="_button menu" @click.prevent.stop="toggleMenu"><span class="fas fa-info-circle"></span></button>
</a> </a>
</div> </div>
<div class="menu" v-else> <div v-else class="menu">
<div class="body"> <div class="body">
<div>Ads by {{ host }}</div> <div>Ads by {{ host }}</div>
<!--<MkButton class="button" primary>{{ $ts._ad.like }}</MkButton>--> <!--<MkButton class="button" primary>{{ $ts._ad.like }}</MkButton>-->

View file

@ -1,9 +1,9 @@
<template> <template>
<span class="eiwwqkts _noSelect" :class="{ cat, square: $store.state.squareAvatars }" :title="acct(user)" v-if="disableLink" v-user-preview="disablePreview ? undefined : user.id" @click="onClick"> <span v-if="disableLink" v-user-preview="disablePreview ? undefined : user.id" class="eiwwqkts _noSelect" :class="{ cat, square: $store.state.squareAvatars }" :title="acct(user)" @click="onClick">
<img class="inner" :src="url" decoding="async"/> <img class="inner" :src="url" decoding="async"/>
<MkUserOnlineIndicator v-if="showIndicator" class="indicator" :user="user"/> <MkUserOnlineIndicator v-if="showIndicator" class="indicator" :user="user"/>
</span> </span>
<MkA class="eiwwqkts _noSelect" :class="{ cat, square: $store.state.squareAvatars }" :to="userPage(user)" :title="acct(user)" :target="target" v-else v-user-preview="disablePreview ? undefined : user.id"> <MkA v-else v-user-preview="disablePreview ? undefined : user.id" class="eiwwqkts _noSelect" :class="{ cat, square: $store.state.squareAvatars }" :to="userPage(user)" :title="acct(user)" :target="target">
<img class="inner" :src="url" decoding="async"/> <img class="inner" :src="url" decoding="async"/>
<MkUserOnlineIndicator v-if="showIndicator" class="indicator" :user="user"/> <MkUserOnlineIndicator v-if="showIndicator" class="indicator" :user="user"/>
</MkA> </MkA>

View file

@ -3,7 +3,7 @@
<div class="mjndxjcg"> <div class="mjndxjcg">
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/> <img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
<p><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</p> <p><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</p>
<MkButton @click="() => $emit('retry')" class="button">{{ $ts.retry }}</MkButton> <MkButton class="button" @click="() => $emit('retry')">{{ $ts.retry }}</MkButton>
</div> </div>
</transition> </transition>
</template> </template>

View file

@ -1,24 +1,24 @@
<template> <template>
<div class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick" ref="el"> <div ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick">
<template v-if="info"> <template v-if="info">
<div class="titleContainer" @click="showTabsPopup" v-if="!hideTitle"> <div v-if="!hideTitle" class="titleContainer" @click="showTabsPopup">
<MkAvatar v-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true" :show-indicator="true"/> <MkAvatar v-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true" :show-indicator="true"/>
<i v-else-if="info.icon" class="icon" :class="info.icon"></i> <i v-else-if="info.icon" class="icon" :class="info.icon"></i>
<div class="title"> <div class="title">
<MkUserName v-if="info.userName" :user="info.userName" :nowrap="false" class="title"/> <MkUserName v-if="info.userName" :user="info.userName" :nowrap="false" class="title"/>
<div v-else-if="info.title" class="title">{{ info.title }}</div> <div v-else-if="info.title" class="title">{{ info.title }}</div>
<div class="subtitle" v-if="!narrow && info.subtitle"> <div v-if="!narrow && info.subtitle" class="subtitle">
{{ info.subtitle }} {{ info.subtitle }}
</div> </div>
<div class="subtitle activeTab" v-if="narrow && hasTabs"> <div v-if="narrow && hasTabs" class="subtitle activeTab">
{{ info.tabs.find(tab => tab.active)?.title }} {{ info.tabs.find(tab => tab.active)?.title }}
<i class="chevron fas fa-chevron-down"></i> <i class="chevron fas fa-chevron-down"></i>
</div> </div>
</div> </div>
</div> </div>
<div class="tabs" v-if="!narrow || hideTitle"> <div v-if="!narrow || hideTitle" class="tabs">
<button class="tab _button" v-for="tab in info.tabs" :class="{ active: tab.active }" @click="tab.onClick" v-tooltip="tab.title"> <button v-for="tab in info.tabs" v-tooltip="tab.title" class="tab _button" :class="{ active: tab.active }" @click="tab.onClick">
<i v-if="tab.icon" class="icon" :class="tab.icon"></i> <i v-if="tab.icon" class="icon" :class="tab.icon"></i>
<span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span> <span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span>
</button> </button>
@ -27,11 +27,11 @@
<div class="buttons right"> <div class="buttons right">
<template v-if="info && info.actions && !narrow"> <template v-if="info && info.actions && !narrow">
<template v-for="action in info.actions"> <template v-for="action in info.actions">
<MkButton class="fullButton" v-if="action.asFullButton" @click.stop="action.handler" primary><i :class="action.icon" style="margin-right: 6px;"></i>{{ action.text }}</MkButton> <MkButton v-if="action.asFullButton" class="fullButton" primary @click.stop="action.handler"><i :class="action.icon" style="margin-right: 6px;"></i>{{ action.text }}</MkButton>
<button v-else class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag" v-tooltip="action.text"><i :class="action.icon"></i></button> <button v-else v-tooltip="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
</template> </template>
</template> </template>
<button v-if="shouldShowMenu" class="_button button" @click.stop="showMenu" @touchstart="preventDrag" v-tooltip="$ts.menu"><i class="fas fa-ellipsis-h"></i></button> <button v-if="shouldShowMenu" v-tooltip="$ts.menu" class="_button button" @click.stop="showMenu" @touchstart="preventDrag"><i class="fas fa-ellipsis-h"></i></button>
</div> </div>
</div> </div>
</template> </template>

View file

@ -7,12 +7,12 @@
<template v-if="!self"> <template v-if="!self">
<span class="schema">{{ schema }}//</span> <span class="schema">{{ schema }}//</span>
<span class="hostname">{{ hostname }}</span> <span class="hostname">{{ hostname }}</span>
<span class="port" v-if="port != ''">:{{ port }}</span> <span v-if="port != ''" class="port">:{{ port }}</span>
</template> </template>
<template v-if="pathname === '/' && self"> <template v-if="pathname === '/' && self">
<span class="self">{{ hostname }}</span> <span class="self">{{ hostname }}</span>
</template> </template>
<span class="pathname" v-if="pathname != ''">{{ self ? pathname.substr(1) : pathname }}</span> <span v-if="pathname != ''" class="pathname">{{ self ? pathname.substr(1) : pathname }}</span>
<span class="query">{{ query }}</span> <span class="query">{{ query }}</span>
<span class="hash">{{ hash }}</span> <span class="hash">{{ hash }}</span>
<i v-if="target === '_blank'" class="fas fa-external-link-square-alt icon"></i> <i v-if="target === '_blank'" class="fas fa-external-link-square-alt icon"></i>

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="mk-google"> <div class="mk-google">
<input type="search" v-model="query" :placeholder="q"> <input v-model="query" type="search" :placeholder="q">
<button @click="search"><i class="fas fa-search"></i> {{ $ts.search }}</button> <button @click="search"><i class="fas fa-search"></i> {{ $ts.search }}</button>
</div> </div>
</template> </template>

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="xubzgfgb" :class="{ cover }" :title="title"> <div class="xubzgfgb" :class="{ cover }" :title="title">
<canvas ref="canvas" :width="size" :height="size" :title="title" v-if="!loaded"/> <canvas v-if="!loaded" ref="canvas" :width="size" :height="size" :title="title"/>
<img v-if="src" :src="src" :title="title" :alt="alt" @load="onLoad"/> <img v-if="src" :src="src" :title="title" :alt="alt" @load="onLoad"/>
</div> </div>
</template> </template>

View file

@ -3,12 +3,12 @@
<div class="szkkfdyq _popup"> <div class="szkkfdyq _popup">
<div class="main"> <div class="main">
<template v-for="item in items"> <template v-for="item in items">
<button v-if="item.action" class="_button" @click="$event => { item.action($event); close(); }" v-click-anime> <button v-if="item.action" v-click-anime class="_button" @click="$event => { item.action($event); close(); }">
<i class="icon" :class="item.icon"></i> <i class="icon" :class="item.icon"></i>
<div class="text">{{ item.text }}</div> <div class="text">{{ item.text }}</div>
<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span> <span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
</button> </button>
<MkA v-else :to="item.to" @click.passive="close()" v-click-anime> <MkA v-else v-click-anime :to="item.to" @click.passive="close()">
<i class="icon" :class="item.icon"></i> <i class="icon" :class="item.icon"></i>
<div class="text">{{ item.text }}</div> <div class="text">{{ item.text }}</div>
<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span> <span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
@ -16,15 +16,15 @@
</template> </template>
</div> </div>
<div class="sub"> <div class="sub">
<a href="https://misskey-hub.net/help.html" target="_blank" @click.passive="close()" v-click-anime> <a v-click-anime href="https://misskey-hub.net/help.html" target="_blank" @click.passive="close()">
<i class="fas fa-question-circle icon"></i> <i class="fas fa-question-circle icon"></i>
<div class="text">{{ $ts.help }}</div> <div class="text">{{ $ts.help }}</div>
</a> </a>
<MkA to="/about" @click.passive="close()" v-click-anime> <MkA v-click-anime to="/about" @click.passive="close()">
<i class="fas fa-info-circle icon"></i> <i class="fas fa-info-circle icon"></i>
<div class="text">{{ $t('aboutX', { x: instanceName }) }}</div> <div class="text">{{ $t('aboutX', { x: instanceName }) }}</div>
</MkA> </MkA>
<MkA to="/about-misskey" @click.passive="close()" v-click-anime> <MkA v-click-anime to="/about-misskey" @click.passive="close()">
<img src="/static-assets/favicon.png" class="icon"/> <img src="/static-assets/favicon.png" class="icon"/>
<div class="text">{{ $ts.aboutMisskey }}</div> <div class="text">{{ $ts.aboutMisskey }}</div>
</MkA> </MkA>

View file

@ -1,8 +1,8 @@
<template> <template>
<component :is="self ? 'MkA' : 'a'" class="xlcxczvw _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target" <component :is="self ? 'MkA' : 'a'" class="xlcxczvw _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
:title="url"
@mouseover="onMouseover" @mouseover="onMouseover"
@mouseleave="onMouseleave" @mouseleave="onMouseleave"
:title="url"
> >
<slot></slot> <slot></slot>
<i v-if="target === '_blank'" class="fas fa-external-link-square-alt icon"></i> <i v-if="target === '_blank'" class="fas fa-external-link-square-alt icon"></i>

View file

@ -1,20 +1,20 @@
<template> <template>
<div class="mk-media-banner"> <div class="mk-media-banner">
<div class="sensitive" v-if="media.isSensitive && hide" @click="hide = false"> <div v-if="media.isSensitive && hide" class="sensitive" @click="hide = false">
<span class="icon"><i class="fas fa-exclamation-triangle"></i></span> <span class="icon"><i class="fas fa-exclamation-triangle"></i></span>
<b>{{ $ts.sensitive }}</b> <b>{{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span> <span>{{ $ts.clickToShow }}</span>
</div> </div>
<div class="audio" v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'"> <div v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" class="audio">
<audio class="audio" <audio ref="audio"
class="audio"
:src="media.url" :src="media.url"
:title="media.name" :title="media.name"
controls controls
ref="audio" preload="metadata"
@volumechange="volumechange" @volumechange="volumechange" />
preload="metadata" />
</div> </div>
<a class="download" v-else <a v-else class="download"
:href="media.url" :href="media.url"
:title="media.name" :title="media.name"
:download="media.name" :download="media.name"

View file

@ -7,9 +7,9 @@
<Mfm v-if="title" class="title" :text="title"/> <Mfm v-if="title" class="title" :text="title"/>
<span class="text-count" :class="{ over: remainingLength < 0 }">{{ remainingLength }}</span> <span class="text-count" :class="{ over: remainingLength < 0 }">{{ remainingLength }}</span>
</header> </header>
<textarea autofocus v-model="inputValue" :placeholder="input.placeholder" @keydown="onInputKeydown"></textarea> <textarea v-model="inputValue" autofocus :placeholder="input.placeholder" @keydown="onInputKeydown"></textarea>
<div class="buttons" v-if="(showOkButton || showCancelButton)"> <div v-if="(showOkButton || showCancelButton)" class="buttons">
<MkButton inline @click="ok" primary :disabled="remainingLength < 0">{{ $ts.ok }}</MkButton> <MkButton inline primary :disabled="remainingLength < 0" @click="ok">{{ $ts.ok }}</MkButton>
<MkButton inline @click="cancel" >{{ $ts.cancel }}</MkButton> <MkButton inline @click="cancel" >{{ $ts.cancel }}</MkButton>
</div> </div>
</div> </div>

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="qjewsnkg" v-if="hide" @click="hide = false"> <div v-if="hide" class="qjewsnkg" @click="hide = false">
<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.comment" :alt="image.comment"/> <ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.comment" :alt="image.comment"/>
<div class="text"> <div class="text">
<div> <div>
@ -8,13 +8,13 @@
</div> </div>
</div> </div>
</div> </div>
<div class="gqnyydlz" :style="{ background: color }" v-else> <div v-else class="gqnyydlz" :style="{ background: color }">
<a <a
:href="image.url" :href="image.url"
:title="image.name" :title="image.name"
> >
<ImgWithBlurhash :hash="image.blurhash" :src="url" :alt="image.comment" :title="image.comment" :cover="false"/> <ImgWithBlurhash :hash="image.blurhash" :src="url" :alt="image.comment" :title="image.comment" :cover="false"/>
<div class="gif" v-if="image.type === 'image/gif'">GIF</div> <div v-if="image.type === 'image/gif'" class="gif">GIF</div>
</a> </a>
<i class="fas fa-eye-slash" @click="hide = true"></i> <i class="fas fa-eye-slash" @click="hide = true"></i>
</div> </div>

View file

@ -1,11 +1,11 @@
<template> <template>
<div class="hoawjimk"> <div class="hoawjimk">
<XBanner v-for="media in mediaList.filter(media => !previewable(media))" :media="media" :key="media.id"/> <XBanner v-for="media in mediaList.filter(media => !previewable(media))" :key="media.id" :media="media"/>
<div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container"> <div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container">
<div :data-count="mediaList.filter(media => previewable(media)).length" ref="gallery"> <div ref="gallery" :data-count="mediaList.filter(media => previewable(media)).length">
<template v-for="media in mediaList"> <template v-for="media in mediaList">
<XVideo :video="media" :key="media.id" v-if="media.type.startsWith('video')"/> <XVideo v-if="media.type.startsWith('video')" :key="media.id" :video="media"/>
<XImage class="image" :data-id="media.id" :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/> <XImage v-else-if="media.type.startsWith('image')" :key="media.id" class="image" :data-id="media.id" :image="media" :raw="raw"/>
</template> </template>
</div> </div>
</div> </div>

View file

@ -1,11 +1,11 @@
<template> <template>
<div class="icozogqfvdetwohsdglrbswgrejoxbdj" v-if="hide" @click="hide = false"> <div v-if="hide" class="icozogqfvdetwohsdglrbswgrejoxbdj" @click="hide = false">
<div> <div>
<b><i class="fas fa-exclamation-triangle"></i> {{ $ts.sensitive }}</b> <b><i class="fas fa-exclamation-triangle"></i> {{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span> <span>{{ $ts.clickToShow }}</span>
</div> </div>
</div> </div>
<div class="kkjnbbplepmiyuadieoenjgutgcmtsvu" v-else> <div v-else class="kkjnbbplepmiyuadieoenjgutgcmtsvu">
<video <video
:poster="video.thumbnailUrl" :poster="video.thumbnailUrl"
:title="video.name" :title="video.name"

View file

@ -1,9 +1,9 @@
<template> <template>
<MkA v-if="url.startsWith('/')" class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" :style="{ background: bg }"> <MkA v-if="url.startsWith('/')" v-user-preview="canonical" class="ldlomzub" :class="{ isMe }" :to="url" :style="{ background: bg }">
<img class="icon" :src="`/avatar/@${username}@${host}`" alt=""> <img class="icon" :src="`/avatar/@${username}@${host}`" alt="">
<span class="main"> <span class="main">
<span class="username">@{{ username }}</span> <span class="username">@{{ username }}</span>
<span class="host" v-if="(host != localHost) || $store.state.showFullAcct">@{{ toUnicode(host) }}</span> <span v-if="(host != localHost) || $store.state.showFullAcct" class="host">@{{ toUnicode(host) }}</span>
</span> </span>
</MkA> </MkA>
<a v-else class="ldlomzub" :href="url" target="_blank" rel="noopener" :style="{ background: bg }"> <a v-else class="ldlomzub" :href="url" target="_blank" rel="noopener" :style="{ background: bg }">

Some files were not shown because too many files have changed in this diff Show more