diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/screens/Settings/ThreadPreferences.tsx | 6 | ||||
-rw-r--r-- | src/state/queries/post-thread.ts | 21 | ||||
-rw-r--r-- | src/state/queries/preferences/const.ts | 2 | ||||
-rw-r--r-- | src/state/queries/preferences/types.ts | 2 |
4 files changed, 28 insertions, 3 deletions
diff --git a/src/screens/Settings/ThreadPreferences.tsx b/src/screens/Settings/ThreadPreferences.tsx index c27cea7de..d29daa58b 100644 --- a/src/screens/Settings/ThreadPreferences.tsx +++ b/src/screens/Settings/ThreadPreferences.tsx @@ -56,6 +56,12 @@ export function ThreadPreferencesScreen({}: Props) { values={sortReplies ? [sortReplies] : []} onChange={values => setThreadViewPrefs({sort: values[0]})}> <View style={[a.gap_sm, a.flex_1]}> + <Toggle.Item name="hotness" label={_(msg`Hot replies first`)}> + <Toggle.Radio /> + <Toggle.LabelText> + <Trans>Hot replies first</Trans> + </Toggle.LabelText> + </Toggle.Item> <Toggle.Item name="oldest" label={_(msg`Oldest replies first`)}> diff --git a/src/state/queries/post-thread.ts b/src/state/queries/post-thread.ts index 93e3a5c3b..4784a9d75 100644 --- a/src/state/queries/post-thread.ts +++ b/src/state/queries/post-thread.ts @@ -237,7 +237,11 @@ export function sortThread( } } - if (opts.sort === 'oldest') { + if (opts.sort === 'hotness') { + const aHotness = getHotness(a.post) + const bHotness = getHotness(b.post) + return bHotness - aHotness + } else if (opts.sort === 'oldest') { return a.post.indexedAt.localeCompare(b.post.indexedAt) } else if (opts.sort === 'newest') { return b.post.indexedAt.localeCompare(a.post.indexedAt) @@ -269,6 +273,21 @@ export function sortThread( // internal methods // = +// Inspired by https://join-lemmy.org/docs/contributors/07-ranking-algo.html +// We want to give recent comments a real chance (and not bury them deep below the fold) +// while also surfacing well-liked comments from the past. In the future, we can explore +// something more sophisticated, but we don't have much data on the client right now. +function getHotness(post: AppBskyFeedDefs.PostView) { + const hoursAgo = + (new Date().getTime() - new Date(post.indexedAt).getTime()) / + (1000 * 60 * 60) + const likeCount = post.likeCount ?? 0 + const likeOrder = Math.log(3 + likeCount) + const timePenaltyExponent = 1.5 + 1.5 / (1 + Math.log(1 + likeCount)) + const timePenalty = Math.pow(hoursAgo + 2, timePenaltyExponent) + return likeOrder / timePenalty +} + function responseToThreadNodes( node: ThreadViewNode, depth = 0, diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts index e07f40ec5..549f7ce29 100644 --- a/src/state/queries/preferences/const.ts +++ b/src/state/queries/preferences/const.ts @@ -15,7 +15,7 @@ export const DEFAULT_HOME_FEED_PREFS: UsePreferencesQueryResponse['feedViewPrefs } export const DEFAULT_THREAD_VIEW_PREFS: ThreadViewPreferences = { - sort: 'newest', + sort: 'hotness', prioritizeFollowedUsers: true, lab_treeViewEnabled: false, } diff --git a/src/state/queries/preferences/types.ts b/src/state/queries/preferences/types.ts index 928bb90da..8f523fcf2 100644 --- a/src/state/queries/preferences/types.ts +++ b/src/state/queries/preferences/types.ts @@ -22,6 +22,6 @@ export type ThreadViewPreferences = Pick< BskyThreadViewPreference, 'prioritizeFollowedUsers' > & { - sort: 'oldest' | 'newest' | 'most-likes' | 'random' | string + sort: 'hotness' | 'oldest' | 'newest' | 'most-likes' | 'random' | string lab_treeViewEnabled?: boolean } |