Now root template only contains elements that exist for every page; navigation, search and popover along with the router view. Removed most all the logic except for prototype functions/variable attached to the vue instance and controlls the state of moviepopup given a id and type.
This commit is contained in:
247
src/App.vue
247
src/App.vue
@@ -1,122 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
|
||||||
|
<!-- Header and hamburger navigation -->
|
||||||
<navigation></navigation>
|
<navigation></navigation>
|
||||||
|
|
||||||
|
<!-- Header with search field -->
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<div class="header__search">
|
<search-input v-model="query"></search-input>
|
||||||
<input class="header__search-input" type="text" v-model.trim="searchQuery" @keyup.enter="search" placeholder="Search for a movie or show...">
|
|
||||||
<svg class="header__search-icon">
|
|
||||||
<use xlink:href="#iconSearch"></use>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<!-- Movie popup that will show above existing rendered content -->
|
||||||
<movie-popup v-if="moviePopupIsVisible" :id="popupID" :type="popupType"></movie-popup>
|
<movie-popup v-if="moviePopupIsVisible" :id="popupID" :type="popupType"></movie-popup>
|
||||||
|
|
||||||
<section class="main">
|
<!-- Display the component assigned to the given route (default: home) -->
|
||||||
<transition name="fade" @after-leave="afterLeave">
|
<router-view class="content"></router-view>
|
||||||
<router-view name="list-router-view" :type="'page'" :mode="'collection'" :key="$route.params.category"></router-view>
|
|
||||||
<router-view name="search-router-view" :type="'page'" :mode="'search'" :key="$route.params.query"></router-view>
|
|
||||||
<router-view name="user-requests-router-view" :type="'page'" :mode="'user-requests'"></router-view>
|
|
||||||
<router-view name="page-router-view"></router-view>
|
|
||||||
</transition>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import Vue from 'vue'
|
||||||
import storage from './storage.js'
|
|
||||||
import Navigation from './components/Navigation.vue'
|
import Navigation from './components/Navigation.vue'
|
||||||
import MoviePopup from './components/MoviePopup.vue'
|
import MoviePopup from './components/MoviePopup.vue'
|
||||||
|
import SearchInput from './components/search/SearchInput.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
components: { Navigation, MoviePopup},
|
components: {
|
||||||
data(){
|
Navigation,
|
||||||
return{
|
MoviePopup,
|
||||||
|
SearchInput
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
query: '',
|
||||||
moviePopupIsVisible: false,
|
moviePopupIsVisible: false,
|
||||||
moviePopupHistoryVisible: false,
|
popupID: 0,
|
||||||
moviePopupId: 0,
|
popupType: 'movie'
|
||||||
moviePopupType: 'movie',
|
|
||||||
searchQuery: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
queryForRouter(){
|
|
||||||
return encodeURI(this.searchQuery.replace(/ /g, "+"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// User Session Methods
|
|
||||||
requestToken(){
|
|
||||||
storage.sessionId = null;
|
|
||||||
axios.get(`https://api.themoviedb.org/3/authentication/token/new?api_key=${storage.apiKey}`)
|
|
||||||
.then(function(resp){
|
|
||||||
if(typeof resp.data == 'string') {
|
|
||||||
resp.data = JSON.parse(resp.data);
|
|
||||||
}
|
|
||||||
let data = resp.data;
|
|
||||||
window.location.href = `https://www.themoviedb.org/authenticate/${data.request_token}?redirect_to=${location.protocol}//${location.host}/profile`
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
setUserStatus(){
|
|
||||||
storage.token = localStorage.getItem('token') || null;
|
|
||||||
storage.username = localStorage.getItem('username') || null;
|
|
||||||
storage.admin = localStorage.getItem('admin') || null;
|
|
||||||
},
|
|
||||||
// Movie Popup Methods
|
|
||||||
openMoviePopup(id, type, newMoviePopup){
|
|
||||||
console.log('app openMoviePopup:', type)
|
|
||||||
if(newMoviePopup){
|
|
||||||
storage.backTitle = document.title;
|
|
||||||
}
|
|
||||||
storage.createMoviePopup = newMoviePopup;
|
|
||||||
this.moviePopupIsVisible = true;
|
|
||||||
this.moviePopupId = id;
|
|
||||||
this.moviePopupType = type;
|
|
||||||
document.querySelector('body').classList.add('hidden');
|
|
||||||
},
|
|
||||||
closeMoviePopup(){
|
|
||||||
storage.createMoviePopup = false;
|
|
||||||
this.moviePopupIsVisible = false;
|
|
||||||
document.querySelector('body').classList.remove('hidden');
|
|
||||||
window.history.back();
|
|
||||||
},
|
|
||||||
onHistoryState(e){
|
|
||||||
storage.moviePopupOnHistory = e.state ? e.state.hasOwnProperty('popup') : false;
|
|
||||||
if(!storage.moviePopupOnHistory){
|
|
||||||
this.moviePopupIsVisible = false;
|
|
||||||
document.title = storage.backTitle;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changeHistoryState(){
|
|
||||||
if(history.state && history.state.popup){
|
|
||||||
let newState = {
|
|
||||||
popup: false
|
|
||||||
};
|
|
||||||
history.replaceState(newState , null, storage.moviePath);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Search Methods
|
|
||||||
search(){
|
|
||||||
if(!this.searchQuery.length) return;
|
|
||||||
this.$router.push({ name: 'search', params: { query: this.queryForRouter }});
|
|
||||||
},
|
|
||||||
setSearchQuery(clear){
|
|
||||||
if(clear){
|
|
||||||
this.searchQuery = '';
|
|
||||||
} else {
|
|
||||||
let query = decodeURIComponent(this.$route.params.query);
|
|
||||||
this.searchQuery = query ? query.replace(/\+/g, " ") : '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Router After Leave
|
|
||||||
afterLeave(){
|
|
||||||
document.querySelector('body').scrollTop = 0;
|
|
||||||
},
|
|
||||||
// Detect if touch device
|
|
||||||
isTouchDevice() {
|
|
||||||
return 'ontouchstart' in document.documentElement;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created(){
|
created(){
|
||||||
@@ -141,7 +61,21 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "./src/scss/media-queries";
|
||||||
|
@import "./src/scss/variables";
|
||||||
|
.content {
|
||||||
|
@include tablet-min{
|
||||||
|
width: calc(100% - 95px);
|
||||||
|
padding-top: $header-size;
|
||||||
|
margin-left: 95px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@import "./src/scss/main";
|
||||||
@import "./src/scss/variables";
|
@import "./src/scss/variables";
|
||||||
@import "./src/scss/media-queries";
|
@import "./src/scss/media-queries";
|
||||||
*{
|
*{
|
||||||
@@ -168,32 +102,10 @@ figure{
|
|||||||
}
|
}
|
||||||
img{
|
img{
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 100%;
|
// max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.loader{
|
|
||||||
animation: load 1s linear infinite;
|
|
||||||
border: 2px solid $c-white;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: block;
|
|
||||||
height: 30px;
|
|
||||||
left: 50%;
|
|
||||||
margin: -1.5em;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
width: 30px;
|
|
||||||
&:after {
|
|
||||||
border: 5px solid $c-green;
|
|
||||||
border-radius: 50%;
|
|
||||||
content: '';
|
|
||||||
left: 10px;
|
|
||||||
position: absolute;
|
|
||||||
top: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes load {
|
|
||||||
100% { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
.wrapper{
|
.wrapper{
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -202,20 +114,20 @@ img{
|
|||||||
background: $c-white;
|
background: $c-white;
|
||||||
z-index: 15;
|
z-index: 15;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
@include tablet-min{
|
@include tablet-min{
|
||||||
width: calc(100% - 170px);
|
width: calc(100% - 170px);
|
||||||
height: 75px;
|
|
||||||
margin-left: 95px;
|
margin-left: 95px;
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
&__search{
|
&__search{
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
width: calc(100% - 110px);
|
width: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 55px;
|
right: 55px;
|
||||||
@@ -244,27 +156,22 @@ img{
|
|||||||
padding: 15px 30px 15px 90px;
|
padding: 15px 30px 15px 90px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&-icon{
|
&-arrow {
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
height: 19px;
|
||||||
fill: rgba($c-dark, 0.5);
|
width: 30px;
|
||||||
transition: fill 0.5s ease;
|
display: flex;
|
||||||
pointer-events: none;
|
align-self: center;
|
||||||
position: absolute;
|
margin-right: 30px;
|
||||||
top: 50%;
|
|
||||||
margin-top: -7px;
|
-moz-transition: all 0.5s ease;
|
||||||
left: 20px;
|
-webkit-transition: all 0.5s ease;
|
||||||
@include tablet-min{
|
transition: all 0.5s ease;
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
&.down {
|
||||||
margin-top: -9px;
|
-ms-transform: rotate(180deg);
|
||||||
left: 30px;
|
-moz-transform: rotate(180deg);
|
||||||
}
|
-webkit-transform: rotate(180deg);
|
||||||
@include tablet-landscape-min{
|
transform: rotate(180deg);
|
||||||
left: 50px;
|
|
||||||
}
|
|
||||||
@include desktop-min{
|
|
||||||
left: 60px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&-input:focus + &-icon{
|
&-input:focus + &-icon{
|
||||||
@@ -272,50 +179,6 @@ img{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.main{
|
|
||||||
position: relative;
|
|
||||||
padding: 50px 0 0;
|
|
||||||
@include tablet-min{
|
|
||||||
width: calc(100% - 95px);
|
|
||||||
padding: 75px 0 0;
|
|
||||||
margin-left: 95px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.button{
|
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid $c-dark;
|
|
||||||
text-transform: uppercase;
|
|
||||||
background: $c-dark;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 2;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
padding: 5px 20px 4px 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: $c-dark;
|
|
||||||
background: transparent;
|
|
||||||
outline: none;
|
|
||||||
transition: background 0.5s ease, color 0.5s ease;
|
|
||||||
@include tablet-min{
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 6px 20px 5px 20px;
|
|
||||||
}
|
|
||||||
&:active, &:hover{
|
|
||||||
background: $c-dark;
|
|
||||||
color: $c-white;
|
|
||||||
}
|
|
||||||
body:not(.touch) &:hover, &:focus{
|
|
||||||
background: $c-dark;
|
|
||||||
color: $c-white;
|
|
||||||
}
|
|
||||||
&__active {
|
|
||||||
@extend .button;
|
|
||||||
background: $c-dark;
|
|
||||||
color: $c-white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// router view transition
|
// router view transition
|
||||||
.fade-enter-active, .fade-leave-active {
|
.fade-enter-active, .fade-leave-active {
|
||||||
|
|||||||
Reference in New Issue
Block a user