Merge branch 'develop' into beta

This commit is contained in:
ThatOneCalculator 2023-04-25 09:18:38 -07:00
commit 77febea8e6
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_: "Ελληνικά"
monthAndDay: "{μήνας}/{ημέρα}"
monthAndDay: "{day}/{month}"
search: "Αναζήτηση"
notifications: "Ειδοποιήσεις"
username: "Όνομα μέλους"
password: "Κωδικός πρόσβασης"
forgotPassword: "Ξέχασα τον κωδικό πρόσβασης"
fetchingAsApObject: "Μαζεύοντας από το Fediverse..."
fetchingAsApObject: "Άντληση από το Fediverse"
ok: "Εντάξει"
gotIt: "Τό'πιασα!"
cancel: "Ακύρωση"
enterUsername: "Εισάγετε το όνομα μέλους"
renotedBy: "Κοινοποιήθηκε από {user}"
noNotes: "Δεν υπάρχουν σημειώματα"
enterUsername: "Εισαγωγή ονόματος μέλους"
renotedBy: "Προωθήθηκε από {user}"
noNotes: "Δεν υπάρχουν δημοσιεύσεις"
noNotifications: "Δεν υπάρχουν ειδοποιήσεις"
settings: "Ρυθμίσεις"
basicSettings: "Βασικές ρυθμίσεις"
otherSettings: "Άλλες ρυθμίσεις"
basicSettings: "Βασικές Ρυθμίσεις"
otherSettings: "Άλλες Ρυθμίσεις"
openInWindow: "Άνοιγμα σε παράθυρο"
profile: "Προφίλ"
timeline: "Χρονολόγιο"
@ -24,24 +23,25 @@ noAccountDescription: "Αυτό το μέλος δεν έχει γράψει β
login: "Σύνδεση"
loggingIn: "Συνδέεστε"
logout: "Αποσύνδεση"
signup: "Δημιουργία λογαριασμού"
signup: "Εγγραφή"
uploading: "Ανέβασμα..."
save: "Αποθήκευση"
users: "Μέλη"
addUser: "Προσθήκη μέλους"
favorite: "Προσθήκη στα αγαπημένα"
favorites: "Αγαπημένα"
unfavorite: "Αφαίρεση από αγαπημένα"
favorited: "Προστέθηκε στα αγαπημένα."
alreadyFavorited: "Έχει ήδη προστεθεί στα αγαπημένα."
cantFavorite: "Αδυναμία προσθήκης στα αγαπημένα."
favorite: "Προσθήκη στους σελιδοδείκτες"
favorites: "Σελιδοδείκτες"
unfavorite: "Αφαίρεση από τους σελιδοδείκτες"
favorited: "Προστέθηκε στους σελιδοδείκτες."
alreadyFavorited: "Έχει ήδη προστεθεί στους σελιδοδείκτες."
cantFavorite: "Αδυναμία προσθήκης στους σελιδοδείκτες."
pin: "Καρφίτσωμα στο προφίλ"
unpin: "Ξεκαρφίτσωμα από το προφίλ"
copyContent: "Αντιγραφή περιεχομένων"
copyLink: "Αντιγραφή συνδέσμου"
delete: "Διαγραφή"
deleteAndEdit: "Διαγραφή και επεξεργασία"
deleteAndEditConfirm: "Σίγουρα θέλετε να διαγράψετε αυτό το σημείωμα και να το επεξεργαστείτε; Θα χάσετε όλες τις αντιδράσεις, κοινοποιήσεις και απαντήσεις σε αυτό."
deleteAndEditConfirm: "Σίγουρα θέλετε να διαγράψετε αυτή τη δημοσίευση και να την\
\ επεξεργαστείτε; Θα χάσετε όλες τις αντιδράσεις, προωθήσεις και απαντήσεις σε αυτήν."
addToList: "Προσθήκη στη λίστα"
sendMessage: "Αποστολή μηνύματος"
copyUsername: "Αντιγραφή ονόματος μέλους"
@ -55,20 +55,22 @@ receiveFollowRequest: "Λάβατε αίτημα ακολούθησης"
followRequestAccepted: "Το αίτημα ακολούθησης έγινε δεκτό"
mention: "Επισήμανση"
mentions: "Επισημάνσεις"
directNotes: "Απευθείας σημειώματα"
importAndExport: "Εισαγωγή / Εξαγωγή"
directNotes: "Απευθείας μηνύματα"
importAndExport: "Εισαγωγή/Εξαγωγή Δεδομένων"
import: "Εισαγωγή"
export: "Εξαγωγή"
files: "Αρχεία"
download: "Λήψη"
driveFileDeleteConfirm: "Θέλετε σίγουρα να διαγράψετε το αρχείο \"{name}\"; Τα σημειώματα με αυτό το συνημμένο αρχείο επίσης θα διαγραφούν."
download: "Κατέβασμα"
driveFileDeleteConfirm: "Θέλετε σίγουρα να διαγράψετε το αρχείο \"{name}\"; Οι δημοσιεύσεις\
\ με αυτό το συνημμένο αρχείο επίσης θα διαγραφούν."
unfollowConfirm: "Θέλετε σίγουρα να σταματήσετε να ακολουθείτε το μέλος {name};"
exportRequested: "Ζητήσατε μία εξαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο. Επίσης θα προστεθεί στον Δίσκο σας μόλις ολοκληρωθεί."
importRequested: "Ζητήσατε μία εισαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο."
exportRequested: "Ζητήσατε μία εξαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο. Θα προστεθεί\
\ στον Αποθηκευτικό Χώρο σας μόλις ολοκληρωθεί."
importRequested: "Ζητήσατε μια εισαγωγή. Αυτό μπορεί να πάρει κάποιον χρόνο."
lists: "Λίστες"
noLists: "Δεν έχετε λίστες"
note: "Σημείωμα"
notes: "Σημειώματα"
note: "Δημοσίευση"
notes: "Δημοσιεύσεις"
following: "Ακολουθεί"
followers: "Ακολουθούν"
followsYou: "Σε ακολουθεί"
@ -78,69 +80,74 @@ error: "Σφάλμα"
somethingHappened: "Προέκυψε ένα σφάλμα"
retry: "Προσπάθεια ξανά"
pageLoadError: "Ένα σφάλμα προέκυψε φορτώνοντας τη σελίδα."
pageLoadErrorDescription: "Αυτό κανονικά προκαλείται από σφάλματα δικτύου ή από την προσωρινή μνήμη του προγράμματος περιήγησης. Δοκιμάστε να σβήσετε την προσωρινή μνήμη (cache) και ξαναδοκιμάστε μετά από λίγο."
serverIsDead: "Αυτός ο server δεν αποκρίνεται. Παρακαλώ περιμέντε λίγο και δοκιμάστε ξανά."
youShouldUpgradeClient: "Για να δείτε αυτή τη σελίδα, παρακαλώ επαναφορτώστε για να ενημερωθεί το πρόγραμμα."
pageLoadErrorDescription: "Αυτό κανονικά προκαλείται από σφάλματα δικτύου ή από την\
\ προσωρινή μνήμη του προγράμματος περιήγησης. Δοκιμάστε να σβήσετε την προσωρινή\
\ μνήμη (cache) και να δοκιμάσετε ξανά μετά από λίγο."
serverIsDead: "Αυτός ο διακομιστής (server) δεν αποκρίνεται. Παρακαλώ περιμένετε λίγο\
\ και δοκιμάστε ξανά."
youShouldUpgradeClient: "Για να δείτε αυτή τη σελίδα, παρακαλώ επαναφορτώστε για να\
\ γίνει ενημέρωση."
enterListName: "Πληκτρολογήστε ένα όνομα για τη λίστα"
privacy: "Ιδιωτικότητα"
makeFollowManuallyApprove: "Τα αιτήματα ακολούθησης χρειάζονται έγκριση"
defaultNoteVisibility: "Προεπιλεγμένη ορατότητα"
follow: "Ακολουθήστε"
followRequest: "Στείλτε αίτημα ακολούθησης"
followRequest: "Ακολουθήστε"
followRequests: "Αιτήματα ακολούθησης"
unfollow: "Να μην ακολουθώ"
followRequestPending: "Το αίτημα ακολούθησης εκκρεμεί"
enterEmoji: "Εισάγετε ένα emoji"
renote: "Κοινοποίηση σημειώματος"
unrenote: "Ακύρωση κοινοποίησης"
renoted: "Κοινοποιήθηκε."
cantRenote: "Αυτή η δημοσίευση δεν μπορεί να κοινοποιηθεί."
cantReRenote: "Μία κοινοποίηση δεν μπορεί να κοινοποιηθεί."
renote: "Προώθηση"
unrenote: "Αναίρεση προώθησης"
renoted: "Προωθήθηκε."
cantRenote: "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί."
cantReRenote: "Μία προώθηση δεν μπορεί να προωθηθεί."
quote: "Παράθεση"
pinnedNote: "Καρφιτσωμένο σημείωμα"
pinnedNote: "Καρφιτσωμένη δημοσίευση"
pinned: "Καρφίτσωμα στο προφίλ"
you: "Εσύ"
clickToShow: "Κάντε κλικ για εμφάνιση"
add: "Προσθέστε"
add: "Προσθήκη"
reaction: "Αντιδράσεις"
reactionSetting: "Αντιδράσεις για εμφάνιση στην επιλογή αντίδρασης"
reactionSettingDescription2: "Σύρετε για να αλλάξετε τη σειρά, κάντε κλικ για να διαγράψετε, πατήστε \"+\" για να προσθέσετε."
rememberNoteVisibility: "Θυμήσου τις ρυθμίσεις ορατότητας σημειώματος"
attachCancel: "Διαγραφή αρχείου"
reactionSetting: "Αντιδράσεις που θα εμφανίζονται στον επιλογέα"
reactionSettingDescription2: "Σύρετε για να αλλάξετε τη σειρά, κάντε κλικ για να διαγράψετε,\
\ πατήστε \"+\" για να προσθέσετε."
rememberNoteVisibility: "Θυμήσου τις ρυθμίσεις ορατότητας για τις δημοσιεύσεις"
attachCancel: "Αφαίρεση επισυναπτόμενου"
enterFileName: "Πληκτρολογήστε όνομα αρχείου"
mute: "Σίγαση"
unmute: "Άρση σίγασης"
unmute: "Διακοπή σίγασης"
block: "Μπλοκάρισμα"
unblock: "Άρση μπλοκαρίσματος"
unblock: "Διακοπή μπλοκαρίσματος"
suspend: "Αποβολή"
unsuspend: "Άρση αποβολής"
unsuspend: "Διακοπή αποβολής"
blockConfirm: "Θέλετε σίγουρα να μπλοκάρετε αυτόν τον λογαριασμό;"
unblockConfirm: "Θέλετε σίγουρα να ξεμπλοκάρετε αυτόν τον λογαριασμό;"
suspendConfirm: "Θέλετε σίγουρα να αποβάλλετε αυτόν τον λογαριασμό;"
suspendConfirm: "Θέλετε σίγουρα να αποβάλετε αυτόν τον λογαριασμό;"
unsuspendConfirm: "Θέλετε σίγουρα να άρετε την αποβολή αυτού του λογαριασμού;"
selectList: "Επιλέξτε μία λίστα"
selectAntenna: "Επιλέξτε μία αντένα"
selectWidget: "Επιλέξτε ένα μαραφέτι"
editWidgets: "Επεξεργασία μαραφετίων"
selectList: "Επιλέξτε μια λίστα"
selectAntenna: "Επιλέξτε μια αντένα"
selectWidget: "Επιλέξτε ένα πρόσθετο"
editWidgets: "Επεξεργασία πρόσθετων"
editWidgetsExit: "Ολοκληρώθηκε"
customEmojis: "Επιπλέον emoji"
customEmojis: "Προσαρμοσμένα Emoji"
emojiName: "Όνομα emoji"
addEmoji: "Προσθήκη emoji"
settingGuide: "Συνιστώμενες ρυθμίσεις"
flagAsBot: "Αυτός ο λογαριασμός είναι bot"
flagAsCat: "Αυτός ο λογαριασμός είναι γάτα"
addEmoji: "Προσθήκη"
settingGuide: "Προτεινόμενες ρυθμίσεις"
flagAsBot: "Δήλωση αυτού του λογαριασμού ως bot"
flagAsCat: "Είσαι γατί; \U0001F63A"
flagShowTimelineReplies: "Εμφάνιση απαντήσεων στο χρονολόγιο"
addAccount: "Προσθήκη λογαριασμού"
general: "Γενικές"
wallpaper: "Ταπετσαρία"
setWallpaper: "Ορισμός ταπετσαρίας"
removeWallpaper: "Διαγραφή ταπετσαρίας"
removeWallpaper: "Αφαίρεση ταπετσαρίας"
searchWith: "Αναζήτηση: {q}"
youHaveNoLists: "Δεν έχετε λίστες"
followConfirm: "Θέλετε σίγουρα να ακολουθήσετε τον λογαριασμό {name};"
host: "Φιλοξενεί"
host: "Φιλοξενεί (Host)"
selectUser: "Επιλέξτε ένα μέλος"
recipient: "Αποδέκτης-τρια"
recipient: "Αποδέκτης-τρια(-ες)"
annotation: "Σχόλια"
federation: "Ομοσπονδία"
storageUsage: "Χρήση χώρου"
@ -148,11 +155,11 @@ version: "Έκδοση"
metadata: "Μεταδεδομένα"
network: "Δίκτυο"
disk: "Δίσκος"
instanceInfo: "Πληροφορίες του instance"
instanceInfo: "Πληροφορίες Instance"
statistics: "Στατιστικά"
clearQueue: "Εκκαθάριση ουράς"
clearQueueConfirmTitle: "Θέλετε να διαγράψετε την ουρά;"
clearCachedFiles: "Εκκαθάριση προσωρινής μνήμης"
clearCachedFiles: "Εκκαθάριση προσωρινής μνήμης (cache)"
done: "Ολοκληρώθηκε"
attachFile: "Επισύναψη αρχείων"
more: "Περισσότερα!"
@ -166,12 +173,12 @@ messaging: "Συνομιλία"
upload: "Ανεβάστε"
fromDrive: "Από τον Αποθηκευτικό Χώρο"
fromUrl: "Από URL"
uploadFromUrl: "Ανεβάστε από URL"
explore: "Εξερευνήστε"
uploadFromUrl: "Ανέβασμα από URL"
explore: "Εξερεύνηση"
messageRead: "Διαβάστηκε"
startMessaging: "Ξεκινήστε μία συνομιλία"
startMessaging: "Ξεκινήστε μια νέα συνομιλία"
nUsersRead: "διαβάστηκε από {n}"
tos: "Όροι χρήσης"
tos: "Όροι Χρήσης"
start: "Ας αρχίσουμε"
home: "Κεντρικό"
activity: "Δραστηριότητα"
@ -180,8 +187,8 @@ birthday: "Γενέθλια"
registeredDate: "Έγινε μέλος στις"
location: "Τοποθεσία"
theme: "Θέματα"
light: "Ανοιχτόχρωμο"
dark: "Σκούρο"
light: "Φωτεινό"
dark: "Σκοτεινό"
drive: "Αποθηκευτικός Χώρος"
fileName: "Όνομα αρχείου"
selectFile: "Επιλέξτε ένα αρχείο"
@ -189,16 +196,16 @@ selectFiles: "Επιλέξτε αρχεία"
selectFolder: "Επιλέξτε φάκελο"
selectFolders: "Επιλέξτε φακέλους"
renameFile: "Μετονομασία αρχείου"
addFile: "Προσθήκη αρχείου"
addFile: "Προσθέστε ένα αρχείο"
emptyDrive: "Ο Αποθηκευτικός Χώρος σας είναι άδειος"
copyUrl: "Αντιγραφή URL"
rename: "Αλλαγή ονόματος"
avatar: "Εικονίδιο"
banner: "Πανό"
copyUrl: "Αντιγραφή διεύθυνσης URL"
rename: "Μετονομασία"
avatar: "Άβαταρ"
banner: "Εξώφυλλο"
reload: "Ανανέωση"
doNothing: "Αγνόηση"
watch: "Παρακολούθηση"
unwatch: "Τέλος παρακολούθησης"
unwatch: "Διακοπή παρακολούθησης"
accept: "Αποδοχή"
reject: "Απόρριψη"
normal: "Κανονικό"
@ -212,23 +219,23 @@ connectService: "Σύνδεση"
disconnectService: "Αποσύνδεση"
registration: "Εγγραφή"
pinnedPages: "Καρφιτσωμένες Σελίδες"
pinnedNotes: "Καρφιτσωμένα σημειώματα"
pinnedNotes: "Καρφιτσωμένες δημοσιεύσεις"
antennas: "Αντένες"
manageAntennas: "Διαχείριση αντενών"
manageAntennas: "Διαχείριση Αντενών"
name: "Όνομα"
antennaSource: "Πηγή αντένας"
antennaSource: "Πηγή Αντένας"
antennaKeywords: "Λέξεις-κλειδιά για παρακολούθηση"
antennaExcludeKeywords: "Λέξεις-κλειδιά για αποκλεισμό"
notifyAntenna: "Ειδοποίηση για νέα σημειώματα"
withFileAntenna: "Μόνο σημειώματα με αρχεία"
antennaExcludeKeywords: "Λέξεις-κλειδιά για εξαίρεση"
notifyAntenna: "Ειδοποίηση για νέες δημοσιεύσεις"
withFileAntenna: "Μόνο δημοσιεύσεις με αρχεία"
caseSensitive: "Διάκριση Πεζών-Κεφαλαίων"
popularTags: "Δημοφιλείς ετικέτες"
userList: "Λίστες"
about: "Πληροφορίες"
moderator: "Συντονιστής"
about: "Σχετικά με"
moderator: "Συντονιστής/στρια"
moderation: "Συντονισμός"
cacheClear: "Εκκαθάριση προσωρινής μνήμης"
markAsReadAllNotifications: "Όλες οι ειδοποιήσεις διαβάστηκαν"
cacheClear: "Εκκαθάριση προσωρινής μνήμης (cache)"
markAsReadAllNotifications: "Σημειώστε όλες τις ειδοποιήσεις ως διαβασμένες"
group: "Ομάδα"
groups: "Ομάδες"
createGroup: "Δημιουργία ομάδας"
@ -236,13 +243,13 @@ ownedGroups: "Οι ομάδες σας"
groupName: "Όνομα ομάδας"
members: "Μέλη"
transfer: "Μεταφορά"
messagingWithUser: "Ιδιωτική συνομιλία"
messagingWithUser: "Προσωπική συνομιλία"
messagingWithGroup: "Ομαδική συνομιλία"
title: "Τίτλος"
text: "Κείμενο"
enable: "Ενεργοποίηση"
next: "Επόμενο"
noteOf: "Σημείωμα από {user}"
noteOf: "Δημοσίευση από {user}"
inviteToGroup: "Πρόσκληση στην ομάδα"
quoteAttached: "Παράθεση"
signinRequired: "Παρακαλούμε δημιουργήστε λογαριασμό ή συνδεθείτε πριν συνεχίσετε"
@ -250,26 +257,26 @@ category: "Κατηγορία"
tags: "Ετικέτες"
createAccount: "Δημιουργία λογαριασμού"
local: "Τοπικό"
remote: "Απομακρυσμένo"
remote: "Απομακρυσμένο"
total: "Σύνολο"
appearance: "Εμφάνιση"
accountSettings: "Ρυθμίσεις λογαριασμού"
accountSettings: "Ρυθμίσεις Λογαριασμού"
sounds: "Ήχοι"
sound: "Ήχοι"
listen: "Ακρόαση"
showInPage: "Εμφάνιση στη σελίδα"
volume: "Ένταση"
masterVolume: "Κύρια ένταση"
masterVolume: "Κεντρική ένταση"
details: "Λεπτομέρειες"
install: "Εγκατάσταση"
uninstall: "Κατάργηση εγκατάστασης"
install: "Εγκαταστήστε"
uninstall: "Απεγκατάσταση"
manage: "Διαχείριση"
smtpHost: "Φιλοξενεί"
smtpHost: "Φιλοξενεί (Host)"
smtpUser: "Όνομα μέλους"
smtpPass: "Κωδικός πρόσβασης"
smtpPass: "Κωδικός"
notificationSetting: "Ρυθμίσεις ειδοποιήσεων"
notificationSettingDesc: "Επιλέξτε τους τύπους ειδοποιήσεων που εμφανίζονται"
switchUi: "Αλλαγή UI"
notificationSettingDesc: "Επιλέξτε τους τύπους ειδοποιήσεων για προβολή."
switchUi: "Διάταξη"
clip: "Κλιπ"
driveFilesCount: "Αριθμός αρχείων Αποθηκευτικού Χώρου"
driveUsage: "Χρήση Αποθηκευτικού Χώρου"
@ -293,7 +300,8 @@ manageAccounts: "Διαχείριση Λογαριασμών"
searchByGoogle: "Αναζήτηση"
file: "Αρχεία"
recommended: "Προτεινόμενα"
cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού Χώρου"
cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού\
\ Χώρου."
_email:
_follow:
title: "Έχετε ένα νέο ακόλουθο"
@ -327,15 +335,20 @@ _ago:
monthsAgo: "{n} μήνα(ες) πριν"
yearsAgo: "{n} έτος(η) πριν"
_permissions:
"write:drive": "Επεξεργαστείτε ή διαγράψτε τα αρχεία και τους φακέλους του Αποθηκευτικού Χώρου σας"
"read:favorites": "Δείτε τη λίστα των αγαπημένων σας"
"write:favorites": "Επεξεργαστείτε τη λίστα των αγαπημένων σας"
"write:drive": "Επεξεργαστείτε ή διαγράψτε τα αρχεία και τους φακέλους του Αποθηκευτικού\
\ Χώρου σας"
"read:favorites": "Δείτε τη λίστα με τους σελιδοδείκτες σας"
"write:favorites": "Επεξεργαστείτε τη λίστα με τους σελιδοδείκτες σας"
"read:messaging": "Δείτε τις συνομιλίες σας"
"write:messaging": "Γράψτε ή διαγράψτε μηνύματα συνομιλίας"
"read:notifications": "Δείτε τις ειδοποιήσεις σας"
"write:notifications": "Διαχειριστείτε τις ειδοποιήσεις σας"
"read:pages": "Δείτε τις Σελίδες σας"
"write:pages": "Επεξεργαστείτε ή διαγράψτε τις σελίδες σας"
"write:gallery-likes": Επεξεργασία της λίστας των αγαπημένων σας δημοσιεύσεων γκαλερί
"read:gallery": Δείτε την γκαλερί σας
"write:gallery": Επεξεργασία της γκαλερί σας
"read:gallery-likes": Δείτε τη λίστα των αγαπημένων σας δημοσιεύσεων γκαλερί
_antennaSources:
all: "Όλα τα σημειώματα"
homeTimeline: "Σημειώματα από μέλη που ακολουθείτε"
@ -368,6 +381,7 @@ _visibility:
_profile:
name: "Όνομα"
username: "Όνομα μέλους"
changeAvatar: Αλλαγή άβαταρ
_exportOrImport:
allNotes: "Όλα τα σημειώματα"
followingList: "Ακολουθεί"
@ -398,11 +412,409 @@ _notification:
reply: "Απάντηση"
renote: "Κοινοποίηση σημειώματος"
_deck:
widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία μαραφετίων\" στο μενού και προσθέστε μαραφέτι."
widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία πρόσθετων\" στο μενού και\
\ προσθέστε μαραφέτι."
_columns:
widgets: "Μαραφέτια"
widgets: "Πρόσθετα"
notifications: "Ειδοποιήσεις"
tl: "Χρονολόγιο"
antenna: "Αντένες"
list: "Λίστα"
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"
headlineMisskey: "An open source, decentralized social media platform that's free forever! 🚀"
introMisskey: "Welcome! Calckey is an open source, decentralized social media platform that's free forever! 🚀"
headlineMisskey: "An open source, decentralized social media platform that's free\
\ forever! \U0001F680"
introMisskey: "Welcome! Calckey is an open source, decentralized social media platform\
\ that's free forever! \U0001F680"
monthAndDay: "{month}/{day}"
search: "Search"
notifications: "Notifications"
@ -46,7 +47,8 @@ copyContent: "Copy contents"
copyLink: "Copy link"
delete: "Delete"
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"
sendMessage: "Send a message"
copyUsername: "Copy username"
@ -66,9 +68,11 @@ import: "Import"
export: "Export"
files: "Files"
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}?"
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."
lists: "Lists"
noLists: "You don't have any lists"
@ -83,7 +87,8 @@ error: "Error"
somethingHappened: "An error has occurred"
retry: "Retry"
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."
youShouldUpgradeClient: "To view this page, please refresh to update your client."
enterListName: "Enter a name for the list"
@ -97,9 +102,6 @@ unfollow: "Unfollow"
followRequestPending: "Follow request pending"
enterEmoji: "Enter an emoji"
renote: "Boost"
renoteAsUnlisted: "Boost (Unlisted)"
renoteToFollowers: "Boost (Followers)"
renoteToRecipients: "Boost (Recipients)"
unrenote: "Take back boost"
renoted: "Boosted."
cantRenote: "This post can't be boosted."
@ -112,6 +114,8 @@ clickToShow: "Click to show"
sensitive: "NSFW"
add: "Add"
reaction: "Reactions"
enableEmojiReactions: "Enable emoji reactions"
showEmojisInReactionNotifications: "Show emojis in reaction notifications"
reactionSetting: "Reactions to show in the reaction picker"
reactionSettingDescription2: "Drag to reorder, click to delete, press \"+\" to add."
rememberNoteVisibility: "Remember post visibility settings"
@ -144,15 +148,21 @@ emojiUrl: "Emoji URL"
addEmoji: "Add"
settingGuide: "Recommended settings"
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"
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."
flagAsCat: "Are you a cat? 😺"
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."
flagAsCat: "Are you a cat? \U0001F63A"
flagAsCatDescription: "You'll get cat ears and speak like a cat!"
flagSpeakAsCat: "Speak as a cat"
flagSpeakAsCatDescription: "Your posts will get nyanified when in cat mode"
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"
addAccount: "Add account"
loginFailed: "Failed to sign in"
@ -166,7 +176,10 @@ searchWith: "Search: {q}"
youHaveNoLists: "You don't have any lists"
followConfirm: "Are you sure that you want to follow {name}?"
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"
selectUser: "Select a user"
selectInstance: "Select an instance"
@ -198,13 +211,17 @@ instanceInfo: "Instance Information"
statistics: "Statistics"
clearQueue: "Clear 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"
clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote files?"
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"
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"
mutedUsers: "Muted users"
blockedUsers: "Blocked users"
@ -254,7 +271,8 @@ saved: "Saved"
messaging: "Chat"
upload: "Upload"
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"
fromUrl: "From URL"
uploadFromUrl: "Upload from a URL"
@ -304,7 +322,8 @@ unableToDelete: "Unable to delete"
inputNewFileName: "Enter a new filename"
inputNewDescription: "Enter new caption"
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."
copyUrl: "Copy URL"
rename: "Rename"
@ -339,7 +358,8 @@ disconnectService: "Disconnect"
enableLocalTimeline: "Enable local timeline"
enableGlobalTimeline: "Enable global 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"
enableRegistration: "Enable new user registration"
invite: "Invite"
@ -351,9 +371,11 @@ bannerUrl: "Banner image URL"
backgroundImageUrl: "Background image URL"
basicInfo: "Basic info"
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"
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"
pinnedNotes: "Pinned posts"
hcaptcha: "hCaptcha"
@ -364,14 +386,17 @@ recaptcha: "reCAPTCHA"
enableRecaptcha: "Enable reCAPTCHA"
recaptchaSiteKey: "Site 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"
manageAntennas: "Manage Antennas"
name: "Name"
antennaSource: "Antenna source"
antennaKeywords: "Keywords to listen to"
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"
withFileAntenna: "Only posts with files"
enableServiceworker: "Enable Push-Notifications for your Browser"
@ -501,19 +526,27 @@ showFeaturedNotesInTimeline: "Show featured posts in timelines"
objectStorage: "Object Storage"
useObjectStorage: "Use object storage"
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"
objectStorageBucketDesc: "Please specify the bucket name used at your provider."
objectStoragePrefix: "Prefix"
objectStoragePrefixDesc: "Files will be stored under directories with this prefix."
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"
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"
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"
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"
serverLogs: "Server logs"
deleteAll: "Delete all"
@ -541,7 +574,9 @@ sort: "Sort"
ascendingOrder: "Ascending"
descendingOrder: "Descending"
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"
script: "Script"
disablePagesScript: "Disable AiScript on Pages"
@ -549,11 +584,14 @@ updateRemoteUser: "Update remote user information"
deleteAllFiles: "Delete all files"
deleteAllFilesConfirm: "Are you sure that you want to delete all files?"
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."
userSilenced: "This user is being silenced."
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"
divider: "Divider"
addItem: "Add Item"
@ -594,12 +632,14 @@ permission: "Permissions"
enableAll: "Enable all"
disableAll: "Disable all"
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"
edit: "Edit"
emailServer: "Email server"
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"
emailAddress: "Email address"
smtpConfig: "SMTP Server Configuration"
@ -613,7 +653,8 @@ smtpSecureInfo: "Turn this off when using STARTTLS"
testEmail: "Test email delivery"
wordMute: "Word mute"
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"
userSaysSomething: "{name} said something"
userSaysSomethingReason: "{name} said {reason}"
@ -630,10 +671,13 @@ create: "Create"
notificationSetting: "Notification settings"
notificationSettingDesc: "Select the types of notification to display."
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"
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."
fileIdOrUrl: "File ID or URL"
behavior: "Behavior"
@ -641,13 +685,15 @@ sample: "Sample"
abuseReports: "Reports"
reportAbuse: "Report"
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."
reporter: "Reporter"
reporteeOrigin: "Reportee Origin"
reporterOrigin: "Reporter Origin"
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"
abuseMarkAsResolved: "Mark report as resolved"
openInNewTab: "Open in new tab"
@ -665,9 +711,11 @@ createNew: "Create new"
optional: "Optional"
createNewClip: "Create new clip"
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"
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"
accountInfo: "Account Info"
notesCount: "Number of posts"
@ -686,12 +734,16 @@ no: "No"
driveFilesCount: "Number of Drive files"
driveUsage: "Drive space usage"
noCrawle: "Reject crawler indexing"
noCrawleDescription: "Ask search engines to not index your profile page, posts, Pages, 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."
noCrawleDescription: "Ask search engines to not index your profile page, posts, Pages,\
\ 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"
loadRawImages: "Load original images instead of showing thumbnails"
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"
emailVerified: "Email has been verified"
noteFavoritesCount: "Number of bookmarked posts"
@ -703,7 +755,8 @@ clips: "Clips"
experimentalFeatures: "Experimental features"
developer: "Developer"
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"
duplicate: "Duplicate"
left: "Left"
@ -718,7 +771,10 @@ onlineUsersCount: "{n} users are online"
nUsers: "{n} Users"
nNotes: "{n} Posts"
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"
backgroundColor: "Background color"
accentColor: "Accent color"
@ -757,14 +813,17 @@ unlikeConfirm: "Really remove your like?"
fullView: "Full view"
quitFullView: "Exit full view"
addDescription: "Add description"
userPagePinTip: "You can display posts here by selecting \"Pin to profile\" from the menu of individual posts."
notSpecifiedMentionWarning: "This post contains mentions of users not included as recipients"
userPagePinTip: "You can display posts here by selecting \"Pin to profile\" from the\
\ menu of individual posts."
notSpecifiedMentionWarning: "This post contains mentions of users not included as\
\ recipients"
info: "About"
userInfo: "User information"
unknown: "Unknown"
onlineStatus: "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"
active: "Active"
offline: "Offline"
@ -801,16 +860,19 @@ secureMode: "Secure Mode (Authorized Fetch)"
instanceSecurity: "Instance Security"
secureModeInfo: "When requesting from other instances, do not send back without proof."
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"
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"
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"
recommended: "Recommended"
squareAvatars: "Display squared avatars"
seperateRenoteQuote: "Seperate boost and quote buttons"
seperateRenoteQuote: "Separate boost and quote buttons"
sent: "Sent"
received: "Received"
searchResult: "Search results"
@ -823,7 +885,9 @@ whatIsNew: "Show changes"
translate: "Translate"
translatedFrom: "Translated from {x}"
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"
keepCw: "Keep content warnings"
pubSub: "Pub/Sub Accounts"
@ -840,12 +904,14 @@ filter: "Filter"
controlPanel: "Control Panel"
manageAccounts: "Manage Accounts"
makeReactionsPublic: "Set reaction history to public"
makeReactionsPublicDescription: "This will make the list of all your past reactions publicly visible."
makeReactionsPublicDescription: "This will make the list of all your past reactions\
\ publicly visible."
classic: "Classic"
muteThread: "Mute thread"
unmuteThread: "Unmute thread"
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"
deleteAccountConfirm: "This will irreversibly delete your account. Proceed?"
incorrectPassword: "Incorrect password."
@ -888,14 +954,16 @@ noEmailServerWarning: "Email server not configured."
thereIsUnresolvedAbuseReportWarning: "There are unsolved reports."
check: "Check"
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."
isSystemAccount: "An account created and automatically operated by the system."
typeToConfirm: "Please enter {x} to confirm"
deleteAccount: "Delete account"
document: "Documentation"
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?"
lastActiveDate: "Last used at"
statusbar: "Status bar"
@ -912,12 +980,19 @@ sensitiveMediaDetection: "Detection of NSFW media"
localOnly: "Local only"
remoteOnly: "Remote only"
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."
cannotUploadBecauseExceedsFileSizeLimit: "This file could not be uploaded because\
\ it exceeds the maximum allowed size."
beta: "Beta"
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."
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."
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."
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"
shuffle: "Shuffle"
account: "Account"
@ -927,18 +1002,27 @@ subscribePushNotification: "Enable push notifications"
unsubscribePushNotification: "Disable push notifications"
pushNotificationAlreadySubscribed: "Push notifications are already enabled"
pushNotificationNotSupported: "Your browser or instance does not support push notifications"
sendPushNotificationReadMessage: "Delete push notifications once the relevant notifications 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."
sendPushNotificationReadMessage: "Delete push notifications once the relevant notifications\
\ 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"
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)"
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)"
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"
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"
splash: "Splash Screen"
updateAvailable: "There might be an update available!"
@ -950,29 +1034,51 @@ migration: "Migration"
moveTo: "Move current account to new account"
moveToLabel: "Account you're moving to:"
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"
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"
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."
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"
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"
license: "License"
indexPosts: "Index Posts"
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"
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"
noteId: "Post ID"
_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"
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"
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"
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:
used: "This email address is already being used"
format: "The format of this email address is invalid"
@ -986,11 +1092,15 @@ _ffVisibility:
_signup:
almostThere: "Almost there"
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: "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."
sendEmail: "Once account deletion has been completed, an email will be sent to the email address registered to this 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."
sendEmail: "Once account deletion has been completed, an email will be sent to the\
\ email address registered to this account."
requestAccountDelete: "Request account deletion"
started: "Deletion has been started."
inProgress: "Deletion is currently in progress"
@ -998,9 +1108,12 @@ _ad:
back: "Back"
reduceFrequencyOfThisAd: "Show this ad less"
_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."
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."
enterEmail: "Enter the email address you used to register. A link with which you\
\ can reset your password will then be sent to it."
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:
my: "My Gallery"
liked: "Liked Posts"
@ -1023,12 +1136,15 @@ _preferencesBackups:
save: "Save changes"
inputName: "Please enter a name for this backup"
cannotSave: "Saving failed"
nameAlreadyExists: "A backup called \"{name}\" already exists. Please enter a different name."
applyConfirm: "Do you really want to apply the \"{name}\" backup to this device? Existing settings of this device will be overwritten."
nameAlreadyExists: "A backup called \"{name}\" already exists. Please enter a different\
\ 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}?"
deleteConfirm: "Delete the {name} backup?"
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}"
updatedAt: "Updated at: {date} {time}"
cannotLoad: "Loading failed"
@ -1040,13 +1156,15 @@ _registry:
domain: "Domain"
createKey: "Create key"
_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"
allContributors: "All contributors"
source: "Source code"
translation: "Translate 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"
_nsfw:
respect: "Hide NSFW media"
@ -1054,7 +1172,8 @@ _nsfw:
force: "Hide all media"
_mfm:
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"
mention: "Mention"
mentionDescription: "You can specify a user by using an At-Symbol and a username."
@ -1073,7 +1192,8 @@ _mfm:
inlineCode: "Code (Inline)"
inlineCodeDescription: "Displays inline syntax highlighting for (program) code."
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)"
inlineMathDescription: "Display math formulas (KaTeX) in-line"
blockMath: "Math (Block)"
@ -1081,7 +1201,8 @@ _mfm:
quote: "Quote"
quoteDescription: "Displays content as a quote."
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"
searchDescription: "Displays a search box with pre-entered text."
flip: "Flip"
@ -1117,7 +1238,8 @@ _mfm:
rotate: "Rotate"
rotateDescription: "Turns content by a specified angle."
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:
none: "Never show"
remote: "Show for remote users"
@ -1147,15 +1269,19 @@ _menuDisplay:
hide: "Hide"
_wordMute:
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."
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"
hard: "Hard"
mutedNotes: "Muted posts"
_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"
title: "Hides posts from listed instances."
heading: "List of instances to be muted"
@ -1261,21 +1387,35 @@ _tutorial:
step1_1: "Welcome!"
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_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_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_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_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_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."
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_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_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_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_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_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!"
_2fa:
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:"
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."
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:
"read:account": "View your account information"
"write:account": "Edit your account information"
@ -1322,7 +1464,8 @@ _permissions:
"write:gallery-likes": "Edit your list of liked gallery posts"
_auth:
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"
pleaseGoBack: "Please go back to the application"
callback: "Returning to the application"
@ -1424,12 +1567,14 @@ _profile:
youCanIncludeHashtags: "You can also include hashtags in your bio."
metadata: "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"
metadataContent: "Content"
changeAvatar: "Change avatar"
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:
allNotes: "All posts"
followingList: "Followed users"
@ -1747,7 +1892,8 @@ _pages:
_for:
arg1: "Number of times to repeat"
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!"
types:
string: "Text"
@ -1809,10 +1955,14 @@ _deck:
popRight: "Pop column to the right"
profile: "Workspace"
newProfile: "New workspace"
renameProfile: "Rename workspace"
deleteProfile: "Delete workspace"
nameAlreadyExists: "This workspace name already exists."
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."
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add a widget."
introduction2: "Click on the + on the right of the screen to add new colums whenever\
\ you want."
widgetsIntroduction: "Please select \"Edit widgets\" in the column menu and add\
\ a widget."
_columns:
main: "Main"
widgets: "Widgets"

