diff --git a/src/components/ColorPicker/index.tsx b/src/components/ColorPicker/index.tsx
index 3181813f..f26dded8 100644
--- a/src/components/ColorPicker/index.tsx
+++ b/src/components/ColorPicker/index.tsx
@@ -32,7 +32,7 @@ const ColorPicker = ({
}: ColorPickerProps): JSX.Element => {
const [currentColor, setCurrentColor] = useState(initialColor);
const [debouncedColor] = useDebounce(currentColor, 250);
- const isInitialRender = useRef(true);
+ const isUserInteraction = useRef(false);
const [isColorPickerVisible, setColorPickerVisible] = useState(false);
const [lastSelectedColor, setLastSelectedColor] = useState(initialColor);
@@ -51,14 +51,13 @@ const ColorPicker = ({
color: newColor.toLowerCase(),
};
applyUserColor(colorChange);
+ updateRecentColors(newColor.toLowerCase());
};
useEffect(() => {
- if (isInitialRender.current) {
- isInitialRender.current = false;
- } else {
+ if (isUserInteraction.current) {
handleColorChange(debouncedColor);
- updateRecentColors(debouncedColor);
+ isUserInteraction.current = false;
}
}, [debouncedColor]);
@@ -66,6 +65,11 @@ const ColorPicker = ({
setCurrentColor(initialColor);
}, [initialColor]);
+ const onColorUpdate = (newColor: string) => {
+ isUserInteraction.current = true;
+ setCurrentColor(newColor);
+ };
+
const updateRecentColors = (color: string) => {
if (recentColors.includes(color)) {
return;
@@ -79,7 +83,7 @@ const ColorPicker = ({
const renderColorPickerComponent = () => (
-
+
@@ -87,7 +91,7 @@ const ColorPicker = ({
className={styles.largeSwatch}
style={{ backgroundColor: lastSelectedColor }}
onClick={() => {
- setCurrentColor(lastSelectedColor);
+ onColorUpdate(lastSelectedColor);
}}
>
@@ -132,7 +134,7 @@ const ColorPicker = ({
key={color}
className={styles.swatch}
style={{ background: color }}
- onClick={() => setCurrentColor(color)}
+ onClick={() => onColorUpdate(color)}
/>
))}
@@ -144,7 +146,7 @@ const ColorPicker = ({
key={color}
className={styles.swatch}
style={{ background: color }}
- onClick={() => setCurrentColor(color)}
+ onClick={() => onColorUpdate(color)}
/>
))}
diff --git a/src/containers/ModelPanel/index.tsx b/src/containers/ModelPanel/index.tsx
index 7c742825..32909878 100644
--- a/src/containers/ModelPanel/index.tsx
+++ b/src/containers/ModelPanel/index.tsx
@@ -3,6 +3,7 @@ import { ActionCreator } from "redux";
import { connect } from "react-redux";
import { State } from "../../state/types";
+import { areDefaultUISettingsApplied } from "../../state/compoundSelectors";
import { ViewerStatus } from "../../state/viewer/types";
import { getStatus } from "../../state/viewer/selectors";
import { RequestNetworkFileAction } from "../../state/trajectory/types";
@@ -17,6 +18,9 @@ import {
SetVisibleAction,
SetRecentColorsAction,
HandleColorChangeAction,
+ ColorSetting,
+ SetCurrentColorSettingAction,
+ ResetAction,
} from "../../state/selection/types";
import {
turnAgentsOnByDisplayKey,
@@ -24,6 +28,8 @@ import {
setAgentsVisible,
setRecentColors,
handleColorChange,
+ setCurrentColorSetting,
+ clearUserSelectedColors,
} from "../../state/selection/actions";
import {
getAgentVisibilityMap,
@@ -36,7 +42,8 @@ import NoTrajectoriesText from "../../components/NoTrajectoriesText";
import NetworkFileFailedText from "../../components/NoTrajectoriesText/NetworkFileFailedText";
import NoTypeMappingText from "../../components/NoTrajectoriesText/NoTypeMappingText";
import SideBarContents from "../../components/SideBarContents";
-import { AgentMetadata } from "../../constants/interfaces";
+import NavButton from "../../components/NavButton";
+import { AgentMetadata, ButtonClass } from "../../constants/interfaces";
import {
getSelectAllVisibilityMap,
getSelectNoneVisibilityMap,
@@ -63,6 +70,9 @@ interface ModelPanelProps {
setRecentColors: ActionCreator
;
selectedAgentMetadata: AgentMetadata;
handleColorChange: ActionCreator;
+ defaultUiSettingsApplied: boolean;
+ setCurrentColorSetting: ActionCreator;
+ clearUserSelectedColors: ActionCreator;
}
const ModelPanel: React.FC = ({
@@ -82,6 +92,9 @@ const ModelPanel: React.FC = ({
setRecentColors,
selectedAgentMetadata,
handleColorChange,
+ defaultUiSettingsApplied,
+ setCurrentColorSetting,
+ clearUserSelectedColors,
}): JSX.Element => {
const checkboxTree = (
= ({
),
};
+ const handlePreviewDefaultColors = (colorSetting: ColorSetting) => {
+ if (!defaultUiSettingsApplied) {
+ setCurrentColorSetting({ currentColorSetting: colorSetting });
+ }
+ };
+
return (
+ {contentMap[viewerStatus]}
+
+ handlePreviewDefaultColors(ColorSetting.Default)
+ }
+ onMouseLeave={() =>
+ handlePreviewDefaultColors(
+ ColorSetting.UserSelected
+ )
+ }
+ />
+
,
+ ]}
selectedAgentMetadata={selectedAgentMetadata}
uiDisplayData={uiDisplayDataTree}
/>
@@ -136,6 +173,7 @@ function mapStateToProps(state: State) {
isNetworkedFile: getIsNetworkedFile(state),
recentColors: getRecentColors(state),
selectedAgentMetadata: getSelectedAgentMetadata(state),
+ defaultUiSettingsApplied: areDefaultUISettingsApplied(state),
};
}
@@ -147,6 +185,8 @@ const dispatchToPropsMap = {
setAgentsVisible,
setRecentColors,
handleColorChange,
+ setCurrentColorSetting,
+ clearUserSelectedColors,
};
export default connect(mapStateToProps, dispatchToPropsMap)(ModelPanel);
diff --git a/src/state/compoundSelectors/compoundSelectors.test.ts b/src/state/compoundSelectors/compoundSelectors.test.ts
index 008ca7ff..9ae538ea 100644
--- a/src/state/compoundSelectors/compoundSelectors.test.ts
+++ b/src/state/compoundSelectors/compoundSelectors.test.ts
@@ -1,4 +1,4 @@
-import { getCurrentUIData } from ".";
+import { getCurrentUIData, areDefaultUISettingsApplied } from ".";
import { initialState } from "..";
import { ColorSetting } from "../selection/types";
@@ -77,3 +77,76 @@ describe("getCurrentUIData", () => {
]);
});
});
+
+describe("areDefaultUISettingsApplied", () => {
+ it("returns false if selectedUIDisplayData contains selections and selectedUIDisplayData and defaultUIData are not equal", () => {
+ expect(
+ areDefaultUISettingsApplied({
+ ...initialState,
+ trajectory: {
+ defaultUIData: [
+ {
+ name: "agent1",
+ displayStates: [],
+ color: "#bbbbbb",
+ },
+ ],
+ },
+ selection: {
+ ...initialState.selection,
+ selectedUIDisplayData: [
+ {
+ name: "agent1",
+ displayStates: [],
+ color: "#000",
+ },
+ ],
+ },
+ })
+ ).toBe(false);
+ });
+ it("returns true if selectedUIDisplayData contains no selections", () => {
+ expect(
+ areDefaultUISettingsApplied({
+ ...initialState,
+ trajectory: {
+ defaultUIData: [
+ {
+ name: "agent1",
+ displayStates: [],
+ color: "#bbbbbb",
+ },
+ ],
+ },
+ selection: {
+ selectedUIDisplayData: [],
+ },
+ })
+ ).toBe(true);
+ });
+ it("returns true if selectedUIDisplayData and defaultUIData are equal", () => {
+ expect(
+ areDefaultUISettingsApplied({
+ ...initialState,
+ trajectory: {
+ defaultUIData: [
+ {
+ name: "agent1",
+ displayStates: [],
+ color: "#bbbbbb",
+ },
+ ],
+ },
+ selection: {
+ selectedUIDisplayData: [
+ {
+ name: "agent1",
+ displayStates: [],
+ color: "#bbbbbb",
+ },
+ ],
+ },
+ })
+ ).toBe(true);
+ });
+});
diff --git a/src/state/compoundSelectors/index.ts b/src/state/compoundSelectors/index.ts
index ce2c1132..ca6ee04d 100644
--- a/src/state/compoundSelectors/index.ts
+++ b/src/state/compoundSelectors/index.ts
@@ -1,5 +1,6 @@
import { createSelector } from "reselect";
import { UIDisplayData } from "@aics/simularium-viewer";
+import { isEqual } from "lodash";
import { getDefaultUIDisplayData } from "../trajectory/selectors";
import {
@@ -27,3 +28,17 @@ export const getCurrentUIData = createSelector(
: defaultData;
}
);
+
+export const areDefaultUISettingsApplied = createSelector(
+ [getSelectedUIDisplayData, getDefaultUIDisplayData],
+ (selectedUIDisplayData, defaultUIData) => {
+ /**
+ * we can't just check if currentColorSettings === ColorSettings.Default
+ * because that state can be used to preview settings
+ */
+ return (
+ selectedUIDisplayData.length === 0 ||
+ isEqual(selectedUIDisplayData, defaultUIData)
+ );
+ }
+);
diff --git a/src/state/selection/actions.ts b/src/state/selection/actions.ts
index c384b98c..70c71506 100644
--- a/src/state/selection/actions.ts
+++ b/src/state/selection/actions.ts
@@ -14,6 +14,7 @@ import {
GET_DISPLAY_DATA_FROM_BROWSER,
SET_CURRENT_COLOR_SETTINGS,
HANDLE_COLOR_CHANGE,
+ CLEAR_UI_DATA_FROM_STATE,
} from "./constants";
import {
ChangeAgentsRenderingStateAction,
@@ -136,3 +137,9 @@ export function setCurrentColorSetting(payload: {
type: SET_CURRENT_COLOR_SETTINGS,
};
}
+
+export function clearUserSelectedColors(): ResetAction {
+ return {
+ type: CLEAR_UI_DATA_FROM_STATE,
+ };
+}
diff --git a/src/state/selection/constants.ts b/src/state/selection/constants.ts
index f72230fc..4db22ba1 100644
--- a/src/state/selection/constants.ts
+++ b/src/state/selection/constants.ts
@@ -32,3 +32,6 @@ export const GET_DISPLAY_DATA_FROM_BROWSER = makeSelectConstant(
export const SET_CURRENT_COLOR_SETTINGS = makeSelectConstant(
"set-current-color-settings"
);
+export const CLEAR_UI_DATA_FROM_STATE = makeSelectConstant(
+ "clear-ui-data-from-state"
+);
diff --git a/src/state/selection/logics.ts b/src/state/selection/logics.ts
index c8a85f22..1258402e 100644
--- a/src/state/selection/logics.ts
+++ b/src/state/selection/logics.ts
@@ -9,6 +9,7 @@ import { getCurrentUIData } from "../compoundSelectors";
import {
GET_DISPLAY_DATA_FROM_BROWSER,
HANDLE_COLOR_CHANGE,
+ CLEAR_UI_DATA_FROM_STATE,
} from "./constants";
import { setCurrentColorSetting, setSelectedUIDisplayData } from "./actions";
import { applyColorChangeToUiDisplayData, isSameAgentTree } from "../../util";
@@ -57,9 +58,6 @@ const getDisplayDataFromBrowserLogic = createLogic({
);
reject(action);
}
- setCurrentColorSetting({
- currentColorSetting: ColorSetting.UserSelected,
- });
allow(setSelectedUIDisplayData(storedUIData));
},
process() {
@@ -70,4 +68,24 @@ const getDisplayDataFromBrowserLogic = createLogic({
type: GET_DISPLAY_DATA_FROM_BROWSER,
});
-export default [handleColorChangeLogic, getDisplayDataFromBrowserLogic];
+export const resetSelectedUIDisplayDataLogic = createLogic({
+ process(deps: ReduxLogicDeps, dispatch, done) {
+ const { getState } = deps;
+ const fileKey = getSimulariumFile(getState()).name;
+ localStorage.removeItem(fileKey);
+ dispatch(
+ setCurrentColorSetting({
+ currentColorSetting: ColorSetting.Default,
+ })
+ );
+ dispatch(setSelectedUIDisplayData([]));
+ done();
+ },
+ type: CLEAR_UI_DATA_FROM_STATE,
+});
+
+export default [
+ handleColorChangeLogic,
+ getDisplayDataFromBrowserLogic,
+ resetSelectedUIDisplayDataLogic,
+];