diff --git a/.gitignore b/.gitignore index 54421791..b386e84e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ node_modules/ .history/ .vscode/ -build/ +extensions/ .idea/ dist/ @@ -17,3 +17,4 @@ yarn.lock keys.json .DS_Store *.zip +i18n-fallback.json diff --git a/build/finalise.js b/build/finalise.js new file mode 100644 index 00000000..a06cce52 --- /dev/null +++ b/build/finalise.js @@ -0,0 +1,61 @@ +import fs from `node:fs`; +import ADMZip from 'adm-zip'; +import * as pkg from '../package.json'; + +export default function finalise(isProd) { + return { + name: 'finalise', + writeBundle() { + if (isProd) { + // clean up + if (fs.existsSync('./extensions')) { + fs.rmSync('./extensions', { recursive: true }); + } + + // prettify and move i18n report + fs.writeFileSync( + './i18n-fallback.json', + JSON.stringify( + JSON.parse(fs.readFileSync('./dist/i18n-fallback.json', 'utf8')), + null, + 2, + ), + ); + fs.rmSync('./dist/i18n-fallback.json'); + + for (const browser of ['chrome', 'firefox']) { + // set up + fs.mkdirSync(`./extensions/${browser}`, { recursive: true }); + // copy manifest + fs.copyFileSync( + `./manifest/${browser}.json`, + `./extensions/${browser}/manifest.json`, + ); + // copy service worker + fs.copyFileSync( + './manifest/background.js', + `./extensions/${browser}/background.js`, + ); + // chrome is weird + if (browser === `${browser}`) { + fs.cpSync( + './manifest/_locales', + `./extensions/${browser}/_locales`, + { + recursive: true, + }, + ); + } + // copy build + fs.cpSync('./dist', `./extensions/${browser}/`, { + recursive: true, + }); + // package + const cZip = new ADMZip(); + cZip.addLocalFolder(`./extensions/${browser}`); + cZip.writeZip(`./extensions/${browser}-${pkg.version}.zip`); + } + } + }, + } +} diff --git a/build/i18n.js b/build/i18n.js new file mode 100644 index 00000000..42fdf0de --- /dev/null +++ b/build/i18n.js @@ -0,0 +1 @@ +// https://hosted.weblate.org/api/components/mue/mue-tab/statistics/ diff --git a/index.html b/index.html index 01d3372a..48034d5f 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,8 @@ - - + + New Tab diff --git a/src/assets/icons/128x128.png b/public/icons/128x128.png similarity index 100% rename from src/assets/icons/128x128.png rename to public/icons/128x128.png diff --git a/src/assets/icons/16x16.png b/public/icons/16x16.png similarity index 100% rename from src/assets/icons/16x16.png rename to public/icons/16x16.png diff --git a/src/assets/icons/32x32.png b/public/icons/32x32.png similarity index 100% rename from src/assets/icons/32x32.png rename to public/icons/32x32.png diff --git a/src/assets/icons/48x48.png b/public/icons/48x48.png similarity index 100% rename from src/assets/icons/48x48.png rename to public/icons/48x48.png diff --git a/src/assets/icons/marketplace-placeholder.png b/public/icons/marketplace-placeholder.png similarity index 100% rename from src/assets/icons/marketplace-placeholder.png rename to public/icons/marketplace-placeholder.png diff --git a/src/assets/icons/mue_about.png b/public/icons/mue_about.png similarity index 100% rename from src/assets/icons/mue_about.png rename to public/icons/mue_about.png diff --git a/src/assets/icons/mue_dark.png b/public/icons/mue_dark.png similarity index 100% rename from src/assets/icons/mue_dark.png rename to public/icons/mue_dark.png diff --git a/src/assets/icons/mue_light.png b/public/icons/mue_light.png similarity index 100% rename from src/assets/icons/mue_light.png rename to public/icons/mue_light.png diff --git a/src/assets/icons/undraw_add_files_modified.svg b/public/icons/undraw_add_files_modified.svg similarity index 100% rename from src/assets/icons/undraw_add_files_modified.svg rename to public/icons/undraw_add_files_modified.svg diff --git a/src/assets/icons/undraw_around_the_world_modified.svg b/public/icons/undraw_around_the_world_modified.svg similarity index 100% rename from src/assets/icons/undraw_around_the_world_modified.svg rename to public/icons/undraw_around_the_world_modified.svg diff --git a/src/assets/icons/undraw_by_the_road.svg b/public/icons/undraw_by_the_road.svg similarity index 100% rename from src/assets/icons/undraw_by_the_road.svg rename to public/icons/undraw_by_the_road.svg diff --git a/src/assets/icons/undraw_celebration.svg b/public/icons/undraw_celebration.svg similarity index 100% rename from src/assets/icons/undraw_celebration.svg rename to public/icons/undraw_celebration.svg diff --git a/src/assets/icons/undraw_dark_mode.svg b/public/icons/undraw_dark_mode.svg similarity index 100% rename from src/assets/icons/undraw_dark_mode.svg rename to public/icons/undraw_dark_mode.svg diff --git a/src/assets/icons/undraw_making_art.svg b/public/icons/undraw_making_art.svg similarity index 100% rename from src/assets/icons/undraw_making_art.svg rename to public/icons/undraw_making_art.svg diff --git a/src/assets/icons/undraw_on_the_way.svg b/public/icons/undraw_on_the_way.svg similarity index 100% rename from src/assets/icons/undraw_on_the_way.svg rename to public/icons/undraw_on_the_way.svg diff --git a/src/assets/icons/undraw_private_data_modified.svg b/public/icons/undraw_private_data_modified.svg similarity index 100% rename from src/assets/icons/undraw_private_data_modified.svg rename to public/icons/undraw_private_data_modified.svg diff --git a/src/assets/icons/undraw_upgrade_modified.svg b/public/icons/undraw_upgrade_modified.svg similarity index 100% rename from src/assets/icons/undraw_upgrade_modified.svg rename to public/icons/undraw_upgrade_modified.svg diff --git a/src/assets/offline-images/1.webp b/public/offline-images/1.webp similarity index 100% rename from src/assets/offline-images/1.webp rename to public/offline-images/1.webp diff --git a/src/assets/offline-images/10.webp b/public/offline-images/10.webp similarity index 100% rename from src/assets/offline-images/10.webp rename to public/offline-images/10.webp diff --git a/src/assets/offline-images/11.webp b/public/offline-images/11.webp similarity index 100% rename from src/assets/offline-images/11.webp rename to public/offline-images/11.webp diff --git a/src/assets/offline-images/12.webp b/public/offline-images/12.webp similarity index 100% rename from src/assets/offline-images/12.webp rename to public/offline-images/12.webp diff --git a/src/assets/offline-images/2.webp b/public/offline-images/2.webp similarity index 100% rename from src/assets/offline-images/2.webp rename to public/offline-images/2.webp diff --git a/src/assets/offline-images/3.webp b/public/offline-images/3.webp similarity index 100% rename from src/assets/offline-images/3.webp rename to public/offline-images/3.webp diff --git a/src/assets/offline-images/4.webp b/public/offline-images/4.webp similarity index 100% rename from src/assets/offline-images/4.webp rename to public/offline-images/4.webp diff --git a/src/assets/offline-images/5.webp b/public/offline-images/5.webp similarity index 100% rename from src/assets/offline-images/5.webp rename to public/offline-images/5.webp diff --git a/src/assets/offline-images/6.webp b/public/offline-images/6.webp similarity index 100% rename from src/assets/offline-images/6.webp rename to public/offline-images/6.webp diff --git a/src/assets/offline-images/7.webp b/public/offline-images/7.webp similarity index 100% rename from src/assets/offline-images/7.webp rename to public/offline-images/7.webp diff --git a/src/assets/offline-images/8.webp b/public/offline-images/8.webp similarity index 100% rename from src/assets/offline-images/8.webp rename to public/offline-images/8.webp diff --git a/src/assets/offline-images/9.webp b/public/offline-images/9.webp similarity index 100% rename from src/assets/offline-images/9.webp rename to public/offline-images/9.webp diff --git a/src/assets/welcome-images/example1.webp b/public/welcome-images/example1.webp similarity index 100% rename from src/assets/welcome-images/example1.webp rename to public/welcome-images/example1.webp diff --git a/src/assets/welcome-images/example2.webp b/public/welcome-images/example2.webp similarity index 100% rename from src/assets/welcome-images/example2.webp rename to public/welcome-images/example2.webp diff --git a/src/assets/welcome-images/example3.webp b/public/welcome-images/example3.webp similarity index 100% rename from src/assets/welcome-images/example3.webp rename to public/welcome-images/example3.webp diff --git a/src/assets/welcome-images/example4.webp b/public/welcome-images/example4.webp similarity index 100% rename from src/assets/welcome-images/example4.webp rename to public/welcome-images/example4.webp diff --git a/src/features/background/api/getOfflineImage.js b/src/features/background/api/getOfflineImage.js index 560df998..f4aebf14 100644 --- a/src/features/background/api/getOfflineImage.js +++ b/src/features/background/api/getOfflineImage.js @@ -29,7 +29,7 @@ export function getOfflineImage(type) { lastImage = randomImage; const object = { - url: `src/assets/offline-images/${randomImage}.webp`, + url: `offline-images/${randomImage}.webp`, type, photoInfo: { offline: true, diff --git a/src/features/marketplace/components/Elements/ItemCard/ItemCard.jsx b/src/features/marketplace/components/Elements/ItemCard/ItemCard.jsx index efb888c6..c93fe322 100644 --- a/src/features/marketplace/components/Elements/ItemCard/ItemCard.jsx +++ b/src/features/marketplace/components/Elements/ItemCard/ItemCard.jsx @@ -1,6 +1,5 @@ import variables from 'config/variables'; import { useEffect, useState } from 'react'; -import placeholderIcon from 'assets/icons/marketplace-placeholder.png'; import { useTab } from 'components/Elements/MainModal/backend/TabContext'; import { useMarketData } from 'features/marketplace/api/MarketplaceDataContext'; import { MdCheckCircle, MdOpenInNew } from 'react-icons/md'; @@ -47,7 +46,7 @@ function ItemCard({ item, type, onCollection, isCurator, cardStyle }) { src={item.icon_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} />
@@ -142,7 +141,7 @@ function ItemCard({ item, type, onCollection, isCurator, cardStyle }) { src={item.icon_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} />
{isItemInstalled(item.name) && }
diff --git a/src/features/marketplace/components/Items/OldItems.jsx b/src/features/marketplace/components/Items/OldItems.jsx index 2093427b..e867f150 100644 --- a/src/features/marketplace/components/Items/OldItems.jsx +++ b/src/features/marketplace/components/Items/OldItems.jsx @@ -1,7 +1,6 @@ import variables from 'config/variables'; import React, { memo } from 'react'; import { MdAutoFixHigh, MdOutlineArrowForward, MdOutlineOpenInNew } from 'react-icons/md'; -import placeholderIcon from 'assets/icons/marketplace-placeholder.png'; import { motion } from 'framer-motion'; import { Button } from 'components/Elements'; @@ -33,7 +32,7 @@ function ItemCard({ item, toggleFunction, type, onCollection, isCurator }) { src={item.icon_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} aria-hidden="true" /> @@ -44,7 +43,7 @@ function ItemCard({ item, toggleFunction, type, onCollection, isCurator }) { src={item.icon_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} />
diff --git a/src/features/marketplace/views/ItemPage.jsx b/src/features/marketplace/views/ItemPage.jsx index 596bd193..04a5e61d 100644 --- a/src/features/marketplace/views/ItemPage.jsx +++ b/src/features/marketplace/views/ItemPage.jsx @@ -1,5 +1,4 @@ import variables from 'config/variables'; -import placeholderIcon from 'assets/icons/marketplace-placeholder.png'; import { useEffect, useState } from 'react'; import { ShareModal } from 'components/Elements'; import { @@ -227,7 +226,7 @@ const ItemPage = () => { src={selectedItem.icon_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} /> {localStorage.getItem('welcomePreview') !== 'true' ? ( @@ -395,7 +394,7 @@ const ItemPage = () => { src={selectedItem.screenshot_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} /> )} diff --git a/src/features/marketplace/views/oldItemPage.jsx b/src/features/marketplace/views/oldItemPage.jsx index fef944f7..df24a5bc 100644 --- a/src/features/marketplace/views/oldItemPage.jsx +++ b/src/features/marketplace/views/oldItemPage.jsx @@ -21,7 +21,6 @@ import { Button } from 'components/Elements'; import { Carousel } from '../components/Elements/Carousel'; import { ShareModal } from 'components/Elements'; -import placeholderIcon from 'assets/icons/marketplace-placeholder.png'; import { Items } from '../components/Items/OldItems'; import Markdown from 'markdown-to-jsx'; @@ -270,7 +269,7 @@ class ItemPage extends PureComponent { src={iconsrc} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} /> )} @@ -386,7 +385,7 @@ class ItemPage extends PureComponent { src={this.props.data.data.icon_url} onError={(e) => { e.target.onerror = null; - e.target.src = placeholderIcon; + e.target.src = '/icons/marketplace-placeholder.png'; }} /> {localStorage.getItem('welcomePreview') !== 'true' ? ( diff --git a/src/features/misc/sections/About.jsx b/src/features/misc/sections/About.jsx index df0a1d27..d04f2f0a 100644 --- a/src/features/misc/sections/About.jsx +++ b/src/features/misc/sections/About.jsx @@ -135,7 +135,7 @@ class About extends PureComponent { Logo
diff --git a/src/features/welcome/components/Elements/AsideImage/AsideImage.jsx b/src/features/welcome/components/Elements/AsideImage/AsideImage.jsx index 5a064574..f6bf1c6f 100644 --- a/src/features/welcome/components/Elements/AsideImage/AsideImage.jsx +++ b/src/features/welcome/components/Elements/AsideImage/AsideImage.jsx @@ -1,11 +1,11 @@ const images = [ - '/src/assets/icons/undraw_celebration.svg', - '/src/assets/icons/undraw_around_the_world_modified.svg', - '/src/assets/icons/undraw_add_files_modified.svg', - '/src/assets/icons/undraw_dark_mode.svg', - '/src/assets/icons/undraw_making_art.svg', - '/src/assets/icons/undraw_private_data_modified.svg', - '/src/assets/icons/undraw_upgrade_modified.svg', + '/icons/undraw_celebration.svg', + '/icons/undraw_around_the_world_modified.svg', + '/icons/undraw_add_files_modified.svg', + '/icons/undraw_dark_mode.svg', + '/icons/undraw_making_art.svg', + '/icons/undraw_private_data_modified.svg', + '/icons/undraw_upgrade_modified.svg', ]; function AsideImage({ currentTab }) { diff --git a/src/features/welcome/components/Sections/Intro.jsx b/src/features/welcome/components/Sections/Intro.jsx index 742fc673..a4e21692 100644 --- a/src/features/welcome/components/Sections/Intro.jsx +++ b/src/features/welcome/components/Sections/Intro.jsx @@ -40,7 +40,7 @@ function Intro() { const ShareYourMue = (
Example Mue setup diff --git a/vite.config.mjs b/vite.config.mjs index 9b5fb0ea..9bccc7c6 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -2,98 +2,14 @@ import { defineConfig, loadEnv } from 'vite'; import inspect from 'vite-plugin-inspect'; import react from '@vitejs/plugin-react-swc'; import path from 'path'; -import fs from 'fs'; -import ADMZip from 'adm-zip'; -import * as pkg from './package.json'; import progress from 'vite-plugin-progress'; import I18nPlugin from '@eartharoid/vite-plugin-i18n'; import YAML from 'yaml'; +import finalise from './build/finalise'; +const r = (...p) => path.resolve(__dirname, ...p); const isProd = process.env.NODE_ENV === 'production'; -const prepareBuilds = () => ({ - name: 'prepareBuilds', - buildEnd() { - if (isProd) { - // make directories if not exist - fs.mkdirSync(path.resolve(__dirname, './build'), { recursive: true }); - fs.mkdirSync(path.resolve(__dirname, './dist'), { recursive: true }); - - // chrome - fs.mkdirSync(path.resolve(__dirname, './build/chrome'), { recursive: true }); - fs.copyFileSync( - path.resolve(__dirname, './manifest/chrome.json'), - path.resolve(__dirname, './build/chrome/manifest.json'), - ); - fs.copyFileSync( - path.resolve(__dirname, './manifest/background.js'), - path.resolve(__dirname, './build/chrome/background.js'), - ); - fs.cpSync( - path.resolve(__dirname, './manifest/_locales'), - path.resolve(__dirname, './build/chrome/_locales'), - { - recursive: true, - }, - ); - fs.cpSync(path.resolve(__dirname, './dist'), path.resolve(__dirname, './build/chrome/'), { - recursive: true, - }); - fs.cpSync( - path.resolve(__dirname, './src/assets/icons'), - path.resolve(__dirname, './build/chrome/icons'), - { - recursive: true, - }, - ); - fs.mkdirSync(path.resolve(__dirname, './build/chrome/src/assets'), { recursive: true }); - fs.cpSync( - path.resolve(__dirname, './src/assets'), - path.resolve(__dirname, './build/chrome/src/assets'), - { - recursive: true, - }, - ); - - // firefox - fs.mkdirSync(path.resolve(__dirname, './build/firefox'), { recursive: true }); - fs.copyFileSync( - path.resolve(__dirname, './manifest/firefox.json'), - path.resolve(__dirname, './build/firefox/manifest.json'), - ); - fs.copyFileSync( - path.resolve(__dirname, './manifest/background.js'), - path.resolve(__dirname, './build/firefox/background.js'), - ); - fs.cpSync(path.resolve(__dirname, './dist'), path.resolve(__dirname, './build/firefox/'), { - recursive: true, - }); - fs.cpSync( - path.resolve(__dirname, './src/assets/icons'), - path.resolve(__dirname, './build/firefox/icons'), - { - recursive: true, - }, - ); - fs.cpSync( - path.resolve(__dirname, './src/assets'), - path.resolve(__dirname, './build/firefox/src/assets'), - { - recursive: true, - }, - ); - - // create zip - const zip = new ADMZip(); - zip.addLocalFolder(path.resolve(__dirname, './build/chrome')); - zip.writeZip(path.resolve(__dirname, `./build/chrome-${pkg.version}.zip`)); - - const zip2 = new ADMZip(); - zip2.addLocalFolder(path.resolve(__dirname, './build/firefox')); - zip2.writeZip(path.resolve(__dirname, `./build/firefox-${pkg.version}.zip`)); - } - }, -}); export default defineConfig(({ command, mode }) => { const env = loadEnv(mode, process.cwd(), ''); @@ -110,7 +26,7 @@ export default defineConfig(({ command, mode }) => { include: './src/i18n/**/*.yml', parser: YAML.parse, }), - prepareBuilds(), + finalise(isProd), progress() ], server: { @@ -141,15 +57,15 @@ export default defineConfig(({ command, mode }) => { resolve: { extensions: ['.js', '.jsx'], alias: { - '@': path.resolve(__dirname, './src'), - i18n: path.resolve(__dirname, './src/i18n'), - components: path.resolve(__dirname, './src/components'), - assets: path.resolve(__dirname, './src/assets'), - config: path.resolve(__dirname, './src/config'), - features: path.resolve(__dirname, './src/features'), - lib: path.resolve(__dirname, './src/lib'), - scss: path.resolve(__dirname, './src/scss'), - utils: path.resolve(__dirname, './src/utils'), + '@': r('./src'), + i18n: r('./src/i18n'), + components: r('./src/components'), + assets: r('./src/assets'), + config: r('./src/config'), + features: r('./src/features'), + lib: r('./src/lib'), + scss: r('./src/scss'), + utils: r('./src/utils'), }, }, };