From 1959194cd62b35ee6cd0f0ff4194cec6129c15d0 Mon Sep 17 00:00:00 2001 From: Caipira Date: Fri, 22 Sep 2023 11:34:50 +0900 Subject: [PATCH 1/2] Merge pull request #371 * feat(backend): Override the file URL rendering in AP --- .config/docker_example.yml | 23 +++++++++++-------- .config/example.yml | 3 +++ .devcontainer/devcontainer.yml | 23 +++++++++++-------- chart/files/default.yml | 23 +++++++++++-------- packages/backend/src/config.ts | 4 ++++ .../src/core/activitypub/ApRendererService.ts | 4 ++-- .../activitypub/models/ApPersonService.ts | 4 ++-- .../core/entities/DriveFileEntityService.ts | 12 +++++++++- 8 files changed, 61 insertions(+), 35 deletions(-) diff --git a/.config/docker_example.yml b/.config/docker_example.yml index 2ec6cf8734..59a0ff7187 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -56,17 +56,17 @@ dbReplications: false # You can configure any number of replicas here #dbSlaves: # - -# host: -# port: -# db: -# user: -# pass: +# host: +# port: +# db: +# user: +# pass: # - -# host: -# port: -# db: -# user: -# pass: +# host: +# port: +# db: +# user: +# pass: # ┌─────────────────────┐ #───┘ Redis configuration └───────────────────────────────────── @@ -154,6 +154,9 @@ id: 'aidx' # saKeyPath: /path/to/service-account-key.json # logName: cherrypick +# Override the file URL rendering in ActivityPub (Object Storage file only) +#apFileBaseUrl: https://example.com/ + # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 diff --git a/.config/example.yml b/.config/example.yml index a74996e463..b38756d1fa 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -172,6 +172,9 @@ id: 'aidx' # saKeyPath: /path/to/service-account-key.json # logName: cherrypick +# Override the file URL rendering in ActivityPub (Object Storage file only) +#apFileBaseUrl: https://example.com/ + # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index 741f768cf0..5f9b66a40d 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -56,17 +56,17 @@ dbReplications: false # You can configure any number of replicas here #dbSlaves: # - -# host: -# port: -# db: -# user: -# pass: +# host: +# port: +# db: +# user: +# pass: # - -# host: -# port: -# db: -# user: -# pass: +# host: +# port: +# db: +# user: +# pass: # ┌─────────────────────┐ #───┘ Redis configuration └───────────────────────────────────── @@ -154,6 +154,9 @@ id: 'aidx' # saKeyPath: /path/to/service-account-key.json # logName: cherrypick +# Override the file URL rendering in ActivityPub (Object Storage file only) +#apFileBaseUrl: https://example.com/ + # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 diff --git a/chart/files/default.yml b/chart/files/default.yml index f209e90a31..178d87026e 100644 --- a/chart/files/default.yml +++ b/chart/files/default.yml @@ -77,17 +77,17 @@ dbReplications: false # You can configure any number of replicas here #dbSlaves: # - -# host: -# port: -# db: -# user: -# pass: +# host: +# port: +# db: +# user: +# pass: # - -# host: -# port: -# db: -# user: -# pass: +# host: +# port: +# db: +# user: +# pass: # ┌─────────────────────┐ #───┘ Redis configuration └───────────────────────────────────── @@ -174,6 +174,9 @@ id: "aidx" # saKeyPath: /path/to/service-account-key.json # logName: cherrypick +# Override the file URL rendering in ActivityPub (Object Storage file only) +#apFileBaseUrl: https://example.com/ + # Proxy for HTTP/HTTPS #proxy: http://127.0.0.1:3128 diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 0798fd1914..ccf7e18f23 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -86,6 +86,8 @@ type Source = { logName?: string; } + apFileBaseUrl?: string; + mediaProxy?: string; proxyRemoteFiles?: boolean; videoThumbnailGenerator?: string; @@ -145,6 +147,7 @@ export type Config = { relashionshipJobPerSec: number | undefined; deliverJobMaxAttempts: number | undefined; inboxJobMaxAttempts: number | undefined; + apFileBaseUrl: string | undefined; proxyRemoteFiles: boolean | undefined; signToActivityPubGet: boolean | undefined; @@ -250,6 +253,7 @@ export function loadConfig(): Config { inboxJobMaxAttempts: config.inboxJobMaxAttempts, proxyRemoteFiles: config.proxyRemoteFiles, signToActivityPubGet: config.signToActivityPubGet, + apFileBaseUrl: config.apFileBaseUrl, mediaProxy: externalMediaProxy ?? internalMediaProxy, externalMediaProxyEnabled: externalMediaProxy !== null && externalMediaProxy !== internalMediaProxy, videoThumbnailGenerator: config.videoThumbnailGenerator ? diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index c967439c12..8e0ae86cb5 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -166,7 +166,7 @@ export class ApRendererService { return { type: 'Document', mediaType: file.webpublicType ?? file.type, - url: this.driveFileEntityService.getPublicUrl(file), + url: this.driveFileEntityService.getPublicUrl(file, undefined, true), name: file.comment, }; } @@ -245,7 +245,7 @@ export class ApRendererService { public renderImage(file: MiDriveFile): IApImage { return { type: 'Image', - url: this.driveFileEntityService.getPublicUrl(file), + url: this.driveFileEntityService.getPublicUrl(file, undefined, true), sensitive: file.isSensitive, name: file.comment, }; diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index 679715f239..52d110f840 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -250,8 +250,8 @@ export class ApPersonService implements OnModuleInit { return { avatarId: avatar?.id ?? null, bannerId: banner?.id ?? null, - avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar') : null, - bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner) : null, + avatarUrl: avatar ? this.driveFileEntityService.getPublicUrl(avatar, 'avatar', true) : null, + bannerUrl: banner ? this.driveFileEntityService.getPublicUrl(banner, undefined, true) : null, avatarBlurhash: avatar?.blurhash ?? null, bannerBlurhash: banner?.blurhash ?? null, }; diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts index 837a7ab13d..c3ad6746cd 100644 --- a/packages/backend/src/core/entities/DriveFileEntityService.ts +++ b/packages/backend/src/core/entities/DriveFileEntityService.ts @@ -107,7 +107,7 @@ export class DriveFileEntityService { } @bindThis - public getPublicUrl(file: MiDriveFile, mode?: 'avatar'): string { // static = thumbnail + public getPublicUrl(file: MiDriveFile, mode?: 'avatar', ap?: boolean): string { // static = thumbnail // リモートかつメディアプロキシ if (file.uri != null && file.userHost != null && this.config.externalMediaProxyEnabled) { return this.getProxiedUrl(file.uri, mode); @@ -129,6 +129,16 @@ export class DriveFileEntityService { if (mode === 'avatar') { return this.getProxiedUrl(url, 'avatar'); } + + if (ap && this.config.apFileBaseUrl) { + const baseUrl = this.config.apFileBaseUrl; + const isValidBaseUrl = /^https?:\/\/[\w.-]+\.[a-zA-Z]{2,}(\/.*)?$/i.test(baseUrl); + if (isValidBaseUrl) { + const trimmedBaseUrl = baseUrl.replace(/\/$/, ''); + return url.replace(/^https?:\/\/[\w.-]+\.[a-zA-Z]{2,}/, trimmedBaseUrl); + } + } + return url; } From d450f27078cd15d76f1ee1be79252b66fa2a3ea6 Mon Sep 17 00:00:00 2001 From: Caipira Date: Fri, 22 Sep 2023 11:35:04 +0900 Subject: [PATCH 2/2] Merge pull request #370 * enhance(frontend): Include fonts in vite build --- packages/frontend/package.json | 3 ++ packages/frontend/src/style.scss | 69 ++++++++++++-------------------- pnpm-lock.yaml | 21 ++++++++++ 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 3c0197538d..90b6f2523e 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@discordapp/twemoji": "14.1.2", + "@fontsource/jetbrains-mono": "^5.0.12", "@github/webauthn-json": "2.1.1", "@rollup/plugin-alias": "5.0.0", "@rollup/plugin-json": "6.0.0", @@ -54,6 +55,8 @@ "json5": "2.2.3", "matter-js": "0.19.0", "photoswipe": "5.4.0", + "pretendard": "^1.3.8", + "pretendard-jp": "^1.3.8", "prismjs": "1.29.0", "punycode": "2.3.0", "querystring": "0.2.1", diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss index c44d37fe88..be88f42078 100644 --- a/packages/frontend/src/style.scss +++ b/packages/frontend/src/style.scss @@ -6,44 +6,28 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -@mixin font($font-family, $font-weight, $font-style, $font-local, $font-url) { - @font-face { - font-family: $font-family; - font-weight: $font-weight; - font-style: $font-style; - font-display: swap; - src: local($font-local), url($font-url) format('woff2'); - } -} +@import "@fontsource/jetbrains-mono/100.css"; +@import "@fontsource/jetbrains-mono/100-italic.css"; +@import "@fontsource/jetbrains-mono/200.css"; +@import "@fontsource/jetbrains-mono/200-italic.css"; +@import "@fontsource/jetbrains-mono/300.css"; +@import "@fontsource/jetbrains-mono/300-italic.css"; +@import "@fontsource/jetbrains-mono/400.css"; +@import "@fontsource/jetbrains-mono/400-italic.css"; +@import "@fontsource/jetbrains-mono/500.css"; +@import "@fontsource/jetbrains-mono/500-italic.css"; +@import "@fontsource/jetbrains-mono/600.css"; +@import "@fontsource/jetbrains-mono/600-italic.css"; +@import "@fontsource/jetbrains-mono/700.css"; +@import "@fontsource/jetbrains-mono/700-italic.css"; +@import "@fontsource/jetbrains-mono/800.css"; +@import "@fontsource/jetbrains-mono/800-italic.css"; +@import "pretendard/dist/web/static/pretendard-dynamic-subset.css"; +@import "pretendard-jp/dist/web/static/pretendard-jp-dynamic-subset.css"; -@include font( - 'Pretendard JP', - 400, - normal, - 'Pretendard JP Regular', - 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard/packages/pretendard-jp/dist/web/static/woff2/PretendardJP-Regular.woff2' -); -@include font( - 'Pretendard JP', - 700, - normal, - 'Pretendard JP Bold', - 'https://cdn.jsdelivr.net/gh/orioncactus/pretendard/packages/pretendard-jp/dist/web/static/woff2/PretendardJP-Bold.woff2' -); -@include font( - 'JetBrains Mono', - 400, - normal, - 'JetBrains Mono Regular', - 'https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@master/fonts/webfonts/JetBrainsMono-Regular.woff2' -); -@include font( - 'JetBrains Mono', - 700, - normal, - 'JetBrains Mono Bold', - 'https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono@master/fonts/webfonts/JetBrainsMono-Bold.woff2' -); +$default-font: "Pretendard JP", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Hiragino Sans", "Apple SD Gothic Neo", Meiryo, "Noto Sans JP", "Noto Sans KR", "Malgun Gothic", Osaka, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif; +$system-font: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", Roboto, "Noto Sans KR", "Segoe UI", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif; +$monospace-font: "JetBrains Mono", "Pretendard JP", Pretendard, Fira code, Fira Mono, Consolas, Menlo, Courier, monospace !important; :root { --radius: 12px; @@ -80,10 +64,7 @@ html { accent-color: var(--accent); overflow: auto; overflow-wrap: break-word; - font-family: "Pretendard JP", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, - Roboto, "Helvetica Neue", "Segoe UI", "Hiragino Sans", "Apple SD Gothic Neo", - Meiryo, "Noto Sans JP", "Noto Sans KR", "Malgun Gothic", Osaka, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif; + font-family: $default-font; // incoming changes from v13 // font-family: 'Hiragino Maru Gothic Pro', "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif; font-size: 14px; @@ -199,7 +180,7 @@ html { } &.useSystemFont { - font-family: system-ui; + font-family: $system-font; } } @@ -515,12 +496,12 @@ hr { } ._monospace { - font-family: "Pretendard JP", "JetBrains Mono", Fira code, Fira Mono, Consolas, Menlo, Courier, monospace !important; + font-family: $monospace-font } code[class*="language-"], pre[class*="language-"] { - font-family: "JetBrains Mono", "Pretendard JP" , Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace !important; + font-family: $monospace-font } .prism-editor__textarea:focus { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4ea1aab5d..480adf7698 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -710,6 +710,9 @@ importers: '@discordapp/twemoji': specifier: 14.1.2 version: 14.1.2 + '@fontsource/jetbrains-mono': + specifier: ^5.0.12 + version: 5.0.12 '@github/webauthn-json': specifier: 2.1.1 version: 2.1.1 @@ -821,6 +824,12 @@ importers: photoswipe: specifier: 5.4.0 version: 5.4.0 + pretendard: + specifier: ^1.3.8 + version: 1.3.8 + pretendard-jp: + specifier: ^1.3.8 + version: 1.3.8 prismjs: specifier: 1.29.0 version: 1.29.0 @@ -3948,6 +3957,10 @@ packages: resolution: {integrity: sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==} dev: true + /@fontsource/jetbrains-mono@5.0.12: + resolution: {integrity: sha512-BO2in8zNXWUn1TJsPWgL2qSMYU2SQKoKOmJ9FRrE9gMFtPhEDKgxc0hUCVmeDUcMFrafFEn+KqZ5a85z8rwMzA==} + dev: false + /@github/webauthn-json@2.1.1: resolution: {integrity: sha512-XrftRn4z75SnaJOmZQbt7Mk+IIjqVHw+glDGOxuHwXkZBZh/MBoRS7MHjSZMDaLhT4RjN2VqiEU7EOYleuJWSQ==} hasBin: true @@ -16915,6 +16928,14 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /pretendard-jp@1.3.8: + resolution: {integrity: sha512-yRnEWummLceSk+J5iNPo9DU650PCHW9PpnqqykNFZYZk/mLTt9b/D5n295pK05Udoki8IRq21qyzGmvn5VChjQ==} + dev: false + + /pretendard@1.3.8: + resolution: {integrity: sha512-LTuUQsX0tE4vQVS4pL5xZ7p0Z4/sOZxZxeENydS0NnhDE4EOu+3pPQS1hoa9EIbaNuy+lL4P9ngAuXhD/FluiQ==} + dev: false + /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'}