Compare commits
54 Commits
Author | SHA1 | Date | |
---|---|---|---|
99eb919f4e | |||
1d640ee118 | |||
aedbab17cc | |||
3e00ce0d88 | |||
b14e347da1 | |||
034b8f09df | |||
c537a0ba93 | |||
897d775b14 | |||
4f43f019e0 | |||
1ea0aaef76 | |||
fd1cfcff5f | |||
c7308f4178 | |||
5cc65c5bd3 | |||
f216dd7617 | |||
af022fd8b8 | |||
5c7181ca21 | |||
30892ebfa3 | |||
ae2d71553e | |||
154e418c34 | |||
cfd1888969 | |||
d53795184c | |||
fe3609451e | |||
3692c9eb64 | |||
89a532eeac | |||
85740dd09f | |||
b05cfe4a84 | |||
322b64c0b4 | |||
601bc3e3cc | |||
c77fe1f2cf | |||
8e7744a695 | |||
901d6894de | |||
b463663175 | |||
2294e9ffdc | |||
1122f7281e | |||
99ced12ac5 | |||
2e80f9dfba | |||
3a990dce75 | |||
cc441258db | |||
ee144acea9 | |||
35b7ce1a96 | |||
dc0e55bf16 | |||
a3dceee7c0 | |||
7940417d23 | |||
b1751543aa | |||
034dcaeb9d | |||
936fb136d2 | |||
55ab528c87 | |||
c544e38f34 | |||
9b771baa5e | |||
f607faef0b | |||
cb16ff866c | |||
d6e85ffb59 | |||
f9e3fd7001 | |||
ba1e14443c |
25
CHANGELOG.md
25
CHANGELOG.md
@ -7,6 +7,31 @@
|
||||
|
||||
-->
|
||||
|
||||
## 12.101.1 (2021/12/29)
|
||||
|
||||
### Bugfixes
|
||||
- SVG絵文字が表示できないのを修正
|
||||
- エクスポートした絵文字の拡張子がfalseになることがあるのを修正
|
||||
|
||||
## 12.101.0 (2021/12/29)
|
||||
|
||||
### Improvements
|
||||
- クライアント: ノートプレビューの精度を改善
|
||||
- クライアント: MFM sparkleエフェクトの改善
|
||||
- クライアント: デザインの調整
|
||||
- セキュリティの向上
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: 一部のコンポーネントが裏に隠れるのを修正
|
||||
- fix html blockquote conversion
|
||||
|
||||
## 12.100.2 (2021/12/18)
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: Deckカラムの増減がページをリロードするまで正しく反映されない問題を修正
|
||||
- クライアント: 一部のコンポーネントが裏に隠れるのを修正
|
||||
- クライアント: カスタム絵文字一覧ページの負荷が高いのを修正
|
||||
|
||||
## 12.100.1 (2021/12/17)
|
||||
|
||||
### Bugfixes
|
||||
|
@ -87,7 +87,7 @@ Configuration files are located in [`/.github/workflows`](/.github/workflows).
|
||||
|
||||
## Vue
|
||||
Misskey uses Vue(v3) as its front-end framework.
|
||||
**When creating a new component, please use the Composition API instead of the Options API.**
|
||||
**When creating a new component, please use the Composition API (and [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html)) instead of the Options API.**
|
||||
Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
||||
|
||||
## Adding MisskeyRoom items
|
||||
|
@ -18,3 +18,9 @@ import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
|
||||
Cypress.on('uncaught:exception', (err, runnable) => {
|
||||
if (err.message.includes('ResizeObserver loop limit exceeded')) {
|
||||
return false
|
||||
}
|
||||
});
|
||||
|
@ -106,7 +106,6 @@ clickToShow: "اضغط للعرض"
|
||||
sensitive: "محتوى حساس"
|
||||
add: "إضافة"
|
||||
reaction: "التفاعلات"
|
||||
reactionSettingDescription: "اختر التفاعلات المفضلة التي تريد تثبيتها في منتقي التفاعلات."
|
||||
reactionSettingDescription2: "اسحب لترتيب ، انقر للحذف ، استخدم \"+\" للإضافة."
|
||||
rememberNoteVisibility: "تذكر إعدادت مدى رؤية الملاحظات"
|
||||
attachCancel: "أزل المرفق"
|
||||
@ -581,7 +580,6 @@ regenerateLoginToken: "أعد توليد الرمز"
|
||||
regenerateLoginTokenDescription: "ينشئ رمز استيثاق جديد في العادة هذا ليس ضروريًا ؛ عند إنشاء رمز جديد ستُخرج جميع الأجهزة."
|
||||
setMultipleBySeparatingWithSpace: "يمكنك ادخال أكثر من مدخل واحد وذلك بفصلها بمسافات."
|
||||
fileIdOrUrl: "معرف الملف أو رابط"
|
||||
chatOpenBehavior: "سلوك نفاذة المحادثة عند فتحها"
|
||||
behavior: "السلوك"
|
||||
sample: "مثال"
|
||||
abuseReports: "البلاغات"
|
||||
|
@ -88,7 +88,6 @@ clickToShow: "Klikněte pro zobrazení"
|
||||
sensitive: "NSFW"
|
||||
add: "Přidat"
|
||||
reaction: "Reakce"
|
||||
reactionSettingDescription: "Vyberte Vaší oblíbenou reakci, kterou chcete připnout ve výběru."
|
||||
reactionSettingDescription2: "Přetažením změníte pořadí, kliknutím smažete, zmáčkněte \"+\" k přidání"
|
||||
rememberNoteVisibility: "Zapamatovat nastavení zobrazení poznámky"
|
||||
attachCancel: "Odstranit přílohu"
|
||||
|
@ -106,7 +106,7 @@ clickToShow: "Zum Anzeigen anklicken"
|
||||
sensitive: "NSFW"
|
||||
add: "Hinzufügen"
|
||||
reaction: "Reaktionen"
|
||||
reactionSettingDescription: "Wähle die Reaktionen aus, die in der Reaktionsauswahl angezeigt werden sollen."
|
||||
reactionSetting: "In der Reaktionsauswahl anzuzeigende Reaktionen"
|
||||
reactionSettingDescription2: "Ziehe zum Anordnen, klicke zum Löschen, drücke + zum Hinzufügen"
|
||||
rememberNoteVisibility: "Notizsichtbarkeit merken"
|
||||
attachCancel: "Anhang entfernen"
|
||||
@ -448,6 +448,7 @@ uiLanguage: "Sprache der Benutzeroberfläche"
|
||||
groupInvited: "Du wurdest in eine Gruppe eingeladen"
|
||||
aboutX: "Über {x}"
|
||||
useOsNativeEmojis: "Eingebaute Emojis des Betriebssystems benutzen"
|
||||
disableDrawer: "Keine ausfahrbaren Menüs verwenden"
|
||||
youHaveNoGroups: "Keine Gruppen vorhanden"
|
||||
joinOrCreateGroup: "Lass dich zu einer Gruppe einladen oder erstelle deine eigene."
|
||||
noHistory: "Kein Verlauf"
|
||||
@ -613,7 +614,6 @@ regenerateLoginToken: "Anmeldungstoken regenerieren"
|
||||
regenerateLoginTokenDescription: "Den zur Anmeldung intern verwendeten Token regenerieren. Normalerweise wird dies nicht benötigt. Bei Regeneration werden alle Geräte ausgeloggt."
|
||||
setMultipleBySeparatingWithSpace: "Trenne Elemente durch ein Leerzeichen um mehrere Einstellungen zu kofigurieren."
|
||||
fileIdOrUrl: "Datei-ID oder URL"
|
||||
chatOpenBehavior: "Verhalten des Chatfensters bei Öffnung"
|
||||
behavior: "Verhalten"
|
||||
sample: "Beispiel"
|
||||
abuseReports: "Meldungen"
|
||||
@ -685,6 +685,7 @@ center: "Mitte"
|
||||
wide: "Breit"
|
||||
narrow: "Schmal"
|
||||
reloadToApplySetting: "Diese Einstellung tritt nach einer Aktualisierung der Seite in Kraft. Jetzt aktualisieren?"
|
||||
needReloadToApply: "Diese Einstellung tritt nach einer Aktualisierung der Seite in Kraft."
|
||||
showTitlebar: "Titelleiste anzeigen"
|
||||
clearCache: "Cache leeren"
|
||||
onlineUsersCount: "{n} Benutzer sind online"
|
||||
@ -813,6 +814,11 @@ deleteAccountConfirm: "Dein Benutzerkonto wird unwiderruflich gelöscht. Trotzde
|
||||
incorrectPassword: "Falsches Passwort."
|
||||
voteConfirm: "Wirklich für \"{choice}\" abstimmen?"
|
||||
hide: "Inhalt verbergen"
|
||||
leaveGroup: "Gruppe verlassen"
|
||||
leaveGroupConfirm: "Möchtest du \"{name}\" wirklich verlassen?"
|
||||
useDrawerReactionPickerForMobile: "Auf mobilen Geräten ausfahrbare Reaktionsauswahl anzeigen"
|
||||
welcomeBackWithName: "Willkommen zurück, {name}"
|
||||
clickToFinishEmailVerification: "Drücke bitte auf [{ok}], um die Email-Bestätigung abzuschließen."
|
||||
_emailUnavailable:
|
||||
used: "Diese Email-Adresse wird bereits verwendet"
|
||||
format: "Das Format dieser Email-Adresse ist ungültig"
|
||||
|
@ -106,7 +106,7 @@ clickToShow: "Click to show"
|
||||
sensitive: "NSFW"
|
||||
add: "Add"
|
||||
reaction: "Reactions"
|
||||
reactionSettingDescription: "Configure which reactions you want to display in the reaction picker."
|
||||
reactionSetting: "Reactions to show in the reaction picker"
|
||||
reactionSettingDescription2: "Drag to reorder, Click to delete, Press \"+\" to add"
|
||||
rememberNoteVisibility: "Remember note visibility settings"
|
||||
attachCancel: "Remove attachment"
|
||||
@ -448,6 +448,7 @@ uiLanguage: "User interface language"
|
||||
groupInvited: "You've been invited to a group"
|
||||
aboutX: "About {x}"
|
||||
useOsNativeEmojis: "Use OS native Emoji"
|
||||
disableDrawer: "Don't use drawer-style menus"
|
||||
youHaveNoGroups: "You have no groups"
|
||||
joinOrCreateGroup: "Get invited to a group or create your own."
|
||||
noHistory: "No history available"
|
||||
@ -613,7 +614,6 @@ regenerateLoginToken: "Regenerate login token"
|
||||
regenerateLoginTokenDescription: "Regenerate the token used internally during login. Normally this action is not necessary. If regenerated, all devices will be logged out."
|
||||
setMultipleBySeparatingWithSpace: "Separate multiple entries with spaces."
|
||||
fileIdOrUrl: "File-ID or URL"
|
||||
chatOpenBehavior: "Behavior of the chat window when opened"
|
||||
behavior: "Behavior"
|
||||
sample: "Sample"
|
||||
abuseReports: "Reports"
|
||||
@ -685,6 +685,7 @@ center: "Center"
|
||||
wide: "Wide"
|
||||
narrow: "Narrow"
|
||||
reloadToApplySetting: "This setting will only apply after a page reload. Reload now?"
|
||||
needReloadToApply: "This setting will only apply after a page reload."
|
||||
showTitlebar: "Show title bar"
|
||||
clearCache: "Clear cache"
|
||||
onlineUsersCount: "{n} users are online"
|
||||
@ -812,6 +813,11 @@ deleteAccountConfirm: "This will irreversibly delete your account. Proceed?"
|
||||
incorrectPassword: "Incorrect password."
|
||||
voteConfirm: "Confirm your vote for \"{choice}\"?"
|
||||
hide: "Hide"
|
||||
leaveGroup: "Leave Group"
|
||||
leaveGroupConfirm: "Are you sure you want to leave \"{name}\"?"
|
||||
useDrawerReactionPickerForMobile: "Display reaction picker as drawer on mobile"
|
||||
welcomeBackWithName: "Welcome back, {name}"
|
||||
clickToFinishEmailVerification: "Please click [{ok}] to complete email verification."
|
||||
_emailUnavailable:
|
||||
used: "This email address is already being used"
|
||||
format: "The format of this email address is invalid"
|
||||
|
@ -2,7 +2,7 @@
|
||||
_lang_: "Esperanto"
|
||||
headlineMisskey: "Reto konektita per notoj"
|
||||
introMisskey: "Bonvenon! Misskey estas malfermitkoda malcentraliza etbloga servo.\nKreu \"noto\"n por diskonigi nunan aferon, aŭ por paroli vian penson al ĉiuj ĉirkaŭ vi. 📡\nLa funkcion \"reago\" ebligas esprimi rapide vian senton pri la noto de la alia en la Fediverso. 👍\nBonvole esploru novan mondon. 🚀"
|
||||
monthAndDay: "la {day}a de la {month}a monato"
|
||||
monthAndDay: "La {day}a de la {month}a monato"
|
||||
search: "Serĉi"
|
||||
notifications: "Sciigoj"
|
||||
username: "Uzantnomo"
|
||||
@ -23,7 +23,7 @@ otherSettings: "Aliaj agordoj"
|
||||
openInWindow: "Malfermi en nova fenestro"
|
||||
profile: "Profilo"
|
||||
timeline: "Templinio"
|
||||
noAccountDescription: "Neniu priskribo"
|
||||
noAccountDescription: "La uzanto ankoraŭ ne skribis la sinprezenton en sia profilo."
|
||||
login: "Saluti"
|
||||
loggingIn: "Salutado…"
|
||||
logout: "Adiaŭi"
|
||||
@ -67,13 +67,13 @@ driveFileDeleteConfirm: "Ĉu vi certas, ke vi volas forviŝi la dosieron \"{name
|
||||
unfollowConfirm: "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?"
|
||||
lists: "Listoj"
|
||||
noLists: "Neniu listo"
|
||||
note: "Sendi"
|
||||
note: "Noti"
|
||||
notes: "Notoj"
|
||||
following: "Sekvatoj"
|
||||
followers: "Sekvantoj"
|
||||
followsYou: "Sekvas vin"
|
||||
createList: "Krei liston"
|
||||
manageLists: "Administri liston"
|
||||
manageLists: "Bonteni liston"
|
||||
error: "Eraro"
|
||||
somethingHappened: "Problemo okazis"
|
||||
retry: "Provi denove"
|
||||
@ -101,8 +101,8 @@ clickToShow: "Klaku por malkaŝu"
|
||||
sensitive: "Enhavo ne estas deca por laborejo (NSFW)"
|
||||
add: "Aldoni"
|
||||
reaction: "Reagoj"
|
||||
reactionSettingDescription: "Agordi la reagojn kiujn vi volas montrigi prefere ĉe la elektilo de reagoj"
|
||||
rememberNoteVisibility: "Rememori la agordon de videbleco de la laste sendita"
|
||||
reactionSetting: "Reagoj aperontaj en la elektilo de reagoj"
|
||||
rememberNoteVisibility: "Rememori la agordon de videbleco de la lasta afiŝado"
|
||||
attachCancel: "Deigi aldonaĵon"
|
||||
markAsSensitive: "Troviĝi NSFW"
|
||||
unmarkAsSensitive: "Ne troviĝi NSFW"
|
||||
@ -122,6 +122,7 @@ selectAntenna: "Elekti antenon"
|
||||
selectWidget: "Elekti enestraĵon"
|
||||
editWidgets: "Redakti fenestraĵon"
|
||||
editWidgetsExit: "Fini la redaktadon"
|
||||
customEmojis: "Federaj emoĵioj"
|
||||
emoji: "Emoĵio"
|
||||
emojis: "Emoĵio"
|
||||
emojiName: "Nomo de la emoĵio"
|
||||
@ -129,11 +130,12 @@ emojiUrl: "URL de la emoĵio"
|
||||
addEmoji: "Aldoni emoĵion"
|
||||
settingGuide: "Agordaj rekomendoj"
|
||||
cacheRemoteFiles: "Stapli forajn dosierojn"
|
||||
flagAsBot: "Agordi por robota uzanto"
|
||||
flagAsCat: "Agordi por kata uzanto"
|
||||
flagAsCatDescription: "Se vi estas kato, ebligu la agordon."
|
||||
flagAsBot: "Marki kiel esti uzanto de roboto"
|
||||
flagAsCat: "Marki kiel esti kato"
|
||||
flagAsCatDescription: "Se vi estas kato, faru ĉi tiun flagon"
|
||||
autoAcceptFollowed: "Aŭtomate akcepti la peton de sekvado far uzantoj kiujn vi sekvas"
|
||||
addAccount: "Aldoni konton"
|
||||
loginFailed: "Saluto malsukcesis"
|
||||
showOnRemote: "Vidi ĉe la surloka nodo"
|
||||
general: "Ĝenerala"
|
||||
wallpaper: "Ekranfonoj"
|
||||
@ -149,6 +151,7 @@ recipient: "Ricevonton"
|
||||
annotation: "Komentarioj"
|
||||
federation: "Federaĵo"
|
||||
instances: "Nodoj"
|
||||
registeredAt: "Registrita je"
|
||||
latestRequestSentAt: "La laste sendita peto"
|
||||
latestRequestReceivedAt: "La laste ricevita peto "
|
||||
latestStatus: "Laŭstato"
|
||||
@ -280,7 +283,7 @@ normal: "Normala"
|
||||
instanceName: "Nomo de la nodo"
|
||||
instanceDescription: "Priskribo de la nodo "
|
||||
maintainerName: "Nomo de la administranto"
|
||||
maintainerEmail: "Retpoŝtadreso de la administranto"
|
||||
maintainerEmail: "Retpoŝta adreso de la administranto"
|
||||
tosUrl: "URL de kondiĉoj de uzado"
|
||||
thisYear: "Ĉi-jare"
|
||||
thisMonth: "Ĉi-monate"
|
||||
@ -320,8 +323,11 @@ antennas: "Antenoj"
|
||||
manageAntennas: "Administri antenojn"
|
||||
name: "Nomo"
|
||||
antennaSource: "Fonto de la anteno"
|
||||
antennaKeywords: "Ricevi per ĉefterminoj"
|
||||
antennaExcludeKeywords: "Krom ĉefterminoj"
|
||||
notifyAntenna: "Oni sciigos novajn notojn"
|
||||
withFileAntenna: "Nur kun aldonaĵo"
|
||||
enableServiceworker: "Aktivigi ServiceWorker"
|
||||
withReplies: "Inkluzive respondoj"
|
||||
connectedTo: "Sekva konto estas konektita"
|
||||
notesAndReplies: "Kun respondoj"
|
||||
@ -331,10 +337,10 @@ silenceConfirm: "Ĉu vi certas ke vi volas mutigi la uzanton?"
|
||||
unsilence: "Malmutigi"
|
||||
unsilenceConfirm: "Ĉu vi certas ke vi volas malmutigi la uzanton?"
|
||||
popularUsers: "Popularaj uzantoj"
|
||||
recentlyUpdatedUsers: "Uzantoj kiuj lastatempe sendis noton"
|
||||
recentlyRegisteredUsers: "Novaliĝintaj uzantoj"
|
||||
recentlyDiscoveredUsers: "Lastatempe trovitaj uzantoj"
|
||||
exploreUsersCount: "Tio estas {count} uzantoj"
|
||||
recentlyUpdatedUsers: "Lastatempe afiŝintaj uzantoj"
|
||||
recentlyRegisteredUsers: "Lastatempe aniĝintaj uzantoj"
|
||||
recentlyDiscoveredUsers: "Lastatempe eltrovitaj uzantoj"
|
||||
exploreUsersCount: "Jen {count} uzantoj"
|
||||
exploreFediverse: "Esplori la Fediverson"
|
||||
popularTags: "Popularaj kradvortoj"
|
||||
userList: "Listoj"
|
||||
@ -348,7 +354,7 @@ nUsersMentioned: "{n} uzanto(j) menciis"
|
||||
securityKey: "Sekureca ŝlosilo"
|
||||
securityKeyName: "Nomo de la ŝlosilo"
|
||||
registerSecurityKey: "Registri ŝlosilon de sekureco"
|
||||
lastUsed: "Plej malnove uzita"
|
||||
lastUsed: "La plej malnove uzita"
|
||||
unregister: "Malregistriĝi"
|
||||
passwordLessLogin: "Saluti sen pasvorto"
|
||||
resetPassword: "Restarigi pasvorton"
|
||||
@ -359,6 +365,7 @@ notFound: "Ne trovita"
|
||||
uploadFolder: "Dosierujo implicita por alŝuto"
|
||||
cacheClear: "Malplenigi staplon"
|
||||
markAsReadAllNotifications: "Marki ĉiujn sciigojn kiel legita"
|
||||
markAsReadAllTalkMessages: "Marki ĉiujn retbabiladojn kiel legita"
|
||||
help: "Manlibro de uzado"
|
||||
inputMessageHere: "Entajpu masaĝo tie ĉi"
|
||||
close: "Fermi"
|
||||
@ -381,7 +388,7 @@ retype: "Retajpu"
|
||||
noteOf: "Noto de {user}"
|
||||
inviteToGroup: "Inviti al grupo"
|
||||
quoteAttached: "Kun citaĵo"
|
||||
quoteQuestion: "Ĉu vi aldonas citaĵon?"
|
||||
quoteQuestion: "Ĉu vi volas aldoni citaĵon?"
|
||||
noMessagesYet: "Ankoraŭ neniu mesaĝo"
|
||||
newMessageExists: "Vi ricevis novan mesaĝon."
|
||||
onlyOneFileCanBeAttached: "Oni povas aldoni nur unu dosieron po mesaĝo."
|
||||
@ -452,9 +459,9 @@ nothing: "Neniu"
|
||||
installedDate: "Dato de instalado"
|
||||
lastUsedDate: "Lastfoje uzita je"
|
||||
state: "Stato"
|
||||
sort: "Ordigado"
|
||||
ascendingOrder: "Kreski"
|
||||
descendingOrder: "Malkreski"
|
||||
sort: "Ordigi laŭ"
|
||||
ascendingOrder: "Kreska ordo"
|
||||
descendingOrder: "Malkreska ordo"
|
||||
scratchpad: "Malneta redaktilo"
|
||||
output: "Elmeto"
|
||||
script: "Skripto"
|
||||
@ -481,7 +488,7 @@ description: "Priskribo"
|
||||
describeFile: "Priskribi la bildon"
|
||||
enterFileDescription: "Priskribu"
|
||||
author: "Aŭtoro"
|
||||
manage: "Administro"
|
||||
manage: "Bonteni"
|
||||
plugins: "Kromaĵoj"
|
||||
deck: "Kartaro"
|
||||
useFullReactionPicker: "Uzi la tuton de la elektilon de reagoj"
|
||||
@ -499,14 +506,14 @@ edit: "Redakti"
|
||||
emailServer: "Retpoŝta servilo"
|
||||
enableEmail: "Ebligi dissendon el retpoŝto"
|
||||
email: "Retpoŝto"
|
||||
emailAddress: "Retpoŝtadreso"
|
||||
emailAddress: "Retpoŝta adreso"
|
||||
smtpConfig: "Agordoj de SMTP servilo"
|
||||
smtpHost: "Transa servilo"
|
||||
smtpPort: "Pordo"
|
||||
smtpUser: "Uzantnomo"
|
||||
smtpPass: "Pasvorto"
|
||||
wordMute: "Silentigi specifajn vortojn"
|
||||
userSaysSomething: "{name} parolis ion"
|
||||
userSaysSomething: "{name} diras ion"
|
||||
makeActive: "Aktivigi"
|
||||
display: "Vidi"
|
||||
copy: "Kopii"
|
||||
@ -522,7 +529,6 @@ useGlobalSetting: "Oni uzas malloka agordo"
|
||||
other: "Aliaj"
|
||||
regenerateLoginToken: "Regeneri la aŭtentikigan pecon"
|
||||
fileIdOrUrl: "Dosiera identigilo aŭ URL"
|
||||
chatOpenBehavior: "Konduto por malfermi la fenestron de babilejo"
|
||||
behavior: "Konduto"
|
||||
sample: "Ekzemplo"
|
||||
abuseReports: "Signaloj"
|
||||
@ -569,6 +575,7 @@ left: "Maldekstra"
|
||||
center: "Centra"
|
||||
wide: "Vasta"
|
||||
narrow: "Malvasta"
|
||||
needReloadToApply: "Tiu agordo estos aplikita nur poste reŝargi."
|
||||
showTitlebar: "Videbligi titolan stangon"
|
||||
clearCache: "Malplenigi staplon"
|
||||
onlineUsersCount: "{n} uzantoj estas surlineaj"
|
||||
@ -586,7 +593,7 @@ saveConfirm: "Ĉu vi konservas la ŝanĝon?"
|
||||
deleteConfirm: "Ĉu certas forviŝi?"
|
||||
closeAccount: "Forigi konton"
|
||||
currentVersion: "Nuna versio"
|
||||
latestVersion: "Plej nova versio"
|
||||
latestVersion: "La plej nova versio"
|
||||
youAreRunningUpToDateClient: "Vi uzas la plej novan version de via kliento."
|
||||
newVersionOfClientAvailable: "Nova versio de via kliento estas disponebla."
|
||||
inUse: "Uzata"
|
||||
@ -608,8 +615,9 @@ offline: "Forkonektita"
|
||||
instanceBlocking: "Bloki specifajn nodojn"
|
||||
selectAccount: "Elekti konton"
|
||||
user: "Uzantoj"
|
||||
administration: "Administro"
|
||||
administration: "Bontenado"
|
||||
accounts: "Kontoj"
|
||||
recentPosts: "Novaj afiŝoj"
|
||||
shareWithNote: "Kundividi en noto"
|
||||
ads: "Reklamaĵo"
|
||||
memo: "Memorigilo"
|
||||
@ -630,11 +638,17 @@ breakFollow: "Ĉesigi la sekvadon al vi"
|
||||
itsOn: "Ŝaltita"
|
||||
unread: "Nelegita"
|
||||
controlPanel: "Ŝaltpodio"
|
||||
manageAccounts: "Bonteni la kontojn"
|
||||
classic: "Klasika"
|
||||
ffVisibility: "Videbleco pri viaj sekvataro/sekvantaro\n"
|
||||
ffVisibilityDescription: "Agordi la videblecon kiu povas vidi tiujn kiujn vi sekvas kaj tiujn kiuj sekvas vin."
|
||||
continueThread: "Vidi pli mesaĝarojn"
|
||||
muteThread: "Silentigi la mesaĝaron"
|
||||
unmuteThread: "Malsilentigi la mesaĝaron"
|
||||
ffVisibility: "Videbleco de la sekvadoj pri vi"
|
||||
ffVisibilityDescription: "Tie ĉi vi povas agordi la videblecon pri kiuj povas vidi tiujn, kiujn vi sekvas kaj kiuj sekvas vin."
|
||||
continueThread: "Pli vidi la mesaĝaron"
|
||||
incorrectPassword: "Nevalida pasvorto"
|
||||
leaveGroup: "Eliĝi el la grupo"
|
||||
leaveGroupConfirm: "Ĉu vi certas ke vi volas eliĝi el la grupo {name}?"
|
||||
welcomeBackWithName: "Alvenbenon! {name}"
|
||||
_emailUnavailable:
|
||||
used: "La retpoŝto jam estas uzita."
|
||||
format: "Nevalida formato."
|
||||
@ -642,7 +656,7 @@ _emailUnavailable:
|
||||
smtp: "Tiu retpoŝta servilo ne respondas"
|
||||
_ffVisibility:
|
||||
public: "Publika"
|
||||
followers: "Afiŝi nur al sekvantoj"
|
||||
followers: "Nur al sekvantoj"
|
||||
private: "Malpublikigita"
|
||||
_signup:
|
||||
emailAddressInfo: "Entajpu vian retpoŝton"
|
||||
@ -662,7 +676,7 @@ _email:
|
||||
title: "Vi ricevis peton de sekvado"
|
||||
_plugin:
|
||||
install: "Instali kromaĵon"
|
||||
manage: "Administri kromaĵojn"
|
||||
manage: "Bonteni kromaĵojn"
|
||||
_registry:
|
||||
key: "Ŝlosilo"
|
||||
keys: "Ŝlosiloj"
|
||||
@ -689,6 +703,7 @@ _mfm:
|
||||
inlineMath: "Formulo (en linio)"
|
||||
blockMath: "Formulo (bloko)"
|
||||
quote: "Citi"
|
||||
emoji: "Federaj emoĵioj"
|
||||
search: "Serĉi"
|
||||
flip: "Inversa"
|
||||
x2: "Granda"
|
||||
@ -709,10 +724,12 @@ _channel:
|
||||
edit: "Redakti kanalon"
|
||||
setBanner: "Apliki standardan bildon"
|
||||
removeBanner: "Forviŝi la standardan bildon"
|
||||
owned: "Posedaĵo"
|
||||
owned: "Bontenitaj de vi"
|
||||
following: "Sekvante"
|
||||
usersCount: "{n} partoprenanto(j)"
|
||||
usersCount: "{n} partoprenantoj"
|
||||
_menuDisplay:
|
||||
sideFull: "Flanko"
|
||||
sideIcon: "Flanko (bildsimbolo)"
|
||||
top: "Supro"
|
||||
hide: "Kaŝi"
|
||||
_wordMute:
|
||||
@ -721,11 +738,12 @@ _wordMute:
|
||||
hard: "Per la servilo"
|
||||
mutedNotes: "Silentigitaj notoj"
|
||||
_theme:
|
||||
manage: "Administri kolorarojn"
|
||||
manage: "Bonteni kolorarojn"
|
||||
code: "Kolorara kodo"
|
||||
description: "Priskribo"
|
||||
defaultValue: "Implicitaĵa valoro"
|
||||
color: "Koloro"
|
||||
func: "Funkcio"
|
||||
darken: "Malbrileco"
|
||||
lighten: "Brileco"
|
||||
keys:
|
||||
@ -738,7 +756,7 @@ _theme:
|
||||
renote: "Plusendita"
|
||||
buttonBg: "Fono de butono"
|
||||
driveFolderBg: "Fono de dosierujo de la disko"
|
||||
messageBg: "Fono de retbabilejo"
|
||||
messageBg: "Fono de la retbabilejo"
|
||||
_sfx:
|
||||
note: "Nova noto"
|
||||
noteMy: "Mia noto"
|
||||
@ -778,10 +796,10 @@ _permissions:
|
||||
"write:drive": "Ĉia operacio por skribi, forviŝi, aŭ alimaniere ŝanĝi la informon de dosiero en via disko de Misskey"
|
||||
"read:favorites": "Vidi vian liston de preferaĵoj"
|
||||
"write:favorites": "Redakti vian liston de preferaĵoj"
|
||||
"read:following": "Vidi la infomaciojn pri tio, kion vi sekvas"
|
||||
"write:following": "Sekvi aŭ malsekvi alian uzanton"
|
||||
"read:messaging": "Vidi vian retbabiladon"
|
||||
"write:messaging": "Retbabilejo"
|
||||
"read:following": "Vidi la infomojn pri la sekvadoj pri vi"
|
||||
"write:following": "Sekvi/Malsekvi alian uzanton"
|
||||
"read:messaging": "Vidi viajn retbabiladojn"
|
||||
"write:messaging": "Administri viajn retbabiladojn"
|
||||
"read:mutes": "Vidi vian liston de silentigitoj"
|
||||
"write:mutes": "Redakti vian liston de silentigitoj"
|
||||
"write:notes": "Krei / Forviŝi noton"
|
||||
@ -794,7 +812,7 @@ _permissions:
|
||||
"read:channels": "Vidi kanalojn"
|
||||
_antennaSources:
|
||||
all: "Ĉiuj notoj"
|
||||
homeTimeline: "Notoj far uzantoj kiujn vi sekvas"
|
||||
homeTimeline: "Notoj de uzantoj kiujn vi sekvas"
|
||||
_weekday:
|
||||
sunday: "Dimanĉo"
|
||||
monday: "Lundo"
|
||||
@ -826,19 +844,25 @@ _poll:
|
||||
closed: "Oni jam balotis ĝin"
|
||||
_visibility:
|
||||
public: "Publika"
|
||||
publicDescription: "Afiŝi al ĉiuj en la Fediverso"
|
||||
publicDescription: "Publikigi al ĉiuj en la Fediverso"
|
||||
home: "Hejma"
|
||||
homeDescription: "Dissendi nur sur hejma templinio"
|
||||
followers: "Nur al sekvantoj"
|
||||
followersDescription: "Afiŝi nur al sekvantoj"
|
||||
specified: "Rekte"
|
||||
specifiedDescription: "Afiŝi nur al specifaj uzantoj"
|
||||
followersDescription: "Videbligi nur al sekvantoj"
|
||||
specified: "Rekte montrita"
|
||||
specifiedDescription: "Montri nur al specifaj uzantoj"
|
||||
localOnly: "Nur loka"
|
||||
localOnlyDescription: "Ne afiŝi al foraj uzantoj"
|
||||
localOnlyDescription: "Ne videbligi al foraj uzantoj"
|
||||
_postForm:
|
||||
replyPlaceholder: "Respondi la noton…"
|
||||
quotePlaceholder: "Citi la noton…"
|
||||
channelPlaceholder: "Mencii en la kanalo…"
|
||||
_placeholders:
|
||||
a: "Kiel vi fartas?"
|
||||
b: "Kio okazis ĉirkaŭ vi?"
|
||||
c: "Kion vi pensas?"
|
||||
d: "Kion vi parolos?"
|
||||
e: "Komencu skribi…"
|
||||
_profile:
|
||||
name: "Nomo"
|
||||
username: "Uzantnomo"
|
||||
@ -901,6 +925,7 @@ _pages:
|
||||
title: "Temlinio"
|
||||
url: "URL de paĝo"
|
||||
alignCenter: "Centrigi"
|
||||
hideTitleWhenPinned: "Kaŝi la titolon de la paĝo kiam alpinglita"
|
||||
chooseBlock: "Aldoni blokon"
|
||||
contentBlocks: "Enhavo"
|
||||
inputBlocks: "Enigo"
|
||||
@ -946,6 +971,9 @@ _pages:
|
||||
default: "Implicitaĵa valoro"
|
||||
script:
|
||||
categories:
|
||||
random: "Hazardo"
|
||||
value: "Valoro"
|
||||
fn: "Funkcio"
|
||||
text: "Manipulo de teksto"
|
||||
list: "Listoj"
|
||||
blocks:
|
||||
@ -963,6 +991,7 @@ _pages:
|
||||
_join:
|
||||
arg1: "Listoj"
|
||||
arg2: "apartigilo"
|
||||
random: "Hazardo"
|
||||
_randomPick:
|
||||
arg1: "Listoj"
|
||||
_dailyRandomPick:
|
||||
@ -980,6 +1009,7 @@ _pages:
|
||||
arg1: "Teksto"
|
||||
_splitStrByLine:
|
||||
arg1: "Teksto"
|
||||
fn: "Funkcio"
|
||||
_fn:
|
||||
slots: "Juntoj"
|
||||
arg1: "Elmeto"
|
||||
@ -1001,9 +1031,9 @@ _notification:
|
||||
youGotQuote: "{name} citis"
|
||||
youRenoted: "{name} plusendis"
|
||||
youGotPoll: "{name} balotis"
|
||||
youGotMessagingMessageFromUser: "{name} sentis mesaĝon al vi."
|
||||
youGotMessagingMessageFromGroup: "Retbabilan mesaĝon oni sendis al la grupo {name}"
|
||||
youWereFollowed: "eksekvis vin"
|
||||
youGotMessagingMessageFromUser: "{name} sendis al vi mesaĝon"
|
||||
youGotMessagingMessageFromGroup: "Oni sendis al la grupo {name} mesaĝon"
|
||||
youWereFollowed: "Eksekvis vin"
|
||||
youReceivedFollowRequest: "Vi ricevis peton de sekvado"
|
||||
yourFollowRequestAccepted: "Via peto de sekvado estis akceptita."
|
||||
youWereInvitedToGroup: "Invitita al grupo"
|
||||
@ -1016,7 +1046,7 @@ _notification:
|
||||
quote: "Citi"
|
||||
reaction: "Reagoj"
|
||||
receiveFollowRequest: "Ricevi peton de sekvado"
|
||||
followRequestAccepted: "Akceptita peto por sekvado"
|
||||
followRequestAccepted: "Akceptita peto de sekvado"
|
||||
groupInvited: "Invitita al grupo"
|
||||
_deck:
|
||||
profile: "Agordaro"
|
||||
|
@ -104,7 +104,6 @@ clickToShow: "Click para ver"
|
||||
sensitive: "Marcado como sensible"
|
||||
add: "Agregar"
|
||||
reaction: "Reacción"
|
||||
reactionSettingDescription: "Asigne sus reacción favoritas que desean anclar en el selector de reacciones."
|
||||
reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete la tecla + para añadir."
|
||||
rememberNoteVisibility: "Recordar visibilidad"
|
||||
attachCancel: "Quitar adjunto"
|
||||
@ -610,7 +609,6 @@ regenerateLoginToken: "Regenerar token de login"
|
||||
regenerateLoginTokenDescription: "Regenerar el token usado internamente durante el login. No siempre es necesario hacerlo. Al hacerlo de nuevo, se deslogueará en todos los dispositivos."
|
||||
setMultipleBySeparatingWithSpace: "Puedes añadir mas de uno, separado por espacios."
|
||||
fileIdOrUrl: "Id del archivo o URL"
|
||||
chatOpenBehavior: "Comportamiento al abrir el chat"
|
||||
behavior: "Comportamiento"
|
||||
sample: "Muestra"
|
||||
abuseReports: "Reportes"
|
||||
|
@ -106,7 +106,6 @@ clickToShow: "Cliquer pour afficher"
|
||||
sensitive: "Contenu sensible"
|
||||
add: "Ajouter"
|
||||
reaction: "Réactions"
|
||||
reactionSettingDescription: "Choisissez vos réactions préférées que vous souhaitez épingler dans le sélecteur de réactions."
|
||||
reactionSettingDescription2: "Déplacer pour réorganiser, cliquer pour effacer, utiliser « + » pour ajouter."
|
||||
rememberNoteVisibility: "Activer l'option \" se souvenir de la visibilité des notes \" vous permet de réutiliser automatiquement la visibilité utilisée lors de la publication de votre note précédente."
|
||||
attachCancel: "Supprimer le fichier attaché"
|
||||
@ -612,7 +611,6 @@ regenerateLoginToken: "Régénérer le jeton de connexion"
|
||||
regenerateLoginTokenDescription: "Générer un nouveau jeton d'authentification. Cette opération ne devrait pas être nécessaire ; lors de la génération d'un nouveau jeton, tous les appareils seront déconnectés. "
|
||||
setMultipleBySeparatingWithSpace: "Vous pouvez en définir plusieurs, en les séparant par des espaces."
|
||||
fileIdOrUrl: "ID du fichier ou URL"
|
||||
chatOpenBehavior: "Comportement de la fenêtre de discussion lors de son ouverture"
|
||||
behavior: "Comportement"
|
||||
sample: "Exemple"
|
||||
abuseReports: "Signalements"
|
||||
|
@ -106,7 +106,6 @@ clickToShow: "Klik untuk melihat"
|
||||
sensitive: "Konten sensitif"
|
||||
add: "Tambahkan"
|
||||
reaction: "Reaksi"
|
||||
reactionSettingDescription: "Masukkan reaksi favorit yang ingin kamu sematkan pada bilah reaksi"
|
||||
reactionSettingDescription2: "Geser untuk memindah urutkan, klik untuk menghapus, tekan \"+\" untuk menambahkan"
|
||||
rememberNoteVisibility: "Ingat pengaturan visibilitas catatan"
|
||||
attachCancel: "Hapus lampiran"
|
||||
@ -612,7 +611,6 @@ regenerateLoginToken: "Perbarui token login"
|
||||
regenerateLoginTokenDescription: "Perbarui token yang digunakan secara internal saat login. Normalnya aksi ini tidak diperlukan. Jika diperbarui, semua perangkat akan dilogout."
|
||||
setMultipleBySeparatingWithSpace: "Kamu dapat menyetel banyak dengan memisahkannya menggunakan spasi."
|
||||
fileIdOrUrl: "File-ID atau URL"
|
||||
chatOpenBehavior: "Perilaku jendelan obrolan ketika dibuka"
|
||||
behavior: "Perilaku"
|
||||
sample: "Contoh"
|
||||
abuseReports: "Laporkan"
|
||||
|
@ -103,7 +103,6 @@ clickToShow: "Clicca per visualizzare"
|
||||
sensitive: "Contenuto sensibile"
|
||||
add: "Aggiungi"
|
||||
reaction: "Reazione"
|
||||
reactionSettingDescription: "Scegli le reazioni che preferisci e fissale nel pannello di reazioni."
|
||||
reactionSettingDescription2: "Trascina per riorganizzare, clicca per cancellare, usa il pulsante \"+\" per aggiungere."
|
||||
rememberNoteVisibility: "Ricordare le impostazioni di visibilità delle note"
|
||||
attachCancel: "Rimuovi allegato"
|
||||
@ -591,7 +590,6 @@ other: "Avanzate"
|
||||
regenerateLoginToken: "Genera di nuovo un token di connessione"
|
||||
regenerateLoginTokenDescription: "Genera un nuovo token di autenticazione. Solitamente questa operazione non è necessaria: quando si genera un nuovo token, tutti i dispositivi vanno disconnessi."
|
||||
fileIdOrUrl: "ID o URL del file"
|
||||
chatOpenBehavior: "Comportamento della finestra di chat quando viene aperta"
|
||||
behavior: "Comportamento"
|
||||
abuseReports: "Segnalazioni"
|
||||
reportAbuse: "Segnalazioni"
|
||||
|
@ -448,6 +448,7 @@ uiLanguage: "UIの表示言語"
|
||||
groupInvited: "グループに招待されました"
|
||||
aboutX: "{x}について"
|
||||
useOsNativeEmojis: "OSネイティブの絵文字を使用"
|
||||
disableDrawer: "メニューをドロワーで表示しない"
|
||||
youHaveNoGroups: "グループがありません"
|
||||
joinOrCreateGroup: "既存のグループに招待してもらうか、新しくグループを作成してください。"
|
||||
noHistory: "履歴はありません"
|
||||
@ -613,7 +614,6 @@ regenerateLoginToken: "ログイントークンを再生成"
|
||||
regenerateLoginTokenDescription: "ログインに使用される内部トークンを再生成します。通常この操作を行う必要はありません。再生成すると、全てのデバイスでログアウトされます。"
|
||||
setMultipleBySeparatingWithSpace: "スペースで区切って複数設定できます。"
|
||||
fileIdOrUrl: "ファイルIDまたはURL"
|
||||
chatOpenBehavior: "チャットを開くときの動作"
|
||||
behavior: "動作"
|
||||
sample: "サンプル"
|
||||
abuseReports: "通報"
|
||||
@ -685,6 +685,7 @@ center: "中央"
|
||||
wide: "広い"
|
||||
narrow: "狭い"
|
||||
reloadToApplySetting: "設定はページリロード後に反映されます。今すぐリロードしますか?"
|
||||
needReloadToApply: "反映には再起動が必要です。"
|
||||
showTitlebar: "タイトルバーを表示する"
|
||||
clearCache: "キャッシュをクリア"
|
||||
onlineUsersCount: "{n}人がオンライン"
|
||||
@ -816,6 +817,8 @@ hide: "隠す"
|
||||
leaveGroup: "グループから抜ける"
|
||||
leaveGroupConfirm: "「{name}」から抜けますか?"
|
||||
useDrawerReactionPickerForMobile: "モバイルデバイスのときドロワーで表示"
|
||||
welcomeBackWithName: "おかえりなさい、{name}さん"
|
||||
clickToFinishEmailVerification: "[{ok}]を押して、メールアドレスの確認を完了してください。"
|
||||
|
||||
_emailUnavailable:
|
||||
used: "既に使用されています"
|
||||
|
@ -104,7 +104,6 @@ clickToShow: "押したら見えるで"
|
||||
sensitive: "ちょっとアカンやつやで"
|
||||
add: "増やす"
|
||||
reaction: "リアクション"
|
||||
reactionSettingDescription: "リアクションピッカーに出しとくリアクションを選んでや。"
|
||||
reactionSettingDescription2: "ドラッグで並び替え、クリックで削除、+を押して追加やで。"
|
||||
rememberNoteVisibility: "公開範囲覚えといて"
|
||||
attachCancel: "のっけるのやめる"
|
||||
@ -204,7 +203,7 @@ noJobs: "ジョブはあらへん"
|
||||
federating: "連合しとる"
|
||||
blocked: "ブロックしとる"
|
||||
suspended: "配信せぇへん"
|
||||
all: "みな"
|
||||
all: "みんな"
|
||||
subscribing: "購読しとる"
|
||||
publishing: "配信しとる"
|
||||
notResponding: "応答してへんで"
|
||||
@ -849,7 +848,7 @@ _permissions:
|
||||
_auth:
|
||||
permissionAsk: "このアプリは次の権限を要求しとるで"
|
||||
_antennaSources:
|
||||
all: "みなのノート"
|
||||
all: "みんなのノート"
|
||||
homeTimeline: "フォローしとるユーザーのノート"
|
||||
_weekday:
|
||||
sunday: "日曜日"
|
||||
@ -897,7 +896,7 @@ _poll:
|
||||
votesCount: "{n}票"
|
||||
vote: "投票する"
|
||||
_visibility:
|
||||
publicDescription: "みなのユーザーに公開"
|
||||
publicDescription: "みんなに公開"
|
||||
home: "ホーム"
|
||||
followers: "フォロワー"
|
||||
_profile:
|
||||
|
@ -106,7 +106,6 @@ clickToShow: "클릭하여 보기"
|
||||
sensitive: "열람주의"
|
||||
add: "추가"
|
||||
reaction: "리액션"
|
||||
reactionSettingDescription: "리액션 선택 상자에 표시할 리액션을 설정합니다."
|
||||
reactionSettingDescription2: "끌어서 순서 변경, 클릭해서 삭제, +를 눌러서 추가할 수 있습니다."
|
||||
rememberNoteVisibility: "공개 범위를 기억하기"
|
||||
attachCancel: "첨부 취소"
|
||||
@ -613,7 +612,6 @@ regenerateLoginToken: "로그인 토큰을 재생성"
|
||||
regenerateLoginTokenDescription: "로그인할 때 사용되는 내부 토큰을 재생성합니다. 일반적으로 이 작업을 실행할 필요는 없습니다. 이 기능을 사용하면 이 계정으로 로그인한 모든 기기에서 로그아웃됩니다."
|
||||
setMultipleBySeparatingWithSpace: "공백으로 구분하여 여러 개 설정할 수 있습니다."
|
||||
fileIdOrUrl: "파일 ID 또는 URL"
|
||||
chatOpenBehavior: "대화를 열 때의 동작"
|
||||
behavior: "동작"
|
||||
sample: "예시"
|
||||
abuseReports: "신고"
|
||||
|
@ -106,7 +106,6 @@ clickToShow: "Klik om te bekijken"
|
||||
sensitive: "NSFW"
|
||||
add: "Toevoegen"
|
||||
reaction: "Reacties"
|
||||
reactionSettingDescription: "Configureer welke reacties je wilt weergeven in de reactiekiezer."
|
||||
reactionSettingDescription2: "Sleep om opnieuw te ordenen, Klik om te verwijderen, Druk op \"+\" om toe te voegen"
|
||||
rememberNoteVisibility: "Vergeet niet de notitie zichtbaarheidsinstellingen"
|
||||
attachCancel: "Verwijder bijlage"
|
||||
|
@ -81,6 +81,8 @@ somethingHappened: "Coś poszło nie tak"
|
||||
retry: "Spróbuj ponownie"
|
||||
pageLoadError: "Nie udało się załadować strony"
|
||||
pageLoadErrorDescription: "Zwykle jest to spowodowane problemem z siecią lub cache przeglądarki. Spróbuj wyczyścić cache i sprawdź jeszcze raz za chwilę."
|
||||
serverIsDead: "Serwer nie odpowiada. Zaczekaj chwilę i spróbuj ponownie."
|
||||
youShouldUpgradeClient: "Odśwież stronę, by zaaktualizować klienta."
|
||||
enterListName: "Nazwa listy"
|
||||
privacy: "Prywatność"
|
||||
makeFollowManuallyApprove: "Prośby o możliwość obserwacji wymagają zatwierdzenia"
|
||||
@ -104,7 +106,7 @@ clickToShow: "Kliknij, aby wyświetlić"
|
||||
sensitive: "NSFW"
|
||||
add: "Dodaj"
|
||||
reaction: "Reakcja"
|
||||
reactionSettingDescription: "Przypisz swoje ulubione reakcje, które chcesz przypiąć w wyborze reakcji."
|
||||
reactionSetting: "Reakcje do pokazania w wyborniku reakcji"
|
||||
reactionSettingDescription2: "Przeciągnij aby zmienić kolejność, naciśnij aby usunąć, naciśnij „+” aby dodać"
|
||||
rememberNoteVisibility: "Zapamiętuj ustawienia widoczności wpisu"
|
||||
attachCancel: "Usuń załącznik"
|
||||
@ -181,6 +183,7 @@ instanceInfo: "Informacje o instancji"
|
||||
statistics: "Statystyki"
|
||||
clearQueue: "Wyczyść kolejkę"
|
||||
clearQueueConfirmTitle: "Czy na pewno chcesz wyczyścić kolejkę?"
|
||||
clearQueueConfirmText: "Wszystkie niewysłane wpisy z kolejki nie zostaną wysłane. Zwykle to nie jest konieczne."
|
||||
clearCachedFiles: "Wyczyść pamięć podręczną"
|
||||
clearCachedFilesConfirm: "Czy na pewno chcesz usunąć wszystkie zdalne pliki z pamięci podręcznej?"
|
||||
blockedInstances: "Zablokowane instancje"
|
||||
@ -220,6 +223,7 @@ more: "Więcej!"
|
||||
featured: "Wyróżnione"
|
||||
usernameOrUserId: "Nazwa lub id użytkownika"
|
||||
noSuchUser: "Nie znaleziono użytkownika"
|
||||
lookup: "Zapytania"
|
||||
announcements: "Ogłoszenia"
|
||||
imageUrl: "Adres URL obrazka"
|
||||
remove: "Usuń"
|
||||
@ -309,22 +313,28 @@ monthX: "{month}"
|
||||
yearX: "{year}"
|
||||
pages: "Strony"
|
||||
integration: "Integracja"
|
||||
connectService: "Połącz"
|
||||
disconnectService: "Rozłącz"
|
||||
enableLocalTimeline: "Włącz lokalną oś czasu"
|
||||
enableGlobalTimeline: "Włącz globalną oś czasu"
|
||||
disablingTimelinesInfo: "Administratorzy i moderatorzy będą zawsze mieć dostęp do wszystkich osi czasu, nawet gdy są one wyłączone."
|
||||
registration: "Zarejestruj się"
|
||||
enableRegistration: "Włącz rejestrację nowych użytkowników"
|
||||
invite: "Zaproś"
|
||||
proxyRemoteFiles: "Przekierowuj pliki obcych instancji przez proxy"
|
||||
proxyRemoteFilesDescription: "Gdy ta opcja jest włączona, zdalne pliki które nie są przechowywane lokalnie, lub zostały usunięte z powodu przekroczenia limitu miejsca będą kierowane przez proxy, razem z generowaniem miniatur. Nie ma to żadnego wpływu na przestrzeń dyskową serwera."
|
||||
driveCapacityPerLocalAccount: "Powierzchnia dyskowa na lokalnego użytkownika"
|
||||
driveCapacityPerRemoteAccount: "Powierzchnia dyskowa na zdalnego użytkownika"
|
||||
inMb: "W megabajtach"
|
||||
iconUrl: "Adres URL ikony"
|
||||
bannerUrl: "Adres URL banera"
|
||||
backgroundImageUrl: "Adres URL tła"
|
||||
basicInfo: "Podstawowe informacje"
|
||||
pinnedUsers: "Przypięty użytkownik"
|
||||
pinnedUsersDescription: "Wypisz po jednej nazwie użytkownika w wierszu. Podani użytkownicy zostaną przypięci pod kartą „Eksploruj”."
|
||||
pinnedPages: "Przypięte strony"
|
||||
pinnedPagesDescription: "Wprowadź ścieżki stron które chcesz przypiąć na głównej stronie instancji, oddzielone znakiem nowego wiersza."
|
||||
pinnedClipId: "ID przypiętego klipu"
|
||||
pinnedNotes: "Przypięty wpis"
|
||||
hcaptcha: "hCaptcha"
|
||||
enableHcaptcha: "Włącz hCaptcha"
|
||||
@ -339,7 +349,9 @@ antennas: "Anteny"
|
||||
manageAntennas: "Zarządzaj Antenami"
|
||||
name: "Nazwa"
|
||||
antennaSource: "Źródło Anteny"
|
||||
antennaKeywords: "Słowa kluczowe do obserwacji"
|
||||
antennaExcludeKeywords: "Wykluczone słowa kluczowe"
|
||||
antennaKeywordsDescription: "Oddziel spacjami dla warunku AND, albo wymuś koniec linii dla warunku OR"
|
||||
notifyAntenna: "Powiadamiaj o nowych wpisach"
|
||||
withFileAntenna: "Filtruj tylko wpisy z załączonym plikiem"
|
||||
enableServiceworker: "Włącz ServiceWorker"
|
||||
@ -587,8 +599,9 @@ useGlobalSetting: "Użyj globalnych ustawień"
|
||||
useGlobalSettingDesc: "Jeżeli włączone, zostaną wykorzystane ustawienia powiadomień Twojego konta. Jeżeli wyłączone, mogą zostać wykonane oddzielne konfiguracje."
|
||||
other: "Inne"
|
||||
regenerateLoginToken: "Generuj token logowania ponownie"
|
||||
regenerateLoginTokenDescription: "Regeneruje token używany wewnętrznie podczas logowania. Zazwyczaj nie jest to konieczne. Po regeneracji wszystkie urządzenia zostaną wylogowane."
|
||||
setMultipleBySeparatingWithSpace: "Możesz ustawić wiele, oddzielając je spacjami."
|
||||
chatOpenBehavior: "Zachowanie okna czatu po otwarciu"
|
||||
fileIdOrUrl: "ID pliku albo URL"
|
||||
behavior: "Zachowanie"
|
||||
sample: "Przykład"
|
||||
abuseReports: "Zgłoszenia"
|
||||
@ -596,6 +609,8 @@ reportAbuse: "Zgłoś"
|
||||
reportAbuseOf: "Zgłoś {name}"
|
||||
fillAbuseReportDescription: "Wypełnij szczegóły zgłoszenia. Jeżeli dotyczy ono określonego wpisu, uwzględnij jego adres URL."
|
||||
abuseReported: "Twoje zgłoszenie zostało wysłane. Dziękujemy."
|
||||
reporteeOrigin: "Pochodzenie zgłoszonego"
|
||||
reporterOrigin: "Pochodzenie zgłaszającego"
|
||||
send: "Wyślij"
|
||||
abuseMarkAsResolved: "Oznacz zgłoszenie jako rozwiązane"
|
||||
openInNewTab: "Otwórz w nowej karcie"
|
||||
@ -608,7 +623,7 @@ random: "Losowe"
|
||||
system: "System"
|
||||
switchUi: "Przełącz interfejs użytkownika"
|
||||
desktop: "Pulpit"
|
||||
createNew: "Utworzy nowy"
|
||||
createNew: "Utwórz nowy"
|
||||
optional: "Nieobowiązkowe"
|
||||
public: "Publiczny"
|
||||
i18nInfo: "Misskey jest tłumaczone na wiele języków przez wolontariuszy. Możesz pomóc na {link}."
|
||||
@ -631,6 +646,7 @@ driveFilesCount: "Liczba plików na dysku"
|
||||
driveUsage: "Użycie przestrzeni dyskowej"
|
||||
noCrawle: "Odrzuć indeksowanie przez crawlery"
|
||||
noCrawleDescription: "Proś wyszukiwarki internetowe, aby nie indeksowały Twojego profilu, wpisów, stron itd."
|
||||
lockedAccountInfo: "Dopóki nie ustawisz widoczności wpisu na \"Obserwujący\", twoje wpisy będą mogli widzieć wszyscy, nawet jeśli ustawisz manualne zatwierdzanie obserwujących."
|
||||
alwaysMarkSensitive: "Oznacz domyślnie jako NSFW"
|
||||
loadRawImages: "Wyświetlaj zdjęcia w załącznikach w całości zamiast miniatur"
|
||||
disableShowingAnimatedImages: "Nie odtwarzaj animowanych obrazów"
|
||||
@ -654,6 +670,7 @@ center: "Wyśsrodkuj"
|
||||
wide: "Szerokie"
|
||||
narrow: "Wąskie"
|
||||
reloadToApplySetting: "To ustawienie zostanie zastosowane po odświeżeniu strony. Chcesz odświeżyć?"
|
||||
needReloadToApply: "To ustawienie zostanie zastosowane po odświeżeniu strony"
|
||||
showTitlebar: "Pokazuj pasek tytułowy"
|
||||
clearCache: "Wyczyść pamięć podręczną"
|
||||
onlineUsersCount: "{n} osób jest online"
|
||||
@ -698,6 +715,8 @@ unlikeConfirm: "Na pewno chcesz usunąć polubienie?"
|
||||
fullView: "Pełny widok"
|
||||
quitFullView: "Opuść pełny widok"
|
||||
addDescription: "Dodaj opis"
|
||||
userPagePinTip: "Możesz wyświetlać wpisy w tym miejscu po wybraniu \"Przypnij do profilu\" z menu pojedyńczego wpisu"
|
||||
notSpecifiedMentionWarning: "Ten wpis zawiera wzmianki o użytkownikach niezawartych jako odbiorcy"
|
||||
info: "Informacje"
|
||||
userInfo: "Informacje o użykowniku"
|
||||
unknown: "Nieznane"
|
||||
@ -735,9 +754,15 @@ middle: "Średnie"
|
||||
low: "Niski"
|
||||
emailNotConfiguredWarning: "Nie podano adresu e-mail"
|
||||
ratio: "Stosunek"
|
||||
previewNoteText: "Pokaż podgląd"
|
||||
customCss: "Własny CSS"
|
||||
customCssWarn: "Używaj tego ustawienia tylko wtedy, gdy wiesz co ono robi. Nieprawidłowe wpisy mogą spowodować, że klient przestanie działać poprawnie."
|
||||
global: "Globalna"
|
||||
squareAvatars: "Wyświetlaj kwadratowe awatary"
|
||||
sent: "Wyślij"
|
||||
received: "Otrzymane"
|
||||
hashtags: "Hashtag"
|
||||
pubSub: "Konta Pub/Sub"
|
||||
hide: "Ukryj"
|
||||
_ffVisibility:
|
||||
public: "Publikuj"
|
||||
@ -978,6 +1003,7 @@ _tutorial:
|
||||
step1_3: "Twoja oś czasu jest jeszcze pusta, ponieważ nie opublikowałeś(-aś) jeszcze żadnych wpisów i nie obserwujesz jeszcze nikogo."
|
||||
step2_1: "Ukończmy konfigurację profilu zanim utworzymy wpis lub zaczniemy kogoś obserwować."
|
||||
step3_1: "Zakończyłeś(-aś) konfigurację profilu?"
|
||||
step3_3: "Wypełnij pole i kliknij przycisk w prawym górnym rogu by wysłać post."
|
||||
_2fa:
|
||||
registerDevice: "Zarejestruj nowe urządzenie"
|
||||
step1: "Najpierw, zainstaluj aplikację uwierzytelniającą (taką jak {a} lub {b}) na swoim urządzeniu."
|
||||
@ -1049,7 +1075,7 @@ _poll:
|
||||
deadlineDate: "Data zakończenia"
|
||||
deadlineTime: "godz."
|
||||
duration: "Czas trwania"
|
||||
votesCount: "{} głosów"
|
||||
votesCount: "{n} głosów"
|
||||
totalVotes: "Łącznie {n} głosów"
|
||||
vote: "Głosowanie w ankiecie"
|
||||
showResult: "Pokaż wyniki"
|
||||
|
@ -106,7 +106,6 @@ clickToShow: "Нажмите для просмотра"
|
||||
sensitive: "Содержимое не для всех"
|
||||
add: "Добавить"
|
||||
reaction: "Реакции"
|
||||
reactionSettingDescription: "Подберите, что будет у вас в палитре реакций"
|
||||
reactionSettingDescription2: "Расставляйте перетаскиванием, удаляйте нажатием, добавляйте кнопкой «+»."
|
||||
rememberNoteVisibility: "Запоминать видимость заметок"
|
||||
attachCancel: "Удалить вложение"
|
||||
@ -612,7 +611,6 @@ regenerateLoginToken: "Создать новый токен для входа"
|
||||
regenerateLoginTokenDescription: "Создаёт новый токен, используемый внутри программы во время входа. Обычно в этом нет необходимости. При создании все устройства будут отключены."
|
||||
setMultipleBySeparatingWithSpace: "Можно написать несколько через пробел"
|
||||
fileIdOrUrl: "Идентификатор файла или ссылка"
|
||||
chatOpenBehavior: "Поведение окна чата при открытии"
|
||||
behavior: "Поведение"
|
||||
sample: "Пример"
|
||||
abuseReports: "Жалобы"
|
||||
@ -684,6 +682,7 @@ center: "По центру"
|
||||
wide: "Толстый"
|
||||
narrow: "Тонкий"
|
||||
reloadToApplySetting: "Это настройка вступает в силу при загрузке страницы. Перезагрузить сейчас?"
|
||||
needReloadToApply: "Чтобы это вступило в силу, требуется перезагрузка."
|
||||
showTitlebar: "Показать заголовок"
|
||||
clearCache: "Очистить кэш"
|
||||
onlineUsersCount: "Пользователей сейчас в сети: {n}"
|
||||
@ -802,10 +801,16 @@ makeReactionsPublicDescription: "Список сделанных вами реа
|
||||
classic: "Классика"
|
||||
unmuteThread: "Отключить звук"
|
||||
ffVisibilityDescription: "Вы можете установить объем вашей следующей/последней информации."
|
||||
voteConfirm: "Вы бы проголосовали за \"{choice}\"?"
|
||||
hide: "Спрятать"
|
||||
leaveGroup: "Покинуть группу"
|
||||
leaveGroupConfirm: "Вы хотите оставить \"{name}\"?"
|
||||
welcomeBackWithName: "С возвращением, {name}!"
|
||||
clickToFinishEmailVerification: "Пожалуйста, нажмите [{ok}], чтобы завершить подтверждение адреса электронной почты."
|
||||
_emailUnavailable:
|
||||
used: "Уже используется"
|
||||
format: "Неправильный формат"
|
||||
mx: "Это неправильный почтовый сервер!"
|
||||
smtp: "Почтовый сервер не отвечает"
|
||||
_ffVisibility:
|
||||
public: "Опубликовать"
|
||||
@ -1263,6 +1268,7 @@ _exportOrImport:
|
||||
muteList: "Скрытые"
|
||||
blockingList: "Заблокированные"
|
||||
userLists: "Списки"
|
||||
excludeMutingUsers: "Исключение отключенных пользователей"
|
||||
_charts:
|
||||
federationInstancesIncDec: "Изменение внешних связей"
|
||||
federationInstancesTotal: "Количество внешних связей"
|
||||
|
@ -103,7 +103,6 @@ clickToShow: "Натисніть для перегляду"
|
||||
sensitive: "NSFW"
|
||||
add: "Додати"
|
||||
reaction: "Реакції"
|
||||
reactionSettingDescription: "Виберіть свої улюблені реакції, які хочете закріпити в селекторі реакцій."
|
||||
reactionSettingDescription2: "Перемістити щоб змінити порядок, Клацнути мишою щоб видалити, Натиснути \"+\" щоб додати."
|
||||
rememberNoteVisibility: "Пам’ятати параметри видимісті"
|
||||
attachCancel: "Видалити вкладення"
|
||||
@ -593,7 +592,6 @@ regenerateLoginToken: "Оновити Login Token"
|
||||
regenerateLoginTokenDescription: "Регенерувати внутрішній ключ використовуваний під час входу. Зазвичай цього не потрібно робити. При регенерації всі пристрої вийдуть з системи."
|
||||
setMultipleBySeparatingWithSpace: "Можна вказати кілька значень, відділивши їх пробілом."
|
||||
fileIdOrUrl: "Ідентифікатор файлу або посилання"
|
||||
chatOpenBehavior: "Поводження вікна переписки під час відкриття"
|
||||
behavior: "Поведінка"
|
||||
sample: "Приклад"
|
||||
abuseReports: "Скарги"
|
||||
|
@ -106,7 +106,7 @@ clickToShow: "点击以显示"
|
||||
sensitive: "敏感内容"
|
||||
add: "添加"
|
||||
reaction: "回应"
|
||||
reactionSettingDescription: "选择您想要置顶的回应。"
|
||||
reactionSetting: "在选择器中显示的回应"
|
||||
reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。"
|
||||
rememberNoteVisibility: "保存上次设置的可见性"
|
||||
attachCancel: "删除附件"
|
||||
@ -448,6 +448,7 @@ uiLanguage: "显示语言"
|
||||
groupInvited: "您有新的群组邀请"
|
||||
aboutX: "关于 {x}"
|
||||
useOsNativeEmojis: "使用系统的原生表情符号"
|
||||
disableDrawer: "不显示抽屉菜单"
|
||||
youHaveNoGroups: "没有群组"
|
||||
joinOrCreateGroup: "请加入一个现有的群组,或者创建新群组。"
|
||||
noHistory: "没有历史记录"
|
||||
@ -613,7 +614,6 @@ regenerateLoginToken: "重新生成登录令牌"
|
||||
regenerateLoginTokenDescription: "重新生成用于登录的内部令牌。通常您不需要这样做。重新生成后,您将在所有设备上登出。"
|
||||
setMultipleBySeparatingWithSpace: "您可以使用空格分隔多个项目。"
|
||||
fileIdOrUrl: "文件ID或者URL"
|
||||
chatOpenBehavior: "聊天窗口打开时的行为"
|
||||
behavior: "行为"
|
||||
sample: "示例"
|
||||
abuseReports: "举报"
|
||||
@ -685,6 +685,7 @@ center: "中央"
|
||||
wide: "宽"
|
||||
narrow: "窄"
|
||||
reloadToApplySetting: "页面刷新后设置才会生效。是否现在刷新页面?"
|
||||
needReloadToApply: "重启后应用才会生效。"
|
||||
showTitlebar: "显示标题栏"
|
||||
clearCache: "清除缓存"
|
||||
onlineUsersCount: "{n}人在线"
|
||||
@ -813,6 +814,11 @@ deleteAccountConfirm: "将要删除账户。是否确认?"
|
||||
incorrectPassword: "密码错误"
|
||||
voteConfirm: "确定投给“{choice}” ?"
|
||||
hide: "隐藏"
|
||||
leaveGroup: "离开群组"
|
||||
leaveGroupConfirm: "确定离开「{name}」?"
|
||||
useDrawerReactionPickerForMobile: "在移动设备上使用抽屉显示"
|
||||
welcomeBackWithName: "欢迎回来,{name}"
|
||||
clickToFinishEmailVerification: "点击 [{ok}] 完成电子邮件地址认证。"
|
||||
_emailUnavailable:
|
||||
used: "已经被使用过"
|
||||
format: "无效的格式"
|
||||
|
@ -104,7 +104,6 @@ clickToShow: "按一下以顯示"
|
||||
sensitive: "敏感內容"
|
||||
add: "新增"
|
||||
reaction: "情感"
|
||||
reactionSettingDescription: "置頂「反應」表情符號\n"
|
||||
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
|
||||
rememberNoteVisibility: "記住貼文可見性"
|
||||
attachCancel: "移除附件"
|
||||
@ -598,7 +597,6 @@ regenerateLoginToken: "重新產生登入權杖"
|
||||
regenerateLoginTokenDescription: "重新產生用於登入的內部權杖。一般情況下是不需要這樣做的。一旦重產,所有裝置將會被登出。"
|
||||
setMultipleBySeparatingWithSpace: "您可以使用空格分隔多個項目。"
|
||||
fileIdOrUrl: "檔案ID或URL"
|
||||
chatOpenBehavior: "開啟聊天窗口時的行為"
|
||||
behavior: "行為"
|
||||
sample: "範例"
|
||||
abuseReports: "檢舉"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"version": "12.100.1",
|
||||
"version": "12.101.1",
|
||||
"codename": "indigo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -168,7 +168,7 @@ export function fromHtml(html: string, hashtagNames?: string[]): string | null {
|
||||
case 'blockquote': {
|
||||
const t = getText(node);
|
||||
if (t) {
|
||||
text += '> ';
|
||||
text += '\n> ';
|
||||
text += t.split('\n').join(`\n> `);
|
||||
}
|
||||
break;
|
||||
|
@ -99,7 +99,10 @@ export async function getFileInfo(path: string): Promise<FileInfo> {
|
||||
/**
|
||||
* Detect MIME Type and extension
|
||||
*/
|
||||
export async function detectType(path: string) {
|
||||
export async function detectType(path: string): Promise<{
|
||||
mime: string;
|
||||
ext: string | null;
|
||||
}> {
|
||||
// Check 0 byte
|
||||
const fileSize = await getFileSize(path);
|
||||
if (fileSize === 0) {
|
||||
|
@ -65,7 +65,8 @@ export async function exportCustomEmojis(job: Bull.Job, done: () => void): Promi
|
||||
|
||||
for (const emoji of customEmojis) {
|
||||
const exportId = ulid().toLowerCase();
|
||||
const emojiPath = path + '/' + exportId + '.' + mime.extension(emoji.type);
|
||||
const ext = mime.extension(emoji.type);
|
||||
const emojiPath = path + '/' + exportId + (ext ? '.' + ext : '');
|
||||
fs.writeFileSync(emojiPath, '', 'binary');
|
||||
let downloaded = false;
|
||||
|
||||
|
@ -4,6 +4,7 @@ block vars
|
||||
- const user = note.user;
|
||||
- const title = user.name ? `${user.name} (@${user.username})` : `@${user.username}`;
|
||||
- const url = `${config.url}/notes/${note.id}`;
|
||||
- const isRenote = note.renote && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
||||
|
||||
block title
|
||||
= `${title} | ${instanceName}`
|
||||
@ -19,7 +20,7 @@ block og
|
||||
meta(property='og:image' content= user.avatarUrl)
|
||||
|
||||
block meta
|
||||
if user.host || profile.noCrawle
|
||||
if user.host || isRenote || profile.noCrawle
|
||||
meta(name='robots' content='noindex')
|
||||
|
||||
meta(name='misskey:user-username' content=user.username)
|
||||
|
@ -3,10 +3,33 @@ import config from '@/config/index';
|
||||
import { SwSubscriptions } from '@/models/index';
|
||||
import { fetchMeta } from '@/misc/fetch-meta';
|
||||
import { Packed } from '@/misc/schema';
|
||||
import { getNoteSummary } from '@/misc/get-note-summary';
|
||||
|
||||
type notificationType = 'notification' | 'unreadMessagingMessage';
|
||||
type notificationBody = Packed<'Notification'> | Packed<'MessagingMessage'>;
|
||||
|
||||
// プッシュメッセージサーバーには文字数制限があるため、内容を削減します
|
||||
function truncateNotification(notification: Packed<'Notification'>): any {
|
||||
if (notification.note) {
|
||||
return {
|
||||
...notification,
|
||||
note: {
|
||||
...notification.note,
|
||||
// textをgetNoteSummaryしたものに置き換える
|
||||
text: getNoteSummary(notification.type === 'renote' ? notification.note.renote as Packed<'Note'> : notification.note),
|
||||
...{
|
||||
cw: undefined,
|
||||
reply: undefined,
|
||||
renote: undefined,
|
||||
user: undefined as any, // 通知を受け取ったユーザーである場合が多いのでこれも捨てる
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return notification;
|
||||
}
|
||||
|
||||
export default async function(userId: string, type: notificationType, body: notificationBody) {
|
||||
const meta = await fetchMeta();
|
||||
|
||||
@ -32,7 +55,9 @@ export default async function(userId: string, type: notificationType, body: noti
|
||||
};
|
||||
|
||||
push.sendNotification(pushSubscription, JSON.stringify({
|
||||
type, body,
|
||||
type,
|
||||
body: type === 'notification' ? truncateNotification(body as Packed<'Notification'>) : body,
|
||||
userId,
|
||||
}), {
|
||||
proxy: config.proxy,
|
||||
}).catch((err: any) => {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 185 B |
@ -27,39 +27,39 @@
|
||||
"@types/oauth": "0.9.1",
|
||||
"@types/parse5": "6.0.3",
|
||||
"@types/punycode": "2.1.0",
|
||||
"@types/qrcode": "1.4.1",
|
||||
"@types/qrcode": "1.4.2",
|
||||
"@types/random-seed": "0.3.3",
|
||||
"@types/request-stats": "3.0.0",
|
||||
"@types/seedrandom": "2.4.28",
|
||||
"@types/throttle-debounce": "2.1.0",
|
||||
"@types/tinycolor2": "1.4.3",
|
||||
"@types/tmp": "0.2.2",
|
||||
"@types/tmp": "0.2.3",
|
||||
"@types/uuid": "8.3.3",
|
||||
"@types/web-push": "3.3.2",
|
||||
"@types/webpack": "5.28.0",
|
||||
"@types/webpack-stream": "3.2.12",
|
||||
"@types/websocket": "1.0.4",
|
||||
"@types/ws": "8.2.2",
|
||||
"@typescript-eslint/parser": "5.6.0",
|
||||
"@vue/compiler-sfc": "3.2.24",
|
||||
"@typescript-eslint/parser": "5.8.1",
|
||||
"@vue/compiler-sfc": "3.2.26",
|
||||
"abort-controller": "3.0.0",
|
||||
"autobind-decorator": "2.4.0",
|
||||
"autosize": "4.0.4",
|
||||
"autwh": "0.1.0",
|
||||
"blurhash": "1.1.4",
|
||||
"broadcast-channel": "4.7.0",
|
||||
"chart.js": "3.6.2",
|
||||
"broadcast-channel": "4.9.0",
|
||||
"chart.js": "3.7.0",
|
||||
"chartjs-adapter-date-fns": "2.0.0",
|
||||
"chartjs-plugin-zoom": "1.2.0",
|
||||
"compare-versions": "3.6.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-disposition": "0.5.4",
|
||||
"crc-32": "1.2.0",
|
||||
"css-loader": "6.5.1",
|
||||
"cssnano": "5.0.12",
|
||||
"date-fns": "2.27.0",
|
||||
"cssnano": "5.0.14",
|
||||
"date-fns": "2.28.0",
|
||||
"dateformat": "4.5.1",
|
||||
"escape-regexp": "0.0.1",
|
||||
"eslint": "8.4.1",
|
||||
"eslint": "8.5.0",
|
||||
"eslint-plugin-vue": "8.2.0",
|
||||
"eventemitter3": "4.0.7",
|
||||
"feed": "4.2.2",
|
||||
@ -80,7 +80,7 @@
|
||||
"parse5": "6.0.1",
|
||||
"photoswipe": "git://github.com/dimsemenov/photoswipe#v5-beta",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss": "8.4.4",
|
||||
"postcss": "8.4.5",
|
||||
"postcss-loader": "6.2.1",
|
||||
"prismjs": "1.25.0",
|
||||
"private-ip": "2.3.3",
|
||||
@ -94,7 +94,7 @@
|
||||
"request-stats": "3.0.0",
|
||||
"rndstr": "1.0.0",
|
||||
"s-age": "1.1.2",
|
||||
"sass": "1.44.0",
|
||||
"sass": "1.45.1",
|
||||
"sass-loader": "12.4.0",
|
||||
"seedrandom": "3.0.5",
|
||||
"strict-event-emitter-types": "2.0.0",
|
||||
@ -111,11 +111,11 @@
|
||||
"tsc-alias": "1.4.2",
|
||||
"tsconfig-paths": "3.12.0",
|
||||
"twemoji-parser": "13.1.0",
|
||||
"typescript": "4.5.2",
|
||||
"typescript": "4.5.4",
|
||||
"uuid": "8.3.2",
|
||||
"v-debounce": "0.1.2",
|
||||
"vanilla-tilt": "1.7.2",
|
||||
"vue": "3.2.24",
|
||||
"vue": "3.2.26",
|
||||
"vue-loader": "16.8.3",
|
||||
"vue-prism-editor": "2.0.0-alpha.2",
|
||||
"vue-router": "4.0.5",
|
||||
@ -126,14 +126,14 @@
|
||||
"webpack": "5.65.0",
|
||||
"webpack-cli": "4.9.1",
|
||||
"websocket": "1.0.34",
|
||||
"ws": "8.3.0"
|
||||
"ws": "8.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@redocly/openapi-core": "1.0.0-beta.54",
|
||||
"@types/fluent-ffmpeg": "2.1.17",
|
||||
"@typescript-eslint/eslint-plugin": "5.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.8.1",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "8.5.0",
|
||||
"cypress": "9.2.0",
|
||||
"eslint-plugin-import": "2.25.3",
|
||||
"start-server-and-test": "1.14.0"
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { del, get, set } from '@/scripts/idb-proxy';
|
||||
import { reactive } from 'vue';
|
||||
import * as misskey from 'misskey-js';
|
||||
import { apiUrl } from '@/config';
|
||||
import { waiting, api, popup, popupMenu, success } from '@/os';
|
||||
import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
|
||||
@ -8,13 +9,7 @@ import { i18n } from './i18n';
|
||||
|
||||
// TODO: 他のタブと永続化されたstateを同期
|
||||
|
||||
type Account = {
|
||||
id: string;
|
||||
token: string;
|
||||
isModerator: boolean;
|
||||
isAdmin: boolean;
|
||||
isDeleted: boolean;
|
||||
};
|
||||
type Account = misskey.entities.MeDetailed;
|
||||
|
||||
const data = localStorage.getItem('account');
|
||||
|
||||
|
@ -157,7 +157,7 @@ export default defineComponent({
|
||||
items: [],
|
||||
mfmTags: [],
|
||||
select: -1,
|
||||
zIndex: os.claimZIndex(true),
|
||||
zIndex: os.claimZIndex('high'),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" :front="true" @click="done(true)" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" :z-priority="'high'" @click="done(true)" @closed="$emit('closed')">
|
||||
<div class="mk-dialog">
|
||||
<div v-if="icon" class="icon">
|
||||
<i :class="icon"></i>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :prefer-type="asReactionPicker && $store.state.reactionPickerUseDrawerForMobile === false ? 'popup' : 'auto'" :transparent-bg="true" :manual-showing="manualShowing" :src="src" :front="true" @click="$refs.modal.close()" @opening="opening" @close="$emit('close')" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :z-priority="'middle'" :prefer-type="asReactionPicker && $store.state.reactionPickerUseDrawerForMobile === false ? 'popup' : 'auto'" :transparent-bg="true" :manual-showing="manualShowing" :src="src" @click="$refs.modal.close()" @opening="opening" @close="$emit('close')" @closed="$emit('closed')">
|
||||
<MkEmojiPicker ref="picker" class="ryghynhb _popup _shadow" :class="{ drawer: type === 'drawer' }" :show-pinned="showPinned" :as-reaction-picker="asReactionPicker" :as-drawer="type === 'drawer'" :max-height="maxHeight" @chosen="chosen"/>
|
||||
</MkModal>
|
||||
</template>
|
||||
|
@ -77,7 +77,7 @@
|
||||
import { defineComponent, markRaw } from 'vue';
|
||||
import { emojilist } from '@/scripts/emojilist';
|
||||
import { getStaticImageUrl } from '@/scripts/get-static-image-url';
|
||||
import Particle from '@/components/particle.vue';
|
||||
import Ripple from '@/components/ripple.vue';
|
||||
import * as os from '@/os';
|
||||
import { isTouchUsing } from '@/scripts/touch';
|
||||
import { isMobile } from '@/scripts/is-mobile';
|
||||
@ -296,9 +296,9 @@ export default defineComponent({
|
||||
if (ev) {
|
||||
const el = ev.currentTarget || ev.target;
|
||||
const rect = el.getBoundingClientRect();
|
||||
const x = rect.left + (el.clientWidth / 2);
|
||||
const y = rect.top + (el.clientHeight / 2);
|
||||
os.popup(Particle, { x, y }, {}, 'end');
|
||||
const x = rect.left + (el.offsetWidth / 2);
|
||||
const y = rect.top + (el.offsetHeight / 2);
|
||||
os.popup(Ripple, { x, y }, {}, 'end');
|
||||
}
|
||||
|
||||
const key = this.getKey(emoji);
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
|
||||
<input ref="inputEl"
|
||||
v-model="v"
|
||||
v-panel
|
||||
v-adaptive-border
|
||||
:type="type"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
@ -243,7 +243,8 @@ export default defineComponent({
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
color: var(--fg);
|
||||
border: solid 0.5px var(--panel);
|
||||
background: var(--panel);
|
||||
border: solid 1px var(--panel);
|
||||
border-radius: 6px;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
@ -251,7 +252,7 @@ export default defineComponent({
|
||||
transition: border-color 0.1s ease-out;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--inputBorderHover);
|
||||
border-color: var(--inputBorderHover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,7 +299,7 @@ export default defineComponent({
|
||||
|
||||
&.focused {
|
||||
> input {
|
||||
border-color: var(--accent);
|
||||
border-color: var(--accent) !important;
|
||||
//box-shadow: 0 0 0 4px var(--focus);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@
|
||||
<div class="label" @click="focus"><slot name="label"></slot></div>
|
||||
<div ref="container" class="input" :class="{ inline, disabled, focused }" @click.prevent="onClick">
|
||||
<div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
|
||||
<select ref="inputEl" v-model="v" v-panel
|
||||
<select ref="inputEl"
|
||||
v-model="v"
|
||||
v-adaptive-border
|
||||
class="select"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
@ -226,7 +228,7 @@ export default defineComponent({
|
||||
|
||||
&:hover {
|
||||
> .select {
|
||||
border-color: var(--inputBorderHover);
|
||||
border-color: var(--inputBorderHover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,6 +244,7 @@ export default defineComponent({
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
color: var(--fg);
|
||||
background: var(--panel);
|
||||
border: solid 1px var(--panel);
|
||||
border-radius: 6px;
|
||||
outline: none;
|
||||
@ -295,7 +298,7 @@ export default defineComponent({
|
||||
|
||||
&.focused {
|
||||
> select {
|
||||
border-color: var(--accent);
|
||||
border-color: var(--accent) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,6 @@
|
||||
<div
|
||||
class="ziffeoms"
|
||||
:class="{ disabled, checked }"
|
||||
role="switch"
|
||||
:aria-checked="checked"
|
||||
:aria-disabled="disabled"
|
||||
@click.prevent="toggle"
|
||||
>
|
||||
<input
|
||||
ref="input"
|
||||
@ -13,18 +9,20 @@
|
||||
:disabled="disabled"
|
||||
@keydown.enter="toggle"
|
||||
>
|
||||
<span v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button">
|
||||
<span class="handle"></span>
|
||||
<span ref="button" v-adaptive-border v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button" @click.prevent="toggle">
|
||||
<i class="check fas fa-check"></i>
|
||||
</span>
|
||||
<span class="label">
|
||||
<span><slot></slot></span>
|
||||
<span @click="toggle"><slot></slot></span>
|
||||
<p class="caption"><slot name="caption"></slot></p>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, ref, toRefs } from 'vue';
|
||||
import * as os from '@/os';
|
||||
import Ripple from '@/components/ripple.vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -37,17 +35,28 @@ export default defineComponent({
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
checked(): boolean {
|
||||
return this.modelValue;
|
||||
}
|
||||
|
||||
setup(props, context) {
|
||||
const button = ref<HTMLElement>();
|
||||
const checked = toRefs(props).modelValue;
|
||||
const toggle = () => {
|
||||
if (props.disabled) return;
|
||||
context.emit('update:modelValue', !checked.value);
|
||||
|
||||
if (!checked.value) {
|
||||
const rect = button.value.getBoundingClientRect();
|
||||
const x = rect.left + (button.value.offsetWidth / 2);
|
||||
const y = rect.top + (button.value.offsetHeight / 2);
|
||||
os.popup(Ripple, { x, y, particle: false }, {}, 'end');
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
button,
|
||||
checked,
|
||||
toggle,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
if (this.disabled) return;
|
||||
this.$emit('update:modelValue', !this.checked);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -55,16 +64,7 @@ export default defineComponent({
|
||||
.ziffeoms {
|
||||
position: relative;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
transition: all 0.2s ease;
|
||||
|
||||
> * {
|
||||
user-select: none;
|
||||
@ -80,27 +80,32 @@ export default defineComponent({
|
||||
|
||||
> .button {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
margin: 0;
|
||||
width: 36px;
|
||||
height: 26px;
|
||||
background: var(--switchBg);
|
||||
box-sizing: border-box;
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
outline: none;
|
||||
border-radius: 999px;
|
||||
background: var(--panel);
|
||||
border: solid 1px var(--panel);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: inherit;
|
||||
|
||||
> .handle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 5px;
|
||||
margin: auto 0;
|
||||
border-radius: 100%;
|
||||
transition: background-color 0.3s, transform 0.3s;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #fff;
|
||||
> .check {
|
||||
margin: auto;
|
||||
opacity: 0;
|
||||
color: var(--fgOnAccent);
|
||||
font-size: 13px;
|
||||
transform: scale(0.5);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> .button {
|
||||
border-color: var(--inputBorderHover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,13 +113,13 @@ export default defineComponent({
|
||||
margin-left: 16px;
|
||||
margin-top: 2px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
transition: inherit;
|
||||
color: var(--fg);
|
||||
|
||||
> span {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
transition: inherit;
|
||||
}
|
||||
|
||||
@ -129,12 +134,6 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> .button {
|
||||
background-color: var(--accentedBg);
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
@ -142,11 +141,12 @@ export default defineComponent({
|
||||
|
||||
&.checked {
|
||||
> .button {
|
||||
background-color: var(--accent);
|
||||
border-color: var(--accent);
|
||||
background-color: var(--accent) !important;
|
||||
border-color: var(--accent) !important;
|
||||
|
||||
> .handle {
|
||||
transform: translateX(10px);
|
||||
> .check {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="input" :class="{ disabled, focused, tall, pre }">
|
||||
<textarea ref="inputEl"
|
||||
v-model="v"
|
||||
v-panel
|
||||
v-adaptive-border
|
||||
:class="{ code, _monospace: code }"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
@ -210,7 +210,8 @@ export default defineComponent({
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
color: var(--fg);
|
||||
border: solid 0.5px var(--panel);
|
||||
background: var(--panel);
|
||||
border: solid 1px var(--panel);
|
||||
border-radius: 6px;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
@ -218,13 +219,13 @@ export default defineComponent({
|
||||
transition: border-color 0.1s ease-out;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--inputBorderHover);
|
||||
border-color: var(--inputBorderHover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.focused {
|
||||
> textarea {
|
||||
border-color: var(--accent);
|
||||
border-color: var(--accent) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,11 +106,6 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.to.startsWith('/my/messaging')) {
|
||||
if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return this.window();
|
||||
if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return this.popout();
|
||||
}
|
||||
|
||||
if (this.behavior) {
|
||||
if (this.behavior === 'window') {
|
||||
return this.window();
|
||||
|
@ -6,7 +6,7 @@
|
||||
<i v-else-if="info.icon" class="icon" :class="info.icon"></i>
|
||||
|
||||
<div class="title">
|
||||
<MkUserName v-if="info.userName" :user="info.userName" :nowrap="false" class="title"/>
|
||||
<MkUserName v-if="info.userName" :user="info.userName" :nowrap="true" class="title"/>
|
||||
<div v-else-if="info.title" class="title">{{ info.title }}</div>
|
||||
<div v-if="!narrow && info.subtitle" class="subtitle">
|
||||
{{ info.subtitle }}
|
||||
@ -268,6 +268,7 @@ export default defineComponent({
|
||||
> .titleContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 400px;
|
||||
overflow: auto;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<component :is="self ? 'MkA' : 'a'" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||
@mouseover="onMouseover"
|
||||
@mouseleave="onMouseleave"
|
||||
<component :is="self ? 'MkA' : 'a'" ref="el" class="ieqqeuvs _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
|
||||
@contextmenu.stop="() => {}"
|
||||
>
|
||||
<template v-if="!self">
|
||||
@ -20,11 +18,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { toUnicode as decodePunycode } from 'punycode/';
|
||||
import { url as local } from '@/config';
|
||||
import { isTouchUsing } from '@/scripts/touch';
|
||||
import * as os from '@/os';
|
||||
import { useTooltip } from '@/scripts/use-tooltip';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -35,74 +33,36 @@ export default defineComponent({
|
||||
rel: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const self = this.url.startsWith(local);
|
||||
setup(props) {
|
||||
const self = props.url.startsWith(local);
|
||||
const url = new URL(props.url);
|
||||
const el = ref();
|
||||
|
||||
useTooltip(el, (showing) => {
|
||||
os.popup(import('@/components/url-preview-popup.vue'), {
|
||||
showing,
|
||||
url: props.url,
|
||||
source: el.value,
|
||||
}, {}, 'closed');
|
||||
});
|
||||
|
||||
return {
|
||||
local,
|
||||
schema: null as string | null,
|
||||
hostname: null as string | null,
|
||||
port: null as string | null,
|
||||
pathname: null as string | null,
|
||||
query: null as string | null,
|
||||
hash: null as string | null,
|
||||
schema: url.protocol,
|
||||
hostname: decodePunycode(url.hostname),
|
||||
port: url.port,
|
||||
pathname: decodeURIComponent(url.pathname),
|
||||
query: decodeURIComponent(url.search),
|
||||
hash: decodeURIComponent(url.hash),
|
||||
self: self,
|
||||
attr: self ? 'to' : 'href',
|
||||
target: self ? null : '_blank',
|
||||
showTimer: null,
|
||||
hideTimer: null,
|
||||
checkTimer: null,
|
||||
close: null,
|
||||
el,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
const url = new URL(this.url);
|
||||
this.schema = url.protocol;
|
||||
this.hostname = decodePunycode(url.hostname);
|
||||
this.port = url.port;
|
||||
this.pathname = decodeURIComponent(url.pathname);
|
||||
this.query = decodeURIComponent(url.search);
|
||||
this.hash = decodeURIComponent(url.hash);
|
||||
},
|
||||
methods: {
|
||||
async showPreview() {
|
||||
if (!document.body.contains(this.$el)) return;
|
||||
if (this.close) return;
|
||||
|
||||
const { dispose } = await os.popup(import('@/components/url-preview-popup.vue'), {
|
||||
url: this.url,
|
||||
source: this.$el
|
||||
});
|
||||
|
||||
this.close = () => {
|
||||
dispose();
|
||||
};
|
||||
|
||||
this.checkTimer = setInterval(() => {
|
||||
if (!document.body.contains(this.$el)) this.closePreview();
|
||||
}, 1000);
|
||||
},
|
||||
closePreview() {
|
||||
if (this.close) {
|
||||
clearInterval(this.checkTimer);
|
||||
this.close();
|
||||
this.close = null;
|
||||
}
|
||||
},
|
||||
onMouseover() {
|
||||
if (isTouchUsing) return;
|
||||
clearTimeout(this.showTimer);
|
||||
clearTimeout(this.hideTimer);
|
||||
this.showTimer = setTimeout(this.showPreview, 500);
|
||||
},
|
||||
onMouseleave() {
|
||||
if (isTouchUsing) return;
|
||||
clearTimeout(this.showTimer);
|
||||
clearTimeout(this.hideTimer);
|
||||
this.hideTimer = setTimeout(this.closePreview, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :z-priority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="xubzgfga">
|
||||
<header>{{ image.name }}</header>
|
||||
<img :src="image.url" :alt="image.comment" :title="image.comment" @click="$refs.modal.close()"/>
|
||||
|
@ -105,6 +105,7 @@ export default defineComponent({
|
||||
return {
|
||||
previewable,
|
||||
gallery,
|
||||
pswpZIndex: os.claimZIndex('middle'),
|
||||
};
|
||||
},
|
||||
});
|
||||
@ -188,3 +189,11 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.pswp {
|
||||
// なぜか機能しない
|
||||
//z-index: v-bind(pswpZIndex);
|
||||
z-index: 2000000;
|
||||
}
|
||||
</style>
|
||||
|
@ -175,14 +175,7 @@ export default defineComponent({
|
||||
if (!this.$store.state.animatedMfm) {
|
||||
return genEl(token.children);
|
||||
}
|
||||
let count = token.props.args.count ? parseInt(token.props.args.count) : 10;
|
||||
if (count > 100) {
|
||||
count = 100;
|
||||
}
|
||||
const speed = token.props.args.speed ? parseFloat(token.props.args.speed) : 1;
|
||||
return h(MkSparkle, {
|
||||
count, speed,
|
||||
}, genEl(token.children));
|
||||
return h(MkSparkle, {}, genEl(token.children));
|
||||
}
|
||||
case 'rotate': {
|
||||
const degrees = parseInt(token.props.args.deg) || '90';
|
||||
|
@ -7,7 +7,7 @@
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="content">
|
||||
<Mfm :text="text" :author="$i" :i="$i"/>
|
||||
<Mfm :text="text.trim()" :author="$i" :i="$i"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,6 +61,7 @@ export default defineComponent({
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
> .main {
|
||||
@ -69,6 +70,7 @@ export default defineComponent({
|
||||
|
||||
> .header {
|
||||
margin-bottom: 2px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> .body {
|
||||
|
74
packages/client/src/components/notification-toast.vue
Normal file
74
packages/client/src/components/notification-toast.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="mk-notification-toast" :style="{ zIndex }">
|
||||
<transition name="notification-toast" appear @after-leave="$emit('closed')">
|
||||
<XNotification v-if="showing" :notification="notification" class="notification _acrylic"/>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import XNotification from './notification.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XNotification
|
||||
},
|
||||
props: {
|
||||
notification: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['closed'],
|
||||
data() {
|
||||
return {
|
||||
showing: true,
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.showing = false;
|
||||
}, 6000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification-toast-enter-active, .notification-toast-leave-active {
|
||||
transition: opacity 0.3s, transform 0.3s !important;
|
||||
}
|
||||
.notification-toast-enter-from, .notification-toast-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-250px);
|
||||
}
|
||||
|
||||
.mk-notification-toast {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
top: 32px;
|
||||
padding: 0 32px;
|
||||
pointer-events: none;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
top: initial;
|
||||
bottom: 112px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
bottom: 92px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
> .notification {
|
||||
height: 100%;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -16,7 +16,13 @@
|
||||
<template #headerLeft>
|
||||
<button v-if="history.length > 0" v-tooltip="$ts.goBack" class="_button" @click="back()"><i class="fas fa-arrow-left"></i></button>
|
||||
</template>
|
||||
<div class="yrolvcoq">
|
||||
<template #headerRight>
|
||||
<button v-tooltip="$ts.showInPage" class="_button" @click="expand()"><i class="fas fa-expand-alt"></i></button>
|
||||
<button v-tooltip="$ts.popout" class="_button" @click="popout()"><i class="fas fa-external-link-alt"></i></button>
|
||||
<button class="_button" @click="menu"><i class="fas fa-ellipsis-h"></i></button>
|
||||
</template>
|
||||
|
||||
<div class="yrolvcoq" :style="{ background: pageInfo?.bg }">
|
||||
<MkStickyContainer>
|
||||
<template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template>
|
||||
<component :is="component" v-bind="props" :ref="changePage"/>
|
||||
@ -33,6 +39,7 @@ import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import { resolve } from '@/router';
|
||||
import { url } from '@/config';
|
||||
import * as symbols from '@/symbols';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -139,6 +146,23 @@ export default defineComponent({
|
||||
this.props = props;
|
||||
},
|
||||
|
||||
menu(ev) {
|
||||
os.popupMenu([{
|
||||
icon: 'fas fa-external-link-alt',
|
||||
text: this.$ts.openInNewTab,
|
||||
action: () => {
|
||||
window.open(this.url, '_blank');
|
||||
this.$refs.window.close();
|
||||
}
|
||||
}, {
|
||||
icon: 'fas fa-link',
|
||||
text: this.$ts.copyLink,
|
||||
action: () => {
|
||||
copyToClipboard(this.url);
|
||||
}
|
||||
}], ev.currentTarget || ev.target);
|
||||
},
|
||||
|
||||
back() {
|
||||
this.navigate(this.history.pop(), false);
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
<button
|
||||
v-if="count > 0"
|
||||
ref="buttonRef"
|
||||
v-particle="canToggle"
|
||||
v-ripple="canToggle"
|
||||
class="hkzvhatu _button"
|
||||
:class="{ reacted: note.myReaction == reaction, canToggle }"
|
||||
@click="toggleReaction()"
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="vswabwbm" :style="{ top: `${y - 64}px`, left: `${x - 64}px` }" :class="{ active }">
|
||||
<div class="vswabwbm" :style="{ zIndex, top: `${y - 64}px`, left: `${x - 64}px` }" :class="{ active }">
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle fill="none" cx="64" cy="64">
|
||||
<animate attributeName="r"
|
||||
@ -52,7 +52,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, onMounted } from 'vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -63,37 +64,46 @@ export default defineComponent({
|
||||
y: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
particle: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
emits: ['end'],
|
||||
data() {
|
||||
setup(props, context) {
|
||||
const particles = [];
|
||||
const origin = 64;
|
||||
const colors = ['#FF1493', '#00FFFF', '#FFE202'];
|
||||
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const angle = Math.random() * (Math.PI * 2);
|
||||
const pos = Math.random() * 16;
|
||||
const velocity = 16 + (Math.random() * 48);
|
||||
particles.push({
|
||||
size: 4 + (Math.random() * 8),
|
||||
xA: origin + (Math.sin(angle) * pos),
|
||||
yA: origin + (Math.cos(angle) * pos),
|
||||
xB: origin + (Math.sin(angle) * (pos + velocity)),
|
||||
yB: origin + (Math.cos(angle) * (pos + velocity)),
|
||||
color: colors[Math.floor(Math.random() * colors.length)]
|
||||
});
|
||||
if (props.particle) {
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const angle = Math.random() * (Math.PI * 2);
|
||||
const pos = Math.random() * 16;
|
||||
const velocity = 16 + (Math.random() * 48);
|
||||
particles.push({
|
||||
size: 4 + (Math.random() * 8),
|
||||
xA: origin + (Math.sin(angle) * pos),
|
||||
yA: origin + (Math.cos(angle) * pos),
|
||||
xB: origin + (Math.sin(angle) * (pos + velocity)),
|
||||
yB: origin + (Math.cos(angle) * (pos + velocity)),
|
||||
color: colors[Math.floor(Math.random() * colors.length)]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
context.emit('end');
|
||||
}, 1100);
|
||||
});
|
||||
|
||||
return {
|
||||
particles
|
||||
particles,
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.$emit('end');
|
||||
}, 1100);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -101,7 +111,6 @@ export default defineComponent({
|
||||
.vswabwbm {
|
||||
pointer-events: none;
|
||||
position: fixed;
|
||||
z-index: 1000000;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
|
@ -51,14 +51,13 @@
|
||||
<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.passwordNotMatched }}</span>
|
||||
</template>
|
||||
</MkInput>
|
||||
<label v-if="meta.tosUrl" class="_formBlock tou">
|
||||
<input v-model="ToSAgreement" type="checkbox">
|
||||
<MkSwitch v-if="meta.tosUrl" v-model="ToSAgreement" class="_formBlock tou">
|
||||
<I18n :src="$ts.agreeTo">
|
||||
<template #0>
|
||||
<a :href="meta.tosUrl" class="_link" target="_blank">{{ $ts.tos }}</a>
|
||||
</template>
|
||||
</I18n>
|
||||
</label>
|
||||
</MkSwitch>
|
||||
<captcha v-if="meta.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" class="_formBlock captcha" provider="hcaptcha" :sitekey="meta.hcaptchaSiteKey"/>
|
||||
<captcha v-if="meta.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" class="_formBlock captcha" provider="recaptcha" :sitekey="meta.recaptchaSiteKey"/>
|
||||
<MkButton class="_formBlock" type="submit" :disabled="shouldDisableSubmitting" gradate data-cy-signup-submit>{{ $ts.start }}</MkButton>
|
||||
@ -258,11 +257,5 @@ export default defineComponent({
|
||||
.captcha {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
> .tou {
|
||||
display: block;
|
||||
margin: 16px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,161 +1,121 @@
|
||||
<template>
|
||||
<span class="mk-sparkle">
|
||||
<span ref="content">
|
||||
<span ref="el">
|
||||
<slot></slot>
|
||||
</span>
|
||||
<canvas ref="canvas"></canvas>
|
||||
<!-- なぜか path に対する key が機能しないため
|
||||
<svg :width="width" :height="height" :viewBox="`0 0 ${width} ${height}`" xmlns="http://www.w3.org/2000/svg">
|
||||
<path v-for="particle in particles" :key="particle.id" style="transform-origin: center; transform-box: fill-box;"
|
||||
:transform="`translate(${particle.x} ${particle.y})`"
|
||||
:fill="particle.color"
|
||||
d="M29.427,2.011C29.721,0.83 30.782,0 32,0C33.218,0 34.279,0.83 34.573,2.011L39.455,21.646C39.629,22.347 39.991,22.987 40.502,23.498C41.013,24.009 41.653,24.371 42.354,24.545L61.989,29.427C63.17,29.721 64,30.782 64,32C64,33.218 63.17,34.279 61.989,34.573L42.354,39.455C41.653,39.629 41.013,39.991 40.502,40.502C39.991,41.013 39.629,41.653 39.455,42.354L34.573,61.989C34.279,63.17 33.218,64 32,64C30.782,64 29.721,63.17 29.427,61.989L24.545,42.354C24.371,41.653 24.009,41.013 23.498,40.502C22.987,39.991 22.347,39.629 21.646,39.455L2.011,34.573C0.83,34.279 0,33.218 0,32C0,30.782 0.83,29.721 2.011,29.427L21.646,24.545C22.347,24.371 22.987,24.009 23.498,23.498C24.009,22.987 24.371,22.347 24.545,21.646L29.427,2.011Z"
|
||||
>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
attributeType="XML"
|
||||
type="rotate"
|
||||
from="0 0 0"
|
||||
to="360 0 0"
|
||||
:dur="`${particle.dur}ms`"
|
||||
repeatCount="indefinite"
|
||||
additive="sum"
|
||||
/>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
attributeType="XML"
|
||||
type="scale"
|
||||
:values="`0; ${particle.size}; 0`"
|
||||
:dur="`${particle.dur}ms`"
|
||||
repeatCount="indefinite"
|
||||
additive="sum"
|
||||
/>
|
||||
</path>
|
||||
</svg>
|
||||
-->
|
||||
<svg v-for="particle in particles" :key="particle.id" :width="width" :height="height" :viewBox="`0 0 ${width} ${height}`" xmlns="http://www.w3.org/2000/svg">
|
||||
<path style="transform-origin: center; transform-box: fill-box;"
|
||||
:transform="`translate(${particle.x} ${particle.y})`"
|
||||
:fill="particle.color"
|
||||
d="M29.427,2.011C29.721,0.83 30.782,0 32,0C33.218,0 34.279,0.83 34.573,2.011L39.455,21.646C39.629,22.347 39.991,22.987 40.502,23.498C41.013,24.009 41.653,24.371 42.354,24.545L61.989,29.427C63.17,29.721 64,30.782 64,32C64,33.218 63.17,34.279 61.989,34.573L42.354,39.455C41.653,39.629 41.013,39.991 40.502,40.502C39.991,41.013 39.629,41.653 39.455,42.354L34.573,61.989C34.279,63.17 33.218,64 32,64C30.782,64 29.721,63.17 29.427,61.989L24.545,42.354C24.371,41.653 24.009,41.013 23.498,40.502C22.987,39.991 22.347,39.629 21.646,39.455L2.011,34.573C0.83,34.279 0,33.218 0,32C0,30.782 0.83,29.721 2.011,29.427L21.646,24.545C22.347,24.371 22.987,24.009 23.498,23.498C24.009,22.987 24.371,22.347 24.545,21.646L29.427,2.011Z"
|
||||
>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
attributeType="XML"
|
||||
type="rotate"
|
||||
from="0 0 0"
|
||||
to="360 0 0"
|
||||
:dur="`${particle.dur}ms`"
|
||||
repeatCount="1"
|
||||
additive="sum"
|
||||
/>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
attributeType="XML"
|
||||
type="scale"
|
||||
:values="`0; ${particle.size}; 0`"
|
||||
:dur="`${particle.dur}ms`"
|
||||
repeatCount="1"
|
||||
additive="sum"
|
||||
/>
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, onMounted, onUnmounted, ref } from 'vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
const sprite = new Image();
|
||||
sprite.src = '/client-assets/sparkle-spritesheet.png';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
count: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
speed: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sprites: [0,6,13,20],
|
||||
particles: [],
|
||||
anim: null,
|
||||
ctx: null,
|
||||
};
|
||||
},
|
||||
unmounted() {
|
||||
window.cancelAnimationFrame(this.anim);
|
||||
},
|
||||
mounted() {
|
||||
this.ctx = this.$refs.canvas.getContext('2d');
|
||||
setup() {
|
||||
const particles = ref([]);
|
||||
const el = ref<HTMLElement>();
|
||||
const width = ref(0);
|
||||
const height = ref(0);
|
||||
const colors = ['#FF1493', '#00FFFF', '#FFE202', '#FFE202', '#FFE202'];
|
||||
|
||||
new ResizeObserver(this.resize).observe(this.$refs.content);
|
||||
|
||||
this.resize();
|
||||
this.tick();
|
||||
},
|
||||
updated() {
|
||||
this.resize();
|
||||
},
|
||||
methods: {
|
||||
createSparkles(w, h, count) {
|
||||
const holder = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
|
||||
const color = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6);
|
||||
|
||||
holder[i] = {
|
||||
position: {
|
||||
x: Math.floor(Math.random() * w),
|
||||
y: Math.floor(Math.random() * h)
|
||||
},
|
||||
style: this.sprites[ Math.floor(Math.random() * 4) ],
|
||||
delta: {
|
||||
x: Math.floor(Math.random() * 1000) - 500,
|
||||
y: Math.floor(Math.random() * 1000) - 500
|
||||
},
|
||||
color: color,
|
||||
opacity: Math.random(),
|
||||
onMounted(() => {
|
||||
const ro = new ResizeObserver((entries, observer) => {
|
||||
width.value = el.value?.offsetWidth + 64;
|
||||
height.value = el.value?.offsetHeight + 64;
|
||||
});
|
||||
ro.observe(el.value);
|
||||
let stop = false;
|
||||
const add = () => {
|
||||
if (stop) return;
|
||||
const x = (Math.random() * (width.value - 64));
|
||||
const y = (Math.random() * (height.value - 64));
|
||||
const sizeFactor = Math.random();
|
||||
const particle = {
|
||||
id: Math.random().toString(),
|
||||
x,
|
||||
y,
|
||||
size: 0.2 + ((sizeFactor / 10) * 3),
|
||||
dur: 1000 + (sizeFactor * 1000),
|
||||
color: colors[Math.floor(Math.random() * colors.length)],
|
||||
};
|
||||
particles.value.push(particle);
|
||||
window.setTimeout(() => {
|
||||
particles.value = particles.value.filter(x => x.id !== particle.id);
|
||||
}, particle.dur - 100);
|
||||
|
||||
}
|
||||
|
||||
return holder;
|
||||
},
|
||||
draw(time) {
|
||||
this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);
|
||||
this.ctx.beginPath();
|
||||
|
||||
const particleSize = Math.floor(this.fontSize / 2);
|
||||
this.particles.forEach((particle) => {
|
||||
var modulus = Math.floor(Math.random()*7);
|
||||
|
||||
if (Math.floor(time) % modulus === 0) {
|
||||
particle.style = this.sprites[ Math.floor(Math.random()*4) ];
|
||||
}
|
||||
|
||||
this.ctx.save();
|
||||
this.ctx.globalAlpha = particle.opacity;
|
||||
this.ctx.drawImage(sprite, particle.style, 0, 7, 7, particle.position.x, particle.position.y, particleSize, particleSize);
|
||||
|
||||
this.ctx.globalCompositeOperation = "source-atop";
|
||||
this.ctx.globalAlpha = 0.5;
|
||||
this.ctx.fillStyle = particle.color;
|
||||
this.ctx.fillRect(particle.position.x, particle.position.y, particleSize, particleSize);
|
||||
|
||||
this.ctx.restore();
|
||||
window.setTimeout(() => {
|
||||
add();
|
||||
}, 500 + (Math.random() * 500));
|
||||
};
|
||||
add();
|
||||
onUnmounted(() => {
|
||||
ro.disconnect();
|
||||
stop = true;
|
||||
});
|
||||
this.ctx.stroke();
|
||||
},
|
||||
tick() {
|
||||
this.anim = window.requestAnimationFrame((time) => {
|
||||
if (!this.$refs.canvas) {
|
||||
return;
|
||||
}
|
||||
this.particles.forEach((particle) => {
|
||||
if (!particle) {
|
||||
return;
|
||||
}
|
||||
var randX = Math.random() > Math.random() * 2;
|
||||
var randY = Math.random() > Math.random() * 3;
|
||||
});
|
||||
|
||||
if (randX) {
|
||||
particle.position.x += (particle.delta.x * this.speed) / 1500;
|
||||
}
|
||||
|
||||
if (!randY) {
|
||||
particle.position.y -= (particle.delta.y * this.speed) / 800;
|
||||
}
|
||||
|
||||
if( particle.position.x > this.$refs.canvas.width ) {
|
||||
particle.position.x = -7;
|
||||
} else if (particle.position.x < -7) {
|
||||
particle.position.x = this.$refs.canvas.width;
|
||||
}
|
||||
|
||||
if (particle.position.y > this.$refs.canvas.height) {
|
||||
particle.position.y = -7;
|
||||
particle.position.x = Math.floor(Math.random() * this.$refs.canvas.width);
|
||||
} else if (particle.position.y < -7) {
|
||||
particle.position.y = this.$refs.canvas.height;
|
||||
particle.position.x = Math.floor(Math.random() * this.$refs.canvas.width);
|
||||
}
|
||||
|
||||
particle.opacity -= 0.005;
|
||||
|
||||
if (particle.opacity <= 0) {
|
||||
particle.opacity = 1;
|
||||
}
|
||||
});
|
||||
|
||||
this.draw(time);
|
||||
|
||||
this.tick();
|
||||
});
|
||||
},
|
||||
resize() {
|
||||
if (this.$refs.content) {
|
||||
const contentRect = this.$refs.content.getBoundingClientRect();
|
||||
this.fontSize = parseFloat(getComputedStyle(this.$refs.content).fontSize);
|
||||
const padding = this.fontSize * 0.2;
|
||||
|
||||
this.$refs.canvas.width = parseInt(contentRect.width + padding);
|
||||
this.$refs.canvas.height = parseInt(contentRect.height + padding);
|
||||
|
||||
this.particles = this.createSparkles(this.$refs.canvas.width, this.$refs.canvas.height, this.count);
|
||||
}
|
||||
},
|
||||
return {
|
||||
el,
|
||||
width,
|
||||
height,
|
||||
particles,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -169,10 +129,10 @@ export default defineComponent({
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
> canvas {
|
||||
> svg {
|
||||
position: absolute;
|
||||
top: -0.1em;
|
||||
left: -0.1em;
|
||||
top: -32px;
|
||||
left: -32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +1,70 @@
|
||||
<template>
|
||||
<div class="mk-toast" :style="{ zIndex }">
|
||||
<transition name="notification-slide" appear @after-leave="$emit('closed')">
|
||||
<XNotification v-if="showing" :notification="notification" class="notification _acrylic"/>
|
||||
<div class="mk-toast">
|
||||
<transition name="toast" appear @after-leave="$emit('closed')">
|
||||
<div v-if="showing" class="body _acrylic" :style="{ zIndex }">
|
||||
<div class="message">
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import XNotification from './notification.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XNotification
|
||||
},
|
||||
props: {
|
||||
notification: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
message: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ['closed'],
|
||||
data() {
|
||||
return {
|
||||
showing: true,
|
||||
zIndex: os.claimZIndex(true),
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.showing = false;
|
||||
}, 6000);
|
||||
}, 4000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification-slide-enter-active, .notification-slide-leave-active {
|
||||
.toast-enter-active, .toast-leave-active {
|
||||
transition: opacity 0.3s, transform 0.3s !important;
|
||||
}
|
||||
.notification-slide-enter-from, .notification-slide-leave-to {
|
||||
.toast-enter-from, .toast-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-250px);
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.mk-toast {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
top: 32px;
|
||||
padding: 0 32px;
|
||||
pointer-events: none;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
top: initial;
|
||||
bottom: 112px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
bottom: 92px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
> .notification {
|
||||
height: 100%;
|
||||
> .body {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: 0 auto;
|
||||
margin-top: 16px;
|
||||
min-width: 300px;
|
||||
max-width: calc(100% - 32px);
|
||||
width: min-content;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
overflow: clip;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
|
||||
> .message {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<transition :name="$store.state.animation ? 'fade' : ''" appear>
|
||||
<div class="nvlagfpb" @contextmenu.prevent.stop="() => {}">
|
||||
<div class="nvlagfpb" :style="{ zIndex }" @contextmenu.prevent.stop="() => {}">
|
||||
<MkMenu :items="items" class="_popup _shadow" :align="'left'" @close="$emit('closed')"/>
|
||||
</div>
|
||||
</transition>
|
||||
@ -10,6 +10,7 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import contains from '@/scripts/contains';
|
||||
import MkMenu from './menu.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -29,6 +30,11 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
emits: ['closed'],
|
||||
data() {
|
||||
return {
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
keymap(): any {
|
||||
return {
|
||||
@ -82,7 +88,6 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.nvlagfpb {
|
||||
position: absolute;
|
||||
z-index: 65535;
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
|
@ -280,12 +280,11 @@ export default defineComponent({
|
||||
|
||||
> .divider {
|
||||
margin: 8px 0;
|
||||
height: 1px;
|
||||
background: var(--divider);
|
||||
border-top: solid 0.5px var(--divider);
|
||||
}
|
||||
|
||||
&.asDrawer {
|
||||
padding: 12px 0;
|
||||
padding: 12px 0 calc(env(safe-area-inset-bottom, 0px) + 12px) 0;
|
||||
width: 100%;
|
||||
|
||||
> .item {
|
||||
|
@ -13,6 +13,7 @@
|
||||
import { defineComponent, nextTick, onMounted, computed, PropType, ref, watch } from 'vue';
|
||||
import * as os from '@/os';
|
||||
import { isTouchUsing } from '@/scripts/touch';
|
||||
import { defaultStore } from '@/store';
|
||||
|
||||
function getFixedContainer(el: Element | null): Element | null {
|
||||
if (el == null || el.tagName === 'BODY') return null;
|
||||
@ -49,10 +50,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: 'auto',
|
||||
},
|
||||
front: {
|
||||
type: Boolean,
|
||||
zPriority: {
|
||||
type: String as PropType<'low' | 'middle' | 'high'>,
|
||||
required: false,
|
||||
default: false,
|
||||
default: 'low',
|
||||
},
|
||||
noOverlap: {
|
||||
type: Boolean,
|
||||
@ -74,10 +75,10 @@ export default defineComponent({
|
||||
const transformOrigin = ref('center');
|
||||
const showing = ref(true);
|
||||
const content = ref<HTMLElement>();
|
||||
const zIndex = os.claimZIndex(props.front);
|
||||
const zIndex = os.claimZIndex(props.zPriority);
|
||||
const type = computed(() => {
|
||||
if (props.preferType === 'auto') {
|
||||
if (isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) {
|
||||
if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) {
|
||||
return 'drawer';
|
||||
} else {
|
||||
return props.src != null ? 'popup' : 'dialog';
|
||||
|
@ -5,7 +5,12 @@
|
||||
<MkError v-else-if="error" @retry="init()"/>
|
||||
|
||||
<div v-else-if="empty" key="_empty_" class="empty">
|
||||
<slot name="empty"></slot>
|
||||
<slot name="empty">
|
||||
<div class="_fullinfo">
|
||||
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
||||
<div>{{ $ts.nothing }}</div>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<div v-else class="cxiknjgy">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :src="src" :transparent-bg="true" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :z-priority="'high'" :src="src" :transparent-bg="true" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkMenu :items="items" :align="align" :width="width" :max-height="maxHeight" :as-drawer="type === 'drawer'" class="sfhdhdhq _popup _shadow" :class="{ drawer: type === 'drawer' }" @close="$refs.modal.close()"/>
|
||||
</MkModal>
|
||||
</template>
|
||||
|
@ -34,7 +34,7 @@ export default defineComponent({
|
||||
|
||||
setup(props, context) {
|
||||
const el = ref<HTMLElement>();
|
||||
const zIndex = os.claimZIndex(true);
|
||||
const zIndex = os.claimZIndex('high');
|
||||
|
||||
const setPosition = () => {
|
||||
if (el.value == null) return;
|
||||
|
@ -155,7 +155,7 @@ export default defineComponent({
|
||||
|
||||
// 最前面へ移動
|
||||
top() {
|
||||
(this.$el as any).style.zIndex = os.claimZIndex(this.front);
|
||||
(this.$el as any).style.zIndex = os.claimZIndex(this.front ? 'middle' : 'low');
|
||||
},
|
||||
|
||||
onBodyMousedown() {
|
||||
@ -414,6 +414,10 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
> .left {
|
||||
min-width: 16px;
|
||||
}
|
||||
|
||||
> .title {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
@ -421,7 +425,6 @@ export default defineComponent({
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<MkModal ref="modal" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :z-priority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="ewlycnyt">
|
||||
<div class="title">{{ $ts.misskeyUpdated }}</div>
|
||||
<div class="title"><MkSparkle>{{ $ts.misskeyUpdated }}</MkSparkle></div>
|
||||
<div class="version">✨{{ version }}🚀</div>
|
||||
<MkButton full @click="whatIsNew">{{ $ts.whatIsNew }}</MkButton>
|
||||
<MkButton class="gotIt" primary full @click="$refs.modal.close()">{{ $ts.gotIt }}</MkButton>
|
||||
@ -9,31 +9,19 @@
|
||||
</MkModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import MkModal from '@/components/ui/modal.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkSparkle from '@/components/sparkle.vue';
|
||||
import { version } from '@/config';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkModal,
|
||||
MkButton,
|
||||
},
|
||||
const modal = ref();
|
||||
|
||||
data() {
|
||||
return {
|
||||
version: version,
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
whatIsNew() {
|
||||
this.$refs.modal.close();
|
||||
window.open(`https://misskey-hub.net/docs/releases.html#_${version.replace(/\./g, '-')}`, '_blank');
|
||||
}
|
||||
}
|
||||
});
|
||||
const whatIsNew = () => {
|
||||
modal.value.close();
|
||||
window.open(`https://misskey-hub.net/docs/releases.html#_${version.replace(/\./g, '-')}`, '_blank');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -35,7 +35,7 @@ export default defineComponent({
|
||||
u: null,
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: os.claimZIndex(),
|
||||
zIndex: os.claimZIndex('middle'),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -65,7 +65,7 @@ export default defineComponent({
|
||||
fetched: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: os.claimZIndex(),
|
||||
zIndex: os.claimZIndex('middle'),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :z-priority="'high'" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="gqyayizv _popup">
|
||||
<button key="public" class="_button" :class="{ active: v == 'public' }" data-index="1" @click="choose('public')">
|
||||
<div><i class="fas fa-globe"></i></div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" @click="success ? done() : () => {}" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" :z-priority="'high'" @click="success ? done() : () => {}" @closed="$emit('closed')">
|
||||
<div class="iuyakobc" :class="{ iconOnly: (text == null) || success }">
|
||||
<i v-if="success" class="fas fa-check icon success"></i>
|
||||
<i v-else class="fas fa-spinner fa-pulse icon waiting"></i>
|
||||
|
24
packages/client/src/directives/adaptive-border.ts
Normal file
24
packages/client/src/directives/adaptive-border.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Directive } from 'vue';
|
||||
|
||||
export default {
|
||||
mounted(src, binding, vn) {
|
||||
const getBgColor = (el: HTMLElement) => {
|
||||
const style = window.getComputedStyle(el);
|
||||
if (style.backgroundColor && !['rgba(0, 0, 0, 0)', 'rgba(0,0,0,0)', 'transparent'].includes(style.backgroundColor)) {
|
||||
return style.backgroundColor;
|
||||
} else {
|
||||
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
|
||||
}
|
||||
}
|
||||
|
||||
const parentBg = getBgColor(src.parentElement);
|
||||
|
||||
const myBg = window.getComputedStyle(src).backgroundColor;
|
||||
|
||||
if (parentBg === myBg) {
|
||||
src.style.borderColor = 'var(--divider)';
|
||||
} else {
|
||||
src.style.borderColor = myBg;
|
||||
}
|
||||
},
|
||||
} as Directive;
|
@ -3,7 +3,7 @@ import { App } from 'vue';
|
||||
import userPreview from './user-preview';
|
||||
import size from './size';
|
||||
import getSize from './get-size';
|
||||
import particle from './particle';
|
||||
import ripple from './ripple';
|
||||
import tooltip from './tooltip';
|
||||
import hotkey from './hotkey';
|
||||
import appear from './appear';
|
||||
@ -11,13 +11,14 @@ import anim from './anim';
|
||||
import stickyContainer from './sticky-container';
|
||||
import clickAnime from './click-anime';
|
||||
import panel from './panel';
|
||||
import adaptiveBorder from './adaptive-border';
|
||||
|
||||
export default function(app: App) {
|
||||
app.directive('userPreview', userPreview);
|
||||
app.directive('user-preview', userPreview);
|
||||
app.directive('size', size);
|
||||
app.directive('get-size', getSize);
|
||||
app.directive('particle', particle);
|
||||
app.directive('ripple', ripple);
|
||||
app.directive('tooltip', tooltip);
|
||||
app.directive('hotkey', hotkey);
|
||||
app.directive('appear', appear);
|
||||
@ -25,4 +26,5 @@ export default function(app: App) {
|
||||
app.directive('click-anime', clickAnime);
|
||||
app.directive('sticky-container', stickyContainer);
|
||||
app.directive('panel', panel);
|
||||
app.directive('adaptive-border', adaptiveBorder);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ export default {
|
||||
if (style.backgroundColor && !['rgba(0, 0, 0, 0)', 'rgba(0,0,0,0)', 'transparent'].includes(style.backgroundColor)) {
|
||||
return style.backgroundColor;
|
||||
} else {
|
||||
return getBgColor(el.parentElement);
|
||||
return el.parentElement ? getBgColor(el.parentElement) : 'transparent';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Particle from '@/components/particle.vue';
|
||||
import Ripple from '@/components/ripple.vue';
|
||||
import { popup } from '@/os';
|
||||
|
||||
export default {
|
||||
@ -9,10 +9,10 @@ export default {
|
||||
el.addEventListener('click', () => {
|
||||
const rect = el.getBoundingClientRect();
|
||||
|
||||
const x = rect.left + (el.clientWidth / 2);
|
||||
const y = rect.top + (el.clientHeight / 2);
|
||||
const x = rect.left + (el.offsetWidth / 2);
|
||||
const y = rect.top + (el.offsetHeight / 2);
|
||||
|
||||
popup(Particle, { x, y }, {}, 'end');
|
||||
popup(Ripple, { x, y }, {}, 'end');
|
||||
});
|
||||
}
|
||||
};
|
@ -26,7 +26,7 @@ import { router } from '@/router';
|
||||
import { applyTheme } from '@/scripts/theme';
|
||||
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
|
||||
import { i18n } from '@/i18n';
|
||||
import { stream, confirm, alert, post, popup } from '@/os';
|
||||
import { stream, confirm, alert, post, popup, toast } from '@/os';
|
||||
import * as sound from '@/scripts/sound';
|
||||
import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
|
||||
import { defaultStore, ColdDeviceStorage } from '@/store';
|
||||
@ -342,6 +342,18 @@ if ($i) {
|
||||
});
|
||||
}
|
||||
|
||||
const lastUsed = localStorage.getItem('lastUsed');
|
||||
if (lastUsed) {
|
||||
const lastUsedDate = parseInt(lastUsed, 10);
|
||||
// 二時間以上前なら
|
||||
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
|
||||
toast(i18n.t('welcomeBackWithName', {
|
||||
name: $i.name || $i.username,
|
||||
}));
|
||||
}
|
||||
}
|
||||
localStorage.setItem('lastUsed', Date.now().toString());
|
||||
|
||||
if ('Notification' in window) {
|
||||
// 許可を得ていなかったらリクエスト
|
||||
if (Notification.permission === 'default') {
|
||||
|
@ -162,16 +162,14 @@ export const popups = ref([]) as Ref<{
|
||||
props: Record<string, any>;
|
||||
}[]>;
|
||||
|
||||
let popupZIndex = 1000000;
|
||||
let popupZIndexForFront = 2000000;
|
||||
export function claimZIndex(front = false): number {
|
||||
if (front) {
|
||||
popupZIndexForFront += 100;
|
||||
return popupZIndexForFront;
|
||||
} else {
|
||||
popupZIndex += 100;
|
||||
return popupZIndex;
|
||||
}
|
||||
const zIndexes = {
|
||||
low: 1000000,
|
||||
middle: 2000000,
|
||||
high: 3000000,
|
||||
};
|
||||
export function claimZIndex(priority: 'low' | 'middle' | 'high' = 'low'): number {
|
||||
zIndexes[priority] += 100;
|
||||
return zIndexes[priority];
|
||||
}
|
||||
|
||||
export async function popup(component: Component | typeof import('*.vue') | Promise<Component | typeof import('*.vue')>, props: Record<string, any>, events = {}, disposeEvent?: string) {
|
||||
@ -223,7 +221,9 @@ export function modalPageWindow(path: string) {
|
||||
}
|
||||
|
||||
export function toast(message: string) {
|
||||
// TODO
|
||||
popup(import('@/components/toast.vue'), {
|
||||
message
|
||||
}, {}, 'closed');
|
||||
}
|
||||
|
||||
export function alert(props: {
|
||||
|
@ -40,7 +40,6 @@ import MkButton from '@/components/ui/button.vue';
|
||||
import MkSwitch from '@/components/form/switch.vue';
|
||||
import XModalWindow from '@/components/ui/modal-window.vue';
|
||||
import MkDriveFileThumbnail from '@/components/drive-file-thumbnail.vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import bytes from '@/filters/bytes';
|
||||
import * as os from '@/os';
|
||||
|
||||
@ -74,11 +73,9 @@ export default defineComponent({
|
||||
|
||||
methods: {
|
||||
async fetch() {
|
||||
Progress.start();
|
||||
this.file = await os.api('drive/files/show', { fileId: this.fileId });
|
||||
this.info = await os.api('admin/drive/show-file', { fileId: this.fileId });
|
||||
this.isSensitive = this.file.isSensitive;
|
||||
Progress.done();
|
||||
},
|
||||
|
||||
showUser() {
|
||||
|
@ -7,8 +7,6 @@
|
||||
src="antenna"
|
||||
:antenna="antennaId"
|
||||
:sound="true"
|
||||
@before="before()"
|
||||
@after="after()"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
@ -17,7 +15,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, defineAsyncComponent, computed } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XTimeline from '@/components/timeline.vue';
|
||||
import { scroll } from '@/scripts/scroll';
|
||||
import * as os from '@/os';
|
||||
@ -76,14 +73,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
},
|
||||
|
||||
queueUpdated(q) {
|
||||
this.queue = q;
|
||||
},
|
||||
|
@ -1,28 +1,26 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="_section">
|
||||
<div class="_content">
|
||||
<MkInput v-model="name">
|
||||
<template #label>{{ $ts.name }}</template>
|
||||
</MkInput>
|
||||
<MkSpacer :content-max="700">
|
||||
<div class="_formRoot">
|
||||
<MkInput v-model="name" class="_formBlock">
|
||||
<template #label>{{ $ts.name }}</template>
|
||||
</MkInput>
|
||||
|
||||
<MkTextarea v-model="description">
|
||||
<template #label>{{ $ts.description }}</template>
|
||||
</MkTextarea>
|
||||
<MkTextarea v-model="description" class="_formBlock">
|
||||
<template #label>{{ $ts.description }}</template>
|
||||
</MkTextarea>
|
||||
|
||||
<div class="banner">
|
||||
<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="fas fa-plus"></i> {{ $ts._channel.setBanner }}</MkButton>
|
||||
<div v-else-if="bannerUrl">
|
||||
<img :src="bannerUrl" style="width: 100%;"/>
|
||||
<MkButton @click="removeBannerImage()"><i class="fas fa-trash-alt"></i> {{ $ts._channel.removeBanner }}</MkButton>
|
||||
</div>
|
||||
<div class="banner">
|
||||
<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="fas fa-plus"></i> {{ $ts._channel.setBanner }}</MkButton>
|
||||
<div v-else-if="bannerUrl">
|
||||
<img :src="bannerUrl" style="width: 100%;"/>
|
||||
<MkButton @click="removeBannerImage()"><i class="fas fa-trash-alt"></i> {{ $ts._channel.removeBanner }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_footer">
|
||||
<div class="_formBlock">
|
||||
<MkButton primary @click="save()"><i class="fas fa-save"></i> {{ channelId ? $ts.save : $ts.create }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -51,9 +49,11 @@ export default defineComponent({
|
||||
[symbols.PAGE_INFO]: computed(() => this.channelId ? {
|
||||
title: this.$ts._channel.edit,
|
||||
icon: 'fas fa-satellite-dish',
|
||||
bg: 'var(--bg)',
|
||||
} : {
|
||||
title: this.$ts._channel.create,
|
||||
icon: 'fas fa-satellite-dish',
|
||||
bg: 'var(--bg)',
|
||||
}),
|
||||
channel: null,
|
||||
name: null,
|
||||
|
@ -1,29 +1,31 @@
|
||||
<template>
|
||||
<div v-if="channel" class="_section">
|
||||
<div class="wpgynlbz _content _panel _gap" :class="{ hide: !showBanner }">
|
||||
<XChannelFollowButton :channel="channel" :full="true" class="subscribe"/>
|
||||
<button class="_button toggle" @click="() => showBanner = !showBanner">
|
||||
<template v-if="showBanner"><i class="fas fa-angle-up"></i></template>
|
||||
<template v-else><i class="fas fa-angle-down"></i></template>
|
||||
</button>
|
||||
<div v-if="!showBanner" class="hideOverlay">
|
||||
</div>
|
||||
<div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" class="banner">
|
||||
<div class="status">
|
||||
<div><i class="fas fa-users fa-fw"></i><I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
|
||||
<div><i class="fas fa-pencil-alt fa-fw"></i><I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
|
||||
<MkSpacer :content-max="700">
|
||||
<div v-if="channel">
|
||||
<div class="wpgynlbz _panel _gap" :class="{ hide: !showBanner }">
|
||||
<XChannelFollowButton :channel="channel" :full="true" class="subscribe"/>
|
||||
<button class="_button toggle" @click="() => showBanner = !showBanner">
|
||||
<template v-if="showBanner"><i class="fas fa-angle-up"></i></template>
|
||||
<template v-else><i class="fas fa-angle-down"></i></template>
|
||||
</button>
|
||||
<div v-if="!showBanner" class="hideOverlay">
|
||||
</div>
|
||||
<div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" class="banner">
|
||||
<div class="status">
|
||||
<div><i class="fas fa-users fa-fw"></i><I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
|
||||
<div><i class="fas fa-pencil-alt fa-fw"></i><I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
|
||||
</div>
|
||||
<div class="fade"></div>
|
||||
</div>
|
||||
<div v-if="channel.description" class="description">
|
||||
<Mfm :text="channel.description" :is-note="false" :i="$i"/>
|
||||
</div>
|
||||
<div class="fade"></div>
|
||||
</div>
|
||||
<div v-if="channel.description" class="description">
|
||||
<Mfm :text="channel.description" :is-note="false" :i="$i"/>
|
||||
</div>
|
||||
|
||||
<XPostForm v-if="$i" :channel="channel" class="post-form _panel _gap" fixed/>
|
||||
|
||||
<XTimeline :key="channelId" class="_gap" src="channel" :channel="channelId" @before="before" @after="after"/>
|
||||
</div>
|
||||
|
||||
<XPostForm v-if="$i" :channel="channel" class="post-form _content _panel _gap" fixed/>
|
||||
|
||||
<XTimeline :key="channelId" class="_content _gap" src="channel" :channel="channelId" @before="before" @after="after"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@ -55,6 +57,12 @@ export default defineComponent({
|
||||
[symbols.PAGE_INFO]: computed(() => this.channel ? {
|
||||
title: this.channel.name,
|
||||
icon: 'fas fa-satellite-dish',
|
||||
bg: 'var(--bg)',
|
||||
actions: [...(this.$i && this.$i.id === this.channel.userId ? [{
|
||||
icon: 'fas fa-cog',
|
||||
text: this.$ts.edit,
|
||||
handler: this.edit,
|
||||
}] : [])],
|
||||
} : null),
|
||||
channel: null,
|
||||
showBanner: true,
|
||||
@ -79,8 +87,10 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
|
||||
methods: {
|
||||
edit() {
|
||||
this.$router.push(`/channels/${this.channel.id}/edit`);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -1,58 +1,63 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="$i" class="_section" style="padding: 0;">
|
||||
<MkTab v-model="tab" class="_content">
|
||||
<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._channel.featured }}</option>
|
||||
<option value="following"><i class="fas fa-heart"></i> {{ $ts._channel.following }}</option>
|
||||
<option value="owned"><i class="fas fa-edit"></i> {{ $ts._channel.owned }}</option>
|
||||
</MkTab>
|
||||
<MkSpacer :content-max="700">
|
||||
<div v-if="tab === 'featured'" class="_content grwlizim featured">
|
||||
<MkPagination v-slot="{items}" :pagination="featuredPagination">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
|
||||
<div class="_section">
|
||||
<div v-if="tab === 'featured'" class="_content grwlizim featured">
|
||||
<MkPagination v-slot="{items}" :pagination="featuredPagination">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
|
||||
<div v-if="tab === 'following'" class="_content grwlizim following">
|
||||
<MkPagination v-slot="{items}" :pagination="followingPagination">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
|
||||
<div v-if="tab === 'owned'" class="_content grwlizim owned">
|
||||
<MkButton class="new" @click="create()"><i class="fas fa-plus"></i></MkButton>
|
||||
<MkPagination v-slot="{items}" :pagination="ownedPagination">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'following'" class="_content grwlizim following">
|
||||
<MkPagination v-slot="{items}" :pagination="followingPagination">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="tab === 'owned'" class="_content grwlizim owned">
|
||||
<MkButton class="new" @click="create()"><i class="fas fa-plus"></i></MkButton>
|
||||
<MkPagination v-slot="{items}" :pagination="ownedPagination">
|
||||
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import MkChannelPreview from '@/components/channel-preview.vue';
|
||||
import MkPagination from '@/components/ui/pagination.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkChannelPreview, MkPagination, MkButton, MkTab
|
||||
MkChannelPreview, MkPagination, MkButton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
[symbols.PAGE_INFO]: computed(() => ({
|
||||
title: this.$ts.channel,
|
||||
icon: 'fas fa-satellite-dish',
|
||||
action: {
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
icon: 'fas fa-plus',
|
||||
handler: this.create
|
||||
}
|
||||
},
|
||||
text: this.$ts.create,
|
||||
handler: this.create,
|
||||
}],
|
||||
tabs: [{
|
||||
active: this.tab === 'featured',
|
||||
title: this.$ts._channel.featured,
|
||||
icon: 'fas fa-fire-alt',
|
||||
onClick: () => { this.tab = 'featured'; },
|
||||
}, {
|
||||
active: this.tab === 'following',
|
||||
title: this.$ts._channel.following,
|
||||
icon: 'fas fa-heart',
|
||||
onClick: () => { this.tab = 'following'; },
|
||||
}, {
|
||||
active: this.tab === 'owned',
|
||||
title: this.$ts._channel.owned,
|
||||
icon: 'fas fa-edit',
|
||||
onClick: () => { this.tab = 'owned'; },
|
||||
},]
|
||||
})),
|
||||
tab: 'featured',
|
||||
featuredPagination: {
|
||||
endpoint: 'channels/featured',
|
||||
|
@ -12,7 +12,6 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import * as os from '@/os';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import VanillaTilt from 'vanilla-tilt';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -22,17 +21,6 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.$store.animation) {
|
||||
VanillaTilt.init(this.$el, {
|
||||
reverse: true,
|
||||
gyroscope: false,
|
||||
scale: 1.1,
|
||||
speed: 500,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
menu(ev) {
|
||||
os.popupMenu([{
|
||||
@ -59,8 +47,6 @@ export default defineComponent({
|
||||
text-align: left;
|
||||
background: var(--panel);
|
||||
border-radius: 8px;
|
||||
transform-style: preserve-3d;
|
||||
transform: perspective(1000px);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--accent);
|
||||
@ -69,14 +55,12 @@ export default defineComponent({
|
||||
> .img {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
transform: translateZ(20px);
|
||||
}
|
||||
|
||||
> .body {
|
||||
padding: 0 0 0 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
transform: translateZ(10px);
|
||||
|
||||
> .name {
|
||||
text-overflow: ellipsis;
|
||||
|
@ -1,14 +1,13 @@
|
||||
<template>
|
||||
<div class="jmelgwjh">
|
||||
<div class="body">
|
||||
<XNotes class="notes" :pagination="pagination" :detail="true" :prop="'note'" @before="before()" @after="after()"/>
|
||||
<XNotes class="notes" :pagination="pagination" :detail="true" :prop="'note'"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
@ -33,16 +32,6 @@ export default defineComponent({
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<XNotes ref="notes" :pagination="pagination" @before="before" @after="after"/>
|
||||
<XNotes ref="notes" :pagination="pagination"/>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
@ -29,15 +28,5 @@ export default defineComponent({
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<XNotes :pagination="pagination" @before="before()" @after="after()"/>
|
||||
<XNotes :pagination="pagination"/>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
@ -28,15 +27,5 @@ export default defineComponent({
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<XNotes :pagination="pagination" @before="before()" @after="after()"/>
|
||||
<XNotes :pagination="pagination"/>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
@ -31,15 +30,5 @@ export default defineComponent({
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -35,7 +35,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
@ -73,7 +72,6 @@ export default defineComponent({
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
Progress.start();
|
||||
os.api('users/groups/show', {
|
||||
groupId: this.groupId
|
||||
}).then(group => {
|
||||
@ -82,7 +80,6 @@ export default defineComponent({
|
||||
userIds: this.group.userIds
|
||||
}).then(users => {
|
||||
this.users = users;
|
||||
Progress.done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
@ -68,7 +67,6 @@ export default defineComponent({
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
Progress.start();
|
||||
os.api('users/lists/show', {
|
||||
listId: this.$route.params.list
|
||||
}).then(list => {
|
||||
@ -77,7 +75,6 @@ export default defineComponent({
|
||||
userIds: this.list.userIds
|
||||
}).then(users => {
|
||||
this.users = users;
|
||||
Progress.done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -1,14 +1,13 @@
|
||||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<div class="clupoqwt">
|
||||
<XNotifications class="notifications" :include-types="includeTypes" :unread-only="tab === 'unread'" @before="before" @after="after"/>
|
||||
<XNotifications class="notifications" :include-types="includeTypes" :unread-only="tab === 'unread'"/>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotifications from '@/components/notifications.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
@ -53,14 +52,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
},
|
||||
|
||||
setFilter(ev) {
|
||||
const typeItems = notificationTypes.map(t => ({
|
||||
text: this.$t(`_notification._types.${t}`),
|
||||
|
@ -1,14 +1,13 @@
|
||||
<template>
|
||||
<div class="_section">
|
||||
<div class="_content">
|
||||
<XNotes ref="notes" :pagination="pagination" @before="before" @after="after"/>
|
||||
<XNotes ref="notes" :pagination="pagination"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
@ -39,15 +38,5 @@ export default defineComponent({
|
||||
(this.$refs.notes as any).reload();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -43,6 +43,7 @@
|
||||
<FormSwitch v-model="useOsNativeEmojis" class="_formBlock">{{ $ts.useOsNativeEmojis }}
|
||||
<div><Mfm :key="useOsNativeEmojis" text="🍮🍦🍭🍩🍰🍫🍬🥞🍪"/></div>
|
||||
</FormSwitch>
|
||||
<FormSwitch v-model="disableDrawer" class="_formBlock">{{ $ts.disableDrawer }}</FormSwitch>
|
||||
|
||||
<FormRadios v-model="fontSize" class="_formBlock">
|
||||
<template #label>{{ $ts.fontSize }}</template>
|
||||
@ -76,13 +77,6 @@
|
||||
<FormSwitch v-model="defaultSideView">{{ $ts.openInSideView }}</FormSwitch>
|
||||
</FormGroup>
|
||||
|
||||
<FormSelect v-model="chatOpenBehavior" class="_formBlock">
|
||||
<template #label>{{ $ts.chatOpenBehavior }}</template>
|
||||
<option value="page">{{ $ts.showInPage }}</option>
|
||||
<option value="window">{{ $ts.openInWindow }}</option>
|
||||
<option value="popout">{{ $ts.popout }}</option>
|
||||
</FormSelect>
|
||||
|
||||
<FormLink to="/settings/deck" class="_formBlock">{{ $ts.deck }}</FormLink>
|
||||
|
||||
<FormLink to="/settings/custom-css" class="_formBlock"><template #icon><i class="fas fa-code"></i></template>{{ $ts.customCss }}</FormLink>
|
||||
@ -140,6 +134,7 @@ export default defineComponent({
|
||||
showGapBetweenNotesInTimeline: defaultStore.makeGetterSetter('showGapBetweenNotesInTimeline'),
|
||||
disableAnimatedMfm: defaultStore.makeGetterSetter('animatedMfm', v => !v, v => !v),
|
||||
useOsNativeEmojis: defaultStore.makeGetterSetter('useOsNativeEmojis'),
|
||||
disableDrawer: defaultStore.makeGetterSetter('disableDrawer'),
|
||||
disableShowingAnimatedImages: defaultStore.makeGetterSetter('disableShowingAnimatedImages'),
|
||||
loadRawImages: defaultStore.makeGetterSetter('loadRawImages'),
|
||||
imageNewTab: defaultStore.makeGetterSetter('imageNewTab'),
|
||||
@ -147,7 +142,6 @@ export default defineComponent({
|
||||
disablePagesScript: defaultStore.makeGetterSetter('disablePagesScript'),
|
||||
showFixedPostForm: defaultStore.makeGetterSetter('showFixedPostForm'),
|
||||
defaultSideView: defaultStore.makeGetterSetter('defaultSideView'),
|
||||
chatOpenBehavior: ColdDeviceStorage.makeGetterSetter('chatOpenBehavior'),
|
||||
instanceTicker: defaultStore.makeGetterSetter('instanceTicker'),
|
||||
enableInfiniteScroll: defaultStore.makeGetterSetter('enableInfiniteScroll'),
|
||||
useReactionPickerForContextMenu: defaultStore.makeGetterSetter('useReactionPickerForContextMenu'),
|
||||
|
@ -30,7 +30,10 @@
|
||||
<option :value="3">{{ $ts.large }}</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormSwitch v-model="reactionPickerUseDrawerForMobile" class="_formBlock">{{ $ts.useDrawerReactionPickerForMobile }}</FormSwitch>
|
||||
<FormSwitch v-model="reactionPickerUseDrawerForMobile" class="_formBlock">
|
||||
{{ $ts.useDrawerReactionPickerForMobile }}
|
||||
<template #caption>{{ $ts.needReloadToApply }}</template>
|
||||
</FormSwitch>
|
||||
|
||||
<FormSection>
|
||||
<div style="display: flex; gap: var(--margin); flex-wrap: wrap;">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="_formRoot">
|
||||
<div v-panel class="rfqxtzch _formBlock">
|
||||
<div v-adaptive-border class="rfqxtzch _panel _formBlock">
|
||||
<div class="toggle">
|
||||
<div class="toggleWrapper">
|
||||
<input id="dn" v-model="darkMode" type="checkbox" class="dn"/>
|
||||
|
@ -31,12 +31,15 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
os.apiWithDialog('signup-pending', {
|
||||
code: this.code,
|
||||
}).then(res => {
|
||||
login(res.i, '/');
|
||||
async mounted() {
|
||||
await os.alert({
|
||||
type: 'info',
|
||||
text: this.$t('clickToFinishEmailVerification', { ok: this.$ts.gotIt }),
|
||||
});
|
||||
const res = await os.apiWithDialog('signup-pending', {
|
||||
code: this.code,
|
||||
});
|
||||
login(res.i, '/');
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<div class="_section">
|
||||
<XNotes ref="notes" class="_content" :pagination="pagination" @before="before" @after="after"/>
|
||||
<XNotes ref="notes" class="_content" :pagination="pagination"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XNotes from '@/components/notes.vue';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
@ -43,15 +42,5 @@ export default defineComponent({
|
||||
(this.$refs.notes as any).reload();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -10,8 +10,6 @@
|
||||
class="tl"
|
||||
:src="src"
|
||||
:sound="true"
|
||||
@before="before()"
|
||||
@after="after()"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
@ -21,7 +19,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, defineAsyncComponent, computed } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XTimeline from '@/components/timeline.vue';
|
||||
import XPostForm from '@/components/post-form.vue';
|
||||
import { scroll } from '@/scripts/scroll';
|
||||
@ -118,14 +115,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
},
|
||||
|
||||
queueUpdated(q) {
|
||||
this.queue = q;
|
||||
},
|
||||
|
@ -7,8 +7,6 @@
|
||||
src="list"
|
||||
:list="listId"
|
||||
:sound="true"
|
||||
@before="before()"
|
||||
@after="after()"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
</div>
|
||||
@ -17,7 +15,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, defineAsyncComponent, computed } from 'vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import XTimeline from '@/components/timeline.vue';
|
||||
import { scroll } from '@/scripts/scroll';
|
||||
import * as os from '@/os';
|
||||
@ -76,14 +73,6 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
methods: {
|
||||
before() {
|
||||
Progress.start();
|
||||
},
|
||||
|
||||
after() {
|
||||
Progress.done();
|
||||
},
|
||||
|
||||
queueUpdated(q) {
|
||||
this.queue = q;
|
||||
},
|
||||
|
@ -205,7 +205,6 @@ import MkFolder from '@/components/ui/folder.vue';
|
||||
import MkRemoteCaution from '@/components/remote-caution.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
import MkInfo from '@/components/ui/info.vue';
|
||||
import Progress from '@/scripts/loading';
|
||||
import * as Acct from 'misskey-js/built/acct';
|
||||
import { getScrollPosition } from '@/scripts/scroll';
|
||||
import { getUserMenu } from '@/scripts/get-user-menu';
|
||||
@ -328,13 +327,10 @@ export default defineComponent({
|
||||
fetch() {
|
||||
if (this.acct == null) return;
|
||||
this.user = null;
|
||||
Progress.start();
|
||||
os.api('users/show', Acct.parse(this.acct)).then(user => {
|
||||
this.user = user;
|
||||
}).catch(e => {
|
||||
this.error = e;
|
||||
}).finally(() => {
|
||||
Progress.done();
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
export default {
|
||||
start: () => {
|
||||
// TODO
|
||||
},
|
||||
done: () => {
|
||||
// TODO
|
||||
},
|
||||
set: val => {
|
||||
// TODO
|
||||
}
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
import { Ref, ref, watch } from 'vue';
|
||||
import { Ref, ref, watch, onUnmounted } from 'vue';
|
||||
|
||||
export function useTooltip(
|
||||
elRef: Ref<HTMLElement | { $el: HTMLElement } | null | undefined>,
|
||||
@ -18,6 +18,9 @@ export function useTooltip(
|
||||
const open = () => {
|
||||
close();
|
||||
if (!isHovering) return;
|
||||
if (elRef.value == null) return;
|
||||
const el = elRef.value instanceof Element ? elRef.value : elRef.value.$el;
|
||||
if (!document.body.contains(el)) return; // openしようとしたときに既に元要素がDOMから消えている場合があるため
|
||||
|
||||
const showing = ref(true);
|
||||
onShow(showing);
|
||||
@ -69,9 +72,14 @@ export function useTooltip(
|
||||
el.addEventListener('mouseleave', onMouseleave, { passive: true });
|
||||
el.addEventListener('touchstart', onTouchstart, { passive: true });
|
||||
el.addEventListener('touchend', onTouchend, { passive: true });
|
||||
el.addEventListener('click', close, { passive: true });
|
||||
}
|
||||
}, {
|
||||
immediate: true,
|
||||
flush: 'post',
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
close();
|
||||
});
|
||||
}
|
||||
|
@ -138,6 +138,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||
where: 'device',
|
||||
default: false
|
||||
},
|
||||
disableDrawer: {
|
||||
where: 'device',
|
||||
default: false
|
||||
},
|
||||
useBlurEffectForModal: {
|
||||
where: 'device',
|
||||
default: true
|
||||
@ -241,7 +245,6 @@ export class ColdDeviceStorage {
|
||||
lightTheme: require('@/themes/l-light.json5') as Theme,
|
||||
darkTheme: require('@/themes/d-dark.json5') as Theme,
|
||||
syncDeviceDarkMode: true,
|
||||
chatOpenBehavior: 'page' as 'page' | 'window' | 'popout',
|
||||
plugins: [] as Plugin[],
|
||||
mediaVolume: 0.5,
|
||||
sound_masterVolume: 0.3,
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
declare var self: ServiceWorkerGlobalScope;
|
||||
|
||||
import { getNoteSummary } from '@/scripts/get-note-summary';
|
||||
import * as misskey from 'misskey-js';
|
||||
|
||||
function getUserName(user: misskey.entities.User): string {
|
||||
@ -26,37 +25,37 @@ export default async function(type, data, i18n): Promise<[string, NotificationOp
|
||||
switch (data.type) {
|
||||
case 'mention':
|
||||
return [i18n.t('_notification.youGotMention', { name: getUserName(data.user) }), {
|
||||
body: getNoteSummary(data.note, i18n.locale),
|
||||
body: data.note.text,
|
||||
icon: data.user.avatarUrl
|
||||
}];
|
||||
|
||||
case 'reply':
|
||||
return [i18n.t('_notification.youGotReply', { name: getUserName(data.user) }), {
|
||||
body: getNoteSummary(data.note, i18n.locale),
|
||||
body: data.note.text,
|
||||
icon: data.user.avatarUrl
|
||||
}];
|
||||
|
||||
case 'renote':
|
||||
return [i18n.t('_notification.youRenoted', { name: getUserName(data.user) }), {
|
||||
body: getNoteSummary(data.note, i18n.locale),
|
||||
body: data.note.text,
|
||||
icon: data.user.avatarUrl
|
||||
}];
|
||||
|
||||
case 'quote':
|
||||
return [i18n.t('_notification.youGotQuote', { name: getUserName(data.user) }), {
|
||||
body: getNoteSummary(data.note, i18n.locale),
|
||||
body: data.note.text,
|
||||
icon: data.user.avatarUrl
|
||||
}];
|
||||
|
||||
case 'reaction':
|
||||
return [`${data.reaction} ${getUserName(data.user)}`, {
|
||||
body: getNoteSummary(data.note, i18n.locale),
|
||||
body: data.note.text,
|
||||
icon: data.user.avatarUrl
|
||||
}];
|
||||
|
||||
case 'pollVote':
|
||||
return [i18n.t('_notification.youGotPoll', { name: getUserName(data.user) }), {
|
||||
body: getNoteSummary(data.note, i18n.locale),
|
||||
body: data.note.text,
|
||||
icon: data.user.avatarUrl
|
||||
}];
|
||||
|
||||
|
@ -34,7 +34,7 @@ export default defineComponent({
|
||||
id: notification.id
|
||||
});
|
||||
|
||||
popup(import('@/components/toast.vue'), {
|
||||
popup(import('@/components/notification-toast.vue'), {
|
||||
notification
|
||||
}, {}, 'closed');
|
||||
}
|
||||
@ -60,7 +60,7 @@ export default defineComponent({
|
||||
#wait {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 3000000;
|
||||
z-index: 4000000;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
|
||||
|
@ -170,6 +170,8 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
&:hover, &.active {
|
||||
color: var(--accent);
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
@ -283,8 +285,10 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
&:before {
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
width: min-content;
|
||||
height: 100%;
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
&.post {
|
||||
@ -296,8 +300,9 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
&.post:before {
|
||||
width: calc(100% - 32px);
|
||||
height: calc(100% - 32px);
|
||||
width: calc(100% - 28px);
|
||||
height: min-content;
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
uploads: os.uploads,
|
||||
zIndex: os.claimZIndex(true),
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -82,7 +82,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const columns = deckStore.reactiveState.columns;
|
||||
const layout = deckStore.reactiveState.layout.value;
|
||||
const layout = deckStore.reactiveState.layout;
|
||||
const menuIndicated = computed(() => {
|
||||
if ($i == null) return false;
|
||||
for (const def in menuDef) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user