[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
|
||||
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 }} />
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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)',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue