Skip to content

Commit 0f8a9fd

Browse files
committed
feat: add option for sorting members by recent apperance
in addition to the existing option of sorting by number of appearances. Closes #87
1 parent 7a20a67 commit 0f8a9fd

9 files changed

Lines changed: 96 additions & 33 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added ✨
11+
12+
- Add option for sorting members by recent apperance in addition to the existing option of sorting by number of appearances. Closes [#87](https://github.com/Questionable-Content-Extensions/client/issues/87)
13+
1014
## [1.2.1] - 2023-09-22
1115

1216
### Fixed 🐛

src/components/ComicDetailsPanel/ComicDetailsPanel.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ export default function ComicDetailsPanel() {
276276
isLoading={isLoadingInitial}
277277
isFetching={isFetching}
278278
useColors={settings.useColors}
279+
orderMembersByLastAppearance={false}
279280
onSetCurrentComic={(c, locked) =>
280281
dispatch(setCurrentComic(c, { locked }))
281282
}
@@ -368,6 +369,9 @@ export default function ComicDetailsPanel() {
368369
}
369370
useColors={settings.useColors}
370371
editMode={settings.editMode}
372+
orderMembersByLastAppearance={
373+
settings.orderMembersByLastAppearance
374+
}
371375
onAddItem={(itemBody) => {
372376
addItem({
373377
token: settings.editModeToken,

src/components/ComicDetailsPanel/ItemNavigation/ItemNavigation.tsx

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default function ItemNavigation({
1515
isLoading,
1616
isFetching,
1717
useColors,
18+
orderMembersByLastAppearance,
1819
onSetCurrentComic,
1920
onShowInfoFor,
2021
mode,
@@ -27,6 +28,7 @@ export default function ItemNavigation({
2728
isLoading: boolean
2829
isFetching: boolean
2930
useColors: boolean
31+
orderMembersByLastAppearance: boolean
3032
onSetCurrentComic: (comicNo: ComicId, locked: boolean) => void
3133
onShowInfoFor: (item: ItemId) => void
3234
mode: PickEnum<
@@ -76,8 +78,16 @@ export default function ItemNavigation({
7678
location: location.map(itemNavigationToNavElement),
7779
storyline: storyline.map(itemNavigationToNavElement),
7880
locked: locked.map(itemNavigationToNavElement),
81+
all: itemNavigationData.map(itemNavigationToNavElement),
7982
}
80-
}, [cast, location, storyline, locked, itemNavigationToNavElement])
83+
}, [
84+
cast,
85+
location,
86+
storyline,
87+
locked,
88+
itemNavigationData,
89+
itemNavigationToNavElement,
90+
])
8191

8292
if (isLoading) {
8393
return (
@@ -98,42 +108,55 @@ export default function ItemNavigation({
98108
return <></>
99109
}
100110

101-
return (
102-
<div className="text-center">
103-
{!!itemNavElements.locked.length && (
104-
<ItemTypeSection
105-
header="Navigation Locked"
106-
isFetching={isFetching}
107-
mode={mode}
108-
elements={itemNavElements.locked}
109-
/>
110-
)}
111-
{!!itemNavElements.cast.length && (
112-
<ItemTypeSection
113-
header="Cast Members"
114-
isFetching={isFetching}
115-
mode={mode}
116-
elements={itemNavElements.cast}
117-
/>
118-
)}
119-
{!!itemNavElements.location.length && (
120-
<ItemTypeSection
121-
header="Locations"
122-
isFetching={isFetching}
123-
mode={mode}
124-
elements={itemNavElements.location}
125-
/>
126-
)}
127-
{!!itemNavElements.storyline.length && (
111+
if (!orderMembersByLastAppearance) {
112+
return (
113+
<div className="text-center">
114+
{!!itemNavElements.locked.length && (
115+
<ItemTypeSection
116+
header="Navigation Locked"
117+
isFetching={isFetching}
118+
mode={mode}
119+
elements={itemNavElements.locked}
120+
/>
121+
)}
122+
{!!itemNavElements.cast.length && (
123+
<ItemTypeSection
124+
header="Cast Members"
125+
isFetching={isFetching}
126+
mode={mode}
127+
elements={itemNavElements.cast}
128+
/>
129+
)}
130+
{!!itemNavElements.location.length && (
131+
<ItemTypeSection
132+
header="Locations"
133+
isFetching={isFetching}
134+
mode={mode}
135+
elements={itemNavElements.location}
136+
/>
137+
)}
138+
{!!itemNavElements.storyline.length && (
139+
<ItemTypeSection
140+
header="Storylines"
141+
isFetching={isFetching}
142+
mode={mode}
143+
elements={itemNavElements.storyline}
144+
/>
145+
)}
146+
</div>
147+
)
148+
} else {
149+
return (
150+
<div className="text-center">
128151
<ItemTypeSection
129-
header="Storylines"
152+
header="Recent"
130153
isFetching={isFetching}
131154
mode={mode}
132-
elements={itemNavElements.storyline}
155+
elements={itemNavElements.all}
133156
/>
134-
)}
135-
</div>
136-
)
157+
</div>
158+
)
159+
}
137160
}
138161

139162
function ItemTypeSection({

src/components/FilteredNavigationData/FilteredNavigationData.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default function FilteredNavigationData({
2424
onSetCurrentComic,
2525
onShowInfoFor,
2626
useColors,
27+
orderMembersByLastAppearance,
2728
editMode,
2829
onAddItem,
2930
}: {
@@ -35,6 +36,7 @@ export default function FilteredNavigationData({
3536
onSetCurrentComic: (comicId: ComicId) => void
3637
onShowInfoFor: (item: ItemId) => void
3738
useColors: boolean
39+
orderMembersByLastAppearance: boolean
3840
editMode: boolean
3941
onAddItem: (item: ItemBody) => void
4042
}) {
@@ -80,6 +82,9 @@ export default function FilteredNavigationData({
8082
isLoading={isLoading}
8183
isFetching={isFetching}
8284
useColors={useColors}
85+
orderMembersByLastAppearance={
86+
orderMembersByLastAppearance
87+
}
8388
onSetCurrentComic={onSetCurrentComic}
8489
onShowInfoFor={onShowInfoFor}
8590
mode={NavElementMode.Missing}

src/components/SettingsDialog/SettingsPanel/SettingsPanel.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ export default function SettingsPanel({
3333
"treated like it's enabled, as an editor needs a list of all the cast to do their job effectively."
3434
}
3535
/>
36+
<ToggleSetting
37+
settings={settings}
38+
setting="orderMembersByLastAppearance"
39+
updateSettings={updateSettings}
40+
label="Order members by last appearance"
41+
description={
42+
"Ordinarily, members are ordered by how frequently they appear in the comic's strips. " +
43+
"By enabling this setting, they will instead be ordered by how recently they've appeared in the comic " +
44+
"relative to the currently viewed comic. This can be useful if you're an editor because the comic tends " +
45+
'to focus on a set of characters and locations in bulk, which makes finding them easier with this setting on.'
46+
}
47+
/>
3648
<ToggleSetting
3749
settings={settings}
3850
setting="skipNonCanon"

src/models/ByIdQuery.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
22
import type { Exclusion } from './Exclusion'
33
import type { Inclusion } from './Inclusion'
4+
import type { Sorting } from './Sorting'
45
import type { Token } from './Token'
56

67
export interface ByIdQuery {
78
token?: Token
89
exclude?: Exclusion
910
include?: Inclusion
11+
sorting?: Sorting
1012
}

src/models/Sorting.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2+
3+
export type Sorting = 'by-count' | 'by-last-appearance'

src/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface SettingValues {
2121
scrollToTop: boolean
2222

2323
showAllMembers: boolean
24+
orderMembersByLastAppearance: boolean
2425
useColors: boolean
2526
showItemRandomButton: boolean
2627
showItemChainButton: boolean
@@ -92,6 +93,7 @@ export class Settings {
9293
scrollToTop: true,
9394

9495
showAllMembers: false,
96+
orderMembersByLastAppearance: false,
9597
useColors: true,
9698
showItemRandomButton: false,
9799
showItemChainButton: false,

src/store/api/comicApiSlice.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export type GetDataQueryArgs = {
3030
skipGuest: boolean
3131
skipNonCanon: boolean
3232
showAllMembers: boolean
33+
orderMembersByLastAppearance: boolean
3334
}
3435

3536
export type GetExcludedQueryArgs = {
@@ -73,6 +74,7 @@ export const comicApiSlice = apiSlice.injectEndpoints({
7374
skipGuest,
7475
skipNonCanon,
7576
showAllMembers,
77+
orderMembersByLastAppearance,
7678
}) => {
7779
const urlParameters: ByIdQuery = {}
7880
if (editModeToken) {
@@ -86,6 +88,11 @@ export const comicApiSlice = apiSlice.injectEndpoints({
8688
if (showAllMembers || editModeToken) {
8789
urlParameters.include = 'all'
8890
}
91+
if (orderMembersByLastAppearance) {
92+
urlParameters.sorting = 'by-last-appearance'
93+
} else {
94+
urlParameters.sorting = 'by-count'
95+
}
8996
const urlQuery = new URLSearchParams(
9097
urlParameters as Record<string, string>
9198
).toString()
@@ -392,6 +399,7 @@ export function toGetDataQueryArgs(
392399
comic,
393400
editModeToken: settings.editMode ? settings.editModeToken : undefined,
394401
showAllMembers: settings.showAllMembers,
402+
orderMembersByLastAppearance: settings.orderMembersByLastAppearance,
395403
skipGuest: settings.skipGuest,
396404
skipNonCanon: settings.skipNonCanon,
397405
}

0 commit comments

Comments
 (0)