Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Looker3d hotkeys #2032

Merged
merged 11 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions app/packages/app/src/components/Modal/Group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,18 @@ const GroupSample: React.FC<
slice: string;
pinned: boolean;
onClick: MouseEventHandler;
onMouseEnter: MouseEventHandler;
onMouseLeave: MouseEventHandler;
}>
> = ({ children, onClick, pinned, sampleId, slice }) => {
> = ({
children,
onClick,
pinned,
sampleId,
slice,
onMouseEnter,
onMouseLeave,
}) => {
const [hovering, setHovering] = useState(false);

const timeout: MutableRefObject<number | null> = useRef<number>(null);
Expand All @@ -73,9 +83,15 @@ const GroupSample: React.FC<
className={
pinned ? classNames(groupSample, groupSampleActive) : groupSample
}
onMouseEnter={update}
onMouseEnter={(e) => {
update();
onMouseEnter(e);
}}
onMouseMove={update}
onMouseLeave={clear}
onMouseLeave={(e) => {
clear();
onMouseLeave(e);
}}
onClickCapture={onClick}
>
{children}
Expand Down Expand Up @@ -110,13 +126,15 @@ const MainSample: React.FC<{
const pinned = !useRecoilValue(sidebarOverride);
const reset = useResetRecoilState(sidebarOverride);
const slice = useSlice(sample);
const hover = fos.useHoveredSample(sample);

return (
<GroupSample
sampleId={sample._id}
slice={slice}
pinned={pinned}
onClick={reset}
{...hover.handlers}
>
<Looker
key={sample._id}
Expand Down Expand Up @@ -188,6 +206,7 @@ const PinnedSample: React.FC = () => {

const [pinned, setPinned] = useRecoilState(sidebarOverride);
const slice = useRecoilValue(pinnedSlice) as string;
const hover = fos.useHoveredSample(sample.sample);

if (sample.__typename === "%other") {
throw new Error("bad sample");
Expand All @@ -199,6 +218,7 @@ const PinnedSample: React.FC = () => {
pinned={Boolean(pinned)}
onClick={() => setPinned(sample.sample._id)}
slice={slice}
{...hover.handlers}
>
<PluggableSample fragmentRef={fragmentRef} />
</GroupSample>
Expand Down
51 changes: 44 additions & 7 deletions app/packages/app/src/components/Modal/Looker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import { ContentDiv, ContentHeader } from "../utils";
import { useEventHandler } from "../../utils/hooks";

import { useErrorHandler } from "react-error-boundary";
import { useTheme } from "@fiftyone/components";
import { HelpPanel, useTheme } from "@fiftyone/components";
import * as fos from "@fiftyone/state";
import { useOnSelectLabel } from "@fiftyone/state";
import { lookerOptions, useOnSelectLabel } from "@fiftyone/state";
import { TooltipInfo } from "./TooltipInfo";
import { Tooltip } from "@material-ui/core";
import { sample } from "lodash";

type EventCallback = (event: CustomEvent) => void;

Expand Down Expand Up @@ -105,22 +106,41 @@ const Looker = ({ lookerRef, onClose, onNext, onPrevious }: LookerProps) => {
useEventHandler(looker, "fullscreen", useFullscreen());
useEventHandler(looker, "showOverlays", useShowOverlays());

onNext && useEventHandler(looker, "next", onNext);
onPrevious && useEventHandler(looker, "previous", onPrevious);
onClose && useEventHandler(looker, "close", onClose);
onNext &&
useEventHandler(looker, "next", (e) => {
jsonPanel.close();
helpPanel.close();
return onNext(e);
});
onPrevious &&
useEventHandler(looker, "previous", (e) => {
jsonPanel.close();
helpPanel.close();
return onPrevious(e);
});
useEventHandler(looker, "select", useOnSelectLabel());
useEventHandler(looker, "error", (event) => handleError(event.detail));
const jsonPanel = fos.useJSONPanel();
useEventHandler(looker, "options", ({ detail }) => {
const { showJSON } = detail || {};
const helpPanel = fos.useHelpPanel();
useEventHandler(looker, "options", (e) => {
const { detail } = e;
const { showJSON, showHelp, SHORTCUTS } = detail || {};
if (showJSON === true) {
jsonPanel.open(sample);
}
if (showJSON === false) {
jsonPanel.close();
}
if (showHelp === true) {
helpPanel.open(shortcutToHelpItems(SHORTCUTS));
}
if (showHelp === false) {
helpPanel.close();
}
});

onClose && useEventHandler(looker, "close", onClose);

useEffect(() => {
initialRef.current = false;
}, []);
Expand All @@ -137,6 +157,19 @@ const Looker = ({ lookerRef, onClose, onNext, onPrevious }: LookerProps) => {
e.detail && tooltip.setCoords(e.detail.coordinates);
});

const hoveredSample = useRecoilValue(fos.hoveredSample);
useEffect(() => {
looker.updater((state) => ({
...state,
shouldHandleKeyEvents: hoveredSample._id === sample._id,
options: {
...state.options,
showJSON: jsonPanel.isOpen,
showHelp: helpPanel.isOpen,
},
}));
}, [hoveredSample, sample, looker, jsonPanel, helpPanel]);

return (
<div
id={id}
Expand All @@ -153,3 +186,7 @@ const Looker = ({ lookerRef, onClose, onNext, onPrevious }: LookerProps) => {
};

export default React.memo(Looker);

function shortcutToHelpItems(SHORTCUTS) {
return Object.values(SHORTCUTS);
}
9 changes: 8 additions & 1 deletion app/packages/app/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Sidebar, { Entries } from "../Sidebar";
import Group from "./Group";
import Sample from "./Sample";
import { lookerPanelOverlayContainer } from "./Group.module.css";
import { JSONPanel } from "@fiftyone/components";
import { HelpPanel, JSONPanel } from "@fiftyone/components";

const ModalWrapper = styled.div`
position: fixed;
Expand Down Expand Up @@ -185,6 +185,7 @@ const SampleModal = () => {
const wrapperRef = useRef<HTMLDivElement>(null);
const isGroup = useRecoilValue(fos.isGroup);
const jsonPanel = fos.useJSONPanel();
const helpPanel = fos.useHelpPanel();

return ReactDOM.createPortal(
<Fragment>
Expand All @@ -202,6 +203,12 @@ const SampleModal = () => {
onCopy={() => jsonPanel.copy()}
/>
)}
{helpPanel.isOpen && (
<HelpPanel
onClose={() => helpPanel.close()}
items={helpPanel.items}
/>
)}
</ContentColumn>
<Sidebar render={renderEntry} modal={true} />
</Container>
Expand Down
5 changes: 2 additions & 3 deletions app/packages/app/src/components/Modal/Sample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@ const Sample: React.FC = () => {
};
}, [clear, hovering]);
const hoveringRef = useRef(false);
const hover = fos.useHoveredSample(data.sample, { update, clear });

return (
<div
style={{ width: "100%", height: "100%", position: "relative" }}
onMouseEnter={update}
onMouseMove={update}
onMouseLeave={clear}
{...hover.handlers}
>
<SampleBar
sampleId={_id}
Expand Down
70 changes: 70 additions & 0 deletions app/packages/components/src/components/HelpPanel/HelpPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Copyright 2017-2022, Voxel51, Inc.
*/
import {
lookerPanel,
lookerPanelContainer,
lookerPanelVerticalContainer,
lookerPanelClose,
lookerHelpPanelItems,
lookerShortcutValue,
lookerShortcutTitle,
lookerShortcutDetail,
lookerPanelFlex,
lookerPanelHeader,
} from "./panel.module.css";
import closeIcon from "../../icons/close.svg";
import { Fragment } from "react";

function Close({ onClick }) {
return (
<img
src={closeIcon}
className={lookerPanelClose}
title="Close JSON"
onClick={onClick}
/>
);
}

export default function HelpPanel({ onClose, items }) {
return (
<div
className={`${lookerPanelContainer}`}
onClick={(e) => e.stopPropagation()}
>
<div className={lookerPanelVerticalContainer}>
<div className={lookerPanel}>
<Scroll>
<Header>Help</Header>
<Items>
{items.map((item, idx) => (
<Item key={`{item.shortcut}-${idx}`} {...item} />
))}
</Items>
</Scroll>
<Close onClick={onClose} />
</div>
</div>
</div>
);
}

function Header({ children }) {
return <div className={lookerPanelHeader}>{children}</div>;
}
function Scroll({ children }) {
return <div className={lookerPanelFlex}>{children}</div>;
}
function Items({ children }) {
return <div className={lookerHelpPanelItems}>{children}</div>;
}
function Item({ shortcut, title, detail }) {
return (
<Fragment>
<div className={lookerShortcutValue}>{shortcut}</div>
<div className={lookerShortcutTitle}>{title}</div>
<div className={lookerShortcutDetail}>{detail}</div>
</Fragment>
);
}
1 change: 1 addition & 0 deletions app/packages/components/src/components/HelpPanel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./HelpPanel";
Loading