434 lines
20 KiB
HTML
434 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
<meta http-equiv="Pragma" content="no-cache">
|
|
<meta http-equiv="Expires" content="0">
|
|
<title>DailyNotification Plugin Test</title>
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
margin: 0;
|
|
padding: 20px;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
min-height: 100vh;
|
|
color: white;
|
|
}
|
|
.container {
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
text-align: center;
|
|
}
|
|
h1 {
|
|
margin-bottom: 30px;
|
|
font-size: 2.5em;
|
|
}
|
|
.button {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
color: white;
|
|
padding: 15px 30px;
|
|
margin: 10px;
|
|
border-radius: 25px;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.button:hover {
|
|
background: rgba(255, 255, 255, 0.3);
|
|
transform: translateY(-2px);
|
|
}
|
|
.status {
|
|
margin-top: 30px;
|
|
padding: 20px;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
border-radius: 10px;
|
|
font-family: monospace;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div id="statusCard" class="status" style="margin-bottom: 20px; font-size: 14px;">
|
|
<strong>Plugin Status</strong><br>
|
|
<div style="margin-top: 10px;">
|
|
⚙️ Plugin Settings: <span id="configStatus">Not configured</span><br>
|
|
🔌 Native Fetcher: <span id="fetcherStatus">Not configured</span><br>
|
|
🔔 Notifications: <span id="notificationPermStatus">Checking...</span><br>
|
|
⏰ Exact Alarms: <span id="exactAlarmPermStatus">Checking...</span><br>
|
|
📢 Channel: <span id="channelStatus">Checking...</span><br>
|
|
<div id="pluginStatusContent" style="margin-top: 8px;">
|
|
Loading plugin status...
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="button" onclick="configurePlugin()">Configure Plugin</button>
|
|
<button class="button" onclick="requestPermissions()">Request Permissions</button>
|
|
<button class="button" onclick="testNotification()">Test Notification</button>
|
|
<button class="button" onclick="checkComprehensiveStatus()">Full System Status</button>
|
|
|
|
<div id="status" class="status">
|
|
Ready to test...
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
console.log('Script loading...');
|
|
console.log('JavaScript is working!');
|
|
|
|
// Use real DailyNotification plugin
|
|
console.log('Using real DailyNotification plugin...');
|
|
window.DailyNotification = window.Capacitor.Plugins.DailyNotification;
|
|
|
|
// Define functions immediately and attach to window
|
|
|
|
function configurePlugin() {
|
|
console.log('configurePlugin called');
|
|
const status = document.getElementById('status');
|
|
const configStatus = document.getElementById('configStatus');
|
|
const fetcherStatus = document.getElementById('fetcherStatus');
|
|
|
|
status.innerHTML = 'Configuring plugin...';
|
|
status.style.background = 'rgba(255, 255, 0, 0.3)'; // Yellow background
|
|
|
|
// Update top status to show configuring
|
|
configStatus.innerHTML = '⏳ Configuring...';
|
|
fetcherStatus.innerHTML = '⏳ Waiting...';
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
status.innerHTML = 'DailyNotification plugin not available';
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
configStatus.innerHTML = '❌ Plugin unavailable';
|
|
fetcherStatus.innerHTML = '❌ Plugin unavailable';
|
|
return;
|
|
}
|
|
|
|
// Configure plugin settings
|
|
window.DailyNotification.configure({
|
|
storage: 'tiered',
|
|
ttlSeconds: 86400,
|
|
prefetchLeadMinutes: 60,
|
|
maxNotificationsPerDay: 3,
|
|
retentionDays: 7
|
|
})
|
|
.then(() => {
|
|
console.log('Plugin settings configured, now configuring native fetcher...');
|
|
// Update top status
|
|
configStatus.innerHTML = '✅ Configured';
|
|
|
|
// Configure native fetcher with demo credentials
|
|
// Note: DemoNativeFetcher uses hardcoded mock data, so this is optional
|
|
// but demonstrates the API. In production, this would be real credentials.
|
|
return window.DailyNotification.configureNativeFetcher({
|
|
apiBaseUrl: 'http://10.0.2.2:3000', // Android emulator → host localhost
|
|
activeDid: 'did:ethr:0xDEMO1234567890', // Demo DID
|
|
jwtSecret: 'demo-jwt-secret-for-development-testing'
|
|
});
|
|
})
|
|
.then(() => {
|
|
// Update top status
|
|
fetcherStatus.innerHTML = '✅ Configured';
|
|
|
|
// Update bottom status for user feedback
|
|
status.innerHTML = 'Plugin configured successfully!';
|
|
status.style.background = 'rgba(0, 255, 0, 0.3)'; // Green background
|
|
})
|
|
.catch(error => {
|
|
// Update top status with error
|
|
if (configStatus.innerHTML.includes('Configuring')) {
|
|
configStatus.innerHTML = '❌ Failed';
|
|
}
|
|
if (fetcherStatus.innerHTML.includes('Waiting') || fetcherStatus.innerHTML.includes('Configuring')) {
|
|
fetcherStatus.innerHTML = '❌ Failed';
|
|
}
|
|
|
|
status.innerHTML = `Configuration failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
});
|
|
} catch (error) {
|
|
configStatus.innerHTML = '❌ Error';
|
|
fetcherStatus.innerHTML = '❌ Error';
|
|
status.innerHTML = `Configuration failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
}
|
|
}
|
|
|
|
function loadPluginStatus() {
|
|
console.log('loadPluginStatus called');
|
|
const pluginStatusContent = document.getElementById('pluginStatusContent');
|
|
const statusCard = document.getElementById('statusCard');
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
pluginStatusContent.innerHTML = '❌ DailyNotification plugin not available';
|
|
statusCard.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
return;
|
|
}
|
|
window.DailyNotification.getNotificationStatus()
|
|
.then(result => {
|
|
const nextTime = result.nextNotificationTime ? new Date(result.nextNotificationTime).toLocaleString() : 'None scheduled';
|
|
const hasSchedules = result.isEnabled || (result.pending && result.pending > 0);
|
|
const statusIcon = hasSchedules ? '✅' : '⏸️';
|
|
pluginStatusContent.innerHTML = `${statusIcon} Active Schedules: ${hasSchedules ? 'Yes' : 'No'}<br>
|
|
📅 Next Notification: ${nextTime}<br>
|
|
⏳ Pending: ${result.pending || 0}`;
|
|
statusCard.style.background = hasSchedules ?
|
|
'rgba(0, 255, 0, 0.15)' : 'rgba(255, 255, 255, 0.1)'; // Green if active, light gray if none
|
|
})
|
|
.catch(error => {
|
|
pluginStatusContent.innerHTML = `⚠️ Status check failed: ${error.message}`;
|
|
statusCard.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
});
|
|
} catch (error) {
|
|
pluginStatusContent.innerHTML = `⚠️ Status check failed: ${error.message}`;
|
|
statusCard.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
}
|
|
}
|
|
|
|
// Notification test functions
|
|
function testNotification() {
|
|
console.log('testNotification called');
|
|
|
|
// Quick sanity check - test plugin availability
|
|
if (window.Capacitor && window.Capacitor.isPluginAvailable) {
|
|
const isAvailable = window.Capacitor.isPluginAvailable('DailyNotification');
|
|
console.log('is plugin available?', isAvailable);
|
|
}
|
|
|
|
const status = document.getElementById('status');
|
|
status.innerHTML = 'Testing plugin connection...';
|
|
status.style.background = 'rgba(255, 255, 0, 0.3)'; // Yellow background
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
status.innerHTML = 'DailyNotification plugin not available';
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
return;
|
|
}
|
|
|
|
// Test the notification method directly
|
|
console.log('Testing notification scheduling...');
|
|
const now = new Date();
|
|
const notificationTime = new Date(now.getTime() + 240000); // 4 minutes from now
|
|
const prefetchTime = new Date(now.getTime() + 120000); // 2 minutes from now (2 min before notification)
|
|
const notificationTimeString = notificationTime.getHours().toString().padStart(2, '0') + ':' +
|
|
notificationTime.getMinutes().toString().padStart(2, '0');
|
|
const prefetchTimeString = prefetchTime.getHours().toString().padStart(2, '0') + ':' +
|
|
prefetchTime.getMinutes().toString().padStart(2, '0');
|
|
|
|
window.DailyNotification.scheduleDailyNotification({
|
|
time: notificationTimeString,
|
|
title: 'Test Notification',
|
|
body: 'This is a test notification from the DailyNotification plugin!',
|
|
sound: true,
|
|
priority: 'high'
|
|
})
|
|
.then(() => {
|
|
const prefetchTimeReadable = prefetchTime.toLocaleTimeString();
|
|
const notificationTimeReadable = notificationTime.toLocaleTimeString();
|
|
status.innerHTML = '✅ Notification scheduled!<br>' +
|
|
'📥 Prefetch: ' + prefetchTimeReadable + ' (' + prefetchTimeString + ')<br>' +
|
|
'🔔 Notification: ' + notificationTimeReadable + ' (' + notificationTimeString + ')';
|
|
status.style.background = 'rgba(0, 255, 0, 0.3)'; // Green background
|
|
// Refresh plugin status display
|
|
setTimeout(() => loadPluginStatus(), 500);
|
|
})
|
|
.catch(error => {
|
|
// Check if this is an exact alarm permission error
|
|
if (error.code === 'EXACT_ALARM_PERMISSION_REQUIRED' ||
|
|
error.message.includes('Exact alarm permission') ||
|
|
error.message.includes('Alarms & reminders')) {
|
|
status.innerHTML = '⚠️ Exact Alarm Permission Required<br><br>' +
|
|
'Settings opened automatically.<br>' +
|
|
'Please enable "Allow exact alarms" and return to try again.';
|
|
status.style.background = 'rgba(255, 165, 0, 0.3)'; // Orange background
|
|
} else {
|
|
status.innerHTML = `❌ Notification failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
}
|
|
});
|
|
} catch (error) {
|
|
status.innerHTML = `Notification test failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
}
|
|
}
|
|
|
|
|
|
// Permission management functions
|
|
function requestPermissions() {
|
|
console.log('requestPermissions called');
|
|
const status = document.getElementById('status');
|
|
status.innerHTML = 'Requesting permissions...';
|
|
status.style.background = 'rgba(255, 255, 0, 0.3)'; // Yellow background
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
status.innerHTML = 'DailyNotification plugin not available';
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
return;
|
|
}
|
|
|
|
window.DailyNotification.requestNotificationPermissions()
|
|
.then(() => {
|
|
status.innerHTML = 'Permission request completed! Check your device settings if needed.';
|
|
status.style.background = 'rgba(0, 255, 0, 0.3)'; // Green background
|
|
|
|
// Refresh permission and channel status display after request
|
|
setTimeout(() => {
|
|
loadPermissionStatus();
|
|
loadChannelStatus();
|
|
}, 1000);
|
|
})
|
|
.catch(error => {
|
|
status.innerHTML = `Permission request failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
});
|
|
} catch (error) {
|
|
status.innerHTML = `Permission request failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
}
|
|
}
|
|
|
|
function loadChannelStatus() {
|
|
const channelStatus = document.getElementById('channelStatus');
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
channelStatus.innerHTML = '❌ Plugin unavailable';
|
|
return;
|
|
}
|
|
|
|
window.DailyNotification.isChannelEnabled()
|
|
.then(result => {
|
|
const importanceText = getImportanceText(result.importance);
|
|
if (result.enabled) {
|
|
channelStatus.innerHTML = `✅ Enabled (${importanceText})`;
|
|
} else {
|
|
channelStatus.innerHTML = `❌ Disabled (${importanceText})`;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
channelStatus.innerHTML = '⚠️ Error';
|
|
});
|
|
} catch (error) {
|
|
channelStatus.innerHTML = '⚠️ Error';
|
|
}
|
|
}
|
|
|
|
function checkComprehensiveStatus() {
|
|
const status = document.getElementById('status');
|
|
status.innerHTML = 'Checking comprehensive status...';
|
|
status.style.background = 'rgba(255, 255, 0, 0.3)'; // Yellow background
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
status.innerHTML = 'DailyNotification plugin not available';
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
return;
|
|
}
|
|
|
|
window.DailyNotification.checkStatus()
|
|
.then(result => {
|
|
const canSchedule = result.canScheduleNow;
|
|
const issues = [];
|
|
|
|
if (!result.postNotificationsGranted) {
|
|
issues.push('POST_NOTIFICATIONS permission');
|
|
}
|
|
if (!result.channelEnabled) {
|
|
issues.push('notification channel disabled');
|
|
}
|
|
if (!result.exactAlarmsGranted) {
|
|
issues.push('exact alarm permission');
|
|
}
|
|
|
|
let statusText = `Status: ${canSchedule ? 'Ready to schedule' : 'Issues found'}`;
|
|
if (issues.length > 0) {
|
|
statusText += `\nIssues: ${issues.join(', ')}`;
|
|
}
|
|
|
|
statusText += `\nChannel: ${getImportanceText(result.channelImportance)}`;
|
|
statusText += `\nChannel ID: ${result.channelId}`;
|
|
|
|
status.innerHTML = statusText;
|
|
status.style.background = canSchedule ? 'rgba(0, 255, 0, 0.3)' : 'rgba(255, 0, 0, 0.3)';
|
|
})
|
|
.catch(error => {
|
|
status.innerHTML = `Status check failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
});
|
|
} catch (error) {
|
|
status.innerHTML = `Status check failed: ${error.message}`;
|
|
status.style.background = 'rgba(255, 0, 0, 0.3)'; // Red background
|
|
}
|
|
}
|
|
|
|
function getImportanceText(importance) {
|
|
switch (importance) {
|
|
case 0: return 'None (blocked)';
|
|
case 1: return 'Min';
|
|
case 2: return 'Low';
|
|
case 3: return 'Default';
|
|
case 4: return 'High';
|
|
case 5: return 'Max';
|
|
default: return `Unknown (${importance})`;
|
|
}
|
|
}
|
|
|
|
// Attach to window object
|
|
window.configurePlugin = configurePlugin;
|
|
window.testNotification = testNotification;
|
|
window.requestPermissions = requestPermissions;
|
|
window.checkComprehensiveStatus = checkComprehensiveStatus;
|
|
|
|
function loadPermissionStatus() {
|
|
const notificationPermStatus = document.getElementById('notificationPermStatus');
|
|
const exactAlarmPermStatus = document.getElementById('exactAlarmPermStatus');
|
|
|
|
try {
|
|
if (!window.DailyNotification) {
|
|
notificationPermStatus.innerHTML = '❌ Plugin unavailable';
|
|
exactAlarmPermStatus.innerHTML = '❌ Plugin unavailable';
|
|
return;
|
|
}
|
|
|
|
window.DailyNotification.checkPermissionStatus()
|
|
.then(result => {
|
|
notificationPermStatus.innerHTML = result.notificationsEnabled ? '✅ Granted' : '❌ Not granted';
|
|
exactAlarmPermStatus.innerHTML = result.exactAlarmEnabled ? '✅ Granted' : '❌ Not granted';
|
|
})
|
|
.catch(error => {
|
|
notificationPermStatus.innerHTML = '⚠️ Error';
|
|
exactAlarmPermStatus.innerHTML = '⚠️ Error';
|
|
});
|
|
} catch (error) {
|
|
notificationPermStatus.innerHTML = '⚠️ Error';
|
|
exactAlarmPermStatus.innerHTML = '⚠️ Error';
|
|
}
|
|
}
|
|
|
|
// Load plugin status automatically on page load
|
|
window.addEventListener('load', () => {
|
|
console.log('Page loaded, loading plugin status...');
|
|
// Small delay to ensure Capacitor is ready
|
|
setTimeout(() => {
|
|
loadPluginStatus();
|
|
loadPermissionStatus();
|
|
loadChannelStatus();
|
|
}, 500);
|
|
});
|
|
|
|
|
|
|
|
console.log('Functions attached to window:', {
|
|
configurePlugin: typeof window.configurePlugin,
|
|
testNotification: typeof window.testNotification
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|