View file

@ -1,7 +1,8 @@
---
_lang_: "Español"
headlineMisskey: "Red conectada por notas"
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! 🚀"
headlineMisskey: "¡Un proyecto de código abierto y una plataforma de medios de comunicación\
\ 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}"
search: "Buscar"
notifications: "Notificaciones"
@ -14,7 +15,7 @@ gotIt: "¡Lo tengo!"
cancel: "Cancelar"
enterUsername: "Introduce el nombre de usuario"
renotedBy: "Renotado por {user}"
noNotes: "No hay notas"
noNotes: "No hay publicaciones"
noNotifications: "No hay notificaciones"
instance: "Instancia"
settings: "Configuración"
@ -23,7 +24,7 @@ otherSettings: "Configuración avanzada"
openInWindow: "Abrir en una ventana"
profile: "Perfil"
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"
loggingIn: "Iniciando sesión"
logout: "Cerrar sesión"
@ -36,7 +37,7 @@ favorite: "Añadir a favoritos"
favorites: "Favoritos"
unfavorite: "Quitar de 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."
pin: "Fijar al perfil"
unpin: "Desfijar"
@ -44,7 +45,8 @@ copyContent: "Copiar contenido"
copyLink: "Copiar enlace"
delete: "Borrar"
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"
sendMessage: "Enviar un mensaje"
copyUsername: "Copiar nombre de usuario"
@ -58,20 +60,22 @@ receiveFollowRequest: "Recibiste una solicitud de seguimiento"
followRequestAccepted: "La solicitud de seguimiento fue aceptada"
mention: "Menciones"
mentions: "Menciones"
directNotes: "Notas directas"
directNotes: "Mensajes Directos"
importAndExport: "Importar y Exportar"
import: "Importar"
export: "Exportar"
files: "Archivos"
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}?"
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."
lists: "Listas"
noLists: "No tiene listas"
note: "Notas"
notes: "Notas"
note: "Publicación"
notes: "Publicaciones"
following: "Siguiendo"
followers: "Seguidores"
followsYou: "Te sigue"
@ -80,10 +84,12 @@ manageLists: "Administrar listas"
error: "Error"
somethingHappened: "Ocurrió un error"
retry: "Reintentar"
pageLoadError: "Error al leer 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."
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."
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"
privacy: "Privacidad"
makeFollowManuallyApprove: "Aprobar manualmente las solicitudes de seguimiento"
@ -94,13 +100,13 @@ followRequests: "Solicitudes de seguimiento"
unfollow: "Dejar de seguir"
followRequestPending: "Solicitudes de seguimiento pendiente"
enterEmoji: "Ingresar emojis"
renote: "Renotar"
unrenote: "Quitar renota"
renoted: "Renotado"
cantRenote: "No se puede renotar este post"
cantReRenote: "No se puede renotar una renota"
renote: "Impulsar"
unrenote: "Quitar impulso"
renoted: "Impulsado."
cantRenote: "No se puede impulsar esta publicación."
cantReRenote: "No se puede impulsar un impulso."
quote: "Citar"
pinnedNote: "Nota fijada"
pinnedNote: "Publicación fijada"
pinned: "Fijar al perfil"
you: "Tú"
clickToShow: "Click para ver"
@ -108,8 +114,9 @@ sensitive: "Marcado como sensible"
add: "Agregar"
reaction: "Reacción"
reactionSetting: "Reacciones para mostrar en el menú de reacciones"
reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete la tecla + para añadir."
rememberNoteVisibility: "Recordar visibilidad"
reactionSettingDescription2: "Arrastre para reordenar, click para borrar, apriete\
\ la tecla + para añadir."
rememberNoteVisibility: "Recordar la configuración de visibilidad de la publicación"
attachCancel: "Quitar adjunto"
markAsSensitive: "Marcar como sensible"
unmarkAsSensitive: "Desmarcar como sensible"
@ -137,16 +144,23 @@ emojiUrl: "URL de la imágen del emoji"
addEmoji: "Agregar emoji"
settingGuide: "Configuración sugerida"
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"
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"
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"
flagShowTimelineRepliesDescription: "Cuando se marca, la línea de tiempo muestra respuestas a otras notas además de las notas del usuario"
autoAcceptFollowed: "Aceptar automáticamente las solicitudes de seguimiento de los usuarios que sigues"
flagShowTimelineRepliesDescription: "Cuando se marca, la línea de tiempo muestra respuestas\
\ 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"
loginFailed: "Error al iniciar sesión."
loginFailed: "Error al iniciar sesión"
showOnRemote: "Ver en una instancia remota"
general: "General"
wallpaper: "Fondo de pantalla"
@ -156,7 +170,11 @@ searchWith: "Buscar: {q}"
youHaveNoLists: "No tienes listas"
followConfirm: "¿Desea seguir a {name}?"
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"
selectUser: "Elegir usuario"
recipient: "Recipiente"
@ -187,21 +205,24 @@ instanceInfo: "información de la instancia"
statistics: "Estadísticas"
clearQueue: "Limpiar 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é"
clearCachedFilesConfirm: "¿Desea borrar todos los archivos remotos cacheados?"
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"
mutedUsers: "Usuarios silenciados"
blockedUsers: "Usuarios bloqueados"
noUsers: "No hay usuarios"
editProfile: "Editar perfil"
noteDeleteConfirm: "¿Desea borrar esta nota?"
pinLimitExceeded: "Ya no se pueden fijar más posts"
intro: "¡La instalación de Misskey ha terminado! Crea el usuario administrador."
noteDeleteConfirm: "¿Desea borrar esta publicación?"
pinLimitExceeded: "Ya no se pueden fijar más publicaciones"
intro: "¡La instalación de Calckey ha terminado! Crea el usuario administrador."
done: "Terminado"
processing: "Procesando"
processing: "Procesando..."
preview: "Vista previa"
default: "Predeterminado"
defaultValueIs: "Predeterminado"
@ -219,7 +240,7 @@ instanceFollowers: "Seguidores de la instancia"
instanceUsers: "Usuarios de la instancia"
changePassword: "Cambiar contraseña"
security: "Seguridad"
retypedNotMatch: "No hay coincidencia"
retypedNotMatch: "No hay coincidencia."
currentPassword: "Contraseña actual"
newPassword: "Contraseña nueva"
newPasswordRetype: "Contraseña nueva (repetir)"
@ -240,7 +261,9 @@ saved: "Guardado"
messaging: "Chat"
upload: "Subir"
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"
fromUrl: "Desde la URL"
uploadFromUrl: "Subir desde una URL"
@ -256,7 +279,7 @@ agreeTo: "De acuerdo con {0}"
tos: "Términos de uso"
start: "Comenzar"
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"
images: "Imágenes"
birthday: "Fecha de nacimiento"
@ -289,7 +312,8 @@ unableToDelete: "No se puede borrar"
inputNewFileName: "Ingrese un nuevo nombre de archivo"
inputNewDescription: "Ingrese nueva descripción"
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."
copyUrl: "Copiar URL"
rename: "Renombrar"
@ -323,7 +347,8 @@ connectService: "Conectar"
disconnectService: "Desconectar"
enableLocalTimeline: "Habilitar linea de tiempo local"
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"
enableRegistration: "Permitir nuevos registros"
invite: "Invitar"
@ -335,9 +360,11 @@ bannerUrl: "URL de la imagen del banner"
backgroundImageUrl: "URL de la imagen de fondo"
basicInfo: "Información básica"
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"
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"
pinnedNotes: "Nota fijada"
hcaptcha: "hCaptcha"
@ -348,14 +375,17 @@ recaptcha: "reCAPTCHA"
enableRecaptcha: "activar reCAPTCHA"
recaptchaSiteKey: "Clave del sitio"
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"
manageAntennas: "Administrar antenas"
name: "Nombre"
antennaSource: "Origen de la antena"
antennaKeywords: "Palabras clave para recibir"
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"
withFileAntenna: "Sólo notas con archivos adjuntados"
enableServiceworker: "Activar ServiceWorker"
@ -378,7 +408,7 @@ exploreFediverse: "Explorar fediverso"
popularTags: "Etiquetas populares"
userList: "Lista"
about: "Información"
aboutMisskey: "Sobre Misskey"
aboutMisskey: "Sobre Calckey"
administrator: "Administrador"
token: "Token"
twoStepAuthentication: "Autenticación de dos factores"
@ -443,7 +473,8 @@ strongPassword: "Muy buena contraseña"
passwordMatched: "Correcto"
passwordNotMatched: "Las contraseñas no son las mismas"
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"
or: "O"
language: "Idioma"
@ -453,7 +484,8 @@ aboutX: "Acerca de {x}"
useOsNativeEmojis: "Usa los emojis nativos de la plataforma"
disableDrawer: "No mostrar los menús en cajones"
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"
signinHistory: "Historial de ingresos"
disableAnimatedMfm: "Deshabilitar MFM que tiene animaciones"
@ -484,19 +516,28 @@ showFeaturedNotesInTimeline: "Mostrar notas destacadas en la línea de tiempo"
objectStorage: "Almacenamiento de objetos"
useObjectStorage: "Usar almacenamiento de objetos"
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"
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"
objectStoragePrefixDesc: "Los archivos se almacenarán en el directorio de este prefijo."
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"
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"
objectStorageUseSSLDesc: "Desactive esto si no va a usar HTTPS para la conexión API"
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 "
serverLogs: "Registros del servidor"
deleteAll: "Eliminar todos"
@ -524,7 +565,8 @@ sort: "Ordenar"
ascendingOrder: "Ascendente"
descendingOrder: "Descendente"
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"
script: "Script"
disablePagesScript: "Deshabilitar AiScript en Páginas"
@ -532,11 +574,14 @@ updateRemoteUser: "Actualizar información de usuario remoto"
deleteAllFiles: "Borrar todos los archivos"
deleteAllFilesConfirm: "¿Desea borrar todos los archivos?"
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."
userSilenced: "Este usuario ha sido silenciado."
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ú"
divider: "Divisor"
addItem: "Agregar elemento"
@ -590,13 +635,15 @@ smtpHost: "Host"
smtpPort: "Puerto"
smtpUser: "Nombre de usuario"
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"
smtpSecureInfo: "Apagar cuando se use STARTTLS"
testEmail: "Prueba de envío"
wordMute: "Silenciar palabras"
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"
userSaysSomething: "{name} dijo algo"
makeActive: "Activar"
@ -612,10 +659,13 @@ create: "Crear"
notificationSetting: "Ajustes de Notificaciones"
notificationSettingDesc: "Por favor elija el tipo de notificación a mostrar"
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"
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."
fileIdOrUrl: "Id del archivo o URL"
behavior: "Comportamiento"
@ -623,13 +673,15 @@ sample: "Muestra"
abuseReports: "Reportes"
reportAbuse: "Reportar"
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."
reporter: "Reportador"
reporteeOrigin: "Reportar a"
reporterOrigin: "Origen del reporte"
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"
abuseMarkAsResolved: "Marcar reporte como resuelto"
openInNewTab: "Abrir en una Nueva Pestaña"
@ -647,9 +699,11 @@ createNew: "Crear"
optional: "Opcional"
createNewClip: "Crear clip nuevo"
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"
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"
accountInfo: "Información de la Cuenta"
notesCount: "Cantidad de notas"
@ -668,12 +722,18 @@ no: "No"
driveFilesCount: "Cantidad de archivos en el drive"
driveUsage: "Uso del drive"
noCrawle: "Rechazar indexación del crawler"
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas, páginas, etc."
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"
noCrawleDescription: "Pedir a los motores de búsqueda que no indexen tu perfil, notas,\
\ páginas, etc."
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"
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"
emailVerified: "Su dirección de correo electrónico ha sido verificada."
noteFavoritesCount: "Número de notas favoritas"
@ -685,14 +745,16 @@ clips: "Clip"
experimentalFeatures: "Características experimentales"
developer: "Desarrolladores"
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"
duplicate: "Duplicar"
left: "Izquierda"
center: "Centrar"
wide: "Ancho"
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"
showTitlebar: "Mostrar la barra de título"
clearCache: "Limpiar caché"
@ -700,7 +762,11 @@ onlineUsersCount: "{n} usuarios en línea"
nUsers: "{n} Usuarios"
nNotes: "{n} Notas"
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"
backgroundColor: "Fondo"
accentColor: "Acento"
@ -728,7 +794,8 @@ receiveAnnouncementFromInstance: "Recibir notificaciones de la instancia"
emailNotification: "Notificaciones por correo electrónico"
publish: "Publicar"
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"
jumpToSpecifiedDate: "Saltar a una fecha específica"
showingPastTimeline: "Mostrar líneas de tiempo antiguas"
@ -739,14 +806,16 @@ unlikeConfirm: "¿Quitar como favorito?"
fullView: "Vista completa"
quitFullView: "quitar vista completa"
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"
info: "Información"
userInfo: "Información del usuario"
unknown: "Desconocido"
onlineStatus: "En línea"
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"
active: "Activo"
offline: "Sin conexión"
@ -781,7 +850,8 @@ emailNotConfiguredWarning: "No se ha configurado una dirección de correo electr
ratio: "Proporción"
previewNoteText: "Mostrar vista preliminar"
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"
squareAvatars: "Mostrar iconos cuadrados"
sent: "Enviar"
@ -791,12 +861,14 @@ hashtags: "Hashtag"
troubleshooting: "Solución de problemas"
useBlurEffect: "Utilizar efecto de desenfoque en la interfaz de usuario"
learnMore: "Ver más"
misskeyUpdated: Misskey ha sido actualizado!"
misskeyUpdated: Calckey ha sido actualizado!"
whatIsNew: "Mostrar cambios"
translate: "Traducir"
translatedFrom: "Traducido de {x}"
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"
keepCw: "Mantener la advertencia de contenido"
pubSub: "Cuentas Pub/Sub"
@ -806,18 +878,21 @@ unresolved: "Sin resolver"
breakFollow: "Dejar de seguir"
itsOn: "¡Está encendido!"
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"
filter: "Filtro"
controlPanel: "Panel de control"
manageAccounts: "Administrar cuenta"
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"
muteThread: "Ocultar hilo"
unmuteThread: "Mostrar hilo"
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"
deleteAccountConfirm: "La cuenta será borrada. ¿Está seguro?"
incorrectPassword: "La contraseña es incorrecta"
@ -858,14 +933,16 @@ thereIsUnresolvedAbuseReportWarning: "Hay reportes sin resolver"
recommended: "Recomendado"
check: "Verificar"
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."
isSystemAccount: "Cuenta creada y operada automáticamente por el sistema"
typeToConfirm: "Ingrese {x} para confirmar"
deleteAccount: "Borrar cuenta"
document: "Documento"
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?"
lastActiveDate: "Utilizado por última vez el"
statusbar: "Barra de estado"
@ -882,42 +959,59 @@ sensitiveMediaDetection: "Detección de contenido NSFW"
localOnly: "Solo local"
remoteOnly: "Sólo remoto"
failedToUpload: "La subida falló"
cannotUploadBecauseInappropriate: "Este archivo no se puede subir debido a que algunas partes han sido detectadas comoNSFW."
cannotUploadBecauseNoFreeSpace: "La subida falló debido a falta de espacio libre en la unidad del usuario."
cannotUploadBecauseInappropriate: "Este archivo no se puede subir debido a que algunas\
\ partes han sido detectadas comoNSFW."
cannotUploadBecauseNoFreeSpace: "La subida falló debido a falta de espacio libre en\
\ la unidad del usuario."
beta: "Beta"
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."
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."
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."
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"
shuffle: "Aleatorio"
account: "Cuentas"
move: "Mover"
_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"
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"
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"
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:
used: "Ya fue usado"
format: "Formato no válido."
disposable: "No es un correo reutilizable"
format: "El formato de este correo electrónico no es válido"
disposable: "No se pueden utilizar direcciones de correo electrónico desechables"
mx: "Servidor de correo inválido"
smtp: "Servidor de correo no disponible"
_ffVisibility:
public: "Publicar"
public: "Público"
followers: "Visible solo para seguidores"
private: "Privado"
_signup:
almostThere: "Ya falta poco"
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: "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."
sendEmail: "Cuando se termine de borrar la cuenta, se enviará un correo a la dirección usada para el registro."
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."
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."
started: "El proceso de eliminación ha comenzado."
inProgress: "La eliminación está en proceso."
@ -925,9 +1019,12 @@ _ad:
back: "Deseleccionar"
reduceFrequencyOfThisAd: "Mostrar menos este anuncio."
_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."
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:
my: "Mi galería"
liked: "Publicaciones que me gustan"
@ -950,12 +1047,15 @@ _preferencesBackups:
save: "Guardar cambios"
inputName: "Por favor, ingresa un nombre para este respaldo"
cannotSave: "Fallo al guardar"
nameAlreadyExists: "Un respaldo llamado \"{name}\" ya existe. Por favor ingresa un nombre diferente"
applyConfirm: "¿Realmente quieres aplicar los cambios desde el archivo \"{name}\" a este dispositivo? Las configuraciones existentes serán sobreescritas. "
nameAlreadyExists: "Un respaldo llamado \"{name}\" ya existe. Por favor ingresa\
\ 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}\"?"
deleteConfirm: "¿Borrar el respaldo \"{name}\"?"
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}"
updatedAt: "Actualizado: {date} {time}"
cannotLoad: "La carga falló"
@ -967,24 +1067,29 @@ _registry:
domain: "Dominio"
createKey: "Crear una llave"
_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"
allContributors: "Todos los colaboradores"
source: "Código fuente"
translation: "Traducir Misskey"
donate: "Donar a Misskey"
morePatrons: "Muchas más personas nos apoyan. Muchas gracias🥰"
patrons: "Patrocinadores"
translation: "Traducir Calckey"
donate: "Donar a Calckey"
morePatrons: "También apreciamos el apoyo de muchos más que no están enlistados\
\ aquí. ¡Gracias! \U0001F970"
patrons: "Mecenas de Calckey"
_nsfw:
respect: "Ocultar medios NSFW"
ignore: "No esconder medios NSFW "
force: "Ocultar todos los medios"
_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."
dummy: "Misskey expande el mundo de la Fediverso"
intro: "MFM es un lenguaje de marcado dedicado que se puede usar en varios lugares\
\ 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"
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"
hashtagDescription: "Puede especificar un hashtag con un numeral y el texto."
url: "URL"
@ -1000,7 +1105,8 @@ _mfm:
inlineCode: "Código (insertado)"
inlineCodeDescription: "Muestra el código de un programa resaltando su sintaxis"
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)"
inlineMathDescription: "Muestra fórmulas (KaTeX) insertadas"
blockMath: "Fórmula (bloque)"
@ -1012,7 +1118,8 @@ _mfm:
search: "Buscar"
searchDescription: "Muestra una caja de búsqueda con texto pre-escrito"
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)"
jellyDescription: "Aplica un efecto de animación tipo gelatina"
tada: "Animación (tadá)"
@ -1034,7 +1141,8 @@ _mfm:
x4: "Totalmente grande"
x4Description: "Muestra el contenido totalmente grande"
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"
fontDescription: "Elegir la fuente del contenido"
rainbow: "Arcoíris"
@ -1044,7 +1152,8 @@ _mfm:
rotate: "Rotar"
rotateDescription: "Rota el contenido a un ángulo especificado."
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:
none: "No mostrar"
remote: "Mostrar a usuarios remotos"
@ -1053,6 +1162,7 @@ _serverDisconnectedBehavior:
reload: "Recargar automáticamente"
dialog: "Mostrar diálogo de advertencia"
quiet: "Advertencia discreta"
nothing: Hacer nada
_channel:
create: "Crear canal"
edit: "Editar canal"
@ -1070,15 +1180,20 @@ _menuDisplay:
hide: "Ocultar"
_wordMute:
muteWords: "Palabras que silenciar"
muteWordsDescription: "Separar con espacios indica una declaracion And, separar con lineas nuevas indica una declaracion Or。"
muteWordsDescription2: "Encerrar las palabras clave entre numerales para usar expresiones regulares"
muteWordsDescription: "Separar con espacios indica una declaracion And, separar\
\ 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"
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"
hard: "Duro"
mutedNotes: "Notas silenciadas"
_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"
title: "Oculta las notas de las instancias listadas."
heading: "Instancias a silenciar"
@ -1184,32 +1299,47 @@ _tutorial:
step1_1: "¡Bienvenido!"
step1_2: "Vamos a configurarte. Estarás listo y funcionando en poco tiempo"
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_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_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_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_4: "La línea de tiempo Local {icon} es donde puedes ver las publicaciones de todos los demás en esta instancia."
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."
step5_3: "La línea de tiempo Inicio {icon} es donde puedes ver las publicaciones\
\ de tus seguidores."
step5_4: "La línea de tiempo Local {icon} es donde puedes ver las publicaciones\
\ de todos los demás en esta instancia."
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_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_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_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_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!"
_2fa:
alreadyRegistered: "Ya has completado la configuración."
registerDevice: "Registrar dispositivo"
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."
step2Url: "En una aplicación de escritorio se puede ingresar la siguiente URL:"
step3: "Para terminar, ingrese el token mostrado en la aplicación."
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:
"read:account": "Ver 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"
_auth:
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"
pleaseGoBack: "Por favor, vuelve a la aplicación"
callback: "Volviendo a la aplicación"
@ -1287,6 +1418,9 @@ _widgets:
serverMetric: "Estadísticas del servidor"
aiscript: "Consola de AiScript"
aichan: "indigo"
userList: Lista Usuarios
_userList:
chooseList: Seleccione una lista
_cw:
hide: "Ocultar"
show: "Ver más"
@ -1348,6 +1482,8 @@ _profile:
metadataContent: "Contenido"
changeAvatar: "Cambiar avatar"
changeBanner: "Cambiar banner"
locationDescription: Si ingresas tu ciudad primero, el tiempo local tuyo será visible
para otros usuarios.
_exportOrImport:
allNotes: "Todas las notas"
followingList: "Siguiendo"
@ -1387,6 +1523,7 @@ _timelines:
local: "Local"
social: "Social"
global: "Global"
recommended: Recomendado
_pages:
newPage: "Crear página"
editPage: "Editar página"
@ -1633,7 +1770,8 @@ _pages:
_seedRandomPick:
arg1: "Semilla"
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:
arg1: "Lista de texto"
pick: "Elegir de la lista"
@ -1664,7 +1802,8 @@ _pages:
_for:
arg1: "Cantidad de repeticiones"
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"
types:
string: "Texto"
@ -1728,8 +1867,10 @@ _deck:
newProfile: "Nuevo perfil"
deleteProfile: "Eliminar perfil"
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."
widgetsIntroduction: "Por favor selecciona \"Editar Widgets\" en el menú columna y agrega un widget."
introduction2: "Presiona en la + de la derecha de la pantalla para añadir nuevas\
\ columnas donde quieras."
widgetsIntroduction: "Por favor selecciona \"Editar Widgets\" en el menú columna\
\ y agrega un widget."
_columns:
main: "Principal"
widgets: "Widgets"
@ -1739,3 +1880,51 @@ _deck:
list: "Listas"
mentions: "Menciones"
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_: "日本語"
headlineMisskey: "ずっと無料でオープンソースの非中央集権型ソーシャルメディアプラットフォーム🚀"
introMisskey: "ようこそCalckeyは、オープンソースの非中央集権型ソーシャルメディアプラットフォームです。\nいま起こっていることを共有したり、あなたについて皆に発信しましょう📡\n「リアクション」機能で、皆の投稿に素早く反応を追加できます👍\n新しい世界を探検しよう🚀"
headlineMisskey: "ずっと無料でオープンソースの非中央集権型ソーシャルメディアプラットフォーム\U0001F680"
introMisskey: "ようこそCalckeyは、オープンソースの非中央集権型ソーシャルメディアプラットフォームです。\nいま起こっていることを共有したり、あなたについて皆に発信しましょう\U0001F4E1\
\n「リアクション」機能で、皆の投稿に素早く反応を追加できます\U0001F44D\n新しい世界を探検しよう\U0001F680"
monthAndDay: "{month}月 {day}日"
search: "検索"
notifications: "通知"
@ -67,7 +67,7 @@ export: "エクスポート"
files: "ファイル"
download: "ダウンロード"
driveFileDeleteConfirm: "ファイル「{name}」を削除しますか?このファイルを添付した投稿も消えます。"
unfollowConfirm: "{name}のフォローを解除しますか?"
unfollowConfirm: "{name}さんのフォローを解除しますか?"
exportRequested: "エクスポートをリクエストしました。これには時間がかかる場合があります。エクスポートが終わると、「ドライブ」に追加されます。"
importRequested: "インポートをリクエストしました。これには時間がかかる場合があります。"
lists: "リスト"
@ -97,9 +97,6 @@ unfollow: "フォロー解除"
followRequestPending: "フォロー許可待ち"
enterEmoji: "絵文字を入力"
renote: "ブースト"
renoteAsUnlisted: "未収載でブースト"
renoteToFollowers: "フォロワー限定でブースト"
renoteToRecipients: "宛先のユーザーにブースト"
unrenote: "ブースト解除"
renoted: "ブーストしました。"
cantRenote: "この投稿はブーストできません。"
@ -112,6 +109,8 @@ clickToShow: "クリックして表示"
sensitive: "閲覧注意"
add: "追加"
reaction: "リアクション"
enableEmojiReactions: "絵文字リアクションを有効にする"
showEmojisInReactionNotifications: "自分の投稿に対するリアクションの通知で絵文字を表示する"
reactionSetting: "ピッカーに表示するリアクション"
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。"
rememberNoteVisibility: "公開範囲を記憶する"
@ -128,7 +127,7 @@ unblock: "ブロック解除"
suspend: "凍結"
unsuspend: "解凍"
blockConfirm: "ブロックしますか?"
unblockConfirm: "ブロック解除しますか?"
unblockConfirm: "ブロック解除しますか?"
suspendConfirm: "凍結しますか?"
unsuspendConfirm: "解凍しますか?"
selectList: "リストを選択"
@ -147,7 +146,7 @@ cacheRemoteFiles: "リモートのファイルをキャッシュする"
cacheRemoteFilesDescription: "この設定を無効にすると、リモートファイルをキャッシュせず直リンクします。サーバーのストレージを節約できますが、サムネイルが生成されないので通信量が増加します。"
flagAsBot: "Botとして設定"
flagAsBotDescription: "このアカウントがBotである場合は、この設定をオンにします。オンにすると、反応の連鎖を防ぐためのフラグとして他の開発者に役立ったり、Calckeyのシステム上での扱いがBotに合ったものになります。"
flagAsCat: "あなたは…猫?😺"
flagAsCat: "あなたは…猫?\U0001F63A"
flagAsCatDescription: "このアカウントが猫であることを示す猫モードを有効にするには、このフラグをオンにします。"
flagSpeakAsCat: "猫語で話す"
flagSpeakAsCatDescription: "猫モードが有効の場合にオンにすると、あなたの投稿の「な」を「にゃ」に変換します。"
@ -383,7 +382,7 @@ withFiles: "ファイル付き"
silence: "サイレンス"
silenceConfirm: "サイレンスしますか?"
unsilence: "サイレンス解除"
unsilenceConfirm: "サイレンス解除しますか?"
unsilenceConfirm: "サイレンス解除しますか?"
popularUsers: "人気のユーザー"
recentlyUpdatedUsers: "最近投稿したユーザー"
recentlyRegisteredUsers: "最近登録したユーザー"
@ -499,7 +498,8 @@ showFeaturedNotesInTimeline: "タイムラインにおすすめの投稿を表
objectStorage: "オブジェクトストレージ"
useObjectStorage: "オブジェクトストレージを使用"
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"
objectStorageBucketDesc: "使用サービスのbucket名を指定してください。"
objectStoragePrefix: "Prefix"
@ -702,7 +702,7 @@ experimentalFeatures: "実験的機能"
developer: "開発者"
makeExplorable: "アカウントを見つけやすくする"
makeExplorableDescription: "オフにすると、「みつける」にアカウントが載らなくなります。"
showGapBetweenNotesInTimeline: "タイムラインの投稿を離して表示"
showGapBetweenNotesInTimeline: "タイムラインの投稿を離して表示する"
duplicate: "複製"
left: "左"
center: "中央"
@ -751,7 +751,7 @@ showingPastTimeline: "過去のタイムラインを表示しています"
clear: "クリア"
markAllAsRead: "全て既読にする"
goBack: "戻る"
unlikeConfirm: "いいね解除しますか?"
unlikeConfirm: "いいね解除しますか?"
fullView: "フルビュー"
quitFullView: "フルビュー解除"
addDescription: "説明を追加"
@ -830,7 +830,7 @@ lastCommunication: "直近の通信"
resolved: "解決済み"
unresolved: "未解決"
breakFollow: "フォロワーを解除"
breakFollowConfirm: "フォロワー除しますか?"
breakFollowConfirm: "フォロワーから削除しますか?"
itsOn: "オンになっています"
itsOff: "オフになっています"
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
@ -913,6 +913,7 @@ remoteOnly: "リモートのみ"
failedToUpload: "アップロード失敗"
cannotUploadBecauseInappropriate: "不適切な内容を含む可能性があると判定されたためアップロードできません。"
cannotUploadBecauseNoFreeSpace: "ドライブの空き容量が無いためアップロードできません。"
cannotUploadBecauseExceedsFileSizeLimit: "ファイルサイズの制限を超えているためアップロードできません。"
beta: "ベータ"
enableAutoSensitive: "自動NSFW判定"
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。"
@ -933,7 +934,8 @@ adminCustomCssWarn: "この設定は、それが何をするものであるか
customMOTD: "カスタムMOTD(スプラッシュスクリーンメッセージ)"
customMOTDDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたMOTD(スプラッシュスクリーン)用のカスタムメッセージ"
customSplashIcons: "カスタムスプラッシュスクリーンアイコン"
customSplashIconsDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたカスタムスプラッシュスクリーンアイコンの URL。画像は静的なURLで、できればすべて192x192にリサイズしてください。"
customSplashIconsDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたカスタムスプラッシュスクリーンアイコンの\
\ URL。画像は静的なURLで、できればすべて192x192にリサイズしてください。"
showUpdates: "Calckeyの更新時にポップアップを表示する"
recommendedInstances: "おすすめインスタンス"
recommendedInstancesDescription: "おすすめタイムラインに表示される、改行で区切られたインスタンス。`https://`を追加しないでください。ドメインのみを追加してください。"
@ -952,14 +954,17 @@ moveAccountDescription: "この操作は取り消せません。まずは引っ
moveFrom: "別のアカウントからこのアカウントに引っ越す"
moveFromLabel: "引っ越し元のアカウント:"
moveFromDescription: "別のアカウントからこのアカウントにフォロワーを引き継いで引っ越したい場合、ここでエイリアスを作成しておく必要があります。必ず引っ越しを実行する前に作成してください!引っ越し元のアカウントをこのように入力してください:@person@instance.com"
migrationConfirm: "本当にこのアカウントを {account} に引っ越しますか?一度引っ越しを行うと取り消せず、二度とこのアカウントを元の状態で使用できなくなります。\nまた、引っ越し先のアカウントでエイリアスを作成したことを確認してください。"
migrationConfirm: "本当にこのアカウントを {account} に引っ越しますか?一度引っ越しを行うと取り消せず、二度とこのアカウントを元の状態で使用できなくなります。\n\
また、引っ越し先のアカウントでエイリアスを作成したことを確認してください。"
defaultReaction: "リモートとローカルの投稿に対するデフォルトの絵文字リアクション"
license: "ライセンス"
indexPosts: "投稿をインデックス"
indexFrom: "この投稿ID以降をインデックスする空白で全ての投稿を指定します"
indexNotice: "インデックスを開始しました。完了まで時間がかかる場合があるため、少なくとも1時間はサーバーを再起動しないでください。"
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マクロを有効にする"
_sensitiveMediaDetection:
@ -1043,7 +1048,7 @@ _aboutMisskey:
source: "ソースコード"
translation: "Calckeyを翻訳"
donate: "Calckeyに寄付"
morePatrons: "他にも多くの方が支援してくれています。ありがとうございます! 🥰"
morePatrons: "他にも多くの方が支援してくれています。ありがとうございます! \U0001F970"
patrons: "支援者"
_nsfw:
respect: "閲覧注意のメディアは隠す"
@ -1260,7 +1265,8 @@ _tutorial:
step2_1: "最初に、あなたのプロフィールを作りましょう。"
step2_2: "プロフィールを設定することで、他の人があなたの投稿を見たり、フォローしたりするときの助けになります。"
step3_1: "それでは、何人かフォローしてみましょう!"
step3_2: "あなたのホームとソーシャルタイムラインは、あなたが誰をフォローしているかで決まります。まずは、いくつかのアカウントをフォローしてみましょう。\nプロフィールの右上にある丸いボタンをクリックするとフォローできます。"
step3_2: "あなたのホームとソーシャルタイムラインは、あなたが誰をフォローしているかで決まります。まずは、いくつかのアカウントをフォローしてみましょう。\n\
プロフィールの右上にある丸い+ボタンをクリックするとフォローできます。"
step4_1: "投稿してみましょう!"
step4_2: "最初は{introduction}に投稿したり、シンプルに「こんにちは、アカウント作ってみました!」などの投稿をする人もいます。"
step5_1: "タイムライン、タイムラインだらけ!"
@ -1426,7 +1432,7 @@ _profile:
metadataContent: "内容"
changeAvatar: "アバター画像を変更"
changeBanner: "バナー画像を変更"
locationDescription: "正しく入力すると、あなたの現地時間が他のユーザーに表示されます。"
locationDescription: "英語表記の都市名から始まる内容を入力すると、現地時間がユーザーページに表示されます。"
_exportOrImport:
allNotes: "全ての投稿"
followingList: "フォロー"
@ -1806,7 +1812,9 @@ _deck:
popRight: "右に出す"
profile: "ワークスペース"
newProfile: "新規ワークスペース"
renameProfile: "ワークスペース名を変更"
deleteProfile: "ワークスペースを削除"
nameAlreadyExists: "この名前のワークスペースは既に存在します。"
introduction: "カラムを組み合わせて自分だけのインターフェイスを作りましょう!"
introduction2: "画面の右にある + を押して、いつでもカラムを追加できます。"
widgetsIntroduction: "カラムのメニューから、「ウィジェットの編集」を選択してウィジェットを追加してください"
@ -1836,3 +1844,6 @@ _apps:
mona: "Mona"
theDesk: "TheDesk"
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: "敏感内容"
add: "添加"
reaction: "回应"
enableEmojiReaction: "启用表情符号回应"
showEmojisInReactionNotifications: "在回应通知中显示表情符号"
reactionSetting: "在选择器中显示的回应"
reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。"
rememberNoteVisibility: "保存上次设置的可见性"
@ -1731,7 +1733,9 @@ _deck:
popRight: "向右弹出"
profile: "配置文件"
newProfile: "新建配置文件"
renameProfile: "重命名配置文件"
deleteProfile: "删除配置文件"
nameAlreadyExists: "该配置文件名已存在。"
introduction: "将各列进行组合以创建您自己的界面!"
introduction2: "您可以随时通过屏幕右侧的 + 来添加列"
widgetsIntroduction: "从列菜单中,选择“小工具编辑”来添加小工具"

