diff options
author | Zero~Informatique | 2020-09-12 22:33:37 +0200 |
---|---|---|
committer | G.Fouet | 2020-09-12 23:19:44 +0200 |
commit | b909ec093591b50950c0de54b2005d471ca28116 (patch) | |
tree | 6fe72175022d4e39a44e9270865f611d2e819b05 | |
parent | 96ed5e6583a7f03d4ea7fa0512e66fffb656cc6e (diff) | |
download | ldgallery-b909ec093591b50950c0de54b2005d471ca28116.tar.gz |
viewer: make default sort order configurable. code review improvements
github: resolves #239
-rw-r--r-- | example/config.json | 2 | ||||
-rw-r--r-- | viewer/src/@types/gallery.d.ts | 2 | ||||
-rw-r--r-- | viewer/src/components/LdCommandSort.vue | 28 | ||||
-rw-r--r-- | viewer/src/services/itemComparators.ts | 10 | ||||
-rw-r--r-- | viewer/src/store/uiStore.ts | 15 |
5 files changed, 26 insertions, 31 deletions
diff --git a/example/config.json b/example/config.json index 892682f..cd08b25 100644 --- a/example/config.json +++ b/example/config.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "galleryRoot": "out/", | 2 | "galleryRoot": "out/", |
3 | "galleryIndex": "index.json", | 3 | "galleryIndex": "index.json", |
4 | "initialSort": "date_desc", | 4 | "initialItemSort": "date_desc", |
5 | "initialTagDisplayLimit": 10 | 5 | "initialTagDisplayLimit": 10 |
6 | } | 6 | } |
diff --git a/viewer/src/@types/gallery.d.ts b/viewer/src/@types/gallery.d.ts index 8ef8fc7..a7f3d29 100644 --- a/viewer/src/@types/gallery.d.ts +++ b/viewer/src/@types/gallery.d.ts | |||
@@ -23,7 +23,7 @@ declare namespace Gallery { | |||
23 | interface Config { | 23 | interface Config { |
24 | galleryRoot: string; | 24 | galleryRoot: string; |
25 | galleryIndex?: string; | 25 | galleryIndex?: string; |
26 | initialSort?: ItemSortStr; | 26 | initialItemSort?: ItemSortStr; |
27 | initialTagDisplayLimit?: number; | 27 | initialTagDisplayLimit?: number; |
28 | } | 28 | } |
29 | 29 | ||
diff --git a/viewer/src/components/LdCommandSort.vue b/viewer/src/components/LdCommandSort.vue index a412afc..30644c1 100644 --- a/viewer/src/components/LdCommandSort.vue +++ b/viewer/src/components/LdCommandSort.vue | |||
@@ -19,42 +19,32 @@ | |||
19 | --> | 19 | --> |
20 | 20 | ||
21 | <template> | 21 | <template> |
22 | <b-dropdown v-model="selectedSort" :mobile-modal="false" append-to-body @change="onChangeSort"> | 22 | <b-dropdown v-model="selectedSort" :mobile-modal="false" append-to-body> |
23 | <a slot="trigger" class="link"> | 23 | <a slot="trigger" class="link"> |
24 | <fa-icon icon="sort-amount-down" size="lg" /> | 24 | <fa-icon icon="sort-amount-down" size="lg" /> |
25 | </a> | 25 | </a> |
26 | <b-dropdown-item v-for="(sort, idx) in SORTS" :key="idx" :value="idx"> | 26 | <b-dropdown-item v-for="(sort, idx) in ITEM_SORTS" :key="idx" :value="idx"> |
27 | <fa-icon :icon="['far', idx === selectedSort ? 'dot-circle' : 'circle']" /> | 27 | <fa-icon :icon="['far', idx === selectedSort ? 'dot-circle' : 'circle']" /> |
28 | <span :class="$style.dropdownLabel">{{ sort.name }}</span> | 28 | <span :class="$style.dropdownLabel">{{ sort.text }}</span> |
29 | </b-dropdown-item> | 29 | </b-dropdown-item> |
30 | </b-dropdown> | 30 | </b-dropdown> |
31 | </template> | 31 | </template> |
32 | 32 | ||
33 | <script lang="ts"> | 33 | <script lang="ts"> |
34 | import { Component, Vue, Prop, Watch } from "vue-property-decorator"; | 34 | import { Component, Vue, Prop } from "vue-property-decorator"; |
35 | import { RawLocation } from "vue-router"; | 35 | import { RawLocation } from "vue-router"; |
36 | import ItemComparators, { ItemComparator } from "@/services/itemComparators"; | 36 | import ItemComparators, { ItemComparator } from "@/services/itemComparators"; |
37 | 37 | ||
38 | @Component | 38 | @Component |
39 | export default class LdCommandSort extends Vue { | 39 | export default class LdCommandSort extends Vue { |
40 | readonly SORTS = [ | 40 | readonly ITEM_SORTS = ItemComparators.ITEM_SORTS; |
41 | { name: this.$t("command.sort.byNameAsc"), fn: ItemComparators.sortByNameAsc }, | ||
42 | { name: this.$t("command.sort.byDateDesc"), fn: ItemComparators.sortByDateDesc }, | ||
43 | ]; | ||
44 | 41 | ||
45 | selectedSort = 0; | 42 | get selectedSort() { |
46 | 43 | return this.ITEM_SORTS.map(s => s.fn).indexOf(this.$uiStore.sortFn); | |
47 | created() { | ||
48 | this.onChangeStore(this.$uiStore.sortFn); | ||
49 | } | ||
50 | |||
51 | @Watch("$uiStore.sortFn") | ||
52 | onChangeStore(newFn: ItemComparator) { | ||
53 | this.selectedSort = this.SORTS.map(s => s.fn).indexOf(newFn); | ||
54 | } | 44 | } |
55 | 45 | ||
56 | onChangeSort(newValue: number) { | 46 | set selectedSort(newValue: number) { |
57 | this.$uiStore.setSortFn(this.SORTS[newValue].fn); | 47 | this.$uiStore.setSortFn(this.ITEM_SORTS[newValue].fn); |
58 | } | 48 | } |
59 | } | 49 | } |
60 | </script> | 50 | </script> |
diff --git a/viewer/src/services/itemComparators.ts b/viewer/src/services/itemComparators.ts index c8fedbe..380c66a 100644 --- a/viewer/src/services/itemComparators.ts +++ b/viewer/src/services/itemComparators.ts | |||
@@ -16,10 +16,20 @@ | |||
16 | -- You should have received a copy of the GNU Affero General Public License | 16 | -- You should have received a copy of the GNU Affero General Public License |
17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. | 17 | -- along with this program. If not, see <https://www.gnu.org/licenses/>. |
18 | */ | 18 | */ |
19 | import { TranslateResult } from "vue-i18n"; | ||
20 | import i18n from "@/plugins/i18n"; | ||
19 | 21 | ||
20 | export type ItemComparator = (left: Gallery.Item, right: Gallery.Item) => number; | 22 | export type ItemComparator = (left: Gallery.Item, right: Gallery.Item) => number; |
23 | export type ItemSort = { name: Gallery.ItemSortStr; text: TranslateResult; fn: ItemComparator }; | ||
21 | 24 | ||
22 | export default class ItemComparators { | 25 | export default class ItemComparators { |
26 | static readonly DEFAULT = ItemComparators.sortByNameAsc; | ||
27 | |||
28 | static readonly ITEM_SORTS: ItemSort[] = [ | ||
29 | { name: "name_asc", text: i18n.t("command.sort.byNameAsc"), fn: ItemComparators.sortByNameAsc }, | ||
30 | { name: "date_desc", text: i18n.t("command.sort.byDateDesc"), fn: ItemComparators.sortByDateDesc }, | ||
31 | ]; | ||
32 | |||
23 | static sortByNameAsc(left: Gallery.Item, right: Gallery.Item): number { | 33 | static sortByNameAsc(left: Gallery.Item, right: Gallery.Item): number { |
24 | return left.title.localeCompare(right.title); | 34 | return left.title.localeCompare(right.title); |
25 | } | 35 | } |
diff --git a/viewer/src/store/uiStore.ts b/viewer/src/store/uiStore.ts index 04f14a0..84e7fed 100644 --- a/viewer/src/store/uiStore.ts +++ b/viewer/src/store/uiStore.ts | |||
@@ -29,7 +29,7 @@ export default class UIStore extends VuexModule { | |||
29 | fullscreen: boolean = false; | 29 | fullscreen: boolean = false; |
30 | fullWidth: boolean = window.innerWidth < Number(process.env.VUE_APP_FULLWIDTH_LIMIT); | 30 | fullWidth: boolean = window.innerWidth < Number(process.env.VUE_APP_FULLWIDTH_LIMIT); |
31 | searchMode: boolean = false; | 31 | searchMode: boolean = false; |
32 | sortFn: ItemComparator = ItemComparators.sortByNameAsc; | 32 | sortFn: ItemComparator = ItemComparators.DEFAULT; |
33 | 33 | ||
34 | // --- | 34 | // --- |
35 | 35 | ||
@@ -50,15 +50,10 @@ export default class UIStore extends VuexModule { | |||
50 | } | 50 | } |
51 | 51 | ||
52 | @action async initFromConfig(config: Gallery.Config) { | 52 | @action async initFromConfig(config: Gallery.Config) { |
53 | switch (config.initialSort ?? "") { | 53 | if (config.initialItemSort) { |
54 | case "date_desc": | 54 | const itemSort = ItemComparators.ITEM_SORTS.find(s => s.name == config.initialItemSort); |
55 | this.setSortFn(ItemComparators.sortByDateDesc); | 55 | if (itemSort) this.setSortFn(itemSort.fn); |
56 | break; | 56 | else throw new Error("Unknown sort type: " + config.initialItemSort); |
57 | case "name_asc": | ||
58 | case "": | ||
59 | break; | ||
60 | default: | ||
61 | throw new Error("Unknown sort type: " + config.initialSort); | ||
62 | } | 57 | } |
63 | } | 58 | } |
64 | } | 59 | } |