Add upcoming Salmon Run schedules

This commit is contained in:
Matt Isenhower 2017-08-11 10:13:57 -07:00
parent 6ee3e2a5a0
commit e5b4e3d30a
9 changed files with 175 additions and 28 deletions

View File

@ -1 +1,2 @@
NINTENDO_SESSION_ID=
SALMON_RUN_CALENDAR_ICS_URL=

View File

@ -26,6 +26,7 @@
"file-loader": "^0.11.2",
"html-loader": "^0.5.0",
"html-webpack-plugin": "^2.30.1",
"ical.js": "^1.2.2",
"mkdirp": "^0.5.1",
"node-sass": "^4.5.3",
"purify-css": "^1.2.5",

View File

@ -133,7 +133,40 @@ body.has-modal #main {
}
.salmon-run-content {
padding-top: 15px;
padding: 10px;
}
.salmon-run-ad-img {
background-image: url(../img/salmon-run.png);
background-size: cover;
background-repeat: no-repeat;
background-position: 50% 50%;
z-index: 1;
}
.salmon-run-future {
background: rgba(0,0,0,0.7);
padding: 5px 10px 10px;
margin: 2px -5px;
border-radius: 12px;
overflow: hidden;
line-height: 20px;
.columns:not(:last-child) {
border-bottom: 0.1rem dashed $grey;
padding-bottom: 0.3rem;
margin-bottom: 0.3rem;
}
}
.calendar-attribution {
background: rgba(0,0,0,0.5);
font-family: $family-sans-serif;
font-size: 0.7rem;
padding: 2px 20px;
a {
color: mix($green, $white-ter, 25%);
}
}
}

