Initial commit
This commit is contained in:
12
pages/popup/index.html
Normal file
12
pages/popup/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Popup</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app-container"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
39
pages/popup/package.json
Normal file
39
pages/popup/package.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "@extension/popup",
|
||||
"version": "0.5.0",
|
||||
"description": "chrome extension - popup",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"sideEffects": true,
|
||||
"files": [
|
||||
"dist/**"
|
||||
],
|
||||
"scripts": {
|
||||
"clean:node_modules": "pnpx rimraf node_modules",
|
||||
"clean:turbo": "rimraf .turbo",
|
||||
"clean": "pnpm clean:turbo && pnpm clean:node_modules",
|
||||
"build": "vite build",
|
||||
"dev": "vite build --mode development",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "pnpm lint --fix",
|
||||
"format": "prettier . --write --ignore-path ../../.prettierignore",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@extension/shared": "workspace:*",
|
||||
"@extension/storage": "workspace:*",
|
||||
"@extension/i18n": "workspace:*",
|
||||
"@extension/ui": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@extension/tailwindcss-config": "workspace:*",
|
||||
"@extension/tsconfig": "workspace:*",
|
||||
"@extension/vite-config": "workspace:*"
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"tailwindcss": {},
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
124
pages/popup/public/logo_vertical.svg
Normal file
124
pages/popup/public/logo_vertical.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 58 KiB |
117
pages/popup/public/logo_vertical_dark.svg
Normal file
117
pages/popup/public/logo_vertical_dark.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 60 KiB |
30
pages/popup/src/Popup.css
Normal file
30
pages/popup/src/Popup.css
Normal file
@@ -0,0 +1,30 @@
|
||||
.App {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 50vmin;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
code {
|
||||
background: rgba(148, 163, 184, 0.5);
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
63
pages/popup/src/Popup.tsx
Normal file
63
pages/popup/src/Popup.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import '@src/Popup.css';
|
||||
import { t } from '@extension/i18n';
|
||||
import { PROJECT_URL_OBJECT, useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
|
||||
import { exampleThemeStorage } from '@extension/storage';
|
||||
import { cn, ErrorDisplay, LoadingSpinner, ToggleButton } from '@extension/ui';
|
||||
|
||||
const notificationOptions = {
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('icon-34.png'),
|
||||
title: 'Injecting content script error',
|
||||
message: 'You cannot inject script here!',
|
||||
} as const;
|
||||
|
||||
const Popup = () => {
|
||||
const { isLight } = useStorage(exampleThemeStorage);
|
||||
const logo = isLight ? 'popup/logo_vertical.svg' : 'popup/logo_vertical_dark.svg';
|
||||
|
||||
const goGithubSite = () => chrome.tabs.create(PROJECT_URL_OBJECT);
|
||||
|
||||
const injectContentScript = async () => {
|
||||
const [tab] = await chrome.tabs.query({ currentWindow: true, active: true });
|
||||
|
||||
if (tab.url!.startsWith('about:') || tab.url!.startsWith('chrome:')) {
|
||||
chrome.notifications.create('inject-error', notificationOptions);
|
||||
}
|
||||
|
||||
await chrome.scripting
|
||||
.executeScript({
|
||||
target: { tabId: tab.id! },
|
||||
files: ['/content-runtime/example.iife.js', '/content-runtime/all.iife.js'],
|
||||
})
|
||||
.catch(err => {
|
||||
// Handling errors related to other paths
|
||||
if (err.message.includes('Cannot access a chrome:// URL')) {
|
||||
chrome.notifications.create('inject-error', notificationOptions);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn('App', isLight ? 'bg-slate-50' : 'bg-gray-800')}>
|
||||
<header className={cn('App-header', isLight ? 'text-gray-900' : 'text-gray-100')}>
|
||||
<button onClick={goGithubSite}>
|
||||
<img src={chrome.runtime.getURL(logo)} className="App-logo" alt="logo" />
|
||||
</button>
|
||||
<p>
|
||||
Edit <code>pages/popup/src/Popup.tsx</code>
|
||||
</p>
|
||||
<button
|
||||
className={cn(
|
||||
'mt-4 rounded px-4 py-1 font-bold shadow hover:scale-105',
|
||||
isLight ? 'bg-blue-200 text-black' : 'bg-gray-700 text-white',
|
||||
)}
|
||||
onClick={injectContentScript}>
|
||||
{t('injectButton')}
|
||||
</button>
|
||||
<ToggleButton>{t('toggleTheme')}</ToggleButton>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withErrorBoundary(withSuspense(Popup, <LoadingSpinner />), ErrorDisplay);
|
||||
6
pages/popup/src/index.css
Normal file
6
pages/popup/src/index.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@import '@extension/ui/global.css';
|
||||
|
||||
body {
|
||||
width: 300px;
|
||||
height: 260px;
|
||||
}
|
||||
15
pages/popup/src/index.tsx
Normal file
15
pages/popup/src/index.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import '@src/index.css';
|
||||
import Popup from '@src/Popup';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
const init = () => {
|
||||
const appContainer = document.querySelector('#app-container');
|
||||
if (!appContainer) {
|
||||
throw new Error('Can not find #app-container');
|
||||
}
|
||||
const root = createRoot(appContainer);
|
||||
|
||||
root.render(<Popup />);
|
||||
};
|
||||
|
||||
init();
|
||||
5
pages/popup/tailwind.config.ts
Normal file
5
pages/popup/tailwind.config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { withUI } from '@extension/ui';
|
||||
|
||||
export default withUI({
|
||||
content: ['index.html', 'src/**/*.tsx'],
|
||||
});
|
||||
11
pages/popup/tsconfig.json
Normal file
11
pages/popup/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "@extension/tsconfig/base",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@src/*": ["src/*"]
|
||||
},
|
||||
"types": ["chrome", "node"]
|
||||
},
|
||||
"include": ["src", "vite.config.mts", "tailwind.config.ts"]
|
||||
}
|
||||
17
pages/popup/vite.config.mts
Normal file
17
pages/popup/vite.config.mts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { resolve } from 'node:path';
|
||||
import { withPageConfig } from '@extension/vite-config';
|
||||
|
||||
const rootDir = resolve(import.meta.dirname);
|
||||
const srcDir = resolve(rootDir, 'src');
|
||||
|
||||
export default withPageConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@src': srcDir,
|
||||
},
|
||||
},
|
||||
publicDir: resolve(rootDir, 'public'),
|
||||
build: {
|
||||
outDir: resolve(rootDir, '..', '..', 'dist', 'popup'),
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user