mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2025-01-24 07:04:50 +00:00
feat(filter): move filter string creating to component
Move the filter string creation the the FilterButton component, so the view only has to handle fetching the data based on the options received from the FilterButton event. Also fix a lot of the other comments raised in the pull requests
This commit is contained in:
parent
06bbf5c948
commit
39348feff1
@ -17,8 +17,9 @@
|
||||
:value="filter.value"
|
||||
:true-value="true"
|
||||
:false-value="false"
|
||||
@change="$emit('input', filters)"
|
||||
@change="emitFiltersOptions"
|
||||
>
|
||||
<!-- @change="$emit('change', filters)" -->
|
||||
</v-checkbox>
|
||||
</v-form>
|
||||
</v-expansion-panel-content>
|
||||
@ -38,17 +39,16 @@ interface FilterItem {
|
||||
|
||||
export default Vue.extend({
|
||||
props: {
|
||||
value: {
|
||||
collectionInfoItem: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedFilters: this.value,
|
||||
filters: {
|
||||
filters: {
|
||||
header: this.$t('filters'),
|
||||
status: {
|
||||
header: this.$t('status'),
|
||||
items: [
|
||||
{ label: this.$t('played'), value: 'IsPlayed', selected: false },
|
||||
{
|
||||
@ -119,74 +119,151 @@ export default Vue.extend({
|
||||
header: this.$t('years'),
|
||||
items: [] as FilterItem[]
|
||||
}
|
||||
}
|
||||
},
|
||||
selectedFilters: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
itemType() {
|
||||
if (this.collectionInfoItem.CollectionType === 'tvshows') {
|
||||
return 'Series';
|
||||
} else if (this.collectionInfoItem.CollectionType === 'movies') {
|
||||
return 'Movie';
|
||||
} else if (this.collectionInfoItem.CollectionType === 'books') {
|
||||
return 'Book';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getFilters() {
|
||||
try {
|
||||
const collectionInfo = await this.$api.items.getItems({
|
||||
uId: this.$auth.user.Id,
|
||||
userId: this.$auth.user.Id,
|
||||
ids: this.$route.params.viewId
|
||||
});
|
||||
|
||||
const options = {
|
||||
userId: this.$auth.user.Id,
|
||||
parentId: this.$route.params.viewId,
|
||||
includeItemTypes: ''
|
||||
};
|
||||
|
||||
if (!collectionInfo.data.Items) {
|
||||
return;
|
||||
}
|
||||
if (collectionInfo.data.Items) {
|
||||
options.includeItemTypes = 'sike';
|
||||
}
|
||||
if (collectionInfo.data.Items[0].CollectionType === 'tvshows') {
|
||||
options.includeItemTypes = 'Series';
|
||||
} else if (collectionInfo.data.Items[0].CollectionType === 'movies') {
|
||||
options.includeItemTypes = 'Movie';
|
||||
} else if (collectionInfo.data.Items[0].CollectionType === 'books') {
|
||||
options.includeItemTypes = 'Book';
|
||||
}
|
||||
|
||||
const result = await this.$api.filter.getQueryFiltersLegacy(options);
|
||||
if (!result.data.Genres) {
|
||||
if (this.itemType === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.filters.genres.items = result.data.Genres.map((x) => ({
|
||||
label: x,
|
||||
value: x,
|
||||
selected: false
|
||||
}));
|
||||
const response = (
|
||||
await this.$api.filter.getQueryFiltersLegacy({
|
||||
userId: this.$auth.user.Id,
|
||||
parentId: this.$route.params.viewId,
|
||||
includeItemTypes: this.itemType
|
||||
})
|
||||
).data;
|
||||
|
||||
if (!result.data.OfficialRatings) {
|
||||
return;
|
||||
}
|
||||
this.filters.officialRatings.items = result.data.OfficialRatings.map(
|
||||
(x) => ({
|
||||
if (response.Genres) {
|
||||
this.filters.genres.items = response.Genres.map((x) => ({
|
||||
label: x,
|
||||
value: x,
|
||||
selected: false
|
||||
})
|
||||
);
|
||||
|
||||
if (!result.data.Years) {
|
||||
return;
|
||||
}));
|
||||
}
|
||||
|
||||
if (response.OfficialRatings) {
|
||||
this.filters.officialRatings.items = response.OfficialRatings.map(
|
||||
(x) => ({
|
||||
label: x,
|
||||
value: x,
|
||||
selected: false
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (response.Years) {
|
||||
this.filters.years.items = response.Years.map((x) => ({
|
||||
label: x.toString(),
|
||||
value: x.toString(),
|
||||
selected: false
|
||||
}));
|
||||
}
|
||||
this.filters.years.items = result.data.Years.map((x) => ({
|
||||
label: x.toString(),
|
||||
value: x.toString(),
|
||||
selected: false
|
||||
}));
|
||||
} catch (error) {
|
||||
this.$nuxt.error({
|
||||
statusCode: 404,
|
||||
message: this.$t('filtersNotFound') as string
|
||||
});
|
||||
}
|
||||
},
|
||||
emitFiltersOptions() {
|
||||
try {
|
||||
if (
|
||||
this.collectionInfoItem !== {} &&
|
||||
(this.collectionInfoItem.Type === 'CollectionFolder' ||
|
||||
this.collectionInfoItem.Type === 'Folder')
|
||||
) {
|
||||
const options: any = {
|
||||
uId: this.$auth.user.Id,
|
||||
userId: this.$auth.user.Id,
|
||||
parentId: this.$route.params.viewId,
|
||||
includeItemTypes: this.itemType,
|
||||
recursive: true
|
||||
};
|
||||
|
||||
options.filters = this.makeFilterString(
|
||||
this.filters.status.items,
|
||||
','
|
||||
);
|
||||
|
||||
for (const feature of this.filters.features.items) {
|
||||
if (!feature.selected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
options[feature.value] = true;
|
||||
}
|
||||
|
||||
options.genres = this.makeFilterString(
|
||||
this.filters.genres.items,
|
||||
'|'
|
||||
);
|
||||
|
||||
options.officialRatings = this.makeFilterString(
|
||||
this.filters.officialRatings.items,
|
||||
'|'
|
||||
);
|
||||
|
||||
let videoTypeString = '';
|
||||
for (const videoType of this.filters.videoTypes.items) {
|
||||
if (!videoType.selected) {
|
||||
continue;
|
||||
}
|
||||
if (videoType.label === 'SD') {
|
||||
options.isHd = false;
|
||||
continue;
|
||||
}
|
||||
if (videoType.label === 'HD') {
|
||||
options.isHd = true;
|
||||
continue;
|
||||
}
|
||||
if (videoType.label === '4K' || videoType.label === '3D') {
|
||||
options[videoType.value] = true;
|
||||
} else {
|
||||
if (videoTypeString.length > 0) {
|
||||
videoTypeString += ',';
|
||||
}
|
||||
videoTypeString += videoType.value;
|
||||
}
|
||||
}
|
||||
options.videoTypes = videoTypeString;
|
||||
|
||||
options.years = this.makeFilterString(this.filters.years.items, ',');
|
||||
|
||||
this.$emit('change', options);
|
||||
}
|
||||
} catch (error) {
|
||||
this.$emit('change', error);
|
||||
}
|
||||
},
|
||||
makeFilterString(filterList: FilterItem[], seperator: string) {
|
||||
let filterString = '';
|
||||
for (const filter of filterList) {
|
||||
if (!filter.selected) {
|
||||
continue;
|
||||
}
|
||||
if (filterString.length > 0) {
|
||||
filterString += seperator;
|
||||
}
|
||||
filterString += filter.value;
|
||||
}
|
||||
return filterString;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -33,7 +33,7 @@
|
||||
"unexpectedError": "Unexpected error",
|
||||
"upNext": "Up next",
|
||||
"filtersNotFound": "Unable to load filters",
|
||||
"filters": "Filters",
|
||||
"status": "Status",
|
||||
"played": "Played",
|
||||
"unplayed": "Unplayed",
|
||||
"resumable": "Resumable",
|
||||
|
@ -32,7 +32,7 @@
|
||||
"endDate": "Sluttdato",
|
||||
"releaseDate": "Slippdato",
|
||||
"alphabetically": "Alfabetisk",
|
||||
"filters": "Filtere",
|
||||
"status": "Status",
|
||||
"played": "Avspilt",
|
||||
"unplayed": "Uspilt",
|
||||
"resumable": "Gjenopptakbar",
|
||||
|
@ -19,7 +19,10 @@
|
||||
</v-col>
|
||||
|
||||
<v-col>
|
||||
<filter-button v-model="allFilters" @input="filterMedia()" />
|
||||
<filter-button
|
||||
:collection-info-item="collectionInfoItem"
|
||||
@change="filterMedia"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="!loaded">
|
||||
@ -64,12 +67,6 @@ import Vue from 'vue';
|
||||
import { chunk } from 'lodash';
|
||||
import { BaseItemDto } from '~/api/api';
|
||||
|
||||
interface FilterItem {
|
||||
label: string;
|
||||
value: string;
|
||||
selected: boolean;
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
@ -83,32 +80,6 @@ export default Vue.extend({
|
||||
],
|
||||
orderMethod: 'SortName',
|
||||
sortDirection: true,
|
||||
allFilters: {
|
||||
filters: {
|
||||
header: '',
|
||||
items: [] as FilterItem[]
|
||||
},
|
||||
features: {
|
||||
header: '',
|
||||
items: [] as FilterItem[]
|
||||
},
|
||||
genres: {
|
||||
header: '',
|
||||
items: [] as FilterItem[]
|
||||
},
|
||||
officialRatings: {
|
||||
header: '',
|
||||
items: [] as FilterItem[]
|
||||
},
|
||||
videoTypes: {
|
||||
header: '',
|
||||
items: [] as FilterItem[]
|
||||
},
|
||||
years: {
|
||||
header: '',
|
||||
items: [] as FilterItem[]
|
||||
}
|
||||
},
|
||||
collectionInfoItem: {}
|
||||
};
|
||||
},
|
||||
@ -201,104 +172,19 @@ export default Vue.extend({
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async filterMedia() {
|
||||
async filterMedia(options: any) {
|
||||
try {
|
||||
const collectionInfo = await this.$api.items.getItems({
|
||||
uId: this.$auth.user.Id,
|
||||
userId: this.$auth.user.Id,
|
||||
ids: this.$route.params.viewId
|
||||
});
|
||||
options.sortBy = this.orderMethod;
|
||||
options.sortOrder = this.sortDirection;
|
||||
options.fields = this.orderMethod;
|
||||
|
||||
if (
|
||||
collectionInfo.data.Items &&
|
||||
(collectionInfo.data.Items[0].Type === 'CollectionFolder' ||
|
||||
collectionInfo.data.Items[0].Type === 'Folder')
|
||||
) {
|
||||
const options: any = {
|
||||
uId: this.$auth.user.Id,
|
||||
userId: this.$auth.user.Id,
|
||||
parentId: this.$route.params.viewId,
|
||||
includeItemTypes: '',
|
||||
recursive: true,
|
||||
sortBy: this.orderMethod,
|
||||
sortOrder: this.sortDirection,
|
||||
fields: this.orderMethod
|
||||
};
|
||||
const itemsResponse = await this.$api.items.getItems(options);
|
||||
|
||||
if (collectionInfo.data.Items[0].CollectionType === 'tvshows') {
|
||||
options.includeItemTypes = 'Series';
|
||||
} else if (collectionInfo.data.Items[0].CollectionType === 'movies') {
|
||||
options.includeItemTypes = 'Movie';
|
||||
} else if (collectionInfo.data.Items[0].CollectionType === 'books') {
|
||||
options.includeItemTypes = 'Book';
|
||||
}
|
||||
|
||||
const filterString = this.makeFilterString(
|
||||
this.allFilters.filters.items,
|
||||
','
|
||||
);
|
||||
options.filters = filterString;
|
||||
|
||||
for (let i = 0; i < this.allFilters.features.items.length; i++) {
|
||||
const feature = this.allFilters.features.items[i];
|
||||
if (!feature.selected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
options[feature.value] = true;
|
||||
}
|
||||
|
||||
const genreString = this.makeFilterString(
|
||||
this.allFilters.genres.items,
|
||||
'|'
|
||||
);
|
||||
options.genres = genreString;
|
||||
|
||||
const ratingString = this.makeFilterString(
|
||||
this.allFilters.officialRatings.items,
|
||||
'|'
|
||||
);
|
||||
options.officialRatings = ratingString;
|
||||
|
||||
let videoTypeString = '';
|
||||
for (let i = 0; i < this.allFilters.videoTypes.items.length; i++) {
|
||||
const videoType = this.allFilters.videoTypes.items[i];
|
||||
if (!videoType.selected) {
|
||||
continue;
|
||||
}
|
||||
if (videoType.label === 'SD') {
|
||||
options.isHd = false;
|
||||
continue;
|
||||
}
|
||||
if (videoType.label === 'HD') {
|
||||
options.isHd = true;
|
||||
continue;
|
||||
}
|
||||
if (videoType.label === '4K' || videoType.label === '3D') {
|
||||
options[videoType.value] = true;
|
||||
} else {
|
||||
if (videoTypeString.length > 0) {
|
||||
videoTypeString += ',';
|
||||
}
|
||||
videoTypeString += videoType.value;
|
||||
}
|
||||
}
|
||||
options.videoTypes = videoTypeString;
|
||||
|
||||
const yearString = this.makeFilterString(
|
||||
this.allFilters.years.items,
|
||||
','
|
||||
);
|
||||
options.years = yearString;
|
||||
|
||||
const itemsResponse = await this.$api.items.getItems(options);
|
||||
|
||||
if (itemsResponse.data) {
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
this.items = itemsResponse.data.Items || [];
|
||||
if (itemsResponse.data) {
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
this.items = itemsResponse.data.Items || [];
|
||||
} catch (error) {
|
||||
// Can't get given library ID
|
||||
this.$nuxt.error({
|
||||
@ -307,21 +193,6 @@ export default Vue.extend({
|
||||
});
|
||||
}
|
||||
},
|
||||
makeFilterString(filterList: FilterItem[], seperator: string) {
|
||||
let filterString = '';
|
||||
for (let i = 0; i < filterList.length; i++) {
|
||||
const filter = filterList[i];
|
||||
if (!filter.selected) {
|
||||
continue;
|
||||
}
|
||||
if (filterString.length > 0) {
|
||||
filterString += seperator;
|
||||
}
|
||||
filterString += filter.value;
|
||||
}
|
||||
return filterString;
|
||||
},
|
||||
|
||||
sortItems() {
|
||||
if (this.sortDirection) {
|
||||
this.items.sort((a, b) =>
|
||||
|
Loading…
x
Reference in New Issue
Block a user