mirror of
https://github.com/misenhower/splatoon2.ink.git
synced 2026-08-28 13:34:30 -05:00
Add Splatfest info for NA
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
"purifycss-webpack": "^0.7.0",
|
||||
"sass-loader": "^6.0.6",
|
||||
"style-loader": "^0.18.2",
|
||||
"v-click-outside": "^0.0.8",
|
||||
"vue": "^2.4.2",
|
||||
"vue-loader": "^13.0.2",
|
||||
"vue-template-compiler": "^2.4.2",
|
||||
|
||||
@@ -6,6 +6,7 @@ $bg-spots: url(../img/bg-spots.png);
|
||||
$bg-mask-product: url(../img/bg-mask-product.png);
|
||||
$bg-mask-title-squid: url(../img/bg-mask-title-squid.png);
|
||||
$bg-mask-hook: url(../img/bg-mask-hook.png);
|
||||
$bg-mask-banner: url(../img/bg-mask-banner.png);
|
||||
|
||||
// Colors
|
||||
$bg-battle-regular: #19d719;
|
||||
@@ -64,3 +65,14 @@ $bg-battle-league: #f02d7d;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.bg-mask-banner {
|
||||
-webkit-mask-image: $bg-mask-banner;
|
||||
mask-image: $bg-mask-banner;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-clear {
|
||||
.button.is-translucent {
|
||||
@extend .text-shadow;
|
||||
|
||||
background: rgba($white-ter, 0.4);
|
||||
@@ -52,12 +52,57 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-clear {
|
||||
@extend .text-shadow;
|
||||
|
||||
background: transparent;
|
||||
border: rgba($white-ter, 0.9);
|
||||
color: $grey-lighter;
|
||||
|
||||
&:hover {
|
||||
background: rgba($white, 0.2);
|
||||
border: rgba($white, 1.0);
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.button.is-rounded {
|
||||
border-radius: 100px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.chevron::before {
|
||||
border-style: solid;
|
||||
border-width: 0.1em 0.1em 0 0;
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 0.45em;
|
||||
left: 0.15em;
|
||||
position: relative;
|
||||
top: 0.15em;
|
||||
transform: rotate(-45deg);
|
||||
vertical-align: top;
|
||||
width: 0.45em;
|
||||
}
|
||||
|
||||
.chevron.right:before {
|
||||
left: 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.chevron.bottom:before {
|
||||
// top: 0;
|
||||
top: 0.45em;
|
||||
left: 0;
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.chevron.left:before {
|
||||
left: 0.1em;
|
||||
transform: rotate(-135deg);
|
||||
}
|
||||
|
||||
.hand {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
@import '~bulma/sass/utilities/initial-variables';
|
||||
|
||||
$background: $black-ter;
|
||||
$body-background-color: #191919;
|
||||
|
||||
$text: $grey-lighter;
|
||||
$text-strong: $white-ter;
|
||||
$title-color: $white-ter;
|
||||
@@ -9,3 +12,8 @@ $purple: #460fc8;
|
||||
|
||||
// Temp: This can be removed after Bulma 0.5.1
|
||||
$sizes: $size-1 $size-2 $size-3 $size-4 $size-5 $size-6 $size-7;
|
||||
|
||||
$dropdown-content-background-color: rgba($grey-dark, 0.9);
|
||||
$dropdown-item-color: $grey-lighter;
|
||||
$dropdown-item-hover-color: $white;
|
||||
$dropdown-item-active-background-color: $orange;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
html {
|
||||
@extend .bg-squids;
|
||||
background-color: #191919;
|
||||
}
|
||||
|
||||
.fa {
|
||||
@@ -46,6 +45,13 @@ html {
|
||||
padding: 35px 10px 10px 10px;
|
||||
margin: auto;
|
||||
|
||||
&.splatfest-schedule-box {
|
||||
// Provide a little more room for the third Splatfest stage
|
||||
max-width: 720px;
|
||||
-webkit-mask-size: 730px 1168px;
|
||||
mask-size: 730px 1168px;
|
||||
}
|
||||
|
||||
&.regular {
|
||||
background-color: $bg-battle-regular;
|
||||
}
|
||||
@@ -123,6 +129,56 @@ html {
|
||||
}
|
||||
}
|
||||
|
||||
.splatfest {
|
||||
@extend .text-shadow;
|
||||
max-width: 500px;
|
||||
margin: auto;
|
||||
|
||||
.hook-box, .hook-box:before {
|
||||
background-color: #888;
|
||||
@extend .bg-stripes;
|
||||
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.splatfest-header, .splatfest-content {
|
||||
padding: 5px 15px 10px;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
position: relative;
|
||||
|
||||
.alpha, .bravo {
|
||||
@extend .font-splatoon1;
|
||||
@extend .title-color;
|
||||
@extend .is-size-5;
|
||||
position: absolute;
|
||||
bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.alpha {
|
||||
left: 0.25rem;
|
||||
}
|
||||
|
||||
.bravo {
|
||||
right: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.festival-period-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.festival-period {
|
||||
@extend .bg-mask-banner;
|
||||
@extend .bg-stripes;
|
||||
background-size: 53px 53px;
|
||||
padding: 4px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.main-schedule {
|
||||
background: rgba(0,0,0,0.7);
|
||||
padding: 5px 10px 10px;
|
||||
|
||||
BIN
src/img/bg-mask-banner.png
Normal file
BIN
src/img/bg-mask-banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 567 B |
@@ -2,7 +2,7 @@
|
||||
<div class="hero is-fullheight">
|
||||
<div class="hero-head">
|
||||
<div class="container is-fluid">
|
||||
<div class="level">
|
||||
<div class="level is-marginless">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<h1 class="title is-1 font-splatoon1 is-inline">Splatoon 2</h1>
|
||||
@@ -14,6 +14,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="level">
|
||||
<div class="level-left"></div>
|
||||
<div class="level-right">
|
||||
<div class="level-item">
|
||||
<Dropdown :options="regions" v-model="selectedRegionKey" style="margin: 0 -12px"></Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,8 +33,21 @@
|
||||
<span class="fa fa-spin squid-refresh"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div class="columns is-desktop">
|
||||
<div v-if="isFestivalActive" class="columns is-desktop" style="max-width: 1392px; margin: auto">
|
||||
<div class="column">
|
||||
<div class="splatfest tilt-left">
|
||||
<div class="hook-box">
|
||||
<SplatfestBox :festival="festival" :now="now"></SplatfestBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<ScheduleBox class="main-schedule-box splatfest-schedule-box tilt-right" cssClass="regular" :schedules="regular" :festival="festival" :now="now"></ScheduleBox>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="columns is-desktop">
|
||||
<div class="column">
|
||||
<ScheduleBox class="main-schedule-box tilt-left" cssClass="regular" :schedules="regular" :now="now"></ScheduleBox>
|
||||
</div>
|
||||
@@ -59,17 +81,27 @@
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import Dropdown from './Dropdown.vue';
|
||||
import ScheduleBox from './ScheduleBox.vue';
|
||||
import SalmonRunBox from './SalmonRunBox.vue';
|
||||
import SplatfestBox from './SplatfestBox.vue';
|
||||
|
||||
export default {
|
||||
components: { ScheduleBox, SalmonRunBox },
|
||||
components: { Dropdown, ScheduleBox, SalmonRunBox, SplatfestBox },
|
||||
data() {
|
||||
return {
|
||||
regions: [
|
||||
{ key: null, name: 'Global' },
|
||||
{ key: 'na', name: 'North America' },
|
||||
],
|
||||
selectedRegionKey: null,
|
||||
now: null,
|
||||
splatnet: {
|
||||
schedules: null,
|
||||
timeline: null,
|
||||
festivals: {
|
||||
na: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -78,6 +110,16 @@ export default {
|
||||
regular() { return !this.loading && this.splatnet.schedules.regular.filter(this.filterSchedule) },
|
||||
ranked() { return !this.loading && this.splatnet.schedules.gachi.filter(this.filterSchedule) },
|
||||
league() { return !this.loading && this.splatnet.schedules.league.filter(this.filterSchedule) },
|
||||
festival() {
|
||||
if (this.loading || !this.selectedRegionKey)
|
||||
return;
|
||||
|
||||
let festivals = this.splatnet.festivals[this.selectedRegionKey];
|
||||
return festivals && festivals.festivals && festivals.festivals[0];
|
||||
},
|
||||
isFestivalActive() {
|
||||
return this.festival && this.festival.times.start <= this.now && this.festival.times.end > this.now;
|
||||
},
|
||||
coop() {
|
||||
if (!this.loading && this.splatnet.timeline.coop && this.splatnet.timeline.coop.schedule.end_time >= this.now)
|
||||
return this.splatnet.timeline.coop;
|
||||
@@ -97,6 +139,7 @@ export default {
|
||||
updateData() {
|
||||
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);
|
||||
},
|
||||
updateNow() {
|
||||
this.now = Math.trunc((new Date).getTime() / 1000);
|
||||
|
||||
41
src/js/components/Dropdown.vue
Normal file
41
src/js/components/Dropdown.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="dropdown is-right font-splatoon2" :class="{ 'is-active': isOpen }">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-clear font-splatoon2" @click="isOpen = !isOpen" v-click-outside="hide">
|
||||
<span v-if="selectedOption">{{ selectedOption.name }}</span>
|
||||
<span class="icon is-small">
|
||||
<span class="chevron bottom"></span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<a href="#" class="dropdown-item" v-for="option in options" :class="{ 'is-active': option.key == value }" @click="$emit('input', option.key)">
|
||||
{{ option.name }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['options', 'value'],
|
||||
data() {
|
||||
return {
|
||||
isOpen: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
selectedOption() {
|
||||
if (this.options)
|
||||
return this.options.find(option => option.key == this.value);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hide() {
|
||||
this.isOpen = false;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -10,7 +10,8 @@
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<h2 class="title is-3 is-size-2-fullhd is-size-4-mobile font-splatoon1">
|
||||
{{ gameMode.name }}
|
||||
<template v-if="isFestival">Splatfest Battle</template>
|
||||
<template v-else>{{ gameMode.name }}</template>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
@@ -19,6 +20,11 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['gameMode'],
|
||||
props: ['gameMode', 'festival', 'now'],
|
||||
computed: {
|
||||
isFestival() {
|
||||
return this.festival && this.festival.times.start <= this.now && this.festival.times.end > this.now;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="font-splatoon2" :class="cssClass" v-if="gameMode">
|
||||
<GameModeHeader :gameMode="gameMode"></GameModeHeader>
|
||||
<GameModeHeader :gameMode="gameMode" :festival="festival" :now="now"></GameModeHeader>
|
||||
|
||||
<div class="main-schedule" v-if="currentSchedule">
|
||||
<div class="level is-mobile top-bar">
|
||||
@@ -18,13 +18,16 @@
|
||||
<div class="columns is-mobile is-slim">
|
||||
<div class="column"><Stage :stage="currentSchedule.stage_a"></Stage></div>
|
||||
<div class="column"><Stage :stage="currentSchedule.stage_b"></Stage></div>
|
||||
<template v-if="festival">
|
||||
<div class="column"><Stage :stage="festival.special_stage"></Stage></div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ScheduleList :schedules="upcomingSchedules" :now="now" :onlyFirst="true"></ScheduleList>
|
||||
|
||||
<p class="has-text-centered" style="margin-top: 10px">
|
||||
<button class="button is-clear is-rounded" @click="isOpen=true">
|
||||
<button class="button is-translucent is-rounded" @click="isOpen=true">
|
||||
<span class="icon squid-icon-tilt">
|
||||
<span class="fa squid-squid"></span>
|
||||
</span>
|
||||
@@ -55,7 +58,7 @@ import ScheduleList from './ScheduleList.vue';
|
||||
|
||||
export default {
|
||||
components: { GameModeHeader, Stage, ScheduleList },
|
||||
props: ['schedules', 'cssClass', 'now'],
|
||||
props: ['schedules', 'cssClass', 'festival', 'now'],
|
||||
data() {
|
||||
return {
|
||||
isOpen: false,
|
||||
|
||||
54
src/js/components/SplatfestBox.vue
Normal file
54
src/js/components/SplatfestBox.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div class="font-splatoon2">
|
||||
<div class="splatfest-header">
|
||||
<h2 class="title is-3 is-size-2-fullhd font-splatoon1">
|
||||
Splatfest
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="panel-container">
|
||||
<div class="image">
|
||||
<img :src="image" />
|
||||
</div>
|
||||
<div class="alpha">
|
||||
{{ festival.names.alpha_short }}
|
||||
</div>
|
||||
<div class="bravo">
|
||||
{{ festival.names.bravo_short }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="has-text-centered is-size-5 title-color festival-period-container">
|
||||
<span class="festival-period" :style="{ 'background-color': festival.colors.middle.css_rgb }">
|
||||
{{ festival.times.start | date }}
|
||||
{{ festival.times.start | time }}
|
||||
–
|
||||
{{ festival.times.end | date }}
|
||||
{{ festival.times.end | time }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="splatfest-content has-text-centered">
|
||||
<template v-if="festival.times.start <= now">
|
||||
{{ festival.times.end - now | duration }}
|
||||
remaining
|
||||
</template>
|
||||
<template v-else>
|
||||
in
|
||||
{{ festival.times.start - now | duration }}
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['festival', 'now'],
|
||||
computed: {
|
||||
image() {
|
||||
if (this.festival)
|
||||
return `https://app.splatoon2.nintendo.net${this.festival.images.panel}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,8 @@
|
||||
import Vue from 'vue';
|
||||
import App from './components/App.vue';
|
||||
import vClickOutside from 'v-click-outside';
|
||||
|
||||
Vue.use(vClickOutside);
|
||||
|
||||
Vue.directive('portal', {
|
||||
inserted(el) {
|
||||
|
||||
@@ -42,7 +42,20 @@ const updateTimeline = function() {
|
||||
});
|
||||
}
|
||||
|
||||
const updateFestivals = function() {
|
||||
console.info('Updating festivals...');
|
||||
|
||||
api.get('festivals/active').then(response => {
|
||||
// Make sure the data path exists
|
||||
mkdirp(dataPath);
|
||||
|
||||
fs.writeFile(`${dataPath}/festivals-na.json`, JSON.stringify(response.data));
|
||||
console.info('Updated festivals.');
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.update = function() {
|
||||
updateSchedules();
|
||||
updateTimeline();
|
||||
updateFestivals();
|
||||
}
|
||||
|
||||
@@ -5366,6 +5366,10 @@ uuid@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
|
||||
|
||||
v-click-outside@^0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/v-click-outside/-/v-click-outside-0.0.8.tgz#1f3033b8c4ace431c3233a4080127fc088d52093"
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
|
||||
|
||||
Reference in New Issue
Block a user