summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2020-02-09 11:44:24 -0500
committerDessalines <tyhou13@gmx.com>2020-02-09 11:44:24 -0500
commitfd8814677ec81eff5358c102b6b424ec1c23c2fb (patch)
treeb715aedaf6b06ccf6bcbb10c099c2d794b2c819c
parent56cd103209605471b27aa5a854cc3b051f2a65f5 (diff)
Live post and comment resorting. Fixes #522
- Moving sorting to utils.
-rw-r--r--ui/src/components/comment-node.tsx6
-rw-r--r--ui/src/components/comment-nodes.tsx19
-rw-r--r--ui/src/components/community.tsx12
-rw-r--r--ui/src/components/main.tsx9
-rw-r--r--ui/src/components/post-listings.tsx22
-rw-r--r--ui/src/components/post.tsx41
-rw-r--r--ui/src/utils.ts108
7 files changed, 164 insertions, 53 deletions
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index a67b1c35..0e511063 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -15,6 +15,8 @@ import {
TransferCommunityForm,
TransferSiteForm,
BanType,
+ CommentSortType,
+ SortType,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
import {
@@ -61,6 +63,8 @@ interface CommentNodeProps {
// TODO is this necessary, can't I get it from the node itself?
postCreatorId?: number;
showCommunity?: boolean;
+ sort?: CommentSortType;
+ sortType?: SortType;
}
export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
@@ -630,6 +634,8 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
moderators={this.props.moderators}
admins={this.props.admins}
postCreatorId={this.props.postCreatorId}
+ sort={this.props.sort}
+ sortType={this.props.sortType}
/>
)}
{/* A collapsed clearfix */}
diff --git a/ui/src/components/comment-nodes.tsx b/ui/src/components/comment-nodes.tsx
index fb700cc4..b15da520 100644
--- a/ui/src/components/comment-nodes.tsx
+++ b/ui/src/components/comment-nodes.tsx
@@ -3,7 +3,10 @@ import {
CommentNode as CommentNodeI,
CommunityUser,
UserView,
+ CommentSortType,
+ SortType,
} from '../interfaces';
+import { commentSort, commentSortSortType } from '../utils';
import { CommentNode } from './comment-node';
interface CommentNodesState {}
@@ -18,6 +21,8 @@ interface CommentNodesProps {
locked?: boolean;
markable?: boolean;
showCommunity?: boolean;
+ sort?: CommentSortType;
+ sortType?: SortType;
}
export class CommentNodes extends Component<
@@ -31,7 +36,7 @@ export class CommentNodes extends Component<
render() {
return (
<div className="comments">
- {this.props.nodes.map(node => (
+ {this.sorter().map(node => (
<CommentNode
node={node}
noIndent={this.props.noIndent}
@@ -42,9 +47,21 @@ export class CommentNodes extends Component<
postCreatorId={this.props.postCreatorId}
markable={this.props.markable}
showCommunity={this.props.showCommunity}
+ sort={this.props.sort}
+ sortType={this.props.sortType}
/>
))}
</div>
);
}
+
+ sorter(): Array<CommentNodeI> {
+ if (this.props.sort !== undefined) {
+ commentSort(this.props.nodes, this.props.sort);
+ } else if (this.props.sortType !== undefined) {
+ commentSortSortType(this.props.nodes, this.props.sortType);
+ }
+
+ return this.props.nodes;
+ }
}
diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx
index 32392ca1..e28c99bc 100644
--- a/ui/src/components/community.tsx
+++ b/ui/src/components/community.tsx
@@ -178,9 +178,17 @@ export class Community extends Component<any, State> {
listings() {
return this.state.dataType == DataType.Post ? (
- <PostListings posts={this.state.posts} removeDuplicates />
+ <PostListings
+ posts={this.state.posts}
+ removeDuplicates
+ sort={this.state.sort}
+ />
) : (
- <CommentNodes nodes={commentsToFlatNodes(this.state.comments)} noIndent />
+ <CommentNodes
+ nodes={commentsToFlatNodes(this.state.comments)}
+ noIndent
+ sortType={this.state.sort}
+ />
);
}
diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx
index 99b1618d..c8e132f7 100644
--- a/ui/src/components/main.tsx
+++ b/ui/src/components/main.tsx
@@ -51,6 +51,7 @@ import {
createPostLikeFindRes,
editPostFindRes,
commentsToFlatNodes,
+ commentSortSortType,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -404,12 +405,18 @@ export class Main extends Component<any, MainState> {
listings() {
return this.state.dataType == DataType.Post ? (
- <PostListings posts={this.state.posts} showCommunity removeDuplicates />
+ <PostListings
+ posts={this.state.posts}
+ showCommunity
+ removeDuplicates
+ sort={this.state.sort}
+ />
) : (
<CommentNodes
nodes={commentsToFlatNodes(this.state.comments)}
noIndent
showCommunity
+ sortType={this.state.sort}
/>
);
}
diff --git a/ui/src/components/post-listings.tsx b/ui/src/components/post-listings.tsx
index 005c4fe0..d61f624d 100644
--- a/ui/src/components/post-listings.tsx
+++ b/ui/src/components/post-listings.tsx
@@ -1,6 +1,7 @@
import { Component } from 'inferno';
import { Link } from 'inferno-router';
-import { Post } from '../interfaces';
+import { Post, SortType } from '../interfaces';
+import { postSort } from '../utils';
import { PostListing } from './post-listing';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -9,6 +10,7 @@ interface PostListingsProps {
posts: Array<Post>;
showCommunity?: boolean;
removeDuplicates?: boolean;
+ sort?: SortType;
}
export class PostListings extends Component<PostListingsProps, any> {
@@ -20,10 +22,7 @@ export class PostListings extends Component<PostListingsProps, any> {
return (
<div>
{this.props.posts.length > 0 ? (
- (this.props.removeDuplicates
- ? this.removeDuplicates(this.props.posts)
- : this.props.posts
- ).map(post => (
+ this.outer().map(post => (
<>
<PostListing
post={post}
@@ -47,6 +46,19 @@ export class PostListings extends Component<PostListingsProps, any> {
);
}
+ outer(): Array<Post> {
+ let out = this.props.posts;
+ if (this.props.removeDuplicates) {
+ out = this.removeDuplicates(out);
+ }
+
+ if (this.props.sort !== undefined) {
+ postSort(out, this.props.sort);
+ }
+
+ return out;
+ }
+
removeDuplicates(posts: Array<Post>): Array<Post> {
// A map from post url to list of posts (dupes)
let urlMap = new Map<string, Array<Post>>();
diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx
index 1f2e40ba..b5b1fce3 100644
--- a/ui/src/components/post.tsx
+++ b/ui/src/components/post.tsx
@@ -31,7 +31,6 @@ import {
import { WebSocketService, UserService } from '../services';
import {
wsJsonToRes,
- hotRank,
toast,
editCommentRes,
saveCommentRes,
@@ -314,48 +313,9 @@ export class Post extends Component<any, PostState> {
}
}
- this.sortTree(tree);
-
return tree;
}
- sortTree(tree: Array<CommentNodeI>) {
- // First, put removed and deleted comments at the bottom, then do your other sorts
- if (this.state.commentSort == CommentSortType.Top) {
- tree.sort(
- (a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- b.comment.score - a.comment.score
- );
- } else if (this.state.commentSort == CommentSortType.New) {
- tree.sort(
- (a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- b.comment.published.localeCompare(a.comment.published)
- );
- } else if (this.state.commentSort == CommentSortType.Old) {
- tree.sort(
- (a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- a.comment.published.localeCompare(b.comment.published)
- );
- } else if (this.state.commentSort == CommentSortType.Hot) {
- tree.sort(
- (a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- hotRank(b.comment) - hotRank(a.comment)
- );
- }
-
- for (let node of tree) {
- this.sortTree(node.children);
- }
- }
-
commentsTree() {
let nodes = this.buildCommentsTree();
return (
@@ -366,6 +326,7 @@ export class Post extends Component<any, PostState> {
moderators={this.state.moderators}
admins={this.state.admins}
postCreatorId={this.state.post.creator_id}
+ sort={this.state.commentSort}
/>
</div>
);
diff --git a/ui/src/utils.ts b/ui/src/utils.ts
index 8cdc02f0..929877fc 100644
--- a/ui/src/utils.ts
+++ b/ui/src/utils.ts
@@ -20,6 +20,7 @@ import {
PrivateMessage,
User,
SortType,
+ CommentSortType,
ListingType,
DataType,
SearchType,
@@ -93,15 +94,22 @@ md.renderer.rules.emoji = function(token, idx) {
return twemoji.parse(token[idx].content);
};
-export function hotRank(comment: Comment): number {
- // Rank = ScaleFactor * sign(Score) * log(1 + abs(Score)) / (Time + 2)^Gravity
+export function hotRankComment(comment: Comment): number {
+ return hotRank(comment.score, comment.published);
+}
+
+export function hotRankPost(post: Post): number {
+ return hotRank(post.score, post.newest_activity_time);
+}
- let date: Date = new Date(comment.published + 'Z'); // Add Z to convert from UTC date
+export function hotRank(score: number, timeStr: string): number {
+ // Rank = ScaleFactor * sign(Score) * log(1 + abs(Score)) / (Time + 2)^Gravity
+ let date: Date = new Date(timeStr + 'Z'); // Add Z to convert from UTC date
let now: Date = new Date();
let hoursElapsed: number = (now.getTime() - date.getTime()) / 36e5;
let rank =
- (10000 * Math.log10(Math.max(1, 3 + comment.score))) /
+ (10000 * Math.log10(Math.max(1, 3 + score))) /
Math.pow(hoursElapsed + 2, 1.8);
// console.log(`Comment: ${comment.content}\nRank: ${rank}\nScore: ${comment.score}\nHours: ${hoursElapsed}`);
@@ -639,3 +647,95 @@ export function commentsToFlatNodes(
}
return nodes;
}
+
+export function commentSort(tree: Array<CommentNode>, sort: CommentSortType) {
+ // First, put removed and deleted comments at the bottom, then do your other sorts
+ if (sort == CommentSortType.Top) {
+ tree.sort(
+ (a, b) =>
+ +a.comment.removed - +b.comment.removed ||
+ +a.comment.deleted - +b.comment.deleted ||
+ b.comment.score - a.comment.score
+ );
+ } else if (sort == CommentSortType.New) {
+ tree.sort(
+ (a, b) =>
+ +a.comment.removed - +b.comment.removed ||
+ +a.comment.deleted - +b.comment.deleted ||
+ b.comment.published.localeCompare(a.comment.published)
+ );
+ } else if (sort == CommentSortType.Old) {
+ tree.sort(
+ (a, b) =>
+ +a.comment.removed - +b.comment.removed ||
+ +a.comment.deleted - +b.comment.deleted ||
+ a.comment.published.localeCompare(b.comment.published)
+ );
+ } else if (sort == CommentSortType.Hot) {
+ tree.sort(
+ (a, b) =>
+ +a.comment.removed - +b.comment.removed ||
+ +a.comment.deleted - +b.comment.deleted ||
+ hotRankComment(b.comment) - hotRankComment(a.comment)
+ );
+ }
+
+ // Go through the children recursively
+ for (let node of tree) {
+ if (node.children) {
+ commentSort(node.children, sort);
+ }
+ }
+}
+
+export function commentSortSortType(tree: Array<CommentNode>, sort: SortType) {
+ commentSort(tree, convertCommentSortType(sort));
+}
+
+function convertCommentSortType(sort: SortType): CommentSortType {
+ if (
+ sort == SortType.TopAll ||
+ sort == SortType.TopDay ||
+ sort == SortType.TopWeek ||
+ sort == SortType.TopMonth ||
+ sort == SortType.TopYear
+ ) {
+ return CommentSortType.Top;
+ } else if (sort == SortType.New) {
+ return CommentSortType.New;
+ } else if (sort == SortType.Hot) {
+ return CommentSortType.Hot;
+ } else {
+ return CommentSortType.Hot;
+ }
+}
+
+export function postSort(posts: Array<Post>, sort: SortType) {
+ // First, put removed and deleted comments at the bottom, then do your other sorts
+ if (
+ sort == SortType.TopAll ||
+ sort == SortType.TopDay ||
+ sort == SortType.TopWeek ||
+ sort == SortType.TopMonth ||
+ sort == SortType.TopYear
+ ) {
+ posts.sort(
+ (a, b) =>
+ +a.removed - +b.removed || +a.deleted - +b.deleted || b.score - a.score
+ );
+ } else if (sort == SortType.New) {
+ posts.sort(
+ (a, b) =>
+ +a.removed - +b.removed ||
+ +a.deleted - +b.deleted ||
+ b.published.localeCompare(a.published)
+ );
+ } else if (sort == SortType.Hot) {
+ posts.sort(
+ (a, b) =>
+ +a.removed - +b.removed ||
+ +a.deleted - +b.deleted ||
+ hotRankPost(b) - hotRankPost(a)
+ );
+ }
+}