From fbd3c680f0216622c7d3c728460fb4cb4bc4f364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kiljan=CC=81czyk?= Date: Mon, 25 Mar 2024 12:13:31 +0100 Subject: [PATCH] Update .prettierrc --- .github/workflows/ci.yml | 48 +++--- .prettierrc | 16 +- README.md | 30 ++-- eslint.config.js | 30 ++-- index.html | 22 +-- manifest.json | 62 ++++---- package.json | 106 ++++++------- src/background/index.ts | 6 +- src/common/chrome-api-wrapper.ts | 54 +++---- src/common/types/scraper.ts | 4 +- src/content/index.ts | 22 +-- src/popup/AppShell/AppShell.css | 8 +- src/popup/AppShell/AppShell.tsx | 10 +- .../components/PopupContent/PopupContent.css | 8 +- .../components/PopupContent/PopupContent.tsx | 10 +- .../components/PopupHeader/PopupHeader.css | 16 +- .../components/PopupHeader/PopupHeader.tsx | 14 +- src/popup/features/HomePage/HomePage.css | 2 +- src/popup/features/HomePage/HomePage.tsx | 142 +++++++++--------- src/popup/index.tsx | 28 ++-- src/popup/styles/index.css | 22 +-- tsconfig.json | 41 ++--- vite.config.background.ts | 22 +-- vite.config.content.ts | 22 +-- vite.config.popup.ts | 14 +- 25 files changed, 386 insertions(+), 373 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1d464a..73f6a4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,31 +3,31 @@ name: ci on: [push] permissions: - contents: read + contents: read env: - NODE_VERSION: '20' + NODE_VERSION: '20' jobs: - ci-ChromeExtension: - name: Chrome extension CI - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'yarn' - cache-dependency-path: 'yarn.lock' - registry-url: 'https://npm.pkg.github.com' - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Lint the code - run: yarn run lint - - - name: Build the code - run: yarn run build + ci-ChromeExtension: + name: Chrome extension CI + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + registry-url: 'https://npm.pkg.github.com' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Lint the code + run: yarn run lint + + - name: Build the code + run: yarn run build diff --git a/.prettierrc b/.prettierrc index 81b1159..8b67fbd 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,10 +1,10 @@ { - "semi": true, - "tabWidth": 2, - "printWidth": 100, - "singleQuote": true, - "jsxSingleQuote": true, - "trailingComma": "none", - "bracketSameLine": false, - "bracketSpacing": false + "semi": true, + "tabWidth": 4, + "printWidth": 100, + "singleQuote": true, + "jsxSingleQuote": true, + "trailingComma": "none", + "bracketSameLine": false, + "bracketSpacing": false } diff --git a/README.md b/README.md index f756d61..879c41e 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,16 @@ from [chrome-extension-boilerplate-react](https://github.com/lxieyang/chrome-ext This is a basic Chrome Extensions boilerplate to help you write modular and modern Javascript code and load CSS easily. This boilerplate is updated with: -- [Chrome Extension Manifest V3](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-overview/) -- [React 18](https://reactjs.org) -- [MUI](https://mui.com/) -- ESLint: - - [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) - - [eslint-config-prettier](https://www.npmjs.com/package/eslint-config-prettier) - - [eslint-plugin-simple-import-sort](https://www.npmjs.com/package/eslint-plugin-simple-import-sort) - - [typescript-eslint](https://www.npmjs.com/package/typescript-eslint) -- [Prettier](https://prettier.io/) -- [TypeScript](https://www.typescriptlang.org/) +- [Chrome Extension Manifest V3](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-overview/) +- [React 18](https://reactjs.org) +- [MUI](https://mui.com/) +- ESLint: + - [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) + - [eslint-config-prettier](https://www.npmjs.com/package/eslint-config-prettier) + - [eslint-plugin-simple-import-sort](https://www.npmjs.com/package/eslint-plugin-simple-import-sort) + - [typescript-eslint](https://www.npmjs.com/package/typescript-eslint) +- [Prettier](https://prettier.io/) +- [TypeScript](https://www.typescriptlang.org/) I have avoided using CRXJS Vite Plugin on purpose as it's last update was in 2022, and it could possibly have some issues with newer versions of Vite. @@ -43,10 +43,10 @@ Please open up an issue to nudge me to keep the npm packages up-to-date. 5. Run `yarn install` to install the dependencies. 6. Run `yarn dist` 7. Load your extension on Chrome following: - 1. Access `chrome://extensions/` - 2. Turn the `Developer mode` switch on (top right corner) - 3. Click on `Load unpacked` - 4. Select the `dist` folder. + 1. Access `chrome://extensions/` + 2. Turn the `Developer mode` switch on (top right corner) + 3. Click on `Load unpacked` + 4. Select the `dist` folder. 8. Happy hacking. ## Structure @@ -81,7 +81,7 @@ at the [official guide](https://developer.chrome.com/webstore/publish) to more i ## Resources: -- [Chrome Extension documentation](https://developer.chrome.com/extensions/getstarted) +- [Chrome Extension documentation](https://developer.chrome.com/extensions/getstarted) --- diff --git a/eslint.config.js b/eslint.config.js index 7d0f317..553d438 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -8,21 +8,21 @@ import simpleImportSort from 'eslint-plugin-simple-import-sort'; import tseslint from 'typescript-eslint'; export default tseslint.config( - { - ignores: ['dist'] - }, - eslint.configs.recommended, - ...tseslint.configs.recommended, - reactRecommended, - reactJsxRuntime, - eslintConfigPrettier, - { - plugins: { - 'simple-import-sort': simpleImportSort + { + ignores: ['dist'] }, - rules: { - 'simple-import-sort/imports': 'warn', - 'simple-import-sort/exports': 'warn' + eslint.configs.recommended, + ...tseslint.configs.recommended, + reactRecommended, + reactJsxRuntime, + eslintConfigPrettier, + { + plugins: { + 'simple-import-sort': simpleImportSort + }, + rules: { + 'simple-import-sort/imports': 'warn', + 'simple-import-sort/exports': 'warn' + } } - } ); diff --git a/index.html b/index.html index 60a9579..753ecb1 100644 --- a/index.html +++ b/index.html @@ -3,16 +3,16 @@ - - - - - Chrome Extension React + + + + + Chrome Extension React - - - -
- - + + + +
+ + diff --git a/manifest.json b/manifest.json index 88fab00..c95f36b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,33 +1,33 @@ { - "manifest_version": 3, - "name": "Chrome Extension with React & Vite", - "version": "1.0.0", - "description": "A chrome extension boilerplate built with React 18 and Vite 5", - "icons": { - "34": "assets/icons/icon-34.png", - "128": "assets/icons/icon-128.png" - }, - "action": { - "default_title": "Chrome Extension React", - "default_popup": "popup/index.html", - "default_icon": "assets/icons/icon-34.png" - }, - "content_scripts": [ - { - "js": ["content/index.js"], - "matches": ["*://*/*"] - } - ], - "background": { - "service_worker": "background/index.js" - }, - "web_accessible_resources": [ - { - "resources": ["assets/icons/*.png"], - "matches": [], - "extension_ids": [] - } - ], - "permissions": ["storage", "tabs", "activeTab"], - "host_permissions": [] + "manifest_version": 3, + "name": "Chrome Extension with React & Vite", + "version": "1.0.0", + "description": "A chrome extension boilerplate built with React 18 and Vite 5", + "icons": { + "34": "assets/icons/icon-34.png", + "128": "assets/icons/icon-128.png" + }, + "action": { + "default_title": "Chrome Extension React", + "default_popup": "popup/index.html", + "default_icon": "assets/icons/icon-34.png" + }, + "content_scripts": [ + { + "js": ["content/index.js"], + "matches": ["*://*/*"] + } + ], + "background": { + "service_worker": "background/index.js" + }, + "web_accessible_resources": [ + { + "resources": ["assets/icons/*.png"], + "matches": [], + "extension_ids": [] + } + ], + "permissions": ["storage", "tabs", "activeTab"], + "host_permissions": [] } diff --git a/package.json b/package.json index 84b6249..1995706 100644 --- a/package.json +++ b/package.json @@ -1,55 +1,55 @@ { - "name": "chrome-extension-boilerplate-react-vite", - "version": "1.0.0", - "description": "A chrome extension boilerplate built with React 18 and Vite 5", - "license": "MIT", - "type": "module", - "scripts": { - "lint": "eslint .", - "lint:fix": "eslint . --fix", - "format": "prettier --write .", - "watch": "yarn dist && yarn watch:popup", - "watch:background": "vite --config vite.config.background.ts build --watch", - "watch:content": "vite --config vite.config.content.ts build --watch", - "watch:popup": "vite --config vite.config.popup.ts build --watch", - "build": "yarn build:background && yarn build:content && yarn build:popup", - "build:background": "vite --config vite.config.background.ts build", - "build:content": "vite --config vite.config.content.ts build", - "build:popup": "vite --config vite.config.popup.ts build", - "clean": "rimraf dist", - "copy:static": "copyfiles manifest.json assets/**/* dist", - "dist:dev": "yarn lint && yarn dist", - "dist": "yarn clean && yarn build && yarn copy:static" - }, - "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.0", - "@fontsource/roboto": "^5.0.12", - "@mui/icons-material": "^5.15.14", - "@mui/material": "^5.15.14", - "@mui/system": "^5.15.14", - "axios": "^1.6.8", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-router-dom": "^6.22.3" - }, - "devDependencies": { - "@eslint/js": "^8.57.0", - "@types/react": "^18.2.69", - "@types/react-dom": "^18.2.22", - "@typescript-eslint/eslint-plugin": "^7.3.1", - "@typescript-eslint/parser": "^7.3.1", - "@vitejs/plugin-react": "^4.2.1", - "chrome-types": "^0.1.274", - "copyfiles": "^2.4.1", - "eslint": "^8.57.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-react": "^7.34.1", - "eslint-plugin-simple-import-sort": "^12.0.0", - "prettier": "^3.2.5", - "rimraf": "^5.0.5", - "typescript": "5.4.3", - "typescript-eslint": "^7.3.1", - "vite": "^5.2.6" - } + "name": "chrome-extension-boilerplate-react-vite", + "version": "1.0.0", + "description": "A chrome extension boilerplate built with React 18 and Vite 5", + "license": "MIT", + "type": "module", + "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "prettier --write .", + "watch": "yarn dist && yarn watch:popup", + "watch:background": "vite --config vite.config.background.ts build --watch", + "watch:content": "vite --config vite.config.content.ts build --watch", + "watch:popup": "vite --config vite.config.popup.ts build --watch", + "build": "yarn build:background && yarn build:content && yarn build:popup", + "build:background": "vite --config vite.config.background.ts build", + "build:content": "vite --config vite.config.content.ts build", + "build:popup": "vite --config vite.config.popup.ts build", + "clean": "rimraf dist", + "copy:static": "copyfiles manifest.json assets/**/* dist", + "dist:dev": "yarn lint && yarn dist", + "dist": "yarn clean && yarn build && yarn copy:static" + }, + "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.0", + "@fontsource/roboto": "^5.0.12", + "@mui/icons-material": "^5.15.14", + "@mui/material": "^5.15.14", + "@mui/system": "^5.15.14", + "axios": "^1.6.8", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.3" + }, + "devDependencies": { + "@eslint/js": "^8.57.0", + "@types/react": "^18.2.69", + "@types/react-dom": "^18.2.22", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", + "@vitejs/plugin-react": "^4.2.1", + "chrome-types": "^0.1.274", + "copyfiles": "^2.4.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-react": "^7.34.1", + "eslint-plugin-simple-import-sort": "^12.0.0", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "typescript": "5.4.3", + "typescript-eslint": "^7.3.1", + "vite": "^5.2.6" + } } diff --git a/src/background/index.ts b/src/background/index.ts index e221845..43ac17d 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -1,10 +1,10 @@ chrome.runtime.onInstalled.addListener(() => { - chrome.storage.local.clear(); + chrome.storage.local.clear(); }); chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { - // TODO: Here you can add logic such as e.g. disable popup button on specific pages - console.debug('tabId', tabId, 'changeInfo', changeInfo, 'tab', tab); + // TODO: Here you can add logic such as e.g. disable popup button on specific pages + console.debug('tabId', tabId, 'changeInfo', changeInfo, 'tab', tab); }); export {}; diff --git a/src/common/chrome-api-wrapper.ts b/src/common/chrome-api-wrapper.ts index 90a9fc2..2b38592 100644 --- a/src/common/chrome-api-wrapper.ts +++ b/src/common/chrome-api-wrapper.ts @@ -1,43 +1,43 @@ export enum ChromeMessageType { - SCRAPER_COMMAND, - SCRAPING_RESULTS + SCRAPER_COMMAND, + SCRAPING_RESULTS } export class ChromeMessage { - readonly type: ChromeMessageType; - readonly payload: T; + readonly type: ChromeMessageType; + readonly payload: T; - constructor(type: ChromeMessageType, payload: T) { - this.type = type; - this.payload = payload; - } + constructor(type: ChromeMessageType, payload: T) { + this.type = type; + this.payload = payload; + } } export class ChromeApiWrapper { - public static async sendTabMessage(message: ChromeMessage): Promise { - const currentTab = await this.getCurrentTab(); - if (currentTab == null) { - throw new Error('Could not find current tab'); + public static async sendTabMessage(message: ChromeMessage): Promise { + const currentTab = await this.getCurrentTab(); + if (currentTab == null) { + throw new Error('Could not find current tab'); + } + + await chrome.tabs.sendMessage(currentTab.id ?? 0, message); } - await chrome.tabs.sendMessage(currentTab.id ?? 0, message); - } + public static async getCurrentTab(): Promise { + const dateStarted = Date.now(); - public static async getCurrentTab(): Promise { - const dateStarted = Date.now(); + // Prevents code from failing when used too soon + while (Date.now() - dateStarted < 5000) { + const tabs = await chrome.tabs.query({active: true, lastFocusedWindow: true}); - // Prevents code from failing when used too soon - while (Date.now() - dateStarted < 5000) { - const tabs = await chrome.tabs.query({active: true, lastFocusedWindow: true}); + const currentTab = tabs[0]; + if (currentTab?.status === 'complete') { + return currentTab; + } - const currentTab = tabs[0]; - if (currentTab?.status === 'complete') { - return currentTab; - } + await new Promise((r) => setTimeout(r, 50)); + } - await new Promise((r) => setTimeout(r, 50)); + return null; } - - return null; - } } diff --git a/src/common/types/scraper.ts b/src/common/types/scraper.ts index 77bd3ad..082f97d 100644 --- a/src/common/types/scraper.ts +++ b/src/common/types/scraper.ts @@ -1,7 +1,7 @@ export enum ScraperCommand { - SCRAPE + SCRAPE } export interface ScraperMessage { - command: ScraperCommand; + command: ScraperCommand; } diff --git a/src/content/index.ts b/src/content/index.ts index 53495f8..a2f63d9 100644 --- a/src/content/index.ts +++ b/src/content/index.ts @@ -2,22 +2,22 @@ import {ChromeMessage, ChromeMessageType} from '../common/chrome-api-wrapper'; import {ScraperCommand, ScraperMessage} from '../common/types/scraper'; async function handleScrapeCommand() { - const pageTitle = document.title; - const message = new ChromeMessage(ChromeMessageType.SCRAPING_RESULTS, pageTitle); - await chrome.runtime.sendMessage(chrome.runtime.id, message); + const pageTitle = document.title; + const message = new ChromeMessage(ChromeMessageType.SCRAPING_RESULTS, pageTitle); + await chrome.runtime.sendMessage(chrome.runtime.id, message); } chrome.runtime.onMessage.addListener((message: ChromeMessage) => { - console.debug('Received message', message); - if (message.type !== ChromeMessageType.SCRAPER_COMMAND) { - return false; - } + console.debug('Received message', message); + if (message.type !== ChromeMessageType.SCRAPER_COMMAND) { + return false; + } - if (message.payload.command === ScraperCommand.SCRAPE) { - handleScrapeCommand().catch((error) => console.error(error)); - } + if (message.payload.command === ScraperCommand.SCRAPE) { + handleScrapeCommand().catch((error) => console.error(error)); + } - return false; + return false; }); console.debug('Chrome plugin content script loaded'); diff --git a/src/popup/AppShell/AppShell.css b/src/popup/AppShell/AppShell.css index b2886f7..3c98aab 100644 --- a/src/popup/AppShell/AppShell.css +++ b/src/popup/AppShell/AppShell.css @@ -1,9 +1,9 @@ .App { - width: 100%; - height: 100%; - text-align: center; + width: 100%; + height: 100%; + text-align: center; } .App button { - border-radius: 200px; + border-radius: 200px; } diff --git a/src/popup/AppShell/AppShell.tsx b/src/popup/AppShell/AppShell.tsx index 6b1f5f6..c7d3983 100644 --- a/src/popup/AppShell/AppShell.tsx +++ b/src/popup/AppShell/AppShell.tsx @@ -4,11 +4,11 @@ import {ReactElement, ReactNode, useEffect} from 'react'; import {useNavigate} from 'react-router-dom'; export default function AppShell(props: {children?: ReactNode}): ReactElement { - const navigate = useNavigate(); + const navigate = useNavigate(); - useEffect(() => { - navigate('/home-page'); - }, []); + useEffect(() => { + navigate('/home-page'); + }, []); - return
{props.children}
; + return
{props.children}
; } diff --git a/src/popup/components/PopupContent/PopupContent.css b/src/popup/components/PopupContent/PopupContent.css index af95018..83d8b36 100644 --- a/src/popup/components/PopupContent/PopupContent.css +++ b/src/popup/components/PopupContent/PopupContent.css @@ -1,6 +1,6 @@ .popup-content { - height: 536px !important; - width: 100%; - margin: 0; - text-align: center; + height: 536px !important; + width: 100%; + margin: 0; + text-align: center; } diff --git a/src/popup/components/PopupContent/PopupContent.tsx b/src/popup/components/PopupContent/PopupContent.tsx index 74cb1fb..f364ff7 100644 --- a/src/popup/components/PopupContent/PopupContent.tsx +++ b/src/popup/components/PopupContent/PopupContent.tsx @@ -4,9 +4,9 @@ import Box from '@mui/material/Box'; import {ReactElement, ReactNode} from 'react'; export default function PopupContent(props: {children?: ReactNode}): ReactElement { - return ( - - {props.children} - - ); + return ( + + {props.children} + + ); } diff --git a/src/popup/components/PopupHeader/PopupHeader.css b/src/popup/components/PopupHeader/PopupHeader.css index 3007b8c..9f6583d 100644 --- a/src/popup/components/PopupHeader/PopupHeader.css +++ b/src/popup/components/PopupHeader/PopupHeader.css @@ -1,16 +1,16 @@ .popup-logo { - pointer-events: none; - width: 32px; - height: 32px; - padding-right: 8px; + pointer-events: none; + width: 32px; + height: 32px; + padding-right: 8px; } .popup-header { - background-color: #0a0f19; - color: #f4f4f5; - height: 64px; + background-color: #0a0f19; + color: #f4f4f5; + height: 64px; } .popup-header button { - color: #f4f4f5; + color: #f4f4f5; } diff --git a/src/popup/components/PopupHeader/PopupHeader.tsx b/src/popup/components/PopupHeader/PopupHeader.tsx index 137e4ae..b36b70e 100644 --- a/src/popup/components/PopupHeader/PopupHeader.tsx +++ b/src/popup/components/PopupHeader/PopupHeader.tsx @@ -5,11 +5,11 @@ import {Toolbar} from '@mui/material'; import {ReactElement, ReactNode} from 'react'; export default function PopupHeader(props: {children?: ReactNode}): ReactElement { - return ( - - -

Chrome Extension React

- {props.children} -
- ); + return ( + + +

Chrome Extension React

+ {props.children} +
+ ); } diff --git a/src/popup/features/HomePage/HomePage.css b/src/popup/features/HomePage/HomePage.css index a011c00..73315b7 100644 --- a/src/popup/features/HomePage/HomePage.css +++ b/src/popup/features/HomePage/HomePage.css @@ -1,3 +1,3 @@ .scrape-button { - width: 300px; + width: 300px; } diff --git a/src/popup/features/HomePage/HomePage.tsx b/src/popup/features/HomePage/HomePage.tsx index 7bf5aa5..7fc858a 100644 --- a/src/popup/features/HomePage/HomePage.tsx +++ b/src/popup/features/HomePage/HomePage.tsx @@ -5,9 +5,9 @@ import Box from '@mui/material/Box'; import {ReactElement, useEffect, useState} from 'react'; import { - ChromeApiWrapper, - ChromeMessage, - ChromeMessageType + ChromeApiWrapper, + ChromeMessage, + ChromeMessageType } from '../../../common/chrome-api-wrapper'; import {ScraperCommand, ScraperMessage} from '../../../common/types/scraper'; import PopupContent from '../../components/PopupContent/PopupContent'; @@ -16,80 +16,88 @@ import PopupHeader from '../../components/PopupHeader/PopupHeader'; const CACHE_KEY = 'scrapedPageTitle'; export default function HomePage(): ReactElement { - const [scrapedPageTitle, setScrapedPageTitle] = useState(''); - const [disableScrapeButton, setDisableScrapeButton] = useState(false); + const [scrapedPageTitle, setScrapedPageTitle] = useState(''); + const [disableScrapeButton, setDisableScrapeButton] = useState(false); - const [showErrorSnackbar, setShowErrorSnackbar] = useState(false); - const [errorSnackbarMessage, setErrorSnackbarMessage] = useState(''); + const [showErrorSnackbar, setShowErrorSnackbar] = useState(false); + const [errorSnackbarMessage, setErrorSnackbarMessage] = useState(''); - function handleSnackbarClose() { - setShowErrorSnackbar(false); - } + function handleSnackbarClose() { + setShowErrorSnackbar(false); + } - async function scrape() { - setDisableScrapeButton(true); + async function scrape() { + setDisableScrapeButton(true); - const message: ChromeMessage = { - type: ChromeMessageType.SCRAPER_COMMAND, - payload: {command: ScraperCommand.SCRAPE} - }; + const message: ChromeMessage = { + type: ChromeMessageType.SCRAPER_COMMAND, + payload: {command: ScraperCommand.SCRAPE} + }; - try { - await ChromeApiWrapper.sendTabMessage(message); - } catch (e) { - console.error(e); - setErrorSnackbarMessage('Failed to scrape page title. Please check console logs.'); - setShowErrorSnackbar(true); - setDisableScrapeButton(false); + try { + await ChromeApiWrapper.sendTabMessage(message); + } catch (e) { + console.error(e); + setErrorSnackbarMessage('Failed to scrape page title. Please check console logs.'); + setShowErrorSnackbar(true); + setDisableScrapeButton(false); + } } - } - useEffect(() => { - chrome.storage.session.get(CACHE_KEY).then((items) => { - const cachedTitle = items[CACHE_KEY]; - setScrapedPageTitle(cachedTitle ?? ''); - }); + useEffect(() => { + chrome.storage.session.get(CACHE_KEY).then((items) => { + const cachedTitle = items[CACHE_KEY]; + setScrapedPageTitle(cachedTitle ?? ''); + }); - chrome.runtime.onMessage.addListener((message: ChromeMessage) => { - if (message.type !== ChromeMessageType.SCRAPING_RESULTS) { - return false; - } + chrome.runtime.onMessage.addListener((message: ChromeMessage) => { + if (message.type !== ChromeMessageType.SCRAPING_RESULTS) { + return false; + } - chrome.storage.session.set({[CACHE_KEY]: message.payload}); - setScrapedPageTitle(message.payload); - setDisableScrapeButton(false); - return false; - }); - }, []); + chrome.storage.session.set({[CACHE_KEY]: message.payload}); + setScrapedPageTitle(message.payload); + setDisableScrapeButton(false); + return false; + }); + }, []); - return ( - <> - - - - -

My Chromium extension

-
+ return ( + <> + + + + +

My Chromium extension

+
-

- Scraped title: {scrapedPageTitle} -

+

+ Scraped title: {scrapedPageTitle} +

- -
-
- - - {errorSnackbarMessage} - - - - ); + +
+
+ + + {errorSnackbarMessage} + + + + ); } diff --git a/src/popup/index.tsx b/src/popup/index.tsx index 317717f..348dffd 100644 --- a/src/popup/index.tsx +++ b/src/popup/index.tsx @@ -8,20 +8,20 @@ import PopupHeader from './components/PopupHeader/PopupHeader'; const HomePage = lazy(() => import('./features/HomePage/HomePage')); function Index(): ReactElement { - return ( - - - - }> - - } /> - } /> - - - - - - ); + return ( + + + + }> + + } /> + } /> + + + + + + ); } const root = createRoot(document.getElementById('root') as HTMLElement); diff --git a/src/popup/styles/index.css b/src/popup/styles/index.css index 7fddd4a..b975ec2 100644 --- a/src/popup/styles/index.css +++ b/src/popup/styles/index.css @@ -1,19 +1,19 @@ body { - /* 800x600 is the current limit of chrome popup size */ - width: 800px; - height: 580px; - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', - 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + /* 800x600 is the current limit of chrome popup size */ + width: 800px; + height: 580px; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', + 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } #root { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } diff --git a/tsconfig.json b/tsconfig.json index e03a227..6b66cc3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,26 @@ { - "compilerOptions": { - "target": "es2022", - "module": "esnext", - "lib": ["esnext", "dom", "dom.iterable"], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "moduleResolution": "node", - "resolveJsonModule": true, + "compilerOptions": { + "target": "es2022", + "module": "esnext", + "lib": ["esnext", "dom", "dom.iterable"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "resolveJsonModule": true, - "noEmit": true, - "jsx": "react-jsx", - "types": ["chrome-types"] - }, - "include": ["src", "vite.config.popup.ts", "vite.config.background.ts", "vite.config.content.ts"] + "noEmit": true, + "jsx": "react-jsx", + "types": ["chrome-types"] + }, + "include": [ + "src", + "vite.config.popup.ts", + "vite.config.background.ts", + "vite.config.content.ts" + ] } diff --git a/vite.config.background.ts b/vite.config.background.ts index b31d356..2b38b81 100644 --- a/vite.config.background.ts +++ b/vite.config.background.ts @@ -2,16 +2,16 @@ import {defineConfig} from 'vite'; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [], - base: './', - build: { - outDir: 'dist/background', - rollupOptions: { - input: 'src/background/index.ts', - output: { - inlineDynamicImports: true, - entryFileNames: '[name].js' - } + plugins: [], + base: './', + build: { + outDir: 'dist/background', + rollupOptions: { + input: 'src/background/index.ts', + output: { + inlineDynamicImports: true, + entryFileNames: '[name].js' + } + } } - } }); diff --git a/vite.config.content.ts b/vite.config.content.ts index 85bf7ff..4b06a43 100644 --- a/vite.config.content.ts +++ b/vite.config.content.ts @@ -2,16 +2,16 @@ import {defineConfig} from 'vite'; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [], - base: './', - build: { - outDir: 'dist/content', - rollupOptions: { - input: 'src/content/index.ts', - output: { - inlineDynamicImports: true, - entryFileNames: '[name].js' - } + plugins: [], + base: './', + build: { + outDir: 'dist/content', + rollupOptions: { + input: 'src/content/index.ts', + output: { + inlineDynamicImports: true, + entryFileNames: '[name].js' + } + } } - } }); diff --git a/vite.config.popup.ts b/vite.config.popup.ts index b76cb6b..6b52a12 100644 --- a/vite.config.popup.ts +++ b/vite.config.popup.ts @@ -3,12 +3,12 @@ import {defineConfig} from 'vite'; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], - base: './', - build: { - outDir: 'dist/popup', - rollupOptions: { - input: 'index.html' + plugins: [react()], + base: './', + build: { + outDir: 'dist/popup', + rollupOptions: { + input: 'index.html' + } } - } });