Merge branch 'develop' into beta

This commit is contained in:
ThatOneCalculator 2023-04-25 09:18:38 -07:00
commit 382b77e26a
No known key found for this signature in database
GPG key ID: 8703CACD01000000
53 changed files with 3567 additions and 2636 deletions

3
.weblate Normal file
View file

@ -0,0 +1,3 @@
[weblate]
url = https://hosted.weblate.org/api/
translation = calckey/locales

View file

@ -1,22 +1,21 @@
---
_lang_: "Ελληνικά" _lang_: "Ελληνικά"
monthAndDay: "{μήνας}/{ημέρα}" monthAndDay: "{day}/{month}"
search: "Αναζήτηση" search: "Αναζήτηση"
notifications: "Ειδοποιήσεις" notifications: "Ειδοποιήσεις"
username: "Όνομα μέλους" username: "Όνομα μέλους"
password: "Κωδικός πρόσβασης" password: "Κωδικός πρόσβασης"
forgotPassword: "Ξέχασα τον κωδικό πρόσβασης" forgotPassword: "Ξέχασα τον κωδικό πρόσβασης"
fetchingAsApObject: "Μαζεύοντας από το Fediverse..." fetchingAsApObject: "Άντληση από το Fediverse"
ok: "Εντάξει" ok: "Εντάξει"
gotIt: "Τό'πιασα!" gotIt: "Τό'πιασα!"
cancel: "Ακύρωση" cancel: "Ακύρωση"
enterUsername: "Εισάγετε το όνομα μέλους" enterUsername: "Εισαγωγή ονόματος μέλους"
renotedBy: "Κοινοποιήθηκε από {user}" renotedBy: "Προωθήθηκε από {user}"
noNotes: "Δεν υπάρχουν σημειώματα" noNotes: "Δεν υπάρχουν δημοσιεύσεις"
noNotifications: "Δεν υπάρχουν ειδοποιήσεις" noNotifications: "Δεν υπάρχουν ειδοποιήσεις"
settings: "Ρυθμίσεις" settings: "Ρυθμίσεις"
basicSettings: "Βασικές ρυθμίσεις" basicSettings: "Βασικές Ρυθμίσεις"
otherSettings: "Άλλες ρυθμίσεις" otherSettings: "Άλλες Ρυθμίσεις"
openInWindow: "Άνοιγμα σε παράθυρο" openInWindow: "Άνοιγμα σε παράθυρο"
profile: "Προφίλ" profile: "Προφίλ"
timeline: "Χρονολόγιο" timeline: "Χρονολόγιο"
@ -24,24 +23,25 @@ noAccountDescription: "Αυτό το μέλος δεν έχει γράψει β
login: "Σύνδεση" login: "Σύνδεση"
loggingIn: "Συνδέεστε" loggingIn: "Συνδέεστε"
logout: "Αποσύνδεση" logout: "Αποσύνδεση"
signup: "Δημιουργία λογαριασμού" signup: "Εγγραφή"
uploading: "Ανέβασμα..." uploading: "Ανέβασμα..."
save: "Αποθήκευση" save: "Αποθήκευση"
users: "Μέλη" users: "Μέλη"
addUser: "Προσθήκη μέλους" addUser: "Προσθήκη μέλους"
favorite: "Προσθήκη στα αγαπημένα" favorite: "Προσθήκη στους σελιδοδείκτες"
favorites: "Αγαπημένα" favorites: "Σελιδοδείκτες"
unfavorite: "Αφαίρεση από αγαπημένα" unfavorite: "Αφαίρεση από τους σελιδοδείκτες"
favorited: "Προστέθηκε στα αγαπημένα." favorited: "Προστέθηκε στους σελιδοδείκτες."
alreadyFavorited: "Έχει ήδη προστεθεί στα αγαπημένα." alreadyFavorited: "Έχει ήδη προστεθεί στους σελιδοδείκτες."
cantFavorite: "Αδυναμία προσθήκης στα αγαπημένα." cantFavorite: "Αδυναμία προσθήκης στους σελιδοδείκτες."
pin: "Καρφίτσωμα στο προφίλ" pin: "Καρφίτσωμα στο προφίλ"
unpin: "Ξεκαρφίτσωμα από το προφίλ" unpin: "Ξεκαρφίτσωμα από το προφίλ"
copyContent: "Αντιγραφή περιεχομένων" copyContent: "Αντιγραφή περιεχομένων"
copyLink: "Αντιγραφή συνδέσμου" copyLink: "Αντιγραφή συνδέσμου"
delete: "Διαγραφή" delete: "Διαγραφή"
deleteAndEdit: "Διαγραφή και επεξεργασία" deleteAndEdit: "Διαγραφή και επεξεργασία"
deleteAndEditConfirm: "Σίγουρα θέλετε να διαγράψετε αυτό το σημείωμα και να το επεξεργαστείτε; Θα χάσετε όλες τις αντιδράσεις, κοινοποιήσεις και απαντήσεις σε αυτό." deleteAndEditConfirm: "Σίγουρα θέλετε να διαγράψετε αυτή τη δημοσίευση και να την\
\ επεξεργαστείτε; Θα χάσετε όλες τις αντιδράσεις, προωθήσεις και απαντήσεις σε αυτήν."
addToList: "Προσθήκη στη λίστα" addToList: "Προσθήκη στη λίστα"
sendMessage: "Αποστολή μηνύματος" sendMessage: "Αποστολή μηνύματος"
copyUsername: "Αντιγραφή ονόματος μέλους" copyUsername: "Αντιγραφή ονόματος μέλους"
@ -55,20 +55,22 @@ receiveFollowRequest: "Λάβατε αίτημα ακολούθησης"
followRequestAccepted: "Το αίτημα ακολούθησης έγινε δεκτό" followRequestAccepted: "Το αίτημα ακολούθησης έγινε δεκτό"
mention: "Επισήμανση" mention: "Επισήμανση"
mentions: "Επισημάνσεις" mentions: "Επισημάνσεις"
directNotes: "Απευθείας σημειώματα" directNotes: "Απευθείας μηνύματα"
importAndExport: "Εισαγωγή / Εξαγωγή" importAndExport: "Εισαγωγή/Εξαγωγή Δεδομένων"
import: "Εισαγωγή" import: "Εισαγωγή"
export: "Εξαγωγή" export: "Εξαγωγή"
files: "Αρχεία" files: "Αρχεία"
download: "Λήψη" download: "Κατέβασμα"
driveFileDeleteConfirm: "Θέλετε σίγουρα να διαγράψετε το αρχείο \"{name}\"; Τα σημειώματα με αυτό το συνημμένο αρχείο επίσης θα διαγραφούν." driveFileDeleteConfirm: "Θέλετε σίγουρα να διαγράψετε το αρχείο \"{name}\"; Οι δημοσιεύσεις\
\ με αυτό το συνημμένο αρχείο επίσης θα διαγραφούν."
unfollowConfirm: "Θέλετε σίγουρα να σταματήσετε να ακολουθείτε το μέλος {name};" unfollowConfirm: "Θέλετε σίγουρα να σταματήσετε να ακολουθείτε το μέλος {name};"
exportRequested: "Ζητήσατε μία εξαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο. Επίσης θα προστεθεί στον Δίσκο σας μόλις ολοκληρωθεί." exportRequested: "Ζητήσατε μία εξαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο. Θα προστεθεί\
importRequested: "Ζητήσατε μία εισαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο." \ στον Αποθηκευτικό Χώρο σας μόλις ολοκληρωθεί."
importRequested: "Ζητήσατε μια εισαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο."
lists: "Λίστες" lists: "Λίστες"
noLists: "Δεν έχετε λίστες" noLists: "Δεν έχετε λίστες"
note: "Σημείωμα" note: "Δημοσίευση"
notes: "Σημειώματα" notes: "Δημοσιεύσεις"
following: "Ακολουθεί" following: "Ακολουθεί"
followers: "Ακολουθούν" followers: "Ακολουθούν"
followsYou: "Σε ακολουθεί" followsYou: "Σε ακολουθεί"
@ -78,69 +80,74 @@ error: "Σφάλμα"
somethingHappened: "Προέκυψε ένα σφάλμα" somethingHappened: "Προέκυψε ένα σφάλμα"
retry: "Προσπάθεια ξανά" retry: "Προσπάθεια ξανά"
pageLoadError: "Ένα σφάλμα προέκυψε φορτώνοντας τη σελίδα." pageLoadError: "Ένα σφάλμα προέκυψε φορτώνοντας τη σελίδα."
pageLoadErrorDescription: "Αυτό κανονικά προκαλείται από σφάλματα δικτύου ή από την προσωρινή μνήμη του προγράμματος περιήγησης. Δοκιμάστε να σβήσετε την προσωρινή μνήμη (cache) και ξαναδοκιμάστε μετά από λίγο." pageLoadErrorDescription: "Αυτό κανονικά προκαλείται από σφάλματα δικτύου ή από την\
serverIsDead: "Αυτός ο server δεν αποκρίνεται. Παρακαλώ περιμέντε λίγο και δοκιμάστε ξανά." \ προσωρινή μνήμη του προγράμματος περιήγησης. Δοκιμάστε να σβήσετε την προσωρινή\
youShouldUpgradeClient: "Για να δείτε αυτή τη σελίδα, παρακαλώ επαναφορτώστε για να ενημερωθεί το πρόγραμμα." \ μνήμη (cache) και να δοκιμάσετε ξανά μετά από λίγο."
serverIsDead: "Αυτός ο διακομιστής (server) δεν αποκρίνεται. Παρακαλώ περιμένετε λίγο\
\ και δοκιμάστε ξανά."
youShouldUpgradeClient: "Για να δείτε αυτή τη σελίδα, παρακαλώ επαναφορτώστε για να\
\ γίνει ενημέρωση."
enterListName: "Πληκτρολογήστε ένα όνομα για τη λίστα" enterListName: "Πληκτρολογήστε ένα όνομα για τη λίστα"
privacy: "Ιδιωτικότητα" privacy: "Ιδιωτικότητα"
makeFollowManuallyApprove: "Τα αιτήματα ακολούθησης χρειάζονται έγκριση" makeFollowManuallyApprove: "Τα αιτήματα ακολούθησης χρειάζονται έγκριση"
defaultNoteVisibility: "Προεπιλεγμένη ορατότητα" defaultNoteVisibility: "Προεπιλεγμένη ορατότητα"
follow: "Ακολουθήστε" follow: "Ακολουθήστε"
followRequest: "Στείλτε αίτημα ακολούθησης" followRequest: "Ακολουθήστε"
followRequests: "Αιτήματα ακολούθησης" followRequests: "Αιτήματα ακολούθησης"
unfollow: "Να μην ακολουθώ" unfollow: "Να μην ακολουθώ"
followRequestPending: "Το αίτημα ακολούθησης εκκρεμεί" followRequestPending: "Το αίτημα ακολούθησης εκκρεμεί"
enterEmoji: "Εισάγετε ένα emoji" enterEmoji: "Εισάγετε ένα emoji"
renote: "Κοινοποίηση σημειώματος" renote: "Προώθηση"
unrenote: "Ακύρωση κοινοποίησης" unrenote: "Αναίρεση προώθησης"
renoted: "Κοινοποιήθηκε." renoted: "Προωθήθηκε."
cantRenote: "Αυτή η δημοσίευση δεν μπορεί να κοινοποιηθεί." cantRenote: "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί."
cantReRenote: "Μία κοινοποίηση δεν μπορεί να κοινοποιηθεί." cantReRenote: "Μία προώθηση δεν μπορεί να προωθηθεί."
quote: "Παράθεση" quote: "Παράθεση"
pinnedNote: "Καρφιτσωμένο σημείωμα" pinnedNote: "Καρφιτσωμένη δημοσίευση"
pinned: "Καρφίτσωμα στο προφίλ" pinned: "Καρφίτσωμα στο προφίλ"
you: "Εσύ" you: "Εσύ"
clickToShow: "Κάντε κλικ για εμφάνιση" clickToShow: "Κάντε κλικ για εμφάνιση"
add: "Προσθέστε" add: "Προσθήκη"
reaction: "Αντιδράσεις" reaction: "Αντιδράσεις"
reactionSetting: "Αντιδράσεις για εμφάνιση στην επιλογή αντίδρασης" reactionSetting: "Αντιδράσεις που θα εμφανίζονται στον επιλογέα"
reactionSettingDescription2: "Σύρετε για να αλλάξετε τη σειρά, κάντε κλικ για να διαγράψετε, πατήστε \"+\" για να προσθέσετε." reactionSettingDescription2: "Σύρετε για να αλλάξετε τη σειρά, κάντε κλικ για να διαγράψετε,\
rememberNoteVisibility: "Θυμήσου τις ρυθμίσεις ορατότητας σημειώματος" \ πατήστε \"+\" για να προσθέσετε."
attachCancel: "Διαγραφή αρχείου" rememberNoteVisibility: "Θυμήσου τις ρυθμίσεις ορατότητας για τις δημοσιεύσεις"
attachCancel: "Αφαίρεση επισυναπτόμενου"
enterFileName: "Πληκτρολογήστε όνομα αρχείου" enterFileName: "Πληκτρολογήστε όνομα αρχείου"
mute: "Σίγαση" mute: "Σίγαση"
unmute: "Άρση σίγασης" unmute: "Διακοπή σίγασης"
block: "Μπλοκάρισμα" block: "Μπλοκάρισμα"
unblock: "Άρση μπλοκαρίσματος" unblock: "Διακοπή μπλοκαρίσματος"
suspend: "Αποβολή" suspend: "Αποβολή"
unsuspend: "Άρση αποβολής" unsuspend: "Διακοπή αποβολής"
blockConfirm: "Θέλετε σίγουρα να μπλοκάρετε αυτόν τον λογαριασμό;" blockConfirm: "Θέλετε σίγουρα να μπλοκάρετε αυτόν τον λογαριασμό;"
unblockConfirm: "Θέλετε σίγουρα να ξεμπλοκάρετε αυτόν τον λογαριασμό;" unblockConfirm: "Θέλετε σίγουρα να ξεμπλοκάρετε αυτόν τον λογαριασμό;"
suspendConfirm: "Θέλετε σίγουρα να αποβάλλετε αυτόν τον λογαριασμό;" suspendConfirm: "Θέλετε σίγουρα να αποβάλετε αυτόν τον λογαριασμό;"
unsuspendConfirm: "Θέλετε σίγουρα να άρετε την αποβολή αυτού του λογαριασμού;" unsuspendConfirm: "Θέλετε σίγουρα να άρετε την αποβολή αυτού του λογαριασμού;"
selectList: "Επιλέξτε μία λίστα" selectList: "Επιλέξτε μια λίστα"
selectAntenna: "Επιλέξτε μία αντένα" selectAntenna: "Επιλέξτε μια αντένα"
selectWidget: "Επιλέξτε ένα μαραφέτι" selectWidget: "Επιλέξτε ένα πρόσθετο"
editWidgets: "Επεξεργασία μαραφετίων" editWidgets: "Επεξεργασία πρόσθετων"
editWidgetsExit: "Ολοκληρώθηκε" editWidgetsExit: "Ολοκληρώθηκε"
customEmojis: "Επιπλέον emoji" customEmojis: "Προσαρμοσμένα Emoji"
emojiName: "Όνομα emoji" emojiName: "Όνομα emoji"
addEmoji: "Προσθήκη emoji" addEmoji: "Προσθήκη"
settingGuide: "Συνιστώμενες ρυθμίσεις" settingGuide: "Προτεινόμενες ρυθμίσεις"
flagAsBot: "Αυτός ο λογαριασμός είναι bot" flagAsBot: "Δήλωση αυτού του λογαριασμού ως bot"
flagAsCat: "Αυτός ο λογαριασμός είναι γάτα" flagAsCat: "Είσαι γατί; \U0001F63A"
flagShowTimelineReplies: "Εμφάνιση απαντήσεων στο χρονολόγιο" flagShowTimelineReplies: "Εμφάνιση απαντήσεων στο χρονολόγιο"
addAccount: "Προσθήκη λογαριασμού" addAccount: "Προσθήκη λογαριασμού"
general: "Γενικές" general: "Γενικές"
wallpaper: "Ταπετσαρία" wallpaper: "Ταπετσαρία"
setWallpaper: "Ορισμός ταπετσαρίας" setWallpaper: "Ορισμός ταπετσαρίας"
removeWallpaper: "Διαγραφή ταπετσαρίας" removeWallpaper: "Αφαίρεση ταπετσαρίας"
searchWith: "Αναζήτηση: {q}" searchWith: "Αναζήτηση: {q}"
youHaveNoLists: "Δεν έχετε λίστες" youHaveNoLists: "Δεν έχετε λίστες"
followConfirm: "Θέλετε σίγουρα να ακολουθήσετε τον λογαριασμό {name};" followConfirm: "Θέλετε σίγουρα να ακολουθήσετε τον λογαριασμό {name};"
host: "Φιλοξενεί" host: "Φιλοξενεί (Host)"
selectUser: "Επιλέξτε ένα μέλος" selectUser: "Επιλέξτε ένα μέλος"
recipient: "Αποδέκτης-τρια" recipient: "Αποδέκτης-τρια(-ες)"
annotation: "Σχόλια" annotation: "Σχόλια"
federation: "Ομοσπονδία" federation: "Ομοσπονδία"
storageUsage: "Χρήση χώρου" storageUsage: "Χρήση χώρου"
@ -148,11 +155,11 @@ version: "Έκδοση"
metadata: "Μεταδεδομένα" metadata: "Μεταδεδομένα"
network: "Δίκτυο" network: "Δίκτυο"
disk: "Δίσκος" disk: "Δίσκος"
instanceInfo: "Πληροφορίες του instance" instanceInfo: "Πληροφορίες Instance"
statistics: "Στατιστικά" statistics: "Στατιστικά"
clearQueue: "Εκκαθάριση ουράς" clearQueue: "Εκκαθάριση ουράς"
clearQueueConfirmTitle: "Θέλετε να διαγράψετε την ουρά;" clearQueueConfirmTitle: "Θέλετε να διαγράψετε την ουρά;"
clearCachedFiles: "Εκκαθάριση προσωρινής μνήμης" clearCachedFiles: "Εκκαθάριση προσωρινής μνήμης (cache)"
done: "Ολοκληρώθηκε" done: "Ολοκληρώθηκε"
attachFile: "Επισύναψη αρχείων" attachFile: "Επισύναψη αρχείων"
more: "Περισσότερα!" more: "Περισσότερα!"
@ -166,12 +173,12 @@ messaging: "Συνομιλία"
upload: "Ανεβάστε" upload: "Ανεβάστε"
fromDrive: "Από τον Αποθηκευτικό Χώρο" fromDrive: "Από τον Αποθηκευτικό Χώρο"
fromUrl: "Από URL" fromUrl: "Από URL"
uploadFromUrl: "Ανεβάστε από URL" uploadFromUrl: "Ανέβασμα από URL"
explore: "Εξερευνήστε" explore: "Εξερεύνηση"
messageRead: "Διαβάστηκε" messageRead: "Διαβάστηκε"
startMessaging: "Ξεκινήστε μία συνομιλία" startMessaging: "Ξεκινήστε μια νέα συνομιλία"
nUsersRead: "διαβάστηκε από {n}" nUsersRead: "διαβάστηκε από {n}"
tos: "Όροι χρήσης" tos: "Όροι Χρήσης"
start: "Ας αρχίσουμε" start: "Ας αρχίσουμε"
home: "Κεντρικό" home: "Κεντρικό"
activity: "Δραστηριότητα" activity: "Δραστηριότητα"
@ -180,8 +187,8 @@ birthday: "Γενέθλια"
registeredDate: "Έγινε μέλος στις" registeredDate: "Έγινε μέλος στις"
location: "Τοποθεσία" location: "Τοποθεσία"
theme: "Θέματα" theme: "Θέματα"
light: "Ανοιχτόχρωμο" light: "Φωτεινό"
dark: "Σκούρο" dark: "Σκοτεινό"
drive: "Αποθηκευτικός Χώρος" drive: "Αποθηκευτικός Χώρος"
fileName: "Όνομα αρχείου" fileName: "Όνομα αρχείου"
selectFile: "Επιλέξτε ένα αρχείο" selectFile: "Επιλέξτε ένα αρχείο"
@ -189,16 +196,16 @@ selectFiles: "Επιλέξτε αρχεία"
selectFolder: "Επιλέξτε φάκελο" selectFolder: "Επιλέξτε φάκελο"
selectFolders: "Επιλέξτε φακέλους" selectFolders: "Επιλέξτε φακέλους"
renameFile: "Μετονομασία αρχείου" renameFile: "Μετονομασία αρχείου"
addFile: "Προσθήκη αρχείου" addFile: "Προσθέστε ένα αρχείο"
emptyDrive: "Ο Αποθηκευτικός Χώρος σας είναι άδειος" emptyDrive: "Ο Αποθηκευτικός Χώρος σας είναι άδειος"
copyUrl: "Αντιγραφή URL" copyUrl: "Αντιγραφή διεύθυνσης URL"
rename: "Αλλαγή ονόματος" rename: "Μετονομασία"
avatar: "Εικονίδιο" avatar: "Άβαταρ"
banner: "Πανό" banner: "Εξώφυλλο"
reload: "Ανανέωση" reload: "Ανανέωση"
doNothing: "Αγνόηση" doNothing: "Αγνόηση"
watch: "Παρακολούθηση" watch: "Παρακολούθηση"
unwatch: "Τέλος παρακολούθησης" unwatch: "Διακοπή παρακολούθησης"
accept: "Αποδοχή" accept: "Αποδοχή"
reject: "Απόρριψη" reject: "Απόρριψη"
normal: "Κανονικό" normal: "Κανονικό"
@ -212,23 +219,23 @@ connectService: "Σύνδεση"
disconnectService: "Αποσύνδεση" disconnectService: "Αποσύνδεση"
registration: "Εγγραφή" registration: "Εγγραφή"
pinnedPages: "Καρφιτσωμένες Σελίδες" pinnedPages: "Καρφιτσωμένες Σελίδες"
pinnedNotes: "Καρφιτσωμένα σημειώματα" pinnedNotes: "Καρφιτσωμένες δημοσιεύσεις"
antennas: "Αντένες" antennas: "Αντένες"
manageAntennas: "Διαχείριση αντενών" manageAntennas: "Διαχείριση Αντενών"
name: "Όνομα" name: "Όνομα"
antennaSource: "Πηγή αντένας" antennaSource: "Πηγή Αντένας"
antennaKeywords: "Λέξεις-κλειδιά για παρακολούθηση" antennaKeywords: "Λέξεις-κλειδιά για παρακολούθηση"
antennaExcludeKeywords: "Λέξεις-κλειδιά για αποκλεισμό" antennaExcludeKeywords: "Λέξεις-κλειδιά για εξαίρεση"
notifyAntenna: "Ειδοποίηση για νέα σημειώματα" notifyAntenna: "Ειδοποίηση για νέες δημοσιεύσεις"
withFileAntenna: "Μόνο σημειώματα με αρχεία" withFileAntenna: "Μόνο δημοσιεύσεις με αρχεία"
caseSensitive: "Διάκριση Πεζών-Κεφαλαίων" caseSensitive: "Διάκριση Πεζών-Κεφαλαίων"
popularTags: "Δημοφιλείς ετικέτες" popularTags: "Δημοφιλείς ετικέτες"
userList: "Λίστες" userList: "Λίστες"
about: "Πληροφορίες" about: "Σχετικά με"
moderator: "Συντονιστής" moderator: "Συντονιστής/στρια"
moderation: "Συντονισμός" moderation: "Συντονισμός"
cacheClear: "Εκκαθάριση προσωρινής μνήμης" cacheClear: "Εκκαθάριση προσωρινής μνήμης (cache)"
markAsReadAllNotifications: "Όλες οι ειδοποιήσεις διαβάστηκαν" markAsReadAllNotifications: "Σημειώστε όλες τις ειδοποιήσεις ως διαβασμένες"
group: "Ομάδα" group: "Ομάδα"
groups: "Ομάδες" groups: "Ομάδες"
createGroup: "Δημιουργία ομάδας" createGroup: "Δημιουργία ομάδας"
@ -236,13 +243,13 @@ ownedGroups: "Οι ομάδες σας"
groupName: "Όνομα ομάδας" groupName: "Όνομα ομάδας"
members: "Μέλη" members: "Μέλη"
transfer: "Μεταφορά" transfer: "Μεταφορά"
messagingWithUser: "Ιδιωτική συνομιλία" messagingWithUser: "Προσωπική συνομιλία"
messagingWithGroup: "Ομαδική συνομιλία" messagingWithGroup: "Ομαδική συνομιλία"
title: "Τίτλος" title: "Τίτλος"
text: "Κείμενο" text: "Κείμενο"
enable: "Ενεργοποίηση" enable: "Ενεργοποίηση"
next: "Επόμενο" next: "Επόμενο"
noteOf: "Σημείωμα από {user}" noteOf: "Δημοσίευση από {user}"
inviteToGroup: "Πρόσκληση στην ομάδα" inviteToGroup: "Πρόσκληση στην ομάδα"
quoteAttached: "Παράθεση" quoteAttached: "Παράθεση"
signinRequired: "Παρακαλούμε δημιουργήστε λογαριασμό ή συνδεθείτε πριν συνεχίσετε" signinRequired: "Παρακαλούμε δημιουργήστε λογαριασμό ή συνδεθείτε πριν συνεχίσετε"
@ -250,26 +257,26 @@ category: "Κατηγορία"
tags: "Ετικέτες" tags: "Ετικέτες"
createAccount: "Δημιουργία λογαριασμού" createAccount: "Δημιουργία λογαριασμού"
local: "Τοπικό" local: "Τοπικό"
remote: "Απομακρυσμένo" remote: "Απομακρυσμένο"
total: "Σύνολο" total: "Σύνολο"
appearance: "Εμφάνιση" appearance: "Εμφάνιση"
accountSettings: "Ρυθμίσεις λογαριασμού" accountSettings: "Ρυθμίσεις Λογαριασμού"
sounds: "Ήχοι" sounds: "Ήχοι"
sound: "Ήχοι" sound: "Ήχοι"
listen: "Ακρόαση" listen: "Ακρόαση"
showInPage: "Εμφάνιση στη σελίδα" showInPage: "Εμφάνιση στη σελίδα"
volume: "Ένταση" volume: "Ένταση"
masterVolume: "Κύρια ένταση" masterVolume: "Κεντρική ένταση"
details: "Λεπτομέρειες" details: "Λεπτομέρειες"
install: "Εγκατάσταση" install: "Εγκαταστήστε"
uninstall: "Κατάργηση εγκατάστασης" uninstall: "Απεγκατάσταση"
manage: "Διαχείριση" manage: "Διαχείριση"
smtpHost: "Φιλοξενεί" smtpHost: "Φιλοξενεί (Host)"
smtpUser: "Όνομα μέλους" smtpUser: "Όνομα μέλους"
smtpPass: "Κωδικός πρόσβασης" smtpPass: "Κωδικός"
notificationSetting: "Ρυθμίσεις ειδοποιήσεων" notificationSetting: "Ρυθμίσεις ειδοποιήσεων"
notificationSettingDesc: "Επιλέξτε τους τύπους ειδοποιήσεων που εμφανίζονται" notificationSettingDesc: "Επιλέξτε τους τύπους ειδοποιήσεων για προβολή."
switchUi: "Αλλαγή UI" switchUi: "Διάταξη"
clip: "Κλιπ" clip: "Κλιπ"
driveFilesCount: "Αριθμός αρχείων Αποθηκευτικού Χώρου" driveFilesCount: "Αριθμός αρχείων Αποθηκευτικού Χώρου"
driveUsage: "Χρήση Αποθηκευτικού Χώρου" driveUsage: "Χρήση Αποθηκευτικού Χώρου"
@ -293,7 +300,8 @@ manageAccounts: "Διαχείριση Λογαριασμών"
searchByGoogle: "Αναζήτηση" searchByGoogle: "Αναζήτηση"
file: "Αρχεία" file: "Αρχεία"
recommended: "Προτεινόμενα" recommended: "Προτεινόμενα"
cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού Χώρου" cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού\
\ Χώρου."
_email: _email:
_follow: _follow:
title: "Έχετε ένα νέο ακόλουθο" title: "Έχετε ένα νέο ακόλουθο"
@ -327,15 +335,20 @@ _ago:
monthsAgo: "{n} μήνα(ες) πριν" monthsAgo: "{n} μήνα(ες) πριν"
yearsAgo: "{n} έτος(η) πριν" yearsAgo: "{n} έτος(η) πριν"
_permissions: _permissions:
"write:drive": "Επεξεργαστείτε ή διαγράψτε τα αρχεία και τους φακέλους του Αποθηκευτικού Χώρου σας" "write:drive": "Επεξεργαστείτε ή διαγράψτε τα αρχεία και τους φακέλους του Αποθηκευτικού\
"read:favorites": "Δείτε τη λίστα των αγαπημένων σας" \ Χώρου σας"
"write:favorites": "Επεξεργαστείτε τη λίστα των αγαπημένων σας" "read:favorites": "Δείτε τη λίστα με τους σελιδοδείκτες σας"
"write:favorites": "Επεξεργαστείτε τη λίστα με τους σελιδοδείκτες σας"
"read:messaging": "Δείτε τις συνομιλίες σας" "read:messaging": "Δείτε τις συνομιλίες σας"
"write:messaging": "Γράψτε ή διαγράψτε μηνύματα συνομιλίας" "write:messaging": "Γράψτε ή διαγράψτε μηνύματα συνομιλίας"
"read:notifications": "Δείτε τις ειδοποιήσεις σας" "read:notifications": "Δείτε τις ειδοποιήσεις σας"
"write:notifications": "Διαχειριστείτε τις ειδοποιήσεις σας" "write:notifications": "Διαχειριστείτε τις ειδοποιήσεις σας"
"read:pages": "Δείτε τις Σελίδες σας" "read:pages": "Δείτε τις Σελίδες σας"
"write:pages": "Επεξεργαστείτε ή διαγράψτε τις σελίδες σας" "write:pages": "Επεξεργαστείτε ή διαγράψτε τις σελίδες σας"
"write:gallery-likes": Επεξεργασία της λίστας των αγαπημένων σας δημοσιεύσεων γκαλερί
"read:gallery": Δείτε την γκαλερί σας
"write:gallery": Επεξεργασία της γκαλερί σας
"read:gallery-likes": Δείτε τη λίστα των αγαπημένων σας δημοσιεύσεων γκαλερί
_antennaSources: _antennaSources:
all: "Όλα τα σημειώματα" all: "Όλα τα σημειώματα"
homeTimeline: "Σημειώματα από μέλη που ακολουθείτε" homeTimeline: "Σημειώματα από μέλη που ακολουθείτε"
@ -368,6 +381,7 @@ _visibility:
_profile: _profile:
name: "Όνομα" name: "Όνομα"
username: "Όνομα μέλους" username: "Όνομα μέλους"
changeAvatar: Αλλαγή άβαταρ
_exportOrImport: _exportOrImport:
allNotes: "Όλα τα σημειώματα" allNotes: "Όλα τα σημειώματα"
followingList: "Ακολουθεί" followingList: "Ακολουθεί"
@ -398,11 +412,409 @@ _notification:
reply: "Απάντηση" reply: "Απάντηση"
renote: "Κοινοποίηση σημειώματος" renote: "Κοινοποίηση σημειώματος"
_deck: _deck:
widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία μαραφετίων\" στο μενού και προσθέστε μαραφέτι." widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία πρόσθετων\" στο μενού και\
\ προσθέστε μαραφέτι."
_columns: _columns:
widgets: "Μαραφέτια" widgets: "Πρόσθετα"
notifications: "Ειδοποιήσεις" notifications: "Ειδοποιήσεις"
tl: "Χρονολόγιο" tl: "Χρονολόγιο"
antenna: "Αντένες" antenna: "Αντένες"
list: "Λίστα" list: "Λίστα"
mentions: "Επισημάνσεις" mentions: "Επισημάνσεις"
sensitive: Ευαίσθητο περιεχόμενο (NSFW)
createFolder: Δημιουργία φακέλου
uploadFromUrlDescription: Το URL του αρχείου που θέλετε να ανεβάσετε
emptyFolder: Αυτός ο φάκελος είναι άδειος
unableToDelete: Αδυναμία διαγραφής
recentlyUpdatedUsers: Πρόσφατα ενεργά μέλη
recentlyRegisteredUsers: Νέα μέλη
exploreUsersCount: Υπάρχουν {count} μέλη
help: Βοήθεια
inputNewFileName: Πληκτρολογήστε ένα νέο όνομα αρχείου
nothing: Δεν υπάρχει τίποτα να δείτε εδώ
newNoteRecived: Υπάρχουν νέες δημοσιεύσεις
passwordMatched: Ταιριάζει
unmarkAsSensitive: Αναίρεση επισήμανσης ως Ευαίσθητο Περιεχόμενο (NSFW)
withNFiles: '{n} αρχείο(-α)'
blockedUsers: Μπλοκαρισμένα μέλη
noteDeleteConfirm: Θέλετε σίγουρα να διαγράψετε αυτή τη δημοσίευση;
preview: Προεπισκόπηση
noCustomEmojis: Δεν υπάρχουν emoji
tosUrl: URL Όρων Χρήσης
monthX: '{month}'
markAsReadAllTalkMessages: Σημειώστε όλα τα μηνύματα ως διαβασμένα
inputMessageHere: Γράψτε εδώ το μήνυμά σας
close: Κλείσιμο
newMessageExists: Υπάρχουν νέα μηνύματα
usernameInvalidFormat: Μπορείτε να χρησιμοποιήσετε κεφαλαία και μικρά γράμματα, αριθμούς,
και κάτω παύλες.
tooShort: Πολύ σύντομο
passwordNotMatched: Δεν ταιριάζει
existingAccount: Υπάρχων λογαριασμός
deleteAll: Διαγραφή όλων
chooseEmoji: Επιλέξτε ένα emoji
sort: Ταξινόμηση
descendingOrder: Φθίνουσα
deleteAllFiles: Διαγραφή όλων των αρχείων
userSuspended: Αυτό το μέλος έχει αποβληθεί.
menu: Μενού
divider: Χώρισμα
deletedNote: Διαγραμμένη δημοσίευση
useCw: Απόκρυψη περιεχομένου
description: Περιγραφή
width: Πλάτος
disableAll: Απενεργοποίηση όλων
notificationType: Τύπος ειδοποίησης
wordMute: Σίγαση λέξεων
userSaysSomething: '{name} είπε κάτι'
metrics: Μετρήσεις
overview: Γενική εικόνα
database: Βάση δεδομένων
channel: Κανάλια
other: Άλλα
abuseReports: Αναφορές
reportAbuse: Αναφορά
unclip: Ακύρωση κλιπ
public: Δημόσιο
renotedCount: Αριθμός προωθήσεων που ελήφθησαν
alwaysMarkSensitive: Επισήμανση ως ευαίσθητο περιεχόμενο (NSFW) ως προεπιλογή
markAllAsRead: Σημειώστε τα όλα ως διαβασμένα
_gallery:
like: Μου αρέσει
liked: Αγαπημένες δημοσιεύσεις
my: Η Γκαλερί μου
unlike: Δεν μου αρέσει
showOnRemote: Δείτε στο απομακρυσμένο instance
perDay: Ανά Ημέρα
software: Λογισμικό
cpuAndMemory: CPU και Μνήμη
noUsers: Δεν υπάρχουν μέλη
processing: Επεξεργασία...
changePassword: Αλλαγή κωδικού
security: Ασφάλεια
featured: Προτεινόμενα
keepOriginalUploading: Διατήρηση πρωτότυπης εικόνας
manageGroups: Διαχείριση ομάδων
deleteFolder: Διαγραφή φακέλου
nsfw: Ευαίσθητο περιεχόμενο (NSFW)
nUsersMentioned: Έχει αναφερθεί από {n} μέλη
notFound: Δεν βρέθηκε
markAsReadAllUnreadNotes: Σημειώστε όλες τις δημοσιεύσεις ως διαβασμένες
invites: Προσκλήσεις
quoteQuestion: Να προστεθεί ως Παράθεση;
noMessagesYet: Δεν υπάρχουν μηνύματα ακόμη
onlyOneFileCanBeAttached: Μπορείτε να επισυνάψετε μόνο ένα αρχείο σε ένα μήνυμα
tooLong: Υπερβολικά μακροσκελές
or: Ή
language: Γλώσσα
groupInvited: Προσκληθήκατε σε μία ομάδα
ascendingOrder: Αύξουσα
visibility: Ορατότητα
invisibleNote: Αόρατη δημοσίευση
enableInfiniteScroll: Αυτόματη φόρτωση περισσοτέρων
poll: Ψηφοφορία
enablePlayer: Άνοιγμα προβολής βίντεο
large: Μεγάλο
medium: Μεσαίο
small: Μικρό
postToGallery: Δημιουργία νέας δημοσίευσης γκαλερί
reloadConfirm: Θα θέλατε να ανανεώσετε το χρονολόγιο;
enableAll: Ενεργοποίηση όλων
permission: Εξουσιοδοτήσεις
sample: Δείγμα
copy: Αντιγραφή
display: Προβολή
send: Αποστολή
behavior: Συμπεριφορά
useGlobalSetting: Χρήση παγκόσμιων ρυθμίσεων
abuseMarkAsResolved: Επισήμανση της αναφοράς ως επιλυμένης
openInNewTab: Άνοιγμα σε νέα καρτέλα
_sensitiveMediaDetection:
setSensitiveFlagAutomatically: Επισήμανση ως ευαίσθητο περιεχόμενο (NSFW)
defaultNavigationBehaviour: Προεπιλεγμένη συμπεριφορά περιήγησης
system: Σύστημα
createNew: Δημιουργία νέου
createNewClip: Δημιουργία νέου κλιπ
repliesCount: Αριθμός απεσταλμένων απαντήσεων
optional: Προαιρετικό
renotesCount: Αριθμός προωθήσεων σε δημοσιεύσεις άλλων
addItem: Προσθήκη αντικειμένου
disablePlayer: Κλείσιμο προβολής βίντεο
describeFile: Προσθήκη περιγραφής
enterFileDescription: Πληκτρολογήστε περιγραφή
author: Συντάκτης/τρια
setMultipleBySeparatingWithSpace: Διαχωρίστε πολλαπλές καταχωρήσεις με κενά.
random: Τυχαίο
accountInfo: Πληροφορίες Λογαριασμού
notesCount: Αριθμός δημοσιεύσεων
repliedCount: Αριθμός απαντήσεων που ελήφθησαν
flagAsCatDescription: Θα έχεις γατοαυτιά και θα μιλάς σαν γατί!
muteAndBlock: Σιγάσεις και Μπλοκαρίσματα
mutedUsers: Σιγασμένα μέλη
editProfile: Επεξεργασία προφίλ
pinLimitExceeded: Δεν μπορείτε να καρφιτσώσετε άλλες δημοσιεύσεις
currentPassword: Τρέχων κωδικός
newPassword: Νέος κωδικός
newPasswordRetype: Ξαναπληκτρολογήστε τον νέο κωδικό
notesAndReplies: Δημοσιεύσεις και απαντήσεις
popularUsers: Δημοφιλή μέλη
share: Κοινοποίηση
retype: Πληκτρολογήστε ξανά
invitations: Προσκλήσεις
available: Διαθέσιμο
unavailable: Μη διαθέσιμο
youHaveNoGroups: Δεν έχετε ομάδες
doing: Επεξεργασία...
yourAccountSuspendedTitle: Αυτός ο λογαριασμός έχει αποβληθεί
leaveConfirm: Υπάρχουν αλλαγές που δεν έχουν σωθεί. Θέλετε να τις απορρίψετε;
height: Ύψος
edit: Επεξεργασία
headlineMisskey: Μία ανοιχτού λογισμικού, αποκεντρωμένη πλατφόρμα κοινωνικής δικτύωσης
που θα είναι για πάντα ελεύθερη! 🚀
introMisskey: Καλώς ήρθατε! Το Calckey είναι μία ανοιχτού λογισμικού, αποκεντρωμένη
πλατφόρμα κοινωνικής δικτύωσης που θα είναι για πάντα ελεύθερη! 🚀
markAsSensitive: Επισήμανση ως Ευαίσθητο Περιεχόμενο (NSFW)
autoAcceptFollowed: Αυτόματη έγκριση αιτημάτων ακολούθησης από λογαριασμούς που ακολουθείτε
loginFailed: Αποτυχία σύνδεσης
accountMoved: 'Έχει μεταφερθεί σε νέο λογαριασμό:'
perHour: Ανά Ώρα
remoteUserCaution: Οι πληροφορίες από απομακρυσμένους λογαριασμούς μπορεί να είναι
ατελείς.
folderName: Όνομα φακέλου
renameFolder: Μετονομασία φακέλου
recentUsed: Χρησιμοποιήθηκαν πρόσφατα
deleteAllFilesConfirm: Σίγουρα θέλετε να διαγράψετε όλα τα αρχεία;
removeAllFollowing: Διακοπή ακολούθησης όλων των ακολουθούμενων μελών
userSilenced: Αυτό το μέλος είναι υπό σιώπηση.
makeActive: Ενεργοποίηση
create: Δημιουργία
reportAbuseOf: Αναφορά {name}
cacheRemoteFilesDescription: Όταν αυτή η ρύθμιση είναι απενεργοποιημένη, τα απομακρυσμένα
αρχεία φορτώνονται απευθείας από το απομακρυσμένο instance. Η απενεργοποίηση θα
μειώσει τη χρήση του δίσκου σας, αλλά θα αυξήσει την κίνηση δεδομένων, καθώς δεν
θα δημιουργούνται σμικρύνσεις αρχείων (thumbnails).
registeredAt: Εγγράφηκε στις
latestStatus: Τελευταία κατάσταση
charts: Πίνακες
stopActivityDelivery: Σταμάτα να στέλνεις δραστηριότητες
operations: Λειτουργίες
monitor: Παρακολούθηση
jobQueue: Ουρά εργασιών
blockedInstances: Μπλοκαρισμένα Instances
blockedInstancesDescription: Παραθέστε τις διευθύνσεις (hostnames) των instances που
θέλετε να μπλοκάρετε. Τα παρακάτω instances δεν θα μπορούν πλέον να επικοινωνούν
με αυτό το instance.
intro: Η εγκατάσταση του Calckey τελείωσε! Παρακαλώ δημιουργήστε ένα μέλος διαχειριστή/στρια.
noThankYou: Όχι, ευχαριστώ
addInstance: Προσθήκη instance
renoteMute: Σίγαση προωθήσεων
emojiUrl: Διεύθυνση emoji (URL)
cacheRemoteFiles: Προσωρινή αποθήκευση απομακρυσμένων αρχείων
flagSpeakAsCat: Να μιλάς σαν γατί
flagSpeakAsCatDescription: Οι δημοσιεύσεις σου θα nyaοποιούνται όταν είσαι γατί
selectInstance: Επιλέξτε ένα instance
latestRequestSentAt: Τελευταίο αίτημα στάλθηκε
hiddenTags: Κρυμμένες Ετικέτες (Hashtags)
noInstances: Δεν υπάρχουν instances
renoteUnmute: Διακοπή σίγασης προωθήσεων
flagAsBotDescription: Ενεργοποιήστε αυτή την επιλογή αν αυτός ο λογαριασμός ελέγχεται
από ένα πρόγραμμα. Αν ενεργοποιηθεί, θα λειτουργεί σαν σημάδι για τους προγραμματιστές,
ώστε να αποφύγουν ατέρμονη αλληλεπίδραση με άλλα bots και για να ρυθμίσει τα εσωτερικά
συστήματα του Calckey ώστε να αντιμετωπίζουν αυτόν τον λογαριασμό ως bot.
flagShowTimelineRepliesDescription: Εμφάνιση απαντήσεων μελών σε δημοσιεύσεις άλλων
μελών στο χρονολόγιο.
latestRequestReceivedAt: Τελευταίο αίτημα ελήφθη
blockThisInstance: Μπλοκάρισμα αυτού του instance
clearQueueConfirmText: Τυχόν δημοσιεύσεις στην ουρά που δεν έχουν αποσταλεί δεν θα
ομοσπονδοποιηθούν. Συνήθως αυτή η λειτουργία δεν χρειάζεται.
clearCachedFilesConfirm: Σίγουρα θέλετε να διαγράψετε όλα τα προσωρινά αποθηκευμένα
απομακρυσμένα αρχεία;
default: Προεπιλεγμένο
defaultValueIs: 'Προεπιλεγμένο: {value}'
noJobs: Δεν υπάρχουν εργασίες (jobs)
federating: Ομοσπονδοποιείται
blocked: Μπλοκαρισμένο
suspended: Σε αποβολή
instanceFollowing: Ακολουθεί στο instance
instanceFollowers: Ακόλουθοι του instance
instanceUsers: Μέλη αυτού του instance
retypedNotMatch: Οι καταχωρήσεις δεν ταιριάζουν.
usernameOrUserId: Όνομα μέλους ή ταυτότητα μέλους (id)
removeAreYouSure: Θέλετε σίγουρα να αφαιρέσετε το "{x}";
deleteAreYouSure: Θέλετε σίγουρα να διαγράψετε το "{x}";
resetAreYouSure: Σίγουρα επανεκκίνηση;
uploadFromUrlMayTakeTime: Ίσως πάρει λίγο χρόνο μέχρι το ανέβασμα να ολοκληρωθεί.
noMoreHistory: Δεν υπάρχει περαιτέρω ιστορικό
agreeTo: Συμφωνώ στο {0}
yearsOld: '{age} ετών'
themeForDarkMode: Θέμα για τη Σκοτεινή Λειτουργία
syncDeviceDarkMode: Συγχρονισμός της Σκοτεινής Λειτουργίας με τις ρυθμίσεις της συσκευής
σας
inputNewDescription: Προσθέστε νέα περιγραφή
whenServerDisconnected: Όταν χάνεται η σύνδεση στον σέρβερ
disconnectedFromServer: Η σύνδεση στον σέρβερ έχει χαθεί
instanceDescription: Περιγραφή instance
maintainerEmail: Διεύθυνση email προγραμματιστή/στριας
yearX: '{year}'
enableGlobalTimeline: Ενεργοποίηση παγκόσμιου χρονολογίου
enableLocalTimeline: Ενεργοποίηση τοπικού χρονολογίου
enableRegistration: Ενεργοποίηση εγγραφής νέων μελών
invite: Πρόσκληση
disablingTimelinesInfo: Οι Διαχειρίστριες-ες και οι Συντονιστές-στριες θα έχουν πάντα
πρόσβαση σε όλα τα χρονολόγια, ακόμα κι αν δεν είναι ενεργοποιημένα.
inMb: Σε megabytes
iconUrl: Διεύθυνση URL εικονιδίου
bannerUrl: Διεύθυνση URL εικόνας Εξώφυλλου
pinnedUsers: Καρφιτσωμένα μέλη
hcaptchaSiteKey: Κλειδί του site
recaptcha: Προστασία reCAPTCHA
enableServiceworker: Ενεργοποίηση Ειδοποιήσεων Push για τον browser σας
recentlyDiscoveredUsers: Μέλη που ανακαλύφθηκαν πρόσφατα
twoStepAuthentication: Επαλήθευση δύο παραγόντων
securityKey: Κλειδί ασφάλειας
registerSecurityKey: Καταχωρήστε ένα κλειδί ασφάλειας
resetPassword: Επαναφορά κωδικού
newPasswordIs: Ο νέος κωδικός είναι "{password}"
uploadFolder: Προεπιλεγμένος φάκελος για ανέβασμα αρχείων
joinedGroups: Οι ομάδες που είστε μέλος
checking: Έλεγχος...
invitationCode: Κωδικός πρόσκλησης
normalPassword: Μέτριος κωδικός
weakPassword: Αδύναμος κωδικός
strongPassword: Δυνατός κωδικός
signinWith: Συνδεθείτε με {x}
tapSecurityKey: Βάλτε το κλειδί ασφάλειας
signinFailed: Αδυναμία σύνδεσης. Το όνομα μέλους ή ο κωδικός είναι λάθος.
aboutX: Σχετικά με {x}
useOsNativeEmojis: Χρήση των Emoji του λειτουργικού συστήματος
uiLanguage: Γλώσσα διεπαφής
disableDrawer: Να μη χρησιμοποιούνται μενού σε στιλ συρταριού
noHistory: Δεν υπάρχει διαθέσιμο ιστορικό
joinOrCreateGroup: Λάβετε πρόσκληση για μία ομάδα ή δημιουργήστε τη δική σας.
docSource: Πηγή αυτού του εγγράφου
regenerate: Επαναδημιουργία
fontSize: Μέγεθος γραμματοσειράς
noFollowRequests: Δεν έχετε αιτήματα ακολούθησης σε αναμονή
dashboard: Ταμπλό
clientSettings: Ρυθμίσεις διεπαφής
numberOfDays: Αριθμός ημερών
hideThisNote: Απόκρυψη αυτής της δημοσίευσης
showFeaturedNotesInTimeline: Εμφάνιση προτεινόμενων δημοσιεύσεων στα χρονολόγια
objectStorage: Αποθήκευση Object Storage
useObjectStorage: Χρήση object storage
objectStorageBucket: ''
showFixedPostForm: Εμφάνιση της φόρμας δημοσίευσης στο πάνω μέρος των χρονολογίων
none: Κανένα
unableToProcess: Η επιχείρηση ήταν αδύνατο να ολοκληρωθεί
installedApps: Εφαρμογές με εξουσιοδότηση
state: Κατάσταση
installedDate: Εξουσιοδοτήθηκε στις
lastUsedDate: Χρησιμοποιήθηκε τελευταία φορά στις
scratchpadDescription: Το σημειωματάριο παρέχει ένα περιβάλλον για πειραματισμό με
AiScript. Σε αυτό μπορείτε να γράψετε, να εκτελέσετε, και να δοκιμάσετε τα αποτελέσματα
της αλληλεπίδρασης του AiScript με το Calckey.
scratchpad: Σημειωματάριο
output: Αποτέλεσμα
updateRemoteUser: Ανανέωση πληροφοριών απομακρυσμένου μέλους
disablePagesScript: Απενεργοποίηση του AiScript στις Σελίδες
removeAllFollowingDescription: Η εκτέλεση θα διακόψη την ακολούθηση όλων των μελών
από {host}. Παρακαλούμε εκτελέστε το αν το instance π.χ. δεν υπάρχει πια.
caption: Αυτόματη Περιγραφή
all: Όλα
subscribing: Εγγραφή σε συνδρομή
publishing: Δημοσιεύεται
notResponding: Δεν αποκρίνεται
keepOriginalUploadingDescription: Αποθηκεύει το πρωτότυπο αρχείο όπως είναι. Αν απενεργοποιηθεί,
μία έκδοση για προβολή στο ίντερνετ θα δημιουργηθεί κατά το ανέβασμα.
lookup: Αναζήτηση
lightThemes: Φωτεινά θέματα
darkThemes: Σκοτεινά θέματα
inputNewFolderName: Πληκτρολογήστε ένα νέο όνομα φακέλου
hasChildFilesOrFolders: Εφόσον αυτός ο φάκελος δεν είναι άδειος, δεν μπορεί να διαγραφεί.
integration: Ενσωματώσεις
enableRecommendedTimeline: Ενεργοποίηση χρονολογίου προτεινόμενων
driveCapacityPerLocalAccount: Μέγεθος Αποθηκευτικού Χώρου ανά τοπικό μέλος
driveCapacityPerRemoteAccount: Μέγεθος Αποθηκευτικού Χώρου ανά απομακρυσμένο μέλος
basicInfo: Βασικές πληροφορίες
pinnedClipId: Ταυτότητα (id) του κλιπ για καρφίτσωμα
hcaptcha: Προστασία hCaptcha
enableHcaptcha: Ενεργοποίηση hCaptcha
hcaptchaSecretKey: Μυστικό κλειδί
enableRecaptcha: Ενεργοποίηση reCAPTCHA
recaptchaSiteKey: Κλειδί του site
recaptchaSecretKey: Μυστικό κλειδί
antennaKeywordsDescription: Διαχωρίστε με κενά για συνθήκη ΚΑΙ ή με αλλαγή γραμμής
για συνθήκη Ή.
antennaUsersDescription: Παραθέστε ένα όνομα μέλους ανά γραμμή
antennaInstancesDescription: Παραθέστε ένα instance host ανά γραμμή
withReplies: Να περιλαμβάνονται οι απαντήσεις
withFiles: Να περιλαμβάνουν αρχεία
silence: Σιώπηση
silenceConfirm: Θέλετε σίγουρα να σιωπήσετε αυτό το μέλος;
unsilenceConfirm: Σίγουρα θέλετε να αναιρέσετε τη σιώπηση αυτού του μέλους;
securityKeyName: Όνομα κλειδιού
lastUsed: Τελευταία χρήση
unregister: Απεγγραφή
notFoundDescription: Δεν ήταν δυνατό να βρεθεί σελίδα που να ανταποκρίνεται σε αυτή
τη διεύθυνση URL.
signinHistory: Ιστορικό συνδέσεων
disableAnimatedMfm: Απενεργοποίηση του MFM με κίνηση
dayOverDayChanges: Αλλαγές την τελευταία ημέρα
promotion: Προμοταρισμένα
promote: Προμοτάρισμα
squareAvatars: Εμφάνιση τετραγωνισμένων άβαταρ
aboutMisskey: Σχετικά με το Calckey
maintainerName: Προγραμματιστής/στρια
uploadFromUrlRequested: Το ανέβασμα ζητήθηκε
themeForLightMode: Θέμα για τη Φωτεινή Λειτουργία
circularReferenceFolder: Ο φάκελος του προορισμού είναι υποφάκελος του φακέλου που
θέλετε να μετακινήσετε.
backgroundImageUrl: Διεύθυνση URL εικόνας φόντου
pinnedUsersDescription: Παραθέστε τα ονόματα μελών που θα είναι καρφιτσωμένα στην
καρτέλα "Εξερεύνηση" χωρίζοντάς τα με αλλαγή γραμμής.
openImageInNewTab: Άνοιγμα εικόνων σε νέα καρτέλα
weekOverWeekChanges: Αλλαγές την τελευταία εβδομάδα
exploreFediverse: Εξερευνήστε το Fediverse
unsilence: Αναίρεση σιώπησης
administrator: Διαχειριστής/στρια
passwordLessLogin: Σύνδεση χωρίς κωδικό
reduceUiAnimation: Ελάττωση των κινούμενων εικόνων
serviceworkerInfo: Πρέπει να είναι ενεργοποιημένο για ειδοποιήσεις push.
expandTweet: Διεύρυνση τουιτ
themeEditor: Επεξεργασία θεμάτων
deck: Ντεκ
undeck: Έξοδος από το Ντεκ
useFullReactionPicker: Χρήση επιλογέα αντιδράσεων πλήρους μεγέθους
tokenRequested: Παροχή πρόσβασης στον λογαριασμό
emailServer: Σέρβερ email
enableEmail: Ενεργοποίηση του email distribution
emailAddress: Διεύθυνση email
emailConfigInfo: Χρησιμοποιείται για επιβεβαίωση του email σας κατά την εγγραφή ή
αν ξεχάσετε τον κωδικό σας
regenerateLoginToken: Επαναδημιουργία token σύνδεσης
fileIdOrUrl: Ταυτότητα αρχείου (ID) ή διεύθυνση URL
typingUsers: '{users} πληκτρολογεί'
yourAccountSuspendedDescription: Αυτός ο λογαριασμός έχει αποβληθεί λόγω μη συμμόρφωσης
με τους κανόνες του σέρβερ ή κάτι παρόμοιο. Επικοινωνήστε με τον διαχειριστή/στρια
αν θα θέλατε έναν πιο λεπτομερή λόγο. Παρακαλούμε μη δημιουργήσετε νέο λογαριασμό.
inboxUrl: Διεύθυνση URL των Εισερχομένων
generateAccessToken: Δημιουργία token πρόσβασης
emptyToDisableSmtpAuth: Αφήστε το όνομα μέλους και τον κωδικό άδεια για να απενεργοποιήσετε
την επαλήθευση SMTP
instanceMute: Σιγάσεις instance
userSaysSomethingReason: '{name} είπε {reason}'
logs: Αρχεία καταγραφής
abuseReported: Η αναφορά σας στάλθηκε. Ευχαριστούμε πολύ.
reporter: Έκανε την αναφορά
reporteeOrigin: Καταγωγή αναφερόμενου λογαριασμού
reporterOrigin: Καταγωγή λογαριασμού που έκανε την αναφορά
forwardReport: Προώθηση της αναφοράς στο απομακρυσμένο instance
openInSideView: Άνοιγμα σε προβολή παράθεσης
delayed: Με καθυστέρηση
useGlobalSettingDesc: Αν ενεργοποιηθεί, οι ρυθμίσεις ειδοποιήσεων του λογαριασμού
σας θα χρησιμοποιηθούν. Αν απενεργοποιηθεί, μπορούν να γίνουν ανεξάρτητες ρυθμίσεις.
fillAbuseReportDescription: Παρακαλούμε συμπληρώστε λεπτομέρειες σχετικά με αυτή την
αναφορά. Αν πρόκειται για συγκεκριμένη δημοσίευση, παρακαλούμε συμπεριλάβετε τη
διεύθυνση URL της δημοσίευσης.
forwardReportIsAnonymous: Αντί για τον λογαριασμό σας, μία ανώνυμη αναφορά από λογαριασμό
του συστήματος θα εμφανιστεί στο απομακρυσμένο instance.

View file

@ -1,7 +1,8 @@
---
_lang_: "English" _lang_: "English"
headlineMisskey: "An open source, decentralized social media platform that's free forever! 🚀" headlineMisskey: "An open source, decentralized social media platform that's free\
introMisskey: "Welcome! Calckey is an open source, decentralized social media platform that's free forever! 🚀" \ forever! \U0001F680"
introMisskey: "Welcome! Calckey is an open source, decentralized social media platform\
\ that's free forever! \U0001F680"
monthAndDay: "{month}/{day}" monthAndDay: "{month}/{day}"
search: "Search" search: "Search"
notifications: "Notifications" notifications: "Notifications"
@ -46,7 +47,8 @@ copyContent: "Copy contents"
copyLink: "Copy link" copyLink: "Copy link"
delete: "Delete" delete: "Delete"
deleteAndEdit: "Delete and edit" deleteAndEdit: "Delete and edit"
deleteAndEditConfirm: "Are you sure you want to delete this post and edit it? You will lose all reactions, boosts and replies to it." deleteAndEditConfirm: "Are you sure you want to delete this post and edit it? You\
\ will lose all reactions, boosts and replies to it."
addToList: "Add to list" addToList: "Add to list"
sendMessage: "Send a message" sendMessage: "Send a message"
copyUsername: "Copy username" copyUsername: "Copy username"
@ -66,9 +68,11 @@ import: "Import"
export: "Export" export: "Export"
files: "Files" files: "Files"
download: "Download" download: "Download"
driveFileDeleteConfirm: "Are you sure you want to delete the file \"{name}\"? Posts with this file attached will also be deleted." driveFileDeleteConfirm: "Are you sure you want to delete the file \"{name}\"? Posts\
\ with this file attached will also be deleted."
unfollowConfirm: "Are you sure that you want to unfollow {name}?" unfollowConfirm: "Are you sure that you want to unfollow {name}?"
exportRequested: "You've requested an export. This may take a while. It will be added to your Drive once completed." exportRequested: "You've requested an export. This may take a while. It will be added\
\ to your Drive once completed."
importRequested: "You've requested an import. This may take a while." importRequested: "You've requested an import. This may take a while."
lists: "Lists" lists: "Lists"
noLists: "You don't have any lists" noLists: "You don't have any lists"
@ -83,7 +87,8 @@ error: "Error"
somethingHappened: "An error has occurred" somethingHappened: "An error has occurred"
retry: "Retry" retry: "Retry"
pageLoadError: "An error occurred loading the page." pageLoadError: "An error occurred loading the page."
pageLoadErrorDescription: "This is normally caused by network errors or the browser's cache. Try clearing the cache and then try again after waiting a little while." pageLoadErrorDescription: "This is normally caused by network errors or the browser's\
\ cache. Try clearing the cache and then try again after waiting a little while."
serverIsDead: "This server is not responding. Please wait for a while and try again." serverIsDead: "This server is not responding. Please wait for a while and try again."
youShouldUpgradeClient: "To view this page, please refresh to update your client." youShouldUpgradeClient: "To view this page, please refresh to update your client."
enterListName: "Enter a name for the list" enterListName: "Enter a name for the list"
@ -97,9 +102,6 @@ unfollow: "Unfollow"
followRequestPending: "Follow request pending" followRequestPending: "Follow request pending"
enterEmoji: "Enter an emoji" enterEmoji: "Enter an emoji"
renote: "Boost" renote: "Boost"
renoteAsUnlisted: "Boost (Unlisted)"
renoteToFollowers: "Boost (Followers)"
renoteToRecipients: "Boost (Recipients)"
unrenote: "Take back boost" unrenote: "Take back boost"
renoted: "Boosted." renoted: "Boosted."
cantRenote: "This post can't be boosted." cantRenote: "This post can't be boosted."
@ -112,6 +114,8 @@ clickToShow: "Click to show"
sensitive: "NSFW" sensitive: "NSFW"
add: "Add" add: "Add"
reaction: "Reactions" reaction: "Reactions"
enableEmojiReactions: "Enable emoji reactions"
showEmojisInReactionNotifications: "Show emojis in reaction notifications"
reactionSetting: "Reactions to show in the reaction picker" reactionSetting: "Reactions to show in the reaction picker"
reactionSettingDescription2: "Drag to reorder, click to delete, press \"+\" to add." reactionSettingDescription2: "Drag to reorder, click to delete, press \"+\" to add."
rememberNoteVisibility: "Remember post visibility settings" rememberNoteVisibility: "Remember post visibility settings"
@ -144,15 +148,21 @@ emojiUrl: "Emoji URL"
addEmoji: "Add" addEmoji: "Add"
settingGuide: "Recommended settings" settingGuide: "Recommended settings"
cacheRemoteFiles: "Cache remote files" cacheRemoteFiles: "Cache remote files"
cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded directly from the remote instance. Disabling this will decrease storage usage, but increase traffic, as thumbnails will not be generated." cacheRemoteFilesDescription: "When this setting is disabled, remote files are loaded\
\ directly from the remote instance. Disabling this will decrease storage usage,\
\ but increase traffic, as thumbnails will not be generated."
flagAsBot: "Mark this account as a bot" flagAsBot: "Mark this account as a bot"
flagAsBotDescription: "Enable this option if this account is controlled by a program. If enabled, it will act as a flag for other developers to prevent endless interaction chains with other bots and adjust Calckey's internal systems to treat this account as a bot." flagAsBotDescription: "Enable this option if this account is controlled by a program.\
flagAsCat: "Are you a cat? 😺" \ If enabled, it will act as a flag for other developers to prevent endless interaction\
\ chains with other bots and adjust Calckey's internal systems to treat this account\
\ as a bot."
flagAsCat: "Are you a cat? \U0001F63A"
flagAsCatDescription: "You'll get cat ears and speak like a cat!" flagAsCatDescription: "You'll get cat ears and speak like a cat!"
flagSpeakAsCat: "Speak as a cat" flagSpeakAsCat: "Speak as a cat"
flagSpeakAsCatDescription: "Your posts will get nyanified when in cat mode" flagSpeakAsCatDescription: "Your posts will get nyanified when in cat mode"
flagShowTimelineReplies: "Show replies in timeline" flagShowTimelineReplies: "Show replies in timeline"
flagShowTimelineRepliesDescription: "Shows replies of users to posts of other users in the timeline if turned on." flagShowTimelineRepliesDescription: "Shows replies of users to posts of other users\
\ in the timeline if turned on."
autoAcceptFollowed: "Automatically approve follow requests from users you're following" autoAcceptFollowed: "Automatically approve follow requests from users you're following"
addAccount: "Add account" addAccount: "Add account"
loginFailed: "Failed to sign in" loginFailed: "Failed to sign in"
@ -166,7 +176,10 @@ searchWith: "Search: {q}"
youHaveNoLists: "You don't have any lists" youHaveNoLists: "You don't have any lists"
followConfirm: "Are you sure that you want to follow {name}?" followConfirm: "Are you sure that you want to follow {name}?"
proxyAccount: "Proxy Account" proxyAccount: "Proxy Account"
proxyAccountDescription: "A proxy account is an account that acts as a remote follower for users under certain conditions. For example, when a user adds a remote user to the list, the remote user's activity will not be delivered to the instance if no local user is following that user, so the proxy account will follow instead." proxyAccountDescription: "A proxy account is an account that acts as a remote follower\
\ for users under certain conditions. For example, when a user adds a remote user\
\ to the list, the remote user's activity will not be delivered to the instance\
\ if no local user is following that user, so the proxy account will follow instead."
host: "Host" host: "Host"
selectUser: "Select a user" selectUser: "Select a user"
selectInstance: "Select an instance" selectInstance: "Select an instance"
@ -198,13 +211,17 @@ instanceInfo: "Instance Information"
statistics: "Statistics" statistics: "Statistics"
clearQueue: "Clear queue" clearQueue: "Clear queue"
clearQueueConfirmTitle: "Are you sure that you want to clear the queue?" clearQueueConfirmTitle: "Are you sure that you want to clear the queue?"
clearQueueConfirmText: "Any undelivered posts remaining in the queue will not be federated. Usually this operation is not needed." clearQueueConfirmText: "Any undelivered posts remaining in the queue will not be federated.\
\ Usually this operation is not needed."
clearCachedFiles: "Clear cache" clearCachedFiles: "Clear cache"
clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote files?" clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote files?"
blockedInstances: "Blocked Instances" blockedInstances: "Blocked Instances"
blockedInstancesDescription: "List the hostnames of the instances that you want to block. Listed instances will no longer be able to communicate with this instance." blockedInstancesDescription: "List the hostnames of the instances that you want to\
\ block. Listed instances will no longer be able to communicate with this instance."
hiddenTags: "Hidden Hashtags" hiddenTags: "Hidden Hashtags"
hiddenTagsDescription: "List the hashtags (without the #) of the hashtags you wish to hide from trending and explore. Hidden hashtags are still discoverable via other means." hiddenTagsDescription: "List the hashtags (without the #) of the hashtags you wish\
\ to hide from trending and explore. Hidden hashtags are still discoverable via\
\ other means."
muteAndBlock: "Mutes and Blocks" muteAndBlock: "Mutes and Blocks"
mutedUsers: "Muted users" mutedUsers: "Muted users"
blockedUsers: "Blocked users" blockedUsers: "Blocked users"
@ -254,7 +271,8 @@ saved: "Saved"
messaging: "Chat" messaging: "Chat"
upload: "Upload" upload: "Upload"
keepOriginalUploading: "Keep original image" keepOriginalUploading: "Keep original image"
keepOriginalUploadingDescription: "Saves the originally uploaded image as-is. If turned off, a version to display on the web will be generated on upload." keepOriginalUploadingDescription: "Saves the originally uploaded image as-is. If turned\
\ off, a version to display on the web will be generated on upload."
fromDrive: "From Drive" fromDrive: "From Drive"
fromUrl: "From URL" fromUrl: "From URL"
uploadFromUrl: "Upload from a URL" uploadFromUrl: "Upload from a URL"
@ -304,7 +322,8 @@ unableToDelete: "Unable to delete"
inputNewFileName: "Enter a new filename" inputNewFileName: "Enter a new filename"
inputNewDescription: "Enter new caption" inputNewDescription: "Enter new caption"
inputNewFolderName: "Enter a new folder name" inputNewFolderName: "Enter a new folder name"
circularReferenceFolder: "The destination folder is a subfolder of the folder you wish to move." circularReferenceFolder: "The destination folder is a subfolder of the folder you\
\ wish to move."
hasChildFilesOrFolders: "Since this folder is not empty, it can not be deleted." hasChildFilesOrFolders: "Since this folder is not empty, it can not be deleted."
copyUrl: "Copy URL" copyUrl: "Copy URL"
rename: "Rename" rename: "Rename"
@ -339,7 +358,8 @@ disconnectService: "Disconnect"
enableLocalTimeline: "Enable local timeline" enableLocalTimeline: "Enable local timeline"
enableGlobalTimeline: "Enable global timeline" enableGlobalTimeline: "Enable global timeline"
enableRecommendedTimeline: "Enable recommended timeline" enableRecommendedTimeline: "Enable recommended timeline"
disablingTimelinesInfo: "Adminstrators and Moderators will always have access to all timelines, even if they are not enabled." disablingTimelinesInfo: "Adminstrators and Moderators will always have access to all\
\ timelines, even if they are not enabled."
registration: "Register" registration: "Register"
enableRegistration: "Enable new user registration" enableRegistration: "Enable new user registration"
invite: "Invite" invite: "Invite"
@ -351,9 +371,11 @@ bannerUrl: "Banner image URL"
backgroundImageUrl: "Background image URL" backgroundImageUrl: "Background image URL"
basicInfo: "Basic info" basicInfo: "Basic info"
pinnedUsers: "Pinned users" pinnedUsers: "Pinned users"
pinnedUsersDescription: "List usernames separated by line breaks to be pinned in the \"Explore\" tab." pinnedUsersDescription: "List usernames separated by line breaks to be pinned in the\
\ \"Explore\" tab."
pinnedPages: "Pinned Pages" pinnedPages: "Pinned Pages"
pinnedPagesDescription: "Enter the paths of the Pages you want to pin to the top page of this instance, separated by line breaks." pinnedPagesDescription: "Enter the paths of the Pages you want to pin to the top page\
\ of this instance, separated by line breaks."
pinnedClipId: "ID of the clip to pin" pinnedClipId: "ID of the clip to pin"
pinnedNotes: "Pinned posts" pinnedNotes: "Pinned posts"
hcaptcha: "hCaptcha" hcaptcha: "hCaptcha"
@ -364,14 +386,17 @@ recaptcha: "reCAPTCHA"
enableRecaptcha: "Enable reCAPTCHA" enableRecaptcha: "Enable reCAPTCHA"
recaptchaSiteKey: "Site key" recaptchaSiteKey: "Site key"
recaptchaSecretKey: "Secret key" recaptchaSecretKey: "Secret key"
avoidMultiCaptchaConfirm: "Using multiple Captcha systems may cause interference between them. Would you like to disable the other Captcha systems currently active? If you would like them to stay enabled, press cancel." avoidMultiCaptchaConfirm: "Using multiple Captcha systems may cause interference between\
\ them. Would you like to disable the other Captcha systems currently active? If\
\ you would like them to stay enabled, press cancel."
antennas: "Antennas" antennas: "Antennas"
manageAntennas: "Manage Antennas" manageAntennas: "Manage Antennas"
name: "Name" name: "Name"
antennaSource: "Antenna source" antennaSource: "Antenna source"
antennaKeywords: "Keywords to listen to" antennaKeywords: "Keywords to listen to"
antennaExcludeKeywords: "Keywords to exclude" antennaExcludeKeywords: "Keywords to exclude"
antennaKeywordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition." antennaKeywordsDescription: "Separate with spaces for an AND condition or with line\
\ breaks for an OR condition."
notifyAntenna: "Notify about new posts" notifyAntenna: "Notify about new posts"
withFileAntenna: "Only posts with files" withFileAntenna: "Only posts with files"
enableServiceworker: "Enable Push-Notifications for your Browser" enableServiceworker: "Enable Push-Notifications for your Browser"
@ -501,19 +526,27 @@ showFeaturedNotesInTimeline: "Show featured posts in timelines"
objectStorage: "Object Storage" objectStorage: "Object Storage"
useObjectStorage: "Use object storage" useObjectStorage: "Use object storage"
objectStorageBaseUrl: "Base URL" objectStorageBaseUrl: "Base URL"
objectStorageBaseUrlDesc: "The URL used as reference. Specify the URL of your CDN or Proxy if you are using either.\nFor S3 use 'https://<bucket>.s3.amazonaws.com' and for GCS or equivalent services use 'https://storage.googleapis.com/<bucket>', etc." objectStorageBaseUrlDesc: "The URL used as reference. Specify the URL of your CDN\
\ or Proxy if you are using either.\nFor S3 use 'https://<bucket>.s3.amazonaws.com'\
\ and for GCS or equivalent services use 'https://storage.googleapis.com/<bucket>',\
\ etc."
objectStorageBucket: "Bucket" objectStorageBucket: "Bucket"
objectStorageBucketDesc: "Please specify the bucket name used at your provider." objectStorageBucketDesc: "Please specify the bucket name used at your provider."
objectStoragePrefix: "Prefix" objectStoragePrefix: "Prefix"
objectStoragePrefixDesc: "Files will be stored under directories with this prefix." objectStoragePrefixDesc: "Files will be stored under directories with this prefix."
objectStorageEndpoint: "Endpoint" objectStorageEndpoint: "Endpoint"
objectStorageEndpointDesc: "Leave this empty if you are using AWS S3, otherwise specify the endpoint as '<host>' or '<host>:<port>', depending on the service you are using." objectStorageEndpointDesc: "Leave this empty if you are using AWS S3, otherwise specify\
\ the endpoint as '<host>' or '<host>:<port>', depending on the service you are\
\ using."
objectStorageRegion: "Region" objectStorageRegion: "Region"
objectStorageRegionDesc: "Specify a region like 'xx-east-1'. If your service does not distinguish between regions, leave this blank or enter 'us-east-1'." objectStorageRegionDesc: "Specify a region like 'xx-east-1'. If your service does\
\ not distinguish between regions, leave this blank or enter 'us-east-1'."
objectStorageUseSSL: "Use SSL" objectStorageUseSSL: "Use SSL"
objectStorageUseSSLDesc: "Turn this off if you are not going to use HTTPS for API connections" objectStorageUseSSLDesc: "Turn this off if you are not going to use HTTPS for API\
\ connections"
objectStorageUseProxy: "Connect over Proxy" objectStorageUseProxy: "Connect over Proxy"
objectStorageUseProxyDesc: "Turn this off if you are not going to use a Proxy for API connections" objectStorageUseProxyDesc: "Turn this off if you are not going to use a Proxy for\
\ API connections"
objectStorageSetPublicRead: "Set \"public-read\" on upload" objectStorageSetPublicRead: "Set \"public-read\" on upload"
serverLogs: "Server logs" serverLogs: "Server logs"
deleteAll: "Delete all" deleteAll: "Delete all"
@ -541,7 +574,9 @@ sort: "Sort"
ascendingOrder: "Ascending" ascendingOrder: "Ascending"
descendingOrder: "Descending" descendingOrder: "Descending"
scratchpad: "Scratchpad" scratchpad: "Scratchpad"
scratchpadDescription: "The scratchpad provides an environment for AiScript experiments. You can write, execute, and check the results of it interacting with Calckey in it." scratchpadDescription: "The scratchpad provides an environment for AiScript experiments.\
\ You can write, execute, and check the results of it interacting with Calckey in\
\ it."
output: "Output" output: "Output"
script: "Script" script: "Script"
disablePagesScript: "Disable AiScript on Pages" disablePagesScript: "Disable AiScript on Pages"
@ -549,11 +584,14 @@ updateRemoteUser: "Update remote user information"
deleteAllFiles: "Delete all files" deleteAllFiles: "Delete all files"
deleteAllFilesConfirm: "Are you sure that you want to delete all files?" deleteAllFilesConfirm: "Are you sure that you want to delete all files?"
removeAllFollowing: "Unfollow all followed users" removeAllFollowing: "Unfollow all followed users"
removeAllFollowingDescription: "Executing this unfollows all accounts from {host}. Please run this if the instance e.g. no longer exists." removeAllFollowingDescription: "Executing this unfollows all accounts from {host}.\
\ Please run this if the instance e.g. no longer exists."
userSuspended: "This user has been suspended." userSuspended: "This user has been suspended."
userSilenced: "This user is being silenced." userSilenced: "This user is being silenced."
yourAccountSuspendedTitle: "This account is suspended" yourAccountSuspendedTitle: "This account is suspended"
yourAccountSuspendedDescription: "This account has been suspended due to breaking the server's terms of services or similar. Contact the administrator if you would like to know a more detailed reason. Please do not create a new account." yourAccountSuspendedDescription: "This account has been suspended due to breaking\
\ the server's terms of services or similar. Contact the administrator if you would\
\ like to know a more detailed reason. Please do not create a new account."
menu: "Menu" menu: "Menu"
divider: "Divider" divider: "Divider"
addItem: "Add Item" addItem: "Add Item"
@ -594,12 +632,14 @@ permission: "Permissions"
enableAll: "Enable all" enableAll: "Enable all"
disableAll: "Disable all" disableAll: "Disable all"
tokenRequested: "Grant access to account" tokenRequested: "Grant access to account"
pluginTokenRequestedDescription: "This plugin will be able to use the permissions set here." pluginTokenRequestedDescription: "This plugin will be able to use the permissions\
\ set here."
notificationType: "Notification type" notificationType: "Notification type"
edit: "Edit" edit: "Edit"
emailServer: "Email server" emailServer: "Email server"
enableEmail: "Enable email distribution" enableEmail: "Enable email distribution"
emailConfigInfo: "Used to confirm your email during sign-up or if you forget your password" emailConfigInfo: "Used to confirm your email during sign-up or if you forget your\
\ password"
email: "Email" email: "Email"
emailAddress: "Email address" emailAddress: "Email address"
smtpConfig: "SMTP Server Configuration" smtpConfig: "SMTP Server Configuration"
@ -613,7 +653,8 @@ smtpSecureInfo: "Turn this off when using STARTTLS"
testEmail: "Test email delivery" testEmail: "Test email delivery"
wordMute: "Word mute" wordMute: "Word mute"
regexpError: "Regular Expression error" regexpError: "Regular Expression error"
regexpErrorDescription: "An error occurred in the regular expression on line {line} of your {tab} word mutes:" regexpErrorDescription: "An error occurred in the regular expression on line {line}\
\ of your {tab} word mutes:"
instanceMute: "Instance Mutes" instanceMute: "Instance Mutes"
userSaysSomething: "{name} said something" userSaysSomething: "{name} said something"
userSaysSomethingReason: "{name} said {reason}" userSaysSomethingReason: "{name} said {reason}"
@ -630,10 +671,13 @@ create: "Create"
notificationSetting: "Notification settings" notificationSetting: "Notification settings"
notificationSettingDesc: "Select the types of notification to display." notificationSettingDesc: "Select the types of notification to display."
useGlobalSetting: "Use global settings" useGlobalSetting: "Use global settings"
useGlobalSettingDesc: "If turned on, your account's notification settings will be used. If turned off, individual configurations can be made." useGlobalSettingDesc: "If turned on, your account's notification settings will be\
\ used. If turned off, individual configurations can be made."
other: "Other" other: "Other"
regenerateLoginToken: "Regenerate login token" regenerateLoginToken: "Regenerate login token"
regenerateLoginTokenDescription: "Regenerates the token used internally during login. Normally this action is not necessary. If regenerated, all devices will be logged out." regenerateLoginTokenDescription: "Regenerates 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." setMultipleBySeparatingWithSpace: "Separate multiple entries with spaces."
fileIdOrUrl: "File ID or URL" fileIdOrUrl: "File ID or URL"
behavior: "Behavior" behavior: "Behavior"
@ -641,13 +685,15 @@ sample: "Sample"
abuseReports: "Reports" abuseReports: "Reports"
reportAbuse: "Report" reportAbuse: "Report"
reportAbuseOf: "Report {name}" reportAbuseOf: "Report {name}"
fillAbuseReportDescription: "Please fill in details regarding this report. If it is about a specific post, please include its URL." fillAbuseReportDescription: "Please fill in details regarding this report. If it is\
\ about a specific post, please include its URL."
abuseReported: "Your report has been sent. Thank you very much." abuseReported: "Your report has been sent. Thank you very much."
reporter: "Reporter" reporter: "Reporter"
reporteeOrigin: "Reportee Origin" reporteeOrigin: "Reportee Origin"
reporterOrigin: "Reporter Origin" reporterOrigin: "Reporter Origin"
forwardReport: "Forward report to remote instance" forwardReport: "Forward report to remote instance"
forwardReportIsAnonymous: "Instead of your account, an anonymous system account will be displayed as reporter at the remote instance." forwardReportIsAnonymous: "Instead of your account, an anonymous system account will\
\ be displayed as reporter at the remote instance."
send: "Send" send: "Send"
abuseMarkAsResolved: "Mark report as resolved" abuseMarkAsResolved: "Mark report as resolved"
openInNewTab: "Open in new tab" openInNewTab: "Open in new tab"
@ -665,9 +711,11 @@ createNew: "Create new"
optional: "Optional" optional: "Optional"
createNewClip: "Create new clip" createNewClip: "Create new clip"
unclip: "Unclip" unclip: "Unclip"
confirmToUnclipAlreadyClippedNote: "This post is already part of the \"{name}\" clip. Do you want to remove it from this clip instead?" confirmToUnclipAlreadyClippedNote: "This post is already part of the \"{name}\" clip.\
\ Do you want to remove it from this clip instead?"
public: "Public" public: "Public"
i18nInfo: "Calckey is being translated into various languages by volunteers. You can help at {link}." i18nInfo: "Calckey is being translated into various languages by volunteers. You can\
\ help at {link}."
manageAccessTokens: "Manage access tokens" manageAccessTokens: "Manage access tokens"
accountInfo: "Account Info" accountInfo: "Account Info"
notesCount: "Number of posts" notesCount: "Number of posts"
@ -686,12 +734,16 @@ no: "No"
driveFilesCount: "Number of Drive files" driveFilesCount: "Number of Drive files"
driveUsage: "Drive space usage" driveUsage: "Drive space usage"
noCrawle: "Reject crawler indexing" noCrawle: "Reject crawler indexing"
noCrawleDescription: "Ask search engines to not index your profile page, posts, Pages, etc." noCrawleDescription: "Ask search engines to not index your profile page, posts, Pages,\
lockedAccountInfo: "Unless you set your post visiblity to \"Followers only\", your posts will be visible to anyone, even if you require followers to be manually approved." \ etc."
lockedAccountInfo: "Unless you set your post visiblity to \"Followers only\", your\
\ posts will be visible to anyone, even if you require followers to be manually\
\ approved."
alwaysMarkSensitive: "Mark as NSFW by default" alwaysMarkSensitive: "Mark as NSFW by default"
loadRawImages: "Load original images instead of showing thumbnails" loadRawImages: "Load original images instead of showing thumbnails"
disableShowingAnimatedImages: "Don't play animated images" disableShowingAnimatedImages: "Don't play animated images"
verificationEmailSent: "A verification email has been sent. Please follow the included link to complete verification." verificationEmailSent: "A verification email has been sent. Please follow the included\
\ link to complete verification."
notSet: "Not set" notSet: "Not set"
emailVerified: "Email has been verified" emailVerified: "Email has been verified"
noteFavoritesCount: "Number of bookmarked posts" noteFavoritesCount: "Number of bookmarked posts"
@ -703,7 +755,8 @@ clips: "Clips"
experimentalFeatures: "Experimental features" experimentalFeatures: "Experimental features"
developer: "Developer" developer: "Developer"
makeExplorable: "Make account visible in \"Explore\"" makeExplorable: "Make account visible in \"Explore\""
makeExplorableDescription: "If you turn this off, your account will not show up in the \"Explore\" section." makeExplorableDescription: "If you turn this off, your account will not show up in\
\ the \"Explore\" section."
showGapBetweenNotesInTimeline: "Show a gap between posts on the timeline" showGapBetweenNotesInTimeline: "Show a gap between posts on the timeline"
duplicate: "Duplicate" duplicate: "Duplicate"
left: "Left" left: "Left"
@ -718,7 +771,10 @@ onlineUsersCount: "{n} users are online"
nUsers: "{n} Users" nUsers: "{n} Users"
nNotes: "{n} Posts" nNotes: "{n} Posts"
sendErrorReports: "Send error reports" sendErrorReports: "Send error reports"
sendErrorReportsDescription: "When turned on, detailed error information will be shared with Calckey when a problem occurs, helping to improve the quality of Misskey.\nThis will include information such the version of your OS, what browser you're using, your activity in Calckey, etc." sendErrorReportsDescription: "When turned on, detailed error information will be shared\
\ with Calckey when a problem occurs, helping to improve the quality of Calckey.\n\
This will include information such the version of your OS, what browser you're using,\
\ your activity in Calckey, etc."
myTheme: "My theme" myTheme: "My theme"
backgroundColor: "Background color" backgroundColor: "Background color"
accentColor: "Accent color" accentColor: "Accent color"
@ -757,14 +813,17 @@ unlikeConfirm: "Really remove your like?"
fullView: "Full view" fullView: "Full view"
quitFullView: "Exit full view" quitFullView: "Exit full view"
addDescription: "Add description" addDescription: "Add description"
userPagePinTip: "You can display posts here by selecting \"Pin to profile\" from the menu of individual posts." userPagePinTip: "You can display posts here by selecting \"Pin to profile\" from the\
notSpecifiedMentionWarning: "This post contains mentions of users not included as recipients" \ menu of individual posts."
notSpecifiedMentionWarning: "This post contains mentions of users not included as\
\ recipients"
info: "About" info: "About"
userInfo: "User information" userInfo: "User information"
unknown: "Unknown" unknown: "Unknown"
onlineStatus: "Online status" onlineStatus: "Online status"
hideOnlineStatus: "Hide online status" hideOnlineStatus: "Hide online status"
hideOnlineStatusDescription: "Hiding your online status reduces the convenience of some features such as the search." hideOnlineStatusDescription: "Hiding your online status reduces the convenience of\
\ some features such as the search."
online: "Online" online: "Online"
active: "Active" active: "Active"
offline: "Offline" offline: "Offline"
@ -801,16 +860,19 @@ secureMode: "Secure Mode (Authorized Fetch)"
instanceSecurity: "Instance Security" instanceSecurity: "Instance Security"
secureModeInfo: "When requesting from other instances, do not send back without proof." secureModeInfo: "When requesting from other instances, do not send back without proof."
privateMode: "Private Mode" privateMode: "Private Mode"
privateModeInfo: "When enabled, only whitelisted instances can federate with your instances. All posts will be hidden from the public." privateModeInfo: "When enabled, only whitelisted instances can federate with your\
\ instances. All posts will be hidden from the public."
allowedInstances: "Whitelisted Instances" allowedInstances: "Whitelisted Instances"
allowedInstancesDescription: "Hosts of instances to be whitelisted for federation, each seperated by a new line (only applies in private mode)." allowedInstancesDescription: "Hosts of instances to be whitelisted for federation,\
\ each separated by a new line (only applies in private mode)."
previewNoteText: "Show preview" previewNoteText: "Show preview"
customCss: "Custom CSS" customCss: "Custom CSS"
customCssWarn: "This setting should only be used if you know what it does. Entering improper values may cause the client to stop functioning normally." customCssWarn: "This setting should only be used if you know what it does. Entering\
\ improper values may cause the client to stop functioning normally."
global: "Global" global: "Global"
recommended: "Recommended" recommended: "Recommended"
squareAvatars: "Display squared avatars" squareAvatars: "Display squared avatars"
seperateRenoteQuote: "Seperate boost and quote buttons" seperateRenoteQuote: "Separate boost and quote buttons"
sent: "Sent" sent: "Sent"
received: "Received" received: "Received"
searchResult: "Search results" searchResult: "Search results"
@ -823,7 +885,9 @@ whatIsNew: "Show changes"
translate: "Translate" translate: "Translate"
translatedFrom: "Translated from {x}" translatedFrom: "Translated from {x}"
accountDeletionInProgress: "Account deletion is currently in progress" accountDeletionInProgress: "Account deletion is currently in progress"
usernameInfo: "A name that identifies your account from others on this server. You can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot be changed later." usernameInfo: "A name that identifies your account from others on this server. You\
\ can use the alphabet (a~z, A~Z), digits (0~9) or underscores (_). Usernames cannot\
\ be changed later."
aiChanMode: "Ai-chan in Classic UI" aiChanMode: "Ai-chan in Classic UI"
keepCw: "Keep content warnings" keepCw: "Keep content warnings"
pubSub: "Pub/Sub Accounts" pubSub: "Pub/Sub Accounts"
@ -840,12 +904,14 @@ filter: "Filter"
controlPanel: "Control Panel" controlPanel: "Control Panel"
manageAccounts: "Manage Accounts" manageAccounts: "Manage Accounts"
makeReactionsPublic: "Set reaction history to public" makeReactionsPublic: "Set reaction history to public"
makeReactionsPublicDescription: "This will make the list of all your past reactions publicly visible." makeReactionsPublicDescription: "This will make the list of all your past reactions\
\ publicly visible."
classic: "Classic" classic: "Classic"
muteThread: "Mute thread" muteThread: "Mute thread"
unmuteThread: "Unmute thread" unmuteThread: "Unmute thread"
ffVisibility: "Follows/Followers Visibility" ffVisibility: "Follows/Followers Visibility"
ffVisibilityDescription: "Allows you to configure who can see who you follow and who follows you." ffVisibilityDescription: "Allows you to configure who can see who you follow and who\
\ follows you."
continueThread: "Continue thread" continueThread: "Continue thread"
deleteAccountConfirm: "This will irreversibly delete your account. Proceed?" deleteAccountConfirm: "This will irreversibly delete your account. Proceed?"
incorrectPassword: "Incorrect password." incorrectPassword: "Incorrect password."
@ -888,14 +954,16 @@ noEmailServerWarning: "Email server not configured."
thereIsUnresolvedAbuseReportWarning: "There are unsolved reports." thereIsUnresolvedAbuseReportWarning: "There are unsolved reports."
check: "Check" check: "Check"
driveCapOverrideLabel: "Change the drive capacity for this user" driveCapOverrideLabel: "Change the drive capacity for this user"
driveCapOverrideCaption: "Reset the capacity to default by inputting a value of 0 or lower." driveCapOverrideCaption: "Reset the capacity to default by inputting a value of 0\
\ or lower."
requireAdminForView: "You must log in with an administrator account to view this." requireAdminForView: "You must log in with an administrator account to view this."
isSystemAccount: "An account created and automatically operated by the system." isSystemAccount: "An account created and automatically operated by the system."
typeToConfirm: "Please enter {x} to confirm" typeToConfirm: "Please enter {x} to confirm"
deleteAccount: "Delete account" deleteAccount: "Delete account"
document: "Documentation" document: "Documentation"
numberOfPageCache: "Number of cached pages" numberOfPageCache: "Number of cached pages"
numberOfPageCacheDescription: "Increasing this number will improve convenience for users but cause more server load as well as more memory to be used." numberOfPageCacheDescription: "Increasing this number will improve convenience for\
\ users but cause more server load as well as more memory to be used."
logoutConfirm: "Really log out?" logoutConfirm: "Really log out?"
lastActiveDate: "Last used at" lastActiveDate: "Last used at"
statusbar: "Status bar" statusbar: "Status bar"
@ -912,12 +980,19 @@ sensitiveMediaDetection: "Detection of NSFW media"
localOnly: "Local only" localOnly: "Local only"
remoteOnly: "Remote only" remoteOnly: "Remote only"
failedToUpload: "Upload failed" failedToUpload: "Upload failed"
cannotUploadBecauseInappropriate: "This file could not be uploaded because parts of it have been detected as potentially NSFW." cannotUploadBecauseInappropriate: "This file could not be uploaded because parts of\
\ it have been detected as potentially NSFW."
cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity." cannotUploadBecauseNoFreeSpace: "Upload failed due to lack of Drive capacity."
cannotUploadBecauseExceedsFileSizeLimit: "This file could not be uploaded because\
\ it exceeds the maximum allowed size."
beta: "Beta" beta: "Beta"
enableAutoSensitive: "Automatic NSFW-Marking" enableAutoSensitive: "Automatic NSFW-Marking"
enableAutoSensitiveDescription: "Allows automatic detection and marking of NSFW media through Machine Learning where possible. Even if this option is disabled, it may be enabled instance-wide." enableAutoSensitiveDescription: "Allows automatic detection and marking of NSFW media\
activeEmailValidationDescription: "Enables stricter validation of email addresses, which includes checking for disposable addresses and by whether it can actually be communicated with. When unchecked, only the format of the email is validated." \ through Machine Learning where possible. Even if this option is disabled, it may\
\ be enabled instance-wide."
activeEmailValidationDescription: "Enables stricter validation of email addresses,\
\ which includes checking for disposable addresses and by whether it can actually\
\ be communicated with. When unchecked, only the format of the email is validated."
navbar: "Navigation bar" navbar: "Navigation bar"
shuffle: "Shuffle" shuffle: "Shuffle"
account: "Account" account: "Account"
@ -927,18 +1002,27 @@ subscribePushNotification: "Enable push notifications"
unsubscribePushNotification: "Disable push notifications" unsubscribePushNotification: "Disable push notifications"
pushNotificationAlreadySubscribed: "Push notifications are already enabled" pushNotificationAlreadySubscribed: "Push notifications are already enabled"
pushNotificationNotSupported: "Your browser or instance does not support push notifications" pushNotificationNotSupported: "Your browser or instance does not support push notifications"
sendPushNotificationReadMessage: "Delete push notifications once the relevant notifications or messages have been read" sendPushNotificationReadMessage: "Delete push notifications once the relevant notifications\
sendPushNotificationReadMessageCaption: "A notification containing the text \"{emptyPushNotificationMessage}\" will be displayed for a short time. This may increase the battery usage of your device, if applicable." \ or messages have been read"
sendPushNotificationReadMessageCaption: "A notification containing the text \"{emptyPushNotificationMessage}\"\
\ will be displayed for a short time. This may increase the battery usage of your\
\ device, if applicable."
showAds: "Show ads" showAds: "Show ads"
enterSendsMessage: "Press Return in Messaging to send message (off is Ctrl + Return)" enterSendsMessage: "Press Return in Messaging to send message (off is Ctrl + Return)"
adminCustomCssWarn: "This setting should only be used if you know what it does. Entering improper values may cause EVERYONE'S clients to stop functioning normally. Please ensure your CSS works properly by testing it in your user settings." adminCustomCssWarn: "This setting should only be used if you know what it does. Entering\
\ improper values may cause EVERYONE'S clients to stop functioning normally. Please\
\ ensure your CSS works properly by testing it in your user settings."
customMOTD: "Custom MOTD (splash screen messages)" customMOTD: "Custom MOTD (splash screen messages)"
customMOTDDescription: "Custom messages for the MOTD (splash screen) separated by line breaks to be shown randomly every time a user loads/reloads the page." customMOTDDescription: "Custom messages for the MOTD (splash screen) separated by\
\ line breaks to be shown randomly every time a user loads/reloads the page."
customSplashIcons: "Custom splash screen icons (urls)" customSplashIcons: "Custom splash screen icons (urls)"
customSplashIconsDescription: "URLs for custom splash screen icons separated by line breaks to be shown randomly every time a user loads/reloads the page. Please make sure the images are on a static URL, preferably all resized to 192x192." customSplashIconsDescription: "URLs for custom splash screen icons separated by line\
\ breaks to be shown randomly every time a user loads/reloads the page. Please make\
\ sure the images are on a static URL, preferably all resized to 192x192."
showUpdates: "Show a popup when Calckey updates" showUpdates: "Show a popup when Calckey updates"
recommendedInstances: "Recommended instances" recommendedInstances: "Recommended instances"
recommendedInstancesDescription: "Recommended instances seperated by line breaks to appear in the recommended timeline. Do NOT add `https://`, ONLY the domain." recommendedInstancesDescription: "Recommended instances separated by line breaks to\
\ appear in the recommended timeline. Do NOT add `https://`, ONLY the domain."
caption: "Auto Caption" caption: "Auto Caption"
splash: "Splash Screen" splash: "Splash Screen"
updateAvailable: "There might be an update available!" updateAvailable: "There might be an update available!"
@ -950,29 +1034,51 @@ migration: "Migration"
moveTo: "Move current account to new account" moveTo: "Move current account to new account"
moveToLabel: "Account you're moving to:" moveToLabel: "Account you're moving to:"
moveAccount: "Move account!" moveAccount: "Move account!"
moveAccountDescription: "This process is irreversible. Make sure you've set up an alias for this account on your new account before moving. Please enter the tag of the account formatted like @person@instance.com" moveAccountDescription: "This process is irreversible. Make sure you've set up an\
\ alias for this account on your new account before moving. Please enter the tag\
\ of the account formatted like @person@instance.com"
moveFrom: "Move to this account from an older account" moveFrom: "Move to this account from an older account"
moveFromLabel: "Account you're moving from:" moveFromLabel: "Account you're moving from:"
moveFromDescription: "This will set an alias of your old account so that you can move from that account to this current one. Do this BEFORE moving from your older account. Please enter the tag of the account formatted like @person@instance.com" moveFromDescription: "This will set an alias of your old account so that you can move\
migrationConfirm: "Are you absolutely sure you want to migrate your acccount to {account}? Once you do this, you won't be able to reverse it, and you won't be able to use your account normally again.\nAlso, please ensure that you've set this current account as the account you're moving from." \ from that account to this current one. Do this BEFORE moving from your older account.\
\ Please enter the tag of the account formatted like @person@instance.com"
migrationConfirm: "Are you absolutely sure you want to migrate your acccount to {account}?\
\ Once you do this, you won't be able to reverse it, and you won't be able to use\
\ your account normally again.\nAlso, please ensure that you've set this current\
\ account as the account you're moving from."
defaultReaction: "Default emoji reaction for outgoing and incoming posts" defaultReaction: "Default emoji reaction for outgoing and incoming posts"
license: "License" license: "License"
indexPosts: "Index Posts" indexPosts: "Index Posts"
indexFrom: "Index from Post ID onwards (leave blank to index every post)" indexFrom: "Index from Post ID onwards (leave blank to index every post)"
indexNotice: "Now indexing. This will probably take a while, please don't restart your server for at least an hour." indexNotice: "Now indexing. This will probably take a while, please don't restart\
\ your server for at least an hour."
customKaTeXMacro: "Custom KaTeX macros" customKaTeXMacro: "Custom KaTeX macros"
customKaTeXMacroDescription: "Set up macros to write mathematical expressions easily! The notation conforms to the LaTeX command definitions and is written as \\newcommand{\\name}{content} or \\newcommand{\\name}[number of arguments]{content}. For example, \\newcommand{\\add}[2]{#1 + #2} will expand \\add{3}{foo} to 3 + foo. The curly brackets surrounding the macro name can be changed to round or square brackets. This affects the brackets used for arguments. One (and only one) macro can be defined per line, and you can't break the line in the middle of the definition. Invalid lines are simply ignored. Only simple string substitution functions are supported; advanced syntax, such as conditional branching, cannot be used here." customKaTeXMacroDescription: "Set up macros to write mathematical expressions easily!\
\ The notation conforms to the LaTeX command definitions and is written as \\newcommand{\\\
name}{content} or \\newcommand{\\name}[number of arguments]{content}. For example,\
\ \\newcommand{\\add}[2]{#1 + #2} will expand \\add{3}{foo} to 3 + foo. The curly\
\ brackets surrounding the macro name can be changed to round or square brackets.\
\ This affects the brackets used for arguments. One (and only one) macro can be\
\ defined per line, and you can't break the line in the middle of the definition.\
\ Invalid lines are simply ignored. Only simple string substitution functions are\
\ supported; advanced syntax, such as conditional branching, cannot be used here."
enableCustomKaTeXMacro: "Enable custom KaTeX macros" enableCustomKaTeXMacro: "Enable custom KaTeX macros"
noteId: "Post ID" noteId: "Post ID"
_sensitiveMediaDetection: _sensitiveMediaDetection:
description: "Reduces the effort of server moderation through automatically recognizing NSFW media via Machine Learning. This will slightly increase the load on the server." description: "Reduces the effort of server moderation through automatically recognizing\
\ NSFW media via Machine Learning. This will slightly increase the load on the\
\ server."
sensitivity: "Detection sensitivity" sensitivity: "Detection sensitivity"
sensitivityDescription: "Reducing the sensitivity will lead to fewer misdetections (false positives) whereas increasing it will lead to fewer missed detections (false negatives)." sensitivityDescription: "Reducing the sensitivity will lead to fewer misdetections\
\ (false positives) whereas increasing it will lead to fewer missed detections\
\ (false negatives)."
setSensitiveFlagAutomatically: "Mark as NSFW" setSensitiveFlagAutomatically: "Mark as NSFW"
setSensitiveFlagAutomaticallyDescription: "The results of the internal detection will be retained even if this option is turned off." setSensitiveFlagAutomaticallyDescription: "The results of the internal detection\
\ will be retained even if this option is turned off."
analyzeVideos: "Enable analysis of videos" analyzeVideos: "Enable analysis of videos"
analyzeVideosDescription: "Analyzes videos in addition to images. This will slightly increase the load on the server." analyzeVideosDescription: "Analyzes videos in addition to images. This will slightly\
\ increase the load on the server."
_emailUnavailable: _emailUnavailable:
used: "This email address is already being used" used: "This email address is already being used"
format: "The format of this email address is invalid" format: "The format of this email address is invalid"
@ -986,11 +1092,15 @@ _ffVisibility:
_signup: _signup:
almostThere: "Almost there" almostThere: "Almost there"
emailAddressInfo: "Please enter your email address. It will not be made public." emailAddressInfo: "Please enter your email address. It will not be made public."
emailSent: "A confirmation email has been sent to your email address ({email}). Please click the included link to complete account creation." emailSent: "A confirmation email has been sent to your email address ({email}).\
\ Please click the included link to complete account creation."
_accountDelete: _accountDelete:
accountDelete: "Delete account" accountDelete: "Delete account"
mayTakeTime: "As account deletion is a resource-heavy process, it may take some time to complete depending on how much content you have created and how many files you have uploaded." mayTakeTime: "As account deletion is a resource-heavy process, it may take some\
sendEmail: "Once account deletion has been completed, an email will be sent to the email address registered to this account." \ time to complete depending on how much content you have created and how many\
\ files you have uploaded."
sendEmail: "Once account deletion has been completed, an email will be sent to the\
\ email address registered to this account."
requestAccountDelete: "Request account deletion" requestAccountDelete: "Request account deletion"
started: "Deletion has been started." started: "Deletion has been started."
inProgress: "Deletion is currently in progress" inProgress: "Deletion is currently in progress"
@ -998,9 +1108,12 @@ _ad:
back: "Back" back: "Back"
reduceFrequencyOfThisAd: "Show this ad less" reduceFrequencyOfThisAd: "Show this ad less"
_forgotPassword: _forgotPassword:
enterEmail: "Enter the email address you used to register. A link with which you can reset your password will then be sent to it." enterEmail: "Enter the email address you used to register. A link with which you\
ifNoEmail: "If you did not use an email during registration, please contact the instance administrator instead." \ can reset your password will then be sent to it."
contactAdmin: "This instance does not support using email addresses, please contact the instance administrator to reset your password instead." ifNoEmail: "If you did not use an email during registration, please contact the\
\ instance administrator instead."
contactAdmin: "This instance does not support using email addresses, please contact\
\ the instance administrator to reset your password instead."
_gallery: _gallery:
my: "My Gallery" my: "My Gallery"
liked: "Liked Posts" liked: "Liked Posts"
@ -1023,12 +1136,15 @@ _preferencesBackups:
save: "Save changes" save: "Save changes"
inputName: "Please enter a name for this backup" inputName: "Please enter a name for this backup"
cannotSave: "Saving failed" cannotSave: "Saving failed"
nameAlreadyExists: "A backup called \"{name}\" already exists. Please enter a different name." nameAlreadyExists: "A backup called \"{name}\" already exists. Please enter a different\
applyConfirm: "Do you really want to apply the \"{name}\" backup to this device? Existing settings of this device will be overwritten." \ name."
applyConfirm: "Do you really want to apply the \"{name}\" backup to this device?\
\ Existing settings of this device will be overwritten."
saveConfirm: "Save backup as {name}?" saveConfirm: "Save backup as {name}?"
deleteConfirm: "Delete the {name} backup?" deleteConfirm: "Delete the {name} backup?"
renameConfirm: "Rename this backup from \"{old}\" to \"{new}\"?" renameConfirm: "Rename this backup from \"{old}\" to \"{new}\"?"
noBackups: "No backups exist. You may backup your client settings on this server by using \"Create new backup\"." noBackups: "No backups exist. You may backup your client settings on this server\
\ by using \"Create new backup\"."
createdAt: "Created at: {date} {time}" createdAt: "Created at: {date} {time}"
updatedAt: "Updated at: {date} {time}" updatedAt: "Updated at: {date} {time}"
cannotLoad: "Loading failed" cannotLoad: "Loading failed"
@ -1040,13 +1156,15 @@ _registry:
domain: "Domain" domain: "Domain"
createKey: "Create key" createKey: "Create key"
_aboutMisskey: _aboutMisskey:
about: "Calckey is a fork of Misskey made by ThatOneCalculator, which has been in development since 2022." about: "Calckey is a fork of Misskey made by ThatOneCalculator, which has been in\
\ development since 2022."
contributors: "Main contributors" contributors: "Main contributors"
allContributors: "All contributors" allContributors: "All contributors"
source: "Source code" source: "Source code"
translation: "Translate Calckey" translation: "Translate Calckey"
donate: "Donate to Calckey" donate: "Donate to Calckey"
morePatrons: "We also appreciate the support of many other helpers not listed here. Thank you! 🥰" morePatrons: "We also appreciate the support of many other helpers not listed here.\
\ Thank you! \U0001F970"
patrons: "Calckey patrons" patrons: "Calckey patrons"
_nsfw: _nsfw:
respect: "Hide NSFW media" respect: "Hide NSFW media"
@ -1054,7 +1172,8 @@ _nsfw:
force: "Hide all media" force: "Hide all media"
_mfm: _mfm:
cheatSheet: "MFM Cheatsheet" cheatSheet: "MFM Cheatsheet"
intro: "MFM is a markup language used on Misskey, Calckey, Akkoma, and more that can be used in many places. Here you can view a list of all available MFM syntax." intro: "MFM is a markup language used on Misskey, Calckey, Akkoma, and more that\
\ can be used in many places. Here you can view a list of all available MFM syntax."
dummy: "Calckey expands the world of the Fediverse" dummy: "Calckey expands the world of the Fediverse"
mention: "Mention" mention: "Mention"
mentionDescription: "You can specify a user by using an At-Symbol and a username." mentionDescription: "You can specify a user by using an At-Symbol and a username."
@ -1073,7 +1192,8 @@ _mfm:
inlineCode: "Code (Inline)" inlineCode: "Code (Inline)"
inlineCodeDescription: "Displays inline syntax highlighting for (program) code." inlineCodeDescription: "Displays inline syntax highlighting for (program) code."
blockCode: "Code (Block)" blockCode: "Code (Block)"
blockCodeDescription: "Displays syntax highlighting for multi-line (program) code in a block." blockCodeDescription: "Displays syntax highlighting for multi-line (program) code\
\ in a block."
inlineMath: "Math (Inline)" inlineMath: "Math (Inline)"
inlineMathDescription: "Display math formulas (KaTeX) in-line" inlineMathDescription: "Display math formulas (KaTeX) in-line"
blockMath: "Math (Block)" blockMath: "Math (Block)"
@ -1081,7 +1201,8 @@ _mfm:
quote: "Quote" quote: "Quote"
quoteDescription: "Displays content as a quote." quoteDescription: "Displays content as a quote."
emoji: "Custom Emoji" emoji: "Custom Emoji"
emojiDescription: "By surrounding a custom emoji name with colons, custom emoji can be displayed." emojiDescription: "By surrounding a custom emoji name with colons, custom emoji\
\ can be displayed."
search: "Search" search: "Search"
searchDescription: "Displays a search box with pre-entered text." searchDescription: "Displays a search box with pre-entered text."
flip: "Flip" flip: "Flip"
@ -1117,7 +1238,8 @@ _mfm:
rotate: "Rotate" rotate: "Rotate"
rotateDescription: "Turns content by a specified angle." rotateDescription: "Turns content by a specified angle."
plain: "Plain" plain: "Plain"
plainDescription: "Deactivates the effects of all MFM contained within this MFM effect." plainDescription: "Deactivates the effects of all MFM contained within this MFM\
\ effect."
_instanceTicker: _instanceTicker:
none: "Never show" none: "Never show"
remote: "Show for remote users" remote: "Show for remote users"
@ -1147,15 +1269,19 @@ _menuDisplay:
hide: "Hide" hide: "Hide"
_wordMute: _wordMute:
muteWords: "Muted words" muteWords: "Muted words"
muteWordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition." muteWordsDescription: "Separate with spaces for an AND condition or with line breaks\
\ for an OR condition."
muteWordsDescription2: "Surround keywords with slashes to use regular expressions." muteWordsDescription2: "Surround keywords with slashes to use regular expressions."
softDescription: "Hide posts that fulfil the set conditions from the timeline." softDescription: "Hide posts that fulfil the set conditions from the timeline."
hardDescription: "Prevents posts fulfilling the set conditions from being added to the timeline. In addition, these posts will not be added to the timeline even if the conditions are changed." hardDescription: "Prevents posts fulfilling the set conditions from being added\
\ to the timeline. In addition, these posts will not be added to the timeline\
\ even if the conditions are changed."
soft: "Soft" soft: "Soft"
hard: "Hard" hard: "Hard"
mutedNotes: "Muted posts" mutedNotes: "Muted posts"
_instanceMute: _instanceMute:
instanceMuteDescription: "This will mute any posts/boosts from the listed instances, including those of users replying to a user from a muted instance." instanceMuteDescription: "This will mute any posts/boosts from the listed instances,\
\ including those of users replying to a user from a muted instance."
instanceMuteDescription2: "Separate with newlines" instanceMuteDescription2: "Separate with newlines"
title: "Hides posts from listed instances." title: "Hides posts from listed instances."
heading: "List of instances to be muted" heading: "List of instances to be muted"
@ -1261,21 +1387,35 @@ _tutorial:
step1_1: "Welcome!" step1_1: "Welcome!"
step1_2: "Let's get you set up. You'll be up and running in no time!" step1_2: "Let's get you set up. You'll be up and running in no time!"
step2_1: "First, please fill out your profile." step2_1: "First, please fill out your profile."
step2_2: "Providing some information about who you are will make it easier for others to tell if they want to see your posts or follow you." step2_2: "Providing some information about who you are will make it easier for others\
\ to tell if they want to see your posts or follow you."
step3_1: "Now time to follow some people!" step3_1: "Now time to follow some people!"
step3_2: "Your home and social timelines are based off of who you follow, so try following a couple accounts to get started.\nClick the plus circle on the top right of a profile to follow them." step3_2: "Your home and social timelines are based off of who you follow, so try\
\ following a couple accounts to get started.\nClick the plus circle on the top\
\ right of a profile to follow them."
step4_1: "Let's get you out there." step4_1: "Let's get you out there."
step4_2: "For your first post, some people like to made a {introduction} post or a simple \"Hello world!\"" step4_2: "For your first post, some people like to made a {introduction} post or\
\ a simple \"Hello world!\""
step5_1: "Timelines, timelines everywhere!" step5_1: "Timelines, timelines everywhere!"
step5_2: "Your instance has {timelines} different timelines enabled." step5_2: "Your instance has {timelines} different timelines enabled."
step5_3: "The Home {icon} timeline is where you can see posts from the accounts you follow and from everyone else on this instance. If you prefer your Home timeline to only display posts from accounts you follow, you can easily change this in Settings!" step5_3: "The Home {icon} timeline is where you can see posts from the accounts\
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this instance." \ you follow and from everyone else on this instance. If you prefer your Home\
step5_5: "The Social {icon} timeline is where you can see posts only from the accounts you follow." \ timeline to only display posts from accounts you follow, you can easily change\
step5_6: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend." \ this in Settings!"
step5_7: "The Global {icon} timeline is where you can see posts from every other connected instance." step5_4: "The Local {icon} timeline is where you can see posts from everyone else\
\ on this instance."
step5_5: "The Social {icon} timeline is where you can see posts only from the accounts\
\ you follow."
step5_6: "The Recommended {icon} timeline is where you can see posts from instances\
\ the admins recommend."
step5_7: "The Global {icon} timeline is where you can see posts from every other\
\ connected instance."
step6_1: "So, what is this place?" step6_1: "So, what is this place?"
step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse, an interconnected network of thousands of servers, called \"instances\"." step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse,\
step6_3: "Each server works in different ways, and not all servers run Calckey. This one does though! It's a bit complicated, but you'll get the hang of it in no time." \ an interconnected network of thousands of servers, called \"instances\"."
step6_3: "Each server works in different ways, and not all servers run Calckey.\
\ This one does though! It's a bit complicated, but you'll get the hang of it\
\ in no time."
step6_4: "Now go, explore, and have fun!" step6_4: "Now go, explore, and have fun!"
_2fa: _2fa:
alreadyRegistered: "You have already registered a 2-factor authentication device." alreadyRegistered: "You have already registered a 2-factor authentication device."
@ -1286,7 +1426,9 @@ _2fa:
step2Url: "You can also enter this URL if you're using a desktop program:" step2Url: "You can also enter this URL if you're using a desktop program:"
step3: "Enter the token provided by your app to finish setup." step3: "Enter the token provided by your app to finish setup."
step4: "From now on, any future login attempts will ask for such a login token." step4: "From now on, any future login attempts will ask for such a login token."
securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup authentication via hardware security keys that support FIDO2 to further secure your account." securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup\
\ authentication via hardware security keys that support FIDO2 to further secure\
\ your account."
_permissions: _permissions:
"read:account": "View your account information" "read:account": "View your account information"
"write:account": "Edit your account information" "write:account": "Edit your account information"
@ -1322,7 +1464,8 @@ _permissions:
"write:gallery-likes": "Edit your list of liked gallery posts" "write:gallery-likes": "Edit your list of liked gallery posts"
_auth: _auth:
shareAccess: "Would you like to authorize \"{name}\" to access this account?" shareAccess: "Would you like to authorize \"{name}\" to access this account?"
shareAccessAsk: "Are you sure you want to authorize this application to access your account?" shareAccessAsk: "Are you sure you want to authorize this application to access your\
\ account?"
permissionAsk: "This application requests the following permissions" permissionAsk: "This application requests the following permissions"
pleaseGoBack: "Please go back to the application" pleaseGoBack: "Please go back to the application"
callback: "Returning to the application" callback: "Returning to the application"
@ -1424,12 +1567,14 @@ _profile:
youCanIncludeHashtags: "You can also include hashtags in your bio." youCanIncludeHashtags: "You can also include hashtags in your bio."
metadata: "Additional Information" metadata: "Additional Information"
metadataEdit: "Edit additional Information" metadataEdit: "Edit additional Information"
metadataDescription: "Using these, you can display additional information fields in your profile." metadataDescription: "Using these, you can display additional information fields\
\ in your profile."
metadataLabel: "Label" metadataLabel: "Label"
metadataContent: "Content" metadataContent: "Content"
changeAvatar: "Change avatar" changeAvatar: "Change avatar"
changeBanner: "Change banner" changeBanner: "Change banner"
locationDescription: "If you enter your city, it will display your local time to other users." locationDescription: "If you enter your city first, it will display your local time\
\ to other users."
_exportOrImport: _exportOrImport:
allNotes: "All posts" allNotes: "All posts"
followingList: "Followed users" followingList: "Followed users"
@ -1747,7 +1892,8 @@ _pages:
_for: _for:
arg1: "Number of times to repeat" arg1: "Number of times to repeat"
arg2: "Action" arg2: "Action"
typeError: "Slot {slot} accepts values of type \"{expect}\", but the provided value is of type \"{actual}\"!" typeError: "Slot {slot} accepts values of type \"{expect}\", but the provided\
\ value is of type \"{actual}\"!"
thereIsEmptySlot: "Slot {slot} is empty!" thereIsEmptySlot: "Slot {slot} is empty!"
types: types:
string: "Text" string: "Text"
@ -1809,10 +1955,14 @@ _deck:
popRight: "Pop column to the right" popRight: "Pop column to the right"
profile: "Workspace" profile: "Workspace"
newProfile: "New workspace" newProfile: "New workspace"
renameProfile: "Rename workspace"
deleteProfile: "Delete workspace" deleteProfile: "Delete workspace"
nameAlreadyExists: "This workspace name already exists."
introduction: "Create the perfect interface for you by arranging columns freely!" introduction: "Create the perfect interface for you by arranging columns freely!"
introduction2: "Click on the + on the right of the screen to add new colums whenever you want." introduction2: "Click on the + on the right of the screen to add new colums whenever\
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget." \ you want."
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add\
\ a widget."
_columns: _columns:
main: "Main" main: "Main"
widgets: "Widgets" widgets: "Widgets"

