-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
191 lines (178 loc) · 8.39 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Westle</title>
<script src="./index.js" defer type="module"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<template id="try-component">
<span v-if="_try?.type === TryType.FAIL" class="try try--fail">
<span class="try__emoji try__emoji--fail">❌</span>
<span class="try__value try__value--fail">{{ _try.value }}</span>
</span>
<span v-if="_try?.type === TryType.SUCCESS" class="try try--success">
<span class="try__emoji try__emoji--success">✅</span>
<span class="try__value try__value--success">{{ _try.value }}</span>
</span>
<span v-if="_try?.type === TryType.SKIP" class="try try--skip">
<span class="try__emoji try__emoji--skip">⏭</span>
<span class="try__value try__value--skip">( skipped )</span>
</span>
<span v-if="_try === null" class="try try--blank"> </span>
</template>
<template id="player-component">
<button v-if="playingStatus === PlayerState.PLAYING" class="button player__button player__button--playing">
⏸️
</button>
<button v-else-if="playingStatus === PlayerState.NOT_PLAYING" @click="play" class="button player__button player__button--not_playing">
▶
</button>
<button v-else class="button player__button player__button--buffering">
⌛ {{ playingStatus }}
</button>
</template>
<template id="game-done-component">
<quote v-if="isGameOver" class="game-done__quote--game-over">
<pre>You're Lost In The World. You're down on your miiiiind.</pre>
</quote>
<quote v-else class="game-done__quote--game-won">
<pre>
Did you realize
That you were a champion
In their eyes?
(Yes, I did)
</pre>
</quote>
<div class="game-done__tomorrow-timer">
Time until next level:
<h1>
{{ Math.floor(secondsUntilTomorrow / 3600).toString().padStart(2, '0') }}
:
{{ Math.floor((secondsUntilTomorrow % 3600) / 60).toString().padStart(2, '0') }}
:
{{ Math.floor(secondsUntilTomorrow % 60).toString().padStart(2, '0') }}
</h1>
</div>
<div v-if="isGameOver" v-scope="TryComponent(new Try(TryType.FAIL, _song.fqSongName))" class="game-done__answer game-done__answer--fail"></div>
<div v-else-if="isGameWon" v-scope="TryComponent(new Try(TryType.SUCCESS, _song.fqSongName))" class="game-done__answer game-done__answer--success"></div>
<button @click="copyToClipboard" class="button game-done__share-btn">
<template v-if="copied">Copied!</template>
<template v-else>Share 🗣️⛷️</template>
</button>
</template>
<template id="controls-component">
<button v-if="skipIncrement !== 0" @click="skip" class="button controls__skip-btn">skip (+{{ skipIncrement }})</button>
<button class="button controls__skip-btn" v-else @click="skip"> skip </button>
<datalist id="song-datalist">
<option v-for="song in songs" :value="song.fqSongName" :key="song.fqSongName">
</datalist>
<input id="guess-input" type="text" class="controls__guess-input" list="song-datalist" v-model="guessTxt">
<button class="button controls__guess-btn" @click="guess">Guess</button>
</template>
<template id="tries-component">
<ul class="try-list">
<li v-for="_try in tries" v-scope="TryComponent(_try)" class="try-list__try" :key="_try"></li>
<li v-for="_try in (maxTries - tries.length)" v-scope="TryComponent(null)" class="try-list__try"></li>
</ul>
</template>
<template id="app-body-component">
<div v-scope="{ $template: '#tries-component' }" v-if="!isGameDone" class="tries"></div>
<div v-if="isGameDone" v-scope="{ $template: '#game-done-component' }" class="game-done"></div>
<div v-scope="PlayerComponent({ yt: _yt, gameLogic: _gameLogic })" v-if="!isGameDone" class="player"></div>
<div v-scope="ControlsComponent({ gameLogic: _gameLogic })" v-if="!isGameDone" class="controls"></div>
</template>
<template id="app-root-component">
<header class="header">
<div class="modal" v-scope="{ modalOpen: firstTimePlaying }">
<span class="modal__activator" @click="modalOpen = true">❓</span>
<div class="modal__outer" v-if="modalOpen" @click="modalOpen = false, firstTimePlaying = false">
<div class="modal__inner" @click.stop="">
<header class="modal__header">
<h1 class="modal__title">How to play</h1>
<button class="modal__close-btn" @click="modalOpen = false, firstTimePlaying = false">×</button>
</header>
<main class="modal__main">
<ol class="help-modal__ol">
<li class="help-modal__li">Listen to the intro, then find the correct Ye song in the list.</li>
<li class="help-modal__li">Skipped or incorrect attempts unlock more of the intro</li>
<li class="help-modal__li">Answer in as few tries as possible and share your score!</li>
</ol>
<button class="button help-modal__play-btn" @click="modalOpen = false, firstTimePlaying = false">Play</button>
</main>
</div>
</div>
</div>
<h1 class="header__title">Westle</h1>
<div class="modal" v-scope="{ modalOpen: false }">
<span class="modal__activator" @click="modalOpen = true">📊</span>
<div class="modal__outer" v-if="modalOpen" @click="modalOpen = false">
<div class="modal__inner" @click.stop="">
<header class="modal__header">
<h1 class="modal__title">Stats</h1>
<button class="button modal__close-btn" @click="modalOpen = false">×</button>
</header>
<main class="modal__main" v-scope="{ stats: _gameLogic.stats }">
<h4>Statistics</h4>
<dl class="stats-modal__dl">
<span class="stats-modal__dl-pair">
<dt class="stats-modal__dt">Played</dt>
<dd class="stats-modal__dd">{{ stats.played }}</dd>
</span>
<span class="stats-modal__dl-pair">
<dt class="stats-modal__dt">Won</dt>
<dd class="stats-modal__dd">{{ stats.won }}</dd>
</span>
<span class="stats-modal__dl-pair">
<dt class="stats-modal__dt">Win %</dt>
<dd class="stats-modal__dd">{{ Math.floor(stats.winRate * 100 * 10) / 10 }}</dd>
</span>
<span class="stats-modal__dl-pair">
<dt class="stats-modal__dt">Current<br>Streak</dt>
<dd class="stats-modal__dd">{{ stats.currentStreak }}</dd>
</span>
<span class="stats-modal__dl-pair">
<dt class="stats-modal__dt">Max<br>Streak</dt>
<dd class="stats-modal__dd">{{ stats.maxStreak }}</dd>
</span>
</dl>
<h4>Guess Distribution</h4>
<div class="stats-graph">
<div class="stats-graph__row" v-for="(val, idx) in stats.winHistogram.other" :key="idx">
<span class="stats-graph__row-idx">{{ idx + 1 }}</span>
<span class="stats-graph__row-bar" :style="`width: ${val / stats.winHistogram.max * 90 + 10}%;`">
<span class="stats-graph__row-num">{{ val }}</span>
</span>
</div>
</div>
</main>
</div>
</div>
</div>
</header>
<main v-scope="{ $template: '#app-body-component' }" class="app-body"></main>
</template>
<div v-scope="{ $template: '#app-root-component' }" id="appRoot" @vue:mounted="mounted"></div>
<!-- boilerplate stuff -->
<div id="youtube-audio">
<div id="youtube-player"></div>
</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function onYouTubeIframeAPIReady() {
console.debug("Youtube API is ready");
// wait for westleMainFn to not be undefined
while (typeof window.westleMainFn === "undefined") {
await sleep(100);
}
window.westleMainFn();
}
</script>
</body>
</html>