Merge branch 'develop' of codeberg.org:calckey/calckey into develop

This commit is contained in:
ThatOneCalculator 2023-04-19 20:42:12 -07:00
commit bcaaa19c43
No known key found for this signature in database
GPG Key ID: 8703CACD01000000
17 changed files with 638 additions and 114 deletions

View File

@ -116,11 +116,11 @@ rememberNoteVisibility: "Θυμήσου τις ρυθμίσεις ορατότη
attachCancel: "Αφαίρεση επισυναπτόμενου" attachCancel: "Αφαίρεση επισυναπτόμενου"
enterFileName: "Πληκτρολογήστε όνομα αρχείου" enterFileName: "Πληκτρολογήστε όνομα αρχείου"
mute: "Σίγαση" mute: "Σίγαση"
unmute: "Άρση σίγασης" unmute: "Διακοπή σίγασης"
block: "Μπλοκάρισμα" block: "Μπλοκάρισμα"
unblock: "Άρση μπλοκαρίσματος" unblock: "Διακοπή μπλοκαρίσματος"
suspend: "Αποβολή" suspend: "Αποβολή"
unsuspend: "Άρση αποβολής" unsuspend: "Διακοπή αποβολής"
blockConfirm: "Θέλετε σίγουρα να μπλοκάρετε αυτόν τον λογαριασμό;" blockConfirm: "Θέλετε σίγουρα να μπλοκάρετε αυτόν τον λογαριασμό;"
unblockConfirm: "Θέλετε σίγουρα να ξεμπλοκάρετε αυτόν τον λογαριασμό;" unblockConfirm: "Θέλετε σίγουρα να ξεμπλοκάρετε αυτόν τον λογαριασμό;"
suspendConfirm: "Θέλετε σίγουρα να αποβάλετε αυτόν τον λογαριασμό;" suspendConfirm: "Θέλετε σίγουρα να αποβάλετε αυτόν τον λογαριασμό;"
@ -187,8 +187,8 @@ birthday: "Γενέθλια"
registeredDate: "Έγινε μέλος στις" registeredDate: "Έγινε μέλος στις"
location: "Τοποθεσία" location: "Τοποθεσία"
theme: "Θέματα" theme: "Θέματα"
light: "Ανοιχτόχρωμο" light: "Φωτεινό"
dark: "Σκούρο" dark: "Σκοτεινό"
drive: "Αποθηκευτικός Χώρος" drive: "Αποθηκευτικός Χώρος"
fileName: "Όνομα αρχείου" fileName: "Όνομα αρχείου"
selectFile: "Επιλέξτε ένα αρχείο" selectFile: "Επιλέξτε ένα αρχείο"
@ -200,12 +200,12 @@ addFile: "Προσθέστε ένα αρχείο"
emptyDrive: "Ο Αποθηκευτικός Χώρος σας είναι άδειος" emptyDrive: "Ο Αποθηκευτικός Χώρος σας είναι άδειος"
copyUrl: "Αντιγραφή διεύθυνσης URL" copyUrl: "Αντιγραφή διεύθυνσης URL"
rename: "Μετονομασία" rename: "Μετονομασία"
avatar: "Εικόνα προφίλ" avatar: "Άβαταρ"
banner: "Εξώφυλλο" banner: "Εξώφυλλο"
reload: "Ανανέωση" reload: "Ανανέωση"
doNothing: "Αγνόηση" doNothing: "Αγνόηση"
watch: "Παρακολούθηση" watch: "Παρακολούθηση"
unwatch: "Άρση παρακολούθησης" unwatch: "Διακοπή παρακολούθησης"
accept: "Αποδοχή" accept: "Αποδοχή"
reject: "Απόρριψη" reject: "Απόρριψη"
normal: "Κανονικό" normal: "Κανονικό"
@ -221,18 +221,18 @@ registration: "Εγγραφή"
pinnedPages: "Καρφιτσωμένες Σελίδες" pinnedPages: "Καρφιτσωμένες Σελίδες"
pinnedNotes: "Καρφιτσωμένες δημοσιεύσεις" pinnedNotes: "Καρφιτσωμένες δημοσιεύσεις"
antennas: "Αντένες" antennas: "Αντένες"
manageAntennas: "Διαχείρισης Αντενών" manageAntennas: "Διαχείριση Αντενών"
name: "Όνομα" name: "Όνομα"
antennaSource: "Πηγή Αντένας" antennaSource: "Πηγή Αντένας"
antennaKeywords: "Λέξεις-κλειδιά για παρακολούθηση" antennaKeywords: "Λέξεις-κλειδιά για παρακολούθηση"
antennaExcludeKeywords: "Λέξεις-κλειδιά για εξαίρεση" antennaExcludeKeywords: "Λέξεις-κλειδιά για εξαίρεση"
notifyAntenna: "Ειδοποίηση για νέες δημοσιεύσεις" notifyAntenna: "Ειδοποίηση για νέες δημοσιεύσεις"
withFileAntenna: "Μόνο σημειώματα με αρχεία" withFileAntenna: "Μόνο δημοσιεύσεις με αρχεία"
caseSensitive: "Διάκριση Πεζών-Κεφαλαίων" caseSensitive: "Διάκριση Πεζών-Κεφαλαίων"
popularTags: "Δημοφιλείς ετικέτες" popularTags: "Δημοφιλείς ετικέτες"
userList: "Λίστες" userList: "Λίστες"
about: "Σχετικά με" about: "Σχετικά με"
moderator: "Συντονιστής" moderator: "Συντονιστής/στρια"
moderation: "Συντονισμός" moderation: "Συντονισμός"
cacheClear: "Εκκαθάριση προσωρινής μνήμης (cache)" cacheClear: "Εκκαθάριση προσωρινής μνήμης (cache)"
markAsReadAllNotifications: "Σημειώστε όλες τις ειδοποιήσεις ως διαβασμένες" markAsReadAllNotifications: "Σημειώστε όλες τις ειδοποιήσεις ως διαβασμένες"
@ -271,7 +271,7 @@ details: "Λεπτομέρειες"
install: "Εγκαταστήστε" install: "Εγκαταστήστε"
uninstall: "Απεγκατάσταση" uninstall: "Απεγκατάσταση"
manage: "Διαχείριση" manage: "Διαχείριση"
smtpHost: "Φιλοξενεί" smtpHost: "Φιλοξενεί (Host)"
smtpUser: "Όνομα μέλους" smtpUser: "Όνομα μέλους"
smtpPass: "Κωδικός" smtpPass: "Κωδικός"
notificationSetting: "Ρυθμίσεις ειδοποιήσεων" notificationSetting: "Ρυθμίσεις ειδοποιήσεων"
@ -301,7 +301,7 @@ searchByGoogle: "Αναζήτηση"
file: "Αρχεία" file: "Αρχεία"
recommended: "Προτεινόμενα" recommended: "Προτεινόμενα"
cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού\ cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού\
\ Χώρου" \ Χώρου."
_email: _email:
_follow: _follow:
title: "Έχετε ένα νέο ακόλουθο" title: "Έχετε ένα νέο ακόλουθο"
@ -381,6 +381,7 @@ _visibility:
_profile: _profile:
name: "Όνομα" name: "Όνομα"
username: "Όνομα μέλους" username: "Όνομα μέλους"
changeAvatar: Αλλαγή άβαταρ
_exportOrImport: _exportOrImport:
allNotes: "Όλα τα σημειώματα" allNotes: "Όλα τα σημειώματα"
followingList: "Ακολουθεί" followingList: "Ακολουθεί"
@ -411,10 +412,10 @@ _notification:
reply: "Απάντηση" reply: "Απάντηση"
renote: "Κοινοποίηση σημειώματος" renote: "Κοινοποίηση σημειώματος"
_deck: _deck:
widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία μαραφετίων\" στο μενού\ widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία πρόσθετων\" στο μενού και\
\ και προσθέστε μαραφέτι." \ προσθέστε μαραφέτι."
_columns: _columns:
widgets: "Μαραφέτια" widgets: "Πρόσθετα"
notifications: "Ειδοποιήσεις" notifications: "Ειδοποιήσεις"
tl: "Χρονολόγιο" tl: "Χρονολόγιο"
antenna: "Αντένες" antenna: "Αντένες"
@ -431,7 +432,7 @@ exploreUsersCount: Υπάρχουν {count} μέλη
help: Βοήθεια help: Βοήθεια
inputNewFileName: Πληκτρολογήστε ένα νέο όνομα αρχείου inputNewFileName: Πληκτρολογήστε ένα νέο όνομα αρχείου
nothing: Δεν υπάρχει τίποτα να δείτε εδώ nothing: Δεν υπάρχει τίποτα να δείτε εδώ
newNoteRecived: Δεν υπάρχουν νέες δημοσιεύσεις newNoteRecived: Υπάρχουν νέες δημοσιεύσεις
passwordMatched: Ταιριάζει passwordMatched: Ταιριάζει
unmarkAsSensitive: Αναίρεση επισήμανσης ως Ευαίσθητο Περιεχόμενο (NSFW) unmarkAsSensitive: Αναίρεση επισήμανσης ως Ευαίσθητο Περιεχόμενο (NSFW)
withNFiles: '{n} αρχείο(-α)' withNFiles: '{n} αρχείο(-α)'
@ -444,10 +445,10 @@ monthX: '{month}'
markAsReadAllTalkMessages: Σημειώστε όλα τα μηνύματα ως διαβασμένα markAsReadAllTalkMessages: Σημειώστε όλα τα μηνύματα ως διαβασμένα
inputMessageHere: Γράψτε εδώ το μήνυμά σας inputMessageHere: Γράψτε εδώ το μήνυμά σας
close: Κλείσιμο close: Κλείσιμο
newMessageExists: Δεν υπάρχουν νέα μηνύματα newMessageExists: Υπάρχουν νέα μηνύματα
usernameInvalidFormat: Μπορείτε να χρησιμοποιήσετε κεφαλαία και μικρά γράμματα, αριθμούς, usernameInvalidFormat: Μπορείτε να χρησιμοποιήσετε κεφαλαία και μικρά γράμματα, αριθμούς,
και κάτω παύλες. και κάτω παύλες.
tooShort: Πολύ μικρό tooShort: Πολύ σύντομο
passwordNotMatched: Δεν ταιριάζει passwordNotMatched: Δεν ταιριάζει
existingAccount: Υπάρχων λογαριασμός existingAccount: Υπάρχων λογαριασμός
deleteAll: Διαγραφή όλων deleteAll: Διαγραφή όλων
@ -500,10 +501,10 @@ nUsersMentioned: Έχει αναφερθεί από {n} μέλη
notFound: Δεν βρέθηκε notFound: Δεν βρέθηκε
markAsReadAllUnreadNotes: Σημειώστε όλες τις δημοσιεύσεις ως διαβασμένες markAsReadAllUnreadNotes: Σημειώστε όλες τις δημοσιεύσεις ως διαβασμένες
invites: Προσκλήσεις invites: Προσκλήσεις
quoteQuestion: Επισύναψη ως παράθεση; quoteQuestion: Να προστεθεί ως Παράθεση;
noMessagesYet: Δεν υπάρχουν μηνύματα ακόμη noMessagesYet: Δεν υπάρχουν μηνύματα ακόμη
onlyOneFileCanBeAttached: Μπορείτε να επισυνάψετε μόνο ένα αρχείο σε ένα μήνυμα onlyOneFileCanBeAttached: Μπορείτε να επισυνάψετε μόνο ένα αρχείο σε ένα μήνυμα
tooLong: Πολύ μεγάλο tooLong: Υπερβολικά μακροσκελές
or: Ή or: Ή
language: Γλώσσα language: Γλώσσα
groupInvited: Προσκληθήκατε σε μία ομάδα groupInvited: Προσκληθήκατε σε μία ομάδα
@ -526,7 +527,7 @@ display: Προβολή
send: Αποστολή send: Αποστολή
behavior: Συμπεριφορά behavior: Συμπεριφορά
useGlobalSetting: Χρήση παγκόσμιων ρυθμίσεων useGlobalSetting: Χρήση παγκόσμιων ρυθμίσεων
abuseMarkAsResolved: Επισήμανση της αναφοράς ως επιλυμένη abuseMarkAsResolved: Επισήμανση της αναφοράς ως επιλυμένης
openInNewTab: Άνοιγμα σε νέα καρτέλα openInNewTab: Άνοιγμα σε νέα καρτέλα
_sensitiveMediaDetection: _sensitiveMediaDetection:
setSensitiveFlagAutomatically: Επισήμανση ως ευαίσθητο περιεχόμενο (NSFW) setSensitiveFlagAutomatically: Επισήμανση ως ευαίσθητο περιεχόμενο (NSFW)
@ -539,9 +540,9 @@ optional: Προαιρετικό
renotesCount: Αριθμός προωθήσεων σε δημοσιεύσεις άλλων renotesCount: Αριθμός προωθήσεων σε δημοσιεύσεις άλλων
addItem: Προσθήκη αντικειμένου addItem: Προσθήκη αντικειμένου
disablePlayer: Κλείσιμο προβολής βίντεο disablePlayer: Κλείσιμο προβολής βίντεο
describeFile: Προσθήκη λεζάντας describeFile: Προσθήκη περιγραφής
enterFileDescription: Πληκτρολογήστε λεζάντα enterFileDescription: Πληκτρολογήστε περιγραφή
author: Συντάκτης author: Συντάκτης/τρια
setMultipleBySeparatingWithSpace: Διαχωρίστε πολλαπλές καταχωρήσεις με κενά. setMultipleBySeparatingWithSpace: Διαχωρίστε πολλαπλές καταχωρήσεις με κενά.
random: Τυχαίο random: Τυχαίο
accountInfo: Πληροφορίες Λογαριασμού accountInfo: Πληροφορίες Λογαριασμού
@ -554,7 +555,7 @@ editProfile: Επεξεργασία προφίλ
pinLimitExceeded: Δεν μπορείτε να καρφιτσώσετε άλλες δημοσιεύσεις pinLimitExceeded: Δεν μπορείτε να καρφιτσώσετε άλλες δημοσιεύσεις
currentPassword: Τρέχων κωδικός currentPassword: Τρέχων κωδικός
newPassword: Νέος κωδικός newPassword: Νέος κωδικός
newPasswordRetype: Ξαναγράψτε τον νέο κωδικό newPasswordRetype: Ξαναπληκτρολογήστε τον νέο κωδικό
notesAndReplies: Δημοσιεύσεις και απαντήσεις notesAndReplies: Δημοσιεύσεις και απαντήσεις
popularUsers: Δημοφιλή μέλη popularUsers: Δημοφιλή μέλη
share: Κοινοποίηση share: Κοινοποίηση
@ -583,8 +584,8 @@ folderName: Όνομα φακέλου
renameFolder: Μετονομασία φακέλου renameFolder: Μετονομασία φακέλου
recentUsed: Χρησιμοποιήθηκαν πρόσφατα recentUsed: Χρησιμοποιήθηκαν πρόσφατα
deleteAllFilesConfirm: Σίγουρα θέλετε να διαγράψετε όλα τα αρχεία; deleteAllFilesConfirm: Σίγουρα θέλετε να διαγράψετε όλα τα αρχεία;
removeAllFollowing: Άρση ακολούθησης όλων των ακολουθούμενων μελών removeAllFollowing: Διακοπή ακολούθησης όλων των ακολουθούμενων μελών
userSilenced: Αυτό το μέλος είναι υπό σίγαση. userSilenced: Αυτό το μέλος είναι υπό σιώπηση.
makeActive: Ενεργοποίηση makeActive: Ενεργοποίηση
create: Δημιουργία create: Δημιουργία
reportAbuseOf: Αναφορά {name} reportAbuseOf: Αναφορά {name}
@ -615,7 +616,7 @@ selectInstance: Επιλέξτε ένα instance
latestRequestSentAt: Τελευταίο αίτημα στάλθηκε latestRequestSentAt: Τελευταίο αίτημα στάλθηκε
hiddenTags: Κρυμμένες Ετικέτες (Hashtags) hiddenTags: Κρυμμένες Ετικέτες (Hashtags)
noInstances: Δεν υπάρχουν instances noInstances: Δεν υπάρχουν instances
renoteUnmute: Άρση σίγασης προωθήσεων renoteUnmute: Διακοπή σίγασης προωθήσεων
flagAsBotDescription: Ενεργοποιήστε αυτή την επιλογή αν αυτός ο λογαριασμός ελέγχεται flagAsBotDescription: Ενεργοποιήστε αυτή την επιλογή αν αυτός ο λογαριασμός ελέγχεται
από ένα πρόγραμμα. Αν ενεργοποιηθεί, θα λειτουργεί σαν σημάδι για τους προγραμματιστές, από ένα πρόγραμμα. Αν ενεργοποιηθεί, θα λειτουργεί σαν σημάδι για τους προγραμματιστές,
ώστε να αποφύγουν ατέρμονη αλληλεπίδραση με άλλα bots και για να ρυθμίσει τα εσωτερικά ώστε να αποφύγουν ατέρμονη αλληλεπίδραση με άλλα bots και για να ρυθμίσει τα εσωτερικά
@ -625,6 +626,195 @@ flagShowTimelineRepliesDescription: Εμφάνιση απαντήσεων μελ
latestRequestReceivedAt: Τελευταίο αίτημα ελήφθη latestRequestReceivedAt: Τελευταίο αίτημα ελήφθη
blockThisInstance: Μπλοκάρισμα αυτού του instance blockThisInstance: Μπλοκάρισμα αυτού του instance
clearQueueConfirmText: Τυχόν δημοσιεύσεις στην ουρά που δεν έχουν αποσταλεί δεν θα clearQueueConfirmText: Τυχόν δημοσιεύσεις στην ουρά που δεν έχουν αποσταλεί δεν θα
ομοσπονδιοποιηθούν. Συνήθως αυτή η λειτουργία δεν χρειάζεται. ομοσπονδοποιηθούν. Συνήθως αυτή η λειτουργία δεν χρειάζεται.
clearCachedFilesConfirm: Σίγουρα θέλετε να διαγράψετε όλα τα προσωρινά αποθηκευμένα 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