View file

@ -1,7 +1,8 @@
---
_lang_: "Español" _lang_: "Español"
headlineMisskey: "Red conectada por notas" headlineMisskey: "¡Un proyecto de código abierto y una plataforma de medios de comunicación\
introMisskey: "¡Bienvenido/a! Misskey es un servicio de microblogging descentralizado de código abierto.\nEscribe \"notas\" para compartir lo que te ocurre ahora o para contar sobre ti a todos 📡\nCon la función de \"reacciones\", puedes también añadir una reacción rápida a las notas de todos 👍\n¡Exploremos juntos un nuevo mundo! 🚀" \ descentralizada que es gratis para siempre! \U0001F680"
introMisskey: "¡Bienvenido! ¡Calckey es un proyecto de código abierto, plataforma\
\ descentralizado medios de comunicación social que es gratis para siempre! \U0001F680"
monthAndDay: "{day}/{month}" monthAndDay: "{day}/{month}"
search: "Buscar" search: "Buscar"
notifications: "Notificaciones" notifications: "Notificaciones"
@ -14,7 +15,7 @@ gotIt: "¡Lo tengo!"
cancel: "Cancelar" cancel: "Cancelar"
enterUsername: "Introduce el nombre de usuario" enterUsername: "Introduce el nombre de usuario"
renotedBy: "Renotado por {user}" renotedBy: "Renotado por {user}"
noNotes: "No hay notas" noNotes: "No hay publicaciones"
noNotifications: "No hay notificaciones" noNotifications: "No hay notificaciones"
instance: "Instancia" instance: "Instancia"
settings: "Configuración" settings: "Configuración"
@ -23,7 +24,7 @@ otherSettings: "Configuración avanzada"
openInWindow: "Abrir en una ventana" openInWindow: "Abrir en una ventana"
profile: "Perfil" profile: "Perfil"
timeline: "Línea de tiempo" timeline: "Línea de tiempo"
noAccountDescription: "Este usuario no ha escrito su biografía aún" noAccountDescription: "Este usuario no ha escrito su biografía aún."
login: "Iniciar sesión" login: "Iniciar sesión"
loggingIn: "Iniciando sesión" loggingIn: "Iniciando sesión"
logout: "Cerrar sesión" logout: "Cerrar sesión"
@ -36,7 +37,7 @@ favorite: "Añadir a favoritos"
favorites: "Favoritos" favorites: "Favoritos"
unfavorite: "Quitar de favoritos" unfavorite: "Quitar de favoritos"
favorited: "Añadido a favoritos." favorited: "Añadido a favoritos."
alreadyFavorited: "Ya había sido añadido a favoritos" alreadyFavorited: "Ya había sido añadido a favoritos."
cantFavorite: "No se puede añadir a favoritos." cantFavorite: "No se puede añadir a favoritos."
pin: "Fijar al perfil" pin: "Fijar al perfil"
unpin: "Desfijar" unpin: "Desfijar"
@ -44,7 +45,8 @@ copyContent: "Copiar contenido"
copyLink: "Copiar enlace" copyLink: "Copiar enlace"
delete: "Borrar" delete: "Borrar"
deleteAndEdit: "Borrar y editar" deleteAndEdit: "Borrar y editar"
deleteAndEditConfirm: "¿Estás seguro de que quieres borrar esta nota y editarla? Perderás todas las reacciones, renotas y respuestas." deleteAndEditConfirm: "¿Estás seguro de que quieres borrar esta publicación y editarla?\
\ Perderás todas las reacciones, impulsados y respuestas."
addToList: "Agregar a lista" addToList: "Agregar a lista"
sendMessage: "Enviar un mensaje" sendMessage: "Enviar un mensaje"
copyUsername: "Copiar nombre de usuario" copyUsername: "Copiar nombre de usuario"
@ -58,20 +60,22 @@ receiveFollowRequest: "Recibiste una solicitud de seguimiento"
followRequestAccepted: "La solicitud de seguimiento fue aceptada" followRequestAccepted: "La solicitud de seguimiento fue aceptada"
mention: "Menciones" mention: "Menciones"
mentions: "Menciones" mentions: "Menciones"
directNotes: "Notas directas" directNotes: "Mensajes Directos"
importAndExport: "Importar y Exportar" importAndExport: "Importar y Exportar"
import: "Importar" import: "Importar"
export: "Exportar" export: "Exportar"
files: "Archivos" files: "Archivos"
download: "Descargar" download: "Descargar"
driveFileDeleteConfirm: "¿Desea borrar el archivo \"{name}\"? Las notas que tengan este archivo como adjunto serán eliminadas" driveFileDeleteConfirm: "¿Desea borrar el archivo \"{name}\"? Las publicaciones que\
\ tengan este archivo como adjunto serán eliminadas."
unfollowConfirm: "¿Desea dejar de seguir a {name}?" unfollowConfirm: "¿Desea dejar de seguir a {name}?"
exportRequested: "Se ha solicitado la exportación. Puede tomar un tiempo. Cuando termine la exportación, se añadirá en el drive" exportRequested: "Se ha solicitado la exportación. Puede tomar un tiempo. Cuando termine\
\ la exportación, se añadirá en el drive."
importRequested: "Se ha solicitado la importación. Puede tomar un tiempo." importRequested: "Se ha solicitado la importación. Puede tomar un tiempo."
lists: "Listas" lists: "Listas"
noLists: "No tiene listas" noLists: "No tiene listas"
note: "Notas" note: "Publicación"
notes: "Notas" notes: "Publicaciones"
following: "Siguiendo" following: "Siguiendo"
followers: "Seguidores" followers: "Seguidores"
followsYou: "Te sigue" followsYou: "Te sigue"
@ -80,10 +84,12 @@ manageLists: "Administrar listas"
error: "Error" error: "Error"
somethingHappened: "Ocurrió un error" somethingHappened: "Ocurrió un error"
retry: "Reintentar" retry: "Reintentar"
pageLoadError: "Error al leer la página" pageLoadError: "Error al cargar la página."
pageLoadErrorDescription: "Normalmente es debido a la red o al caché del navegador. Por favor limpie el caché o intente más tarde." pageLoadErrorDescription: "Normalmente es debido a la red o al caché del navegador.\
\ Por favor limpie el caché o intente más tarde."
serverIsDead: "No hay respuesta del servidor. Espere un momento y vuelva a intentarlo." serverIsDead: "No hay respuesta del servidor. Espere un momento y vuelva a intentarlo."
youShouldUpgradeClient: "Para ver esta página, por favor refrezca el navegador y utiliza una versión más reciente del cliente." youShouldUpgradeClient: "Para ver esta página, por favor refrezca el navegador y utiliza\
\ una versión más reciente del cliente."
enterListName: "Ingrese nombre de lista" enterListName: "Ingrese nombre de lista"
privacy: "Privacidad" privacy: "Privacidad"
makeFollowManuallyApprove: "Aprobar manualmente las solicitudes de seguimiento" makeFollowManuallyApprove: "Aprobar manualmente las solicitudes de seguimiento"
@ -94,13 +100,13 @@ followRequests: "Solicitudes de seguimiento"
unfollow: "Dejar de seguir" unfollow: "Dejar de seguir"
followRequestPending: "Solicitudes de seguimiento pendiente" followRequestPending: "Solicitudes de seguimiento pendiente"
enterEmoji: "Ingresar emojis" enterEmoji: "Ingresar emojis"
renote: "Renotar" renote: "Impulsar"
unrenote: "Quitar renota" unrenote: "Quitar impulso"
renoted: "Renotado" renoted: "Impulsado."
cantRenote: "No se puede renotar este post" cantRenote: "No se puede impulsar esta publicación."
cantReRenote: "No se puede renotar una renota" cantReRenote: "No se puede impulsar un impulso."
quote: "Citar" quote: "Citar"
pinnedNote: "Nota fijada" pinnedNote: "Publicación fijada"
pinned: "Fijar al perfil" pinned: "Fijar al perfil"
you: "Tú" you: "Tú"
clickToShow: "Click para ver" clickToShow: "Click para ver"
@ -108,8 +114,9 @@ sensitive: "Marcado como sensible"
add: "Agregar" add: "Agregar"
reaction: "Reacción" reaction: "Reacción"
reactionSetting: "Reacciones para mostrar en el menú de reacciones" reactionSetting: "Reacciones para mostrar en el menú de reacciones"
reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete la tecla + para añadir." reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete\
rememberNoteVisibility: "Recordar visibilidad" \ la tecla + para añadir."
rememberNoteVisibility: "Recordar la configuración de visibilidad de la publicación"
attachCancel: "Quitar adjunto" attachCancel: "Quitar adjunto"
markAsSensitive: "Marcar como sensible" markAsSensitive: "Marcar como sensible"
unmarkAsSensitive: "Desmarcar como sensible" unmarkAsSensitive: "Desmarcar como sensible"
@ -137,16 +144,23 @@ emojiUrl: "URL de la imágen del emoji"
addEmoji: "Agregar emoji" addEmoji: "Agregar emoji"
settingGuide: "Configuración sugerida" settingGuide: "Configuración sugerida"
cacheRemoteFiles: "Mantener en cache los archivos remotos" cacheRemoteFiles: "Mantener en cache los archivos remotos"
cacheRemoteFilesDescription: "Si desactiva esta configuración, Los archivos remotos se cargarán desde el link directo sin usar la caché. Con eso se puede ahorrar almacenamiento del servidor, pero eso aumentará el tráfico al no crear miniaturas." cacheRemoteFilesDescription: "Si desactiva esta configuración, Los archivos remotos\
\ se cargarán desde el link directo sin usar la caché. Con eso se puede ahorrar\
\ almacenamiento del servidor, pero eso aumentará el tráfico al no crear miniaturas."
flagAsBot: "Esta cuenta es un bot" flagAsBot: "Esta cuenta es un bot"
flagAsBotDescription: "En caso de que esta cuenta fuera usada por un programa, active esta opción. Al hacerlo, esta opción servirá para otros desarrolladores para evitar cadenas infinitas de reacciones, y ajustará los sistemas internos de Misskey para que trate a esta cuenta como un bot." flagAsBotDescription: "En caso de que esta cuenta fuera usada por un programa, active\
\ esta opción. Al hacerlo, esta opción servirá para otros desarrolladores para evitar\
\ cadenas infinitas de reacciones, y ajustará los sistemas internos de Calckey para\
\ que trate a esta cuenta como un bot."
flagAsCat: "Esta cuenta es un gato" flagAsCat: "Esta cuenta es un gato"
flagAsCatDescription: "En caso de que declare que esta cuenta es de un gato, active esta opción." flagAsCatDescription: "Vas a tener orejas de gato y hablar como un gato!"
flagShowTimelineReplies: "Mostrar respuestas a las notas en la biografía" flagShowTimelineReplies: "Mostrar respuestas a las notas en la biografía"
flagShowTimelineRepliesDescription: "Cuando se marca, la línea de tiempo muestra respuestas a otras notas además de las notas del usuario" flagShowTimelineRepliesDescription: "Cuando se marca, la línea de tiempo muestra respuestas\
autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los usuarios que sigues" \ a otras publicaciones además de las publicaciones del usuario."
autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los\
\ usuarios que sigues"
addAccount: "Agregar Cuenta" addAccount: "Agregar Cuenta"
loginFailed: "Error al iniciar sesión." loginFailed: "Error al iniciar sesión"
showOnRemote: "Ver en una instancia remota" showOnRemote: "Ver en una instancia remota"
general: "General" general: "General"
wallpaper: "Fondo de pantalla" wallpaper: "Fondo de pantalla"
@ -156,7 +170,11 @@ searchWith: "Buscar: {q}"
youHaveNoLists: "No tienes listas" youHaveNoLists: "No tienes listas"
followConfirm: "¿Desea seguir a {name}?" followConfirm: "¿Desea seguir a {name}?"
proxyAccount: "Cuenta proxy" proxyAccount: "Cuenta proxy"
proxyAccountDescription: "Una cuenta proxy es una cuenta que actúa como un seguidor remoto de un usuario bajo ciertas condiciones. Por ejemplo, cuando un usuario añade un usuario remoto a una lista, si ningún usuario local sigue al usuario agregado a la lista, la instancia no puede obtener su actividad. Así que la cuenta proxy sigue al usuario añadido a la lista" proxyAccountDescription: "Una cuenta proxy es una cuenta que actúa como un seguidor\
\ remoto de un usuario bajo ciertas condiciones. Por ejemplo, cuando un usuario\
\ añade un usuario remoto a una lista, si ningún usuario local sigue al usuario\
\ agregado a la lista, la instancia no puede obtener su actividad. Así que la cuenta\
\ proxy sigue al usuario añadido a la lista."
host: "Host" host: "Host"
selectUser: "Elegir usuario" selectUser: "Elegir usuario"
recipient: "Recipiente" recipient: "Recipiente"
@ -187,21 +205,24 @@ instanceInfo: "información de la instancia"
statistics: "Estadísticas" statistics: "Estadísticas"
clearQueue: "Limpiar cola" clearQueue: "Limpiar cola"
clearQueueConfirmTitle: "¿Desea limpiar la cola?" clearQueueConfirmTitle: "¿Desea limpiar la cola?"
clearQueueConfirmText: "Las notas aún no entregadas no se federarán. Normalmente no se necesita ejecutar esta operación" clearQueueConfirmText: "Las publicaciones aún no entregadas no se federarán. Normalmente\
\ no se necesita ejecutar esta operación."
clearCachedFiles: "Limpiar caché" clearCachedFiles: "Limpiar caché"
clearCachedFilesConfirm: "¿Desea borrar todos los archivos remotos cacheados?" clearCachedFilesConfirm: "¿Desea borrar todos los archivos remotos cacheados?"
blockedInstances: "Instancias bloqueadas" blockedInstances: "Instancias bloqueadas"
blockedInstancesDescription: "Seleccione los hosts de las instancias que desea bloquear, separadas por una linea nueva. Las instancias bloqueadas no podrán comunicarse con esta instancia." blockedInstancesDescription: "Seleccione los hosts de las instancias que desea bloquear,\
\ separadas por una linea nueva. Las instancias bloqueadas no podrán comunicarse\
\ con esta instancia."
muteAndBlock: "Silenciar y bloquear" muteAndBlock: "Silenciar y bloquear"
mutedUsers: "Usuarios silenciados" mutedUsers: "Usuarios silenciados"
blockedUsers: "Usuarios bloqueados" blockedUsers: "Usuarios bloqueados"
noUsers: "No hay usuarios" noUsers: "No hay usuarios"
editProfile: "Editar perfil" editProfile: "Editar perfil"
noteDeleteConfirm: "¿Desea borrar esta nota?" noteDeleteConfirm: "¿Desea borrar esta publicación?"
pinLimitExceeded: "Ya no se pueden fijar más posts" pinLimitExceeded: "Ya no se pueden fijar más publicaciones"
intro: "¡La instalación de Misskey ha terminado! Crea el usuario administrador." intro: "¡La instalación de Calckey ha terminado! Crea el usuario administrador."
done: "Terminado" done: "Terminado"
processing: "Procesando" processing: "Procesando..."
preview: "Vista previa" preview: "Vista previa"
default: "Predeterminado" default: "Predeterminado"
defaultValueIs: "Predeterminado" defaultValueIs: "Predeterminado"
@ -219,7 +240,7 @@ instanceFollowers: "Seguidores de la instancia"
instanceUsers: "Usuarios de la instancia" instanceUsers: "Usuarios de la instancia"
changePassword: "Cambiar contraseña" changePassword: "Cambiar contraseña"
security: "Seguridad" security: "Seguridad"
retypedNotMatch: "No hay coincidencia" retypedNotMatch: "No hay coincidencia."
currentPassword: "Contraseña actual" currentPassword: "Contraseña actual"
newPassword: "Contraseña nueva" newPassword: "Contraseña nueva"
newPasswordRetype: "Contraseña nueva (repetir)" newPasswordRetype: "Contraseña nueva (repetir)"
@ -240,7 +261,9 @@ saved: "Guardado"
messaging: "Chat" messaging: "Chat"
upload: "Subir" upload: "Subir"
keepOriginalUploading: "Mantener la imagen original" keepOriginalUploading: "Mantener la imagen original"
keepOriginalUploadingDescription: "Mantener la versión original al cargar imágenes. Si está desactivado, el navegador generará imágenes para la publicación web en el momento de recargar la página" keepOriginalUploadingDescription: "Mantener la versión original al cargar imágenes.\
\ Si está desactivado, el navegador generará imágenes para la publicación web en\
\ el momento de recargar la página."
fromDrive: "Desde el drive" fromDrive: "Desde el drive"
fromUrl: "Desde la URL" fromUrl: "Desde la URL"
uploadFromUrl: "Subir desde una URL" uploadFromUrl: "Subir desde una URL"
@ -256,7 +279,7 @@ agreeTo: "De acuerdo con {0}"
tos: "Términos de uso" tos: "Términos de uso"
start: "Comenzar" start: "Comenzar"
home: "Inicio" home: "Inicio"
remoteUserCaution: "Para el usuario remoto, la información está incompleta" remoteUserCaution: "La información del usuario remoto tal vez esta incompleta."
activity: "Actividad" activity: "Actividad"
images: "Imágenes" images: "Imágenes"
birthday: "Fecha de nacimiento" birthday: "Fecha de nacimiento"
@ -289,7 +312,8 @@ unableToDelete: "No se puede borrar"
inputNewFileName: "Ingrese un nuevo nombre de archivo" inputNewFileName: "Ingrese un nuevo nombre de archivo"
inputNewDescription: "Ingrese nueva descripción" inputNewDescription: "Ingrese nueva descripción"
inputNewFolderName: "Ingrese un nuevo nombre de la carpeta" inputNewFolderName: "Ingrese un nuevo nombre de la carpeta"
circularReferenceFolder: "La carpeta de destino es una sub-carpeta de la carpeta que quieres mover." circularReferenceFolder: "La carpeta de destino es una sub-carpeta de la carpeta que\
\ quieres mover."
hasChildFilesOrFolders: "No se puede borrar esta carpeta. No está vacía." hasChildFilesOrFolders: "No se puede borrar esta carpeta. No está vacía."
copyUrl: "Copiar URL" copyUrl: "Copiar URL"
rename: "Renombrar" rename: "Renombrar"
@ -323,7 +347,8 @@ connectService: "Conectar"
disconnectService: "Desconectar" disconnectService: "Desconectar"
enableLocalTimeline: "Habilitar linea de tiempo local" enableLocalTimeline: "Habilitar linea de tiempo local"
enableGlobalTimeline: "Habilitar linea de tiempo global" enableGlobalTimeline: "Habilitar linea de tiempo global"
disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia el administrador y los moderadores pueden seguir usándolos" disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia\
\ el administrador y los moderadores pueden seguir usándolos"
registration: "Registro" registration: "Registro"
enableRegistration: "Permitir nuevos registros" enableRegistration: "Permitir nuevos registros"
invite: "Invitar" invite: "Invitar"
@ -335,9 +360,11 @@ bannerUrl: "URL de la imagen del banner"
backgroundImageUrl: "URL de la imagen de fondo" backgroundImageUrl: "URL de la imagen de fondo"
basicInfo: "Información básica" basicInfo: "Información básica"
pinnedUsers: "Usuarios fijados" pinnedUsers: "Usuarios fijados"
pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\" separados por una linea nueva" pinnedUsersDescription: "Describir los usuarios que quiere fijar en la página \"Descubrir\"\
\ separados por una linea nueva"
pinnedPages: "Páginas fijadas" pinnedPages: "Páginas fijadas"
pinnedPagesDescription: "Describa las rutas de las páginas que desea fijar a la página principal de la instancia, separadas por lineas nuevas" pinnedPagesDescription: "Describa las rutas de las páginas que desea fijar a la página\
\ principal de la instancia, separadas por lineas nuevas"
pinnedClipId: "Id del clip fijado" pinnedClipId: "Id del clip fijado"
pinnedNotes: "Nota fijada" pinnedNotes: "Nota fijada"
hcaptcha: "hCaptcha" hcaptcha: "hCaptcha"
@ -348,14 +375,17 @@ recaptcha: "reCAPTCHA"
enableRecaptcha: "activar reCAPTCHA" enableRecaptcha: "activar reCAPTCHA"
recaptchaSiteKey: "Clave del sitio" recaptchaSiteKey: "Clave del sitio"
recaptchaSecretKey: "Clave secreta" recaptchaSecretKey: "Clave secreta"
avoidMultiCaptchaConfirm: "El uso de múltiples Captchas puede causar interferencia. ¿Desea desactivar el otro Captcha? Puede dejar múltiples Captchas habilitadas presionando cancelar." avoidMultiCaptchaConfirm: "El uso de múltiples Captchas puede causar interferencia.\
\ ¿Desea desactivar el otro Captcha? Puede dejar múltiples Captchas habilitadas\
\ presionando cancelar."
antennas: "Antenas" antennas: "Antenas"
manageAntennas: "Administrar antenas" manageAntennas: "Administrar antenas"
name: "Nombre" name: "Nombre"
antennaSource: "Origen de la antena" antennaSource: "Origen de la antena"
antennaKeywords: "Palabras clave para recibir" antennaKeywords: "Palabras clave para recibir"
antennaExcludeKeywords: "Palabras clave para excluir" antennaExcludeKeywords: "Palabras clave para excluir"
antennaKeywordsDescription: "Separar con espacios es una declaración AND, separar con una linea nueva es una declaración OR" antennaKeywordsDescription: "Separar con espacios es una declaración AND, separar\
\ con una linea nueva es una declaración OR"
notifyAntenna: "Notificar nueva nota" notifyAntenna: "Notificar nueva nota"
withFileAntenna: "Sólo notas con archivos adjuntados" withFileAntenna: "Sólo notas con archivos adjuntados"
enableServiceworker: "Activar ServiceWorker" enableServiceworker: "Activar ServiceWorker"
@ -378,7 +408,7 @@ exploreFediverse: "Explorar fediverso"
popularTags: "Etiquetas populares" popularTags: "Etiquetas populares"
userList: "Lista" userList: "Lista"
about: "Información" about: "Información"
aboutMisskey: "Sobre Misskey" aboutMisskey: "Sobre Calckey"
administrator: "Administrador" administrator: "Administrador"
token: "Token" token: "Token"
twoStepAuthentication: "Autenticación de dos factores" twoStepAuthentication: "Autenticación de dos factores"
@ -443,7 +473,8 @@ strongPassword: "Muy buena contraseña"
passwordMatched: "Correcto" passwordMatched: "Correcto"
passwordNotMatched: "Las contraseñas no son las mismas" passwordNotMatched: "Las contraseñas no son las mismas"
signinWith: "Inicie sesión con {x}" signinWith: "Inicie sesión con {x}"
signinFailed: "Autenticación fallida. Asegúrate de haber usado el nombre de usuario y contraseña correctos." signinFailed: "Autenticación fallida. Asegúrate de haber usado el nombre de usuario\
\ y contraseña correctos."
tapSecurityKey: "Toque la clave de seguridad" tapSecurityKey: "Toque la clave de seguridad"
or: "O" or: "O"
language: "Idioma" language: "Idioma"
@ -453,7 +484,8 @@ aboutX: "Acerca de {x}"
useOsNativeEmojis: "Usa los emojis nativos de la plataforma" useOsNativeEmojis: "Usa los emojis nativos de la plataforma"
disableDrawer: "No mostrar los menús en cajones" disableDrawer: "No mostrar los menús en cajones"
youHaveNoGroups: "Sin grupos" youHaveNoGroups: "Sin grupos"
joinOrCreateGroup: "Obtenga una invitación para unirse al grupos o puede crear su propio grupo." joinOrCreateGroup: "Obtenga una invitación para unirse al grupos o puede crear su\
\ propio grupo."
noHistory: "No hay datos en el historial" noHistory: "No hay datos en el historial"
signinHistory: "Historial de ingresos" signinHistory: "Historial de ingresos"
disableAnimatedMfm: "Deshabilitar MFM que tiene animaciones" disableAnimatedMfm: "Deshabilitar MFM que tiene animaciones"
@ -484,19 +516,28 @@ showFeaturedNotesInTimeline: "Mostrar notas destacadas en la línea de tiempo"
objectStorage: "Almacenamiento de objetos" objectStorage: "Almacenamiento de objetos"
useObjectStorage: "Usar almacenamiento de objetos" useObjectStorage: "Usar almacenamiento de objetos"
objectStorageBaseUrl: "Base URL" objectStorageBaseUrl: "Base URL"
objectStorageBaseUrlDesc: "Prefijo de URL utilizado para construir URL para hacer referencia a objetos (medios). Especifique su URL si está utilizando un CDN o Proxy; de lo contrario, especifique la dirección a la que se puede acceder públicamente de acuerdo con la guía de servicio que va a utilizar. i.g 'https://<bucket>.s3.amazonaws.com' para AWS S3 y 'https://storage.googleapis.com/<bucket>' para GCS." objectStorageBaseUrlDesc: "Prefijo de URL utilizado para construir URL para hacer\
\ referencia a objetos (medios). Especifique su URL si está utilizando un CDN o\
\ Proxy; de lo contrario, especifique la dirección a la que se puede acceder públicamente\
\ de acuerdo con la guía de servicio que va a utilizar. i.g 'https://<bucket>.s3.amazonaws.com'\
\ para AWS S3 y 'https://storage.googleapis.com/<bucket>' para GCS."
objectStorageBucket: "Bucket" objectStorageBucket: "Bucket"
objectStorageBucketDesc: "Especifique el nombre del depósito utilizado en el servicio configurado." objectStorageBucketDesc: "Especifique el nombre del depósito utilizado en el servicio\
\ configurado."
objectStoragePrefix: "Prefix" objectStoragePrefix: "Prefix"
objectStoragePrefixDesc: "Los archivos se almacenarán en el directorio de este prefijo." objectStoragePrefixDesc: "Los archivos se almacenarán en el directorio de este prefijo."
objectStorageEndpoint: "Endpoint" objectStorageEndpoint: "Endpoint"
objectStorageEndpointDesc: "Deje esto en blanco si está utilizando AWS S3; de lo contrario, especifique el punto final como '<host>' o '<host>: <port>' de acuerdo con la guía de servicio que va a utilizar." objectStorageEndpointDesc: "Deje esto en blanco si está utilizando AWS S3; de lo contrario,\
\ especifique el punto final como '<host>' o '<host>: <port>' de acuerdo con la\
\ guía de servicio que va a utilizar."
objectStorageRegion: "Region" objectStorageRegion: "Region"
objectStorageRegionDesc: "Especifique una región como 'xx-east-1'. Si su servicio no tiene distinción sobre regiones, déjelo en blanco o complete con 'us-east-1'." objectStorageRegionDesc: "Especifique una región como 'xx-east-1'. Si su servicio\
\ no tiene distinción sobre regiones, déjelo en blanco o complete con 'us-east-1'."
objectStorageUseSSL: "Usar SSL" objectStorageUseSSL: "Usar SSL"
objectStorageUseSSLDesc: "Desactive esto si no va a usar HTTPS para la conexión API" objectStorageUseSSLDesc: "Desactive esto si no va a usar HTTPS para la conexión API"
objectStorageUseProxy: "Conectarse a través de Proxy" objectStorageUseProxy: "Conectarse a través de Proxy"
objectStorageUseProxyDesc: "Desactive esto si no va a usar Proxy para la conexión de Almacenamiento de objetos" objectStorageUseProxyDesc: "Desactive esto si no va a usar Proxy para la conexión\
\ de Almacenamiento de objetos"
objectStorageSetPublicRead: "Seleccionar \"public-read\" al subir " objectStorageSetPublicRead: "Seleccionar \"public-read\" al subir "
serverLogs: "Registros del servidor" serverLogs: "Registros del servidor"
deleteAll: "Eliminar todos" deleteAll: "Eliminar todos"
@ -524,7 +565,8 @@ sort: "Ordenar"
ascendingOrder: "Ascendente" ascendingOrder: "Ascendente"
descendingOrder: "Descendente" descendingOrder: "Descendente"
scratchpad: "Scratch pad" scratchpad: "Scratch pad"
scratchpadDescription: "Scratchpad proporciona un entorno experimental para AiScript. Puede escribir, ejecutar y verificar los resultados que interactúan con Misskey." scratchpadDescription: "Scratchpad proporciona un entorno experimental para AiScript.\
\ Puede escribir, ejecutar y verificar los resultados que interactúan con Calckey."
output: "Salida" output: "Salida"
script: "Script" script: "Script"
disablePagesScript: "Deshabilitar AiScript en Páginas" disablePagesScript: "Deshabilitar AiScript en Páginas"
@ -532,11 +574,14 @@ updateRemoteUser: "Actualizar información de usuario remoto"
deleteAllFiles: "Borrar todos los archivos" deleteAllFiles: "Borrar todos los archivos"
deleteAllFilesConfirm: "¿Desea borrar todos los archivos?" deleteAllFilesConfirm: "¿Desea borrar todos los archivos?"
removeAllFollowing: "Retener todos los siguientes" removeAllFollowing: "Retener todos los siguientes"
removeAllFollowingDescription: "Cancelar todos los siguientes del servidor {host}. Ejecutar en caso de que esta instancia haya dejado de existir" removeAllFollowingDescription: "Cancelar todos los siguientes del servidor {host}.\
\ Ejecutar en caso de que esta instancia haya dejado de existir"
userSuspended: "Este usuario ha sido suspendido." userSuspended: "Este usuario ha sido suspendido."
userSilenced: "Este usuario ha sido silenciado." userSilenced: "Este usuario ha sido silenciado."
yourAccountSuspendedTitle: "Esta cuenta ha sido suspendida" yourAccountSuspendedTitle: "Esta cuenta ha sido suspendida"
yourAccountSuspendedDescription: "Esta cuenta ha sido suspendida debido a violaciones de los términos de servicio del servidor y otras razones. Para más información, póngase en contacto con el administrador. Por favor, no cree una nueva cuenta." yourAccountSuspendedDescription: "Esta cuenta ha sido suspendida debido a violaciones\
\ de los términos de servicio del servidor y otras razones. Para más información,\
\ póngase en contacto con el administrador. Por favor, no cree una nueva cuenta."
menu: "Menú" menu: "Menú"
divider: "Divisor" divider: "Divisor"
addItem: "Agregar elemento" addItem: "Agregar elemento"
@ -590,13 +635,15 @@ smtpHost: "Host"
smtpPort: "Puerto" smtpPort: "Puerto"
smtpUser: "Nombre de usuario" smtpUser: "Nombre de usuario"
smtpPass: "Contraseña" smtpPass: "Contraseña"
emptyToDisableSmtpAuth: "Deje el nombre del usuario y la contraseña en blanco para deshabilitar la autenticación SMTP" emptyToDisableSmtpAuth: "Deje el nombre del usuario y la contraseña en blanco para\
\ deshabilitar la autenticación SMTP"
smtpSecure: "Usar SSL/TLS implícito en la conexión SMTP" smtpSecure: "Usar SSL/TLS implícito en la conexión SMTP"
smtpSecureInfo: "Apagar cuando se use STARTTLS" smtpSecureInfo: "Apagar cuando se use STARTTLS"
testEmail: "Prueba de envío" testEmail: "Prueba de envío"
wordMute: "Silenciar palabras" wordMute: "Silenciar palabras"
regexpError: "Error de la expresión regular" regexpError: "Error de la expresión regular"
regexpErrorDescription: "Ocurrió un error en la expresión regular en la linea {line} de las palabras muteadas {tab}" regexpErrorDescription: "Ocurrió un error en la expresión regular en la linea {line}\
\ de las palabras muteadas {tab}"
instanceMute: "Instancias silenciadas" instanceMute: "Instancias silenciadas"
userSaysSomething: "{name} dijo algo" userSaysSomething: "{name} dijo algo"
makeActive: "Activar" makeActive: "Activar"
@ -612,10 +659,13 @@ create: "Crear"
notificationSetting: "Ajustes de Notificaciones" notificationSetting: "Ajustes de Notificaciones"
notificationSettingDesc: "Por favor elija el tipo de notificación a mostrar" notificationSettingDesc: "Por favor elija el tipo de notificación a mostrar"
useGlobalSetting: "Usar ajustes globales" useGlobalSetting: "Usar ajustes globales"
useGlobalSettingDesc: "Al activarse, se usará la configuración de notificaciones de la cuenta, al desactivarse se pueden hacer configuraciones particulares." useGlobalSettingDesc: "Al activarse, se usará la configuración de notificaciones de\
\ la cuenta, al desactivarse se pueden hacer configuraciones particulares."
other: "Otro" other: "Otro"
regenerateLoginToken: "Regenerar token de login" 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." 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." setMultipleBySeparatingWithSpace: "Puedes añadir mas de uno, separado por espacios."
fileIdOrUrl: "Id del archivo o URL" fileIdOrUrl: "Id del archivo o URL"
behavior: "Comportamiento" behavior: "Comportamiento"
@ -623,13 +673,15 @@ sample: "Muestra"
abuseReports: "Reportes" abuseReports: "Reportes"
reportAbuse: "Reportar" reportAbuse: "Reportar"
reportAbuseOf: "Reportar a {name}" reportAbuseOf: "Reportar a {name}"
fillAbuseReportDescription: "Ingrese los detalles del reporte. Si hay una nota en particular, ingrese la URL de esta." fillAbuseReportDescription: "Ingrese los detalles del reporte. Si hay una nota en\
\ particular, ingrese la URL de esta."
abuseReported: "Se ha enviado el reporte. Muchas gracias." abuseReported: "Se ha enviado el reporte. Muchas gracias."
reporter: "Reportador" reporter: "Reportador"
reporteeOrigin: "Reportar a" reporteeOrigin: "Reportar a"
reporterOrigin: "Origen del reporte" reporterOrigin: "Origen del reporte"
forwardReport: "Transferir un informe a una instancia remota" forwardReport: "Transferir un informe a una instancia remota"
forwardReportIsAnonymous: "No puede ver su información de la instancia remota y aparecerá como una cuenta anónima del sistema" forwardReportIsAnonymous: "No puede ver su información de la instancia remota y aparecerá\
\ como una cuenta anónima del sistema"
send: "Enviar" send: "Enviar"
abuseMarkAsResolved: "Marcar reporte como resuelto" abuseMarkAsResolved: "Marcar reporte como resuelto"
openInNewTab: "Abrir en una Nueva Pestaña" openInNewTab: "Abrir en una Nueva Pestaña"
@ -647,9 +699,11 @@ createNew: "Crear"
optional: "Opcional" optional: "Opcional"
createNewClip: "Crear clip nuevo" createNewClip: "Crear clip nuevo"
unclip: "Quitar clip" unclip: "Quitar clip"
confirmToUnclipAlreadyClippedNote: "Esta nota ya está incluida en el clip \"{name}\". ¿Quiere quitar la nota del clip?" confirmToUnclipAlreadyClippedNote: "Esta nota ya está incluida en el clip \"{name}\"\
. ¿Quiere quitar la nota del clip?"
public: "Público" public: "Público"
i18nInfo: "Calckey está siendo traducido a varios idiomas gracias a voluntarios. Se puede colaborar traduciendo en {link}" i18nInfo: "Calckey está siendo traducido a varios idiomas gracias a voluntarios. Se\
\ puede colaborar traduciendo en {link}"
manageAccessTokens: "Administrar tokens de acceso" manageAccessTokens: "Administrar tokens de acceso"
accountInfo: "Información de la Cuenta" accountInfo: "Información de la Cuenta"
notesCount: "Cantidad de notas" notesCount: "Cantidad de notas"
@ -668,12 +722,18 @@ no: "No"
driveFilesCount: "Cantidad de archivos en el drive" driveFilesCount: "Cantidad de archivos en el drive"
driveUsage: "Uso del drive" driveUsage: "Uso del drive"
noCrawle: "Rechazar indexación del crawler" noCrawle: "Rechazar indexación del crawler"
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc." noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas,\
lockedAccountInfo: "A menos que configures la visibilidad de tus notas como \"Sólo seguidores\", tus notas serán visibles para cualquiera, incluso si requieres que los seguidores sean aprobados manualmente." \ páginas, etc."
alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por defecto" lockedAccountInfo: "A menos que configures la visibilidad de tus notas como \"Sólo\
\ seguidores\", tus notas serán visibles para cualquiera, incluso si requieres que\
\ los seguidores sean aprobados manualmente."
alwaysMarkSensitive: "Marcar los medios de comunicación como contenido sensible por\
\ defecto"
loadRawImages: "Cargar las imágenes originales en lugar de mostrar las miniaturas" loadRawImages: "Cargar las imágenes originales en lugar de mostrar las miniaturas"
disableShowingAnimatedImages: "No reproducir imágenes animadas" disableShowingAnimatedImages: "No reproducir imágenes animadas"
verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por favor, acceda al enlace proporcionado en el correo electrónico para completar la configuración." verificationEmailSent: "Se le ha enviado un correo electrónico de confirmación. Por\
\ favor, acceda al enlace proporcionado en el correo electrónico para completar\
\ la configuración."
notSet: "Sin especificar" notSet: "Sin especificar"
emailVerified: "Su dirección de correo electrónico ha sido verificada." emailVerified: "Su dirección de correo electrónico ha sido verificada."
noteFavoritesCount: "Número de notas favoritas" noteFavoritesCount: "Número de notas favoritas"
@ -685,14 +745,16 @@ clips: "Clip"
experimentalFeatures: "Características experimentales" experimentalFeatures: "Características experimentales"
developer: "Desarrolladores" developer: "Desarrolladores"
makeExplorable: "Hacer visible la cuenta en \"Explorar\"" makeExplorable: "Hacer visible la cuenta en \"Explorar\""
makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la sección \"Explorar\"." makeExplorableDescription: "Si desactiva esta opción, su cuenta no aparecerá en la\
\ sección \"Explorar\"."
showGapBetweenNotesInTimeline: "Mostrar un intervalo entre notas en la línea de tiempo" showGapBetweenNotesInTimeline: "Mostrar un intervalo entre notas en la línea de tiempo"
duplicate: "Duplicar" duplicate: "Duplicar"
left: "Izquierda" left: "Izquierda"
center: "Centrar" center: "Centrar"
wide: "Ancho" wide: "Ancho"
narrow: "Estrecho" narrow: "Estrecho"
reloadToApplySetting: "Esta configuración sólo se aplicará después de recargar la página. ¿Recargar ahora?" reloadToApplySetting: "Esta configuración sólo se aplicará después de recargar la\
\ página. ¿Recargar ahora?"
needReloadToApply: "Se requiere un reinicio para la aplicar los cambios" needReloadToApply: "Se requiere un reinicio para la aplicar los cambios"
showTitlebar: "Mostrar la barra de título" showTitlebar: "Mostrar la barra de título"
clearCache: "Limpiar caché" clearCache: "Limpiar caché"
@ -700,7 +762,11 @@ onlineUsersCount: "{n} usuarios en línea"
nUsers: "{n} Usuarios" nUsers: "{n} Usuarios"
nNotes: "{n} Notas" nNotes: "{n} Notas"
sendErrorReports: "Envíar informe de errores" sendErrorReports: "Envíar informe de errores"
sendErrorReportsDescription: "Si habilita esta opción, ayudará a mejorar la calidad de Misskey compartiendo información detallada sobre los errores cuando se produzca un problema.\nEsto incluye información como la versión de su sistema operativo, el tipo de navegador que utiliza, su historial de actividad, etc." sendErrorReportsDescription: "Si habilita esta opción, los detalles de los errores\
\ serán compartidos con Calckey cuando ocurra un problema, lo que ayudará a mejorar\
\ la calidad de Calckey. \nEsto incluye información como la versión del sistema\
\ operativo, el tipo de navegador que está utilizando y su historial en Calckey,\
\ entre otros datos."
myTheme: "Mi Tema" myTheme: "Mi Tema"
backgroundColor: "Fondo" backgroundColor: "Fondo"
accentColor: "Acento" accentColor: "Acento"
@ -728,7 +794,8 @@ receiveAnnouncementFromInstance: "Recibir notificaciones de la instancia"
emailNotification: "Notificaciones por correo electrónico" emailNotification: "Notificaciones por correo electrónico"
publish: "Publicar" publish: "Publicar"
inChannelSearch: "Buscar en el canal" inChannelSearch: "Buscar en el canal"
useReactionPickerForContextMenu: "Haga clic con el botón derecho para abrir el menu de reacciones" useReactionPickerForContextMenu: "Haga clic con el botón derecho para abrir el menu\
\ de reacciones"
typingUsers: "{users} está escribiendo" typingUsers: "{users} está escribiendo"
jumpToSpecifiedDate: "Saltar a una fecha específica" jumpToSpecifiedDate: "Saltar a una fecha específica"
showingPastTimeline: "Mostrar líneas de tiempo antiguas" showingPastTimeline: "Mostrar líneas de tiempo antiguas"
@ -739,14 +806,16 @@ unlikeConfirm: "¿Quitar como favorito?"
fullView: "Vista completa" fullView: "Vista completa"
quitFullView: "quitar vista completa" quitFullView: "quitar vista completa"
addDescription: "Agregar descripción" addDescription: "Agregar descripción"
userPagePinTip: "Puede mantener sus notas visibles aquí seleccionando Pin en el menú de notas individuales" userPagePinTip: "Puede mantener sus notas visibles aquí seleccionando Pin en el menú\
\ de notas individuales"
notSpecifiedMentionWarning: "Algunas menciones no están incluidas en el destino" notSpecifiedMentionWarning: "Algunas menciones no están incluidas en el destino"
info: "Información" info: "Información"
userInfo: "Información del usuario" userInfo: "Información del usuario"
unknown: "Desconocido" unknown: "Desconocido"
onlineStatus: "En línea" onlineStatus: "En línea"
hideOnlineStatus: "mostrarse como desconectado" hideOnlineStatus: "mostrarse como desconectado"
hideOnlineStatusDescription: "Ocultar su estado en línea puede reducir la eficacia de algunas funciones, como la búsqueda" hideOnlineStatusDescription: "Ocultar su estado en línea puede reducir la eficacia\
\ de algunas funciones, como la búsqueda"
online: "En línea" online: "En línea"
active: "Activo" active: "Activo"
offline: "Sin conexión" offline: "Sin conexión"
@ -781,7 +850,8 @@ emailNotConfiguredWarning: "No se ha configurado una dirección de correo electr
ratio: "Proporción" ratio: "Proporción"
previewNoteText: "Mostrar vista preliminar" previewNoteText: "Mostrar vista preliminar"
customCss: "CSS personalizado" customCss: "CSS personalizado"
customCssWarn: "Este ajuste sólo debe utilizarse si se sabe lo que hace. Introducir valores inadecuados puede hacer que el cliente deje de funcionar con normalidad." customCssWarn: "Este ajuste sólo debe utilizarse si se sabe lo que hace. Introducir\
\ valores inadecuados puede hacer que el cliente deje de funcionar con normalidad."
global: "Global" global: "Global"
squareAvatars: "Mostrar iconos cuadrados" squareAvatars: "Mostrar iconos cuadrados"
sent: "Enviar" sent: "Enviar"
@ -791,12 +861,14 @@ hashtags: "Hashtag"
troubleshooting: "Solución de problemas" troubleshooting: "Solución de problemas"
useBlurEffect: "Utilizar efecto de desenfoque en la interfaz de usuario" useBlurEffect: "Utilizar efecto de desenfoque en la interfaz de usuario"
learnMore: "Ver más" learnMore: "Ver más"
misskeyUpdated: Misskey ha sido actualizado!" misskeyUpdated: Calckey ha sido actualizado!"
whatIsNew: "Mostrar cambios" whatIsNew: "Mostrar cambios"
translate: "Traducir" translate: "Traducir"
translatedFrom: "Traducido de {x}" translatedFrom: "Traducido de {x}"
accountDeletionInProgress: "La eliminación de la cuenta está en curso" accountDeletionInProgress: "La eliminación de la cuenta está en curso"
usernameInfo: "Un nombre que identifique su cuenta de otras en este servidor. Puede utilizar el alfabeto (a~z, A~Z), dígitos (0~9) o guiones bajos (_). Los nombres de usuario no se pueden cambiar posteriormente." usernameInfo: "Un nombre que identifique su cuenta de otras en este servidor. Puede\
\ utilizar el alfabeto (a~z, A~Z), dígitos (0~9) o guiones bajos (_). Los nombres\
\ de usuario no se pueden cambiar posteriormente."
aiChanMode: "Modo Ai" aiChanMode: "Modo Ai"
keepCw: "Mantener la advertencia de contenido" keepCw: "Mantener la advertencia de contenido"
pubSub: "Cuentas Pub/Sub" pubSub: "Cuentas Pub/Sub"
@ -806,18 +878,21 @@ unresolved: "Sin resolver"
breakFollow: "Dejar de seguir" breakFollow: "Dejar de seguir"
itsOn: "¡Está encendido!" itsOn: "¡Está encendido!"
itsOff: "¡Está apagado!" itsOff: "¡Está apagado!"
emailRequiredForSignup: "Se requere una dirección de correo electrónico para el registro de la cuenta" emailRequiredForSignup: "Se requere una dirección de correo electrónico para el registro\
\ de la cuenta"
unread: "No leído" unread: "No leído"
filter: "Filtro" filter: "Filtro"
controlPanel: "Panel de control" controlPanel: "Panel de control"
manageAccounts: "Administrar cuenta" manageAccounts: "Administrar cuenta"
makeReactionsPublic: "Hacer el historial de reacciones público" makeReactionsPublic: "Hacer el historial de reacciones público"
makeReactionsPublicDescription: "Todas las reacciones que hayas hecho serán públicamente visibles." makeReactionsPublicDescription: "Todas las reacciones que hayas hecho serán públicamente\
\ visibles."
classic: "Clásico" classic: "Clásico"
muteThread: "Ocultar hilo" muteThread: "Ocultar hilo"
unmuteThread: "Mostrar hilo" unmuteThread: "Mostrar hilo"
ffVisibility: "Visibilidad de seguidores y seguidos" ffVisibility: "Visibilidad de seguidores y seguidos"
ffVisibilityDescription: "Puedes configurar quien puede ver a quienes sigues y quienes te siguen" ffVisibilityDescription: "Puedes configurar quien puede ver a quienes sigues y quienes\
\ te siguen"
continueThread: "Ver la continuación del hilo" continueThread: "Ver la continuación del hilo"
deleteAccountConfirm: "La cuenta será borrada. ¿Está seguro?" deleteAccountConfirm: "La cuenta será borrada. ¿Está seguro?"
incorrectPassword: "La contraseña es incorrecta" incorrectPassword: "La contraseña es incorrecta"
@ -858,14 +933,16 @@ thereIsUnresolvedAbuseReportWarning: "Hay reportes sin resolver"
recommended: "Recomendado" recommended: "Recomendado"
check: "Verificar" check: "Verificar"
driveCapOverrideLabel: "Cambiar la capacidad de la unidad para este usuario" driveCapOverrideLabel: "Cambiar la capacidad de la unidad para este usuario"
driveCapOverrideCaption: "Restablecer la capacidad a su predeterminado ingresando un valor de 0 o menos" driveCapOverrideCaption: "Restablecer la capacidad a su predeterminado ingresando\
\ un valor de 0 o menos"
requireAdminForView: "Necesitas iniciar sesión como administrador para ver esto." requireAdminForView: "Necesitas iniciar sesión como administrador para ver esto."
isSystemAccount: "Cuenta creada y operada automáticamente por el sistema" isSystemAccount: "Cuenta creada y operada automáticamente por el sistema"
typeToConfirm: "Ingrese {x} para confirmar" typeToConfirm: "Ingrese {x} para confirmar"
deleteAccount: "Borrar cuenta" deleteAccount: "Borrar cuenta"
document: "Documento" document: "Documento"
numberOfPageCache: "Cantidad de páginas cacheadas" numberOfPageCache: "Cantidad de páginas cacheadas"
numberOfPageCacheDescription: "Al aumentar el número mejora la conveniencia pero tambien puede aumentar la carga y la memoria a usarse" numberOfPageCacheDescription: "Al aumentar el número mejora la conveniencia pero tambien\
\ puede aumentar la carga y la memoria a usarse"
logoutConfirm: "¿Cerrar sesión?" logoutConfirm: "¿Cerrar sesión?"
lastActiveDate: "Utilizado por última vez el" lastActiveDate: "Utilizado por última vez el"
statusbar: "Barra de estado" statusbar: "Barra de estado"
@ -882,42 +959,59 @@ sensitiveMediaDetection: "Detección de contenido NSFW"
localOnly: "Solo local" localOnly: "Solo local"
remoteOnly: "Sólo remoto" remoteOnly: "Sólo remoto"
failedToUpload: "La subida falló" failedToUpload: "La subida falló"
cannotUploadBecauseInappropriate: "Este archivo no se puede subir debido a que algunas partes han sido detectadas comoNSFW." cannotUploadBecauseInappropriate: "Este archivo no se puede subir debido a que algunas\
cannotUploadBecauseNoFreeSpace: "La subida falló debido a falta de espacio libre en la unidad del usuario." \ partes han sido detectadas comoNSFW."
cannotUploadBecauseNoFreeSpace: "La subida falló debido a falta de espacio libre en\
\ la unidad del usuario."
beta: "Beta" beta: "Beta"
enableAutoSensitive: "Marcar automáticamente contenido NSFW" enableAutoSensitive: "Marcar automáticamente contenido NSFW"
enableAutoSensitiveDescription: "Permite la detección y marcado automático de contenido NSFW usando 'Machine Learning' cuando sea posible. Incluso si esta opción está desactivada, puede ser activado para toda la instancia." enableAutoSensitiveDescription: "Permite la detección y marcado automático de contenido\
activeEmailValidationDescription: "Habilita la validación estricta de direcciones de correo electrónico, lo cual incluye la revisión de direcciones desechables y si se puede comunicar con éstas. Cuando está deshabilitado, sólo el formato de la dirección es validado." \ NSFW usando 'Machine Learning' cuando sea posible. Incluso si esta opción está\
\ desactivada, puede ser activado para toda la instancia."
activeEmailValidationDescription: "Habilita la validación estricta de direcciones\
\ de correo electrónico, lo cual incluye la revisión de direcciones desechables\
\ y si se puede comunicar con éstas. Cuando está deshabilitado, sólo el formato\
\ de la dirección es validado."
navbar: "Barra de navegación" navbar: "Barra de navegación"
shuffle: "Aleatorio" shuffle: "Aleatorio"
account: "Cuentas" account: "Cuentas"
move: "Mover" move: "Mover"
_sensitiveMediaDetection: _sensitiveMediaDetection:
description: "Reduce el esfuerzo de la moderación el el servidor a través del reconocimiento automático de contenido NSFW usando 'Machine Learning'. Esto puede incrementar ligeramente la carga en el servidor." description: "Reduce el esfuerzo de la moderación el el servidor a través del reconocimiento\
\ automático de contenido NSFW usando 'Machine Learning'. Esto puede incrementar\
\ ligeramente la carga en el servidor."
sensitivity: "Sensibilidad de detección" sensitivity: "Sensibilidad de detección"
sensitivityDescription: "Reducir la sensibilidad puede acarrear a varios falsos positivos, mientras que incrementarla puede reducir las detecciones (falsos negativos)." sensitivityDescription: "Reducir la sensibilidad puede acarrear a varios falsos\
\ positivos, mientras que incrementarla puede reducir las detecciones (falsos\
\ negativos)."
setSensitiveFlagAutomatically: "Marcar como NSFW" setSensitiveFlagAutomatically: "Marcar como NSFW"
setSensitiveFlagAutomaticallyDescription: "Los resultados de la detección interna pueden ser retenidos incluso si la opción está desactivada." setSensitiveFlagAutomaticallyDescription: "Los resultados de la detección interna\
\ pueden ser retenidos incluso si la opción está desactivada."
analyzeVideos: "Habilitar el análisis de videos" analyzeVideos: "Habilitar el análisis de videos"
analyzeVideosDescription: "Analizar videos en adición a las imágenes. Esto puede incrementar ligeramente la carga del servidor." analyzeVideosDescription: "Analizar videos en adición a las imágenes. Esto puede\
\ incrementar ligeramente la carga del servidor."
_emailUnavailable: _emailUnavailable:
used: "Ya fue usado" used: "Ya fue usado"
format: "Formato no válido." format: "El formato de este correo electrónico no es válido"
disposable: "No es un correo reutilizable" disposable: "No se pueden utilizar direcciones de correo electrónico desechables"
mx: "Servidor de correo inválido" mx: "Servidor de correo inválido"
smtp: "Servidor de correo no disponible" smtp: "Servidor de correo no disponible"
_ffVisibility: _ffVisibility:
public: "Publicar" public: "Público"
followers: "Visible solo para seguidores" followers: "Visible solo para seguidores"
private: "Privado" private: "Privado"
_signup: _signup:
almostThere: "Ya falta poco" almostThere: "Ya falta poco"
emailAddressInfo: "Ingrese el correo electrónico que usa. Este no se hará público." emailAddressInfo: "Ingrese el correo electrónico que usa. Este no se hará público."
emailSent: "Se envió un correo de verificación a la dirección {email}. Acceda al link enviado en el correo para completar el ingreso." emailSent: "Se envió un correo de verificación a la dirección {email}. Acceda al\
\ link enviado en el correo para completar el ingreso."
_accountDelete: _accountDelete:
accountDelete: "Eliminar Cuenta" accountDelete: "Eliminar Cuenta"
mayTakeTime: "La eliminación de la cuenta es un proceso que precisa de carga. Puede pasar un tiempo hasta que se complete si es mucho el contenido creado y los archivos subidos." mayTakeTime: "La eliminación de la cuenta es un proceso que precisa de carga. Puede\
sendEmail: "Cuando se termine de borrar la cuenta, se enviará un correo a la dirección usada para el registro." \ pasar un tiempo hasta que se complete si es mucho el contenido creado y los\
\ archivos subidos."
sendEmail: "Cuando se termine de borrar la cuenta, se enviará un correo a la dirección\
\ usada para el registro."
requestAccountDelete: "Pedir la eliminación de la cuenta." requestAccountDelete: "Pedir la eliminación de la cuenta."
started: "El proceso de eliminación ha comenzado." started: "El proceso de eliminación ha comenzado."
inProgress: "La eliminación está en proceso." inProgress: "La eliminación está en proceso."
@ -925,9 +1019,12 @@ _ad:
back: "Deseleccionar" back: "Deseleccionar"
reduceFrequencyOfThisAd: "Mostrar menos este anuncio." reduceFrequencyOfThisAd: "Mostrar menos este anuncio."
_forgotPassword: _forgotPassword:
enterEmail: "Ingrese el correo usado para registrar la cuenta. Se enviará un link para resetear la contraseña." enterEmail: "Ingrese el correo usado para registrar la cuenta. Se enviará un link\
\ para resetear la contraseña."
ifNoEmail: "Si no utilizó un correo para crear la cuenta, contáctese con el administrador." ifNoEmail: "Si no utilizó un correo para crear la cuenta, contáctese con el administrador."
contactAdmin: "Esta instancia no admite el uso de direcciones de correo electrónico, póngase en contacto con el administrador de la instancia para restablecer su contraseña" contactAdmin: "Esta instancia no admite el uso de direcciones de correo electrónico,\
\ póngase en contacto con el administrador de la instancia para restablecer su\
\ contraseña"
_gallery: _gallery:
my: "Mi galería" my: "Mi galería"
liked: "Publicaciones que me gustan" liked: "Publicaciones que me gustan"
@ -950,12 +1047,15 @@ _preferencesBackups:
save: "Guardar cambios" save: "Guardar cambios"
inputName: "Por favor, ingresa un nombre para este respaldo" inputName: "Por favor, ingresa un nombre para este respaldo"
cannotSave: "Fallo al guardar" cannotSave: "Fallo al guardar"
nameAlreadyExists: "Un respaldo llamado \"{name}\" ya existe. Por favor ingresa un nombre diferente" nameAlreadyExists: "Un respaldo llamado \"{name}\" ya existe. Por favor ingresa\
applyConfirm: "¿Realmente quieres aplicar los cambios desde el archivo \"{name}\" a este dispositivo? Las configuraciones existentes serán sobreescritas. " \ un nombre diferente"
applyConfirm: "¿Realmente quieres aplicar los cambios desde el archivo \"{name}\"\
\ a este dispositivo? Las configuraciones existentes serán sobreescritas. "
saveConfirm: "¿Guardar respaldo como \"{name}\"?" saveConfirm: "¿Guardar respaldo como \"{name}\"?"
deleteConfirm: "¿Borrar el respaldo \"{name}\"?" deleteConfirm: "¿Borrar el respaldo \"{name}\"?"
renameConfirm: "¿Renombrar este respaldo de \"{old}\" a \"{new}\"?" renameConfirm: "¿Renombrar este respaldo de \"{old}\" a \"{new}\"?"
noBackups: "No existen respaldos. Deberás respaldar las configuraciones del cliente en este servidor usando \"Crear nuevo respaldo\"" noBackups: "No existen respaldos. Deberás respaldar las configuraciones del cliente\
\ en este servidor usando \"Crear nuevo respaldo\""
createdAt: "Creado: {date} {time}" createdAt: "Creado: {date} {time}"
updatedAt: "Actualizado: {date} {time}" updatedAt: "Actualizado: {date} {time}"
cannotLoad: "La carga falló" cannotLoad: "La carga falló"
@ -967,24 +1067,29 @@ _registry:
domain: "Dominio" domain: "Dominio"
createKey: "Crear una llave" createKey: "Crear una llave"
_aboutMisskey: _aboutMisskey:
about: "Misskey es un software de código abierto, desarrollado por syuilo desde el 2014" about: "Calckey es una bifurcación de Misskey creada por ThatOneCalculator, que\
\ ha estado en desarrollo desde el 2022."
contributors: "Principales colaboradores" contributors: "Principales colaboradores"
allContributors: "Todos los colaboradores" allContributors: "Todos los colaboradores"
source: "Código fuente" source: "Código fuente"
translation: "Traducir Misskey" translation: "Traducir Calckey"
donate: "Donar a Misskey" donate: "Donar a Calckey"
morePatrons: "Muchas más personas nos apoyan. Muchas gracias🥰" morePatrons: "También apreciamos el apoyo de muchos más que no están enlistados\
patrons: "Patrocinadores" \ aquí. ¡Gracias! \U0001F970"
patrons: "Mecenas de Calckey"
_nsfw: _nsfw:
respect: "Ocultar medios NSFW" respect: "Ocultar medios NSFW"
ignore: "No esconder medios NSFW " ignore: "No esconder medios NSFW "
force: "Ocultar todos los medios" force: "Ocultar todos los medios"
_mfm: _mfm:
cheatSheet: "Hoja de referencia de MFM" cheatSheet: "Hoja de referencia de MFM"
intro: "MFM es un lenguaje de marcado dedicado que se puede usar en varios lugares dentro de Misskey. Aquí puede ver una lista de sintaxis disponibles en MFM." intro: "MFM es un lenguaje de marcado dedicado que se puede usar en varios lugares\
dummy: "Misskey expande el mundo de la Fediverso" \ dentro de Misskey, Calckey, Akkoma, y mucho más. Aquí puede ver una lista de\
\ sintaxis disponibles en MFM."
dummy: "Calckey expande el mundo de la Fediverso"
mention: "Menciones" mention: "Menciones"
mentionDescription: "El signo @ seguido de un nombre de usuario se puede utilizar para notificar a un usuario en particular." mentionDescription: "El signo @ seguido de un nombre de usuario se puede utilizar\
\ para notificar a un usuario en particular."
hashtag: "Hashtag" hashtag: "Hashtag"
hashtagDescription: "Puede especificar un hashtag con un numeral y el texto." hashtagDescription: "Puede especificar un hashtag con un numeral y el texto."
url: "URL" url: "URL"
@ -1000,7 +1105,8 @@ _mfm:
inlineCode: "Código (insertado)" inlineCode: "Código (insertado)"
inlineCodeDescription: "Muestra el código de un programa resaltando su sintaxis" inlineCodeDescription: "Muestra el código de un programa resaltando su sintaxis"
blockCode: "Código (bloque)" blockCode: "Código (bloque)"
blockCodeDescription: "Código de resaltado de sintaxis, como programas de varias líneas con bloques." blockCodeDescription: "Código de resaltado de sintaxis, como programas de varias\
\ líneas con bloques."
inlineMath: "Fórmula (insertado)" inlineMath: "Fórmula (insertado)"
inlineMathDescription: "Muestra fórmulas (KaTeX) insertadas" inlineMathDescription: "Muestra fórmulas (KaTeX) insertadas"
blockMath: "Fórmula (bloque)" blockMath: "Fórmula (bloque)"
@ -1012,7 +1118,8 @@ _mfm:
search: "Buscar" search: "Buscar"
searchDescription: "Muestra una caja de búsqueda con texto pre-escrito" searchDescription: "Muestra una caja de búsqueda con texto pre-escrito"
flip: "Echar de un capirotazo" flip: "Echar de un capirotazo"
flipDescription: "Voltea el contenido hacia arriba / abajo o hacia la izquierda / derecha." flipDescription: "Voltea el contenido hacia arriba / abajo o hacia la izquierda\
\ / derecha."
jelly: "Animación (gelatina)" jelly: "Animación (gelatina)"
jellyDescription: "Aplica un efecto de animación tipo gelatina" jellyDescription: "Aplica un efecto de animación tipo gelatina"
tada: "Animación (tadá)" tada: "Animación (tadá)"
@ -1034,7 +1141,8 @@ _mfm:
x4: "Totalmente grande" x4: "Totalmente grande"
x4Description: "Muestra el contenido totalmente grande" x4Description: "Muestra el contenido totalmente grande"
blur: "Desenfoque" blur: "Desenfoque"
blurDescription: "Para desenfocar el contenido. Se muestra claramente al colocar el puntero encima." blurDescription: "Para desenfocar el contenido. Se muestra claramente al colocar\
\ el puntero encima."
font: "Fuente" font: "Fuente"
fontDescription: "Elegir la fuente del contenido" fontDescription: "Elegir la fuente del contenido"
rainbow: "Arcoíris" rainbow: "Arcoíris"
@ -1044,7 +1152,8 @@ _mfm:
rotate: "Rotar" rotate: "Rotar"
rotateDescription: "Rota el contenido a un ángulo especificado." rotateDescription: "Rota el contenido a un ángulo especificado."
plain: "Plano" plain: "Plano"
plainDescription: "Desactiva los efectos de todo el contenido MFM con este efecto MFM." plainDescription: "Desactiva los efectos de todo el contenido MFM con este efecto\
\ MFM."
_instanceTicker: _instanceTicker:
none: "No mostrar" none: "No mostrar"
remote: "Mostrar a usuarios remotos" remote: "Mostrar a usuarios remotos"
@ -1053,6 +1162,7 @@ _serverDisconnectedBehavior:
reload: "Recargar automáticamente" reload: "Recargar automáticamente"
dialog: "Mostrar diálogo de advertencia" dialog: "Mostrar diálogo de advertencia"
quiet: "Advertencia discreta" quiet: "Advertencia discreta"
nothing: Hacer nada
_channel: _channel:
create: "Crear canal" create: "Crear canal"
edit: "Editar canal" edit: "Editar canal"
@ -1070,15 +1180,20 @@ _menuDisplay:
hide: "Ocultar" hide: "Ocultar"
_wordMute: _wordMute:
muteWords: "Palabras que silenciar" muteWords: "Palabras que silenciar"
muteWordsDescription: "Separar con espacios indica una declaracion And, separar con lineas nuevas indica una declaracion Or。" muteWordsDescription: "Separar con espacios indica una declaracion And, separar\
muteWordsDescription2: "Encerrar las palabras clave entre numerales para usar expresiones regulares" \ con lineas nuevas indica una declaracion Or。"
muteWordsDescription2: "Encerrar las palabras clave entre numerales para usar expresiones\
\ regulares"
softDescription: "Ocultar en la linea de tiempo las notas que cumplen las condiciones" softDescription: "Ocultar en la linea de tiempo las notas que cumplen las condiciones"
hardDescription: "Evitar que se agreguen a la linea de tiempo las notas que cumplen las condiciones. Las notas no agregadas seguirán quitadas aunque cambien las condiciones." hardDescription: "Evitar que se agreguen a la linea de tiempo las notas que cumplen\
\ las condiciones. Las notas no agregadas seguirán quitadas aunque cambien las\
\ condiciones."
soft: "Suave" soft: "Suave"
hard: "Duro" hard: "Duro"
mutedNotes: "Notas silenciadas" mutedNotes: "Notas silenciadas"
_instanceMute: _instanceMute:
instanceMuteDescription: "Silencia todas las notas y reposts de la instancias seleccionadas, incluyendo respuestas a los usuarios de las mismas" instanceMuteDescription: "Silencia todas las notas y reposts de la instancias seleccionadas,\
\ incluyendo respuestas a los usuarios de las mismas"
instanceMuteDescription2: "Separar por líneas" instanceMuteDescription2: "Separar por líneas"
title: "Oculta las notas de las instancias listadas." title: "Oculta las notas de las instancias listadas."
heading: "Instancias a silenciar" heading: "Instancias a silenciar"
@ -1184,32 +1299,47 @@ _tutorial:
step1_1: "¡Bienvenido!" step1_1: "¡Bienvenido!"
step1_2: "Vamos a configurarte. Estarás listo y funcionando en poco tiempo" step1_2: "Vamos a configurarte. Estarás listo y funcionando en poco tiempo"
step2_1: "En primer lugar, rellena tu perfil" step2_1: "En primer lugar, rellena tu perfil"
step2_2: "Proporcionar algo de información sobre quién eres hará que sea más fácil para los demás saber si quieren ver tus notas o seguirte." step2_2: "Proporcionar algo de información sobre quién eres hará que sea más fácil\
\ para los demás saber si quieren ver tus notas o seguirte."
step3_1: "¡Ahora es el momento de seguir a algunas personas!" step3_1: "¡Ahora es el momento de seguir a algunas personas!"
step3_2: "Tu página de inicio y tus líneas de tiempo sociales se basan en quién sigues, así que intenta seguir un par de cuentas para empezar.\nHaz clic en el círculo más en la parte superior derecha de un perfil para seguirlos." step3_2: "Tu página de inicio y tus líneas de tiempo sociales se basan en quién\
\ sigues, así que intenta seguir un par de cuentas para empezar.\nHaz clic en\
\ el círculo más en la parte superior derecha de un perfil para seguirlos."
step4_1: "Vamos a salir a la calle" step4_1: "Vamos a salir a la calle"
step4_2: "Para tu primer post, a algunas personas les gusta hacer un post de {introduction} o un simple \"¡Hola mundo!\"" step4_2: "Para tu primer post, a algunas personas les gusta hacer un post de {introduction}\
\ o un simple \"¡Hola mundo!\""
step5_1: "¡Líneas de tiempo, líneas de tiempo por todas partes!" step5_1: "¡Líneas de tiempo, líneas de tiempo por todas partes!"
step5_2: "Su instancia tiene {timelines} diferentes líneas de tiempo habilitadas" step5_2: "Su instancia tiene {timelines} diferentes líneas de tiempo habilitadas"
step5_3: "La línea de tiempo Inicio {icon} es donde puedes ver las publicaciones de tus seguidores." step5_3: "La línea de tiempo Inicio {icon} es donde puedes ver las publicaciones\
step5_4: "La línea de tiempo Local {icon} es donde puedes ver las publicaciones de todos los demás en esta instancia." \ de tus seguidores."
step5_5: "La línea de tiempo {icon} recomendada es donde puedes ver las publicaciones de las instancias que los administradores recomiendan." step5_4: "La línea de tiempo Local {icon} es donde puedes ver las publicaciones\
step5_6: "La línea de tiempo Social {icon} es donde puedes ver las publicaciones de los amigos de tus seguidores." \ de todos los demás en esta instancia."
step5_7: "La línea de tiempo Global {icon} es donde puedes ver las publicaciones de todas las demás instancias conectadas." step5_5: "La línea de tiempo {icon} recomendada es donde puedes ver las publicaciones\
\ de las instancias que los administradores recomiendan."
step5_6: "La línea de tiempo Social {icon} es donde puedes ver las publicaciones\
\ de los amigos de tus seguidores."
step5_7: "La línea de tiempo Global {icon} es donde puedes ver las publicaciones\
\ de todas las demás instancias conectadas."
step6_1: "Entonces, ¿qué es este lugar?" step6_1: "Entonces, ¿qué es este lugar?"
step6_2: "Bueno, no sólo te has unido a Calckey. Te has unido a un portal del Fediverso, una red interconectada de miles de servidores, llamada \"instancias\"" step6_2: "Bueno, no sólo te has unido a Calckey. Te has unido a un portal del Fediverso,\
step6_3: "Cada servidor funciona de forma diferente, y no todos los servidores ejecutan Calckey. Sin embargo, ¡éste lo hace! Es un poco complicado, pero le cogerás el tranquillo enseguida" \ una red interconectada de miles de servidores, llamada \"instancias\""
step6_3: "Cada servidor funciona de forma diferente, y no todos los servidores ejecutan\
\ Calckey. Sin embargo, ¡éste lo hace! Es un poco complicado, pero le cogerás\
\ el tranquillo enseguida"
step6_4: "¡Ahora ve, explora y diviértete!" step6_4: "¡Ahora ve, explora y diviértete!"
_2fa: _2fa:
alreadyRegistered: "Ya has completado la configuración." alreadyRegistered: "Ya has completado la configuración."
registerDevice: "Registrar dispositivo" registerDevice: "Registrar dispositivo"
registerKey: "Registrar clave" registerKey: "Registrar clave"
step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o {b} u otra." step1: "Primero, instale en su dispositivo la aplicación de autenticación {a} o\
\ {b} u otra."
step2: "Luego, escanee con la aplicación el código QR mostrado en pantalla." step2: "Luego, escanee con la aplicación el código QR mostrado en pantalla."
step2Url: "En una aplicación de escritorio se puede ingresar la siguiente URL:" step2Url: "En una aplicación de escritorio se puede ingresar la siguiente URL:"
step3: "Para terminar, ingrese el token mostrado en la aplicación." step3: "Para terminar, ingrese el token mostrado en la aplicación."
step4: "Ahora cuando inicie sesión, ingrese el mismo token" step4: "Ahora cuando inicie sesión, ingrese el mismo token"
securityKeyInfo: "Se puede configurar el inicio de sesión usando una clave de seguridad de hardware que soporte FIDO2 o con un certificado de huella digital o con un PIN" securityKeyInfo: "Se puede configurar el inicio de sesión usando una clave de seguridad\
\ de hardware que soporte FIDO2 o con un certificado de huella digital o con un\
\ PIN"
_permissions: _permissions:
"read:account": "Ver información de la cuenta" "read:account": "Ver información de la cuenta"
"write:account": "Editar información de la cuenta" "write:account": "Editar información de la cuenta"
@ -1245,7 +1375,8 @@ _permissions:
"write:gallery-likes": "Editar favoritos de la galería" "write:gallery-likes": "Editar favoritos de la galería"
_auth: _auth:
shareAccess: "¿Desea permitir el acceso a la cuenta \"{name}\"?" shareAccess: "¿Desea permitir el acceso a la cuenta \"{name}\"?"
shareAccessAsk: "¿Está seguro de que desea autorizar esta aplicación para acceder a su cuenta?" shareAccessAsk: "¿Está seguro de que desea autorizar esta aplicación para acceder\
\ a su cuenta?"
permissionAsk: "Esta aplicación requiere los siguientes permisos" permissionAsk: "Esta aplicación requiere los siguientes permisos"
pleaseGoBack: "Por favor, vuelve a la aplicación" pleaseGoBack: "Por favor, vuelve a la aplicación"
callback: "Volviendo a la aplicación" callback: "Volviendo a la aplicación"
@ -1287,6 +1418,9 @@ _widgets:
serverMetric: "Estadísticas del servidor" serverMetric: "Estadísticas del servidor"
aiscript: "Consola de AiScript" aiscript: "Consola de AiScript"
aichan: "indigo" aichan: "indigo"
userList: Lista Usuarios
_userList:
chooseList: Seleccione una lista
_cw: _cw:
hide: "Ocultar" hide: "Ocultar"
show: "Ver más" show: "Ver más"
@ -1348,6 +1482,8 @@ _profile:
metadataContent: "Contenido" metadataContent: "Contenido"
changeAvatar: "Cambiar avatar" changeAvatar: "Cambiar avatar"
changeBanner: "Cambiar banner" changeBanner: "Cambiar banner"
locationDescription: Si ingresas tu ciudad primero, el tiempo local tuyo será visible
para otros usuarios.
_exportOrImport: _exportOrImport:
allNotes: "Todas las notas" allNotes: "Todas las notas"
followingList: "Siguiendo" followingList: "Siguiendo"
@ -1387,6 +1523,7 @@ _timelines:
local: "Local" local: "Local"
social: "Social" social: "Social"
global: "Global" global: "Global"
recommended: Recomendado
_pages: _pages:
newPage: "Crear página" newPage: "Crear página"
editPage: "Editar página" editPage: "Editar página"
@ -1633,7 +1770,8 @@ _pages:
_seedRandomPick: _seedRandomPick:
arg1: "Semilla" arg1: "Semilla"
arg2: "Listas" arg2: "Listas"
DRPWPM: "Elegir aleatoriamente de la lista ponderada (Diariamente para cada usuario)" DRPWPM: "Elegir aleatoriamente de la lista ponderada (Diariamente para cada\
\ usuario)"
_DRPWPM: _DRPWPM:
arg1: "Lista de texto" arg1: "Lista de texto"
pick: "Elegir de la lista" pick: "Elegir de la lista"
@ -1664,7 +1802,8 @@ _pages:
_for: _for:
arg1: "Cantidad de repeticiones" arg1: "Cantidad de repeticiones"
arg2: "Acción" arg2: "Acción"
typeError: "El slot {slot} acepta el tipo {expect} pero fue ingresado el tipo {actual}" typeError: "El slot {slot} acepta el tipo {expect} pero fue ingresado el tipo\
\ {actual}"
thereIsEmptySlot: "El slot {slot} está vacío" thereIsEmptySlot: "El slot {slot} está vacío"
types: types:
string: "Texto" string: "Texto"
@ -1728,8 +1867,10 @@ _deck:
newProfile: "Nuevo perfil" newProfile: "Nuevo perfil"
deleteProfile: "Eliminar perfil" deleteProfile: "Eliminar perfil"
introduction: "¡Crea la interfaz perfecta para tí organizando las columnas libremente!" introduction: "¡Crea la interfaz perfecta para tí organizando las columnas libremente!"
introduction2: "Presiona en la + de la derecha de la pantalla para añadir nuevas columnas donde quieras." introduction2: "Presiona en la + de la derecha de la pantalla para añadir nuevas\
widgetsIntroduction: "Por favor selecciona \"Editar Widgets\" en el menú columna y agrega un widget." \ columnas donde quieras."
widgetsIntroduction: "Por favor selecciona \"Editar Widgets\" en el menú columna\
\ y agrega un widget."
_columns: _columns:
main: "Principal" main: "Principal"
widgets: "Widgets" widgets: "Widgets"
@ -1739,3 +1880,51 @@ _deck:
list: "Listas" list: "Listas"
mentions: "Menciones" mentions: "Menciones"
direct: "Mensaje directo" direct: "Mensaje directo"
manageGroups: Administrar grupos
replayTutorial: Repetir Tutorial
privateMode: Modo privado
addInstance: Añadir una instancia
renoteMute: Silenciar impulsos
renoteUnmute: Dejar de silenciar impulsos
flagSpeakAsCat: Habla como un gato
selectInstance: Selectiona una instancia
flagSpeakAsCatDescription: Tu publicación se "nyanified" cuando esté en modo gato
allowedInstances: Instancias en la lista blanca
breakFollowConfirm: ¿Estás seguro de que quieres eliminar el seguidor?
subscribePushNotification: Habilitar notificaciones
unsubscribePushNotification: Desactivar notificaciones
pushNotificationAlreadySubscribed: Las notificaciones ya están activados
pushNotificationNotSupported: Su navegador o instancia no admite notificaciones
moveAccount: ¡Mover cuenta!
moveFrom: Mueve a esta cuenta de una cuenta antigua
moveFromLabel: 'La cuenta que estás moviendo de:'
moveAccountDescription: ''
license: Licencia
_apps:
apps: Aplicaciones
crossPlatform: Plataforma Cruzada
mobile: Teléfono móvil
secondClass: Segunda clase
lesskey: ''
firstClass: Primera clase
thirdClass: Tercera clase
theDesk: ''
pwa: Instalar PWA
free: Gratis
paid: Pagado
noThankYou: No gracias
userSaysSomethingReason: '{name} dijo {reason}'
hiddenTags: Etiquetas Ocultas
noInstances: No hay instancias
accountMoved: 'Usuario ha movido a una cuenta nueva:'
caption: Auto Subtítulos
showAds: Mostrar Anuncios
enterSendsMessage: Presione "RETORNO" en los mensajes para enviar el mensaje (para
apagarlo es Ctrl + RETORNO)
recommendedInstances: Instancias Recomendadas
instanceSecurity: Seguridad de la instancia
seperateRenoteQuote: Separar impulsados y Citar botones
_messaging:
groups: Grupos
dms: Privado
pushNotification: Notificaciones

View file

@ -1,7 +1,7 @@
---
_lang_: "日本語" _lang_: "日本語"
headlineMisskey: "ずっと無料でオープンソースの非中央集権型ソーシャルメディアプラットフォーム🚀" headlineMisskey: "ずっと無料でオープンソースの非中央集権型ソーシャルメディアプラットフォーム\U0001F680"
introMisskey: "ようこそCalckeyは、オープンソースの非中央集権型ソーシャルメディアプラットフォームです。\nいま起こっていることを共有したり、あなたについて皆に発信しましょう📡\n「リアクション」機能で、皆の投稿に素早く反応を追加できます👍\n新しい世界を探検しよう🚀" introMisskey: "ようこそCalckeyは、オープンソースの非中央集権型ソーシャルメディアプラットフォームです。\nいま起こっていることを共有したり、あなたについて皆に発信しましょう\U0001F4E1\
\n「リアクション」機能で、皆の投稿に素早く反応を追加できます\U0001F44D\n新しい世界を探検しよう\U0001F680"
monthAndDay: "{month}月 {day}日" monthAndDay: "{month}月 {day}日"
search: "検索" search: "検索"
notifications: "通知" notifications: "通知"
@ -67,7 +67,7 @@ export: "エクスポート"
files: "ファイル" files: "ファイル"
download: "ダウンロード" download: "ダウンロード"
driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを添付した投稿も消えます。" driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを添付した投稿も消えます。"
unfollowConfirm: "{name}のフォローを解除しますか?" unfollowConfirm: "{name}さんのフォローを解除しますか?"
exportRequested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、「ドライブ」に追加されます。" exportRequested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、「ドライブ」に追加されます。"
importRequested: "インポートをリクエストしました。これには時間がかかる場合があります。" importRequested: "インポートをリクエストしました。これには時間がかかる場合があります。"
lists: "リスト" lists: "リスト"
@ -97,9 +97,6 @@ unfollow: "フォロー解除"
followRequestPending: "フォロー許可待ち" followRequestPending: "フォロー許可待ち"
enterEmoji: "絵文字を入力" enterEmoji: "絵文字を入力"
renote: "ブースト" renote: "ブースト"
renoteAsUnlisted: "未収載でブースト"
renoteToFollowers: "フォロワー限定でブースト"
renoteToRecipients: "宛先のユーザーにブースト"
unrenote: "ブースト解除" unrenote: "ブースト解除"
renoted: "ブーストしました。" renoted: "ブーストしました。"
cantRenote: "この投稿はブーストできません。" cantRenote: "この投稿はブーストできません。"
@ -112,6 +109,8 @@ clickToShow: "クリックして表示"
sensitive: "閲覧注意" sensitive: "閲覧注意"
add: "追加" add: "追加"
reaction: "リアクション" reaction: "リアクション"
enableEmojiReactions: "絵文字リアクションを有効にする"
showEmojisInReactionNotifications: "自分の投稿に対するリアクションの通知で絵文字を表示する"
reactionSetting: "ピッカーに表示するリアクション" reactionSetting: "ピッカーに表示するリアクション"
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。" reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。"
rememberNoteVisibility: "公開範囲を記憶する" rememberNoteVisibility: "公開範囲を記憶する"
@ -128,7 +127,7 @@ unblock: "ブロック解除"
suspend: "凍結" suspend: "凍結"
unsuspend: "解凍" unsuspend: "解凍"
blockConfirm: "ブロックしますか?" blockConfirm: "ブロックしますか?"
unblockConfirm: "ブロック解除しますか?" unblockConfirm: "ブロック解除しますか?"
suspendConfirm: "凍結しますか?" suspendConfirm: "凍結しますか?"
unsuspendConfirm: "解凍しますか?" unsuspendConfirm: "解凍しますか?"
selectList: "リストを選択" selectList: "リストを選択"
@ -147,7 +146,7 @@ cacheRemoteFiles: "リモートのファイルをキャッシュする"
cacheRemoteFilesDescription: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクします。サーバーのストレージを節約できますが、サムネイルが生成されないので通信量が増加します。" cacheRemoteFilesDescription: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクします。サーバーのストレージを節約できますが、サムネイルが生成されないので通信量が増加します。"
flagAsBot: "Botとして設定" flagAsBot: "Botとして設定"
flagAsBotDescription: "このアカウントがBotである場合は、この設定をオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Calckeyのシステム上での扱いがBotに合ったものになります。" flagAsBotDescription: "このアカウントがBotである場合は、この設定をオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Calckeyのシステム上での扱いがBotに合ったものになります。"
flagAsCat: "あなたは…猫?😺" flagAsCat: "あなたは…猫?\U0001F63A"
flagAsCatDescription: "このアカウントが猫であることを示す猫モードを有効にするには、このフラグをオンにします。" flagAsCatDescription: "このアカウントが猫であることを示す猫モードを有効にするには、このフラグをオンにします。"
flagSpeakAsCat: "猫語で話す" flagSpeakAsCat: "猫語で話す"
flagSpeakAsCatDescription: "猫モードが有効の場合にオンにすると、あなたの投稿の「な」を「にゃ」に変換します。" flagSpeakAsCatDescription: "猫モードが有効の場合にオンにすると、あなたの投稿の「な」を「にゃ」に変換します。"
@ -383,7 +382,7 @@ withFiles: "ファイル付き"
silence: "サイレンス" silence: "サイレンス"
silenceConfirm: "サイレンスしますか?" silenceConfirm: "サイレンスしますか?"
unsilence: "サイレンス解除" unsilence: "サイレンス解除"
unsilenceConfirm: "サイレンス解除しますか?" unsilenceConfirm: "サイレンス解除しますか?"
popularUsers: "人気のユーザー" popularUsers: "人気のユーザー"
recentlyUpdatedUsers: "最近投稿したユーザー" recentlyUpdatedUsers: "最近投稿したユーザー"
recentlyRegisteredUsers: "最近登録したユーザー" recentlyRegisteredUsers: "最近登録したユーザー"
@ -499,7 +498,8 @@ showFeaturedNotesInTimeline: "タイムラインにおすすめの投稿を表
objectStorage: "オブジェクトストレージ" objectStorage: "オブジェクトストレージ"
useObjectStorage: "オブジェクトストレージを使用" useObjectStorage: "オブジェクトストレージを使用"
objectStorageBaseUrl: "Base URL" objectStorageBaseUrl: "Base URL"
objectStorageBaseUrlDesc: "参照に使用するURL。CDNやProxyを使用している場合はそのURL、S3: 'https://<bucket>.s3.amazonaws.com'、GCS等: 'https://storage.googleapis.com/<bucket>'。" objectStorageBaseUrlDesc: "参照に使用するURL。CDNやProxyを使用している場合はそのURL、S3: 'https://<bucket>.s3.amazonaws.com'、GCS等:\
\ 'https://storage.googleapis.com/<bucket>'。"
objectStorageBucket: "Bucket" objectStorageBucket: "Bucket"
objectStorageBucketDesc: "使用サービスのbucket名を指定してください。" objectStorageBucketDesc: "使用サービスのbucket名を指定してください。"
objectStoragePrefix: "Prefix" objectStoragePrefix: "Prefix"
@ -702,7 +702,7 @@ experimentalFeatures: "実験的機能"
developer: "開発者" developer: "開発者"
makeExplorable: "アカウントを見つけやすくする" makeExplorable: "アカウントを見つけやすくする"
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。" makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。"
showGapBetweenNotesInTimeline: "タイムラインの投稿を離して表示" showGapBetweenNotesInTimeline: "タイムラインの投稿を離して表示する"
duplicate: "複製" duplicate: "複製"
left: "左" left: "左"
center: "中央" center: "中央"
@ -751,7 +751,7 @@ showingPastTimeline: "過去のタイムラインを表示しています"
clear: "クリア" clear: "クリア"
markAllAsRead: "全て既読にする" markAllAsRead: "全て既読にする"
goBack: "戻る" goBack: "戻る"
unlikeConfirm: "いいね解除しますか?" unlikeConfirm: "いいね解除しますか?"
fullView: "フルビュー" fullView: "フルビュー"
quitFullView: "フルビュー解除" quitFullView: "フルビュー解除"
addDescription: "説明を追加" addDescription: "説明を追加"
@ -830,7 +830,7 @@ lastCommunication: "直近の通信"
resolved: "解決済み" resolved: "解決済み"
unresolved: "未解決" unresolved: "未解決"
breakFollow: "フォロワーを解除" breakFollow: "フォロワーを解除"
breakFollowConfirm: "フォロワー除しますか?" breakFollowConfirm: "フォロワーから削除しますか?"
itsOn: "オンになっています" itsOn: "オンになっています"
itsOff: "オフになっています" itsOff: "オフになっています"
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする" emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
@ -913,6 +913,7 @@ remoteOnly: "リモートのみ"
failedToUpload: "アップロード失敗" failedToUpload: "アップロード失敗"
cannotUploadBecauseInappropriate: "不適切な内容を含む可能性があると判定されたためアップロードできません。" cannotUploadBecauseInappropriate: "不適切な内容を含む可能性があると判定されたためアップロードできません。"
cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。" cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。"
cannotUploadBecauseExceedsFileSizeLimit: "ファイルサイズの制限を超えているためアップロードできません。"
beta: "ベータ" beta: "ベータ"
enableAutoSensitive: "自動NSFW判定" enableAutoSensitive: "自動NSFW判定"
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。" enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。"
@ -933,7 +934,8 @@ adminCustomCssWarn: "この設定は、それが何をするものであるか
customMOTD: "カスタムMOTD(スプラッシュスクリーンメッセージ)" customMOTD: "カスタムMOTD(スプラッシュスクリーンメッセージ)"
customMOTDDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたMOTD(スプラッシュスクリーン)用のカスタムメッセージ" customMOTDDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたMOTD(スプラッシュスクリーン)用のカスタムメッセージ"
customSplashIcons: "カスタムスプラッシュスクリーンアイコン" customSplashIcons: "カスタムスプラッシュスクリーンアイコン"
customSplashIconsDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたカスタムスプラッシュスクリーンアイコンの URL。画像は静的なURLで、できればすべて192x192にリサイズしてください。" customSplashIconsDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたカスタムスプラッシュスクリーンアイコンの\
\ URL。画像は静的なURLで、できればすべて192x192にリサイズしてください。"
showUpdates: "Calckeyの更新時にポップアップを表示する" showUpdates: "Calckeyの更新時にポップアップを表示する"
recommendedInstances: "おすすめインスタンス" recommendedInstances: "おすすめインスタンス"
recommendedInstancesDescription: "おすすめタイムラインに表示される、改行で区切られたインスタンス。`https://`を追加しないでください。ドメインのみを追加してください。" recommendedInstancesDescription: "おすすめタイムラインに表示される、改行で区切られたインスタンス。`https://`を追加しないでください。ドメインのみを追加してください。"
@ -952,14 +954,17 @@ moveAccountDescription: "この操作は取り消せません。まずは引っ
moveFrom: "別のアカウントからこのアカウントに引っ越す" moveFrom: "別のアカウントからこのアカウントに引っ越す"
moveFromLabel: "引っ越し元のアカウント:" moveFromLabel: "引っ越し元のアカウント:"
moveFromDescription: "別のアカウントからこのアカウントにフォロワーを引き継いで引っ越したい場合、ここでエイリアスを作成しておく必要があります。必ず引っ越しを実行する前に作成してください!引っ越し元のアカウントをこのように入力してください:@person@instance.com" moveFromDescription: "別のアカウントからこのアカウントにフォロワーを引き継いで引っ越したい場合、ここでエイリアスを作成しておく必要があります。必ず引っ越しを実行する前に作成してください!引っ越し元のアカウントをこのように入力してください:@person@instance.com"
migrationConfirm: "本当にこのアカウントを {account} に引っ越しますか?一度引っ越しを行うと取り消せず、二度とこのアカウントを元の状態で使用できなくなります。\nまた、引っ越し先のアカウントでエイリアスを作成したことを確認してください。" migrationConfirm: "本当にこのアカウントを {account} に引っ越しますか?一度引っ越しを行うと取り消せず、二度とこのアカウントを元の状態で使用できなくなります。\n\
また、引っ越し先のアカウントでエイリアスを作成したことを確認してください。"
defaultReaction: "リモートとローカルの投稿に対するデフォルトの絵文字リアクション" defaultReaction: "リモートとローカルの投稿に対するデフォルトの絵文字リアクション"
license: "ライセンス" license: "ライセンス"
indexPosts: "投稿をインデックス" indexPosts: "投稿をインデックス"
indexFrom: "この投稿ID以降をインデックスする空白で全ての投稿を指定します" indexFrom: "この投稿ID以降をインデックスする空白で全ての投稿を指定します"
indexNotice: "インデックスを開始しました。完了まで時間がかかる場合があるため、少なくとも1時間はサーバーを再起動しないでください。" indexNotice: "インデックスを開始しました。完了まで時間がかかる場合があるため、少なくとも1時間はサーバーを再起動しないでください。"
customKaTeXMacro: "カスタムKaTeXマクロ" customKaTeXMacro: "カスタムKaTeXマクロ"
customKaTeXMacroDescription: "数式入力を楽にするためのマクロを設定しましょう記法はLaTeXにおけるコマンドの定義と同様に \\newcommand{\\name}{content} または \\newcommand{\\add}[2]{#1 + #2} のように記述します。後者の例では \\add{3}{foo} が 3 + foo に展開されます。また、マクロの名前を囲む波括弧を丸括弧 () および角括弧 [] に変更した場合、マクロの引数に使用する括弧が変更されます。マクロの定義は一行に一つのみで、途中で改行はできません。マクロの定義が無効な行は無視されます。文字列を単純に置換する機能のみに対応していて、条件分岐などの高度な構文は使用できません。" customKaTeXMacroDescription: "数式入力を楽にするためのマクロを設定しましょう記法はLaTeXにおけるコマンドの定義と同様に \\newcommand{\\\
name}{content} または \\newcommand{\\add}[2]{#1 + #2} のように記述します。後者の例では \\add{3}{foo}\
\ が 3 + foo に展開されます。また、マクロの名前を囲む波括弧を丸括弧 () および角括弧 [] に変更した場合、マクロの引数に使用する括弧が変更されます。マクロの定義は一行に一つのみで、途中で改行はできません。マクロの定義が無効な行は無視されます。文字列を単純に置換する機能のみに対応していて、条件分岐などの高度な構文は使用できません。"
enableCustomKaTeXMacro: "カスタムKaTeXマクロを有効にする" enableCustomKaTeXMacro: "カスタムKaTeXマクロを有効にする"
_sensitiveMediaDetection: _sensitiveMediaDetection:
@ -1043,7 +1048,7 @@ _aboutMisskey:
source: "ソースコード" source: "ソースコード"
translation: "Calckeyを翻訳" translation: "Calckeyを翻訳"
donate: "Calckeyに寄付" donate: "Calckeyに寄付"
morePatrons: "他にも多くの方が支援してくれています。ありがとうございます! 🥰" morePatrons: "他にも多くの方が支援してくれています。ありがとうございます! \U0001F970"
patrons: "支援者" patrons: "支援者"
_nsfw: _nsfw:
respect: "閲覧注意のメディアは隠す" respect: "閲覧注意のメディアは隠す"
@ -1260,7 +1265,8 @@ _tutorial:
step2_1: "最初に、あなたのプロフィールを作りましょう。" step2_1: "最初に、あなたのプロフィールを作りましょう。"
step2_2: "プロフィールを設定することで、他の人があなたの投稿を見たり、フォローしたりするときの助けになります。" step2_2: "プロフィールを設定することで、他の人があなたの投稿を見たり、フォローしたりするときの助けになります。"
step3_1: "それでは、何人かフォローしてみましょう!" step3_1: "それでは、何人かフォローしてみましょう!"
step3_2: "あなたのホームとソーシャルタイムラインは、あなたが誰をフォローしているかで決まります。まずは、いくつかのアカウントをフォローしてみましょう。\nプロフィールの右上にある丸いボタンをクリックするとフォローできます。" step3_2: "あなたのホームとソーシャルタイムラインは、あなたが誰をフォローしているかで決まります。まずは、いくつかのアカウントをフォローしてみましょう。\n\
プロフィールの右上にある丸い+ボタンをクリックするとフォローできます。"
step4_1: "投稿してみましょう!" step4_1: "投稿してみましょう!"
step4_2: "最初は{introduction}に投稿したり、シンプルに「こんにちは、アカウント作ってみました!」などの投稿をする人もいます。" step4_2: "最初は{introduction}に投稿したり、シンプルに「こんにちは、アカウント作ってみました!」などの投稿をする人もいます。"
step5_1: "タイムライン、タイムラインだらけ!" step5_1: "タイムライン、タイムラインだらけ!"
@ -1426,7 +1432,7 @@ _profile:
metadataContent: "内容" metadataContent: "内容"
changeAvatar: "アバター画像を変更" changeAvatar: "アバター画像を変更"
changeBanner: "バナー画像を変更" changeBanner: "バナー画像を変更"
locationDescription: "正しく入力すると、あなたの現地時間が他のユーザーに表示されます。" locationDescription: "英語表記の都市名から始まる内容を入力すると、現地時間がユーザーページに表示されます。"
_exportOrImport: _exportOrImport:
allNotes: "全ての投稿" allNotes: "全ての投稿"
followingList: "フォロー" followingList: "フォロー"
@ -1806,7 +1812,9 @@ _deck:
popRight: "右に出す" popRight: "右に出す"
profile: "ワークスペース" profile: "ワークスペース"
newProfile: "新規ワークスペース" newProfile: "新規ワークスペース"
renameProfile: "ワークスペース名を変更"
deleteProfile: "ワークスペースを削除" deleteProfile: "ワークスペースを削除"
nameAlreadyExists: "この名前のワークスペースは既に存在します。"
introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!" introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!"
introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。" introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。"
widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください" widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください"
@ -1836,3 +1844,6 @@ _apps:
mona: "Mona" mona: "Mona"
theDesk: "TheDesk" theDesk: "TheDesk"
lesskey: "Lesskey" lesskey: "Lesskey"
noteId: 投稿のID
hiddenTagsDescription: 'トレンドと「みつける」から除外したいハッシュタグを(先頭の # を除いて)改行区切りで入力してください。この設定はトレンドと「みつける」以外には影響しません。'
hiddenTags: 非表示にするハッシュタグ

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -107,6 +107,8 @@ clickToShow: "点击以显示"
sensitive: "敏感内容" sensitive: "敏感内容"
add: "添加" add: "添加"
reaction: "回应" reaction: "回应"
enableEmojiReaction: "启用表情符号回应"
showEmojisInReactionNotifications: "在回应通知中显示表情符号"
reactionSetting: "在选择器中显示的回应" reactionSetting: "在选择器中显示的回应"
reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。" reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。"
rememberNoteVisibility: "保存上次设置的可见性" rememberNoteVisibility: "保存上次设置的可见性"
@ -1731,7 +1733,9 @@ _deck:
popRight: "向右弹出" popRight: "向右弹出"
profile: "配置文件" profile: "配置文件"
newProfile: "新建配置文件" newProfile: "新建配置文件"
renameProfile: "重命名配置文件"
deleteProfile: "删除配置文件" deleteProfile: "删除配置文件"
nameAlreadyExists: "该配置文件名已存在。"
introduction: "将各列进行组合以创建您自己的界面!" introduction: "将各列进行组合以创建您自己的界面!"
introduction2: "您可以随时通过屏幕右侧的 + 来添加列" introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具" widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"

