diff --git a/README.md b/README.md index 5836447..5858002 100644 --- a/README.md +++ b/README.md @@ -8,79 +8,9 @@ and expand to crowd-fund with time & money, then record and see the impact of co See [project.task.yaml](project.task.yaml) for current priorities. (Numbers at the beginning of lines are estimated hours. See [taskyaml.org](https://taskyaml.org/) for details.) -## Setup - -We like pkgx: `sh <(curl https://pkgx.sh) +vite sh` - -``` -npm install -``` - -### Compile and hot-reloads for development -``` -npm run dev -``` - -See the test locations for "IMAGE_API_SERVER" or "PARTNER_API_SERVER" below, or use http://localhost:3000 for local endorser.ch - -### Build the test & production app -``` -npm run serve -``` - -### Lint and fix files -``` -npm run lint -``` - -### Run all UI tests - -Look below for the "test-all" instructions. - - -### Compile and minify for test & production - -* If there are DB changes: before updating the test server, open browser(s) with current version to test DB migrations. - -* `npx prettier --write ./sw_scripts/` - -* Update the ClickUp tasks & CHANGELOG.md & the version in package.json, run `npm install`. - -* Commit everything (since the commit hash is used the app). - -* Put the commit hash in the changelog (which will help you remember to bump the version later). - -* Tag with the new version, [online](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/releases) or `git tag 0.3.36` && `git push origin 0.3.36`. - -* For test, build the app (because test server is not yet set up to build): - -``` -TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_APP_SERVER=https://test.timesafari.app VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch VITE_PASSKEYS_ENABLED=true npm run build -``` - - ... and transfer to the test server: `rsync -azvu -e "ssh -i ~/.ssh/..." dist ubuntutest@test.timesafari.app:time-safari` - - (Let's replace that with a .env.development or .env.staging file.) - - (Note: The test BVC_MEETUPS_PROJECT_CLAIM_ID does not resolve as a URL because it's only in the test DB and the prod redirect won't redirect there.) - -* For prod, get on the server and run the correct build: - - ... and log onto the server: - - * `pkgx +npm sh` - - * `cd crowd-funder-for-time-pwa && git checkout master && git pull && git checkout 0.3.36 && npm install && npm run build && cd -` - - (The plain `npm run build` uses the .env.production file.) - -* Back up the time-safari/dist folder, then `mv time-safari/dist time-safari-dist-prev.0 && mv crowd-funder-for-time-pwa/dist time-safari/` - -* Record the new hash in the changelog. Edit package.json to increment version & add "-beta", `npm install`, and commit. Also record what version is on production. - - - +## Setup & Building +See [BUILDING.md](BUILDING.md) for detailed build and setup instructions. ## Tests diff --git a/src/electron/main.js b/src/electron/main.js index 8896958..a0ee755 100644 --- a/src/electron/main.js +++ b/src/electron/main.js @@ -3,13 +3,13 @@ const path = require("path"); const fs = require("fs"); // Check if running in dev mode -const isDev = process.argv.includes('--inspect'); +const isDev = process.argv.includes("--inspect"); function createWindow() { // Add before createWindow function - const preloadPath = path.join(__dirname, 'preload.js'); - console.log('Checking preload path:', preloadPath); - console.log('Preload exists:', fs.existsSync(preloadPath)); + const preloadPath = path.join(__dirname, "preload.js"); + console.log("Checking preload path:", preloadPath); + console.log("Preload exists:", fs.existsSync(preloadPath)); // Create the browser window. const mainWindow = new BrowserWindow({ @@ -20,7 +20,7 @@ function createWindow() { contextIsolation: true, webSecurity: true, allowRunningInsecureContent: false, - preload: path.join(__dirname, 'preload.js') + preload: path.join(__dirname, "preload.js"), }, }); @@ -33,30 +33,32 @@ function createWindow() { console.log("__dirname:", __dirname); console.log("process.cwd():", process.cwd()); - const indexPath = path.join(__dirname, 'www', 'index.html'); - console.log("www path:", path.join(__dirname, 'www')); - console.log("www assets path:", path.join(__dirname, 'www', 'assets')); + const indexPath = path.join(__dirname, "www", "index.html"); + console.log("www path:", path.join(__dirname, "www")); + console.log("www assets path:", path.join(__dirname, "www", "assets")); if (!fs.existsSync(indexPath)) { console.error(`Index file not found at: ${indexPath}`); - throw new Error('Index file not found'); + throw new Error("Index file not found"); } // Set CSP headers - mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => { - callback({ - responseHeaders: { - ...details.responseHeaders, - 'Content-Security-Policy': [ - "default-src 'self';" + - "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;" + - "font-src 'self' https://fonts.gstatic.com;" + - "script-src 'self' 'unsafe-eval' 'unsafe-inline';" + - "img-src 'self' data: https:;" - ] - } - }); - }); + mainWindow.webContents.session.webRequest.onHeadersReceived( + (details, callback) => { + callback({ + responseHeaders: { + ...details.responseHeaders, + "Content-Security-Policy": [ + "default-src 'self';" + + "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;" + + "font-src 'self' https://fonts.gstatic.com;" + + "script-src 'self' 'unsafe-eval' 'unsafe-inline';" + + "img-src 'self' data: https:;", + ], + }, + }); + }, + ); // Load the index.html mainWindow @@ -79,17 +81,23 @@ function createWindow() { }); // Add right after creating the BrowserWindow - mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => { - console.error('Page failed to load:', errorCode, errorDescription); - }); + mainWindow.webContents.on( + "did-fail-load", + (event, errorCode, errorDescription) => { + console.error("Page failed to load:", errorCode, errorDescription); + }, + ); - mainWindow.webContents.on('preload-error', (event, preloadPath, error) => { - console.error('Preload script error:', preloadPath, error); + mainWindow.webContents.on("preload-error", (event, preloadPath, error) => { + console.error("Preload script error:", preloadPath, error); }); - mainWindow.webContents.on('console-message', (event, level, message, line, sourceId) => { - console.log('Renderer Console:', message); - }); + mainWindow.webContents.on( + "console-message", + (event, level, message, line, sourceId) => { + console.log("Renderer Console:", line, sourceId, message); + }, + ); // Enable remote debugging when in dev mode if (isDev) { diff --git a/src/electron/preload.js b/src/electron/preload.js index fc630cd..1704b25 100644 --- a/src/electron/preload.js +++ b/src/electron/preload.js @@ -1,39 +1,40 @@ -const { contextBridge, ipcRenderer } = require('electron'); +const { contextBridge, ipcRenderer } = require("electron"); // Use a more direct path resolution approach const getPath = (pathType) => { - switch(pathType) { - case 'userData': - return process.env.APPDATA || ( - process.platform === 'darwin' + switch (pathType) { + case "userData": + return ( + process.env.APPDATA || + (process.platform === "darwin" ? `${process.env.HOME}/Library/Application Support` - : `${process.env.HOME}/.local/share` + : `${process.env.HOME}/.local/share`) ); - case 'home': + case "home": return process.env.HOME; - case 'appPath': + case "appPath": return process.resourcesPath; default: - return ''; + return ""; } }; -console.log('Preload script starting...'); +console.log("Preload script starting..."); try { - contextBridge.exposeInMainWorld('electronAPI', { + contextBridge.exposeInMainWorld("electronAPI", { // Path utilities getPath, - + // IPC functions send: (channel, data) => { - const validChannels = ['toMain']; + const validChannels = ["toMain"]; if (validChannels.includes(channel)) { ipcRenderer.send(channel, data); } }, receive: (channel, func) => { - const validChannels = ['fromMain']; + const validChannels = ["fromMain"]; if (validChannels.includes(channel)) { ipcRenderer.on(channel, (event, ...args) => func(...args)); } @@ -41,15 +42,15 @@ try { // Environment info env: { isElectron: true, - isDev: process.env.NODE_ENV === 'development' + isDev: process.env.NODE_ENV === "development", }, // Path utilities getBasePath: () => { - return process.env.NODE_ENV === 'development' ? '/' : './'; - } + return process.env.NODE_ENV === "development" ? "/" : "./"; + }, }); - console.log('Preload script completed successfully'); + console.log("Preload script completed successfully"); } catch (error) { - console.error('Error in preload script:', error); -} \ No newline at end of file + console.error("Error in preload script:", error); +} diff --git a/src/registerServiceWorker.ts b/src/registerServiceWorker.ts index ae9ac0a..d3182ac 100644 --- a/src/registerServiceWorker.ts +++ b/src/registerServiceWorker.ts @@ -3,7 +3,10 @@ import { register } from "register-service-worker"; // Only register service worker if explicitly enabled and in production -if (process.env.VITE_PWA_ENABLED === 'true' && process.env.NODE_ENV === "production") { +if ( + process.env.VITE_PWA_ENABLED === "true" && + process.env.NODE_ENV === "production" +) { register(`${process.env.BASE_URL}sw.js`, { ready() { console.log("Service worker is active."); @@ -21,12 +24,16 @@ if (process.env.VITE_PWA_ENABLED === 'true' && process.env.NODE_ENV === "product console.log("New content is available; please refresh."); }, offline() { - console.log("No internet connection found. App is running in offline mode."); + console.log( + "No internet connection found. App is running in offline mode.", + ); }, error(error) { console.error("Error during service worker registration:", error); - } + }, }); } else { - console.log("Service worker registration skipped - not enabled or not in production"); + console.log( + "Service worker registration skipped - not enabled or not in production", + ); } diff --git a/src/router/index.ts b/src/router/index.ts index 051ad43..0c63eec 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -286,7 +286,7 @@ const routes: Array = [ const isElectron = window.location.protocol === "file:"; const initialPath = isElectron - ? window.location.pathname.split('/dist-electron/www/')[1] || '/' + ? window.location.pathname.split("/dist-electron/www/")[1] || "/" : window.location.pathname; const history = isElectron diff --git a/src/vite.config.utils.js b/src/vite.config.utils.js index 8498b76..719edfc 100644 --- a/src/vite.config.utils.js +++ b/src/vite.config.utils.js @@ -1,6 +1,6 @@ import * as path from "path"; import { promises as fs } from "fs"; -import { fileURLToPath } from 'url'; +import { fileURLToPath } from "url"; export async function loadAppConfig() { const packageJson = await loadPackageJson(); @@ -34,15 +34,16 @@ export async function loadAppConfig() { sizes: "512x512", type: "image/png", purpose: "maskable", - } - ] - } + }, + ], + }, }, aliasConfig: { "@": path.resolve(path.dirname(__dirname), "src"), buffer: path.resolve(path.dirname(__dirname), "node_modules", "buffer"), - "dexie-export-import/dist/import": "dexie-export-import/dist/import/index.js", - } + "dexie-export-import/dist/import": + "dexie-export-import/dist/import/index.js", + }, }; }