Compare commits

..

2 commits

View file

@ -11,11 +11,18 @@
<h1>Name All the Cities</h1> <h1>Name All the Cities</h1>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">State:</label> <label class="form-label">State:</label>
<div class="input-group"> <div class="btn-toolbar">
<select class="form-select" v-model="state_name" :disabled="launched"> <div class="input-group me-3 flex-grow-1">
<option v-for="state in states">{{ state }}</option> <select class="form-select" v-model="state_name" :disabled="launched">
</select> <option value="" selected>Select a state…</option>
<button class="btn btn-primary" type="button" @click="launch" :disabled="launched">Play</button> <option v-for="state in states">{{ state }}</option>
</select>
<button class="btn btn-primary" type="button" @click="launch" :disabled="launched">Play</button>
</div>
<div class="btn-group">
<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>
</div>
</div> </div>
</div> </div>
<div class="row" v-show="state_cities != null"> <div class="row" v-show="state_cities != null">
@ -100,20 +107,17 @@
"All above 50k": cities => cities.filter(city => city.pop >= 50000), "All above 50k": cities => cities.filter(city => city.pop >= 50000),
"All above 25k": cities => cities.filter(city => city.pop >= 25000), "All above 25k": cities => cities.filter(city => city.pop >= 25000),
}, },
guess() { async mounted() {
const rank = this.simplified_cities.indexOf(simplify(this.city_guess)) // Fire off this request ASAP
if (rank >= 0) { this.shapes_request = fetch("data/states.geojson");
const city = this.state_cities[rank];
if (!city.guessed) { // Check if there's a parameter in the URL already
city.guessed = true; this.state_name = (new URLSearchParams(window.location.search)).get('state');
this.message = `${city.name} (population ${city.pop}) is the ${ordinal_suffix_of(rank + 1)} most populated city in ${this.state}.`; if (this.state_name) {
this.city_guess = ""; this.launch();
this.draw(); } else {
} else { const response = await fetch("data/states.json");
this.message = `Already guessed ${city.name} (population ${city.pop}, rank ${rank}).`; this.states = await response.json();
this.city_guess = "";
}
} }
}, },
async launch() { async launch() {
@ -135,17 +139,39 @@
this.draw(); this.draw();
}, },
async mounted() { async save() {
// Fire off this request ASAP const data = {
this.shapes_request = fetch("data/states.geojson"); state: this.state_name,
cities: this.state_cities,
time: new Date,
};
// https://stackoverflow.com/a/30800715
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data));
const downloadAnchorNode = document.createElement('a');
downloadAnchorNode.setAttribute("href", dataStr);
const safeStateName = this.state_name.replace(/[^A-Za-z]/, '-');
const datestring = `${data.time.getFullYear()}-${data.time.getMonth() + 1}-${data.time.getDate()}`;
downloadAnchorNode.setAttribute("download", `name-all-cities-${safeStateName}-${datestring}.json`);
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
},
async restore() {
},
guess() {
const rank = this.simplified_cities.indexOf(simplify(this.city_guess))
if (rank >= 0) {
const city = this.state_cities[rank];
// Check if there's a parameter in the URL already if (!city.guessed) {
this.state_name = (new URLSearchParams(window.location.search)).get('state'); city.guessed = true;
if (this.state_name) { this.message = `${city.name} (population ${city.pop}) is the ${ordinal_suffix_of(rank + 1)} most populated city in ${this.state}.`;
this.launch(); this.city_guess = "";
} else { this.draw();
const response = await fetch("data/states.json"); } else {
this.states = await response.json(); this.message = `Already guessed ${city.name} (population ${city.pop}, rank ${rank}).`;
this.city_guess = "";
}
} }
}, },
draw() { draw() {