Generalized filters bar, added to network page.
This commit is contained in:
		
							parent
							
								
									23492bb5d0
								
							
						
					
					
						commit
						0575dbc7e4
					
				|  | @ -7,7 +7,7 @@ | |||
|                     :checked="range === 'all'" | ||||
|                     type="radio" | ||||
|                     class="range-input" | ||||
|                     @click="$emit('set-range', 'all')" | ||||
|                     @click="setRange('all')" | ||||
|                 > | ||||
|                 <label | ||||
|                     :for="`${_uid}-all`" | ||||
|  | @ -21,7 +21,7 @@ | |||
|                     :checked="range === 'new'" | ||||
|                     type="radio" | ||||
|                     class="range-input" | ||||
|                     @click="$emit('set-range', 'new')" | ||||
|                     @click="setRange('new')" | ||||
|                 > | ||||
|                 <label | ||||
|                     :for="`${_uid}-new`" | ||||
|  | @ -35,7 +35,7 @@ | |||
|                     :checked="range === 'upcoming'" | ||||
|                     type="radio" | ||||
|                     class="range-input" | ||||
|                     @click="$emit('set-range', 'upcoming')" | ||||
|                     @click="setRange('upcoming')" | ||||
|                 > | ||||
|                 <label | ||||
|                     :for="`${_uid}-upcoming`" | ||||
|  | @ -50,7 +50,7 @@ | |||
|             <Filters | ||||
|                 class="filters-container" | ||||
|                 :filter="filter" | ||||
|                 @set-filter="filter => $emit('set-filter', filter)" | ||||
|                 @set-filter="setFilter" | ||||
|             /> | ||||
| 
 | ||||
|             <v-popover class="filters-compact"> | ||||
|  | @ -60,7 +60,7 @@ | |||
|                     <Filters | ||||
|                         :compact="true" | ||||
|                         :filter="filter" | ||||
|                         @set-filter="filter => $emit('set-filter', filter)" | ||||
|                         @set-filter="setFilter" | ||||
|                     /> | ||||
|                 </div> | ||||
|             </v-popover> | ||||
|  | @ -69,22 +69,49 @@ | |||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import { mapState } from 'vuex'; | ||||
| import Filters from './filters.vue'; | ||||
| 
 | ||||
| function filter(state) { | ||||
|     return state.ui.filter; | ||||
| } | ||||
| 
 | ||||
| function range(state) { | ||||
|     return state.ui.range; | ||||
| } | ||||
| 
 | ||||
| async function setFilter(newFilter) { | ||||
|     this.$store.dispatch('setFilter', newFilter); | ||||
| 
 | ||||
|     await this.fetchReleases(); | ||||
| } | ||||
| 
 | ||||
