diff --git a/.config/ci.yml b/.config/ci.yml index d20ede8d35..7639df8807 100644 --- a/.config/ci.yml +++ b/.config/ci.yml @@ -221,9 +221,10 @@ 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". # Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)). -#allowedPrivateNetworks: [ -# '127.0.0.1/32' -#] +allowedPrivateNetworks: [ + '127.0.0.1/32', + '192.168.65.0/24' +] #customMOTD: ['Hello World', 'The sharks rule all', 'Shonks'] diff --git a/.config/docker_ci.env b/.config/docker_ci.env new file mode 100644 index 0000000000..d70db4adcc --- /dev/null +++ b/.config/docker_ci.env @@ -0,0 +1,11 @@ +# misskey settings +# MISSKEY_URL=https://example.tld/ + +# db settings +POSTGRES_PASSWORD=ci +# DATABASE_PASSWORD=${POSTGRES_PASSWORD} +POSTGRES_USER=postgres +# DATABASE_USER=${POSTGRES_USER} +POSTGRES_DB=postgres +# DATABASE_DB=${POSTGRES_DB} +DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}" diff --git a/.forgejo/workflows/tests.yml b/.forgejo/workflows/tests.yml new file mode 100644 index 0000000000..941ae6e2c1 --- /dev/null +++ b/.forgejo/workflows/tests.yml @@ -0,0 +1,31 @@ +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + testCommit: + runs-on: yeentown-dev + container: + image: node:iron + services: + postgres: + image: postgres:15 + env: + POSTGRES_PASSWORD: ci + redis: + image: redis:latest + steps: + - uses: actions/checkout@v4 + - run: | + apt-get update && apt-get install -y git wget curl build-essential python3 ffmpeg + 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 diff --git a/.gitignore b/.gitignore index 7cc7354a4a..670b7a3005 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ coverage !/.config/docker_example.yml !/.config/docker_example.env !/.config/cypress-devcontainer.yml +!/.config/docker_ci.env docker-compose.yml compose.yml .devcontainer/compose.yml diff --git a/compose.local-dev.yml b/compose.local-dev.yml new file mode 100644 index 0000000000..17f4f91a6b --- /dev/null +++ b/compose.local-dev.yml @@ -0,0 +1,51 @@ +# このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します +name: barkey-devcontainer +services: + redis: + restart: always + image: redis:7-alpine + ports: + - "6379:6379" + volumes: + - ./redis:/data + healthcheck: + test: "redis-cli ping" + interval: 5s + retries: 20 + + postgres: + restart: always + image: postgres:15-alpine + ports: + - "5432:5432" + env_file: + - .config/docker.env + volumes: + - ./db:/var/lib/postgresql/data + healthcheck: + test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB" + interval: 5s + retries: 20 + + web: + restart: always + image: node:iron + ports: + - 3000:3000 + - 5173:5173 + working_dir: /host + volumes: + - ./:/host + command: sleep infinity + +# meilisearch: +# restart: always +# image: getmeili/meilisearch:v1.3.4 +# environment: +# - MEILI_NO_ANALYTICS=true +# - MEILI_ENV=production +# env_file: +# - .config/meilisearch.env +# volumes: +# - ./meili_data:/meili_data + diff --git a/compose.local-test.yml b/compose.local-test.yml new file mode 100644 index 0000000000..0a1f4f541f --- /dev/null +++ b/compose.local-test.yml @@ -0,0 +1,46 @@ +# このconfigは、 dockerでMisskey本体を起動せず、 redisとpostgresql などだけを起動します +name: barkey-test +services: + redis: + restart: always + image: redis:7-alpine + ports: + - "6379:6379" + healthcheck: + test: "redis-cli ping" + interval: 5s + retries: 20 + + postgres: + restart: always + image: postgres:15-alpine + ports: + - "5432:5432" + env_file: + - .config/docker.env + healthcheck: + test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB" + interval: 5s + retries: 20 + + web: + restart: always + image: node:iron + ports: + - 3000:3000 + working_dir: /host + volumes: + - ./:/host + command: sleep infinity + +# meilisearch: +# restart: always +# image: getmeili/meilisearch:v1.3.4 +# environment: +# - MEILI_NO_ANALYTICS=true +# - MEILI_ENV=production +# env_file: +# - .config/meilisearch.env +# volumes: +# - ./meili_data:/meili_data + diff --git a/locales/index.d.ts b/locales/index.d.ts index d1cb1f97ea..4948bc1817 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -11374,6 +11374,48 @@ export interface Locale extends ILocale { * Remote followers may have incomplete or outdated activity */ "remoteFollowersWarning": string; + /** + * Sort key + */ + "sortKey": string; + "_unicodeEmoji": { + /** + * Smileys + */ + "face": string; + /** + * People + */ + "people": string; + /** + * Animals & nature + */ + "animals_and_nature": string; + /** + * Food & drink + */ + "food_and_drink": string; + /** + * Activity + */ + "activity": string; + /** + * Travel & places + */ + "travel_and_places": string; + /** + * Objects + */ + "objects": string; + /** + * Symbols + */ + "symbols": string; + /** + * Flags + */ + "flags": string; + }; } declare const locales: { [lang: string]: Locale; diff --git a/packages/backend/assets/fonts/NewRodinPro-B.ttf b/packages/backend/assets/fonts/NewRodinPro-B.ttf index 4127b273c2..109c21a84d 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-B.ttf and b/packages/backend/assets/fonts/NewRodinPro-B.ttf differ diff --git a/packages/backend/assets/fonts/NewRodinPro-B.woff2 b/packages/backend/assets/fonts/NewRodinPro-B.woff2 index 787a9758a7..040bb6c13e 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-B.woff2 and b/packages/backend/assets/fonts/NewRodinPro-B.woff2 differ diff --git a/packages/backend/assets/fonts/NewRodinPro-DB.ttf b/packages/backend/assets/fonts/NewRodinPro-DB.ttf index a1028ca048..90935cfd6c 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-DB.ttf and b/packages/backend/assets/fonts/NewRodinPro-DB.ttf differ diff --git a/packages/backend/assets/fonts/NewRodinPro-DB.woff2 b/packages/backend/assets/fonts/NewRodinPro-DB.woff2 index 1c401e2299..814d59f6fe 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-DB.woff2 and b/packages/backend/assets/fonts/NewRodinPro-DB.woff2 differ diff --git a/packages/backend/assets/fonts/NewRodinPro-EB.ttf b/packages/backend/assets/fonts/NewRodinPro-EB.ttf index d9d7a7e180..9bbfb39b2b 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-EB.ttf and b/packages/backend/assets/fonts/NewRodinPro-EB.ttf differ diff --git a/packages/backend/assets/fonts/NewRodinPro-EB.woff2 b/packages/backend/assets/fonts/NewRodinPro-EB.woff2 index 79cfa744ed..4f653ce6a6 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-EB.woff2 and b/packages/backend/assets/fonts/NewRodinPro-EB.woff2 differ diff --git a/packages/backend/assets/fonts/NewRodinPro-M.ttf b/packages/backend/assets/fonts/NewRodinPro-M.ttf index 48e906690a..916d4d6a31 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-M.ttf and b/packages/backend/assets/fonts/NewRodinPro-M.ttf differ diff --git a/packages/backend/assets/fonts/NewRodinPro-M.woff2 b/packages/backend/assets/fonts/NewRodinPro-M.woff2 index 9ef38f4ac9..a52cc5ef9d 100644 Binary files a/packages/backend/assets/fonts/NewRodinPro-M.woff2 and b/packages/backend/assets/fonts/NewRodinPro-M.woff2 differ diff --git a/packages/backend/migration/1733435351051-add-emoji-sort-key.js b/packages/backend/migration/1733435351051-add-emoji-sort-key.js new file mode 100644 index 0000000000..7060434cde --- /dev/null +++ b/packages/backend/migration/1733435351051-add-emoji-sort-key.js @@ -0,0 +1,11 @@ +export class AddEmojiSortKey1733435351051 { + name = 'AddEmojiSortKey1733435351051' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "emoji" ADD "sortKey" character varying(64)`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "sortKey"`); + } +} diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index cd906a72af..4958eb376a 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -76,6 +76,7 @@ export class CustomEmojiService implements OnApplicationShutdown { isSensitive: boolean; localOnly: boolean; roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][]; + sortKey: string | null; }, moderator?: MiUser): Promise { const emoji = await this.emojisRepository.insertOne({ id: this.idService.gen(), @@ -91,6 +92,7 @@ export class CustomEmojiService implements OnApplicationShutdown { isSensitive: data.isSensitive, localOnly: data.localOnly, roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction, + sortKey: data.sortKey, }); if (data.host == null) { @@ -121,6 +123,7 @@ export class CustomEmojiService implements OnApplicationShutdown { isSensitive?: boolean; localOnly?: boolean; roleIdsThatCanBeUsedThisEmojiAsReaction?: MiRole['id'][]; + sortKey?: string | null; }, moderator?: MiUser): Promise { const emoji = await this.emojisRepository.findOneByOrFail({ id: id }); const sameNameEmoji = await this.emojisRepository.findOneBy({ name: data.name, host: IsNull() }); @@ -138,6 +141,7 @@ export class CustomEmojiService implements OnApplicationShutdown { publicUrl: data.driveFile != null ? (data.driveFile.webpublicUrl ?? data.driveFile.url) : undefined, type: data.driveFile != null ? (data.driveFile.webpublicType ?? data.driveFile.type) : undefined, roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction ?? undefined, + sortKey: data.sortKey, }); this.localEmojisCache.refresh(); diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts index 841bd731c0..e3ec6b1dee 100644 --- a/packages/backend/src/core/entities/EmojiEntityService.ts +++ b/packages/backend/src/core/entities/EmojiEntityService.ts @@ -34,6 +34,7 @@ export class EmojiEntityService { localOnly: emoji.localOnly ? true : undefined, isSensitive: emoji.isSensitive ? true : undefined, roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length > 0 ? emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : undefined, + sortKey: emoji.sortKey, }; } @@ -62,6 +63,7 @@ export class EmojiEntityService { isSensitive: emoji.isSensitive, localOnly: emoji.localOnly, roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction, + sortKey: emoji.sortKey, }; } diff --git a/packages/backend/src/models/Emoji.ts b/packages/backend/src/models/Emoji.ts index d62b6e9f6f..9ef570deb1 100644 --- a/packages/backend/src/models/Emoji.ts +++ b/packages/backend/src/models/Emoji.ts @@ -81,4 +81,9 @@ export class MiEmoji { array: true, length: 128, default: '{}', }) public roleIdsThatCanBeUsedThisEmojiAsReaction: string[]; + + @Column('varchar', { + length: 64, nullable: true, + }) + public sortKey: string | null; } diff --git a/packages/backend/src/models/json-schema/emoji.ts b/packages/backend/src/models/json-schema/emoji.ts index 62686ad5ae..11b78db1c5 100644 --- a/packages/backend/src/models/json-schema/emoji.ts +++ b/packages/backend/src/models/json-schema/emoji.ts @@ -44,6 +44,10 @@ export const packedEmojiSimpleSchema = { format: 'id', }, }, + sortKey: { + type: 'string', + optional: false, nullable: true, + }, }, } as const; @@ -102,5 +106,9 @@ export const packedEmojiDetailedSchema = { format: 'id', }, }, + sortKey: { + type: 'string', + optional: false, nullable: true, + }, }, } as const; diff --git a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts index 17ba71df3d..07df550114 100644 --- a/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts +++ b/packages/backend/src/queue/processors/ImportCustomEmojisProcessorService.ts @@ -105,6 +105,7 @@ export class ImportCustomEmojisProcessorService { isSensitive: emojiInfo.isSensitive, localOnly: emojiInfo.localOnly, roleIdsThatCanBeUsedThisEmojiAsReaction: [], + sortKey: emojiInfo.sortKey?.normalize('NFC'), }); } catch (e) { if (e instanceof Error || typeof e === 'string') { diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts index b45a3c7156..6267f5b8dd 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts @@ -56,6 +56,7 @@ export const paramDef = { roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: { type: 'string', } }, + sortKey: { type: 'string', nullable: true }, }, required: ['name', 'fileId'], } as const; @@ -91,6 +92,7 @@ export default class extends Endpoint { // eslint- isSensitive: ps.isSensitive ?? false, localOnly: ps.localOnly ?? false, roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [], + sortKey: ps.sortKey?.normalize('NFC') ?? null, }, me); return this.emojiEntityService.packDetailed(emoji); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts index acd2494131..8ae2e85275 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts @@ -97,6 +97,7 @@ export default class extends Endpoint { // eslint- isSensitive: emoji.isSensitive, localOnly: emoji.localOnly, roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction, + sortKey: emoji.sortKey?.normalize('NFC') ?? null, }, me); return this.emojiEntityService.packDetailed(addedEmoji); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts index f35a6667f4..fbc05dabd0 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts @@ -56,6 +56,10 @@ export const meta = { type: 'string', optional: false, nullable: false, }, + sortKey: { + type: 'string', + optional: false, nullable: true, + }, }, }, }, diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts index 3caa0f84a3..957134c1ad 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts @@ -56,6 +56,7 @@ export const paramDef = { roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: { type: 'string', } }, + sortKey: { type: 'string', nullable: true }, }, anyOf: [ { required: ['id'] }, @@ -104,6 +105,7 @@ export default class extends Endpoint { // eslint- isSensitive: ps.isSensitive, localOnly: ps.localOnly, roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction, + sortKey: ps.sortKey, }, me); }); } diff --git a/packages/frontend-embed/vite.config.local-dev.ts b/packages/frontend-embed/vite.config.local-dev.ts index bf2f478887..528e28aa75 100644 --- a/packages/frontend-embed/vite.config.local-dev.ts +++ b/packages/frontend-embed/vite.config.local-dev.ts @@ -31,7 +31,7 @@ const devConfig: UserConfig = { publicDir: '../assets', base: '/embed', server: { - host: 'localhost', + host: true, port: 5174, proxy: { '/api': { diff --git a/packages/frontend-embed/vite.config.ts b/packages/frontend-embed/vite.config.ts index b95533c2cd..785aefbf8b 100644 --- a/packages/frontend-embed/vite.config.ts +++ b/packages/frontend-embed/vite.config.ts @@ -64,6 +64,7 @@ export function getConfig(): UserConfig { server: { port: 5174, + host: true }, plugins: [ diff --git a/packages/frontend/src/components/MkCustomEmojiDetailedDialog.vue b/packages/frontend/src/components/MkCustomEmojiDetailedDialog.vue index c7f1288729..d964061519 100644 --- a/packages/frontend/src/components/MkCustomEmojiDetailedDialog.vue +++ b/packages/frontend/src/components/MkCustomEmojiDetailedDialog.vue @@ -49,6 +49,13 @@ SPDX-License-Identifier: AGPL-3.0-only {{ emoji.url }} + + + + diff --git a/packages/frontend/src/components/MkEmojiPicker.section.vue b/packages/frontend/src/components/MkEmojiPicker.section.vue index 151843b18c..b20d683062 100644 --- a/packages/frontend/src/components/MkEmojiPicker.section.vue +++ b/packages/frontend/src/components/MkEmojiPicker.section.vue @@ -6,9 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only