diff --git a/src/components/Movie.vue b/src/components/Movie.vue index c4378e5..fc2e2e7 100644 --- a/src/components/Movie.vue +++ b/src/components/Movie.vue @@ -2,28 +2,32 @@
-
-
-
+
+
+ + + + +
+ + alt="movie poster image" + src="~assets/placeholder.png"> movie poster image -
+ --> -
-

{{ movie.title }}

- -
-
+

{{ movie.title }}

+
@@ -64,32 +68,48 @@
-
{{ movie.overview }}
+
+ {{ movie.overview }} + +
- +
-
-

Release Date

-
{{ movie.year }}
+
+

Release Date

+
{{ movie.year }}
-
-

Rating

-
{{ movie.rank }}
+
+

Rating

+
{{ movie.rating }}
-
-

Seasons

-
{{ movie.seasons }}
+
+

Seasons

+
{{ movie.seasons }}
-
-

Genres

-
{{ nestedDataToString(movie.genres) }}
+
+

Genres

+
{{ movie.genres.join(', ') }}
+
+ +
+

Production status

+
{{ movie.production_status }}
+
+ + +
+

Runtime

+
{{ movie.runtime[0] }} minutes
@@ -126,7 +146,17 @@ import LoadingPlaceholder from './ui/LoadingPlaceholder' import { getMovie, getPerson, getShow, request, getRequestStatus } from '@/api' export default { - props: ['id', 'type'], + // props: ['id', 'type'], + props: { + id: { + required: true, + type: Number + }, + type: { + required: false, + type: String + } + }, components: { TorrentList, Person, LoadingPlaceholder, SidebarListElement }, directives: { img: img }, // TODO decide to remove or use data(){ @@ -142,11 +172,40 @@ export default { requested: false, admin: localStorage.getItem('admin') == "true" ? true : false, showTorrents: false, - compact: false + compact: false, + loading: true, + truncatedDescription: true + } + }, + watch: { + id: function(val){ + if (this.type === 'movie') { + this.fetchMovie(val); + } else { + this.fetchShow(val) + } + }, + backdrop: function(backdrop) { + if (backdrop != null) { + const style = { + backgroundImage: 'url(' + this.ASSET_URL + this.ASSET_SIZES[1] + backdrop + ')' + } + + Object.assign(this.$refs.header.style, style) + } + } + }, + computed: { + numberOfTorrentResults: () => { + let numTorrents = store.getters['torrentModule/resultCount'] + return numTorrents !== null ? numTorrents + ' results' : null } }, methods: { parseResponse(movie) { + setTimeout(() => { + + this.loading = false this.movie = { ...movie } this.title = movie.title this.poster = movie.poster @@ -155,13 +214,22 @@ export default { this.checkIfRequested(movie) .then(status => this.requested = status) + store.dispatch('documentTitle/updateTitle', movie.title) + this.setPosterSrc() + }, 1000) }, async checkIfRequested(movie) { return await getRequestStatus(movie.id, movie.type) }, - nestedDataToString(data) { - return data.join(', ') + setPosterSrc() { + const poster = this.$refs['poster-image'] + if (this.poster == null) { + poster.src = '/dist/no-image.png' + return + } + + poster.src = `${this.ASSET_URL}${this.ASSET_SIZES[0]}${this.poster}` }, sendRequest(){ request(this.id, this.type, storage.token) @@ -176,25 +244,7 @@ export default { window.location.href = 'https://www.themoviedb.org/' + tmdbType + '/' + this.id }, }, - watch: { - id: function(val){ - if (this.type === 'movie') { - this.fetchMovie(val); - } else { - this.fetchShow(val) - } - } - }, - computed: { - numberOfTorrentResults: () => { - let numTorrents = store.getters['torrentModule/resultCount'] - return numTorrents !== null ? numTorrents + ' results' : null - } - }, - beforeDestroy() { - store.dispatch('documentTitle/updateTitle', this.prevDocumentTitle) - }, - created(){ + created() { this.prevDocumentTitle = store.getters['documentTitle/title'] if (this.type === 'movie') { @@ -216,8 +266,9 @@ export default { this.$router.push({ name: '404' }); }) } - - console.log('admin: ', this.admin) + }, + beforeDestroy() { + store.dispatch('documentTitle/updateTitle', this.prevDocumentTitle) } } @@ -226,6 +277,89 @@ export default { @import "./src/scss/loading-placeholder"; @import "./src/scss/variables"; @import "./src/scss/media-queries"; +@import "./src/scss/main"; + +header { + $duration: 0.2s; + height: 250px; + transform: scaleY(1); + transition: height $duration ease; + transform-origin: top; + position: relative; + background-size: cover; + background-repeat: no-repeat; + background-position: 50% 50%; + background-color: $background-color; + display: flex; + align-items: center; + + @include tablet-min { + height: 350px; + } + &:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + z-index: 0; + width: 100%; + height: 100%; + background: $background-dark-85; + } + @include mobile { + &.compact { + height: 100px; + } + } +} + +.movie__poster { + display: none; + + @include desktop { + background: $background-color; + height: 0; + display: block; + position: absolute; + width: calc(45% - 40px); + top: 40px; + left: 40px; + + > img { + width: 100%; + } + } +} + +.truncate-toggle { + border: none; + background: none; + width: 100%; + display: flex; + align-items: center; + text-align: center; + color: $text-color; + + > i { + font-style: unset; + font-size: 0.7rem; + transition: 0.3s ease all; + transform: rotateY(180deg) + } + + &::before, &::after { + content: ''; + flex: 1; + border-bottom: 1px solid $text-color-50; + } + &::before { + margin-right: 1rem; + } + &::after { + margin-left: 1rem; + } +} .movie { &__wrap { @@ -246,49 +380,6 @@ export default { color: $text-color; } } - &__header { - $duration: 0.2s; - height: 250px; - transform: scaleY(1); - transition: height $duration ease; - transform-origin: top; - position: relative; - background-size: cover; - background-repeat: no-repeat; - background-position: 50% 50%; - background-color: $background-color; - @include tablet-min { - height: 350px; - } - &:before { - content: ""; - display: block; - position: absolute; - top: 0; - left: 0; - z-index: 0; - width: 100%; - height: 100%; - background: $background-dark-85; - } - &.compact { - height: 100px; - } - } - - &__poster { - display: none; - @include tablet-min { - background: $background-color; - height: 0; - display: block; - position: absolute; - width: calc(45% - 40px); - top: 40px; - left: 40px; - - } - } &__img { display: block; @@ -364,37 +455,49 @@ export default { font-size: 13px; line-height: 1.8; margin-bottom: 20px; + + & .truncated { + display: -webkit-box; + overflow: hidden; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + + & + .truncate-toggle > i { + transform: rotateY(0deg) rotateZ(180deg); + } + } + @include tablet-min { margin-bottom: 30px; font-size: 14px; } } &__details { - &-block { - float: left; - } - &-block:not(:last-child) { + display: flex; + flex-wrap: wrap; + + > div { margin-bottom: 20px; margin-right: 20px; @include tablet-min { margin-bottom: 30px; margin-right: 30px; } - } - &-title { - margin: 0; - font-weight: 400; - text-transform: uppercase; - font-size: 14px; - color: $green; - @include tablet-min { - font-size: 16px; + & .title { + margin: 0; + font-weight: 400; + text-transform: uppercase; + font-size: 14px; + color: $green; + @include tablet-min { + font-size: 16px; + } + } + & .text { + font-weight: 300; + font-size: 14px; + margin-top: 5px; } - } - &-text { - font-weight: 300; - font-size: 14px; - margin-top: 5px; } } &__admin { diff --git a/src/components/MoviesListItem.vue b/src/components/MoviesListItem.vue index 1bb7326..b8f6206 100644 --- a/src/components/MoviesListItem.vue +++ b/src/components/MoviesListItem.vue @@ -1,21 +1,24 @@ @@ -38,6 +41,8 @@ export default { }, data(){ return { + poster: undefined, + observed: false, posterSizes: [{ id: 'w500', minWidth: 500 @@ -54,37 +59,35 @@ export default { } }, computed: { - posterUrl: function() { - if (this.movie.poster == null) - return "~assets/no-image.png" - - const correctWidth = this.posterQualityIdentifierFromPosterWidth - - return `https://image.tmdb.org/t/p/${correctWidth}${this.movie.poster}` - }, - posterQualityIdentifierFromPosterWidth: function() { - const posterWidth = this.$refs.image.clientHeight - if (posterWidth > this.posterSizes[0].minWidth) - return this.posterSizes[0].id - - const widthCandidates = this.posterSizes.filter(size => posterWidth < size.minWidth ? size.id : null) - return widthCandidates[widthCandidates.length - 1].id + posterAltText: function() { + const type = this.movie.type || '' + const title = this.movie.title || this.movie.name + return this.movie.poster ? `Poster for ${type} ${title}` : `Missing image for ${type} ${title}` + } + }, + beforeMount() { + if (this.movie.poster != null) { + this.poster = 'https://image.tmdb.org/t/p/w500' + this.movie.poster + } else { + this.poster = '/dist/no-image.png' } }, mounted() { - if (this.$refs.image == undefined) + const poster = this.$refs['poster-image'] + if (poster == null) return + const imageObserver = new IntersectionObserver((entries, imgObserver) => { entries.forEach((entry) => { - if (entry.isIntersecting) { + if (entry.isIntersecting && this.observed == false) { const lazyImage = entry.target - lazyImage.src = this.posterUrl - lazyImage.class + lazyImage.src = lazyImage.dataset.src + this.observed = true } }) }); - imageObserver.observe(this.$refs.image); + imageObserver.observe(poster); }, methods: { openMoviePopup(id, type) { @@ -94,74 +97,103 @@ export default { } -