BIN
src/img/salmon-run-mini.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -67,10 +67,10 @@
</div>
</div>
</div>
<div class="column" v-if="coop">
<div class="column" v-if="coop || coopCalendar">
<div class="salmon-run tilt-left">
<div class="hook-box">
<SalmonRunBox :coop="coop" :now="now"></SalmonRunBox>
<SalmonRunBox :coop="coop" :coopCalendar="coopCalendar" :now="now"></SalmonRunBox>
</div>
</div>
</div>
@ -99,7 +99,7 @@
Hello!
</h3>
<p>
Splatoon2.ink shows the current and upcoming map schedule for Splatoon 2.
Splatoon2.ink shows the current and upcoming map schedules for Splatoon 2.
</p>
<p>
This site was built with <a href="https://vuejs.org/" target="_blank">Vue.js</a>
@ -110,11 +110,12 @@
<a href="https://twitter.com/mattisenhower" target="_blank">Follow me on Twitter</a>
or <a href="mailto:matt@isenhower.com" target="_blank">email me</a> with any questions!
</p>
<h5 class="font-splatoon2 title is-5">Known Issues</h5>
<h5 class="font-splatoon2 title is-5">Notes &amp; Issues</h5>
<p>
<strong>Salmon Run:</strong>
Times are only displayed when a Salmon Run stage is open.
The API doesn't provide a way to see maps, available weapons, or upcoming Salmon Run times.
The SplatNet API doesn't provide a way to see maps, available weapons, or upcoming Salmon Run times.
Upcoming times are provided by
<a href="https://www.reddit.com/r/splatoon/comments/6pgqy4/i_couldnt_find_a_calendar_online_with_a_list_of/" target="_blank">thejellydude</a>.
</p>
<p>
<strong>Splatfests:</strong>
@ -154,6 +155,7 @@ export default {
na: null,
},
},
salmonruncalendar: null,
aboutOpen: false,
};
},
@ -176,6 +178,13 @@ export default {
if (!this.loading && this.splatnet.timeline.coop && this.splatnet.timeline.coop.schedule.end_time > this.now)
return this.splatnet.timeline.coop;
},
coopCalendar() {
if (this.salmonruncalendar) {
let schedules = this.salmonruncalendar.schedules.filter(this.filterSchedule);
if (schedules.length > 0)
return schedules;
}
},
},
created() {
this.detectRegion();
@ -193,6 +202,7 @@ export default {
axios.get('/data/schedules.json').then(response => this.splatnet.schedules = response.data);
axios.get('/data/timeline.json').then(response => this.splatnet.timeline = response.data);
axios.get('/data/festivals-na.json').then(response => this.splatnet.festivals.na = response.data);
axios.get('/data/salmonruncalendar.json').then(response => this.salmonruncalendar = response.data);
},
detectRegion() {
if (window.navigator && window.navigator.language) {

View File

@ -18,31 +18,59 @@
</div>
<div class="columns is-gapless">
<div class="column is-5">
<div class="image is-16by9">
<img src="../../img/salmon-run.png" style="z-index: 1" />
</div>
<div class="column is-4 salmon-run-ad-img">
<div class="image is-16by9 is-hidden-desktop"></div>
</div>
<div class="column">
<div class="salmon-run-content">
<div class="is-size-5 title-squid font-splatoon1">
<span v-if="isOpen">Now open!</span>
<span v-else>Soon!</span>
<div v-if="currentSchedule">
<div class="is-size-5 title-squid font-splatoon1">
Now open!
</div>
<div class="title-color is-size-5">
{{ currentSchedule.start_time | date }}
{{ currentSchedule.start_time | time }}
&ndash;
{{ currentSchedule.end_time | date }}
{{ currentSchedule.end_time | time }}
</div>
<div>
{{ currentSchedule.end_time - now | duration }} remaining
</div>
</div>
<div class="title-color is-size-5">
{{ coop.schedule.start_time | date }}
{{ coop.schedule.start_time | time }}
&ndash;
{{ coop.schedule.end_time | date }}
{{ coop.schedule.end_time | time }}
</div>
<div v-if="isOpen">
{{ coop.schedule.end_time - now | duration }} remaining
</div>
<div v-else>
in {{ coop.schedule.start_time - now | duration }}
<div v-if="upcomingSchedules.length > 0">
<div class="salmon-run-future">
<div class="is-size-6 title-squid font-splatoon1">
Soon
</div>
<div v-for="event in upcomingSchedules" class="columns is-gapless is-mobile">
<div class="column is-narrow" style="margin-right: 5px">
<div class="image is-4by3" style="width: 23px">
<img src="../../img/salmon-run-mini.png" />
</div>
</div>
<div class="column">
<span class="title-color is-size-6">
{{ event.start_time | date }}
{{ event.start_time | time }}
&ndash;
{{ event.end_time | date }}
{{ event.end_time | time }}
</span>
<span class="is-size-7 is-hidden-touch is-pulled-right">
in {{ event.start_time - now | duration }}
</span>
</div>
</div>
</div>
</div>
</div>
<div v-if="upcomingSchedules.length > 0" class="has-text-right calendar-attribution">
Salmon Run schedule courtesy of
<a href="https://www.reddit.com/r/splatoon/comments/6pgqy4/i_couldnt_find_a_calendar_online_with_a_list_of/" target="_blank">thejellydude</a>
</div>
</div>
</div>
</div>
@ -50,9 +78,33 @@
<script>
export default {
props: ['coop', 'now'],
props: ['coop', 'coopCalendar', 'now'],
computed: {
isOpen() { return this.coop.schedule.start_time <= this.now; },
allSchedules() {
let results = [];
// Track the "official" schedule so we don't duplicate it from the calendar data
let knownSchedule = null;
if (this.coop && this.coop.schedule.end_time > this.now) {
knownSchedule = this.coop.schedule;
results.push(this.coop.schedule);
}
// Add calendar data
if (this.coopCalendar) {
let filteredSchedules = this.coopCalendar
.filter(schedule => (!knownSchedule || schedule.start_time != knownSchedule.start_time));
results.push(...filteredSchedules);
}
return results;
},
upcomingSchedules() { return this.allSchedules.filter(schedule => schedule.start_time > this.now) },
currentSchedule() {
if (this.allSchedules.length > 0 && this.allSchedules[0].start_time <= this.now)
return this.allSchedules[0];
},
},
}
</script>

View File

@ -0,0 +1,44 @@
require('dotenv').config();
require('console-stamp')(console);
const axios = require('axios');
const path = require('path');
const fs = require('fs');
const mkdirp = require('mkdirp');
const ical = require('ical.js');
const dataPath = path.resolve('public/data');
module.exports.update = function() {
console.info('Updating Salmon Run calendar...');
axios.get(process.env.SALMON_RUN_CALENDAR_ICS_URL).then(response => {
let now = Math.trunc((new Date).getTime() / 1000);
let schedules = [];
// Parse the ical format
let jcalData = ical.parse(response.data);
let comp = new ical.Component(jcalData);
let vevents = comp.getAllSubcomponents('vevent');
vevents.forEach(vevent => {
let event = new ical.Event(vevent);
// We only care about Salmon Run events
if (event.summary.toLowerCase().indexOf('salmon') === -1)
return;
let start_time = event.startDate.toUnixTime();
let end_time = event.endDate.toUnixTime();
// We only want events that haven't ended yet
if (end_time < now)
return;
schedules.push({ start_time, end_time });
});
schedules.sort((a, b) => { return a.start_time - b.start_time });
fs.writeFile(`${dataPath}/salmonruncalendar.json`, JSON.stringify({ schedules }));
console.info('Updated Salmon Run calendar.');
});
}

View File

@ -1,3 +1,5 @@
const splatnet = require('./splatnet');
const salmoncalendar = require('./salmoncalendar');
splatnet.update();
salmoncalendar.update();

View File

@ -2621,6 +2621,10 @@ https-browserify@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
ical.js@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/ical.js/-/ical.js-1.2.2.tgz#59b517362a8f61dce0342fe67deb7c20dd119f6e"
icss-replace-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"