Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<!-- Custom Assets -->
<link rel="stylesheet" href="./src/styles.css?v=13" />
<script src="./src/scanner.js?v=13"></script>
<script src="./src/vision-scanner.js?v=13"></script>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script src="https://cdn.jsdelivr.net/npm/appwrite@14.0.1"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
Expand Down
2 changes: 2 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ReGenXRealtime } from './realtime-sync.js';
import { CloudSync } from './cloud-sync.js';
import { ESGReporter } from './esg-reporter.js';
import { AccessibilityManager } from './accessibility.js';
import { initOfflineDB, setupNetworkListeners } from './offline-sync.js';
const STORAGE_KEY_PREFIX = "regenx-v3:";
const TRUST_LEDGER_KEY = STORAGE_KEY_PREFIX + "trust-ledger";
const ESG_ALERTS_KEY = STORAGE_KEY_PREFIX + "esg-alerts";
Expand Down Expand Up @@ -5208,6 +5209,7 @@ switchAuthTab('login');
// ── Initialize Appwrite Cloud Sync Engine ──
setTimeout(() => { ReGenXRealtime?.init(); ReGenXRealtime?.requestSnapshot?.(); }, 1000);
setTimeout(() => { if (window.CloudSync) window.CloudSync.init(); }, 1000);
initOfflineDB().then(() => { setupNetworkListeners(); }).catch(err => console.error('[OfflineSync] Failed to initialize:', err));

// Expose module-scoped functions to global scope for inline HTML handlers
window.doRegister = doRegister;
Expand Down
37 changes: 20 additions & 17 deletions src/offline-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,24 +171,27 @@ export async function syncPendingActions() {
* @returns {Promise<void>}
*/
async function processAction(action) {
// Replace with actual API endpoints per action type
const endpoints = {
dispatch: '/api/dispatch',
pickup: '/api/pickup',
gps: '/api/location',
scan: '/api/scan',
reward: '/api/rewards'
};

const url = endpoints[action.type] || '/api/sync';

const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(action.payload)
});
if (!window.CloudSync || !window.CloudSync.isLive) {
throw new Error('[OfflineSync] CloudSync not available or not live');
}

if (!response.ok) throw new Error(`HTTP ${response.status}`);
switch (action.type) {
case 'dispatch':
case 'pickup':
case 'scan':
case 'plant':
await window.CloudSync.pushDocument(window.CloudSync.config.ordersCollectionId, action.payload);
break;
case 'reward':
await window.CloudSync.pushAccount(action.payload);
break;
case 'gps':
window.CloudSync.queueOfflineWrite('gps:' + action.payload.riderId, action.payload);
break;
default:
console.error(`[OfflineSync] Unknown action type: ${action.type} (${action.id})`);
throw new Error(`Unknown action type: ${action.type}`);
}
}

/**
Expand Down
45 changes: 37 additions & 8 deletions src/vision-scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export const VisionScanner = {
/**
* Captures a frame, checks for low light, and simulates AI analysis.
*/
captureAndAnalyze: (targetInputId) => {
captureAndAnalyze: async (targetInputId) => {
if (VisionScanner.isLowLight) {
console.warn("Inference paused: Low light conditions detected.");
return; // Prevent TensorFlow inference when noisy
Expand All @@ -260,23 +260,52 @@ export const VisionScanner = {
btn.style.opacity = '0.8';
}

setTimeout(() => {
// Algorithmic Mock: Generate a score between 60 and 95
const simulatedScore = Math.floor(Math.random() * (95 - 60 + 1) + 60);

try {
if (!window.BioScanner) throw new Error('BioScanner not available');

const result = await window.BioScanner.performScan(canvas);

if (!result || result.confidence == null) {
throw new Error('Scan result unavailable');
}

if (result.confidence < 30) {
VisionScanner.closeScanner();
if (window.showToast) {
window.showToast('⚠️ AI confidence too low. Please try again in better light.');
}
return;
}

if (!result.accepted) {
VisionScanner.closeScanner();
if (window.showToast) {
window.showToast('⚠️ Non-organic waste detected. Segregation score not applied.');
}
return;
}

const score = result.organicPercent;

// Set the value in the target input
const targetEl = document.getElementById(targetInputId);
if (targetEl) {
targetEl.value = simulatedScore;
targetEl.value = score;
targetEl.dispatchEvent(new Event('input', { bubbles: true }));
}

// Close scanner and notify
VisionScanner.closeScanner();
if (window.showToast) {
window.showToast(`✓ AI Scan Complete: Segregation Score ${simulatedScore}/100`);
window.showToast(`✓ AI Scan Complete: Segregation Score ${score}/100`);
}
}, 1500);
} catch (err) {
console.error("AI Vision Scanner error:", err);
VisionScanner.closeScanner();
if (window.showToast) {
window.showToast('⚠️ AI scan failed. Please try again or enter score manually.');
}
}
},

/**
Expand Down