import {
BlockCommunityResponse,
BlockPersonResponse,
+ Comment as CommentI,
+ CommentNode as CommentNodeI,
CommentReportView,
+ CommentSortType,
CommentView,
CommunityBlockView,
CommunityModeratorView,
import Toastify from "toastify-js";
import { httpBase } from "./env";
import { i18n, languages } from "./i18next";
-import {
- CommentNode as CommentNodeI,
- CommentSortType,
- DataType,
- IsoData,
-} from "./interfaces";
+import { DataType, IsoData } from "./interfaces";
import { UserService, WebSocketService } from "./services";
var Tribute: any;
export const elementUrl = "https://element.io";
export const postRefetchSeconds: number = 60 * 1000;
-export const fetchLimit = 20;
+export const fetchLimit = 40;
export const trendingFetchLimit = 6;
export const mentionDropdownFetchLimit = 10;
+export const commentTreeMaxDepth = 8;
export const relTags = "noopener nofollow";
export function canAdmin(
admins: Option<PersonViewSafe[]>,
creator_id: number,
- myUserInfo = UserService.Instance.myUserInfo
+ myUserInfo = UserService.Instance.myUserInfo,
+ onSelf = false
): boolean {
- return canMod(None, admins, creator_id, myUserInfo);
+ return canMod(None, admins, creator_id, myUserInfo, onSelf);
}
export function isMod(
let info: NotifyInfo = {
name: comment_view.creator.name,
icon: comment_view.creator.avatar,
- link: `/post/${comment_view.post.id}/comment/${comment_view.comment.id}`,
+ link: `/comment/${comment_view.comment.id}`,
body: comment_view.comment.content,
};
notify(info, router);
function notify(info: NotifyInfo, router: any) {
messageToastify(info, router);
- // TODO absolute nightmare bug, but notifs are currently broken.
- // Notification.new will try to do a browser fetch ???
-
- // if (Notification.permission !== "granted") Notification.requestPermission();
- // else {
- // var notification = new Notification(info.name, {
- // icon: info.icon,
- // body: info.body,
- // });
+ if (Notification.permission !== "granted") Notification.requestPermission();
+ else {
+ var notification = new Notification(info.name, {
+ ...{ body: info.body },
+ ...(info.icon.isSome() && { icon: info.icon.unwrap() }),
+ });
- // notification.onclick = (ev: Event): any => {
- // ev.preventDefault();
- // router.history.push(info.link);
- // };
- // }
+ notification.onclick = (ev: Event): any => {
+ ev.preventDefault();
+ router.history.push(info.link);
+ };
+ }
}
export function setupTribute() {
: 1;
}
-export function getIdFromProps(props: any): number {
- return Number(props.match.params.id);
+export function getIdFromProps(props: any): Option<number> {
+ let id: string = props.match.params.post_id;
+ return id ? Some(Number(id)) : None;
}
-export function getCommentIdFromProps(props: any): number {
- return Number(props.match.params.comment_id);
+export function getCommentIdFromProps(props: any): Option<number> {
+ let id: string = props.match.params.comment_id;
+ return id ? Some(Number(id)) : None;
}
export function getUsernameFromProps(props: any): string {
let found = comments.find(c => c.comment.id == data.comment.id);
if (found) {
found.comment.content = data.comment.content;
+ found.comment.distinguished = data.comment.distinguished;
found.comment.updated = data.comment.updated;
found.comment.removed = data.comment.removed;
found.comment.deleted = data.comment.deleted;
export function commentsToFlatNodes(comments: CommentView[]): CommentNodeI[] {
let nodes: CommentNodeI[] = [];
for (let comment of comments) {
- nodes.push({ comment_view: comment });
+ nodes.push({ comment_view: comment, children: [], depth: 0 });
}
return nodes;
}
-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(
- (a, b) =>
- +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
- +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
- b.comment_view.counts.score - a.comment_view.counts.score
- );
- } else if (sort == CommentSortType.New) {
- tree.sort(
- (a, b) =>
- +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
- +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
- b.comment_view.comment.published.localeCompare(
- a.comment_view.comment.published
- )
- );
- } else if (sort == CommentSortType.Old) {
- tree.sort(
- (a, b) =>
- +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
- +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
- a.comment_view.comment.published.localeCompare(
- b.comment_view.comment.published
- )
- );
- } else if (sort == CommentSortType.Hot) {
- tree.sort(
- (a, b) =>
- +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
- +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
- hotRankComment(b.comment_view as CommentView) -
- hotRankComment(a.comment_view as CommentView)
- );
- }
-
- // Go through the children recursively
- for (let node of tree) {
- if (node.children) {
- commentSort(node.children, sort);
- }
- }
-}
-
-export function commentSortSortType(tree: CommentNodeI[], sort: SortType) {
- commentSort(tree, convertCommentSortType(sort));
-}
-
-function convertCommentSortType(sort: SortType): CommentSortType {
+export function convertCommentSortType(sort: SortType): CommentSortType {
if (
sort == SortType.TopAll ||
sort == SortType.TopDay ||
export function buildCommentsTree(
comments: CommentView[],
- commentSortType: CommentSortType
+ parentComment: boolean
): CommentNodeI[] {
let map = new Map<number, CommentNodeI>();
+ let depthOffset = !parentComment
+ ? 0
+ : getDepthFromComment(comments[0].comment);
+
for (let comment_view of comments) {
let node: CommentNodeI = {
comment_view: comment_view,
children: [],
- depth: 0,
+ depth: getDepthFromComment(comment_view.comment) - depthOffset,
};
map.set(comment_view.comment.id, { ...node });
}
+
let tree: CommentNodeI[] = [];
+
+ // if its a parent comment fetch, then push the first comment to the top node.
+ if (parentComment) {
+ tree.push(map.get(comments[0].comment.id));
+ }
+
for (let comment_view of comments) {
let child = map.get(comment_view.comment.id);
- let parent_id = comment_view.comment.parent_id;
+ let parent_id = getCommentParentId(comment_view.comment);
parent_id.match({
some: parentId => {
let parent = map.get(parentId);
}
},
none: () => {
- tree.push(child);
+ if (!parentComment) {
+ tree.push(child);
+ }
},
});
-
- setDepth(child);
}
- commentSort(tree, commentSortType);
-
return tree;
}
-function setDepth(node: CommentNodeI, i = 0) {
- for (let child of node.children) {
- child.depth = i;
- setDepth(child, i + 1);
+export function getCommentParentId(comment: CommentI): Option<number> {
+ let split = comment.path.split(".");
+ // remove the 0
+ split.shift();
+
+ if (split.length > 1) {
+ return Some(Number(split[split.length - 2]));
+ } else {
+ return None;
}
}
-export function insertCommentIntoTree(tree: CommentNodeI[], cv: CommentView) {
+export function getDepthFromComment(comment: CommentI): number {
+ return comment.path.split(".").length - 2;
+}
+
+export function insertCommentIntoTree(
+ tree: CommentNodeI[],
+ cv: CommentView,
+ parentComment: boolean
+) {
// Building a fake node to be used for later
let node: CommentNodeI = {
comment_view: cv,
depth: 0,
};
- cv.comment.parent_id.match({
+ getCommentParentId(cv.comment).match({
some: parentId => {
let parentComment = searchCommentTree(tree, parentId);
parentComment.match({
});
},
none: () => {
- tree.unshift(node);
+ if (!parentComment) {
+ tree.unshift(node);
+ }
},
});
}
export const colorList: string[] = [
hsl(0),
+ hsl(50),
hsl(100),
hsl(150),
hsl(200),
searchResultLimit: fetchLimit,
classNames: {
containerOuter: "choices mb-2 custom-select col-4 px-0",
- containerInner: "choices__inner bg-secondary border-0 py-0 modlog-choices-font-size",
+ containerInner:
+ "choices__inner bg-secondary border-0 py-0 modlog-choices-font-size",
input: "form-control",
inputCloned: "choices__input--cloned w-100",
list: "choices__list",
export function enableNsfw(siteRes: GetSiteResponse): boolean {
return siteRes.site_view.map(s => s.site.enable_nsfw).unwrapOr(false);
}
+
+export function postToCommentSortType(sort: SortType): CommentSortType {
+ if ([SortType.Active, SortType.Hot].includes(sort)) {
+ return CommentSortType.Hot;
+ } else if ([SortType.New, SortType.NewComments].includes(sort)) {
+ return CommentSortType.New;
+ } else if (sort == SortType.Old) {
+ return CommentSortType.Old;
+ } else {
+ return CommentSortType.Top;
+ }
+}