mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-12-23 03:11:25 +00:00
Comments and posts no longer live-sorted. Fixes #51
- Only changing the view or sort, or reloading the page will resort. - New comments by default added to the top, and left unsorted.
This commit is contained in:
parent
04955cc45e
commit
b24eba6fea
7 changed files with 102 additions and 128 deletions
|
@ -15,15 +15,10 @@ import {
|
|||
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,
|
||||
|
@ -82,8 +77,6 @@ interface CommentNodeProps {
|
|||
// TODO is this necessary, can't I get it from the node itself?
|
||||
postCreatorId?: number;
|
||||
showCommunity?: boolean;
|
||||
sort?: CommentSortType;
|
||||
sortType?: SortType;
|
||||
enableDownvotes: boolean;
|
||||
}
|
||||
|
||||
|
@ -745,8 +738,6 @@ 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}
|
||||
enableDownvotes={this.props.enableDownvotes}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
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 {}
|
||||
|
@ -22,8 +17,6 @@ interface CommentNodesProps {
|
|||
markable?: boolean;
|
||||
showContext?: boolean;
|
||||
showCommunity?: boolean;
|
||||
sort?: CommentSortType;
|
||||
sortType?: SortType;
|
||||
enableDownvotes: boolean;
|
||||
}
|
||||
|
||||
|
@ -38,7 +31,7 @@ export class CommentNodes extends Component<
|
|||
render() {
|
||||
return (
|
||||
<div className="comments">
|
||||
{this.sorter().map(node => (
|
||||
{this.props.nodes.map(node => (
|
||||
<CommentNode
|
||||
key={node.comment_view.comment.id}
|
||||
node={node}
|
||||
|
@ -52,22 +45,10 @@ export class CommentNodes extends Component<
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,7 +291,6 @@ export class Community extends Component<any, State> {
|
|||
<PostListings
|
||||
posts={this.state.posts}
|
||||
removeDuplicates
|
||||
sort={this.state.sort}
|
||||
enableDownvotes={site.enable_downvotes}
|
||||
enableNsfw={site.enable_nsfw}
|
||||
/>
|
||||
|
@ -306,7 +305,6 @@ export class Community extends Component<any, State> {
|
|||
<CommentNodes
|
||||
nodes={commentsToFlatNodes(this.state.comments)}
|
||||
noIndent
|
||||
sortType={this.state.sort}
|
||||
showContext
|
||||
enableDownvotes={site.enable_downvotes}
|
||||
/>
|
||||
|
|
|
@ -561,7 +561,6 @@ export class Main extends Component<any, MainState> {
|
|||
posts={this.state.posts}
|
||||
showCommunity
|
||||
removeDuplicates
|
||||
sort={this.state.sort}
|
||||
enableDownvotes={site.enable_downvotes}
|
||||
enableNsfw={site.enable_nsfw}
|
||||
/>
|
||||
|
@ -570,7 +569,6 @@ export class Main extends Component<any, MainState> {
|
|||
nodes={commentsToFlatNodes(this.state.comments)}
|
||||
noIndent
|
||||
showCommunity
|
||||
sortType={this.state.sort}
|
||||
showContext
|
||||
enableDownvotes={site.enable_downvotes}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
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';
|
||||
|
@ -10,7 +9,6 @@ interface PostListingsProps {
|
|||
posts: PostView[];
|
||||
showCommunity?: boolean;
|
||||
removeDuplicates?: boolean;
|
||||
sort?: SortType;
|
||||
enableDownvotes: boolean;
|
||||
enableNsfw: boolean;
|
||||
}
|
||||
|
@ -58,10 +56,6 @@ export class PostListings extends Component<PostListingsProps, any> {
|
|||
out = this.removeDuplicates(out);
|
||||
}
|
||||
|
||||
if (this.props.sort !== undefined) {
|
||||
postSort(out, this.props.sort, this.props.showCommunity == undefined);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ import {
|
|||
setOptionalAuth,
|
||||
saveScrollPosition,
|
||||
restoreScrollPosition,
|
||||
buildCommentsTree,
|
||||
insertCommentIntoTree,
|
||||
} from '../utils';
|
||||
import { PostListing } from './post-listing';
|
||||
import { Sidebar } from './sidebar';
|
||||
|
@ -63,6 +65,7 @@ import { i18n } from '../i18next';
|
|||
interface PostState {
|
||||
postRes: GetPostResponse;
|
||||
postId: number;
|
||||
commentTree: CommentNodeI[];
|
||||
commentId?: number;
|
||||
commentSort: CommentSortType;
|
||||
commentViewType: CommentViewType;
|
||||
|
@ -79,6 +82,7 @@ export class Post extends Component<any, PostState> {
|
|||
private emptyState: PostState = {
|
||||
postRes: null,
|
||||
postId: getIdFromProps(this.props),
|
||||
commentTree: [],
|
||||
commentId: getCommentIdFromProps(this.props),
|
||||
commentSort: CommentSortType.Hot,
|
||||
commentViewType: CommentViewType.Tree,
|
||||
|
@ -100,6 +104,10 @@ export class Post extends Component<any, PostState> {
|
|||
// 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;
|
||||
|
||||
|
@ -368,6 +376,7 @@ export class Post extends Component<any, PostState> {
|
|||
}
|
||||
|
||||
commentsFlat() {
|
||||
// These are already sorted by new
|
||||
return (
|
||||
<div>
|
||||
<CommentNodes
|
||||
|
@ -379,7 +388,6 @@ export class Post extends Component<any, PostState> {
|
|||
postCreatorId={this.state.postRes.post_view.creator.id}
|
||||
showContext
|
||||
enableDownvotes={this.state.siteRes.site_view.site.enable_downvotes}
|
||||
sort={this.state.commentSort}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -404,58 +412,32 @@ export class Post extends Component<any, PostState> {
|
|||
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>
|
||||
|
@ -480,6 +462,10 @@ export class Post extends Component<any, PostState> {
|
|||
} 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
|
||||
|
@ -493,6 +479,7 @@ export class Post extends Component<any, PostState> {
|
|||
// 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();
|
||||
|
|
|
@ -942,7 +942,7 @@ export function commentsToFlatNodes(comments: CommentView[]): CommentNodeI[] {
|
|||
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(
|
||||
|
@ -1008,51 +1008,80 @@ function convertCommentSortType(sort: SortType): CommentSortType {
|
|||
}
|
||||
}
|
||||
|
||||
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[] = [
|
||||
|
@ -1068,10 +1097,6 @@ function hsl(num: number) {
|
|||
return `hsla(${num}, 35%, 50%, 1)`;
|
||||
}
|
||||
|
||||
// function randomHsl() {
|
||||
// return `hsla(${Math.random() * 360}, 100%, 50%, 1)`;
|
||||
// }
|
||||
|
||||
export function previewLines(
|
||||
text: string,
|
||||
maxChars: number = 300,
|
||||
|
|
Loading…
Reference in a new issue