- Only changing the view or sort, or reloading the page will resort.
- New comments by default added to the top, and left unsorted.
AddAdmin,
TransferCommunity,
TransferSite,
- SortType,
CommentView,
UserMentionView,
} from 'lemmy-js-client';
-import {
- CommentSortType,
- CommentNode as CommentNodeI,
- BanType,
-} from '../interfaces';
+import { CommentNode as CommentNodeI, BanType } from '../interfaces';
import { WebSocketService, UserService } from '../services';
import {
mdToHtml,
// TODO is this necessary, can't I get it from the node itself?
postCreatorId?: number;
showCommunity?: boolean;
- sort?: CommentSortType;
- sortType?: SortType;
enableDownvotes: boolean;
}
moderators={this.props.moderators}
admins={this.props.admins}
postCreatorId={this.props.postCreatorId}
- sort={this.props.sort}
- sortType={this.props.sortType}
enableDownvotes={this.props.enableDownvotes}
/>
)}
import { Component } from 'inferno';
-import { CommentSortType, CommentNode as CommentNodeI } from '../interfaces';
-import {
- CommunityModeratorView,
- UserViewSafe,
- SortType,
-} from 'lemmy-js-client';
-import { commentSort, commentSortSortType } from '../utils';
+import { CommentNode as CommentNodeI } from '../interfaces';
+import { CommunityModeratorView, UserViewSafe } from 'lemmy-js-client';
import { CommentNode } from './comment-node';
interface CommentNodesState {}
markable?: boolean;
showContext?: boolean;
showCommunity?: boolean;
- sort?: CommentSortType;
- sortType?: SortType;
enableDownvotes: boolean;
}
render() {
return (
<div className="comments">
- {this.sorter().map(node => (
+ {this.props.nodes.map(node => (
<CommentNode
key={node.comment_view.comment.id}
node={node}
markable={this.props.markable}
showContext={this.props.showContext}
showCommunity={this.props.showCommunity}
- sort={this.props.sort}
- sortType={this.props.sortType}
enableDownvotes={this.props.enableDownvotes}
/>
))}
</div>
);
}
-
- sorter(): 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;
- }
}
<PostListings
posts={this.state.posts}
removeDuplicates
- sort={this.state.sort}
enableDownvotes={site.enable_downvotes}
enableNsfw={site.enable_nsfw}
/>
<CommentNodes
nodes={commentsToFlatNodes(this.state.comments)}
noIndent
- sortType={this.state.sort}
showContext
enableDownvotes={site.enable_downvotes}
/>
posts={this.state.posts}
showCommunity
removeDuplicates
- sort={this.state.sort}
enableDownvotes={site.enable_downvotes}
enableNsfw={site.enable_nsfw}
/>
nodes={commentsToFlatNodes(this.state.comments)}
noIndent
showCommunity
- sortType={this.state.sort}
showContext
enableDownvotes={site.enable_downvotes}
/>
import { Component } from 'inferno';
import { Link } from 'inferno-router';
-import { PostView, SortType } from 'lemmy-js-client';
-import { postSort } from '../utils';
+import { PostView } from 'lemmy-js-client';
import { PostListing } from './post-listing';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
posts: PostView[];
showCommunity?: boolean;
removeDuplicates?: boolean;
- sort?: SortType;
enableDownvotes: boolean;
enableNsfw: boolean;
}
out = this.removeDuplicates(out);
}
- if (this.props.sort !== undefined) {
- postSort(out, this.props.sort, this.props.showCommunity == undefined);
- }
-
return out;
}
setOptionalAuth,
saveScrollPosition,
restoreScrollPosition,
+ buildCommentsTree,
+ insertCommentIntoTree,
} from '../utils';
import { PostListing } from './post-listing';
import { Sidebar } from './sidebar';
interface PostState {
postRes: GetPostResponse;
postId: number;
+ commentTree: CommentNodeI[];
commentId?: number;
commentSort: CommentSortType;
commentViewType: CommentViewType;
private emptyState: PostState = {
postRes: null,
postId: getIdFromProps(this.props),
+ commentTree: [],
commentId: getCommentIdFromProps(this.props),
commentSort: CommentSortType.Hot,
commentViewType: CommentViewType.Tree,
// Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
this.state.postRes = this.isoData.routeData[0];
+ this.state.commentTree = buildCommentsTree(
+ this.state.postRes.comments,
+ this.state.commentSort
+ );
this.state.categories = this.isoData.routeData[1].categories;
this.state.loading = false;
}
commentsFlat() {
+ // These are already sorted by new
return (
<div>
<CommentNodes
postCreatorId={this.state.postRes.post_view.creator.id}
showContext
enableDownvotes={this.state.siteRes.site_view.site.enable_downvotes}
- sort={this.state.commentSort}
/>
</div>
);
handleCommentSortChange(i: Post, event: any) {
i.state.commentSort = Number(event.target.value);
i.state.commentViewType = CommentViewType.Tree;
+ i.state.commentTree = buildCommentsTree(
+ i.state.postRes.comments,
+ i.state.commentSort
+ );
i.setState(i.state);
}
handleCommentViewTypeChange(i: Post, event: any) {
i.state.commentViewType = Number(event.target.value);
i.state.commentSort = CommentSortType.New;
+ i.state.commentTree = buildCommentsTree(
+ i.state.postRes.comments,
+ i.state.commentSort
+ );
i.setState(i.state);
}
- buildCommentsTree(): CommentNodeI[] {
- let map = new Map<number, CommentNodeI>();
- for (let comment_view of this.state.postRes.comments) {
- let node: CommentNodeI = {
- comment_view: comment_view,
- children: [],
- };
- map.set(comment_view.comment.id, { ...node });
- }
- let tree: CommentNodeI[] = [];
- for (let comment_view of this.state.postRes.comments) {
- let child = map.get(comment_view.comment.id);
- if (comment_view.comment.parent_id) {
- let parent_ = map.get(comment_view.comment.parent_id);
- parent_.children.push(child);
- } else {
- tree.push(child);
- }
-
- this.setDepth(child);
- }
-
- return tree;
- }
-
- setDepth(node: CommentNodeI, i: number = 0): void {
- for (let child of node.children) {
- child.depth = i;
- this.setDepth(child, i + 1);
- }
- }
-
commentsTree() {
- let nodes = this.buildCommentsTree();
return (
<div>
<CommentNodes
- nodes={nodes}
+ nodes={this.state.commentTree}
locked={this.state.postRes.post_view.post.locked}
moderators={this.state.postRes.moderators}
admins={this.state.siteRes.admins}
postCreatorId={this.state.postRes.post_view.creator.id}
- sort={this.state.commentSort}
enableDownvotes={this.state.siteRes.site_view.site.enable_downvotes}
/>
</div>
} else if (op == UserOperation.GetPost) {
let data = wsJsonToRes<GetPostResponse>(msg).data;
this.state.postRes = data;
+ this.state.commentTree = buildCommentsTree(
+ this.state.postRes.comments,
+ this.state.commentSort
+ );
this.state.loading = false;
// Get cross-posts
// Necessary since it might be a user reply, which has the recipients, to avoid double
if (data.recipient_ids.length == 0) {
this.state.postRes.comments.unshift(data.comment_view);
+ insertCommentIntoTree(this.state.commentTree, data.comment_view);
this.state.postRes.post_view.counts.comments++;
this.setState(this.state);
setupTippy();
return nodes;
}
-export function commentSort(tree: CommentNodeI[], sort: CommentSortType) {
+function commentSort(tree: CommentNodeI[], sort: CommentSortType) {
// First, put removed and deleted comments at the bottom, then do your other sorts
if (sort == CommentSortType.Top) {
tree.sort(
}
}
-export function postSort(
- posts: PostView[],
- sort: SortType,
- communityType: boolean
-) {
- // 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.post.removed - +b.post.removed ||
- +a.post.deleted - +b.post.deleted ||
- (communityType && +b.post.stickied - +a.post.stickied) ||
- b.counts.score - a.counts.score
- );
- } else if (sort == SortType.New) {
- posts.sort(
- (a, b) =>
- +a.post.removed - +b.post.removed ||
- +a.post.deleted - +b.post.deleted ||
- (communityType && +b.post.stickied - +a.post.stickied) ||
- b.post.published.localeCompare(a.post.published)
- );
- } else if (sort == SortType.Hot) {
- posts.sort(
- (a, b) =>
- +a.post.removed - +b.post.removed ||
- +a.post.deleted - +b.post.deleted ||
- (communityType && +b.post.stickied - +a.post.stickied) ||
- hotRankPost(b) - hotRankPost(a)
- );
- } else if (sort == SortType.Active) {
- posts.sort(
- (a, b) =>
- +a.post.removed - +b.post.removed ||
- +a.post.deleted - +b.post.deleted ||
- (communityType && +b.post.stickied - +a.post.stickied) ||
- hotRankActivePost(b) - hotRankActivePost(a)
- );
+export function buildCommentsTree(
+ comments: CommentView[],
+ commentSortType: CommentSortType
+): CommentNodeI[] {
+ let map = new Map<number, CommentNodeI>();
+ for (let comment_view of comments) {
+ let node: CommentNodeI = {
+ comment_view: comment_view,
+ children: [],
+ };
+ map.set(comment_view.comment.id, { ...node });
+ }
+ let tree: CommentNodeI[] = [];
+ for (let comment_view of comments) {
+ let child = map.get(comment_view.comment.id);
+ if (comment_view.comment.parent_id) {
+ let parent_ = map.get(comment_view.comment.parent_id);
+ parent_.children.push(child);
+ } else {
+ tree.push(child);
+ }
+
+ setDepth(child);
+ }
+
+ commentSort(tree, commentSortType);
+
+ return tree;
+}
+
+function setDepth(node: CommentNodeI, i: number = 0) {
+ for (let child of node.children) {
+ child.depth = i;
+ setDepth(child, i + 1);
+ }
+}
+
+export function insertCommentIntoTree(tree: CommentNodeI[], cv: CommentView) {
+ // Building a fake node to be used for later
+ let node: CommentNodeI = {
+ comment_view: cv,
+ children: [],
+ depth: 0,
+ };
+
+ if (cv.comment.parent_id) {
+ let parentComment = searchCommentTree(tree, cv.comment.parent_id);
+ if (parentComment) {
+ node.depth = parentComment.depth + 1;
+ parentComment.children.unshift(node);
+ }
+ } else {
+ tree.unshift(node);
}
}
+export function searchCommentTree(
+ tree: CommentNodeI[],
+ id: number
+): CommentNodeI {
+ for (let node of tree) {
+ if (node.comment_view.comment.id === id) {
+ return node;
+ }
+
+ for (const child of node.children) {
+ const res = searchCommentTree([child], id);
+
+ if (res) {
+ return res;
+ }
+ }
+ }
+ return null;
+}
+
export const colorList: string[] = [
hsl(0),
hsl(100),
return `hsla(${num}, 35%, 50%, 1)`;
}
-// function randomHsl() {
-// return `hsla(${Math.random() * 360}, 100%, 50%, 1)`;
-// }
-
export function previewLines(
text: string,
maxChars: number = 300,