forked from DebaucheryLibrarian/traxxx
Using query instead of parameters for tag filter URI. Added generic scrolling component, using for actor photos and entity children. Removed pagination from filter bar.
This commit is contained in:
56
assets/components/entities/children.vue
Normal file
56
assets/components/entities/children.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="children">
|
||||
<EntityTile
|
||||
v-for="child in entity.children"
|
||||
:key="`child-${child.id}`"
|
||||
:entity="child"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EntityTile from './tile.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EntityTile,
|
||||
},
|
||||
props: {
|
||||
entity: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.children {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
border-bottom: solid 1px var(--darken-hint);
|
||||
overflow-x: auto;
|
||||
scroll-behavior: smooth;
|
||||
scrollbar-width: none;
|
||||
|
||||
.tile {
|
||||
width: 15rem;
|
||||
margin: 0 1rem 0 0;
|
||||
}
|
||||
|
||||
&.expanded {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
|
||||
grid-gap: 1rem;
|
||||
|
||||
.tile {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -47,73 +47,20 @@
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="content-inner">
|
||||
<div
|
||||
v-if="entity.children.length > 0"
|
||||
class="children-container"
|
||||
>
|
||||
<div
|
||||
v-if="expanded"
|
||||
class="expand noselect"
|
||||
@click="expanded = !expanded"
|
||||
>
|
||||
<Icon
|
||||
v-show="expanded"
|
||||
icon="arrow-up3"
|
||||
<div
|
||||
ref="content"
|
||||
class="content-inner"
|
||||
>
|
||||
<Scroll class="scroll-dark">
|
||||
<Children :entity="entity" />
|
||||
|
||||
<template v-slot:expanded>
|
||||
<Children
|
||||
class="expanded"
|
||||
:entity="entity"
|
||||
/>
|
||||
|
||||
<Icon
|
||||
v-show="!expanded"
|
||||
icon="arrow-down3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="scroll-container"
|
||||
:class="{ expanded }"
|
||||
>
|
||||
<div
|
||||
class="scroll scroll-left noselect"
|
||||
:class="{ 'scroll-start': scrollAtStart }"
|
||||
@click="scroll('left')"
|
||||
><Icon icon="arrow-left3" /></div>
|
||||
|
||||
<div
|
||||
ref="children"
|
||||
class="children"
|
||||
:class="{ expanded }"
|
||||
@scroll="updateScroll"
|
||||
>
|
||||
<EntityTile
|
||||
v-for="child in entity.children"
|
||||
:key="`child-${child.id}`"
|
||||
:entity="child"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="scroll scroll-right noselect"
|
||||
:class="{ 'scroll-end': scrollAtEnd }"
|
||||
@click="scroll('right')"
|
||||
><Icon icon="arrow-right3" /></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="scrollable || expanded"
|
||||
class="expand noselect"
|
||||
@click="expanded = !expanded"
|
||||
>
|
||||
<Icon
|
||||
v-show="expanded"
|
||||
icon="arrow-up3"
|
||||
/>
|
||||
|
||||
<Icon
|
||||
v-show="!expanded"
|
||||
icon="arrow-down3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Scroll>
|
||||
|
||||
<FilterBar
|
||||
:fetch-releases="fetchEntity"
|
||||
@@ -123,15 +70,25 @@
|
||||
|
||||
<div class="releases">
|
||||
<Releases :releases="entity.releases" />
|
||||
|
||||
<Pagination
|
||||
:items-total="totalCount"
|
||||
:items-per-page="limit"
|
||||
class="pagination-top"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EntityTile from './tile.vue';
|
||||
import Vue from 'vue';
|
||||
|
||||
import FilterBar from '../header/filter-bar.vue';
|
||||
import Pagination from '../pagination/pagination.vue';
|
||||
import Releases from '../releases/releases.vue';
|
||||
import Children from './children.vue';
|
||||
import Scroll from '../scroll/scroll.vue';
|
||||
|
||||
async function fetchEntity() {
|
||||
const { entity, totalCount } = await this.$store.dispatch('fetchEntityBySlugAndType', {
|
||||
@@ -146,68 +103,41 @@ async function fetchEntity() {
|
||||
this.totalCount = totalCount;
|
||||
|
||||
this.pageTitle = entity.name;
|
||||
}
|
||||
|
||||
function updateScroll() {
|
||||
this.scrollable = this.$refs.children.scrollWidth > this.$refs.children.clientWidth;
|
||||
this.scrollAtStart = this.$refs.children.scrollLeft === 0;
|
||||
this.scrollAtEnd = this.$refs.children.scrollWidth - this.$refs.children.clientWidth === this.$refs.children.scrollLeft;
|
||||
}
|
||||
|
||||
function scroll(direction) {
|
||||
if (direction === 'right') {
|
||||
this.$refs.children.scrollLeft = this.$refs.children.scrollLeft + this.$refs.children.clientWidth - 100;
|
||||
}
|
||||
|
||||
if (direction === 'left') {
|
||||
this.$refs.children.scrollLeft = this.$refs.children.scrollLeft - this.$refs.children.clientWidth + 100;
|
||||
}
|
||||
Vue.nextTick(() => {
|
||||
this.$refs.content.scrollTop = 0;
|
||||
});
|
||||
}
|
||||
|
||||
async function mounted() {
|
||||
await this.fetchEntity();
|
||||
|
||||
this.updateScroll();
|
||||
window.addEventListener('resize', this.updateScroll);
|
||||
}
|
||||
|
||||
function beforeDestroy() {
|
||||
window.removeEventListener('resize', this.updateScroll);
|
||||
}
|
||||
|
||||
async function route() {
|
||||
await this.fetchEntity();
|
||||
|
||||
this.expanded = false;
|
||||
this.updateScroll();
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EntityTile,
|
||||
FilterBar,
|
||||
Pagination,
|
||||
Children,
|
||||
Releases,
|
||||
Scroll,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
entity: null,
|
||||
totalCount: null,
|
||||
limit: 10,
|
||||
expanded: false,
|
||||
scrollable: true,
|
||||
scrollAtStart: true,
|
||||
scrollAtEnd: false,
|
||||
limit: 20,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: route,
|
||||
},
|
||||
mounted,
|
||||
beforeDestroy,
|
||||
methods: {
|
||||
fetchEntity,
|
||||
updateScroll,
|
||||
scroll,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -250,117 +180,4 @@ export default {
|
||||
.logo-parent {
|
||||
object-position: 100% 50%;
|
||||
}
|
||||
|
||||
.children-container {
|
||||
background: var(--profile);
|
||||
}
|
||||
|
||||
.children {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
border-bottom: solid 1px var(--darken-hint);
|
||||
overflow-x: auto;
|
||||
scroll-behavior: smooth;
|
||||
scrollbar-width: none;
|
||||
|
||||
.tile {
|
||||
width: 15rem;
|
||||
margin: 0 1rem 0 0;
|
||||
}
|
||||
|
||||
&.expanded {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
|
||||
grid-gap: 1rem;
|
||||
|
||||
.tile {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.expand {
|
||||
.icon {
|
||||
fill: var(--lighten);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--lighten-hint);
|
||||
|
||||
.icon {
|
||||
fill: var(--text-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
position: relative;
|
||||
padding: 0 1rem 0 0;
|
||||
|
||||
&.expanded {
|
||||
padding: 0;
|
||||
|
||||
.scroll {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
&.scroll-start ,
|
||||
&.scroll-end {
|
||||
/* use over v-show so button stays visible while still hovered */
|
||||
display: none;
|
||||
|
||||
.icon {
|
||||
fill: var(--lighten-weak);
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
fill: var(--lighten);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
|
||||
&:not(.scroll-start):not(.scroll-end) {
|
||||
.icon {
|
||||
fill: var(--text-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-left {
|
||||
left: 0;
|
||||
padding: 1rem 2rem 1rem 1rem;
|
||||
background: linear-gradient(to right, var(--profile) 50%, transparent);
|
||||
}
|
||||
|
||||
.scroll-right {
|
||||
right: 0;
|
||||
padding: 1rem 1rem 1rem 2rem;
|
||||
background: linear-gradient(to left, var(--profile) 50%, transparent);
|
||||
}
|
||||
|
||||
@media(max-width: $breakpoint) {
|
||||
.scroll {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user