feat(ios): add iOS deployment support and web assets parity
Add comprehensive iOS build and deployment infrastructure with command-line tooling, documentation, and web assets synchronization. Changes: - Update Capacitor dependencies to v6.0 in podspec - Add iOS build support to build-native.sh with NVM integration - Sync iOS web assets to match www/ source directory - Create deployment scripts for both native iOS app and Vue 3 test app - Add comprehensive iOS simulator deployment documentation - Document web assets parity requirements between Android and iOS This enables: - Command-line iOS builds without Xcode UI - Automated deployment to iOS simulators - Consistent web assets across platforms - Clear separation between native iOS app (ios/App) and Vue 3 test app Files modified: - ios/DailyNotificationPlugin.podspec (Capacitor 6.0) - ios/App/App/public/index.html (synced from www/) - scripts/build-native.sh (iOS build support) Files added: - docs/WEB_ASSETS_PARITY.md - docs/standalone-ios-simulator-guide.md - scripts/build-and-deploy-native-ios.sh - test-apps/daily-notification-test/docs/IOS_BUILD_QUICK_REFERENCE.md - test-apps/daily-notification-test/scripts/build-and-deploy-ios.sh
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
<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 {
|
||||
@@ -14,98 +17,627 @@
|
||||
color: white;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-size: 2.5em;
|
||||
}
|
||||
.section {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.section h2 {
|
||||
margin-top: 0;
|
||||
color: #ffd700;
|
||||
}
|
||||
.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;
|
||||
padding: 12px 24px;
|
||||
margin: 8px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s ease;
|
||||
display: inline-block;
|
||||
}
|
||||
.button:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
.status {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 15px;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
border-radius: 8px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
white-space: pre-wrap;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.success { color: #4CAF50; }
|
||||
.error { color: #f44336; }
|
||||
.warning { color: #ff9800; }
|
||||
.info { color: #2196F3; }
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.input-group {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.input-group label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.input-group input, .input-group select {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: white;
|
||||
}
|
||||
.input-group input::placeholder {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔔 DailyNotification Plugin Test</h1>
|
||||
<p>Test the DailyNotification plugin functionality</p>
|
||||
|
||||
<button class="button" onclick="testPlugin()">Test Plugin</button>
|
||||
<!-- Plugin Status Section -->
|
||||
<div class="section">
|
||||
<h2>📊 Plugin Status</h2>
|
||||
<div class="grid">
|
||||
<button class="button" onclick="checkPluginAvailability()">Check Availability</button>
|
||||
<button class="button" onclick="getNotificationStatus()">Get Status</button>
|
||||
<button class="button" onclick="checkPermissions()">Check Permissions</button>
|
||||
<button class="button" onclick="getBatteryStatus()">Battery Status</button>
|
||||
</div>
|
||||
<div id="status" class="status">Ready to test...</div>
|
||||
</div>
|
||||
|
||||
<!-- Permission Management Section -->
|
||||
<div class="section">
|
||||
<h2>🔐 Permission Management</h2>
|
||||
<div class="grid">
|
||||
<button class="button" onclick="requestPermissions()">Request Permissions</button>
|
||||
<button class="button" onclick="requestExactAlarmPermission()">Request Exact Alarm</button>
|
||||
<button class="button" onclick="openExactAlarmSettings()">Open Settings</button>
|
||||
<button class="button" onclick="requestBatteryOptimizationExemption()">Battery Exemption</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notification Scheduling Section -->
|
||||
<div class="section">
|
||||
<h2>⏰ Notification Scheduling</h2>
|
||||
<div class="input-group">
|
||||
<label for="notificationUrl">Content URL:</label>
|
||||
<input type="text" id="notificationUrl" placeholder="https://api.example.com/daily-content" value="https://api.example.com/daily-content">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="notificationTime">Schedule Time:</label>
|
||||
<input type="time" id="notificationTime" value="09:00">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="notificationTitle">Title:</label>
|
||||
<input type="text" id="notificationTitle" placeholder="Daily Notification" value="Daily Notification">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="notificationBody">Body:</label>
|
||||
<input type="text" id="notificationBody" placeholder="Your daily content is ready!" value="Your daily content is ready!">
|
||||
</div>
|
||||
<div class="grid">
|
||||
<button class="button" onclick="scheduleNotification()">Schedule Notification</button>
|
||||
<button class="button" onclick="cancelAllNotifications()">Cancel All</button>
|
||||
<button class="button" onclick="getLastNotification()">Get Last</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Section -->
|
||||
<div class="section">
|
||||
<h2>⚙️ Plugin Configuration</h2>
|
||||
<div class="input-group">
|
||||
<label for="configUrl">Fetch URL:</label>
|
||||
<input type="text" id="configUrl" placeholder="https://api.example.com/content" value="https://api.example.com/content">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="configTime">Schedule Time:</label>
|
||||
<input type="time" id="configTime" value="09:00">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="configRetryCount">Retry Count:</label>
|
||||
<input type="number" id="configRetryCount" value="3" min="0" max="10">
|
||||
</div>
|
||||
<div class="grid">
|
||||
<button class="button" onclick="configurePlugin()">Configure Plugin</button>
|
||||
<button class="button" onclick="checkStatus()">Check Status</button>
|
||||
|
||||
<div id="status" class="status">
|
||||
Ready to test...
|
||||
<button class="button" onclick="updateSettings()">Update Settings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced Features Section -->
|
||||
<div class="section">
|
||||
<h2>🚀 Advanced Features</h2>
|
||||
<div class="grid">
|
||||
<button class="button" onclick="getExactAlarmStatus()">Exact Alarm Status</button>
|
||||
<button class="button" onclick="getRebootRecoveryStatus()">Reboot Recovery</button>
|
||||
<button class="button" onclick="getRollingWindowStats()">Rolling Window</button>
|
||||
<button class="button" onclick="maintainRollingWindow()">Maintain Window</button>
|
||||
<button class="button" onclick="getContentCache()">Content Cache</button>
|
||||
<button class="button" onclick="clearContentCache()">Clear Cache</button>
|
||||
<button class="button" onclick="getContentHistory()">Content History</button>
|
||||
<button class="button" onclick="getDualScheduleStatus()">Dual Schedule</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
window.Capacitor = Capacitor;
|
||||
window.DailyNotification = DailyNotification;
|
||||
|
||||
window.testPlugin = async function() {
|
||||
const status = document.getElementById('status');
|
||||
status.innerHTML = 'Testing plugin...';
|
||||
|
||||
<script>
|
||||
console.log('🔔 DailyNotification Plugin Test Interface Loading...');
|
||||
|
||||
// Global variables
|
||||
let plugin = null;
|
||||
let isPluginAvailable = false;
|
||||
|
||||
// Initialize plugin on page load
|
||||
document.addEventListener('DOMContentLoaded', async function() {
|
||||
console.log('📱 DOM loaded, initializing plugin...');
|
||||
await initializePlugin();
|
||||
});
|
||||
|
||||
// Initialize the real DailyNotification plugin
|
||||
async function initializePlugin() {
|
||||
try {
|
||||
// Plugin is loaded and ready
|
||||
status.innerHTML = 'Plugin is loaded and ready!';
|
||||
// Try to access the real plugin through Capacitor
|
||||
if (window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.DailyNotification) {
|
||||
plugin = window.Capacitor.Plugins.DailyNotification;
|
||||
isPluginAvailable = true;
|
||||
console.log('✅ Real DailyNotification plugin found!');
|
||||
updateStatus('success', '✅ Real DailyNotification plugin loaded successfully!');
|
||||
} else {
|
||||
// Fallback to mock for development
|
||||
console.log('⚠️ Real plugin not available, using mock for development');
|
||||
plugin = createMockPlugin();
|
||||
isPluginAvailable = false;
|
||||
updateStatus('warning', '⚠️ Using mock plugin (real plugin not available)');
|
||||
}
|
||||
} catch (error) {
|
||||
status.innerHTML = `Plugin test failed: ${error.message}`;
|
||||
console.error('❌ Plugin initialization failed:', error);
|
||||
updateStatus('error', `❌ Plugin initialization failed: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
window.configurePlugin = async function() {
|
||||
const status = document.getElementById('status');
|
||||
status.innerHTML = 'Configuring plugin...';
|
||||
|
||||
}
|
||||
|
||||
// Create mock plugin for development/testing
|
||||
function createMockPlugin() {
|
||||
return {
|
||||
configure: async (options) => {
|
||||
console.log('Mock configure called with:', options);
|
||||
return Promise.resolve();
|
||||
},
|
||||
getNotificationStatus: async () => {
|
||||
return Promise.resolve({
|
||||
isEnabled: true,
|
||||
isScheduled: true,
|
||||
lastNotificationTime: Date.now() - 86400000,
|
||||
nextNotificationTime: Date.now() + 3600000,
|
||||
pending: 1,
|
||||
settings: { url: 'https://api.example.com/content', time: '09:00' },
|
||||
error: null
|
||||
});
|
||||
},
|
||||
checkPermissions: async () => {
|
||||
return Promise.resolve({
|
||||
notifications: 'granted',
|
||||
backgroundRefresh: 'granted',
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true
|
||||
});
|
||||
},
|
||||
requestPermissions: async () => {
|
||||
return Promise.resolve({
|
||||
notifications: 'granted',
|
||||
backgroundRefresh: 'granted',
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true
|
||||
});
|
||||
},
|
||||
scheduleDailyNotification: async (options) => {
|
||||
console.log('Mock scheduleDailyNotification called with:', options);
|
||||
return Promise.resolve();
|
||||
},
|
||||
cancelAllNotifications: async () => {
|
||||
console.log('Mock cancelAllNotifications called');
|
||||
return Promise.resolve();
|
||||
},
|
||||
getLastNotification: async () => {
|
||||
return Promise.resolve({
|
||||
id: 'mock-123',
|
||||
title: 'Mock Notification',
|
||||
body: 'This is a mock notification',
|
||||
timestamp: Date.now() - 3600000,
|
||||
url: 'https://example.com'
|
||||
});
|
||||
},
|
||||
getBatteryStatus: async () => {
|
||||
return Promise.resolve({
|
||||
level: 85,
|
||||
isCharging: false,
|
||||
powerState: 1,
|
||||
isOptimizationExempt: false
|
||||
});
|
||||
},
|
||||
getExactAlarmStatus: async () => {
|
||||
return Promise.resolve({
|
||||
supported: true,
|
||||
enabled: true,
|
||||
canSchedule: true,
|
||||
fallbackWindow: '±15 minutes'
|
||||
});
|
||||
},
|
||||
requestExactAlarmPermission: async () => {
|
||||
console.log('Mock requestExactAlarmPermission called');
|
||||
return Promise.resolve();
|
||||
},
|
||||
openExactAlarmSettings: async () => {
|
||||
console.log('Mock openExactAlarmSettings called');
|
||||
return Promise.resolve();
|
||||
},
|
||||
requestBatteryOptimizationExemption: async () => {
|
||||
console.log('Mock requestBatteryOptimizationExemption called');
|
||||
return Promise.resolve();
|
||||
},
|
||||
getRebootRecoveryStatus: async () => {
|
||||
return Promise.resolve({
|
||||
inProgress: false,
|
||||
lastRecoveryTime: Date.now() - 86400000,
|
||||
timeSinceLastRecovery: 86400000,
|
||||
recoveryNeeded: false
|
||||
});
|
||||
},
|
||||
getRollingWindowStats: async () => {
|
||||
return Promise.resolve({
|
||||
stats: 'Window: 7 days, Notifications: 5, Success rate: 100%',
|
||||
maintenanceNeeded: false,
|
||||
timeUntilNextMaintenance: 3600000
|
||||
});
|
||||
},
|
||||
maintainRollingWindow: async () => {
|
||||
console.log('Mock maintainRollingWindow called');
|
||||
return Promise.resolve();
|
||||
},
|
||||
getContentCache: async () => {
|
||||
return Promise.resolve({
|
||||
'cache-key-1': { content: 'Mock cached content', timestamp: Date.now() },
|
||||
'cache-key-2': { content: 'Another mock item', timestamp: Date.now() - 3600000 }
|
||||
});
|
||||
},
|
||||
clearContentCache: async () => {
|
||||
console.log('Mock clearContentCache called');
|
||||
return Promise.resolve();
|
||||
},
|
||||
getContentHistory: async () => {
|
||||
return Promise.resolve([
|
||||
{ id: '1', timestamp: Date.now() - 86400000, success: true, content: 'Mock content 1' },
|
||||
{ id: '2', timestamp: Date.now() - 172800000, success: true, content: 'Mock content 2' }
|
||||
]);
|
||||
},
|
||||
getDualScheduleStatus: async () => {
|
||||
return Promise.resolve({
|
||||
isActive: true,
|
||||
contentSchedule: { nextRun: Date.now() + 3600000, isEnabled: true },
|
||||
userSchedule: { nextRun: Date.now() + 7200000, isEnabled: true },
|
||||
lastContentFetch: Date.now() - 3600000,
|
||||
lastUserNotification: Date.now() - 7200000
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Utility function to update status display
|
||||
function updateStatus(type, message) {
|
||||
const statusEl = document.getElementById('status');
|
||||
statusEl.className = `status ${type}`;
|
||||
statusEl.textContent = message;
|
||||
console.log(`[${type.toUpperCase()}] ${message}`);
|
||||
}
|
||||
|
||||
// Plugin availability check
|
||||
async function checkPluginAvailability() {
|
||||
updateStatus('info', '🔍 Checking plugin availability...');
|
||||
try {
|
||||
await DailyNotification.configure({
|
||||
fetchUrl: 'https://api.example.com/daily-content',
|
||||
scheduleTime: '09:00',
|
||||
enableNotifications: true
|
||||
});
|
||||
status.innerHTML = 'Plugin configured successfully!';
|
||||
if (plugin) {
|
||||
updateStatus('success', `✅ Plugin available: ${isPluginAvailable ? 'Real plugin' : 'Mock plugin'}`);
|
||||
} else {
|
||||
updateStatus('error', '❌ Plugin not available');
|
||||
}
|
||||
} catch (error) {
|
||||
status.innerHTML = `Configuration failed: ${error.message}`;
|
||||
updateStatus('error', `❌ Availability check failed: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
window.checkStatus = async function() {
|
||||
const status = document.getElementById('status');
|
||||
status.innerHTML = 'Checking plugin status...';
|
||||
|
||||
}
|
||||
|
||||
// Get notification status
|
||||
async function getNotificationStatus() {
|
||||
updateStatus('info', '📊 Getting notification status...');
|
||||
try {
|
||||
const result = await DailyNotification.getStatus();
|
||||
status.innerHTML = `Plugin status: ${JSON.stringify(result, null, 2)}`;
|
||||
const status = await plugin.getNotificationStatus();
|
||||
updateStatus('success', `📊 Status: ${JSON.stringify(status, null, 2)}`);
|
||||
} catch (error) {
|
||||
status.innerHTML = `Status check failed: ${error.message}`;
|
||||
updateStatus('error', `❌ Status check failed: ${error.message}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Check permissions
|
||||
async function checkPermissions() {
|
||||
updateStatus('info', '🔐 Checking permissions...');
|
||||
try {
|
||||
const permissions = await plugin.checkPermissions();
|
||||
updateStatus('success', `🔐 Permissions: ${JSON.stringify(permissions, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Permission check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Request permissions
|
||||
async function requestPermissions() {
|
||||
updateStatus('info', '🔐 Requesting permissions...');
|
||||
try {
|
||||
const result = await plugin.requestPermissions();
|
||||
updateStatus('success', `🔐 Permission result: ${JSON.stringify(result, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Permission request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get battery status
|
||||
async function getBatteryStatus() {
|
||||
updateStatus('info', '🔋 Getting battery status...');
|
||||
try {
|
||||
const battery = await plugin.getBatteryStatus();
|
||||
updateStatus('success', `🔋 Battery: ${JSON.stringify(battery, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Battery check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule notification
|
||||
async function scheduleNotification() {
|
||||
updateStatus('info', '⏰ Scheduling notification...');
|
||||
try {
|
||||
const timeInput = document.getElementById('notificationTime').value;
|
||||
const [hours, minutes] = timeInput.split(':');
|
||||
const now = new Date();
|
||||
const scheduledTime = new Date();
|
||||
scheduledTime.setHours(parseInt(hours), parseInt(minutes), 0, 0);
|
||||
|
||||
// If scheduled time is in the past, schedule for tomorrow
|
||||
if (scheduledTime <= now) {
|
||||
scheduledTime.setDate(scheduledTime.getDate() + 1);
|
||||
}
|
||||
|
||||
// Calculate prefetch time (5 minutes before notification)
|
||||
const prefetchTime = new Date(scheduledTime.getTime() - 300000); // 5 minutes
|
||||
const prefetchTimeReadable = prefetchTime.toLocaleTimeString();
|
||||
const notificationTimeReadable = scheduledTime.toLocaleTimeString();
|
||||
const prefetchTimeString = prefetchTime.getHours().toString().padStart(2, '0') + ':' +
|
||||
prefetchTime.getMinutes().toString().padStart(2, '0');
|
||||
const notificationTimeString = scheduledTime.getHours().toString().padStart(2, '0') + ':' +
|
||||
scheduledTime.getMinutes().toString().padStart(2, '0');
|
||||
|
||||
const options = {
|
||||
url: document.getElementById('notificationUrl').value,
|
||||
time: timeInput,
|
||||
title: document.getElementById('notificationTitle').value,
|
||||
body: document.getElementById('notificationBody').value,
|
||||
sound: true,
|
||||
priority: 'high'
|
||||
};
|
||||
await plugin.scheduleDailyNotification(options);
|
||||
updateStatus('success', `✅ Notification scheduled!<br>` +
|
||||
`📥 Prefetch: ${prefetchTimeReadable} (${prefetchTimeString})<br>` +
|
||||
`🔔 Notification: ${notificationTimeReadable} (${notificationTimeString})`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Scheduling failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel all notifications
|
||||
async function cancelAllNotifications() {
|
||||
updateStatus('info', '❌ Cancelling all notifications...');
|
||||
try {
|
||||
await plugin.cancelAllNotifications();
|
||||
updateStatus('success', '❌ All notifications cancelled');
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Cancel failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get last notification
|
||||
async function getLastNotification() {
|
||||
updateStatus('info', '📱 Getting last notification...');
|
||||
try {
|
||||
const notification = await plugin.getLastNotification();
|
||||
updateStatus('success', `📱 Last notification: ${JSON.stringify(notification, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Get last notification failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure plugin
|
||||
async function configurePlugin() {
|
||||
updateStatus('info', '⚙️ Configuring plugin...');
|
||||
try {
|
||||
const config = {
|
||||
fetchUrl: document.getElementById('configUrl').value,
|
||||
scheduleTime: document.getElementById('configTime').value,
|
||||
retryCount: parseInt(document.getElementById('configRetryCount').value),
|
||||
enableNotifications: true,
|
||||
offlineFallback: true
|
||||
};
|
||||
await plugin.configure(config);
|
||||
updateStatus('success', `⚙️ Plugin configured: ${JSON.stringify(config, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Configuration failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Update settings
|
||||
async function updateSettings() {
|
||||
updateStatus('info', '⚙️ Updating settings...');
|
||||
try {
|
||||
const settings = {
|
||||
url: document.getElementById('configUrl').value,
|
||||
time: document.getElementById('configTime').value,
|
||||
retryCount: parseInt(document.getElementById('configRetryCount').value),
|
||||
sound: true,
|
||||
priority: 'high'
|
||||
};
|
||||
await plugin.updateSettings(settings);
|
||||
updateStatus('success', `⚙️ Settings updated: ${JSON.stringify(settings, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Settings update failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get exact alarm status
|
||||
async function getExactAlarmStatus() {
|
||||
updateStatus('info', '⏰ Getting exact alarm status...');
|
||||
try {
|
||||
const status = await plugin.getExactAlarmStatus();
|
||||
updateStatus('success', `⏰ Exact alarm status: ${JSON.stringify(status, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Exact alarm check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Request exact alarm permission
|
||||
async function requestExactAlarmPermission() {
|
||||
updateStatus('info', '⏰ Requesting exact alarm permission...');
|
||||
try {
|
||||
await plugin.requestExactAlarmPermission();
|
||||
updateStatus('success', '⏰ Exact alarm permission requested');
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Exact alarm permission request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Open exact alarm settings
|
||||
async function openExactAlarmSettings() {
|
||||
updateStatus('info', '⚙️ Opening exact alarm settings...');
|
||||
try {
|
||||
await plugin.openExactAlarmSettings();
|
||||
updateStatus('success', '⚙️ Exact alarm settings opened');
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Open settings failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Request battery optimization exemption
|
||||
async function requestBatteryOptimizationExemption() {
|
||||
updateStatus('info', '🔋 Requesting battery optimization exemption...');
|
||||
try {
|
||||
await plugin.requestBatteryOptimizationExemption();
|
||||
updateStatus('success', '🔋 Battery optimization exemption requested');
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Battery exemption request failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get reboot recovery status
|
||||
async function getRebootRecoveryStatus() {
|
||||
updateStatus('info', '🔄 Getting reboot recovery status...');
|
||||
try {
|
||||
const status = await plugin.getRebootRecoveryStatus();
|
||||
updateStatus('success', `🔄 Reboot recovery status: ${JSON.stringify(status, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Reboot recovery check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get rolling window stats
|
||||
async function getRollingWindowStats() {
|
||||
updateStatus('info', '📊 Getting rolling window stats...');
|
||||
try {
|
||||
const stats = await plugin.getRollingWindowStats();
|
||||
updateStatus('success', `📊 Rolling window stats: ${JSON.stringify(stats, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Rolling window stats failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Maintain rolling window
|
||||
async function maintainRollingWindow() {
|
||||
updateStatus('info', '🔧 Maintaining rolling window...');
|
||||
try {
|
||||
await plugin.maintainRollingWindow();
|
||||
updateStatus('success', '🔧 Rolling window maintenance completed');
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Rolling window maintenance failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get content cache
|
||||
async function getContentCache() {
|
||||
updateStatus('info', '💾 Getting content cache...');
|
||||
try {
|
||||
const cache = await plugin.getContentCache();
|
||||
updateStatus('success', `💾 Content cache: ${JSON.stringify(cache, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Content cache check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear content cache
|
||||
async function clearContentCache() {
|
||||
updateStatus('info', '🗑️ Clearing content cache...');
|
||||
try {
|
||||
await plugin.clearContentCache();
|
||||
updateStatus('success', '🗑️ Content cache cleared');
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Clear cache failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get content history
|
||||
async function getContentHistory() {
|
||||
updateStatus('info', '📚 Getting content history...');
|
||||
try {
|
||||
const history = await plugin.getContentHistory();
|
||||
updateStatus('success', `📚 Content history: ${JSON.stringify(history, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Content history check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Get dual schedule status
|
||||
async function getDualScheduleStatus() {
|
||||
updateStatus('info', '🔄 Getting dual schedule status...');
|
||||
try {
|
||||
const status = await plugin.getDualScheduleStatus();
|
||||
updateStatus('success', `🔄 Dual schedule status: ${JSON.stringify(status, null, 2)}`);
|
||||
} catch (error) {
|
||||
updateStatus('error', `❌ Dual schedule check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🔔 DailyNotification Plugin Test Interface Loaded Successfully!');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,8 +8,8 @@ Pod::Spec.new do |s|
|
||||
s.source = { :git => 'https://github.com/timesafari/daily-notification-plugin.git', :tag => s.version.to_s }
|
||||
s.source_files = 'Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
||||
s.ios.deployment_target = '13.0'
|
||||
s.dependency 'Capacitor', '~> 5.0.0'
|
||||
s.dependency 'CapacitorCordova', '~> 5.0.0'
|
||||
s.dependency 'Capacitor', '~> 6.0'
|
||||
s.dependency 'CapacitorCordova', '~> 6.0'
|
||||
s.swift_version = '5.1'
|
||||
s.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1' }
|
||||
s.deprecated = false
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
PODS:
|
||||
- Capacitor (5.0.0):
|
||||
- Capacitor (6.2.1):
|
||||
- CapacitorCordova
|
||||
- CapacitorCordova (5.0.0)
|
||||
- CapacitorCordova (6.2.1)
|
||||
- DailyNotificationPlugin (1.0.0):
|
||||
- Capacitor (~> 5.0.0)
|
||||
- CapacitorCordova (~> 5.0.0)
|
||||
- Capacitor (~> 6.0)
|
||||
- CapacitorCordova (~> 6.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- "Capacitor (from `../node_modules/@capacitor/ios`)"
|
||||
@@ -20,9 +20,9 @@ EXTERNAL SOURCES:
|
||||
:path: "."
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Capacitor: ba8cd5cce13c6ab3c4faf7ef98487be481c9c1c8
|
||||
CapacitorCordova: 4ea17670ee562680988a7ce9db68dee5160fe564
|
||||
DailyNotificationPlugin: 745a0606d51baec6fc9a025f1de1ade125ed193a
|
||||
Capacitor: 1e0d0e7330dea9f983b50da737d8918abcf273f8
|
||||
CapacitorCordova: 8d93e14982f440181be7304aa9559ca631d77fff
|
||||
DailyNotificationPlugin: 79f269b45580c89b044ece1cfe09293b7e974d98
|
||||
|
||||
PODFILE CHECKSUM: ac8c229d24347f6f83e67e6b95458e0b81e68f7c
|
||||
|
||||
|
||||
Reference in New Issue
Block a user