Skip to content

Commit

Permalink
[#180] UX improvements for scene timer
Browse files Browse the repository at this point in the history
  • Loading branch information
noahko96 committed Feb 24, 2022
1 parent c1a591e commit 4333163
Show file tree
Hide file tree
Showing 8 changed files with 7,269 additions and 7,096 deletions.
1 change: 1 addition & 0 deletions app/javascript/src/Store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface PortMetaContent {
itemChanges?: ItemChange[]
statChanges?: StatChange[]
isTimer: boolean
hideChoice: boolean
timeoutSeconds: number
}

Expand Down
68 changes: 49 additions & 19 deletions app/javascript/src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'storm-react-diagrams'
import ReactAudioPlayer from 'react-audio-player'
import { isMobile } from "react-device-detect";
import Countdown from 'react-countdown'

import './Player.css'

Expand Down Expand Up @@ -104,8 +105,6 @@ class Player extends React.Component<PlayerProps, PlayerState> {
showItemsStats: false
}

timeout: any = null

constructor(props: PlayerProps) {
super(props)

Expand Down Expand Up @@ -404,19 +403,17 @@ class Player extends React.Component<PlayerProps, PlayerState> {
{this.ports(node).map(port => {
let showItem = this.showIfItem(port)
let showStat = this.showIfStat(port)
let isTimer = this.isTimer(port)
if (isTimer && this.timeout == null) {
this.timeout = this.startTimer(port)
}
return !isTimer && showItem && showStat ? (
let hideChoice = this.hideChoice(port)

return !hideChoice && showItem && showStat ? (
<div key={port.getID()}>
<a
className="PlayerChoice"
title="Follow this path"
onClick={this.makeChoice.bind(this, port)}
href="#"
>
{port.label}
{port.label} {this.renderCountdown(port)}
</a>
</div>
) : null
Expand All @@ -425,6 +422,40 @@ class Player extends React.Component<PlayerProps, PlayerState> {
)
}

private renderCountdown(port: DefaultPortModel) {
const isTimer = this.isTimer(port)
const timeoutSeconds = this.timeoutSeconds(port)

const that = this

return isTimer && timeoutSeconds > 0 ? (
<Countdown
date={Date.now() + (timeoutSeconds * 1000)}
onComplete={function() {that.updateScene(port)}}
renderer={props => that.timeFromSeconds(Math.floor(props.total / 1000))}
/>
) : null
}

private timeFromSeconds(seconds: number): string {
let rv = ""

const minutes = Math.floor(seconds / 60)
const remainder = seconds % 60

if (minutes < 10) {
rv = rv.concat("0")
}
rv = rv.concat(minutes.toString())
rv = rv.concat(":")
if (remainder < 10) {
rv = rv.concat("0")
}
rv = rv.concat(remainder.toString())

return rv
}

private renderBackButton() {
return this.props.backButton ? (
<a className="SlantButton" id="back-button" onClick={this.revertToPreviousState.bind(this)} >
Expand All @@ -434,8 +465,6 @@ class Player extends React.Component<PlayerProps, PlayerState> {
}

private revertToPreviousState() {
this.stopTimer()

let newHistory = clone(this.state.history)

// remove last element from history array and assign it to lastHistory
Expand All @@ -455,6 +484,16 @@ class Player extends React.Component<PlayerProps, PlayerState> {
return isTimer
}

private hideChoice(port: DefaultPortModel): boolean {
const hideChoice: boolean = get(this.props.portMeta as any, `${port.id}.hideChoice`)
return hideChoice
}

private timeoutSeconds(port: DefaultPortModel): number {
const timeoutSeconds: number = get(this.props.portMeta as any, `${port.id}.timeoutSeconds`)
return timeoutSeconds
}

private startTimer(port: DefaultPortModel): ReturnType<typeof setTimeout> {
const timeoutSeconds: number = get(this.props.portMeta as any, `${port.id}.timeoutSeconds`)
const that = this
Expand Down Expand Up @@ -584,16 +623,7 @@ class Player extends React.Component<PlayerProps, PlayerState> {
this.updateScene(port)
}

private stopTimer() {
if (this.timeout) {
clearTimeout(this.timeout)
this.timeout = null
}
}

private updateScene(port: DefaultPortModel) {
this.stopTimer()

const itemChanges: ItemChange[] =
get(this.props.portMeta as any, `${port.id}.itemChanges`) || []
const statChanges: StatChange[] =
Expand Down
35 changes: 25 additions & 10 deletions app/javascript/src/components/PortEditor.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,32 +49,47 @@ label {
.pe-list input[type="checkbox"] + label {
align-items: center;
background: none;
background: red;
border: none;
display: flex;
height: 33px;
justify-content: center;
padding: 0;
width: 33px;
border-radius: 5px;
border-radius: 5px
}

.pe-list input[type="checkbox"] + label:after {
background: url(../images/x-icon.svg);
background-color: red;
background-image: url(../images/x-icon.svg);
background-origin: content-box;
background-repeat: no-repeat;
background-size: contain;
border-radius: 5px;
content: '';
display: block;
height: 20px;
width: 20px;
height: 33px;
width: 33px;
padding: 6px;
}

.pe-list input[type="checkbox"]:checked + label {
background: var(--mkt-gold);
.pe-list input[type="checkbox"]:checked + label:after {
background-color: var(--mkt-gold);
background-image: url(../images/check-icon.svg);
}

.pe-list input[type="checkbox"]:checked + label:after {
background: url(../images/check-icon.svg);
.pe-list .checkbox-label:after {
margin-left: 5px;
}

.pe-list .labeled-select {
display: flex;
}

.pe-list .labeled-select label {
background: none;
border: none;
justify-content: center;
padding-left: 5px;
padding-top: 5px;
}

.pe-header {
Expand Down
35 changes: 26 additions & 9 deletions app/javascript/src/components/PortEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class PortEditor extends React.Component<
const {
selectedTab,
optionsOpen,
thisPortMeta: { showIfItems, showIfStats, itemChanges, statChanges, isTimer, timeoutSeconds }
thisPortMeta: { showIfItems, showIfStats, itemChanges, statChanges, isTimer, hideChoice, timeoutSeconds }
} = this.state

return (
Expand Down Expand Up @@ -414,21 +414,33 @@ class PortEditor extends React.Component<
<li>
<div>
<input
id="is-timer"
id={`is-timer-${port.id}`}
type="checkbox"
checked={isTimer}
onChange={this.toggleTimer.bind(this)}
/>
<label htmlFor="is-timer">
<span className="sr-only">Is Timer?</span>
<label htmlFor={`is-timer-${port.id}`} className="checkbox-label">
Is Timer?
</label>
</div>
</li>
<li>
<div>
<label
className="sr-only"
htmlFor="timeout-seconds"
>
Timout Seconds
<input
id={`hide-choice-${port.id}`}
type="checkbox"
checked={hideChoice}
onChange={this.toggleHideChoice.bind(this)}
/>
<label htmlFor={`hide-choice-${port.id}`} className="checkbox-label">
Hide Choice?
</label>
</div>
</li>
<li>
<div className="labeled-select">
<label htmlFor="timeout-seconds">
Seconds
</label>
<input
id="timeout-seconds"
Expand Down Expand Up @@ -467,6 +479,11 @@ class PortEditor extends React.Component<
this.savePortMeta()
}

toggleHideChoice = (e: React.MouseEvent) => {
this.state.thisPortMeta.hideChoice = !this.state.thisPortMeta.hideChoice
this.savePortMeta()
}

setTimeoutSeconds = (e: React.FocusEvent<HTMLInputElement>) => {
this.state.thisPortMeta.timeoutSeconds = parseInt(e.target.value, 0)
this.savePortMeta()
Expand Down
4 changes: 1 addition & 3 deletions app/javascript/src/components/TutorialPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@ const pages: TutorialPageContent[] = [
{
title: '#10 - Advanced - Using Timers',
text: [
"Using timers allows you to automatically send players to the next scene if they do not choose an option within a certain amount of time.",
"You just need to check the box and set how many seconds pass before moving on under the Timers tab in choice options.",
"Please note that choices that are timers will not be seen by the player and only the first timer in the choice list will actually be used."
"Using timers allows you to automatically send players to the next scene if they do not choose an option within a certain amount of time."
],
image: require('../images/tutorial/timers.gif')
},
Expand Down
Binary file modified app/javascript/src/images/tutorial/timers.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"prop-types": "^15.6.2",
"react": "16.14",
"react-audio-player": "^0.17.0",
"react-countdown": "^2.3.2",
"react-device-detect": "^1.17.0",
"react-dnd": "^13.1.1",
"react-dnd-html5-backend": "^12.1.1",
Expand Down
Loading

0 comments on commit 4333163

Please sign in to comment.