@ -114,6 +114,7 @@ clickToShow: "Click to show"
sensitive: "NSFW" sensitive: "NSFW"
add: "Add" add: "Add"
reaction: "Reactions" reaction: "Reactions"
enableEmojiReactions: "Enable emoji reactions"
reactionSetting: "Reactions to show in the reaction picker" reactionSetting: "Reactions to show in the reaction picker"
reactionSettingDescription2: "Drag to reorder, click to delete, press \"+\" to add." reactionSettingDescription2: "Drag to reorder, click to delete, press \"+\" to add."
rememberNoteVisibility: "Remember post visibility settings" rememberNoteVisibility: "Remember post visibility settings"

View File

@ -1162,6 +1162,7 @@ _serverDisconnectedBehavior:
reload: "Recargar automáticamente" reload: "Recargar automáticamente"
dialog: "Mostrar diálogo de advertencia" dialog: "Mostrar diálogo de advertencia"
quiet: "Advertencia discreta" quiet: "Advertencia discreta"
nothing: Hacer nada
_channel: _channel:
create: "Crear canal" create: "Crear canal"
edit: "Editar canal" edit: "Editar canal"
@ -1418,6 +1419,8 @@ _widgets:
aiscript: "Consola de AiScript" aiscript: "Consola de AiScript"
aichan: "indigo" aichan: "indigo"
userList: Lista Usuarios userList: Lista Usuarios
_userList:
chooseList: Seleccione una lista
_cw: _cw:
hide: "Ocultar" hide: "Ocultar"
show: "Ver más" show: "Ver más"
@ -1479,6 +1482,8 @@ _profile:
metadataContent: "Contenido" metadataContent: "Contenido"
changeAvatar: "Cambiar avatar" changeAvatar: "Cambiar avatar"
changeBanner: "Cambiar banner" changeBanner: "Cambiar banner"
locationDescription: Si ingresas tu ciudad primero, el tiempo local tuyo será visible
para otros usuarios.
_exportOrImport: _exportOrImport:
allNotes: "Todas las notas" allNotes: "Todas las notas"
followingList: "Siguiendo" followingList: "Siguiendo"
@ -1917,3 +1922,9 @@ showAds: Mostrar Anuncios
enterSendsMessage: Presione "RETORNO" en los mensajes para enviar el mensaje (para enterSendsMessage: Presione "RETORNO" en los mensajes para enviar el mensaje (para
apagarlo es Ctrl + RETORNO) apagarlo es Ctrl + RETORNO)
recommendedInstances: Instancias Recomendadas recommendedInstances: Instancias Recomendadas
instanceSecurity: Seguridad de la instancia
seperateRenoteQuote: Separar impulsados y Citar botones
_messaging:
groups: Grupos
dms: Privado
pushNotification: Notificaciones

