feat: remmember collapsed threads (#752)
* add persistence to comment collapse * move comments logic to separate file * fix imports * add .history to .gitignore
This commit is contained in:
parent
07d442f3be
commit
7409ed872d
|
@ -54,3 +54,4 @@ db.sqlite3
|
|||
venv/
|
||||
|
||||
gdpr/downloads/*.zip
|
||||
.history
|
|
@ -4,8 +4,8 @@ import Lightense from "lightense-images";
|
|||
|
||||
import "./inline-attachment";
|
||||
import "./codemirror-4.inline-attachment";
|
||||
|
||||
import { findParentForm, isCommunicationForm } from "./common/utils.js";
|
||||
import { findParentForm, isCommunicationForm } from "./common/utils";
|
||||
import { getCollapsedCommentThreadsSet } from "./common/comments";
|
||||
|
||||
const INITIAL_SYNC_DELAY = 50;
|
||||
|
||||
|
@ -87,6 +87,7 @@ const App = {
|
|||
this.initializeImageZoom();
|
||||
this.initializeEmojiForPoorPeople();
|
||||
this.blockCommunicationFormsResubmit();
|
||||
this.restoreCommentThreadsState();
|
||||
|
||||
const registeredEditors = this.initializeMarkdownEditor();
|
||||
|
||||
|
@ -298,6 +299,15 @@ const App = {
|
|||
|
||||
return false;
|
||||
},
|
||||
restoreCommentThreadsState() {
|
||||
const comments = document.querySelectorAll(".reply, .comment");
|
||||
const collapsedSet = getCollapsedCommentThreadsSet();
|
||||
for (const comment of comments) {
|
||||
if (collapsedSet.has(comment.id)) {
|
||||
comment.querySelector(".comment-collapse-stub, .reply-collapse-stub").click();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
const COLLAPSED_COMMENTS_LOCAL_STORAGE_KEY = "collapsed-comments";
|
||||
const WEEK_LENGTH_IN_MS = 7 * 24 * 60 * 60 * 1000;
|
||||
|
||||
export const getCollapsedCommentThreadsForTwoWeeks = () => {
|
||||
const currentValue = localStorage[COLLAPSED_COMMENTS_LOCAL_STORAGE_KEY];
|
||||
const thisWeek = Math.floor(new Date() / WEEK_LENGTH_IN_MS);
|
||||
let parsed = {};
|
||||
try {
|
||||
parsed = JSON.parse(currentValue);
|
||||
} catch {}
|
||||
return [parsed[thisWeek - 1] ?? [], parsed[thisWeek] ?? []];
|
||||
};
|
||||
|
||||
export const getCollapsedCommentThreadsSet = () => {
|
||||
const [lastWeekCollapsedComments, thisWeekCollapsedComments] = getCollapsedCommentThreadsForTwoWeeks();
|
||||
return new Set([...lastWeekCollapsedComments, ...thisWeekCollapsedComments]);
|
||||
};
|
||||
|
||||
export const handleCommentThreadCollapseToggle = (wasCollapsed, commentId) => {
|
||||
const thisWeek = Math.floor(new Date() / WEEK_LENGTH_IN_MS);
|
||||
const lastWeek = thisWeek - 1;
|
||||
const [lastWeekCollapsedComments, thisWeekCollapsedComments] = getCollapsedCommentThreadsForTwoWeeks();
|
||||
const thisWeekSet = new Set(thisWeekCollapsedComments);
|
||||
let lastWeekSet;
|
||||
if (wasCollapsed) {
|
||||
thisWeekSet.add(commentId);
|
||||
} else {
|
||||
lastWeekSet = new Set(lastWeekCollapsedComments);
|
||||
thisWeekSet.delete(commentId);
|
||||
lastWeekSet.delete(commentId);
|
||||
}
|
||||
localStorage[COLLAPSED_COMMENTS_LOCAL_STORAGE_KEY] = JSON.stringify({
|
||||
[thisWeek]: Array.from(thisWeekSet),
|
||||
[lastWeek]: lastWeekSet ? Array.from(lastWeekSet) : lastWeekCollapsedComments,
|
||||
});
|
||||
};
|
|
@ -5,6 +5,7 @@ import "../css/index.css";
|
|||
import App from "./App.js";
|
||||
import ClubApi from "./common/api.service.js";
|
||||
import { pluralize } from "./common/utils.js";
|
||||
import { handleCommentThreadCollapseToggle } from "./common/comments.js";
|
||||
|
||||
Vue.component("post-upvote", () => import("./components/PostUpvote.vue"));
|
||||
Vue.component("post-bookmark", () => import("./components/PostBookmark.vue"));
|
||||
|
@ -52,12 +53,15 @@ new Vue({
|
|||
}
|
||||
|
||||
// show/hide placeholder with thread length
|
||||
const collapseStub = comment.querySelector(".comment-collapse-stub") || comment.querySelector(".reply-collapse-stub");
|
||||
collapseStub.style.display = collapseStub.style.display !== "block" ? "block" : "none";
|
||||
const collapseStub =
|
||||
comment.querySelector(".comment-collapse-stub") || comment.querySelector(".reply-collapse-stub");
|
||||
const wasCollapsed = collapseStub.style.display !== "block";
|
||||
collapseStub.style.display = wasCollapsed ? "block" : "none";
|
||||
const threadLength = comment.querySelectorAll(".reply").length + 1;
|
||||
const pluralForm = pluralize(threadLength, ["комментарий", "комментария", "комментариев"]);
|
||||
collapseStub.querySelector(".thread-collapse-length").innerHTML = `${threadLength} ${pluralForm}`;
|
||||
|
||||
handleCommentThreadCollapseToggle(wasCollapsed, comment.id);
|
||||
// scroll back to comment if it's outside of the screen
|
||||
const commentPosition = comment.getBoundingClientRect();
|
||||
if (commentPosition.top < 0) {
|
||||
|
|
Loading…
Reference in New Issue