| async function setRange(newRange) { | ||||
|     this.$store.dispatch('setRange', newRange); | ||||
| 
 | ||||
|     await this.fetchReleases(); | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     components: { | ||||
|         Filters, | ||||
|     }, | ||||
|     props: { | ||||
|         filter: { | ||||
|             type: Array, | ||||
|             default: () => [], | ||||
|         }, | ||||
|         range: { | ||||
|             type: String, | ||||
|         fetchReleases: { | ||||
|             type: Function, | ||||
|             default: null, | ||||
|         }, | ||||
|     }, | ||||
|     computed: { | ||||
|         ...mapState({ | ||||
|             filter, | ||||
|             range, | ||||
|         }), | ||||
|     }, | ||||
|     methods: { | ||||
|         setFilter, | ||||
|         setRange, | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
| 
 | ||||
|  | @ -1,11 +1,6 @@ | |||
| <template> | ||||
|     <div class="content"> | ||||
|         <FilterBar | ||||
|             :filter="filter" | ||||
|             :range="range" | ||||
|             @set-filter="setFilter" | ||||
|             @set-range="setRange" | ||||
|         /> | ||||
|         <FilterBar :fetch-releases="fetchReleases" /> | ||||
| 
 | ||||
|         <div class="content-inner"> | ||||
|             <ul class="scenes nolist"> | ||||
|  | @ -22,30 +17,11 @@ | |||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import FilterBar from './filter-bar.vue'; | ||||
| import FilterBar from '../header/filter-bar.vue'; | ||||
| import ReleaseTile from '../tile/release.vue'; | ||||
| 
 | ||||
| import rangeDates from '../../js/range-dates'; | ||||
| 
 | ||||
| async function fetchReleases() { | ||||
|     this.releases = await this.$store.dispatch('fetchReleases', { | ||||
|         filter: this.filter, | ||||
|         ...rangeDates(this.range), | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| async function setFilter(filter) { | ||||
|     this.filter = filter; | ||||
|     localStorage.setItem('filter', this.filter); | ||||
| 
 | ||||
|     await this.fetchReleases(); | ||||
| } | ||||
| 
 | ||||
| async function setRange(range) { | ||||
|     this.range = range; | ||||
|     localStorage.setItem('range', this.range); | ||||
| 
 | ||||
|     await this.fetchReleases(); | ||||
|     this.releases = await this.$store.dispatch('fetchReleases'); | ||||
| } | ||||
| 
 | ||||
| async function mounted() { | ||||
|  | @ -60,12 +36,7 @@ export default { | |||
|         ReleaseTile, | ||||
|     }, | ||||
|     data() { | ||||
|         const storedFilter = localStorage.getItem('filter'); | ||||
|         const storedRange = localStorage.getItem('range'); | ||||
| 
 | ||||
|         return { | ||||
|             filter: storedFilter ? storedFilter.split(',') : ['gay', 'transsexual'], | ||||
|             range: storedRange || 'new', | ||||
|             releases: [], | ||||
|             networks: [], | ||||
|             pageTitle: null, | ||||
|  | @ -74,8 +45,6 @@ export default { | |||
|     mounted, | ||||
|     methods: { | ||||
|         fetchReleases, | ||||
|         setFilter, | ||||
|         setRange, | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
|  |  | |||
|  | @ -3,6 +3,8 @@ | |||
|         v-if="network" | ||||
|         class="content network" | ||||
|     > | ||||
|         <FilterBar :fetch-releases="fetchReleases" /> | ||||
| 
 | ||||
|         <div class="content-inner"> | ||||
|             <div class="header"> | ||||
|                 <a | ||||
|  | @ -54,12 +56,19 @@ | |||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import FilterBar from '../header/filter-bar.vue'; | ||||
| import ReleaseTile from '../tile/release.vue'; | ||||
| import SiteTile from '../tile/site.vue'; | ||||
| 
 | ||||
| async function mounted() { | ||||
|     [this.network] = await this.$store.dispatch('fetchNetworks', this.$route.params.networkSlug); | ||||
| async function fetchReleases() { | ||||
|     this.releases = await this.$store.dispatch('fetchNetworkReleases', this.$route.params.networkSlug); | ||||
| } | ||||
| 
 | ||||
| async function mounted() { | ||||
|     [[this.network]] = await Promise.all([ | ||||
|         this.$store.dispatch('fetchNetworks', this.$route.params.networkSlug), | ||||
|         this.fetchReleases(), | ||||
|     ]); | ||||
| 
 | ||||
|     this.sites = this.network.sites | ||||
|         .filter(site => !site.independent) | ||||
|  | @ -70,6 +79,7 @@ async function mounted() { | |||
| 
 | ||||
| export default { | ||||
|     components: { | ||||
|         FilterBar, | ||||
|         ReleaseTile, | ||||
|         SiteTile, | ||||
|     }, | ||||
|  | @ -82,6 +92,9 @@ export default { | |||
|         }; | ||||
|     }, | ||||
|     mounted, | ||||
|     methods: { | ||||
|         fetchReleases, | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
|  | @ -207,7 +207,7 @@ function pageTitle() { | |||
| } | ||||
| 
 | ||||
| async function mounted() { | ||||
|     this.release = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId }); | ||||
|     this.release = await this.$store.dispatch('fetchReleaseById', this.$route.params.releaseId); | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|  |  | |||
|  | @ -1,14 +1,20 @@ | |||
| import { get } from '../api'; | ||||
| 
 | ||||
| function initNetworksActions(_store, _router) { | ||||
| function initNetworksActions(store, _router) { | ||||
|     async function fetchNetworks({ _commit }, networkId) { | ||||
|         const networks = await get(`/networks/${networkId || ''}`); | ||||
|         const networks = await get(`/networks/${networkId || ''}`, { | ||||
| 
 | ||||
|         }); | ||||
| 
 | ||||
|         return networks; | ||||
|     } | ||||
| 
 | ||||
|     async function fetchNetworkReleases({ _commit }, networkId) { | ||||
|         const releases = await get(`/networks/${networkId}/releases`); | ||||
|         const releases = await get(`/networks/${networkId}/releases`, { | ||||
|             filter: store.state.ui.filter, | ||||
|             after: store.getters.after, | ||||
|             before: store.getters.before, | ||||
|         }); | ||||
| 
 | ||||
|         return releases; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,18 +0,0 @@ | |||
| function rangeDates(range) { | ||||
|     return ({ | ||||
|         new: () => ({ | ||||
|             after: new Date(0), | ||||
|             before: new Date(), | ||||
|         }), | ||||
|         upcoming: () => ({ | ||||
|             after: new Date(), | ||||
|             before: new Date(2 ** 42), | ||||
|         }), | ||||
|         all: () => ({ | ||||
|             after: new Date(0), | ||||
|             before: new Date(2 ** 42), | ||||
|         }), | ||||
|     })[range](); | ||||
| } | ||||
| 
 | ||||
| export default rangeDates; | ||||
|  | @ -1,28 +1,25 @@ | |||
| import dayjs from 'dayjs'; | ||||
| 
 | ||||
| import { get } from '../api'; | ||||
| 
 | ||||
| function initReleasesActions(_store, _router) { | ||||
|     async function fetchReleases({ _commit }, { | ||||
|         id, | ||||
|         filter, | ||||
|         after, | ||||
|         before, | ||||
|     }) { | ||||
|         const afterString = dayjs(after).format('YYYY-MM-DD'); | ||||
|         const beforeString = dayjs(before).format('YYYY-MM-DD'); | ||||
| 
 | ||||
|         const releases = await get(`/releases/${id || ''}`, { | ||||
|             filter, | ||||
|             after: afterString, | ||||
|             before: beforeString, | ||||
| function initReleasesActions(store, _router) { | ||||
|     async function fetchReleases({ _commit }) { | ||||
|         const releases = await get('/releases', { | ||||
|             filter: store.state.ui.filter, | ||||
|             after: store.getters.after, | ||||
|             before: store.getters.before, | ||||
|         }); | ||||
| 
 | ||||
|         return releases; | ||||
|     } | ||||
| 
 | ||||
|     async function fetchReleaseById({ _commit }, releaseId) { | ||||
|         const release = await get(`/releases/${releaseId}`); | ||||
| 
 | ||||
|         return release; | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|         fetchReleases, | ||||
|         fetchReleaseById, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import Vue from 'vue'; | ||||
| import Vuex from 'vuex'; | ||||
| 
 | ||||
| import initUiStore from './ui/ui'; | ||||
| import initAuthStore from './auth/auth'; | ||||
| import initReleasesStore from './releases/releases'; | ||||
| import initSitesStore from './sites/sites'; | ||||
|  | @ -13,6 +14,7 @@ function initStore(router) { | |||
| 
 | ||||
|     const store = new Vuex.Store(); | ||||
| 
 | ||||
|     store.registerModule('ui', initUiStore(store, router)); | ||||
|     store.registerModule('auth', initAuthStore(store, router)); | ||||
|     store.registerModule('releases', initReleasesStore(store, router)); | ||||
|     store.registerModule('actors', initActorsStore(store, router)); | ||||
|  |  | |||
|  | @ -0,0 +1,20 @@ | |||
| // import { get } from '../api';
 | ||||
| 
 | ||||
| function initUiActions(_store, _router) { | ||||
|     function setFilter({ commit }, filter) { | ||||
|         commit('setFilter', filter); | ||||
|         localStorage.setItem('filter', filter); | ||||
|     } | ||||
| 
 | ||||
|     function setRange({ commit }, range) { | ||||
|         commit('setRange', range); | ||||
|         localStorage.setItem('range', range); | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|         setFilter, | ||||
|         setRange, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export default initUiActions; | ||||
|  | @ -0,0 +1,34 @@ | |||
| import dayjs from 'dayjs'; | ||||
| 
 | ||||
| const dateRanges = { | ||||
|     new: () => ({ | ||||
|         after: dayjs(new Date(0)).format('YYYY-MM-DD'), | ||||
|         before: dayjs(new Date()).format('YYYY-MM-DD'), | ||||
|     }), | ||||
|     upcoming: () => ({ | ||||
|         after: dayjs(new Date()).format('YYYY-MM-DD'), | ||||
|         before: dayjs(new Date(2 ** 42)).format('YYYY-MM-DD'), | ||||
|     }), | ||||
|     all: () => ({ | ||||
|         after: dayjs(new Date(0)).format('YYYY-MM-DD'), | ||||
|         before: dayjs(new Date(2 ** 42)).format('YYYY-MM-DD'), | ||||
|     }), | ||||
| }; | ||||
| 
 | ||||
| function rangeDates(state) { | ||||
|     return dateRanges[state.range](); | ||||
| } | ||||
| 
 | ||||
| function before(state) { | ||||
|     return dateRanges[state.range]().before; | ||||
| } | ||||
| 
 | ||||
| function after(state) { | ||||
|     return dateRanges[state.range]().after; | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     rangeDates, | ||||
|     before, | ||||
|     after, | ||||
| }; | ||||
|  | @ -0,0 +1,12 @@ | |||
| function setFilter(state, filter) { | ||||
|     state.filter = filter; | ||||
| } | ||||
| 
 | ||||
| function setRange(state, range) { | ||||
|     state.range = range; | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|     setFilter, | ||||
|     setRange, | ||||
| }; | ||||
|  | @ -0,0 +1,7 @@ | |||
| const storedFilter = localStorage.getItem('filter'); | ||||
| const storedRange = localStorage.getItem('range'); | ||||
| 
 | ||||
| export default { | ||||
|     filter: storedFilter ? storedFilter.split(',') : ['gay', 'transsexual'], | ||||
|     range: storedRange || 'new', | ||||
| }; | ||||
|  | @ -0,0 +1,15 @@ | |||
| import state from './state'; | ||||
| import mutations from './mutations'; | ||||
| import getters from './getters'; | ||||
| import actions from './actions'; | ||||
| 
 | ||||
| function initUiStore(store, router) { | ||||
|     return { | ||||
|         state, | ||||
|         mutations, | ||||
|         getters, | ||||
|         actions: actions(store, router), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export default initUiStore; | ||||
|  | @ -1,24 +1,24 @@ | |||
| /* $primary: #ff886c; */ | ||||
| .filters[data-v-643133a6] { | ||||
| .filters[data-v-e35db0d8] { | ||||
|   display: inline-block; | ||||
|   list-style: none; | ||||
|   padding: .5rem; | ||||
|   margin: 0; | ||||
| } | ||||
| .filters[data-v-643133a6]:not(:last-child) { | ||||
| .filters[data-v-e35db0d8]:not(:last-child) { | ||||
|     border-right: solid 1px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| .filter[data-v-643133a6] { | ||||
| .filter[data-v-e35db0d8] { | ||||
|   display: inline-block; | ||||
| } | ||||
| .compact .filters[data-v-643133a6] { | ||||
| .compact .filters[data-v-e35db0d8] { | ||||
|   padding: 0; | ||||
|   border: none; | ||||
| } | ||||
| .compact .filter[data-v-643133a6] { | ||||
| .compact .filter[data-v-e35db0d8] { | ||||
|   margin: 0 0 1.5rem 0; | ||||
| } | ||||
| .toggle[data-v-643133a6] { | ||||
| .toggle[data-v-e35db0d8] { | ||||
|   color: rgba(0, 0, 0, 0.2); | ||||
|   box-sizing: border-box; | ||||
|   padding: .5rem; | ||||
|  | @ -28,19 +28,19 @@ | |||
|   font-weight: bold; | ||||
|   cursor: pointer; | ||||
| } | ||||
| .toggle .check[data-v-643133a6] { | ||||
| .toggle .check[data-v-e35db0d8] { | ||||
|     display: none; | ||||
| } | ||||
| .toggle[data-v-643133a6]:hover { | ||||
| .toggle[data-v-e35db0d8]:hover { | ||||
|     color: rgba(0, 0, 0, 0.5); | ||||
| } | ||||
| .toggle.active[data-v-643133a6] { | ||||
| .toggle.active[data-v-e35db0d8] { | ||||
|     color: #ff6c88; | ||||
|     box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); | ||||
| } | ||||
| 
 | ||||
| /* $primary: #ff886c; */ | ||||
| .filter-bar[data-v-a678373a] { | ||||
| .filter-bar[data-v-6db17c96] { | ||||
|   background: #fff; | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
|  | @ -48,19 +48,19 @@ | |||
|   font-size: 0; | ||||
|   box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); | ||||
| } | ||||
| .filter-bar .icon[data-v-a678373a] { | ||||
| .filter-bar .icon[data-v-6db17c96] { | ||||
|     fill: rgba(0, 0, 0, 0.5); | ||||
| } | ||||
| .filters-container[data-v-a678373a] { | ||||
| .filters-container[data-v-6db17c96] { | ||||
|   display: inline-block; | ||||
| } | ||||
| .filters-compact[data-v-a678373a] { | ||||
| .filters-compact[data-v-6db17c96] { | ||||
|   font-size: 1rem; | ||||
|   font-weight: bold; | ||||
|   display: none; | ||||
|   margin: 0 0 0 .5rem; | ||||
| } | ||||
| .range-button[data-v-a678373a] { | ||||
| .range-button[data-v-6db17c96] { | ||||
|   color: rgba(0, 0, 0, 0.5); | ||||
|   background: #fff; | ||||
|   display: inline-block; | ||||
|  | @ -70,21 +70,21 @@ | |||
|   font-size: .8rem; | ||||
|   font-weight: bold; | ||||
| } | ||||
| .range-button[data-v-a678373a]:hover { | ||||
| .range-button[data-v-6db17c96]:hover { | ||||
|     color: #222; | ||||
|     cursor: pointer; | ||||
| } | ||||
| .range-input[data-v-a678373a] { | ||||
| .range-input[data-v-6db17c96] { | ||||
|   display: none; | ||||
| } | ||||
| .range-input:checked + .range-button[data-v-a678373a] { | ||||
| .range-input:checked + .range-button[data-v-6db17c96] { | ||||
|     color: #ff6c88; | ||||
| } | ||||
| @media (max-width: 720px) { | ||||
| .filters-container[data-v-a678373a] { | ||||
| .filters-container[data-v-6db17c96] { | ||||
|     display: none; | ||||
| } | ||||
| .filters-compact[data-v-a678373a] { | ||||
| .filters-compact[data-v-6db17c96] { | ||||
|     display: inline-block; | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -77,6 +77,8 @@ function commonQuery(queryBuilder, { | |||
|     before = new Date(2 ** 44), // May 2109
 | ||||
|     limit = 100, | ||||
| }) { | ||||
|     const finalFilter = [].concat(filter); // ensure filter is array
 | ||||
| 
 | ||||
|     queryBuilder | ||||
|         .leftJoin('sites', 'releases.site_id', 'sites.id') | ||||
|         .leftJoin('studios', 'releases.studio_id', 'studios.id') | ||||
|  | @ -93,7 +95,7 @@ function commonQuery(queryBuilder, { | |||
|                 .select('*') | ||||
|                 .from('tags_associated') | ||||
|                 .leftJoin('tags', 'tags_associated.tag_id', 'tags.id') | ||||
|                 .whereIn('tags.slug', filter) | ||||
|                 .whereIn('tags.slug', finalFilter) | ||||
|                 .andWhereRaw('tags_associated.release_id = releases.id'); | ||||
|         }) | ||||
|         .andWhere('date', '>', after) | ||||
|  |  | |||
|  | @ -9,13 +9,7 @@ const { | |||
| } = require('../releases'); | ||||
| 
 | ||||
| async function fetchReleasesApi(req, res) { | ||||
|     const filter = req.query.filter ? [].concat(req.query.filter) : []; // don't filter for 'undefined'
 | ||||
| 
 | ||||
|     const releases = await fetchReleases({}, { | ||||
|         filter, | ||||
|         after: req.query.after, | ||||
|         before: req.query.before, | ||||
|     }); | ||||
|     const releases = await fetchReleases({}, req.query); | ||||
| 
 | ||||
|     res.send(releases); | ||||
| } | ||||
|  | @ -47,7 +41,7 @@ async function fetchNetworkReleasesApi(req, res) { | |||
|     const releases = await fetchNetworkReleases({ | ||||
|         id: networkId, | ||||
|         slug: networkSlug, | ||||
|     }); | ||||
|     }, req.query); | ||||
| 
 | ||||
|     res.send(releases); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue