Skip to content

Commit 398b071

Browse files
authored
Merge pull request #12870 from notbakaneko/feature/move-sort-discussions-state
Move discussion sort state into discussions state
2 parents 9d05813 + 6fa5680 commit 398b071

File tree

3 files changed

+63
-56
lines changed

3 files changed

+63
-56
lines changed

resources/js/beatmap-discussions/discussions-state.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { parseJsonNullable, storeJson } from 'utils/json';
1919
import { Filter, filters } from './current-discussions';
2020
import DiscussionMode, { discussionModes } from './discussion-mode';
2121
import DiscussionPage, { isDiscussionPage } from './discussion-page';
22+
import Sort from './sort';
2223

2324
const defaultFilterPraise = new Set<BeatmapsetStatus>(['approved', 'ranked']);
2425
const jsonId = 'json-discussions-state';
@@ -69,6 +70,12 @@ export default class DiscussionsState {
6970
@observable selectedNominatedRulesets: Ruleset[] = [];
7071
@observable selectedUserId: number | null = null;
7172
@observable showDeleted = true; // this toggle only affects All and deleted discussion filters, other filters don't show deleted
73+
@observable sort: Record<DiscussionMode, Sort> = {
74+
general: 'updated_at',
75+
generalAll: 'updated_at',
76+
reviews: 'updated_at',
77+
timeline: 'timeline',
78+
};
7279

7380
private previousFilter: Filter = 'total';
7481
private previousPage: DiscussionPage = 'general';
@@ -87,6 +94,13 @@ export default class DiscussionsState {
8794
return beatmap;
8895
}
8996

97+
@computed
98+
get currentSort() {
99+
return this.currentPage === 'events'
100+
? 'timeline' // returning any valid mode is fine.
101+
: this.sort[this.currentPage];
102+
}
103+
90104
/**
91105
* Discussions for the current beatmap grouped by filters
92106
*/

resources/js/beatmap-discussions/discussions.tsx

Lines changed: 7 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,81 +4,32 @@
44
import IconExpand from 'components/icon-expand';
55
import BeatmapsetDiscussionJson, { BeatmapsetDiscussionJsonForShow } from 'interfaces/beatmapset-discussion-json';
66
import BeatmapsetDiscussionsStore from 'interfaces/beatmapset-discussions-store';
7-
import { action, computed, makeObservable, observable } from 'mobx';
7+
import { action, computed, makeObservable } from 'mobx';
88
import { observer } from 'mobx-react';
99
import * as React from 'react';
1010
import { canModeratePosts } from 'utils/beatmapset-discussion-helper';
1111
import { classWithModifiers } from 'utils/css';
1212
import { trans } from 'utils/lang';
1313
import { Discussion } from './discussion';
14-
import DiscussionMode from './discussion-mode';
1514
import DiscussionsState from './discussions-state';
15+
import Sort, { sortPresets } from './sort';
1616

1717
const bn = 'beatmap-discussions';
1818

19-
const sortPresets = {
20-
created_at: {
21-
sort(a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) {
22-
return a.created_at === b.created_at
23-
? a.id - b.id
24-
: Date.parse(a.created_at) - Date.parse(b.created_at);
25-
},
26-
text: trans('beatmaps.discussions.sort.created_at'),
27-
},
28-
// there's obviously no timeline field
29-
timeline: {
30-
sort(a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) {
31-
// TODO: this shouldn't be called when not timeline, anyway.
32-
if (a.timestamp == null || b.timestamp == null) {
33-
return 0;
34-
}
35-
36-
return a.timestamp === b.timestamp
37-
? a.id - b.id
38-
: a.timestamp - b.timestamp;
39-
},
40-
text: trans('beatmaps.discussions.sort.timeline'),
41-
},
42-
updated_at: {
43-
sort(a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) {
44-
return a.last_post_at === b.last_post_at
45-
? b.id - a.id
46-
: Date.parse(b.last_post_at) - Date.parse(a.last_post_at);
47-
},
48-
text: trans('beatmaps.discussions.sort.updated_at'),
49-
},
50-
};
51-
52-
type Sort = 'created_at' | 'updated_at' | 'timeline';
53-
5419
interface Props {
5520
discussionsState: DiscussionsState;
5621
store: BeatmapsetDiscussionsStore;
5722
}
5823

5924
@observer
6025
export class Discussions extends React.Component<Props> {
61-
@observable private sort: Record<DiscussionMode, Sort> = {
62-
general: 'updated_at',
63-
generalAll: 'updated_at',
64-
reviews: 'updated_at',
65-
timeline: 'timeline',
66-
};
67-
68-
@computed
69-
private get currentSort() {
70-
return this.discussionsState.currentPage === 'events'
71-
? 'timeline' // returning any valid mode is fine.
72-
: this.sort[this.discussionsState.currentPage];
73-
}
74-
7526
private get discussionsState() {
7627
return this.props.discussionsState;
7728
}
7829

7930
@computed
8031
private get isTimelineVisible() {
81-
return this.discussionsState.currentPage === 'timeline' && this.currentSort === 'timeline';
32+
return this.discussionsState.currentPage === 'timeline' && this.discussionsState.currentSort === 'timeline';
8233
}
8334

8435
private get store() {
@@ -94,7 +45,7 @@ export class Discussions extends React.Component<Props> {
9445
return discussions.slice().sort((a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) => {
9546
const mapperNoteCompare =
9647
// no sticky for timeline sort
97-
this.currentSort !== 'timeline'
48+
this.discussionsState.currentSort !== 'timeline'
9849
// stick the mapper note
9950
&& [a.message_type, b.message_type].includes('mapper_note')
10051
// but if both are mapper note, do base comparison
@@ -103,7 +54,7 @@ export class Discussions extends React.Component<Props> {
10354
if (mapperNoteCompare) {
10455
return a.message_type === 'mapper_note' ? -1 : 1;
10556
} else {
106-
return sortPresets[this.currentSort].sort(a, b);
57+
return sortPresets[this.discussionsState.currentSort].sort(a, b);
10758
}
10859
});
10960
}
@@ -139,7 +90,7 @@ export class Discussions extends React.Component<Props> {
13990
@action
14091
private readonly handleChangeSort = (e: React.SyntheticEvent<HTMLButtonElement>) => {
14192
if (this.discussionsState.currentPage === 'events') return;
142-
this.sort[this.discussionsState.currentPage] = e.currentTarget.dataset.sortPreset as Sort;
93+
this.discussionsState.sort[this.discussionsState.currentPage] = e.currentTarget.dataset.sortPreset as Sort;
14394
};
14495

14596
@action
@@ -237,7 +188,7 @@ export class Discussions extends React.Component<Props> {
237188
{presets.map((preset) => (
238189
<button
239190
key={preset}
240-
className={classWithModifiers('sort__item', 'button', { active: this.currentSort === preset })}
191+
className={classWithModifiers('sort__item', 'button', { active: this.discussionsState.currentSort === preset })}
241192
data-sort-preset={preset}
242193
onClick={this.handleChangeSort}
243194
type='button'
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
import BeatmapsetDiscussionJson from 'interfaces/beatmapset-discussion-json';
5+
import { trans } from 'utils/lang';
6+
7+
export const sortPresets = {
8+
created_at: {
9+
sort(a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) {
10+
return a.created_at === b.created_at
11+
? a.id - b.id
12+
: Date.parse(a.created_at) - Date.parse(b.created_at);
13+
},
14+
text: trans('beatmaps.discussions.sort.created_at'),
15+
},
16+
// there's obviously no timeline field
17+
timeline: {
18+
sort(a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) {
19+
// TODO: this shouldn't be called when not timeline, anyway.
20+
if (a.timestamp == null || b.timestamp == null) {
21+
return 0;
22+
}
23+
24+
return a.timestamp === b.timestamp
25+
? a.id - b.id
26+
: a.timestamp - b.timestamp;
27+
},
28+
text: trans('beatmaps.discussions.sort.timeline'),
29+
},
30+
updated_at: {
31+
sort(a: BeatmapsetDiscussionJson, b: BeatmapsetDiscussionJson) {
32+
return a.last_post_at === b.last_post_at
33+
? b.id - a.id
34+
: Date.parse(b.last_post_at) - Date.parse(a.last_post_at);
35+
},
36+
text: trans('beatmaps.discussions.sort.updated_at'),
37+
},
38+
};
39+
40+
type Sort = 'created_at' | 'updated_at' | 'timeline';
41+
42+
export default Sort;

0 commit comments

Comments
 (0)