1
0
Fork 0

[react] fix: Respect user account units & header fixes

This fixes #310 by ensuring the user units are respected.
It also includes some tweaks for the header menu in the editor

- Better default/non-default styling for icons
- Fix alignment of various menus within the ribbon
This commit is contained in:
joostdecock 2025-05-01 17:36:40 +02:00 committed by Joost De Cock
parent 02e5ed25da
commit b6cb59e94c
4 changed files with 40 additions and 22 deletions

View file

@ -3,6 +3,7 @@ import { missingMeasurements, flattenFlags } from '../lib/index.mjs'
// Hooks
import React, { useState, useEffect } from 'react'
import { useBackend } from '@freesewing/react/hooks/useBackend'
import { useAccount } from '@freesewing/react/hooks/useAccount'
import { useDesignTranslation } from '@freesewing/react/hooks/useDesignTranslation'
// Components
import { Null } from '@freesewing/react/components/Null'
@ -69,7 +70,7 @@ export const HeaderMenuDraftView = (props) => {
return (
<>
<div className="tw:flex tw:flex-row tw:gap-0.5 tw:lg:gap-1">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-0.5 tw:lg:gap-1">
<HeaderMenuDraftViewDesignOptions {...props} i18n={i18n} />
<HeaderMenuDraftViewCoreSettings {...props} i18n={i18n} />
<HeaderMenuDraftViewUiPreferences {...props} i18n={i18n} />
@ -265,24 +266,31 @@ export const HeaderMenuDraftViewFlags = (props) => {
export const HeaderMenuDraftViewIcons = (props) => {
const { update, state } = props
const { settings = {} } = state // Guard against undefined settings
const { account } = useAccount() // we need to know the user's preferred units
const accountUnits = account.imperial ? 'imperial' : 'metric'
const Button = HeaderMenuButton
const size = 'tw:w-5 tw:h-5'
const muted = 'tw:text-current tw:opacity-50'
const ux = state.ui.ux
const levels = {
...props.config.uxLevels.core,
...props.config.uxLevels.ui,
}
// Visual indication between default and non-default settings
const style = {
dflt: 'tw:text-current tw:opacity-50',
custom: 'tw:text-accent',
}
return (
<div className="tw:hidden tw:lg:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<div className="tw:hidden tw:lg:flex tw:flex-row tw:items-center tw:min-h-12 tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
{ux >= levels.sa ? (
<Button
lgOnly
updateHandler={update.toggleSa}
tooltip="Turns Seam Allowance on or off (see Core Settings)"
>
<SaIcon className={`${size} ${settings.sabool ? 'tw:text-secondary' : muted}`} />
<SaIcon className={`${size} ${settings.sabool ? style.custom : style.dflt}`} />
</Button>
) : null}
{ux >= levels.units ? (
@ -294,7 +302,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Switches Units between metric and imperial (see Core Settings)"
>
<UnitsIcon
className={`${size} ${settings.units === 'imperial' ? 'tw:text-secondary' : muted}`}
className={`${size} ${settings.units === accountUnits ? style.dflt : style.custom}`}
/>
</Button>
) : null}
@ -304,9 +312,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
updateHandler={() => update.settings('paperless', settings.paperless ? 0 : 1)}
tooltip="Turns Paperless on or off (see Core Settings)"
>
<PaperlessIcon
className={`${size} ${settings.paperless ? 'tw:text-secondary' : muted}`}
/>
<PaperlessIcon className={`${size} ${settings.paperless ? style.custom : style.dflt}`} />
</Button>
) : null}
{ux >= levels.complete ? (
@ -318,7 +324,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Details on or off (see Core Settings)"
>
<DetailIcon
className={`${size} ${[false, 0, '0'].includes(settings.complete) ? 'tw:text-secondary' : muted}`}
className={`${size} ${[false, 0, '0'].includes(settings.complete) ? style.custom : style.dflt}`}
/>
</Button>
) : null}
@ -331,7 +337,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Expand on or off (see Core Settings)"
>
<ExpandIcon
className={`${size} ${[false, 0, '0'].includes(settings.expand) ? 'tw:text-secondary' : muted}`}
className={`${size} ${[false, 0, '0'].includes(settings.expand) ? style.custom : style.dflt}`}
/>
</Button>
) : null}
@ -342,7 +348,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
updateHandler={() => update.ui('aside', state.ui.aside ? 0 : 1)}
tooltip="Toggles the side menu (see UI Preferences)"
>
<AsideIcon className={`${size} ${state.ui.aside ? 'tw:text-secondary' : muted}`} />
<AsideIcon className={`${size} ${state.ui.aside ? style.custom : style.dflt}`} />
</Button>
) : null}
{ux >= levels.renderer ? (
@ -354,7 +360,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Switches the Render Engine between React and SVG (see UI Preferences)"
>
<RocketIcon
className={`${size} ${state.ui.renderer === 'svg' ? 'tw:text-secondary' : muted}`}
className={`${size} ${state.ui.renderer === 'svg' ? style.custom : style.dflt}`}
/>
</Button>
) : null}
@ -369,7 +375,7 @@ export const HeaderMenuUndoIcons = (props) => {
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
return (
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<div className="tw:flex tw:flex-row tw:items-center tw:min-h-12 tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<Button
lgOnly
updateHandler={() => update.restore(0, state._)}
@ -478,7 +484,7 @@ export const HeaderMenuSaveIcons = (props) => {
}
return (
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-2">
<div className="tw:flex tw:flex-row tw:items-center tw:min-h-12 tw:flex-wrap tw:items-center tw:justify-center tw:px-2">
<Button updateHandler={savePattern} tooltip="Save pattern" disabled={saveable ? false : true}>
<SaveIcon className={`${size} ${saveable ? 'tw:text-success' : ''}`} />
</Button>
@ -689,11 +695,6 @@ const headerMenus = {
test: HeaderMenuTestView,
layout: HeaderMenuLayoutView,
timing: HeaderMenuDraftView,
//HeaderMenuDraftViewDesignOptions,
//HeaderMenuDraftViewCoreSettings,
//HeaderMenuDraftViewUiPreferences,
//HeaderMenuDraftViewFlags,
//HeaderMenuDraftViewIcons,
}
export const HeaderMenu = ({ config, Design, pattern, state, update, strings }) => {
@ -713,7 +714,7 @@ export const HeaderMenu = ({ config, Design, pattern, state, update, strings })
} tw:transition-[top] tw:duration-300 tw:ease-in-out`}
>
<div
className={`tw:flex tw:flex-row tw:flex-wrap tw:gap-0.5 tw:lg:gap-1 tw:w-full tw:items-start tw:justify-center tw:py-1 tw:md:py-1.5`}
className={`tw:flex tw:flex-row tw:items-center tw:flex-wrap tw:gap-0.5 tw:lg:gap-1 tw:w-full tw:items-start tw:justify-center tw:py-1 tw:md:py-1.5`}
>
<HeaderMenuViewMenu {...{ config, state, update, open, setOpen, strings }} />
<ViewSpecificMenu {...{ config, state, update, Design, pattern, open, setOpen, strings }} />

View file

@ -1,4 +1,5 @@
import React from 'react'
import { useAccount } from '@freesewing/react/hooks/useAccount'
import {
menuCoreSettingsOnlyHandler,
menuCoreSettingsSaboolHandler,
@ -32,11 +33,13 @@ import { SettingsIcon } from '@freesewing/react/components/Icon'
*/
export const CoreSettingsMenu = ({ Design, state, i18n, update }) => {
const { settings = {} } = state // Guard against undefined settings
const { account } = useAccount() // We need to know the user's preferred units
const structure = menuCoreSettingsStructure({
units: settings.units,
sabool: settings.sabool,
parts: Design.patternConfig.draftOrder,
accountUnits: account.imperial ? 'imperial' : 'metric',
})
const inputs = {

View file

@ -122,6 +122,15 @@ export const Editor = ({
// object stored in account.control in localStorage instead of an integer
const ux = Number.isInteger(account.control) ? account.control : 3
/*
* Ensure we respect the units in the user's account
* But only if not units are set
*/
if (!state.settings?.units && account.imperial) {
if (passDownState.settings) passDownState.settings.units = 'imperial'
else passDownState.settings = { units: 'imperial' }
}
if (state.ui?.ux === undefined) {
passDownState.ui = { ...(state.ui || {}), ux: ux }
}

View file

@ -67,7 +67,12 @@ const CoreDocsLink = ({ item }) => (
</a>
)
export function menuCoreSettingsStructure({ units = 'metric', sabool = false, parts = [] }) {
export function menuCoreSettingsStructure({
units = 'metric',
sabool = false,
parts = [],
accountUnits = 'metric',
}) {
return {
sabool: {
dense: true,
@ -118,7 +123,7 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa
),
ux: config.uxLevels.core.units,
list: ['metric', 'imperial'],
dflt: 'metric',
dflt: accountUnits,
choiceTitles: {
metric: 'Metric Units (cm)',
imperial: 'Imperial Units (inch)',