feat: Save penDetected and penMode, and detect pen already on ToolButton click (#4955)

* save penMode and penDetected to browser cache

* added on pointer down

* added onPointerDown

* factor out and merge handlers

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
zsviczian 2022-03-22 13:29:27 +01:00 committed by GitHub
parent db28595302
commit ed31980f84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 40 deletions

View File

@ -132,8 +132,8 @@ const APP_STATE_STORAGE_CONF = (<
editingLinearElement: { browser: false, export: false, server: false }, editingLinearElement: { browser: false, export: false, server: false },
elementLocked: { browser: true, export: false, server: false }, elementLocked: { browser: true, export: false, server: false },
elementType: { browser: true, export: false, server: false }, elementType: { browser: true, export: false, server: false },
penMode: { browser: false, export: false, server: false }, penMode: { browser: true, export: false, server: false },
penDetected: { browser: false, export: false, server: false }, penDetected: { browser: true, export: false, server: false },
errorMessage: { browser: false, export: false, server: false }, errorMessage: { browser: false, export: false, server: false },
exportBackground: { browser: true, export: false, server: false }, exportBackground: { browser: true, export: false, server: false },
exportEmbedScene: { browser: true, export: false, server: false }, exportEmbedScene: { browser: true, export: false, server: false },

View File

@ -15,7 +15,12 @@ import {
} from "../scene"; } from "../scene";
import { SHAPES } from "../shapes"; import { SHAPES } from "../shapes";
import { AppState, Zoom } from "../types"; import { AppState, Zoom } from "../types";
import { capitalizeString, isTransparent, setCursorForShape } from "../utils"; import {
capitalizeString,
isTransparent,
setCursorForShape,
withBatchedUpdates,
} from "../utils";
import Stack from "./Stack"; import Stack from "./Stack";
import { ToolButton } from "./ToolButton"; import { ToolButton } from "./ToolButton";
import { hasStrokeColor } from "../scene/comparisons"; import { hasStrokeColor } from "../scene/comparisons";
@ -192,43 +197,66 @@ export const ShapesSwitcher = ({
setAppState: React.Component<any, AppState>["setState"]; setAppState: React.Component<any, AppState>["setState"];
onImageAction: (data: { pointerType: PointerType | null }) => void; onImageAction: (data: { pointerType: PointerType | null }) => void;
appState: AppState; appState: AppState;
}) => ( }) => {
<> const onChange = withBatchedUpdates(
{SHAPES.map(({ value, icon, key }, index) => { ({
const label = t(`toolBar.${value}`); elementType,
const letter = key && (typeof key === "string" ? key : key[0]); pointerType,
const shortcut = letter }: {
? `${capitalizeString(letter)} ${t("helpDialog.or")} ${index + 1}` elementType: typeof SHAPES[number]["value"];
: `${index + 1}`; pointerType: PointerType | null;
return ( }) => {
<ToolButton if (!appState.penDetected && pointerType === "pen") {
className="Shape" setAppState({
key={value} penDetected: true,
type="radio" penMode: true,
icon={icon} });
checked={elementType === value} }
name="editor-current-shape" setAppState({
title={`${capitalizeString(label)}${shortcut}`} elementType,
keyBindingLabel={`${index + 1}`} multiElement: null,
aria-label={capitalizeString(label)} selectedElementIds: {},
aria-keyshortcuts={shortcut} });
data-testid={value} setCursorForShape(canvas, { ...appState, elementType });
onChange={({ pointerType }) => { if (elementType === "image") {
setAppState({ onImageAction({ pointerType });
elementType: value, }
multiElement: null, },
selectedElementIds: {}, );
});
setCursorForShape(canvas, { ...appState, elementType: value }); return (
if (value === "image") { <>
onImageAction({ pointerType }); {SHAPES.map(({ value, icon, key }, index) => {
} const label = t(`toolBar.${value}`);
}} const letter = key && (typeof key === "string" ? key : key[0]);
/> const shortcut = letter
); ? `${capitalizeString(letter)} ${t("helpDialog.or")} ${index + 1}`
})} : `${index + 1}`;
</> return (
); <ToolButton
className="Shape"
key={value}
type="radio"
icon={icon}
checked={elementType === value}
name="editor-current-shape"
title={`${capitalizeString(label)}${shortcut}`}
keyBindingLabel={`${index + 1}`}
aria-label={capitalizeString(label)}
aria-keyshortcuts={shortcut}
data-testid={value}
onPointerDown={({ pointerType }) => {
onChange({ elementType: value, pointerType });
}}
onChange={({ pointerType }) => {
onChange({ elementType: value, pointerType });
}}
/>
);
})}
</>
);
};
export const ZoomActions = ({ export const ZoomActions = ({
renderAction, renderAction,

View File

@ -48,6 +48,7 @@ type ToolButtonProps =
type: "radio"; type: "radio";
checked: boolean; checked: boolean;
onChange?(data: { pointerType: PointerType | null }): void; onChange?(data: { pointerType: PointerType | null }): void;
onPointerDown?(data: { pointerType: PointerType }): void;
}); });
export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => { export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
@ -149,6 +150,7 @@ export const ToolButton = React.forwardRef((props: ToolButtonProps, ref) => {
title={props.title} title={props.title}
onPointerDown={(event) => { onPointerDown={(event) => {
lastPointerTypeRef.current = event.pointerType || null; lastPointerTypeRef.current = event.pointerType || null;
props.onPointerDown?.({ pointerType: event.pointerType || null });
}} }}
onPointerUp={() => { onPointerUp={() => {
requestAnimationFrame(() => { requestAnimationFrame(() => {