mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
Merge branch 'codex/feature/submit-board-button'
This commit is contained in:
@@ -44,6 +44,7 @@ vi.mock('react-i18next', () => ({
|
||||
if (key === 'directory_status_online') return 'online';
|
||||
if (key === 'directory_status_offline') return 'offline';
|
||||
if (key === 'directory_heading') return `${values?.boardIdentifier} directory`;
|
||||
if (key === 'directory_submit_board') return 'Submit Your Board';
|
||||
if (key === 'view') return 'View';
|
||||
return key;
|
||||
},
|
||||
@@ -75,18 +76,18 @@ vi.mock('../../../components/board-buttons/board-buttons', () => ({
|
||||
TopButton: () => createElement('button', { type: 'button' }, 'top'),
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/footer', () => ({
|
||||
vi.mock('../../../components/footer/footer', () => ({
|
||||
PageFooterDesktop: ({ firstRow, styleRow }: { firstRow: React.ReactNode; styleRow: React.ReactNode }) =>
|
||||
createElement('footer', { 'data-testid': 'desktop-footer' }, firstRow, styleRow),
|
||||
PageFooterMobile: ({ children }: { children: React.ReactNode }) => createElement('footer', { 'data-testid': 'mobile-footer' }, children),
|
||||
ThreadFooterStyleRow: () => createElement('div', null, 'style'),
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/loading-ellipsis', () => ({
|
||||
vi.mock('../../../components/loading-ellipsis/loading-ellipsis', () => ({
|
||||
default: ({ string }: { string: string }) => createElement('span', null, string),
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/tooltip', () => ({
|
||||
vi.mock('../../../components/tooltip/tooltip', () => ({
|
||||
default: ({ content, children }: { content: React.ReactNode; children: React.ReactNode }) =>
|
||||
createElement('span', { title: typeof content === 'string' ? content : undefined }, children),
|
||||
}));
|
||||
@@ -167,6 +168,7 @@ const createCommunity = (address: string, updatedAt = testState.nowSeconds - 60)
|
||||
});
|
||||
|
||||
const getDirectoryRow = (address = 'anime-and-manga.bso') => Array.from(container.querySelectorAll('tbody tr')).find((row) => row.textContent?.includes(address));
|
||||
const getSubmitBoardLinks = () => Array.from(container.querySelectorAll<HTMLAnchorElement>('a')).filter((link) => link.textContent === 'Submit Your Board');
|
||||
|
||||
describe('Directory', () => {
|
||||
beforeEach(() => {
|
||||
@@ -230,6 +232,20 @@ describe('Directory', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('links the submit-board controls to the GitHub directory edit flow', async () => {
|
||||
await renderDirectory();
|
||||
|
||||
const submitLinks = getSubmitBoardLinks();
|
||||
expect(submitLinks).toHaveLength(4);
|
||||
|
||||
for (const link of submitLinks) {
|
||||
expect(link.getAttribute('href')).toBe('https://github.com/bitsocialnet/lists/edit/master/5chan-directories/5chan-a-directory.json');
|
||||
expect(link.getAttribute('target')).toBe('_blank');
|
||||
expect(link.getAttribute('rel')).toContain('noreferrer');
|
||||
expect(link.getAttribute('rel')).toContain('noopener');
|
||||
}
|
||||
});
|
||||
|
||||
it('shows loading status while the listed board status is loading', async () => {
|
||||
testState.communities = {};
|
||||
testState.offlineHookValue = {
|
||||
|
||||
@@ -18,12 +18,24 @@
|
||||
.desktopNavLinks {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.navButtonGroup {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.submitBoardControl {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.desktopNavLinks a:not([class~='button']),
|
||||
.desktopFooterButtons a:not([class~='button']) {
|
||||
all: unset;
|
||||
@@ -36,11 +48,18 @@
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mobileNavLinks button {
|
||||
.mobileNavLinks button,
|
||||
.mobileNavLinks a[class~='button'],
|
||||
.mobileFooterButtons button,
|
||||
.mobileFooterButtons a[class~='button'] {
|
||||
text-transform: capitalize;
|
||||
margin: 5px 2px;
|
||||
}
|
||||
|
||||
.mobileSubmitRow {
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.mobileNavLinks a:not([class~='button']),
|
||||
.mobileFooterButtons a:not([class~='button']) {
|
||||
all: unset;
|
||||
@@ -49,7 +68,8 @@
|
||||
.desktopFooterButtons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
@@ -59,11 +79,6 @@
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.mobileFooterButtons button {
|
||||
text-transform: capitalize;
|
||||
margin: 5px 2px;
|
||||
}
|
||||
|
||||
.directorySummary {
|
||||
margin: 0 0 12px;
|
||||
text-align: center;
|
||||
|
||||
@@ -4,9 +4,9 @@ import { Trans, useTranslation } from 'react-i18next';
|
||||
import { useCommunity } from '@bitsocial/bitsocial-react-hooks';
|
||||
import { shouldShowSnow } from '../../lib/snow';
|
||||
import { BottomButton, BracketedCatalogButton, CatalogButton, ReturnButton, TopButton } from '../../components/board-buttons/board-buttons';
|
||||
import { PageFooterDesktop, PageFooterMobile, ThreadFooterStyleRow } from '../../components/footer';
|
||||
import LoadingEllipsis from '../../components/loading-ellipsis';
|
||||
import Tooltip from '../../components/tooltip';
|
||||
import { PageFooterDesktop, PageFooterMobile, ThreadFooterStyleRow } from '../../components/footer/footer';
|
||||
import LoadingEllipsis from '../../components/loading-ellipsis/loading-ellipsis';
|
||||
import Tooltip from '../../components/tooltip/tooltip';
|
||||
import { useDirectories } from '../../hooks/use-directories';
|
||||
import { useCommunityIdentifier } from '../../hooks/use-community-identifiers';
|
||||
import { useResolvedCommunityAddress } from '../../hooks/use-resolved-community-address';
|
||||
@@ -44,43 +44,73 @@ const computeBoardStatus = (
|
||||
|
||||
const PASS_LINK = '/pass';
|
||||
|
||||
const DirectoryDesktopTopControls = ({ communityAddress }: { communityAddress: string | undefined }) => (
|
||||
const DirectorySubmitBoardLink = ({ href }: { href: string }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<a className='button' href={href} target='_blank' rel='noreferrer noopener'>
|
||||
{t('directory_submit_board')}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
const DirectoryDesktopTopControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
|
||||
<div className={styles.desktopNavLinks}>
|
||||
<span>
|
||||
[<ReturnButton address={communityAddress} />]
|
||||
</span>
|
||||
<BracketedCatalogButton address={communityAddress} />
|
||||
<span>
|
||||
[<BottomButton />]
|
||||
<div className={styles.navButtonGroup}>
|
||||
<span>
|
||||
[<ReturnButton address={communityAddress} />]
|
||||
</span>
|
||||
<BracketedCatalogButton address={communityAddress} />
|
||||
<span>
|
||||
[<BottomButton />]
|
||||
</span>
|
||||
</div>
|
||||
<span className={styles.submitBoardControl}>
|
||||
[<DirectorySubmitBoardLink href={submitHref} />]
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
const DirectoryDesktopFooterControls = ({ communityAddress }: { communityAddress: string | undefined }) => (
|
||||
const DirectoryDesktopFooterControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
|
||||
<div className={styles.desktopFooterButtons}>
|
||||
<span>
|
||||
[<ReturnButton address={communityAddress} />]
|
||||
</span>
|
||||
<BracketedCatalogButton address={communityAddress} />
|
||||
<span>
|
||||
[<TopButton />]
|
||||
<div className={styles.navButtonGroup}>
|
||||
<span>
|
||||
[<ReturnButton address={communityAddress} />]
|
||||
</span>
|
||||
<BracketedCatalogButton address={communityAddress} />
|
||||
<span>
|
||||
[<TopButton />]
|
||||
</span>
|
||||
</div>
|
||||
<span className={styles.submitBoardControl}>
|
||||
[<DirectorySubmitBoardLink href={submitHref} />]
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
const DirectoryMobileTopControls = ({ communityAddress }: { communityAddress: string | undefined }) => (
|
||||
const DirectoryMobileTopControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
|
||||
<div className={styles.mobileNavLinks}>
|
||||
<ReturnButton address={communityAddress} />
|
||||
<CatalogButton address={communityAddress} />
|
||||
<BottomButton />
|
||||
<div>
|
||||
<ReturnButton address={communityAddress} />
|
||||
<CatalogButton address={communityAddress} />
|
||||
<BottomButton />
|
||||
</div>
|
||||
<div className={styles.mobileSubmitRow}>
|
||||
<DirectorySubmitBoardLink href={submitHref} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const DirectoryMobileFooterControls = ({ communityAddress }: { communityAddress: string | undefined }) => (
|
||||
const DirectoryMobileFooterControls = ({ communityAddress, submitHref }: { communityAddress: string | undefined; submitHref: string }) => (
|
||||
<div className={styles.mobileFooterButtons}>
|
||||
<ReturnButton address={communityAddress} />
|
||||
<CatalogButton address={communityAddress} />
|
||||
<TopButton />
|
||||
<div>
|
||||
<ReturnButton address={communityAddress} />
|
||||
<CatalogButton address={communityAddress} />
|
||||
<TopButton />
|
||||
</div>
|
||||
<div className={styles.mobileSubmitRow}>
|
||||
<DirectorySubmitBoardLink href={submitHref} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -199,9 +229,9 @@ const Directory = () => {
|
||||
|
||||
return (
|
||||
<div id='top' className={`${styles.page} ${shouldShowSnow() ? styles.garland : ''}`}>
|
||||
<DirectoryMobileTopControls communityAddress={communityAddress} />
|
||||
<DirectoryMobileTopControls communityAddress={communityAddress} submitHref={repoEditUrl} />
|
||||
<hr className={styles.desktopDivider} />
|
||||
<DirectoryDesktopTopControls communityAddress={communityAddress} />
|
||||
<DirectoryDesktopTopControls communityAddress={communityAddress} submitHref={repoEditUrl} />
|
||||
<hr className={styles.divider} />
|
||||
{isLoadingShell ? (
|
||||
<h4 className={styles.directorySummary}>
|
||||
@@ -257,9 +287,9 @@ const Directory = () => {
|
||||
</>
|
||||
)}
|
||||
|
||||
<PageFooterDesktop firstRow={<DirectoryDesktopFooterControls communityAddress={communityAddress} />} styleRow={<ThreadFooterStyleRow />} />
|
||||
<PageFooterDesktop firstRow={<DirectoryDesktopFooterControls communityAddress={communityAddress} submitHref={repoEditUrl} />} styleRow={<ThreadFooterStyleRow />} />
|
||||
<PageFooterMobile>
|
||||
<DirectoryMobileFooterControls communityAddress={communityAddress} />
|
||||
<DirectoryMobileFooterControls communityAddress={communityAddress} submitHref={repoEditUrl} />
|
||||
</PageFooterMobile>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user