initial commit
This commit is contained in:
commit
c902bc9236
30 changed files with 4091 additions and 0 deletions
28
.gitignore
vendored
Executable file
28
.gitignore
vendored
Executable file
|
@ -0,0 +1,28 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# Config files
|
||||
.webextrc
|
||||
.webextrc.*
|
33
package.json
Executable file
33
package.json
Executable file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "ext-test",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "TARGET=firefox vite",
|
||||
"build-firefox": "tsc && TARGET=firefox vite build",
|
||||
"build": "tsc && vite build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@fontsource/roboto": "^5.0.13",
|
||||
"@mui/icons-material": "^5.16.4",
|
||||
"@mui/material": "^5.16.4",
|
||||
"@mui/styled-engine-sc": "6.0.0-alpha.18",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"styled-components": "^6.1.12",
|
||||
"wouter": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"@types/webextension-polyfill": "^0.10.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"typescript": "^5.3.2",
|
||||
"vite": "^5.0.0",
|
||||
"vite-plugin-web-extension": "^4.0.0",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
}
|
||||
}
|
3523
pnpm-lock.yaml
Executable file
3523
pnpm-lock.yaml
Executable file
File diff suppressed because it is too large
Load diff
29
public/icon-with-shadow.svg
Executable file
29
public/icon-with-shadow.svg
Executable file
|
@ -0,0 +1,29 @@
|
|||
<svg width="585" height="585" viewBox="0 0 585 585" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="mask0_2_13" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="585" height="585">
|
||||
<path d="M585 292.5C585 454.043 454.043 585 292.5 585C130.957 585 0 454.043 0 292.5C0 130.957 130.957 0 292.5 0C454.043 0 585 130.957 585 292.5Z" fill="url(#paint0_radial_2_13)"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_2_13)">
|
||||
<path d="M585 292.5C585 454.043 454.043 585 292.5 585C130.957 585 0 454.043 0 292.5C0 130.957 130.957 0 292.5 0C454.043 0 585 130.957 585 292.5Z" fill="url(#paint1_linear_2_13)"/>
|
||||
</g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M281 182C308.614 182 331 159.614 331 132L401 132C417.569 132 431 145.431 431 162V232.158C456.744 234.195 477 255.732 477 282C477 308.268 456.744 329.805 431 331.842V402C431 418.569 417.569 432 401 432H331C331 459.614 308.614 482 281 482C253.386 482 231 459.614 231 432H161C144.431 432 131 418.569 131 402L131 332C158.614 332 181 309.614 181 282C181 254.386 158.614 232 131 232L131 162C131 145.431 144.431 132 161 132L231 132C231 159.614 253.386 182 281 182Z" fill="url(#paint2_linear_2_13)"/>
|
||||
<path d="M364.115 102.193L234.791 127.497C232.666 127.913 231.092 129.712 230.964 131.871L223.009 266.034C222.821 269.194 225.728 271.647 228.816 270.936L264.822 262.638C268.191 261.862 271.235 264.825 270.543 268.208L259.845 320.515C259.125 324.035 262.435 327.046 265.878 326.001L288.117 319.254C291.565 318.209 294.877 321.228 294.148 324.751L277.148 406.914C276.084 412.053 282.93 414.856 285.785 410.449L287.692 407.507L393.073 197.505C394.838 193.989 391.795 189.98 387.927 190.725L350.865 197.867C347.382 198.538 344.419 195.299 345.402 191.897L369.592 108.161C370.576 104.753 367.602 101.511 364.115 102.193Z" fill="url(#paint3_linear_2_13)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_2_13" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(292.958 292.042) rotate(90) scale(292.958 292.958)">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint1_linear_2_13" x1="216.056" y1="140.528" x2="477.969" y2="374.671" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#41D1FF"/>
|
||||
<stop offset="1" stop-color="#BD34FE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_2_13" x1="116.5" y1="223" x2="414.5" y2="482" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#41D1FF"/>
|
||||
<stop offset="1" stop-color="#BD34FE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_2_13" x1="270.74" y1="109.063" x2="309.973" y2="378.586" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFEA83"/>
|
||||
<stop offset="0.0833333" stop-color="#FFDD35"/>
|
||||
<stop offset="1" stop-color="#FFA800"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
BIN
public/icon/128.png
Executable file
BIN
public/icon/128.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
public/icon/16.png
Executable file
BIN
public/icon/16.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 698 B |
BIN
public/icon/32.png
Executable file
BIN
public/icon/32.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
public/icon/48.png
Executable file
BIN
public/icon/48.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
BIN
public/icon/96.png
Executable file
BIN
public/icon/96.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
7
src/background.ts
Executable file
7
src/background.ts
Executable file
|
@ -0,0 +1,7 @@
|
|||
import browser from "webextension-polyfill";
|
||||
|
||||
console.log("Hello from the background!");
|
||||
|
||||
browser.runtime.onInstalled.addListener((details) => {
|
||||
console.log("Extension installed:", details);
|
||||
});
|
31
src/components/MenuBar.tsx
Executable file
31
src/components/MenuBar.tsx
Executable file
|
@ -0,0 +1,31 @@
|
|||
import { IconButton, Toolbar, Typography } from '@mui/material';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Box from '@mui/material/Box';
|
||||
import MenuIcon from '@mui/icons-material/Menu'
|
||||
import { useContext } from 'react';
|
||||
import { DrawerOpenContext } from '../contexts/DrawerOpenContext';
|
||||
|
||||
export default function MenuBar() {
|
||||
const {drawerOpen, setDrawerOpen} = useContext(DrawerOpenContext)
|
||||
return (
|
||||
<Box sx={{flexGrow: 1}}>
|
||||
<AppBar position="static">
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
size='large'
|
||||
edge='start'
|
||||
color='inherit'
|
||||
aria-label='menu'
|
||||
sx={{ mr: 2 }}
|
||||
onClick={() => setDrawerOpen(!drawerOpen)}
|
||||
>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
|
||||
Tamakis Homepage
|
||||
</Typography>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</Box>
|
||||
)
|
||||
}
|
18
src/components/linkcard.tsx
Executable file
18
src/components/linkcard.tsx
Executable file
|
@ -0,0 +1,18 @@
|
|||
import { Card, CardActionArea, CardContent, Typography } from "@mui/material";
|
||||
|
||||
export default function LinkCard({title = "None", subtitle = "None", hyperlink = "https://example.com"}) {
|
||||
return (
|
||||
<Card sx={{ maxWidth: 345, minWidth: 256 }}>
|
||||
<CardActionArea href={hyperlink}>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="div">
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{subtitle}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
</Card>
|
||||
)
|
||||
}
|
28
src/components/menudrawer.tsx
Normal file
28
src/components/menudrawer.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { useContext } from "react";
|
||||
import { DrawerOpenContext } from "../contexts/DrawerOpenContext";
|
||||
import { Drawer, List, Box, ListItem, ListItemButton, ListItemText, Typography } from "@mui/material";
|
||||
import { CurrentPageContext } from "../contexts/CurrentPageContext";
|
||||
|
||||
export default function MenuDrawer() {
|
||||
const {drawerOpen, setDrawerOpen} = useContext(DrawerOpenContext)
|
||||
const {currentPage, setCurrentPage} = useContext(CurrentPageContext)
|
||||
|
||||
return (
|
||||
<Drawer open={drawerOpen} onClose={() => setDrawerOpen(!drawerOpen)}>
|
||||
<Box role='presentation' sx={{width: 250}} onClick={() => setDrawerOpen(!drawerOpen )}>
|
||||
<List>
|
||||
<ListItem key='home' disablePadding>
|
||||
<ListItemButton onClick={() => setCurrentPage('home')}>
|
||||
<ListItemText primary='Home' />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
<ListItem key='edit' disablePadding>
|
||||
<ListItemButton onClick={() => setCurrentPage('edit')}>
|
||||
<ListItemText primary='Edit' />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Box>
|
||||
</Drawer>
|
||||
)
|
||||
}
|
25
src/components/settingsPage.tsx
Normal file
25
src/components/settingsPage.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { Grid, styled, TextField, Typography } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
|
||||
const FormGrid = styled(Grid)(() => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}))
|
||||
|
||||
export default function SettingsPage() {
|
||||
const [data, setData] = useState([{title: '', subtitle: '', hyperlink: ''}])
|
||||
|
||||
return (
|
||||
<Grid container spacing={3} sx={{mt: 4, mb: 4}}>
|
||||
<FormGrid item xs={12} md={6}>
|
||||
<TextField
|
||||
required
|
||||
id='text'
|
||||
label='text'
|
||||
name='text'
|
||||
onChange={e => console.log(e.target.name)}
|
||||
/>
|
||||
</FormGrid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
24
src/contexts/CurrentPageContext.tsx
Normal file
24
src/contexts/CurrentPageContext.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { ContainerProps } from "@mui/material"
|
||||
import { createContext, Dispatch, SetStateAction, useState } from "react"
|
||||
|
||||
type CurrentPageContextType = {
|
||||
currentPage: string,
|
||||
setCurrentPage: Dispatch<SetStateAction<string>>
|
||||
}
|
||||
|
||||
const CurrentPageContext = createContext<CurrentPageContextType>({
|
||||
currentPage: 'home',
|
||||
setCurrentPage: () => {}
|
||||
})
|
||||
|
||||
const CurrentPageContextProvider = (props: ContainerProps) => {
|
||||
const [currentPage, setCurrentPage] = useState('home')
|
||||
|
||||
return (
|
||||
<CurrentPageContext.Provider value={{currentPage, setCurrentPage}}>
|
||||
{props.children}
|
||||
</CurrentPageContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export {CurrentPageContext, CurrentPageContextProvider}
|
25
src/contexts/DrawerOpenContext.tsx
Normal file
25
src/contexts/DrawerOpenContext.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
import { ContainerProps } from "@mui/material";
|
||||
import { createContext, Dispatch, SetStateAction, useState } from "react";
|
||||
|
||||
type DrawerOpenContextType = {
|
||||
drawerOpen: boolean,
|
||||
setDrawerOpen: Dispatch<SetStateAction<boolean>>
|
||||
}
|
||||
|
||||
const DrawerOpenContext = createContext<DrawerOpenContextType>({
|
||||
drawerOpen: false,
|
||||
setDrawerOpen: () => {},
|
||||
})
|
||||
|
||||
const DrawerOpenContextProvider = (props: ContainerProps) => {
|
||||
const [drawerOpen, setDrawerOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<DrawerOpenContext.Provider value={{drawerOpen, setDrawerOpen}}>
|
||||
{props.children}
|
||||
</DrawerOpenContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export {DrawerOpenContext, DrawerOpenContextProvider}
|
24
src/data/sites.json
Executable file
24
src/data/sites.json
Executable file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"sites": [
|
||||
{
|
||||
"title": "Sonarr",
|
||||
"subtitle": "A tracker for all your series",
|
||||
"hyperlink": "https://sonarr.local.thanalan.cat-enby.club"
|
||||
},
|
||||
{
|
||||
"title": "Radarr",
|
||||
"subtitle": "A tracker for all your movies",
|
||||
"hyperlink": "https://radarr.local.thanalan.cat-enby.club"
|
||||
},
|
||||
{
|
||||
"title": "qbittorrent",
|
||||
"subtitle": "Torrent Software powered by qt",
|
||||
"hyperlink": "https://qb.local.thanalan.cat-enby.club"
|
||||
},
|
||||
{
|
||||
"title": "sabnzb",
|
||||
"subtitle": "Usenet client",
|
||||
"hyperlink": "https://sab.local.thanalan.cat-enby.club"
|
||||
}
|
||||
]
|
||||
}
|
13
src/index.html
Executable file
13
src/index.html
Executable file
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React + TS</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="./index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
26
src/index.tsx
Executable file
26
src/index.tsx
Executable file
|
@ -0,0 +1,26 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './site/App'
|
||||
import MenuBar from './components/MenuBar';
|
||||
import '@fontsource/roboto/300.css';
|
||||
import '@fontsource/roboto/400.css';
|
||||
import '@fontsource/roboto/500.css';
|
||||
import '@fontsource/roboto/700.css';
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import { CssBaseline } from '@mui/material';
|
||||
import theme from './theme';
|
||||
import { DrawerOpenContextProvider } from './contexts/DrawerOpenContext';
|
||||
import { CurrentPageContextProvider } from './contexts/CurrentPageContext';
|
||||
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline>
|
||||
<DrawerOpenContextProvider>
|
||||
<CurrentPageContextProvider>
|
||||
<App />
|
||||
</CurrentPageContextProvider>
|
||||
</DrawerOpenContextProvider>
|
||||
</CssBaseline>
|
||||
</ThemeProvider>
|
||||
)
|
28
src/manifest.json
Executable file
28
src/manifest.json
Executable file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"{{chrome}}.manifest_version": 3,
|
||||
"{{firefox}}.manifest_version": 2,
|
||||
"icons": {
|
||||
"16": "icon/16.png",
|
||||
"32": "icon/32.png",
|
||||
"48": "icon/48.png",
|
||||
"96": "icon/96.png",
|
||||
"128": "icon/128.png"
|
||||
},
|
||||
"{{chrome}}.action": {
|
||||
"default_popup": "src/popup.html"
|
||||
},
|
||||
"{{firefox}}.settings_overrides": {
|
||||
"homepage": "src/index.html"
|
||||
},
|
||||
"{{firefox}}.browser_action": {
|
||||
"default_popup":"src/popup.html"
|
||||
},
|
||||
"chrome_url_overrides": {
|
||||
"newtab": "src/index.html"
|
||||
},
|
||||
"background": {
|
||||
"{{chrome}}.service_worker": "src/background.ts",
|
||||
"{{firefox}}.scripts": ["src/background.ts"]
|
||||
},
|
||||
"permissions": ["storage"]
|
||||
}
|
13
src/popup.html
Normal file
13
src/popup.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Popup</title>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
|
||||
<script type="module" src="./popup.tsx"></script>
|
||||
</html>
|
9
src/popup.tsx
Executable file
9
src/popup.tsx
Executable file
|
@ -0,0 +1,9 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import Popup from "./popup/Popup";
|
||||
|
||||
ReactDOM.createRoot(document.body).render(
|
||||
<React.StrictMode>
|
||||
<Popup />
|
||||
</React.StrictMode>
|
||||
);
|
37
src/popup/Popup.css
Executable file
37
src/popup/Popup.css
Executable file
|
@ -0,0 +1,37 @@
|
|||
div {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: white;
|
||||
opacity: 0.7;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
background-color: #ffffff24;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.test {
|
||||
color: white
|
||||
}
|
33
src/popup/Popup.tsx
Executable file
33
src/popup/Popup.tsx
Executable file
|
@ -0,0 +1,33 @@
|
|||
import { useEffect } from 'react';
|
||||
import "./Popup.css";
|
||||
import Sites from "@Data/sites.json"
|
||||
import React from 'react';
|
||||
|
||||
export default function() {
|
||||
const [test, setTest] = React.useState(
|
||||
JSON.parse(localStorage.getItem('test') as string) || false
|
||||
)
|
||||
|
||||
const handleToggle = () => {
|
||||
localStorage.setItem('test', JSON.stringify(!test))
|
||||
setTest(!test)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Hello from the popup!");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<img src="/icon-with-shadow.svg" />
|
||||
<h1>vite-plugin-web-extension</h1>
|
||||
<ul>
|
||||
{Sites.sites.map(site => (
|
||||
<li><a href={site.hyperlink}>{site.title}</a></li>
|
||||
))}
|
||||
</ul>
|
||||
<button onClick={handleToggle}>Test</button>
|
||||
{test &&<div className='test'>Test</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
52
src/site/App.tsx
Executable file
52
src/site/App.tsx
Executable file
|
@ -0,0 +1,52 @@
|
|||
import Sites from '@Data/sites.json'
|
||||
import { Box, Button, debounce, FormLabel, Grid, OutlinedInput, styled, TextField, Typography } from '@mui/material'
|
||||
import React, { useContext, useState } from 'react'
|
||||
import MenuBar from '../components/MenuBar'
|
||||
import LinkCard from '../components/linkcard'
|
||||
import { Link, Route } from 'wouter'
|
||||
import MenuDrawer from '../components/menudrawer'
|
||||
import { CurrentPageContext } from '../contexts/CurrentPageContext'
|
||||
import SettingsPage from '../components/settingsPage'
|
||||
|
||||
const useLocalStorage = (storageKey: string, fallbackState: any) => {
|
||||
const [value, setValue] = React.useState(
|
||||
JSON.parse(localStorage.getItem(storageKey) as string) ?? fallbackState
|
||||
)
|
||||
React.useEffect(() => {
|
||||
localStorage.setItem(storageKey, JSON.stringify(value))
|
||||
}, [value, setValue])
|
||||
|
||||
return [value, setValue]
|
||||
}
|
||||
|
||||
function App() {
|
||||
const {currentPage, setCurrentPage} = useContext(CurrentPageContext)
|
||||
const [drawerOpen, setDrawerOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuBar />
|
||||
<MenuDrawer />
|
||||
<Box sx={{m: 4}} maxWidth="lg">
|
||||
{currentPage === 'home' ? (
|
||||
<Grid container spacing={2}>
|
||||
{Sites.sites.map(site => (
|
||||
<Grid item key={site.title}>
|
||||
<LinkCard
|
||||
title={site.title}
|
||||
subtitle={site.subtitle}
|
||||
hyperlink={site.hyperlink}
|
||||
/>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
): null}
|
||||
{currentPage === 'edit' ? (
|
||||
<SettingsPage />
|
||||
): null}
|
||||
</Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
18
src/theme.ts
Executable file
18
src/theme.ts
Executable file
|
@ -0,0 +1,18 @@
|
|||
import { createTheme } from "@mui/material";
|
||||
import { red } from "@mui/material/colors";
|
||||
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#556cd6',
|
||||
},
|
||||
secondary: {
|
||||
main: '#19857b',
|
||||
},
|
||||
error: {
|
||||
main: red.A400,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default theme
|
1
src/vite-env.d.ts
vendored
Executable file
1
src/vite-env.d.ts
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
26
tsconfig.json
Executable file
26
tsconfig.json
Executable file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"allowJs": false,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@Data/*": [
|
||||
"./src/data/*"
|
||||
],
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
9
tsconfig.node.json
Executable file
9
tsconfig.node.json
Executable file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
31
vite.config.ts
Executable file
31
vite.config.ts
Executable file
|
@ -0,0 +1,31 @@
|
|||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import webExtension, { readJsonFile } from "vite-plugin-web-extension";
|
||||
import path from 'path'
|
||||
|
||||
function generateManifest() {
|
||||
const manifest = readJsonFile("src/manifest.json");
|
||||
const pkg = readJsonFile("package.json");
|
||||
return {
|
||||
name: pkg.name,
|
||||
description: pkg.description,
|
||||
version: pkg.version,
|
||||
...manifest,
|
||||
};
|
||||
}
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
webExtension({
|
||||
manifest: generateManifest,
|
||||
browser: process.env.TARGET || "chrome",
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@Data": path.resolve(__dirname, './src/data')
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue