Skip to content

Commit

Permalink
Merge pull request #417 from simularium/feature/updated-looping-playback
Browse files Browse the repository at this point in the history
looping playback and tooltip styling
  • Loading branch information
interim17 authored Jun 9, 2023
2 parents cc135e8 + ac22916 commit 0749f1a
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 18 deletions.
10 changes: 0 additions & 10 deletions src/components/CheckBoxTree/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,4 @@

.container :global(.ant-typography-ellipsis) {
color: var(--dark-theme-sidebar-text)
}

/* Tooltip styling */
/* Has to be global because it's at the bottom of the dom */
:global(.ant-tooltip-inner){
background-color: var(--side-panel-tooltip);
}

:global(.ant-tooltip-arrow-content){
background-color: var(--side-panel-tooltip);
}
3 changes: 3 additions & 0 deletions src/components/Icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
PlusOutlined,
MinusOutlined,
HomeOutlined,
RetweetOutlined,
} from "@ant-design/icons";

import PurpleArrowPointingRight from "../../assets/open-arrow.svg";
Expand All @@ -27,6 +28,7 @@ export const GoBack = <ArrowLeftOutlined />;
export const Reset = <HomeOutlined />;
export const ZoomIn = <PlusOutlined />;
export const ZoomOut = <MinusOutlined />;
export const LoopOutlined = <RetweetOutlined />;

export const PurpleArrow = <img src={PurpleArrowPointingRight} />;
export const AicsLogo = <img src={AicsLogoWhite} style={{ width: "140px" }} />;
Expand All @@ -51,4 +53,5 @@ export default {
ZoomIn,
ZoomOut,
BetaTag,
LoopOutlined,
};
29 changes: 28 additions & 1 deletion src/components/PlaybackControls/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ interface PlayBackProps {
pauseHandler: () => void;
prevHandler: () => void;
nextHandler: () => void;
loopHandler: () => void;
firstFrameTime: number;
lastFrameTime: number;
isPlaying: boolean;
isLooping: boolean;
onTimeChange: (time: number) => void;
loading: boolean;
timeStep: number;
Expand All @@ -31,7 +33,9 @@ const PlayBackControls = ({
playHandler,
pauseHandler,
prevHandler,
loopHandler,
isPlaying,
isLooping,
nextHandler,
firstFrameTime,
lastFrameTime,
Expand Down Expand Up @@ -187,7 +191,7 @@ const PlayBackControls = ({
value={time}
onChange={handleTimeChange}
onAfterChange={handleSliderMouseUp}
tooltip={{open : false}}
tooltip={{ open: false }}
className={[styles.slider, styles.item].join(" ")}
step={timeStep}
min={firstFrameTime}
Expand All @@ -210,6 +214,29 @@ const PlayBackControls = ({
{timeUnits ? timeUnits.name : "s"}
</span>
</div>
<Tooltip
placement="top"
title={isLooping ? "Turn off looping" : "Turn on looping"}
color={TOOLTIP_COLOR}
arrowPointAtCenter
>
<Button
className={
isLooping
? btnClassNames
: classNames([
styles.item,
styles.btn,
styles.removeBorder,
])
}
size="small"
icon={Icons.LoopOutlined}
onClick={loopHandler}
loading={loading}
disabled={isEmpty}
/>
</Tooltip>
</div>
);
};
Expand Down
5 changes: 5 additions & 0 deletions src/components/PlaybackControls/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
padding: 1px 7px 4px 7px;
border-radius: 3px;
text-align: center;
margin-right: 4px;
}

.lastFrameTime {
Expand All @@ -94,4 +95,8 @@

.step-forward::after {
content: "\e907";
}

.remove-border{
border: none;
}
4 changes: 2 additions & 2 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const URL_PARAM_KEY_FILE_NAME = "trajFileName";
export const URL_PARAM_KEY_USER_URL = "trajUrl";
export const CHECKBOX_TYPE_STAR = "star";
export type CHECKBOX_TYPE_STAR = typeof CHECKBOX_TYPE_STAR;
export const TOOLTIP_COLOR = "#141219";
export const TOOLTIP_COLOR = "#3B3649";
export const LEFT_PANEL_TOOLTIP_COLOR = "#3b3649";
export const LEFT_PANEL_TOOLTIP_DELAY = 1; // in seconds

Expand Down Expand Up @@ -48,4 +48,4 @@ export const USER_TRAJ_REDIRECTS = [
"https://aics-agentviz-data.s3.us-east-2.amazonaws.com/trajectory/springsalad_condensate_formation_Above_Ksp.simularium",
];

export const MOBILE_CUTOFF = "(max-width: 900px)";
export const MOBILE_CUTOFF = "(max-width: 900px)";
19 changes: 18 additions & 1 deletion src/containers/ViewerPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ interface ViewerPanelProps {
displayTimes: DisplayTimes;
timeUnits: TimeUnits;
isPlaying: boolean;
isLooping: boolean;
fileIsDraggedOver: boolean;
status: string;
numFrames: number;
Expand All @@ -79,6 +80,7 @@ interface ViewerPanelProps {
receiveAgentNamesAndStates: ActionCreator<ReceiveAction>;
selectionStateInfoForViewer: SelectionStateInfo;
setIsPlaying: ActionCreator<ToggleAction>;
setIsLooping: ActionCreator<ToggleAction>;
loadLocalFile: (localSimFile: LocalSimFile) => void;
dragOverViewer: ActionCreator<DragOverViewerAction>;
resetDragOverViewer: ActionCreator<ResetDragOverViewerAction>;
Expand All @@ -104,6 +106,7 @@ class ViewerPanel extends React.Component<ViewerPanelProps, ViewerPanelState> {
this.playBackOne = this.playBackOne.bind(this);
this.playForwardOne = this.playForwardOne.bind(this);
this.startPlay = this.startPlay.bind(this);
this.toggleLooping = this.toggleLooping.bind(this);
this.pause = this.pause.bind(this);
this.receiveTimeChange = this.receiveTimeChange.bind(this);
this.handleJsonMeshData = this.handleJsonMeshData.bind(this);
Expand Down Expand Up @@ -239,6 +242,11 @@ class ViewerPanel extends React.Component<ViewerPanelProps, ViewerPanelState> {
setIsPlaying(false);
}

public toggleLooping() {
const { isLooping, setIsLooping } = this.props;
setIsLooping(!isLooping);
}

public onTrajectoryFileInfoChanged(data: TrajectoryFileInfo) {
const { receiveTrajectory, simulariumController } = this.props;
const tickIntervalLength = simulariumController.tickIntervalLength;
Expand Down Expand Up @@ -270,6 +278,7 @@ class ViewerPanel extends React.Component<ViewerPanelProps, ViewerPanelState> {
timeStep,
receiveTrajectory,
setBuffering,
isLooping,
} = this.props;

if (this.state.isInitialPlay) {
Expand All @@ -291,7 +300,10 @@ class ViewerPanel extends React.Component<ViewerPanelProps, ViewerPanelState> {

const atLastFrame =
compareTimes(timeData.time, lastFrameTime, timeStep) === 0;
if (atLastFrame) {
if (atLastFrame && isLooping) {
actions.push(changeTime(0));
this.startPlay(0);
} else if (atLastFrame) {
this.pause();
}

Expand Down Expand Up @@ -356,6 +368,7 @@ class ViewerPanel extends React.Component<ViewerPanelProps, ViewerPanelState> {
displayTimes,
isBuffering,
isPlaying,
isLooping,
status,
setError,
scaleBarLabel,
Expand Down Expand Up @@ -404,6 +417,8 @@ class ViewerPanel extends React.Component<ViewerPanelProps, ViewerPanelState> {
prevHandler={this.playBackOne}
nextHandler={this.playForwardOne}
isPlaying={isPlaying}
isLooping={isLooping}
loopHandler={this.toggleLooping}
firstFrameTime={firstFrameTime}
lastFrameTime={lastFrameTime}
loading={isBuffering}
Expand Down Expand Up @@ -448,6 +463,7 @@ function mapStateToProps(state: State) {
viewerStateBranch.selectors.getFileDraggedOver(state),
isBuffering: viewerStateBranch.selectors.getIsBuffering(state),
isPlaying: viewerStateBranch.selectors.getIsPlaying(state),
isLooping: viewerStateBranch.selectors.getIsLooping(state),
};
}

Expand All @@ -463,6 +479,7 @@ const dispatchToPropsMap = {
resetDragOverViewer: viewerStateBranch.actions.resetDragOverViewer,
setBuffering: viewerStateBranch.actions.setBuffering,
setIsPlaying: viewerStateBranch.actions.setIsPlaying,
setIsLooping: viewerStateBranch.actions.setIsLooping,
setError: viewerStateBranch.actions.setError,
};

Expand Down
8 changes: 8 additions & 0 deletions src/state/viewer/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
SET_BUFFERING,
SET_IS_PLAYING,
SET_ERROR,
SET_IS_LOOPING,
} from "./constants";
import {
ViewerStatus,
Expand Down Expand Up @@ -57,3 +58,10 @@ export function setIsPlaying(isPlaying: boolean): ToggleAction {
type: SET_IS_PLAYING,
};
}

export function setIsLooping(isLooping: boolean): ToggleAction {
return {
payload: isLooping,
type: SET_IS_LOOPING,
};
}
2 changes: 2 additions & 0 deletions src/state/viewer/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ export const DRAG_FILE_OVER = makeViewerConstant("drag-file-over");
export const RESET_DRAG_FILE_OVER = makeViewerConstant("reset-drag-file-over");
export const SET_BUFFERING = makeViewerConstant("set-buffering");
export const SET_IS_PLAYING = makeViewerConstant("set-is-playing");
export const SET_IS_LOOPING = makeViewerConstant("set-is-looping");

export const VIEWER_EMPTY = "empty";
export const VIEWER_LOADING = "loading";
export const VIEWER_ERROR = "error";
export const VIEWER_SUCCESS = "success";
export const VIEWER_IMPORTING = "importing";
10 changes: 10 additions & 0 deletions src/state/viewer/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
SET_BUFFERING,
SET_IS_PLAYING,
VIEWER_ERROR,
SET_IS_LOOPING,
} from "./constants";
import {
ViewerStateBranch,
Expand All @@ -28,6 +29,7 @@ export const initialState = {
fileDraggedOver: false,
isBuffering: false,
isPlaying: false,
isLooping: false,
};

const actionToConfigMap: TypeToDescriptionMap = {
Expand Down Expand Up @@ -88,6 +90,14 @@ const actionToConfigMap: TypeToDescriptionMap = {
isPlaying: action.payload,
}),
},
[SET_IS_LOOPING]: {
accepts: (action: AnyAction): action is ToggleAction =>
action.type === SET_IS_LOOPING,
perform: (state: ViewerStateBranch, action: ToggleAction) => ({
...state,
isLooping: action.payload,
}),
},
};

export default makeReducer<ViewerStateBranch>(actionToConfigMap, initialState);
1 change: 1 addition & 0 deletions src/state/viewer/selectors/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export const getFileDraggedOver = (state: State) =>
state.viewer.fileDraggedOver;
export const getIsBuffering = (state: State) => state.viewer.isBuffering;
export const getIsPlaying = (state: State) => state.viewer.isPlaying;
export const getIsLooping = (state: State) => state.viewer.isLooping;
8 changes: 4 additions & 4 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ use the :after pseduo selector to input the content.

.ant-tooltip-inner,
.ant-popover-inner {
border-radius: 3px;
font-weight: 300;
box-shadow: 2px 2px 3px black;
}
background: var(--charcoal-grey) 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 4px var(--black);
opacity: 1;
}

0 comments on commit 0749f1a

Please sign in to comment.