From 643c71469abc485ae431a4724033e1dfb3e05f15 Mon Sep 17 00:00:00 2001 From: devfake Date: Mon, 28 Nov 2016 08:50:09 +0100 Subject: [PATCH] modal, display episodes, few other updates --- .../Http/Controllers/SettingController.php | 20 ++- .../app/Http/Controllers/TMDBController.php | 4 +- client/app/app.js | 3 +- client/app/components/Content/Content.vue | 4 +- client/app/components/Content/TMDBContent.vue | 3 +- client/app/components/Header.vue | 25 ++-- client/app/components/Modal/Index.vue | 29 ++++ client/app/components/Modal/Season.vue | 55 ++++++++ client/app/helper.js | 4 + client/app/routes.js | 14 +- client/app/store/actions.js | 13 +- client/app/store/index.js | 6 +- client/app/store/mutations.js | 22 +++ client/app/store/types.js | 6 +- client/resources/app.blade.php | 1 + client/resources/languages/de.json | 12 +- client/resources/languages/en.json | 6 +- client/resources/sass/_base.scss | 4 + client/resources/sass/_misc.scss | 4 + client/resources/sass/app.scss | 3 +- .../resources/sass/components/_content.scss | 10 +- client/resources/sass/components/_footer.scss | 4 + client/resources/sass/components/_header.scss | 39 ++++-- client/resources/sass/components/_modal.scss | 132 ++++++++++++++++++ client/resources/sass/components/_search.scss | 4 + public/assets/img/seen-active.png | Bin 0 -> 310 bytes public/assets/img/seen.png | Bin 0 -> 305 bytes 27 files changed, 372 insertions(+), 55 deletions(-) create mode 100644 client/app/components/Modal/Index.vue create mode 100644 client/app/components/Modal/Season.vue create mode 100644 client/resources/sass/components/_modal.scss create mode 100644 public/assets/img/seen-active.png create mode 100644 public/assets/img/seen.png diff --git a/backend/app/Http/Controllers/SettingController.php b/backend/app/Http/Controllers/SettingController.php index ee737d8..5df7c42 100644 --- a/backend/app/Http/Controllers/SettingController.php +++ b/backend/app/Http/Controllers/SettingController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; + use App\Episode; use App\Http\Requests\ImportRequest; use App\Item; use App\Services\Storage; @@ -14,25 +15,29 @@ class SettingController { private $item; + private $episodes; private $storage; - public function __construct(Item $item, Storage $storage) + public function __construct(Item $item, Episode $episodes, Storage $storage) { $this->item = $item; + $this->episodes = $episodes; $this->storage = $storage; } /** - * Save all movies as json file and return an download response. + * Save all movies and series as json file and return an download response. * * @return \Symfony\Component\HttpFoundation\BinaryFileResponse */ public function export() { - $items = json_encode($this->item->all()); + $data['items'] = $this->item->all(); + $data['episodes'] = $this->episodes->all(); + $file = 'flox--' . date('Y-m-d---H-i') . '.json'; - $this->storage->saveExport($file, $items); + $this->storage->saveExport($file, json_encode($data)); return response()->download(base_path('../public/exports/' . $file)); } @@ -55,10 +60,15 @@ $data = json_decode(file_get_contents($file)); $this->item->truncate(); - foreach($data as $item) { + foreach($data->items as $item) { $this->item->create((array) $item); $this->storage->createPosterFile($item->poster); } + + $this->episodes->truncate(); + foreach($data->episodes as $episode) { + $this->episodes->create((array) $episode); + } } /** diff --git a/backend/app/Http/Controllers/TMDBController.php b/backend/app/Http/Controllers/TMDBController.php index 4e6ae9d..d6cc93e 100644 --- a/backend/app/Http/Controllers/TMDBController.php +++ b/backend/app/Http/Controllers/TMDBController.php @@ -19,9 +19,9 @@ return $this->tmdb->search(Input::get('q')); } - public function suggestions($tmdbID) + public function suggestions($tmdbID, $mediaType) { - return $this->tmdb->suggestions($tmdbID); + return $this->tmdb->suggestions($mediaType, $tmdbID); } public function trending() diff --git a/client/app/app.js b/client/app/app.js index addf62a..02a4db9 100644 --- a/client/app/app.js +++ b/client/app/app.js @@ -7,6 +7,7 @@ import SiteHeader from './components/Header.vue'; import Search from './components/Search.vue'; import SiteFooter from './components/Footer.vue'; import Login from './components/Login.vue'; +import Modal from './components/Modal/Index.vue'; import router from './routes'; import store from './store/index'; @@ -26,7 +27,7 @@ const App = new Vue({ }, components: { - SiteHeader, Search, SiteFooter, Login + SiteHeader, Search, SiteFooter, Login, Modal }, methods: { diff --git a/client/app/components/Content/Content.vue b/client/app/components/Content/Content.vue index db98f23..3cdf5da 100644 --- a/client/app/components/Content/Content.vue +++ b/client/app/components/Content/Content.vue @@ -55,7 +55,9 @@ ...mapActions([ 'loadItems', 'loadMoreItems', 'setSearchTitle' ]), fetchData() { - this.loadItems(this.userFilter); + let name = this.$route.name; + + this.loadItems({name, filter: this.userFilter}); this.setSearchTitle(''); }, diff --git a/client/app/components/Content/TMDBContent.vue b/client/app/components/Content/TMDBContent.vue index 879c467..e763c9a 100644 --- a/client/app/components/Content/TMDBContent.vue +++ b/client/app/components/Content/TMDBContent.vue @@ -58,8 +58,9 @@ initSuggestions() { const tmdbID = this.$route.query.for; + const type = this.$route.query.type; - http(`${config.api}/suggestions/${tmdbID}`).then(value => { + http(`${config.api}/suggestions/${tmdbID}/${type}`).then(value => { this.items = value.data; this.SET_LOADING(false); }); diff --git a/client/app/components/Header.vue b/client/app/components/Header.vue index f1a6b41..def87ee 100644 --- a/client/app/components/Header.vue +++ b/client/app/components/Header.vue @@ -11,12 +11,15 @@ - + + + @@ -62,10 +65,12 @@ this.SET_USER_FILTER(localStorage.getItem('filter')); }, - setUserFilter(type) { - localStorage.setItem('filter', type); - this.SET_USER_FILTER(type); - this.loadItems(type); + setUserFilter(filter) { + let name = this.$route.name; + + localStorage.setItem('filter', filter); + this.SET_USER_FILTER(filter); + this.loadItems({name, filter}); } } } diff --git a/client/app/components/Modal/Index.vue b/client/app/components/Modal/Index.vue new file mode 100644 index 0000000..6e09787 --- /dev/null +++ b/client/app/components/Modal/Index.vue @@ -0,0 +1,29 @@ + + + \ No newline at end of file diff --git a/client/app/components/Modal/Season.vue b/client/app/components/Modal/Season.vue new file mode 100644 index 0000000..3bb0595 --- /dev/null +++ b/client/app/components/Modal/Season.vue @@ -0,0 +1,55 @@ + + + diff --git a/client/app/helper.js b/client/app/helper.js index 85da953..73454b5 100644 --- a/client/app/helper.js +++ b/client/app/helper.js @@ -20,6 +20,10 @@ export default { window.requestAnimationFrame(step); }, + addZero(item) { + return ('0' + item).slice(-2); + }, + // Language helper lang(text) { const language = JSON.parse(config.language); diff --git a/client/app/routes.js b/client/app/routes.js index 1c57245..ea177b8 100644 --- a/client/app/routes.js +++ b/client/app/routes.js @@ -14,12 +14,14 @@ export default new Router({ mode: 'history', base: config.uri, routes: [ - { path: '/', component: Content }, - { path: '/search', component: SearchContent }, - { path: '/settings', component: Settings }, - { path: '/suggestions', component: TMDBContent }, - { path: '/trending', component: TMDBContent }, - { path: '/upcoming', component: TMDBContent }, + { path: '/', component: Content, name: 'home' }, + { path: '/movies', component: Content, name: 'movie' }, + { path: '/tv', component: Content, name: 'tv' }, + { path: '/search', component: SearchContent, name: 'search' }, + { path: '/settings', component: Settings, name: 'settings' }, + { path: '/suggestions', component: TMDBContent, name: 'suggestions' }, + { path: '/trending', component: TMDBContent, name: 'trending' }, + { path: '/upcoming', component: TMDBContent, name: 'upcoming' }, { path: '*', component: Content } ] }); \ No newline at end of file diff --git a/client/app/store/actions.js b/client/app/store/actions.js index 0bf3ce6..f7b3627 100644 --- a/client/app/store/actions.js +++ b/client/app/store/actions.js @@ -1,8 +1,8 @@ import http from 'axios'; -export function loadItems({commit}, filter) { +export function loadItems({commit}, response) { commit('SET_LOADING', true); - http(`${config.api}/items/${filter}`).then(value => { + http(`${config.api}/items/${response.name}/${response.filter}`).then(value => { const {data, next_page_url} = value.data; commit('SET_ITEMS', data); @@ -39,4 +39,13 @@ export function setSearchTitle({commit}, title) { export function setColorScheme({commit}, color) { localStorage.setItem('color', color); commit('SET_COLOR_SCHEME', color); +} + +export function fetchEpisodes({commit}, data) { + http(`${config.api}/episodes/${data.tmdb_id}`).then(response => { + commit('SET_MODAL_DATA', { + title: data.title, + episodes: response.data + }); + }); } \ No newline at end of file diff --git a/client/app/store/index.js b/client/app/store/index.js index c3337ea..6bf3355 100644 --- a/client/app/store/index.js +++ b/client/app/store/index.js @@ -14,7 +14,11 @@ export default new Vuex.Store({ loading: false, clickedMoreLoading: false, paginator: null, - colorScheme: '' + colorScheme: '', + overlay: false, + modalData: {}, + seasonActiveModal: 1, + modalType: '' }, mutations, actions diff --git a/client/app/store/mutations.js b/client/app/store/mutations.js index 4b5e623..ea15c70 100644 --- a/client/app/store/mutations.js +++ b/client/app/store/mutations.js @@ -31,5 +31,27 @@ export default { [type.SET_COLOR_SCHEME](state, color) { state.colorScheme = color; + }, + + [type.CLOSE_MODAL](state) { + state.modalType = false; + state.overlay = false; + state.seasonActiveModal = 1; + document.body.className = document.body.className.replace('open-modal', ''); + }, + + [type.OPEN_MODAL](state, data) { + state.overlay = true; + state.modalType = data.type; + state.modalData = data.data; + document.body.className += ' open-modal'; + }, + + [type.SET_SEASON_ACTIVE_MODAL](state, season) { + state.seasonActiveModal = season; + }, + + [type.SET_MODAL_DATA](state, data) { + state.modalData = data; } } \ No newline at end of file diff --git a/client/app/store/types.js b/client/app/store/types.js index 51d5bce..1d8a0b3 100644 --- a/client/app/store/types.js +++ b/client/app/store/types.js @@ -5,4 +5,8 @@ export const PUSH_TO_ITEMS = 'PUSH_TO_ITEMS'; export const SET_LOADING = 'SET_LOADING'; export const SET_PAGINATOR = 'SET_PAGINATOR'; export const SET_CLICKED_LOADING = 'SET_CLICKED_LOADING'; -export const SET_COLOR_SCHEME = 'SET_COLOR_SCHEME'; \ No newline at end of file +export const SET_COLOR_SCHEME = 'SET_COLOR_SCHEME'; +export const CLOSE_MODAL = 'CLOSE_MODAL'; +export const OPEN_MODAL = 'OPEN_MODAL'; +export const SET_SEASON_ACTIVE_MODAL = 'SET_SEASON_ACTIVE_MODAL'; +export const SET_MODAL_DATA = 'SET_MODAL_DATA'; diff --git a/client/resources/app.blade.php b/client/resources/app.blade.php index 4d622d2..85e9261 100644 --- a/client/resources/app.blade.php +++ b/client/resources/app.blade.php @@ -24,6 +24,7 @@ @if(Request::is('login')) @else + diff --git a/client/resources/languages/de.json b/client/resources/languages/de.json index c8ee8da..3a2762f 100644 --- a/client/resources/languages/de.json +++ b/client/resources/languages/de.json @@ -7,13 +7,15 @@ "suggestions": "Vorschläge", "delete movie": "Löschen", "confirm delete": "Wirklich löschen?", - "search": "Film suchen", - "search or add": "Film suchen oder hinzufügen", + "search": "Suchen", + "search or add": "Suchen oder hinzufügen", "load more": "Mehr anzeigen", "nothing found": "Nichts gefunden", "trending": "Beliebt", "upcoming": "Kommend", + "tv": "TV", + "movies": "Filme", "last seen": "Zuletzt gesehen", "best rated": "Am besten bewertet", "change color": "Farbmodus wechseln", @@ -29,11 +31,11 @@ "export button": "Exportieren", "import button": "Importieren", "or divider": "ODER", - "update genre": "Genre updaten", - "sync scout": "Sync Laravel Scout", + "update genre": "Genre aktualisieren", + "sync scout": "Synchronisieren Laravel Scout", "display genre": "Genre anzeigen", "display date": "Datum anzeigen", "success import": "Filme wurden erfolgreich importiert", "import warn": "Durch den Import werden alle Filme ersetzt. Erstelle vorher ein Backup!", - "genre message": "Um eine alte Version von Flox upzudaten" + "genre message": "Um eine alte Version von Flox zu aktualisieren " } \ No newline at end of file diff --git a/client/resources/languages/en.json b/client/resources/languages/en.json index 5b2ae53..8ee2c9d 100644 --- a/client/resources/languages/en.json +++ b/client/resources/languages/en.json @@ -7,13 +7,15 @@ "suggestions": "Suggestions", "delete movie": "Delete", "confirm delete": "Are you sure?", - "search": "Search movie", - "search or add": "Search or add movie", + "search": "Search", + "search or add": "Search or add", "load more": "Load More", "nothing found": "Nothing found", "trending": "Trending", "upcoming": "Upcoming", + "tv": "TV", + "movies": "Movies", "last seen": "Last seen", "best rated": "Best rated", "change color": "Change colors", diff --git a/client/resources/sass/_base.scss b/client/resources/sass/_base.scss index f5fb759..9ba3d5c 100644 --- a/client/resources/sass/_base.scss +++ b/client/resources/sass/_base.scss @@ -10,6 +10,10 @@ body { &.dark { background: #1c1c1c; } + + &.open-modal { + overflow: hidden; + } } html { diff --git a/client/resources/sass/_misc.scss b/client/resources/sass/_misc.scss index 0d7e584..04f2680 100644 --- a/client/resources/sass/_misc.scss +++ b/client/resources/sass/_misc.scss @@ -62,6 +62,10 @@ $rating3: #cd2727; } } +.no-select { + user-select: none; +} + .fullsize-loader { position: absolute; left: calc(50% - 14px); diff --git a/client/resources/sass/app.scss b/client/resources/sass/app.scss index 188fcdc..fca74b8 100644 --- a/client/resources/sass/app.scss +++ b/client/resources/sass/app.scss @@ -10,4 +10,5 @@ 'components/search', 'components/content', 'components/login', -'components/footer'; \ No newline at end of file +'components/footer', +'components/modal'; \ No newline at end of file diff --git a/client/resources/sass/components/_content.scss b/client/resources/sass/components/_content.scss index b1add74..b8127c8 100644 --- a/client/resources/sass/components/_content.scss +++ b/client/resources/sass/components/_content.scss @@ -7,6 +7,10 @@ main { .dark & { background: #1c1c1c; } + + .open-modal & { + padding: 110px 16px 0 0; + } } .item-wrap { @@ -41,10 +45,10 @@ main { .item-new { display: block; } - } - .show-episode { - bottom: 24px; + .show-episode { + bottom: 24px; + } } .recommend-item, diff --git a/client/resources/sass/components/_footer.scss b/client/resources/sass/components/_footer.scss index 1558ddf..961b82f 100644 --- a/client/resources/sass/components/_footer.scss +++ b/client/resources/sass/components/_footer.scss @@ -5,6 +5,10 @@ footer { background: $main2; background: linear-gradient(to right, $main1, $main2); + .open-modal & { + padding: 40px 16px 0 0; + } + .dark & { opacity: .9; } diff --git a/client/resources/sass/components/_header.scss b/client/resources/sass/components/_header.scss index 07a70eb..a4a1a0f 100644 --- a/client/resources/sass/components/_header.scss +++ b/client/resources/sass/components/_header.scss @@ -11,6 +11,10 @@ header { .dark & { opacity: .9; } + + .open-modal & { + padding: 25px 16px 25px 0; + } } .logo { @@ -59,11 +63,11 @@ header { } .icon-sort-time { - background: url(../../../public/assets/img/sort-time.png); + background: url(../../../public/assets/img/sort-time.png) no-repeat; } .icon-sort-star { - background: url(../../../public/assets/img/sort-star.png); + background: url(../../../public/assets/img/sort-star.png) no-repeat; } .icon-constrast { @@ -91,23 +95,19 @@ header { } } -.site-nav { - float: right; - margin: 7px 60px 0 0; +.site-nav, +.site-nav-second { + float: left; + margin: 7px 0 0 40px; + list-style: none; + padding: 0; - @include media(5) { + @include media(4) { + clear: left; float: left; - width: 100%; margin: 20px 0 0 0; } - ul { - float: left; - list-style: none; - margin: 0; - padding: 0; - } - li { float: left; margin: 0 20px 0 0; @@ -136,4 +136,15 @@ header { font-size: 14px; } } +} + +.site-nav-second { + float: right; + margin: 7px 60px 0 0; + + @include media(4) { + clear: none; + float: left; + margin: 20px 0 0 20px; + } } \ No newline at end of file diff --git a/client/resources/sass/components/_modal.scss b/client/resources/sass/components/_modal.scss new file mode 100644 index 0000000..a75a30b --- /dev/null +++ b/client/resources/sass/components/_modal.scss @@ -0,0 +1,132 @@ +.overlay { + background: rgba(#333, .7); + height: 100vh; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 50; +} + +.modal-wrap { + left: 50%; + max-width: 550px; + position: fixed; + top: 10%; + transform: translateX(-50%); + width: 100%; + box-shadow: 0 5px 20px 0 rgba(#000, .6); + z-index: 100; + + @include media(4) { + top: 0; + } +} + +.modal-header { + background: $main2; + background: linear-gradient(to right, $main1, $main2); + color: #fff; + float: left; + font-size: 20px; + width: 100%; + padding: 10px 15px; +} + +.season-tabs { + float: left; + width: 100%; + background: #464646; + + span { + float: left; + cursor: pointer; + font-size: 16px; + color: #a9a9a9; + padding: 10px 0; + width: 10%; + text-align: center; + + @include media(6) { + width: 20%; + } + + @include transition(background); + + &.active, + &:hover { + background: #2f2f2f; + } + } +} + +.modal-content { + float: left; + width: 100%; + background: #2f2f2f; + max-height: calc(60vh - 100px); + overflow: auto; + + @include media(4) { + max-height: calc(100vh - 150px); + } +} + +.modal-item { + float: left; + width: 100%; + padding: 10px; + color: #fff; + cursor: pointer; + border-bottom: 1px solid #444; + + @include transition(background); + + &:hover { + background: darken(#2f2f2f, 5%); + } + + &:active { + background: darken(#2f2f2f, 3%); + } + + &:last-child { + border: none; + } +} + +.modal-episode { + float: left; + width: 35px; + text-align: right; + //color: #a9a9a9; + opacity: .4; + font-size: 15px; + margin: 0 10px 0 0; +} + +.modal-name { + float: left; + //color: #d1d1d1; + opacity: .7; + max-width: calc(100% - 100px); + font-size: 15px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.episode-seen { + float: right; + + i { + float: left; + width: 22px; + height: 22px; + background: url(../../../public/assets/img/seen.png) no-repeat; + } + + &.seen i { + background: url(../../../public/assets/img/seen-active.png) no-repeat; + } +} \ No newline at end of file diff --git a/client/resources/sass/components/_search.scss b/client/resources/sass/components/_search.scss index 7c95e51..272f165 100644 --- a/client/resources/sass/components/_search.scss +++ b/client/resources/sass/components/_search.scss @@ -10,6 +10,10 @@ background: #2f2f2f; } + .open-modal & { + padding: 0 16px 0 0; + } + &.sticky { @include media(sticky) { position: fixed; diff --git a/public/assets/img/seen-active.png b/public/assets/img/seen-active.png new file mode 100644 index 0000000000000000000000000000000000000000..5d47377c24bbb031c7b9d5feb75b4237c550678a GIT binary patch literal 310 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6t^qzFu0T3_gA|3xX7aZSAk#~N z{DK)~{k?QHMp;3E<;Kpy~0 zgPpi@N_=+u?JOFsu|-}jt5<;z7Mp{c6(4}Q4){KgsC+REDnlFv>( u*X2H*VmkGxR%+?8&=vdp+Ahqqc)+NTBA_O#o^lZADh5wiKbLh*2~7a6#(;QJ;6@5Ze{YlMIbIz3$+LnJOwy?C0hMS-XFp|j?S6_0bz z{oemdAYwvS_s94;#-N}FAND-uSJ2vR;&kHf%(9>bJmNm#3z|xHJU#KhB4!!8UHZC} zkI(z8%dmO6JM`}ji?vfWznHf5