diff --git a/frontend/src/common/constants.ts b/frontend/src/common/constants.ts index 28dbff89e..8a90a0cb5 100644 --- a/frontend/src/common/constants.ts +++ b/frontend/src/common/constants.ts @@ -95,6 +95,12 @@ export const Back: Faces = "back"; export const NavPillButtonHeight = 40; // pixels export const NavUnderlineButtonHeight = 42; // pixels export const ToggleButtonHeight = 38; // pixels +// Compact metrics for dense filter panels (grid-selector modal, search settings): +// Bootstrap sm control height so full-width toggle bars stay short in narrow panels. +// The 38px ToggleButtonHeight above stays the binding value for the +// /display rail's source toggles (SPEC-display-left-rail.md) - do not conflate them. +export const CompactToggleHeight = 31; // pixels +export const SourceToggleWidth = 88; // pixels // The tag name behind the default mature-content exclusion. Must match the backend's // cardpicker/constants.py NSFW constant - it's the same string filename-bracket tagging // writes into Card.tags and the seeded sensitive tag uses (docs/features/moderation.md). diff --git a/frontend/src/features/filters/CompressedFilter.tsx b/frontend/src/features/filters/CompressedFilter.tsx index 2ce416eea..a4861d682 100644 --- a/frontend/src/features/filters/CompressedFilter.tsx +++ b/frontend/src/features/filters/CompressedFilter.tsx @@ -2,7 +2,7 @@ import Form from "react-bootstrap/Form"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight } from "@/common/constants"; interface CompressedFilterProps { compressed: boolean; @@ -24,9 +24,9 @@ export const CompressedFilter = ({ offClassName="flex-centre" onstyle="info" offstyle="success" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={compressed} /> diff --git a/frontend/src/features/filters/MatureContentFilter.tsx b/frontend/src/features/filters/MatureContentFilter.tsx index 91b28f429..9b9e3fab6 100644 --- a/frontend/src/features/filters/MatureContentFilter.tsx +++ b/frontend/src/features/filters/MatureContentFilter.tsx @@ -11,7 +11,7 @@ import Container from "react-bootstrap/Container"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { NSFW_TAG_NAME, ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight, NSFW_TAG_NAME } from "@/common/constants"; import { FilterSettings } from "@/common/schema_types"; interface MatureContentFilterProps { @@ -48,9 +48,9 @@ export function MatureContentFilter({ offClassName="flex-centre" onstyle="warning" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={showingMatureContent} /> diff --git a/frontend/src/features/filters/ResolvedAttributeFilter.tsx b/frontend/src/features/filters/ResolvedAttributeFilter.tsx index 82804c065..de891fde1 100644 --- a/frontend/src/features/filters/ResolvedAttributeFilter.tsx +++ b/frontend/src/features/filters/ResolvedAttributeFilter.tsx @@ -10,7 +10,7 @@ import Container from "react-bootstrap/Container"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight } from "@/common/constants"; import { FilterSettings } from "@/common/schema_types"; interface ResolvedAttributeFilterProps { @@ -45,9 +45,9 @@ export function ResolvedAttributeFilter({ offClassName="flex-centre" onstyle="success" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={filterSettings.fullArtOnly} />
@@ -65,9 +65,9 @@ export function ResolvedAttributeFilter({ offClassName="flex-centre" onstyle="success" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={filterSettings.borderlessOnly} /> diff --git a/frontend/src/features/filters/SourceBackendFilter.tsx b/frontend/src/features/filters/SourceBackendFilter.tsx index 58c05d705..7f3bdafbf 100644 --- a/frontend/src/features/filters/SourceBackendFilter.tsx +++ b/frontend/src/features/filters/SourceBackendFilter.tsx @@ -2,7 +2,7 @@ import { useEffect } from "react"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight } from "@/common/constants"; import { BackendType } from "@/common/types"; import { useGoogleDriveBackendConfigured, @@ -45,9 +45,9 @@ export const SourceBackendFilter = ({ offClassName="flex-centre" onstyle="success" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={backendType === "remote"} disabled={!(remoteBackendConfigured && localBackendConfigured)} /> diff --git a/frontend/src/features/gridSelector/GridSelectorFilters.tsx b/frontend/src/features/gridSelector/GridSelectorFilters.tsx index db266e560..1dff426a8 100644 --- a/frontend/src/features/gridSelector/GridSelectorFilters.tsx +++ b/frontend/src/features/gridSelector/GridSelectorFilters.tsx @@ -49,7 +49,9 @@ interface GridSelectorFiltersProps { * rail forces compressed tiles anyway (Bkg 4 - the "Card display style"/Compressed toggle is * near-inert there and clips at the rail edge) - both controls live inside the one "View" * accordion (ViewSettings.tsx), so hiding that section kills both in one exclusion. */ - hiddenSections?: Array<"jump" | "view" | "sort" | "filter">; + hiddenSections?: Array< + "jump" | "view" | "sort" | "filter" | "filter-sources" | "filter-attributes" + >; } export const GridSelectorFilters = ({ @@ -145,14 +147,19 @@ export const GridSelectorFilters = ({ maxDPIUpperBound={projectFilter?.maximumDPI} maxSizeUpperBound={projectFilter?.maximumSize} showBoilerplate={false} + // The rail's chip fieldset already covers these (SPEC-display-left-rail.md) - + // the rail caller hides the stock duplicates; modal/browse callers keep them. + showResolvedAttributeFilter={!hidden.has("filter-attributes")} // allowedLanguages={allowedLanguages} /> - + {!hidden.has("filter-sources") && ( + + )} )} diff --git a/frontend/src/features/gridSelector/SelectVersionResults.tsx b/frontend/src/features/gridSelector/SelectVersionResults.tsx index a63271fab..e836f8dc1 100644 --- a/frontend/src/features/gridSelector/SelectVersionResults.tsx +++ b/frontend/src/features/gridSelector/SelectVersionResults.tsx @@ -1646,8 +1646,16 @@ export function SelectVersionResults({ setSourceSettings={search.setSourceSettings} projectFilter={search.projectFilter} // E4/X4 (Bkg 3/4) - only the stacked (rail) caller hides "View" (Group-by/Compressed); - // the sidebar (modal/browse) callers are unaffected. - hiddenSections={layout === "stacked" ? ["view"] : undefined} + // the sidebar (modal/browse) callers are unaffected. 2026-07-24 owner escalation: + // the rail also hides the stock sources table and attribute toggle bars - the rail's + // own SOURCES accordion and Treatment/Frame/Border chip fieldset are the designed + // versions of both (SPEC-display-left-rail.md), and rendering the stock duplicates + // beneath them was the "looks nothing like Quorra's spec" report. + hiddenSections={ + layout === "stacked" + ? ["view", "filter-sources", "filter-attributes"] + : undefined + } /> ); diff --git a/frontend/src/features/searchSettings/FilterSettings.tsx b/frontend/src/features/searchSettings/FilterSettings.tsx index ee6cbf10c..8d5b93641 100644 --- a/frontend/src/features/searchSettings/FilterSettings.tsx +++ b/frontend/src/features/searchSettings/FilterSettings.tsx @@ -26,6 +26,11 @@ interface FilterSettingsProps { maxSizeUpperBound?: number; allowedLanguages?: Array; showBoilerplate?: boolean; + /** The /display rail already renders the spec's Treatment/Frame/Border chip fieldset + * (SPEC-display-left-rail.md), so its embedding of this panel hides the duplicate + * stock attribute toggles. Every other caller (Search Settings modal, classic grid + * selector) leaves this true and is unchanged. */ + showResolvedAttributeFilter?: boolean; } export function FilterSettings({ @@ -36,6 +41,7 @@ export function FilterSettings({ maxSizeUpperBound, allowedLanguages, showBoilerplate = true, + showResolvedAttributeFilter = true, }: FilterSettingsProps) { return ( <> @@ -80,11 +86,15 @@ export function FilterSettings({ filterSettings={filterSettings} setFilterSettings={setFilterSettings} /> -
- + {showResolvedAttributeFilter && ( + <> +
+ + + )} ); } diff --git a/frontend/src/features/searchSettings/SearchTypeSettings.tsx b/frontend/src/features/searchSettings/SearchTypeSettings.tsx index 3ed42e0f5..ee30d697d 100644 --- a/frontend/src/features/searchSettings/SearchTypeSettings.tsx +++ b/frontend/src/features/searchSettings/SearchTypeSettings.tsx @@ -9,7 +9,7 @@ import Container from "react-bootstrap/Container"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight } from "@/common/constants"; import { SearchTypeSettings as SearchTypeSettingsType } from "@/common/types"; interface SearchTypeSettingsProps { @@ -44,9 +44,9 @@ export function SearchTypeSettings({ offClassName="flex-centre" onstyle="success" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={searchTypeSettings.fuzzySearch} /> {enableFiltersApplyToCardbacks && ( @@ -66,9 +66,9 @@ export function SearchTypeSettings({ offClassName="flex-centre" onstyle="success" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={searchTypeSettings.filterCardbacks} /> diff --git a/frontend/src/features/searchSettings/SourceSettings.tsx b/frontend/src/features/searchSettings/SourceSettings.tsx index cddcbfb36..9a5e27cdd 100644 --- a/frontend/src/features/searchSettings/SourceSettings.tsx +++ b/frontend/src/features/searchSettings/SourceSettings.tsx @@ -15,7 +15,7 @@ import Table from "react-bootstrap/Table"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight, SourceToggleWidth } from "@/common/constants"; import { SourceDocument, SourceRow as SourceRowType, @@ -64,9 +64,9 @@ const SourceRow = ({ offClassName="flex-centre prevent-select" onstyle="primary" offstyle="secondary" - size="md" - width={80 + "%"} - height={ToggleButtonHeight + "px"} + size="sm" + width={SourceToggleWidth + "px"} + height={CompactToggleHeight + "px"} active={enabled} onClick={() => toggleSpecificSourceActiveStatus(index)} /> @@ -208,10 +208,20 @@ export function SourceSettings({ if (maybeSourceDocuments != null) { sourceTable = ( - +
{/* TODO: migrate this to AutofillTable at some point? too big a job for right now. */} - +
Active Name @@ -262,7 +272,7 @@ export function SourceSettings({ )}
-
diff --git a/frontend/src/features/viewSettings/ViewSettings.tsx b/frontend/src/features/viewSettings/ViewSettings.tsx index ccc109269..597d30a58 100644 --- a/frontend/src/features/viewSettings/ViewSettings.tsx +++ b/frontend/src/features/viewSettings/ViewSettings.tsx @@ -8,7 +8,7 @@ import React from "react"; // @ts-ignore: https://github.com/arnthor3/react-bootstrap-toggle/issues/21 import Toggle from "react-bootstrap-toggle"; -import { ToggleButtonHeight } from "@/common/constants"; +import { CompactToggleHeight } from "@/common/constants"; import { useAppDispatch, useAppSelector } from "@/common/types"; import { selectFrontsVisible, @@ -27,9 +27,9 @@ export function ViewSettings() { offClassName="flex-centre" onstyle="info" offstyle="info" - width={100 + "%"} - size="md" - height={ToggleButtonHeight + "px"} + width={"100%"} + size="sm" + height={CompactToggleHeight + "px"} active={frontsVisible} /> );