switch to vite + crxjs, million.js and sentry plugin

This commit is contained in:
SethBurkart123
2024-03-21 21:44:14 +11:00
parent 340622c558
commit c8894d7b99
7 changed files with 75 additions and 45 deletions
+1 -2
View File
@@ -20,8 +20,7 @@
"permissions": ["tabs", "notifications", "storage"], "permissions": ["tabs", "notifications", "storage"],
"host_permissions": ["https://newsapi.org/", "*://*/*"], "host_permissions": ["https://newsapi.org/", "*://*/*"],
"background": { "background": {
"service_worker": "src/background.ts", "service_worker": "src/background.ts"
"type": "module"
}, },
"content_scripts": [ "content_scripts": [
{ {
+10 -18
View File
@@ -5,16 +5,8 @@
"description": "BetterSEQTA+ is a browser extension that adds features to SEQTA.", "description": "BetterSEQTA+ is a browser extension that adds features to SEQTA.",
"browserslist": "> 0.5%, last 2 versions, not dead", "browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": { "scripts": {
"dev": "parcel watch manifest.json --host localhost --config @parcel/config-webextension --no-hmr --no-content-hash", "dev": "vite dev",
"dev:firefox": "parcel watch firefox/manifest.json --host localhost --config @parcel/config-webextension --no-hmr --no-content-hash", "build": "vite build",
"build": "parcel build manifest.json --config @parcel/config-webextension --no-content-hash --no-cache",
"build:firefox": "parcel build firefox/manifest.json --config @parcel/config-webextension --no-content-hash --no-cache",
"production": "rimraf ./dist/* && npm-run-all build sentry:sourcemaps sentry:popup-sourcemaps package",
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org betterseqta-plus --project betterseqtaplus-main ./dist && sentry-cli sourcemaps upload --org betterseqta-plus --project betterseqtaplus-main ./dist",
"sentry:popup-sourcemaps": "sentry-cli sourcemaps inject --org betterseqta-plus --project betterseqtaplus-popup ./dist && sentry-cli sourcemaps upload --org betterseqta-plus --project betterseqtaplus-popup ./dist",
"package": "rimraf ./dist/*.map && 7z a -tzip extension.zip ./dist/*" "package": "rimraf ./dist/*.map && 7z a -tzip extension.zip ./dist/*"
}, },
"targets": { "targets": {
@@ -28,41 +20,40 @@
"author": "", "author": "",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@parcel/config-webextension": "^2.11.0", "@crxjs/vite-plugin": "beta",
"@parcel/optimizer-data-url": "^2.11.0", "@vitejs/plugin-react-swc": "^3.6.0",
"@parcel/packager-ts": "2.11.0",
"@parcel/transformer-inline-string": "^2.11.0",
"@parcel/transformer-sass": "2.12.0",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"parcel": "^2.11.0", "parcel": "^2.11.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"process": "^0.11.10", "process": "^0.11.10",
"querystring-es3": "^0.2.1",
"sass": "^1.70.0", "sass": "^1.70.0",
"sass-loader": "^13.3.3", "sass-loader": "^13.3.3",
"url": "^0.11.3" "url": "^0.11.3"
}, },
"dependencies": { "dependencies": {
"@parcel/transformer-raw": "^2.11.0", "@million/lint": "latest",
"@sentry/browser": "^7.100.1", "@sentry/browser": "^7.100.1",
"@sentry/cli": "^2.28.6", "@sentry/cli": "^2.28.6",
"@sentry/react": "^7.100.1", "@sentry/react": "^7.100.1",
"@sentry/vite-plugin": "^2.16.0",
"@types/color": "^3.0.6", "@types/color": "^3.0.6",
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"@types/react": "^18.2.55", "@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19", "@types/react-dom": "^18.2.19",
"@types/sortablejs": "^1.15.7", "@types/sortablejs": "^1.15.7",
"@types/webextension-polyfill": "^0.10.7", "@types/webextension-polyfill": "^0.10.7",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.17", "autoprefixer": "^10.4.17",
"color": "^4.2.3", "color": "^4.2.3",
"dompurify": "^3.0.8", "dompurify": "^3.0.8",
"framer-motion": "^10.18.0", "framer-motion": "^10.18.0",
"install": "^0.13.0", "install": "^0.13.0",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"million": "latest",
"motion": "^10.17.0", "motion": "^10.17.0",
"npm": "^10.4.0", "npm": "^10.4.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.4.35", "preact": "^10.20.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-best-gradient-color-picker": "^3.0.5", "react-best-gradient-color-picker": "^3.0.5",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
@@ -72,6 +63,7 @@
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vite": "^5.2.2",
"webextension-polyfill": "^0.10.0" "webextension-polyfill": "^0.10.0"
} }
} }
+33 -17
View File
@@ -3,13 +3,11 @@ import * as Sentry from "@sentry/browser";
import { animate, spring, stagger } from 'motion' import { animate, spring, stagger } from 'motion'
import loading, { AppendLoadingSymbol } from './seqta/ui/Loading' import loading, { AppendLoadingSymbol } from './seqta/ui/Loading'
import updateVideo from 'url:./resources/update-video.mp4' import updateVideo from './resources/update-video.mp4'
import IconFamily from 'url:./resources/fonts/IconFamily.woff' import IconFamily from './resources/fonts/IconFamily.woff'
import LogoLight from 'url:./resources/icons/betterseqta-light-icon.png' import LogoLight from './resources/icons/betterseqta-light-icon.png'
import LogoLightOutline from 'url:./resources/icons/betterseqta-light-outline.png' import LogoLightOutline from './resources/icons/betterseqta-light-outline.png'
import icon48 from 'url:./resources/icons/icon-48.png' import icon48 from './resources/icons/icon-48.png'
import Popup from 'url:./interface/index.html'
import Color from 'color' import Color from 'color'
import MenuitemSVGKey from './seqta/content/MenuItemSVGKey.json' import MenuitemSVGKey from './seqta/content/MenuItemSVGKey.json'
@@ -24,12 +22,14 @@ import browser from 'webextension-polyfill'
import coursesicon from './seqta/icons/coursesIcon' import coursesicon from './seqta/icons/coursesIcon'
import { delay } from "./seqta/utils/delay" import { delay } from "./seqta/utils/delay"
import { enableCurrentTheme } from './seqta/ui/Themes' import { enableCurrentTheme } from './seqta/ui/Themes'
import * as iframeCSS from "bundle-text:./css/iframe.scss" import iframeCSSURL from "./css/iframe.scss?raw"
import { onError } from './seqta/utils/onError' import { onError } from './seqta/utils/onError'
import stringToHTML from './seqta/utils/stringToHTML' import stringToHTML from './seqta/utils/stringToHTML'
import { updateAllColors } from './seqta/ui/colors/Manager' import { updateAllColors } from './seqta/ui/colors/Manager'
import { updateBgDurations } from './seqta/ui/Animation' import { updateBgDurations } from './seqta/ui/Animation'
import { SettingsResizer } from "./seqta/ui/SettingsResizer"; import { SettingsResizer } from "./seqta/ui/SettingsResizer";
import documentLoadCSS from './css/documentload.scss?inline'
import injectedCSS from './css/injected.scss?inline'
declare global { declare global {
interface Window { interface Window {
@@ -44,6 +44,7 @@ let UserInitalCode = ''
let currentSelectedDate = new Date() let currentSelectedDate = new Date()
let LessonInterval: any let LessonInterval: any
export let DarkMode: boolean export let DarkMode: boolean
let iframeCSS: string
var MenuItemMutation = false var MenuItemMutation = false
var NonSEQTAPage = false var NonSEQTAPage = false
@@ -61,15 +62,25 @@ document.addEventListener(
if (hasSEQTAText && hasSEQTATitle && !IsSEQTAPage) { if (hasSEQTAText && hasSEQTATitle && !IsSEQTAPage) {
IsSEQTAPage = true IsSEQTAPage = true
console.log('[BetterSEQTA+] Verified SEQTA Page') console.log('[BetterSEQTA+] Verified SEQTA Page')
import('./css/documentload.scss') console.log('[BetterSEQTA+] Injecting CSS')
const documentLoadStyle = document.createElement('style')
documentLoadStyle.textContent = documentLoadCSS
document.head.appendChild(documentLoadStyle)
/* console.log(browser.runtime.getURL(documentLoadCSS))
console.log(stringToHTML(`<link rel="stylesheet" href="${browser.runtime.getURL(documentLoadCSS)}" />`))
document.head.appendChild(stringToHTML(`<link rel="stylesheet" href="${browser.runtime.getURL(documentLoadCSS)}" />`).firstChild as HTMLLinkElement)
*/
enableCurrentTheme() enableCurrentTheme()
try { try {
const items = await browser.storage.local.get() as SettingsState const items = await browser.storage.local.get() as SettingsState
if (items.onoff) { if (items.onoff) {
import('./css/injected.scss') const injectedStyle = document.createElement('style')
injectedStyle.textContent = injectedCSS
document.head.appendChild(injectedStyle)
//document.head.appendChild(stringToHTML(`<link rel="stylesheet" href="${browser.runtime.getURL(injectedCSS)}" />`).firstChild as HTMLLinkElement)
} }
main(items) main(items)
@@ -136,7 +147,7 @@ export function OpenWhatsNewPopup() {
let video = document.createElement('video') let video = document.createElement('video')
let source = document.createElement('source') let source = document.createElement('source')
// Perhaps we host this on a server and then grab it instead of having it locally? // Perhaps we host this on a server and then grab it instead of having it locally?
source.setAttribute('src', updateVideo) source.setAttribute('src', browser.runtime.getURL(updateVideo))
source.setAttribute('type', 'video/mp4') source.setAttribute('type', 'video/mp4')
video.autoplay = true video.autoplay = true
video.muted = true video.muted = true
@@ -428,6 +439,11 @@ function removeThemeTagsFromNotices () {
} }
async function updateIframesWithDarkMode(): Promise<void> { async function updateIframesWithDarkMode(): Promise<void> {
if (iframeCSS === undefined) {
//iframeCSS = await (await fetch(iframeCSSURL)).text()
iframeCSS = iframeCSSURL
}
// Load the CSS file to overwrite iFrame default CSS // Load the CSS file to overwrite iFrame default CSS
const cssLink = document.createElement('style') const cssLink = document.createElement('style')
cssLink.classList.add('iframecss') cssLink.classList.add('iframecss')
@@ -819,7 +835,7 @@ function InjectCustomIcons() {
style.innerHTML = ` style.innerHTML = `
@font-face { @font-face {
font-family: 'IconFamily'; font-family: 'IconFamily';
src: url('${IconFamily}') format('woff'); src: url('${browser.runtime.getURL(IconFamily)}') format('woff');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
}` }`
@@ -906,7 +922,7 @@ function addExtensionSettings() {
document.body.appendChild(extensionPopup) document.body.appendChild(extensionPopup)
const extensionIframe: HTMLIFrameElement = document.createElement('iframe') const extensionIframe: HTMLIFrameElement = document.createElement('iframe')
extensionIframe.src = `${Popup}#settings/embedded` extensionIframe.src = `${browser.runtime.getURL('src/interface/index.html')}#settings/embedded`
extensionIframe.id = 'ExtensionIframe' extensionIframe.id = 'ExtensionIframe'
extensionIframe.setAttribute('allowTransparency', 'true') extensionIframe.setAttribute('allowTransparency', 'true')
extensionIframe.setAttribute('excludeDarkCheck', 'true') extensionIframe.setAttribute('excludeDarkCheck', 'true')
@@ -1722,7 +1738,7 @@ function callHomeTimetable(date: string, change?: any) {
var dummyDay = document.createElement('div') var dummyDay = document.createElement('div')
dummyDay.classList.add('day-empty') dummyDay.classList.add('day-empty')
let img = document.createElement('img') let img = document.createElement('img')
img.src = LogoLight img.src = browser.runtime.getURL(LogoLight)
let text = document.createElement('p') let text = document.createElement('p')
text.innerText = 'No lessons available.' text.innerText = 'No lessons available.'
dummyDay.append(img) dummyDay.append(img)
@@ -2275,7 +2291,7 @@ async function loadHomePage() {
} }
const icon = document.querySelector('link[rel*="icon"]')! as HTMLLinkElement const icon = document.querySelector('link[rel*="icon"]')! as HTMLLinkElement
icon.href = icon48 icon.href = browser.runtime.getURL(icon48)
currentSelectedDate = new Date() currentSelectedDate = new Date()
@@ -2764,7 +2780,7 @@ function SendNewsPage() {
articleimage.classList.add('articleimage') articleimage.classList.add('articleimage')
if (newsarticles[i].urlToImage == 'null') { if (newsarticles[i].urlToImage == 'null') {
articleimage.style.backgroundImage = `url(${LogoLightOutline})` articleimage.style.backgroundImage = `url(${browser.runtime.getURL(LogoLightOutline)})`
articleimage.style.width = '20%' articleimage.style.width = '20%'
articleimage.style.margin = '0 7.5%' articleimage.style.margin = '0 7.5%'
} else { } else {
+2 -2
View File
@@ -5,7 +5,7 @@ import './index.css';
import { SettingsContextProvider } from './SettingsContext.js'; import { SettingsContextProvider } from './SettingsContext.js';
import SettingsPage from './SettingsPage.js'; import SettingsPage from './SettingsPage.js';
import browser from 'webextension-polyfill'; import browser from 'webextension-polyfill';
import font from 'url:../resources/fonts/IconFamily.woff' import font from '../resources/fonts/IconFamily.woff'
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
@@ -26,7 +26,7 @@ style.setAttribute("type", "text/css");
style.innerHTML = ` style.innerHTML = `
@font-face { @font-face {
font-family: 'IconFamily'; font-family: 'IconFamily';
src: url('${font}') format('woff'); src: url('${browser.runtime.getURL(font)}') format('woff');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
}`; }`;
+1 -2
View File
@@ -1,4 +1,3 @@
import backgroundPage from 'url:./background/background.html'
import browser from 'webextension-polyfill'; import browser from 'webextension-polyfill';
import { SettingsState } from '../../types/storage'; import { SettingsState } from '../../types/storage';
@@ -14,6 +13,6 @@ export async function appendBackgroundToUI() {
background.id = 'background'; background.id = 'background';
background.classList.add('imageBackground'); background.classList.add('imageBackground');
background.setAttribute('excludeDarkCheck', 'true'); background.setAttribute('excludeDarkCheck', 'true');
background.src = backgroundPage; background.src = browser.runtime.getURL('src/seqta/ui/background/background.html');
parent!.appendChild(background); parent!.appendChild(background);
} }
+4 -4
View File
@@ -4,8 +4,8 @@ import { lightenAndPaleColor } from './lightenAndPaleColor';
import ColorLuminance from './ColorLuminance'; import ColorLuminance from './ColorLuminance';
import { SettingsState } from '../../../types/storage'; import { SettingsState } from '../../../types/storage';
import darkLogo from 'url:../../../resources/icons/betterseqta-light-full.png'; import darkLogo from '../../../resources/icons/betterseqta-light-full.png';
import lightLogo from 'url:../../../resources/icons/betterseqta-dark-full.png'; import lightLogo from '../../../resources/icons/betterseqta-dark-full.png';
// Helper functions // Helper functions
const setCSSVar = (varName: any, value: any) => document.documentElement.style.setProperty(varName, value); const setCSSVar = (varName: any, value: any) => document.documentElement.style.setProperty(varName, value);
@@ -39,10 +39,10 @@ export function updateAllColors(storedSetting: any, newColor = null) {
let modeProps = {}; let modeProps = {};
if (DarkMode !== null) { if (DarkMode !== null) {
modeProps = DarkMode ? { modeProps = DarkMode ? {
'--betterseqta-logo': `url(${darkLogo})` '--betterseqta-logo': `url(${browser.runtime.getURL(darkLogo)})`
} : { } : {
'--better-pale': lightenAndPaleColor(selectedColor), '--better-pale': lightenAndPaleColor(selectedColor),
'--betterseqta-logo': `url(${lightLogo})` '--betterseqta-logo': `url(${browser.runtime.getURL(lightLogo)})`
}; };
if (DarkMode) { if (DarkMode) {
+24
View File
@@ -0,0 +1,24 @@
import { defineConfig } from 'vite'
import { crx } from '@crxjs/vite-plugin'
import million from "million/compiler"
import manifest from './manifest.json'
import react from '@vitejs/plugin-react-swc'
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig({
plugins: [
react(),
million.vite({}),
crx({ manifest }),
sentryVitePlugin({
org: process.env.SENTRY_ORG,
project: 'betterseqtaplus-main',
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
sentryVitePlugin({
org: process.env.SENTRY_ORG,
project: 'betterseqtaplus-popup',
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
],
})