From e115e98faa5d017a63bbac31d5120310e60dcc33 Mon Sep 17 00:00:00 2001 From: shaokeyibb Date: Tue, 6 Aug 2024 15:50:47 +0800 Subject: [PATCH] refactor: code and cache, bump version to 0.0.5 --- frontend/index.html | 2 +- frontend/lib/main.ts | 122 +++++++++++++++---------------------- frontend/lib/style.css | 4 ++ frontend/package.json | 6 +- frontend/src/vite-env.d.ts | 1 + frontend/vite.config.ts | 3 + frontend/yarn.lock | 12 ++++ 7 files changed, 75 insertions(+), 75 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 0a848e3a..894f9dbe 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ - Test environment for Review + offsets-injection-review playground
diff --git a/frontend/lib/main.ts b/frontend/lib/main.ts index a31f45c9..aedac389 100644 --- a/frontend/lib/main.ts +++ b/frontend/lib/main.ts @@ -32,17 +32,14 @@ const dateTimeFormatter = new Intl.DateTimeFormat(undefined, { }); let globalInitialized = false; +let apiEndpoint = "/api"; let selectedOffset: HTMLElement | null = null; let commentsCache: Comment[] | undefined; -let commentsButton = document.querySelector( - "#review-comments-button", -)! as HTMLDivElement; -let commentsPanel = document.querySelector( - "#review-comments-panel", -)! as HTMLDivElement; +let commentsButton: HTMLElement; +let commentsPanel: HTMLElement; const _registerDialog = ({ id, @@ -60,8 +57,10 @@ const _registerDialog = ({ actions?: Map void>; tag?: keyof HTMLElementTagNameMap; initialize?: (el: HTMLElement) => void; -}) => { - if (parent.querySelector(`#${id}`)) return; +}): HTMLElement => { + let dialog = document.querySelector(`#${id}`); + if (dialog) return dialog; + parent.insertAdjacentHTML( insertPosition, ` @@ -70,8 +69,10 @@ const _registerDialog = ({ `.trim(), ); - const dialog = document.querySelector(`#${id}`)! as HTMLElement; + dialog = document.querySelector(`#${id}`)! as HTMLElement; + initialize(dialog); + const actionElements = dialog.querySelectorAll(`[data-action]`); for (const actionEl of actionElements) { actionEl.addEventListener("click", (e) => { @@ -81,16 +82,16 @@ const _registerDialog = ({ actions.get(action)?.(el); }); } + + return dialog; }; const _selectOffsetParagraph = ({ el, focusReply = false, - apiEndpoint, }: { el: HTMLElement; focusReply?: boolean; - apiEndpoint: string; }) => { if (selectedOffset !== el) { selectedOffset?.classList.remove("review_selected"); @@ -103,9 +104,7 @@ const _selectOffsetParagraph = ({ ) { selectedOffset.classList.remove("review_focused"); selectedOffset.classList.add("review_selected"); - _openCommentsPanel({ - apiEndpoint, - }); + _openCommentsPanel(); } }; @@ -114,13 +113,7 @@ const _unselectOffsetParagraph = () => { selectedOffset = null; }; -const _openContextMenu = ({ - el, - apiEndpoint, -}: { - el: HTMLElement; - apiEndpoint: string; -}) => { +const _openContextMenu = ({ el }: { el: HTMLElement }) => { _registerDialog({ id: "review-context-menu", content: ` @@ -138,7 +131,6 @@ const _openContextMenu = ({ _selectOffsetParagraph({ el, focusReply: true, - apiEndpoint, }); }, ], @@ -159,13 +151,8 @@ const _closeContextMenu = () => { contextMenu.remove(); }; -const _openCommentsPanel = async ({ - apiEndpoint, -}: { - focusReply?: boolean; - apiEndpoint: string; -}) => { - const comments = [...(await _fetchComments({ apiEndpoint }))]; +const _openCommentsPanel = async () => { + const comments = [...(await _fetchComments())]; const selected = selectedOffset; @@ -191,7 +178,7 @@ const _openCommentsPanel = async ({ }); } - _renderComments(comments, apiEndpoint); + _renderComments(comments); let selectedCommentsGroup = document.querySelector( `#review-comments-panel .comments_group[data-original-document-start="${selectedOffset?.dataset.originalDocumentStart}"][data-original-document-end="${selectedOffset?.dataset.originalDocumentEnd}"]`, ); @@ -212,12 +199,10 @@ const _closeCommentsPanel = () => { }; const _submitComment = async ({ - apiEndpoint, offsets, username, content, }: { - apiEndpoint: string; offsets: [number, number]; username: string; content: string; @@ -227,8 +212,6 @@ const _submitComment = async ({ throw new Error("Commit hash not found"); } - apiEndpoint = apiEndpoint.endsWith("/") ? apiEndpoint : apiEndpoint + "/"; - const comment = { offset: { start: offsets[0], @@ -265,15 +248,14 @@ const _submitComment = async ({ }); } - _updateAvailableComments({ apiEndpoint }); + _updateAvailableComments(); }; -const _fetchComments = async ({ apiEndpoint }: { apiEndpoint: string }) => { +const _fetchComments = async () => { if (commentsCache) { return commentsCache; } - apiEndpoint = apiEndpoint.endsWith("/") ? apiEndpoint : apiEndpoint + "/"; const res = await fetch( `${apiEndpoint}comment/${encodeURIComponent(new URL(window.location.href).pathname)}`, ); @@ -287,7 +269,7 @@ const _fetchComments = async ({ apiEndpoint }: { apiEndpoint: string }) => { return comments; }; -const _renderComments = (comments: Comment[], apiEndpoint: string) => { +const _renderComments = (comments: Comment[]) => { const commentsEl = commentsPanel.querySelector( ".panel_main", )! as HTMLDivElement; @@ -383,7 +365,6 @@ const _renderComments = (comments: Comment[], apiEndpoint: string) => { notification.textContent = ""; _submitComment({ - apiEndpoint, offsets: [ parseInt(selectedOffset!.dataset.originalDocumentStart!), parseInt(selectedOffset!.dataset.originalDocumentEnd!), @@ -397,9 +378,7 @@ const _renderComments = (comments: Comment[], apiEndpoint: string) => { notification.textContent = ""; submitButton.disabled = false; - _openCommentsPanel({ - apiEndpoint, - }); + _openCommentsPanel(); }) .catch((e) => { console.error(e); @@ -465,18 +444,14 @@ const _renderComments = (comments: Comment[], apiEndpoint: string) => { commentsEl.appendChild(fragment); }; -const _updateAvailableComments = async ({ - apiEndpoint, -}: { - apiEndpoint: string; -}) => { +const _updateAvailableComments = async () => { const offsets = Array.from( document.querySelectorAll( ".review_enabled[data-original-document-start][data-original-document-end]", ), ); - await _fetchComments({ apiEndpoint }); + await _fetchComments(); for (let offset of offsets) { offset.classList.remove("review_has_comments"); @@ -493,17 +468,26 @@ const _updateAvailableComments = async ({ } }; +export const __VERSION__: string = __LIB_VERSION__; + export function setupReview( el: Element, - { apiEndpoint = "/api" }: { apiEndpoint?: string } = {}, + { apiEndpoint: endpoint = "/api" }: { apiEndpoint?: string } = {}, ) { + apiEndpoint = endpoint.endsWith("/") ? endpoint : endpoint + "/"; + const offsets = Array.from( el.querySelectorAll( "[data-original-document-start][data-original-document-end]", ), ); - if (!offsets) return; + if (!offsets) { + console.warn( + "offsets-injection-review not found any offsets to inject, quitting...", + ); + return; + } for (let offset of offsets) { offset.classList.add("review_enabled"); @@ -511,13 +495,11 @@ export function setupReview( e.stopPropagation(); // Prevent bubble so that the document click event won't be triggered _selectOffsetParagraph({ el: e.currentTarget as HTMLElement, - apiEndpoint, }); }); offset.addEventListener("mouseenter", (e) => { _openContextMenu({ el: e.currentTarget as HTMLElement, - apiEndpoint, }); }); offset.addEventListener("mouseleave", () => { @@ -525,33 +507,32 @@ export function setupReview( }); } - _updateAvailableComments({ apiEndpoint }); + // clear cache + commentsCache = undefined; + + _updateAvailableComments(); - if (globalInitialized) return; + if (globalInitialized) { + _closeCommentsPanel(); + console.log("offsets-injection-review has been successfully reset."); + return; + } document.addEventListener("click", () => { _unselectOffsetParagraph(); }); - _registerDialog({ + commentsButton = _registerDialog({ id: "review-comments-button", content: ` `, - actions: new Map([ - [ - "open", - () => - _openCommentsPanel({ - apiEndpoint, - }), - ], - ]), + actions: new Map([["open", () => _openCommentsPanel()]]), }); - _registerDialog({ + commentsPanel = _registerDialog({ id: "review-comments-panel", content: `
@@ -566,15 +547,12 @@ export function setupReview( actions: new Map([["close", () => _closeCommentsPanel()]]), }); - commentsButton = document.querySelector( - "#review-comments-button", - )! as HTMLDivElement; - commentsPanel = document.querySelector( - "#review-comments-panel", - )! as HTMLDivElement; - // initialize comments panel position _closeCommentsPanel(); + console.log( + `offsets-injection-review version ${__VERSION__} has been successfully installed.`, + ); + globalInitialized = true; } diff --git a/frontend/lib/style.css b/frontend/lib/style.css index 649fdd96..0215d34c 100644 --- a/frontend/lib/style.css +++ b/frontend/lib/style.css @@ -73,6 +73,8 @@ iconify-icon.iconify-inline { transition: transform 0.3s; + z-index: 100; + &:hover { transform: translateX(-20%); } @@ -101,6 +103,8 @@ iconify-icon.iconify-inline { transition: transform 0.3s; + z-index: 100; + @media (--mobile) { width: 100vw; height: 100%; diff --git a/frontend/package.json b/frontend/package.json index 188ac35c..3836bbcb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "offsets-injection-review", "private": false, - "version": "0.0.1", + "version": "0.0.6", "license": "Apache-2.0", "type": "module", "files": [ @@ -19,9 +19,11 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "fmt": "prettier --write ." + "fmt": "prettier --write .", + "prepublishOnly": "yarn build" }, "devDependencies": { + "@types/node": "^22.1.0", "autoprefixer": "^10.4.19", "postcss": "^8.4.40", "postcss-preset-env": "^10.0.0", diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 11f02fe2..8e22fa4a 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -1 +1,2 @@ /// +declare const __LIB_VERSION__: string; diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 279abeb6..ddcd5152 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -29,4 +29,7 @@ export default defineConfig({ }, }, }, + define: { + __LIB_VERSION__: JSON.stringify(process.env.npm_package_version), + }, }); diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 0521c145..f7d9f532 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -511,6 +511,13 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/node@^22.1.0": + version "22.1.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.1.0.tgz#6d6adc648b5e03f0e83c78dc788c2b037d0ad94b" + integrity sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw== + dependencies: + undici-types "~6.13.0" + autoprefixer@^10.4.19: version "10.4.19" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f" @@ -964,6 +971,11 @@ typescript@^5.4.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== +undici-types@~6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.13.0.tgz#e3e79220ab8c81ed1496b5812471afd7cf075ea5" + integrity sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg== + update-browserslist-db@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e"