From 141d2ea6a6fb43eba47b7c2ef9b19b73df0e1268 Mon Sep 17 00:00:00 2001 From: jared Date: Wed, 28 Jan 2026 18:16:33 +0000 Subject: [PATCH] Add standalone /carmode route and nginx documentation - Add /carmode URL that auto-enters car mode without exit option - /carmode uses its own API route (/carmode/api/) for isolation - Hide exit button and disable Escape key on /carmode - Skip lock screen on dedicated car mode URL - Replace macOS/Ubuntu docs with nginx configuration guide Co-Authored-By: Claude Opus 4.5 --- news-app/How_To_MacOS.txt | 80 ----------------------------------- news-app/How_To_Nginx.txt | 88 +++++++++++++++++++++++++++++++++++++++ news-app/for_ubuntu.txt | 61 --------------------------- news-app/src/main.js | 35 +++++++++++++--- 4 files changed, 118 insertions(+), 146 deletions(-) delete mode 100644 news-app/How_To_MacOS.txt create mode 100644 news-app/How_To_Nginx.txt delete mode 100644 news-app/for_ubuntu.txt diff --git a/news-app/How_To_MacOS.txt b/news-app/How_To_MacOS.txt deleted file mode 100644 index d4a2969..0000000 --- a/news-app/How_To_MacOS.txt +++ /dev/null @@ -1,80 +0,0 @@ -News App - macOS Service Management -==================================== - -Service: com.je.carnews -Port: 5555 -Plist: /Library/LaunchDaemons/com.je.carnews.plist - - -BASIC COMMANDS --------------- - -Start the service: - sudo launchctl kickstart system/com.je.carnews - -Stop the service: - sudo launchctl kill SIGTERM system/com.je.carnews - -Restart the service: - sudo launchctl kickstart -k system/com.je.carnews - -Check status: - sudo launchctl print system/com.je.carnews - -Check if running: - lsof -i :5555 - - -ADD TO STARTUP (BOOT) ---------------------- - -1. Copy the plist to LaunchDaemons: - sudo cp /opt/homebrew/var/www/news-app/com.je.carnews.plist /Library/LaunchDaemons/ - -2. Load the service: - sudo launchctl bootstrap system /Library/LaunchDaemons/com.je.carnews.plist - -3. Start it: - sudo launchctl kickstart system/com.je.carnews - -The service will now start automatically on boot. - - -REMOVE FROM STARTUP (BOOT) --------------------------- - -1. Stop and unload the service: - sudo launchctl bootout system/com.je.carnews - -2. Remove the plist file: - sudo rm /Library/LaunchDaemons/com.je.carnews.plist - -The service will no longer start on boot. - - -VIEW LOGS ---------- - -Output log: - tail -f /opt/homebrew/var/www/news-app/logs/out.log - -Error log: - tail -f /opt/homebrew/var/www/news-app/logs/error.log - - -TROUBLESHOOTING ---------------- - -If the service fails to start, check: - -1. Node version - the plist uses: - /Users/jared/.nvm/versions/node/v22.19.0/bin/node - -2. If you update Node via nvm, rebuild native modules: - cd /opt/homebrew/var/www/news-app - npm rebuild better-sqlite3 - -3. Then update the node path in the plist if needed and reload: - sudo launchctl bootout system/com.je.carnews - sudo launchctl bootstrap system /Library/LaunchDaemons/com.je.carnews.plist - sudo launchctl kickstart system/com.je.carnews diff --git a/news-app/How_To_Nginx.txt b/news-app/How_To_Nginx.txt new file mode 100644 index 0000000..b92039c --- /dev/null +++ b/news-app/How_To_Nginx.txt @@ -0,0 +1,88 @@ +Nginx Configuration for Car News App +===================================== + +This app requires two route groups in your nginx server block: + +1. /carnews/ - Full news app with regular and car mode views +2. /carmode/ - Standalone car mode display (no exit, no links to main app) + +Both routes share the same backend API server (port 5555) and static files. + + +NGINX CONFIGURATION +------------------- + +Add the following to your server block: + + # --- Car News App --- + location = /carnews { + return 301 /carnews/; + } + + location /carnews/api/ { + proxy_pass http://127.0.0.1:5555/api/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 180s; + proxy_connect_timeout 180s; + proxy_send_timeout 180s; + } + + location /carnews/ { + alias /var/www/news-feed-car-mode/news-app/dist/; + index index.html; + try_files $uri $uri/ /carnews/index.html; + } + + # --- Car Mode Direct Access --- + location = /carmode { + return 301 /carmode/; + } + + location /carmode/api/ { + proxy_pass http://127.0.0.1:5555/api/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 180s; + proxy_connect_timeout 180s; + proxy_send_timeout 180s; + } + + location /carmode/ { + alias /var/www/news-feed-car-mode/news-app/dist/; + index index.html; + try_files $uri $uri/ /carmode/index.html; + } + + +CONFIGURATION NOTES +------------------- + +- The API timeout is set to 180s because AI grouping requests can take time +- Both /carnews/ and /carmode/ serve the same dist/ folder +- The frontend JS detects which URL it's on and adjusts behavior accordingly +- proxy_http_version 1.1 is required for proper keep-alive connections + + +AFTER CHANGES +------------- + +Test and reload nginx: + + sudo nginx -t + sudo systemctl reload nginx + + +BUILDING THE APP +---------------- + +After code changes, rebuild the frontend: + + cd /var/www/news-feed-car-mode/news-app + npm run build diff --git a/news-app/for_ubuntu.txt b/news-app/for_ubuntu.txt deleted file mode 100644 index 0b523a5..0000000 --- a/news-app/for_ubuntu.txt +++ /dev/null @@ -1,61 +0,0 @@ -Based on the codebase analysis, here's what needs to change for your Ubuntu deployment: - - Required Changes - - Create a systemd service file instead: - - # /etc/systemd/system/carnews.service - [Unit] - Description=Car News API Server - After=network.target - - [Service] - Type=simple - User= - WorkingDirectory=/path/to/news-app - ExecStart=/usr/bin/node server.js - Restart=on-failure - EnvironmentFile=/path/to/news-app/.env - - [Install] - WantedBy=multi-user.target - - 2. Rebuild native modules - - The better-sqlite3 package requires recompilation on Ubuntu: - npm rebuild better-sqlite3 - - 3. Nginx configuration for Ubuntu - - You'll need to create an Nginx config (not included in this repo). Example: - - location /carnews/ { - alias /path/to/news-app/dist/; - try_files $uri $uri/ /carnews/index.html; - } - - location /carnews/api/ { - proxy_pass http://localhost:5555/api/; - proxy_http_version 1.1; - proxy_set_header Host $host; - } - - 4. Update paths if directory structure differs - - On Ubuntu: /var/www/news-feed-car-mode/news-app - - No Changes Needed - - - vite.config.js - base: '/carnews/' stays the same - - server.js - Port 5555 works as-is - - .env file - copied over - - All source code - Uses relative paths - - Deployment Steps - - 1. Copy the codebase to Ubuntu - 2. Run npm install and npm rebuild better-sqlite3 - 3. Run npm run build to generate fresh /dist files - 4. Create the systemd service file - 5. Configure Nginx with the proxy rules - 6. Enable and start the service: sudo systemctl enable --now carnews diff --git a/news-app/src/main.js b/news-app/src/main.js index 7e8ae42..ee90b8f 100644 --- a/news-app/src/main.js +++ b/news-app/src/main.js @@ -1,6 +1,10 @@ import './style.css' -const API_BASE = '/carnews/api' +// Check if we're on the dedicated car mode URL +const isCarModeUrl = window.location.pathname === '/carmode' || window.location.pathname === '/carmode/' + +// Use appropriate API base depending on URL +const API_BASE = isCarModeUrl ? '/carmode/api' : '/carnews/api' const app = document.querySelector('#app') // Fetch with timeout helper (default 2 minutes for AI calls) @@ -49,15 +53,16 @@ const state = { error: null, filter: 'all', viewMode: 'regular', // 'regular' or 'ai' - carMode: false, + carMode: isCarModeUrl, // Auto-enter car mode if on /carmode URL carModeIndex: 0, carModeInterval: null, carModeScrollTimeout: null, carModeScrollInterval: null, aiArticleCount: 0, - locked: !getCookie('news_feed_unlocked'), + locked: isCarModeUrl ? false : !getCookie('news_feed_unlocked'), // Skip lock for car mode URL unlockClicks: 0, isTransitioning: false, + isCarModeUrl: isCarModeUrl, // Track if we're on dedicated car mode URL } function formatDate(dateString) { @@ -274,11 +279,13 @@ function renderCarMode() {

${loadingMessage}

+ ${!state.isCarModeUrl ? ` + ` : ''} ` } @@ -291,12 +298,14 @@ function renderCarMode() {
+ ${!state.isCarModeUrl ? ` + ` : ''}
@@ -599,6 +608,11 @@ window.enterCarMode = async function() { } window.exitCarMode = function() { + // On dedicated car mode URL, just refresh the page to restart + if (state.isCarModeUrl) { + window.location.reload() + return + } state.carMode = false stopCarModeCycle() render() @@ -692,7 +706,10 @@ document.addEventListener('keydown', (e) => { switch (e.key) { case 'Escape': - window.exitCarMode() + // Don't allow escape on dedicated car mode URL + if (!state.isCarModeUrl) { + window.exitCarMode() + } break case 'ArrowRight': case ' ': @@ -704,9 +721,17 @@ document.addEventListener('keydown', (e) => { } }) -fetchNews() +// Initialize: either start car mode or fetch regular news +if (isCarModeUrl) { + // On dedicated car mode URL, directly enter car mode + window.enterCarMode() +} else { + fetchNews() +} setInterval(() => { + // Don't auto-refresh if in car mode (it handles its own data) + if (state.carMode) return if (state.viewMode === 'ai') { fetchGroupedNews() } else {