mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	* test(storybook): add `components/Mk[D-E].*` stories * fix: mock instance name * fix: invalid `reactionAcceptance` value * style: missing trailing commas
This commit is contained in:
		
							parent
							
								
									5c42a0e439
								
							
						
					
					
						commit
						c7354c5e30
					
				
					 17 changed files with 597 additions and 17 deletions
				
			
		| 
						 | 
					@ -47,18 +47,7 @@ export function clip(id = 'someclipid', name = 'Some Clip'): entities.Clip {
 | 
				
			||||||
		createdAt: '2016-12-28T22:49:51.000Z',
 | 
							createdAt: '2016-12-28T22:49:51.000Z',
 | 
				
			||||||
		lastClippedAt: null,
 | 
							lastClippedAt: null,
 | 
				
			||||||
		userId: 'someuserid',
 | 
							userId: 'someuserid',
 | 
				
			||||||
		user: {
 | 
							user: userLite(),
 | 
				
			||||||
			id: 'someuserid',
 | 
					 | 
				
			||||||
			name: 'Misskey User',
 | 
					 | 
				
			||||||
			username: 'miskist',
 | 
					 | 
				
			||||||
			host: 'misskey-hub.net',
 | 
					 | 
				
			||||||
			avatarUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/about-icon.png?raw=true',
 | 
					 | 
				
			||||||
			avatarBlurhash: 'eQFRshof5NWBRi},juayfPju53WB?0ofs;s*a{ofjuay^SoMEJR%ay',
 | 
					 | 
				
			||||||
			avatarDecorations: [],
 | 
					 | 
				
			||||||
			emojis: {},
 | 
					 | 
				
			||||||
			badgeRoles: [],
 | 
					 | 
				
			||||||
			onlineStatus: 'unknown',
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		notesCount: undefined,
 | 
							notesCount: undefined,
 | 
				
			||||||
		name,
 | 
							name,
 | 
				
			||||||
		description: 'Some clip description',
 | 
							description: 'Some clip description',
 | 
				
			||||||
| 
						 | 
					@ -125,6 +114,15 @@ export function file(isSensitive = false) {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function folder(id = 'somefolderid', name = 'Some Folder', parentId: string | null = null): entities.DriveFolder {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							id,
 | 
				
			||||||
 | 
							createdAt: '2016-12-28T22:49:51.000Z',
 | 
				
			||||||
 | 
							name,
 | 
				
			||||||
 | 
							parentId,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function federationInstance(): entities.FederationInstance {
 | 
					export function federationInstance(): entities.FederationInstance {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		id: 'someinstanceid',
 | 
							id: 'someinstanceid',
 | 
				
			||||||
| 
						 | 
					@ -154,7 +152,27 @@ export function federationInstance(): entities.FederationInstance {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function userDetailed(id = 'someuserid', username = 'miskist', host:entities.UserDetailed['host'] = 'misskey-hub.net', name:entities.UserDetailed['name'] = 'Misskey User'): entities.UserDetailed {
 | 
					export function note(id = 'somenoteid'): entities.Note {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							id,
 | 
				
			||||||
 | 
							createdAt: '2016-12-28T22:49:51.000Z',
 | 
				
			||||||
 | 
							deletedAt: null,
 | 
				
			||||||
 | 
							text: 'some note',
 | 
				
			||||||
 | 
							cw: null,
 | 
				
			||||||
 | 
							userId: 'someuserid',
 | 
				
			||||||
 | 
							user: userLite(),
 | 
				
			||||||
 | 
							visibility: 'public',
 | 
				
			||||||
 | 
							reactionAcceptance: 'nonSensitiveOnly',
 | 
				
			||||||
 | 
							reactionEmojis: {},
 | 
				
			||||||
 | 
							reactions: {},
 | 
				
			||||||
 | 
							myReaction: null,
 | 
				
			||||||
 | 
							reactionCount: 0,
 | 
				
			||||||
 | 
							renoteCount: 0,
 | 
				
			||||||
 | 
							repliesCount: 0,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function userLite(id = 'someuserid', username = 'miskist', host: entities.UserDetailed['host'] = 'misskey-hub.net', name: entities.UserDetailed['name'] = 'Misskey User'): entities.UserLite {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		id,
 | 
							id,
 | 
				
			||||||
		username,
 | 
							username,
 | 
				
			||||||
| 
						 | 
					@ -165,6 +183,12 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host:entit
 | 
				
			||||||
		avatarBlurhash: 'eQFRshof5NWBRi},juayfPju53WB?0ofs;s*a{ofjuay^SoMEJR%ay',
 | 
							avatarBlurhash: 'eQFRshof5NWBRi},juayfPju53WB?0ofs;s*a{ofjuay^SoMEJR%ay',
 | 
				
			||||||
		avatarDecorations: [],
 | 
							avatarDecorations: [],
 | 
				
			||||||
		emojis: {},
 | 
							emojis: {},
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function userDetailed(id = 'someuserid', username = 'miskist', host: entities.UserDetailed['host'] = 'misskey-hub.net', name: entities.UserDetailed['name'] = 'Misskey User'): entities.UserDetailed {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							...userLite(id, username, host, name),
 | 
				
			||||||
		bannerBlurhash: 'eQA^IW^-MH8w9tE8I=S^o{$*R4RikXtSxutRozjEnNR.RQadoyozog',
 | 
							bannerBlurhash: 'eQA^IW^-MH8w9tE8I=S^o{$*R4RikXtSxutRozjEnNR.RQadoyozog',
 | 
				
			||||||
		bannerUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true',
 | 
							bannerUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true',
 | 
				
			||||||
		birthday: '2014-06-20',
 | 
							birthday: '2014-06-20',
 | 
				
			||||||
| 
						 | 
					@ -215,7 +239,7 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host:entit
 | 
				
			||||||
		movedTo: null,
 | 
							movedTo: null,
 | 
				
			||||||
		alsoKnownAs: null,
 | 
							alsoKnownAs: null,
 | 
				
			||||||
		notify: 'none',
 | 
							notify: 'none',
 | 
				
			||||||
		memo: null
 | 
							memo: null,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -397,8 +397,7 @@ function toStories(component: string): Promise<string> {
 | 
				
			||||||
	const globs = await Promise.all([
 | 
						const globs = await Promise.all([
 | 
				
			||||||
		glob('src/components/global/Mk*.vue'),
 | 
							glob('src/components/global/Mk*.vue'),
 | 
				
			||||||
		glob('src/components/global/RouterView.vue'),
 | 
							glob('src/components/global/RouterView.vue'),
 | 
				
			||||||
		glob('src/components/Mk[A-C]*.vue'),
 | 
							glob('src/components/Mk[A-E]*.vue'),
 | 
				
			||||||
		glob('src/components/MkDigitalClock.vue'),
 | 
					 | 
				
			||||||
		glob('src/components/MkGalleryPostPreview.vue'),
 | 
							glob('src/components/MkGalleryPostPreview.vue'),
 | 
				
			||||||
		glob('src/components/MkSignupServerRules.vue'),
 | 
							glob('src/components/MkSignupServerRules.vue'),
 | 
				
			||||||
		glob('src/components/MkUserSetupDialog.vue'),
 | 
							glob('src/components/MkUserSetupDialog.vue'),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkDateSeparatedList from './MkDateSeparatedList.vue';
 | 
				
			||||||
 | 
					void MkDateSeparatedList;
 | 
				
			||||||
							
								
								
									
										159
									
								
								packages/frontend/src/components/MkDialog.stories.impl.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								packages/frontend/src/components/MkDialog.stories.impl.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,159 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { action } from '@storybook/addon-actions';
 | 
				
			||||||
 | 
					import { expect, userEvent, waitFor, within } from '@storybook/test';
 | 
				
			||||||
 | 
					import { StoryObj } from '@storybook/vue3';
 | 
				
			||||||
 | 
					import { i18n } from '@/i18n.js';
 | 
				
			||||||
 | 
					import MkDialog from './MkDialog.vue';
 | 
				
			||||||
 | 
					const Base = {
 | 
				
			||||||
 | 
						render(args) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								components: {
 | 
				
			||||||
 | 
									MkDialog,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setup() {
 | 
				
			||||||
 | 
									return {
 | 
				
			||||||
 | 
										args,
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								computed: {
 | 
				
			||||||
 | 
									props() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											...this.args,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									events() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											done: action('done'),
 | 
				
			||||||
 | 
											closed: action('closed'),
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								template: '<MkDialog v-bind="props" v-on="events" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							text: 'Hello, world!',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const Success = {
 | 
				
			||||||
 | 
						...Base,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Base.args,
 | 
				
			||||||
 | 
							type: 'success',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const Error = {
 | 
				
			||||||
 | 
						...Base,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Base.args,
 | 
				
			||||||
 | 
							type: 'error',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const Warning = {
 | 
				
			||||||
 | 
						...Base,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Base.args,
 | 
				
			||||||
 | 
							type: 'warning',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const Info = {
 | 
				
			||||||
 | 
						...Base,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Base.args,
 | 
				
			||||||
 | 
							type: 'info',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const Question = {
 | 
				
			||||||
 | 
						...Base,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Base.args,
 | 
				
			||||||
 | 
							type: 'question',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const Waiting = {
 | 
				
			||||||
 | 
						...Base,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Base.args,
 | 
				
			||||||
 | 
							type: 'waiting',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const DialogWithActions = {
 | 
				
			||||||
 | 
						...Question,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Question.args,
 | 
				
			||||||
 | 
							text: i18n.ts.areYouSure,
 | 
				
			||||||
 | 
							actions: [
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									text: i18n.ts.yes,
 | 
				
			||||||
 | 
									primary: true,
 | 
				
			||||||
 | 
									callback() {
 | 
				
			||||||
 | 
										action('YES')();
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									text: i18n.ts.no,
 | 
				
			||||||
 | 
									callback() {
 | 
				
			||||||
 | 
										action('NO')();
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const DialogWithDangerActions = {
 | 
				
			||||||
 | 
						...Warning,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Warning.args,
 | 
				
			||||||
 | 
							text: i18n.ts.resetAreYouSure,
 | 
				
			||||||
 | 
							actions: [
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									text: i18n.ts.yes,
 | 
				
			||||||
 | 
									danger: true,
 | 
				
			||||||
 | 
									primary: true,
 | 
				
			||||||
 | 
									callback() {
 | 
				
			||||||
 | 
										action('YES')();
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									text: i18n.ts.no,
 | 
				
			||||||
 | 
									callback() {
 | 
				
			||||||
 | 
										action('NO')();
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
 | 
					export const DialogWithInput = {
 | 
				
			||||||
 | 
						...Question,
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							...Question.args,
 | 
				
			||||||
 | 
							title: 'Hello, world!',
 | 
				
			||||||
 | 
							text: undefined,
 | 
				
			||||||
 | 
							input: {
 | 
				
			||||||
 | 
								placeholder: i18n.ts.inputMessageHere,
 | 
				
			||||||
 | 
								type: 'text',
 | 
				
			||||||
 | 
								default: null,
 | 
				
			||||||
 | 
								minLength: 2,
 | 
				
			||||||
 | 
								maxLength: 3,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						async play({ canvasElement }) {
 | 
				
			||||||
 | 
							const canvas = within(canvasElement);
 | 
				
			||||||
 | 
							await expect(canvasElement).toHaveTextContent(i18n.tsx._dialog.charactersBelow({ current: 0, min: 2 }));
 | 
				
			||||||
 | 
							const okButton = canvas.getByRole('button', { name: i18n.ts.ok });
 | 
				
			||||||
 | 
							await expect(okButton).toBeDisabled();
 | 
				
			||||||
 | 
							const input = canvas.getByRole<HTMLInputElement>('combobox');
 | 
				
			||||||
 | 
							await waitFor(() => userEvent.hover(input));
 | 
				
			||||||
 | 
							await waitFor(() => userEvent.click(input));
 | 
				
			||||||
 | 
							await waitFor(() => userEvent.type(input, 'M'));
 | 
				
			||||||
 | 
							await expect(canvasElement).toHaveTextContent(i18n.tsx._dialog.charactersBelow({ current: 1, min: 2 }));
 | 
				
			||||||
 | 
							await waitFor(() => userEvent.type(input, 'i'));
 | 
				
			||||||
 | 
							await expect(okButton).toBeEnabled();
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDialog>;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkDivider from './MkDivider.vue';
 | 
				
			||||||
 | 
					void MkDivider;
 | 
				
			||||||
							
								
								
									
										54
									
								
								packages/frontend/src/components/MkDonation.stories.impl.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								packages/frontend/src/components/MkDonation.stories.impl.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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: '<MkDonation v-bind="props" v-on="events" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						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: '<story/>',
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDonation>;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 MkDrive_file from './MkDrive.file.vue';
 | 
				
			||||||
 | 
					import { file } from '../../.storybook/fakes.js';
 | 
				
			||||||
 | 
					export const Default = {
 | 
				
			||||||
 | 
						render(args) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								components: {
 | 
				
			||||||
 | 
									MkDrive_file,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setup() {
 | 
				
			||||||
 | 
									return {
 | 
				
			||||||
 | 
										args,
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								computed: {
 | 
				
			||||||
 | 
									props() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											...this.args,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									events() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											chosen: action('chosen'),
 | 
				
			||||||
 | 
											dragstart: action('dragstart'),
 | 
				
			||||||
 | 
											dragend: action('dragend'),
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								template: '<MkDrive_file v-bind="props" v-on="events" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							file: file(),
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							chromatic: {
 | 
				
			||||||
 | 
								// NOTE: ロードが終わるまで待つ
 | 
				
			||||||
 | 
								delay: 3000,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDrive_file>;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 { http, HttpResponse } from 'msw';
 | 
				
			||||||
 | 
					import * as Misskey from 'misskey-js';
 | 
				
			||||||
 | 
					import MkDrive_folder from './MkDrive.folder.vue';
 | 
				
			||||||
 | 
					import { folder } from '../../.storybook/fakes.js';
 | 
				
			||||||
 | 
					import { commonHandlers } from '../../.storybook/mocks.js';
 | 
				
			||||||
 | 
					export const Default = {
 | 
				
			||||||
 | 
						render(args) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								components: {
 | 
				
			||||||
 | 
									MkDrive_folder,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setup() {
 | 
				
			||||||
 | 
									return {
 | 
				
			||||||
 | 
										args,
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								computed: {
 | 
				
			||||||
 | 
									props() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											...this.args,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									events() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											chosen: action('chosen'),
 | 
				
			||||||
 | 
											move: action('move'),
 | 
				
			||||||
 | 
											upload: action('upload'),
 | 
				
			||||||
 | 
											removeFile: action('removeFile'),
 | 
				
			||||||
 | 
											removeFolder: action('removeFolder'),
 | 
				
			||||||
 | 
											dragstart: action('dragstart'),
 | 
				
			||||||
 | 
											dragend: action('dragend'),
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								template: '<MkDrive_folder v-bind="props" v-on="events" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							folder: folder(),
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
							msw: {
 | 
				
			||||||
 | 
								handlers: [
 | 
				
			||||||
 | 
									...commonHandlers,
 | 
				
			||||||
 | 
									http.post('/api/drive/folders/delete', async ({ request }) => {
 | 
				
			||||||
 | 
										action('POST /api/drive/folders/delete')(await request.json());
 | 
				
			||||||
 | 
										return HttpResponse.json(undefined, { status: 204 });
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
									http.post('/api/drive/folders/update', async ({ request }) => {
 | 
				
			||||||
 | 
										const req = await request.json() as Misskey.entities.DriveFoldersUpdateRequest;
 | 
				
			||||||
 | 
										action('POST /api/drive/folders/update')(req);
 | 
				
			||||||
 | 
										return HttpResponse.json({
 | 
				
			||||||
 | 
											...folder(),
 | 
				
			||||||
 | 
											id: req.folderId,
 | 
				
			||||||
 | 
											name: req.name ?? folder().name,
 | 
				
			||||||
 | 
											parentId: req.parentId ?? folder().parentId,
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDrive_folder>;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkDrive_navFolder from './MkDrive.navFolder.vue';
 | 
				
			||||||
 | 
					void MkDrive_navFolder;
 | 
				
			||||||
							
								
								
									
										82
									
								
								packages/frontend/src/components/MkDrive.stories.impl.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								packages/frontend/src/components/MkDrive.stories.impl.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 { http, HttpResponse } from 'msw';
 | 
				
			||||||
 | 
					import * as Misskey from 'misskey-js';
 | 
				
			||||||
 | 
					import MkDrive from './MkDrive.vue';
 | 
				
			||||||
 | 
					import { file, folder } from '../../.storybook/fakes.js';
 | 
				
			||||||
 | 
					import { commonHandlers } from '../../.storybook/mocks.js';
 | 
				
			||||||
 | 
					export const Default = {
 | 
				
			||||||
 | 
						render(args) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								components: {
 | 
				
			||||||
 | 
									MkDrive,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setup() {
 | 
				
			||||||
 | 
									return {
 | 
				
			||||||
 | 
										args,
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								computed: {
 | 
				
			||||||
 | 
									props() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											...this.args,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									events() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											selected: action('selected'),
 | 
				
			||||||
 | 
											'change-selection': action('change-selection'),
 | 
				
			||||||
 | 
											'move-root': action('move-root'),
 | 
				
			||||||
 | 
											cd: action('cd'),
 | 
				
			||||||
 | 
											'open-folder': action('open-folder'),
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								template: '<MkDrive v-bind="props" v-on="events" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							chromatic: {
 | 
				
			||||||
 | 
								// NOTE: ロードが終わるまで待つ
 | 
				
			||||||
 | 
								delay: 3000,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
							msw: {
 | 
				
			||||||
 | 
								handlers: [
 | 
				
			||||||
 | 
									...commonHandlers,
 | 
				
			||||||
 | 
									http.post('/api/drive/files', async ({ request }) => {
 | 
				
			||||||
 | 
										action('POST /api/drive/files')(await request.json());
 | 
				
			||||||
 | 
										return HttpResponse.json([file()]);
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
									http.post('/api/drive/folders', async ({ request }) => {
 | 
				
			||||||
 | 
										action('POST /api/drive/folders')(await request.json());
 | 
				
			||||||
 | 
										return HttpResponse.json([folder(crypto.randomUUID())]);
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
									http.post('/api/drive/folders/create', async ({ request }) => {
 | 
				
			||||||
 | 
										const req = await request.json() as Misskey.entities.DriveFoldersCreateRequest;
 | 
				
			||||||
 | 
										action('POST /api/drive/folders/create')(req);
 | 
				
			||||||
 | 
										return HttpResponse.json(folder(crypto.randomUUID(), req.name, req.parentId));
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
									http.post('/api/drive/folders/delete', async ({ request }) => {
 | 
				
			||||||
 | 
										action('POST /api/drive/folders/delete')(await request.json());
 | 
				
			||||||
 | 
										return HttpResponse.json(undefined, { status: 204 });
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
									http.post('/api/drive/folders/update', async ({ request }) => {
 | 
				
			||||||
 | 
										const req = await request.json() as Misskey.entities.DriveFoldersUpdateRequest;
 | 
				
			||||||
 | 
										action('POST /api/drive/folders/update')(req);
 | 
				
			||||||
 | 
										return HttpResponse.json({
 | 
				
			||||||
 | 
											...folder(),
 | 
				
			||||||
 | 
											id: req.folderId,
 | 
				
			||||||
 | 
											name: req.name ?? folder().name,
 | 
				
			||||||
 | 
											parentId: req.parentId ?? folder().parentId,
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									}),
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDrive>;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { StoryObj } from '@storybook/vue3';
 | 
				
			||||||
 | 
					import MkDriveFileThumbnail from './MkDriveFileThumbnail.vue';
 | 
				
			||||||
 | 
					import { file } from '../../.storybook/fakes.js';
 | 
				
			||||||
 | 
					export const Default = {
 | 
				
			||||||
 | 
						render(args) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								components: {
 | 
				
			||||||
 | 
									MkDriveFileThumbnail,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setup() {
 | 
				
			||||||
 | 
									return {
 | 
				
			||||||
 | 
										args,
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								computed: {
 | 
				
			||||||
 | 
									props() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											...this.args,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								template: '<MkDriveFileThumbnail v-bind="props" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						args: {
 | 
				
			||||||
 | 
							file: file(),
 | 
				
			||||||
 | 
							fit: 'contain',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							chromatic: {
 | 
				
			||||||
 | 
								// NOTE: ロードが終わるまで待つ
 | 
				
			||||||
 | 
								delay: 3000,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkDriveFileThumbnail>;
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = defineProps<{
 | 
				
			||||||
	file: Misskey.entities.DriveFile;
 | 
						file: Misskey.entities.DriveFile;
 | 
				
			||||||
	fit: string;
 | 
						fit: 'cover' | 'contain';
 | 
				
			||||||
}>();
 | 
					}>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const is = computed(() => {
 | 
					const is = computed(() => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkDriveSelectDialog from './MkDriveSelectDialog.vue';
 | 
				
			||||||
 | 
					void MkDriveSelectDialog;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkDriveWindow from './MkDriveWindow.vue';
 | 
				
			||||||
 | 
					void MkDriveWindow;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkEmojiPicker_section from './MkEmojiPicker.section.vue';
 | 
				
			||||||
 | 
					void MkEmojiPicker_section;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { action } from '@storybook/addon-actions';
 | 
				
			||||||
 | 
					import { expect, userEvent, waitFor, within } from '@storybook/test';
 | 
				
			||||||
 | 
					import { StoryObj } from '@storybook/vue3';
 | 
				
			||||||
 | 
					import { i18n } from '@/i18n.js';
 | 
				
			||||||
 | 
					import MkEmojiPicker from './MkEmojiPicker.vue';
 | 
				
			||||||
 | 
					export const Default = {
 | 
				
			||||||
 | 
						render(args) {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								components: {
 | 
				
			||||||
 | 
									MkEmojiPicker,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								setup() {
 | 
				
			||||||
 | 
									return {
 | 
				
			||||||
 | 
										args,
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								computed: {
 | 
				
			||||||
 | 
									props() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											...this.args,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									events() {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											chosen: action('chosen'),
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								template: '<MkEmojiPicker v-bind="props" v-on="events" />',
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						async play({ canvasElement }) {
 | 
				
			||||||
 | 
							const canvas = within(canvasElement);
 | 
				
			||||||
 | 
							const faceSection = canvas.getByText(/face/i);
 | 
				
			||||||
 | 
							await waitFor(() => userEvent.click(faceSection));
 | 
				
			||||||
 | 
							const grinning = canvasElement.querySelector('[data-emoji="😀"]');
 | 
				
			||||||
 | 
							await expect(grinning).toBeInTheDocument();
 | 
				
			||||||
 | 
							if (grinning == null) throw new Error(); // NOTE: not called
 | 
				
			||||||
 | 
							await waitFor(() => userEvent.click(grinning));
 | 
				
			||||||
 | 
							const recentUsedSection = canvas.getByText(new RegExp(i18n.ts.recentUsed)).parentElement;
 | 
				
			||||||
 | 
							await expect(recentUsedSection).toBeInTheDocument();
 | 
				
			||||||
 | 
							if (recentUsedSection == null) throw new Error(); // NOTE: not called
 | 
				
			||||||
 | 
							await expect(within(recentUsedSection).getByAltText('😀')).toBeInTheDocument();
 | 
				
			||||||
 | 
							await expect(within(recentUsedSection).queryByAltText('😬')).toEqual(null);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						parameters: {
 | 
				
			||||||
 | 
							layout: 'centered',
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					} satisfies StoryObj<typeof MkEmojiPicker>;
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * SPDX-FileCopyrightText: syuilo and misskey-project
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import MkEmojiPickerDialog from './MkEmojiPickerDialog.vue';
 | 
				
			||||||
 | 
					void MkEmojiPickerDialog;
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue