From cb668b22ade96151bc97435f6e01e1221e095ff7 Mon Sep 17 00:00:00 2001 From: samunohito <46447427+samunohito@users.noreply.github.com> Date: Mon, 26 Feb 2024 07:27:41 +0900 Subject: [PATCH] =?UTF-8?q?=E8=AA=B2=E9=A1=8C=E3=81=AF=E3=81=BE=E3=81=A0?= =?UTF-8?q?=E6=AE=8B=E3=81=A3=E3=81=A6=E3=81=84=E3=82=8B=E3=81=8C=E3=80=81?= =?UTF-8?q?=E3=81=B2=E3=81=A8=E3=81=BE=E3=81=9A=E5=AE=8C=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/.storybook/fake-utils.ts | 21 ++++- .../custom-emojis-manager2.stories.impl.ts | 83 ++++++++++++++++++- 2 files changed, 98 insertions(+), 6 deletions(-) diff --git a/packages/frontend/.storybook/fake-utils.ts b/packages/frontend/.storybook/fake-utils.ts index 330acf95f6..6506121037 100644 --- a/packages/frontend/.storybook/fake-utils.ts +++ b/packages/frontend/.storybook/fake-utils.ts @@ -1,7 +1,9 @@ +import crypto from "node:crypto"; + /** * AIで生成した無作為なファーストネーム */ -export const firstNameDict: string = [ +export const firstNameDict = [ 'Ethan', 'Olivia', 'Jackson', 'Emma', 'Liam', 'Ava', 'Aiden', 'Sophia', 'Mason', 'Isabella', 'Noah', 'Mia', 'Lucas', 'Harper', 'Caleb', 'Abigail', 'Samuel', 'Emily', 'Logan', 'Madison', 'Benjamin', 'Chloe', 'Elijah', 'Grace', 'Alexander', 'Scarlett', 'William', 'Zoey', 'James', 'Lily', @@ -10,7 +12,7 @@ export const firstNameDict: string = [ /** * AIで生成した無作為なラストネーム */ -export const lastNameDict: string = [ +export const lastNameDict = [ 'Anderson', 'Johnson', 'Thompson', 'Davis', 'Rodriguez', 'Smith', 'Patel', 'Williams', 'Lee', 'Brown', 'Garcia', 'Jackson', 'Martinez', 'Taylor', 'Harris', 'Nguyen', 'Miller', 'Jones', 'Wilson', 'White', 'Thomas', 'Garcia', 'Martinez', 'Robinson', 'Turner', 'Lewis', 'Hall', 'King', 'Baker', 'Cooper', @@ -19,7 +21,7 @@ export const lastNameDict: string = [ /** * AIで生成した無作為な国名 */ -export const countryDict: string = [ +export const countryDict = [ 'Japan', 'Canada', 'Brazil', 'Australia', 'Italy', 'SouthAfrica', 'Mexico', 'Sweden', 'Russia', 'India', 'Germany', 'Argentina', 'South Korea', 'France', 'Nigeria', 'Turkey', 'Spain', 'Egypt', 'Thailand', 'Vietnam', 'Kenya', 'Saudi Arabia', 'Netherlands', 'Colombia', 'Poland', 'Chile', 'Malaysia', 'Ukraine', 'New Zealand', 'Peru', @@ -94,6 +96,19 @@ export function country(): string { return choose(countryDict); } +const TIME2000 = 946684800000; +export function fakeId(): string { + let time = new Date().getTime(); + + time = time - TIME2000; + if (time < 0) time = 0; + + const timeStr = time.toString(36).padStart(8, '0'); + const noiseStr = text(2); + + return timeStr + noiseStr; +} + export function imageDataUrl(options?: { size?: { width?: number, diff --git a/packages/frontend/src/pages/admin/custom-emojis-manager2.stories.impl.ts b/packages/frontend/src/pages/admin/custom-emojis-manager2.stories.impl.ts index 21e84d4e47..c4c5a66241 100644 --- a/packages/frontend/src/pages/admin/custom-emojis-manager2.stories.impl.ts +++ b/packages/frontend/src/pages/admin/custom-emojis-manager2.stories.impl.ts @@ -8,11 +8,15 @@ import { StoryObj } from '@storybook/vue3'; import { entities } from 'misskey-js'; import { commonHandlers } from '../../../.storybook/mocks.js'; import { emoji } from '../../../.storybook/fakes.js'; +import { fakeId } from '../../../.storybook/fake-utils.js'; import custom_emojis_manager2 from './custom-emojis-manager2.vue'; function createRender(params: { emojis: entities.EmojiDetailedAdmin[]; }) { + const storedEmojis: entities.EmojiDetailedAdmin[] = [...params.emojis]; + const storedDriveFiles: entities.DriveFile[] = []; + return { render(args) { return { @@ -42,13 +46,13 @@ function createRender(params: { msw: { handlers: [ ...commonHandlers, - http.post('/api/admin/emoji/v2/list', async (req) => { + http.post('/api/admin/emoji/v2/list', async ({ request }) => { await delay(100); - const bodyStream = req.request.body as ReadableStream; + const bodyStream = request.body as ReadableStream; const body = await new Response(bodyStream).json() as entities.AdminEmojiV2ListRequest; - const emojis = params.emojis; + const emojis = storedEmojis; const limit = body.limit ?? 10; const page = body.page ?? 1; const result = emojis.slice((page - 1) * limit, page * limit); @@ -60,6 +64,79 @@ function createRender(params: { allPages: Math.ceil(emojis.length / limit), }); }), + http.post('/api/drive/folders', () => { + return HttpResponse.json([]); + }), + http.post('/api/drive/files', () => { + return HttpResponse.json(storedDriveFiles); + }), + http.post('/api/drive/files/create', async ({ request }) => { + const data = await request.formData(); + const file = data.get('file'); + if (!file || !(file instanceof File)) { + return HttpResponse.json({ error: 'file is required' }, { + status: 400, + }); + } + + // FIXME: ファイルのバイナリに0xEF 0xBF 0xBDが混入してしまい、うまく画像ファイルとして表示できない問題がある + const base64 = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onload = () => { + resolve(reader.result as string); + }; + reader.readAsDataURL(new Blob([file], { type: 'image/webp' })); + }); + + const driveFile: entities.DriveFile = { + id: fakeId(), + createdAt: new Date().toISOString(), + name: file.name, + type: file.type, + md5: '', + size: file.size, + isSensitive: false, + blurhash: null, + properties: {}, + url: base64, + thumbnailUrl: null, + comment: null, + folderId: null, + folder: null, + userId: null, + user: null, + }; + + storedDriveFiles.push(driveFile); + + return HttpResponse.json(driveFile); + }), + http.post('api/admin/emoji/add', async ({ request }) => { + await delay(100); + + const bodyStream = request.body as ReadableStream; + const body = await new Response(bodyStream).json() as entities.AdminEmojiAddRequest; + + const fileId = body.fileId; + const file = storedDriveFiles.find(f => f.id === fileId); + + const em = emoji({ + id: fakeId(), + name: body.name, + url: body.url, + publicUrl: file.url, + originalUrl: file.url, + type: file.type, + aliases: body.aliases, + category: body.category, + license: body.license, + localOnly: body.localOnly, + isSensitive: body.isSensitive, + }); + storedEmojis.push(em); + + return HttpResponse.json(null); + }), ], }, },