Redesigned homepage.

This commit is contained in:
ThePendulum 2019-11-14 01:18:19 +01:00
parent 4497cc41b6
commit 4fa13bb163
10 changed files with 352 additions and 178 deletions

View File

@ -19,7 +19,10 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import 'theme';
.container { .container {
background: $background-dim;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -30,7 +33,7 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-grow: 1; flex-grow: 1;
overflow: hidden; overflow-y: auto;
} }
.content-inner { .content-inner {

View File

@ -13,9 +13,10 @@
@import 'theme'; @import 'theme';
.header { .header {
color: $text-contrast; background: $background;
background: $primary; color: $primary;
padding: .5rem 1rem; padding: .5rem 1rem;
border-bottom: solid 1px $shadow-hint;
} }
.logo-link { .logo-link {

View File

@ -0,0 +1,76 @@
<template>
<div class="filter-bar noselect">
<Icon icon="filter" />
<Filters
class="filters-container"
:filter="filter"
@set-filter="filter => $emit('set-filter', filter)"
/>
<v-popover class="filters-compact">
<div>Filters</div>
<div slot="popover">
<Filters
:compact="true"
:filter="filter"
@set-filter="filter => $emit('set-filter', filter)"
/>
</div>
</v-popover>
</div>
</template>
<script>
import Filters from './filters.vue';
export default {
components: {
Filters,
},
props: {
filter: {
type: Array,
default: () => [],
},
},
};
</script>
<style lang="scss" scoped>
@import 'theme';
.filter-bar {
background: $background;
display: block;
padding: .5rem 1rem;
font-size: 0;
box-shadow: 0 0 3px $shadow;
.icon {
fill: $shadow;
}
}
.filters-container {
display: inline-block;
}
.filters-compact {
font-size: 1rem;
font-weight: bold;
display: none;
margin: 0 0 0 .5rem;
}
@media(max-width: $breakpoint) {
.filters-container {
display: none;
}
.filters-compact {
display: inline-block;
}
}
</style>

View File

@ -1,7 +1,5 @@
<template> <template>
<div class="filters-bar noselect"> <div :class="{ compact }">
<Icon icon="filter" />
<ul class="filters"> <ul class="filters">
<li <li
v-tooltip.bottom="'Not yet available'" v-tooltip.bottom="'Not yet available'"
@ -111,6 +109,10 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
compact: {
type: Boolean,
default: false,
},
}, },
data() { data() {
return { return {
@ -123,17 +125,6 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import 'theme'; @import 'theme';
.filters-bar {
display: block;
background: $shadow-hint;
padding: .5rem 1rem;
font-size: 0;
.icon {
fill: $shadow;
}
}
.filters { .filters {
display: inline-block; display: inline-block;
list-style: none; list-style: none;
@ -141,7 +132,7 @@ export default {
margin: 0; margin: 0;
&:not(:last-child) { &:not(:last-child) {
border-right: solid 1px $shadow-weak; border-right: solid 1px $shadow-hint;
} }
} }
@ -149,12 +140,23 @@ export default {
display: inline-block; display: inline-block;
} }
.compact {
.filters {
padding: 0;
border: none;
}
.filter {
margin: 0 0 1.5rem 0;
}
}
.toggle { .toggle {
color: $shadow; color: $shadow-weak;
background: $shadow-hint;
box-sizing: border-box; box-sizing: border-box;
padding: .5rem; padding: .5rem;
margin: 0 .25rem; margin: 0 .25rem;
border: solid 1px transparent;
border-radius: .5rem; border-radius: .5rem;
font-size: .9rem; font-size: .9rem;
font-weight: bold; font-weight: bold;
@ -164,9 +166,13 @@ export default {
display: none; display: none;
} }
&:hover {
color: $shadow;
}
&.active { &.active {
color: $text-contrast; color: $primary;
background: $primary; box-shadow: 0 0 2px $shadow-weak;
} }
} }
</style> </style>

View File

@ -20,7 +20,7 @@
</template> </template>
<script> <script>
import FilterBar from './filter.vue'; import FilterBar from './filter-bar.vue';
import ReleaseTile from '../tile/release.vue'; import ReleaseTile from '../tile/release.vue';
async function fetchReleases() { async function fetchReleases() {

View File

@ -0,0 +1,103 @@
<template>
<div
class="banner"
@wheel.prevent="scrollBanner"
>
<div class="trailer">
<video
v-if="release.trailer"
:src="`/media/${release.trailer.path}`"
:poster="`/media/${(release.poster && release.poster.thumbnail) || (release.photos.length && release.photos[Math.floor(Math.random() * release.photos.length)].path)}`"
:alt="release.title"
class="item trailer-video"
controls
>Sorry, the tailer cannot be played in your browser</video>
</div>
<a
v-for="photo in photos"
:key="`banner-${photo.index}`"
:href="`/media/${photo.path}`"
target="_blank"
rel="noopener noreferrer"
>
<img
:src="`/media/${photo.thumbnail}`"
:alt="`Photo ${photo.index + 1}`"
class="item"
>
</a>
</div>
</template>
<script>
function photos() {
if (this.release.photos.length) {
const set = this.release.photos.sort(({ index: indexA }, { index: indexB }) => indexA - indexB);
if (this.release.trailer) {
return set;
}
return [this.release.poster].concat(set);
}
if (this.release.poster && !this.release.trailer) {
return [this.release.poster];
}
return [];
}
function scrollBanner(event) {
event.currentTarget.scrollLeft += event.deltaY; // eslint-disable-line no-param-reassign
}
export default {
props: {
release: {
type: Object,
default: null,
},
},
computed: {
photos,
},
methods: {
scrollBanner,
},
};
</script>
<style lang="scss" scoped>
@import 'theme';
.banner {
background: $empty;
flex-shrink: 0;
white-space: nowrap;
overflow-x: auto;
margin: 0 0 1rem 0;
scrollbar-width: none;
box-shadow: 0 0 3px $shadow;
font-size: 0;
&::-webkit-scrollbar {
display: none;
}
}
.trailer {
display: inline-block;
max-width: 100vw;
}
.trailer-video {
max-width: 100%;
}
.item {
max-height: 18rem;
vertical-align: middle;
}
</style>

View File

@ -1,34 +1,9 @@
<template> <template>
<div v-if="release">
<div <div
class="banner" v-if="release"
@wheel.prevent="scrollBanner" class="content"
> >
<div class="banner-trailer"> <Banner :release="release" />
<video
v-if="release.trailer"
:src="`/media/${release.trailer.path}`"
:poster="`/media/${(release.poster && release.poster.thumbnail) || (release.photos.length && release.photos[Math.floor(Math.random() * release.photos.length)].path)}`"
:alt="release.title"
class="banner-item"
controls
>Sorry, the tailer cannot be played in your browser</video>
</div>
<a
v-for="photo in photos"
:key="`banner-${photo.index}`"
:href="`/media/${photo.path}`"
target="_blank"
rel="noopener noreferrer"
>
<img
:src="`/media/${photo.thumbnail}`"
:alt="`Photo ${photo.index + 1}`"
class="banner-item"
>
</a>
</div>
<h2 class="row title">{{ release.title }}</h2> <h2 class="row title">{{ release.title }}</h2>
@ -141,37 +116,20 @@
</template> </template>
<script> <script>
import Banner from './banner.vue';
function pageTitle() { function pageTitle() {
return this.release && this.release.title; return this.release && this.release.title;
} }
function scrollBanner(event) {
event.currentTarget.scrollLeft += event.deltaY; // eslint-disable-line no-param-reassign
}
function photos() {
if (this.release.photos.length) {
const set = this.release.photos.sort(({ index: indexA }, { index: indexB }) => indexA - indexB);
if (this.release.trailer) {
return set;
}
return [this.release.poster].concat(set);
}
if (this.release.poster && !this.release.trailer) {
return [this.release.poster];
}
return [];
}
async function mounted() { async function mounted() {
[this.release] = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId }); [this.release] = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId });
} }
export default { export default {
components: {
Banner,
},
data() { data() {
return { return {
release: null, release: null,
@ -179,41 +137,13 @@ export default {
}, },
computed: { computed: {
pageTitle, pageTitle,
photos,
}, },
mounted, mounted,
methods: {
scrollBanner,
},
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import 'theme'; @import 'theme';
.banner {
background: $empty;
white-space: nowrap;
overflow-x: auto;
margin: 0 0 1rem 0;
scrollbar-width: none;
box-shadow: 0 0 3px $shadow;
font-size: 0;
&::-webkit-scrollbar {
display: none;
}
}
.banner-trailer {
display: inline-block;
}
.banner-item {
height: 20rem;
vertical-align: middle;
}
.row { .row {
display: block; display: block;
padding: 0 1rem; padding: 0 1rem;

View File

@ -3,13 +3,16 @@
<span class="banner"> <span class="banner">
<span class="details"> <span class="details">
<a <a
:href="`/site/${release.site.slug}`" v-tooltip.bottom="`Part of ${release.network.name}`"
:title="`Part of ${release.network.name}`" :title="`Part of ${release.network.name}`"
:href="`/site/${release.site.slug}`"
class="site site-link" class="site site-link"
>{{ release.site.name }}</a> >{{ release.site.name }}</a>
<a <a
v-if="release.date" v-if="release.date"
v-tooltip.bottom="`View scene on ${release.site.name}`"
:title="`View scene on ${release.site.name}`"
:href="release.url" :href="release.url"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
@ -78,11 +81,10 @@
</ul> </ul>
</span> </span>
<span <ul
:title="release.tags.map(tag => tag.name).join(', ')" :title="release.tags.map(tag => tag.name).join(', ')"
class="row" class="tags nolist"
> >
<ul class="tags nolist">
<li <li
v-for="tag in release.tags" v-for="tag in release.tags"
:key="`tag-${tag.slug}`" :key="`tag-${tag.slug}`"
@ -94,7 +96,6 @@
>{{ tag.name }}</a> >{{ tag.name }}</a>
</li> </li>
</ul> </ul>
</span>
</div> </div>
</div> </div>
</template> </template>
@ -114,6 +115,7 @@ export default {
@import 'theme'; @import 'theme';
.tile { .tile {
background: $background;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
box-sizing: border-box; box-sizing: border-box;
@ -149,7 +151,7 @@ export default {
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: 0 .5rem; padding: 0 .5rem;
margin: 0 0 .25rem 0; margin: 0 0 .5rem 0;
} }
.details { .details {
@ -179,6 +181,8 @@ export default {
} }
.info { .info {
display: flex;
flex-direction: column;
flex-grow: 1; flex-grow: 1;
} }
@ -210,32 +214,26 @@ export default {
} }
.tags { .tags {
word-wrap: break-word;
overflow: hidden;
max-height: 2.5rem; max-height: 2.5rem;
padding: .25rem .5rem 1rem .5rem;
line-height: 1.25rem; line-height: 1.25rem;
} word-wrap: break-word;
overflow-y: hidden;
.actor,
.tag {
margin: 0 .25rem 0 0;
} }
.actor { .actor {
font-size: .9rem; margin: 0 .25rem 0 0;
} }
.tag { .tag {
font-size: .75rem; margin: 0 .25rem .5rem 0;
} }
.actor:not(:last-of-type)::after, .actor:not(:last-of-type)::after {
.tag:not(:last-child):after {
content: ","; content: ",";
} }
.actor-link, .actor-link {
.tag-link {
text-decoration: none; text-decoration: none;
&:hover { &:hover {
@ -248,6 +246,16 @@ export default {
} }
.tag-link { .tag-link {
color: $shadow-strong; color: $shadow;
padding: .25rem;
border-radius: .25rem;
box-shadow: 0 0 2px $shadow-weak;
font-size: .75rem;
font-weight: bold;
text-decoration: none;
&:hover {
color: $primary;
}
} }
</style> </style>

View File

@ -3,6 +3,7 @@ $breakpoint: 720px;
$primary: #ff6c88; $primary: #ff6c88;
$background: #fff; $background: #fff;
$background-dim: #fafafa;
$text: #222; $text: #222;
$text-contrast: #fff; $text-contrast: #fff;

View File

@ -1,46 +1,77 @@
/* $primary: #ff886c; */ /* $primary: #ff886c; */
.filters-bar[data-v-7de6ddc6] { .filters[data-v-643133a6] {
display: block;
background: rgba(0, 0, 0, 0.1);
padding: .5rem 1rem;
font-size: 0;
}
.filters-bar .icon[data-v-7de6ddc6] {
fill: rgba(0, 0, 0, 0.5);
}
.filters[data-v-7de6ddc6] {
display: inline-block; display: inline-block;
list-style: none; list-style: none;
padding: .5rem; padding: .5rem;
margin: 0; margin: 0;
} }
.filters[data-v-7de6ddc6]:not(:last-child) { .filters[data-v-643133a6]:not(:last-child) {
border-right: solid 1px rgba(0, 0, 0, 0.2); border-right: solid 1px rgba(0, 0, 0, 0.1);
} }
.filter[data-v-7de6ddc6] { .filter[data-v-643133a6] {
display: inline-block; display: inline-block;
} }
.toggle[data-v-7de6ddc6] { .compact .filters[data-v-643133a6] {
color: rgba(0, 0, 0, 0.5); padding: 0;
background: rgba(0, 0, 0, 0.1); border: none;
}
.compact .filter[data-v-643133a6] {
margin: 0 0 1.5rem 0;
}
.toggle[data-v-643133a6] {
color: rgba(0, 0, 0, 0.2);
box-sizing: border-box; box-sizing: border-box;
padding: .5rem; padding: .5rem;
margin: 0 .25rem; margin: 0 .25rem;
border: solid 1px transparent;
border-radius: .5rem; border-radius: .5rem;
font-size: .9rem; font-size: .9rem;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
} }
.toggle .check[data-v-7de6ddc6] { .toggle .check[data-v-643133a6] {
display: none; display: none;
} }
.toggle.active[data-v-7de6ddc6] { .toggle[data-v-643133a6]:hover {
color: #fff; color: rgba(0, 0, 0, 0.5);
background: #ff6c88; }
.toggle.active[data-v-643133a6] {
color: #ff6c88;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}
/* $primary: #ff886c; */
.filter-bar[data-v-a678373a] {
background: #fff;
display: block;
padding: .5rem 1rem;
font-size: 0;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
}
.filter-bar .icon[data-v-a678373a] {
fill: rgba(0, 0, 0, 0.5);
}
.filters-container[data-v-a678373a] {
display: inline-block;
}
.filters-compact[data-v-a678373a] {
font-size: 1rem;
font-weight: bold;
display: none;
margin: 0 0 0 .5rem;
}
@media (max-width: 720px) {
.filters-container[data-v-a678373a] {
display: none;
}
.filters-compact[data-v-a678373a] {
display: inline-block;
}
} }
/* $primary: #ff886c; */ /* $primary: #ff886c; */
.tile[data-v-3abcf101] { .tile[data-v-3abcf101] {
background: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
box-sizing: border-box; box-sizing: border-box;
@ -74,7 +105,7 @@
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: 0 .5rem; padding: 0 .5rem;
margin: 0 0 .25rem 0; margin: 0 0 .5rem 0;
} }
.details[data-v-3abcf101] { .details[data-v-3abcf101] {
width: 100%; width: 100%;
@ -99,6 +130,8 @@
border-radius: 0 0 0 .25rem; border-radius: 0 0 0 .25rem;
} }
.info[data-v-3abcf101] { .info[data-v-3abcf101] {
display: flex;
flex-direction: column;
flex-grow: 1; flex-grow: 1;
} }
.link[data-v-3abcf101] { .link[data-v-3abcf101] {
@ -125,43 +158,47 @@
line-height: 1.25rem; line-height: 1.25rem;
} }
.tags[data-v-3abcf101] { .tags[data-v-3abcf101] {
word-wrap: break-word;
overflow: hidden;
max-height: 2.5rem; max-height: 2.5rem;
padding: .25rem .5rem 1rem .5rem;
line-height: 1.25rem; line-height: 1.25rem;
} word-wrap: break-word;
.actor[data-v-3abcf101], overflow-y: hidden;
.tag[data-v-3abcf101] {
margin: 0 .25rem 0 0;
} }
.actor[data-v-3abcf101] { .actor[data-v-3abcf101] {
font-size: .9rem; margin: 0 .25rem 0 0;
} }
.tag[data-v-3abcf101] { .tag[data-v-3abcf101] {
font-size: .75rem; margin: 0 .25rem .5rem 0;
} }
.actor[data-v-3abcf101]:not(:last-of-type)::after, .actor[data-v-3abcf101]:not(:last-of-type)::after {
.tag[data-v-3abcf101]:not(:last-child):after {
content: ","; content: ",";
} }
.actor-link[data-v-3abcf101], .actor-link[data-v-3abcf101] {
.tag-link[data-v-3abcf101] {
text-decoration: none; text-decoration: none;
} }
.actor-link[data-v-3abcf101]:hover, .actor-link[data-v-3abcf101]:hover {
.tag-link[data-v-3abcf101]:hover {
color: #ff6c88; color: #ff6c88;
} }
.actor-link[data-v-3abcf101] { .actor-link[data-v-3abcf101] {
color: #cc4466; color: #cc4466;
} }
.tag-link[data-v-3abcf101] { .tag-link[data-v-3abcf101] {
color: rgba(0, 0, 0, 0.7); color: rgba(0, 0, 0, 0.5);
padding: .25rem;
border-radius: .25rem;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
font-size: .75rem;
font-weight: bold;
text-decoration: none;
}
.tag-link[data-v-3abcf101]:hover {
color: #ff6c88;
} }
/* $primary: #ff886c; */ /* $primary: #ff886c; */
.banner[data-v-2bc41e74] { .banner[data-v-cbb14462] {
background: #222; background: #222;
flex-shrink: 0;
white-space: nowrap; white-space: nowrap;
overflow-x: auto; overflow-x: auto;
margin: 0 0 1rem 0; margin: 0 0 1rem 0;
@ -169,16 +206,22 @@
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
font-size: 0; font-size: 0;
} }
.banner[data-v-2bc41e74]::-webkit-scrollbar { .banner[data-v-cbb14462]::-webkit-scrollbar {
display: none; display: none;
} }
.banner-trailer[data-v-2bc41e74] { .trailer[data-v-cbb14462] {
display: inline-block; display: inline-block;
max-width: 100vw;
} }
.banner-item[data-v-2bc41e74] { .trailer-video[data-v-cbb14462] {
height: 20rem; max-width: 100%;
}
.item[data-v-cbb14462] {
max-height: 18rem;
vertical-align: middle; vertical-align: middle;
} }
/* $primary: #ff886c; */
.row[data-v-2bc41e74] { .row[data-v-2bc41e74] {
display: block; display: block;
padding: 0 1rem; padding: 0 1rem;
@ -543,9 +586,10 @@ body {
/* $primary: #ff886c; */ /* $primary: #ff886c; */
.header[data-v-10b7ec04] { .header[data-v-10b7ec04] {
color: #fff; background: #fff;
background: #ff6c88; color: #ff6c88;
padding: .5rem 1rem; padding: .5rem 1rem;
border-bottom: solid 1px rgba(0, 0, 0, 0.1);
} }
.logo-link[data-v-10b7ec04] { .logo-link[data-v-10b7ec04] {
color: inherit; color: inherit;
@ -556,7 +600,9 @@ body {
margin: 0; margin: 0;
} }
/* $primary: #ff886c; */
.container { .container {
background: #fafafa;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -566,7 +612,7 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-grow: 1; flex-grow: 1;
overflow: hidden; overflow-y: auto;
} }
.content-inner { .content-inner {
flex-grow: 1; flex-grow: 1;