muspe-cli
Version:
MusPE Advanced Framework v2.1.3 - Mobile User-friendly Simple Progressive Engine with Enhanced CLI Tools, Specialized E-Commerce Templates, Material Design 3, Progressive Enhancement, Mobile Optimizations, Performance Analysis, and Enterprise-Grade Develo
415 lines (368 loc) β’ 13.9 kB
JavaScript
// Cordova Demo Component - showcases native device integration
class CordovaDemo {
constructor() {
this.deviceInfo = null;
this.networkInfo = null;
this.init();
}
init() {
// Wait for MusPE and Cordova to be ready
if (typeof MusPE !== 'undefined' && MusPE.cordova) {
MusPE.cordova.ready(() => {
this.setupDemo();
});
} else {
// Fallback for browser mode
setTimeout(() => this.setupDemo(), 500);
}
}
setupDemo() {
this.render();
this.setupEventListeners();
this.updateDeviceInfo();
this.updateNetworkInfo();
}
render() {
const container = MusPE.$('#app');
const template = `
<div class="cordova-demo">
<div class="demo-header">
<h1>π± Cordova Integration Demo</h1>
<p>Test native device features with MusPE + Cordova</p>
</div>
<div class="demo-section">
<h2>π Device Information</h2>
<div id="device-info" class="info-card">
<div class="loading">Loading device info...</div>
</div>
</div>
<div class="demo-section">
<h2>π Network Status</h2>
<div id="network-info" class="info-card">
<div class="loading">Checking network...</div>
</div>
</div>
<div class="demo-section">
<h2>π· Camera Features</h2>
<div class="feature-buttons">
<button id="take-photo" class="btn btn-primary">
πΈ Take Photo
</button>
<button id="choose-photo" class="btn btn-secondary">
πΌοΈ Choose from Gallery
</button>
</div>
<div id="photo-result" class="photo-container"></div>
</div>
<div class="demo-section">
<h2>π Geolocation</h2>
<div class="feature-buttons">
<button id="get-location" class="btn btn-primary">
πΊοΈ Get Current Location
</button>
<button id="watch-location" class="btn btn-secondary">
ποΈ Watch Location
</button>
<button id="stop-watch" class="btn btn-danger" disabled>
βΉοΈ Stop Watching
</button>
</div>
<div id="location-result" class="info-card">
<div class="placeholder">No location data yet</div>
</div>
</div>
<div class="demo-section">
<h2>π§ System Controls</h2>
<div class="feature-buttons">
<button id="hide-statusbar" class="btn btn-secondary">
π± Hide Status Bar
</button>
<button id="show-statusbar" class="btn btn-secondary">
π± Show Status Bar
</button>
<button id="hide-splash" class="btn btn-primary">
π« Hide Splash Screen
</button>
<button id="open-browser" class="btn btn-info">
π Open In-App Browser
</button>
</div>
</div>
<div class="demo-section">
<h2>π± App Events</h2>
<div id="event-log" class="event-log">
<div class="log-item">App started</div>
</div>
</div>
</div>
`;
container.innerHTML = template;
}
setupEventListeners() {
// Camera buttons
MusPE.$('#take-photo').on('click', () => this.takePicture());
MusPE.$('#choose-photo').on('click', () => this.choosePicture());
// Location buttons
MusPE.$('#get-location').on('click', () => this.getCurrentLocation());
MusPE.$('#watch-location').on('click', () => this.watchLocation());
MusPE.$('#stop-watch').on('click', () => this.stopWatchingLocation());
// System control buttons
MusPE.$('#hide-statusbar').on('click', () => this.hideStatusBar());
MusPE.$('#show-statusbar').on('click', () => this.showStatusBar());
MusPE.$('#hide-splash').on('click', () => this.hideSplashScreen());
MusPE.$('#open-browser').on('click', () => this.openInAppBrowser());
// Listen to MusPE events
if (typeof MusPE !== 'undefined') {
MusPE.on('app:pause', () => this.logEvent('App paused'));
MusPE.on('app:resume', () => this.logEvent('App resumed'));
MusPE.on('device:backbutton', () => this.logEvent('Back button pressed'));
MusPE.on('device:menubutton', () => this.logEvent('Menu button pressed'));
MusPE.on('network:online', () => this.logEvent('Network online'));
MusPE.on('network:offline', () => this.logEvent('Network offline'));
}
}
updateDeviceInfo() {
const container = MusPE.$('#device-info');
if (MusPE.cordova && MusPE.cordova.isCordova()) {
const info = MusPE.cordova.getDeviceInfo();
if (info) {
container.innerHTML = `
<div class="info-row"><strong>Platform:</strong> ${info.platform}</div>
<div class="info-row"><strong>Model:</strong> ${info.model}</div>
<div class="info-row"><strong>Version:</strong> ${info.version}</div>
<div class="info-row"><strong>UUID:</strong> ${info.uuid}</div>
<div class="info-row"><strong>Cordova:</strong> ${info.cordova}</div>
<div class="info-row"><strong>Manufacturer:</strong> ${info.manufacturer || 'N/A'}</div>
<div class="info-row"><strong>Virtual:</strong> ${info.isVirtual ? 'Yes' : 'No'}</div>
`;
} else {
container.innerHTML = '<div class="error">Device info not available</div>';
}
} else {
container.innerHTML = `
<div class="info-row"><strong>Platform:</strong> Browser</div>
<div class="info-row"><strong>User Agent:</strong> ${navigator.userAgent}</div>
<div class="info-row"><strong>Language:</strong> ${navigator.language}</div>
<div class="info-row"><strong>Cookies:</strong> ${navigator.cookieEnabled ? 'Enabled' : 'Disabled'}</div>
`;
}
}
updateNetworkInfo() {
const container = MusPE.$('#network-info');
if (MusPE.cordova && MusPE.cordova.isCordova()) {
const info = MusPE.cordova.getNetworkInfo();
container.innerHTML = `
<div class="info-row"><strong>Status:</strong>
<span class="status ${info.isOnline ? 'online' : 'offline'}">
${info.isOnline ? 'π’ Online' : 'π΄ Offline'}
</span>
</div>
<div class="info-row"><strong>Connection:</strong> ${info.type || 'Unknown'}</div>
<div class="info-row"><strong>Effective Type:</strong> ${info.effectiveType || 'N/A'}</div>
<div class="info-row"><strong>Downlink:</strong> ${info.downlink || 'N/A'} Mbps</div>
<div class="info-row"><strong>RTT:</strong> ${info.rtt || 'N/A'} ms</div>
`;
} else {
container.innerHTML = `
<div class="info-row"><strong>Status:</strong>
<span class="status ${navigator.onLine ? 'online' : 'offline'}">
${navigator.onLine ? 'π’ Online' : 'π΄ Offline'}
</span>
</div>
<div class="info-row"><strong>Connection:</strong> Browser (navigator.onLine)</div>
`;
}
}
async takePicture() {
try {
if (!MusPE.cordova || !MusPE.cordova.isCordova()) {
this.showAlert('Camera not available in browser mode');
return;
}
const imageUri = await MusPE.cordova.camera.getPicture({
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA
});
this.displayPhoto(imageUri);
this.logEvent('Photo taken from camera');
} catch (error) {
this.showAlert('Camera error: ' + error.message);
this.logEvent('Camera error: ' + error.message);
}
}
async choosePicture() {
try {
if (!MusPE.cordova || !MusPE.cordova.isCordova()) {
this.showAlert('Gallery not available in browser mode');
return;
}
const imageUri = await MusPE.cordova.camera.getPicture({
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY
});
this.displayPhoto(imageUri);
this.logEvent('Photo selected from gallery');
} catch (error) {
this.showAlert('Gallery error: ' + error.message);
this.logEvent('Gallery error: ' + error.message);
}
}
displayPhoto(imageUri) {
const container = MusPE.$('#photo-result');
container.innerHTML = `
<div class="photo-preview">
<img src="${imageUri}" alt="Captured photo" style="max-width: 100%; height: auto; border-radius: 8px;">
<p class="photo-info">Image URI: ${imageUri}</p>
</div>
`;
}
async getCurrentLocation() {
try {
const position = await this.getPosition();
this.displayLocation(position, 'current');
this.logEvent('Current location retrieved');
} catch (error) {
this.showAlert('Location error: ' + error.message);
this.logEvent('Location error: ' + error.message);
}
}
watchLocation() {
if (this.watchId) {
this.stopWatchingLocation();
}
if (MusPE.cordova && MusPE.cordova.isCordova()) {
this.watchId = MusPE.cordova.geolocation.watchPosition(
(position) => {
this.displayLocation(position, 'watching');
this.logEvent('Location updated (watching)');
},
(error) => {
this.showAlert('Watch location error: ' + error.message);
},
{ enableHighAccuracy: true, timeout: 5000, maximumAge: 1000 }
);
} else {
this.watchId = navigator.geolocation.watchPosition(
(position) => {
this.displayLocation(position, 'watching');
this.logEvent('Location updated (watching)');
},
(error) => {
this.showAlert('Watch location error: ' + error.message);
}
);
}
MusPE.$('#watch-location').prop('disabled', true);
MusPE.$('#stop-watch').prop('disabled', false);
this.logEvent('Started watching location');
}
stopWatchingLocation() {
if (this.watchId) {
if (MusPE.cordova && MusPE.cordova.isCordova()) {
MusPE.cordova.geolocation.clearWatch(this.watchId);
} else {
navigator.geolocation.clearWatch(this.watchId);
}
this.watchId = null;
}
MusPE.$('#watch-location').prop('disabled', false);
MusPE.$('#stop-watch').prop('disabled', true);
this.logEvent('Stopped watching location');
}
getPosition() {
return new Promise((resolve, reject) => {
if (MusPE.cordova && MusPE.cordova.isCordova()) {
MusPE.cordova.geolocation.getCurrentPosition(resolve, reject);
} else {
navigator.geolocation.getCurrentPosition(resolve, reject);
}
});
}
displayLocation(position, type) {
const container = MusPE.$('#location-result');
const coords = position.coords;
container.innerHTML = `
<div class="location-info">
<div class="info-row"><strong>Type:</strong> ${type}</div>
<div class="info-row"><strong>Latitude:</strong> ${coords.latitude.toFixed(6)}</div>
<div class="info-row"><strong>Longitude:</strong> ${coords.longitude.toFixed(6)}</div>
<div class="info-row"><strong>Accuracy:</strong> ${coords.accuracy} meters</div>
<div class="info-row"><strong>Altitude:</strong> ${coords.altitude || 'N/A'}</div>
<div class="info-row"><strong>Speed:</strong> ${coords.speed || 'N/A'} m/s</div>
<div class="info-row"><strong>Heading:</strong> ${coords.heading || 'N/A'}Β°</div>
<div class="info-row"><strong>Timestamp:</strong> ${new Date(position.timestamp).toLocaleString()}</div>
</div>
`;
}
hideStatusBar() {
if (MusPE.cordova && MusPE.cordova.isCordova()) {
MusPE.cordova.statusBar.hide();
this.logEvent('Status bar hidden');
} else {
this.showAlert('Status bar control not available in browser');
}
}
showStatusBar() {
if (MusPE.cordova && MusPE.cordova.isCordova()) {
MusPE.cordova.statusBar.show();
this.logEvent('Status bar shown');
} else {
this.showAlert('Status bar control not available in browser');
}
}
hideSplashScreen() {
if (MusPE.cordova && MusPE.cordova.isCordova()) {
MusPE.cordova.splashScreen.hide();
this.logEvent('Splash screen hidden');
} else {
this.showAlert('Splash screen control not available in browser');
}
}
openInAppBrowser() {
const url = 'https://muspe.com';
if (MusPE.cordova && MusPE.cordova.isCordova()) {
MusPE.cordova.inAppBrowser.open(url, '_blank', 'location=yes,hidden=no');
this.logEvent('Opened in-app browser: ' + url);
} else {
window.open(url, '_blank');
this.logEvent('Opened browser window: ' + url);
}
}
showAlert(message) {
if (MusPE.cordova && MusPE.cordova.isCordova() && navigator.notification) {
navigator.notification.alert(message, null, 'MusPE Demo', 'OK');
} else {
alert(message);
}
}
logEvent(message) {
const container = MusPE.$('#event-log');
const timestamp = new Date().toLocaleTimeString();
const logItem = MusPE.dom.create('div', {
class: 'log-item',
textContent: `[${timestamp}] ${message}`
});
container.prepend(logItem);
// Keep only last 10 log items
const items = container.querySelectorAll('.log-item');
if (items.length > 10) {
items[items.length - 1].remove();
}
}
}
// Auto-initialize when DOM is ready
if (typeof MusPE !== 'undefined') {
MusPE.ready(() => {
new CordovaDemo();
});
} else {
document.addEventListener('DOMContentLoaded', () => {
new CordovaDemo();
});
}
// Export for module usage
if (typeof module !== 'undefined' && module.exports) {
module.exports = CordovaDemo;
}