From a777d30bd49e6a1c5cad35a87404c53ccc17a732 Mon Sep 17 00:00:00 2001 From: nemanjam Date: Wed, 17 Apr 2024 11:33:26 +0200 Subject: [PATCH] nested comments, check that only comments content is in viewport --- docs/work-notes/test-code2.ts | 9 +++++++++ docs/work-notes/todo2.md | 1 + package.json | 2 +- source/manifest-v2-firefox.json | 2 +- source/manifest-v3-chrome.json | 2 +- source/manifest.json | 2 +- source/reddit-comments/constants/selectors.ts | 19 ++++++++++++++----- .../reddit-comments/dom/highlight-by-read.ts | 13 +++++++++++-- .../reddit-comments/dom/highlight-common.ts | 14 ++++++++++++-- source/reddit-comments/dom/timestamp.ts | 4 ++-- 10 files changed, 53 insertions(+), 15 deletions(-) diff --git a/docs/work-notes/test-code2.ts b/docs/work-notes/test-code2.ts index ca0a05e..ac8058d 100644 --- a/docs/work-notes/test-code2.ts +++ b/docs/work-notes/test-code2.ts @@ -60,3 +60,12 @@ document.querySelector('button[id="comment-sort-button"]'); document.querySelector('data[value="NEW"]').click() document.querySelector('#main-content').click() + +------------- + +var currentElement = document.querySelector('shreddit-comment[thingid^="t1_kz4bckd"]') +var contentElement = currentElement.querySelector('shreddit-comment[thingid^="t1_kz4bckd"] > div[slot="comment"]') +contentElement; + + + diff --git a/docs/work-notes/todo2.md b/docs/work-notes/todo2.md index 43b0d67..b7688db 100644 --- a/docs/work-notes/todo2.md +++ b/docs/work-notes/todo2.md @@ -13,6 +13,7 @@ everything should throw custom exception classes and log db wrapper mark thread as read button, immediately radio add version label + nested comments, check that only comments content is in viewport // ovde na pocetku nove sesije oznacava prethodnu kao procitanu const { threadId, updatedAt } = existingThread; diff --git a/package.json b/package.json index 67bc59f..56e7eba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "reddit-unread-comments", - "version": "0.0.4", + "version": "1.0.0", "description": "Web extension for easier tracking of new comments on Reddit.", "private": false, "repository": "https://github.com/nemanjam/reddit-unread-comments", diff --git a/source/manifest-v2-firefox.json b/source/manifest-v2-firefox.json index b0eeee6..1fda161 100644 --- a/source/manifest-v2-firefox.json +++ b/source/manifest-v2-firefox.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Reddit Unread Comments", - "version": "0.0.4", + "version": "1.0.0", "icons": { "16": "assets/icons/favicon-16.png", diff --git a/source/manifest-v3-chrome.json b/source/manifest-v3-chrome.json index c132d51..1e3ba76 100644 --- a/source/manifest-v3-chrome.json +++ b/source/manifest-v3-chrome.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Reddit Unread Comments", - "version": "0.0.4", + "version": "1.0.0", "icons": { "16": "assets/icons/favicon-16.png", diff --git a/source/manifest.json b/source/manifest.json index b0eeee6..1fda161 100644 --- a/source/manifest.json +++ b/source/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Reddit Unread Comments", - "version": "0.0.4", + "version": "1.0.0", "icons": { "16": "assets/icons/favicon-16.png", diff --git a/source/reddit-comments/constants/selectors.ts b/source/reddit-comments/constants/selectors.ts index eaf7d8a..5475ab8 100644 --- a/source/reddit-comments/constants/selectors.ts +++ b/source/reddit-comments/constants/selectors.ts @@ -9,20 +9,29 @@ export const redditUrlRegex = /https?:\/\/www\.?reddit\.com.*/; export const commentIdAttribute = 'thingid'; export const commentSelector = 'shreddit-comment[thingid^="t1_"]'; -export const getCommentSelectorById = (commentId: string) => - `shreddit-comment[thingid^="${commentId}"]`; export const commentIdRegexValidate = /^t1_[a-z0-9]+$/; -/*----------------- timestamp ----------------*/ +// comment +export const getCommentSelectorFromId = (commentId: string) => + `shreddit-comment[thingid^="${commentId}"]`; -export const getTimestampSelectorById = (commentId: string) => { - const targetCommentSelector = getCommentSelectorById(commentId); +// timestamp +export const getTimestampSelectorFromId = (commentId: string) => { + const targetCommentSelector = getCommentSelectorFromId(commentId); // select direct child element first to exclude nested comments const timestampSelector = `${targetCommentSelector} > div[slot="commentMeta"] time[datetime]`; return timestampSelector; }; +// content +export const getContentSelectorFromId = (commentId: string) => { + const targetCommentSelector = getCommentSelectorFromId(commentId); + + const contentSelector = `${targetCommentSelector} > div[slot="comment"]`; // used in styles.scss too + return contentSelector; +}; + /*----------------- thread ----------------*/ export const threadPostSelector = 'shreddit-post[id^="t3_"]'; diff --git a/source/reddit-comments/dom/highlight-by-read.ts b/source/reddit-comments/dom/highlight-by-read.ts index c07966b..bdbf38d 100644 --- a/source/reddit-comments/dom/highlight-by-read.ts +++ b/source/reddit-comments/dom/highlight-by-read.ts @@ -20,7 +20,12 @@ import { MyCreateModelFailedDBException } from '../exceptions'; import logger from '../logger'; import { isActiveTabAndRedditThread } from '../utils'; import { validateCommentElementIdOrThrow } from '../validation'; -import { addClass, isElementInViewport, removeClass } from './highlight-common'; +import { + addClass, + getCommentContentElement, + isElementInViewport, + removeClass, +} from './highlight-common'; import { getThreadIdFromDom } from './thread'; import { getDateFromCommentId } from './timestamp'; @@ -154,7 +159,11 @@ export const markAsRead = async ( const commentId = validateCommentElementIdOrThrow(commentElement); const isAlreadyMarkedComment = allSessionsCommentsIds.includes(commentId); // all checks in one loop - if (!isElementInViewport(commentElement) || isAlreadyMarkedComment) return; + // since comments are now nested, select only content of the comment + const commentContentElement = getCommentContentElement(commentElement); + if (!commentContentElement) return; + + if (!isElementInViewport(commentContentElement) || isAlreadyMarkedComment) return; const sessionCreatedAt = currentSessionCreatedAt; await addComment(db, { threadId, commentId, sessionCreatedAt }); diff --git a/source/reddit-comments/dom/highlight-common.ts b/source/reddit-comments/dom/highlight-common.ts index 1b204bf..bd51e23 100644 --- a/source/reddit-comments/dom/highlight-common.ts +++ b/source/reddit-comments/dom/highlight-common.ts @@ -4,11 +4,11 @@ import { highlightedCommentClass, highlightedCommentReadClass, } from '../constants/config'; -import { commentSelector } from '../constants/selectors'; +import { commentSelector, getContentSelectorFromId } from '../constants/selectors'; import { validateCommentElementIdOrThrow } from '../validation'; // sync, fix for big comments -export const isElementInViewport = (element: HTMLElement) => { +export const isElementInViewport = (element: HTMLElement): boolean => { const rect = element.getBoundingClientRect(); const elementHeight = commentHeightHeadroom + (rect.bottom - rect.top); @@ -27,6 +27,16 @@ export const isElementInViewport = (element: HTMLElement) => { return result; }; +export const getCommentContentElement = (commentElement: HTMLElement) => { + const commentId = validateCommentElementIdOrThrow(commentElement); + const contentSelector = getContentSelectorFromId(commentId); + + // query from commentElement to save performance + // selector for current element can match element itself + const contentElement = commentElement.querySelector(contentSelector); + return contentElement; +}; + export const addClass = (element: HTMLElement, className: string): void => { if (!element.classList.contains(className)) element.classList.add(className); }; diff --git a/source/reddit-comments/dom/timestamp.ts b/source/reddit-comments/dom/timestamp.ts index 51098db..1d3a24a 100644 --- a/source/reddit-comments/dom/timestamp.ts +++ b/source/reddit-comments/dom/timestamp.ts @@ -1,11 +1,11 @@ -import { getTimestampSelectorById } from '../constants/selectors'; +import { getTimestampSelectorFromId } from '../constants/selectors'; import { MyElementAttributeNotValidDOMException, MyElementNotFoundDOMException, } from '../exceptions'; export const getTimestampElementFromCommentId = (commentId: string) => { - const timestampSelector = getTimestampSelectorById(commentId); + const timestampSelector = getTimestampSelectorFromId(commentId); const timestampElement = document.querySelector(timestampSelector); return timestampElement;