diff --git a/.config/ci.yml b/.config/ci.yml index 8730ccab3a..c48fca49bf 100644 --- a/.config/ci.yml +++ b/.config/ci.yml @@ -6,7 +6,7 @@ #───┘ URL └───────────────────────────────────────────────────── # Final accessible URL seen by a user. -url: http://misskey.local +url: https://example.tld/ # ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE # URL SETTINGS AFTER THAT! @@ -106,7 +106,7 @@ redis: # ┌───────────────────────────┐ #───┘ MeiliSearch configuration └───────────────────────────── -# You can set scope to local (default value) or global +# You can set scope to local (default value) or global # (include notes from remote). #meilisearch: @@ -167,18 +167,8 @@ id: 'aidx' # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 -# Amount of characters that can be used when writing notes. Longer notes will be rejected. (minimum: 1) -#maxNoteLength: 3000 -# Amount of characters that will be saved for remote notes. Longer notes will be truncated to this length. (minimum: 1) -#maxRemoteNoteLength: 100000 -# Amount of characters that can be used when writing content warnings. Longer warnings will be rejected. (minimum: 1) -#maxCwLength: 500 -# Amount of characters that will be saved for remote content warnings. Longer warnings will be truncated to this length. (minimum: 1) -#maxRemoteCwLength: 5000 -# Amount of characters that can be used when writing media descriptions (alt text). Longer descriptions will be rejected. (minimum: 1) -#maxAltTextLength: 20000 -# Amount of characters that will be saved for remote media descriptions (alt text). Longer descriptions will be truncated to this length. (minimum: 1) -#maxRemoteAltTextLength: 100000 +# Amount of characters that can be used when writing notes (maximum: 8192, minimum: 1) +maxNoteLength: 3000 # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 @@ -208,18 +198,13 @@ proxyRemoteFiles: true # https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4 #videoThumbnailGenerator: https://example.com -# Sign outgoing ActivityPub GET request (default: true) +# Sign to ActivityPub GET request (default: true) signToActivityPubGet: true -# Sign outgoing ActivityPub Activities (default: true) -# Linked Data signatures are cryptographic signatures attached to each activity to provide proof of authenticity. -# When using authorized fetch, this is often undesired as any signed activity can be forwarded to a blocked instance by relays and other instances. -# This setting allows admins to disable LD signatures for increased privacy, at the expense of fewer relayed activities and additional inbound fetch (GET) requests. -attachLdSignatureForRelays: true # check that inbound ActivityPub GET requests are signed ("authorized fetch") checkActivityPubGetSignature: false # For security reasons, uploading attachments from the intranet is prohibited, -# but exceptions can be made from the following settings. Default value is "undefined". +# but exceptions can be made from the following settings. Default value is "undefined". # Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)). #allowedPrivateNetworks: [ # '127.0.0.1/32' @@ -229,8 +214,3 @@ checkActivityPubGetSignature: false # Upload or download file size limits (bytes) #maxFileSize: 262144000 - -# CHMod-style permission bits to apply to uploaded files. -# Permission bits are specified as a base-8 string representing User/Group/Other permissions. -# This setting is only useful for custom deployments, such as using a reverse proxy to serve media. -#filePermissionBits: '644' diff --git a/.config/cypress-devcontainer.yml b/.config/cypress-devcontainer.yml deleted file mode 100644 index 342b0f43da..0000000000 --- a/.config/cypress-devcontainer.yml +++ /dev/null @@ -1,229 +0,0 @@ -#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -# Misskey configuration -#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -# ┌─────┐ -#───┘ URL └───────────────────────────────────────────────────── - -# Final accessible URL seen by a user. -url: 'http://misskey.local' - -# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE -# URL SETTINGS AFTER THAT! - -# ┌───────────────────────┐ -#───┘ Port and TLS settings └─────────────────────────────────── - -# -# Misskey requires a reverse proxy to support HTTPS connections. -# -# +----- https://example.tld/ ------------+ -# +------+ |+-------------+ +----------------+| -# | User | ---> || Proxy (443) | ---> | Misskey (3000) || -# +------+ |+-------------+ +----------------+| -# +---------------------------------------+ -# -# You need to set up a reverse proxy. (e.g. nginx) -# An encrypted connection with HTTPS is highly recommended -# because tokens may be transferred in GET requests. - -# The port that your Misskey server should listen on. -port: 61812 - -# ┌──────────────────────────┐ -#───┘ PostgreSQL configuration └──────────────────────────────── - -db: - host: db - port: 5432 - - # Database name - db: misskey - - # Auth - user: postgres - pass: postgres - - # Whether disable Caching queries - #disableCache: true - - # Extra Connection options - #extra: - # ssl: true - -dbReplications: false - -# You can configure any number of replicas here -#dbSlaves: -# - -# host: -# port: -# db: -# user: -# pass: -# - -# host: -# port: -# db: -# user: -# pass: - -# ┌─────────────────────┐ -#───┘ Redis configuration └───────────────────────────────────── - -redis: - host: redis - port: 6379 - #family: 0 # 0=Both, 4=IPv4, 6=IPv6 - #pass: example-pass - #prefix: example-prefix - #db: 1 - -#redisForPubsub: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - -#redisForJobQueue: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - -#redisForTimelines: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - -#redisForReactions: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - -# ┌───────────────────────────┐ -#───┘ MeiliSearch configuration └───────────────────────────── - -#meilisearch: -# host: meilisearch -# port: 7700 -# apiKey: '' -# ssl: true -# index: '' - -# ┌───────────────┐ -#───┘ ID generation └─────────────────────────────────────────── - -# You can select the ID generation method. -# You don't usually need to change this setting, but you can -# change it according to your preferences. - -# Available methods: -# aid ... Short, Millisecond accuracy -# aidx ... Millisecond accuracy -# meid ... Similar to ObjectID, Millisecond accuracy -# ulid ... Millisecond accuracy -# objectid ... This is left for backward compatibility - -# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE -# ID SETTINGS AFTER THAT! - -id: 'aidx' - -# ┌────────────────┐ -#───┘ Error tracking └────────────────────────────────────────── - -# Sentry is available for error tracking. -# See the Sentry documentation for more details on options. - -#sentryForBackend: -# enableNodeProfiling: true -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - -#sentryForFrontend: -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - -# ┌─────────────────────┐ -#───┘ Other configuration └───────────────────────────────────── - -# Whether disable HSTS -#disableHsts: true - -# Number of worker processes -#clusterLimit: 1 - -# Job concurrency per worker -# deliverJobConcurrency: 128 -# inboxJobConcurrency: 16 - -# Job rate limiter -# deliverJobPerSec: 128 -# inboxJobPerSec: 32 - -# Job attempts -# deliverJobMaxAttempts: 12 -# inboxJobMaxAttempts: 8 - -# IP address family used for outgoing request (ipv4, ipv6 or dual) -#outgoingAddressFamily: ipv4 - -# Amount of characters that can be used when writing notes. Longer notes will be rejected. (minimum: 1) -#maxNoteLength: 3000 -# Amount of characters that will be saved for remote notes. Longer notes will be truncated to this length. (minimum: 1) -#maxRemoteNoteLength: 100000 -# Amount of characters that can be used when writing content warnings. Longer warnings will be rejected. (minimum: 1) -#maxCwLength: 500 -# Amount of characters that will be saved for remote content warnings. Longer warnings will be truncated to this length. (minimum: 1) -#maxRemoteCwLength: 5000 -# Amount of characters that can be used when writing media descriptions (alt text). Longer descriptions will be rejected. (minimum: 1) -#maxAltTextLength: 20000 -# Amount of characters that will be saved for remote media descriptions (alt text). Longer descriptions will be truncated to this length. (minimum: 1) -#maxRemoteAltTextLength: 100000 - -# Proxy for HTTP/HTTPS -#proxy: http://127.0.0.1:3128 - -proxyBypassHosts: - - api.deepl.com - - api-free.deepl.com - - www.recaptcha.net - - hcaptcha.com - - challenges.cloudflare.com - -# Proxy for SMTP/SMTPS -#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT -#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4 -#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5 - -# Media Proxy -#mediaProxy: https://example.com/proxy - -# Proxy remote files (default: true) -proxyRemoteFiles: true - -# Sign to ActivityPub GET request (default: true) -signToActivityPubGet: true - -allowedPrivateNetworks: [ - '127.0.0.1/32' -] - -# Upload or download file size limits (bytes) -#maxFileSize: 262144000 - -# CHMod-style permission bits to apply to uploaded files. -# Permission bits are specified as a base-8 string representing User/Group/Other permissions. -# This setting is only useful for custom deployments, such as using a reverse proxy to serve media. -#filePermissionBits: '644' diff --git a/.config/docker_example.env b/.config/docker_example.env index c61248da2e..4fe8e76b78 100644 --- a/.config/docker_example.env +++ b/.config/docker_example.env @@ -1,11 +1,5 @@ -# misskey settings -# MISSKEY_URL=https://example.tld/ - # db settings POSTGRES_PASSWORD=example-misskey-pass -# DATABASE_PASSWORD=${POSTGRES_PASSWORD} POSTGRES_USER=example-misskey-user -# DATABASE_USER=${POSTGRES_USER} POSTGRES_DB=misskey -# DATABASE_DB=${POSTGRES_DB} DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}" diff --git a/.config/docker_example.yml b/.config/docker_example.yml index ce2daf3aec..296237c95d 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -63,7 +63,6 @@ #───┘ URL └───────────────────────────────────────────────────── # Final accessible URL seen by a user. -# You can set url from an environment variable instead. url: https://example.tld/ # ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE @@ -96,11 +95,9 @@ db: port: 5432 # Database name - # You can set db from an environment variable instead. db: misskey # Auth - # You can set user and pass from environment variables instead. user: example-misskey-user pass: example-misskey-pass @@ -163,18 +160,10 @@ redis: # #prefix: example-prefix # #db: 1 -#redisForReactions: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - # ┌───────────────────────────┐ #───┘ MeiliSearch configuration └───────────────────────────── -# You can set scope to local (default value) or global +# You can set scope to local (default value) or global # (include notes from remote). #meilisearch: @@ -204,21 +193,6 @@ redis: id: 'aidx' -# ┌────────────────┐ -#───┘ Error tracking └────────────────────────────────────────── - -# Sentry is available for error tracking. -# See the Sentry documentation for more details on options. - -#sentryForBackend: -# enableNodeProfiling: true -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - -#sentryForFrontend: -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - # ┌─────────────────────┐ #───┘ Other configuration └───────────────────────────────────── @@ -250,18 +224,8 @@ id: 'aidx' # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 -# Amount of characters that can be used when writing notes. Longer notes will be rejected. (minimum: 1) -#maxNoteLength: 3000 -# Amount of characters that will be saved for remote notes. Longer notes will be truncated to this length. (minimum: 1) -#maxRemoteNoteLength: 100000 -# Amount of characters that can be used when writing content warnings. Longer warnings will be rejected. (minimum: 1) -#maxCwLength: 500 -# Amount of characters that will be saved for remote content warnings. Longer warnings will be truncated to this length. (minimum: 1) -#maxRemoteCwLength: 5000 -# Amount of characters that can be used when writing media descriptions (alt text). Longer descriptions will be rejected. (minimum: 1) -#maxAltTextLength: 20000 -# Amount of characters that will be saved for remote media descriptions (alt text). Longer descriptions will be truncated to this length. (minimum: 1) -#maxRemoteAltTextLength: 100000 +# Amount of characters that can be used when writing notes (maximum: 8192, minimum: 1) +maxNoteLength: 3000 # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 @@ -291,18 +255,13 @@ proxyRemoteFiles: true # https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4 #videoThumbnailGenerator: https://example.com -# Sign outgoing ActivityPub GET request (default: true) +# Sign to ActivityPub GET request (default: true) signToActivityPubGet: true -# Sign outgoing ActivityPub Activities (default: true) -# Linked Data signatures are cryptographic signatures attached to each activity to provide proof of authenticity. -# When using authorized fetch, this is often undesired as any signed activity can be forwarded to a blocked instance by relays and other instances. -# This setting allows admins to disable LD signatures for increased privacy, at the expense of fewer relayed activities and additional inbound fetch (GET) requests. -attachLdSignatureForRelays: true # check that inbound ActivityPub GET requests are signed ("authorized fetch") checkActivityPubGetSignature: false # For security reasons, uploading attachments from the intranet is prohibited, -# but exceptions can be made from the following settings. Default value is "undefined". +# but exceptions can be made from the following settings. Default value is "undefined". # Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)). #allowedPrivateNetworks: [ # '127.0.0.1/32' @@ -312,8 +271,3 @@ checkActivityPubGetSignature: false # Upload or download file size limits (bytes) #maxFileSize: 262144000 - -# CHMod-style permission bits to apply to uploaded files. -# Permission bits are specified as a base-8 string representing User/Group/Other permissions. -# This setting is only useful for custom deployments, such as using a reverse proxy to serve media. -#filePermissionBits: '644' diff --git a/.config/example.yml b/.config/example.yml index 9debb3bf70..c037a280b6 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -38,7 +38,7 @@ # Option 3: If neither of the above applies to you. # (In this case, the source code should be published # on the Misskey interface. IT IS NOT ENOUGH TO -# DISCLOSE THE SOURCE CODE WHEN A USER REQUESTS IT BY +# DISCLOSE THE SOURCE CODE WEHN A USER REQUESTS IT BY # E-MAIL OR OTHER MEANS. If you are not satisfied # with this, it is recommended that you read the # license again carefully. Anyway, enabling this @@ -99,10 +99,10 @@ db: port: 5432 # Database name - db: sharkey + db: misskey # Auth - user: sharkey + user: example-misskey-user pass: example-misskey-pass # Whether disable Caching queries @@ -172,16 +172,6 @@ redis: # # You can specify more ioredis options... # #username: example-username -#redisForReactions: -# host: localhost -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 -# # You can specify more ioredis options... -# #username: example-username - # ┌───────────────────────────┐ #───┘ MeiliSearch configuration └───────────────────────────── @@ -215,21 +205,6 @@ redis: id: 'aidx' -# ┌────────────────┐ -#───┘ Error tracking └────────────────────────────────────────── - -# Sentry is available for error tracking. -# See the Sentry documentation for more details on options. - -#sentryForBackend: -# enableNodeProfiling: true -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - -#sentryForFrontend: -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - # ┌─────────────────────┐ #───┘ Other configuration └───────────────────────────────────── @@ -261,18 +236,8 @@ id: 'aidx' # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 -# Amount of characters that can be used when writing notes. Longer notes will be rejected. (minimum: 1) -#maxNoteLength: 3000 -# Amount of characters that will be saved for remote notes. Longer notes will be truncated to this length. (minimum: 1) -#maxRemoteNoteLength: 100000 -# Amount of characters that can be used when writing content warnings. Longer warnings will be rejected. (minimum: 1) -#maxCwLength: 500 -# Amount of characters that will be saved for remote content warnings. Longer warnings will be truncated to this length. (minimum: 1) -#maxRemoteCwLength: 5000 -# Amount of characters that can be used when writing media descriptions (alt text). Longer descriptions will be rejected. (minimum: 1) -#maxAltTextLength: 20000 -# Amount of characters that will be saved for remote media descriptions (alt text). Longer descriptions will be truncated to this length. (minimum: 1) -#maxRemoteAltTextLength: 100000 +# Amount of characters that can be used when writing notes (maximum: 8192, minimum: 1) +maxNoteLength: 3000 # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 @@ -305,13 +270,8 @@ proxyRemoteFiles: true # https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4 #videoThumbnailGenerator: https://example.com -# Sign outgoing ActivityPub GET request (default: true) +# Sign to ActivityPub GET request (default: true) signToActivityPubGet: true -# Sign outgoing ActivityPub Activities (default: true) -# Linked Data signatures are cryptographic signatures attached to each activity to provide proof of authenticity. -# When using authorized fetch, this is often undesired as any signed activity can be forwarded to a blocked instance by relays and other instances. -# This setting allows admins to disable LD signatures for increased privacy, at the expense of fewer relayed activities and additional inbound fetch (GET) requests. -attachLdSignatureForRelays: true # check that inbound ActivityPub GET requests are signed ("authorized fetch") checkActivityPubGetSignature: false @@ -327,15 +287,5 @@ checkActivityPubGetSignature: false # Upload or download file size limits (bytes) #maxFileSize: 262144000 -# timeout and maximum size for imports (e.g. note imports) -#import: -# downloadTimeout: 30 -# maxFileSize: 262144000 - # PID File of master process #pidFile: /tmp/misskey.pid - -# CHMod-style permission bits to apply to uploaded files. -# Permission bits are specified as a base-8 string representing User/Group/Other permissions. -# This setting is only useful for custom deployments, such as using a reverse proxy to serve media. -#filePermissionBits: '644' diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fbf959d449..e409adf644 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,22 +1,25 @@ { "name": "Misskey", - "dockerComposeFile": "compose.yml", + "dockerComposeFile": "docker-compose.yml", "service": "app", "workspaceFolder": "/workspace", "features": { - "ghcr.io/devcontainers/features/node:1": { - "version": "20.16.0" + "ghcr.io/devcontainers-contrib/features/pnpm:2": { + "version": "8.9.2" }, - "ghcr.io/devcontainers-contrib/features/corepack:1": {} + "ghcr.io/devcontainers/features/node:1": { + "version": "20.10.0" + } }, "forwardPorts": [3000], - "postCreateCommand": "/bin/bash .devcontainer/init.sh", + "postCreateCommand": "sudo chmod 755 .devcontainer/init.sh && .devcontainer/init.sh", "customizations": { "vscode": { "extensions": [ "editorconfig.editorconfig", "dbaeumer.vscode-eslint", "Vue.volar", + "Vue.vscode-typescript-vue-plugin", "Orta.vscode-jest", "dbaeumer.vscode-eslint", "mrmlnc.vscode-json5" diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index 3eb4fc2879..7ea0929469 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -103,14 +103,6 @@ redis: # #prefix: example-prefix # #db: 1 -#redisForReactions: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - # ┌───────────────────────────┐ #───┘ MeiliSearch configuration └───────────────────────────── @@ -140,21 +132,6 @@ redis: id: 'aidx' -# ┌────────────────┐ -#───┘ Error tracking └────────────────────────────────────────── - -# Sentry is available for error tracking. -# See the Sentry documentation for more details on options. - -#sentryForBackend: -# enableNodeProfiling: true -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - -#sentryForFrontend: -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - # ┌─────────────────────┐ #───┘ Other configuration └───────────────────────────────────── diff --git a/.devcontainer/compose.yml b/.devcontainer/docker-compose.yml similarity index 93% rename from .devcontainer/compose.yml rename to .devcontainer/docker-compose.yml index d02d2a8f4a..2809cd2ca4 100644 --- a/.devcontainer/compose.yml +++ b/.devcontainer/docker-compose.yml @@ -1,3 +1,5 @@ +version: '3.8' + services: app: build: @@ -6,7 +8,6 @@ services: volumes: - ../:/workspace:cached - - node_modules:/workspace/node_modules command: sleep infinity @@ -45,7 +46,6 @@ services: volumes: postgres-data: redis-data: - node_modules: networks: internal_network: diff --git a/.devcontainer/init.sh b/.devcontainer/init.sh index e02a533c15..bcad3e6d85 100755 --- a/.devcontainer/init.sh +++ b/.devcontainer/init.sh @@ -2,16 +2,10 @@ set -xe -sudo chown node node_modules -sudo apt-get update -sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb -git config --global --add safe.directory /workspace +sudo chown -R node /workspace git submodule update --init -corepack install -corepack enable pnpm config set store-dir /home/node/.local/share/pnpm/store pnpm install --frozen-lockfile cp .devcontainer/devcontainer.yml .config/default.yml pnpm build pnpm migrate -pnpm exec cypress install diff --git a/.dockerignore b/.dockerignore index f204349160..1de0c7982b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,11 +7,12 @@ Dockerfile build/ built/ db/ -.devcontainer/compose.yml +docker-compose.yml node_modules/ packages/*/node_modules redis/ files/ +misskey-assets/ fluent-emojis/ .pnp.* @@ -27,4 +28,4 @@ fluent-emojis/ .idea/ packages/*/.vscode/ -packages/backend/test/compose.yml +packages/backend/test/docker-compose.yml diff --git a/.gitignore b/.gitignore index 7cc7354a4a..2b6a5c1ebf 100644 --- a/.gitignore +++ b/.gitignore @@ -23,9 +23,6 @@ packages/sw/.yarn/cache # pnpm .pnpm-store -# eslint -**/.eslintcache - # Cypress cypress/screenshots cypress/videos @@ -38,17 +35,13 @@ coverage !/.config/example.yml !/.config/docker_example.yml !/.config/docker_example.env -!/.config/cypress-devcontainer.yml docker-compose.yml -compose.yml -.devcontainer/compose.yml -!/.devcontainer/compose.yml +!/.devcontainer/docker-compose.yml # misskey /build built built-test -js-built /data /.cache-loader /db @@ -66,11 +59,9 @@ ormconfig.json temp /packages/frontend/src/**/*.stories.ts tsdoc-metadata.json -misskey-assets -# Vite temporary files -vite.config.js.timestamp-* -vite.config.ts.timestamp-* +# Sharkey +/packages/megalodon/lib # blender backups *.blend1 @@ -81,6 +72,3 @@ vite.config.ts.timestamp-* # VSCode addon .favorites.json - -# Sharkey -/packages/megalodon/lib diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4db8bda32e..be00aa7097 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,25 +4,21 @@ stages: testCommit: stage: test - image: node:iron + image: node:latest services: - postgres:15 - redis variables: POSTGRES_PASSWORD: ci script: - - apt-get update && apt-get install -y git wget curl build-essential python3 ffmpeg + - apt-get update && apt-get install -y git wget curl build-essential python3 - cp .config/ci.yml .config/default.yml - - cp .config/ci.yml .config/test.yml - corepack enable - corepack prepare pnpm@latest --activate - git submodule update --init - pnpm install --frozen-lockfile - pnpm run build - pnpm run migrate - - pnpm run --filter='!megalodon' test - - pnpm run --filter=backend --filter=misskey-js lint - - pnpm run --filter=frontend --filter=frontend-embed eslint cache: key: test policy: pull-push diff --git a/.gitlab/issue_templates/bug.md b/.gitlab/issue_templates/bug.md index a909067269..6914647570 100644 --- a/.gitlab/issue_templates/bug.md +++ b/.gitlab/issue_templates/bug.md @@ -3,33 +3,27 @@ 🔒 Found a security vulnerability? [Please disclose it responsibly.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/SECURITY.md) 🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) --> -# **What happened?** - +**What happened?** _(Please give us a brief description of what happened.)_ -# **What did you expect to happen?** - +**What did you expect to happen?** _(Please give us a brief description of what you expected to happen.)_ -# **Version** - +**Version** _(What version of Sharkey is your instance running? You can find this by clicking your instance's logo at the top left and then clicking instance information.)_ -# **Instance** - +**Instance** _(What instance of Sharkey are you using?)_ -# **What type of issue is this?** - +**What type of issue is this?** _(If this happens on your device and has to do with the user interface, it's client-side. If this happens on either with the API or the backend, or you got a server-side error in the client, it's server-side.)_ -# **What browser are you using? (Client-side issues only)** +**What browser are you using? (Client-side issues only)** -# **What operating system are you using? (Client-side issues only)** +**What operating system are you using? (Client-side issues only)** -# **How do you deploy Sharkey on your server? (Server-side issues only)** +**How do you deploy Sharkey on your server? (Server-side issues only)** -# **What operating system are you using? (Server-side issues only)** +**What operating system are you using? (Server-side issues only)** -# **Relevant log output** - +**Relevant log output** _(Please copy and paste any relevant log output. You can find your log by inspecting the page, and going to the "console" tab. This will be automatically formatted into code, so no need for backticks.)_ -# **Contribution Guidelines** +**Contribution Guidelines** By submitting this issue, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) - [ ] I agree to follow this project's Contribution Guidelines - [ ] I have searched the issue tracker for similar issues, and this is not a duplicate. diff --git a/.gitlab/issue_templates/feature.md b/.gitlab/issue_templates/feature.md index a77f9335fe..d4235eb5a3 100644 --- a/.gitlab/issue_templates/feature.md +++ b/.gitlab/issue_templates/feature.md @@ -3,19 +3,15 @@ 🔒 Found a security vulnerability? [Please disclose it responsibly.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/SECURITY.md) 🤝 By submitting this feature request, you agree to follow our [Contribution Guidelines.](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) --> -# **What feature would you like implemented?** - +**What feature would you like implemented?** _(Please give us a brief description of what you'd like.)_ -# **Why should we add this feature?** - +**Why should we add this feature?** _(Please give us a brief description of why your feature is important.)_ -# **Version** - +**Version** _(What version of Sharkey is your instance running? You can find this by clicking your instance's logo at the top left and then clicking instance information.)_ -# **Instance** - +**Instance** _(What instance of Sharkey are you using?)_ -# **Contribution Guidelines** +**Contribution Guidelines** By submitting this issue, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) - [ ] I agree to follow this project's Contribution Guidelines - [ ] I have searched the issue tracker for similar requests, and this is not a duplicate. diff --git a/.gitlab/merge_request_templates/default.md b/.gitlab/merge_request_templates/default.md index e6977def70..18bffa5419 100644 --- a/.gitlab/merge_request_templates/default.md +++ b/.gitlab/merge_request_templates/default.md @@ -1,12 +1,11 @@ -# **What does this MR do?** - +**What does this PR do?** _(Please give us a brief description of what this PR does.)_ -# **Contribution Guidelines** +**Contribution Guidelines** By submitting this merge request, you agree to follow our [Contribution Guidelines](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/CONTRIBUTING.md) - [ ] I agree to follow this project's Contribution Guidelines -- [ ] I have made sure to test this merge request +- [ ] I have made sure to test this pull request diff --git a/.gitmodules b/.gitmodules index 1a68b48180..a3ca76cc96 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ +[submodule "misskey-assets"] + path = misskey-assets + url = https://github.com/misskey-dev/assets.git [submodule "fluent-emojis"] path = fluent-emojis url = https://github.com/misskey-dev/emojis.git diff --git a/.node-version b/.node-version index 8ce7030825..d5a159609d 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -20.16.0 +20.10.0 diff --git a/.old/workflows/lint.yml b/.old/workflows/lint.yml new file mode 100644 index 0000000000..8ad19b45c8 --- /dev/null +++ b/.old/workflows/lint.yml @@ -0,0 +1,95 @@ +name: Lint + +on: + push: + branches: + - stable + - develop + paths: + - packages/** + pull_request: + paths: + - packages/backend/** + - packages/frontend/** + - packages/sw/** + - packages/misskey-js/** + - packages/shared/.eslintrc.js + +jobs: + pnpm_install: + runs-on: docker + steps: + - uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + submodules: true + - uses: https://github.com/pnpm/action-setup@v2 + with: + version: 8 + run_install: false + - uses: https://code.forgejo.org/actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + - run: corepack enable + - run: pnpm i --frozen-lockfile + + lint: + needs: [pnpm_install] + runs-on: docker + continue-on-error: true + strategy: + matrix: + workspace: + - backend + - frontend + - sw + - misskey-js + steps: + - uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + submodules: true + - uses: https://github.com/pnpm/action-setup@v2 + with: + version: 7 + run_install: false + - uses: https://code.forgejo.org/actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + - run: corepack enable + - run: pnpm i --frozen-lockfile + - run: pnpm --filter ${{ matrix.workspace }} run eslint + + typecheck: + needs: [pnpm_install] + runs-on: docker + continue-on-error: true + strategy: + matrix: + workspace: + - backend + - misskey-js + steps: + - uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + submodules: true + - uses: https://github.com/pnpm/action-setup@v2 + with: + version: 7 + run_install: false + - uses: https://code.forgejo.org/actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + - run: corepack enable + - run: pnpm i --frozen-lockfile + - run: pnpm --filter misskey-js run build + if: ${{ matrix.workspace == 'backend' }} + - run: pnpm --filter misskey-reversi run build:tsc + if: ${{ matrix.workspace == 'backend' }} + - run: pnpm --filter misskey-bubble-game run build + if: ${{ matrix.workspace == 'backend' }} + - run: pnpm --filter ${{ matrix.workspace }} run typecheck diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3cdf81e339..baca8db246 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,7 +3,9 @@ "editorconfig.editorconfig", "dbaeumer.vscode-eslint", "Vue.volar", + "Vue.vscode-typescript-vue-plugin", "Orta.vscode-jest", + "dbaeumer.vscode-eslint", "mrmlnc.vscode-json5" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 0ceec23acd..e2a82b1ffe 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ "*.test.ts": "typescript" }, "jest.jestCommandLine": "pnpm run jest", - "jest.runMode": "on-demand", + "jest.autoRun": "off", "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, diff --git a/CHANGELOG.md b/CHANGELOG.md index cf0437e51a..bafee277d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,325 +1,16 @@ -## 2024.9.0 + ## 2024.3.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2e48ec61d..50f323fab0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,12 +11,10 @@ Before creating an issue, please check the following: - Issues should only be used to feature requests, suggestions, and bug tracking. - Please ask questions or troubleshooting in [Discord](https://discord.gg/6VgKmEqHNk). -> [!WARNING] +> **Warning** > Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged. -### Recommended discussing before implementation -We welcome your proposal. - +## Before implementation When you want to add a feature or fix a bug, *please open an issue*, don't just start writing code. We may suggest different approaches, or show that the "bug" is actually intended behaviour (and offer @@ -27,20 +25,7 @@ Misskey. Each of these examples have actually happened! On the other hand, it's very likely that we'll tell you "go ahead!". We try our best to incorporate improvements from our users! -Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask Committer to assign you). -By expressing your intention to work on the Issue, you can prevent conflicts in the work. - -To the Committers: you should not assign someone on it before the Final Decision. - -### How issues are triaged - -The Committers may: -* close an issue that is not reproducible on latest stable release, -* merge an issue into another issue, -* split an issue into multiple issues, -* or re-open that has been closed for some reason which is not applicable anymore. - -@syuilo reserves the Final Decision rights including whether the project will implement feature and how to implement, these rights are not always exercised. +Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work. ## Well-known branches - **`stable`** branch is tracking the latest release and used for production purposes. @@ -50,14 +35,14 @@ The Committers may: ## Creating a PR Thank you for your PR! Before creating a PR, please check the following: - If possible, prefix the title with a keyword that identifies the type of this PR, as shown below. - - `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc - - Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR. + - `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc + - Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR. - If there is an Issue which will be resolved by this PR, please include a reference to the Issue in the text. - Please add the summary of the changes to [`CHANGELOG.md`](CHANGELOG.md). However, this is not necessary for changes that do not affect the users, such as refactoring. - Check if there are any documents that need to be created or updated due to this change. - If you have added a feature or fixed a bug, please add a test case if possible. - Please make sure that tests and Lint are passed in advance. - - You can run it with `pnpm test` and `pnpm lint`. [See more info](#testing) + - You can run it with `pnpm test` and `pnpm lint`. [See more info](#testing) - If this PR includes UI changes, please attach a screenshot in the text. Thanks for your cooperation 🤗 @@ -67,8 +52,8 @@ Be willing to comment on the good points and not just the things you want fixed ### Review perspective - Scope - - Are the goals of the PR clear? - - Is the granularity of the PR appropriate? + - Are the goals of the PR clear? + - Is the granularity of the PR appropriate? - Security - Does merging this PR create a vulnerability? - Performance @@ -83,7 +68,7 @@ Be willing to comment on the good points and not just the things you want fixed ## Release ### Release Instructions -1. Commit version changes in the `develop` branch ([package.json](package.json)) +1. Commit version changes in the `develop` branch ([package.json](https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/package.json)) 2. Create a release PR. - Into `stable` from `develop` branch. - The title must be in the format `Release: x.y.z`. @@ -94,7 +79,7 @@ Be willing to comment on the good points and not just the things you want fixed - The target branch must be `stable` - The tag name must be the version -> [!NOTE] +> **Note** > Why this instruction is necessary: > - To perform final QA checks > - To distribute responsibility @@ -111,52 +96,13 @@ If your language is not listed in Crowdin, please open an issue. ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg) -## Icon Font (Shark Font) -Sharkey has its own Icon Font called Shark Font which can be found at https://activitypub.software/TransFem-org/shark-font -Build Instructions can all be found over there in the `README`. - -If you have an Icon Suggestion or want to add an Icon please open an issue/merge request over at that repo. - -When Updating the Font make sure to copy **all generated files** from the `dest` folder into `packages/backend/assets/fonts/sharkey-icons` -For the CSS simply copy the file content and replace the old content in `style.css` and for the WOFF, TTF and SVG simply replace them. - ## Development -### Setup -Before developing, you have to set up environment. Misskey requires Redis, PostgreSQL, and FFmpeg. - -You would want to install Meilisearch to experiment related features. Technically, meilisearch is not strict requirement, but some features and tests require it. - -There are a few ways to proceed. - -#### Use system-wide software -You could install them in system-wide (such as from package manager). - -#### Use `docker compose` -You could obtain middleware container by typing `docker compose -f $PROJECT_ROOT/compose.local-db.yml up -d`. - -#### Use Devcontainer -Devcontainer also has necessary setting. This method can be done by connecting from VSCode. - -Instead of running `pnpm` locally, you can use Dev Container to set up your development environment. -To use Dev Container, open the project directory on VSCode with Dev Containers installed. -**Note:** If you are using Windows, please clone the repository with WSL. Using Git for Windows will result in broken files due to the difference in how newlines are handled. - -It will run the following command automatically inside the container. -``` bash -git submodule update --init -pnpm install --frozen-lockfile -cp .devcontainer/devcontainer.yml .config/default.yml -pnpm build -pnpm migrate -``` - -After finishing the migration, you can proceed. - -### Start developing During development, it is useful to use the + ``` pnpm dev ``` + command. - Server-side source files and automatically builds them if they are modified. Automatically start the server process(es). @@ -180,6 +126,26 @@ MK_DEV_PREFER=backend pnpm dev - To change the port of Vite, specify with `VITE_PORT` environment variable. - HMR may not work in some environments such as Windows. +### Dev Container +Instead of running `pnpm` locally, you can use Dev Container to set up your development environment. +To use Dev Container, open the project directory on VSCode with Dev Containers installed. +**Note:** If you are using Windows, please clone the repository with WSL. Using Git for Windows will result in broken files due to the difference in how newlines are handled. + +It will run the following command automatically inside the container. +``` bash +git submodule update --init +pnpm install --frozen-lockfile +cp .devcontainer/devcontainer.yml .config/default.yml +pnpm build +pnpm migrate +``` + +After finishing the migration, run the `pnpm dev` command to start the development server. + +``` bash +pnpm dev +``` + ## Testing - Test codes are located in [`/packages/backend/test`](packages/backend/test). @@ -190,7 +156,7 @@ cp .github/misskey/test.yml .config/ ``` Prepare DB/Redis for testing. ``` -docker compose -f packages/backend/test/compose.yml up +docker compose -f packages/backend/test/docker-compose.yml up ``` Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`. @@ -229,7 +195,7 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド ### ルート定義 ルート定義は、以下の形式のオブジェクトの配列です。 -```ts +``` ts { name?: string; path: string; @@ -242,7 +208,7 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド } ``` -> [!WARNING] +> **Warning** > 現状、ルートは定義された順に評価されます。 > たとえば、`/foo/:id`ルート定義の次に`/foo/bar`ルート定義がされていた場合、後者がマッチすることはありません。 @@ -304,7 +270,7 @@ export const Default = { parameters: { layout: 'centered', }, -} satisfies StoryObj; +} satisfies StoryObj; ``` If you want to opt-out from the automatic generation, create a `MyComponent.stories.impl.ts` file and add the following line to the file. @@ -341,98 +307,6 @@ export const handlers = [ Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files. -## Nest - -### Nest Service Circular dependency / Nestでサービスの循環参照でエラーが起きた場合 - -#### forwardRef -まずは簡単に`forwardRef`を試してみる - -```typescript -export class FooService { - constructor( - @Inject(forwardRef(() => BarService)) - private barService: BarService - ) { - } -} -``` - -#### OnModuleInit -できなければ`OnModuleInit`を使う - -```typescript -import { Injectable, OnModuleInit } from '@nestjs/common'; -import { ModuleRef } from '@nestjs/core'; -import { BarService } from '@/core/BarService'; - -@Injectable() -export class FooService implements OnModuleInit { - private barService: BarService // constructorから移動してくる - - constructor( - private moduleRef: ModuleRef, - ) { - } - - async onModuleInit() { - this.barService = this.moduleRef.get(BarService.name); - } - - public async niceMethod() { - return await this.barService.incredibleMethod({ hoge: 'fuga' }); - } -} -``` - -##### Service Unit Test -テストで`onModuleInit`を呼び出す必要がある - -```typescript -// import ... - -describe('test', () => { - let app: TestingModule; - let fooService: FooService; // for test case - let barService: BarService; // for test case - - beforeEach(async () => { - app = await Test.createTestingModule({ - imports: ..., - providers: [ - FooService, - { // mockする (mockは必須ではないかもしれない) - provide: BarService, - useFactory: () => ({ - incredibleMethod: jest.fn(), - }), - }, - { // Provideにする - provide: BarService.name, - useExisting: BarService, - }, - ], - }) - .useMocker(... - .compile(); - - fooService = app.get(FooService); - barService = app.get(BarService) as jest.Mocked; - - // onModuleInitを実行する - await fooService.onModuleInit(); - }); - - test('nice', () => { - await fooService.niceMethod(); - - expect(barService.incredibleMethod).toHaveBeenCalled(); - expect(barService.incredibleMethod.mock.lastCall![0]) - .toEqual({ hoge: 'fuga' }); - }); -}) -``` - ## Notes ### Misskeyのドメイン固有の概念は`Mi`をprefixする @@ -529,21 +403,20 @@ enumの列挙の内容の削除は、その値をもつレコードを全て削 ### Migration作成方法 packages/backendで: ```sh -pnpm run build -pnpm dlx typeorm migration:generate -d ormconfig.js -o migration/ +pnpm dlx typeorm migration:generate -d ormconfig.js -o ``` - 生成後、ファイルをmigration下に移してください - 作成されたスクリプトは不必要な変更を含むため除去してください ### JSON SchemaのobjectでanyOfを使うとき -JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。 -バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます) +JSON Schemaで、objectに対してanyOfを使う場合、anyOfの中でpropertiesを定義しないこと。 +バリデーションが効かないため。(SchemaTypeもそのように作られており、objectのanyOf内のpropertiesは捨てられます) https://github.com/misskey-dev/misskey/pull/10082 テキストhogeおよびfugaについて、片方を必須としつつ両方の指定もありうる場合: -```ts +``` export const paramDef = { type: 'object', properties: { @@ -574,26 +447,6 @@ marginはそのコンポーネントを使う側が設定する ### indexというファイル名を使うな ESMではディレクトリインポートは廃止されているのと、ディレクトリインポートせずともファイル名が index だと何故か一部のライブラリ?でディレクトリインポートだと見做されてエラーになる -## CSS Recipe - -### Lighten CSS vars - -``` css -color: hsl(from var(--accent) h s calc(l + 10)); -``` - -### Darken CSS vars - -``` css -color: hsl(from var(--accent) h s calc(l - 10)); -``` - -### Add alpha to CSS vars - -``` css -color: color(from var(--accent) srgb r g b / 0.5); -``` - ## Merging from Misskey into Sharkey Make sure you have both remotes in the same clone (`git remote add misskey @@ -604,52 +457,18 @@ https://github.com/misskey-dev/misskey.git`), then: git checkout -m merge/$(date +%Y-%m-%d) # or whatever git merge --no-ff misskey/develop -fix conflicts and *commit*! (conflicts in `pnpm-lock.yaml` can usually -be fixed by running `pnpm install`, it detects conflict markers and -seems to do a decent job) +fix conflicts and *commit*! *after that commit*, do all the extra work, on the same branch: -* copy all changes (commit after each step): - * in - `packages/backend/src/core/activitypub/models/ApNoteService.ts`, - from `createNote` to `updateNote` - * from `packages/backend/src/core/NoteCreateService.ts` to - `packages/backend/src/core/NoteEditService.vue` - * from `packages/backend/src/server/api/endpoints/notes/create.ts` - to `packages/backend/src/server/api/endpoints/notes/edit.ts` - * from `packages/frontend/src/components/MkNote*.vue` to - `packages/frontend/src/components/SkNote*.vue` (if sensible) - * from the global timeline to the bubble timeline - (`packages/backend/src/server/api/stream/channels/global-timeline.ts`, - `packages/backend/src/server/api/stream/channels/bubble-timeline.ts`, - `packages/frontend/src/timelines.ts`, - `packages/frontend/src/components/MkTimeline.vue`, - `packages/frontend/src/pages/timeline.vue`, - `packages/frontend/src/ui/deck/tl-column.vue`, - `packages/frontend/src/widgets/WidgetTimeline.vue`) -* check the changes against our `develop` (`git diff develop`) and - against Misskey (`git diff misskey/develop`) -* re-generate `misskey-js` (`pnpm build-misskey-js-with-types`) and commit -* build the frontend: `rm -rf built/; NODE_ENV=development pnpm - --filter=frontend --filter=frontend-embed build` (the `development` - tells it to keep some of the original filenames in the built files) -* make sure there aren't any new `ti-*` classes (Tabler Icons), and - replace them with appropriate `ph-*` ones (Phosphor Icons): - `grep -rP '["'\'']ti[ -](?!fw)' -- built/` should show you what to change. - NOTE: `ti-fw` is a special class that's defined by Misskey, leave it - alone - - after every change, re-build the frontend and check again, until - there are no more `ti-*` classes in the built files - - commit! -* double-check the new migration, that they won't conflict with our db - changes: `git diff develop -- packages/backend/migration/` -* `pnpm clean; pnpm build` -* run tests `pnpm --filter='!megalodon' test` (requires a test - database, [see above](#testing)) and fix as much as you can - * right now `megalodon` doesn't pass its tests, so we skip them +* copy all changes: + * from `NoteCreateService.create` to `NoteCreateService.import` (and + vice versa if `git` got confused!) + * from `NoteCreateService` to `NoteEditService` + * from `ApNoteService.createNote` to `ApNoteService.updateNote` + * from `endoints/notes/create.ts` to `endoints/notes/edit.ts` + * from `MkNote*` to `SkNote*` (if sensible) +* run tests `pnpm test` and fix as much as you can * run lint `pnpm --filter=backend lint` + `pnpm --filter=frontend eslint` and fix as much as you can diff --git a/Dockerfile b/Dockerfile index abee7fb098..7e0a778862 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax = docker/dockerfile:1.4 -ARG NODE_VERSION=20.16.0-alpine3.20 +ARG NODE_VERSION=20.10.0-alpine3.18 FROM node:${NODE_VERSION} as build @@ -8,7 +8,8 @@ RUN apk add git linux-headers build-base ENV PYTHONUNBUFFERED=1 RUN apk add --update python3 && ln -sf python3 /usr/bin/python -RUN apk add py3-pip py3-setuptools +RUN python3 -m ensurepip +RUN pip3 install --no-cache --upgrade pip setuptools RUN corepack enable @@ -23,10 +24,9 @@ RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ RUN pnpm build RUN node scripts/trim-deps.mjs RUN mv packages/frontend/assets sharkey-assets -RUN mv packages/frontend-embed/assets sharkey-embed-assets RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ pnpm prune -RUN rm -r node_modules packages/frontend packages/frontend-shared packages/frontend-embed packages/sw +RUN rm -r node_modules packages/frontend packages/sw RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \ pnpm i --prod --frozen-lockfile --aggregate-output RUN rm -rf .git @@ -40,18 +40,12 @@ RUN apk add ffmpeg tini jemalloc \ && corepack enable \ && addgroup -g "${GID}" sharkey \ && adduser -D -u "${UID}" -G sharkey -h /sharkey sharkey \ - && mkdir /sharkey/files \ - && chown sharkey:sharkey /sharkey/files \ && find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -exec chmod u-s {} \; \ && find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /g+s -exec chmod g-s {} \; USER sharkey WORKDIR /sharkey -# add package.json to add pnpm -COPY --chown=sharkey:sharkey ./package.json ./package.json -RUN corepack install - COPY --chown=sharkey:sharkey --from=build /sharkey/node_modules ./node_modules COPY --chown=sharkey:sharkey --from=build /sharkey/packages/backend/node_modules ./packages/backend/node_modules COPY --chown=sharkey:sharkey --from=build /sharkey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules @@ -67,11 +61,11 @@ COPY --chown=sharkey:sharkey --from=build /sharkey/packages/megalodon/lib ./pack COPY --chown=sharkey:sharkey --from=build /sharkey/fluent-emojis ./fluent-emojis COPY --chown=sharkey:sharkey --from=build /sharkey/tossface-emojis/dist ./tossface-emojis/dist COPY --chown=sharkey:sharkey --from=build /sharkey/sharkey-assets ./packages/frontend/assets -COPY --chown=sharkey:sharkey --from=build /sharkey/sharkey-embed-assets ./packages/frontend-embed/assets +COPY --chown=sharkey:sharkey package.json ./package.json COPY --chown=sharkey:sharkey pnpm-workspace.yaml ./pnpm-workspace.yaml COPY --chown=sharkey:sharkey packages/backend/package.json ./packages/backend/package.json -COPY --chown=sharkey:sharkey packages/backend/scripts/check_connect.js ./packages/backend/scripts/check_connect.js +COPY --chown=sharkey:sharkey packages/backend/check_connect.js ./packages/backend/check_connect.js COPY --chown=sharkey:sharkey packages/backend/ormconfig.js ./packages/backend/ormconfig.js COPY --chown=sharkey:sharkey packages/backend/migration ./packages/backend/migration COPY --chown=sharkey:sharkey packages/backend/assets ./packages/backend/assets diff --git a/README.md b/README.md index f9198c06c0..c002acbff9 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ --- + + find an instance + create an instance @@ -16,8 +19,8 @@ join the community - - donate + + donate --- @@ -31,7 +34,7 @@ - **ActivityPub support**\ Not on Sharkey? No problem! Not only can Sharkey instances talk to each other, but you can make friends with people on other networks like Mastodon and Pixelfed! - **Federated Backgrounds and Music status**\ -You can add a background to your profile as well as a music status via ListenBrainz, show everyone what music you are currently listening to +You can add a background to your profile as well as a music status via ListenBrainz, show everyone what music you are currently listening too - **Mastodon API**\ Sharkey implements the Mastodon API unlike normal Misskey - **UI/UX Improvements**\ diff --git a/UPGRADE_NOTES.md b/UPGRADE_NOTES.md deleted file mode 100644 index c941de6643..0000000000 --- a/UPGRADE_NOTES.md +++ /dev/null @@ -1,74 +0,0 @@ -# Upgrade Notes - -## 2024.10.0 - -### Hellspawns - -Sharkey versions before 2024.10 suffered from a bug in the "Mark instance as NSFW" feature. -When a user from such an instance boosted a note, the boost would be converted to a hellspawn (pure renote with Content Warning). -Hellspawns are buggy and do not properly federate, so it may be desirable to correct any that already exist in the database. -The following script will correct any local or remote hellspawns in the database. - -```postgresql -/* Remove "instance is marked as NSFW" hellspawns */ -UPDATE "note" -SET "cw" = null -WHERE - "renoteId" IS NOT NULL - AND "text" IS NULL - AND "cw" = 'Instance is marked as NSFW' - AND "replyId" IS NULL - AND "hasPoll" = false - AND "fileIds" = '{}'; - -/* Fix legacy / user-created hellspawns */ -UPDATE "note" -SET "text" = '.' -WHERE - "renoteId" IS NOT NULL - AND "text" IS NULL - AND "cw" IS NOT NULL - AND "replyId" IS NULL - AND "hasPoll" = false - AND "fileIds" = '{}'; -``` - -## 2024.9.0 - -### Following Feed - -When upgrading an existing instance to version 2024.9.0, the Following Feed will initially be empty. -The feed will gradually fill as new posts federate, but it may be desirable to back-fill the feed with existing data. -This database script will populate the feed with the latest post of each type for all users, ensuring that data is fully populated after the update. -Run this after migrations but before starting the instance. -Warning: the script may take a long time to execute! - -```postgresql -INSERT INTO latest_note (user_id, note_id, is_public, is_reply, is_quote) -SELECT - "userId" as user_id, - id as note_id, - visibility = 'public' AS is_public, - "replyId" IS NOT NULL AS is_reply, - ( - "renoteId" IS NOT NULL - AND ( - text IS NOT NULL - OR cw IS NOT NULL - OR "replyId" IS NOT NULL - OR "hasPoll" - OR "fileIds" != '{}' - ) - ) AS is_quote -FROM note -WHERE ( -- Exclude pure renotes (boosts) - "renoteId" IS NULL - OR text IS NOT NULL - OR cw IS NOT NULL - OR "replyId" IS NOT NULL - OR "hasPoll" - OR "fileIds" != '{}' - ) -ORDER BY id DESC -- This part is very important: it ensures that we only load the *latest* notes of each type. Do not remove it! -ON CONFLICT DO NOTHING; -- Any conflicts are guaranteed to be older notes that we can ignore. -``` diff --git a/chart/files/default.yml b/chart/files/default.yml index 97201aad66..9c81964736 100644 --- a/chart/files/default.yml +++ b/chart/files/default.yml @@ -124,14 +124,6 @@ redis: # #prefix: example-prefix # #db: 1 -#redisForReactions: -# host: redis -# port: 6379 -# #family: 0 # 0=Both, 4=IPv4, 6=IPv6 -# #pass: example-pass -# #prefix: example-prefix -# #db: 1 - # ┌───────────────────────────┐ #───┘ MeiliSearch configuration └───────────────────────────── @@ -160,22 +152,6 @@ redis: # ID SETTINGS AFTER THAT! id: "aidx" - -# ┌────────────────┐ -#───┘ Error tracking └────────────────────────────────────────── - -# Sentry is available for error tracking. -# See the Sentry documentation for more details on options. - -#sentryForBackend: -# enableNodeProfiling: true -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - -#sentryForFrontend: -# options: -# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0' - # ┌─────────────────────┐ #───┘ Other configuration └───────────────────────────────────── @@ -216,13 +192,8 @@ id: "aidx" # Media Proxy #mediaProxy: https://example.com/proxy -# Sign outgoing ActivityPub GET request (default: true) +# Sign to ActivityPub GET request (default: true) signToActivityPubGet: true -# Sign outgoing ActivityPub Activities (default: true) -# Linked Data signatures are cryptographic signatures attached to each activity to provide proof of authenticity. -# When using authorized fetch, this is often undesired as any signed activity can be forwarded to a blocked instance by relays and other instances. -# This setting allows admins to disable LD signatures for increased privacy, at the expense of fewer relayed activities and additional inbound fetch (GET) requests. -attachLdSignatureForRelays: true # check that inbound ActivityPub GET requests are signed ("authorized fetch") checkActivityPubGetSignature: false diff --git a/crowdin.yml b/crowdin.yml index 0525ac7b0b..774ddc7a63 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,4 +1,4 @@ files: - - source: /sharkey-locales/en-US.yml - translation: /sharkey-locales/%locale%.yml + - source: /locales/ja-JP.yml + translation: /locales/%locale%.yml update_option: update_as_unapproved diff --git a/cypress/e2e/basic.cy.ts b/cypress/e2e/basic.cy.js similarity index 98% rename from cypress/e2e/basic.cy.ts rename to cypress/e2e/basic.cy.js index d2525e0a7d..604241d13c 100644 --- a/cypress/e2e/basic.cy.ts +++ b/cypress/e2e/basic.cy.js @@ -1,8 +1,3 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - describe('Before setup instance', () => { beforeEach(() => { cy.resetState(); diff --git a/cypress/e2e/router.cy.ts b/cypress/e2e/router.cy.js similarity index 91% rename from cypress/e2e/router.cy.ts rename to cypress/e2e/router.cy.js index 8d8fb3af31..6de27be5f4 100644 --- a/cypress/e2e/router.cy.ts +++ b/cypress/e2e/router.cy.js @@ -1,8 +1,3 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - describe('Router transition', () => { describe('Redirect', () => { // サーバの初期化。ルートのテストに関しては各describeごとに1度だけ実行で十分だと思う(使いまわした方が早い) diff --git a/cypress/e2e/widgets.cy.ts b/cypress/e2e/widgets.cy.js similarity index 95% rename from cypress/e2e/widgets.cy.ts rename to cypress/e2e/widgets.cy.js index 847801a69f..df6ec8357d 100644 --- a/cypress/e2e/widgets.cy.ts +++ b/cypress/e2e/widgets.cy.js @@ -1,8 +1,3 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - /* flaky describe('After user signed in', () => { beforeEach(() => { diff --git a/cypress/support/commands.ts b/cypress/support/commands.js similarity index 87% rename from cypress/support/commands.ts rename to cypress/support/commands.js index 281f2e6ccd..91a4d7abe6 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.js @@ -30,13 +30,9 @@ Cypress.Commands.add('visitHome', () => { }) Cypress.Commands.add('resetState', () => { - // iframe.contentWindow.indexedDB.deleteDatabase() がchromeのバグで使用できないため、indexedDBを無効化している。 - // see https://github.com/misskey-dev/misskey/issues/13605#issuecomment-2053652123 - /* - cy.window().then(win => { + cy.window(win => { win.indexedDB.deleteDatabase('keyval-store'); }); - */ cy.request('POST', '/api/reset-db', {}).as('reset'); cy.get('@reset').its('status').should('equal', 204); cy.reload(true); diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.js similarity index 100% rename from cypress/support/e2e.ts rename to cypress/support/e2e.js diff --git a/cypress/support/index.ts b/cypress/support/index.ts deleted file mode 100644 index c1bed21979..0000000000 --- a/cypress/support/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -declare global { - namespace Cypress { - interface Chainable { - login(username: string, password: string): Chainable; - - registerUser( - username: string, - password: string, - isAdmin?: boolean - ): Chainable; - - resetState(): Chainable; - - visitHome(): Chainable; - } - } -} - -export {} diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json deleted file mode 100644 index 6fe7f32cc4..0000000000 --- a/cypress/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "es5"], - "target": "es5", - "types": ["cypress", "node"] - }, - "include": ["./**/*.ts"] -} diff --git a/compose.local-db.yml b/docker-compose.local-db.yml similarity index 98% rename from compose.local-db.yml rename to docker-compose.local-db.yml index 3835cb23db..16ba4b49e1 100644 --- a/compose.local-db.yml +++ b/docker-compose.local-db.yml @@ -1,3 +1,5 @@ +version: "3" + # このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します services: diff --git a/compose_example.yml b/docker-compose_example.yml similarity index 91% rename from compose_example.yml rename to docker-compose_example.yml index 0db8b04dc6..647f6f0c77 100644 --- a/compose_example.yml +++ b/docker-compose_example.yml @@ -1,3 +1,5 @@ +version: "3" + services: web: # image: registry.activitypub.software/transfem-org/sharkey:latest @@ -17,8 +19,6 @@ services: - "3000:3000" networks: - shonk - # env_file: - # - .config/docker.env volumes: - ./files:/sharkey/files - ./.config:/sharkey/.config:ro @@ -53,7 +53,8 @@ services: # restart: always # image: mcaptcha/mcaptcha:latest # networks: -# shonk: +# internal_network: +# external_network: # aliases: # - localhost # ports: @@ -63,8 +64,6 @@ services: # environment: # PORT: 7493 # MCAPTCHA_redis_URL: "redis://mcaptcha_redis/" -# MCAPTCHA_allow_registration: true -# MCAPTCHA_server_DOMAIN: "example.tld" # depends_on: # db: # condition: service_healthy @@ -74,7 +73,7 @@ services: # mcaptcha_redis: # image: mcaptcha/cache:latest # networks: -# - shonk +# - internal_network # healthcheck: # test: "redis-cli ping" # interval: 5s diff --git a/eslint/locale.js b/eslint/locale.js deleted file mode 100644 index dbb807b714..0000000000 --- a/eslint/locale.js +++ /dev/null @@ -1,251 +0,0 @@ -/* - * SPDX-FileCopyrightText: dakkar and other Sharkey contributors - * SPDX-License-Identifier: AGPL-3.0-only -*/ - -/* This is a ESLint rule to report use of the `i18n.ts` and `i18n.tsx` - * objects that reference translation items that don't actually exist - * in the lexicon (the `locale/` files) - */ - -/* given a MemberExpression node, collects all the member names - * - * e.g. for a bit of code like `foo=one.two.three`, `collectMembers` - * called on the node for `three` would return `['one', 'two', - * 'three']` - */ -function collectMembers(node) { - if (!node) return []; - if (node.type !== 'MemberExpression') return []; - // this is something like `foo[bar]` - if (node.computed) return []; - return [ node.property.name, ...collectMembers(node.parent) ]; -} - -/* given an object and an array of names, recursively descends the - * object via those names - * - * e.g. `walkDown({one:{two:{three:15}}},['one','two','three'])` would - * return 15 - */ -function walkDown(locale, path) { - if (!locale) return null; - if (!path || path.length === 0 || !path[0]) return locale; - return walkDown(locale[path[0]], path.slice(1)); -} - -/* given a MemberExpression node, returns its attached CallExpression - * node if present - * - * e.g. for a bit of code like `foo=one.two.three()`, - * `findCallExpression` called on the node for `three` would return - * the node for function call (which is the parent of the `one` and - * `two` nodes, and holds the nodes for the argument list) - * - * if the code had been `foo=one.two.three`, `findCallExpression` - * would have returned null, because there's no function call attached - * to the MemberExpressions - */ -function findCallExpression(node) { - if (!node.parent) return null; - - // the second half of this guard protects from cases like - // `foo(one.two.three)` where the CallExpression is parent of the - // MemberExpressions, but via `arguments`, not `callee` - if (node.parent.type === 'CallExpression' && node.parent.callee === node) return node.parent; - if (node.parent.type === 'MemberExpression') return findCallExpression(node.parent); - return null; -} - -// same, but for Vue expressions (``) -function findVueExpression(node) { - if (!node.parent) return null; - - if (node.parent.type.match(/^VExpr/) && node.parent.expression === node) return node.parent; - if (node.parent.type === 'MemberExpression') return findVueExpression(node.parent); - return null; -} - -function areArgumentsOneObject(node) { - return node.arguments.length === 1 && - node.arguments[0].type === 'ObjectExpression'; -} - -// only call if `areArgumentsOneObject(node)` is true -function getArgumentObjectProperties(node) { - return new Set(node.arguments[0].properties.map( - p => { - if (p.key && p.key.type === 'Identifier') return p.key.name; - return null; - }, - )); -} - -function getTranslationParameters(translation) { - return new Set(Array.from(translation.matchAll(/\{(\w+)\}/g)).map( m => m[1] )); -} - -function setDifference(a,b) { - const result = []; - for (const element of a.values()) { - if (!b.has(element)) { - result.push(element); - } - } - - return result; -} - -/* the actual rule body - */ -function theRuleBody(context,node) { - // we get the locale/translations via the options; it's the data - // that goes into a specific language's JSON file, see - // `scripts/build-assets.mjs` - const locale = context.options[0]; - - // sometimes we get MemberExpression nodes that have a - // *descendent* with the right identifier: skip them, we'll get - // the right ones as well - if (node.object?.name !== 'i18n') { - return; - } - - // `method` is going to be `'ts'` or `'tsx'`, `path` is going to - // be the various translation steps/names - const [ method, ...path ] = collectMembers(node); - const pathStr = `i18n.${method}.${path.join('.')}`; - - // does that path point to a real translation? - const translation = walkDown(locale, path); - if (!translation) { - context.report({ - node, - message: `translation missing for ${pathStr}`, - }); - return; - } - - // we hit something weird, assume the programmers know what - // they're doing (this is usually some complicated slicing of - // the translation structure) - if (typeof(translation) !== 'string') return; - - const callExpression = findCallExpression(node); - const vueExpression = findVueExpression(node); - - // some more checks on how the translation is called - if (method === 'ts') { - // the ` component gets parametric translations via - // `i18n.ts.*`, but we error out elsewhere - if (translation.match(/\{/) && !vueExpression) { - context.report({ - node, - message: `translation for ${pathStr} is parametric, but called via 'ts'`, - }); - return; - } - - if (callExpression) { - context.report({ - node, - message: `translation for ${pathStr} is not parametric, but is called as a function`, - }); - } - } - - if (method === 'tsx') { - if (!translation.match(/\{/)) { - context.report({ - node, - message: `translation for ${pathStr} is not parametric, but called via 'tsx'`, - }); - return; - } - - if (!callExpression && !vueExpression) { - context.report({ - node, - message: `translation for ${pathStr} is parametric, but not called as a function`, - }); - return; - } - - // we're not currently checking arguments when used via the - // `` component, because it's too complicated (also, it - // would have to be done inside the `if (method === 'ts')`) - if (!callExpression) return; - - if (!areArgumentsOneObject(callExpression)) { - context.report({ - node, - message: `translation for ${pathStr} should be called with a single object as argument`, - }); - return; - } - - const translationParameters = getTranslationParameters(translation); - const parameterCount = translationParameters.size; - const callArguments = getArgumentObjectProperties(callExpression); - const argumentCount = callArguments.size; - - if (parameterCount !== argumentCount) { - context.report({ - node, - message: `translation for ${pathStr} has ${parameterCount} parameters, but is called with ${argumentCount} arguments`, - }); - } - - // node 20 doesn't have `Set.difference`... - const extraArguments = setDifference(callArguments, translationParameters); - const missingArguments = setDifference(translationParameters, callArguments); - - if (extraArguments.length > 0) { - context.report({ - node, - message: `translation for ${pathStr} passes unused arguments ${extraArguments.join(' ')}`, - }); - } - - if (missingArguments.length > 0) { - context.report({ - node, - message: `translation for ${pathStr} does not pass arguments ${missingArguments.join(' ')}`, - }); - } - } -} - -function theRule(context) { - // we get the locale/translations via the options; it's the data - // that goes into a specific language's JSON file, see - // `scripts/build-assets.mjs` - const locale = context.options[0]; - - // for all object member access that have an identifier 'i18n'... - return context.getSourceCode().parserServices.defineTemplateBodyVisitor( - { - // this is for -
+
@@ -63,7 +61,7 @@ SPDX-License-Identifier: AGPL-3.0-only - diff --git a/packages/frontend/src/components/MkDonation.stories.impl.ts b/packages/frontend/src/components/MkDonation.stories.impl.ts deleted file mode 100644 index 27d6b7df6c..0000000000 --- a/packages/frontend/src/components/MkDonation.stories.impl.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { action } from '@storybook/addon-actions'; -import { StoryObj } from '@storybook/vue3'; -import { onBeforeUnmount } from 'vue'; -import MkDonation from './MkDonation.vue'; -import { instance } from '@/instance.js'; -export const Default = { - render(args) { - return { - components: { - MkDonation, - }, - setup() { - return { - args, - }; - }, - computed: { - props() { - return { - ...this.args, - }; - }, - events() { - return { - closed: action('closed'), - }; - }, - }, - template: '', - }; - }, - args: { - // @ts-expect-error name is used for mocking instance - name: 'Misskey Hub', - }, - decorators: [ - (_, { args }) => ({ - setup() { - // @ts-expect-error name is used for mocking instance - instance.name = args.name; - onBeforeUnmount(() => instance.name = null); - }, - template: '', - }), - ], - parameters: { - layout: 'centered', - }, -} satisfies StoryObj; diff --git a/packages/frontend/src/components/MkDonation.vue b/packages/frontend/src/components/MkDonation.vue index 1dfdebf0d4..a2780ddfe9 100644 --- a/packages/frontend/src/components/MkDonation.vue +++ b/packages/frontend/src/components/MkDonation.vue @@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.learnMore }} + {{ i18n.ts.learnMore }}
@@ -41,14 +41,14 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.neverShow }}
- + - - diff --git a/packages/frontend/src/components/MkEmojiPicker.section.stories.impl.ts b/packages/frontend/src/components/MkEmojiPicker.section.stories.impl.ts deleted file mode 100644 index 69aef577de..0000000000 --- a/packages/frontend/src/components/MkEmojiPicker.section.stories.impl.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import MkEmojiPicker_section from './MkEmojiPicker.section.vue'; -void MkEmojiPicker_section; diff --git a/packages/frontend/src/components/MkEmojiPicker.section.vue b/packages/frontend/src/components/MkEmojiPicker.section.vue index 151843b18c..a5839586b6 100644 --- a/packages/frontend/src/components/MkEmojiPicker.section.vue +++ b/packages/frontend/src/components/MkEmojiPicker.section.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- (:{{ emojis.length }}) + (:{{ emojis.length }})
diff --git a/packages/frontend/src/components/MkUserInfo.vue b/packages/frontend/src/components/MkUserInfo.vue index 73cdd9ce00..63c4af41a0 100644 --- a/packages/frontend/src/components/MkUserInfo.vue +++ b/packages/frontend/src/components/MkUserInfo.vue @@ -5,24 +5,16 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -49,8 +41,6 @@ import { userPage } from '@/filters/user.js'; import { i18n } from '@/i18n.js'; import { $i } from '@/account.js'; import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js'; -import { getStaticImageUrl } from '@/scripts/media-proxy.js'; -import { defaultStore } from '@/store.js'; defineProps<{ user: Misskey.entities.UserDetailed; @@ -152,30 +142,4 @@ defineProps<{ top: 8px; right: 8px; } - -.infoBadges { - position: absolute; - top: 12px; - left: 12px; - - display: flex; - flex-direction: row; - - padding: 0; - margin: 0; - - > * { - padding: 4px 8px; - color: #fff; - background: rgba(0, 0, 0, 0.7); - font-size: 0.7em; - border-radius: var(--radius-sm); - list-style-type: none; - margin-left: 0; - } - - > :not(:first-child) { - margin-left: 8px; - } -} diff --git a/packages/frontend/src/components/MkUserList.vue b/packages/frontend/src/components/MkUserList.vue index ac82ecc3d6..17a9254d01 100644 --- a/packages/frontend/src/components/MkUserList.vue +++ b/packages/frontend/src/components/MkUserList.vue @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only -->