1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-05 18:24:54 +02:00
This commit is contained in:
kakkokari-gtyih
2026-07-03 16:32:37 +09:00
parent 91db5ad709
commit 17fa6cd13a
3 changed files with 36 additions and 94 deletions

View File

@@ -69,8 +69,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.noteHeaderUsername">
<MkAcct :user="appearNote.user"/>
</div>
<div v-if="appearNote.user.badgeRoles" :class="$style.noteHeaderBadgeRoles">
<img v-for="(role, i) in appearNote.user.badgeRoles" :key="i" v-tooltip="role.name" :class="$style.noteHeaderBadgeRole" :src="role.iconUrl!"/>
<div v-if="badgeRoles" :class="$style.noteHeaderBadgeRoles">
<img v-for="(role, i) in badgeRoles" :key="i" v-tooltip="role.name" :class="$style.noteHeaderBadgeRole" :src="role.iconUrl!"/>
</div>
</div>
<MkInstanceTicker v-if="showTicker" :host="appearNote.user.host" :instance="appearNote.user.instance"/>
@@ -344,6 +344,13 @@ const showTicker = (prefer.s.instanceTicker === 'always') || (prefer.s.instanceT
const conversation = ref<Misskey.entities.Note[]>([]);
const replies = ref<Misskey.entities.Note[]>([]);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.visibility) || appearNote.userId === $i?.id);
const badgeRoles = computed(() => {
const roles = appearNote.user.badgeRoles;
if (roles == null || $i == null || $i.id !== props.note.userId) return roles;
const hiddenRoleIds = new Set(($i.hiddenRoleIds) ?? []);
return roles.filter(role => !hiddenRoleIds.has(role.id));
});
useGlobalEvent('noteDeleted', (noteId) => {
if (noteId === note.id || noteId === appearNote.id) {

View File

@@ -37,6 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, inject } from 'vue';
import * as Misskey from 'misskey-js';
import { $i } from '@/i.js';
import { i18n } from '@/i18n.js';
import { notePage } from '@/filters/note.js';
import { userPage } from '@/filters/user.js';
@@ -46,11 +47,13 @@ const props = defineProps<{
note: Misskey.entities.Note;
}>();
type BadgeRoleWithId = NonNullable<Misskey.entities.Note['user']['badgeRoles']>[number] & {
id: string;
};
const badgeRoles = computed(() => {
const roles = props.note.user.badgeRoles;
if (roles == null || $i == null || $i.id !== props.note.userId) return roles;
const badgeRoles = computed(() => props.note.user.badgeRoles as BadgeRoleWithId[] | undefined);
const hiddenRoleIds = new Set(($i.hiddenRoleIds) ?? []);
return roles.filter(role => !hiddenRoleIds.has(role.id));
});
const mock = inject(DI.mock, false);
</script>

View File

@@ -3,82 +3,32 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { expect, waitFor, within } from '@storybook/test';
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import type { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw';
import { userDetailed } from '../../../.storybook/fakes.js';
import { commonHandlers } from '../../../.storybook/mocks.js';
import home_ from './home.vue';
import type { StoryObj } from '@storybook/vue3';
import { $i } from '@/i.js';
type UserDetailed = ReturnType<typeof userDetailed>;
type ProfileRole = UserDetailed['roles'][number] & {
isPublicDisplayRequired?: boolean;
};
type MeRoleDisplay = NonNullable<typeof $i> & {
hiddenRoleIds?: string[];
};
function createProfileRole(id: string, name: string, color: string, isPublicDisplayRequired = false): ProfileRole {
return {
id,
name,
color,
iconUrl: null,
description: `${name} description`,
isModerator: false,
isAdministrator: false,
asBadge: false,
displayOrder: 0,
isPublicDisplayRequired,
};
}
const visibleRole = createProfileRole('role-display-visible', 'Visible Role', '#3b82f6');
const hiddenRole = createProfileRole('role-display-hidden', 'Hidden Role', '#ef4444');
const forcedRole = createProfileRole('role-display-forced', 'Forced Role', '#22c55e', true);
const roleDisplayUser = {
...userDetailed(),
roles: [visibleRole, hiddenRole, forcedRole],
};
function setStoryAccount(user: UserDetailed, hiddenRoleIds: string[]): void {
if ($i == null) return;
Object.assign($i as MeRoleDisplay, {
id: user.id,
username: user.username,
host: user.host,
name: user.name,
hiddenRoleIds,
});
}
function renderHome(args: UserDetailedHomeArgs, hiddenRoleIds: string[] = []) {
return {
components: {
home_,
},
setup() {
setStoryAccount(args.user, hiddenRoleIds);
return {
props: args,
};
},
template: '<home_ v-bind="props" />',
};
}
type UserDetailedHomeArgs = {
user: UserDetailed;
disableNotes?: boolean;
};
export const Default = {
render(args) {
return renderHome(args);
return {
components: {
home_,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<home_ v-bind="props" />',
};
},
args: {
user: userDetailed(),
@@ -129,21 +79,3 @@ export const Default = {
},
},
} satisfies StoryObj<typeof home_>;
export const RoleDisplayVisibility = {
...Default,
render(args) {
return renderHome(args, [hiddenRole.id]);
},
async play({ canvasElement }) {
const canvas = within(canvasElement);
await expect(await canvas.findByText(visibleRole.name)).toBeInTheDocument();
await expect(await canvas.findByText(forcedRole.name)).toBeInTheDocument();
await waitFor(() => expect(canvas.queryByText(hiddenRole.name)).not.toBeInTheDocument());
},
args: {
...Default.args,
user: roleDisplayUser,
},
} satisfies StoryObj<typeof home_>;