mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(flags): resolve comment flags from directory list candidates
Use directory list board entries when the active address is not yet in the directories cache so /pol and similar boards get correct flag UI.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getDirectoryEntryForAddress } from '../use-directory-entry';
|
||||
|
||||
describe('getDirectoryEntryForAddress', () => {
|
||||
it('inherits directory metadata for a non-primary directory candidate board', () => {
|
||||
const entry = getDirectoryEntryForAddress({
|
||||
address: 'nothing-is-beyond-our-reach.bso',
|
||||
directoryCodeHint: 'pol',
|
||||
directories: [
|
||||
{
|
||||
address: 'politically-incorrect.bso',
|
||||
directoryCode: 'pol',
|
||||
features: { hasFlags: true, requirePostLink: true },
|
||||
title: '/pol/ - Politically Incorrect',
|
||||
},
|
||||
],
|
||||
list: {
|
||||
directoryCode: 'pol',
|
||||
title: '/pol/ - Politically Incorrect',
|
||||
features: { hasFlags: true, requirePostLink: true },
|
||||
boards: [{ address: 'politically-incorrect.bso' }, { address: 'nothing-is-beyond-our-reach.bso', publicKey: 'pol-candidate-key' }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(entry).toMatchObject({
|
||||
address: 'nothing-is-beyond-our-reach.bso',
|
||||
directoryCode: 'pol',
|
||||
features: { hasFlags: true, requirePostLink: true },
|
||||
publicKey: 'pol-candidate-key',
|
||||
title: '/pol/ - Politically Incorrect',
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,80 @@
|
||||
import { findDirectoryByAddress, type DirectoryCommunity, useDirectories } from './use-directories';
|
||||
import { getDirectoryCodeForBoardAddress, normalizeBoardAddress } from '../lib/utils/directory-list-lookup-utils';
|
||||
import { type DirectoryList, type DirectoryListBoard } from '../lib/utils/directory-list-utils';
|
||||
import { useDirectoryList } from './use-directory-list';
|
||||
|
||||
const DIRECTORY_CODE_HINT_PATTERN = /^[a-z0-9]+$/i;
|
||||
|
||||
const getDirectoryCode = (directory: DirectoryCommunity | undefined): string | undefined =>
|
||||
directory?.directoryCode ?? directory?.title?.match(/^\/([^/]+)\//)?.[1]?.toLowerCase();
|
||||
|
||||
const findDirectoryByCode = (directories: DirectoryCommunity[], directoryCode: string | undefined): DirectoryCommunity | undefined =>
|
||||
directoryCode ? directories.find((directory) => getDirectoryCode(directory) === directoryCode) : undefined;
|
||||
|
||||
const getDirectoryCodeFromHint = (directoryCodeHint: string | undefined, directories: DirectoryCommunity[]): string | undefined => {
|
||||
if (!directoryCodeHint) return undefined;
|
||||
return (
|
||||
getDirectoryCode(findDirectoryByCode(directories, directoryCodeHint)) ??
|
||||
(DIRECTORY_CODE_HINT_PATTERN.test(directoryCodeHint) ? directoryCodeHint.toLowerCase() : undefined)
|
||||
);
|
||||
};
|
||||
|
||||
const isSameBoardAddress = (left: string | undefined, right: string | undefined): boolean => {
|
||||
if (!left || !right) return false;
|
||||
return left === right || normalizeBoardAddress(left) === normalizeBoardAddress(right);
|
||||
};
|
||||
|
||||
const findBoardInDirectoryList = (list: DirectoryList | null, address: string | undefined): DirectoryListBoard | undefined =>
|
||||
address ? list?.boards.find((board) => isSameBoardAddress(board.address, address) || board.publicKey === address) : undefined;
|
||||
|
||||
const getCandidateDirectoryEntry = ({
|
||||
address,
|
||||
directory,
|
||||
list,
|
||||
}: {
|
||||
address: string | undefined;
|
||||
directory: DirectoryCommunity | undefined;
|
||||
list: DirectoryList | null;
|
||||
}): DirectoryCommunity | undefined => {
|
||||
const board = findBoardInDirectoryList(list, address);
|
||||
if (!board || !list) return undefined;
|
||||
const features = list.features ?? directory?.features ?? board.features;
|
||||
const nsfw = board.nsfw ?? directory?.nsfw;
|
||||
|
||||
return {
|
||||
address: board.address,
|
||||
name: board.address,
|
||||
...(board.publicKey ? { publicKey: board.publicKey } : {}),
|
||||
...((list.title ?? directory?.title) ? { title: list.title ?? directory?.title } : {}),
|
||||
directoryCode: list.directoryCode,
|
||||
...(features ? { features } : {}),
|
||||
...(nsfw !== undefined ? { nsfw } : {}),
|
||||
};
|
||||
};
|
||||
|
||||
export const useDirectoryEntry = (address: string | undefined, directoryCodeHint?: string): DirectoryCommunity | undefined => {
|
||||
const directories = useDirectories();
|
||||
const directEntry = findDirectoryByAddress(directories, address);
|
||||
const directoryCode = getDirectoryCodeFromHint(directoryCodeHint, directories) ?? getDirectoryCode(directEntry) ?? getDirectoryCodeForBoardAddress(address);
|
||||
const { list } = useDirectoryList(directoryCode);
|
||||
|
||||
return getDirectoryEntryForAddress({ address, directories, directoryCodeHint: directoryCode, list });
|
||||
};
|
||||
|
||||
export const getDirectoryEntryForAddress = ({
|
||||
address,
|
||||
directories,
|
||||
directoryCodeHint,
|
||||
list,
|
||||
}: {
|
||||
address: string | undefined;
|
||||
directories: DirectoryCommunity[];
|
||||
directoryCodeHint?: string;
|
||||
list?: DirectoryList | null;
|
||||
}): DirectoryCommunity | undefined => {
|
||||
const directEntry = findDirectoryByAddress(directories, address);
|
||||
const hintedDirectoryCode = getDirectoryCodeFromHint(directoryCodeHint, directories);
|
||||
const directoryCode = hintedDirectoryCode ?? getDirectoryCode(directEntry) ?? list?.directoryCode ?? getDirectoryCodeForBoardAddress(address);
|
||||
const directory = findDirectoryByCode(directories, directoryCode);
|
||||
return getCandidateDirectoryEntry({ address, directory, list: list ?? null }) ?? directEntry;
|
||||
};
|
||||
Reference in New Issue
Block a user