Layout overhaul, add popups to view all upcoming stages

This commit is contained in:
Matt Isenhower
2017-08-04 00:01:22 -07:00
parent 079f4b083a
commit bfc0dcd3f9
11 changed files with 317 additions and 111 deletions

View File

@@ -5,6 +5,46 @@
padding-top: 35px;
}
.modal-card-product-box {
.modal-card-head {
@extend .bg-mask-product;
-webkit-mask-size: 730px 1168px;
mask-size: 730px 1168px;
background-position-y: bottom;
border: none;
border-top-left-radius: 32px;
border-top-right-radius: 32px;
padding-top: 45px;
display: block; // Fixes issues with .level
}
.modal-card-body {
@extend .bg-stripes;
border-bottom-left-radius: 32px;
border-bottom-right-radius: 32px;
padding-bottom: 32px;
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
margin-bottom: 32px;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba($white, 0.6);
&:hover {
background: rgba($white-ter, 0.8);
}
}
}
}
.hook-box {
border-radius: 32px;
padding: 10px;

View File

@@ -32,6 +32,26 @@
}
}
.button.is-clear {
@extend .text-shadow;
background: rgba($white-ter, 0.4);
border: rgba($white-ter, 0.9);
color: $white-ter;
&:hover {
background: rgba($white, 0.5);
border: rgba($white, 1.0);
color: $white;
}
}
.button.is-rounded {
border-radius: 100px;
padding-left: 12px;
padding-right: 12px;
}
.hand {
cursor: pointer;
}
@@ -57,11 +77,21 @@
transform: rotate(1.4deg);
}
.tilt-right-slight {
-webkit-transform: rotate(1.2deg);
transform: rotate(1.2deg);
}
.tilt-left {
-webkit-transform: rotate(-1.4deg);
transform: rotate(-1.4deg);
}
.tilt-left-slight {
-webkit-transform: rotate(-1.2deg);
transform: rotate(-1.2deg);
}
.columns.is-slim {
margin-left: -0.4rem;
margin-right: -0.4rem;

View File

@@ -10,17 +10,34 @@ html {
background-color: #191919;
}
.squid-refresh {
.fa {
&:before {
display: inline-block;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}
.squid-refresh {
&:before {
@extend .font-splatoon2;
content: "\e066";
}
}
.schedule-box {
.squid-squid {
&:before {
@extend .font-splatoon2;
content: "\e065";
}
}
.squid-icon-tilt {
-webkit-transform: rotate(25deg);
transform: rotate(25deg);
}
.main-schedule-box {
@extend .product-box;
@extend .bg-stripes;
@extend .text-shadow;
@@ -42,6 +59,47 @@ html {
}
}
.modal-card.schedule-box {
@extend .modal-card-product-box;
@extend .text-shadow;
.modal-card-head {
@extend .bg-spots-dots;
}
.modal-card-body {
@extend .bg-stripes;
}
&.regular {
.modal-card-head {
background-color: darken($bg-battle-regular, 30%);
}
.modal-card-body {
background-color: $bg-battle-regular;
}
}
&.ranked {
.modal-card-head {
background-color: darken($bg-battle-ranked, 30%);
// background-color: $grey-darker;
background-color: mix($bg-battle-ranked, $black-ter, 25%);
}
.modal-card-body {
background-color: $bg-battle-ranked;
}
}
&.league {
.modal-card-head {
background-color: darken($bg-battle-league, 30%);
}
.modal-card-body {
background-color: $bg-battle-league;
}
}
}
.salmon-run {
@extend .text-shadow;
max-width: 600px;

View File

@@ -27,13 +27,13 @@
<div v-else>
<div class="columns is-desktop">
<div class="column">
<ScheduleBox class="schedule-box tilt-left regular" :schedules="regular" :now="now"></ScheduleBox>
<ScheduleBox class="main-schedule-box tilt-left" cssClass="regular" :schedules="regular" :now="now"></ScheduleBox>
</div>
<div class="column">
<ScheduleBox class="schedule-box tilt-right ranked" :schedules="ranked" :now="now"></ScheduleBox>
<ScheduleBox class="main-schedule-box tilt-right" cssClass="ranked" :schedules="ranked" :now="now"></ScheduleBox>
</div>
<div class="column">
<ScheduleBox class="schedule-box tilt-left league" :schedules="league" :now="now"></ScheduleBox>
<ScheduleBox class="main-schedule-box tilt-left" cssClass="league" :schedules="league" :now="now"></ScheduleBox>
</div>
</div>

View File

@@ -0,0 +1,24 @@
<template>
<div class="level">
<div class="level-left">
<div class="level-item">
<div class="image is-48x48" style="margin-bottom: -6px">
<img v-if="gameMode.key == 'regular'" src="../../img/battle-regular.png" />
<img v-if="gameMode.key == 'gachi'" src="../../img/battle-ranked.png" />
<img v-if="gameMode.key == 'league'" src="../../img/battle-league.png" />
</div>
</div>
<div class="level-item">
<h2 class="title is-3 is-size-2-fullhd is-size-4-mobile font-splatoon1">
{{ gameMode.name }}
</h2>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['gameMode'],
}
</script>

View File

@@ -48,26 +48,10 @@
</template>
<script>
import moment from 'moment';
export default {
props: ['coop', 'now'],
computed: {
isOpen() { return this.coop.schedule.start_time <= this.now; },
},
filters: {
time(value) {
return moment.unix(value).local().format('ha');
},
duration(value) {
let duration = moment.duration(value, 'seconds');
let hours = Math.floor(duration.asHours());
let minutes = ('0' + duration.minutes()).substr(-2);
let seconds = ('0' + duration.seconds()).substr(-2);
if (hours)
return `${hours}h ${minutes}m ${seconds}s`;
return `${minutes}m ${seconds}s`;
},
},
}
</script>

View File

@@ -1,124 +1,82 @@
<template>
<div class="font-splatoon2" v-if="firstSchedule">
<div class="level">
<div class="level-left">
<div class="level-item">
<div class="image is-48x48" style="margin-bottom: -6px">
<img v-if="firstSchedule.game_mode.key == 'regular'" src="../../img/battle-regular.png" />
<img v-if="firstSchedule.game_mode.key == 'gachi'" src="../../img/battle-ranked.png" />
<img v-if="firstSchedule.game_mode.key == 'league'" src="../../img/battle-league.png" />
</div>
</div>
<div class="level-item">
<h2 class="title is-3 is-size-2-fullhd font-splatoon1">
{{ firstSchedule.game_mode.name }}
</h2>
</div>
</div>
</div>
<div class="font-splatoon2" :class="cssClass" v-if="gameMode">
<GameModeHeader :gameMode="gameMode"></GameModeHeader>
<div class="main-schedule">
<div class="main-schedule" v-if="currentSchedule">
<div class="level is-mobile top-bar">
<div class="level-left">
<div class="level-item title-color is-size-5">{{ firstSchedule.rule.name }}</div>
<div class="level-item title-color is-size-5">{{ currentSchedule.rule.name }}</div>
</div>
<div class="level-right">
<div class="level-item">
{{ firstSchedule.start_time | time }} &ndash;
{{ firstSchedule.end_time | time }}
{{ currentSchedule.start_time | time }} &ndash;
{{ currentSchedule.end_time | time }}
</div>
</div>
</div>
<div class="is-clearfix"></div>
<div class="columns is-mobile is-slim">
<div class="column"><Stage :stage="firstSchedule.stage_a"></Stage></div>
<div class="column"><Stage :stage="firstSchedule.stage_b"></Stage></div>
<div class="column"><Stage :stage="currentSchedule.stage_a"></Stage></div>
<div class="column"><Stage :stage="currentSchedule.stage_b"></Stage></div>
</div>
</div>
<div class="upcoming-schedule" v-if="upcomingSchedule">
<div class="is-size-5 title-squid font-splatoon1">
Next
</div>
<div class="level is-mobile is-marginless is-hidden-tablet">
<div class="level-left">
<div class="level-item title-color is-size-5">{{ upcomingSchedule.rule.name }}</div>
</div>
<div class="level-right">
<div class="level-item">
in {{ upcomingSchedule.start_time - now | duration }},
{{ upcomingSchedule.start_time | time }} &ndash;
{{ upcomingSchedule.end_time | time }}
</div>
</div>
</div>
<ScheduleList :schedules="upcomingSchedules" :now="now" :onlyFirst="true"></ScheduleList>
<div class="columns is-slim" v-if="upcomingSchedule">
<div class="column has-text-centered is-hidden-mobile" style="margin-top: auto; margin-bottom: auto;">
<div class="title is-6 is-size-5-fullhd">{{ upcomingSchedule.rule.name }}</div>
<div class="subtitle is-7 is-size-6-fullhd ">
in {{ upcomingSchedule.start_time - now | duration }}
<br />
{{ upcomingSchedule.start_time | time }} &ndash;
{{ upcomingSchedule.end_time | time }}
</div>
</div>
<div class="column is-8">
<div class="columns is-mobile is-slim">
<div class="column"><Stage :stage="upcomingSchedule.stage_a"></Stage></div>
<div class="column"><Stage :stage="upcomingSchedule.stage_b"></Stage></div>
</div>
</div>
<p class="has-text-centered" style="margin-top: 10px">
<button class="button is-smallZ is-clear is-rounded" @click="isOpen=true">
<span class="icon is-smallZ squid-icon-tilt">
<span class="fa squid-squid"></span>
</span>
<span class="font-splatoon2">All Upcoming Stages</span>
</button>
</p>
<div class="modal is-active font-splatoon2" v-if="isOpen" v-portal>
<div class="modal-background" @click="isOpen = false"></div>
<div class="modal-card schedule-box tilt-left-slight" :class="cssClass">
<header class="modal-card-head">
<GameModeHeader :gameMode="gameMode"></GameModeHeader>
</header>
<section class="modal-card-body">
<ScheduleList :schedules="schedules" :now="now" :onlyFirst="false"></ScheduleList>
</section>
</div>
<button class="modal-close is-large" @click="isOpen = false"></button>
</div>
</div>
</template>
<script>
import moment from 'moment';
import GameModeHeader from './GameModeHeader.vue';
import Stage from './Stage.vue';
import ScheduleList from './ScheduleList.vue';
export default {
components: { Stage },
props: ['schedules', 'now'],
components: { GameModeHeader, Stage, ScheduleList },
props: ['schedules', 'cssClass', 'now'],
data() {
return {
upcomingScheduleIndex: 0,
isOpen: false,
};
},
computed: {
firstSchedule() { return this.schedules && this.schedules[0]; },
upcomingSchedules() { return this.schedules && this.schedules.slice(1); },
upcomingSchedule() { return this.upcomingSchedules && this.upcomingSchedules[this.upcomingScheduleIndex]; },
},
watch: {
firstSchedule(newSchedule, oldSchedule) { if (oldSchedule != newSchedule) this.upcomingScheduleIndex = 0; },
},
filters: {
time(value) {
return moment.unix(value).local().format('ha');
gameMode() {
if (this.schedules && this.schedules[0])
return this.schedules[0].game_mode;
},
duration(value) {
let duration = moment.duration(value, 'seconds');
let hours = Math.floor(duration.asHours());
let minutes = ('0' + duration.minutes()).substr(-2);
let seconds = ('0' + duration.seconds()).substr(-2);
if (hours)
return `${hours}h ${minutes}m ${seconds}s`;
return `${minutes}m ${seconds}s`;
currentSchedule() {
if (this.schedules && this.schedules[0] && this.schedules[0].start_time <= this.now)
return this.schedules[0];
},
},
methods: {
// nextSchedule() {
// this.upcomingScheduleIndex++;
// if (this.upcomingScheduleIndex >= this.upcomingSchedules.length)
// this.upcomingScheduleIndex = 0;
// },
// previousSchedule() {
// this.upcomingScheduleIndex--;
// if (this.upcomingScheduleIndex < 0)
// this.upcomingScheduleIndex = this.upcomingSchedules.length - 1;
// },
upcomingSchedules() {
if (this.schedules) {
if (this.currentSchedule)
return this.schedules.slice(1);
return this.schedules;
}
}
},
}
</script>

View File

@@ -0,0 +1,50 @@
<template>
<div>
<div v-if="first">
<div class="is-size-5 title-squid font-splatoon1">
<span v-if="first.start_time <= this.now">Now</span>
<span v-else-if="onlyFirst">Next</span>
<span v-else>Soon!</span>
</div>
<ScheduleRow :schedule="first" :now="now"></ScheduleRow>
</div>
<template v-if="!onlyFirst">
<div v-if="second">
<div class="is-size-5 title-squid font-splatoon1">
Next
</div>
<ScheduleRow :schedule="second" :now="now"></ScheduleRow>
</div>
<div v-if="others && others.length">
<div class="is-size-5 title-squid font-splatoon1">
Future
</div>
<ScheduleRow
v-for="schedule in others"
:key="schedule.id"
:schedule="schedule"
:now="now"
></ScheduleRow>
</div>
</template>
</div>
</template>
<script>
import ScheduleRow from './ScheduleRow.vue';
export default {
components: { ScheduleRow },
props: ['schedules', 'now', 'onlyFirst'],
computed: {
first() { return this.schedules && this.schedules[0]; },
second() { return this.schedules && this.schedules[1]; },
others() { return this.schedules && this.schedules.splice(2); },
},
}
</script>

View File

@@ -0,0 +1,47 @@
<template>
<div>
<div class="level is-mobile is-marginless is-hidden-tablet">
<div class="level-left">
<div class="level-item title-color is-size-5">{{ schedule.rule.name }}</div>
</div>
<div class="level-right">
<div class="level-item">
<template v-if="schedule.start_time > now">
in {{ schedule.start_time - now | duration }},
</template>
{{ schedule.start_time | time }} &ndash;
{{ schedule.end_time | time }}
</div>
</div>
</div>
<div class="columns is-slim" v-if="schedule">
<div class="column has-text-centered is-hidden-mobile" style="margin-top: auto; margin-bottom: auto;">
<div class="title is-6 is-size-5-fullhd is-size-5-touch">{{ schedule.rule.name }}</div>
<div class="subtitle is-7 is-size-6-fullhd is-size-6-touch">
<template v-if="schedule.start_time > now">
in {{ schedule.start_time - now | duration }}
<br />
</template>
{{ schedule.start_time | time }} &ndash;
{{ schedule.end_time | time }}
</div>
</div>
<div class="column is-8">
<div class="columns is-mobile is-slim">
<div class="column"><Stage :stage="schedule.stage_a"></Stage></div>
<div class="column"><Stage :stage="schedule.stage_b"></Stage></div>
</div>
</div>
</div>
</div>
</template>
<script>
import Stage from './Stage.vue';
export default {
components: { Stage },
props: ['schedule', 'now'],
}
</script>

View File

@@ -5,7 +5,7 @@
<div class="modal is-active" v-if="isOpen" v-portal>
<div class="modal-background" @click="isOpen = false"></div>
<div class="modal-content">
<div class="modal-content tilt-right-slight">
<p class="image is-16by9">
<img :src="image" />
</p>

View File

@@ -1,5 +1,6 @@
import Vue from 'vue';
import App from './components/App.vue';
import moment from 'moment';
Vue.directive('portal', {
inserted(el) {
@@ -7,4 +8,18 @@ Vue.directive('portal', {
}
});
Vue.filter('time', function(value) {
return moment.unix(value).local().format('ha');
});
Vue.filter('duration', function(value) {
let duration = moment.duration(value, 'seconds');
let hours = Math.floor(duration.asHours());
let minutes = ('0' + duration.minutes()).substr(-2);
let seconds = ('0' + duration.seconds()).substr(-2);
if (hours)
return `${hours}h ${minutes}m ${seconds}s`;
return `${minutes}m ${seconds}s`;
});
new Vue(App).$mount('#app');