View File

@ -109,6 +109,7 @@ clickToShow: "クリックして表示"
sensitive: "閲覧注意" sensitive: "閲覧注意"
add: "追加" add: "追加"
reaction: "リアクション" reaction: "リアクション"
enableEmojiReactions: "絵文字リアクションを有効にする"
reactionSetting: "ピッカーに表示するリアクション" reactionSetting: "ピッカーに表示するリアクション"
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。" reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。"
rememberNoteVisibility: "公開範囲を記憶する" rememberNoteVisibility: "公開範囲を記憶する"

View File

@ -754,7 +754,7 @@ nUsers: "Пользователей: {n}"
nNotes: "Заметок: {n}" nNotes: "Заметок: {n}"
sendErrorReports: "Посылать отчёты о сбоях" sendErrorReports: "Посылать отчёты о сбоях"
sendErrorReportsDescription: "Если включено, когда возникнет какая-нибудь техническая\ sendErrorReportsDescription: "Если включено, когда возникнет какая-нибудь техническая\
\ проблема, подробные сведения об этом будут отправлены разработчикам Misskey. Это\ \ проблема, подробные сведения об этом будут отправлены разработчикам Calckey. Это\
\ очень помогает делать программу лучше. В отчёты попадают тип и версия ОС, браузера,\ \ очень помогает делать программу лучше. В отчёты попадают тип и версия ОС, браузера,\
\ журнал действий (что привело к сбою) и тому подобное." \ журнал действий (что привело к сбою) и тому подобное."
myTheme: "Личная тема" myTheme: "Личная тема"
@ -1789,3 +1789,78 @@ renoteUnmute: Разглушить репосты
hiddenTags: Скрытые хештеги hiddenTags: Скрытые хештеги
noInstances: Нет инстансов noInstances: Нет инстансов
secureModeInfo: При запросах с других инстансов не отправлять ответ без подтверждения. secureModeInfo: При запросах с других инстансов не отправлять ответ без подтверждения.
instanceDefaultThemeDescription: Введите код темы в формате объекта.
tenMinutes: 10 минут
oneHour: Один час
thereIsUnresolvedAbuseReportWarning: Есть не рассмотренные жалобы.
cropImage: Обрезать изображение
requireAdminForView: Вы должны войти с аккаунта администратора что просмотреть это.
refreshInterval: 'Интервал обновления '
slow: Медленно
fast: Быстро
sensitiveMediaDetection: Обнаружение NSFW медиа
remoteOnly: Только другие сайты
navbar: Панель навигации
customMOTD: Своё MOTD (сообщения на заставке)
customMOTDDescription: Пользовательские сообщения для MOTD (заставки), разделенные
разрывами строк, будут отображаться случайным образом каждый раз, когда пользователь
загружает / перезагружает страницу.
recommendedInstancesDescription: Рекомендуемые инстансы, разделенные разрывами строк,
должны отображаться на рекомендуемой ленте. НЕ добавляйте `https://`, ТОЛЬКО домен.
caption: Автоматическая подпись
splash: Заставка
updateAvailable: Возможно, доступно обновление!
move: Переместить
swipeOnDesktop: Разрешить свайпы в мобильном стиле на десктопе
showAds: Показывать рекламу
noEmailServerWarning: Почтовый сервер не настроен.
type: Тип
numberOfPageCacheDescription: Увеличение этого числа повысит удобство для пользователей,
но приведет к увеличению нагрузки на сервер, а также к использованию большего объема
памяти.
statusbar: Панель статуса
speed: Скорость
oneDay: Один день
oneWeek: Одна неделя
failedToFetchAccountInformation: Не удалось получить информацию о аккаунте
cropImageAsk: Желаете ли вы обрезать это изображение?
recentNHours: Последние {n} часов
recentNDays: Последние {n} дней
typeToConfirm: Введите {x} чтобы подтвердить
document: Документация
logoutConfirm: Действительно выйти?
failedToUpload: Не удалось загрузить
pushNotification: Пуш уведомления
subscribePushNotification: Включить пуш уведомления
unsubscribePushNotification: Отключить пуш уведомления
pushNotificationAlreadySubscribed: Пуш уведомления уже включены
sendPushNotificationReadMessage: Удалять пуш уведомления после того как соответствующие
уведомления или сообщения были прочитаны
customSplashIcons: Свои иконки для заставки (URL)
customSplashIconsDescription: URL-адреса для пользовательских значков заставки, разделенных
разрывами строк, будут отображаться случайным образом каждый раз, когда пользователь
загружает / перезагружает страницу. Пожалуйста, убедитесь, что изображения находятся
на статическом URL-адресе, предпочтительно все с размером 192x192.
logoImageUrl: URL изображения логотипа
showAdminUpdates: Указать, что доступна новая версия Calckey (только для администратора)
replayTutorial: Перезапустить туториал
migration: Миграция
showLocalPosts: 'Показать локальные посты в:'
homeTimeline: Домашняя лента
socialTimeline: Социальная лента
driveCapOverrideCaption: Сбросить до настроек по умолчанию введя значение 0 или меньше.
deleteAccount: Удалить аккаунт
numberOfPageCache: Число кэшируемых страниц
pushNotificationNotSupported: Ваш браузер или инстанс не поддерживает пуш уведомления
sendPushNotificationReadMessageCaption: Уведомление содержащее текст "{emptyPushNotificationMessage}"
будет показано на короткое время. Это может увеличить расход батареи вашего устройства,
если это применимо.
cannotUploadBecauseNoFreeSpace: Загрузка не удалась из-за нехватки места на Диске.
cannotUploadBecauseInappropriate: Этот файл не может быть загружен потому что его
части были обнаружены как потенциальное NSFW.
adminCustomCssWarn: Этот параметр следует использовать только в том случае, если вы
знаете, что он делает. Ввод неправильных значений может привести к тому, что ВСЕ
клиенты перестанут нормально функционировать. Пожалуйста, убедитесь, что ваш CSS
работает должным образом, протестировав его в настройках вашего пользователя.
showUpdates: Показывать всплывающее окно при обновлении Calckey
recommendedInstances: Рекомендованные инстансы

