[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:
parent
02e5ed25da
commit
b6cb59e94c
4 changed files with 40 additions and 22 deletions
|
@ -3,6 +3,7 @@ import { missingMeasurements, flattenFlags } from '../lib/index.mjs'
|
||||||
// Hooks
|
// Hooks
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
import { useBackend } from '@freesewing/react/hooks/useBackend'
|
||||||
|
import { useAccount } from '@freesewing/react/hooks/useAccount'
|
||||||
import { useDesignTranslation } from '@freesewing/react/hooks/useDesignTranslation'
|
import { useDesignTranslation } from '@freesewing/react/hooks/useDesignTranslation'
|
||||||
// Components
|
// Components
|
||||||
import { Null } from '@freesewing/react/components/Null'
|
import { Null } from '@freesewing/react/components/Null'
|
||||||
|
@ -69,7 +70,7 @@ export const HeaderMenuDraftView = (props) => {
|
||||||
|
|
||||||
return (
|
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} />
|
<HeaderMenuDraftViewDesignOptions {...props} i18n={i18n} />
|
||||||
<HeaderMenuDraftViewCoreSettings {...props} i18n={i18n} />
|
<HeaderMenuDraftViewCoreSettings {...props} i18n={i18n} />
|
||||||
<HeaderMenuDraftViewUiPreferences {...props} i18n={i18n} />
|
<HeaderMenuDraftViewUiPreferences {...props} i18n={i18n} />
|
||||||
|
@ -265,24 +266,31 @@ export const HeaderMenuDraftViewFlags = (props) => {
|
||||||
export const HeaderMenuDraftViewIcons = (props) => {
|
export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
const { update, state } = props
|
const { update, state } = props
|
||||||
const { settings = {} } = state // Guard against undefined settings
|
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 Button = HeaderMenuButton
|
||||||
const size = 'tw:w-5 tw:h-5'
|
const size = 'tw:w-5 tw:h-5'
|
||||||
const muted = 'tw:text-current tw:opacity-50'
|
|
||||||
const ux = state.ui.ux
|
const ux = state.ui.ux
|
||||||
const levels = {
|
const levels = {
|
||||||
...props.config.uxLevels.core,
|
...props.config.uxLevels.core,
|
||||||
...props.config.uxLevels.ui,
|
...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 (
|
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 ? (
|
{ux >= levels.sa ? (
|
||||||
<Button
|
<Button
|
||||||
lgOnly
|
lgOnly
|
||||||
updateHandler={update.toggleSa}
|
updateHandler={update.toggleSa}
|
||||||
tooltip="Turns Seam Allowance on or off (see Core Settings)"
|
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>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
{ux >= levels.units ? (
|
{ux >= levels.units ? (
|
||||||
|
@ -294,7 +302,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
tooltip="Switches Units between metric and imperial (see Core Settings)"
|
tooltip="Switches Units between metric and imperial (see Core Settings)"
|
||||||
>
|
>
|
||||||
<UnitsIcon
|
<UnitsIcon
|
||||||
className={`${size} ${settings.units === 'imperial' ? 'tw:text-secondary' : muted}`}
|
className={`${size} ${settings.units === accountUnits ? style.dflt : style.custom}`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -304,9 +312,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
updateHandler={() => update.settings('paperless', settings.paperless ? 0 : 1)}
|
updateHandler={() => update.settings('paperless', settings.paperless ? 0 : 1)}
|
||||||
tooltip="Turns Paperless on or off (see Core Settings)"
|
tooltip="Turns Paperless on or off (see Core Settings)"
|
||||||
>
|
>
|
||||||
<PaperlessIcon
|
<PaperlessIcon className={`${size} ${settings.paperless ? style.custom : style.dflt}`} />
|
||||||
className={`${size} ${settings.paperless ? 'tw:text-secondary' : muted}`}
|
|
||||||
/>
|
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
{ux >= levels.complete ? (
|
{ux >= levels.complete ? (
|
||||||
|
@ -318,7 +324,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
tooltip="Turns Details on or off (see Core Settings)"
|
tooltip="Turns Details on or off (see Core Settings)"
|
||||||
>
|
>
|
||||||
<DetailIcon
|
<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>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -331,7 +337,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
tooltip="Turns Expand on or off (see Core Settings)"
|
tooltip="Turns Expand on or off (see Core Settings)"
|
||||||
>
|
>
|
||||||
<ExpandIcon
|
<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>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -342,7 +348,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
updateHandler={() => update.ui('aside', state.ui.aside ? 0 : 1)}
|
updateHandler={() => update.ui('aside', state.ui.aside ? 0 : 1)}
|
||||||
tooltip="Toggles the side menu (see UI Preferences)"
|
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>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
{ux >= levels.renderer ? (
|
{ux >= levels.renderer ? (
|
||||||
|
@ -354,7 +360,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
|
||||||
tooltip="Switches the Render Engine between React and SVG (see UI Preferences)"
|
tooltip="Switches the Render Engine between React and SVG (see UI Preferences)"
|
||||||
>
|
>
|
||||||
<RocketIcon
|
<RocketIcon
|
||||||
className={`${size} ${state.ui.renderer === 'svg' ? 'tw:text-secondary' : muted}`}
|
className={`${size} ${state.ui.renderer === 'svg' ? style.custom : style.dflt}`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -369,7 +375,7 @@ export const HeaderMenuUndoIcons = (props) => {
|
||||||
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
|
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
|
||||||
|
|
||||||
return (
|
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
|
<Button
|
||||||
lgOnly
|
lgOnly
|
||||||
updateHandler={() => update.restore(0, state._)}
|
updateHandler={() => update.restore(0, state._)}
|
||||||
|
@ -478,7 +484,7 @@ export const HeaderMenuSaveIcons = (props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
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}>
|
<Button updateHandler={savePattern} tooltip="Save pattern" disabled={saveable ? false : true}>
|
||||||
<SaveIcon className={`${size} ${saveable ? 'tw:text-success' : ''}`} />
|
<SaveIcon className={`${size} ${saveable ? 'tw:text-success' : ''}`} />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -689,11 +695,6 @@ const headerMenus = {
|
||||||
test: HeaderMenuTestView,
|
test: HeaderMenuTestView,
|
||||||
layout: HeaderMenuLayoutView,
|
layout: HeaderMenuLayoutView,
|
||||||
timing: HeaderMenuDraftView,
|
timing: HeaderMenuDraftView,
|
||||||
//HeaderMenuDraftViewDesignOptions,
|
|
||||||
//HeaderMenuDraftViewCoreSettings,
|
|
||||||
//HeaderMenuDraftViewUiPreferences,
|
|
||||||
//HeaderMenuDraftViewFlags,
|
|
||||||
//HeaderMenuDraftViewIcons,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HeaderMenu = ({ config, Design, pattern, state, update, strings }) => {
|
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`}
|
} tw:transition-[top] tw:duration-300 tw:ease-in-out`}
|
||||||
>
|
>
|
||||||
<div
|
<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 }} />
|
<HeaderMenuViewMenu {...{ config, state, update, open, setOpen, strings }} />
|
||||||
<ViewSpecificMenu {...{ config, state, update, Design, pattern, open, setOpen, strings }} />
|
<ViewSpecificMenu {...{ config, state, update, Design, pattern, open, setOpen, strings }} />
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { useAccount } from '@freesewing/react/hooks/useAccount'
|
||||||
import {
|
import {
|
||||||
menuCoreSettingsOnlyHandler,
|
menuCoreSettingsOnlyHandler,
|
||||||
menuCoreSettingsSaboolHandler,
|
menuCoreSettingsSaboolHandler,
|
||||||
|
@ -32,11 +33,13 @@ import { SettingsIcon } from '@freesewing/react/components/Icon'
|
||||||
*/
|
*/
|
||||||
export const CoreSettingsMenu = ({ Design, state, i18n, update }) => {
|
export const CoreSettingsMenu = ({ Design, state, i18n, update }) => {
|
||||||
const { settings = {} } = state // Guard against undefined settings
|
const { settings = {} } = state // Guard against undefined settings
|
||||||
|
const { account } = useAccount() // We need to know the user's preferred units
|
||||||
|
|
||||||
const structure = menuCoreSettingsStructure({
|
const structure = menuCoreSettingsStructure({
|
||||||
units: settings.units,
|
units: settings.units,
|
||||||
sabool: settings.sabool,
|
sabool: settings.sabool,
|
||||||
parts: Design.patternConfig.draftOrder,
|
parts: Design.patternConfig.draftOrder,
|
||||||
|
accountUnits: account.imperial ? 'imperial' : 'metric',
|
||||||
})
|
})
|
||||||
|
|
||||||
const inputs = {
|
const inputs = {
|
||||||
|
|
|
@ -122,6 +122,15 @@ export const Editor = ({
|
||||||
// object stored in account.control in localStorage instead of an integer
|
// object stored in account.control in localStorage instead of an integer
|
||||||
const ux = Number.isInteger(account.control) ? account.control : 3
|
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) {
|
if (state.ui?.ux === undefined) {
|
||||||
passDownState.ui = { ...(state.ui || {}), ux: ux }
|
passDownState.ui = { ...(state.ui || {}), ux: ux }
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,12 @@ const CoreDocsLink = ({ item }) => (
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
|
|
||||||
export function menuCoreSettingsStructure({ units = 'metric', sabool = false, parts = [] }) {
|
export function menuCoreSettingsStructure({
|
||||||
|
units = 'metric',
|
||||||
|
sabool = false,
|
||||||
|
parts = [],
|
||||||
|
accountUnits = 'metric',
|
||||||
|
}) {
|
||||||
return {
|
return {
|
||||||
sabool: {
|
sabool: {
|
||||||
dense: true,
|
dense: true,
|
||||||
|
@ -118,7 +123,7 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa
|
||||||
),
|
),
|
||||||
ux: config.uxLevels.core.units,
|
ux: config.uxLevels.core.units,
|
||||||
list: ['metric', 'imperial'],
|
list: ['metric', 'imperial'],
|
||||||
dflt: 'metric',
|
dflt: accountUnits,
|
||||||
choiceTitles: {
|
choiceTitles: {
|
||||||
metric: 'Metric Units (cm)',
|
metric: 'Metric Units (cm)',
|
||||||
imperial: 'Imperial Units (inch)',
|
imperial: 'Imperial Units (inch)',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue