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

View File

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

View File

@ -20,7 +20,7 @@
</template>
<script>
import FilterBar from './filter.vue';
import FilterBar from './filter-bar.vue';
import ReleaseTile from '../tile/release.vue';
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>
<div v-if="release">
<div
class="banner"
@wheel.prevent="scrollBanner"
v-if="release"
class="content"
>
<div class="banner-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="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>
<Banner :release="release" />
<h2 class="row title">{{ release.title }}</h2>
@ -141,37 +116,20 @@
</template>
<script>
import Banner from './banner.vue';
function pageTitle() {
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() {
[this.release] = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId });
}
export default {
components: {
Banner,
},
data() {
return {
release: null,
@ -179,41 +137,13 @@ export default {
},
computed: {
pageTitle,
photos,
},
mounted,
methods: {
scrollBanner,
},
};
</script>
<style lang="scss" scoped>
@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 {
display: block;
padding: 0 1rem;

View File

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

View File

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

View File

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