View File

@ -107,6 +107,7 @@ clickToShow: "点击以显示"
sensitive: "敏感内容" sensitive: "敏感内容"
add: "添加" add: "添加"
reaction: "回应" reaction: "回应"
enableEmojiReaction: "启用表情符号回应"
reactionSetting: "在选择器中显示的回应" reactionSetting: "在选择器中显示的回应"
reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。" reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。"
rememberNoteVisibility: "保存上次设置的可见性" rememberNoteVisibility: "保存上次设置的可见性"

View File

@ -107,6 +107,7 @@ clickToShow: "按一下以顯示"
sensitive: "敏感內容" sensitive: "敏感內容"
add: "新增" add: "新增"
reaction: "情感" reaction: "情感"
enableEmojiReaction: "啟用表情符號反應"
reactionSetting: "在選擇器中顯示反應" reactionSetting: "在選擇器中顯示反應"
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。" reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
rememberNoteVisibility: "記住貼文可見性" rememberNoteVisibility: "記住貼文可見性"

View File

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

View File

@ -176,6 +176,7 @@
</div> </div>
<footer ref="el" class="footer" @click.stop> <footer ref="el" class="footer" @click.stop>
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
:note="appearNote" :note="appearNote"
/> />
@ -195,14 +196,32 @@
:note="appearNote" :note="appearNote"
:count="appearNote.renoteCount" :count="appearNote.renoteCount"
/> />
<XStarButtonNoEmoji
v-if="!enableEmojiReactions"
class="button"
:note="appearNote"
:count="
Object.values(appearNote.reactions).reduce(
(partialSum, val) => partialSum + val,
0
)
"
:reacted="appearNote.myReaction != null"
/>
<XStarButton <XStarButton
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton" ref="starButton"
class="button" class="button"
:note="appearNote" :note="appearNote"
/> />
<button <button
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@ -211,7 +230,10 @@
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
<button <button
v-if="appearNote.myReaction != null" v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click="undoReact(appearNote)"
@ -263,6 +285,7 @@ import XPoll from "@/components/MkPoll.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue"; import XReactionsViewer from "@/components/MkReactionsViewer.vue";
import XStarButton from "@/components/MkStarButton.vue"; import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue"; import MkUrlPreview from "@/components/MkUrlPreview.vue";
import MkVisibility from "@/components/MkVisibility.vue"; import MkVisibility from "@/components/MkVisibility.vue";
@ -333,6 +356,7 @@ const translating = ref(false);
const urls = appearNote.text const urls = appearNote.text
? extractUrlFromMfm(mfm.parse(appearNote.text)).slice(0, 5) ? extractUrlFromMfm(mfm.parse(appearNote.text)).slice(0, 5)
: null; : null;
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
const keymap = { const keymap = {
r: () => reply(true), r: () => reply(true),

View File

@ -179,6 +179,7 @@
</MkA> </MkA>
</div> </div>
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
:note="appearNote" :note="appearNote"
/> />
@ -203,14 +204,32 @@
:note="appearNote" :note="appearNote"
:count="appearNote.renoteCount" :count="appearNote.renoteCount"
/> />
<XStarButtonNoEmoji
v-if="!enableEmojiReactions"
class="button"
:note="appearNote"
:count="
Object.values(appearNote.reactions).reduce(
(partialSum, val) => partialSum + val,
0
)
"
:reacted="appearNote.myReaction != null"
/>
<XStarButton <XStarButton
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton" ref="starButton"
class="button" class="button"
:note="appearNote" :note="appearNote"
/> />
<button <button
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@ -219,7 +238,10 @@
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
<button <button
v-if="appearNote.myReaction != null" v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click="undoReact(appearNote)"
@ -283,6 +305,7 @@ import XMediaList from "@/components/MkMediaList.vue";
import XCwButton from "@/components/MkCwButton.vue"; import XCwButton from "@/components/MkCwButton.vue";
import XPoll from "@/components/MkPoll.vue"; import XPoll from "@/components/MkPoll.vue";
import XStarButton from "@/components/MkStarButton.vue"; import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import MkUrlPreview from "@/components/MkUrlPreview.vue"; import MkUrlPreview from "@/components/MkUrlPreview.vue";
@ -316,6 +339,8 @@ const inChannel = inject("inChannel", null);
let note = $ref(deepClone(props.note)); let note = $ref(deepClone(props.note));
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
// plugin // plugin
if (noteViewInterruptors.length > 0) { if (noteViewInterruptors.length > 0) {
onMounted(async () => { onMounted(async () => {

View File

@ -87,6 +87,7 @@
</div> </div>
<footer class="footer" @click.stop> <footer class="footer" @click.stop>
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
:note="appearNote" :note="appearNote"
/> />
@ -106,14 +107,32 @@
:note="appearNote" :note="appearNote"
:count="appearNote.renoteCount" :count="appearNote.renoteCount"
/> />
<XStarButtonNoEmoji
v-if="!enableEmojiReactions"
class="button"
:note="appearNote"
:count="
Object.values(appearNote.reactions).reduce(
(partialSum, val) => partialSum + val,
0
)
"
:reacted="appearNote.myReaction != null"
/>
<XStarButton <XStarButton
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="starButton" ref="starButton"
class="button" class="button"
:note="appearNote" :note="appearNote"
/> />
<button <button
v-if="appearNote.myReaction == null" v-if="
enableEmojiReactions &&
appearNote.myReaction == null
"
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@ -122,7 +141,10 @@
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
<button <button
v-if="appearNote.myReaction != null" v-if="
enableEmojiReactions &&
appearNote.myReaction != null
"
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click="undoReact(appearNote)"
@ -187,6 +209,7 @@ import XNoteHeader from "@/components/MkNoteHeader.vue";
import MkSubNoteContent from "@/components/MkSubNoteContent.vue"; import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
import XReactionsViewer from "@/components/MkReactionsViewer.vue"; import XReactionsViewer from "@/components/MkReactionsViewer.vue";
import XStarButton from "@/components/MkStarButton.vue"; import XStarButton from "@/components/MkStarButton.vue";
import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
import XRenoteButton from "@/components/MkRenoteButton.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue";
import XQuoteButton from "@/components/MkQuoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue";
import XCwButton from "@/components/MkCwButton.vue"; import XCwButton from "@/components/MkCwButton.vue";
@ -199,6 +222,7 @@ import { reactionPicker } from "@/scripts/reaction-picker";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { deepClone } from "@/scripts/clone"; import { deepClone } from "@/scripts/clone";
import { useNoteCapture } from "@/scripts/use-note-capture"; import { useNoteCapture } from "@/scripts/use-note-capture";
import { defaultStore } from "@/store";
const router = useRouter(); const router = useRouter();
@ -247,6 +271,7 @@ const replies: misskey.entities.Note[] =
item.renoteId === props.note.id item.renoteId === props.note.id
) )
.reverse() ?? []; .reverse() ?? [];
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
useNoteCapture({ useNoteCapture({
rootEl: el, rootEl: el,

View File

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

View File

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

View File

@ -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

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

View File

@ -1,7 +1,15 @@
<template> <template>
<div class="_formRoot"> <div class="_formRoot">
<FormSwitch v-model="enableEmojiReactions" class="_formBlock">
{{ i18n.ts.enableEmojiReactions }}
<template #caption>{{ i18n.ts.needReloadToApply }}</template>
</FormSwitch>
<div v-if="enableEmojiReactions">
<FromSlot class="_formBlock"> <FromSlot class="_formBlock">
<template #label>{{ i18n.ts.reactionSettingDescription }}</template> <template #label>{{
i18n.ts.reactionSettingDescription
}}</template>
<div v-panel style="border-radius: 6px"> <div v-panel style="border-radius: 6px">
<XDraggable <XDraggable
v-model="reactions" v-model="reactions"
@ -71,12 +79,15 @@
{{ i18n.ts.preview }}</FormButton {{ i18n.ts.preview }}</FormButton
> >
<FormButton inline danger @click="setDefault" <FormButton inline danger @click="setDefault"
><i class="ph-arrow-counter-clockwise ph-bold ph-lg"></i> ><i
class="ph-arrow-counter-clockwise ph-bold ph-lg"
></i>
{{ i18n.ts.default }}</FormButton {{ i18n.ts.default }}</FormButton
> >
</div> </div>
</FormSection> </FormSection>
</div> </div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -108,6 +119,9 @@ const reactionPickerHeight = $computed(
const reactionPickerUseDrawerForMobile = $computed( const reactionPickerUseDrawerForMobile = $computed(
defaultStore.makeGetterSetter("reactionPickerUseDrawerForMobile") defaultStore.makeGetterSetter("reactionPickerUseDrawerForMobile")
); );
const enableEmojiReactions = $computed(
defaultStore.makeGetterSetter("enableEmojiReactions")
);
function save() { function save() {
defaultStore.set("reactions", reactions); defaultStore.set("reactions", reactions);

View File

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