View file

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

View file

@ -1,12 +1,12 @@
{
"name": "calckey",
"version": "13.2.0-beta6",
"version": "13.2.0-beta7",
"codename": "aqua",
"repository": {
"type": "git",
"url": "https://codeberg.org/calckey/calckey.git"
},
"packageManager": "pnpm@8.2.0",
"packageManager": "pnpm@8.3.1",
"private": true,
"scripts": {
"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/koa": "^4.6.4",
"@bull-board/ui": "^4.6.4",
"@calckey/megalodon": "5.1.23",
"@calckey/megalodon": "5.1.24",
"@discordapp/twemoji": "14.0.2",
"@elastic/elasticsearch": "7.17.0",
"@koa/cors": "3.4.3",
@ -75,11 +75,9 @@
"koa": "2.13.4",
"koa-body": "^6.0.1",
"koa-bodyparser": "4.3.0",
"koa-favicon": "2.1.0",
"koa-json-body": "5.3.0",
"koa-logger": "3.2.1",
"koa-mount": "4.0.0",
"koa-remove-trailing-slashes": "2.0.3",
"koa-send": "5.0.1",
"koa-slow": "2.1.0",
"koa-views": "7.0.2",
@ -117,7 +115,7 @@
"sonic-channel": "^1.3.1",
"speakeasy": "2.0.0",
"stringz": "2.1.0",
"summaly": "2.7.0",
"summaly": "github:misskey-dev/summaly",
"syslog-pro": "1.0.0",
"systeminformation": "5.16.9",
"tesseract.js": "^3.0.3",
@ -133,8 +131,8 @@
"xev": "3.0.2"
},
"devDependencies": {
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.26",
"@swc/cli": "^0.1.62",
"@swc/core": "^1.3.50",
"@types/bcryptjs": "2.4.2",
"@types/bull": "3.15.9",
"@types/cbor": "6.0.0",

View file

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

View file

@ -37,6 +37,11 @@ export const meta = {
code: "FORBIDDEN",
id: "f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba",
},
cannot_find: {
message: "Cannot find the following.",
code: "CANNOT_FIND",
id: "7a55f0d7-8e06-4a7e-9c77-ee7d59b25a82",
}
},
} as const;
@ -97,7 +102,7 @@ export default define(meta, paramDef, async (ps, me) => {
followerId: me.id,
});
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) => {
const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
const accessTokens = ctx.request.headers.authorization;

View file

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

View file

@ -10,7 +10,6 @@ import Router from "@koa/router";
import mount from "koa-mount";
import koaLogger from "koa-logger";
import * as slow from "koa-slow";
import { IsNull } from "typeorm";
import config from "@/config/index.js";
import Logger from "@/services/logger.js";
@ -30,7 +29,6 @@ import proxyServer from "./proxy/index.js";
import webServer from "./web/index.js";
import { initializeStreamingServer } from "./api/streaming.js";
import { koaBody } from "koa-body";
import removeTrailingSlash from "koa-remove-trailing-slashes";
import { v4 as uuid } from "uuid";
export const serverLogger = new Logger("server", "gray", false);
@ -39,7 +37,12 @@ export const serverLogger = new Logger("server", "gray", false);
const app = new Koa();
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 || "")) {
// Logger

View file

@ -8,13 +8,11 @@ import { readFileSync } from "node:fs";
import Koa from "koa";
import Router from "@koa/router";
import send from "koa-send";
import favicon from "koa-favicon";
import views from "koa-views";
import sharp from "sharp";
import { createBullBoard } from "@bull-board/api";
import { BullAdapter } from "@bull-board/api/bullAdapter.js";
import { KoaAdapter } from "@bull-board/koa";
import { In, IsNull } from "typeorm";
import { fetchMeta } from "@/misc/fetch-meta.js";
import config from "@/config/index.js";
@ -98,8 +96,14 @@ app.use(
}),
);
// Serve favicon
app.use(favicon(`${_dirname}/../../../assets/favicon.ico`));
// Favicon Router
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
app.use(async (ctx, next) => {

View file

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

View file

@ -1,7 +1,13 @@
<template>
<button class="nrvgflfu _button" @click.stop="toggle">
<b>{{ modelValue ? i18n.ts._cw.hide : i18n.ts._cw.show }}</b>
<span v-if="!modelValue">{{ label }}</span>
<button
class="_button"
: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>
</template>
@ -30,7 +36,8 @@ const label = computed(() => {
? [i18n.t("_cw.files", { count: props.note.files.length })]
: [],
props.note.poll != null ? [i18n.ts.poll] : [],
] as string[][]).join(" / ");
props.note.renote != null ? [i18n.ts.quoteAttached] : [],
] as string[][]).join(", ");
});
const toggle = () => {
@ -39,37 +46,25 @@ const toggle = () => {
</script>
<style lang="scss" scoped>
.nrvgflfu {
position: relative;
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);
}
._button {
font-weight: 700;
> span {
margin-left: 4px;
&:before {
content: "(";
}
&:after {
content: ")";
background: var(--cwBg) !important;
color: var(--cwFg);
transition: background 0.2s, color 0.2s;
> span {
font-weight: 500;
&::before {
content: "(";
}
&::after {
content: ")";
}
}
}
&:hover > span {
background: var(--cwFg) !important;
color: var(--cwBg) !important;
}
}
</style>

View file

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

View file

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

View file

@ -10,11 +10,11 @@
:class="{ renote: isRenote }"
>
<MkNoteSub
v-if="appearNote.reply"
v-if="appearNote.reply && !detailedView"
:note="appearNote.reply"
class="reply-to"
/>
<div class="note-context" @click="noteClick">
<div v-if="!detailedView" class="note-context" @click="noteClick">
<div class="line"></div>
<div v-if="appearNote._prId_" class="info">
<i class="ph-megaphone-simple-bold ph-lg"></i>
@ -77,93 +77,31 @@
/>
</div>
<div class="body">
<p v-if="appearNote.cw != null" class="cw">
<Mfm
v-if="appearNote.cw != ''"
class="text"
:text="appearNote.cw"
:author="appearNote.user"
:custom-emojis="appearNote.emojis"
:i="$i"
/>
<br />
<XCwButton v-model="showContent" :note="appearNote" />
</p>
<div
v-show="appearNote.cw == null || showContent"
class="content"
:class="{ collapsed, isLong }"
>
<div class="text">
<MkSubNoteContent
class="text"
:note="appearNote"
:detailed="true"
:detailedView="detailedView"
:parentId="appearNote.parentId"
@push="(e) => router.push(notePage(e))"
></MkSubNoteContent>
<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
v-if="appearNote.text"
:text="appearNote.text"
:text="translation.text"
:author="appearNote.user"
:i="$i"
: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 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>
<MkA
v-if="appearNote.channel && !inChannel"
@ -174,8 +112,14 @@
{{ appearNote.channel.name }}</MkA
>
</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>
<XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer"
:note="appearNote"
/>
@ -195,14 +139,32 @@
:note="appearNote"
: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
v-if="appearNote.myReaction == null"
v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton"
class="button"
:note="appearNote"
/>
<button
v-if="appearNote.myReaction == null"
v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button"
@ -211,7 +173,10 @@
<i class="ph-smiley ph-bold ph-lg"></i>
</button>
<button
v-if="appearNote.myReaction != null"
v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton"
class="button _button reacted"
@click="undoReact(appearNote)"
@ -255,6 +220,7 @@ import * as mfm from "mfm-js";
import type { Ref } from "vue";
import type * as misskey from "calckey-js";
import MkNoteSub from "@/components/MkNoteSub.vue";
import MkSubNoteContent from "./MkSubNoteContent.vue";
import XNoteHeader from "@/components/MkNoteHeader.vue";
import XNoteSimple from "@/components/MkNoteSimple.vue";
import XMediaList from "@/components/MkMediaList.vue";
@ -263,6 +229,7 @@ import XPoll from "@/components/MkPoll.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue";
import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue";
import MkVisibility from "@/components/MkVisibility.vue";
@ -274,7 +241,6 @@ import { userPage } from "@/filters/user";
import * as os from "@/os";
import { defaultStore, noteViewInterruptors } from "@/store";
import { reactionPicker } from "@/scripts/reaction-picker";
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
import { $i } from "@/account";
import { i18n } from "@/i18n";
import { getNoteMenu } from "@/scripts/get-note-menu";
@ -287,6 +253,7 @@ const router = useRouter();
const props = defineProps<{
note: misskey.entities.Note;
pinned?: boolean;
detailedView?: boolean;
}>();
const inChannel = inject("inChannel", null);
@ -321,18 +288,11 @@ let appearNote = $computed(() =>
);
const isMyRenote = $i && $i.id === note.userId;
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 muted = ref(getWordMute(appearNote, $i, defaultStore.state.mutedWords));
const translation = ref(null);
const translating = ref(false);
const urls = appearNote.text
? extractUrlFromMfm(mfm.parse(appearNote.text)).slice(0, 5)
: null;
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
const keymap = {
r: () => reply(true),
@ -479,7 +439,7 @@ function focusAfter() {
}
function noteClick(e) {
if (document.getSelection().type === "Range") {
if (document.getSelection().type === "Range" || props.detailedView) {
e.stopPropagation();
} else {
router.push(notePage(appearNote));
@ -666,123 +626,24 @@ function readPromo() {
> .body {
margin-top: 0.7em;
> .cw {
cursor: default;
display: block;
margin: 0;
padding: 0;
overflow-wrap: break-word;
> .text {
margin-right: 8px;
}
}
> .content {
&.isLong {
> .showLess {
width: 100%;
margin-top: 1em;
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 {
> .translation {
border: solid 0.5px var(--divider);
border-radius: var(--radius);
padding: 12px;
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);
}
}
> .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);
}
}
}
@ -792,13 +653,18 @@ function readPromo() {
font-size: 80%;
}
}
> .info {
margin-block: 16px;
opacity: 0.7;
font-size: 0.9em;
}
> .footer {
position: relative;
z-index: 2;
display: flex;
flex-wrap: wrap;
pointer-events: none; // Allow clicking anything w/out pointer-events: all; to open post
margin-top: 0.4em;
> .button {
margin: 0;
padding: 8px;

View file

@ -20,224 +20,16 @@
:note="appearNote.reply"
class="reply-to"
/>
<div v-if="isRenote" class="renote">
<MkAvatar class="avatar" :user="note.user" />
<i class="ph-repeat ph-bold ph-lg"></i>
<I18n :src="i18n.ts.renotedBy" tag="span">
<template #user>
<MkA
v-user-preview="note.userId"
class="name"
: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 ref="noteEl" class="article" tabindex="-1">
<MkNote
@contextmenu.stop="onContextmenu"
tabindex="-1"
:note="appearNote"
:detailedView="true"
></MkNote>
</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
v-for="note in directReplies"
:key="note.id"
@ -276,6 +68,7 @@ import {
} from "vue";
import * as mfm from "mfm-js";
import type * as misskey from "calckey-js";
import MkNote from "@/components/MkNote.vue";
import MkNoteSub from "@/components/MkNoteSub.vue";
import XNoteSimple from "@/components/MkNoteSimple.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue";
@ -283,6 +76,7 @@ import XMediaList from "@/components/MkMediaList.vue";
import XCwButton from "@/components/MkCwButton.vue";
import XPoll from "@/components/MkPoll.vue";
import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue";
@ -316,6 +110,8 @@ const inChannel = inject("inChannel", null);
let note = $ref(deepClone(props.note));
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
// plugin
if (noteViewInterruptors.length > 0) {
onMounted(async () => {
@ -647,8 +443,7 @@ onUnmounted(() => {
}
> .article {
padding: 32px;
padding-bottom: 6px;
padding-block: 28px 6px;
&:last-child {
padding-bottom: 24px;
}
@ -656,151 +451,8 @@ onUnmounted(() => {
overflow: clip;
outline: none;
scroll-margin-top: calc(var(--stickyTop) + 20vh);
> .header {
display: flex;
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);
}
}
}
:deep(.article) {
cursor: unset;
}
}
@ -884,7 +536,7 @@ onUnmounted(() => {
}
> .article {
padding: 16px;
padding: 6px 0 0 0;
> .header > .body {
padding-left: 10px;
}

View file

@ -4,21 +4,7 @@
<div class="main">
<XNoteHeader class="header" :note="note" :mini="true" />
<div class="body">
<p v-if="note.cw != null" class="cw">
<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>
<MkSubNoteContent class="text" :note="note" />
</div>
</div>
</div>
@ -29,7 +15,6 @@ import {} from "vue";
import * as misskey from "calckey-js";
import XNoteHeader from "@/components/MkNoteHeader.vue";
import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
import XCwButton from "@/components/MkCwButton.vue";
const props = defineProps<{
note: misskey.entities.Note;
@ -79,28 +64,6 @@ const showContent = $ref(false);
> .header {
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>

View file

@ -21,51 +21,12 @@
<div class="body">
<XNoteHeader class="header" :note="note" :mini="true" />
<div class="body">
<p v-if="appearNote.cw != null" class="cw">
<MkA
v-if="appearNote.replyId"
:to="`/notes/${appearNote.replyId}`"
class="reply-icon"
@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>
<MkSubNoteContent
class="text"
:note="note"
:parentId="appearNote.parentId"
:conversation="conversation"
/>
<div v-if="translating || translation" class="translation">
<MkLoading v-if="translating" mini />
<div v-else class="translated">
@ -87,6 +48,7 @@
</div>
<footer class="footer" @click.stop>
<XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer"
:note="appearNote"
/>
@ -106,14 +68,32 @@
:note="appearNote"
: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
v-if="appearNote.myReaction == null"
v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton"
class="button"
:note="appearNote"
/>
<button
v-if="appearNote.myReaction == null"
v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button"
@ -122,7 +102,10 @@
<i class="ph-smiley ph-bold ph-lg"></i>
</button>
<button
v-if="appearNote.myReaction != null"
v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton"
class="button _button reacted"
@click="undoReact(appearNote)"
@ -142,27 +125,31 @@
</div>
</div>
<template v-if="conversation">
<template v-if="replies.length == 1">
<MkNoteSub
v-for="reply in replies"
:key="reply.id"
:note="reply"
class="reply single"
:conversation="conversation"
:depth="depth"
:parentId="appearNote.replyId"
/>
</template>
<template v-else-if="depth < 5">
<MkNoteSub
v-for="reply in replies"
:key="reply.id"
:note="reply"
class="reply"
:conversation="conversation"
:depth="depth + 1"
:parentId="appearNote.replyId"
/>
<template v-if="replyLevel < 11 && depth < 5">
<template v-if="replies.length == 1">
<MkNoteSub
v-for="reply in replies"
:key="reply.id"
:note="reply"
class="reply single"
:conversation="conversation"
:depth="depth"
:replyLevel="replyLevel + 1"
:parentId="appearNote.replyId"
/>
</template>
<template v-else>
<MkNoteSub
v-for="reply in replies"
:key="reply.id"
:note="reply"
class="reply"
:conversation="conversation"
:depth="depth + 1"
:replyLevel="replyLevel + 1"
:parentId="appearNote.replyId"
/>
</template>
</template>
<div v-else-if="replies.length > 0" class="more">
<div class="line"></div>
@ -183,9 +170,9 @@ import XNoteHeader from "@/components/MkNoteHeader.vue";
import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue";
import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue";
import XCwButton from "@/components/MkCwButton.vue";
import { pleaseLogin } from "@/scripts/please-login";
import { getNoteMenu } from "@/scripts/get-note-menu";
import { notePage } from "@/filters/note";
@ -195,6 +182,7 @@ import { reactionPicker } from "@/scripts/reaction-picker";
import { i18n } from "@/i18n";
import { deepClone } from "@/scripts/clone";
import { useNoteCapture } from "@/scripts/use-note-capture";
import { defaultStore } from "@/store";
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
depth?: number;
// the actual reply level of this note within the conversation thread
replyLevel?: number;
}>(),
{
depth: 1,
replyLevel: 1,
}
);
@ -231,7 +222,6 @@ let appearNote = $computed(() =>
const isDeleted = ref(false);
const translation = ref(null);
const translating = ref(false);
let showContent = $ref(false);
const replies: misskey.entities.Note[] =
props.conversation
?.filter(
@ -240,6 +230,7 @@ const replies: misskey.entities.Note[] =
item.renoteId === props.note.id
)
.reverse() ?? [];
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
useNoteCapture({
rootEl: el,
@ -368,35 +359,6 @@ function noteClick(e) {
}
> .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 {
border: solid 0.5px var(--divider);
border-radius: var(--radius);

View file

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

View file

@ -6,7 +6,7 @@
@close="dialog.close()"
@closed="emit('closed')"
>
<template #header>{{ i18n.ts.reactions }}</template>
<template #header>{{ i18n.ts.reaction }}</template>
<MkSpacer :margin-min="20" :margin-max="28">
<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)) {
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"],
danger: false,
action: () => {
@ -130,7 +130,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
if (props.note.visibility === "specified") {
buttonActions.push({
text: i18n.ts.renoteToRecipients,
text: `${i18n.ts.renote} (${i18n.ts.recipient})`,
icons: [
"ph-repeat ph-bold ph-lg",
"ph-envelope-simple-open ph-bold ph-lg",
@ -158,7 +158,7 @@ const renote = async (viaKeyboard = false, ev?: MouseEvent) => {
});
} else {
buttonActions.push({
text: i18n.ts.renoteToFollowers,
text: `${i18n.ts.renote} (${i18n.ts._visibility.followers})`,
icons: [
"ph-repeat 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>
<div class="wrmlmaau" :class="{ collapsed, isLong }">
<div class="body">
<span v-if="note.deletedAt" style="opacity: 0.5"
>({{ i18n.ts.deleted }})</span
>
<template v-if="!note.cw">
<MkA
v-if="note.replyId"
:to="`/notes/${note.replyId}`"
class="reply-icon"
@click.stop
<p v-if="note.cw != null" class="cw">
<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>
<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>
</MkA>
<template v-if="!note.cw">
<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
v-if="
conversation &&
note.renoteId &&
note.renoteId != parentId &&
!note.replyId
"
v-if="!detailed && note.renoteId"
class="rp"
:to="`/notes/${note.renoteId}`"
class="reply-icon"
@click.stop
>{{ i18n.ts.quoteAttached }}: ...</MkA
>
<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 v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`"
>{{ i18n.ts.quoteAttached }}: ...</MkA
<div v-if="note.files.length > 0" class="files">
<XMediaList :media-list="note.files" />
</div>
<XPoll v-if="note.poll" :note="note" class="poll" />
<template v-if="detailed">
<MkUrlPreview
v-for="url in urls"
:key="url"
:url="url"
:compact="true"
:detail="false"
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 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>
</template>
@ -83,6 +124,7 @@ import XNoteSimple from "@/components/MkNoteSimple.vue";
import XMediaList from "@/components/MkMediaList.vue";
import XPoll from "@/components/MkPoll.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue";
import XCwButton from "@/components/MkCwButton.vue";
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
import { i18n } from "@/i18n";
@ -91,82 +133,157 @@ const props = defineProps<{
parentId?;
conversation?;
detailed?: boolean;
detailedView?: boolean;
}>();
const emit = defineEmits<{
(ev: "push", v): void;
}>();
const isLong =
!props.detailedView &&
props.note.cw == null &&
props.note.text != null &&
(props.note.text.split("\n").length > 9 || props.note.text.length > 500);
const collapsed = $ref(props.note.cw == null && isLong);
const urls = props.note.text
? extractUrlFromMfm(mfm.parse(props.note.text))
? extractUrlFromMfm(mfm.parse(props.note.text)).slice(0, 5)
: null;
let showContent = $ref(false);
</script>
<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;
> .body {
> .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);
}
}
> .text {
margin-right: 8px;
}
> .mk-url-preview {
margin-top: 8px;
}
&.collapsed {
position: relative;
max-height: 9em;
overflow: hidden;
}
.wrmlmaau {
.content {
overflow-wrap: break-word;
> .body {
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 {
transition: filter 0.1s;
> .rp {
margin-left: 4px;
font-style: oblique;
color: var(--renote);
}
.reply-icon {
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%);
border-radius: 6px;
padding: 0.2em 0.2em;
margin-right: 0.2em;
color: var(--accent);
transition: background 0.2s;
&:hover,
&:focus {
background: var(--buttonHoverBg);
}
}
> .files {
margin-top: 0.4em;
margin-bottom: 0.4em;
}
> .url-preview {
margin-top: 8px;
}
&:hover {
> span {
background: var(--panelHighlight);
> .poll {
font-size: 80%;
}
> .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 {
> .showLess {
&.collapsed,
&.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%;
margin-top: 1em;
position: sticky;

View file

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

View file

@ -12,7 +12,6 @@ import MkGoogle from "@/components/MkGoogle.vue";
import MkSparkle from "@/components/MkSparkle.vue";
import MkA from "@/components/global/MkA.vue";
import { host } from "@/config";
import { MFM_TAGS } from "@/scripts/mfm-tags";
import { reducedMotion } from "@/scripts/reduced-motion";
import { defaultStore } from "@/store";
@ -368,11 +367,7 @@ export default defineComponent({
MkA,
{
key: Math.random(),
to: this.isNote
? `/tags/${encodeURIComponent(token.props.hashtag)}`
: `/explore/tags/${encodeURIComponent(
token.props.hashtag,
)}`,
to: `/tags/${encodeURIComponent(token.props.hashtag)}`,
style: "color:var(--hashtag);",
},
`#${token.props.hashtag}`,
@ -461,7 +456,7 @@ export default defineComponent({
case "search": {
// Disable "search" keyword
// (see the issue #9816 on Codeberg)
if (token.props.content.endsWith("search")) {
if (token.props.content.slice(-6).toLowerCase() === "search") {
const sentinel = "#";
let ast2 = (isPlain ? mfm.parseSimple : mfm.parse)(
token.props.content.slice(0, -6) + sentinel,
@ -473,19 +468,32 @@ export default defineComponent({
ast2[ast2.length - 1].props.text = ast2[
ast2.length - 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";
if (
index === 0 ||
["blockCode", "mathBlock", "search", "quote"].includes(
ast[index - 1].type,
)
[
"blockCode",
"center",
"mathBlock",
"quote",
"search",
].includes(ast[index - 1].type)
) {
prefix = "";
}
return [prefix, ...genEl(ast2), "search\n"];
return [
prefix,
...genEl(ast2),
`${token.props.content.slice(-6)}\n`,
];
}
return [

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,81 +1,99 @@
<template>
<div class="_formRoot">
<FromSlot class="_formBlock">
<template #label>{{ i18n.ts.reactionSettingDescription }}</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
>
</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 v-model="enableEmojiReactions" class="_formBlock">
{{ i18n.ts.enableEmojiReactions }}
</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
<div v-if="enableEmojiReactions">
<FromSlot class="_formBlock">
<template #label>{{
i18n.ts.reactionSettingDescription
}}</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"
><i class="ph-arrow-counter-clockwise ph-bold ph-lg"></i>
{{ i18n.ts.default }}</FormButton
>
</div>
</FormSection>
</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>
<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>
</template>
@ -93,6 +111,17 @@ import { defaultStore } from "@/store";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata";
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));
@ -108,6 +137,12 @@ const reactionPickerHeight = $computed(
const reactionPickerUseDrawerForMobile = $computed(
defaultStore.makeGetterSetter("reactionPickerUseDrawerForMobile")
);
const enableEmojiReactions = $computed(
defaultStore.makeGetterSetter("enableEmojiReactions")
);
const showEmojisInReactionNotifications = $computed(
defaultStore.makeGetterSetter("showEmojisInReactionNotifications")
);
function save() {
defaultStore.set("reactions", reactions);
@ -171,6 +206,10 @@ watch(
}
);
watch(enableEmojiReactions, async () => {
await reloadAsk();
});
const headerActions = $computed(() => []);
const headerTabs = $computed(() => []);

View file

@ -1,24 +1,58 @@
<template>
<MkStickyContainer>
<template #header
><MkPageHeader :actions="headerActions" :tabs="headerTabs"
><MkPageHeader
v-model:tab="tab"
:actions="headerActions"
:tabs="headerTabs"
:display-back-button="true"
/></template>
<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>
</MkStickyContainer>
</template>
<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 XUserList from "@/components/MkUserList.vue";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata";
import { defaultStore } from "@/store";
import "swiper/scss";
import "swiper/scss/virtual";
const props = defineProps<{
tag: string;
}>();
const pagination = {
const notesPagination = {
endpoint: "notes/search-by-tag" as const,
limit: 10,
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 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(
computed(() => ({

View file

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

View file

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

View file

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

View file

@ -94,7 +94,13 @@ export function uploadFile(
// TODO: 消すのではなくて(ネットワーク的なエラーなら)再送できるようにしたい
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);
if (res.error?.id === "bec5bd69-fba3-43c9-b4fb-2894b66ad5d2") {
alert({

View file

@ -294,6 +294,14 @@ export const defaultStore = markRaw(
where: "device",
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>
</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
v-if="deckStore.state.profile !== 'default'"
v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile"
@ -161,6 +169,7 @@ import {
addColumn as addColumnToStore,
loadDeck,
getProfiles,
renameProfile as renameProfile_,
deleteProfile as deleteProfile_,
} from "./deck/deck-store";
import DeckColumnCore from "@/ui/deck/column-core.vue";
@ -319,6 +328,23 @@ function changeProfile(ev: MouseEvent) {
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() {
const { canceled } = await os.confirm({
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) {
if (column.name === undefined) column.name = null;
deckStore.push("columns", column);

View file

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

View file

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

File diff suppressed because it is too large Load diff