Merge branch 'develop' into gh-fa55fa5e/10452/unknown/rtl
This commit is contained in:
commit
78a67525d3
64 changed files with 250 additions and 160 deletions
Binary file not shown.
BIN
custom/assets/badges/error.webp
Normal file
BIN
custom/assets/badges/error.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
BIN
custom/assets/badges/info.webp
Normal file
BIN
custom/assets/badges/info.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
BIN
custom/assets/badges/not-found.webp
Normal file
BIN
custom/assets/badges/not-found.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
|
@ -1,9 +1,11 @@
|
|||
# Changes to the Firefish API
|
||||
|
||||
Breaking changes are indecated by the :warning: icon.
|
||||
Breaking changes are indicated by the :warning: icon.
|
||||
|
||||
## v1.0.5 (unreleased)
|
||||
|
||||
### dev17
|
||||
|
||||
- Added `lang` parameter to `notes/create` and `notes/edit`.
|
||||
|
||||
### dev11
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
There is a `docker-compose.yml` in the root of the project that you can use to build the container from source
|
||||
|
||||
- .config/docker.env (**db config settings**)
|
||||
- .config/docker_example.env (**db config settings**)
|
||||
- .config/default.yml (**firefish server settings**)
|
||||
|
||||
## Configuring
|
||||
|
@ -16,7 +16,7 @@ Rename the files:
|
|||
|
||||
`cp .config/example.yml .config/default.yml`
|
||||
|
||||
`cp .config/example.env .config/docker.env`
|
||||
`cp .config/docker_example.env .config/docker.env`
|
||||
|
||||
then edit them according to your environment.
|
||||
You can configure `docker.env` with anything you like, but you will have to pay attention to the `default.yml` file:
|
||||
|
|
|
@ -1441,7 +1441,8 @@ _accountDelete:
|
|||
requestAccountDelete: Sol·licitar la supressió del compte
|
||||
_ad:
|
||||
back: Enrera
|
||||
reduceFrequencyOfThisAd: Mostrar aquest anunci menys
|
||||
reduceFrequencyOfThisAd: Mostrar menys aquest anunci
|
||||
adsBy: Anunci comunitari per {by}
|
||||
_gallery:
|
||||
my: La meva Galeria
|
||||
liked: Publicacions que m'han agradat
|
||||
|
@ -1539,8 +1540,8 @@ low: Baixa
|
|||
emailNotConfiguredWarning: L'adreça de correu electrònic no està definida.
|
||||
instanceSecurity: Seguretat del servidor
|
||||
privateMode: Mode Privat
|
||||
allowedInstances: Servidors a la llista blanca
|
||||
allowedInstancesDescription: Llista blanca de Hosts amb qui federar, cadascún separat
|
||||
allowedInstances: Servidors permesos
|
||||
allowedInstancesDescription: Llista permesa de Hosts amb qui federar, cadascún separat
|
||||
per una línia nova (només s'aplica en mode privat).
|
||||
previewNoteText: Mostra la vista prèvia
|
||||
customCss: CSS personalitzat
|
||||
|
@ -1552,7 +1553,7 @@ troubleshooting: Resolució de problemes
|
|||
learnMore: Més informació
|
||||
misskeyUpdated: Firefish s'ha actualitzat!
|
||||
translate: Tradueix
|
||||
translatedFrom: Traduït per {x}
|
||||
translatedFrom: Traduït desde {x}
|
||||
aiChanMode: Ai-chan a la interfície d'usuari clàssica
|
||||
keepCw: Mantenir els avisos de contingut
|
||||
pubSub: Comptes Pub/Sub
|
||||
|
@ -1646,8 +1647,8 @@ customCssWarn: Aquesta configuració només s'ha d'utilitzar si sabeu què fa. L
|
|||
squareAvatars: Mostra avatars quadrats
|
||||
secureModeInfo: Quan es faci una solicitut d'altres servidors no contestar sense una
|
||||
prova.
|
||||
privateModeInfo: Quan està activat, només els servidors a la llista blanca es poden
|
||||
federar amb el vostre servidor. Totes les publicacions s'amagaran al públic.
|
||||
privateModeInfo: Quan està activat, només els servidors a la llista es poden federar
|
||||
amb el vostre servidor. Totes les publicacions s'amagaran al públic.
|
||||
useBlurEffect: Utilitzeu efectes de desenfocament a la interfície d'usuari
|
||||
accountDeletionInProgress: La supressió del compte està en curs
|
||||
unmuteThread: Desfés el silenci al fil
|
||||
|
|
|
@ -83,7 +83,8 @@ exportRequested: "You've requested an export. This may take a while. It will be
|
|||
to your Drive once completed."
|
||||
importRequested: "You've requested an import. This may take a while."
|
||||
lists: "Lists"
|
||||
listsDesc: "Lists let you create timelines with specified users. They can be accessed from the timelines page."
|
||||
listsDesc: "Lists let you create timelines with specified users. They can be accessed
|
||||
from the timelines page."
|
||||
noLists: "You don't have any lists"
|
||||
note: "Post"
|
||||
notes: "Posts"
|
||||
|
@ -408,7 +409,8 @@ avoidMultiCaptchaConfirm: "Using multiple Captcha systems may cause interference
|
|||
them. Would you like to disable the other Captcha systems currently active? If you
|
||||
would like them to stay enabled, press cancel."
|
||||
antennas: "Antennas"
|
||||
antennasDesc: "Antennas display new posts matching the criteria you set!\n They can be accessed from the timelines page."
|
||||
antennasDesc: "Antennas display new posts matching the criteria you set!\n They can
|
||||
be accessed from the timelines page."
|
||||
manageAntennas: "Manage Antennas"
|
||||
name: "Name"
|
||||
antennaSource: "Antenna source"
|
||||
|
@ -603,7 +605,8 @@ output: "Output"
|
|||
script: "Script"
|
||||
disablePagesScript: "Disable AiScript on Pages"
|
||||
expandOnNoteClick: "Open post on click"
|
||||
expandOnNoteClickDesc: "If disabled, you can still open posts in the right-click menu or by clicking the timestamp."
|
||||
expandOnNoteClickDesc: "If disabled, you can still open posts in the right-click menu
|
||||
or by clicking the timestamp."
|
||||
updateRemoteUser: "Update remote user information"
|
||||
deleteAllFiles: "Delete all files"
|
||||
deleteAllFilesConfirm: "Are you sure that you want to delete all files?"
|
||||
|
@ -743,8 +746,8 @@ unclip: "Unclip"
|
|||
confirmToUnclipAlreadyClippedNote: "This post is already part of the \"{name}\" clip.
|
||||
Do you want to remove it from this clip instead?"
|
||||
public: "Public"
|
||||
i18nInfo: "Firefish is being translated into various languages by volunteers. You can
|
||||
help at {link}."
|
||||
i18nInfo: "Firefish is being translated into various languages by volunteers. You
|
||||
can help at {link}."
|
||||
manageAccessTokens: "Manage access tokens"
|
||||
accountInfo: "Account Info"
|
||||
notesCount: "Number of posts"
|
||||
|
@ -779,7 +782,8 @@ pageLikedCount: "Number of received Page likes"
|
|||
contact: "Contact"
|
||||
useSystemFont: "Use the system's default font"
|
||||
clips: "Clips"
|
||||
clipsDesc: "Clips are like share-able categorized bookmarks. You can create clips from the menu of individual posts."
|
||||
clipsDesc: "Clips are like share-able categorized bookmarks. You can create clips
|
||||
from the menu of individual posts."
|
||||
experimentalFeatures: "Experimental features"
|
||||
developer: "Developer"
|
||||
makeExplorable: "Make account visible in \"Explore\""
|
||||
|
@ -888,10 +892,10 @@ secureMode: "Secure Mode (Authorized Fetch)"
|
|||
instanceSecurity: "Server Security"
|
||||
secureModeInfo: "When requesting from other servers, do not send back without proof."
|
||||
privateMode: "Private Mode"
|
||||
privateModeInfo: "When enabled, only whitelisted servers can federate with your server.
|
||||
privateModeInfo: "When enabled, only allowlisted servers can federate with your server.
|
||||
All posts will be hidden from the public."
|
||||
allowedInstances: "Whitelisted Servers"
|
||||
allowedInstancesDescription: "Hosts of servers to be whitelisted for federation, each
|
||||
allowedInstances: "Allowlisted Servers"
|
||||
allowedInstancesDescription: "Hosts of servers to be allowlisted for federation, each
|
||||
separated by a new line (only applies in private mode)."
|
||||
previewNoteText: "Show preview"
|
||||
customCss: "Custom CSS"
|
||||
|
@ -1083,8 +1087,8 @@ license: "License"
|
|||
indexPosts: "Index Posts"
|
||||
indexFrom: "Index from Post ID onwards"
|
||||
indexFromDescription: "Leave blank to index every post"
|
||||
indexNotice: "Now indexing. This will probably take a while, please don't restart\
|
||||
\ your server for at least an hour."
|
||||
indexNotice: "Now indexing. This will probably take a while, please don't restart
|
||||
your server for at least an hour."
|
||||
customKaTeXMacro: "Custom KaTeX macros"
|
||||
customKaTeXMacroDescription: "Set up macros to write mathematical expressions easily!
|
||||
The notation conforms to the LaTeX command definitions and is written as \\newcommand{\\
|
||||
|
@ -1132,9 +1136,11 @@ origin: "Origin"
|
|||
delete2fa: "Disable 2FA"
|
||||
deletePasskeys: "Delete passkeys"
|
||||
delete2faConfirm: "This will irreversibly delete 2FA on this account. Proceed?"
|
||||
deletePasskeysConfirm: "This will irreversibly delete all passkeys and security keys on this account. Proceed?"
|
||||
deletePasskeysConfirm: "This will irreversibly delete all passkeys and security keys
|
||||
on this account. Proceed?"
|
||||
inputNotMatch: "Input does not match"
|
||||
addRe: "Add \"re:\" at the beginning of comment in reply to a post with a content warning"
|
||||
addRe: "Add \"re:\" at the beginning of comment in reply to a post with a content
|
||||
warning"
|
||||
confirm: "Confirm"
|
||||
importZip: "Import ZIP"
|
||||
exportZip: "Export ZIP"
|
||||
|
@ -1142,7 +1148,8 @@ emojiPackCreator: "Emoji pack creator"
|
|||
indexable: "Indexable"
|
||||
indexableDescription: "Allow built-in search to show your public posts"
|
||||
languageForTranslation: "Post translation language"
|
||||
detectPostLanguage: "Automatically detect the language and show a translate button for posts in foreign languages"
|
||||
detectPostLanguage: "Automatically detect the language and show a translate button
|
||||
for posts in foreign languages"
|
||||
vibrate: "Play vibrations"
|
||||
openServerInfo: "Show server information by clicking the server ticker on a post"
|
||||
|
||||
|
@ -1237,8 +1244,8 @@ _registry:
|
|||
domain: "Domain"
|
||||
createKey: "Create key"
|
||||
_aboutFirefish:
|
||||
about: "Firefish is a fork of Misskey made by ThatOneCalculator, which has been in
|
||||
development since 2022."
|
||||
about: "Firefish is a fork of Misskey made by ThatOneCalculator, which has been
|
||||
in development since 2022."
|
||||
contributors: "Main contributors"
|
||||
allContributors: "All contributors"
|
||||
misskeyContributors: "Misskey contributors"
|
||||
|
@ -1247,13 +1254,15 @@ _aboutFirefish:
|
|||
donate: "Donate to Firefish"
|
||||
donateTitle: "Enjoying Firefish?"
|
||||
pleaseDonateToFirefish: "Please consider donating to Firefish to support its development."
|
||||
pleaseDonateToHost: "Please also consider donating to your home server, {host}, to help support its operation costs."
|
||||
pleaseDonateToHost: "Please also consider donating to your home server, {host},
|
||||
to help support its operation costs."
|
||||
donateHost: "Donate to {host}"
|
||||
morePatrons: "We also appreciate the support of many other helpers not listed here.
|
||||
Thank you! 🥰"
|
||||
sponsors: "Firefish sponsors"
|
||||
patrons: "Firefish patrons"
|
||||
patronsList: "Listed chronologically, not by donation size. Donate with the link above to get your name on here!"
|
||||
patronsList: "Listed chronologically, not by donation size. Donate with the link
|
||||
above to get your name on here!"
|
||||
_nsfw:
|
||||
respect: "Hide NSFW media"
|
||||
ignore: "Don't hide NSFW media"
|
||||
|
@ -1268,7 +1277,8 @@ _mfm:
|
|||
can be used in many places. Here you can view a list of all available MFM syntax."
|
||||
dummy: "Firefish expands the world of the Fediverse"
|
||||
advanced: "Advanced MFM"
|
||||
advancedDescription: "If disabled, only allows for basic markup unless animated MFM is playing"
|
||||
advancedDescription: "If disabled, only allows for basic markup unless animated
|
||||
MFM is playing"
|
||||
mention: "Mention"
|
||||
mentionDescription: "You can specify a user by using an At-Symbol and a username."
|
||||
hashtag: "Hashtag"
|
||||
|
@ -1524,10 +1534,10 @@ _tutorial:
|
|||
step5_4: "The Local {icon} timeline is where you can see posts from everyone else
|
||||
on this server."
|
||||
step5_5: "The Social {icon} timeline is a combination of the Home and Local timelines."
|
||||
step5_6: "The Recommended {icon} timeline is where you can see posts from servers\
|
||||
\ the admins recommend."
|
||||
step5_7: "The Global {icon} timeline is where you can see posts from every other\
|
||||
\ connected server."
|
||||
step5_6: "The Recommended {icon} timeline is where you can see posts from servers
|
||||
the admins recommend."
|
||||
step5_7: "The Global {icon} timeline is where you can see posts from every other
|
||||
connected server."
|
||||
step6_1: "So, what is this place?"
|
||||
step6_2: "Well, you didn't just join Firefish. You joined a portal to the Fediverse,
|
||||
an interconnected network of thousands of servers."
|
||||
|
@ -1540,23 +1550,29 @@ _2fa:
|
|||
registerTOTP: "Register authenticator app"
|
||||
step1: "First, install an authentication app (such as {a} or {b}) on your device."
|
||||
step2: "Then, scan the QR code displayed on this screen."
|
||||
step2Click: "Clicking on this QR code will allow you to register 2FA to your security key or phone authenticator app."
|
||||
step2Click: "Clicking on this QR code will allow you to register 2FA to your security
|
||||
key or phone authenticator app."
|
||||
step2Url: "You can also enter this URL if you're using a desktop program:"
|
||||
step3Title: "Enter an authentication code"
|
||||
step3: "Enter the token provided by your app to finish setup."
|
||||
step4: "From now on, any future login attempts will ask for such a login token."
|
||||
securityKeyNotSupported: "Your browser does not support security keys."
|
||||
registerTOTPBeforeKey: "Please set up an authenticator app to register a security or pass key."
|
||||
securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup authentication via hardware security keys that support FIDO2 to further secure your account."
|
||||
registerTOTPBeforeKey: "Please set up an authenticator app to register a security
|
||||
or pass key."
|
||||
securityKeyInfo: "Besides fingerprint or PIN authentication, you can also setup
|
||||
authentication via hardware security keys that support FIDO2 to further secure
|
||||
your account."
|
||||
chromePasskeyNotSupported: "Chrome passkeys are currently not supported."
|
||||
registerSecurityKey: "Register a security or pass key"
|
||||
securityKeyName: "Enter a key name"
|
||||
tapSecurityKey: "Please follow your browser to register the security or pass key"
|
||||
removeKey: "Remove security key"
|
||||
removeKeyConfirm: "Really delete the {name} key?"
|
||||
whyTOTPOnlyRenew: "The authenticator app cannot be removed as long as a security key is registered."
|
||||
whyTOTPOnlyRenew: "The authenticator app cannot be removed as long as a security
|
||||
key is registered."
|
||||
renewTOTP: "Reconfigure authenticator app"
|
||||
renewTOTPConfirm: "This will cause verification codes from your previous app to stop working"
|
||||
renewTOTPConfirm: "This will cause verification codes from your previous app to
|
||||
stop working"
|
||||
renewTOTPOk: "Reconfigure"
|
||||
renewTOTPCancel: "Cancel"
|
||||
token: "2FA Token"
|
||||
|
@ -1704,10 +1720,9 @@ _profile:
|
|||
youCanIncludeHashtags: "You can also include hashtags in your bio."
|
||||
metadata: "Additional Information"
|
||||
metadataEdit: "Edit additional Information"
|
||||
metadataDescription:
|
||||
"Using these, you can display additional information fields
|
||||
in your profile. You can add an {a} tag or {l} tag with {rel}
|
||||
to verify the link on your profile!"
|
||||
metadataDescription: "Using these, you can display additional information fields
|
||||
in your profile. You can add an {a} tag or {l} tag with {rel} to verify the link
|
||||
on your profile!"
|
||||
metadataLabel: "Label"
|
||||
metadataContent: "Content"
|
||||
changeAvatar: "Change avatar"
|
||||
|
@ -2118,9 +2133,9 @@ _deck:
|
|||
_experiments:
|
||||
title: "Experiments"
|
||||
enablePostImports: "Enable post imports"
|
||||
postImportsCaption: "Allows users to import their posts from past Firefish,\
|
||||
\ Misskey, Mastodon, Akkoma, and Pleroma accounts. It may cause slowdowns during\
|
||||
\ load if your queue is bottlenecked."
|
||||
postImportsCaption: "Allows users to import their posts from past Firefish, Misskey,
|
||||
Mastodon, Akkoma, and Pleroma accounts. It may cause slowdowns during load if
|
||||
your queue is bottlenecked."
|
||||
_dialog:
|
||||
charactersExceeded: "Max characters exceeded! Current: {current}/Limit: {max}"
|
||||
charactersBelow: "Not enough characters! Current: {current}/Limit: {min}"
|
||||
|
|
|
@ -953,7 +953,8 @@ _accountDelete:
|
|||
inProgress: "Penghapusan sedang dalam proses"
|
||||
_ad:
|
||||
back: "Kembali"
|
||||
reduceFrequencyOfThisAd: "Tampilkan iklan ini lebih sedikit"
|
||||
reduceFrequencyOfThisAd: "Tampilkan banner ini lebih sedikit"
|
||||
adsBy: Banner komunitas oleh {by}
|
||||
_forgotPassword:
|
||||
enterEmail: "Masukkan alamat surel yang kamu gunakan pada saat mendaftar. Sebuah
|
||||
tautan untuk mengatur ulang kata sandi kamu akan dikirimkan ke alamat surel tersebut."
|
||||
|
@ -1923,9 +1924,9 @@ moderation: Moderasi
|
|||
userSaysSomethingReason: '{name} mengatakan {reason}'
|
||||
secureMode: Mode Aman (Pengambilan Terotorisasi)
|
||||
secureModeInfo: Saat meminta dari server lain, jangan kirim kembali tanpa bukti.
|
||||
privateModeInfo: Saat aktif, hanya server yang masuk daftar putih dapat terfederasi
|
||||
dengan servermu. Semua postingan akan disembunyikan dari publik.
|
||||
allowedInstances: Server Masuk Daftar Putih
|
||||
privateModeInfo: Saat aktif, hanya server yang masuk daftar yang diizinkan yang dapat
|
||||
terfederasi dengan servermu. Semua postingan akan disembunyikan dari publik.
|
||||
allowedInstances: Daftar Server Diizinkan
|
||||
newer: lebih baru
|
||||
userSaysSomethingReasonReply: '{name} membalas postingan berisi {reason}'
|
||||
userSaysSomethingReasonRenote: '{name} memposting ulang postingan berisi {reason}'
|
||||
|
@ -1935,8 +1936,8 @@ jumpToPrevious: Lompat ke sebelumnya
|
|||
flagSpeakAsCatDescription: Postinganmu akan nyampak dalam mode kucing
|
||||
cw: Peringatan konten
|
||||
flagSpeakAsCat: Bicara sebagai kucing
|
||||
allowedInstancesDescription: Host server akan masuk daftar putih untuk federasi, mereka
|
||||
dipisahkan dengan baris baru (hanya diterapkan pada mode pribadi).
|
||||
allowedInstancesDescription: Server host akan masuk daftar yang diizinkan untuk federasi,
|
||||
mereka dipisahkan dengan baris baru (hanya diterapkan pada mode pribadi).
|
||||
xl: XL
|
||||
privateMode: Mode Pribadi
|
||||
seperateRenoteQuote: Tombol posting ulang dan kutip terpisah
|
||||
|
@ -2182,3 +2183,4 @@ languageForTranslation: Bahasa terjemahan kiriman
|
|||
openServerInfo: Tampilkan informasi server dengan mengeklik ticker server di sebuah
|
||||
kiriman
|
||||
vibrate: Putar getaran
|
||||
clickToShowPatterns: Klik untuk menampilkan pola modul
|
||||
|
|
|
@ -901,7 +901,8 @@ _accountDelete:
|
|||
caricato.
|
||||
_ad:
|
||||
back: "Indietro"
|
||||
reduceFrequencyOfThisAd: "Mostra meno spesso questa pubblicità"
|
||||
reduceFrequencyOfThisAd: "Mostra meno spesso questo banner"
|
||||
adsBy: Banner della comunità da {by}
|
||||
_forgotPassword:
|
||||
enterEmail: "Inserisci l'e-mail che hai registrato nel tuo profilo. Il link di ripristino
|
||||
della password verrà inviato a questo indirizzo."
|
||||
|
@ -1997,11 +1998,11 @@ secureMode: Modalità sicura (Acquisizione autorizzata)
|
|||
secureModeInfo: Le richieste dai server remoti non ricevono risposta senza prima una
|
||||
verifica.
|
||||
privateMode: Modalità privata
|
||||
allowedInstancesDescription: Gli host dei server che saranno federati in esclusiva,
|
||||
allowedInstancesDescription: Gli host dei server con cui sarà permessa la federazione,
|
||||
uno per riga (funziona solo in modalità privata).
|
||||
privateModeInfo: Se abilitata, solo i server in una whitelist potranno essere federati
|
||||
privateModeInfo: Se abilitata, solo i server nell'elenco potranno essere federati
|
||||
con questo server. Tutti i post saranno nascosti al pubblico.
|
||||
allowedInstances: Whitelist dei server
|
||||
allowedInstances: Elenco server permessi
|
||||
customCssWarn: Questa impostazione dovrebbe essere usata solo se sai cosa stai facendo.
|
||||
Inserire valori errati potrebbe bloccare il funzionamento del client.
|
||||
lastCommunication: Ultima comunicazione
|
||||
|
@ -2170,3 +2171,4 @@ languageForTranslation: Linguaggio di traduzione dei post
|
|||
openServerInfo: Mostra informazioni sul server cliccando sul riquadro del server in
|
||||
un post
|
||||
vibrate: Abilita la vibrazione
|
||||
clickToShowPatterns: Clicca per vedere i pattern del modulo
|
||||
|
|
|
@ -58,7 +58,7 @@ followRequestAccepted: "关注请求已通过"
|
|||
mention: "提及"
|
||||
mentions: "提及"
|
||||
directNotes: "私信"
|
||||
importAndExport: "导入/导出数据"
|
||||
importAndExport: "导入 / 导出数据"
|
||||
import: "导入"
|
||||
export: "导出"
|
||||
files: "文件"
|
||||
|
@ -675,7 +675,7 @@ driveFilesCount: "网盘的文件数"
|
|||
driveUsage: "网盘的空间用量"
|
||||
noCrawle: "要求搜索引擎不索引该用户"
|
||||
noCrawleDescription: "要求外部搜索引擎不收录(索引)您的内容。"
|
||||
lockedAccountInfo: "即使通过了关注请求,只要您不将帖子可见范围设置成“关注者”,任何人都可以看到您的帖子。"
|
||||
lockedAccountInfo: "即使通过了关注请求,只要您不将帖子可见范围设置成「关注者」,任何人都可以看到您的帖子。"
|
||||
alwaysMarkSensitive: "默认将媒体文件标记为敏感内容"
|
||||
loadRawImages: "加载原始图像而不是显示缩略图"
|
||||
disableShowingAnimatedImages: "不播放动画"
|
||||
|
@ -1245,7 +1245,7 @@ _tutorial:
|
|||
step6_1: "那么,这里是什么地方?"
|
||||
step6_2: "好吧,您不只是加入 Firefish。您已经加入了 Fediverse 的一个门户,这是一个由成千上万台服务器组成的互联网络。"
|
||||
step6_3: "每个服务器的工作方式不同,并不是所有的服务器都运行 Firefish。但这个服务器是的! 这有点复杂,但您很快就会明白的。"
|
||||
step6_4: "现在,去吧,去探索,去享受乐趣吧!"
|
||||
step6_4: "现在,去吧,去探索,去享受乐趣吧!"
|
||||
_2fa:
|
||||
alreadyRegistered: "您已经注册了两步验证设备。"
|
||||
registerTOTP: "注册身份验证器应用"
|
||||
|
@ -1917,7 +1917,7 @@ _skinTones:
|
|||
isModerator: 监察员
|
||||
isAdmin: 管理员
|
||||
findOtherInstance: 寻找其它服务器
|
||||
moveFromDescription: 这将为您的旧账号设置一个别名,以便您可以从该旧账号迁移到当前账号。在从旧账号迁移之前执行此操作。请输入格式如@person@server.com
|
||||
moveFromDescription: 这将为您的旧账号设置一个别名,以便您可以从该旧账号迁移到当前账号。在从旧账号迁移之前执行此操作。请输入格式如 @person@server.com
|
||||
的账号标签
|
||||
indexPosts: 索引帖子
|
||||
signupsDisabled: 该服务器目前关闭注册,但您随时可以在另一台服务器上注册!如果您有该服务器的邀请码,请在下面输入。
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"type": "git",
|
||||
"url": "https://git.joinfirefish.org/firefish/firefish.git"
|
||||
},
|
||||
"packageManager": "pnpm@8.7.6",
|
||||
"packageManager": "pnpm@8.8.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"rebuild": "pnpm run clean && ./scripts/build-greet.sh && pnpm --filter !sw -r --parallel run build && pnpm --filter sw run build && pnpm run gulp",
|
||||
|
@ -64,7 +64,7 @@
|
|||
"gulp-replace": "1.1.4",
|
||||
"gulp-terser": "2.1.0",
|
||||
"install-peers": "^1.0.4",
|
||||
"pnpm": "8.7.1",
|
||||
"pnpm": "8.8.0",
|
||||
"start-server-and-test": "1.15.2",
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
|
|
Binary file not shown.
BIN
packages/backend/assets/badges/error.webp
Normal file
BIN
packages/backend/assets/badges/error.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
BIN
packages/backend/assets/badges/info.webp
Normal file
BIN
packages/backend/assets/badges/info.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
BIN
packages/backend/assets/badges/not-found.webp
Normal file
BIN
packages/backend/assets/badges/not-found.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -220,7 +220,7 @@ export class Init1000000000000 {
|
|||
`CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON "notification" ("notifieeId") `,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/static-assets/badges/info.avif', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT '/static-assets/badges/error.avif', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT false, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`,
|
||||
`CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/static-assets/badges/info.webp', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT '/static-assets/badges/error.webp', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT false, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_c76c6e044bdf76ecf8bfb82a645" PRIMARY KEY ("id"))`,
|
||||
|
|
11
packages/backend/src/misc/detect-language.ts
Normal file
11
packages/backend/src/misc/detect-language.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { detect } from "tinyld";
|
||||
import * as mfm from "mfm-js";
|
||||
|
||||
export default function detectLanguage(text: string): string {
|
||||
const nodes = mfm.parse(text);
|
||||
const filtered = mfm.extract(nodes, (node) => {
|
||||
return node.type === "text" || node.type === "quote";
|
||||
});
|
||||
const purified = mfm.toString(filtered);
|
||||
return detect(purified);
|
||||
}
|
|
@ -1,28 +1,31 @@
|
|||
export function nyaize(text: string): string {
|
||||
return (
|
||||
text
|
||||
// ja-JP
|
||||
.replaceAll("な", "にゃ")
|
||||
.replaceAll("ナ", "ニャ")
|
||||
.replaceAll("ナ", "ニャ")
|
||||
// en-US
|
||||
.replace(/(?<=n)a/gi, (x) => (x === "A" ? "YA" : "ya"))
|
||||
.replace(/(?<=morn)ing/gi, (x) => (x === "ING" ? "YAN" : "yan"))
|
||||
.replace(/(?<=every)one/gi, (x) => (x === "ONE" ? "NYAN" : "nyan"))
|
||||
.replace(/non(?=[bcdfghjklmnpqrstvwxyz])/gi, (x) =>
|
||||
x === "NON" ? "NYAN" : "nyan",
|
||||
)
|
||||
// ko-KR
|
||||
.replace(/[나-낳]/g, (match) =>
|
||||
String.fromCharCode(
|
||||
match.charCodeAt(0)! + "냐".charCodeAt(0) - "나".charCodeAt(0),
|
||||
),
|
||||
)
|
||||
.replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, "다냥")
|
||||
.replace(/(야(?=\?))|(야$)|(야(?= ))/gm, "냥")
|
||||
// el-GR
|
||||
.replaceAll("να", "νια")
|
||||
.replaceAll("ΝΑ", "ΝΙΑ")
|
||||
.replaceAll("Να", "Νια")
|
||||
);
|
||||
export function nyaize(text: string, lang?: string): string {
|
||||
text = text
|
||||
// ja-JP
|
||||
.replaceAll("な", "にゃ")
|
||||
.replaceAll("ナ", "ニャ")
|
||||
.replaceAll("ナ", "ニャ")
|
||||
// en-US
|
||||
.replace(/(?<=n)a/gi, (x) => (x === "A" ? "YA" : "ya"))
|
||||
.replace(/(?<=morn)ing/gi, (x) => (x === "ING" ? "YAN" : "yan"))
|
||||
.replace(/(?<=every)one/gi, (x) => (x === "ONE" ? "NYAN" : "nyan"))
|
||||
.replace(/non(?=[bcdfghjklmnpqrstvwxyz])/gi, (x) =>
|
||||
x === "NON" ? "NYAN" : "nyan",
|
||||
)
|
||||
// ko-KR
|
||||
.replace(/[나-낳]/g, (match) =>
|
||||
String.fromCharCode(
|
||||
match.charCodeAt(0)! + "냐".charCodeAt(0) - "나".charCodeAt(0),
|
||||
),
|
||||
)
|
||||
.replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, "다냥")
|
||||
.replace(/(야(?=\?))|(야$)|(야(?= ))/gm, "냥")
|
||||
// el-GR
|
||||
.replaceAll("να", "νια")
|
||||
.replaceAll("ΝΑ", "ΝΙΑ")
|
||||
.replaceAll("Να", "Νια");
|
||||
|
||||
// zh-CN, zh-TW
|
||||
if (lang === "zh") text = text.replace(/(妙|庙|描|渺|瞄|秒|苗|藐|廟)/g, "喵");
|
||||
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ export class Meta {
|
|||
@Column("varchar", {
|
||||
length: 512,
|
||||
nullable: true,
|
||||
default: "/static-assets/badges/info.avif",
|
||||
default: "/static-assets/badges/info.webp",
|
||||
})
|
||||
public mascotImageUrl: string | null;
|
||||
|
||||
|
@ -187,7 +187,7 @@ export class Meta {
|
|||
@Column("varchar", {
|
||||
length: 512,
|
||||
nullable: true,
|
||||
default: "/static-assets/badges/error.avif",
|
||||
default: "/static-assets/badges/error.webp",
|
||||
})
|
||||
public errorImageUrl: string | null;
|
||||
|
||||
|
|
|
@ -264,7 +264,8 @@ export const NoteRepository = db.getRepository(Note).extend({
|
|||
const tokens = packed.text ? mfm.parse(packed.text) : [];
|
||||
function nyaizeNode(node: mfm.MfmNode) {
|
||||
if (node.type === "quote") return;
|
||||
if (node.type === "text") node.props.text = nyaize(node.props.text);
|
||||
if (node.type === "text")
|
||||
node.props.text = nyaize(node.props.text, packed.lang);
|
||||
|
||||
if (node.children) {
|
||||
for (const child of node.children) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { In, IsNull } from "typeorm";
|
||||
import { detect as detectLanguage } from "tinyld";
|
||||
import config from "@/config/index.js";
|
||||
import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
|
||||
import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||
import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js";
|
||||
import type { Emoji } from "@/models/entities/emoji.js";
|
||||
import type { Poll } from "@/models/entities/poll.js";
|
||||
import toHtml from "../misc/get-note-html.js";
|
||||
import toHtml from "@/remote/activitypub/misc/get-note-html.js";
|
||||
import detectLanguage from "@/misc/detect-language.js";
|
||||
import renderEmoji from "./emoji.js";
|
||||
import renderMention from "./mention.js";
|
||||
import renderHashtag from "./hashtag.js";
|
||||
|
|
|
@ -64,7 +64,7 @@ export const meta = {
|
|||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
default: "/static-assets/badges/info.avif",
|
||||
default: "/static-assets/badges/info.webp",
|
||||
},
|
||||
bannerUrl: {
|
||||
type: "string",
|
||||
|
@ -75,7 +75,7 @@ export const meta = {
|
|||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
default: "/static-assets/badges/error.avif",
|
||||
default: "/static-assets/badges/error.webp",
|
||||
},
|
||||
iconUrl: {
|
||||
type: "string",
|
||||
|
|
|
@ -49,7 +49,7 @@ export default define(meta, paramDef, async (ps) => {
|
|||
createNotification(user.id, "app", {
|
||||
customBody: ps.comment,
|
||||
customHeader: "Moderation Notice",
|
||||
customIcon: "/static-assets/badges/info.avif",
|
||||
customIcon: "/static-assets/badges/info.webp",
|
||||
});
|
||||
|
||||
setImmediate(async () => {
|
||||
|
|
|
@ -155,7 +155,7 @@ export const meta = {
|
|||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
default: "/static-assets/badges/info.avif",
|
||||
default: "/static-assets/badges/info.webp",
|
||||
},
|
||||
bannerUrl: {
|
||||
type: "string",
|
||||
|
@ -166,7 +166,7 @@ export const meta = {
|
|||
type: "string",
|
||||
optional: false,
|
||||
nullable: false,
|
||||
default: "/static-assets/badges/error.avif",
|
||||
default: "/static-assets/badges/error.webp",
|
||||
},
|
||||
iconUrl: {
|
||||
type: "string",
|
||||
|
|
|
@ -35,8 +35,8 @@ import renderUpdate from "@/remote/activitypub/renderer/update.js";
|
|||
import { deliverToRelays } from "@/services/relay.js";
|
||||
// import { deliverQuestionUpdate } from "@/services/note/polls/update.js";
|
||||
import { fetchMeta } from "@/misc/fetch-meta.js";
|
||||
import { detect as detectLanguage } from "tinyld";
|
||||
import { langmap } from "@/misc/langmap.js";
|
||||
import detectLanguage from "@/misc/detect-language.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["notes"],
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
/* atkinson-hyperlegible-regular - latin_latin-ext */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Atkinson Hyperlegible";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url("/static-assets/fonts/atkinson-hyperlegible-v11-latin_latin-ext-regular.woff2")
|
||||
format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
html {
|
||||
background-color: var(--bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html {
|
||||
--bg: rgb(17, 17, 27);
|
||||
|
@ -104,7 +115,7 @@ html {
|
|||
}
|
||||
}
|
||||
|
||||
@media(prefers-reduced-motion) {
|
||||
@media (prefers-reduced-motion) {
|
||||
#splashSpinner {
|
||||
display: block;
|
||||
}
|
||||
|
@ -122,5 +133,5 @@ html {
|
|||
height: 0;
|
||||
text-align: center;
|
||||
padding-top: 100px;
|
||||
font-family: sans-serif;
|
||||
font-family: "Atkinson Hyperlegible", sans-serif;
|
||||
}
|
||||
|
|
|
@ -36,9 +36,9 @@ html
|
|||
link(rel='icon' href= icon || `/favicon.ico?${ timestamp }`)
|
||||
link(rel='apple-touch-icon' href= icon || `/apple-touch-icon.png?${ timestamp }`)
|
||||
link(rel='manifest' href='/manifest.json')
|
||||
link(rel='prefetch' href=`/static-assets/badges/info.avif?${ timestamp }`)
|
||||
link(rel='prefetch' href=`/static-assets/badges/not-found.avif?${ timestamp }`)
|
||||
link(rel='prefetch' href=`/static-assets/badges/error.avif?${ timestamp }`)
|
||||
link(rel='prefetch' href=`/static-assets/badges/info.webp?${ timestamp }`)
|
||||
link(rel='prefetch' href=`/static-assets/badges/not-found.webp?${ timestamp }`)
|
||||
link(rel='prefetch' href=`/static-assets/badges/error.webp?${ timestamp }`)
|
||||
link(rel='stylesheet' href=`/static-assets/instance.css?${ timestamp }`)
|
||||
link(rel='modulepreload' href=`/assets/${clientEntry.file}`)
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ async function save(
|
|||
if (type === "image/png") ext = ".png";
|
||||
if (type === "image/webp") ext = ".webp";
|
||||
if (type === "image/apng") ext = ".apng";
|
||||
if (type === "image/avif") ext = ".avif";
|
||||
if (type === "image/avif") ext = ".webp";
|
||||
if (type === "image/vnd.mozilla.apng") ext = ".apng";
|
||||
}
|
||||
|
||||
|
|
|
@ -64,11 +64,11 @@ import type { UserProfile } from "@/models/entities/user-profile.js";
|
|||
import { db } from "@/db/postgre.js";
|
||||
import { getActiveWebhooks } from "@/misc/webhook-cache.js";
|
||||
import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
||||
import meilisearch from "../../db/meilisearch.js";
|
||||
import meilisearch from "@/db/meilisearch.js";
|
||||
import { redisClient } from "@/db/redis.js";
|
||||
import { Mutex } from "redis-semaphore";
|
||||
import { detect as detectLanguage } from "tinyld";
|
||||
import { langmap } from "@/misc/langmap.js";
|
||||
import detectLanguage from "@/misc/detect-language.js";
|
||||
|
||||
const mutedWordsCache = new Cache<
|
||||
{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/not-found.avif"
|
||||
src="/static-assets/badges/not-found.webp"
|
||||
class="_ghost"
|
||||
:alt="i18n.ts.notFound"
|
||||
/>
|
||||
|
|
|
@ -54,7 +54,12 @@
|
|||
<Mfm :text="i18n.ts.password" />
|
||||
</header>
|
||||
<div v-if="text" :class="$style.text">
|
||||
<Mfm :text="text" />
|
||||
<span
|
||||
v-if="isPlaintext === true"
|
||||
style="white-space: pre-line"
|
||||
>{{ text }}</span
|
||||
>
|
||||
<Mfm v-else :text="text" />
|
||||
</div>
|
||||
<MkInput
|
||||
v-if="input && input.type !== 'paragraph'"
|
||||
|
@ -245,6 +250,7 @@ const props = withDefaults(
|
|||
| "search";
|
||||
title: string;
|
||||
text?: string;
|
||||
isPlaintext?: boolean;
|
||||
input?: Input;
|
||||
select?: Select;
|
||||
icon?: string;
|
||||
|
@ -268,6 +274,7 @@ const props = withDefaults(
|
|||
isYesNo: false,
|
||||
|
||||
cancelableByBgClick: true,
|
||||
isPlaintext: false,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ function captionPopup() {
|
|||
os.alert({
|
||||
type: "info",
|
||||
text: props.media.comment,
|
||||
isPlaintext: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -332,6 +332,7 @@ const previewableCount = props.mediaList.filter((media) =>
|
|||
overflow-x: clip;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.pwsp__alt-text:empty {
|
||||
|
|
|
@ -276,7 +276,6 @@ import { computed, inject, onMounted, ref } from "vue";
|
|||
import * as mfm from "mfm-js";
|
||||
import type { Ref } from "vue";
|
||||
import type * as firefish from "firefish-js";
|
||||
import { detect as detectLanguage_ } from "tinyld";
|
||||
import MkSubNoteContent from "./MkSubNoteContent.vue";
|
||||
import MkNoteSub from "@/components/MkNoteSub.vue";
|
||||
import XNoteHeader from "@/components/MkNoteHeader.vue";
|
||||
|
@ -287,6 +286,7 @@ import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
|
|||
import XQuoteButton from "@/components/MkQuoteButton.vue";
|
||||
import MkVisibility from "@/components/MkVisibility.vue";
|
||||
import copyToClipboard from "@/scripts/copy-to-clipboard";
|
||||
import detectLanguage from "@/scripts/detect-language";
|
||||
import { url } from "@/config";
|
||||
import { pleaseLogin } from "@/scripts/please-login";
|
||||
import { focusNext, focusPrev } from "@/scripts/focus";
|
||||
|
@ -372,15 +372,6 @@ const expandOnNoteClick = defaultStore.state.expandOnNoteClick;
|
|||
const lang = localStorage.getItem("lang");
|
||||
const translateLang = localStorage.getItem("translateLang");
|
||||
|
||||
function detectLanguage(text: string) {
|
||||
const nodes = mfm.parse(text);
|
||||
const filtered = mfm.extract(nodes, (node) => {
|
||||
return node.type === "text" || node.type === "quote";
|
||||
});
|
||||
const purified = mfm.toString(filtered);
|
||||
return detectLanguage_(purified);
|
||||
}
|
||||
|
||||
const isForeignLanguage: boolean =
|
||||
defaultStore.state.detectPostLanguage &&
|
||||
appearNote.value.text != null &&
|
||||
|
@ -948,7 +939,7 @@ defineExpose({
|
|||
padding: 8px;
|
||||
opacity: 0.7;
|
||||
&:disabled {
|
||||
opacity: 0.5 !important;
|
||||
opacity: 0.2 !important;
|
||||
}
|
||||
flex-grow: 1;
|
||||
max-width: 3.5em;
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {} from "vue";
|
||||
import { preprocess } from "@/scripts/preprocess";
|
||||
import preprocess from "@/scripts/preprocess";
|
||||
|
||||
const props = defineProps<{
|
||||
text: string;
|
||||
|
|
|
@ -193,7 +193,6 @@ import { computed, inject, ref } from "vue";
|
|||
import type { Ref } from "vue";
|
||||
import type * as firefish from "firefish-js";
|
||||
import * as mfm from "mfm-js";
|
||||
import { detect as detectLanguage_ } from "tinyld";
|
||||
import XNoteHeader from "@/components/MkNoteHeader.vue";
|
||||
import MkSubNoteContent from "@/components/MkSubNoteContent.vue";
|
||||
import XReactionsViewer from "@/components/MkReactionsViewer.vue";
|
||||
|
@ -202,6 +201,7 @@ import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue";
|
|||
import XRenoteButton from "@/components/MkRenoteButton.vue";
|
||||
import XQuoteButton from "@/components/MkQuoteButton.vue";
|
||||
import copyToClipboard from "@/scripts/copy-to-clipboard";
|
||||
import detectLanguage from "@/scripts/detect-language";
|
||||
import { url } from "@/config";
|
||||
import { pleaseLogin } from "@/scripts/please-login";
|
||||
import { getNoteMenu } from "@/scripts/get-note-menu";
|
||||
|
@ -288,15 +288,6 @@ const expandOnNoteClick = defaultStore.state.expandOnNoteClick;
|
|||
const lang = localStorage.getItem("lang");
|
||||
const translateLang = localStorage.getItem("translateLang");
|
||||
|
||||
function detectLanguage(text: string) {
|
||||
const nodes = mfm.parse(text);
|
||||
const filtered = mfm.extract(nodes, (node) => {
|
||||
return node.type === "text" || node.type === "quote";
|
||||
});
|
||||
const purified = mfm.toString(filtered);
|
||||
return detectLanguage_(purified);
|
||||
}
|
||||
|
||||
const isForeignLanguage: boolean =
|
||||
defaultStore.state.detectPostLanguage &&
|
||||
appearNote.value.text != null &&
|
||||
|
@ -552,7 +543,7 @@ function noteClick(e) {
|
|||
padding: 8px;
|
||||
opacity: 0.7;
|
||||
&:disabled {
|
||||
opacity: 0.5 !important;
|
||||
opacity: 0.2 !important;
|
||||
}
|
||||
flex-grow: 1;
|
||||
max-width: 3.5em;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Info"
|
||||
/>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Info"
|
||||
/>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<slot name="empty">
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Error"
|
||||
/>
|
||||
|
|
|
@ -276,7 +276,7 @@ import {
|
|||
import { uploadFile } from "@/scripts/upload";
|
||||
import { deepClone } from "@/scripts/clone";
|
||||
import XCheatSheet from "@/components/MkCheatSheetDialog.vue";
|
||||
import { preprocess } from "@/scripts/preprocess";
|
||||
import preprocess from "@/scripts/preprocess";
|
||||
import { vibrate } from "@/scripts/vibrate";
|
||||
|
||||
const modal = inject("modal");
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
v-if="canRenote"
|
||||
ref="buttonRef"
|
||||
v-tooltip.noDelay.bottom="i18n.ts.renote"
|
||||
class="button _button canRenote"
|
||||
class="button _button"
|
||||
:class="{ renoted: hasRenotedBefore }"
|
||||
@click.stop="renote(false, $event)"
|
||||
>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<button
|
||||
v-else
|
||||
v-tooltip.noDelay.bottom="i18n.ts.disabled"
|
||||
class="eddddedb _button"
|
||||
class="_button"
|
||||
disabled="true"
|
||||
>
|
||||
<i class="ph-rocket-launch ph-bold ph-lg"></i>
|
||||
|
@ -266,7 +266,7 @@ const renote = (viaKeyboard = false, ev?: MouseEvent) => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.button {
|
||||
&:not(.canRenote) {
|
||||
&:not(.button) {
|
||||
cursor: default;
|
||||
}
|
||||
&.renoted {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Info"
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
|
||||
<div class="mjndxjcg">
|
||||
<img
|
||||
src="/static-assets/badges/error.avif"
|
||||
src="/static-assets/badges/error.webp"
|
||||
class="_ghost"
|
||||
alt="Error"
|
||||
/>
|
||||
|
|
|
@ -277,6 +277,7 @@ export function alert(props: {
|
|||
type?: "error" | "info" | "success" | "warning" | "waiting" | "question";
|
||||
title?: string | null;
|
||||
text?: string | null;
|
||||
isPlaintext?: boolean;
|
||||
}): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (props.text == null && props.type === "error") {
|
||||
|
@ -301,6 +302,7 @@ export function confirm(props: {
|
|||
text?: string | null;
|
||||
okText?: string;
|
||||
cancelText?: string;
|
||||
isPlaintext?: boolean;
|
||||
}): Promise<{ canceled: boolean }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
popup(
|
||||
|
@ -323,6 +325,7 @@ export function yesno(props: {
|
|||
type: "error" | "info" | "success" | "warning" | "waiting" | "question";
|
||||
title?: string | null;
|
||||
text?: string | null;
|
||||
isPlaintext?: boolean;
|
||||
}): Promise<{ canceled: boolean }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
popup(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
|
||||
<div v-show="loaded" class="mjndxjch">
|
||||
<img
|
||||
src="/static-assets/badges/error.avif"
|
||||
src="/static-assets/badges/error.webp"
|
||||
class="_ghost"
|
||||
alt="Error"
|
||||
/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Info"
|
||||
/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
aria-label="none"
|
||||
class="_ghost"
|
||||
/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Info"
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
|
||||
<div :class="$style.root">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Error"
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="ipledcug">
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/not-found.avif"
|
||||
src="/static-assets/badges/not-found.webp"
|
||||
class="_ghost"
|
||||
alt="Not found"
|
||||
/>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
<img
|
||||
src="/static-assets/badges/info.avif"
|
||||
src="/static-assets/badges/info.webp"
|
||||
class="_ghost"
|
||||
alt="Info"
|
||||
/>
|
||||
|
|
11
packages/client/src/scripts/detect-language.ts
Normal file
11
packages/client/src/scripts/detect-language.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { detect } from "tinyld";
|
||||
import * as mfm from "mfm-js";
|
||||
|
||||
export default function detectLanguage(text: string): string {
|
||||
const nodes = mfm.parse(text);
|
||||
const filtered = mfm.extract(nodes, (node) => {
|
||||
return node.type === "text" || node.type === "quote";
|
||||
});
|
||||
const purified = mfm.toString(filtered);
|
||||
return detect(purified);
|
||||
}
|
|
@ -2,7 +2,7 @@ import * as mfm from "mfm-js";
|
|||
import { defaultStore } from "@/store";
|
||||
import { expandKaTeXMacro } from "@/scripts/katex-macro";
|
||||
|
||||
export function preprocess(text: string): string {
|
||||
export default function preprocess(text: string): string {
|
||||
if (defaultStore.state.enableCustomKaTeXMacro) {
|
||||
const parsedKaTeXMacro =
|
||||
localStorage.getItem("customKaTeXMacroParsed") ?? "{}";
|
||||
|
|
|
@ -25,6 +25,43 @@
|
|||
//--ad: rgb(255 169 0 / 10%);
|
||||
}
|
||||
|
||||
/* atkinson-hyperlegible-regular - latin_latin-ext */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Atkinson Hyperlegible";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url("/static-assets/fonts/atkinson-hyperlegible-v11-latin_latin-ext-regular.woff2")
|
||||
format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* atkinson-hyperlegible-italic - latin_latin-ext */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Atkinson Hyperlegible";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url("/static-assets/fonts/atkinson-hyperlegible-v11-latin_latin-ext-italic.woff2")
|
||||
format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* atkinson-hyperlegible-700 - latin_latin-ext */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Atkinson Hyperlegible";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url("/static-assets/fonts/atkinson-hyperlegible-v11-latin_latin-ext-700.woff2")
|
||||
format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
/* atkinson-hyperlegible-700italic - latin_latin-ext */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Atkinson Hyperlegible";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("/static-assets/fonts/atkinson-hyperlegible-v11-latin_latin-ext-700italic.woff2")
|
||||
format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: #fff;
|
||||
background-color: var(--accent);
|
||||
|
@ -39,7 +76,8 @@ html {
|
|||
accent-color: var(--accent);
|
||||
overflow: auto;
|
||||
overflow-wrap: break-word;
|
||||
font-family: Roboto, HelveticaNeue, Arial, sans-serif;
|
||||
font-family: "Atkinson Hyperlegible", Roboto, HelveticaNeue, Arial,
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
text-size-adjust: 100%;
|
||||
|
@ -50,8 +88,8 @@ html {
|
|||
-webkit-text-size-adjust: none;
|
||||
|
||||
&.useCJKFont {
|
||||
font-family: "Hiragino Maru Gothic Pro", "BIZ UDGothic", Roboto,
|
||||
HelveticaNeue, Arial, sans-serif;
|
||||
font-family: "Hiragino Maru Gothic Pro", "BIZ UDGothic",
|
||||
"Atkinson Hyperlegible", Roboto, HelveticaNeue, Arial, sans-serif;
|
||||
}
|
||||
|
||||
&.useSystemFont {
|
||||
|
|
|
@ -85,8 +85,8 @@ importers:
|
|||
specifier: ^1.0.4
|
||||
version: 1.0.4
|
||||
pnpm:
|
||||
specifier: 8.7.1
|
||||
version: 8.7.1
|
||||
specifier: 8.8.0
|
||||
version: 8.8.0
|
||||
start-server-and-test:
|
||||
specifier: 1.15.2
|
||||
version: 1.15.2
|
||||
|
@ -742,7 +742,7 @@ importers:
|
|||
version: 2.30.0
|
||||
emojilib:
|
||||
specifier: github:thatonecalculator/emojilib
|
||||
version: github.com/thatonecalculator/emojilib/d3c8c6a77d4362b3b3180099f1d2eac344ce245c
|
||||
version: github.com/thatonecalculator/emojilib/c3c82a3c8f360e1ec567c61012b95d23f0d22175
|
||||
escape-regexp:
|
||||
specifier: 0.0.1
|
||||
version: 0.0.1
|
||||
|
@ -15186,8 +15186,8 @@ packages:
|
|||
engines: {node: '>=14.19.0'}
|
||||
dev: false
|
||||
|
||||
/pnpm@8.7.1:
|
||||
resolution: {integrity: sha512-Qbt3EhYUaXFS2k4FLQA7r2/eYz/JoDeG680/3UXG0Ga03LPuY4GgdvCLe+zO3M7ZnWG4VI4bAwk7QpJyfr5eqA==}
|
||||
/pnpm@8.8.0:
|
||||
resolution: {integrity: sha512-eY5rMiZpzmPI2oVr1irR97bzb036oKwCWvK91wDQndXcqUPlytPtrF0bO668Syw/uA+7hTf5NnM8Mr4ux4BRRA==}
|
||||
engines: {node: '>=16.14'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
@ -19461,8 +19461,8 @@ packages:
|
|||
url-polyfill: 1.1.12
|
||||
dev: true
|
||||
|
||||
github.com/thatonecalculator/emojilib/d3c8c6a77d4362b3b3180099f1d2eac344ce245c:
|
||||
resolution: {tarball: https://codeload.github.com/thatonecalculator/emojilib/tar.gz/d3c8c6a77d4362b3b3180099f1d2eac344ce245c}
|
||||
github.com/thatonecalculator/emojilib/c3c82a3c8f360e1ec567c61012b95d23f0d22175:
|
||||
resolution: {tarball: https://codeload.github.com/thatonecalculator/emojilib/tar.gz/c3c82a3c8f360e1ec567c61012b95d23f0d22175}
|
||||
name: emojilib
|
||||
version: 3.0.10
|
||||
dev: true
|
||||
|
|
Loading…
Reference in a new issue