Compare commits
3 commits
174067d946
...
668a5e3dd0
Author | SHA1 | Date | |
---|---|---|---|
Chandler Swift | 668a5e3dd0 | ||
Chandler Swift | 72844f83ce | ||
Chandler Swift | 92518cee5a |
39
index.html
39
index.html
|
@ -17,15 +17,16 @@
|
||||||
<option value="" selected>Select a state…</option>
|
<option value="" selected>Select a state…</option>
|
||||||
<option v-for="state in states">{{ state }}</option>
|
<option v-for="state in states">{{ state }}</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="btn btn-primary" type="button" @click="launch" :disabled="launched">Play</button>
|
<button class="btn btn-primary" type="button" @click="launch" :disabled="launched || !state_name">Play</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-secondary" type="button" @click="save" :disabled="!launched">Save</button>
|
<button class="btn btn-secondary" type="button" @click="save" :disabled="!launched">Save</button>
|
||||||
<button class="btn btn-success" type="button" @click="restore" :disabled="launched">Restore</button>
|
<label for="restore-input" class="btn btn-success" :class="{disabled: launched}">Restore</label>
|
||||||
|
</div>
|
||||||
|
<input id="restore-input" type="file" @input="restore" style="display: none;"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="row" v-show="launched">
|
||||||
<div class="row" v-show="state_cities != null">
|
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="city-guess" class="form-label">City:</label>
|
<label for="city-guess" class="form-label">City:</label>
|
||||||
|
@ -156,7 +157,35 @@
|
||||||
downloadAnchorNode.click();
|
downloadAnchorNode.click();
|
||||||
downloadAnchorNode.remove();
|
downloadAnchorNode.remove();
|
||||||
},
|
},
|
||||||
async restore() {
|
async restore(event) {
|
||||||
|
this.launched = true;
|
||||||
|
|
||||||
|
// Sure would be nice if the API were just designed this way!
|
||||||
|
const read_file = async (file) => new Promise((resolve) => {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
fileReader.onload = (e) => resolve(fileReader.result);
|
||||||
|
fileReader.readAsText(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
const save_data = await read_file(event.target.files[0]);
|
||||||
|
const save = JSON.parse(save_data, (k, v) => k == 'time' ? new Date(v) : v);
|
||||||
|
this.state_cities = save.cities;
|
||||||
|
this.simplified_cities = this.state_cities.map(city => simplify(city.name));
|
||||||
|
this.state_name = save.state;
|
||||||
|
this.message = `Restored game from ${save.time.toLocaleString()} with ${save.cities.filter(c => c.guessed).length }/${ save.cities.length} cities guessed`;
|
||||||
|
|
||||||
|
// The rest of this function is duplicated from launch(), above
|
||||||
|
const shapes_response = await this.shapes_request;
|
||||||
|
const shapes_data = await shapes_response.json();
|
||||||
|
const shape = shapes_data.features.find(f => f.properties.NAME.toLowerCase() == this.state_name.toLowerCase());
|
||||||
|
if (shape.geometry.type == "MultiPolygon") {
|
||||||
|
this.state_shape = shape.geometry.coordinates.map(a => a.flat());
|
||||||
|
} else { // Polygon
|
||||||
|
this.state_shape = shape.geometry.coordinates;
|
||||||
|
}
|
||||||
|
this.state_mercator_adjusted_bounds = find_bounds(this.state_shape.flat().map(mercator));
|
||||||
|
|
||||||
|
this.draw();
|
||||||
},
|
},
|
||||||
guess() {
|
guess() {
|
||||||
const rank = this.simplified_cities.indexOf(simplify(this.city_guess))
|
const rank = this.simplified_cities.indexOf(simplify(this.city_guess))
|
||||||
|
|
Loading…
Reference in a new issue