Commit afdc4ddb authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix: include native-bridge.js that engine.js imports

Missing file caused blank screen after deploy.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 4073a3f3
import * as bus from './bus.js';
import * as store from './store.js';
import * as scene from './scene.js';
import * as input from './input.js';
let bridge = null;
export function init() {
if (!window.flutter_bridge) return;
bridge = window.flutter_bridge;
// Mark as native app — CSS uses this to hide web bottom nav
document.documentElement.classList.add('native-app');
window.IS_NATIVE_APP = true;
// Register handler object for Flutter → Web calls
window.el3ab_native = {
onDeepLink: handleDeepLink,
onPushTap: handlePushTap,
onConnectivityChanged: handleConnectivity,
onTokenRefreshed: handleTokenRefresh,
onNavTap: handleNavTap,
};
// Override haptic to use native
if (input.haptic) {
const originalHaptic = input.haptic;
input.haptic = (type) => {
send('haptic', { type: type || 'light' });
originalHaptic(type);
};
}
// Listen for auth events to notify Flutter
bus.on('auth:success', () => {
const token = store.get('auth.token');
const userId = store.get('auth.userId');
send('auth_ready', { token, userId });
});
bus.on('auth:logout', () => {
send('auth_logout', {});
});
// Listen for world/nav changes to sync Flutter bottom bar
bus.on('scene:world_changed', (world) => {
send('nav_sync', { world, gameMode: false });
});
// Listen for game mode enter/exit
bus.on('game:enter', () => {
send('nav_sync', { world: 'play', gameMode: true });
});
bus.on('game:exit', () => {
const world = store.get('activeWorld') || 'play';
send('nav_sync', { world, gameMode: false });
});
// Listen for notification badge updates
bus.on('notifications:count', (count) => {
send('badge', { count });
});
console.log('[Native Bridge] Initialized');
}
function send(cmd, data) {
if (!bridge) return;
bridge.postMessage(JSON.stringify({ cmd, ...data }));
}
function handleDeepLink(data) {
const { route, id } = data;
switch (route) {
case 'match':
bus.emit('native:open_match', id);
break;
case 'invite':
bus.emit('native:accept_invite', id);
break;
case 'tournament':
scene.switchWorld('tournaments');
bus.emit('native:open_tournament', id);
break;
case 'profile':
scene.switchWorld('profile');
bus.emit('native:open_profile', id);
break;
case 'play':
scene.switchWorld('play');
break;
default:
scene.switchWorld('play');
}
}
function handlePushTap(data) {
const { type, match_id, route } = data;
switch (type) {
case 'match_invite':
case 'your_turn':
case 'match_result':
if (match_id) bus.emit('native:open_match', match_id);
break;
case 'tournament_start':
scene.switchWorld('tournaments');
break;
case 'friend_online':
scene.switchWorld('social');
break;
case 'chat_message':
scene.switchWorld('social');
break;
default:
if (route) {
const segments = route.split('/').filter(Boolean);
if (segments.length >= 1) handleDeepLink({ route: segments[0], id: segments[1] });
}
}
}
function handleConnectivity(data) {
bus.emit('connectivity:changed', data.online);
}
function handleTokenRefresh(data) {
if (data.token) {
store.set('auth.token', data.token);
}
}
function handleNavTap(data) {
const { world } = data;
if (world) scene.switchWorld(world);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment