- Moving sorting to utils.
TransferCommunityForm,
TransferSiteForm,
BanType,
+ CommentSortType,
+ SortType,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
import {
// 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> {
moderators={this.props.moderators}
admins={this.props.admins}
postCreatorId={this.props.postCreatorId}
+ sort={this.props.sort}
+ sortType={this.props.sortType}
/>
)}
{/* A collapsed clearfix */}
CommentNode as CommentNodeI,
CommunityUser,
UserView,
+ CommentSortType,
+ SortType,
} from '../interfaces';
+import { commentSort, commentSortSortType } from '../utils';
import { CommentNode } from './comment-node';
interface CommentNodesState {}
locked?: boolean;
markable?: boolean;
showCommunity?: boolean;
+ sort?: CommentSortType;
+ sortType?: SortType;
}
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}
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;
+ }
}
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}
+ />
);
}
createPostLikeFindRes,
editPostFindRes,
commentsToFlatNodes,
+ commentSortSortType,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
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}
/>
);
}
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';
posts: Array<Post>;
showCommunity?: boolean;
removeDuplicates?: boolean;
+ sort?: SortType;
}
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}
);
}
+ 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>>();
import { WebSocketService, UserService } from '../services';
import {
wsJsonToRes,
- hotRank,
toast,
editCommentRes,
saveCommentRes,
}
}
- 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 (
moderators={this.state.moderators}
admins={this.state.admins}
postCreatorId={this.state.post.creator_id}
+ sort={this.state.commentSort}
/>
</div>
);
PrivateMessage,
User,
SortType,
+ CommentSortType,
ListingType,
DataType,
SearchType,
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}`);
}
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)
+ );
+ }
+}