From d7b443d1f043eb6a903991ed08733cb294720295 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:21:32 +0900 Subject: [PATCH 01/14] chore: update `.swcrc` schema link (#15428) --- packages/backend/test-server/.swcrc | 2 +- packages/misskey-js/.swcrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/test-server/.swcrc b/packages/backend/test-server/.swcrc index e3d6935169..eeac7eabc6 100644 --- a/packages/backend/test-server/.swcrc +++ b/packages/backend/test-server/.swcrc @@ -1,5 +1,5 @@ { - "$schema": "https://json.schemastore.org/swcrc", + "$schema": "https://swc.rs/schema.json", "jsc": { "parser": { "syntax": "typescript", diff --git a/packages/misskey-js/.swcrc b/packages/misskey-js/.swcrc index 0504a2d389..6fd7486370 100644 --- a/packages/misskey-js/.swcrc +++ b/packages/misskey-js/.swcrc @@ -1,5 +1,5 @@ { - "$schema": "https://json.schemastore.org/swcrc", + "$schema": "https://swc.rs/schema.json", "jsc": { "parser": { "syntax": "typescript", From a3cc865e118f645e2af8f0d45f0fb630c7ec785c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:28:05 +0900 Subject: [PATCH 02/14] =?UTF-8?q?fix(ci):=20okteto=E3=81=AE=E5=B0=8E?= =?UTF-8?q?=E7=B7=9A=E3=82=92=E5=89=8A=E9=99=A4=20(#15427)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ok-to-test.yml | 36 ---------- .github/workflows/pr-preview-deploy.yml | 92 ------------------------ .github/workflows/pr-preview-destroy.yml | 54 -------------- 3 files changed, 182 deletions(-) delete mode 100644 .github/workflows/ok-to-test.yml delete mode 100644 .github/workflows/pr-preview-deploy.yml delete mode 100644 .github/workflows/pr-preview-destroy.yml diff --git a/.github/workflows/ok-to-test.yml b/.github/workflows/ok-to-test.yml deleted file mode 100644 index 8362c006eb..0000000000 --- a/.github/workflows/ok-to-test.yml +++ /dev/null @@ -1,36 +0,0 @@ -# If someone with write access comments "/ok-to-test" on a pull request, emit a repository_dispatch event -name: Ok To Test - -on: - issue_comment: - types: [created] - -jobs: - ok-to-test: - runs-on: ubuntu-latest - # Only run for PRs, not issue comments - if: ${{ github.event.issue.pull_request }} - steps: - # Generate a GitHub App installation access token from an App ID and private key - # To create a new GitHub App: - # https://developer.github.com/apps/building-github-apps/creating-a-github-app/ - # See app.yml for an example app manifest - - name: Generate token - id: generate_token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.DEPLOYBOT_APP_ID }} - private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }} - - - name: Slash Command Dispatch - uses: peter-evans/slash-command-dispatch@v4 - env: - TOKEN: ${{ steps.generate_token.outputs.token }} - with: - token: ${{ env.TOKEN }} # GitHub App installation access token - # token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} # PAT or OAuth token will also work - reaction-token: ${{ secrets.GITHUB_TOKEN }} - issue-type: pull-request - commands: deploy - named-args: true - permission: write diff --git a/.github/workflows/pr-preview-deploy.yml b/.github/workflows/pr-preview-deploy.yml deleted file mode 100644 index 964d24c3d7..0000000000 --- a/.github/workflows/pr-preview-deploy.yml +++ /dev/null @@ -1,92 +0,0 @@ -# Run secret-dependent integration tests only after /deploy approval -on: - repository_dispatch: - types: [deploy-command] - -name: Deploy preview environment - -jobs: - # Repo owner has commented /deploy on a (fork-based) pull request - deploy-preview-environment: - runs-on: ubuntu-latest - if: - github.event.client_payload.slash_command.sha != '' && - contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha) - steps: - - uses: actions/github-script@v7.0.1 - id: check-id - env: - number: ${{ github.event.client_payload.pull_request.number }} - job: ${{ github.job }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - result-encoding: string - script: | - const { data: pull } = await github.rest.pulls.get({ - ...context.repo, - pull_number: process.env.number - }); - const ref = pull.head.sha; - - const { data: checks } = await github.rest.checks.listForRef({ - ...context.repo, - ref - }); - - const check = checks.check_runs.filter(c => c.name === process.env.job); - - return check[0].id; - - - uses: actions/github-script@v7.0.1 - env: - check_id: ${{ steps.check-id.outputs.result }} - details_url: ${{ github.server_url }}/${{ github.repository }}/runs/${{ github.run_id }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - await github.rest.checks.update({ - ...context.repo, - check_run_id: process.env.check_id, - status: 'in_progress', - details_url: process.env.details_url - }); - - # Check out merge commit - - name: Fork based /deploy checkout - uses: actions/checkout@v4.1.1 - with: - ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge' - - # - - name: Context - uses: okteto/context@latest - with: - token: ${{ secrets.OKTETO_TOKEN }} - - - name: Deploy preview environment - uses: ikuradon/deploy-preview@latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - name: pr-${{ github.event.client_payload.pull_request.number }}-syuilo - timeout: 15m - - # Update check run called "integration-fork" - - uses: actions/github-script@v7.0.1 - id: update-check-run - if: ${{ always() }} - env: - # Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run - conclusion: ${{ job.status }} - check_id: ${{ steps.check-id.outputs.result }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { data: result } = await github.rest.checks.update({ - ...context.repo, - check_run_id: process.env.check_id, - status: 'completed', - conclusion: process.env.conclusion - }); - - return result; diff --git a/.github/workflows/pr-preview-destroy.yml b/.github/workflows/pr-preview-destroy.yml deleted file mode 100644 index 8967eb2f94..0000000000 --- a/.github/workflows/pr-preview-destroy.yml +++ /dev/null @@ -1,54 +0,0 @@ -# file: .github/workflows/preview-closed.yaml -on: - pull_request: - types: - - closed - -name: Destroy preview environment - -jobs: - destroy-preview-environment: - runs-on: ubuntu-latest - steps: - - uses: actions/github-script@v7.0.1 - id: check-conclusion - env: - number: ${{ github.event.number }} - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - result-encoding: string - script: | - const { data: pull } = await github.rest.pulls.get({ - ...context.repo, - pull_number: process.env.number - }); - const ref = pull.head.sha; - - const { data: checks } = await github.rest.checks.listForRef({ - ...context.repo, - ref - }); - - const check = checks.check_runs.filter(c => c.name === 'deploy-preview-environment'); - - if (check.length === 0) { - return; - } - - const { data: result } = await github.rest.checks.get({ - ...context.repo, - check_run_id: check[0].id, - }); - - return result.conclusion; - - name: Context - if: steps.check-conclusion.outputs.result == 'success' - uses: okteto/context@latest - with: - token: ${{ secrets.OKTETO_TOKEN }} - - - name: Destroy preview environment - if: steps.check-conclusion.outputs.result == 'success' - uses: okteto/destroy-preview@latest - with: - name: pr-${{ github.event.number }}-syuilo From 54fc232a23742ca62232d35c8e976cbec40a61d2 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:29:24 +0900 Subject: [PATCH 03/14] fix(backend): use unique `operationId` in the OpenAPI schema (#15420) * fix(backend): use unique `operationId` in the OpenAPI schema * fix: read with UTF-8 encoding --- .../src/server/api/openapi/gen-spec.ts | 10 ++++-- .../misskey-js/generator/src/generator.ts | 33 ++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index 3b20ec1321..ea64e32ee6 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -210,9 +210,15 @@ export function genOpenapiSpec(config: Config, includeSelfRef = false) { spec.paths['/' + endpoint.name] = { ...(endpoint.meta.allowGet ? { - get: info, + get: { + ...info, + operationId: 'get___' + info.operationId, + }, } : {}), - post: info, + post: { + ...info, + operationId: 'post___' + info.operationId, + }, }; } diff --git a/packages/misskey-js/generator/src/generator.ts b/packages/misskey-js/generator/src/generator.ts index 88f2ae9ee9..a77ffeedc2 100644 --- a/packages/misskey-js/generator/src/generator.ts +++ b/packages/misskey-js/generator/src/generator.ts @@ -1,8 +1,9 @@ -import { mkdir, writeFile } from 'fs/promises'; +import assert from 'assert'; +import { mkdir, readFile, writeFile } from 'fs/promises'; import { OpenAPIV3_1 } from 'openapi-types'; import { toPascal } from 'ts-case-convert'; import OpenAPIParser from '@readme/openapi-parser'; -import openapiTS from 'openapi-typescript'; +import openapiTS, { OpenAPI3, OperationObject, PathItemObject } from 'openapi-typescript'; async function generateBaseTypes( openApiDocs: OpenAPIV3_1.Document, @@ -20,7 +21,29 @@ async function generateBaseTypes( } lines.push(''); - const generatedTypes = await openapiTS(openApiJsonPath, { + // NOTE: Align `operationId` of GET and POST to avoid duplication of type definitions + const openApi = JSON.parse(await readFile(openApiJsonPath, 'utf8')) as OpenAPI3; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + for (const [key, item] of Object.entries(openApi.paths!)) { + assert('post' in item); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + openApi.paths![key] = { + ...('get' in item ? { + get: { + ...item.get, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + operationId: ((item as PathItemObject).get as OperationObject).operationId!.replaceAll('get___', ''), + }, + } : {}), + post: { + ...item.post, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + operationId: ((item as PathItemObject).post as OperationObject).operationId!.replaceAll('post___', ''), + }, + }; + } + + const generatedTypes = await openapiTS(openApi, { exportType: true, transform(schemaObject) { if ('format' in schemaObject && schemaObject.format === 'binary') { @@ -78,7 +101,7 @@ async function generateEndpoints( for (const operation of postPathItems) { const path = operation._path_; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const operationId = operation.operationId!; + const operationId = operation.operationId!.replaceAll('get___', '').replaceAll('post___', ''); const endpoint = new Endpoint(path); endpoints.push(endpoint); @@ -195,7 +218,7 @@ async function generateApiClientJSDoc( for (const operation of postPathItems) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const operationId = operation.operationId!; + const operationId = operation.operationId!.replaceAll('get___', '').replaceAll('post___', ''); if (operation.description) { endpoints.push({ From 026ec40b3b5da29362491841d20f3fd7659c4ce5 Mon Sep 17 00:00:00 2001 From: Esurio/1673beta <60435625+1673beta@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:29:51 +0900 Subject: [PATCH 04/14] =?UTF-8?q?fix(dev):=20devcontainer=E3=81=AEcorepack?= =?UTF-8?q?=E3=81=AE=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=20(#15415)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .devcontainer/devcontainer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 713c2e5fdd..8dd9d1c704 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,9 @@ "ghcr.io/devcontainers/features/node:1": { "version": "22.11.0" }, - "ghcr.io/devcontainers-contrib/features/corepack:1": {} + "ghcr.io/devcontainers-extra/features/corepack:1": { + "version": "0.31.0" + } }, "forwardPorts": [3000], "postCreateCommand": "/bin/bash .devcontainer/init.sh", From 4b98b446bee6eefb05141d6d400271ba131e709d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:31:28 +0900 Subject: [PATCH 05/14] =?UTF-8?q?enhance(frontend):=20=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=82=A2=E3=83=B3=E3=83=88=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E7=94=BB=E9=9D=A2=E3=81=AE=E5=A4=9A=E8=A8=80=E8=AA=9E=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C=20(#15411)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * enhance(frontend): クライアントエラー画面のマルチリンガル対応 * Update Changelog * update message --- CHANGELOG.md | 1 + locales/index.d.ts | 46 +++++++++++++++++++ locales/ja-JP.yml | 13 ++++++ packages/backend/src/server/web/boot.embed.js | 12 +++-- packages/backend/src/server/web/boot.js | 38 ++++++++++----- 5 files changed, 95 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 596bd62be9..4be21b1444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Client - Enhance: 投稿フォームの「迷惑になる可能性があります」のダイアログを表示する条件においてCWを考慮するように - Enhance: アンテナ、リスト等の名前をカラム名のデフォルト値にするように `#13992` +- Enhance: クライアントエラー画面の多言語対応 ### Server - diff --git a/locales/index.d.ts b/locales/index.d.ts index 4e26d5406b..4e4e95b6ed 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -10944,6 +10944,52 @@ export interface Locale extends ILocale { }; }; }; + "_bootErrors": { + /** + * 読み込みに失敗しました + */ + "title": string; + /** + * 少し待ってからリロードしてもまだ問題が解決されない場合、以下のError IDを添えてサーバー管理者に連絡してください。 + */ + "serverError": string; + /** + * 以下を行うと解決する可能性があります。 + */ + "solution": string; + /** + * ブラウザおよびOSを最新バージョンに更新する + */ + "solution1": string; + /** + * アドブロッカーを無効にする + */ + "solution2": string; + /** + * ブラウザのキャッシュをクリアする + */ + "solution3": string; + /** + * (Tor Browser) dom.webaudio.enabledをtrueに設定する + */ + "solution4": string; + /** + * その他のオプション + */ + "otherOption": string; + /** + * クライアント設定とキャッシュを削除 + */ + "otherOption1": string; + /** + * 簡易クライアントを起動 + */ + "otherOption2": string; + /** + * 修復ツールを起動 + */ + "otherOption3": string; + }; } declare const locales: { [lang: string]: Locale; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 13d8aec9b8..ea18cc063c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -2927,3 +2927,16 @@ _captcha: _unknown: title: "CAPTCHAエラー" text: "想定外のエラーが発生しました。" + +_bootErrors: + title: "読み込みに失敗しました" + serverError: "少し待ってからリロードしてもまだ問題が解決されない場合、以下のError IDを添えてサーバー管理者に連絡してください。" + solution: "以下を行うと解決する可能性があります。" + solution1: "ブラウザおよびOSを最新バージョンに更新する" + solution2: "アドブロッカーを無効にする" + solution3: "ブラウザのキャッシュをクリアする" + solution4: "(Tor Browser) dom.webaudio.enabledをtrueに設定する" + otherOption: "その他のオプション" + otherOption1: "クライアント設定とキャッシュを削除" + otherOption2: "簡易クライアントを起動" + otherOption3: "修復ツールを起動" diff --git a/packages/backend/src/server/web/boot.embed.js b/packages/backend/src/server/web/boot.embed.js index 48d1cd262b..9de1275380 100644 --- a/packages/backend/src/server/web/boot.embed.js +++ b/packages/backend/src/server/web/boot.embed.js @@ -114,13 +114,17 @@ if (document.readyState === 'loading') { await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve)); } + + const locale = JSON.parse(localStorage.getItem('locale') || '{}'); + + const title = locale?._bootErrors?.title || 'Failed to initialize Misskey'; + const reload = locale?.reload || 'Reload'; + document.body.innerHTML = ` -
読み込みに失敗しました
-
Failed to initialize Misskey
+
${title}
Error Code: ${code}
`; addStyle(` #misskey_app, diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index a04640d993..b55d327f86 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -151,6 +151,22 @@ await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve)); } + const locale = JSON.parse(localStorage.getItem('locale') || '{}'); + + const messages = Object.assign({ + title: 'Failed to initialize Misskey', + solution: 'The following actions may solve the problem.', + solution1: 'Update your os and browser', + solution2: 'Disable an adblocker', + solution3: 'Clear the browser cache', + solution4: '(Tor Browser) Set dom.webaudio.enabled to true', + otherOption: 'Other options', + otherOption1: 'Clear preferences and cache', + otherOption2: 'Start the simple client', + otherOption3: 'Start the repair tool', + }, locale?._bootErrors || {}); + const reload = locale?.reload || 'Reload'; + let errorsElement = document.getElementById('errors'); if (!errorsElement) { @@ -160,32 +176,32 @@ -

Failed to load
読み込みに失敗しました

+

${messages.title}

-

The following actions may solve the problem. / 以下を行うと解決する可能性があります。

-

Update your os and browser / ブラウザおよびOSを最新バージョンに更新する

-

Disable an adblocker / アドブロッカーを無効にする

-

Clear the browser cache / ブラウザのキャッシュをクリアする

-

(Tor Browser) Set dom.webaudio.enabled to true / dom.webaudio.enabledをtrueに設定する

+

${messages.solution}

+

${messages.solution1}

+

${messages.solution2}

+

${messages.solution3}

+

${messages.solution4}

- Other options / その他のオプション + ${messages.otherOption}

From 2f8d02024a389181794ee9e8f2b70ffbd057cf6f Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:33:09 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat(frontend):=20=E7=94=BB=E5=83=8F?= =?UTF-8?q?=E3=82=92=E6=8A=95=E7=A8=BF=E5=89=8D=E3=81=AB=E3=83=97=E3=83=AC?= =?UTF-8?q?=E3=83=93=E3=83=A5=E3=83=BC=E5=8F=AF=E8=83=BD=E3=81=AB=20(#1534?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(client): 画像をプレビュー可能に * Update Changelog * SPDX * 消えてたのFix * Add storybook for MkImgPreviewDialog * backgroundのスタイル変更 Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> * Add MkImgPreviewDialog to storybook generator * Update packages/frontend/.storybook/generate.tsx --------- Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> --- CHANGELOG.md | 1 + packages/frontend/.storybook/generate.tsx | 1 + .../MkImgPreviewDialog.stories.impl.ts | 40 +++++++++++++ .../src/components/MkImgPreviewDialog.vue | 58 +++++++++++++++++++ .../src/components/MkPostFormAttaches.vue | 20 +++++-- 5 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 packages/frontend/src/components/MkImgPreviewDialog.stories.impl.ts create mode 100644 packages/frontend/src/components/MkImgPreviewDialog.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index 4be21b1444..1f07185516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ * β版として公開のため、旧画面も引き続き利用可能です ### Client +- Feat: 投稿フォームで画像をプレビュー可能に - Enhance: PC画面でチャンネルが複数列で表示されるように (Cherry-picked from https://github.com/Otaku-Social/maniakey/pull/13) - Enhance: 照会に失敗した場合、その理由を表示するように diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index 8830523810..3cd08191f5 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -414,6 +414,7 @@ function toStories(component: string): Promise { glob('src/components/MkSignupServerRules.vue'), glob('src/components/MkUserSetupDialog.vue'), glob('src/components/MkUserSetupDialog.*.vue'), + glob('src/components/MkImgPreviewDialog.vue'), glob('src/components/MkInstanceCardMini.vue'), glob('src/components/MkInviteCode.vue'), glob('src/components/MkTagItem.vue'), diff --git a/packages/frontend/src/components/MkImgPreviewDialog.stories.impl.ts b/packages/frontend/src/components/MkImgPreviewDialog.stories.impl.ts new file mode 100644 index 0000000000..339e6d10f3 --- /dev/null +++ b/packages/frontend/src/components/MkImgPreviewDialog.stories.impl.ts @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { StoryObj } from '@storybook/vue3'; +import { file } from '../../.storybook/fakes.js'; +import MkImgPreviewDialog from './MkImgPreviewDialog.vue'; +export const Default = { + render(args) { + return { + components: { + MkImgPreviewDialog, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '', + }; + }, + args: { + file: file(), + }, + parameters: { + chromatic: { + // NOTE: ロードが終わるまで待つ + delay: 3000, + }, + layout: 'centered', + }, +} satisfies StoryObj; diff --git a/packages/frontend/src/components/MkImgPreviewDialog.vue b/packages/frontend/src/components/MkImgPreviewDialog.vue new file mode 100644 index 0000000000..3e6e4e0ec9 --- /dev/null +++ b/packages/frontend/src/components/MkImgPreviewDialog.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/packages/frontend/src/components/MkPostFormAttaches.vue b/packages/frontend/src/components/MkPostFormAttaches.vue index 1336b61356..33fe82b759 100644 --- a/packages/frontend/src/components/MkPostFormAttaches.vue +++ b/packages/frontend/src/components/MkPostFormAttaches.vue @@ -22,20 +22,24 @@ SPDX-License-Identifier: AGPL-3.0-only -

{{ 16 - props.modelValue.length }}/16

+

+ {{ 16 - props.modelValue.length }}/16 +