feat(panel): RESET shows a star while the look differs from a clean start
This commit is contained in:
@@ -28,6 +28,14 @@ import { PARAM_DEFS } from './src/utils/paramDefs';
|
||||
// @ts-ignore
|
||||
import './global.css';
|
||||
|
||||
// Shallow value diff over the union of both objects' keys: undefined and a
|
||||
// missing key both read as "no value", so an old session without the newer
|
||||
// optional knobs is not reported as an edit.
|
||||
const differs = <T extends object>(a: T, b: T) => {
|
||||
const keys = new Set([...Object.keys(a), ...Object.keys(b)]) as Set<keyof T>;
|
||||
return [...keys].some((k) => (a[k] ?? null) !== (b[k] ?? null));
|
||||
};
|
||||
|
||||
const SESSION_KEY = 'saved_session';
|
||||
const STARTUP_MODE_KEY = 'startup_mode';
|
||||
// Camera/device settings that survive restarts regardless of startup mode
|
||||
@@ -523,8 +531,28 @@ export default function App() {
|
||||
setWmRotation(0);
|
||||
setPhotoRotation(0);
|
||||
setWallLandscape(false);
|
||||
setCropRatio('none');
|
||||
setCropRect(DEFAULT_CROP_RECT);
|
||||
};
|
||||
|
||||
// RESET lights up while the look differs from what handleResetAll puts back —
|
||||
// every clause here has a matching setter there, or the star never goes out.
|
||||
// The clean-start values: the startup sim, neutral knobs, no frame, no crop,
|
||||
// both marks at their defaults, GPS stamp off, nothing rotated.
|
||||
const resetDirty =
|
||||
(selectedRecipe?.id ?? 'sim-provia') !== 'sim-provia' ||
|
||||
differs(adjustments, DEFAULT_ADJUSTMENTS) ||
|
||||
selectedFrame !== 'none' ||
|
||||
differs(customWm, DEFAULT_CUSTOM_WM) ||
|
||||
differs(customWmApplied, DEFAULT_CUSTOM_WM) ||
|
||||
differs(gpsWm, DEFAULT_GPS_WM) ||
|
||||
useGeotag ||
|
||||
wmRotation !== 0 ||
|
||||
photoRotation !== 0 ||
|
||||
wallLandscape ||
|
||||
cropRatio !== 'none' ||
|
||||
differs(cropRect, DEFAULT_CROP_RECT);
|
||||
|
||||
const handleUpdateAdjustments = (updates: Partial<ColorAdjustments>) => {
|
||||
// Storm guard, generic across every param: same-value writes (slider
|
||||
// micro-jitter / repeated pointer-move events) still build a fresh
|
||||
@@ -1276,6 +1304,7 @@ export default function App() {
|
||||
currentRecipeId={selectedRecipe?.id || ''}
|
||||
adjustments={adjustments}
|
||||
onResetAll={handleResetAll}
|
||||
resetDirty={resetDirty}
|
||||
selectedFrame={selectedFrame}
|
||||
cropRatio={cropRatio}
|
||||
onUpdateCropRatio={setCropRatio}
|
||||
|
||||
@@ -41,6 +41,9 @@ interface AdjustmentPanelProps {
|
||||
// RESET: the app's own defaults, from any tab — the startup look, every
|
||||
// parameter, the frame and the watermarks.
|
||||
onResetAll: () => void;
|
||||
// True while the look differs from a clean start: the RESET chip says so
|
||||
// ("RESET *", amber) instead of silently doing nothing visible.
|
||||
resetDirty: boolean;
|
||||
selectedFrame: FrameId;
|
||||
// FRAME tab CROP. Only meaningful on the library's plain frames (the camera
|
||||
// composes through its ratio band, polaroid/wall through their own window),
|
||||
@@ -179,6 +182,7 @@ export default function AdjustmentPanel({
|
||||
currentRecipeId,
|
||||
adjustments,
|
||||
onResetAll,
|
||||
resetDirty,
|
||||
selectedFrame,
|
||||
cropRatio,
|
||||
onUpdateCropRatio,
|
||||
@@ -327,8 +331,11 @@ export default function AdjustmentPanel({
|
||||
// one can sit off-screen just when it is wanted.
|
||||
const resetChip = (): ChipDef => ({
|
||||
key: 'reset-all',
|
||||
label: 'RESET',
|
||||
// Trailing star + amber text: there is a change to undo (the chip is
|
||||
// otherwise a plain neutral RESET that puts the code back to a clean start).
|
||||
label: resetDirty ? 'RESET *' : 'RESET',
|
||||
active: false,
|
||||
amberValue: resetDirty,
|
||||
onPress: onResetAll,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user