diff options
| author | Acid Chicken (硫酸鶏) <root@acid-chicken.com> | 2023-04-06 08:19:49 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-06 08:19:49 +0900 |
| commit | 3b3f683f8cdff33c8c745e1da99596e7499ca2d6 (patch) | |
| tree | b94e01d12a668cf142fa3859e965aac9174bea34 /packages/frontend/src | |
| parent | docs: thanks (#10487) (diff) | |
| download | sharkey-3b3f683f8cdff33c8c745e1da99596e7499ca2d6.tar.gz sharkey-3b3f683f8cdff33c8c745e1da99596e7499ca2d6.tar.bz2 sharkey-3b3f683f8cdff33c8c745e1da99596e7499ca2d6.zip | |
feat(#8149): respect nsfw settings on gallery list (#10481)
* feat(#8149): respect nsfw settings on gallery list
* ci(#10336): use pull_request
* test(#8149): add interaction tests
* test(#10336): use `waitFor`
* chore: transition
Diffstat (limited to 'packages/frontend/src')
6 files changed, 131 insertions, 15 deletions
diff --git a/packages/frontend/src/components/MkGalleryPostPreview.stories.impl.ts b/packages/frontend/src/components/MkGalleryPostPreview.stories.impl.ts new file mode 100644 index 0000000000..e46a708192 --- /dev/null +++ b/packages/frontend/src/components/MkGalleryPostPreview.stories.impl.ts @@ -0,0 +1,85 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { expect } from '@storybook/jest'; +import { userEvent, waitFor, within } from '@storybook/testing-library'; +import { StoryObj } from '@storybook/vue3'; +import { galleryPost } from '../../.storybook/fakes'; +import MkGalleryPostPreview from './MkGalleryPostPreview.vue'; +export const Default = { + render(args) { + return { + components: { + MkGalleryPostPreview, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '<MkGalleryPostPreview v-bind="props" />', + }; + }, + async play({ canvasElement }) { + const canvas = within(canvasElement); + const links = canvas.getAllByRole('link'); + await expect(links).toHaveLength(2); + await expect(links[0]).toHaveAttribute('href', `/gallery/${galleryPost().id}`); + await expect(links[1]).toHaveAttribute('href', `/@${galleryPost().user.username}@${galleryPost().user.host}`); + }, + args: { + post: galleryPost(), + }, + decorators: [ + () => ({ + template: '<div style="width:260px"><story /></div>', + }), + ], + parameters: { + layout: 'centered', + }, +} satisfies StoryObj<typeof MkGalleryPostPreview>; +export const Hover = { + ...Default, + async play(context) { + await Default.play(context); + const canvas = within(context.canvasElement); + const links = canvas.getAllByRole('link'); + await waitFor(() => userEvent.hover(links[0])); + }, +} satisfies StoryObj<typeof MkGalleryPostPreview>; +export const HoverThenUnhover = { + ...Default, + async play(context) { + await Hover.play(context); + const canvas = within(context.canvasElement); + const links = canvas.getAllByRole('link'); + await waitFor(() => userEvent.unhover(links[0])); + }, +} satisfies StoryObj<typeof MkGalleryPostPreview>; +export const Sensitive = { + ...Default, + args: { + ...Default.args, + post: galleryPost(true), + }, +} satisfies StoryObj<typeof MkGalleryPostPreview>; +export const SensitiveHover = { + ...Hover, + args: { + ...Hover.args, + post: galleryPost(true), + }, +} satisfies StoryObj<typeof MkGalleryPostPreview>; +export const SensitiveHoverThenUnhover = { + ...HoverThenUnhover, + args: { + ...HoverThenUnhover.args, + post: galleryPost(true), + }, +} satisfies StoryObj<typeof MkGalleryPostPreview>; diff --git a/packages/frontend/src/components/MkGalleryPostPreview.vue b/packages/frontend/src/components/MkGalleryPostPreview.vue index 2c5032119f..944f5ad97b 100644 --- a/packages/frontend/src/components/MkGalleryPostPreview.vue +++ b/packages/frontend/src/components/MkGalleryPostPreview.vue @@ -1,7 +1,10 @@ <template> -<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel" tabindex="-1"> +<MkA :to="`/gallery/${post.id}`" class="ttasepnz _panel" tabindex="-1" @pointerenter="enterHover" @pointerleave="leaveHover"> <div class="thumbnail"> - <ImgWithBlurhash class="img" :src="post.files[0].thumbnailUrl" :hash="post.files[0].blurhash"/> + <ImgWithBlurhash class="img" :hash="post.files[0].blurhash"/> + <Transition> + <ImgWithBlurhash v-if="show" class="img layered" :src="post.files[0].thumbnailUrl" :hash="post.files[0].blurhash"/> + </Transition> </div> <article> <header> @@ -15,12 +18,25 @@ </template> <script lang="ts" setup> -import { } from 'vue'; +import * as misskey from 'misskey-js'; +import { computed, ref } from 'vue'; import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue'; +import { defaultStore } from '@/store'; const props = defineProps<{ - post: any; + post: misskey.entities.GalleryPost; }>(); + +const hover = ref(false); +const show = computed(() => defaultStore.state.nsfw === 'ignore' || defaultStore.state.nsfw === 'respect' && !props.post.isSensitive || hover.value); + +function enterHover(): void { + hover.value = true; +} + +function leaveHover(): void { + hover.value = false; +} </script> <style lang="scss" scoped> @@ -56,6 +72,21 @@ const props = defineProps<{ width: 100%; height: 100%; object-fit: cover; + + &.layered { + position: absolute; + top: 0; + + &.v-enter-active, + &.v-leave-active { + transition: opacity 0.5s ease; + } + + &.v-enter-from, + &.v-leave-to { + opacity: 0; + } + } } } diff --git a/packages/frontend/src/components/global/MkAcct.stories.impl.ts b/packages/frontend/src/components/global/MkAcct.stories.impl.ts index 7dfa1a14f2..d5e3fc3568 100644 --- a/packages/frontend/src/components/global/MkAcct.stories.impl.ts +++ b/packages/frontend/src/components/global/MkAcct.stories.impl.ts @@ -25,7 +25,7 @@ export const Default = { }, args: { user: { - ...userDetailed, + ...userDetailed(), host: null, }, }, @@ -37,7 +37,7 @@ export const Detail = { ...Default, args: { ...Default.args, - user: userDetailed, + user: userDetailed(), detail: true, }, } satisfies StoryObj<typeof MkAcct>; diff --git a/packages/frontend/src/components/global/MkAvatar.stories.impl.ts b/packages/frontend/src/components/global/MkAvatar.stories.impl.ts index 6c46f75b5f..3c69c80825 100644 --- a/packages/frontend/src/components/global/MkAvatar.stories.impl.ts +++ b/packages/frontend/src/components/global/MkAvatar.stories.impl.ts @@ -24,7 +24,7 @@ const common = { }; }, args: { - user: userDetailed, + user: userDetailed(), }, decorators: [ (Story, context) => ({ @@ -49,7 +49,7 @@ export const ProfilePageCat = { args: { ...ProfilePage.args, user: { - ...userDetailed, + ...userDetailed(), isCat: true, }, }, diff --git a/packages/frontend/src/components/global/MkUrl.stories.impl.ts b/packages/frontend/src/components/global/MkUrl.stories.impl.ts index 2344c4851a..c5875d4779 100644 --- a/packages/frontend/src/components/global/MkUrl.stories.impl.ts +++ b/packages/frontend/src/components/global/MkUrl.stories.impl.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { expect } from '@storybook/jest'; -import { userEvent, within } from '@storybook/testing-library'; +import { userEvent, waitFor, within } from '@storybook/testing-library'; import { StoryObj } from '@storybook/vue3'; import { rest } from 'msw'; import { commonHandlers } from '../../../.storybook/mocks'; @@ -30,7 +30,7 @@ export const Default = { const canvas = within(canvasElement); const a = canvas.getByRole<HTMLAnchorElement>('link'); await expect(a).toHaveAttribute('href', 'https://misskey-hub.net/'); - await userEvent.hover(a); + await waitFor(() => userEvent.hover(a)); /* await tick(); // FIXME: wait for network request const anchors = canvas.getAllByRole<HTMLAnchorElement>('link'); @@ -44,7 +44,7 @@ export const Default = { await expect(icon).toBeInTheDocument(); await expect(icon).toHaveAttribute('src', 'https://misskey-hub.net/favicon.ico'); */ - await userEvent.unhover(a); + await waitFor(() => userEvent.unhover(a)); }, args: { url: 'https://misskey-hub.net/', diff --git a/packages/frontend/src/components/global/MkUserName.stories.impl.ts b/packages/frontend/src/components/global/MkUserName.stories.impl.ts index 41b1567a6f..fa4f0f3b72 100644 --- a/packages/frontend/src/components/global/MkUserName.stories.impl.ts +++ b/packages/frontend/src/components/global/MkUserName.stories.impl.ts @@ -26,10 +26,10 @@ export const Default = { }; }, async play({ canvasElement }) { - await expect(canvasElement).toHaveTextContent(userDetailed.name); + await expect(canvasElement).toHaveTextContent(userDetailed().name); }, args: { - user: userDetailed, + user: userDetailed(), }, parameters: { layout: 'centered', @@ -38,12 +38,12 @@ export const Default = { export const Anonymous = { ...Default, async play({ canvasElement }) { - await expect(canvasElement).toHaveTextContent(userDetailed.username); + await expect(canvasElement).toHaveTextContent(userDetailed().username); }, args: { ...Default.args, user: { - ...userDetailed, + ...userDetailed(), name: null, }, }, |