Merge branch 'develop' of https://codeberg.org/calckey/calckey into keyboard-accessability
|
@ -27,9 +27,9 @@
|
||||||
- Notable differences:
|
- Notable differences:
|
||||||
- Improved UI/UX (especially on mobile)
|
- Improved UI/UX (especially on mobile)
|
||||||
- Improved notifications
|
- Improved notifications
|
||||||
- Fediverse account migration
|
|
||||||
- Improved instance security
|
- Improved instance security
|
||||||
- Improved accessibility
|
- Improved accessibility
|
||||||
|
- Improved threads
|
||||||
- Recommended Instances timeline
|
- Recommended Instances timeline
|
||||||
- OCR image captioning
|
- OCR image captioning
|
||||||
- New and improved Groups
|
- New and improved Groups
|
||||||
|
|
|
@ -675,3 +675,48 @@ useGlobalSetting: Fes servir els ajustos globals
|
||||||
useGlobalSettingDesc: Si s'activa, es faran servir els ajustos de notificacions del
|
useGlobalSettingDesc: Si s'activa, es faran servir els ajustos de notificacions del
|
||||||
teu compte. Si es desactiva , es poden fer configuracions individuals.
|
teu compte. Si es desactiva , es poden fer configuracions individuals.
|
||||||
other: Altres
|
other: Altres
|
||||||
|
menu: Menú
|
||||||
|
addItem: Afegeix un element
|
||||||
|
divider: Divisor
|
||||||
|
relays: Relés
|
||||||
|
addRelay: Afegeix un Relé
|
||||||
|
inboxUrl: Adreça de la safata d'entrada
|
||||||
|
addedRelays: Relés afegits
|
||||||
|
serviceworkerInfo: Ha de estar activat per les notificacions push.
|
||||||
|
poll: Enquesta
|
||||||
|
deletedNote: Article eliminat
|
||||||
|
disablePlayer: Tancar el reproductor de vídeo
|
||||||
|
fileIdOrUrl: ID o adreça URL del fitxer
|
||||||
|
behavior: Comportament
|
||||||
|
regenerateLoginTokenDescription: Regenera el token que es fa servir de manera interna
|
||||||
|
durant l'inici de sessió. Normalment això no és necessari. Si es torna a genera
|
||||||
|
el token, es tancarà la sessió a tots els dispositius.
|
||||||
|
setMultipleBySeparatingWithSpace: Separa diferents entrades amb espais.
|
||||||
|
reportAbuseOf: Informa sobre {name}
|
||||||
|
sample: Exemple
|
||||||
|
abuseReports: Informes
|
||||||
|
reportAbuse: Informe
|
||||||
|
reporter: Informador
|
||||||
|
reporterOrigin: Origen d'el informador
|
||||||
|
forwardReport: Envia l'informe a una instancia remota
|
||||||
|
abuseReported: El teu informe ha sigut enviat. Moltes gràcies.
|
||||||
|
reporteeOrigin: Origen de l'informe
|
||||||
|
send: Enviar
|
||||||
|
abuseMarkAsResolved: Marcar l'informe com a resolt
|
||||||
|
visibility: Visibilitat
|
||||||
|
useCw: Amaga el contingut
|
||||||
|
enablePlayer: Obre el reproductor de vídeo
|
||||||
|
yourAccountSuspendedDescription: Aquest compte ha sigut suspesa per no seguir els
|
||||||
|
termes de servei del servidor o quelcom similar. Contacte amb l'administrador si
|
||||||
|
vols conèixer la raó amb més detall. Si us plau no facis un compte nou.
|
||||||
|
invisibleNote: Article ocult
|
||||||
|
enableInfiniteScroll: Carregar més de forma automàtica
|
||||||
|
fillAbuseReportDescription: Si us plau omple els detalls sobre aquest informe. Si
|
||||||
|
es sobre un article en concret, si us plau inclou l'adreça URL.
|
||||||
|
forwardReportIsAnonymous: Com a informador a l'instància remota no es mostrarà el
|
||||||
|
teu compte, si no un compte anònim.
|
||||||
|
openInNewTab: Obrir en una pestanya nova
|
||||||
|
openInSideView: Obrir a la vista lateral
|
||||||
|
defaultNavigationBehaviour: Navegació per defecte
|
||||||
|
editTheseSettingsMayBreakAccount: Si edites aquestes configuracions pots fer mal bé
|
||||||
|
el teu compte.
|
||||||
|
|
|
@ -1042,7 +1042,7 @@ moveFromLabel: "Account you're moving from:"
|
||||||
moveFromDescription: "This will set an alias of your old account so that you can move\
|
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.\
|
\ 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"
|
\ 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}?\
|
migrationConfirm: "Are you absolutely sure you want to migrate your account to {account}?\
|
||||||
\ Once you do this, you won't be able to reverse it, and you won't be able to use\
|
\ 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\
|
\ your account normally again.\nAlso, please ensure that you've set this current\
|
||||||
\ account as the account you're moving from."
|
\ account as the account you're moving from."
|
||||||
|
|
182
locales/fi.yml
|
@ -3,7 +3,7 @@ fetchingAsApObject: Hae Fedeversestä
|
||||||
gotIt: Selvä!
|
gotIt: Selvä!
|
||||||
cancel: Peruuta
|
cancel: Peruuta
|
||||||
enterUsername: Anna käyttäjänimi
|
enterUsername: Anna käyttäjänimi
|
||||||
renotedBy: Buustannut {käyttäjä}
|
renotedBy: Buustannut {user}
|
||||||
noNotes: Ei lähetyksiä
|
noNotes: Ei lähetyksiä
|
||||||
noNotifications: Ei ilmoituksia
|
noNotifications: Ei ilmoituksia
|
||||||
instance: Instanssi
|
instance: Instanssi
|
||||||
|
@ -41,3 +41,183 @@ favorite: Lisää kirjanmerkkeihin
|
||||||
copyContent: Kopioi sisältö
|
copyContent: Kopioi sisältö
|
||||||
deleteAndEdit: Poista ja muokkaa
|
deleteAndEdit: Poista ja muokkaa
|
||||||
copyLink: Kopioi linkki
|
copyLink: Kopioi linkki
|
||||||
|
makeFollowManuallyApprove: Seuraajapyyntö vaatii hyväksymistä
|
||||||
|
follow: Seuraa
|
||||||
|
pinned: Kiinnitä profiiliin
|
||||||
|
followRequestPending: Seuraajapyyntö odottaa
|
||||||
|
you: Sinä
|
||||||
|
unrenote: Peruuta buustaus
|
||||||
|
reaction: Reaktiot
|
||||||
|
reactionSettingDescription2: Vedä uudelleenjärjestelläksesi, napsauta poistaaksesi,
|
||||||
|
paina "+" lisätäksesi.
|
||||||
|
attachCancel: Poista liite
|
||||||
|
enterFileName: Anna tiedostonimi
|
||||||
|
mute: Hiljennä
|
||||||
|
unmute: Poista hiljennys
|
||||||
|
headlineMisskey: Avoimen lähdekoodin, hajautettu sosiaalisen median alusta, joka on
|
||||||
|
ikuisesti ilmainen! 🚀
|
||||||
|
monthAndDay: '{day}/{month}'
|
||||||
|
deleteAndEditConfirm: Oletko varma, että haluat poistaa tämän lähetyksen ja muokata
|
||||||
|
sitä? Menetät kaikki reaktiot, buustaukset ja vastaukset lähetyksestäsi.
|
||||||
|
addToList: Lisää listaan
|
||||||
|
sendMessage: Lähetä viesti
|
||||||
|
reply: Vastaa
|
||||||
|
loadMore: Lataa enemmän
|
||||||
|
showMore: Näytä enemmän
|
||||||
|
receiveFollowRequest: Seuraajapyyntö vastaanotettu
|
||||||
|
followRequestAccepted: Seuraajapyyntö hyväksytty
|
||||||
|
mentions: Maininnat
|
||||||
|
importAndExport: Tuo/Vie Tietosisältö
|
||||||
|
import: Tuo
|
||||||
|
export: Vie
|
||||||
|
files: Tiedostot
|
||||||
|
download: Lataa
|
||||||
|
unfollowConfirm: Oletko varma, ettet halua seurata enää käyttäjää {name}?
|
||||||
|
noLists: Sinulla ei ole listoja
|
||||||
|
note: Lähetys
|
||||||
|
notes: Lähetykset
|
||||||
|
following: Seuraa
|
||||||
|
createList: Luo lista
|
||||||
|
manageLists: Hallitse listoja
|
||||||
|
error: Virhe
|
||||||
|
somethingHappened: On tapahtunut virhe
|
||||||
|
retry: Yritä uudelleen
|
||||||
|
pageLoadError: Virhe ladattaessa sivua.
|
||||||
|
serverIsDead: Tämä palvelin ei vastaa. Yritä hetken kuluttua uudelleen.
|
||||||
|
youShouldUpgradeClient: Nähdäksesi tämän sivun, virkistä päivittääksesi asiakasohjelmasi.
|
||||||
|
privacy: Tietosuoja
|
||||||
|
defaultNoteVisibility: Oletusnäkyvyys
|
||||||
|
followRequest: Seuraajapyyntö
|
||||||
|
followRequests: Seuraajapyynnöt
|
||||||
|
unfollow: Poista seuraaminen
|
||||||
|
enterEmoji: Syötä emoji
|
||||||
|
renote: Buustaa
|
||||||
|
renoted: Buustattu.
|
||||||
|
cantRenote: Tätä lähetystä ei voi buustata.
|
||||||
|
cantReRenote: Buustausta ei voi buustata.
|
||||||
|
quote: Lainaus
|
||||||
|
pinnedNote: Lukittu lähetys
|
||||||
|
clickToShow: Napsauta nähdäksesi
|
||||||
|
sensitive: Herkkää sisältöä (NSFW)
|
||||||
|
add: Lisää
|
||||||
|
enableEmojiReactions: Ota käyttöön emoji-reaktiot
|
||||||
|
showEmojisInReactionNotifications: Näytä emojit reaktioilmoituksissa
|
||||||
|
reactionSetting: Reaktiot näytettäväksi reaktiovalitsimessa
|
||||||
|
rememberNoteVisibility: Muista lähetyksen näkyvyysasetukset
|
||||||
|
markAsSensitive: Merkitse herkäksi sisällöksi (NSFW)
|
||||||
|
unmarkAsSensitive: Poista merkintä herkkää sisältöä (NSFW)
|
||||||
|
renoteMute: Hiljennä buustit
|
||||||
|
renoteUnmute: Poista buustien hiljennys
|
||||||
|
block: Estä
|
||||||
|
unblock: Poista esto
|
||||||
|
unsuspend: Poista keskeytys
|
||||||
|
suspend: Keskeytys
|
||||||
|
blockConfirm: Oletko varma, että haluat estää tämän tilin?
|
||||||
|
unblockConfirm: Oletko varma, että haluat poistaa tämän tilin eston?
|
||||||
|
selectAntenna: Valitse antenni
|
||||||
|
selectWidget: Valitse vimpain
|
||||||
|
editWidgets: Muokkaa vimpaimia
|
||||||
|
editWidgetsExit: Valmis
|
||||||
|
emoji: Emoji
|
||||||
|
emojis: Emojit
|
||||||
|
emojiName: Emojin nimi
|
||||||
|
emojiUrl: Emojin URL-linkki
|
||||||
|
cacheRemoteFiles: Taltioi etätiedostot välimuistiin
|
||||||
|
flagAsBot: Merkitse tili botiksi
|
||||||
|
flagAsBotDescription: Ota tämä vaihtoehto käyttöön, jos tätä tiliä ohjaa ohjelma.
|
||||||
|
Jos se on käytössä, se toimii lippuna muille kehittäjille, jotta estetään loputtomat
|
||||||
|
vuorovaikutusketjut muiden bottien kanssa ja säädetään Calckeyn sisäiset järjestelmät
|
||||||
|
käsittelemään tätä tiliä botina.
|
||||||
|
flagAsCat: Oletko kissa? 🐱
|
||||||
|
flagAsCatDescription: Saat kissan korvat ja puhut kuin kissa!
|
||||||
|
flagSpeakAsCat: Puhu kuin kissa
|
||||||
|
flagShowTimelineReplies: Näytä vastaukset aikajanalla
|
||||||
|
addAccount: Lisää tili
|
||||||
|
loginFailed: Kirjautuminen epäonnistui
|
||||||
|
showOnRemote: Katsele etäinstanssilla
|
||||||
|
general: Yleistä
|
||||||
|
accountMoved: 'Käyttäjä on muuttanut uuteen tiliin:'
|
||||||
|
wallpaper: Taustakuva
|
||||||
|
setWallpaper: Aseta taustakuva
|
||||||
|
searchWith: 'Etsi: {q}'
|
||||||
|
youHaveNoLists: Sinulla ei ole listoja
|
||||||
|
followConfirm: Oletko varma, että haluat seurata käyttäjää {name}?
|
||||||
|
host: Isäntä
|
||||||
|
selectUser: Valitse käyttäjä
|
||||||
|
annotation: Kommentit
|
||||||
|
registeredAt: Rekisteröity
|
||||||
|
latestRequestReceivedAt: Viimeisin pyyntö vastaanotettu
|
||||||
|
latestRequestSentAt: Viimeisin pyyntö lähetetty
|
||||||
|
storageUsage: Tallennustilan käyttö
|
||||||
|
charts: Kaaviot
|
||||||
|
stopActivityDelivery: Lopeta toimintojen lähettäminen
|
||||||
|
blockThisInstance: Estä tämä instanssi
|
||||||
|
operations: Toiminnot
|
||||||
|
metadata: Metatieto
|
||||||
|
monitor: Seuranta
|
||||||
|
jobQueue: Työjono
|
||||||
|
cpuAndMemory: Prosessori ja muisti
|
||||||
|
network: Verkko
|
||||||
|
disk: Levy
|
||||||
|
clearCachedFiles: Tyhjennä välimuisti
|
||||||
|
clearCachedFilesConfirm: Oletko varma, että haluat tyhjentää kaikki välimuistiin tallennetut
|
||||||
|
etätiedostot?
|
||||||
|
blockedInstances: Estetyt instanssit
|
||||||
|
hiddenTags: Piilotetut asiatunnisteet
|
||||||
|
mention: Maininta
|
||||||
|
copyUsername: Kopioi käyttäjänimi
|
||||||
|
searchUser: Etsi käyttäjää
|
||||||
|
showLess: Sulje
|
||||||
|
youGotNewFollower: seurasi sinua
|
||||||
|
directNotes: Yksityisviestit
|
||||||
|
driveFileDeleteConfirm: Oletko varma, että haluat poistaa tiedoston " {name}"? Lähetykset,
|
||||||
|
jotka sisältyvät tiedostoon, poistuvat myös.
|
||||||
|
importRequested: Olet pyytänyt viemistä. Tämä voi viedä hetken.
|
||||||
|
exportRequested: Olet pyytänyt tuomista. Tämä voi viedä hetken. Se lisätään asemaan
|
||||||
|
kun tuonti valmistuu.
|
||||||
|
lists: Listat
|
||||||
|
followers: Seuraajat
|
||||||
|
followsYou: Seuraa sinua
|
||||||
|
pageLoadErrorDescription: Tämä yleensä johtuu verkkovirheistä tai selaimen välimuistista.
|
||||||
|
Kokeile tyhjentämällä välimuisti ja yritä sitten hetken kuluttua uudelleen.
|
||||||
|
enterListName: Anna listalle nimi
|
||||||
|
withNFiles: '{n} tiedosto(t)'
|
||||||
|
instanceInfo: Instanssin tiedot
|
||||||
|
clearQueue: Tyhjennä jono
|
||||||
|
suspendConfirm: Oletko varma, että haluat keskeyttää tämän tilin?
|
||||||
|
unsuspendConfirm: Oletko varma, että haluat poistaa tämän tilin keskeytyksen?
|
||||||
|
selectList: Valitse lista
|
||||||
|
customEmojis: Kustomoitu Emoji
|
||||||
|
addEmoji: Lisää
|
||||||
|
settingGuide: Suositellut asetukset
|
||||||
|
cacheRemoteFilesDescription: Kun tämä asetus ei ole käytössä, etätiedostot on ladattu
|
||||||
|
suoraan etäinstanssilta. Asetuksen poistaminen käytöstä vähentää tallennustilan
|
||||||
|
käyttöä, mutta lisää verkkoliikennettä kun pienoiskuvat eivät muodostu.
|
||||||
|
flagSpeakAsCatDescription: Lähetyksesi nyanifioidaan, kun olet kissatilassa
|
||||||
|
flagShowTimelineRepliesDescription: Näyttää käyttäjien vastaukset muiden käyttäjien
|
||||||
|
lähetyksiin aikajanalla, jos se on päällä.
|
||||||
|
autoAcceptFollowed: Automaattisesti hyväksy seuraamispyynnöt käyttäjiltä, joita seuraat
|
||||||
|
perHour: Tunnissa
|
||||||
|
removeWallpaper: Poista taustakuva
|
||||||
|
recipient: Vastaanottaja(t)
|
||||||
|
federation: Federaatio
|
||||||
|
software: Ohjelmisto
|
||||||
|
proxyAccount: Proxy-tili
|
||||||
|
proxyAccountDescription: Välitystili (Proxy-tili) on tili, joka toimii käyttäjien
|
||||||
|
etäseuraajana tietyin edellytyksin. Kun käyttäjä esimerkiksi lisää etäkäyttäjän
|
||||||
|
luetteloon, etäkäyttäjän toimintaa ei toimiteta instanssiin, jos yksikään paikallinen
|
||||||
|
käyttäjä ei seuraa kyseistä käyttäjää, joten välitystili seuraa sen sijaan.
|
||||||
|
latestStatus: Viimeisin tila
|
||||||
|
selectInstance: Valitse instanssi
|
||||||
|
instances: Instanssit
|
||||||
|
perDay: Päivässä
|
||||||
|
version: Versio
|
||||||
|
statistics: Tilastot
|
||||||
|
clearQueueConfirmTitle: Oletko varma, että haluat tyhjentää jonon?
|
||||||
|
introMisskey: Tervetuloa! Calckey on avoimen lähdekoodin, hajautettu sosiaalisen median
|
||||||
|
alusta, joka on ikuisesti ilmainen! 🚀
|
||||||
|
clearQueueConfirmText: Mitkään välittämättömät lähetykset, jotka ovat jonossa, eivät
|
||||||
|
federoidu. Yleensä tätä toimintoa ei tarvita.
|
||||||
|
blockedInstancesDescription: Lista instanssien isäntänimistä, jotka haluat estää.
|
||||||
|
Listatut instanssit eivät kykene kommunikoimaan enää tämän instanssin kanssa.
|
||||||
|
_lang_: Suomi
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "calckey",
|
"name": "calckey",
|
||||||
"version": "13.2.0-dev38",
|
"version": "13.2.0-dev41",
|
||||||
"codename": "aqua",
|
"codename": "aqua",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 6 KiB |
|
@ -1,25 +1 @@
|
||||||
<svg id="svg10" version="1.1" sodipodi:docname="title_float.svg" inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="1.95 0.97 167.97 103.23">
|
<svg viewBox="1.95 0.97 128 128" width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><linearGradient id="a" gradientTransform="rotate(90)"><stop offset="5%" stop-color="#9ccfd8" style="--darkreader-inline-stopcolor:#265760"/><stop offset="95%" stop-color="#31748f" style="--darkreader-inline-stopcolor:#275d72"/></linearGradient><defs><linearGradient xlink:href="#a" id="f" gradientTransform="scale(1.27567 .7839)" x1="-43.77" y1="98.469" x2="-27.05" y2="137.466" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#a" id="d" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#a" id="e" gradientTransform="scale(1.27567 .7839)" x1="-43.77" y1="98.468" x2="-8.156" y2="98.468" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#a" id="c" gradientTransform="scale(1.27567 .7839)" x1="1.571" y1="1.27" x2="133.179" y2="1.27" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#a" id="b" gradientTransform="scale(1.27567 .7839)" x1="1.571" y1="1.27" x2="133.179" y2="1.27" gradientUnits="userSpaceOnUse"/></defs><g style="fill:url(#b)" transform="translate(.934 25.196) scale(.75646)"><g style="fill:url(#c)" fill="url(#a)" word-spacing="0" letter-spacing="0" font-family="'OTADESIGN Rounded'" font-weight="400"><g transform="translate(-55.341 -52.023) scale(.26953)" style="fill:url(#d)"/><g style="fill:url(#e)"><path style="fill:url(#f)" d="M-41.832 77.19c-3.868 0-7.177 1.358-9.93 4.074-2.716 2.752-4.074 6.063-4.074 9.931 0 3.869 1.358 7.04 4.074 9.793 2.753 2.716 6.064 4.073 9.932 4.073 3.831 0 7.122-1.357 9.875-4.073.855-.855 1.283-1.896 1.283-3.123 0-1.228-.428-2.271-1.283-3.127-.856-.855-1.897-1.281-3.123-1.281-1.229 0-2.27.426-3.125 1.281-1.004 1.042-2.213 1.563-3.627 1.563-3.035-.31-5.208-2.263-5.246-5.106.038-2.842 2.21-4.935 5.244-5.246 1.414 0 2.623.52 3.627 1.563.855.855 1.898 1.283 3.127 1.283 1.226 0 2.267-.428 3.123-1.283.855-.856 1.283-1.897 1.283-3.125 0-1.227-.428-2.268-1.283-3.123-2.753-2.716-6.046-4.075-9.877-4.075zm20.902 6.91c-2.88 0-5.353 1.02-7.422 3.06-.642.643-.964 1.426-.964 2.348 0 .923.322 1.706.964 2.35.644.642 1.427.962 2.348.962.924 0 1.707-.32 2.35-.963.754-.783 1.662-1.173 2.724-1.173 1.09 0 2.026.376 2.809 1.13a3.909 3.909 0 0 1 1.135 2.811c0 1.062-.393 1.97-1.176 2.725-.392.419-.868.7-1.426.84-.141.027-.252.012-.336-.044-.056-.084-.028-.168.084-.251l.84-.881c.643-.643.965-1.411.965-2.305 0-.922-.28-1.663-.838-2.223-.559-.559-1.343-.84-2.35-.84-.698 0-1.397.35-2.095 1.05l-4.866 4.822c-.643.643-.964 1.426-.964 2.347 0 .923.321 1.705.964 2.348 1.957 1.93 4.375 2.894 7.254 2.894 2.908 0 5.396-1.034 7.465-3.103 2.041-2.041 3.06-4.5 3.06-7.379 0-2.907-1.019-5.396-3.06-7.465-2.069-2.04-4.557-3.06-7.465-3.06z" transform="translate(208.34 -284.25) scale(3.6954)" clip-rule="evenodd" fill-rule="evenodd"/></g></g></g></svg>
|
||||||
<sodipodi:namedview id="namedview21" pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" showgrid="false" inkscape:zoom="1.1507704" inkscape:cx="260.69492" inkscape:cy="102.54" inkscape:window-width="1600" inkscape:window-height="931" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="svg10"/>
|
|
||||||
<metadata id="metadata16">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
|
||||||
<dc:title/>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<linearGradient id="myGradient" gradientTransform="rotate(90)">
|
|
||||||
<stop offset="5%" stop-color="#9ccfd8" id="stop5" style="--darkreader-inline-stopcolor: #265760;" data-darkreader-inline-stopcolor=""/>
|
|
||||||
<stop offset="95%" stop-color="#31748f" id="stop7" style="--darkreader-inline-stopcolor: #275d72;" data-darkreader-inline-stopcolor=""/>
|
|
||||||
</linearGradient>
|
|
||||||
<defs id="defs14"/>
|
|
||||||
<g id="g8" fill="url('#myGradient')" word-spacing="0" letter-spacing="0" font-family="OTADESIGN Rounded" font-weight="400">
|
|
||||||
<g id="g17">
|
|
||||||
<g transform="matrix(.26953 0 0 .26953 -55.341 -52.023)" id="g11"/>
|
|
||||||
<g transform="matrix(3.6954 0 0 3.6954 208.34 -284.25)" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" id="g15">
|
|
||||||
<path d="m -41.8312,77.19 c -3.8683,0 -7.1782,1.3578 -9.9311,4.0734 -2.716,2.7525 -4.0734,6.0628 -4.0734,9.9311 5.0539,0.04979 6.082,0.01348 8.7525,0.0011 0.0024,-4.51e-4 0.0044,-6.05e-4 0.0069,-0.0011 0.03779,-2.8423 2.2103,-4.9346 5.2451,-5.2451 1.4137,0 2.6227,0.52089 3.6268,1.5629 0.855,0.8548 1.897,1.2822 3.1257,1.2822 1.2258,0 2.2676,-0.42741 3.1236,-1.2822 0.85499,-0.85567 1.2833,-1.8976 1.2833,-3.1257 0,-1.2264 -0.42828,-2.2673 -1.2833,-3.1231 -2.7528,-2.7156 -6.0446,-4.0734 -9.8761,-4.0734 z m -5.252,14.006 c -3.4453,-5.5934 -3.4667,0.08539 -8.7525,-0.0011 0,3.8683 1.3584,7.0406 4.0744,9.7931 2.7528,2.7156 6.0623,4.0734 9.9305,4.0734 3.8315,0 7.1238,-1.3578 9.8766,-4.0734 0.85499,-0.85577 1.2827,-1.8967 1.2827,-3.1231 0,-1.2282 -0.42775,-2.2701 -1.2827,-3.1257 -0.85596,-0.8548 -1.8978,-1.2822 -3.1236,-1.2822 -1.2287,0 -2.2707,0.42741 -3.1257,1.2822 -1.0041,1.042 -2.2136,1.5623 -3.6273,1.5623 -3.0348,-0.31051 -5.2084,-2.2633 -5.2462,-5.1056 -0.0024,1.1e-5 -0.0039,-1.2e-5 -0.0063,0 z m 26.154,-7.0965 c -2.8795,0 -5.3538,1.0204 -7.4227,3.0612 -0.64257,0.64316 -0.96404,1.4255 -0.96404,2.3472 0,0.92303 0.32146,1.7062 0.96404,2.3493 0.64331,0.64243 1.4265,0.96351 2.3477,0.96351 0.92347,0 1.7068,-0.32108 2.3493,-0.96351 0.75465,-0.78308 1.6632,-1.1744 2.7256,-1.1744 1.0894,0 2.0261,0.37695 2.8091,1.1316 0.75536,0.78309 1.1332,1.7201 1.1332,2.8102 0,1.0617 -0.39242,1.9703 -1.1754,2.7256 -0.39149,0.4193 -0.86676,0.69884 -1.4249,0.83878 -0.14116,0.02773 -0.25248,0.01369 -0.33614,-0.04175 -0.05605,-0.08456 -0.02751,-0.16827 0.08456,-0.25211 l 0.83825,-0.88053 c 0.64329,-0.64315 0.9651,-1.412 0.9651,-2.306 0,-0.92236 -0.27937,-1.6632 -0.83825,-2.2225 -0.55888,-0.55932 -1.3422,-0.83878 -2.3493,-0.83878 -0.6986,0 -1.397,0.34902 -2.0956,1.0475 l -4.8651,4.8223 c -0.64328,0.6438 -0.96457,1.4271 -0.96457,2.3488 0,0.92302 0.32128,1.7053 0.96457,2.3477 1.9568,1.9293 4.3751,2.8942 7.2546,2.8942 2.9072,0 5.3945,-1.0343 7.4634,-3.103 2.0412,-2.0409 3.0618,-4.501 3.0618,-7.3804 0,-2.9072 -1.0206,-5.3952 -3.0618,-7.4639 -2.0689,-2.0409 -4.5562,-3.0612 -7.4634,-3.0612 z" clip-rule="evenodd" fill-rule="nonzero" stroke-miterlimit="2" stroke-width="0" id="path13" sodipodi:nodetypes="cccccccscsccccccscscscccccccscscscscccccscsccscscsccc"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 21 KiB |
BIN
packages/backend/assets/inverse wordmark.png
Normal file
After Width: | Height: | Size: 21 KiB |
|
@ -1,65 +1 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg xml:space="preserve" viewBox="0 0 512 512" height="512" width="512" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="a"><stop style="stop-color:#31748f;stop-opacity:1" offset="0"/><stop style="stop-color:#9ccfd8;stop-opacity:1" offset="1"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="254.819" y1="411.542" x2="259.34" y2="-1.41" gradientUnits="userSpaceOnUse"/></defs><path style="fill:url(#b);fill-opacity:1;stroke-width:.996356" d="M0 0v512h512V0Z"/><g style="font-weight:400;font-family:"OTADESIGN Rounded";letter-spacing:0;word-spacing:0;fill:#fff"><g transform="translate(-38.55 37.929) scale(.5619)" style="fill:#fff"/><path style="fill:#fff" d="M-41.832 77.19c-3.868 0-7.177 1.358-9.93 4.074-2.716 2.752-4.074 6.063-4.074 9.931 0 3.869 1.358 7.04 4.074 9.793 2.753 2.716 6.064 4.073 9.932 4.073 3.831 0 7.122-1.357 9.875-4.073.855-.855 1.283-1.896 1.283-3.123 0-1.228-.428-2.271-1.283-3.127-.856-.855-1.897-1.281-3.123-1.281-1.229 0-2.27.426-3.125 1.281-1.004 1.042-2.213 1.563-3.627 1.563-3.035-.31-5.208-2.263-5.246-5.106.038-2.842 2.21-4.935 5.244-5.246 1.414 0 2.623.52 3.627 1.563.855.855 1.898 1.283 3.127 1.283 1.226 0 2.267-.428 3.123-1.283.855-.856 1.283-1.897 1.283-3.125 0-1.227-.428-2.268-1.283-3.123-2.753-2.716-6.046-4.075-9.877-4.075zm20.902 6.91c-2.88 0-5.353 1.02-7.422 3.06-.642.643-.964 1.426-.964 2.348 0 .923.322 1.706.964 2.35.644.642 1.427.962 2.348.962.924 0 1.707-.32 2.35-.963.754-.783 1.662-1.173 2.724-1.173 1.09 0 2.026.376 2.809 1.13a3.909 3.909 0 0 1 1.135 2.811c0 1.062-.393 1.97-1.176 2.725-.392.419-.868.7-1.426.84-.141.027-.252.012-.336-.044-.056-.084-.028-.168.084-.251l.84-.881c.643-.643.965-1.411.965-2.305 0-.922-.28-1.663-.838-2.223-.559-.559-1.343-.84-2.35-.84-.698 0-1.397.35-2.095 1.05l-4.866 4.822c-.643.643-.964 1.426-.964 2.347 0 .923.321 1.705.964 2.348 1.957 1.93 4.375 2.894 7.254 2.894 2.908 0 5.396-1.034 7.465-3.103 2.041-2.041 3.06-4.5 3.06-7.379 0-2.907-1.019-5.396-3.06-7.465-2.069-2.04-4.557-3.06-7.465-3.06z" transform="translate(511.15 -446.2) scale(7.70387)" clip-rule="evenodd" fill-rule="evenodd"/></g></svg>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="512.0px"
|
|
||||||
height="512.0px"
|
|
||||||
viewBox="0 0 512.0 512.0"
|
|
||||||
version="1.1"
|
|
||||||
id="SVGRoot"
|
|
||||||
sodipodi:docname="inverse wordmark.svg"
|
|
||||||
xml:space="preserve"
|
|
||||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
|
||||||
id="namedview71"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
showgrid="true"
|
|
||||||
inkscape:zoom="0.50150542"
|
|
||||||
inkscape:cx="59.819892"
|
|
||||||
inkscape:cy="189.42966"
|
|
||||||
inkscape:window-width="1600"
|
|
||||||
inkscape:window-height="931"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1"><inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid77" /></sodipodi:namedview><defs
|
|
||||||
id="defs66" /><g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"><path
|
|
||||||
id="rect136"
|
|
||||||
style="fill:#31748f;fill-opacity:1;stroke-width:0.996356"
|
|
||||||
d="M 0,0 V 512 H 512 V 0 Z" /><g
|
|
||||||
id="g17"
|
|
||||||
style="font-weight:400;font-family:'OTADESIGN Rounded';letter-spacing:0;word-spacing:0;fill:#ffffff"
|
|
||||||
transform="matrix(2.0847185,0,0,2.0847185,76.820648,146.38203)"><g
|
|
||||||
transform="matrix(0.26953,0,0,0.26953,-55.341,-52.023)"
|
|
||||||
id="g11"
|
|
||||||
style="fill:#ffffff" /><g
|
|
||||||
transform="matrix(3.6954,0,0,3.6954,208.34,-284.25)"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
fill-rule="evenodd"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-miterlimit="2"
|
|
||||||
id="g15"
|
|
||||||
style="fill:#ffffff"><path
|
|
||||||
d="m -41.8312,77.19 c -3.8683,0 -7.1782,1.3578 -9.9311,4.0734 -2.716,2.7525 -4.0734,6.0628 -4.0734,9.9311 5.0539,0.04979 6.082,0.01348 8.7525,0.0011 0.0024,-4.51e-4 0.0044,-6.05e-4 0.0069,-0.0011 0.03779,-2.8423 2.2103,-4.9346 5.2451,-5.2451 1.4137,0 2.6227,0.52089 3.6268,1.5629 0.855,0.8548 1.897,1.2822 3.1257,1.2822 1.2258,0 2.2676,-0.42741 3.1236,-1.2822 0.85499,-0.85567 1.2833,-1.8976 1.2833,-3.1257 0,-1.2264 -0.42828,-2.2673 -1.2833,-3.1231 -2.7528,-2.7156 -6.0446,-4.0734 -9.8761,-4.0734 z m -5.252,14.006 c -3.4453,-5.5934 -3.4667,0.08539 -8.7525,-0.0011 0,3.8683 1.3584,7.0406 4.0744,9.7931 2.7528,2.7156 6.0623,4.0734 9.9305,4.0734 3.8315,0 7.1238,-1.3578 9.8766,-4.0734 0.85499,-0.85577 1.2827,-1.8967 1.2827,-3.1231 0,-1.2282 -0.42775,-2.2701 -1.2827,-3.1257 -0.85596,-0.8548 -1.8978,-1.2822 -3.1236,-1.2822 -1.2287,0 -2.2707,0.42741 -3.1257,1.2822 -1.0041,1.042 -2.2136,1.5623 -3.6273,1.5623 -3.0348,-0.31051 -5.2084,-2.2633 -5.2462,-5.1056 -0.0024,1.1e-5 -0.0039,-1.2e-5 -0.0063,0 z m 26.154,-7.0965 c -2.8795,0 -5.3538,1.0204 -7.4227,3.0612 -0.64257,0.64316 -0.96404,1.4255 -0.96404,2.3472 0,0.92303 0.32146,1.7062 0.96404,2.3493 0.64331,0.64243 1.4265,0.96351 2.3477,0.96351 0.92347,0 1.7068,-0.32108 2.3493,-0.96351 0.75465,-0.78308 1.6632,-1.1744 2.7256,-1.1744 1.0894,0 2.0261,0.37695 2.8091,1.1316 0.75536,0.78309 1.1332,1.7201 1.1332,2.8102 0,1.0617 -0.39242,1.9703 -1.1754,2.7256 -0.39149,0.4193 -0.86676,0.69884 -1.4249,0.83878 -0.14116,0.02773 -0.25248,0.01369 -0.33614,-0.04175 -0.05605,-0.08456 -0.02751,-0.16827 0.08456,-0.25211 l 0.83825,-0.88053 c 0.64329,-0.64315 0.9651,-1.412 0.9651,-2.306 0,-0.92236 -0.27937,-1.6632 -0.83825,-2.2225 -0.55888,-0.55932 -1.3422,-0.83878 -2.3493,-0.83878 -0.6986,0 -1.397,0.34902 -2.0956,1.0475 l -4.8651,4.8223 c -0.64328,0.6438 -0.96457,1.4271 -0.96457,2.3488 0,0.92302 0.32128,1.7053 0.96457,2.3477 1.9568,1.9293 4.3751,2.8942 7.2546,2.8942 2.9072,0 5.3945,-1.0343 7.4634,-3.103 2.0412,-2.0409 3.0618,-4.501 3.0618,-7.3804 0,-2.9072 -1.0206,-5.3952 -3.0618,-7.4639 -2.0689,-2.0409 -4.5562,-3.0612 -7.4634,-3.0612 z"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
fill-rule="nonzero"
|
|
||||||
stroke-miterlimit="2"
|
|
||||||
stroke-width="0"
|
|
||||||
id="path13"
|
|
||||||
sodipodi:nodetypes="cccccccscsccccccscscscccccccscscscscccccscsccscscsccc"
|
|
||||||
style="fill:#ffffff" /></g></g></g></svg>
|
|
||||||
|
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 20 KiB |
23
packages/backend/migration/1682777547198-LibreTranslate.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export class LibreTranslate1682777547198 {
|
||||||
|
name = "LibreTranslate1682777547198";
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "meta"
|
||||||
|
ADD "libreTranslateApiUrl" character varying(512)
|
||||||
|
`);
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "meta"
|
||||||
|
ADD "libreTranslateApiKey" character varying(128)
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "meta" DROP COLUMN "libreTranslateApiKey"
|
||||||
|
`);
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE "meta" DROP COLUMN "libreTranslateApiUrl"
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
"@bull-board/api": "^4.6.4",
|
"@bull-board/api": "^4.6.4",
|
||||||
"@bull-board/koa": "^4.6.4",
|
"@bull-board/koa": "^4.6.4",
|
||||||
"@bull-board/ui": "^4.6.4",
|
"@bull-board/ui": "^4.6.4",
|
||||||
"@calckey/megalodon": "5.1.24",
|
"@calckey/megalodon": "5.2.0",
|
||||||
"@discordapp/twemoji": "14.0.2",
|
"@discordapp/twemoji": "14.0.2",
|
||||||
"@elastic/elasticsearch": "7.17.0",
|
"@elastic/elasticsearch": "7.17.0",
|
||||||
"@koa/cors": "3.4.3",
|
"@koa/cors": "3.4.3",
|
||||||
|
|
|
@ -89,6 +89,11 @@ export type Source = {
|
||||||
authKey?: string;
|
authKey?: string;
|
||||||
isPro?: boolean;
|
isPro?: boolean;
|
||||||
};
|
};
|
||||||
|
libreTranslate: {
|
||||||
|
managed?: boolean;
|
||||||
|
apiUrl?: string;
|
||||||
|
apiKey?: string;
|
||||||
|
};
|
||||||
email: {
|
email: {
|
||||||
managed?: boolean;
|
managed?: boolean;
|
||||||
address?: string;
|
address?: string;
|
||||||
|
|
|
@ -386,6 +386,18 @@ export class Meta {
|
||||||
})
|
})
|
||||||
public deeplIsPro: boolean;
|
public deeplIsPro: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 512,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public libreTranslateApiUrl: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 128,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
public libreTranslateApiKey: string | null;
|
||||||
|
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
length: 512,
|
length: 512,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|
|
@ -30,6 +30,17 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
set.deeplIsPro = config.deepl.isPro;
|
set.deeplIsPro = config.deepl.isPro;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
config.libreTranslate.managed != null &&
|
||||||
|
config.libreTranslate.managed === true
|
||||||
|
) {
|
||||||
|
if (typeof config.libreTranslate.apiUrl === "string") {
|
||||||
|
set.libreTranslateApiUrl = config.libreTranslate.apiUrl;
|
||||||
|
}
|
||||||
|
if (typeof config.libreTranslate.apiKey === "string") {
|
||||||
|
set.libreTranslateApiKey = config.libreTranslate.apiKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (config.email.managed != null && config.email.managed === true) {
|
if (config.email.managed != null && config.email.managed === true) {
|
||||||
set.enableEmail = true;
|
set.enableEmail = true;
|
||||||
if (typeof config.email.address === "string") {
|
if (typeof config.email.address === "string") {
|
||||||
|
|
|
@ -512,7 +512,8 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
enableGithubIntegration: instance.enableGithubIntegration,
|
enableGithubIntegration: instance.enableGithubIntegration,
|
||||||
enableDiscordIntegration: instance.enableDiscordIntegration,
|
enableDiscordIntegration: instance.enableDiscordIntegration,
|
||||||
enableServiceWorker: instance.enableServiceWorker,
|
enableServiceWorker: instance.enableServiceWorker,
|
||||||
translatorAvailable: instance.deeplAuthKey != null,
|
translatorAvailable:
|
||||||
|
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
|
||||||
pinnedPages: instance.pinnedPages,
|
pinnedPages: instance.pinnedPages,
|
||||||
pinnedClipId: instance.pinnedClipId,
|
pinnedClipId: instance.pinnedClipId,
|
||||||
cacheRemoteFiles: instance.cacheRemoteFiles,
|
cacheRemoteFiles: instance.cacheRemoteFiles,
|
||||||
|
@ -564,6 +565,8 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
|
objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
|
||||||
deeplAuthKey: instance.deeplAuthKey,
|
deeplAuthKey: instance.deeplAuthKey,
|
||||||
deeplIsPro: instance.deeplIsPro,
|
deeplIsPro: instance.deeplIsPro,
|
||||||
|
libreTranslateApiUrl: instance.libreTranslateApiUrl,
|
||||||
|
libreTranslateApiKey: instance.libreTranslateApiKey,
|
||||||
enableIpLogging: instance.enableIpLogging,
|
enableIpLogging: instance.enableIpLogging,
|
||||||
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
enableActiveEmailValidation: instance.enableActiveEmailValidation,
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,6 +124,8 @@ export const paramDef = {
|
||||||
summalyProxy: { type: "string", nullable: true },
|
summalyProxy: { type: "string", nullable: true },
|
||||||
deeplAuthKey: { type: "string", nullable: true },
|
deeplAuthKey: { type: "string", nullable: true },
|
||||||
deeplIsPro: { type: "boolean" },
|
deeplIsPro: { type: "boolean" },
|
||||||
|
libreTranslateApiUrl: { type: "string", nullable: true },
|
||||||
|
libreTranslateApiKey: { type: "string", nullable: true },
|
||||||
enableTwitterIntegration: { type: "boolean" },
|
enableTwitterIntegration: { type: "boolean" },
|
||||||
twitterConsumerKey: { type: "string", nullable: true },
|
twitterConsumerKey: { type: "string", nullable: true },
|
||||||
twitterConsumerSecret: { type: "string", nullable: true },
|
twitterConsumerSecret: { type: "string", nullable: true },
|
||||||
|
@ -515,6 +517,22 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
set.deeplIsPro = ps.deeplIsPro;
|
set.deeplIsPro = ps.deeplIsPro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.libreTranslateApiUrl !== undefined) {
|
||||||
|
if (ps.libreTranslateApiUrl === "") {
|
||||||
|
set.libreTranslateApiUrl = null;
|
||||||
|
} else {
|
||||||
|
set.libreTranslateApiUrl = ps.libreTranslateApiUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps.libreTranslateApiKey !== undefined) {
|
||||||
|
if (ps.libreTranslateApiKey === "") {
|
||||||
|
set.libreTranslateApiKey = null;
|
||||||
|
} else {
|
||||||
|
set.libreTranslateApiKey = ps.libreTranslateApiKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ps.enableIpLogging !== undefined) {
|
if (ps.enableIpLogging !== undefined) {
|
||||||
set.enableIpLogging = ps.enableIpLogging;
|
set.enableIpLogging = ps.enableIpLogging;
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,7 +482,8 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
|
|
||||||
enableServiceWorker: instance.enableServiceWorker,
|
enableServiceWorker: instance.enableServiceWorker,
|
||||||
|
|
||||||
translatorAvailable: instance.deeplAuthKey != null,
|
translatorAvailable:
|
||||||
|
instance.deeplAuthKey != null || instance.libreTranslateApiUrl != null,
|
||||||
defaultReaction: instance.defaultReaction,
|
defaultReaction: instance.defaultReaction,
|
||||||
|
|
||||||
...(ps.detail
|
...(ps.detail
|
||||||
|
|
|
@ -51,15 +51,54 @@ export default define(meta, paramDef, async (ps, user) => {
|
||||||
|
|
||||||
const instance = await fetchMeta();
|
const instance = await fetchMeta();
|
||||||
|
|
||||||
if (instance.deeplAuthKey == null) {
|
if (instance.deeplAuthKey == null && instance.libreTranslateApiUrl == null) {
|
||||||
return 204; // TODO: 良い感じのエラー返す
|
return 204; // TODO: 良い感じのエラー返す
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetLang = ps.targetLang;
|
let targetLang = ps.targetLang;
|
||||||
if (targetLang.includes("-")) targetLang = targetLang.split("-")[0];
|
if (targetLang.includes("-")) targetLang = targetLang.split("-")[0];
|
||||||
|
|
||||||
|
if (instance.libreTranslateApiUrl != null) {
|
||||||
|
const jsonBody = {
|
||||||
|
q: note.text,
|
||||||
|
source: "auto",
|
||||||
|
target: targetLang,
|
||||||
|
format: "text",
|
||||||
|
api_key: instance.libreTranslateApiKey ?? "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = new URL(instance.libreTranslateApiUrl);
|
||||||
|
if (url.pathname.endsWith("/")) {
|
||||||
|
url.pathname = url.pathname.slice(0, -1);
|
||||||
|
}
|
||||||
|
if (!url.pathname.endsWith("/translate")) {
|
||||||
|
url.pathname += "/translate";
|
||||||
|
}
|
||||||
|
const res = await fetch(url.toString(), {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(jsonBody),
|
||||||
|
agent: getAgentByUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
const json = (await res.json()) as {
|
||||||
|
detectedLanguage?: {
|
||||||
|
confidence: number;
|
||||||
|
language: string;
|
||||||
|
};
|
||||||
|
translatedText: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
sourceLang: json.detectedLanguage?.language,
|
||||||
|
text: json.translatedText,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.append("auth_key", instance.deeplAuthKey);
|
params.append("auth_key", instance.deeplAuthKey ?? "");
|
||||||
params.append("text", note.text);
|
params.append("text", note.text);
|
||||||
params.append("target_lang", targetLang);
|
params.append("target_lang", targetLang);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
node_modules
|
|
||||||
/built
|
|
||||||
/coverage
|
|
||||||
/.eslintrc.js
|
|
||||||
/jest.config.ts
|
|
||||||
/test
|
|
||||||
/test-d
|
|
|
@ -1,65 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
parser: "@typescript-eslint/parser",
|
|
||||||
parserOptions: {
|
|
||||||
tsconfigRootDir: __dirname,
|
|
||||||
project: ["./tsconfig.json"],
|
|
||||||
},
|
|
||||||
plugins: ["@typescript-eslint"],
|
|
||||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
|
||||||
rules: {
|
|
||||||
indent: [
|
|
||||||
"error",
|
|
||||||
"tab",
|
|
||||||
{
|
|
||||||
SwitchCase: 1,
|
|
||||||
MemberExpression: "off",
|
|
||||||
flatTernaryExpressions: true,
|
|
||||||
ArrayExpression: "first",
|
|
||||||
ObjectExpression: "first",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"eol-last": ["error", "always"],
|
|
||||||
semi: ["error", "always"],
|
|
||||||
quotes: ["error", "single"],
|
|
||||||
"comma-dangle": ["error", "always-multiline"],
|
|
||||||
"keyword-spacing": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
before: true,
|
|
||||||
after: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"key-spacing": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
beforeColon: false,
|
|
||||||
afterColon: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"space-infix-ops": ["error"],
|
|
||||||
"space-before-blocks": ["error", "always"],
|
|
||||||
"object-curly-spacing": ["error", "always"],
|
|
||||||
"nonblock-statement-body-position": ["error", "beside"],
|
|
||||||
eqeqeq: ["error", "always", { null: "ignore" }],
|
|
||||||
"no-multiple-empty-lines": ["error", { max: 1 }],
|
|
||||||
"no-multi-spaces": ["error"],
|
|
||||||
"no-var": ["error"],
|
|
||||||
"prefer-arrow-callback": ["error"],
|
|
||||||
"no-throw-literal": ["error"],
|
|
||||||
"no-param-reassign": ["warn"],
|
|
||||||
"no-constant-condition": ["warn"],
|
|
||||||
"no-empty-pattern": ["warn"],
|
|
||||||
"@typescript-eslint/no-unnecessary-condition": ["error"],
|
|
||||||
"@typescript-eslint/no-inferrable-types": ["warn"],
|
|
||||||
"@typescript-eslint/no-non-null-assertion": ["warn"],
|
|
||||||
"@typescript-eslint/explicit-function-return-type": ["warn"],
|
|
||||||
"@typescript-eslint/no-misused-promises": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
checksVoidReturn: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"@typescript-eslint/consistent-type-imports": "error",
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -9,9 +9,8 @@
|
||||||
"tsd": "tsd",
|
"tsd": "tsd",
|
||||||
"api": "pnpm api-extractor run --local --verbose",
|
"api": "pnpm api-extractor run --local --verbose",
|
||||||
"api-prod": "pnpm api-extractor run --verbose",
|
"api-prod": "pnpm api-extractor run --verbose",
|
||||||
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint": "pnpm typecheck && pnpm eslint",
|
"lint": "pnpm typecheck && pnpm rome check \"src/*.ts\"",
|
||||||
"jest": "jest --coverage --detectOpenHandles",
|
"jest": "jest --coverage --detectOpenHandles",
|
||||||
"test": "pnpm jest && pnpm tsd"
|
"test": "pnpm jest && pnpm tsd"
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,9 +20,12 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
compiledFormula(): any {
|
compiledFormula(): any {
|
||||||
return katex.renderToString(this.formula, {
|
const katexString = katex.renderToString(this.formula, {
|
||||||
throwOnError: false,
|
throwOnError: false,
|
||||||
} as any);
|
} as any);
|
||||||
|
return this.block
|
||||||
|
? `<div style="text-align:center">${katexString}</div>`
|
||||||
|
: katexString;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tail" :class="{ collapsed }">
|
<div class="tail">
|
||||||
<header>
|
<header>
|
||||||
<span v-if="notification.type === 'pollEnded'">{{
|
<span v-if="notification.type === 'pollEnded'">{{
|
||||||
i18n.ts._notification.pollEnded
|
i18n.ts._notification.pollEnded
|
||||||
|
@ -112,11 +112,11 @@
|
||||||
v-if="notification.type === 'reaction'"
|
v-if="notification.type === 'reaction'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="notePage(notification.note)"
|
:to="notePage(notification.note)"
|
||||||
:title="summary"
|
:title="getNoteSummary(notification.note)"
|
||||||
>
|
>
|
||||||
<i class="ph-quotes ph-fill ph-lg"></i>
|
<i class="ph-quotes ph-fill ph-lg"></i>
|
||||||
<Mfm
|
<Mfm
|
||||||
:text="summary"
|
:text="getNoteSummary(notification.note)"
|
||||||
:plain="true"
|
:plain="true"
|
||||||
:nowrap="!full"
|
:nowrap="!full"
|
||||||
:custom-emojis="notification.note.emojis"
|
:custom-emojis="notification.note.emojis"
|
||||||
|
@ -142,10 +142,10 @@
|
||||||
v-if="notification.type === 'reply'"
|
v-if="notification.type === 'reply'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="notePage(notification.note)"
|
:to="notePage(notification.note)"
|
||||||
:title="summary"
|
:title="getNoteSummary(notification.note)"
|
||||||
>
|
>
|
||||||
<Mfm
|
<Mfm
|
||||||
:text="summary"
|
:text="getNoteSummary(notification.note)"
|
||||||
:plain="true"
|
:plain="true"
|
||||||
:nowrap="!full"
|
:nowrap="!full"
|
||||||
:custom-emojis="notification.note.emojis"
|
:custom-emojis="notification.note.emojis"
|
||||||
|
@ -155,10 +155,10 @@
|
||||||
v-if="notification.type === 'mention'"
|
v-if="notification.type === 'mention'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="notePage(notification.note)"
|
:to="notePage(notification.note)"
|
||||||
:title="summary"
|
:title="getNoteSummary(notification.note)"
|
||||||
>
|
>
|
||||||
<Mfm
|
<Mfm
|
||||||
:text="summary"
|
:text="getNoteSummary(notification.note)"
|
||||||
:plain="true"
|
:plain="true"
|
||||||
:nowrap="!full"
|
:nowrap="!full"
|
||||||
:custom-emojis="notification.note.emojis"
|
:custom-emojis="notification.note.emojis"
|
||||||
|
@ -168,10 +168,10 @@
|
||||||
v-if="notification.type === 'quote'"
|
v-if="notification.type === 'quote'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="notePage(notification.note)"
|
:to="notePage(notification.note)"
|
||||||
:title="summary"
|
:title="getNoteSummary(notification.note)"
|
||||||
>
|
>
|
||||||
<Mfm
|
<Mfm
|
||||||
:text="summary"
|
:text="getNoteSummary(notification.note)"
|
||||||
:plain="true"
|
:plain="true"
|
||||||
:nowrap="!full"
|
:nowrap="!full"
|
||||||
:custom-emojis="notification.note.emojis"
|
:custom-emojis="notification.note.emojis"
|
||||||
|
@ -181,11 +181,11 @@
|
||||||
v-if="notification.type === 'pollVote'"
|
v-if="notification.type === 'pollVote'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="notePage(notification.note)"
|
:to="notePage(notification.note)"
|
||||||
:title="summary"
|
:title="getNoteSummary(notification.note)"
|
||||||
>
|
>
|
||||||
<i class="ph-quotes ph-fill ph-lg"></i>
|
<i class="ph-quotes ph-fill ph-lg"></i>
|
||||||
<Mfm
|
<Mfm
|
||||||
:text="summary"
|
:text="getNoteSummary(notification.note)"
|
||||||
:plain="true"
|
:plain="true"
|
||||||
:nowrap="!full"
|
:nowrap="!full"
|
||||||
:custom-emojis="notification.note.emojis"
|
:custom-emojis="notification.note.emojis"
|
||||||
|
@ -196,11 +196,11 @@
|
||||||
v-if="notification.type === 'pollEnded'"
|
v-if="notification.type === 'pollEnded'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="notePage(notification.note)"
|
:to="notePage(notification.note)"
|
||||||
:title="summary"
|
:title="getNoteSummary(notification.note)"
|
||||||
>
|
>
|
||||||
<i class="ph-quotes ph-fill ph-lg"></i>
|
<i class="ph-quotes ph-fill ph-lg"></i>
|
||||||
<Mfm
|
<Mfm
|
||||||
:text="summary"
|
:text="getNoteSummary(notification.note)"
|
||||||
:plain="true"
|
:plain="true"
|
||||||
:nowrap="!full"
|
:nowrap="!full"
|
||||||
:custom-emojis="notification.note.emojis"
|
:custom-emojis="notification.note.emojis"
|
||||||
|
@ -264,7 +264,6 @@
|
||||||
<span v-if="notification.type === 'app'" class="text">
|
<span v-if="notification.type === 'app'" class="text">
|
||||||
<Mfm :text="notification.body" :nowrap="!full" />
|
<Mfm :text="notification.body" :nowrap="!full" />
|
||||||
</span>
|
</span>
|
||||||
<xShowMoreButton v-if="isLong" v-model="collapsed"></xShowMoreButton>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -275,7 +274,6 @@ import * as misskey from "calckey-js";
|
||||||
import XReactionIcon from "@/components/MkReactionIcon.vue";
|
import XReactionIcon from "@/components/MkReactionIcon.vue";
|
||||||
import MkFollowButton from "@/components/MkFollowButton.vue";
|
import MkFollowButton from "@/components/MkFollowButton.vue";
|
||||||
import XReactionTooltip from "@/components/MkReactionTooltip.vue";
|
import XReactionTooltip from "@/components/MkReactionTooltip.vue";
|
||||||
import XShowMoreButton from "./MkShowMoreButton.vue";
|
|
||||||
import { getNoteSummary } from "@/scripts/get-note-summary";
|
import { getNoteSummary } from "@/scripts/get-note-summary";
|
||||||
import { notePage } from "@/filters/note";
|
import { notePage } from "@/filters/note";
|
||||||
import { userPage } from "@/filters/user";
|
import { userPage } from "@/filters/user";
|
||||||
|
@ -301,19 +299,12 @@ const props = withDefaults(
|
||||||
const elRef = ref<HTMLElement>(null);
|
const elRef = ref<HTMLElement>(null);
|
||||||
const reactionRef = ref(null);
|
const reactionRef = ref(null);
|
||||||
|
|
||||||
const summary = getNoteSummary(props.notification.note);
|
|
||||||
|
|
||||||
const showEmojiReactions =
|
const showEmojiReactions =
|
||||||
defaultStore.state.enableEmojiReactions ||
|
defaultStore.state.enableEmojiReactions ||
|
||||||
defaultStore.state.showEmojisInReactionNotifications;
|
defaultStore.state.showEmojisInReactionNotifications;
|
||||||
const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReaction)
|
const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReaction)
|
||||||
? instance.defaultReaction
|
? instance.defaultReaction
|
||||||
: "⭐";
|
: "⭐";
|
||||||
const isLong = (summary.split("\n").length > 3 || summary.length > 200);
|
|
||||||
const collapsed = $ref(isLong);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let readObserver: IntersectionObserver | undefined;
|
let readObserver: IntersectionObserver | undefined;
|
||||||
let connection;
|
let connection;
|
||||||
|
@ -495,7 +486,6 @@ useTooltip(reactionRef, (showing) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
> .tail {
|
> .tail {
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
|
@ -536,17 +526,6 @@ useTooltip(reactionRef, (showing) => {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.collapsed > .text {
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
max-height: calc(4em + 50px);
|
|
||||||
overflow: hidden;
|
|
||||||
mask: linear-gradient(black calc(100% - 64px), transparent);
|
|
||||||
-webkit-mask: linear-gradient(
|
|
||||||
black calc(100% - 64px),
|
|
||||||
transparent
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
<template>
|
|
||||||
<button
|
|
||||||
v-if="modelValue"
|
|
||||||
class="fade _button"
|
|
||||||
@click.stop="toggle"
|
|
||||||
>
|
|
||||||
<span>{{ i18n.ts.showMore }}</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
v-if="!modelValue"
|
|
||||||
class="showLess _button"
|
|
||||||
@click.stop="toggle"
|
|
||||||
>
|
|
||||||
<span>{{ i18n.ts.showLess }}</span>
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { i18n } from "@/i18n";
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
modelValue: boolean;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(ev: "update:modelValue", v: boolean): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const toggle = () => {
|
|
||||||
emit("update:modelValue", !props.modelValue);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.showLess {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 1em;
|
|
||||||
position: sticky;
|
|
||||||
bottom: var(--stickyBottom);
|
|
||||||
|
|
||||||
> span {
|
|
||||||
display: inline-block;
|
|
||||||
background: var(--panel);
|
|
||||||
padding: 6px 10px;
|
|
||||||
font-size: 0.8em;
|
|
||||||
border-radius: 999px;
|
|
||||||
box-shadow: 0 0 7px 7px var(--bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -120,7 +120,6 @@ import XNoteSimple from "@/components/MkNoteSimple.vue";
|
||||||
import XMediaList from "@/components/MkMediaList.vue";
|
import XMediaList from "@/components/MkMediaList.vue";
|
||||||
import XPoll from "@/components/MkPoll.vue";
|
import XPoll from "@/components/MkPoll.vue";
|
||||||
import MkUrlPreview from "@/components/MkUrlPreview.vue";
|
import MkUrlPreview from "@/components/MkUrlPreview.vue";
|
||||||
import XShowMoreButton from "./MkShowMoreButton.vue";
|
|
||||||
import XCwButton from "@/components/MkCwButton.vue";
|
import XCwButton from "@/components/MkCwButton.vue";
|
||||||
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
import { extractUrlFromMfm } from "@/scripts/extract-url-from-mfm";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
@ -145,7 +144,6 @@ const isLong =
|
||||||
props.note.text != null &&
|
props.note.text != null &&
|
||||||
(props.note.text.split("\n").length > 9 || props.note.text.length > 500);
|
(props.note.text.split("\n").length > 9 || props.note.text.length > 500);
|
||||||
const collapsed = $ref(props.note.cw == null && isLong);
|
const collapsed = $ref(props.note.cw == null && isLong);
|
||||||
|
|
||||||
const urls = props.note.text
|
const urls = props.note.text
|
||||||
? extractUrlFromMfm(mfm.parse(props.note.text)).slice(0, 5)
|
? extractUrlFromMfm(mfm.parse(props.note.text)).slice(0, 5)
|
||||||
: null;
|
: null;
|
||||||
|
@ -274,6 +272,43 @@ function focusFooter(ev) {
|
||||||
top: 40px;
|
top: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
: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;
|
||||||
|
bottom: var(--stickyBottom);
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: inline-block;
|
||||||
|
background: var(--panel);
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
border-radius: 999px;
|
||||||
|
box-shadow: 0 0 7px 7px var(--bg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,20 @@
|
||||||
:custom-emojis="user.emojis"
|
:custom-emojis="user.emojis"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<XShowMoreButton v-if="isLong" v-model="collapsed"></XShowMoreButton>
|
<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 v-if="user.fields.length > 0" class="fields">
|
<div v-if="user.fields.length > 0" class="fields">
|
||||||
<dl
|
<dl
|
||||||
v-for="(field, i) in user.fields"
|
v-for="(field, i) in user.fields"
|
||||||
|
@ -115,7 +128,6 @@ import * as Acct from "calckey-js/built/acct";
|
||||||
import type * as misskey from "calckey-js";
|
import type * as misskey from "calckey-js";
|
||||||
import MkFollowButton from "@/components/MkFollowButton.vue";
|
import MkFollowButton from "@/components/MkFollowButton.vue";
|
||||||
import { userPage } from "@/filters/user";
|
import { userPage } from "@/filters/user";
|
||||||
import XShowMoreButton from "./MkShowMoreButton.vue";
|
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { $i } from "@/account";
|
import { $i } from "@/account";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
|
|
|
@ -371,6 +371,34 @@
|
||||||
<template #label>Pro account</template>
|
<template #label>Pro account</template>
|
||||||
</FormSwitch>
|
</FormSwitch>
|
||||||
</FormSection>
|
</FormSection>
|
||||||
|
|
||||||
|
<FormSection>
|
||||||
|
<template #label>Libre Translate</template>
|
||||||
|
|
||||||
|
<FormInput
|
||||||
|
v-model="libreTranslateApiUrl"
|
||||||
|
class="_formBlock"
|
||||||
|
>
|
||||||
|
<template #prefix
|
||||||
|
><i class="ph-link ph-bold ph-lg"></i
|
||||||
|
></template>
|
||||||
|
<template #label
|
||||||
|
>Libre Translate API URL</template
|
||||||
|
>
|
||||||
|
</FormInput>
|
||||||
|
|
||||||
|
<FormInput
|
||||||
|
v-model="libreTranslateApiKey"
|
||||||
|
class="_formBlock"
|
||||||
|
>
|
||||||
|
<template #prefix
|
||||||
|
><i class="ph-key ph-bold ph-lg"></i
|
||||||
|
></template>
|
||||||
|
<template #label
|
||||||
|
>Libre Translate API Key</template
|
||||||
|
>
|
||||||
|
</FormInput>
|
||||||
|
</FormSection>
|
||||||
</div>
|
</div>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
|
@ -422,6 +450,8 @@ let swPublicKey: any = $ref(null);
|
||||||
let swPrivateKey: any = $ref(null);
|
let swPrivateKey: any = $ref(null);
|
||||||
let deeplAuthKey: string = $ref("");
|
let deeplAuthKey: string = $ref("");
|
||||||
let deeplIsPro: boolean = $ref(false);
|
let deeplIsPro: boolean = $ref(false);
|
||||||
|
let libreTranslateApiUrl: string = $ref("");
|
||||||
|
let libreTranslateApiKey: string = $ref("");
|
||||||
let defaultReaction: string = $ref("");
|
let defaultReaction: string = $ref("");
|
||||||
let defaultReactionCustom: string = $ref("");
|
let defaultReactionCustom: string = $ref("");
|
||||||
|
|
||||||
|
@ -456,6 +486,8 @@ async function init() {
|
||||||
swPrivateKey = meta.swPrivateKey;
|
swPrivateKey = meta.swPrivateKey;
|
||||||
deeplAuthKey = meta.deeplAuthKey;
|
deeplAuthKey = meta.deeplAuthKey;
|
||||||
deeplIsPro = meta.deeplIsPro;
|
deeplIsPro = meta.deeplIsPro;
|
||||||
|
libreTranslateApiUrl = meta.libreTranslateApiUrl;
|
||||||
|
libreTranslateApiKey = meta.libreTranslateApiKey;
|
||||||
defaultReaction = ["⭐", "👍", "❤️"].includes(meta.defaultReaction)
|
defaultReaction = ["⭐", "👍", "❤️"].includes(meta.defaultReaction)
|
||||||
? meta.defaultReaction
|
? meta.defaultReaction
|
||||||
: "custom";
|
: "custom";
|
||||||
|
@ -498,6 +530,8 @@ function save() {
|
||||||
swPrivateKey,
|
swPrivateKey,
|
||||||
deeplAuthKey,
|
deeplAuthKey,
|
||||||
deeplIsPro,
|
deeplIsPro,
|
||||||
|
libreTranslateApiUrl,
|
||||||
|
libreTranslateApiKey,
|
||||||
defaultReaction,
|
defaultReaction,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
fetchInstance();
|
fetchInstance();
|
||||||
|
|
|
@ -87,8 +87,8 @@ importers:
|
||||||
specifier: ^4.6.4
|
specifier: ^4.6.4
|
||||||
version: 4.10.2
|
version: 4.10.2
|
||||||
'@calckey/megalodon':
|
'@calckey/megalodon':
|
||||||
specifier: 5.1.24
|
specifier: 5.2.0
|
||||||
version: 5.1.24
|
version: 5.2.0
|
||||||
'@discordapp/twemoji':
|
'@discordapp/twemoji':
|
||||||
specifier: 14.0.2
|
specifier: 14.0.2
|
||||||
version: 14.0.2
|
version: 14.0.2
|
||||||
|
@ -1384,8 +1384,8 @@ packages:
|
||||||
'@bull-board/api': 4.10.2
|
'@bull-board/api': 4.10.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@calckey/megalodon@5.1.24:
|
/@calckey/megalodon@5.2.0:
|
||||||
resolution: {integrity: sha512-VRd6x8MFQ2pMF0rnGF67/GVxgp/92CV7lg2XT1wnPAfQZ1NTsjwlDQX3HewEW3fSG/r7Nzh5WbIBXC8WMWKs9g==}
|
resolution: {integrity: sha512-9MEjzKJPyd7o5bHGGlNq4oE1tMt22GUJ8o8tZXcXSpXlrSDb2rSwumirM1KXUWTW8G6NGi1leCM59gOBGLko3w==}
|
||||||
engines: {node: '>=15.0.0'}
|
engines: {node: '>=15.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/oauth': 0.9.1
|
'@types/oauth': 0.9.1
|
||||||
|
@ -5910,8 +5910,8 @@ packages:
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/core-js@3.30.0:
|
/core-js@3.30.1:
|
||||||
resolution: {integrity: sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg==}
|
resolution: {integrity: sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -15413,7 +15413,7 @@ packages:
|
||||||
name: plyr
|
name: plyr
|
||||||
version: 3.7.0
|
version: 3.7.0
|
||||||
dependencies:
|
dependencies:
|
||||||
core-js: 3.30.0
|
core-js: 3.30.1
|
||||||
custom-event-polyfill: 1.0.7
|
custom-event-polyfill: 1.0.7
|
||||||
loadjs: 4.2.0
|
loadjs: 4.2.0
|
||||||
rangetouch: 2.0.1
|
rangetouch: 2.0.1
|
||||||
|
|