forked from DebaucheryLibrarian/traxxx
588 lines
15 KiB
Vue
588 lines
15 KiB
Vue
<template>
|
|
<div
|
|
v-if="actor"
|
|
class="content actor"
|
|
>
|
|
<FilterBar :fetch-releases="fetchReleases" />
|
|
|
|
<div class="actor-inner">
|
|
<div class="profile">
|
|
<a
|
|
v-if="actor.avatar"
|
|
:href="`/media/${actor.avatar.path}`"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="avatar-link"
|
|
>
|
|
<img
|
|
:src="`/media/${actor.avatar.thumbnail}`"
|
|
class="avatar"
|
|
>
|
|
</a>
|
|
|
|
<ul class="bio nolist">
|
|
<li class="bio-header">
|
|
<h2 class="bio-name">{{ actor.name }}</h2>
|
|
<span
|
|
v-if="actor.gender"
|
|
class="bio-gender"
|
|
:class="{ male: actor.gender === 'male', female: actor.gender === 'female' }"
|
|
><Icon :icon="actor.gender" /></span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.aliases.length"
|
|
class="bio-item"
|
|
>
|
|
<dfn class="bio-label">Also known as</dfn>
|
|
<span>{{ actor.aliases.join(', ') }}</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.birthdate"
|
|
class="bio-item"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="cake" />Birthdate</dfn>
|
|
|
|
<span
|
|
v-if="actor.birthdate"
|
|
class="birthdate"
|
|
>{{ formatDate(actor.birthdate, 'MMMM D, YYYY') }}<span class="age">{{ age }}</span></span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.origin"
|
|
class="bio-item birth"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="home2" />Born in</dfn>
|
|
|
|
<span>
|
|
<span
|
|
v-if="actor.origin.city"
|
|
class="city"
|
|
>{{ actor.origin.city }}</span><span
|
|
v-if="actor.origin.state && (!actor.origin.city || (actor.origin.country && actor.origin.country.alpha2 === 'US'))"
|
|
class="state"
|
|
>{{ actor.origin.city ? `, ${actor.origin.state}` : actor.origin.state }}</span>
|
|
|
|
<span
|
|
v-if="actor.origin.country"
|
|
class="country birthcountry"
|
|
>
|
|
<img
|
|
class="flag"
|
|
:src="`/img/flags/${actor.origin.country.alpha2.toLowerCase()}.png`"
|
|
>{{ actor.origin.country.alias || actor.origin.country.name }}
|
|
</span>
|
|
</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.residence"
|
|
class="bio-item residence"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="location" />Lives in</dfn>
|
|
|
|
<span>
|
|
<span
|
|
v-if="actor.residence.city"
|
|
class="city"
|
|
>{{ actor.residence.city }}</span><span
|
|
v-if="actor.residence.state && actor.residence.country && actor.residence.country.alpha2 === 'US'"
|
|
class="state"
|
|
>{{ actor.residence.city ? `, ${actor.residence.state}` : actor.residence.state }}</span>
|
|
|
|
<span
|
|
v-if="actor.residence.country"
|
|
class="country"
|
|
>
|
|
<img
|
|
class="flag"
|
|
:src="`/img/flags/${actor.residence.country.alpha2.toLowerCase()}.png`"
|
|
>{{ actor.residence.country.alias || actor.residence.country.name }}
|
|
</span>
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="bio nolist">
|
|
<li
|
|
v-if="actor.ethnicity"
|
|
class="bio-item ethnicity"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="earth2" />Ethnicity</dfn>
|
|
<span>{{ actor.ethnicity }}</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.bust || actor.waist || actor.hip"
|
|
title="bust-waist-hip"
|
|
class="bio-item"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="ruler" />Sizes</dfn>
|
|
<span>
|
|
<Icon
|
|
v-if="actor.naturalBoobs === false"
|
|
v-tooltip="'Boobs enhanced'"
|
|
icon="magic-wand"
|
|
class="enhanced"
|
|
/>{{ actor.bust || '??' }}-{{ actor.waist || '??' }}-{{ actor.hip || '??' }}
|
|
</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.height"
|
|
class="bio-item height"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="height" />Height</dfn>
|
|
<span>
|
|
<span class="height-metric">{{ actor.height }} cm</span>
|
|
<span class="height-imperial">{{ imperialHeight.feet }}' {{ imperialHeight.inches }}"</span>
|
|
</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.weight"
|
|
class="bio-item weight"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="scale" />Weight</dfn>
|
|
|
|
<span>
|
|
<span class="weight-metric">{{ actor.weight }} kg</span>
|
|
<span class="weight-imperial">{{ imperialWeight }} lbs</span>
|
|
</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.hasTattoos"
|
|
class="bio-item tattoos"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="flower" />Tattoos</dfn>
|
|
|
|
<span
|
|
v-if="actor.tattoos"
|
|
v-tooltip="actor.tattoos"
|
|
class="bio-value"
|
|
>{{ actor.tattoos }}</span>
|
|
<span v-else>Yes</span>
|
|
</li>
|
|
|
|
<li
|
|
v-if="actor.hasPiercings"
|
|
class="bio-item piercings"
|
|
>
|
|
<dfn class="bio-label"><Icon icon="trophy4" />Piercings</dfn>
|
|
|
|
<span
|
|
v-if="actor.piercings"
|
|
v-tooltip="actor.piercings"
|
|
class="bio-value"
|
|
>{{ actor.piercings }}</span>
|
|
<span v-else>Yes</span>
|
|
</li>
|
|
|
|
<span class="scraped">Updated on {{ formatDate(actor.scrapedAt, 'YYYY-MM-DD HH:mm') }}</span>
|
|
</ul>
|
|
|
|
<div class="extra">
|
|
<p
|
|
v-if="actor.description"
|
|
class="description"
|
|
>{{ actor.description }}</p>
|
|
|
|
<li
|
|
v-if="actor.social && actor.social.length > 0"
|
|
class="social"
|
|
>
|
|
<a
|
|
v-for="social in actor.social"
|
|
:key="`social-${social.id}`"
|
|
v-tooltip.bottom="social.url"
|
|
:href="social.url"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="social-link"
|
|
>
|
|
<Icon
|
|
v-if="social.platform"
|
|
:icon="social.platform"
|
|
/>
|
|
|
|
<Icon
|
|
v-else
|
|
icon="link"
|
|
/>
|
|
</a>
|
|
</li>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="actor-content">
|
|
<div
|
|
v-if="actor.photos && actor.photos.length > 0"
|
|
class="photos-container"
|
|
>
|
|
<Photos :actor="actor" />
|
|
|
|
<Photos
|
|
:actor="actor"
|
|
class="compact"
|
|
@wheel.native.prevent="scrollPhotos"
|
|
/>
|
|
</div>
|
|
|
|
<Releases :releases="releases" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import dayjs from 'dayjs';
|
|
|
|
import { cmToFeetInches, kgToLbs } from '../../../src/utils/convert';
|
|
|
|
import Photos from './photos.vue';
|
|
import FilterBar from '../header/filter-bar.vue';
|
|
import Releases from '../releases/releases.vue';
|
|
|
|
function age() {
|
|
return dayjs(new Date()).diff(this.actor.birthdate, 'years');
|
|
}
|
|
|
|
async function fetchReleases() {
|
|
this.releases = await this.$store.dispatch('fetchActorReleases', this.$route.params.actorSlug);
|
|
}
|
|
|
|
function imperialHeight() {
|
|
return cmToFeetInches(this.actor.height);
|
|
}
|
|
|
|
function imperialWeight() {
|
|
return kgToLbs(this.actor.weight);
|
|
}
|
|
|
|
function scrollPhotos(event) {
|
|
event.currentTarget.scrollLeft += event.deltaY; // eslint-disable-line no-param-reassign
|
|
}
|
|
|
|
async function mounted() {
|
|
[this.actor] = await Promise.all([
|
|
this.$store.dispatch('fetchActors', { actorId: this.$route.params.actorSlug }),
|
|
this.fetchReleases(),
|
|
]);
|
|
|
|
if (this.actor) {
|
|
this.pageTitle = this.actor.name;
|
|
}
|
|
}
|
|
|
|
export default {
|
|
components: {
|
|
FilterBar,
|
|
Photos,
|
|
Releases,
|
|
},
|
|
data() {
|
|
return {
|
|
actor: null,
|
|
releases: null,
|
|
pageTitle: null,
|
|
expanded: false,
|
|
};
|
|
},
|
|
computed: {
|
|
age,
|
|
imperialHeight,
|
|
imperialWeight,
|
|
},
|
|
mounted,
|
|
methods: {
|
|
fetchReleases,
|
|
scrollPhotos,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import 'theme';
|
|
|
|
.actor-inner {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 0;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.profile {
|
|
background: $profile;
|
|
color: $highlight-extreme;
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-shrink: 0;
|
|
|
|
.avatar-link {
|
|
font-size: 0;
|
|
padding: 1rem 0 1rem 1rem;
|
|
}
|
|
|
|
.avatar {
|
|
height: 15rem;
|
|
width: 12rem;
|
|
flex-shrink: 0;
|
|
margin: 0 1rem 0 0;
|
|
object-fit: cover;
|
|
object-position: 50% 0;
|
|
}
|
|
}
|
|
|
|
.bio {
|
|
flex-grow: 1;
|
|
min-width: 20rem;
|
|
box-sizing: border-box;
|
|
padding: 1rem;
|
|
margin: 0 2rem 0 0;
|
|
}
|
|
|
|
.bio-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin: 0 0 1rem 0;
|
|
}
|
|
|
|
.bio-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 0 0 .25rem 0;
|
|
margin: 0 0 .25rem 0;
|
|
line-height: 1.75;
|
|
text-align: right;
|
|
font-size: .9rem;
|
|
font-weight: 600;
|
|
|
|
&:not(:last-of-type) {
|
|
border-bottom: solid 1px $highlight-hint;
|
|
}
|
|
}
|
|
|
|
.bio-label {
|
|
color: $highlight;
|
|
margin: 0 1rem 0 0;
|
|
flex-shrink: 0;
|
|
font-style: normal;
|
|
font-weight: 400;
|
|
|
|
.icon {
|
|
fill: $highlight;
|
|
margin: 0 .5rem 0 0;
|
|
}
|
|
}
|
|
|
|
.bio-value {
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.flag {
|
|
margin: 0 .25rem 0 0;
|
|
}
|
|
|
|
.bio-name {
|
|
display: inline-block;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.bio-gender {
|
|
display: inline-block;
|
|
font-weight: bold;
|
|
text-transform: capitalize;
|
|
font-weight: normal;
|
|
|
|
.icon {
|
|
width: 1.25rem;
|
|
height: 1.25rem;
|
|
}
|
|
|
|
&.female .icon {
|
|
fill: $female;
|
|
}
|
|
|
|
&.male .icon {
|
|
fill: $male;
|
|
}
|
|
}
|
|
|
|
.birthdate {
|
|
display: block;
|
|
}
|
|
|
|
.age {
|
|
font-weight: bold;
|
|
padding: 0 0 0 .5rem;
|
|
border-left: solid 1px $highlight-weak;
|
|
margin: 0 0 0 .5rem;
|
|
}
|
|
|
|
.country {
|
|
display: block;
|
|
}
|
|
|
|
.height-imperial,
|
|
.weight-imperial {
|
|
padding: 0 0 0 .5rem;
|
|
border-left: solid 1px $highlight-weak;
|
|
margin: 0 0 0 .5rem;
|
|
}
|
|
|
|
.enhanced.icon {
|
|
fill: $primary;
|
|
padding: 0 .5rem;
|
|
}
|
|
|
|
.scraped {
|
|
color: $highlight-weak;
|
|
margin: 1rem 0 0 0;
|
|
font-size: .8rem;
|
|
}
|
|
|
|
.extra {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.description {
|
|
max-height: 12rem;
|
|
position: relative;
|
|
display: block;
|
|
box-sizing: border-box;
|
|
padding: 1rem 0 0 0;
|
|
margin: 0 2rem 0 0;
|
|
line-height: 1.5;
|
|
text-overflow: ellipsis;
|
|
font-size: .9rem;
|
|
overflow: auto;
|
|
scrollbar-width: none;
|
|
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.social {
|
|
display: block;
|
|
margin: 1rem 0;
|
|
}
|
|
|
|
.social-link {
|
|
display: inline-block;
|
|
padding: 0 1rem 0 0;
|
|
|
|
.icon {
|
|
fill: $highlight;
|
|
width: 1.5rem;
|
|
height: 1.5rem;
|
|
}
|
|
|
|
&:hover .icon {
|
|
fill: $primary;
|
|
}
|
|
}
|
|
|
|
.actor-content {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
flex-direction: row;
|
|
}
|
|
|
|
.heading {
|
|
padding: 0;
|
|
margin: 0 0 1rem 0;
|
|
}
|
|
|
|
.photos-container {
|
|
min-width: 15rem;
|
|
box-sizing: border-box;
|
|
border-right: solid 1px $shadow-hint;
|
|
padding: 1rem 1.5rem 1rem 1rem;
|
|
margin: 0 .5rem 0 0;
|
|
}
|
|
|
|
.photos.compact {
|
|
display: none;
|
|
}
|
|
|
|
.releases {
|
|
flex-grow: 1;
|
|
padding: 1rem;
|
|
}
|
|
|
|
@media(max-width: $breakpoint4) {
|
|
.description {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
@media(max-width: $breakpoint3) {
|
|
.profile .avatar-link,
|
|
.extra {
|
|
display: none;
|
|
}
|
|
|
|
.actor-content {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.photos-container {
|
|
border: none;
|
|
border-bottom: solid 1px $shadow-hint;
|
|
padding: 1rem 1rem 1.5rem 1rem;
|
|
margin: 0 0 .5rem 0;
|
|
}
|
|
|
|
.photos {
|
|
display: none;
|
|
}
|
|
|
|
.photos.compact {
|
|
display: flex;
|
|
}
|
|
}
|
|
|
|
@media(max-width: $breakpoint) {
|
|
.profile {
|
|
flex-direction: column;
|
|
padding: 0 0 .5rem 0;
|
|
}
|
|
|
|
.bio {
|
|
width: 100%;
|
|
padding: 0 1rem;
|
|
margin: 0;
|
|
}
|
|
|
|
.bio-header {
|
|
margin: 1rem 0;
|
|
}
|
|
|
|
.city,
|
|
.state,
|
|
.ethnicity,
|
|
.residence,
|
|
.weight,
|
|
.tattoos,
|
|
.piercings,
|
|
.scraped {
|
|
display: none;
|
|
}
|
|
|
|
.social {
|
|
padding: 0 1rem;
|
|
}
|
|
}
|
|
</style>
|