mirror of
https://iceshrimp.dev/crimekillz/iceshrimp-161sh.git
synced 2024-11-25 05:29:07 +01:00
Merge branch 'develop' of https://codeberg.org/calckey/calckey into keyboard-accessability
This commit is contained in:
commit
7e2d5c45d2
@ -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
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",
|
||||||
|
BIN
packages/backend/assets/favicon.ico
(Stored with Git LFS)
BIN
packages/backend/assets/favicon.ico
(Stored with Git LFS)
Binary file not shown.
BIN
packages/backend/assets/favicon.png
(Stored with Git LFS)
BIN
packages/backend/assets/favicon.png
(Stored with Git LFS)
Binary file not shown.
BIN
packages/backend/assets/favicon.svg
(Stored with Git LFS)
BIN
packages/backend/assets/favicon.svg
(Stored with Git LFS)
Binary file not shown.
BIN
packages/backend/assets/icons/192.png
(Stored with Git LFS)
BIN
packages/backend/assets/icons/192.png
(Stored with Git LFS)
Binary file not shown.
BIN
packages/backend/assets/icons/512.png
(Stored with Git LFS)
BIN
packages/backend/assets/icons/512.png
(Stored with Git LFS)
Binary file not shown.
BIN
packages/backend/assets/inverse wordmark.png
(Stored with Git LFS)
Normal file
BIN
packages/backend/assets/inverse wordmark.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
packages/backend/assets/inverse wordmark.svg
(Stored with Git LFS)
BIN
packages/backend/assets/inverse wordmark.svg
(Stored with Git LFS)
Binary file not shown.
BIN
packages/backend/assets/splash.png
(Stored with Git LFS)
BIN
packages/backend/assets/splash.png
(Stored with Git LFS)
Binary file not shown.
23
packages/backend/migration/1682777547198-LibreTranslate.js
Normal file
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
|
||||||
|
Loading…
Reference in New Issue
Block a user