View file

@ -107,6 +107,8 @@ clickToShow: "按一下以顯示"
sensitive: "敏感內容" sensitive: "敏感內容"
add: "新增" add: "新增"
reaction: "情感" reaction: "情感"
enableEmojiReaction: "啟用表情符號反應"
showEmojisInReactionNotifications: "在反應通知中顯示表情符號"
reactionSetting: "在選擇器中顯示反應" reactionSetting: "在選擇器中顯示反應"
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。" reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
rememberNoteVisibility: "記住貼文可見性" rememberNoteVisibility: "記住貼文可見性"
@ -1731,7 +1733,9 @@ _deck:
popRight: "向右彈出" popRight: "向右彈出"
profile: "個人檔案" profile: "個人檔案"
newProfile: "新建個人檔案" newProfile: "新建個人檔案"
renameProfile: "重新命名個人檔案"
deleteProfile: "刪除個人檔案" deleteProfile: "刪除個人檔案"
nameAlreadyExists: "該個人檔案名已經存在。"
introduction: "組合欄位來製作屬於自己的介面吧!" introduction: "組合欄位來製作屬於自己的介面吧!"
introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。" introduction2: "您可以隨時透過按畫面右方的 + 來添加欄位。"
widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具" widgetsIntroduction: "請從欄位的選單中,選擇「編輯小工具」來添加小工具"

View file

@ -1,12 +1,12 @@
{ {
"name": "calckey", "name": "calckey",
"version": "13.2.0-beta6", "version": "13.2.0-beta7",
"codename": "aqua", "codename": "aqua",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://codeberg.org/calckey/calckey.git" "url": "https://codeberg.org/calckey/calckey.git"
}, },
"packageManager": "pnpm@8.2.0", "packageManager": "pnpm@8.3.1",
"private": true, "private": true,
"scripts": { "scripts": {
"rebuild": "pnpm run clean && pnpm -r run build && pnpm run gulp", "rebuild": "pnpm run clean && pnpm -r run build && pnpm run gulp",

View file

@ -26,7 +26,7 @@
"@bull-board/api": "^4.6.4", "@bull-board/api": "^4.6.4",
"@bull-board/koa": "^4.6.4", "@bull-board/koa": "^4.6.4",
"@bull-board/ui": "^4.6.4", "@bull-board/ui": "^4.6.4",
"@calckey/megalodon": "5.1.23", "@calckey/megalodon": "5.1.24",
"@discordapp/twemoji": "14.0.2", "@discordapp/twemoji": "14.0.2",
"@elastic/elasticsearch": "7.17.0", "@elastic/elasticsearch": "7.17.0",
"@koa/cors": "3.4.3", "@koa/cors": "3.4.3",
@ -75,11 +75,9 @@
"koa": "2.13.4", "koa": "2.13.4",
"koa-body": "^6.0.1", "koa-body": "^6.0.1",
"koa-bodyparser": "4.3.0", "koa-bodyparser": "4.3.0",
"koa-favicon": "2.1.0",
"koa-json-body": "5.3.0", "koa-json-body": "5.3.0",
"koa-logger": "3.2.1", "koa-logger": "3.2.1",
"koa-mount": "4.0.0", "koa-mount": "4.0.0",
"koa-remove-trailing-slashes": "2.0.3",
"koa-send": "5.0.1", "koa-send": "5.0.1",
"koa-slow": "2.1.0", "koa-slow": "2.1.0",
"koa-views": "7.0.2", "koa-views": "7.0.2",
@ -117,7 +115,7 @@
"sonic-channel": "^1.3.1", "sonic-channel": "^1.3.1",
"speakeasy": "2.0.0", "speakeasy": "2.0.0",
"stringz": "2.1.0", "stringz": "2.1.0",
"summaly": "2.7.0", "summaly": "github:misskey-dev/summaly",
"syslog-pro": "1.0.0", "syslog-pro": "1.0.0",
"systeminformation": "5.16.9", "systeminformation": "5.16.9",
"tesseract.js": "^3.0.3", "tesseract.js": "^3.0.3",
@ -133,8 +131,8 @@
"xev": "3.0.2" "xev": "3.0.2"
}, },
"devDependencies": { "devDependencies": {
"@swc/cli": "^0.1.59", "@swc/cli": "^0.1.62",
"@swc/core": "^1.3.26", "@swc/core": "^1.3.50",
"@types/bcryptjs": "2.4.2", "@types/bcryptjs": "2.4.2",
"@types/bull": "3.15.9", "@types/bull": "3.15.9",
"@types/cbor": "6.0.0", "@types/cbor": "6.0.0",

View file

@ -29,6 +29,10 @@ export async function createImage(
throw new Error("invalid image: url not privided"); throw new Error("invalid image: url not privided");
} }
if (!image.url.startsWith("https://") && !image.url.startsWith("http://")) {
throw new Error("invalid image: unexpected shcema of url: " + image.url);
}
logger.info(`Creating the Image: ${image.url}`); logger.info(`Creating the Image: ${image.url}`);
const instance = await fetchMeta(); const instance = await fetchMeta();

View file

@ -11,6 +11,7 @@ import { generateRepliesQuery } from "../../common/generate-replies-query.js";
import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js"; import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js";
import { generateChannelQuery } from "../../common/generate-channel-query.js"; import { generateChannelQuery } from "../../common/generate-channel-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js"; import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import { generateMutedUserRenotesQueryForNotes } from "../../common/generated-muted-renote-query.js";
export const meta = { export const meta = {
tags: ["notes"], tags: ["notes"],
@ -99,6 +100,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (user) generateMutedUserQuery(query, user); if (user) generateMutedUserQuery(query, user);
if (user) generateMutedNoteQuery(query, user); if (user) generateMutedNoteQuery(query, user);
if (user) generateBlockedUserQuery(query, user); if (user) generateBlockedUserQuery(query, user);
if (user) generateMutedUserRenotesQueryForNotes(query, user);
if (ps.withFiles) { if (ps.withFiles) {
query.andWhere("note.fileIds != '{}'"); query.andWhere("note.fileIds != '{}'");

View file

@ -37,6 +37,11 @@ export const meta = {
code: "FORBIDDEN", code: "FORBIDDEN",
id: "f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba", id: "f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba",
}, },
cannot_find: {
message: "Cannot find the following.",
code: "CANNOT_FIND",
id: "7a55f0d7-8e06-4a7e-9c77-ee7d59b25a82",
}
}, },
} as const; } as const;
@ -97,7 +102,7 @@ export default define(meta, paramDef, async (ps, me) => {
followerId: me.id, followerId: me.id,
}); });
if (following == null) { if (following == null) {
throw new ApiError(meta.errors.forbidden); throw new ApiError(meta.errors.cannot_find);
} }
} }
} }

View file

@ -62,6 +62,37 @@ export function apiMastodonCompatible(router: Router): void {
} }
}); });
router.get("/v1/announcements", async (ctx) => {
const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
const accessTokens = ctx.request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.getInstanceAnnouncements();
ctx.body = data.data;
} catch (e: any) {
console.error(e);
ctx.status = 401;
ctx.body = e.response.data;
}
});
router.post<{ Params: { id: string } }>(
"/v1/announcements/:id/dismiss",
async (ctx) => {
const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
const accessTokens = ctx.request.headers.authorization;
const client = getClient(BASE_URL, accessTokens);
try {
const data = await client.dismissInstanceAnnouncement(ctx.params.id);
ctx.body = data.data;
} catch (e: any) {
console.error(e);
ctx.status = 401;
ctx.body = e.response.data;
}
},
);
router.get("/v1/filters", async (ctx) => { router.get("/v1/filters", async (ctx) => {
const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
const accessTokens = ctx.request.headers.authorization; const accessTokens = ctx.request.headers.authorization;

View file

@ -69,6 +69,9 @@ export default class extends Channel {
// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する // 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
if (isUserRelated(note, this.blocking)) return; if (isUserRelated(note, this.blocking)) return;
if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
return;
// 流れてきたNoteがミュートすべきNoteだったら無視する // 流れてきたNoteがミュートすべきNoteだったら無視する
// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある) // TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、 // 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、

View file

@ -10,7 +10,6 @@ import Router from "@koa/router";
import mount from "koa-mount"; import mount from "koa-mount";
import koaLogger from "koa-logger"; import koaLogger from "koa-logger";
import * as slow from "koa-slow"; import * as slow from "koa-slow";
import { IsNull } from "typeorm"; import { IsNull } from "typeorm";
import config from "@/config/index.js"; import config from "@/config/index.js";
import Logger from "@/services/logger.js"; import Logger from "@/services/logger.js";
@ -30,7 +29,6 @@ import proxyServer from "./proxy/index.js";
import webServer from "./web/index.js"; import webServer from "./web/index.js";
import { initializeStreamingServer } from "./api/streaming.js"; import { initializeStreamingServer } from "./api/streaming.js";
import { koaBody } from "koa-body"; import { koaBody } from "koa-body";
import removeTrailingSlash from "koa-remove-trailing-slashes";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
export const serverLogger = new Logger("server", "gray", false); export const serverLogger = new Logger("server", "gray", false);
@ -39,7 +37,12 @@ export const serverLogger = new Logger("server", "gray", false);
const app = new Koa(); const app = new Koa();
app.proxy = true; app.proxy = true;
app.use(removeTrailingSlash()); // Replace trailing slashes
app.use(async (ctx, next) => {
if (ctx.request.path !== "/" && ctx.request.path.endsWith("/"))
return ctx.redirect(ctx.request.path.replace(/\/$/, ""));
else await next();
});
if (!["production", "test"].includes(process.env.NODE_ENV || "")) { if (!["production", "test"].includes(process.env.NODE_ENV || "")) {
// Logger // Logger

View file

@ -8,13 +8,11 @@ import { readFileSync } from "node:fs";
import Koa from "koa"; import Koa from "koa";
import Router from "@koa/router"; import Router from "@koa/router";
import send from "koa-send"; import send from "koa-send";
import favicon from "koa-favicon";
import views from "koa-views"; import views from "koa-views";
import sharp from "sharp"; import sharp from "sharp";
import { createBullBoard } from "@bull-board/api"; import { createBullBoard } from "@bull-board/api";
import { BullAdapter } from "@bull-board/api/bullAdapter.js"; import { BullAdapter } from "@bull-board/api/bullAdapter.js";
import { KoaAdapter } from "@bull-board/koa"; import { KoaAdapter } from "@bull-board/koa";
import { In, IsNull } from "typeorm"; import { In, IsNull } from "typeorm";
import { fetchMeta } from "@/misc/fetch-meta.js"; import { fetchMeta } from "@/misc/fetch-meta.js";
import config from "@/config/index.js"; import config from "@/config/index.js";
@ -98,8 +96,14 @@ app.use(
}), }),
); );
// Serve favicon // Favicon Router
app.use(favicon(`${_dirname}/../../../assets/favicon.ico`)); app.use(async (ctx, next) => {
if (ctx.path != "/favicon.ico") return next();
const meta = await fetchMeta();
if (meta.iconUrl === "")
ctx.body = readFileSync(`${_dirname}/../../../assets/favicon.ico`);
else ctx.redirect(meta.iconUrl);
});
// Common request handler // Common request handler
app.use(async (ctx, next) => { app.use(async (ctx, next) => {

View file

@ -39,14 +39,14 @@ export async function sendEmail(
to: to, to: to,
subject: subject, subject: subject,
text: text, text: text,
html: `<!doctype html> html: `<!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>${subject}</title> <title>${subject}</title>
<style> <style>
html { html {
background: #eee; background: #191724;
} }
body { body {
@ -67,17 +67,19 @@ export async function sendEmail(
main { main {
max-width: 500px; max-width: 500px;
margin: 0 auto; margin: 0 auto;
background: #e0def4; background: #1f1d2e;
color: #6e6a86; color: #e0def4;
} }
main > header { main > header {
padding: 32px; padding: 32px;
background: #31748f; background: #31748f;
display: flex;
} }
main > header > img { main > header > img {
max-width: 128px; max-width: 128px;
max-height: 28px; max-height: 72px;
vertical-align: bottom; vertical-align: bottom;
margin-right: 16px;
} }
main > article { main > article {
padding: 32px; padding: 32px;
@ -87,7 +89,7 @@ export async function sendEmail(
} }
main > footer { main > footer {
padding: 32px; padding: 32px;
border-top: solid 1px #eee; border-top: solid 1px #26233a;
} }
nav { nav {
@ -97,14 +99,15 @@ export async function sendEmail(
padding: 0 32px; padding: 0 32px;
} }
nav > a { nav > a {
color: #888; color: #6e6a86;
} }
</style> </style>
</head> </head>
<body> <body>
<main> <main>
<header> <header>
<img src="${meta.logoImageUrl || meta.iconUrl || iconUrl}"/> <img src="${meta.logoImageUrl || meta.iconUrl || iconUrl}" height="100"/>
<h1>${meta.name}</h1>
</header> </header>
<article> <article>
<h1>${subject}</h1> <h1>${subject}</h1>

View file

@ -1,7 +1,13 @@
<template> <template>
<button class="nrvgflfu _button" @click.stop="toggle"> <button
<b>{{ modelValue ? i18n.ts._cw.hide : i18n.ts._cw.show }}</b> class="_button"
<span v-if="!modelValue">{{ label }}</span> :class="{ showLess: modelValue, fade: !modelValue }"
@click.stop="toggle"
>
<span
>{{ modelValue ? i18n.ts._cw.hide : i18n.ts._cw.show }}
<span v-if="!modelValue">{{ label }}</span>
</span>
</button> </button>
</template> </template>
@ -30,7 +36,8 @@ const label = computed(() => {
? [i18n.t("_cw.files", { count: props.note.files.length })] ? [i18n.t("_cw.files", { count: props.note.files.length })]
: [], : [],
props.note.poll != null ? [i18n.ts.poll] : [], props.note.poll != null ? [i18n.ts.poll] : [],
] as string[][]).join(" / "); props.note.renote != null ? [i18n.ts.quoteAttached] : [],
] as string[][]).join(", ");
}); });
const toggle = () => { const toggle = () => {
@ -39,37 +46,25 @@ const toggle = () => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.nrvgflfu { ._button {
position: relative; font-weight: 700;
z-index: 2;
display: inline-block;
padding: 4px 8px;
font-size: 0.8em;
color: var(--cwFg);
background: var(--cwBg);
padding: 6px 10px;
width: 90%;
border-radius: 10px;
border: 1px solid var(--divider);
margin-top: 10px;
margin-bottom: 10px;
transition: background-color 0.25s ease-in-out;
&:hover {
background: var(--cwFg);
color: var(--cwBg);
}
> span { > span {
margin-left: 4px; background: var(--cwBg) !important;
color: var(--cwFg);
&:before { transition: background 0.2s, color 0.2s;
content: "("; > span {
} font-weight: 500;
&::before {
&:after { content: "(";
content: ")"; }
&::after {
content: ")";
}
} }
} }
&:hover > span {
background: var(--cwFg) !important;
color: var(--cwBg) !important;
}
} }
</style> </style>

View file

@ -39,7 +39,8 @@ const search = () => {
font-size: 16px; font-size: 16px;
border: solid 1px var(--divider); border: solid 1px var(--divider);
border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px;
-webkit-appearance: textfield; -webkit-appearance: none;
-webkit-border-radius: 4px 0 0 4px;
} }
> button { > button {

View file

@ -1,5 +1,10 @@
<template> <template>
<div class="hpaizdrt" ref="ticker" :style="bg"> <div
class="hpaizdrt"
v-tooltip="capitalize(instance.softwareName)"
ref="ticker"
:style="bg"
>
<img class="icon" :src="getInstanceIcon(instance)" aria-hidden="true" /> <img class="icon" :src="getInstanceIcon(instance)" aria-hidden="true" />
<span class="name">{{ instance.name }}</span> <span class="name">{{ instance.name }}</span>
</div> </div>
@ -15,6 +20,7 @@ const props = defineProps<{
faviconUrl?: string; faviconUrl?: string;
name: string; name: string;
themeColor?: string; themeColor?: string;
softwareName?: string;
}; };
}>(); }>();
@ -29,8 +35,11 @@ const instance = props.instance ?? {
'meta[name="theme-color-orig"]' 'meta[name="theme-color-orig"]'
) as HTMLMetaElement ) as HTMLMetaElement
)?.content, )?.content,
software: Instance.softwareName || "Calckey",
}; };
const capitalize = (s: string) => s && s[0].toUpperCase() + s.slice(1);
const computedStyle = getComputedStyle(document.documentElement); const computedStyle = getComputedStyle(document.documentElement);
const themeColor = const themeColor =
instance.themeColor ?? computedStyle.getPropertyValue("--bg"); instance.themeColor ?? computedStyle.getPropertyValue("--bg");
@ -50,15 +59,11 @@ function getInstanceIcon(instance): string {
<style lang="scss" scoped> <style lang="scss" scoped>
.hpaizdrt { .hpaizdrt {
display: flex;
align-items: center;
height: 1.1em;
display: flex; display: flex;
align-items: center; align-items: center;
height: 1.1em; height: 1.1em;
justify-self: flex-end; justify-self: flex-end;
padding: 0.2em 0.4em; padding: 0.2em 0.4em;
padding: 0.2em 0.4em;
border-radius: 100px; border-radius: 100px;
font-size: 0.8em; font-size: 0.8em;
text-shadow: 0 2px 2px var(--shadow); text-shadow: 0 2px 2px var(--shadow);
@ -67,10 +72,6 @@ function getInstanceIcon(instance): string {
width: max-content; width: max-content;
max-width: 100%; max-width: 100%;
} }
.header > .body & {
width: max-content;
max-width: 100%;
}
> .icon { > .icon {
height: 100%; height: 100%;
@ -78,27 +79,19 @@ function getInstanceIcon(instance): string {
} }
> .name { > .name {
display: none;
display: none; display: none;
margin-left: 4px; margin-left: 4px;
font-size: 0.85em; font-size: 0.85em;
font-size: 0.85em;
vertical-align: top; vertical-align: top;
font-weight: bold; font-weight: bold;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: -1px -1px 0 var(--bg), 1px -1px 0 var(--bg), text-shadow: -1px -1px 0 var(--bg), 1px -1px 0 var(--bg),
-1px 1px 0 var(--bg), 1px 1px 0 var(--bg); -1px 1px 0 var(--bg), 1px 1px 0 var(--bg);
.article > .main &, .article > .main &,
.header > .body & { .header > .body & {
display: unset; display: unset;
} }
.article > .main &,
.header > .body & {
display: unset;
}
} }
} }
</style> </style>

View file

@ -10,11 +10,11 @@
:class="{ renote: isRenote }" :class="{ renote: isRenote }"
> >
<MkNoteSub <MkNoteSub
v-if="appearNote.reply" v-if="appearNote.reply && !detailedView"
:note="appearNote.reply" :note="appearNote.reply"
class="reply-to" class="reply-to"
/> />
<div class="note-context" @click="noteClick"> <div v-if="!detailedView" class="note-context" @click="noteClick">
<div class="line"></div> <div class="line"></div>
<div v-if="appearNote._prId_" class="info"> <div v-if="appearNote._prId_" class="info">
<i class="ph-megaphone-simple-bold ph-lg"></i> <i class="ph-megaphone-simple-bold ph-lg"></i>
@ -77,93 +77,31 @@
/> />
</div> </div>
<div class="body"> <div class="body">
<p v-if="appearNote.cw != null" class="cw"> <MkSubNoteContent
<Mfm class="text"
v-if="appearNote.cw != ''" :note="appearNote"
class="text" :detailed="true"
:text="appearNote.cw" :detailedView="detailedView"
:author="appearNote.user" :parentId="appearNote.parentId"
:custom-emojis="appearNote.emojis" @push="(e) => router.push(notePage(e))"
:i="$i" ></MkSubNoteContent>
/> <div v-if="translating || translation" class="translation">
<br /> <MkLoading v-if="translating" mini />
<XCwButton v-model="showContent" :note="appearNote" /> <div v-else class="translated">
</p> <b
<div >{{
v-show="appearNote.cw == null || showContent" i18n.t("translatedFrom", {
class="content" x: translation.sourceLang,
:class="{ collapsed, isLong }" })
> }}:
<div class="text"> </b>
<Mfm <Mfm
v-if="appearNote.text" :text="translation.text"
:text="appearNote.text"
:author="appearNote.user" :author="appearNote.user"
:i="$i" :i="$i"
:custom-emojis="appearNote.emojis" :custom-emojis="appearNote.emojis"
/> />
<!-- <a v-if="appearNote.renote != null" class="rp">RN:</a> -->
<div
v-if="translating || translation"
class="translation"
>
<MkLoading v-if="translating" mini />
<div v-else class="translated">
<b
>{{
i18n.t("translatedFrom", {
x: translation.sourceLang,
})
}}:
</b>
<Mfm
:text="translation.text"
:author="appearNote.user"
:i="$i"
:custom-emojis="appearNote.emojis"
/>
</div>
</div>
</div> </div>
<div v-if="appearNote.files.length > 0" class="files">
<XMediaList :media-list="appearNote.files" />
</div>
<XPoll
v-if="appearNote.poll"
ref="pollViewer"
:note="appearNote"
class="poll"
/>
<MkUrlPreview
v-for="url in urls"
:key="url"
:url="url"
:compact="true"
:detail="false"
class="url-preview"
/>
<div v-if="appearNote.renote" class="renote">
<XNoteSimple
:note="appearNote.renote"
@click.stop="
router.push(notePage(appearNote.renote))
"
/>
</div>
<button
v-if="isLong && collapsed"
class="fade _button"
@click.stop="collapsed = false"
>
<span>{{ i18n.ts.showMore }}</span>
</button>
<button
v-else-if="isLong && !collapsed"
class="showLess _button"
@click.stop="collapsed = true"
>
<span>{{ i18n.ts.showLess }}</span>
</button>
</div> </div>
<MkA <MkA
v-if="appearNote.channel && !inChannel" v-if="appearNote.channel && !inChannel"
@ -174,8 +112,14 @@
{{ appearNote.channel.name }}</MkA {{ appearNote.channel.name }}</MkA
> >
</div> </div>
<div v-if="detailedView" class="info">
<MkA class="created-at" :to="notePage(appearNote)">
<MkTime :time="appearNote.createdAt" mode="absolute" />
</MkA>
</div>
<footer ref="el" class="footer" @click.stop> <footer ref="el" class="footer" @click.stop>
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
:note="appearNote" :note="appearNote"
/> />
@ -195,14 +139,32 @@
:note="appearNote" :note="appearNote"
:count="appearNote.renoteCount" :count="appearNote.renoteCount"
/> />
<XStarButtonNoEmoji
v-if="!enableEmojiReactions"
class="button"
:note="appearNote"
:count="
Object.values(appearNote.reactions).reduce(
(partialSum, val) => partialSum + val,
0
)
"
:reacted="appearNote.myReaction != null"
/>
<XStarButton <XStarButton
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton" ref="starButton"
class="button" class="button"
:note="appearNote" :note="appearNote"
/> />
<button <button
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@ -211,7 +173,10 @@
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
<button <button
v-if="appearNote.myReaction != null" v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click="undoReact(appearNote)"
@ -255,6 +220,7 @@ import * as mfm from "mfm-js";
import type { Ref } from "vue"; import type { Ref } from "vue";
import type * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import MkNoteSub from "@/components/MkNoteSub.vue"; import MkNoteSub from "@/components/MkNoteSub.vue";
import MkSubNoteContent from "./MkSubNoteContent.vue";
import XNoteHeader from "@/components/MkNoteHeader.vue"; import XNoteHeader from "@/components/MkNoteHeader.vue";
import XNoteSimple from "@/components/MkNoteSimple.vue"; import XNoteSimple from "@/components/MkNoteSimple.vue";
import XMediaList from "@/components/MkMediaList.vue"; import XMediaList from "@/components/MkMediaList.vue";
@ -263,6 +229,7 @@ import XPoll from "@/components/MkPoll.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue"; import XReactionsViewer from "@/components/MkReactionsViewer.vue";
import XStarButton from "@/components/MkStarButton.vue"; import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue"; import MkUrlPreview from "@/components/MkUrlPreview.vue";
import MkVisibility from "@/components/MkVisibility.vue"; import MkVisibility from "@/components/MkVisibility.vue";
@ -274,7 +241,6 @@ import { userPage } from "@/filters/user";
import * as os from "@/os"; import * as os from "@/os";
import { defaultStore, noteViewInterruptors } from "@/store"; import { defaultStore, noteViewInterruptors } from "@/store";
import { reactionPicker } from "@/scripts/reaction-picker"; import { reactionPicker } from "@/scripts/reaction-picker";
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
import { $i } from "@/account"; import { $i } from "@/account";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { getNoteMenu } from "@/scripts/get-note-menu"; import { getNoteMenu } from "@/scripts/get-note-menu";
@ -287,6 +253,7 @@ const router = useRouter();
const props = defineProps<{ const props = defineProps<{
note: misskey.entities.Note; note: misskey.entities.Note;
pinned?: boolean; pinned?: boolean;
detailedView?: boolean;
}>(); }>();
const inChannel = inject("inChannel", null); const inChannel = inject("inChannel", null);
@ -321,18 +288,11 @@ let appearNote = $computed(() =>
); );
const isMyRenote = $i && $i.id === note.userId; const isMyRenote = $i && $i.id === note.userId;
const showContent = ref(false); const showContent = ref(false);
const isLong =
appearNote.cw == null &&
appearNote.text != null &&
(appearNote.text.split("\n").length > 9 || appearNote.text.length > 500);
const collapsed = ref(appearNote.cw == null && isLong);
const isDeleted = ref(false); const isDeleted = ref(false);
const muted = ref(getWordMute(appearNote, $i, defaultStore.state.mutedWords)); const muted = ref(getWordMute(appearNote, $i, defaultStore.state.mutedWords));
const translation = ref(null); const translation = ref(null);
const translating = ref(false); const translating = ref(false);
const urls = appearNote.text const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
? extractUrlFromMfm(mfm.parse(appearNote.text)).slice(0, 5)
: null;
const keymap = { const keymap = {
r: () => reply(true), r: () => reply(true),
@ -479,7 +439,7 @@ function focusAfter() {
} }
function noteClick(e) { function noteClick(e) {
if (document.getSelection().type === "Range") { if (document.getSelection().type === "Range" || props.detailedView) {
e.stopPropagation(); e.stopPropagation();
} else { } else {
router.push(notePage(appearNote)); router.push(notePage(appearNote));
@ -666,123 +626,24 @@ function readPromo() {
> .body { > .body {
margin-top: 0.7em; margin-top: 0.7em;
> .cw {
cursor: default;
display: block;
margin: 0;
padding: 0;
overflow-wrap: break-word;
> .text {
margin-right: 8px;
}
}
> .content { > .content {
&.isLong { > .translation {
> .showLess { border: solid 0.5px var(--divider);
width: 100%; border-radius: var(--radius);
margin-top: 1em; padding: 12px;
position: sticky;
bottom: var(--stickyBottom);
> span {
display: inline-block;
background: var(--popup);
padding: 6px 10px;
font-size: 0.8em;
border-radius: 999px;
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
}
}
}
&.collapsed {
position: relative;
max-height: 9em;
overflow: hidden;
> .text {
max-height: 9em;
mask: linear-gradient(
black calc(100% - 64px),
transparent
);
-webkit-mask: linear-gradient(
black calc(100% - 64px),
transparent
);
}
> .fade {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 64px;
> span {
display: inline-block;
background: var(--panel);
padding: 6px 10px;
font-size: 0.8em;
border-radius: 999px;
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
}
&:hover {
> span {
background: var(--panelHighlight);
}
}
}
}
> .text {
overflow-wrap: break-word;
> .reply {
color: var(--accent);
margin-right: 0.5em;
}
> .rp {
margin-left: 4px;
font-style: oblique;
color: var(--renote);
}
> .translation {
border: solid 0.5px var(--divider);
border-radius: var(--radius);
padding: 12px;
margin-top: 8px;
}
}
> .files {
margin-top: 0.4em;
margin-bottom: 0.4em;
}
> .url-preview {
margin-top: 8px; margin-top: 8px;
} }
}
> .poll { > .renote {
font-size: 80%; padding-top: 8px;
} > * {
padding: 16px;
> .renote { border: solid 1px var(--renote);
padding: 8px 0; border-radius: 8px;
transition: background 0.2s;
> * { &:hover,
padding: 16px; &:focus-within {
border: solid 1px var(--renote); background-color: var(--panelHighlight);
border-radius: 8px;
transition: background 0.2s;
&:hover,
&:focus-within {
background-color: var(--panelHighlight);
}
} }
} }
} }
@ -792,13 +653,18 @@ function readPromo() {
font-size: 80%; font-size: 80%;
} }
} }
> .info {
margin-block: 16px;
opacity: 0.7;
font-size: 0.9em;
}
> .footer { > .footer {
position: relative; position: relative;
z-index: 2; z-index: 2;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
pointer-events: none; // Allow clicking anything w/out pointer-events: all; to open post pointer-events: none; // Allow clicking anything w/out pointer-events: all; to open post
margin-top: 0.4em;
> .button { > .button {
margin: 0; margin: 0;
padding: 8px; padding: 8px;

View file

@ -20,224 +20,16 @@
:note="appearNote.reply" :note="appearNote.reply"
class="reply-to" class="reply-to"
/> />
<div v-if="isRenote" class="renote">
<MkAvatar class="avatar" :user="note.user" /> <div ref="noteEl" class="article" tabindex="-1">
<i class="ph-repeat ph-bold ph-lg"></i> <MkNote
<I18n :src="i18n.ts.renotedBy" tag="span"> @contextmenu.stop="onContextmenu"
<template #user> tabindex="-1"
<MkA :note="appearNote"
v-user-preview="note.userId" :detailedView="true"
class="name" ></MkNote>
:to="userPage(note.user)"
>
<MkUserName :user="note.user" />
</MkA>
</template>
</I18n>
<div class="info">
<button
ref="renoteTime"
class="_button time"
@click="showRenoteMenu()"
>
<i
v-if="isMyRenote"
class="ph-dots-three-outline ph-bold ph-lg dropdownIcon"
></i>
<MkTime :time="note.createdAt" />
</button>
<MkVisibility :note="note" />
</div>
</div> </div>
<article
ref="noteEl"
class="article"
@contextmenu.stop="onContextmenu"
tabindex="-1"
>
<header class="header">
<MkAvatar
class="avatar"
:user="appearNote.user"
:show-indicator="true"
/>
<div class="body">
<div class="top">
<MkA
v-user-preview="appearNote.user.id"
class="name"
:to="userPage(appearNote.user)"
>
<MkUserName :user="appearNote.user" />
</MkA>
<span v-if="appearNote.user.isBot" class="is-bot"
>bot</span
>
<div class="info">
<MkVisibility :note="appearNote" />
</div>
</div>
<div class="username">
<MkAcct :user="appearNote.user" />
</div>
<MkInstanceTicker
v-if="showTicker"
class="ticker"
:instance="appearNote.user.instance"
/>
</div>
</header>
<div class="main">
<div class="body">
<div v-if="appearNote.cw != null" class="cw">
<Mfm
v-if="appearNote.cw != ''"
class="text"
:text="appearNote.cw"
:author="appearNote.user"
:i="$i"
:custom-emojis="appearNote.emojis"
/>
<br />
<XCwButton v-model="showContent" :note="appearNote" />
</div>
<div
v-show="appearNote.cw == null || showContent"
class="content"
>
<div class="text">
<Mfm
v-if="appearNote.text"
:text="appearNote.text"
:author="appearNote.user"
:i="$i"
:custom-emojis="appearNote.emojis"
/>
<div
v-if="translating || translation"
class="translation"
>
<MkLoading v-if="translating" mini />
<div v-else class="translated">
<b
>{{
i18n.t("translatedFrom", {
x: translation.sourceLang,
})
}}:
</b>
<Mfm
:text="translation.text"
:author="appearNote.user"
:i="$i"
:custom-emojis="appearNote.emojis"
/>
</div>
</div>
</div>
<div v-if="appearNote.files.length > 0" class="files">
<XMediaList :media-list="appearNote.files" />
</div>
<XPoll
v-if="appearNote.poll"
ref="pollViewer"
:note="appearNote"
class="poll"
/>
<MkUrlPreview
v-for="url in urls"
:key="url"
:url="url"
:compact="true"
:detail="true"
class="url-preview"
/>
<div v-if="appearNote.renote" class="renote">
<XNoteSimple
:note="appearNote.renote"
@click.stop="
router.push(notePage(appearNote.renote))
"
/>
</div>
</div>
<MkA
v-if="appearNote.channel && !inChannel"
class="channel"
:to="`/channels/${appearNote.channel.id}`"
><i class="ph-television ph-bold ph-lg"></i>
{{ appearNote.channel.name }}</MkA
>
</div>
<footer class="footer">
<div class="info">
<MkA class="created-at" :to="notePage(appearNote)">
<MkTime
:time="appearNote.createdAt"
mode="detail"
/>
</MkA>
</div>
<XReactionsViewer
ref="reactionsViewer"
:note="appearNote"
/>
<button
v-tooltip.noDelay.bottom="i18n.ts.reply"
class="button _button"
@click="reply()"
>
<template v-if="appearNote.reply"
><i class="ph-arrow-u-up-left ph-bold ph-lg"></i
></template>
<template v-else
><i class="ph-arrow-bend-up-left ph-bold ph-lg"></i
></template>
<p v-if="appearNote.repliesCount > 0" class="count">
{{ appearNote.repliesCount }}
</p>
</button>
<XRenoteButton
ref="renoteButton"
class="button"
:note="appearNote"
:count="appearNote.renoteCount"
/>
<XStarButton
v-if="appearNote.myReaction == null"
ref="starButton"
class="button"
:note="appearNote"
/>
<button
v-if="appearNote.myReaction == null"
ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button"
@click="react()"
>
<i class="ph-smiley ph-bold ph-lg"></i>
</button>
<button
v-if="appearNote.myReaction != null"
ref="reactButton"
class="button _button reacted"
@click="undoReact(appearNote)"
>
<i class="ph-minus ph-bold ph-lg"></i>
</button>
<XQuoteButton class="button" :note="appearNote" />
<button
ref="menuButton"
v-tooltip.noDelay.bottom="i18n.ts.more"
class="button _button"
@click="menu()"
>
<i class="ph-dots-three-outline ph-bold ph-lg"></i>
</button>
</footer>
</div>
</article>
<MkNoteSub <MkNoteSub
v-for="note in directReplies" v-for="note in directReplies"
:key="note.id" :key="note.id"
@ -276,6 +68,7 @@ import {
} from "vue"; } from "vue";
import * as mfm from "mfm-js"; import * as mfm from "mfm-js";
import type * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import MkNote from "@/components/MkNote.vue";
import MkNoteSub from "@/components/MkNoteSub.vue"; import MkNoteSub from "@/components/MkNoteSub.vue";
import XNoteSimple from "@/components/MkNoteSimple.vue"; import XNoteSimple from "@/components/MkNoteSimple.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue"; import XReactionsViewer from "@/components/MkReactionsViewer.vue";
@ -283,6 +76,7 @@ import XMediaList from "@/components/MkMediaList.vue";
import XCwButton from "@/components/MkCwButton.vue"; import XCwButton from "@/components/MkCwButton.vue";
import XPoll from "@/components/MkPoll.vue"; import XPoll from "@/components/MkPoll.vue";
import XStarButton from "@/components/MkStarButton.vue"; import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue"; import MkUrlPreview from "@/components/MkUrlPreview.vue";
@ -316,6 +110,8 @@ const inChannel = inject("inChannel", null);
let note = $ref(deepClone(props.note)); let note = $ref(deepClone(props.note));
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
// plugin // plugin
if (noteViewInterruptors.length > 0) { if (noteViewInterruptors.length > 0) {
onMounted(async () => { onMounted(async () => {
@ -647,8 +443,7 @@ onUnmounted(() => {
} }
> .article { > .article {
padding: 32px; padding-block: 28px 6px;
padding-bottom: 6px;
&:last-child { &:last-child {
padding-bottom: 24px; padding-bottom: 24px;
} }
@ -656,151 +451,8 @@ onUnmounted(() => {
overflow: clip; overflow: clip;
outline: none; outline: none;
scroll-margin-top: calc(var(--stickyTop) + 20vh); scroll-margin-top: calc(var(--stickyTop) + 20vh);
> .header { :deep(.article) {
display: flex; cursor: unset;
position: relative;
margin-bottom: 16px;
> .avatar {
display: block;
flex-shrink: 0;
width: var(--avatarSize);
height: var(--avatarSize);
}
> .body {
width: 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 14px;
font-size: 0.95em;
> .top {
display: flex;
align-items: center;
> .name {
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
}
> .is-bot {
flex-shrink: 0;
align-self: center;
margin: 0 0.5em;
padding: 4px 6px;
font-size: 80%;
border: solid 0.5px var(--divider);
border-radius: 4px;
}
> .info {
float: right;
}
}
}
}
> .main {
> .body {
> .cw {
cursor: default;
display: block;
margin: 0;
padding: 0;
overflow-wrap: break-word;
> .text {
margin-right: 8px;
}
}
> .content {
> .text {
overflow-wrap: break-word;
> .reply {
color: var(--accent);
margin-right: 0.5em;
}
> .rp {
margin-left: 4px;
font-style: oblique;
color: var(--renote);
}
> .translation {
border: solid 0.5px var(--divider);
border-radius: var(--radius);
padding: 12px;
margin-top: 8px;
}
}
> .url-preview {
margin-top: 8px;
}
> .poll {
font-size: 80%;
}
> .renote {
padding: 8px 0;
> * {
padding: 16px;
border: solid 1px var(--renote);
border-radius: 8px;
transition: background 0.2s;
&:hover,
&:focus-within {
background-color: var(--panelHighlight);
}
}
}
}
> .channel {
opacity: 0.7;
font-size: 80%;
}
}
> .footer {
> .info {
margin: 16px 0;
opacity: 0.7;
font-size: 0.9em;
}
> .button {
margin: 0;
padding: 8px;
opacity: 0.7;
&:not(:last-child) {
margin-right: 16px;
}
&:hover {
color: var(--fgHighlighted);
}
> .count {
display: inline;
margin: 0 0 0 8px;
opacity: 0.7;
}
&.reacted {
color: var(--accent);
}
}
}
} }
} }
@ -884,7 +536,7 @@ onUnmounted(() => {
} }
> .article { > .article {
padding: 16px; padding: 6px 0 0 0;
> .header > .body { > .header > .body {
padding-left: 10px; padding-left: 10px;
} }

View file

@ -4,21 +4,7 @@
<div class="main"> <div class="main">
<XNoteHeader class="header" :note="note" :mini="true" /> <XNoteHeader class="header" :note="note" :mini="true" />
<div class="body"> <div class="body">
<p v-if="note.cw != null" class="cw"> <MkSubNoteContent class="text" :note="note" />
<Mfm
v-if="note.cw != ''"
class="text"
:text="note.cw"
:author="note.user"
:i="$i"
:custom-emojis="note.emojis"
/>
<br />
<XCwButton v-model="showContent" :note="note" />
</p>
<div v-show="note.cw == null || showContent" class="content">
<MkSubNoteContent class="text" :note="note" />
</div>
</div> </div>
</div> </div>
</div> </div>
@ -29,7 +15,6 @@ import {} from "vue";
import * as misskey from "calckey-js"; import * as misskey from "calckey-js";
import XNoteHeader from "@/components/MkNoteHeader.vue"; import XNoteHeader from "@/components/MkNoteHeader.vue";
import MkSubNoteContent from "@/components/MkSubNoteContent.vue"; import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
import XCwButton from "@/components/MkCwButton.vue";
const props = defineProps<{ const props = defineProps<{
note: misskey.entities.Note; note: misskey.entities.Note;
@ -79,28 +64,6 @@ const showContent = $ref(false);
> .header { > .header {
margin-bottom: 2px; margin-bottom: 2px;
} }
> .body {
> .cw {
cursor: default;
display: block;
margin: 0;
padding: 0;
overflow-wrap: break-word;
> .text {
margin-right: 8px;
}
}
> .content {
> .text {
cursor: default;
margin: 0;
padding: 0;
}
}
}
} }
} }
</style> </style>

View file

@ -21,51 +21,12 @@
<div class="body"> <div class="body">
<XNoteHeader class="header" :note="note" :mini="true" /> <XNoteHeader class="header" :note="note" :mini="true" />
<div class="body"> <div class="body">
<p v-if="appearNote.cw != null" class="cw"> <MkSubNoteContent
<MkA class="text"
v-if="appearNote.replyId" :note="note"
:to="`/notes/${appearNote.replyId}`" :parentId="appearNote.parentId"
class="reply-icon" :conversation="conversation"
@click.stop />
>
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
</MkA>
<MkA
v-if="
conversation &&
appearNote.renoteId &&
appearNote.renoteId != parentId &&
!appearNote.replyId
"
:to="`/notes/${appearNote.renoteId}`"
class="reply-icon"
@click.stop
>
<i class="ph-quotes ph-bold ph-lg"></i>
</MkA>
<Mfm
v-if="appearNote.cw != ''"
class="text"
:text="appearNote.cw"
:author="appearNote.user"
:i="$i"
:custom-emojis="appearNote.emojis"
/>
<br />
<XCwButton v-model="showContent" :note="note" />
</p>
<div
v-show="appearNote.cw == null || showContent"
class="content"
>
<MkSubNoteContent
class="text"
:note="note"
:detailed="true"
:parentId="appearNote.parentId"
:conversation="conversation"
/>
</div>
<div v-if="translating || translation" class="translation"> <div v-if="translating || translation" class="translation">
<MkLoading v-if="translating" mini /> <MkLoading v-if="translating" mini />
<div v-else class="translated"> <div v-else class="translated">
@ -87,6 +48,7 @@
</div> </div>
<footer class="footer" @click.stop> <footer class="footer" @click.stop>
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
:note="appearNote" :note="appearNote"
/> />
@ -106,14 +68,32 @@
:note="appearNote" :note="appearNote"
:count="appearNote.renoteCount" :count="appearNote.renoteCount"
/> />
<XStarButtonNoEmoji
v-if="!enableEmojiReactions"
class="button"
:note="appearNote"
:count="
Object.values(appearNote.reactions).reduce(
(partialSum, val) => partialSum + val,
0
)
"
:reacted="appearNote.myReaction != null"
/>
<XStarButton <XStarButton
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton" ref="starButton"
class="button" class="button"
:note="appearNote" :note="appearNote"
/> />
<button <button
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@ -122,7 +102,10 @@
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
<button <button
v-if="appearNote.myReaction != null" v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click="undoReact(appearNote)"
@ -142,27 +125,31 @@
</div> </div>
</div> </div>
<template v-if="conversation"> <template v-if="conversation">
<template v-if="replies.length == 1"> <template v-if="replyLevel < 11 && depth < 5">
<MkNoteSub <template v-if="replies.length == 1">
v-for="reply in replies" <MkNoteSub
:key="reply.id" v-for="reply in replies"
:note="reply" :key="reply.id"
class="reply single" :note="reply"
:conversation="conversation" class="reply single"
:depth="depth" :conversation="conversation"
:parentId="appearNote.replyId" :depth="depth"
/> :replyLevel="replyLevel + 1"
</template> :parentId="appearNote.replyId"
<template v-else-if="depth < 5"> />
<MkNoteSub </template>
v-for="reply in replies" <template v-else>
:key="reply.id" <MkNoteSub
:note="reply" v-for="reply in replies"
class="reply" :key="reply.id"
:conversation="conversation" :note="reply"
:depth="depth + 1" class="reply"
:parentId="appearNote.replyId" :conversation="conversation"
/> :depth="depth + 1"
:replyLevel="replyLevel + 1"
:parentId="appearNote.replyId"
/>
</template>
</template> </template>
<div v-else-if="replies.length > 0" class="more"> <div v-else-if="replies.length > 0" class="more">
<div class="line"></div> <div class="line"></div>
@ -183,9 +170,9 @@ import XNoteHeader from "@/components/MkNoteHeader.vue";
import MkSubNoteContent from "@/components/MkSubNoteContent.vue"; import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue"; import XReactionsViewer from "@/components/MkReactionsViewer.vue";
import XStarButton from "@/components/MkStarButton.vue"; import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import XCwButton from "@/components/MkCwButton.vue";
import { pleaseLogin } from "@/scripts/please-login"; import { pleaseLogin } from "@/scripts/please-login";
import { getNoteMenu } from "@/scripts/get-note-menu"; import { getNoteMenu } from "@/scripts/get-note-menu";
import { notePage } from "@/filters/note"; import { notePage } from "@/filters/note";
@ -195,6 +182,7 @@ import { reactionPicker } from "@/scripts/reaction-picker";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { deepClone } from "@/scripts/clone"; import { deepClone } from "@/scripts/clone";
import { useNoteCapture } from "@/scripts/use-note-capture"; import { useNoteCapture } from "@/scripts/use-note-capture";
import { defaultStore } from "@/store";
const router = useRouter(); const router = useRouter();
@ -206,9 +194,12 @@ const props = withDefaults(
// how many notes are in between this one and the note being viewed in detail // how many notes are in between this one and the note being viewed in detail
depth?: number; depth?: number;
// the actual reply level of this note within the conversation thread
replyLevel?: number;
}>(), }>(),
{ {
depth: 1, depth: 1,
replyLevel: 1,
} }
); );
@ -231,7 +222,6 @@ let appearNote = $computed(() =>
const isDeleted = ref(false); const isDeleted = ref(false);
const translation = ref(null); const translation = ref(null);
const translating = ref(false); const translating = ref(false);
let showContent = $ref(false);
const replies: misskey.entities.Note[] = const replies: misskey.entities.Note[] =
props.conversation props.conversation
?.filter( ?.filter(
@ -240,6 +230,7 @@ const replies: misskey.entities.Note[] =
item.renoteId === props.note.id item.renoteId === props.note.id
) )
.reverse() ?? []; .reverse() ?? [];
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
useNoteCapture({ useNoteCapture({
rootEl: el, rootEl: el,
@ -368,35 +359,6 @@ function noteClick(e) {
} }
> .body { > .body {
.reply-icon {
display: inline-block;
border-radius: 6px;
padding: 0.2em 0.2em;
margin-right: 0.2em;
color: var(--accent);
transition: background 0.2s;
&:hover,
&:focus {
background: var(--buttonHoverBg);
}
}
> .cw {
cursor: default;
display: block;
margin: 0;
padding: 0;
overflow-wrap: break-word;
> .text {
margin-right: 8px;
}
}
> .content {
> .text {
margin: 0;
padding: 0;
}
}
> .translation { > .translation {
border: solid 0.5px var(--divider); border: solid 0.5px var(--divider);
border-radius: var(--radius); border-radius: var(--radius);

View file

@ -65,7 +65,9 @@
></i> ></i>
<!-- notification.reaction null になることはまずないがここでoptional chaining使うと一部ブラウザで刺さるので念の為 --> <!-- notification.reaction null になることはまずないがここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
<XReactionIcon <XReactionIcon
v-else-if="notification.type === 'reaction'" v-else-if="
showEmojiReactions && notification.type === 'reaction'
"
ref="reactionRef" ref="reactionRef"
:reaction=" :reaction="
notification.reaction notification.reaction
@ -78,6 +80,13 @@
:custom-emojis="notification.note.emojis" :custom-emojis="notification.note.emojis"
:no-style="true" :no-style="true"
/> />
<XReactionIcon
v-else-if="
!showEmojiReactions && notification.type === 'reaction'
"
:reaction="defaultReaction"
:no-style="true"
/>
</div> </div>
</div> </div>
<div class="tail"> <div class="tail">
@ -272,6 +281,8 @@ import { i18n } from "@/i18n";
import * as os from "@/os"; import * as os from "@/os";
import { stream } from "@/stream"; import { stream } from "@/stream";
import { useTooltip } from "@/scripts/use-tooltip"; import { useTooltip } from "@/scripts/use-tooltip";
import { defaultStore } from "@/store";
import { instance } from "@/instance";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@ -288,6 +299,13 @@ const props = withDefaults(
const elRef = ref<HTMLElement>(null); const elRef = ref<HTMLElement>(null);
const reactionRef = ref(null); const reactionRef = ref(null);
const showEmojiReactions =
defaultStore.state.enableEmojiReactions ||
defaultStore.state.showEmojisInReactionNotifications;
const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReaction)
? instance.defaultReaction
: "⭐";
let readObserver: IntersectionObserver | undefined; let readObserver: IntersectionObserver | undefined;
let connection; let connection;

View file

@ -6,7 +6,7 @@
@close="dialog.close()" @close="dialog.close()"
@closed="emit('closed')" @closed="emit('closed')"
> >
<template #header>{{ i18n.ts.reactions }}</template> <template #header>{{ i18n.ts.reaction }}</template>
<MkSpacer :margin-min="20" :margin-max="28"> <MkSpacer :margin-min="20" :margin-max="28">
<div v-if="note" class="_gaps"> <div v-if="note" class="_gaps">

View file

@ -104,7 +104,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
if (["public", "home"].includes(props.note.visibility)) { if (["public", "home"].includes(props.note.visibility)) {
buttonActions.push({ buttonActions.push({
text: i18n.ts.renoteAsUnlisted, text: `${i18n.ts.renote} (${i18n.ts._visibility.home})`,
icons: ["ph-repeat ph-bold ph-lg", "ph-house ph-bold ph-lg"], icons: ["ph-repeat ph-bold ph-lg", "ph-house ph-bold ph-lg"],
danger: false, danger: false,
action: () => { action: () => {
@ -130,7 +130,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
if (props.note.visibility === "specified") { if (props.note.visibility === "specified") {
buttonActions.push({ buttonActions.push({
text: i18n.ts.renoteToRecipients, text: `${i18n.ts.renote} (${i18n.ts.recipient})`,
icons: [ icons: [
"ph-repeat ph-bold ph-lg", "ph-repeat ph-bold ph-lg",
"ph-envelope-simple-open ph-bold ph-lg", "ph-envelope-simple-open ph-bold ph-lg",
@ -158,7 +158,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
}); });
} else { } else {
buttonActions.push({ buttonActions.push({
text: i18n.ts.renoteToFollowers, text: `${i18n.ts.renote} (${i18n.ts._visibility.followers})`,
icons: [ icons: [
"ph-repeat ph-bold ph-lg", "ph-repeat ph-bold ph-lg",
"ph-lock-simple-open ph-bold ph-lg", "ph-lock-simple-open ph-bold ph-lg",

View file

@ -0,0 +1,133 @@
<template>
<button
v-tooltip.noDelay.bottom="i18n.ts._gallery.like"
class="_button"
:class="$style.root"
ref="buttonRef"
@click="toggleStar($event)"
>
<span v-if="!reacted">
<i
v-if="instance.defaultReaction === '👍'"
class="ph-thumbs-up ph-bold ph-lg"
></i>
<i
v-else-if="instance.defaultReaction === '❤️'"
class="ph-heart ph-bold ph-lg"
></i>
<i v-else class="ph-star ph-bold ph-lg"></i>
</span>
<span v-else>
<i
v-if="instance.defaultReaction === '👍'"
class="ph-thumbs-up ph-bold ph-lg ph-fill"
:class="$style.yellow"
></i>
<i
v-else-if="instance.defaultReaction === '❤️'"
class="ph-heart ph-bold ph-lg ph-fill"
:class="$style.red"
></i>
<i
v-else
class="ph-star ph-bold ph-lg ph-fill"
:class="$style.yellow"
></i>
</span>
<template v-if="count > 0"
><p :class="$style.count">{{ count }}</p></template
>
</button>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import type { Note } from "calckey-js/built/entities";
import Ripple from "@/components/MkRipple.vue";
import XDetails from "@/components/MkUsersTooltip.vue";
import { pleaseLogin } from "@/scripts/please-login";
import * as os from "@/os";
import { defaultStore } from "@/store";
import { i18n } from "@/i18n";
import { instance } from "@/instance";
import { useTooltip } from "@/scripts/use-tooltip";
const props = defineProps<{
note: Note;
count: number;
reacted: boolean;
}>();
const buttonRef = ref<HTMLElement>();
function toggleStar(ev?: MouseEvent): void {
pleaseLogin();
if (!props.reacted) {
os.api("notes/reactions/create", {
noteId: props.note.id,
reaction: instance.defaultReaction,
});
const el =
ev &&
((ev.currentTarget ?? ev.target) as HTMLElement | null | undefined);
if (el) {
const rect = el.getBoundingClientRect();
const x = rect.left + el.offsetWidth / 2;
const y = rect.top + el.offsetHeight / 2;
os.popup(Ripple, { x, y }, {}, "end");
}
} else {
os.api("notes/reactions/delete", {
noteId: props.note.id,
});
}
}
useTooltip(buttonRef, async (showing) => {
const reactions = await os.apiGet("notes/reactions", {
noteId: props.note.id,
limit: 11,
_cacheKey_: props.count,
});
const users = reactions.map((x) => x.user);
if (users.length < 1) return;
os.popup(
XDetails,
{
showing,
users,
count: props.count,
targetElement: buttonRef.value,
},
{},
"closed"
);
});
</script>
<style lang="scss" module>
.root {
display: inline-block;
height: 32px;
margin: 2px;
padding: 0 6px;
}
.yellow {
color: var(--warn);
}
.red {
color: var(--error);
}
.count {
display: inline;
margin: 0 0 0 8px;
opacity: 0.7;
}
</style>

View file

@ -1,77 +1,118 @@
<template> <template>
<div class="wrmlmaau" :class="{ collapsed, isLong }"> <p v-if="note.cw != null" class="cw">
<div class="body"> <MkA
<span v-if="note.deletedAt" style="opacity: 0.5" v-if="!detailed && note.replyId"
>({{ i18n.ts.deleted }})</span :to="`/notes/${note.replyId}`"
> class="reply-icon"
<template v-if="!note.cw"> @click.stop
<MkA >
v-if="note.replyId" <i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
:to="`/notes/${note.replyId}`" </MkA>
class="reply-icon" <MkA
@click.stop v-if="
conversation &&
note.renoteId &&
note.renoteId != parentId &&
!note.replyId
"
:to="`/notes/${note.renoteId}`"
class="reply-icon"
@click.stop
>
<i class="ph-quotes ph-bold ph-lg"></i>
</MkA>
<Mfm
v-if="note.cw != ''"
class="text"
:text="note.cw"
:author="note.user"
:i="$i"
:custom-emojis="note.emojis"
/>
</p>
<div class="wrmlmaau">
<div
class="content"
:class="{ collapsed, isLong, showContent: note.cw && !showContent }"
>
<div class="body">
<span v-if="note.deletedAt" style="opacity: 0.5"
>({{ i18n.ts.deleted }})</span
> >
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i> <template v-if="!note.cw">
</MkA> <MkA
v-if="!detailed && note.replyId"
:to="`/notes/${note.replyId}`"
class="reply-icon"
@click.stop
>
<i class="ph-arrow-bend-left-up ph-bold ph-lg"></i>
</MkA>
<MkA
v-if="
conversation &&
note.renoteId &&
note.renoteId != parentId &&
!note.replyId
"
:to="`/notes/${note.renoteId}`"
class="reply-icon"
@click.stop
>
<i class="ph-quotes ph-bold ph-lg"></i>
</MkA>
</template>
<Mfm
v-if="note.text"
:text="note.text"
:author="note.user"
:i="$i"
:custom-emojis="note.emojis"
/>
<MkA <MkA
v-if=" v-if="!detailed && note.renoteId"
conversation && class="rp"
note.renoteId &&
note.renoteId != parentId &&
!note.replyId
"
:to="`/notes/${note.renoteId}`" :to="`/notes/${note.renoteId}`"
class="reply-icon" >{{ i18n.ts.quoteAttached }}: ...</MkA
@click.stop
> >
<i class="ph-quotes ph-bold ph-lg"></i> <div v-if="note.files.length > 0" class="files">
</MkA> <XMediaList :media-list="note.files" />
</template> </div>
<Mfm <XPoll v-if="note.poll" :note="note" class="poll" />
v-if="note.text" <template v-if="detailed">
:text="note.text" <MkUrlPreview
:author="note.user" v-for="url in urls"
:i="$i" :key="url"
:custom-emojis="note.emojis" :url="url"
/> :compact="true"
<MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`" :detail="false"
>{{ i18n.ts.quoteAttached }}: ...</MkA class="url-preview"
/>
<div
v-if="note.renote"
class="renote"
@click.stop="emit('push', note.renote)"
>
<XNoteSimple :note="note.renote" />
</div>
</template>
</div>
<button
v-if="isLong && collapsed"
class="fade _button"
@click.stop="collapsed = false"
> >
<span>{{ i18n.ts.showMore }}</span>
</button>
<button
v-if="isLong && !collapsed"
class="showLess _button"
@click.stop="collapsed = true"
>
<span>{{ i18n.ts.showLess }}</span>
</button>
<XCwButton v-if="note.cw" v-model="showContent" :note="note" />
</div> </div>
<div v-if="note.files.length > 0">
<XMediaList :media-list="note.files" />
</div>
<div v-if="note.poll">
<summary>{{ i18n.ts.poll }}</summary>
<XPoll :note="note" />
</div>
<template v-if="detailed">
<!-- <div v-if="note.renoteId" class="renote">
<XNoteSimple :note="note.renote"/>
</div> -->
<MkUrlPreview
v-for="url in urls"
:key="url"
:url="url"
:compact="true"
:detail="false"
class="url-preview"
/>
</template>
<button
v-if="isLong && collapsed"
class="fade _button"
@click.stop="collapsed = false"
>
<span>{{ i18n.ts.showMore }}</span>
</button>
<button
v-if="isLong && !collapsed"
class="showLess _button"
@click.stop="collapsed = true"
>
<span>{{ i18n.ts.showLess }}</span>
</button>
</div> </div>
</template> </template>
@ -83,6 +124,7 @@ import XNoteSimple from "@/components/MkNoteSimple.vue";
import XMediaList from "@/components/MkMediaList.vue"; import XMediaList from "@/components/MkMediaList.vue";
import XPoll from "@/components/MkPoll.vue"; import XPoll from "@/components/MkPoll.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue"; import MkUrlPreview from "@/components/MkUrlPreview.vue";
import XCwButton from "@/components/MkCwButton.vue";
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm"; import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
@ -91,82 +133,157 @@ const props = defineProps<{
parentId?; parentId?;
conversation?; conversation?;
detailed?: boolean; detailed?: boolean;
detailedView?: boolean;
}>();
const emit = defineEmits<{
(ev: "push", v): void;
}>(); }>();
const isLong = const isLong =
!props.detailedView &&
props.note.cw == null && props.note.cw == null &&
props.note.text != null && props.note.text != null &&
(props.note.text.split("\n").length > 9 || props.note.text.length > 500); (props.note.text.split("\n").length > 9 || props.note.text.length > 500);
const collapsed = $ref(props.note.cw == null && isLong); const collapsed = $ref(props.note.cw == null && isLong);
const urls = props.note.text const urls = props.note.text
? extractUrlFromMfm(mfm.parse(props.note.text)) ? extractUrlFromMfm(mfm.parse(props.note.text)).slice(0, 5)
: null; : null;
let showContent = $ref(false);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.wrmlmaau { .reply-icon {
display: inline-block;
border-radius: 6px;
padding: 0.2em 0.2em;
margin-right: 0.2em;
color: var(--accent);
transition: background 0.2s;
&:hover,
&:focus {
background: var(--buttonHoverBg);
}
}
.cw {
cursor: default;
display: block;
margin: 0;
padding: 0;
margin-bottom: 10px;
overflow-wrap: break-word; overflow-wrap: break-word;
> .text {
> .body { margin-right: 8px;
> .rp {
margin-left: 4px;
font-style: oblique;
color: var(--renote);
}
.reply-icon {
display: inline-block;
border-radius: 6px;
padding: 0.2em 0.2em;
margin-right: 0.2em;
color: var(--accent);
transition: background 0.2s;
&:hover,
&:focus {
background: var(--buttonHoverBg);
}
}
} }
}
> .mk-url-preview { .wrmlmaau {
margin-top: 8px; .content {
} overflow-wrap: break-word;
&.collapsed {
position: relative;
max-height: 9em;
overflow: hidden;
> .body { > .body {
max-height: 9em; transition: filter 0.1s;
mask: linear-gradient(black calc(100% - 64px), transparent); > .rp {
-webkit-mask: linear-gradient(black calc(100% - 64px), transparent); margin-left: 4px;
} font-style: oblique;
> .fade { color: var(--renote);
display: block; }
position: absolute; .reply-icon {
bottom: 0;
left: 0;
width: 100%;
height: 64px;
> span {
display: inline-block; display: inline-block;
background: var(--panel); border-radius: 6px;
padding: 6px 10px; padding: 0.2em 0.2em;
font-size: 0.8em; margin-right: 0.2em;
border-radius: 999px; color: var(--accent);
box-shadow: 0 2px 6px rgb(0 0 0 / 20%); transition: background 0.2s;
&:hover,
&:focus {
background: var(--buttonHoverBg);
}
}
> .files {
margin-top: 0.4em;
margin-bottom: 0.4em;
}
> .url-preview {
margin-top: 8px;
} }
&:hover { > .poll {
> span { font-size: 80%;
background: var(--panelHighlight); }
> .renote {
padding-top: 8px;
> * {
padding: 16px;
border: solid 1px var(--renote);
border-radius: 8px;
transition: background 0.2s;
&:hover,
&:focus-within {
background-color: var(--panelHighlight);
}
} }
} }
} }
}
&.isLong { &.collapsed,
> .showLess { &.showContent {
position: relative;
max-height: calc(9em + 50px);
> .body {
max-height: inherit;
mask: linear-gradient(black calc(100% - 64px), transparent);
-webkit-mask: linear-gradient(
black calc(100% - 64px),
transparent
);
padding-inline: 50px;
margin-inline: -50px;
margin-top: -50px;
padding-top: 50px;
overflow: hidden;
}
&.collapsed > .body {
box-sizing: border-box;
}
&.showContent {
> .body {
min-height: 2em;
max-height: 5em;
filter: blur(4px);
}
:deep(.fade) {
inset: 0;
top: 40px;
}
:deep(span) {
animation: none !important;
}
}
:deep(.fade) {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
> span {
display: inline-block;
background: var(--panel);
padding: 0.4em 1em;
font-size: 0.8em;
border-radius: 999px;
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
}
&:hover {
> span {
background: var(--panelHighlight);
}
}
}
}
:deep(.showLess) {
width: 100%; width: 100%;
margin-top: 1em; margin-top: 1em;
position: sticky; position: sticky;

View file

@ -34,15 +34,15 @@
<div class="status"> <div class="status">
<div> <div>
<p>{{ i18n.ts.notes }}</p> <p>{{ i18n.ts.notes }}</p>
<span>{{ user.notesCount }}</span> <MkNumber :value="user.notesCount" />
</div> </div>
<div> <div>
<p>{{ i18n.ts.following }}</p> <p>{{ i18n.ts.following }}</p>
<span>{{ user.followingCount }}</span> <MkNumber :value="user.followingCount" />
</div> </div>
<div> <div>
<p>{{ i18n.ts.followers }}</p> <p>{{ i18n.ts.followers }}</p>
<span>{{ user.followersCount }}</span> <MkNumber :value="user.followersCount" />
</div> </div>
</div> </div>
<MkFollowButton <MkFollowButton
@ -57,6 +57,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import * as misskey from "calckey-js"; import * as misskey from "calckey-js";
import MkFollowButton from "@/components/MkFollowButton.vue"; import MkFollowButton from "@/components/MkFollowButton.vue";
import MkNumber from "@/components/MkNumber.vue";
import { userPage } from "@/filters/user"; import { userPage } from "@/filters/user";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

View file

@ -12,7 +12,6 @@ import MkGoogle from "@/components/MkGoogle.vue";
import MkSparkle from "@/components/MkSparkle.vue"; import MkSparkle from "@/components/MkSparkle.vue";
import MkA from "@/components/global/MkA.vue"; import MkA from "@/components/global/MkA.vue";
import { host } from "@/config"; import { host } from "@/config";
import { MFM_TAGS } from "@/scripts/mfm-tags";
import { reducedMotion } from "@/scripts/reduced-motion"; import { reducedMotion } from "@/scripts/reduced-motion";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
@ -368,11 +367,7 @@ export default defineComponent({
MkA, MkA,
{ {
key: Math.random(), key: Math.random(),
to: this.isNote to: `/tags/${encodeURIComponent(token.props.hashtag)}`,
? `/tags/${encodeURIComponent(token.props.hashtag)}`
: `/explore/tags/${encodeURIComponent(
token.props.hashtag,
)}`,
style: "color:var(--hashtag);", style: "color:var(--hashtag);",
}, },
`#${token.props.hashtag}`, `#${token.props.hashtag}`,
@ -461,7 +456,7 @@ export default defineComponent({
case "search": { case "search": {
// Disable "search" keyword // Disable "search" keyword
// (see the issue #9816 on Codeberg) // (see the issue #9816 on Codeberg)
if (token.props.content.endsWith("search")) { if (token.props.content.slice(-6).toLowerCase() === "search") {
const sentinel = "#"; const sentinel = "#";
let ast2 = (isPlain ? mfm.parseSimple : mfm.parse)( let ast2 = (isPlain ? mfm.parseSimple : mfm.parse)(
token.props.content.slice(0, -6) + sentinel, token.props.content.slice(0, -6) + sentinel,
@ -473,19 +468,32 @@ export default defineComponent({
ast2[ast2.length - 1].props.text = ast2[ ast2[ast2.length - 1].props.text = ast2[
ast2.length - 1 ast2.length - 1
].props.text.slice(0, -1); ].props.text.slice(0, -1);
} else {
// I don't think this scope is reachable
console.warn(
"Something went wrong while parsing MFM. Please send a bug report, if possible.",
);
} }
let prefix = "\n"; let prefix = "\n";
if ( if (
index === 0 || index === 0 ||
["blockCode", "mathBlock", "search", "quote"].includes( [
ast[index - 1].type, "blockCode",
) "center",
"mathBlock",
"quote",
"search",
].includes(ast[index - 1].type)
) { ) {
prefix = ""; prefix = "";
} }
return [prefix, ...genEl(ast2), "search\n"]; return [
prefix,
...genEl(ast2),
`${token.props.content.slice(-6)}\n`,
];
} }
return [ return [

View file

@ -161,12 +161,16 @@ const menuDef = $computed(() => [
}, },
] ]
: []), : []),
{ ...($i.isAdmin
type: "button", ? [
icon: "ph-list-magnifying-glass ph-bold ph-lg", {
text: i18n.ts.indexPosts, type: "button",
action: indexPosts, icon: "ph-list-magnifying-glass ph-bold ph-lg",
}, text: i18n.ts.indexPosts,
action: indexPosts,
},
]
: []),
], ],
}, },
{ {

View file

@ -81,6 +81,8 @@ definePageMetadata({
display: block; display: block;
max-height: 300px; max-height: 300px;
max-width: 100%; max-width: 100%;
border-radius: 10px;
margin-top: 1rem;
} }
} }
} }

View file

@ -80,14 +80,14 @@
<MkA <MkA
v-for="tag in tagsLocal" v-for="tag in tagsLocal"
:key="'local:' + tag.tag" :key="'local:' + tag.tag"
:to="`/explore/tags/${tag.tag}`" :to="`/tags/${tag.tag}`"
class="local" class="local"
>{{ tag.tag }}</MkA >{{ tag.tag }}</MkA
> >
<MkA <MkA
v-for="tag in tagsRemote" v-for="tag in tagsRemote"
:key="'remote:' + tag.tag" :key="'remote:' + tag.tag"
:to="`/explore/tags/${tag.tag}`" :to="`/tags/${tag.tag}`"
>{{ tag.tag }}</MkA >{{ tag.tag }}</MkA
> >
</div> </div>

View file

@ -39,7 +39,6 @@ import { Virtual } from "swiper";
import { Swiper, SwiperSlide } from "swiper/vue"; import { Swiper, SwiperSlide } from "swiper/vue";
import XFeatured from "./explore.featured.vue"; import XFeatured from "./explore.featured.vue";
import XUsers from "./explore.users.vue"; import XUsers from "./explore.users.vue";
import type MkFolder from "@/components/MkFolder.vue";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { deviceKind } from "@/scripts/device-kind"; import { deviceKind } from "@/scripts/device-kind";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
@ -47,23 +46,10 @@ import { defaultStore } from "@/store";
import "swiper/scss"; import "swiper/scss";
import "swiper/scss/virtual"; import "swiper/scss/virtual";
const props = defineProps<{ const tabs = ["users", "featured"];
tag?: string;
}>();
const tabs = ["featured", "users"];
let tab = $ref(tabs[0]); let tab = $ref(tabs[0]);
watch($$(tab), () => syncSlide(tabs.indexOf(tab))); watch($$(tab), () => syncSlide(tabs.indexOf(tab)));
let tagsEl = $ref<InstanceType<typeof MkFolder>>();
watch(
() => props.tag,
() => {
if (tagsEl) tagsEl.toggleContent(props.tag == null);
}
);
const headerActions = $computed(() => []); const headerActions = $computed(() => []);
const headerTabs = $computed(() => [ const headerTabs = $computed(() => [

View file

@ -203,7 +203,7 @@ function shareWithNote() {
} }
function like() { function like() {
os.apiWithDialog("gallery/posts/like", { os.api("gallery/posts/like", {
postId: props.postId, postId: props.postId,
}).then(() => { }).then(() => {
post.isLiked = true; post.isLiked = true;
@ -266,6 +266,7 @@ definePageMetadata(
max-width: 100%; max-width: 100%;
max-height: 500px; max-height: 500px;
margin: 0 auto; margin: 0 auto;
border-radius: 10px;
} }
& + .file { & + .file {

View file

@ -122,7 +122,7 @@ window.addEventListener("resize", () => {
}); });
async function readAllMessagingMessages() { async function readAllMessagingMessages() {
await os.api("i/read-all-messaging-messages"); await os.apiWithDialog("i/read-all-messaging-messages");
} }
const headerActions = $computed(() => [ const headerActions = $computed(() => [

View file

@ -1,93 +1,94 @@
<template> <template>
<MkStickyContainer> <div
<template #header ref="rootEl"
><MkPageHeader class="_section"
:actions="headerActions" @dragover.prevent.stop="onDragover"
:tabs="headerTabs" @drop.prevent.stop="onDrop"
:display-back-button="true" >
/></template> <div class="_content mk-messaging-room">
<MkSpacer :content-max="800" class="mk-messaging-room"> <MkSpacer :content-max="800">
<div class="body"> <div class="body">
<MkPagination <MkPagination
v-if="pagination" v-if="pagination"
ref="pagingComponent" ref="pagingComponent"
:key="userAcct || groupId" :key="userAcct || groupId"
:pagination="pagination" :pagination="pagination"
>
<template #empty>
<div class="_fullinfo">
<img
src="/static-assets/badges/info.png"
class="_ghost"
alt="Info"
/>
<div>{{ i18n.ts.noMessagesYet }}</div>
</div>
</template>
<template
#default="{ items: messages, fetching: pFetching }"
> >
<XList <template #empty>
v-if="messages.length > 0" <div class="_fullinfo">
v-slot="{ item: message }" <img
:class="{ src="/static-assets/badges/info.png"
messages: true, class="_ghost"
'deny-move-transition': pFetching, alt="Info"
}" />
:items="messages" <div>{{ i18n.ts.noMessagesYet }}</div>
direction="up" </div>
reversed
>
<XMessage
:key="message.id"
:message="message"
:is-group="group != null"
/>
</XList>
</template>
</MkPagination>
</div>
<footer>
<div v-if="typers.length > 0" class="typers">
<I18n
:src="i18n.ts.typingUsers"
text-tag="span"
class="users"
>
<template #users>
<b
v-for="typer in typers"
:key="typer.id"
class="user"
>{{ typer.username }}</b
>
</template> </template>
</I18n> <template
<MkEllipsis /> #default="{ items: messages, fetching: pFetching }"
</div>
<transition :name="animation ? 'fade' : ''">
<div v-show="showIndicator" class="new-message">
<button
class="_buttonPrimary"
@click="onIndicatorClick"
> >
<i <XList
class="fas ph-fw ph-lg ph-arrow-circle-down ph-bold ph-lg" v-if="messages.length > 0"
></i v-slot="{ item: message }"
>{{ i18n.ts.newMessageExists }} :class="{
</button> messages: true,
'deny-move-transition': pFetching,
}"
:items="messages"
direction="up"
reversed
>
<XMessage
:key="message.id"
:message="message"
:is-group="group != null"
/>
</XList>
</template>
</MkPagination>
</div>
<footer>
<div v-if="typers.length > 0" class="typers">
<I18n
:src="i18n.ts.typingUsers"
text-tag="span"
class="users"
>
<template #users>
<b
v-for="typer in typers"
:key="typer.id"
class="user"
>{{ typer.username }}</b
>
</template>
</I18n>
<MkEllipsis />
</div> </div>
</transition> <transition :name="animation ? 'fade' : ''">
<XForm <div v-show="showIndicator" class="new-message">
v-if="!fetching" <button
ref="formEl" class="_buttonPrimary"
:user="user" @click="onIndicatorClick"
:group="group" >
class="form" <i
/> class="fas ph-fw ph-lg ph-arrow-circle-down-bold ph-lg"
</footer> ></i
</MkSpacer> >{{ i18n.ts.newMessageExists }}
</MkStickyContainer> </button>
</div>
</transition>
<XForm
v-if="!fetching"
ref="formEl"
:user="user"
:group="group"
class="form"
/>
</footer>
</MkSpacer>
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -327,12 +328,14 @@ function onVisibilitychange() {
} }
} }
const headerActions = $computed(() => []);
const headerTabs = $computed(() => []);
onMounted(() => { onMounted(() => {
fetch(); fetch();
definePageMetadata(
computed(() => ({
title: group != null ? group.name : user?.name,
icon: "ph-chats-teardrop-bold ph-lg",
}))
);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
@ -340,15 +343,6 @@ onBeforeUnmount(() => {
document.removeEventListener("visibilitychange", onVisibilitychange); document.removeEventListener("visibilitychange", onVisibilitychange);
if (scrollRemove) scrollRemove(); if (scrollRemove) scrollRemove();
}); });
await fetch();
definePageMetadata(
computed(() => ({
title: group != null ? group.name : user?.name,
icon: "ph-chats-teardrop ph-bold ph-lg",
avatar: group != null ? null : user,
}))
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -357,6 +351,9 @@ XMessage:last-of-type {
} }
.mk-messaging-room { .mk-messaging-room {
position: relative;
overflow: auto;
> .body { > .body {
.more { .more {
display: block; display: block;

View file

@ -114,6 +114,8 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
"swipeOnDesktop", "swipeOnDesktop",
"showAdminUpdates", "showAdminUpdates",
"enableCustomKaTeXMacro", "enableCustomKaTeXMacro",
"enableEmojiReactions",
"showEmojisInReactionNotifications",
]; ];
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [ const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
"lightTheme", "lightTheme",

View file

@ -1,81 +1,99 @@
<template> <template>
<div class="_formRoot"> <div class="_formRoot">
<FromSlot class="_formBlock"> <FormSwitch v-model="enableEmojiReactions" class="_formBlock">
<template #label>{{ i18n.ts.reactionSettingDescription }}</template> {{ i18n.ts.enableEmojiReactions }}
<div v-panel style="border-radius: 6px">
<XDraggable
v-model="reactions"
class="zoaiodol"
:item-key="(item) => item"
animation="150"
delay="100"
delay-on-touch-only="true"
>
<template #item="{ element }">
<button
class="_button item"
@click="remove(element, $event)"
>
<MkEmoji :emoji="element" :normal="true" />
</button>
</template>
<template #footer>
<button class="_button add" @click="chooseEmoji">
<i class="ph-plus ph-bold ph-lg"></i>
</button>
</template>
</XDraggable>
</div>
<template #caption
>{{ i18n.ts.reactionSettingDescription2 }}
<button class="_textButton" @click="preview">
{{ i18n.ts.preview }}
</button></template
>
</FromSlot>
<FormRadios v-model="reactionPickerSize" class="_formBlock">
<template #label>{{ i18n.ts.size }}</template>
<option :value="1">{{ i18n.ts.small }}</option>
<option :value="2">{{ i18n.ts.medium }}</option>
<option :value="3">{{ i18n.ts.large }}</option>
</FormRadios>
<FormRadios v-model="reactionPickerWidth" class="_formBlock">
<template #label>{{ i18n.ts.numberOfColumn }}</template>
<option :value="1">5</option>
<option :value="2">6</option>
<option :value="3">7</option>
<option :value="4">8</option>
<option :value="5">9</option>
</FormRadios>
<FormRadios v-model="reactionPickerHeight" class="_formBlock">
<template #label>{{ i18n.ts.height }}</template>
<option :value="1">{{ i18n.ts.small }}</option>
<option :value="2">{{ i18n.ts.medium }}</option>
<option :value="3">{{ i18n.ts.large }}</option>
<option :value="4">{{ i18n.ts.large }}+</option>
</FormRadios>
<FormSwitch
v-model="reactionPickerUseDrawerForMobile"
class="_formBlock"
>
{{ i18n.ts.useDrawerReactionPickerForMobile }}
<template #caption>{{ i18n.ts.needReloadToApply }}</template>
</FormSwitch> </FormSwitch>
<FormSection> <div v-if="enableEmojiReactions">
<div style="display: flex; gap: var(--margin); flex-wrap: wrap"> <FromSlot class="_formBlock">
<FormButton inline @click="preview" <template #label>{{
><i class="ph-eye ph-bold ph-lg"></i> i18n.ts.reactionSettingDescription
{{ i18n.ts.preview }}</FormButton }}</template>
<div v-panel style="border-radius: 6px">
<XDraggable
v-model="reactions"
class="zoaiodol"
:item-key="(item) => item"
animation="150"
delay="100"
delay-on-touch-only="true"
>
<template #item="{ element }">
<button
class="_button item"
@click="remove(element, $event)"
>
<MkEmoji :emoji="element" :normal="true" />
</button>
</template>
<template #footer>
<button class="_button add" @click="chooseEmoji">
<i class="ph-plus ph-bold ph-lg"></i>
</button>
</template>
</XDraggable>
</div>
<template #caption
>{{ i18n.ts.reactionSettingDescription2 }}
<button class="_textButton" @click="preview">
{{ i18n.ts.preview }}
</button></template
> >
<FormButton inline danger @click="setDefault" </FromSlot>
><i class="ph-arrow-counter-clockwise ph-bold ph-lg"></i>
{{ i18n.ts.default }}</FormButton <FormRadios v-model="reactionPickerSize" class="_formBlock">
> <template #label>{{ i18n.ts.size }}</template>
</div> <option :value="1">{{ i18n.ts.small }}</option>
</FormSection> <option :value="2">{{ i18n.ts.medium }}</option>
<option :value="3">{{ i18n.ts.large }}</option>
</FormRadios>
<FormRadios v-model="reactionPickerWidth" class="_formBlock">
<template #label>{{ i18n.ts.numberOfColumn }}</template>
<option :value="1">5</option>
<option :value="2">6</option>
<option :value="3">7</option>
<option :value="4">8</option>
<option :value="5">9</option>
</FormRadios>
<FormRadios v-model="reactionPickerHeight" class="_formBlock">
<template #label>{{ i18n.ts.height }}</template>
<option :value="1">{{ i18n.ts.small }}</option>
<option :value="2">{{ i18n.ts.medium }}</option>
<option :value="3">{{ i18n.ts.large }}</option>
<option :value="4">{{ i18n.ts.large }}+</option>
</FormRadios>
<FormSwitch
v-model="reactionPickerUseDrawerForMobile"
class="_formBlock"
>
{{ i18n.ts.useDrawerReactionPickerForMobile }}
<template #caption>{{ i18n.ts.needReloadToApply }}</template>
</FormSwitch>
<FormSection>
<div style="display: flex; gap: var(--margin); flex-wrap: wrap">
<FormButton inline @click="preview"
><i class="ph-eye ph-bold ph-lg"></i>
{{ i18n.ts.preview }}</FormButton
>
<FormButton inline danger @click="setDefault"
><i
class="ph-arrow-counter-clockwise ph-bold ph-lg"
></i>
{{ i18n.ts.default }}</FormButton
>
</div>
</FormSection>
</div>
<div v-else>
<FormSwitch
v-model="showEmojisInReactionNotifications"
class="_formBlock"
>
{{ i18n.ts.showEmojisInReactionNotifications }}
</FormSwitch>
</div>
</div> </div>
</template> </template>
@ -93,6 +111,17 @@ import { defaultStore } from "@/store";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { deepClone } from "@/scripts/clone"; import { deepClone } from "@/scripts/clone";
import { unisonReload } from "@/scripts/unison-reload";
async function reloadAsk() {
const { canceled } = await os.confirm({
type: "info",
text: i18n.ts.reloadToApplySetting,
});
if (canceled) return;
unisonReload();
}
let reactions = $ref(deepClone(defaultStore.state.reactions)); let reactions = $ref(deepClone(defaultStore.state.reactions));
@ -108,6 +137,12 @@ const reactionPickerHeight = $computed(
const reactionPickerUseDrawerForMobile = $computed( const reactionPickerUseDrawerForMobile = $computed(
defaultStore.makeGetterSetter("reactionPickerUseDrawerForMobile") defaultStore.makeGetterSetter("reactionPickerUseDrawerForMobile")
); );
const enableEmojiReactions = $computed(
defaultStore.makeGetterSetter("enableEmojiReactions")
);
const showEmojisInReactionNotifications = $computed(
defaultStore.makeGetterSetter("showEmojisInReactionNotifications")
);
function save() { function save() {
defaultStore.set("reactions", reactions); defaultStore.set("reactions", reactions);
@ -171,6 +206,10 @@ watch(
} }
); );
watch(enableEmojiReactions, async () => {
await reloadAsk();
});
const headerActions = $computed(() => []); const headerActions = $computed(() => []);
const headerTabs = $computed(() => []); const headerTabs = $computed(() => []);

View file

@ -1,24 +1,58 @@
<template> <template>
<MkStickyContainer> <MkStickyContainer>
<template #header <template #header
><MkPageHeader :actions="headerActions" :tabs="headerTabs" ><MkPageHeader
v-model:tab="tab"
:actions="headerActions"
:tabs="headerTabs"
:display-back-button="true"
/></template> /></template>
<MkSpacer :content-max="800"> <MkSpacer :content-max="800">
<XNotes class="_content" :pagination="pagination" /> <swiper
:modules="[Virtual]"
:space-between="20"
:virtual="true"
:allow-touch-move="
!(
deviceKind === 'desktop' &&
!defaultStore.state.swipeOnDesktop
)
"
@swiper="setSwiperRef"
@slide-change="onSlideChange"
>
<swiper-slide>
<XNotes ref="notes" :pagination="notesPagination" />
</swiper-slide>
<swiper-slide>
<XUserList
ref="users"
class="_gap"
:pagination="usersPagination"
/>
</swiper-slide>
</swiper>
</MkSpacer> </MkSpacer>
</MkStickyContainer> </MkStickyContainer>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed, watch, onMounted } from "vue";
import { Virtual } from "swiper";
import { Swiper, SwiperSlide } from "swiper/vue";
import XNotes from "@/components/MkNotes.vue"; import XNotes from "@/components/MkNotes.vue";
import XUserList from "@/components/MkUserList.vue";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { defaultStore } from "@/store";
import "swiper/scss";
import "swiper/scss/virtual";
const props = defineProps<{ const props = defineProps<{
tag: string; tag: string;
}>(); }>();
const pagination = { const notesPagination = {
endpoint: "notes/search-by-tag" as const, endpoint: "notes/search-by-tag" as const,
limit: 10, limit: 10,
params: computed(() => ({ params: computed(() => ({
@ -26,9 +60,52 @@ const pagination = {
})), })),
}; };
const usersPagination = {
endpoint: "users/search" as const,
limit: 10,
params: computed(() => ({
query: `#${props.tag}`,
origin: "combined",
})),
};
const tabs = ["notes", "users"];
let tab = $ref(tabs[0]);
watch($$(tab), () => syncSlide(tabs.indexOf(tab)));
const headerActions = $computed(() => []); const headerActions = $computed(() => []);
const headerTabs = $computed(() => []); const headerTabs = $computed(() => [
{
key: "notes",
icon: "ph-note ph-bold ph-lg",
title: i18n.ts.notes,
},
{
key: "users",
icon: "ph-users ph-bold ph-lg",
title: i18n.ts.users,
},
]);
let swiperRef = null;
function setSwiperRef(swiper) {
swiperRef = swiper;
syncSlide(tabs.indexOf(tab));
}
function onSlideChange() {
tab = tabs[swiperRef.activeIndex];
}
function syncSlide(index) {
swiperRef.slideTo(index);
}
onMounted(() => {
syncSlide(tabs.indexOf(swiperRef.activeIndex));
});
definePageMetadata( definePageMetadata(
computed(() => ({ computed(() => ({

View file

@ -353,18 +353,41 @@ const age = $computed(() => {
}); });
const timeForThem = $computed(() => { const timeForThem = $computed(() => {
const tzInfo = cityTimezones.lookupViaCity( const maybeCityNames = [
props.user.location!.replace(/\s.*/, "") props.user.location!,
); props.user
if (tzInfo.length == 0) return ""; .location!.replace(
const tz = tzInfo[0].timezone; /[^A-Za-z0-9ÁĆÉǴÍḰĹḾŃÓṔŔŚÚÝŹáćéǵíḱĺḿńóṕŕśúýź\-\'\.\s].*/,
const theirTime = new Date().toLocaleString("en-US", { ""
timeZone: tz, )
hour12: false, .trim(),
}); props.user.location!.replace(
return ` (${theirTime.split(",")[1].trim().split(":")[0]}:${theirTime /[^A-Za-zÁĆÉǴÍḰĹḾŃÓṔŔŚÚÝŹáćéǵíḱĺḿńóṕŕśúýź\-\'\.].*/,
.split(" ")[1] ""
.slice(-5, -3)})`; ),
props.user.location!.replace(
/[^A-Za-zÁĆÉǴÍḰĹḾŃÓṔŔŚÚÝŹáćéǵíḱĺḿńóṕŕśúýź].*/,
""
),
];
for (const city of maybeCityNames) {
let tzInfo = cityTimezones.lookupViaCity(city);
if (tzInfo.length == 0) continue;
const tz = tzInfo[0].timezone;
if (!tz) continue;
const theirTime = new Date().toLocaleString("en-US", {
timeZone: tz,
hour12: false,
});
return ` (${theirTime.split(",")[1].trim().split(":")[0]}:${theirTime
.split(" ")[1]
.slice(-5, -3)})`;
}
return "";
}); });
function menu(ev) { function menu(ev) {

View file

@ -38,6 +38,7 @@
class="logo" class="logo"
v-if="meta.logoImageUrl" v-if="meta.logoImageUrl"
:src="meta.logoImageUrl" :src="meta.logoImageUrl"
alt="logo"
/> />
<span v-else class="text">{{ instanceName }}</span> <span v-else class="text">{{ instanceName }}</span>
</h1> </h1>

View file

@ -6,7 +6,7 @@
v-bind:class="{ scroll: isScrolling }" v-bind:class="{ scroll: isScrolling }"
> >
<div v-for="note in notes" class="note"> <div v-for="note in notes" class="note">
<div class="content _panel"> <div class="content _panel" v-if="note.cw == null">
<div class="body"> <div class="body">
<MkA <MkA
v-if="note.replyId" v-if="note.replyId"

View file

@ -94,7 +94,13 @@ export function uploadFile(
// TODO: 消すのではなくて(ネットワーク的なエラーなら)再送できるようにしたい // TODO: 消すのではなくて(ネットワーク的なエラーなら)再送できるようにしたい
uploads.value = uploads.value.filter((x) => x.id !== id); uploads.value = uploads.value.filter((x) => x.id !== id);
if (ev.target?.response) { if (xhr.status === 413) {
alert({
type: "error",
title: i18n.ts.failedToUpload,
text: i18n.ts.cannotUploadBecauseExceedsFileSizeLimit,
});
} else if (ev.target?.response) {
const res = JSON.parse(ev.target.response); const res = JSON.parse(ev.target.response);
if (res.error?.id === "bec5bd69-fba3-43c9-b4fb-2894b66ad5d2") { if (res.error?.id === "bec5bd69-fba3-43c9-b4fb-2894b66ad5d2") {
alert({ alert({

View file

@ -294,6 +294,14 @@ export const defaultStore = markRaw(
where: "device", where: "device",
default: false, default: false,
}, },
enableEmojiReactions: {
where: "account",
default: true,
},
showEmojisInReactionNotifications: {
where: "account",
default: true,
},
}), }),
); );

View file

@ -70,6 +70,14 @@
> >
<i class="ph-caret-down ph-bold ph-lg"></i> <i class="ph-caret-down ph-bold ph-lg"></i>
</button> </button>
<button
v-if="deckStore.state.profile !== 'default'"
v-tooltip.noDelay.left="i18n.ts._deck.renameProfile"
class="_button button"
@click="renameProfile"
>
<i class="ph-pencil ph-bold ph-lg"></i>
</button>
<button <button
v-if="deckStore.state.profile !== 'default'" v-if="deckStore.state.profile !== 'default'"
v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile"
@ -161,6 +169,7 @@ import {
addColumn as addColumnToStore, addColumn as addColumnToStore,
loadDeck, loadDeck,
getProfiles, getProfiles,
renameProfile as renameProfile_,
deleteProfile as deleteProfile_, deleteProfile as deleteProfile_,
} from "./deck/deck-store"; } from "./deck/deck-store";
import DeckColumnCore from "@/ui/deck/column-core.vue"; import DeckColumnCore from "@/ui/deck/column-core.vue";
@ -319,6 +328,23 @@ function changeProfile(ev: MouseEvent) {
os.popupMenu(items, ev.currentTarget ?? ev.target); os.popupMenu(items, ev.currentTarget ?? ev.target);
} }
async function renameProfile() {
const { canceled, result: newProfileName } = await os.inputText({
title: i18n.ts._deck.renameProfile,
allowEmpty: false,
});
if (canceled) return;
const profiles = await getProfiles();
if (profiles.includes(newProfileName)) {
os.alert({ type: "error", text: i18n.ts._deck.nameAlreadyExists });
return;
}
await renameProfile_(deckStore.state.profile, newProfileName);
unisonReload();
}
async function deleteProfile() { async function deleteProfile() {
const { canceled } = await os.confirm({ const { canceled } = await os.confirm({
type: "warning", type: "warning",

View file

@ -115,6 +115,20 @@ export async function deleteProfile(key: string): Promise<any> {
}); });
} }
export async function renameProfile(oldKey: string, newKey: string) {
if (oldKey === newKey) return;
await api("i/registry/set", {
scope: ["client", "deck", "profiles"],
key: newKey,
value: { columns: deckStore.state.columns, layout: deckStore.state.layout },
});
deckStore.set("profile", newKey);
saveDeck();
deleteProfile(oldKey);
}
export function addColumn(column: Column) { export function addColumn(column: Column) {
if (column.name === undefined) column.name = null; if (column.name === undefined) column.name = null;
deckStore.push("columns", column); deckStore.push("columns", column);

View file

@ -10,8 +10,8 @@
}, },
"devDependencies": { "devDependencies": {
"@swc/cli": "^0.1.59", "@swc/cli": "^0.1.62",
"@swc/core": "^1.3.26", "@swc/core": "^1.3.50",
"@swc/core-android-arm64": "1.3.11", "@swc/core-android-arm64": "1.3.11",
"calckey-js": "workspace:*", "calckey-js": "workspace:*",
"idb-keyval": "^6.2.0", "idb-keyval": "^6.2.0",

View file

@ -22,6 +22,7 @@
"@unattributed@calckey.social", "@unattributed@calckey.social",
"@cody@mk.codingneko.com", "@cody@mk.codingneko.com",
"@kate@blahaj.zone", "@kate@blahaj.zone",
"@emtk@mkkey.net",
"Interkosmos Link" "Interkosmos Link"
] ]
} }

File diff suppressed because it is too large Load diff