mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(mod queue): reset board filter on navigation (#1166)
This commit is contained in:
@@ -95,9 +95,9 @@ describe('persisted extra stores', () => {
|
|||||||
alertThresholdUnit: 'hours',
|
alertThresholdUnit: 'hours',
|
||||||
dismissedCommentCids: [],
|
dismissedCommentCids: [],
|
||||||
queuedCommentHistory: [],
|
queuedCommentHistory: [],
|
||||||
selectedBoardFilter: 'music.eth',
|
|
||||||
viewMode: 'feed',
|
viewMode: 'feed',
|
||||||
});
|
});
|
||||||
|
expect(useModQueueStore.getState()).not.toHaveProperty('selectedBoardFilter');
|
||||||
expect(useModQueueStore.getState().getAlertThresholdSeconds()).toBe(10_800);
|
expect(useModQueueStore.getState().getAlertThresholdSeconds()).toBe(10_800);
|
||||||
|
|
||||||
useModQueueStore.getState().setAlertThreshold(15, 'minutes');
|
useModQueueStore.getState().setAlertThreshold(15, 'minutes');
|
||||||
@@ -105,7 +105,6 @@ describe('persisted extra stores', () => {
|
|||||||
useModQueueStore.getState().dismissCommentFromQueue('approved-cid');
|
useModQueueStore.getState().dismissCommentFromQueue('approved-cid');
|
||||||
useModQueueStore.getState().rememberCommentsInQueue([{ cid: 'approved-cid', approved: true, content: 'approved body' }]);
|
useModQueueStore.getState().rememberCommentsInQueue([{ cid: 'approved-cid', approved: true, content: 'approved body' }]);
|
||||||
useModQueueStore.getState().rememberCommentsInQueue([{ cid: 'rejected-cid', approved: false, content: 'rejected body' }]);
|
useModQueueStore.getState().rememberCommentsInQueue([{ cid: 'rejected-cid', approved: false, content: 'rejected body' }]);
|
||||||
useModQueueStore.getState().setSelectedBoardFilter('tech.eth');
|
|
||||||
useModQueueStore.getState().setViewMode('compact');
|
useModQueueStore.getState().setViewMode('compact');
|
||||||
|
|
||||||
expect(useModQueueStore.getState()).toMatchObject({
|
expect(useModQueueStore.getState()).toMatchObject({
|
||||||
@@ -116,9 +115,9 @@ describe('persisted extra stores', () => {
|
|||||||
{ cid: 'rejected-cid', approved: false, content: 'rejected body' },
|
{ cid: 'rejected-cid', approved: false, content: 'rejected body' },
|
||||||
{ cid: 'approved-cid', approved: true, content: 'approved body' },
|
{ cid: 'approved-cid', approved: true, content: 'approved body' },
|
||||||
],
|
],
|
||||||
selectedBoardFilter: 'tech.eth',
|
|
||||||
viewMode: 'compact',
|
viewMode: 'compact',
|
||||||
});
|
});
|
||||||
|
expect(localStorage.getItem('mod-queue-storage')).not.toContain('selectedBoardFilter');
|
||||||
expect(useModQueueStore.getState().getAlertThresholdSeconds()).toBe(900);
|
expect(useModQueueStore.getState().getAlertThresholdSeconds()).toBe(900);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,10 @@ interface ModQueueState {
|
|||||||
alertThresholdUnit: AlertThresholdUnit;
|
alertThresholdUnit: AlertThresholdUnit;
|
||||||
dismissedCommentCids: string[];
|
dismissedCommentCids: string[];
|
||||||
queuedCommentHistory: QueuedCommentSnapshot[];
|
queuedCommentHistory: QueuedCommentSnapshot[];
|
||||||
selectedBoardFilter: string | null;
|
|
||||||
viewMode: ModQueueViewMode;
|
viewMode: ModQueueViewMode;
|
||||||
dismissCommentFromQueue: (cid: string) => void;
|
dismissCommentFromQueue: (cid: string) => void;
|
||||||
rememberCommentsInQueue: (comments: QueuedCommentSnapshot[]) => void;
|
rememberCommentsInQueue: (comments: QueuedCommentSnapshot[]) => void;
|
||||||
setAlertThreshold: (value: number, unit: AlertThresholdUnit) => void;
|
setAlertThreshold: (value: number, unit: AlertThresholdUnit) => void;
|
||||||
setSelectedBoardFilter: (boardAddress: string | null) => void;
|
|
||||||
setViewMode: (viewMode: ModQueueViewMode) => void;
|
setViewMode: (viewMode: ModQueueViewMode) => void;
|
||||||
// Helper to get threshold in seconds for calculations
|
// Helper to get threshold in seconds for calculations
|
||||||
getAlertThresholdSeconds: () => number;
|
getAlertThresholdSeconds: () => number;
|
||||||
@@ -34,10 +32,7 @@ interface OldPersistedState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Type for persisted data (without methods)
|
// Type for persisted data (without methods)
|
||||||
type PersistedModQueueData = Pick<
|
type PersistedModQueueData = Pick<ModQueueState, 'alertThresholdValue' | 'alertThresholdUnit' | 'dismissedCommentCids' | 'queuedCommentHistory' | 'viewMode'>;
|
||||||
ModQueueState,
|
|
||||||
'alertThresholdValue' | 'alertThresholdUnit' | 'dismissedCommentCids' | 'queuedCommentHistory' | 'selectedBoardFilter' | 'viewMode'
|
|
||||||
>;
|
|
||||||
|
|
||||||
const useModQueueStore = create<ModQueueState>()(
|
const useModQueueStore = create<ModQueueState>()(
|
||||||
persist(
|
persist(
|
||||||
@@ -69,10 +64,8 @@ const useModQueueStore = create<ModQueueState>()(
|
|||||||
|
|
||||||
return { queuedCommentHistory: [...rememberedByCid.values()].slice(0, MAX_QUEUE_HISTORY_COMMENTS) };
|
return { queuedCommentHistory: [...rememberedByCid.values()].slice(0, MAX_QUEUE_HISTORY_COMMENTS) };
|
||||||
}),
|
}),
|
||||||
selectedBoardFilter: null,
|
|
||||||
viewMode: 'feed',
|
viewMode: 'feed',
|
||||||
setAlertThreshold: (value, unit) => set({ alertThresholdValue: value, alertThresholdUnit: unit }),
|
setAlertThreshold: (value, unit) => set({ alertThresholdValue: value, alertThresholdUnit: unit }),
|
||||||
setSelectedBoardFilter: (boardAddress) => set({ selectedBoardFilter: boardAddress }),
|
|
||||||
setViewMode: (viewMode) => set({ viewMode }),
|
setViewMode: (viewMode) => set({ viewMode }),
|
||||||
getAlertThresholdSeconds: () => {
|
getAlertThresholdSeconds: () => {
|
||||||
const { alertThresholdValue, alertThresholdUnit } = get();
|
const { alertThresholdValue, alertThresholdUnit } = get();
|
||||||
@@ -81,7 +74,7 @@ const useModQueueStore = create<ModQueueState>()(
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: 'mod-queue-storage',
|
name: 'mod-queue-storage',
|
||||||
version: 2,
|
version: 3,
|
||||||
// Migrate old alertThresholdHours format to new alertThresholdValue/alertThresholdUnit format
|
// Migrate old alertThresholdHours format to new alertThresholdValue/alertThresholdUnit format
|
||||||
migrate: (persistedState, version): ModQueueState => {
|
migrate: (persistedState, version): ModQueueState => {
|
||||||
const state = persistedState as OldPersistedState;
|
const state = persistedState as OldPersistedState;
|
||||||
@@ -91,7 +84,6 @@ const useModQueueStore = create<ModQueueState>()(
|
|||||||
alertThresholdUnit: 'hours' as AlertThresholdUnit,
|
alertThresholdUnit: 'hours' as AlertThresholdUnit,
|
||||||
dismissedCommentCids: state.dismissedCommentCids ?? [],
|
dismissedCommentCids: state.dismissedCommentCids ?? [],
|
||||||
queuedCommentHistory: state.queuedCommentHistory ?? [],
|
queuedCommentHistory: state.queuedCommentHistory ?? [],
|
||||||
selectedBoardFilter: state.selectedBoardFilter ?? null,
|
|
||||||
viewMode: state.viewMode ?? 'feed',
|
viewMode: state.viewMode ?? 'feed',
|
||||||
};
|
};
|
||||||
// Zustand will merge this with the store definition (which includes methods)
|
// Zustand will merge this with the store definition (which includes methods)
|
||||||
@@ -103,7 +95,6 @@ const useModQueueStore = create<ModQueueState>()(
|
|||||||
alertThresholdUnit: state.alertThresholdUnit ?? 'hours',
|
alertThresholdUnit: state.alertThresholdUnit ?? 'hours',
|
||||||
dismissedCommentCids: state.dismissedCommentCids ?? [],
|
dismissedCommentCids: state.dismissedCommentCids ?? [],
|
||||||
queuedCommentHistory: state.queuedCommentHistory ?? [],
|
queuedCommentHistory: state.queuedCommentHistory ?? [],
|
||||||
selectedBoardFilter: state.selectedBoardFilter ?? null,
|
|
||||||
viewMode: state.viewMode ?? 'feed',
|
viewMode: state.viewMode ?? 'feed',
|
||||||
};
|
};
|
||||||
return current as ModQueueState;
|
return current as ModQueueState;
|
||||||
@@ -113,7 +104,6 @@ const useModQueueStore = create<ModQueueState>()(
|
|||||||
alertThresholdUnit: state.alertThresholdUnit,
|
alertThresholdUnit: state.alertThresholdUnit,
|
||||||
dismissedCommentCids: state.dismissedCommentCids,
|
dismissedCommentCids: state.dismissedCommentCids,
|
||||||
queuedCommentHistory: state.queuedCommentHistory,
|
queuedCommentHistory: state.queuedCommentHistory,
|
||||||
selectedBoardFilter: state.selectedBoardFilter,
|
|
||||||
viewMode: state.viewMode,
|
viewMode: state.viewMode,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
import { createRoot, type Root } from 'react-dom/client';
|
import { createRoot, type Root } from 'react-dom/client';
|
||||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
import { Link, MemoryRouter, Route, Routes, useNavigate } from 'react-router-dom';
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import ModQueueView from '../mod-queue';
|
import ModQueueView from '../mod-queue';
|
||||||
|
|
||||||
@@ -31,7 +31,6 @@ const testState = vi.hoisted(() => ({
|
|||||||
queuedCommentHistory: [] as TestComment[],
|
queuedCommentHistory: [] as TestComment[],
|
||||||
rememberCommentsInQueueMock: vi.fn(),
|
rememberCommentsInQueueMock: vi.fn(),
|
||||||
resetMock: vi.fn(),
|
resetMock: vi.fn(),
|
||||||
selectedBoardFilter: null as string | null,
|
|
||||||
setResetFunctionMock: vi.fn(),
|
setResetFunctionMock: vi.fn(),
|
||||||
viewMode: 'compact' as 'compact' | 'feed',
|
viewMode: 'compact' as 'compact' | 'feed',
|
||||||
}));
|
}));
|
||||||
@@ -42,8 +41,6 @@ const getModQueueState = () => ({
|
|||||||
getAlertThresholdSeconds: () => 6 * 60 * 60,
|
getAlertThresholdSeconds: () => 6 * 60 * 60,
|
||||||
queuedCommentHistory: testState.queuedCommentHistory,
|
queuedCommentHistory: testState.queuedCommentHistory,
|
||||||
rememberCommentsInQueue: testState.rememberCommentsInQueueMock,
|
rememberCommentsInQueue: testState.rememberCommentsInQueueMock,
|
||||||
selectedBoardFilter: testState.selectedBoardFilter,
|
|
||||||
setSelectedBoardFilter: vi.fn(),
|
|
||||||
setViewMode: vi.fn(),
|
setViewMode: vi.fn(),
|
||||||
viewMode: testState.viewMode,
|
viewMode: testState.viewMode,
|
||||||
});
|
});
|
||||||
@@ -161,6 +158,13 @@ vi.mock('../../../hooks/use-current-time', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('../../../hooks/use-directories', () => ({
|
vi.mock('../../../hooks/use-directories', () => ({
|
||||||
|
findDirectoryByAddress: (directories: typeof testState.directories, address: string) =>
|
||||||
|
directories.find((directory) =>
|
||||||
|
[directory.address, directory.directoryCode, directory.title].some(
|
||||||
|
(value) => typeof value === 'string' && value.replace(/(\.bso|\.eth)$/, '') === address.replace(/(\.bso|\.eth)$/, ''),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
normalizeBoardAddress: (address: string) => address.replace(/(\.bso|\.eth)$/, ''),
|
||||||
useDirectories: () => testState.directories,
|
useDirectories: () => testState.directories,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -176,17 +180,17 @@ vi.mock('../../../components/error-display/error-display', () => ({
|
|||||||
default: ({ error }: { error?: Error }) => createElement('div', { 'data-testid': 'error-display' }, error?.message || 'error'),
|
default: ({ error }: { error?: Error }) => createElement('div', { 'data-testid': 'error-display' }, error?.message || 'error'),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('../../../components/footer', () => ({
|
vi.mock('../../../components/footer/footer', () => ({
|
||||||
PageFooterDesktop: ({ firstRow }: { firstRow: React.ReactNode }) => createElement('div', { 'data-testid': 'footer-desktop' }, firstRow),
|
PageFooterDesktop: ({ firstRow }: { firstRow: React.ReactNode }) => createElement('div', { 'data-testid': 'footer-desktop' }, firstRow),
|
||||||
PageFooterMobile: ({ children }: { children: React.ReactNode }) => createElement('div', { 'data-testid': 'footer-mobile' }, children),
|
PageFooterMobile: ({ children }: { children: React.ReactNode }) => createElement('div', { 'data-testid': 'footer-mobile' }, children),
|
||||||
StyleOnlyFooterFirstRow: () => createElement('div', { 'data-testid': 'style-footer-row' }),
|
StyleOnlyFooterFirstRow: () => createElement('div', { 'data-testid': 'style-footer-row' }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('../../../components/loading-ellipsis', () => ({
|
vi.mock('../../../components/loading-ellipsis/loading-ellipsis', () => ({
|
||||||
default: ({ string }: { string: string }) => createElement('div', { 'data-testid': 'loading-ellipsis' }, string),
|
default: ({ string }: { string: string }) => createElement('div', { 'data-testid': 'loading-ellipsis' }, string),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('../../../components/tooltip', () => ({
|
vi.mock('../../../components/tooltip/tooltip', () => ({
|
||||||
default: ({ children }: { children: React.ReactNode }) => createElement(React.Fragment, {}, children),
|
default: ({ children }: { children: React.ReactNode }) => createElement(React.Fragment, {}, children),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -208,6 +212,16 @@ vi.mock('../../post/post', () => ({
|
|||||||
let container: HTMLDivElement;
|
let container: HTMLDivElement;
|
||||||
let root: Root;
|
let root: Root;
|
||||||
|
|
||||||
|
const ModQueueWithLeaveButton = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return createElement(
|
||||||
|
React.Fragment,
|
||||||
|
{},
|
||||||
|
createElement('button', { type: 'button', 'data-testid': 'leave-route', onClick: () => navigate('/other') }, 'leave'),
|
||||||
|
createElement(ModQueueView),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const renderModQueue = async () => {
|
const renderModQueue = async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
root.render(
|
root.render(
|
||||||
@@ -220,15 +234,36 @@ const renderModQueue = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderModQueueWithOtherRoute = async () => {
|
||||||
|
await act(async () => {
|
||||||
|
root.render(
|
||||||
|
createElement(
|
||||||
|
MemoryRouter,
|
||||||
|
{ initialEntries: ['/mod/queue'] },
|
||||||
|
createElement(
|
||||||
|
Routes,
|
||||||
|
{},
|
||||||
|
createElement(Route, { path: '/mod/queue', element: createElement(ModQueueWithLeaveButton) }),
|
||||||
|
createElement(Route, {
|
||||||
|
path: '/other',
|
||||||
|
element: createElement('div', {}, createElement(Link, { to: '/mod/queue' }, 'queue'), createElement('span', {}, 'other route')),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
describe('ModQueueView', () => {
|
describe('ModQueueView', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
testState.accountCommunityAddresses = ['music-posting.eth'];
|
||||||
|
testState.directories = [{ address: 'music-posting.eth', directoryCode: 'mu', title: '/mu/ - Music' }];
|
||||||
testState.dismissedCommentCids = [];
|
testState.dismissedCommentCids = [];
|
||||||
testState.feed = [];
|
testState.feed = [];
|
||||||
testState.hasMore = false;
|
testState.hasMore = false;
|
||||||
testState.isMobile = false;
|
testState.isMobile = false;
|
||||||
testState.queuedCommentHistory = [];
|
testState.queuedCommentHistory = [];
|
||||||
testState.selectedBoardFilter = null;
|
|
||||||
testState.viewMode = 'compact';
|
testState.viewMode = 'compact';
|
||||||
|
|
||||||
container = document.createElement('div');
|
container = document.createElement('div');
|
||||||
@@ -265,6 +300,58 @@ describe('ModQueueView', () => {
|
|||||||
expect(text.indexOf('No.')).toBeLessThan(text.indexOf('queue_is_empty'));
|
expect(text.indexOf('No.')).toBeLessThan(text.indexOf('queue_is_empty'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('resets the board summary selection to all after leaving and returning to the route', async () => {
|
||||||
|
testState.accountCommunityAddresses = ['music-posting.eth', 'sports-posting.eth'];
|
||||||
|
testState.directories = [
|
||||||
|
{ address: 'music-posting.eth', directoryCode: 'mu', title: '/mu/ - Music' },
|
||||||
|
{ address: 'sports-posting.eth', directoryCode: 'sp', title: '/sp/ - Sports' },
|
||||||
|
];
|
||||||
|
testState.feed = [
|
||||||
|
{
|
||||||
|
cid: 'music-pending',
|
||||||
|
communityAddress: 'music-posting.eth',
|
||||||
|
content: 'music pending body',
|
||||||
|
pendingApproval: true,
|
||||||
|
timestamp: 90_000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cid: 'sports-pending',
|
||||||
|
communityAddress: 'sports-posting.eth',
|
||||||
|
content: 'sports pending body',
|
||||||
|
pendingApproval: true,
|
||||||
|
timestamp: 90_000,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await renderModQueueWithOtherRoute();
|
||||||
|
|
||||||
|
const musicButton = Array.from(container.querySelectorAll<HTMLButtonElement>('button')).find((button) => button.textContent?.includes('mu'));
|
||||||
|
expect(musicButton).toBeTruthy();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
musicButton?.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(Array.from(container.querySelectorAll<HTMLButtonElement>('button')).find((button) => button.textContent?.includes('mu'))?.className).toContain(
|
||||||
|
'boardSummaryLinkSelected',
|
||||||
|
);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
container.querySelector<HTMLButtonElement>('[data-testid="leave-route"]')?.click();
|
||||||
|
});
|
||||||
|
expect(container.textContent).toContain('other route');
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
container.querySelector<HTMLAnchorElement>('a[href="/mod/queue"]')?.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
const allButton = Array.from(container.querySelectorAll<HTMLButtonElement>('button')).find((button) => button.textContent?.includes('all'));
|
||||||
|
expect(allButton?.className).toContain('boardSummaryLinkSelected');
|
||||||
|
expect(Array.from(container.querySelectorAll<HTMLButtonElement>('button')).find((button) => button.textContent?.includes('mu'))?.className).not.toContain(
|
||||||
|
'boardSummaryLinkSelected',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('opens a full floating post preview from a compact excerpt hover', async () => {
|
it('opens a full floating post preview from a compact excerpt hover', async () => {
|
||||||
testState.feed = [
|
testState.feed = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { Virtuoso } from 'react-virtuoso';
|
|||||||
import styles from './mod-queue.module.css';
|
import styles from './mod-queue.module.css';
|
||||||
import postStyles from '../post/post.module.css';
|
import postStyles from '../post/post.module.css';
|
||||||
import useModQueueStore from '../../stores/use-mod-queue-store';
|
import useModQueueStore from '../../stores/use-mod-queue-store';
|
||||||
import LoadingEllipsis from '../../components/loading-ellipsis';
|
import LoadingEllipsis from '../../components/loading-ellipsis/loading-ellipsis';
|
||||||
import ErrorDisplay from '../../components/error-display/error-display';
|
import ErrorDisplay from '../../components/error-display/error-display';
|
||||||
import { useFeedStateString } from '../../hooks/use-state-string';
|
import { useFeedStateString } from '../../hooks/use-state-string';
|
||||||
import { getCommunityAddress, getBoardPath, areSameBoardAddress } from '../../lib/utils/route-utils';
|
import { getCommunityAddress, getBoardPath, areSameBoardAddress } from '../../lib/utils/route-utils';
|
||||||
@@ -40,7 +40,7 @@ import {
|
|||||||
getVisibleQueuedCommentHistory,
|
getVisibleQueuedCommentHistory,
|
||||||
shouldKeepQueuedCommentHistory,
|
shouldKeepQueuedCommentHistory,
|
||||||
} from '../../lib/utils/mod-queue-utils';
|
} from '../../lib/utils/mod-queue-utils';
|
||||||
import Tooltip from '../../components/tooltip';
|
import Tooltip from '../../components/tooltip/tooltip';
|
||||||
import { useCommunityIdentifier, useCommunityIdentifiers } from '../../hooks/use-community-identifiers';
|
import { useCommunityIdentifier, useCommunityIdentifiers } from '../../hooks/use-community-identifiers';
|
||||||
import useIsMobile from '../../hooks/use-is-mobile';
|
import useIsMobile from '../../hooks/use-is-mobile';
|
||||||
import { useCurrentTime } from '../../hooks/use-current-time';
|
import { useCurrentTime } from '../../hooks/use-current-time';
|
||||||
@@ -48,7 +48,7 @@ import { Post } from '../post/post';
|
|||||||
import { canAccessBoardModQueue, hasModQueueAccessRole } from '../../lib/utils/mod-access';
|
import { canAccessBoardModQueue, hasModQueueAccessRole } from '../../lib/utils/mod-access';
|
||||||
import capitalize from 'lodash/capitalize';
|
import capitalize from 'lodash/capitalize';
|
||||||
import lowerCase from 'lodash/lowerCase';
|
import lowerCase from 'lodash/lowerCase';
|
||||||
import { PageFooterDesktop, PageFooterMobile, StyleOnlyFooterFirstRow } from '../../components/footer';
|
import { PageFooterDesktop, PageFooterMobile, StyleOnlyFooterFirstRow } from '../../components/footer/footer';
|
||||||
import footerStyles from '../../components/footer/footer.module.css';
|
import footerStyles from '../../components/footer/footer.module.css';
|
||||||
import { useModeratedCommunityAddresses } from '../../hooks/use-moderated-community-addresses';
|
import { useModeratedCommunityAddresses } from '../../hooks/use-moderated-community-addresses';
|
||||||
|
|
||||||
@@ -263,15 +263,7 @@ const ModQueueExcerptPreviewLink = ({ comment, excerpt, postUrl, postUrlState }:
|
|||||||
{excerpt}
|
{excerpt}
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span title={excerpt} ref={setReferenceNode} tabIndex={0} onMouseEnter={openPreview} onFocus={openPreview} onMouseLeave={closePreview} onBlur={closePreview}>
|
||||||
title={excerpt}
|
|
||||||
ref={setReferenceNode}
|
|
||||||
tabIndex={0}
|
|
||||||
onMouseEnter={openPreview}
|
|
||||||
onFocus={openPreview}
|
|
||||||
onMouseLeave={closePreview}
|
|
||||||
onBlur={closePreview}
|
|
||||||
>
|
|
||||||
{excerpt}
|
{excerpt}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -687,6 +679,8 @@ interface ModQueueBoardSummaryProps {
|
|||||||
feed: Comment[];
|
feed: Comment[];
|
||||||
directories: DirectoryCommunity[];
|
directories: DirectoryCommunity[];
|
||||||
accountCommunityAddresses: string[];
|
accountCommunityAddresses: string[];
|
||||||
|
selectedBoardFilter: string | null;
|
||||||
|
setSelectedBoardFilter: (boardAddress: string | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModQueueBoardCount = ({ normal, urgent }: { normal: number; urgent: number }) => {
|
const ModQueueBoardCount = ({ normal, urgent }: { normal: number; urgent: number }) => {
|
||||||
@@ -710,10 +704,8 @@ const ModQueueBoardCount = ({ normal, urgent }: { normal: number; urgent: number
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModQueueBoardSummary = ({ feed, directories, accountCommunityAddresses }: ModQueueBoardSummaryProps) => {
|
const ModQueueBoardSummary = ({ feed, directories, accountCommunityAddresses, selectedBoardFilter, setSelectedBoardFilter }: ModQueueBoardSummaryProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const selectedBoardFilter = useModQueueStore((state) => state.selectedBoardFilter);
|
|
||||||
const setSelectedBoardFilter = useModQueueStore((state) => state.setSelectedBoardFilter);
|
|
||||||
const getAlertThresholdSeconds = useModQueueStore((state) => state.getAlertThresholdSeconds);
|
const getAlertThresholdSeconds = useModQueueStore((state) => state.getAlertThresholdSeconds);
|
||||||
const currentTime = useCurrentTime();
|
const currentTime = useCurrentTime();
|
||||||
const alertThresholdSeconds = getAlertThresholdSeconds();
|
const alertThresholdSeconds = getAlertThresholdSeconds();
|
||||||
@@ -936,7 +928,7 @@ export const ModQueueButton = ({ boardIdentifier, isMobile }: ModQueueButtonProp
|
|||||||
const ModQueueView = ({ boardIdentifier: propBoardIdentifier }: ModQueueViewProps) => {
|
const ModQueueView = ({ boardIdentifier: propBoardIdentifier }: ModQueueViewProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const selectedBoardFilter = useModQueueStore((state) => state.selectedBoardFilter);
|
const [selectedBoardFilter, setSelectedBoardFilter] = useState<string | null>(null);
|
||||||
const viewMode = useModQueueStore((state) => state.viewMode);
|
const viewMode = useModQueueStore((state) => state.viewMode);
|
||||||
const dismissedCommentCids = useModQueueStore((state) => state.dismissedCommentCids);
|
const dismissedCommentCids = useModQueueStore((state) => state.dismissedCommentCids);
|
||||||
const queuedCommentHistory = useModQueueStore((state) => state.queuedCommentHistory);
|
const queuedCommentHistory = useModQueueStore((state) => state.queuedCommentHistory);
|
||||||
@@ -1098,7 +1090,13 @@ const ModQueueView = ({ boardIdentifier: propBoardIdentifier }: ModQueueViewProp
|
|||||||
{!resolvedAddress && (
|
{!resolvedAddress && (
|
||||||
<div className={styles.controls}>
|
<div className={styles.controls}>
|
||||||
<div className={styles.controlsLeft}>
|
<div className={styles.controlsLeft}>
|
||||||
<ModQueueBoardSummary feed={feed} directories={directories} accountCommunityAddresses={accountCommunityAddresses} />
|
<ModQueueBoardSummary
|
||||||
|
feed={feed}
|
||||||
|
directories={directories}
|
||||||
|
accountCommunityAddresses={accountCommunityAddresses}
|
||||||
|
selectedBoardFilter={selectedBoardFilter}
|
||||||
|
setSelectedBoardFilter={setSelectedBoardFilter}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user