Skip to content

Commit

Permalink
[#180] Add timer to scenes
Browse files Browse the repository at this point in the history
  • Loading branch information
noahko96 committed Feb 24, 2022
1 parent e86404a commit a22dc8e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 6 deletions.
2 changes: 2 additions & 0 deletions app/javascript/src/Store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export interface PortMetaContent {
showIfStats?: ShowIfStat[]
itemChanges?: ItemChange[]
statChanges?: StatChange[]
isTimer: boolean
timeoutSeconds: number
}

export interface ShowIfItem {
Expand Down
34 changes: 33 additions & 1 deletion app/javascript/src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class Player extends React.Component<PlayerProps, PlayerState> {
showItemsStats: false
}

timeout: number = 0

constructor(props: PlayerProps) {
super(props)

Expand Down Expand Up @@ -402,7 +404,11 @@ class Player extends React.Component<PlayerProps, PlayerState> {
{this.ports(node).map(port => {
let showItem = this.showIfItem(port)
let showStat = this.showIfStat(port)
return showItem && showStat ? (
let isTimer = this.isTimer(port)
if (isTimer && this.timeout == 0) {
this.timeout = this.startTimer(port)
}
return !isTimer && showItem && showStat ? (
<div key={port.getID()}>
<a
className="PlayerChoice"
Expand All @@ -428,6 +434,8 @@ 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 @@ -442,6 +450,17 @@ class Player extends React.Component<PlayerProps, PlayerState> {
)
}

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

private startTimer(port: DefaultPortModel): number {
const timeoutSeconds: number = get(this.props.portMeta as any, `${port.id}.timeoutSeconds`)
const that = this
return setTimeout(function() {that.updateScene(port)}, timeoutSeconds * 1000)
}

private showIfItem(port: DefaultPortModel): boolean {
const { currentItems } = this.state
const showIfItems: ShowIfItem[] = get(
Expand Down Expand Up @@ -562,6 +581,19 @@ class Player extends React.Component<PlayerProps, PlayerState> {
private makeChoice(port: DefaultPortModel, event: Event) {
event.preventDefault()

this.updateScene(port)
}

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

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

const itemChanges: ItemChange[] =
get(this.props.portMeta as any, `${port.id}.itemChanges`) || []
const statChanges: StatChange[] =
Expand Down
62 changes: 61 additions & 1 deletion 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 }
thisPortMeta: { showIfItems, showIfStats, itemChanges, statChanges, isTimer, timeoutSeconds }
} = this.state

return (
Expand Down Expand Up @@ -123,6 +123,16 @@ class PortEditor extends React.Component<
>
Show If
</button>
<button
className={
selectedTab === 'timer'
? 'pe-active-tab'
: 'pe-inactive-tab'
}
onClick={() => this.setSelectedTab('timer')}
>
Timer
</button>
</div>

{selectedTab === 'items' && (
Expand Down Expand Up @@ -395,6 +405,43 @@ class PortEditor extends React.Component<
<PortEditorFooter onClick={this.addShowIfStat.bind(this)} />
</div>
)}

{selectedTab === 'timer' && (
<div className="flexDiv">
<PortEditorHeader>Set Up Timer</PortEditorHeader>

<ul className="pe-list">
<li>
<div>
<input
id="is-timer"
type="checkbox"
checked={isTimer}
onChange={this.toggleTimer.bind(this)}
/>
<label htmlFor="is-timer">
<span className="sr-only">Is Timer?</span>
</label>
</div>
<div>
<label
className="sr-only"
htmlFor="timeout-seconds"
>
Timout Seconds
</label>
<input
id="timeout-seconds"
onBlur={this.setTimeoutSeconds.bind(this)}
defaultValue={
timeoutSeconds ? timeoutSeconds.toString() : ''
}
/>
</div>
</li>
</ul>
</div>
)}
</>
)}
</section>
Expand All @@ -412,6 +459,19 @@ class PortEditor extends React.Component<
this.setState(prevState => ({ optionsOpen: !prevState.optionsOpen }))
}

/**
* Timer
*/
toggleTimer = (e: React.MouseEvent) => {
this.state.thisPortMeta.isTimer = !this.state.thisPortMeta.isTimer
this.savePortMeta()
}

setTimeoutSeconds = (e: React.FocusEvent<HTMLInputElement>) => {
this.state.thisPortMeta.timeoutSeconds = parseInt(e.target.value, 0)
this.savePortMeta()
}

/**
* Show If Items
*/
Expand Down
17 changes: 13 additions & 4 deletions app/javascript/src/components/TutorialPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,16 @@ const pages: TutorialPageContent[] = [
image: require('../images/tutorial/using_conditions.gif')
},
{
title: '#10 - Advanced - Using Formatting',
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."
],
image: require('../images/tutorial/timers.gif')
},
{
title: '#11 - Advanced - Using Formatting',
text: [
'Formatting allows you to customize the scene content depending on your items and stats.',
'When someone is playing the game created by the below example, we will show the player their \'Energy\' and \'Speed\' values and then will tell them that they have the \'Key\' if the \'Key\' is present.'
Expand All @@ -106,19 +115,19 @@ const pages: TutorialPageContent[] = [
link: 'Get additional help.'
},
{
title: "#11 - Advanced - Copying and Pasting",
title: "#12 - Advanced - Copying and Pasting",
text: [
'If you want certain sections of your story to also be in another one of your stories, you can easily copy and paste that section of the story with either our \'Copy\' and \'Paste\' buttons or your typical keyboard shortcuts.',
'In order to select the section of your story to copy, you have several options. You can just click on a singular scene you want to copy, you can hold the Shift key and drag your mouse over the seciton you want to copy, or you can hold the Shift key while clicking the scenes you wish to copy.'
],
image: require('../images/tutorial/copy-paste.gif')
},
{
title: '#12 - Time to Play!',
title: '#13 - Time to Play!',
text: ['Press “Play” to read your story and get a shareable link.']
},
{
title: '#13 - Disclaimer',
title: '#14 - Disclaimer',
text: [
"This project was primarily built in a weekend, so you may encounter some quirks along the way. If something doesn't look right, saving your story and refreshing the page might do the trick. If saving isn't working, you can try copying and pasting your story into a new story as a last resort.",
'And of course, feel free to drop us a note in our feedback form (available from the footer on the homepage).',
Expand Down
Binary file added 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.

0 comments on commit a22dc8e

Please sign in to comment.