Compare commits

..

61 Commits

Author SHA1 Message Date
Hosted Weblate
97267c563c
chore: Merge branch 'origin/develop' into Weblate. 2023-12-29 06:13:15 +00:00
josé m
309c6905b9
chore: Translated using Weblate (Galician)
Currently translated at 18.2% (343 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/gl/
2023-12-29 07:13:12 +01:00
naskya
a5bf9da0da
chore: up pnpm to v8.13.1 2023-12-27 03:40:29 +09:00
mei23
4a659e131a
fix: prohibit Apps to use admin/moderator permission 2023-12-27 03:33:48 +09:00
Hosted Weblate
f7a36bf836
chore: Merge branch 'origin/develop' into Weblate. 2023-12-24 16:08:36 +00:00
Bhanu Stark
b1dd35d9e2
chore: Translated using Weblate (Hindi)
Currently translated at 0.1% (2 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/hi/
2023-12-24 16:08:31 +00:00
naskya
6ac3169996 Merge branch 'fix/page-firefox-drag' into 'develop'
fix: page block not draggable on Firefox

Co-authored-by: sup39 <dev@sup39.dev>

Closes #9925

See merge request firefish/firefish!10653
2023-12-24 06:22:34 +00:00
sup39
6609218f75
fix: page block not draggable on Firefox 2023-12-24 13:23:40 +09:00
サポミク
b77c9ecc19
chore: Translated using Weblate (Chinese (Traditional))
Currently translated at 99.8% (1873 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/zh_Hant/
2023-12-23 21:47:39 +01:00
@DDoSkiray@ddoskey.com
57627407ed
chore: Translated using Weblate (Japanese (Kansai))
Currently translated at 70.2% (1317 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ja_KS/
2023-12-19 14:09:44 +00:00
@DDoSkiray@ddoskey.com
d584742aad
chore: Translated using Weblate (Japanese (Kansai))
Currently translated at 69.9% (1313 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ja_KS/
2023-12-17 18:06:31 +01:00
@DDoSkiray@ddoskey.com
a3c7c4a2f2
chore: Translated using Weblate (Japanese)
Currently translated at 100.0% (1876 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ja/
2023-12-17 18:06:30 +01:00
サポミク
8c49dbe617
chore: Translated using Weblate (Chinese (Traditional))
Currently translated at 99.3% (1864 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/zh_Hant/
2023-12-16 15:09:39 +01:00
Ramdziana F Y
6064a427c0
chore: Translated using Weblate (Indonesian)
Currently translated at 100.0% (1876 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/id/
2023-12-16 15:09:39 +01:00
Pavel Biryukov
e48284ca40
chore: Translated using Weblate (Russian)
Currently translated at 98.4% (1846 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ru/
2023-12-14 21:08:27 +00:00
Salif Mehmed
858220489a
chore: Translated using Weblate (Bulgarian (bul_BG))
Currently translated at 23.2% (437 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/bul_BG/
2023-12-13 12:05:54 +01:00
Hosted Weblate
0e1bc17fbf
chore: Merge branch 'origin/develop' into Weblate. 2023-12-12 02:30:36 +00:00
Late Night Defender
d1b6874b54
chore: Translated using Weblate (Thai)
Currently translated at 57.8% (1086 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/th/
2023-12-12 03:30:29 +01:00
Pynolo
4846db6d8a
chore: Translated using Weblate (Italian)
Currently translated at 100.0% (1876 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/it/
2023-12-12 03:30:28 +01:00
jolupa
12975856e3
chore: Translated using Weblate (Catalan)
Currently translated at 100.0% (1876 of 1876 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ca/
2023-12-12 03:30:28 +01:00
ThatOneCalculator
db604b8f46
Merge branch 'develop' of git.joinfirefish.org:firefish/firefish into develop 2023-12-07 10:44:28 -08:00
ThatOneCalculator
9f3d0a2656
refactor: 🔥 remove unused constants 2023-12-07 10:44:23 -08:00
Hosted Weblate
d8d6b64f2c
chore: Merge branch 'origin/develop' into Weblate. 2023-12-07 10:06:22 +01:00
Pynolo
6de2fe245e
chore: Translated using Weblate (Italian)
Currently translated at 100.0% (1874 of 1874 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/it/
2023-12-07 10:06:20 +01:00
ThatOneCalculator
73cf3b64e5
refactor: 🔥 remove local twemoji in backend assets, replace with @discordapp/twemoji
They ended up publishing svg in dist
2023-12-06 11:11:42 -08:00
ThatOneCalculator
a6df31606c
fix: 💄 make fullPageHeader on MkDrive look like standard MkPageHeader 2023-12-05 19:41:45 -08:00
ThatOneCalculator
6d602fa80a
chore: 🎨 format 2023-12-05 19:32:39 -08:00
Kainoa Kanter
f0391d0769 Merge branch 'fix/drive' into 'develop'
fix: 🐛 Fix MkDrive nav header on drive.vue


See merge request firefish/firefish!10650
2023-12-06 03:31:56 +00:00
Kainoa Kanter
7db4e06093 fix: 🐛 Fix MkDrive nav header on drive.vue 2023-12-06 03:31:56 +00:00
Kainoa Kanter
afe0e8b4b3 Merge branch 'make-tsc-dev-deps' into 'develop'
Move typescript of megalodon from deps to dev-deps

Co-authored-by: Mizunashi Mana <contact@mizunashi.work>

See merge request firefish/firefish!10648
2023-12-05 19:19:38 +00:00
Mizunashi Mana
e3f4936f69 Move typescript of megalodon from deps to dev-deps 2023-12-05 19:19:37 +00:00
Kainoa Kanter
30a33a7445 Merge branch 'fix/nodeinfo' into 'develop'
fix: nodeinfo 2.0 compliance

Co-authored-by: naskya <m@naskya.net>

Closes #10798

See merge request firefish/firefish!10643
2023-12-05 18:46:39 +00:00
naskya
7ec84615a0 chore (locale, minor): update ja-JP.yml 2023-12-05 08:58:57 +00:00
ThatOneCalculator
452f29bcb3
Revert "chore: 🚨 lint"
This reverts commit f7ce60cd9f.
2023-12-04 23:12:33 -08:00
ThatOneCalculator
623cadf981
Revert "chore: lint import order"
This reverts commit 8d3c35c0c6.
2023-12-04 23:12:10 -08:00
ThatOneCalculator
a6f0143017
refactor: ♻️ isNan -> Number.isNan 2023-12-04 22:36:57 -08:00
ThatOneCalculator
34ce779309
chore: 🎨 format 2023-12-04 19:52:37 -08:00
ThatOneCalculator
e958834158
refactor: ♻️ Upgrade Twemoji to Emoji 15.0
Adds a new option to load Twemoji from the JSDelivr CDN (default) or from the server.  For Twemoji stored on the server,  they are grabbed directly from the @twemoji/api Github repo's assets, given they're no longer distributed in the @twemoji/api dist. No longer uses @discordapp/twemoji due to being unmaintained.
2023-12-04 19:50:44 -08:00
ThatOneCalculator
00f8924030
fix: 🐛 service worker notification badges 2023-12-04 19:07:26 -08:00
Kainoa Kanter
342166c01f Merge branch 'audio' into 'develop'
fix: sound effects stop music playback in iOS

Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>

Closes #10804

See merge request firefish/firefish!10641
2023-12-04 04:45:51 +00:00
naskya
1011b88850 fix: sound effects stop music playback in iOS
Co-authored-by: osamu <46447427+sam-osamu@users.noreply.github.com>
2023-12-04 04:45:51 +00:00
Kainoa Kanter
373ed7028e Merge branch 'fix/unicode-15' into 'develop'
fix: ⬆️ switch from twemoji-parser to @twemoji/parser


See merge request firefish/firefish!10645
2023-12-04 04:45:42 +00:00
Kainoa Kanter
1d870fa78d fix: ⬆️ switch from twemoji-parser to @twemoji/parser 2023-12-04 04:45:42 +00:00
Kainoa Kanter
adf7522654 Merge branch 'develop' into 'develop'
fix ignoring person._misskey_summary on updating remote profiles

Co-authored-by: blueb <ihateblueb@proton.me>

See merge request firefish/firefish!10646
2023-12-04 04:45:33 +00:00
blueb
e1dcba9aba fix ignoring person._misskey_summary on updating remote profiles 2023-12-04 04:45:33 +00:00
Kainoa Kanter
6017c1786f Merge branch 'Dockerfile' into 'develop'
update Docker environments

Co-authored-by: naskya <m@naskya.net>

See merge request firefish/firefish!10642
2023-12-04 04:45:24 +00:00
naskya
94eab33338 update Docker environments 2023-12-04 04:45:24 +00:00
Hosted Weblate
4ce603ec83
chore: Merge branch 'origin/develop' into Weblate. 2023-12-03 14:04:13 +00:00
Ramdziana F Y
2f3c798032
chore: Translated using Weblate (Indonesian)
Currently translated at 100.0% (1874 of 1874 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/id/
2023-12-03 15:04:07 +01:00
jolupa
1dd1d8cf8f
chore: Translated using Weblate (Catalan)
Currently translated at 100.0% (1874 of 1874 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ca/
2023-12-03 15:04:06 +01:00
mei23
831b3d4ee2
fix: filter featured collection
Co-authored-by: naskya <m@naskya.net>
2023-12-02 20:25:36 +09:00
naskya
e8b21b593a
chore: remove unneeded files 2023-12-02 06:23:37 +09:00
Hosted Weblate
bb5a6d02ce
chore: Merge branch 'origin/develop' into Weblate. 2023-12-01 14:05:51 +00:00
randint
f83cf1d337
chore: Translated using Weblate (Chinese (Traditional))
Currently translated at 99.5% (1864 of 1872 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/zh_Hant/
2023-12-01 14:05:27 +00:00
Late Night Defender
ce191a954e
chore: Translated using Weblate (Thai)
Currently translated at 57.8% (1083 of 1872 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/th/
2023-12-01 14:05:26 +00:00
hogueras
9cda63be61
chore: Translated using Weblate (Spanish)
Currently translated at 98.5% (1844 of 1872 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/es/
2023-12-01 14:05:24 +00:00
jolupa
7748313962
chore: Translated using Weblate (Catalan)
Currently translated at 99.9% (1871 of 1872 strings)

Translation: Firefish/locales
Translate-URL: https://hosted.weblate.org/projects/firefish/locales/ca/
2023-12-01 14:05:23 +00:00
naskya
3570406b05
fix: nodeinfo 2.0 compliance 2023-11-29 04:22:11 +09:00
naskya
7803aa80d0
chore: format 2023-11-29 04:05:57 +09:00
naskya
e473dfb10e
chore: up pnpm 2023-11-29 00:50:53 +09:00
naskya
b87a28622a
Revert "fix: ♻️ add data.localOnly back to dontFederateInitially check"
Closes #10817

This reverts commit 31ccedf177.
2023-11-29 00:48:10 +09:00
730 changed files with 3227 additions and 3091 deletions

View File

@ -1 +0,0 @@
v18.16.0

1
.npmrc
View File

@ -1 +0,0 @@
use-lockfile-v6=true

View File

@ -1,4 +0,0 @@
{
"$schema": "http://json.schemastore.org/vsls",
"gitignore": "exclude"
}

View File

@ -1,5 +1,5 @@
## Install dev and compilation dependencies, build files ## Install dev and compilation dependencies, build files
FROM node:20 as build FROM node:20-slim as build
WORKDIR /firefish WORKDIR /firefish
# Install compilation dependencies # Install compilation dependencies
@ -48,11 +48,11 @@ RUN env NODE_ENV=production sh -c "pnpm run --filter '!native-utils' build && pn
RUN pnpm i --prod --frozen-lockfile RUN pnpm i --prod --frozen-lockfile
## Runtime container ## Runtime container
FROM node:20 FROM node:20-slim
WORKDIR /firefish WORKDIR /firefish
# Install runtime dependencies # Install runtime dependencies
RUN apt-get update && apt-get install -y libvips-dev zip unzip tini ffmpeg RUN apt-get update && apt-get install -y --no-install-recommends libvips-dev zip unzip tini ffmpeg
COPY . ./ COPY . ./

View File

@ -4,18 +4,19 @@ services:
web: web:
# Choose one of these tags: # Choose one of these tags:
# stable-amd64, stable-arm64, beta-amd64, beta-arm64 # stable-amd64, stable-arm64, beta-amd64, beta-arm64
image: registry.joinfirefish.org/firefish/firefish:beta-amd64 image: registry.joinfirefish.org/firefish/firefish:stable-amd64
container_name: rudeshark_web container_name: firefish_web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- db - db
- redis - redis
- meilisearch ### Uncomment one of the following to use a search engine
# - meilisearch
# - sonic # - sonic
ports: ports:
- "127.0.0.1:8071:3000" - "3000:3000"
networks: networks:
- firenet - calcnet
# - web # - web
environment: environment:
NODE_ENV: production NODE_ENV: production
@ -25,41 +26,39 @@ services:
redis: redis:
restart: unless-stopped restart: unless-stopped
image: docker.io/redis:7-alpine image: docker.io/redis:7.0-alpine
container_name: rudeshark_redis container_name: firefish_redis
networks: networks:
- firenet - calcnet
volumes: volumes:
- ./redis:/data - ./redis:/data
db: db:
restart: unless-stopped restart: unless-stopped
image: docker.io/postgres:15-alpine image: docker.io/postgres:12.2-alpine
container_name: rudeshark_db container_name: firefish_db
networks: networks:
- firenet - calcnet
env_file: env_file:
- .config/docker.env - .config/docker.env
volumes: volumes:
- ./postgresql:/var/lib/postgresql/data - ./db:/var/lib/postgresql/data
### Only one of the below should be used. ### Only one of the below should be used.
### Meilisearch is better overall, but resource-intensive. Sonic is a very light full text search engine. ### Meilisearch is better overall, but resource-intensive. Sonic is a very light full text search engine.
meilisearch: # meilisearch:
container_name: rudeshark_meilisearch # container_name: meilisearch
image: getmeili/meilisearch:v1.1.1 # image: getmeili/meilisearch:v1.1.1
environment: # environment:
- MEILI_ENV=production # - MEILI_ENV=${MEILI_ENV:-development}
env_file:
- ./.config/meilisearch.env
# ports: # ports:
# - "127.0.0.1:7706:7700" # - "7700:7700"
networks: # networks:
- firenet # - calcnet
volumes: # volumes:
- ./meilisearch/data:/meili_data # - ./meili_data:/meili_data
restart: unless-stopped # restart: unless-stopped
# sonic: # sonic:
# restart: unless-stopped # restart: unless-stopped
@ -67,16 +66,13 @@ services:
# logging: # logging:
# driver: none # driver: none
# networks: # networks:
# - firenet # - calcnet
# volumes: # volumes:
# - ./sonic:/var/lib/sonic/store # - ./sonic:/var/lib/sonic/store
# - ./sonic/config.cfg:/etc/sonic.cfg # - ./sonic/config.cfg:/etc/sonic.cfg
networks: networks:
firenet: calcnet:
ipam:
config:
- subnet: 172.22.22.0/24
# web: # web:
# external: # external:
# name: web # name: web

View File

@ -475,3 +475,5 @@ _preferencesBackups:
editWidgetsExit: Готово editWidgetsExit: Готово
done: Готово done: Готово
emailRequiredForSignup: Изискване за адрес на е-поща за регистриране emailRequiredForSignup: Изискване за адрес на е-поща за регистриране
preview: Преглед
privacy: Поверителност

View File

@ -895,7 +895,7 @@ nUsersRead: llegit per {n}
agreeTo: Estic d'acord amb {0} agreeTo: Estic d'acord amb {0}
activity: Activitat activity: Activitat
home: Inici home: Inici
remoteUserCaution: La informació dels usuaris remots pot estar incompleta. remoteUserCaution: La informació dels usuaris remots és incompleta.
themeForDarkMode: Tema a fer servir en mode fosc themeForDarkMode: Tema a fer servir en mode fosc
light: Clar light: Clar
registeredDate: Data de registre registeredDate: Data de registre
@ -1051,7 +1051,7 @@ popularTags: Etiquetes populars
about: Sobre about: Sobre
recentlyUpdatedUsers: Usuaris actius fa poc recentlyUpdatedUsers: Usuaris actius fa poc
recentlyRegisteredUsers: Usuaris registrats fa poc recentlyRegisteredUsers: Usuaris registrats fa poc
recentlyDiscoveredUsers: Nous suaris descoberts recentlyDiscoveredUsers: Nous usuaris descoberts
administrator: Administrador administrator: Administrador
token: Token token: Token
registerSecurityKey: Registreu una clau de seguretat registerSecurityKey: Registreu una clau de seguretat
@ -2212,3 +2212,9 @@ attachedToNotes: Publicacions que contenen aquest fitxer
replies: Respostes replies: Respostes
quotes: Cites quotes: Cites
renotes: Impulsos renotes: Impulsos
moreUrls: Pàgines fixades
moreUrlsDescription: "Introdueix les pàgines que vols fixar al menú d'ajuda a la part
inferior esquerra fent servir aquesta notació:\n\"Nom a mostrar\": https://example.com/"
useEmojiCdn: Aconsegueix Twemoji des d'un CDN
useEmojiCdnDescription: Fes servir Twemoji des del CDN de JSDeliver en lloc de fer
servir el del propi servidor.

View File

@ -1156,6 +1156,8 @@ detectPostLanguage: "Automatically detect the language and show a translate butt
vibrate: "Play vibrations" vibrate: "Play vibrations"
openServerInfo: "Show server information by clicking the server ticker on a post" openServerInfo: "Show server information by clicking the server ticker on a post"
iconSet: "Icon set" iconSet: "Icon set"
useEmojiCdn: "Get Twemoji from CDN"
useEmojiCdnDescription: "Use Twemoji from the JSDelivr CDN instead of the server's assets."
_sensitiveMediaDetection: _sensitiveMediaDetection:
description: "Reduces the effort of server moderation through automatically recognizing description: "Reduces the effort of server moderation through automatically recognizing

View File

@ -1219,6 +1219,13 @@ _wordMute:
soft: "Suave" soft: "Suave"
hard: "Duro" hard: "Duro"
mutedNotes: "Publicaciones silenciadas" mutedNotes: "Publicaciones silenciadas"
muteLangsDescription2: 'Utilizar códigos de idioma, por ejemplo: en, fr, ja, zh.'
lang: Idioma
langDescription: Ocultar publicaciones de linea de tiempo que coincidan con el idioma
seleccionado.
muteLangs: Idiomas silenciados
muteLangsDescription: Separar con espacios o saltos de lineas para una condición
OR
_instanceMute: _instanceMute:
instanceMuteDescription: "Silencia todas las publicaciones e impusos de los servidores instanceMuteDescription: "Silencia todas las publicaciones e impusos de los servidores
seleccionados, incluyendo respuestas a los usuarios de las mismas." seleccionados, incluyendo respuestas a los usuarios de las mismas."
@ -2162,3 +2169,15 @@ silencedWarning: Esta página se muestra debido a que estos usuarios son de serv
que tu administrador ha silenciado, ya que son presumiblemente fuente de spam. que tu administrador ha silenciado, ya que son presumiblemente fuente de spam.
isBot: Esta cuenta es un bot isBot: Esta cuenta es un bot
clickToShowPatterns: Haz clic para mostrar patrones de módulos clickToShowPatterns: Haz clic para mostrar patrones de módulos
detectPostLanguage: Detectar automáticamente el idioma y mostrar el botón de traducción
para publicaciones en otros idiomas
indexableDescription: Permitir que el buscador integrado muestre tus publicaciones
reactions: Reacciones
exportZip: Exportar ZIP
emojiPackCreator: Creador de pack de Emoji
importZip: Importar ZIP
vibrate: Reproducir vibraciones
openServerInfo: Mostrar información del servidor al presionar el simbolo del servidor
en una publicación
languageForTranslation: Traducción de publicaciones
confirm: Confirmar

View File

@ -355,3 +355,24 @@ driveFileDeleteConfirm: Tes a certeza de querer eliminar o ficheiro "{name}"? Va
ser retirado de todas as publicacións nas que estea como anexo. ser retirado de todas as publicacións nas que estea como anexo.
inputNewFolderName: Escribe o novo nome do cartafol inputNewFolderName: Escribe o novo nome do cartafol
hasChildFilesOrFolders: Como o cartafol non está baleiro, non pode ser eliminado. hasChildFilesOrFolders: Como o cartafol non está baleiro, non pode ser eliminado.
dayX: '{day}'
reloadConfirm: Queres actualizar a cronoloxía?
watch: Ver
normal: Normal
monthX: '{month}'
instanceDescription: Descrición do servidor
disconnectedFromServer: Perdeuse a conexión co servidor
enableLocalTimeline: Activar cronoloxía local
reload: Actualizar
doNothing: Ignorar
instanceName: Nome do servidor
yearX: '{year}'
thisYear: Ano
unwatch: Deixar de ver
tosUrl: URL dos Termos do Servizo
thisMonth: Mes
pages: Páxinas
reject: Rexeitar
accept: Aceptar
maintainerName: Mantido por
today: Hoxe

View File

@ -1 +1,3 @@
_lang_: "हिन्दी" _lang_: "हिन्दी"
headlineFirefish: एक ओपन सोर्स , डिसेंट्रलाइज़्ड सोशल मीडिया प्लेटफ़ॉर्म जो हमेशा के
लिए मुफ़्त है! 🚀

View File

@ -2193,3 +2193,8 @@ quotes: Kutipan
renotes: Postingan ulang renotes: Postingan ulang
showAttachedNotes: Tampilkan postingan dengan berkas ini showAttachedNotes: Tampilkan postingan dengan berkas ini
attachedToNotes: Posting dengan berkas ini attachedToNotes: Posting dengan berkas ini
moreUrls: Halaman tersemat
moreUrlsDescription: "Masukkan halaman yang ingin kamu sematkan ke menu bantuan di
pojok kiri bawah dengan notasi ini:\n\"Nama tampilan\": https://contoh.com/"
useEmojiCdn: Dapatkan Twemoji dari CDN
useEmojiCdnDescription: Gunakan Twemoji dari JSDelv CDN bukan dari aset server.

View File

@ -2182,3 +2182,8 @@ quotes: Citazioni
renotes: Boost renotes: Boost
showAttachedNotes: Mostra i post con questo allegato showAttachedNotes: Mostra i post con questo allegato
attachedToNotes: Post con questo allegato attachedToNotes: Post con questo allegato
moreUrls: Pagine del menu di aiuto
moreUrlsDescription: "Inserisci con questo formato le pagine che vuoi aggiungere al
menu di aiuto nell'angolo in basso a sinistra:\n\"Nome link\": https://example.com/"
useEmojiCdn: Scarica Twemoji da CDN
useEmojiCdnDescription: Usa Twemoji dalla CDN di JSDelivr invece che dal server locale.

View File

@ -981,7 +981,7 @@ customKaTeXMacroDescription: "数式入力を楽にするためのマクロを
が 3 + foo に展開されます。また、マクロの名前を囲む波括弧を丸括弧 () および角括弧 [] に変更した場合、マクロの引数に使用する括弧が変更されます。マクロの定義は一行に一つのみで、途中で改行はできません。マクロの定義が無効な行は無視されます。文字列を単純に置換する機能のみに対応していて、条件分岐などの高度な構文は使用できません。" が 3 + foo に展開されます。また、マクロの名前を囲む波括弧を丸括弧 () および角括弧 [] に変更した場合、マクロの引数に使用する括弧が変更されます。マクロの定義は一行に一つのみで、途中で改行はできません。マクロの定義が無効な行は無視されます。文字列を単純に置換する機能のみに対応していて、条件分岐などの高度な構文は使用できません。"
enableCustomKaTeXMacro: "カスタムKaTeXマクロを有効にする" enableCustomKaTeXMacro: "カスタムKaTeXマクロを有効にする"
preventAiLearning: "AIによる学習を防止" preventAiLearning: "AIによる学習を防止"
preventAiLearningDescription: "投稿したノート、添付した画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。" preventAiLearningDescription: "投稿した文章や、添付した画像などのコンテンツを学習の対象にしないようAIに要求します。これはnoaiフラグをHTMLレスポンスに含めることによって実現されます。"
noGraze: "ブラウザの拡張機能「Graze for Mastodon」は、Firefishの動作を妨げるため、無効にしてください。" noGraze: "ブラウザの拡張機能「Graze for Mastodon」は、Firefishの動作を妨げるため、無効にしてください。"
enableServerMachineStats: "サーバーのマシン情報を公開する" enableServerMachineStats: "サーバーのマシン情報を公開する"
enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする"
@ -994,6 +994,8 @@ addRe: "閲覧注意の投稿への返信で、注釈の先頭に\"re:\"を追
languageForTranslation: "投稿翻訳に使用する言語" languageForTranslation: "投稿翻訳に使用する言語"
detectPostLanguage: "投稿の言語を自動検出し、外国語の投稿に翻訳ボタンを表示する" detectPostLanguage: "投稿の言語を自動検出し、外国語の投稿に翻訳ボタンを表示する"
iconSet: "アイコンのスタイル" iconSet: "アイコンのスタイル"
useEmojiCdn: "CDNのTwemojiを利用する"
useEmojiCdnDescription: "サーバー上に保存されているTwemojiのアセットの代わりに、JSDelivr CDNから配信されたものを用います。"
_sensitiveMediaDetection: _sensitiveMediaDetection:
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てられます。サーバーの負荷が少し増えます。" description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てられます。サーバーの負荷が少し増えます。"
@ -1031,7 +1033,7 @@ _ad:
_forgotPassword: _forgotPassword:
enterEmail: "アカウントに登録したメールアドレスを入力してください。そのアドレス宛てに、パスワードリセット用のリンクが送信されます。" enterEmail: "アカウントに登録したメールアドレスを入力してください。そのアドレス宛てに、パスワードリセット用のリンクが送信されます。"
ifNoEmail: "メールアドレスを登録していない場合は、管理者までお問い合わせください。" ifNoEmail: "メールアドレスを登録していない場合は、管理者までお問い合わせください。"
contactAdmin: "このインスタンスではメールアドレスの登録がサポートされていないため、パスワードリセットを行う場合は管理者までお問い合わせください。" contactAdmin: "このサーバーではメールアドレスの登録がサポートされていないため、パスワードリセットを行う場合は管理者までお問い合わせください。"
_gallery: _gallery:
my: "自分の投稿" my: "自分の投稿"
liked: "いいねした投稿" liked: "いいねした投稿"

View File

@ -714,7 +714,7 @@ registry: "レジストリ"
closeAccount: "このアカウントにさいならする" closeAccount: "このアカウントにさいならする"
currentVersion: "現在のバージョン" currentVersion: "現在のバージョン"
latestVersion: "最新のバージョン" latestVersion: "最新のバージョン"
youAreRunningUpToDateClient: "今使てるクライアントが最新やで!" youAreRunningUpToDateClient: "今使てるクライアントが最新やで!"
newVersionOfClientAvailable: "新しいバージョンのクライアントが使えるで。" newVersionOfClientAvailable: "新しいバージョンのクライアントが使えるで。"
usageAmount: "使用量" usageAmount: "使用量"
capacity: "容量" capacity: "容量"
@ -778,7 +778,7 @@ emailNotConfiguredWarning: "メアドの設定がされてへんで。"
ratio: "比率" ratio: "比率"
previewNoteText: "本文を下見するで" previewNoteText: "本文を下見するで"
customCss: "カスタムCSS" customCss: "カスタムCSS"
customCssWarn: "この設定は必ず知識のある人がやらなあかんで。あんま良くない設定をしたるとクライアントがちゃんと使えへんくなってくで。" customCssWarn: "この設定は必ず知識のある人がやらなあかん。下手にいじるとわやなって使えんくなってまうで。"
global: "グローバル" global: "グローバル"
squareAvatars: "アイコンを四角形で表示するで" squareAvatars: "アイコンを四角形で表示するで"
sent: "送信" sent: "送信"
@ -793,7 +793,7 @@ whatIsNew: "更新情報を見るで"
translate: "翻訳" translate: "翻訳"
translatedFrom: "{x}から翻訳するで" translatedFrom: "{x}から翻訳するで"
accountDeletionInProgress: "アカウント削除しとるで待っとってなー" accountDeletionInProgress: "アカウント削除しとるで待っとってなー"
usernameInfo: "サーバー上であんたのアカウントをあんたや分かるようにするための名前や。アルファベット(a~z, A~Z)、数字(0~9)、それとアンダーバー(_)が使って考えてな。この名前は後から変更することはできへんからちゃんと考えるんやで。" usernameInfo: "サーバー上であんたのアカウントをあんたや分かるようにするための名前や。アルファベット(a~z, A~Z)、数字(0~9)、それとアンダーバー(_)が使えるで。この名前は後から変更することはでけへんから、ちゃんと考えや。"
aiChanMode: "藍モードやで" aiChanMode: "藍モードやで"
keepCw: "CWを維持するで" keepCw: "CWを維持するで"
pubSub: "Pub/Subのアカウント" pubSub: "Pub/Subのアカウント"
@ -812,7 +812,7 @@ typeToConfirm: "この操作をやるんなら {x} と入力してなー"
deleteAccount: "アカウント削除するで" deleteAccount: "アカウント削除するで"
document: "ドキュメント" document: "ドキュメント"
numberOfPageCache: "ページキャッシュ数やで" numberOfPageCache: "ページキャッシュ数やで"
numberOfPageCacheDescription: "増やすと使いやすくなる、負荷とメモリ使用量が増えてくで。一長一短やな。" numberOfPageCacheDescription: "増やすと使いやすくなるけど、サーバーの負荷とメモリ使用量が増えてまう。一長一短やな。"
logoutConfirm: "ログアウトしまっか?" logoutConfirm: "ログアウトしまっか?"
lastActiveDate: "最後に使った日時" lastActiveDate: "最後に使った日時"
statusbar: "ステータスバー" statusbar: "ステータスバー"
@ -1444,12 +1444,17 @@ _tutorial:
step4_1: 投稿しとーみ step4_1: 投稿しとーみ
step5_1: タイムライン! 文字と写真の宝石箱や~ step5_1: タイムライン! 文字と写真の宝石箱や~
step5_2: うちのサーバーでは{timelines}種類のタイムラインをご用意しとります。 step5_2: うちのサーバーでは{timelines}種類のタイムラインをご用意しとります。
step4_2: 最初は{introduction}に投稿したり、シンプルに「ここは賑やかどすなぁ。ウチはそんなに喋れまへんが、どうぞよろしゅうに」などと投稿しはる方もいてます。 step4_2: 最初は{introduction}に投稿したり、シンプルに「ここは賑やかどすなぁ」などと投稿しはる方もいてます。
step5_7: グローバル{icon}タイムラインでは、接続しとるそこいらのサーバーからアレがガーッ流れてきてえらいこっちゃで。 step5_7: グローバル{icon}タイムラインでは、接続しとるそこいらのサーバーからアレがガーッ流れてきてえらいこっちゃで。
step5_6: おすすめ{icon}タイムラインでは、うちの管理人がばりおすすめしとるサーバーの投稿を表示させとうよ。 step5_6: おすすめ{icon}タイムラインでは、うちの管理人がばりおすすめしとるサーバーの投稿を表示させとうよ。
step5_5: ソーシャル{icon}タイムラインでは、ホームタイムラインとローカルタイムラインの投稿が両方見られてホンマお得やわぁ。 step5_5: ソーシャル{icon}タイムラインでは、ホームタイムラインとローカルタイムラインの投稿が両方見られてホンマお得やわぁ。
step5_3: ホーム{icon}タイムラインでは、あんたはんがフォローしてはる兄ちゃんらの投稿が見られまんねん。 step5_3: ホーム{icon}タイムラインでは、あんたはんがフォローしてはる兄ちゃんらの投稿が見られまんねん。
step5_4: ローカル{icon}タイムラインでは、このサーバーにおる人らの投稿を見られますわ。 step5_4: ローカル{icon}タイムラインでは、このサーバーにおる人らの投稿を見られますわ。
step6_1: ほんなら、ここはどないな場所なん?
step6_2: 実は、あんたはんはFirefishに参加しただけやあらしまへん。ここは、何千もの相互接続されたサーバーが構成しとる Fediverse への入口どす。
step6_3:
それぞれのサーバーでは必ずしもFirefishが使われとるわけやなく、異なる動作をしはるサーバーもあります。せやけど、あんたはんは他のサーバーのアカウントもフォローしたり、返信・ブーストしたりできます。一見難儀そやけど、だんないあんじょうやれますえ。
step6_4: これで完了どす。楽しんどくれやす!
_postForm: _postForm:
_placeholders: _placeholders:
b: なんかおましたか? b: なんかおましたか?
@ -1459,6 +1464,7 @@ _postForm:
f: あんさん書くんを待っとるんどす... f: あんさん書くんを待っとるんどす...
a: いまなにしとん? a: いまなにしとん?
flagSpeakAsCat: 猫弁で喋る flagSpeakAsCat: 猫弁で喋る
flagSpeakAsCatDescription: オンにすると、ワレの投稿の「な」を「にゃ」に変換したるで。 flagSpeakAsCatDescription: オンにすると、ワレの投稿の「な」「na」を「にゃ」「nya」に変換したるで。
welcomeBackWithName: おおきに、{name}はん welcomeBackWithName: おおきに、{name}はん
migration: アカウントの引っ越し migration: アカウントの引っ越し
makeReactionsPublicDescription: あんたが付けたリアクションの一覧をみんなにも見せたるで。

View File

@ -111,7 +111,7 @@ you: "Вы"
clickToShow: "Нажмите для просмотра" clickToShow: "Нажмите для просмотра"
sensitive: "Содержимое не для всех" sensitive: "Содержимое не для всех"
add: "Добавить" add: "Добавить"
reaction: "Реакции" reaction: "Реакция"
reactionSetting: "Реакции, отображаемые в палитре" reactionSetting: "Реакции, отображаемые в палитре"
reactionSettingDescription2: "Расставляйте перетаскиванием, удаляйте нажатием, добавляйте reactionSettingDescription2: "Расставляйте перетаскиванием, удаляйте нажатием, добавляйте
кнопкой «+»." кнопкой «+»."
@ -491,7 +491,7 @@ noFollowRequests: "Нерассмотренные запросы на подпи
openImageInNewTab: "Открыть изображение в новой вкладке" openImageInNewTab: "Открыть изображение в новой вкладке"
dashboard: "Панель управления" dashboard: "Панель управления"
local: "С этого сайта" local: "С этого сайта"
remote: "С других сайтов" remote: "Исходный сайт"
total: "Всего" total: "Всего"
weekOverWeekChanges: "За неделю" weekOverWeekChanges: "За неделю"
dayOverDayChanges: "За день" dayOverDayChanges: "За день"

View File

@ -1,25 +1,26 @@
_lang_: "ภาษาไทย" _lang_: "ภาษาไทย"
headlineFirefish: "เชื่อมต่อเครือข่ายโดยโน้ต" headlineFirefish: "แพลตฟอร์มโซเชียลมีเดียแบบโอเพนซอร์สที่มีการกระจายอำนาจซึ่งให้บริการฟรีตลอดไป!
introFirefish: "ยินดีต้อนรับค่ะ/ครับ! Firefish เป็นแพลตฟอร์มโซเชียลมีเดียแบบโอเพ่นซอร์สที่มีการกระจายอำนาจซึ่งให้บริการฟรีตลอดไป! 🚀"
introFirefish: "ยินดีต้อนรับค่ะ/ครับ! Firefish เป็นแพลตฟอร์มโซเชียลมีเดียแบบโอเพนซอร์สที่มีการกระจายอำนาจซึ่งให้บริการฟรีตลอดไป!
🚀" 🚀"
monthAndDay: "{เดือน}/{วัน}" monthAndDay: "{เดือน}/{วัน}"
search: "ค้นหา" search: "ค้นหา"
notifications: "การเเจ้งเตือน" notifications: "การเเจ้งเตือน"
username: "ชื่อผู้ใช้" username: "ชื่อผู้ใช้"
password: "รหัสผ่าน" password: "รหัสผ่าน"
forgotPassword: "ลืมรหัสผ่านอ่ะ" forgotPassword: "ลืมรหัสผ่าน"
fetchingAsApObject: "กำลังดึงข้อมูล จาก เฟดิเวิร์ส" fetchingAsApObject: "กำลังดึงข้อมูลจากเฟดิเวิร์ส"
ok: "ตกลง" ok: "ตกลง"
gotIt: "เข้าใจแล้ว !" gotIt: "เข้าใจแล้ว !"
cancel: "ยกเลิก" cancel: "ยกเลิก"
enterUsername: "ใส่ชื่อผู้ใช้" enterUsername: "ใส่ชื่อผู้ใช้"
renotedBy: "บูตเตอร์โดย {user}" renotedBy: "บูสต์โดย {user}"
noNotes: "ไม่มีโพสต์" noNotes: "ไม่มีโพสต์"
noNotifications: "ไม่มีการแจ้งเตือน" noNotifications: "ไม่มีการแจ้งเตือน"
instance: "เซิฟเวอร์" instance: "เซิร์ฟเวอร์"
settings: "การตั้งค่า" settings: "การตั้งค่า"
basicSettings: "การตั้งค่าพื้นฐาน" basicSettings: "การตั้งค่าพื้นฐาน"
otherSettings: "การตั้งค่าอื่นๆ" otherSettings: "การตั้งค่าอื่น ๆ"
openInWindow: "เปิดในหน้าต่าง" openInWindow: "เปิดในหน้าต่าง"
profile: "โปรไฟล์" profile: "โปรไฟล์"
timeline: "ไทม์ไลน์" timeline: "ไทม์ไลน์"
@ -28,14 +29,14 @@ login: "เข้าสู่ระบบ"
loggingIn: "กำลังเข้าสู่ระบบ" loggingIn: "กำลังเข้าสู่ระบบ"
logout: "ออกจากระบบ" logout: "ออกจากระบบ"
signup: "สร้างบัญชีผู้ใช้" signup: "สร้างบัญชีผู้ใช้"
uploading: "กำลังอัโหลด..." uploading: "กำลังอัโหลด..."
save: "บันทึก" save: "บันทึก"
users: "ผู้ใช้งาน" users: "ผู้ใช้งาน"
addUser: "เพิ่มผู้ใช้" addUser: "เพิ่มผู้ใช้"
favorite: "รายการโปรด" favorite: "เพิ่มลงในรายการโปรด"
favorites: "รายการโปรด" favorites: "รายการโปรด"
unfavorite: "ลบออกจากรายการโปรด" unfavorite: "ลบออกจากรายการโปรด"
favorited: "เพิ่มแล้วในรายการโปรด" favorited: "เพิ่มในรายการโปรดแล้ว"
alreadyFavorited: "เพิ่มในรายการโปรดอยู่แล้ว" alreadyFavorited: "เพิ่มในรายการโปรดอยู่แล้ว"
cantFavorite: "ไม่สามารถเพิ่มในรายการโปรดได้" cantFavorite: "ไม่สามารถเพิ่มในรายการโปรดได้"
pin: "ปักหมุดไปยังโปรไฟล์" pin: "ปักหมุดไปยังโปรไฟล์"
@ -55,22 +56,22 @@ loadMore: "โหลดเพิ่มเติม"
showMore: "แสดงเพิ่มเติม" showMore: "แสดงเพิ่มเติม"
showLess: "ปิด" showLess: "ปิด"
youGotNewFollower: "ได้ติดตามคุณ" youGotNewFollower: "ได้ติดตามคุณ"
receiveFollowRequest: "คำขอผู้ติดตามที่ได้รับ" receiveFollowRequest: "ได้รับคำขอติดตาม"
followRequestAccepted: "ผู้ติดตามได้ตอบรับคำขอร้องของคุณแล้ว" followRequestAccepted: "ผู้ติดตามได้ตอบรับคำขอของคุณแล้ว"
mention: "กล่าวถึง" mention: "กล่าวถึง"
mentions: "พูดถึง" mentions: "กล่าวถึง"
directNotes: "ไดเร็คข้อความ" directNotes: "ไดเร็คข้อความ"
importAndExport: "นำเข้า / ส่งออก" importAndExport: "นำเข้า / ส่งออกข้อมูล"
import: "การนำเข้า" import: "นำเข้า"
export: "การนำออก" export: "ส่งออก"
files: "ไฟล์" files: "ไฟล์"
download: "ดาวน์โหลด" download: "ดาวน์โหลด"
driveFileDeleteConfirm: "คุณแน่ใจแล้วหรอว่าต้องการลบไฟล์ \"{name}\"? โพสต์ย่อที่แนบมากับไฟล์นี้ก็จะถูกลบด้วยนะ" driveFileDeleteConfirm: "คุณแน่ใจแล้วหรอว่าต้องการลบไฟล์ \"{name}\"? โพสต์ย่อที่แนบมากับไฟล์นี้ก็จะถูกลบด้วยนะ"
unfollowConfirm: "คุณแน่ใจแล้วหรอว่าต้องการเลิกติดตาม {name}?" unfollowConfirm: "คุณแน่ใจแล้วหรอว่าต้องการเลิกติดตาม {name}?"
exportRequested: "เมื่อคุณได้ร้องขอการส่งออก อาจจะต้องใช้เวลาสักครู่ และจะถูกเพิ่มในไดรฟ์ของคุณเมื่อเสร็จสิ้นแล้ว" exportRequested: "เมื่อคุณได้ร้องขอการส่งออก อาจจะต้องใช้เวลาสักครู่ และจะถูกเพิ่มในไดรฟ์ของคุณเมื่อเสร็จสิ้นแล้ว"
importRequested: "เมื่อคุณได้ร้องขอการนำเข้า อาจจะต้องใช้เวลาสักครู่นะ" importRequested: "คุณได้ร้องขอการนำเข้า อาจจะต้องใช้เวลาสักครู่นะ"
lists: "รายการ" lists: "ลิสต์"
noLists: "คุณไม่มีลิสต์ใดนะ" noLists: "คุณไม่มีลิสต์ใด ๆ"
note: "โพสต์" note: "โพสต์"
notes: "โพสต์" notes: "โพสต์"
following: "กำลังติดตาม" following: "กำลังติดตาม"
@ -79,76 +80,76 @@ followsYou: "ติดตามคุณ"
createList: "สร้างลิสต์" createList: "สร้างลิสต์"
manageLists: "จัดการลิสต์" manageLists: "จัดการลิสต์"
error: "ผิดพลาด" error: "ผิดพลาด"
somethingHappened: "อุ๊ย ! มีอะไรบางอย่างผิดพลาด" somethingHappened: "เกิดข้อผิดพลาด"
retry: "ลองใหม่อีกครั้ง" retry: "ลองใหม่อีกครั้ง"
pageLoadError: "เกิดข้อผิดพลาดในการโหลดหน้านี้" pageLoadError: "เกิดข้อผิดพลาดในการโหลดหน้านี้"
pageLoadErrorDescription: "โดยปกติแล้วมักจะเกิดจากข้อผิดพลาดของเครือข่ายหรือแคชของเบราว์เซอร์ pageLoadErrorDescription: "โดยปกติแล้วมักจะเกิดจากข้อผิดพลาดของเครือข่ายหรือแคชของเบราว์เซอร์
ลองล้างแคชแล้วลองใหม่อีกครั้งหลังจากรอสักครู่นะ" ลองล้างแคชแล้วลองใหม่อีกครั้งหลังจากรอสักครู่นะ"
serverIsDead: "เซิร์ฟเวอร์นี้ไม่มีการตอบสนอง ได้โปรดกรุณารอสักครู่แล้วลองใหม่อีกครั้งนะ" serverIsDead: "เซิร์ฟเวอร์นี้ไม่มีการตอบสนอง กรุณารอสักครู่แล้วลองใหม่อีกครั้งนะ"
youShouldUpgradeClient: "หากต้องการดูหน้านี้ได้โปรดกรุณา รีเซ็ตเพื่ออัปเดตไคลเอ็นต์ของคุณนะ" youShouldUpgradeClient: "หากต้องการดูหน้านี้ กรุณารีเฟรชเพื่ออัปเดตไคลเอ็นต์ของคุณ"
enterListName: "ใส่ชื่อสำหรับรายการลิสต์" enterListName: "ใส่ชื่อสำหรับลิสต์"
privacy: "ความเป็นส่วนตัว" privacy: "ความเป็นส่วนตัว"
makeFollowManuallyApprove: "ติดตามคำขอที่ต้องได้รับการอนุมัติ" makeFollowManuallyApprove: "คำขอติดตามต้องได้รับการอนุมัติ"
defaultNoteVisibility: "การมองเห็นที่เป็นค่าเริ่มต้น" defaultNoteVisibility: "การมองเห็นที่เป็นค่าเริ่มต้น"
follow: "กำลังติดตาม" follow: "ติดตาม"
followRequest: "คำขอติดตาม" followRequest: "คำขอติดตาม"
followRequests: "ติดตามการร้องขอ" followRequests: "การติดตามที่ร้องขอ"
unfollow: "เลิกติดตาม" unfollow: "เลิกติดตาม"
followRequestPending: "กำลังรอดำเนินการร้องขอติดตาม" followRequestPending: "กำลังรอดำเนินการร้องขอติดตาม"
enterEmoji: "ใส่อีโมจิ" enterEmoji: "ใส่อีโมจิ"
renote: "บูสต์" renote: "บูสต์"
unrenote: "เลิกบูสต์" unrenote: "เลิกบูสต์"
renoted: "บูสต์แล้ว" renoted: "บูสต์แล้ว"
cantRenote: "โพสต์นี้ไม่สามารถบูสต์ใหม่ได้" cantRenote: "โพสต์นี้ไม่สามารถบูสต์ได้"
cantReRenote: "ไม่สามารถบูสต์ไว้ใหม่ได้" cantReRenote: "ไม่สามารถบูสต์การบูสต์ได้"
quote: "อ้างคำพูด" quote: "โควต"
pinnedNote: "โพสต์ที่ปักหมุดแล้ว" pinnedNote: "โพสต์ที่ปักหมุดแล้ว"
pinned: "ปักหมุดไปยังโปรไฟล์" pinned: "ปักหมุดไปยังโปรไฟล์"
you: "ตัวเอง" you: "คุณ"
clickToShow: "คลิกเพื่อแสดง" clickToShow: "คลิกเพื่อแสดง"
sensitive: "เนื้อหาที่ละเอียดอ่อน NSFW" sensitive: "เนื้อหาที่ละเอียดอ่อน"
add: "เพิ่ม" add: "เพิ่ม"
reaction: "รีแอคชัน" reaction: "รีแอคชัน"
reactionSetting: "รีแอคชั่นไปยังแสดงผลในตัวเลือกการรีแอคชัน" reactionSetting: "รีแอคชันที่จะแสดงผลในตัวเลือกการรีแอคชัน"
reactionSettingDescription2: "กดลากเพื่อจัดลำดับใหม่ กดคลิกเพื่อลบ กด \"+\" เพื่อเพิ่ม" reactionSettingDescription2: "ลากเพื่อจัดลำดับใหม่ คลิกเพื่อลบ กด \"+\" เพื่อเพิ่ม"
rememberNoteVisibility: "จดจำการตั้งค่าการมองเห็นโพสต์" rememberNoteVisibility: "จดจำการตั้งค่าการมองเห็นโพสต์"
attachCancel: "ลบไฟล์ออกที่แนบมา" attachCancel: "ลบไฟล์ที่แนบมา"
markAsSensitive: "ทำเครื่องหมายว่าละเอียดอ่อน" markAsSensitive: "ทำเครื่องหมายว่าละเอียดอ่อน"
unmarkAsSensitive: "ยกเลิกทำเครื่องหมายเป็น NSFW" unmarkAsSensitive: "ยกเลิกทำเครื่องหมายว่าละเอียดอ่อน"
enterFileName: "พิมพ์ชื่อไฟล์" enterFileName: "พิมพ์ชื่อไฟล์"
mute: "ปิดเสียง" mute: "ปิดเสียง"
unmute: "ไม่ปิดเสียง" unmute: "ยกเลิกการปิดเสียง"
block: "บล็อค" block: "บล็อค"
unblock: "เลิกปิดกั้น" unblock: "เลิกบล็อค"
suspend: "ถูกระงับ" suspend: "ถูกระงับ"
unsuspend: "ยกเลิกระงับ" unsuspend: "ยกเลิกระงับ"
blockConfirm: "คุณแน่ใจแล้วเหรอ ว่าต้องการบล็อบัญชีนี้?" blockConfirm: "คุณแน่ใจแล้วเหรอ ว่าต้องการบล็อบัญชีนี้?"
unblockConfirm: "คุณแน่ใจแล้วเหรอ ว่าต้องการปลดบล็อคบัญชีนี้?" unblockConfirm: "คุณแน่ใจแล้วเหรอ ว่าต้องการปลดบล็อคบัญชีนี้?"
suspendConfirm: "คุณแน่ใจแล้วเหรอว่าต้องการระงับบัญชีนี้อ่ะ?" suspendConfirm: "คุณแน่ใจแล้วเหรอว่าต้องการระงับบัญชีนี้?"
unsuspendConfirm: "คุณแน่ใจแล้วหรอว่าต้องการยกเลิกการระงับบัญชีนี้?" unsuspendConfirm: "คุณแน่ใจแล้วหรอว่าต้องการยกเลิกการระงับบัญชีนี้?"
selectList: "เลือกรายการ" selectList: "เลือกลิสต์"
selectAntenna: "เลือกเสาอากาศ" selectAntenna: "เลือกเสาอากาศ"
selectWidget: "เลือกวิดเจ็ต" selectWidget: "เลือกวิดเจ็ต"
editWidgets: "แก้ไขวิดเจ็ต" editWidgets: "แก้ไขวิดเจ็ต"
editWidgetsExit: "เรียบร้อย" editWidgetsExit: "เรียบร้อย"
customEmojis: "กำหนดอีโมจิเอง" customEmojis: "อีโมจิที่กำหนดเอง"
emoji: "อีโมจิ" emoji: "อีโมจิ"
emojis: "อีโมจิ" emojis: "อีโมจิ"
emojiName: "ชื่ออิโมจิ" emojiName: "ชื่ออิโมจิ"
emojiUrl: "อิโมจิ URL" emojiUrl: "URL ของอิโมจิ"
addEmoji: "แทรกอีโมจิ" addEmoji: "เพิ่มอีโมจิ"
settingGuide: "การตั้งค่าที่แนะนำ" settingGuide: "การตั้งค่าที่แนะนำ"
cacheRemoteFiles: "แคชไฟล์ระยะไกล" cacheRemoteFiles: "แคชไฟล์ระยะไกล"
cacheRemoteFilesDescription: "เมื่อปิดใช้งานการตั้งค่านี้ ไฟล์ระยะไกลนั้นจะถูกโหลดโดยตรงจากระยะไกลเซิฟเวอร์ cacheRemoteFilesDescription: "เมื่อปิดใช้งานการตั้งค่านี้ ไฟล์ระยะไกลนั้นจะถูกโหลดจากเซิร์ฟเวอร์ระยะไกลโดยตรง
แต่กรณีการปิดใช้งานนี้จะช่วยลดปริมาณการใช้พื้นที่จัดเก็บข้อมูล แต่เพิ่มปริมาณการใช้งาน แต่กรณีการปิดใช้งานนี้จะช่วยลดปริมาณการใช้พื้นที่จัดเก็บข้อมูล แต่เพิ่มปริมาณทราฟฟิค
เพราะเนื่องจากจะไม่มีการสร้างภาพขนาดย่อ" เพราะเนื่องจากจะไม่มีการสร้างภาพขนาดย่อ"
flagAsBot: "ทำเครื่องหมายบอกว่าบัญชีนี้เป็นบอท" flagAsBot: "ทำเครื่องหมายบอกว่าบัญชีนี้เป็นบัญชีอัตโนมัติ"
flagAsBotDescription: "การเปิดใช้งานตัวเลือกนี้หากบัญชีนี้ถูกควบคุมโดยนักเขียนโปรแกรม flagAsBotDescription: "เปิดใช้งานตัวเลือกนี้หากบัญชีนี้ถูกควบคุมโดยโปรแกรม หากเปิดใช้งาน
หรือ ถ้าหากเปิดใช้งาน มันจะทำหน้าที่เป็นแฟล็กสำหรับนักพัฒนารายอื่นๆ และเพื่อป้องกันการโต้ตอบแบบไม่มีที่สิ้นสุดกับบอทตัวอื่นๆ มันจะทำหน้าที่เป็นแฟล็กสำหรับนักพัฒนารายอื่น ๆ และเพื่อป้องกันการโต้ตอบแบบไม่มีที่สิ้นสุดกับบัญชีอัตโนมัติอื่นๆ
และยังสามารถปรับเปลี่ยนระบบภายในของ Firefish เพื่อปฏิบัติต่อบัญชีนี้เป็นบอท" และปรับเปลี่ยนระบบภายในของ Firefish เพื่อปฏิบัติต่อบัญชีนี้เป็นบัญชีอัตโนมัติ"
flagAsCat: "ทำเครื่องหมายบอกว่าบัญชีนี้เป็นแมว" flagAsCat: "ทำเครื่องหมายบอกว่าบัญชีนี้เป็นแมว"
flagAsCatDescription: "คุณจะได้รับหูแมวและพูดเหมือนแมวนะ!" flagAsCatDescription: "คุณจะได้รับหูแมวและพูดเหมือนแมวนะ!"
flagShowTimelineReplies: "แสดงตอบกลับ ในไทม์ไลน์" flagShowTimelineReplies: "แสดงการตอบกลับ ในไทม์ไลน์"
flagShowTimelineRepliesDescription: "แสดงการตอบกลับของผู้ใช้งานไปยังโพสต์ของผู้ใช้งานรายอื่นๆในไทม์ไลน์หากได้เปิดเอาไว้" flagShowTimelineRepliesDescription: "แสดงการตอบกลับของผู้ใช้งานไปยังโพสต์ของผู้ใช้งานรายอื่นๆในไทม์ไลน์หากได้เปิดเอาไว้"
autoAcceptFollowed: "อนุมัติคำขอติดตามโดยอัตโนมัติทันที จากผู้ใช้งานที่คุณกำลังติดตาม" autoAcceptFollowed: "อนุมัติคำขอติดตามโดยอัตโนมัติทันที จากผู้ใช้งานที่คุณกำลังติดตาม"
addAccount: "เพิ่มบัญชี" addAccount: "เพิ่มบัญชี"
@ -1245,22 +1246,28 @@ _deck:
list: "รายการ" list: "รายการ"
mentions: "พูดถึง" mentions: "พูดถึง"
noThankYou: ไม่ล่ะขอบคุณ noThankYou: ไม่ล่ะขอบคุณ
removeReaction: ลบรีเเอดชั่นของคุณ removeReaction: ลบรีเเอคชันของคุณ
renoteMute: ปิดเสียงบูส renoteMute: ปิดเสียงบูสต์
renoteUnmute: เลิกปิดเสียงบูส renoteUnmute: เลิกปิดเสียงบูสต์
manageGroups: จัดการกลุ่ม manageGroups: จัดการกลุ่ม
addInstance: เพิ่มเซิฟเวอร์ addInstance: เพิ่มเซิร์ฟเวอร์
searchPlaceholder: ค้นหา Firefish searchPlaceholder: ค้นหาใน Firefish
deleted: ลบแล้ว deleted: ลบแล้ว
editNote: แก้ไขโพสต์ editNote: แก้ไขโพสต์
edited: แก้ไขแล้วเมื่อ {date} {time} edited: แก้ไขแล้วเมื่อ {date} {time}
jumpToPrevious: ข้ามไปที่ก่อนหน้านี้ jumpToPrevious: ข้ามไปที่ก่อนหน้านี้
listsDesc: ลิสต์รายการนั้นช่วยให้คุณได้สร้างไทม์ไลน์กับผู้ใช้ที่ระบุได้นะ ยังสามารถเข้าถึงได้จากหน้าไทม์ไลน์ได้อีกด้วย listsDesc: ลิสต์นั้นช่วยให้คุณได้สร้างไทม์ไลน์กับผู้ใช้ที่ระบุได้ คุณสามารถเข้าถึงได้จากหน้าไทม์ไลน์
enableEmojiReactions: เปิดใช้งานรีแอดชั่นอีโมจิ enableEmojiReactions: เปิดใช้งานรีแอคชันอีโมจิ
selectChannel: เลือกช่อง selectChannel: เลือกช่อง
older: เก่ากว่านี้ older: เก่ากว่า
newer: ใหม่กว่านี้ newer: ใหม่กว่า
selectInstance: เลือกเซิฟเวอร์ selectInstance: เลือกเซิฟเวอร์
showEmojisInReactionNotifications: แสดงอิโมจิในการแจ้งเตือนรีแอคชั showEmojisInReactionNotifications: แสดงอิโมจิในการแจ้งเตือนรีแอคชั
flagSpeakAsCat: พูดเหมือนแมว flagSpeakAsCat: พูดเหมือนแมว
cw: คำเตือนเนื้อหา cw: คำเตือนเนื้อหา
reactions: รีแอคชัน
replies: การตอบกลับ
quotes: โควต
clickToShowPatterns: คลิกเพื่อแสดงรูปแบบโมดูล
renotes: บูสต์
flagSpeakAsCatDescription: ในโหมดแมว โพสต์ของคุณจะถูกทำให้เป็นแมว

View File

@ -22,7 +22,7 @@ otherSettings: "其他設定"
openInWindow: "在新視窗開啟" openInWindow: "在新視窗開啟"
profile: "個人檔案" profile: "個人檔案"
timeline: "時間軸" timeline: "時間軸"
noAccountDescription: "此用戶還沒有自我介紹。" noAccountDescription: "此使用者尚未自我介紹。"
login: "登入" login: "登入"
loggingIn: "登入中" loggingIn: "登入中"
logout: "登出" logout: "登出"
@ -127,8 +127,8 @@ block: "封鎖"
unblock: "解除封鎖" unblock: "解除封鎖"
suspend: "凍結" suspend: "凍結"
unsuspend: "解除凍結" unsuspend: "解除凍結"
blockConfirm: "確定要封鎖此用戶" blockConfirm: "確定要封鎖此使用者嗎"
unblockConfirm: "確定解除封鎖此用戶" unblockConfirm: "確定要解除封鎖此使用者嗎"
suspendConfirm: "確定凍結此帳號?" suspendConfirm: "確定凍結此帳號?"
unsuspendConfirm: "確定解凍此帳號?" unsuspendConfirm: "確定解凍此帳號?"
selectList: "選擇清單" selectList: "選擇清單"
@ -145,12 +145,12 @@ addEmoji: "加入表情符號"
settingGuide: "推薦設定" settingGuide: "推薦設定"
cacheRemoteFiles: "快取遠端檔案" cacheRemoteFiles: "快取遠端檔案"
cacheRemoteFilesDescription: "禁用此設定會停止遠端檔案的緩存,從而節省儲存空間,但資料會因直接連線從而產生額外數據花費。" cacheRemoteFilesDescription: "禁用此設定會停止遠端檔案的緩存,從而節省儲存空間,但資料會因直接連線從而產生額外數據花費。"
flagAsBot: "標記此帳號是機器人" flagAsBot: "標記此帳號為自動化帳號"
flagAsBotDescription: "如果本帳戶是由程式控制,請啟用此選項。啟用後會作為標示幫助其他開發者防止機器人之間產生無限互動的行為並會調整Firefish內部系統將本帳戶識別為機器人。" flagAsBotDescription: "如果本帳戶是由程式控制,請啟用此選項。此選項將作為一個標示以幫助其他開發者防止自動化帳號之間產生無限互動的行為並會調整Firefish內部系統將此帳號識別為自動化帳號。"
flagAsCat: "你是喵咪嗎w😺" flagAsCat: "你是喵咪嗎w😺"
flagAsCatDescription: "如果想將本帳戶標示為一隻貓,請開啟此標示!" flagAsCatDescription: "如果想將本帳戶標示為一隻貓,請開啟此標示!"
flagShowTimelineReplies: "在時間軸上顯示貼文的回覆" flagShowTimelineReplies: "在時間軸上顯示貼文的回覆"
flagShowTimelineRepliesDescription: "啟用時,時間軸除了顯示用戶的貼文以外,還會顯示用戶對其他貼文的回覆。" flagShowTimelineRepliesDescription: "啟用後,時間軸除了顯示使用者的貼文之外,也會顯示使用者對其他貼文的回覆。"
autoAcceptFollowed: "自動准予追隨中使用者的追隨請求" autoAcceptFollowed: "自動准予追隨中使用者的追隨請求"
addAccount: "添加帳戶" addAccount: "添加帳戶"
loginFailed: "登入失敗" loginFailed: "登入失敗"
@ -163,7 +163,7 @@ searchWith: "搜尋: {q}"
youHaveNoLists: "你沒有任何清單" youHaveNoLists: "你沒有任何清單"
followConfirm: "你真的要追隨 「{name}」 嗎?" followConfirm: "你真的要追隨 「{name}」 嗎?"
proxyAccount: "代理帳戶" proxyAccount: "代理帳戶"
proxyAccountDescription: "代理帳戶是在某些情況下充當其他伺服器用戶的帳戶。例如,當使用者將一個來自其他伺服器的帳戶放在列表中時,由於沒有其他使用者追蹤該帳戶,該指令不會傳送到該伺服器上,因此會由代理帳戶追蹤。" proxyAccountDescription: "代理帳戶是在某些情況下代替本地使用者追隨遠端使用者的帳戶。例如,當本地使用者將遠端使用者加入清單時,若沒有其他本地使用者追隨該遠端使用者,該遠端使用者的動態將不會發送到本地伺服器,因此將以代理帳戶代為追隨。"
host: "主機" host: "主機"
selectUser: "選取使用者" selectUser: "選取使用者"
recipient: "收件人" recipient: "收件人"
@ -199,8 +199,8 @@ clearCachedFilesConfirm: "確定要清除所有遠端暫存資料嗎?"
blockedInstances: "已封鎖的伺服器" blockedInstances: "已封鎖的伺服器"
blockedInstancesDescription: "請逐行輸入需要封鎖的伺服器。已封鎖的伺服器將無法與本伺服器進行通訊。" blockedInstancesDescription: "請逐行輸入需要封鎖的伺服器。已封鎖的伺服器將無法與本伺服器進行通訊。"
muteAndBlock: "靜音和封鎖" muteAndBlock: "靜音和封鎖"
mutedUsers: "已靜音用戶" mutedUsers: "已靜音的使用者"
blockedUsers: "已封鎖用戶" blockedUsers: "已封鎖的使用者"
noUsers: "沒有任何使用者" noUsers: "沒有任何使用者"
editProfile: "編輯個人檔案" editProfile: "編輯個人檔案"
noteDeleteConfirm: "確定刪除此貼文嗎?" noteDeleteConfirm: "確定刪除此貼文嗎?"
@ -222,7 +222,7 @@ publishing: "直播中"
notResponding: "沒有回應" notResponding: "沒有回應"
instanceFollowing: "追蹤伺服器" instanceFollowing: "追蹤伺服器"
instanceFollowers: "伺服器的追蹤者" instanceFollowers: "伺服器的追蹤者"
instanceUsers: "此伺服器的用戶" instanceUsers: "此伺服器的使用者"
changePassword: "修改密碼" changePassword: "修改密碼"
security: "安全性" security: "安全性"
retypedNotMatch: "兩次輸入不一致。" retypedNotMatch: "兩次輸入不一致。"
@ -262,7 +262,7 @@ agreeTo: "我同意{0}"
tos: "使用條款" tos: "使用條款"
start: "開始" start: "開始"
home: "首頁" home: "首頁"
remoteUserCaution: "由於該使用者來自遠端實例,因此資料可能是非即時的。" remoteUserCaution: "遠端使用者的資訊並不完整。"
activity: "動態" activity: "動態"
images: "圖片" images: "圖片"
birthday: "生日" birthday: "生日"
@ -330,14 +330,14 @@ disablingTimelinesInfo: "即使您關閉了時間軸功能,管理員和板主
registration: "註冊" registration: "註冊"
enableRegistration: "開啟新使用者註冊" enableRegistration: "開啟新使用者註冊"
invite: "邀請" invite: "邀請"
driveCapacityPerLocalAccount: "每個本地用戶的雲端空間大小" driveCapacityPerLocalAccount: "每個本地使用者的雲端容量"
driveCapacityPerRemoteAccount: "每個非本地用戶的雲端容量" driveCapacityPerRemoteAccount: "每個遠端使用者的雲端容量"
inMb: "以MB為單位" inMb: "以MB為單位"
iconUrl: "圖標網址" iconUrl: "圖標網址"
bannerUrl: "橫幅圖像網址" bannerUrl: "橫幅圖像網址"
backgroundImageUrl: "背景圖片的來源網址" backgroundImageUrl: "背景圖片的來源網址"
basicInfo: "基本資訊" basicInfo: "基本資訊"
pinnedUsers: "置頂用戶" pinnedUsers: "置頂的使用者"
pinnedUsersDescription: "在「探索」頁面中使用換行標記想要置頂的使用者。" pinnedUsersDescription: "在「探索」頁面中使用換行標記想要置頂的使用者。"
pinnedPages: "已釘選的頁面" pinnedPages: "已釘選的頁面"
pinnedPagesDescription: "輸入要固定至伺服器首頁的頁面路徑,一行一個。" pinnedPagesDescription: "輸入要固定至伺服器首頁的頁面路徑,一行一個。"
@ -362,14 +362,14 @@ antennaKeywordsDescription: "用空格分隔指定AND、用換行符分隔指定
notifyAntenna: "通知有新貼文" notifyAntenna: "通知有新貼文"
withFileAntenna: "僅帶有附件的貼文" withFileAntenna: "僅帶有附件的貼文"
enableServiceworker: "開啟 ServiceWorker" enableServiceworker: "開啟 ServiceWorker"
antennaUsersDescription: "指定用換行符分隔的用戶名" antennaUsersDescription: "指定使用者名稱,一行一個"
caseSensitive: "區分大小寫" caseSensitive: "區分大小寫"
withReplies: "包含回覆" withReplies: "包含回覆"
connectedTo: "您的帳戶已連接到以下社交帳戶" connectedTo: "您的帳戶已連接到以下社交帳戶"
notesAndReplies: "貼文與回覆" notesAndReplies: "貼文與回覆"
withFiles: "附件" withFiles: "附件"
silence: "禁言" silence: "禁言"
silenceConfirm: "確定要禁言此用戶嗎?" silenceConfirm: "確定要禁言此使用者嗎?"
unsilence: "解除禁言" unsilence: "解除禁言"
unsilenceConfirm: "確定要解除禁言嗎?" unsilenceConfirm: "確定要解除禁言嗎?"
popularUsers: "熱門使用者" popularUsers: "熱門使用者"
@ -537,7 +537,7 @@ deleteAllFilesConfirm: "確定要刪除所有檔案嗎?"
removeAllFollowing: "解除所有追蹤" removeAllFollowing: "解除所有追蹤"
removeAllFollowingDescription: "解除{host}所有的追蹤。在伺服器不再存在時執行。" removeAllFollowingDescription: "解除{host}所有的追蹤。在伺服器不再存在時執行。"
userSuspended: "此使用者已被停用。" userSuspended: "此使用者已被停用。"
userSilenced: "該用戶已被禁言。" userSilenced: "該使用者已被禁言。"
yourAccountSuspendedTitle: "帳戶已被凍結" yourAccountSuspendedTitle: "帳戶已被凍結"
yourAccountSuspendedDescription: "由於違反了伺服器的服務條款或其他原因,該帳戶已被凍結。 您可以與管理員連繫以了解更多訊息。 請不要創建一個新的帳戶。" yourAccountSuspendedDescription: "由於違反了伺服器的服務條款或其他原因,該帳戶已被凍結。 您可以與管理員連繫以了解更多訊息。 請不要創建一個新的帳戶。"
menu: "選單" menu: "選單"
@ -660,7 +660,7 @@ repliesCount: "回覆數量"
renotesCount: "轉發數量" renotesCount: "轉發數量"
repliedCount: "回覆數量" repliedCount: "回覆數量"
renotedCount: "轉發次數" renotedCount: "轉發次數"
followingCount: "正在跟隨的用戶數量" followingCount: "追隨中的使用者數量"
followersCount: "跟隨者數量" followersCount: "跟隨者數量"
sentReactionsCount: "反應發送次數" sentReactionsCount: "反應發送次數"
receivedReactionsCount: "反應收到次數" receivedReactionsCount: "反應收到次數"
@ -700,7 +700,7 @@ needReloadToApply: "必須重新載入才會生效。"
showTitlebar: "顯示標題列" showTitlebar: "顯示標題列"
clearCache: "清除快取資料" clearCache: "清除快取資料"
onlineUsersCount: "{n}人正在線上" onlineUsersCount: "{n}人正在線上"
nUsers: "{n}用戶" nUsers: "{n}使用者"
nNotes: "{n}貼文" nNotes: "{n}貼文"
sendErrorReports: "傳送錯誤報告" sendErrorReports: "傳送錯誤報告"
sendErrorReportsDescription: "開啟後,錯誤出現時將會與 Firefish 分享詳細紀錄,對於 Firefish 的開發會有非常大的幫助。\n sendErrorReportsDescription: "開啟後,錯誤出現時將會與 Firefish 分享詳細紀錄,對於 Firefish 的開發會有非常大的幫助。\n
@ -746,7 +746,7 @@ addDescription: "添加描述"
userPagePinTip: "在貼文的選單中選擇\"置頂\",即可置頂該貼文至您的個人檔案頁面。" userPagePinTip: "在貼文的選單中選擇\"置頂\",即可置頂該貼文至您的個人檔案頁面。"
notSpecifiedMentionWarning: "此貼文有未指定的提及" notSpecifiedMentionWarning: "此貼文有未指定的提及"
info: "資訊" info: "資訊"
userInfo: "用戶資料" userInfo: "使用者資訊"
unknown: "未知" unknown: "未知"
onlineStatus: "在線狀態" onlineStatus: "在線狀態"
hideOnlineStatus: "隱藏在線狀態" hideOnlineStatus: "隱藏在線狀態"
@ -891,7 +891,7 @@ cannotUploadBecauseNoFreeSpace: "由於雲端硬碟沒有可用空間,因此
beta: "Beta" beta: "Beta"
enableAutoSensitive: "自動NSFW判定" enableAutoSensitive: "自動NSFW判定"
enableAutoSensitiveDescription: "如可用,請利用機器學習在媒體上自動設置 NSFW 旗標。 即使關閉此功能,依伺服器而定也可能會自動設置。" enableAutoSensitiveDescription: "如可用,請利用機器學習在媒體上自動設置 NSFW 旗標。 即使關閉此功能,依伺服器而定也可能會自動設置。"
activeEmailValidationDescription: "積極地驗證用戶的電子郵件地址,判斷它是否為免洗地址,或者它是否可以通信。 若關閉,則只會檢查字元是否正確。" activeEmailValidationDescription: "強化驗證使用者的電子郵件地址,包含判斷是否為免洗信箱,以及是否可以實際通訊。 停用此選項時,只會檢查是否符合電子郵件地址的形式。"
navbar: "導覽列" navbar: "導覽列"
shuffle: "隨機" shuffle: "隨機"
account: "帳戶" account: "帳戶"
@ -900,8 +900,8 @@ customKaTeXMacro: "自訂KaTeX巨集"
customKaTeXMacroDescription: "使用巨集來輕鬆輸入數學表達式吧!巨集的用法與 LaTeX 中的命令定義相同。你可以使用 \\newcommand{\\ customKaTeXMacroDescription: "使用巨集來輕鬆輸入數學表達式吧!巨集的用法與 LaTeX 中的命令定義相同。你可以使用 \\newcommand{\\
name}{content} 或 \\newcommand{\\name}[number of arguments]{content} 來輸入數學表達式。舉例來說,\\ name}{content} 或 \\newcommand{\\name}[number of arguments]{content} 來輸入數學表達式。舉例來說,\\
newcommand{\\add}[2]{#1 + #2} 會將 \\add{3}{foo} 展開為 3 + foo。巨集名稱除了可用大括號 {} 括起來之外,也可使用小括號 newcommand{\\add}[2]{#1 + #2} 會將 \\add{3}{foo} 展開為 3 + foo。巨集名稱除了可用大括號 {} 括起來之外,也可使用小括號
() 和中括號 [],但使用於巨集參數的括號會有所變更。每行只能夠定義一個巨集,巨集中間無法間換。無效的行將被忽略。只支援簡單字串的替換功能,不支援條件分歧的進階語法。" () 和中括號 [],但使用於巨集參數的括號會有所變更。每行只能定義一個巨集,巨集中間無法換行,無效的行將被忽略。只支援簡單字串的替換功能,不支援條件分歧的進階語法。"
enableCustomKaTeXMacro: "啟用自定義 KaTeX 宏" enableCustomKaTeXMacro: "啟用自訂 KaTeX 巨集"
_sensitiveMediaDetection: _sensitiveMediaDetection:
description: "您可以使用機器學習自動檢測敏感媒體並將其用於審核。 伺服器的負荷會稍微增加。" description: "您可以使用機器學習自動檢測敏感媒體並將其用於審核。 伺服器的負荷會稍微增加。"
sensitivity: "檢測敏感度" sensitivity: "檢測敏感度"
@ -918,7 +918,7 @@ _emailUnavailable:
smtp: "郵件伺服器沒有應答" smtp: "郵件伺服器沒有應答"
_ffVisibility: _ffVisibility:
public: "發佈" public: "發佈"
followers: "只有關注你的用戶能看到" followers: "僅追隨者可見"
private: "私密" private: "私密"
_signup: _signup:
almostThere: "即將完成" almostThere: "即將完成"
@ -1002,7 +1002,7 @@ _mfm:
intro: "MFM是Misskey、Firefish、Akkoma等專用的標記語言可以在各個位置使用。 您可以這裏看到MFM可用語法列表。" intro: "MFM是Misskey、Firefish、Akkoma等專用的標記語言可以在各個位置使用。 您可以這裏看到MFM可用語法列表。"
dummy: "Firefish拓展了Fediverse的世界" dummy: "Firefish拓展了Fediverse的世界"
mention: "提及" mention: "提及"
mentionDescription: "透過 @+用戶名 來標示特定使用者。" mentionDescription: "透過 @+使用者名稱 來標示特定使用者。"
hashtag: "#tag" hashtag: "#tag"
hashtagDescription: "可以使用\"#\"符號後加文字表示話題標籤。" hashtagDescription: "可以使用\"#\"符號後加文字表示話題標籤。"
url: "URL" url: "URL"
@ -1122,7 +1122,7 @@ _wordMute:
muteLangs: 被靜音的語言 muteLangs: 被靜音的語言
muteLangsDescription: OR條件以空格或換行進行分隔。 muteLangsDescription: OR條件以空格或換行進行分隔。
_instanceMute: _instanceMute:
instanceMuteDescription: "包括對被靜音伺服器上的用戶的回覆,被設定的伺服器上所有貼文及轉發都會被靜音。" instanceMuteDescription: "將設定的伺服器的所有貼文及轉發靜音。對被靜音伺服器的使用者的回覆也將被靜音。"
instanceMuteDescription2: "設定時以換行進行分隔" instanceMuteDescription2: "設定時以換行進行分隔"
title: "被設定的伺服器,貼文將被隱藏。" title: "被設定的伺服器,貼文將被隱藏。"
heading: "將會被靜音的伺服器" heading: "將會被靜音的伺服器"
@ -1236,7 +1236,7 @@ _tutorial:
step5_1: "時間軸,到處都是時間軸!" step5_1: "時間軸,到處都是時間軸!"
step5_2: "您的伺服器已啟用了{timelines}個時間軸。" step5_2: "您的伺服器已啟用了{timelines}個時間軸。"
step5_3: "首頁 {icon} 時間軸是顯示你追蹤的帳號的貼文。" step5_3: "首頁 {icon} 時間軸是顯示你追蹤的帳號的貼文。"
step5_4: "本地 {icon} 時間軸是你可以看到伺服器中所有其他用戶的貼文的時間軸。" step5_4: "本地{icon}時間軸是你可以看到此伺服器上所有使用者的貼文的時間軸。"
step5_5: "社交 {icon} 時間軸是你的 首頁時間軸 和 本地時間軸 的結合體。" step5_5: "社交 {icon} 時間軸是你的 首頁時間軸 和 本地時間軸 的結合體。"
step5_6: "推薦 {icon} 時間軸是顯示你的伺服器管理員推薦的貼文。" step5_6: "推薦 {icon} 時間軸是顯示你的伺服器管理員推薦的貼文。"
step5_7: "全球 {icon} 時間軸是顯示來自所有其他連接的伺服器的貼文。" step5_7: "全球 {icon} 時間軸是顯示來自所有其他連接的伺服器的貼文。"
@ -1268,16 +1268,17 @@ _2fa:
renewTOTPOk: 重新配置 renewTOTPOk: 重新配置
step3Title: 輸入驗證碼 step3Title: 輸入驗證碼
securityKeyNotSupported: 您使用的瀏覧器不支援安全金鑰(Security key)。 securityKeyNotSupported: 您使用的瀏覧器不支援安全金鑰(Security key)。
step2Click: 點擊此二維條碼以註冊2FA至你的安全密鑰或手機的Authenticator應用程式。
_permissions: _permissions:
"read:account": "查看我的帳戶資訊" "read:account": "查看我的帳戶資訊"
"write:account": "更改我的帳戶資訊" "write:account": "更改我的帳戶資訊"
"read:blocks": "已封鎖用戶名單" "read:blocks": "查看封鎖的使用者名單"
"write:blocks": "編輯已封鎖用戶名單" "write:blocks": "編輯封鎖的使用者名單"
"read:drive": "存取雲端硬碟" "read:drive": "存取雲端硬碟"
"write:drive": "編輯雲端硬碟的檔案" "write:drive": "編輯雲端硬碟的檔案"
"read:favorites": "瀏覽我的最愛" "read:favorites": "瀏覽我的最愛"
"write:favorites": "編輯我的最愛列表" "write:favorites": "編輯我的最愛列表"
"read:following": "查看追隨中的用戶資訊" "read:following": "查看追隨中的使用者資訊"
"write:following": "追隨/解除追隨" "write:following": "追隨/解除追隨"
"read:messaging": "顯示訊息" "read:messaging": "顯示訊息"
"write:messaging": "撰寫或刪除私人訊息" "write:messaging": "撰寫或刪除私人訊息"
@ -1343,7 +1344,7 @@ _widgets:
postForm: "發佈窗口" postForm: "發佈窗口"
slideshow: "幻燈片" slideshow: "幻燈片"
button: "按鈕" button: "按鈕"
onlineUsers: "線上的用戶" onlineUsers: "線上的使用者"
jobQueue: "佇列" jobQueue: "佇列"
serverMetric: "伺服器指標" serverMetric: "伺服器指標"
aiscript: "AiScript 控制台" aiscript: "AiScript 控制台"
@ -1416,14 +1417,14 @@ _profile:
metadataContent: "内容" metadataContent: "内容"
changeAvatar: "更換大頭貼" changeAvatar: "更換大頭貼"
changeBanner: "變更橫幅圖像" changeBanner: "變更橫幅圖像"
locationDescription: 如果你先輸入你所在的城市,則會向其他用戶顯示你的當地時間。 locationDescription: 如果你先輸入你所在的城市,則會向其他使用者顯示你的當地時間。
_exportOrImport: _exportOrImport:
allNotes: "所有貼文" allNotes: "所有貼文"
followingList: "追隨中" followingList: "追隨中"
muteList: "靜音" muteList: "靜音"
blockingList: "封鎖" blockingList: "封鎖"
userLists: "清單" userLists: "清單"
excludeMutingUsers: "排除被靜音的用戶" excludeMutingUsers: "排除被靜音的使用者"
excludeInactiveUsers: "排除不活躍帳戶" excludeInactiveUsers: "排除不活躍帳戶"
_charts: _charts:
federation: "站台聯邦" federation: "站台聯邦"
@ -1826,16 +1827,16 @@ _messaging:
manageGroups: 管理群組 manageGroups: 管理群組
replayTutorial: 重新播放教程 replayTutorial: 重新播放教程
moveFromLabel: '您想遷移的舊帳戶:' moveFromLabel: '您想遷移的舊帳戶:'
customMOTDDescription: 自訂MOTD(啟動畫面)訊息,一行一個。每次用戶載入/重新整理頁面時將會隨機顯示。 customMOTDDescription: 自訂MOTD(啟動畫面)訊息,一行一個。使用者載入/重新整理頁面時將隨機顯示。
privateModeInfo: 啟用後,只有列入允許名單的伺服器才能與你的伺服器聯合。所有貼文都將對公眾隱藏。 privateModeInfo: 啟用後,只有列入允許名單的伺服器才能與你的伺服器聯合。所有貼文都將對公眾隱藏。
adminCustomCssWarn: 除非你知道它的作用,否則請不要使用此設定。 輸入不正確的值可能會導致每個人的客戶端無法正常運行。你可在你的的用戶設定中測試,確保你的 adminCustomCssWarn: 除非你知道它的作用,否則請不要使用此設定。 輸入不正確的值可能會導致每個人的用戶端無法正常運行。你可在你的使用者設定中先行測試,以確保你的
CSS 正常作。 CSS 正常作。
showUpdates: Firefish 更新時顯示彈出視窗 showUpdates: Firefish 更新時顯示彈出視窗
recommendedInstances: 建議的伺服器 recommendedInstances: 建議的伺服器
caption: 自動加上替代文字(alt) caption: 自動加上替代文字(alt)
enterSendsMessage: 在 Messaging 中按 Return 發送消息 (如關閉則是 Ctrl + Return) enterSendsMessage: 在 Messaging 中按 Return 發送消息 (如關閉則是 Ctrl + Return)
migrationConfirm: "您確定要將你的帳戶遷移到 {account} 嗎? 一旦這樣做,你將無法復原,而你將無法再次正常使用您的帳戶。\n另外請確保你已將此當前帳戶設置為您要遷移的帳戶。" migrationConfirm: "您確定要將你的帳戶遷移到 {account} 嗎? 一旦這樣做,你將無法復原,而你將無法再次正常使用您的帳戶。\n另外請確保你已將此當前帳戶設置為您要遷移的帳戶。"
customSplashIconsDescription: 每次用戶加載/重新加載頁面時,以換行符號分隔的自定啟動畫面圖標的網址將隨機顯示。請確保圖片位於靜態網址上,最好所有圖片解析度調整 customSplashIconsDescription: 自訂啟動畫面的圖標網址,一行一個。使用者載入/重新整理頁面時將隨機顯示。請確保圖片位於靜態網址上,最好每個圖片的解析度皆縮放
192x192。 192x192。
accountMoved: '該使用者已遷移至新帳戶:' accountMoved: '該使用者已遷移至新帳戶:'
showAds: 顯示社群橫幅 showAds: 顯示社群橫幅
@ -1873,7 +1874,8 @@ silenced: 已靜音
_experiments: _experiments:
title: 試驗功能 title: 試驗功能
enablePostImports: 啟用匯入貼文的功能 enablePostImports: 啟用匯入貼文的功能
postImportsCaption: 允許用戶從舊有的Firefish・Misskey・Mastodon・Akkoma・Pleroma帳號匯入貼文。在伺服器佇列堵塞時匯入貼文可能會導致載入速度變慢。 postImportsCaption:
允許使用者從舊有的Firefish・Misskey・Mastodon・Akkoma・Pleroma帳號匯入貼文。在伺服器佇列堵塞時匯入貼文可能會導致載入速度變慢。
findOtherInstance: 找找另一個伺服器 findOtherInstance: 找找另一個伺服器
noGraze: 瀏覽器擴充元件 "Graze for Mastodon" 會與Firefish發生衝突請停用該擴充元件。 noGraze: 瀏覽器擴充元件 "Graze for Mastodon" 會與Firefish發生衝突請停用該擴充元件。
userSaysSomethingReasonRenote: '{name} 轉發了包含 {reason} 的貼文' userSaysSomethingReasonRenote: '{name} 轉發了包含 {reason} 的貼文'
@ -1903,7 +1905,7 @@ newer: 較新
older: 較舊 older: 較舊
jumpToPrevious: 跳到上一個 jumpToPrevious: 跳到上一個
removeReaction: 移除你的反應 removeReaction: 移除你的反應
listsDesc: 清單可以創建一個只有您指定用戶的時間軸。 可以從時間軸頁面訪問它們。 listsDesc: 清單可以讓您創建含用指定使用者的時間軸。您可以在時間軸頁面查看它們。
flagSpeakAsCatDescription: 在喵咪模式下你的貼文會被喵化ヾ(•ω•`)o flagSpeakAsCatDescription: 在喵咪模式下你的貼文會被喵化ヾ(•ω•`)o
antennasDesc: "天線會顯示符合您設置條件的新貼文!\n 可以從時間軸訪問它們。" antennasDesc: "天線會顯示符合您設置條件的新貼文!\n 可以從時間軸訪問它們。"
expandOnNoteClick: 點擊以打開貼文 expandOnNoteClick: 點擊以打開貼文
@ -1937,7 +1939,7 @@ isAdmin: 管理員
isPatron: Firefish 項目贊助者 isPatron: Firefish 項目贊助者
silencedWarning: 顯示此頁面是因為這些使用者來自您伺服器管理員已靜音的伺服器,因此他們可能是垃圾訊息。 silencedWarning: 顯示此頁面是因為這些使用者來自您伺服器管理員已靜音的伺服器,因此他們可能是垃圾訊息。
signupsDisabled: 此伺服器目前停止註冊,但您隨時可以在另一台伺服器上註冊!如果您有此伺服器的邀請碼,請在下面輸入。 signupsDisabled: 此伺服器目前停止註冊,但您隨時可以在另一台伺服器上註冊!如果您有此伺服器的邀請碼,請在下面輸入。
showPopup: 通過彈出式視窗通知用戶 showPopup: 通過彈出式視窗通知使用者
showWithSparkles: 讓標題閃閃發光 showWithSparkles: 讓標題閃閃發光
youHaveUnreadAnnouncements: 您有未讀的公告 youHaveUnreadAnnouncements: 您有未讀的公告
donationLink: 連結到贊助頁面 donationLink: 連結到贊助頁面
@ -1946,7 +1948,7 @@ remindMeLater: 可能之後
removeQuote: 删除引用 removeQuote: 删除引用
removeRecipient: 刪除收件者 removeRecipient: 刪除收件者
removeMember: 刪除成員 removeMember: 刪除成員
isBot: 此帳戶是機器人 isBot: 此帳號為自動化帳號
verifiedLink: 已驗證連結 verifiedLink: 已驗證連結
_filters: _filters:
followersOnly: 只顯示關注者的 followersOnly: 只顯示關注者的
@ -2001,3 +2003,9 @@ _iconSets:
bold: 粗線 bold: 粗線
duotone: 雙色 duotone: 雙色
light: 細線 light: 細線
showAttachedNotes: 顯示有此附件的貼文
attachedToNotes: 帶有此附件的貼文
useEmojiCdn: 使用CDN的Twemoji
useEmojiCdnDescription: 使用JSDelivr CDN提供的Twemoji而不使用儲存在伺服器上的檔案。
moreUrls: 置頂的頁面
moreUrlsDescription: "請以下列形式輸入欲釘選在左下角幫助選單的頁面,一行一個:\n\"顯示名稱\": https://example.com/"

View File

@ -6,7 +6,7 @@
"type": "git", "type": "git",
"url": "https://git.joinfirefish.org/firefish/firefish.git" "url": "https://git.joinfirefish.org/firefish/firefish.git"
}, },
"packageManager": "pnpm@8.10.5", "packageManager": "pnpm@8.13.1",
"private": true, "private": true,
"scripts": { "scripts": {
"rebuild": "pnpm run clean && pnpm run build", "rebuild": "pnpm run clean && pnpm run build",
@ -64,7 +64,7 @@
"gulp-replace": "1.1.4", "gulp-replace": "1.1.4",
"gulp-terser": "2.1.0", "gulp-terser": "2.1.0",
"install-peers": "^1.0.4", "install-peers": "^1.0.4",
"pnpm": "8.10.5", "pnpm": "8.13.1",
"start-server-and-test": "2.0.3", "start-server-and-test": "2.0.3",
"typescript": "5.2.2" "typescript": "5.2.2"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 889 B

After

Width:  |  Height:  |  Size: 889 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

View File

@ -29,7 +29,7 @@
"@bull-board/api": "5.9.1", "@bull-board/api": "5.9.1",
"@bull-board/koa": "5.9.1", "@bull-board/koa": "5.9.1",
"@bull-board/ui": "5.9.1", "@bull-board/ui": "5.9.1",
"@discordapp/twemoji": "14.1.2", "@discordapp/twemoji": "^15.0.2",
"@elastic/elasticsearch": "8.10.0", "@elastic/elasticsearch": "8.10.0",
"@koa/cors": "4.0.0", "@koa/cors": "4.0.0",
"@koa/multer": "3.0.2", "@koa/multer": "3.0.2",
@ -39,6 +39,7 @@
"@redocly/openapi-core": "1.4.1", "@redocly/openapi-core": "1.4.1",
"@sinonjs/fake-timers": "11.2.2", "@sinonjs/fake-timers": "11.2.2",
"@tensorflow/tfjs": "^4.13.0", "@tensorflow/tfjs": "^4.13.0",
"@twemoji/parser": "^15.0.0",
"adm-zip": "^0.5.10", "adm-zip": "^0.5.10",
"ajv": "8.12.0", "ajv": "8.12.0",
"archiver": "6.0.1", "archiver": "6.0.1",
@ -128,7 +129,6 @@
"tinycolor2": "1.6.0", "tinycolor2": "1.6.0",
"tinyld": "^1.3.4", "tinyld": "^1.3.4",
"tmp": "0.2.1", "tmp": "0.2.1",
"twemoji-parser": "14.0.0",
"typeorm": "0.3.17", "typeorm": "0.3.17",
"ulid": "2.3.0", "ulid": "2.3.0",
"uuid": "9.0.1", "uuid": "9.0.1",

View File

@ -5,11 +5,11 @@ import Xev from "xev";
import Logger from "@/services/logger.js"; import Logger from "@/services/logger.js";
import { envOption } from "../env.js"; import { envOption } from "../env.js";
import os from "node:os";
// for typeorm // for typeorm
import "reflect-metadata"; import "reflect-metadata";
import { masterMain } from "./master.js"; import { masterMain } from "./master.js";
import { workerMain } from "./worker.js"; import { workerMain } from "./worker.js";
import os from "node:os";
const logger = new Logger("core", "cyan"); const logger = new Logger("core", "cyan");
const clusterLogger = logger.createSubLogger("cluster", "orange", false); const clusterLogger = logger.createSubLogger("cluster", "orange", false);

View File

@ -1,18 +1,18 @@
import cluster from "node:cluster";
import * as fs from "node:fs"; import * as fs from "node:fs";
import * as os from "node:os";
import { dirname } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { dirname } from "node:path";
import * as os from "node:os";
import cluster from "node:cluster";
import chalk from "chalk"; import chalk from "chalk";
import chalkTemplate from "chalk-template"; import chalkTemplate from "chalk-template";
import semver from "semver"; import semver from "semver";
import Logger from "@/services/logger.js";
import loadConfig from "@/config/load.js"; import loadConfig from "@/config/load.js";
import type { Config } from "@/config/types.js"; import type { Config } from "@/config/types.js";
import { db, initDb } from "@/db/postgre.js";
import { envOption } from "@/env.js"; import { envOption } from "@/env.js";
import { showMachineInfo } from "@/misc/show-machine-info.js"; import { showMachineInfo } from "@/misc/show-machine-info.js";
import Logger from "@/services/logger.js"; import { db, initDb } from "@/db/postgre.js";
const _filename = fileURLToPath(import.meta.url); const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);
@ -148,9 +148,7 @@ function showNodejsVersion(): void {
nodejsLogger.info(`Version ${process.version} detected.`); nodejsLogger.info(`Version ${process.version} detected.`);
const minVersion = fs const minVersion = "v18.16.0";
.readFileSync(`${_dirname}/../../../../.node-version`, "utf-8")
.trim();
if (semver.lt(process.version, minVersion)) { if (semver.lt(process.version, minVersion)) {
nodejsLogger.error(`At least Node.js ${minVersion} required!`); nodejsLogger.error(`At least Node.js ${minVersion} required!`);
process.exit(1); process.exit(1);

View File

@ -1,6 +1,6 @@
import cluster from "node:cluster"; import cluster from "node:cluster";
import os from "node:os";
import { initDb } from "@/db/postgre.js"; import { initDb } from "@/db/postgre.js";
import os from "node:os";
/** /**
* Init worker process * Init worker process

View File

@ -3,10 +3,10 @@
*/ */
import * as fs from "node:fs"; import * as fs from "node:fs";
import { dirname } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { dirname } from "node:path";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import type { Mixin, Source } from "./types.js"; import type { Source, Mixin } from "./types.js";
const _filename = fileURLToPath(import.meta.url); const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);

View File

@ -14,10 +14,8 @@ export const MAX_CAPTION_TEXT_LENGTH = Math.min(
); );
export const SECOND = 1000; export const SECOND = 1000;
export const SEC = 1000; // why do we need this duplicate here? export const MINUTE = 60 * SECOND;
export const MINUTE = 60 * SEC; export const HOUR = 60 * MINUTE;
export const MIN = 60 * SEC; // why do we need this duplicate here?
export const HOUR = 60 * MIN;
export const DAY = 24 * HOUR; export const DAY = 24 * HOUR;
export const USER_ONLINE_THRESHOLD = 10 * MINUTE; export const USER_ONLINE_THRESHOLD = 10 * MINUTE;

View File

@ -1,5 +1,5 @@
import { deliverQueue, inboxQueue } from "@/queue/queues.js";
import Xev from "xev"; import Xev from "xev";
import { deliverQueue, inboxQueue } from "@/queue/queues.js";
const ev = new Xev(); const ev = new Xev();

View File

@ -1,8 +1,8 @@
import meilisearch from "@/db/meilisearch.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import * as osUtils from "os-utils";
import si from "systeminformation"; import si from "systeminformation";
import Xev from "xev"; import Xev from "xev";
import * as osUtils from "os-utils";
import { fetchMeta } from "@/misc/fetch-meta.js";
import meilisearch from "@/db/meilisearch.js";
const ev = new Xev(); const ev = new Xev();

View File

@ -1,5 +1,5 @@
import config from "@/config/index.js";
import * as elasticsearch from "@elastic/elasticsearch"; import * as elasticsearch from "@elastic/elasticsearch";
import config from "@/config/index.js";
const index = { const index = {
settings: { settings: {

View File

@ -1,9 +1,9 @@
import { Health, Index, MeiliSearch, Stats } from "meilisearch"; import { Health, Index, MeiliSearch, Stats } from "meilisearch";
import { dbLogger } from "./logger.js"; import { dbLogger } from "./logger.js";
import * as url from "url";
import config from "@/config/index.js"; import config from "@/config/index.js";
import { Note } from "@/models/entities/note.js"; import { Note } from "@/models/entities/note.js";
import * as url from "url";
import { ILocalUser } from "@/models/entities/user.js"; import { ILocalUser } from "@/models/entities/user.js";
import { Followings, Users } from "@/models/index.js"; import { Followings, Users } from "@/models/index.js";
@ -154,7 +154,7 @@ function timestampToUnix(timestamp: string) {
if (unix === 0) { if (unix === 0) {
// Try to parse the timestamp as JavaScript Date // Try to parse the timestamp as JavaScript Date
const date = Date.parse(timestamp); const date = Date.parse(timestamp);
if (isNaN(date)) return 0; if (Number.isNaN(date)) return 0;
unix = date / 1000; unix = date / 1000;
} }

View File

@ -2,76 +2,76 @@
import pg from "pg"; import pg from "pg";
pg.types.setTypeParser(20, Number); pg.types.setTypeParser(20, Number);
import config from "@/config/index.js";
import * as highlight from "cli-highlight";
import type { Logger } from "typeorm"; import type { Logger } from "typeorm";
import { DataSource } from "typeorm"; import { DataSource } from "typeorm";
import * as highlight from "cli-highlight";
import config from "@/config/index.js";
import { AbuseUserReport } from "@/models/entities/abuse-user-report.js"; import { User } from "@/models/entities/user.js";
import { AccessToken } from "@/models/entities/access-token.js";
import { Ad } from "@/models/entities/ad.js";
import { AnnouncementRead } from "@/models/entities/announcement-read.js";
import { Announcement } from "@/models/entities/announcement.js";
import { Antenna } from "@/models/entities/antenna.js";
import { App } from "@/models/entities/app.js";
import { AttestationChallenge } from "@/models/entities/attestation-challenge.js";
import { AuthSession } from "@/models/entities/auth-session.js";
import { Blocking } from "@/models/entities/blocking.js";
import { ChannelFollowing } from "@/models/entities/channel-following.js";
import { ChannelNotePining } from "@/models/entities/channel-note-pining.js";
import { Channel } from "@/models/entities/channel.js";
import { ClipNote } from "@/models/entities/clip-note.js";
import { Clip } from "@/models/entities/clip.js";
import { DriveFile } from "@/models/entities/drive-file.js"; import { DriveFile } from "@/models/entities/drive-file.js";
import { DriveFolder } from "@/models/entities/drive-folder.js"; import { DriveFolder } from "@/models/entities/drive-folder.js";
import { Emoji } from "@/models/entities/emoji.js"; import { AccessToken } from "@/models/entities/access-token.js";
import { FollowRequest } from "@/models/entities/follow-request.js"; import { App } from "@/models/entities/app.js";
import { Following } from "@/models/entities/following.js"; import { PollVote } from "@/models/entities/poll-vote.js";
import { GalleryLike } from "@/models/entities/gallery-like.js"; import { Note } from "@/models/entities/note.js";
import { GalleryPost } from "@/models/entities/gallery-post.js";
import { Hashtag } from "@/models/entities/hashtag.js";
import { Instance } from "@/models/entities/instance.js";
import { MessagingMessage } from "@/models/entities/messaging-message.js";
import { Meta } from "@/models/entities/meta.js";
import { ModerationLog } from "@/models/entities/moderation-log.js";
import { MutedNote } from "@/models/entities/muted-note.js";
import { Muting } from "@/models/entities/muting.js";
import { NoteEdit } from "@/models/entities/note-edit.js";
import { NoteFavorite } from "@/models/entities/note-favorite.js";
import { NoteReaction } from "@/models/entities/note-reaction.js"; import { NoteReaction } from "@/models/entities/note-reaction.js";
import { NoteWatching } from "@/models/entities/note-watching.js";
import { NoteThreadMuting } from "@/models/entities/note-thread-muting.js"; import { NoteThreadMuting } from "@/models/entities/note-thread-muting.js";
import { NoteUnread } from "@/models/entities/note-unread.js"; import { NoteUnread } from "@/models/entities/note-unread.js";
import { NoteWatching } from "@/models/entities/note-watching.js";
import { Note } from "@/models/entities/note.js";
import { Notification } from "@/models/entities/notification.js"; import { Notification } from "@/models/entities/notification.js";
import { PageLike } from "@/models/entities/page-like.js"; import { Meta } from "@/models/entities/meta.js";
import { Page } from "@/models/entities/page.js"; import { Following } from "@/models/entities/following.js";
import { PasswordResetRequest } from "@/models/entities/password-reset-request.js"; import { Instance } from "@/models/entities/instance.js";
import { PollVote } from "@/models/entities/poll-vote.js"; import { Muting } from "@/models/entities/muting.js";
import { RenoteMuting } from "@/models/entities/renote-muting.js";
import { SwSubscription } from "@/models/entities/sw-subscription.js";
import { Blocking } from "@/models/entities/blocking.js";
import { UserList } from "@/models/entities/user-list.js";
import { UserListJoining } from "@/models/entities/user-list-joining.js";
import { UserGroup } from "@/models/entities/user-group.js";
import { UserGroupJoining } from "@/models/entities/user-group-joining.js";
import { UserGroupInvitation } from "@/models/entities/user-group-invitation.js";
import { Hashtag } from "@/models/entities/hashtag.js";
import { NoteFavorite } from "@/models/entities/note-favorite.js";
import { AbuseUserReport } from "@/models/entities/abuse-user-report.js";
import { RegistrationTicket } from "@/models/entities/registration-tickets.js";
import { MessagingMessage } from "@/models/entities/messaging-message.js";
import { Signin } from "@/models/entities/signin.js";
import { AuthSession } from "@/models/entities/auth-session.js";
import { FollowRequest } from "@/models/entities/follow-request.js";
import { Emoji } from "@/models/entities/emoji.js";
import { UserNotePining } from "@/models/entities/user-note-pining.js";
import { Poll } from "@/models/entities/poll.js"; import { Poll } from "@/models/entities/poll.js";
import { UserKeypair } from "@/models/entities/user-keypair.js";
import { UserPublickey } from "@/models/entities/user-publickey.js";
import { UserProfile } from "@/models/entities/user-profile.js";
import { UserSecurityKey } from "@/models/entities/user-security-key.js";
import { AttestationChallenge } from "@/models/entities/attestation-challenge.js";
import { Page } from "@/models/entities/page.js";
import { PageLike } from "@/models/entities/page-like.js";
import { GalleryPost } from "@/models/entities/gallery-post.js";
import { GalleryLike } from "@/models/entities/gallery-like.js";
import { ModerationLog } from "@/models/entities/moderation-log.js";
import { UsedUsername } from "@/models/entities/used-username.js";
import { Announcement } from "@/models/entities/announcement.js";
import { AnnouncementRead } from "@/models/entities/announcement-read.js";
import { Clip } from "@/models/entities/clip.js";
import { ClipNote } from "@/models/entities/clip-note.js";
import { Antenna } from "@/models/entities/antenna.js";
import { PromoNote } from "@/models/entities/promo-note.js"; import { PromoNote } from "@/models/entities/promo-note.js";
import { PromoRead } from "@/models/entities/promo-read.js"; import { PromoRead } from "@/models/entities/promo-read.js";
import { RegistrationTicket } from "@/models/entities/registration-tickets.js";
import { RegistryItem } from "@/models/entities/registry-item.js";
import { Relay } from "@/models/entities/relay.js"; import { Relay } from "@/models/entities/relay.js";
import { RenoteMuting } from "@/models/entities/renote-muting.js"; import { MutedNote } from "@/models/entities/muted-note.js";
import { Signin } from "@/models/entities/signin.js"; import { Channel } from "@/models/entities/channel.js";
import { SwSubscription } from "@/models/entities/sw-subscription.js"; import { ChannelFollowing } from "@/models/entities/channel-following.js";
import { UsedUsername } from "@/models/entities/used-username.js"; import { ChannelNotePining } from "@/models/entities/channel-note-pining.js";
import { UserGroupInvitation } from "@/models/entities/user-group-invitation.js"; import { RegistryItem } from "@/models/entities/registry-item.js";
import { UserGroupJoining } from "@/models/entities/user-group-joining.js"; import { Ad } from "@/models/entities/ad.js";
import { UserGroup } from "@/models/entities/user-group.js"; import { PasswordResetRequest } from "@/models/entities/password-reset-request.js";
import { UserIp } from "@/models/entities/user-ip.js";
import { UserKeypair } from "@/models/entities/user-keypair.js";
import { UserListJoining } from "@/models/entities/user-list-joining.js";
import { UserList } from "@/models/entities/user-list.js";
import { UserNotePining } from "@/models/entities/user-note-pining.js";
import { UserPending } from "@/models/entities/user-pending.js"; import { UserPending } from "@/models/entities/user-pending.js";
import { UserProfile } from "@/models/entities/user-profile.js";
import { UserPublickey } from "@/models/entities/user-publickey.js";
import { UserSecurityKey } from "@/models/entities/user-security-key.js";
import { User } from "@/models/entities/user.js";
import { Webhook } from "@/models/entities/webhook.js"; import { Webhook } from "@/models/entities/webhook.js";
import { UserIp } from "@/models/entities/user-ip.js";
import { NoteEdit } from "@/models/entities/note-edit.js";
import { entities as charts } from "@/services/chart/entities.js"; import { entities as charts } from "@/services/chart/entities.js";
import { dbLogger } from "./logger.js"; import { dbLogger } from "./logger.js";

View File

@ -1,5 +1,5 @@
import config from "@/config/index.js";
import Redis from "ioredis"; import Redis from "ioredis";
import config from "@/config/index.js";
export function createConnection() { export function createConnection() {
let source = config.redis; let source = config.redis;

View File

@ -1,8 +1,8 @@
import config from "@/config/index.js";
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
import { intersperse } from "@/prelude/array.js";
import { Window } from "happy-dom"; import { Window } from "happy-dom";
import type * as mfm from "mfm-js"; import type * as mfm from "mfm-js";
import config from "@/config/index.js";
import { intersperse } from "@/prelude/array.js";
import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
export function toHtml( export function toHtml(
nodes: mfm.MfmNode[] | null, nodes: mfm.MfmNode[] | null,

View File

@ -1,6 +1,6 @@
import { subscriber } from "@/db/redis.js";
import type { Antenna } from "@/models/entities/antenna.js";
import { Antennas } from "@/models/index.js"; import { Antennas } from "@/models/index.js";
import type { Antenna } from "@/models/entities/antenna.js";
import { subscriber } from "@/db/redis.js";
let antennasFetched = false; let antennasFetched = false;
let antennas: Antenna[] = []; let antennas: Antenna[] = [];

View File

@ -1,5 +1,7 @@
// https://gist.github.com/nfantone/1eaa803772025df69d07f4dbf5df7e58 // https://gist.github.com/nfantone/1eaa803772025df69d07f4dbf5df7e58
"use strict";
/** /**
* @callback BeforeShutdownListener * @callback BeforeShutdownListener
* @param {string} [signalOrEvent] The exit signal or event name received on the process. * @param {string} [signalOrEvent] The exit signal or event name received on the process.

View File

@ -1,6 +1,6 @@
import { redisClient } from "@/db/redis.js"; import { redisClient } from "@/db/redis.js";
import { encode, decode } from "msgpackr";
import { ChainableCommander } from "ioredis"; import { ChainableCommander } from "ioredis";
import { decode, encode } from "msgpackr";
export class Cache<T> { export class Cache<T> {
private ttl: number; private ttl: number;

View File

@ -1,7 +1,7 @@
import { URLSearchParams } from "node:url";
import config from "@/config/index.js";
import { getAgentByUrl } from "@/misc/fetch.js";
import fetch from "node-fetch"; import fetch from "node-fetch";
import { URLSearchParams } from "node:url";
import { getAgentByUrl } from "@/misc/fetch.js";
import config from "@/config/index.js";
export async function verifyRecaptcha(secret: string, response: string) { export async function verifyRecaptcha(secret: string, response: string) {
const result = await getCaptchaResponse( const result = await getCaptchaResponse(

View File

@ -1,12 +1,12 @@
import * as Acct from "@/misc/acct.js";
import { Cache } from "@/misc/cache.js";
import { getWordHardMute } from "@/misc/check-word-mute.js";
import { getFullApAccount } from "@/misc/convert-host.js";
import type { Packed } from "@/misc/schema.js";
import type { Antenna } from "@/models/entities/antenna.js"; import type { Antenna } from "@/models/entities/antenna.js";
import type { Note } from "@/models/entities/note.js"; import type { Note } from "@/models/entities/note.js";
import type { User } from "@/models/entities/user.js"; import type { User } from "@/models/entities/user.js";
import { Blockings, UserProfiles } from "@/models/index.js"; import { Blockings, UserProfiles } from "@/models/index.js";
import { getFullApAccount } from "@/misc/convert-host.js";
import * as Acct from "@/misc/acct.js";
import type { Packed } from "@/misc/schema.js";
import { Cache } from "@/misc/cache.js";
import { getWordHardMute } from "@/misc/check-word-mute.js";
const blockingCache = new Cache<User["id"][]>("blocking", 60 * 5); const blockingCache = new Cache<User["id"][]>("blocking", 60 * 5);
const mutedWordsCache = new Cache<string[][] | undefined>("mutedWords", 60 * 5); const mutedWordsCache = new Cache<string[][] | undefined>("mutedWords", 60 * 5);

View File

@ -1,5 +1,5 @@
import type { Note } from "@/models/entities/note.js";
import RE2 from "re2"; import RE2 from "re2";
import type { Note } from "@/models/entities/note.js";
type NoteLike = { type NoteLike = {
userId: Note["userId"]; userId: Note["userId"];

View File

@ -1,6 +1,6 @@
import { URL } from "node:url"; import { URL } from "node:url";
import { toASCII } from "punycode";
import config from "@/config/index.js"; import config from "@/config/index.js";
import { toASCII } from "punycode";
export function getFullApAccount(username: string, host: string | null) { export function getFullApAccount(username: string, host: string | null) {
return host return host

View File

@ -1,5 +1,5 @@
import * as mfm from "mfm-js";
import { detect } from "tinyld"; import { detect } from "tinyld";
import * as mfm from "mfm-js";
export default function detectLanguage(text: string): string { export default function detectLanguage(text: string): string {
const nodes = mfm.parse(text); const nodes = mfm.parse(text);

View File

@ -1,13 +1,13 @@
import * as fs from "node:fs"; import * as fs from "node:fs";
import * as stream from "node:stream"; import * as stream from "node:stream";
import * as util from "node:util"; import * as util from "node:util";
import config from "@/config/index.js";
import Logger from "@/services/logger.js";
import chalk from "chalk";
import got, * as Got from "got"; import got, * as Got from "got";
import { httpAgent, httpsAgent, StatusError } from "./fetch.js";
import config from "@/config/index.js";
import chalk from "chalk";
import Logger from "@/services/logger.js";
import IPCIDR from "ip-cidr"; import IPCIDR from "ip-cidr";
import PrivateIp from "private-ip"; import PrivateIp from "private-ip";
import { StatusError, httpAgent, httpsAgent } from "./fetch.js";
const pipeline = util.promisify(stream.pipeline); const pipeline = util.promisify(stream.pipeline);

View File

@ -2,9 +2,9 @@ import probeImageSize from "probe-image-size";
import { Mutex } from "redis-semaphore"; import { Mutex } from "redis-semaphore";
import { FILE_TYPE_BROWSERSAFE } from "@/const.js"; import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
import { redisClient } from "@/db/redis.js";
import Logger from "@/services/logger.js"; import Logger from "@/services/logger.js";
import { Cache } from "./cache.js"; import { Cache } from "./cache.js";
import { redisClient } from "@/db/redis.js";
export type Size = { export type Size = {
width: number; width: number;

View File

@ -1,4 +1,4 @@
import twemoji from "twemoji-parser/dist/lib/regex.js"; import twemoji from "@twemoji/parser/dist/lib/regex.js";
const twemojiRegex = twemoji.default; const twemojiRegex = twemoji.default;
export const emojiRegex = new RegExp(`(${twemojiRegex.source})`); export const emojiRegex = new RegExp(`(${twemojiRegex.source})`);

View File

@ -1,5 +1,5 @@
import { unique } from "@/prelude/array.js";
import * as mfm from "mfm-js"; import * as mfm from "mfm-js";
import { unique } from "@/prelude/array.js";
export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] { export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
const emojiNodes = mfm.extract(nodes, (node) => { const emojiNodes = mfm.extract(nodes, (node) => {

View File

@ -1,5 +1,5 @@
import { unique } from "@/prelude/array.js";
import * as mfm from "mfm-js"; import * as mfm from "mfm-js";
import { unique } from "@/prelude/array.js";
export function extractHashtags(nodes: mfm.MfmNode[]): string[] { export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
const hashtagNodes = mfm.extract(nodes, (node) => node.type === "hashtag"); const hashtagNodes = mfm.extract(nodes, (node) => node.type === "hashtag");

View File

@ -1,6 +1,6 @@
import { fetchMeta } from "./fetch-meta.js";
import type { ILocalUser } from "@/models/entities/user.js"; import type { ILocalUser } from "@/models/entities/user.js";
import { Users } from "@/models/index.js"; import { Users } from "@/models/index.js";
import { fetchMeta } from "./fetch-meta.js";
export async function fetchProxyAccount(): Promise<ILocalUser | null> { export async function fetchProxyAccount(): Promise<ILocalUser | null> {
const meta = await fetchMeta(); const meta = await fetchMeta();

View File

@ -1,10 +1,10 @@
import * as http from "node:http"; import * as http from "node:http";
import * as https from "node:https"; import * as https from "node:https";
import type { URL } from "node:url"; import type { URL } from "node:url";
import config from "@/config/index.js";
import CacheableLookup from "cacheable-lookup"; import CacheableLookup from "cacheable-lookup";
import { HttpProxyAgent, HttpsProxyAgent } from "hpagent";
import fetch from "node-fetch"; import fetch from "node-fetch";
import { HttpProxyAgent, HttpsProxyAgent } from "hpagent";
import config from "@/config/index.js";
export async function getJson( export async function getJson(
url: string, url: string,

View File

@ -1,8 +1,8 @@
import config from "@/config/index.js"; import config from "@/config/index.js";
import { import {
nativeCreateId, nativeCreateId,
nativeGetTimestamp,
nativeInitIdGenerator, nativeInitIdGenerator,
nativeGetTimestamp,
} from "native-utils/built/index.js"; } from "native-utils/built/index.js";
const length = Math.min(Math.max(config.cuid?.length ?? 16, 16), 24); const length = Math.min(Math.max(config.cuid?.length ?? 16, 16), 24);

View File

@ -1,17 +1,17 @@
import * as crypto from "node:crypto";
import * as fs from "node:fs"; import * as fs from "node:fs";
import * as crypto from "node:crypto";
import { join } from "node:path"; import { join } from "node:path";
import * as stream from "node:stream"; import * as stream from "node:stream";
import * as util from "node:util"; import * as util from "node:util";
import { detectSensitive } from "@/services/detect-sensitive.js";
import { encode } from "blurhash";
import { FSWatcher } from "chokidar"; import { FSWatcher } from "chokidar";
import { fileTypeFromFile } from "file-type"; import { fileTypeFromFile } from "file-type";
import probeImageSize from "probe-image-size";
import FFmpeg from "fluent-ffmpeg"; import FFmpeg from "fluent-ffmpeg";
import isSvg from "is-svg"; import isSvg from "is-svg";
import { type predictionType } from "nsfwjs"; import { type predictionType } from "nsfwjs";
import probeImageSize from "probe-image-size";
import sharp from "sharp"; import sharp from "sharp";
import { encode } from "blurhash";
import { detectSensitive } from "@/services/detect-sensitive.js";
import { createTempDir } from "./create-temp.js"; import { createTempDir } from "./create-temp.js";
const pipeline = util.promisify(stream.pipeline); const pipeline = util.promisify(stream.pipeline);

View File

@ -1,6 +1,6 @@
import type { UserKeypair } from "@/models/entities/user-keypair.js";
import type { User } from "@/models/entities/user.js";
import { UserKeypairs } from "@/models/index.js"; import { UserKeypairs } from "@/models/index.js";
import type { User } from "@/models/entities/user.js";
import type { UserKeypair } from "@/models/entities/user-keypair.js";
import { Cache } from "./cache.js"; import { Cache } from "./cache.js";
const cache = new Cache<UserKeypair>("keypairStore", 60 * 30); const cache = new Cache<UserKeypair>("keypairStore", 60 * 30);

View File

@ -1,5 +1,5 @@
import * as argon2 from "argon2";
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
import * as argon2 from "argon2";
export async function hashPassword(password: string): Promise<string> { export async function hashPassword(password: string): Promise<string> {
return argon2.hash(password); return argon2.hash(password);

View File

@ -1,13 +1,13 @@
import config from "@/config/index.js"; import { In, IsNull } from "typeorm";
import { redisClient } from "@/db/redis.js"; import { Emojis } from "@/models/index.js";
import type { Emoji } from "@/models/entities/emoji.js"; import type { Emoji } from "@/models/entities/emoji.js";
import type { Note } from "@/models/entities/note.js"; import type { Note } from "@/models/entities/note.js";
import { Emojis } from "@/models/index.js";
import { query } from "@/prelude/url.js";
import { In, IsNull } from "typeorm";
import { Cache } from "./cache.js"; import { Cache } from "./cache.js";
import { isSelfHost, toPunyNullable } from "./convert-host.js"; import { isSelfHost, toPunyNullable } from "./convert-host.js";
import { decodeReaction } from "./reaction-lib.js"; import { decodeReaction } from "./reaction-lib.js";
import config from "@/config/index.js";
import { query } from "@/prelude/url.js";
import { redisClient } from "@/db/redis.js";
const cache = new Cache<Emoji | null>("populateEmojis", 60 * 60 * 12); const cache = new Cache<Emoji | null>("populateEmojis", 60 * 60 * 12);

View File

@ -1,13 +1,13 @@
import * as fs from "node:fs"; import * as fs from "node:fs";
import * as Path from "node:path";
import { Users } from "@/models/index.js";
import { addFile } from "@/services/drive/add-file.js";
import Logger from "@/services/logger.js"; import Logger from "@/services/logger.js";
import decompress from "decompress";
import gunzip from "gunzip-maybe";
import * as tar from "tar-stream";
import { createTemp, createTempDir } from "./create-temp.js"; import { createTemp, createTempDir } from "./create-temp.js";
import { downloadUrl } from "./download-url.js"; import { downloadUrl } from "./download-url.js";
import { addFile } from "@/services/drive/add-file.js";
import { Users } from "@/models/index.js";
import * as tar from "tar-stream";
import gunzip from "gunzip-maybe";
import decompress from "decompress";
import * as Path from "node:path";
const logger = new Logger("process-masto-notes"); const logger = new Logger("process-masto-notes");

View File

@ -1,8 +1,8 @@
import { Emojis } from "@/models/index.js";
import { IsNull } from "typeorm";
import { toPunyNullable } from "./convert-host.js";
import { emojiRegex } from "./emoji-regex.js"; import { emojiRegex } from "./emoji-regex.js";
import { fetchMeta } from "./fetch-meta.js"; import { fetchMeta } from "./fetch-meta.js";
import { Emojis } from "@/models/index.js";
import { toPunyNullable } from "./convert-host.js";
import { IsNull } from "typeorm";
export function convertReactions(reactions: Record<string, number>) { export function convertReactions(reactions: Record<string, number>) {
const result = new Map(); const result = new Map();

View File

@ -1,36 +1,36 @@
import { packedAntennaSchema } from "@/models/schema/antenna.js";
import { packedAppSchema } from "@/models/schema/app.js";
import { packedBlockingSchema } from "@/models/schema/blocking.js";
import { packedChannelSchema } from "@/models/schema/channel.js";
import { packedClipSchema } from "@/models/schema/clip.js";
import { packedDriveFileSchema } from "@/models/schema/drive-file.js";
import { packedDriveFolderSchema } from "@/models/schema/drive-folder.js";
import { packedEmojiSchema } from "@/models/schema/emoji.js";
import { packedFederationInstanceSchema } from "@/models/schema/federation-instance.js";
import { packedFollowingSchema } from "@/models/schema/following.js";
import { packedGalleryPostSchema } from "@/models/schema/gallery-post.js";
import { packedHashtagSchema } from "@/models/schema/hashtag.js";
import { packedMessagingMessageSchema } from "@/models/schema/messaging-message.js";
import { packedMutingSchema } from "@/models/schema/muting.js";
import { packedNoteEdit } from "@/models/schema/note-edit.js";
import { packedNoteFavoriteSchema } from "@/models/schema/note-favorite.js";
import { packedNoteReactionSchema } from "@/models/schema/note-reaction.js";
import { packedNoteSchema } from "@/models/schema/note.js";
import { packedNotificationSchema } from "@/models/schema/notification.js";
import { packedPageSchema } from "@/models/schema/page.js";
import { packedQueueCountSchema } from "@/models/schema/queue.js";
import { packedRenoteMutingSchema } from "@/models/schema/renote-muting.js";
import { packedUserGroupSchema } from "@/models/schema/user-group.js";
import { packedUserListSchema } from "@/models/schema/user-list.js";
import { import {
packedMeDetailedOnlySchema,
packedMeDetailedSchema,
packedUserDetailedNotMeOnlySchema,
packedUserDetailedNotMeSchema,
packedUserDetailedSchema,
packedUserLiteSchema, packedUserLiteSchema,
packedUserDetailedNotMeOnlySchema,
packedMeDetailedOnlySchema,
packedUserDetailedNotMeSchema,
packedMeDetailedSchema,
packedUserDetailedSchema,
packedUserSchema, packedUserSchema,
} from "@/models/schema/user.js"; } from "@/models/schema/user.js";
import { packedNoteSchema } from "@/models/schema/note.js";
import { packedUserListSchema } from "@/models/schema/user-list.js";
import { packedAppSchema } from "@/models/schema/app.js";
import { packedMessagingMessageSchema } from "@/models/schema/messaging-message.js";
import { packedNotificationSchema } from "@/models/schema/notification.js";
import { packedDriveFileSchema } from "@/models/schema/drive-file.js";
import { packedDriveFolderSchema } from "@/models/schema/drive-folder.js";
import { packedFollowingSchema } from "@/models/schema/following.js";
import { packedMutingSchema } from "@/models/schema/muting.js";
import { packedRenoteMutingSchema } from "@/models/schema/renote-muting.js";
import { packedBlockingSchema } from "@/models/schema/blocking.js";
import { packedNoteReactionSchema } from "@/models/schema/note-reaction.js";
import { packedHashtagSchema } from "@/models/schema/hashtag.js";
import { packedPageSchema } from "@/models/schema/page.js";
import { packedUserGroupSchema } from "@/models/schema/user-group.js";
import { packedNoteFavoriteSchema } from "@/models/schema/note-favorite.js";
import { packedChannelSchema } from "@/models/schema/channel.js";
import { packedAntennaSchema } from "@/models/schema/antenna.js";
import { packedClipSchema } from "@/models/schema/clip.js";
import { packedFederationInstanceSchema } from "@/models/schema/federation-instance.js";
import { packedQueueCountSchema } from "@/models/schema/queue.js";
import { packedGalleryPostSchema } from "@/models/schema/gallery-post.js";
import { packedEmojiSchema } from "@/models/schema/emoji.js";
import { packedNoteEdit } from "@/models/schema/note-edit.js";
export const refs = { export const refs = {
UserLite: packedUserLiteSchema, UserLite: packedUserLiteSchema,

View File

@ -1,6 +1,6 @@
import * as os from "node:os"; import * as os from "node:os";
import type Logger from "@/services/logger.js";
import sysUtils from "systeminformation"; import sysUtils from "systeminformation";
import type Logger from "@/services/logger.js";
export async function showMachineInfo(parentLogger: Logger) { export async function showMachineInfo(parentLogger: Logger) {
const logger = parentLogger.createSubLogger("machine"); const logger = parentLogger.createSubLogger("machine");

View File

@ -1,8 +1,8 @@
import { DAY } from "@/const.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import type { Instance } from "@/models/entities/instance.js";
import { Instances } from "@/models/index.js";
import { Brackets } from "typeorm"; import { Brackets } from "typeorm";
import { fetchMeta } from "@/misc/fetch-meta.js";
import { Instances } from "@/models/index.js";
import type { Instance } from "@/models/entities/instance.js";
import { DAY } from "@/const.js";
import { shouldBlockInstance } from "./should-block-instance.js"; import { shouldBlockInstance } from "./should-block-instance.js";
// Threshold from last contact after which an instance will be considered // Threshold from last contact after which an instance will be considered

View File

@ -1,6 +1,6 @@
import { subscriber } from "@/db/redis.js";
import type { Webhook } from "@/models/entities/webhook.js";
import { Webhooks } from "@/models/index.js"; import { Webhooks } from "@/models/index.js";
import type { Webhook } from "@/models/entities/webhook.js";
import { subscriber } from "@/db/redis.js";
let webhooksFetched = false; let webhooksFetched = false;
let webhooks: Webhook[] = []; let webhooks: Webhook[] = [];

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class AbuseUserReport { export class AbuseUserReport {

View File

@ -1,14 +1,14 @@
import { import {
Column,
Entity, Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryColumn, PrimaryColumn,
Index,
Column,
ManyToOne,
JoinColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { App } from "./app.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { App } from "./app.js";
import { id } from "../id.js";
@Entity() @Entity()
export class AccessToken { export class AccessToken {

View File

@ -1,4 +1,4 @@
import { Column, Entity, Index, PrimaryColumn } from "typeorm"; import { Entity, Index, Column, PrimaryColumn } from "typeorm";
import { id } from "../id.js"; import { id } from "../id.js";
@Entity() @Entity()

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { Announcement } from "./announcement.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { Announcement } from "./announcement.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["userId", "announcementId"], { unique: true }) @Index(["userId", "announcementId"], { unique: true })

View File

@ -1,4 +1,4 @@
import { Column, Entity, Index, PrimaryColumn } from "typeorm"; import { Entity, Index, Column, PrimaryColumn } from "typeorm";
import { id } from "../id.js"; import { id } from "../id.js";
@Entity() @Entity()

View File

@ -1,15 +1,15 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { UserGroupJoining } from "./user-group-joining.js";
import { UserList } from "./user-list.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
import { UserList } from "./user-list.js";
import { UserGroupJoining } from "./user-group-joining.js";
@Entity() @Entity()
export class Antenna { export class Antenna {

View File

@ -1,6 +1,6 @@
import { Column, Entity, Index, ManyToOne, PrimaryColumn } from "typeorm"; import { Entity, PrimaryColumn, Column, Index, ManyToOne } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class App { export class App {

View File

@ -1,13 +1,13 @@
import { import {
Column,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryColumn, PrimaryColumn,
Entity,
JoinColumn,
Column,
ManyToOne,
Index,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class AttestationChallenge { export class AttestationChallenge {

View File

@ -1,14 +1,14 @@
import { import {
Column,
Entity, Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryColumn, PrimaryColumn,
Index,
Column,
ManyToOne,
JoinColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { App } from "./app.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { App } from "./app.js";
import { id } from "../id.js";
@Entity() @Entity()
export class AuthSession { export class AuthSession {

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["blockerId", "blockeeId"], { unique: true }) @Index(["blockerId", "blockeeId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { User } from "./user.js";
import { id } from "../id.js"; import { id } from "../id.js";
import { Channel } from "./channel.js"; import { Channel } from "./channel.js";
import { User } from "./user.js";
@Entity() @Entity()
@Index(["followerId", "followeeId"], { unique: true }) @Index(["followerId", "followeeId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { Channel } from "./channel.js";
import { Note } from "./note.js"; import { Note } from "./note.js";
import { Channel } from "./channel.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["channelId", "noteId"], { unique: true }) @Index(["channelId", "noteId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { User } from "./user.js";
import { id } from "../id.js"; import { id } from "../id.js";
import { DriveFile } from "./drive-file.js"; import { DriveFile } from "./drive-file.js";
import { User } from "./user.js";
@Entity() @Entity()
export class Channel { export class Channel {

View File

@ -1,14 +1,14 @@
import { import {
Column,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn, PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { Clip } from "./clip.js";
import { Note } from "./note.js"; import { Note } from "./note.js";
import { Clip } from "./clip.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["noteId", "clipId"], { unique: true }) @Index(["noteId", "clipId"], { unique: true })

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class Clip { export class Clip {

View File

@ -1,15 +1,15 @@
import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js"; import { id } from "../id.js";
import { DriveFolder } from "./drive-folder.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { DriveFolder } from "./drive-folder.js";
import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
@Entity() @Entity()
@Index(["userId", "folderId", "id"]) @Index(["userId", "folderId", "id"])

View File

@ -1,13 +1,13 @@
import { import {
Column,
Entity,
Index,
JoinColumn, JoinColumn,
ManyToOne, ManyToOne,
Entity,
PrimaryColumn, PrimaryColumn,
Index,
Column,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class DriveFolder { export class DriveFolder {

View File

@ -1,4 +1,4 @@
import { Column, Entity, Index, PrimaryColumn } from "typeorm"; import { PrimaryColumn, Entity, Index, Column } from "typeorm";
import { id } from "../id.js"; import { id } from "../id.js";
@Entity() @Entity()

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["followerId", "followeeId"], { unique: true }) @Index(["followerId", "followeeId"], { unique: true })

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["followerId", "followeeId"], { unique: true }) @Index(["followerId", "followeeId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { User } from "./user.js";
import { id } from "../id.js"; import { id } from "../id.js";
import { GalleryPost } from "./gallery-post.js"; import { GalleryPost } from "./gallery-post.js";
import { User } from "./user.js";
@Entity() @Entity()
@Index(["userId", "postId"], { unique: true }) @Index(["userId", "postId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
ManyToOne, Column,
PrimaryColumn, PrimaryColumn,
ManyToOne,
} from "typeorm"; } from "typeorm";
import { User } from "./user.js";
import { id } from "../id.js"; import { id } from "../id.js";
import type { DriveFile } from "./drive-file.js"; import type { DriveFile } from "./drive-file.js";
import { User } from "./user.js";
@Entity() @Entity()
export class GalleryPost { export class GalleryPost {

View File

@ -1,6 +1,6 @@
import { Column, Entity, Index, PrimaryColumn } from "typeorm"; import { Entity, PrimaryColumn, Index, Column } from "typeorm";
import { id } from "../id.js";
import type { User } from "./user.js"; import type { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class Hashtag { export class Hashtag {

View File

@ -1,4 +1,4 @@
import { Column, Entity, Index, PrimaryColumn } from "typeorm"; import { Entity, PrimaryColumn, Index, Column } from "typeorm";
import { id } from "../id.js"; import { id } from "../id.js";
@Entity() @Entity()

View File

@ -1,15 +1,15 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { DriveFile } from "./drive-file.js";
import { UserGroup } from "./user-group.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { DriveFile } from "./drive-file.js";
import { id } from "../id.js";
import { UserGroup } from "./user-group.js";
@Entity() @Entity()
export class MessagingMessage { export class MessagingMessage {

View File

@ -1,7 +1,7 @@
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; import { Entity, Column, PrimaryColumn, ManyToOne, JoinColumn } from "typeorm";
import { id } from "../id.js"; import { id } from "../id.js";
import type { Clip } from "./clip.js";
import { User } from "./user.js"; import { User } from "./user.js";
import type { Clip } from "./clip.js";
@Entity() @Entity()
export class Meta { export class Meta {

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
export class ModerationLog { export class ModerationLog {

View File

@ -1,15 +1,15 @@
import { import {
Column,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn, PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { mutedNoteReasons } from "../../types.js";
import { id } from "../id.js";
import { Note } from "./note.js"; import { Note } from "./note.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
import { mutedNoteReasons } from "../../types.js";
@Entity() @Entity()
@Index(["noteId", "userId"], { unique: true }) @Index(["noteId", "userId"], { unique: true })

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["muterId", "muteeId"], { unique: true }) @Index(["muterId", "muteeId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column,
Entity, Entity,
Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn, PrimaryColumn,
Index,
} from "typeorm"; } from "typeorm";
import { Note } from "./note.js";
import { id } from "../id.js"; import { id } from "../id.js";
import { DriveFile } from "./drive-file.js"; import { DriveFile } from "./drive-file.js";
import { Note } from "./note.js";
@Entity() @Entity()
export class NoteEdit { export class NoteEdit {

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { Note } from "./note.js"; import { Note } from "./note.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["userId", "noteId"], { unique: true }) @Index(["userId", "noteId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { Note } from "./note.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { Note } from "./note.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["userId", "noteId"], { unique: true }) @Index(["userId", "noteId"], { unique: true })

View File

@ -1,13 +1,13 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["userId", "threadId"], { unique: true }) @Index(["userId", "threadId"], { unique: true })

View File

@ -1,15 +1,15 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { User } from "./user.js";
import { Note } from "./note.js";
import { id } from "../id.js"; import { id } from "../id.js";
import type { Channel } from "./channel.js"; import type { Channel } from "./channel.js";
import { Note } from "./note.js";
import { User } from "./user.js";
@Entity() @Entity()
@Index(["userId", "noteId"], { unique: true }) @Index(["userId", "noteId"], { unique: true })

View File

@ -1,14 +1,14 @@
import { import {
Column, PrimaryColumn,
Entity, Entity,
Index, Index,
JoinColumn, JoinColumn,
Column,
ManyToOne, ManyToOne,
PrimaryColumn,
} from "typeorm"; } from "typeorm";
import { id } from "../id.js";
import { Note } from "./note.js";
import { User } from "./user.js"; import { User } from "./user.js";
import { Note } from "./note.js";
import { id } from "../id.js";
@Entity() @Entity()
@Index(["userId", "noteId"], { unique: true }) @Index(["userId", "noteId"], { unique: true })

Some files were not shown because too many files have changed in this diff Show More