mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
switch to vite + crxjs, million.js and sentry plugin
This commit is contained in:
+1
-2
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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,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,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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user