diff --git a/src/css/documentload.scss b/src/css/documentload.scss index 720dfb3d..cbd51ac7 100644 --- a/src/css/documentload.scss +++ b/src/css/documentload.scss @@ -94,3 +94,57 @@ body:has(.outside-container:not(.hide)) background: var(--text-primary) !important; color: var(--theme-primary) !important; } +.fixed-tooltip { + display: inline-block; + z-index: 5 !important; + width: 28px; + background: none; + box-shadow: none; + padding: 2px; + position: absolute; +} +.fixed-tooltip svg { + fill: var(--theme-primary); +} +.tooltiptext-fixed { + width: 120px; + transform: scale(0); + transition: transform 0.2s; + transform-origin: top; + background: var(--background-primary); + color: var(--text-primary); + text-align: center; + border-radius: 6px; + padding: 2px; + position: fixed; + z-index: 1000; + top: 0; + left: 0; + margin-left: -62px; +} +.tooltiptext-fixed::after { + content: ""; + position: absolute; + bottom: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: transparent transparent var(--text-primary) transparent; +} +.tooltiptext-fixed.show { + transform: scale(1); + transform-origin: top; + transition: transform 0.2s; +} +.tooltiptext-fixed p:hover { + cursor: pointer; + background: rgba(0, 0, 0, 0.3) !important; + transition: 200ms; +} +.tooltiptext-fixed p { + border-radius: 8px !important; + padding-top: 2px; + padding-bottom: 2px; + margin: 2px; +} diff --git a/src/css/injected.scss b/src/css/injected.scss index 34ea5b09..539665ad 100644 --- a/src/css/injected.scss +++ b/src/css/injected.scss @@ -2733,12 +2733,13 @@ body { .menuShown #menuToggle .hamburger-line:nth-child(3) { transform: translateY(-6px) rotate(-45deg); } -.day-empty { +div.day-empty { display: flex; align-items: center; height: 15em; width: 100%; border-radius: 16px 0; + padding: 0 !important; img { margin: 20px; diff --git a/src/resources/update-video.mp4 b/src/resources/update-video.mp4 index 8722969a..95051212 100644 Binary files a/src/resources/update-video.mp4 and b/src/resources/update-video.mp4 differ diff --git a/src/seqta/utils/Loaders/LoadHomePage.ts b/src/seqta/utils/Loaders/LoadHomePage.ts index 75dcee2a..18bbe1ab 100644 --- a/src/seqta/utils/Loaders/LoadHomePage.ts +++ b/src/seqta/utils/Loaders/LoadHomePage.ts @@ -13,6 +13,7 @@ import { CreateCustomShortcutDiv } from "@/seqta/utils/CreateEnable/CreateCustom import { CreateElement } from "@/seqta/utils/CreateEnable/CreateElement"; import { FilterUpcomingAssessments } from "@/seqta/utils/FilterUpcomingAssessments"; import { getMockNotices } from "@/seqta/ui/dev/hideSensitiveContent"; +import { setupFixedTooltips } from "@/seqta/utils/fixedTooltip"; let LessonInterval: any; let currentSelectedDate = new Date(); @@ -628,12 +629,13 @@ function openNoticeModal( // Get the current scale applied to the source element and compensate for it const computedStyle = getComputedStyle(sourceElement); const transform = computedStyle.transform; - let scaleX = 1, scaleY = 1; - - if (transform && transform !== 'none') { + let scaleX = 1, + scaleY = 1; + + if (transform && transform !== "none") { const matrix = transform.match(/matrix.*\((.+)\)/); if (matrix) { - const values = matrix[1].split(', '); + const values = matrix[1].split(", "); scaleX = parseFloat(values[0]); scaleY = parseFloat(values[3]); } @@ -642,11 +644,11 @@ function openNoticeModal( // Apply inverse scale to get true original dimensions and positions const newSourceWidth = newSourceRect.width / scaleX; const newSourceHeight = newSourceRect.height / scaleY; - + // Calculate position shift due to center-based scaling const deltaX = (newSourceWidth - newSourceRect.width) / 2; const deltaY = (newSourceHeight - newSourceRect.height) / 2; - + const newSourceLeft = newSourceRect.left - deltaX; const newSourceTop = newSourceRect.top - deltaY; @@ -965,7 +967,7 @@ function makeLessonDiv(lesson: any, num: number) { .join(""); lessonString += ` -
+
@@ -975,8 +977,9 @@ function makeLessonDiv(lesson: any, num: number) { } lessonString += "
"; - - return stringToHTML(lessonString); + const element = stringToHTML(lessonString); + setupFixedTooltips(element); + return element; } function buildAssessmentURL(programmeID: any, metaID: any, itemID = "") { diff --git a/src/seqta/utils/Whatsnew.ts b/src/seqta/utils/Whatsnew.ts index 7e639145..49f92394 100644 --- a/src/seqta/utils/Whatsnew.ts +++ b/src/seqta/utils/Whatsnew.ts @@ -41,7 +41,7 @@ export function OpenWhatsNewPopup() { let imagecont = document.createElement("div"); imagecont.classList.add("whatsnewImgContainer"); - /* let video = document.createElement("video"); + let video = document.createElement("video"); let source = document.createElement("source"); source.setAttribute( @@ -53,13 +53,13 @@ export function OpenWhatsNewPopup() { video.loop = true; video.appendChild(source); video.classList.add("whatsnewImg"); - imagecont.appendChild(video); */ + imagecont.appendChild(video); - let whatsnewimg = document.createElement("img"); + /* let whatsnewimg = document.createElement("img"); //whatsnewimg.src = "https://raw.githubusercontent.com/BetterSEQTA/BetterSEQTA-Plus/main/src/resources/update-image.webp"; whatsnewimg.src = browser.runtime.getURL('../../resources/update-image.webp'); whatsnewimg.classList.add("whatsnewImg"); - imagecont.appendChild(whatsnewimg); + imagecont.appendChild(whatsnewimg); */ let textcontainer = document.createElement("div"); textcontainer.classList.add("whatsnewTextContainer"); @@ -77,6 +77,7 @@ export function OpenWhatsNewPopup() {
  • Fixed 12-hour time not applying correctly in timetable
  • Fixed background flickering on page load
  • Fixed homepage lessons not properly changing days
  • +
  • Performance improvements for global search
  • Performance improvements across the extension
  • Other bug fixes and improvements
  • diff --git a/src/seqta/utils/fixedTooltip.ts b/src/seqta/utils/fixedTooltip.ts new file mode 100644 index 00000000..c3349eed --- /dev/null +++ b/src/seqta/utils/fixedTooltip.ts @@ -0,0 +1,59 @@ +export function setupFixedTooltips(root: Document | HTMLElement = document) { + const elements = root.querySelectorAll(".fixed-tooltip"); + elements.forEach((tooltip) => { + const text = tooltip.querySelector(".tooltiptext"); + if (!text) return; + tooltip.removeChild(text); + text.classList.add("tooltiptext-fixed"); + + let hideTimeout: number | undefined; + + const show = () => { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = undefined; + } + document.body.appendChild(text); + const rect = tooltip.getBoundingClientRect(); + text.style.left = `${rect.left + rect.width / 2}px`; + text.style.top = `${rect.bottom + 5}px`; + requestAnimationFrame(() => text.classList.add("show")); + }; + + const scheduleHide = () => { + hideTimeout = window.setTimeout(() => { + text.classList.remove("show"); + setTimeout(() => { + if (text.parentElement === document.body) { + document.body.removeChild(text); + } + }, 200); + }, 300); + }; + + tooltip.addEventListener("mouseenter", show); + tooltip.addEventListener("mouseleave", scheduleHide); + tooltip.addEventListener("blur", scheduleHide); + tooltip.addEventListener("click", scheduleHide); + + text.addEventListener("mouseenter", () => { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = undefined; + } + }); + text.addEventListener("mouseleave", scheduleHide); + text.addEventListener("click", () => { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = undefined; + } + text.classList.remove("show"); + setTimeout(() => { + if (text.parentElement === document.body) { + document.body.removeChild(text); + } + }, 200); + }); + }); +}