fix public work author display
This commit is contained in:
@@ -15295,6 +15295,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
<PlatformWorkDetailView
|
<PlatformWorkDetailView
|
||||||
entry={selectedPublicWorkDetail}
|
entry={selectedPublicWorkDetail}
|
||||||
authorAvatarUrl={selectedPublicWorkAuthor?.avatarUrl ?? null}
|
authorAvatarUrl={selectedPublicWorkAuthor?.avatarUrl ?? null}
|
||||||
|
authorUsername={selectedPublicWorkAuthor?.username ?? null}
|
||||||
authorDisplayName={selectedPublicWorkAuthor?.displayName ?? null}
|
authorDisplayName={selectedPublicWorkAuthor?.displayName ?? null}
|
||||||
isBusy={
|
isBusy={
|
||||||
isPublicWorkDetailBusy ||
|
isPublicWorkDetailBusy ||
|
||||||
@@ -15342,6 +15343,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
<PlatformWorkDetailView
|
<PlatformWorkDetailView
|
||||||
entry={mapRpgGalleryCardToPublicWorkDetail(selectedDetailEntry)}
|
entry={mapRpgGalleryCardToPublicWorkDetail(selectedDetailEntry)}
|
||||||
authorAvatarUrl={selectedPublicWorkAuthor?.avatarUrl ?? null}
|
authorAvatarUrl={selectedPublicWorkAuthor?.avatarUrl ?? null}
|
||||||
|
authorUsername={selectedPublicWorkAuthor?.username ?? null}
|
||||||
authorDisplayName={
|
authorDisplayName={
|
||||||
selectedPublicWorkAuthor?.displayName ?? null
|
selectedPublicWorkAuthor?.displayName ?? null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME,
|
EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_NAME,
|
||||||
type PlatformEdutainmentGalleryCard,
|
type PlatformEdutainmentGalleryCard,
|
||||||
type PlatformPuzzleGalleryCard,
|
type PlatformPuzzleGalleryCard,
|
||||||
|
type PlatformWoodenFishGalleryCard,
|
||||||
} from '../rpg-entry/rpgEntryWorldPresentation';
|
} from '../rpg-entry/rpgEntryWorldPresentation';
|
||||||
import { PlatformWorkDetailView } from './PlatformWorkDetailView';
|
import { PlatformWorkDetailView } from './PlatformWorkDetailView';
|
||||||
|
|
||||||
@@ -82,6 +83,29 @@ function createBabyObjectMatchEntry(): PlatformEdutainmentGalleryCard {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createWoodenFishEntry(): PlatformWoodenFishGalleryCard {
|
||||||
|
return {
|
||||||
|
sourceType: 'wooden-fish',
|
||||||
|
workId: 'wooden-fish-work-1',
|
||||||
|
profileId: 'wooden-fish-profile-1',
|
||||||
|
publicWorkCode: 'WF-001',
|
||||||
|
ownerUserId: 'user-wooden-fish',
|
||||||
|
authorDisplayName: '敲木鱼玩家',
|
||||||
|
worldName: '莲花木鱼',
|
||||||
|
subtitle: '敲木鱼',
|
||||||
|
summaryText: '莲花主题敲木鱼。',
|
||||||
|
coverImageSrc: null,
|
||||||
|
themeTags: ['敲木鱼'],
|
||||||
|
playCount: 12,
|
||||||
|
remixCount: 0,
|
||||||
|
likeCount: 4,
|
||||||
|
recentPlayCount7d: 0,
|
||||||
|
visibility: 'published',
|
||||||
|
publishedAt: '2026-05-20T10:00:00.000Z',
|
||||||
|
updatedAt: '2026-05-20T12:00:00.000Z',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vi.useRealTimers();
|
vi.useRealTimers();
|
||||||
});
|
});
|
||||||
@@ -133,6 +157,26 @@ test('PlatformWorkDetailView prefers resolved public user display name', () => {
|
|||||||
expect(screen.queryByText('137****6613')).toBeNull();
|
expect(screen.queryByText('137****6613')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('PlatformWorkDetailView prefers resolved username for wooden fish works', () => {
|
||||||
|
render(
|
||||||
|
<PlatformWorkDetailView
|
||||||
|
entry={createWoodenFishEntry()}
|
||||||
|
authorUsername="lotus_user"
|
||||||
|
authorDisplayName="公开昵称"
|
||||||
|
isBusy={false}
|
||||||
|
error={null}
|
||||||
|
onBack={vi.fn()}
|
||||||
|
onLike={vi.fn()}
|
||||||
|
onStart={vi.fn()}
|
||||||
|
onRemix={vi.fn()}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByText('lotus_user')).toBeTruthy();
|
||||||
|
expect(screen.queryByText('敲木鱼玩家')).toBeNull();
|
||||||
|
expect(screen.queryByText('公开昵称')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
test('PlatformWorkDetailView calls like handler', () => {
|
test('PlatformWorkDetailView calls like handler', () => {
|
||||||
const onLike = vi.fn();
|
const onLike = vi.fn();
|
||||||
render(
|
render(
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
isBarkBattleGalleryEntry,
|
isBarkBattleGalleryEntry,
|
||||||
isEdutainmentGalleryEntry,
|
isEdutainmentGalleryEntry,
|
||||||
type PlatformPublicGalleryCard,
|
type PlatformPublicGalleryCard,
|
||||||
|
resolvePlatformWorkAuthorDisplayName,
|
||||||
resolvePlatformPublicWorkCode,
|
resolvePlatformPublicWorkCode,
|
||||||
resolvePlatformWorldCoverSlides,
|
resolvePlatformWorldCoverSlides,
|
||||||
resolvePlatformWorldStats,
|
resolvePlatformWorldStats,
|
||||||
@@ -33,6 +34,7 @@ import {
|
|||||||
export interface PlatformWorkDetailViewProps {
|
export interface PlatformWorkDetailViewProps {
|
||||||
entry: PlatformPublicGalleryCard;
|
entry: PlatformPublicGalleryCard;
|
||||||
authorAvatarUrl?: string | null;
|
authorAvatarUrl?: string | null;
|
||||||
|
authorUsername?: string | null;
|
||||||
authorDisplayName?: string | null;
|
authorDisplayName?: string | null;
|
||||||
isBusy: boolean;
|
isBusy: boolean;
|
||||||
error?: string | null;
|
error?: string | null;
|
||||||
@@ -86,6 +88,7 @@ const PLATFORM_WORK_COVER_CAROUSEL_INTERVAL_MS = 4200;
|
|||||||
export function PlatformWorkDetailView({
|
export function PlatformWorkDetailView({
|
||||||
entry,
|
entry,
|
||||||
authorAvatarUrl,
|
authorAvatarUrl,
|
||||||
|
authorUsername,
|
||||||
authorDisplayName,
|
authorDisplayName,
|
||||||
isBusy,
|
isBusy,
|
||||||
visibleCoverCount = 1,
|
visibleCoverCount = 1,
|
||||||
@@ -109,8 +112,10 @@ export function PlatformWorkDetailView({
|
|||||||
const hasCoverCarousel = coverSlides.length > 1;
|
const hasCoverCarousel = coverSlides.length > 1;
|
||||||
const publicWorkCode = resolvePlatformPublicWorkCode(entry);
|
const publicWorkCode = resolvePlatformPublicWorkCode(entry);
|
||||||
const normalizedAuthorAvatarUrl = authorAvatarUrl?.trim() ?? '';
|
const normalizedAuthorAvatarUrl = authorAvatarUrl?.trim() ?? '';
|
||||||
const resolvedAuthorDisplayName =
|
const resolvedAuthorDisplayName = resolvePlatformWorkAuthorDisplayName(
|
||||||
authorDisplayName?.trim() || entry.authorDisplayName;
|
entry,
|
||||||
|
authorUsername?.trim() || authorDisplayName?.trim() || null,
|
||||||
|
);
|
||||||
const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>(
|
const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>(
|
||||||
'idle',
|
'idle',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ import {
|
|||||||
isWoodenFishGalleryEntry,
|
isWoodenFishGalleryEntry,
|
||||||
type PlatformPublicGalleryCard,
|
type PlatformPublicGalleryCard,
|
||||||
type PlatformWorldCardLike,
|
type PlatformWorldCardLike,
|
||||||
|
resolvePlatformWorkAuthorDisplayName,
|
||||||
resolvePlatformPublicWorkCode,
|
resolvePlatformPublicWorkCode,
|
||||||
resolvePlatformWorldCoverImage,
|
resolvePlatformWorldCoverImage,
|
||||||
resolvePlatformWorldCoverSlides,
|
resolvePlatformWorldCoverSlides,
|
||||||
@@ -655,7 +656,7 @@ function WorldCard({
|
|||||||
const remixCount = getPlatformWorldRemixCount(entry);
|
const remixCount = getPlatformWorldRemixCount(entry);
|
||||||
const likeCount = getPlatformWorldLikeCount(entry);
|
const likeCount = getPlatformWorldLikeCount(entry);
|
||||||
const typeLabel = describePublicGalleryCardKind(entry);
|
const typeLabel = describePublicGalleryCardKind(entry);
|
||||||
const authorName = resolvePublicEntryAuthorDisplayText(
|
const authorName = resolvePlatformWorkAuthorDisplayName(
|
||||||
entry,
|
entry,
|
||||||
authorUsername,
|
authorUsername,
|
||||||
);
|
);
|
||||||
@@ -1024,7 +1025,7 @@ function RecommendRuntimeMeta({
|
|||||||
}) {
|
}) {
|
||||||
const likeCount = getPlatformWorldLikeCount(entry);
|
const likeCount = getPlatformWorldLikeCount(entry);
|
||||||
const remixCount = getPlatformWorldRemixCount(entry);
|
const remixCount = getPlatformWorldRemixCount(entry);
|
||||||
const authorName = resolvePublicEntryAuthorDisplayText(
|
const authorName = resolvePlatformWorkAuthorDisplayName(
|
||||||
entry,
|
entry,
|
||||||
authorUsername,
|
authorUsername,
|
||||||
);
|
);
|
||||||
@@ -1935,17 +1936,6 @@ function getPublicAuthorAvatarLabel(authorDisplayName: string) {
|
|||||||
return Array.from(authorDisplayName.trim() || '玩')[0] ?? '玩';
|
return Array.from(authorDisplayName.trim() || '玩')[0] ?? '玩';
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolvePublicEntryAuthorDisplayText(
|
|
||||||
entry: PlatformPublicGalleryCard,
|
|
||||||
authorUsername?: string | null,
|
|
||||||
) {
|
|
||||||
if (isWoodenFishGalleryEntry(entry)) {
|
|
||||||
return authorUsername?.trim() || entry.authorDisplayName.trim() || '玩家';
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry.authorDisplayName.trim() || '玩家';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPlatformWorldLikeCount(entry: PlatformWorldCardLike) {
|
function getPlatformWorldLikeCount(entry: PlatformWorldCardLike) {
|
||||||
return Math.max(0, Math.round(entry.likeCount ?? 0));
|
return Math.max(0, Math.round(entry.likeCount ?? 0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
mapWoodenFishWorkToPlatformGalleryCard,
|
mapWoodenFishWorkToPlatformGalleryCard,
|
||||||
type PlatformEdutainmentGalleryCard,
|
type PlatformEdutainmentGalleryCard,
|
||||||
type PlatformPuzzleGalleryCard,
|
type PlatformPuzzleGalleryCard,
|
||||||
|
resolvePlatformWorkAuthorDisplayName,
|
||||||
resolvePlatformPublicWorkCode,
|
resolvePlatformPublicWorkCode,
|
||||||
resolvePlatformWorldFallbackCoverImage,
|
resolvePlatformWorldFallbackCoverImage,
|
||||||
} from './rpgEntryWorldPresentation';
|
} from './rpgEntryWorldPresentation';
|
||||||
@@ -197,6 +198,30 @@ test('maps wooden fish work to platform gallery card with WF public code', () =>
|
|||||||
expect(buildPlatformWorldDisplayTags(card, 2)).toEqual(['敲木鱼']);
|
expect(buildPlatformWorldDisplayTags(card, 2)).toEqual(['敲木鱼']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('resolves public work author from live username before stored author name', () => {
|
||||||
|
const card = mapWoodenFishWorkToPlatformGalleryCard({
|
||||||
|
publicWorkCode: 'WF-AUTHOR1',
|
||||||
|
workId: 'wooden-fish-work-author',
|
||||||
|
profileId: 'wooden-fish-profile-author',
|
||||||
|
ownerUserId: 'user-author',
|
||||||
|
authorDisplayName: '敲木鱼玩家',
|
||||||
|
workTitle: '莲花木鱼',
|
||||||
|
workDescription: '莲花主题敲木鱼。',
|
||||||
|
coverImageSrc: null,
|
||||||
|
themeTags: ['敲木鱼'],
|
||||||
|
publicationStatus: 'published',
|
||||||
|
playCount: 0,
|
||||||
|
updatedAt: '2026-05-20T00:00:00.000Z',
|
||||||
|
publishedAt: '2026-05-20T00:00:00.000Z',
|
||||||
|
generationStatus: 'ready',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resolvePlatformWorkAuthorDisplayName(card, 'lotus_user')).toBe(
|
||||||
|
'lotus_user',
|
||||||
|
);
|
||||||
|
expect(resolvePlatformWorkAuthorDisplayName(card, ' ')).toBe('敲木鱼玩家');
|
||||||
|
});
|
||||||
|
|
||||||
test('keeps baby object match public card code and template label intact', () => {
|
test('keeps baby object match public card code and template label intact', () => {
|
||||||
const card: PlatformEdutainmentGalleryCard = {
|
const card: PlatformEdutainmentGalleryCard = {
|
||||||
sourceType: 'edutainment',
|
sourceType: 'edutainment',
|
||||||
|
|||||||
@@ -862,6 +862,13 @@ export function formatPlatformWorkDisplayTags(
|
|||||||
].slice(0, limit);
|
].slice(0, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolvePlatformWorkAuthorDisplayName(
|
||||||
|
entry: PlatformPublicGalleryCard,
|
||||||
|
authorUsername?: string | null,
|
||||||
|
) {
|
||||||
|
return authorUsername?.trim() || entry.authorDisplayName.trim() || '玩家';
|
||||||
|
}
|
||||||
|
|
||||||
export function buildPlatformWorldDisplayTags(
|
export function buildPlatformWorldDisplayTags(
|
||||||
entry: PlatformWorldCardLike,
|
entry: PlatformWorldCardLike,
|
||||||
limit = 3,
|
limit = 3,
|
||||||
|
|||||||
Reference in New Issue
Block a user