Merge branch 'develop' of codeberg.org:calckey/calckey into develop
This commit is contained in:
commit
bcaaa19c43
|
@ -116,11 +116,11 @@ rememberNoteVisibility: "Θυμήσου τις ρυθμίσεις ορατότη
|
|||
attachCancel: "Αφαίρεση επισυναπτόμενου"
|
||||
enterFileName: "Πληκτρολογήστε όνομα αρχείου"
|
||||
mute: "Σίγαση"
|
||||
unmute: "Άρση σίγασης"
|
||||
unmute: "Διακοπή σίγασης"
|
||||
block: "Μπλοκάρισμα"
|
||||
unblock: "Άρση μπλοκαρίσματος"
|
||||
unblock: "Διακοπή μπλοκαρίσματος"
|
||||
suspend: "Αποβολή"
|
||||
unsuspend: "Άρση αποβολής"
|
||||
unsuspend: "Διακοπή αποβολής"
|
||||
blockConfirm: "Θέλετε σίγουρα να μπλοκάρετε αυτόν τον λογαριασμό;"
|
||||
unblockConfirm: "Θέλετε σίγουρα να ξεμπλοκάρετε αυτόν τον λογαριασμό;"
|
||||
suspendConfirm: "Θέλετε σίγουρα να αποβάλετε αυτόν τον λογαριασμό;"
|
||||
|
@ -187,8 +187,8 @@ birthday: "Γενέθλια"
|
|||
registeredDate: "Έγινε μέλος στις"
|
||||
location: "Τοποθεσία"
|
||||
theme: "Θέματα"
|
||||
light: "Ανοιχτόχρωμο"
|
||||
dark: "Σκούρο"
|
||||
light: "Φωτεινό"
|
||||
dark: "Σκοτεινό"
|
||||
drive: "Αποθηκευτικός Χώρος"
|
||||
fileName: "Όνομα αρχείου"
|
||||
selectFile: "Επιλέξτε ένα αρχείο"
|
||||
|
@ -200,12 +200,12 @@ addFile: "Προσθέστε ένα αρχείο"
|
|||
emptyDrive: "Ο Αποθηκευτικός Χώρος σας είναι άδειος"
|
||||
copyUrl: "Αντιγραφή διεύθυνσης URL"
|
||||
rename: "Μετονομασία"
|
||||
avatar: "Εικόνα προφίλ"
|
||||
avatar: "Άβαταρ"
|
||||
banner: "Εξώφυλλο"
|
||||
reload: "Ανανέωση"
|
||||
doNothing: "Αγνόηση"
|
||||
watch: "Παρακολούθηση"
|
||||
unwatch: "Άρση παρακολούθησης"
|
||||
unwatch: "Διακοπή παρακολούθησης"
|
||||
accept: "Αποδοχή"
|
||||
reject: "Απόρριψη"
|
||||
normal: "Κανονικό"
|
||||
|
@ -221,18 +221,18 @@ registration: "Εγγραφή"
|
|||
pinnedPages: "Καρφιτσωμένες Σελίδες"
|
||||
pinnedNotes: "Καρφιτσωμένες δημοσιεύσεις"
|
||||
antennas: "Αντένες"
|
||||
manageAntennas: "Διαχείρισης Αντενών"
|
||||
manageAntennas: "Διαχείριση Αντενών"
|
||||
name: "Όνομα"
|
||||
antennaSource: "Πηγή Αντένας"
|
||||
antennaKeywords: "Λέξεις-κλειδιά για παρακολούθηση"
|
||||
antennaExcludeKeywords: "Λέξεις-κλειδιά για εξαίρεση"
|
||||
notifyAntenna: "Ειδοποίηση για νέες δημοσιεύσεις"
|
||||
withFileAntenna: "Μόνο σημειώματα με αρχεία"
|
||||
withFileAntenna: "Μόνο δημοσιεύσεις με αρχεία"
|
||||
caseSensitive: "Διάκριση Πεζών-Κεφαλαίων"
|
||||
popularTags: "Δημοφιλείς ετικέτες"
|
||||
userList: "Λίστες"
|
||||
about: "Σχετικά με"
|
||||
moderator: "Συντονιστής"
|
||||
moderator: "Συντονιστής/στρια"
|
||||
moderation: "Συντονισμός"
|
||||
cacheClear: "Εκκαθάριση προσωρινής μνήμης (cache)"
|
||||
markAsReadAllNotifications: "Σημειώστε όλες τις ειδοποιήσεις ως διαβασμένες"
|
||||
|
@ -271,7 +271,7 @@ details: "Λεπτομέρειες"
|
|||
install: "Εγκαταστήστε"
|
||||
uninstall: "Απεγκατάσταση"
|
||||
manage: "Διαχείριση"
|
||||
smtpHost: "Φιλοξενεί"
|
||||
smtpHost: "Φιλοξενεί (Host)"
|
||||
smtpUser: "Όνομα μέλους"
|
||||
smtpPass: "Κωδικός"
|
||||
notificationSetting: "Ρυθμίσεις ειδοποιήσεων"
|
||||
|
@ -301,7 +301,7 @@ searchByGoogle: "Αναζήτηση"
|
|||
file: "Αρχεία"
|
||||
recommended: "Προτεινόμενα"
|
||||
cannotUploadBecauseNoFreeSpace: "Το ανέβασμα απέτυχε λόγω ανεπαρκούς Αποθηκευτικού\
|
||||
\ Χώρου"
|
||||
\ Χώρου."
|
||||
_email:
|
||||
_follow:
|
||||
title: "Έχετε ένα νέο ακόλουθο"
|
||||
|
@ -381,6 +381,7 @@ _visibility:
|
|||
_profile:
|
||||
name: "Όνομα"
|
||||
username: "Όνομα μέλους"
|
||||
changeAvatar: Αλλαγή άβαταρ
|
||||
_exportOrImport:
|
||||
allNotes: "Όλα τα σημειώματα"
|
||||
followingList: "Ακολουθεί"
|
||||
|
@ -411,10 +412,10 @@ _notification:
|
|||
reply: "Απάντηση"
|
||||
renote: "Κοινοποίηση σημειώματος"
|
||||
_deck:
|
||||
widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία μαραφετίων\" στο μενού\
|
||||
\ και προσθέστε μαραφέτι."
|
||||
widgetsIntroduction: "Παρακαλούμε επιλέξτε \"Επεξεργασία πρόσθετων\" στο μενού και\
|
||||
\ προσθέστε μαραφέτι."
|
||||
_columns:
|
||||
widgets: "Μαραφέτια"
|
||||
widgets: "Πρόσθετα"
|
||||
notifications: "Ειδοποιήσεις"
|
||||
tl: "Χρονολόγιο"
|
||||
antenna: "Αντένες"
|
||||
|
@ -431,7 +432,7 @@ exploreUsersCount: Υπάρχουν {count} μέλη
|
|||
help: Βοήθεια
|
||||
inputNewFileName: Πληκτρολογήστε ένα νέο όνομα αρχείου
|
||||
nothing: Δεν υπάρχει τίποτα να δείτε εδώ
|
||||
newNoteRecived: Δεν υπάρχουν νέες δημοσιεύσεις
|
||||
newNoteRecived: Υπάρχουν νέες δημοσιεύσεις
|
||||
passwordMatched: Ταιριάζει
|
||||
unmarkAsSensitive: Αναίρεση επισήμανσης ως Ευαίσθητο Περιεχόμενο (NSFW)
|
||||
withNFiles: '{n} αρχείο(-α)'
|
||||
|
@ -444,10 +445,10 @@ monthX: '{month}'
|
|||
markAsReadAllTalkMessages: Σημειώστε όλα τα μηνύματα ως διαβασμένα
|
||||
inputMessageHere: Γράψτε εδώ το μήνυμά σας
|
||||
close: Κλείσιμο
|
||||
newMessageExists: Δεν υπάρχουν νέα μηνύματα
|
||||
newMessageExists: Υπάρχουν νέα μηνύματα
|
||||
usernameInvalidFormat: Μπορείτε να χρησιμοποιήσετε κεφαλαία και μικρά γράμματα, αριθμούς,
|
||||
και κάτω παύλες.
|
||||
tooShort: Πολύ μικρό
|
||||
tooShort: Πολύ σύντομο
|
||||
passwordNotMatched: Δεν ταιριάζει
|
||||
existingAccount: Υπάρχων λογαριασμός
|
||||
deleteAll: Διαγραφή όλων
|
||||
|
@ -500,10 +501,10 @@ nUsersMentioned: Έχει αναφερθεί από {n} μέλη
|
|||
notFound: Δεν βρέθηκε
|
||||
markAsReadAllUnreadNotes: Σημειώστε όλες τις δημοσιεύσεις ως διαβασμένες
|
||||
invites: Προσκλήσεις
|
||||
quoteQuestion: Επισύναψη ως παράθεση;
|
||||
quoteQuestion: Να προστεθεί ως Παράθεση;
|
||||
noMessagesYet: Δεν υπάρχουν μηνύματα ακόμη
|
||||
onlyOneFileCanBeAttached: Μπορείτε να επισυνάψετε μόνο ένα αρχείο σε ένα μήνυμα
|
||||
tooLong: Πολύ μεγάλο
|
||||
tooLong: Υπερβολικά μακροσκελές
|
||||
or: Ή
|
||||
language: Γλώσσα
|
||||
groupInvited: Προσκληθήκατε σε μία ομάδα
|
||||
|
@ -526,7 +527,7 @@ display: Προβολή
|
|||
send: Αποστολή
|
||||
behavior: Συμπεριφορά
|
||||
useGlobalSetting: Χρήση παγκόσμιων ρυθμίσεων
|
||||
abuseMarkAsResolved: Επισήμανση της αναφοράς ως επιλυμένη
|
||||
abuseMarkAsResolved: Επισήμανση της αναφοράς ως επιλυμένης
|
||||
openInNewTab: Άνοιγμα σε νέα καρτέλα
|
||||
_sensitiveMediaDetection:
|
||||
setSensitiveFlagAutomatically: Επισήμανση ως ευαίσθητο περιεχόμενο (NSFW)
|
||||
|
@ -539,9 +540,9 @@ optional: Προαιρετικό
|
|||
renotesCount: Αριθμός προωθήσεων σε δημοσιεύσεις άλλων
|
||||
addItem: Προσθήκη αντικειμένου
|
||||
disablePlayer: Κλείσιμο προβολής βίντεο
|
||||
describeFile: Προσθήκη λεζάντας
|
||||
enterFileDescription: Πληκτρολογήστε λεζάντα
|
||||
author: Συντάκτης
|
||||
describeFile: Προσθήκη περιγραφής
|
||||
enterFileDescription: Πληκτρολογήστε περιγραφή
|
||||
author: Συντάκτης/τρια
|
||||
setMultipleBySeparatingWithSpace: Διαχωρίστε πολλαπλές καταχωρήσεις με κενά.
|
||||
random: Τυχαίο
|
||||
accountInfo: Πληροφορίες Λογαριασμού
|
||||
|
@ -554,7 +555,7 @@ editProfile: Επεξεργασία προφίλ
|
|||
pinLimitExceeded: Δεν μπορείτε να καρφιτσώσετε άλλες δημοσιεύσεις
|
||||
currentPassword: Τρέχων κωδικός
|
||||
newPassword: Νέος κωδικός
|
||||
newPasswordRetype: Ξαναγράψτε τον νέο κωδικό
|
||||
newPasswordRetype: Ξαναπληκτρολογήστε τον νέο κωδικό
|
||||
notesAndReplies: Δημοσιεύσεις και απαντήσεις
|
||||
popularUsers: Δημοφιλή μέλη
|
||||
share: Κοινοποίηση
|
||||
|
@ -583,8 +584,8 @@ folderName: Όνομα φακέλου
|
|||
renameFolder: Μετονομασία φακέλου
|
||||
recentUsed: Χρησιμοποιήθηκαν πρόσφατα
|
||||
deleteAllFilesConfirm: Σίγουρα θέλετε να διαγράψετε όλα τα αρχεία;
|
||||
removeAllFollowing: Άρση ακολούθησης όλων των ακολουθούμενων μελών
|
||||
userSilenced: Αυτό το μέλος είναι υπό σίγαση.
|
||||
removeAllFollowing: Διακοπή ακολούθησης όλων των ακολουθούμενων μελών
|
||||
userSilenced: Αυτό το μέλος είναι υπό σιώπηση.
|
||||
makeActive: Ενεργοποίηση
|
||||
create: Δημιουργία
|
||||
reportAbuseOf: Αναφορά {name}
|
||||
|
@ -615,7 +616,7 @@ selectInstance: Επιλέξτε ένα instance
|
|||
latestRequestSentAt: Τελευταίο αίτημα στάλθηκε
|
||||
hiddenTags: Κρυμμένες Ετικέτες (Hashtags)
|
||||
noInstances: Δεν υπάρχουν instances
|
||||
renoteUnmute: Άρση σίγασης προωθήσεων
|
||||
renoteUnmute: Διακοπή σίγασης προωθήσεων
|
||||
flagAsBotDescription: Ενεργοποιήστε αυτή την επιλογή αν αυτός ο λογαριασμός ελέγχεται
|
||||
από ένα πρόγραμμα. Αν ενεργοποιηθεί, θα λειτουργεί σαν σημάδι για τους προγραμματιστές,
|
||||
ώστε να αποφύγουν ατέρμονη αλληλεπίδραση με άλλα bots και για να ρυθμίσει τα εσωτερικά
|
||||
|
@ -625,6 +626,195 @@ 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.
|
||||
|
|
|
@ -114,6 +114,7 @@ clickToShow: "Click to show"
|
|||
sensitive: "NSFW"
|
||||
add: "Add"
|
||||
reaction: "Reactions"
|
||||
enableEmojiReactions: "Enable emoji reactions"
|
||||
reactionSetting: "Reactions to show in the reaction picker"
|
||||
reactionSettingDescription2: "Drag to reorder, click to delete, press \"+\" to add."
|
||||
rememberNoteVisibility: "Remember post visibility settings"
|
||||
|
|
|
@ -1162,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"
|
||||
|
@ -1418,6 +1419,8 @@ _widgets:
|
|||
aiscript: "Consola de AiScript"
|
||||
aichan: "indigo"
|
||||
userList: Lista Usuarios
|
||||
_userList:
|
||||
chooseList: Seleccione una lista
|
||||
_cw:
|
||||
hide: "Ocultar"
|
||||
show: "Ver más"
|
||||
|
@ -1479,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"
|
||||
|
@ -1917,3 +1922,9 @@ 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
|
||||
|
|
|
@ -109,6 +109,7 @@ clickToShow: "クリックして表示"
|
|||
sensitive: "閲覧注意"
|
||||
add: "追加"
|
||||
reaction: "リアクション"
|
||||
enableEmojiReactions: "絵文字リアクションを有効にする"
|
||||
reactionSetting: "ピッカーに表示するリアクション"
|
||||
reactionSettingDescription2: "ドラッグして並び替え、クリックして削除、+を押して追加します。"
|
||||
rememberNoteVisibility: "公開範囲を記憶する"
|
||||
|
|
|
@ -754,7 +754,7 @@ nUsers: "Пользователей: {n}"
|
|||
nNotes: "Заметок: {n}"
|
||||
sendErrorReports: "Посылать отчёты о сбоях"
|
||||
sendErrorReportsDescription: "Если включено, когда возникнет какая-нибудь техническая\
|
||||
\ проблема, подробные сведения об этом будут отправлены разработчикам Misskey. Это\
|
||||
\ проблема, подробные сведения об этом будут отправлены разработчикам Calckey. Это\
|
||||
\ очень помогает делать программу лучше. В отчёты попадают тип и версия ОС, браузера,\
|
||||
\ журнал действий (что привело к сбою) и тому подобное."
|
||||
myTheme: "Личная тема"
|
||||
|
@ -1789,3 +1789,78 @@ renoteUnmute: Разглушить репосты
|
|||
hiddenTags: Скрытые хештеги
|
||||
noInstances: Нет инстансов
|
||||
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: Рекомендованные инстансы
|
||||
|
|
|
@ -107,6 +107,7 @@ clickToShow: "点击以显示"
|
|||
sensitive: "敏感内容"
|
||||
add: "添加"
|
||||
reaction: "回应"
|
||||
enableEmojiReaction: "启用表情符号回应"
|
||||
reactionSetting: "在选择器中显示的回应"
|
||||
reactionSettingDescription2: "拖动重新排序,单击删除,点击 + 添加。"
|
||||
rememberNoteVisibility: "保存上次设置的可见性"
|
||||
|
|
|
@ -107,6 +107,7 @@ clickToShow: "按一下以顯示"
|
|||
sensitive: "敏感內容"
|
||||
add: "新增"
|
||||
reaction: "情感"
|
||||
enableEmojiReaction: "啟用表情符號反應"
|
||||
reactionSetting: "在選擇器中顯示反應"
|
||||
reactionSettingDescription2: "拖動以重新列序,點擊以刪除,按下 + 添加。"
|
||||
rememberNoteVisibility: "記住貼文可見性"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -176,6 +176,7 @@
|
|||
</div>
|
||||
<footer ref="el" class="footer" @click.stop>
|
||||
<XReactionsViewer
|
||||
v-if="enableEmojiReactions"
|
||||
ref="reactionsViewer"
|
||||
:note="appearNote"
|
||||
/>
|
||||
|
@ -195,14 +196,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 +230,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)"
|
||||
|
@ -263,6 +285,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";
|
||||
|
@ -333,6 +356,7 @@ 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),
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
</MkA>
|
||||
</div>
|
||||
<XReactionsViewer
|
||||
v-if="enableEmojiReactions"
|
||||
ref="reactionsViewer"
|
||||
:note="appearNote"
|
||||
/>
|
||||
|
@ -203,14 +204,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"
|
||||
|
@ -219,7 +238,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)"
|
||||
|
@ -283,6 +305,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 +339,8 @@ const inChannel = inject("inChannel", null);
|
|||
|
||||
let note = $ref(deepClone(props.note));
|
||||
|
||||
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
|
||||
|
||||
// plugin
|
||||
if (noteViewInterruptors.length > 0) {
|
||||
onMounted(async () => {
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
</div>
|
||||
<footer class="footer" @click.stop>
|
||||
<XReactionsViewer
|
||||
v-if="enableEmojiReactions"
|
||||
ref="reactionsViewer"
|
||||
:note="appearNote"
|
||||
/>
|
||||
|
@ -106,14 +107,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 +141,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)"
|
||||
|
@ -187,6 +209,7 @@ 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";
|
||||
|
@ -199,6 +222,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();
|
||||
|
||||
|
@ -247,6 +271,7 @@ const replies: misskey.entities.Note[] =
|
|||
item.renoteId === props.note.id
|
||||
)
|
||||
.reverse() ?? [];
|
||||
const enableEmojiReactions = defaultStore.state.enableEmojiReactions;
|
||||
|
||||
useNoteCapture({
|
||||
rootEl: el,
|
||||
|
|
|
@ -65,7 +65,10 @@
|
|||
></i>
|
||||
<!-- notification.reaction が null になることはまずないが、ここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
|
||||
<XReactionIcon
|
||||
v-else-if="notification.type === 'reaction'"
|
||||
v-else-if="
|
||||
notification.type === 'reaction' &&
|
||||
defaultStore.state.enableEmojiReactions
|
||||
"
|
||||
ref="reactionRef"
|
||||
:reaction="
|
||||
notification.reaction
|
||||
|
@ -78,6 +81,14 @@
|
|||
:custom-emojis="notification.note.emojis"
|
||||
:no-style="true"
|
||||
/>
|
||||
<XReactionIcon
|
||||
v-else-if="
|
||||
notification.type === 'reaction' &&
|
||||
!defaultStore.state.enableEmojiReactions
|
||||
"
|
||||
:reaction="defaultReaction"
|
||||
:no-style="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tail">
|
||||
|
@ -272,6 +283,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 +301,10 @@ const props = withDefaults(
|
|||
const elRef = ref<HTMLElement>(null);
|
||||
const reactionRef = ref(null);
|
||||
|
||||
const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReaction)
|
||||
? instance.defaultReaction
|
||||
: "⭐";
|
||||
|
||||
let readObserver: IntersectionObserver | undefined;
|
||||
let connection;
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
|
@ -114,6 +114,7 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
|
|||
"swipeOnDesktop",
|
||||
"showAdminUpdates",
|
||||
"enableCustomKaTeXMacro",
|
||||
"enableEmojiReactions",
|
||||
];
|
||||
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
|
||||
"lightTheme",
|
||||
|
|
|
@ -1,81 +1,92 @@
|
|||
<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 }}
|
||||
<FormSwitch v-model="enableEmojiReactions" class="_formBlock">
|
||||
{{ i18n.ts.enableEmojiReactions }}
|
||||
<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
|
||||
<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>
|
||||
</template>
|
||||
|
||||
|
@ -108,6 +119,9 @@ const reactionPickerHeight = $computed(
|
|||
const reactionPickerUseDrawerForMobile = $computed(
|
||||
defaultStore.makeGetterSetter("reactionPickerUseDrawerForMobile")
|
||||
);
|
||||
const enableEmojiReactions = $computed(
|
||||
defaultStore.makeGetterSetter("enableEmojiReactions")
|
||||
);
|
||||
|
||||
function save() {
|
||||
defaultStore.set("reactions", reactions);
|
||||
|
|
|
@ -294,6 +294,10 @@ export const defaultStore = markRaw(
|
|||
where: "device",
|
||||
default: false,
|
||||
},
|
||||
enableEmojiReactions: {
|
||||
where: "account",
|
||||
default: true,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue