You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
7.7 KiB
269 lines
7.7 KiB
/**
|
|
* TimeSafari Starred Plans Integration Example
|
|
*
|
|
* Demonstrates how to integrate the Daily Notification Plugin's starred plans
|
|
* management with the TimeSafari app's starred projects functionality.
|
|
*
|
|
* This example shows:
|
|
* 1. How to update starred plan IDs when users star/unstar projects
|
|
* 2. How to sync starred plans on app startup
|
|
* 3. How to verify stored plan IDs
|
|
*
|
|
* @author Matthew Raymer
|
|
* @version 1.0.0
|
|
*/
|
|
|
|
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
|
import { logger } from './logger'; // Assuming a logger utility
|
|
|
|
/**
|
|
* TimeSafari Starred Plans Manager
|
|
*
|
|
* Integrates with the Daily Notification Plugin to keep starred plan IDs
|
|
* synchronized with the TimeSafari app's account settings.
|
|
*/
|
|
export class TimeSafariStarredPlansManager {
|
|
private plugin: DailyNotification;
|
|
private currentPlanIds: string[] = [];
|
|
|
|
constructor(plugin: DailyNotification) {
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
/**
|
|
* Sync starred plans from account settings to the plugin
|
|
*
|
|
* Call this when:
|
|
* - App starts up
|
|
* - User logs in
|
|
* - Account settings are refreshed
|
|
*
|
|
* @param starredPlanHandleIds Array of plan handle IDs from account settings
|
|
*/
|
|
async syncStarredPlansFromAccount(
|
|
starredPlanHandleIds: string[]
|
|
): Promise<void> {
|
|
try {
|
|
logger.info('Syncing starred plans to plugin', {
|
|
count: starredPlanHandleIds.length
|
|
});
|
|
|
|
// Update plugin with current starred plan IDs
|
|
const result = await this.plugin.updateStarredPlans({
|
|
planIds: starredPlanHandleIds
|
|
});
|
|
|
|
if (result.success) {
|
|
this.currentPlanIds = starredPlanHandleIds;
|
|
logger.info('Starred plans synced successfully', {
|
|
count: result.planIdsCount,
|
|
updatedAt: new Date(result.updatedAt).toISOString()
|
|
});
|
|
} else {
|
|
logger.error('Failed to sync starred plans to plugin');
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error syncing starred plans', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update starred plans when a user stars a project
|
|
*
|
|
* Call this when:
|
|
* - User clicks star on a project
|
|
* - Star action completes successfully
|
|
*
|
|
* @param planHandleId The plan handle ID that was starred
|
|
*/
|
|
async addStarredPlan(planHandleId: string): Promise<void> {
|
|
try {
|
|
// Get current starred plans from plugin (to avoid duplicate updates)
|
|
const current = await this.plugin.getStarredPlans();
|
|
|
|
// Add new plan ID if not already present
|
|
if (!current.planIds.includes(planHandleId)) {
|
|
const updatedPlanIds = [...current.planIds, planHandleId];
|
|
|
|
await this.plugin.updateStarredPlans({
|
|
planIds: updatedPlanIds
|
|
});
|
|
|
|
this.currentPlanIds = updatedPlanIds;
|
|
|
|
logger.info('Starred plan added', { planHandleId });
|
|
} else {
|
|
logger.debug('Plan already starred', { planHandleId });
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error adding starred plan', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update starred plans when a user unstars a project
|
|
*
|
|
* Call this when:
|
|
* - User clicks unstar on a project
|
|
* - Unstar action completes successfully
|
|
*
|
|
* @param planHandleId The plan handle ID that was unstarred
|
|
*/
|
|
async removeStarredPlan(planHandleId: string): Promise<void> {
|
|
try {
|
|
// Get current starred plans from plugin
|
|
const current = await this.plugin.getStarredPlans();
|
|
|
|
// Remove plan ID if present
|
|
const updatedPlanIds = current.planIds.filter(
|
|
id => id !== planHandleId
|
|
);
|
|
|
|
if (updatedPlanIds.length !== current.planIds.length) {
|
|
await this.plugin.updateStarredPlans({
|
|
planIds: updatedPlanIds
|
|
});
|
|
|
|
this.currentPlanIds = updatedPlanIds;
|
|
|
|
logger.info('Starred plan removed', { planHandleId });
|
|
} else {
|
|
logger.debug('Plan not in starred list', { planHandleId });
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error removing starred plan', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get current starred plans from plugin
|
|
*
|
|
* Useful for verifying synchronization or displaying current state.
|
|
*
|
|
* @returns Current starred plan IDs stored in the plugin
|
|
*/
|
|
async getCurrentStarredPlans(): Promise<string[]> {
|
|
try {
|
|
const result = await this.plugin.getStarredPlans();
|
|
this.currentPlanIds = result.planIds;
|
|
return result.planIds;
|
|
} catch (error) {
|
|
logger.error('Error getting starred plans', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verify starred plans synchronization
|
|
*
|
|
* Compares account settings with plugin storage to ensure they match.
|
|
* Useful for debugging or validation after sync operations.
|
|
*
|
|
* @param accountPlanIds Plan IDs from account settings
|
|
* @returns Object with sync status and any mismatches
|
|
*/
|
|
async verifySync(accountPlanIds: string[]): Promise<{
|
|
inSync: boolean;
|
|
accountCount: number;
|
|
pluginCount: number;
|
|
mismatches: {
|
|
inAccountNotPlugin: string[];
|
|
inPluginNotAccount: string[];
|
|
};
|
|
}> {
|
|
try {
|
|
const pluginResult = await this.plugin.getStarredPlans();
|
|
const pluginPlanIds = pluginResult.planIds;
|
|
|
|
const inAccountNotPlugin = accountPlanIds.filter(
|
|
id => !pluginPlanIds.includes(id)
|
|
);
|
|
const inPluginNotAccount = pluginPlanIds.filter(
|
|
id => !accountPlanIds.includes(id)
|
|
);
|
|
|
|
const inSync =
|
|
inAccountNotPlugin.length === 0 && inPluginNotAccount.length === 0;
|
|
|
|
return {
|
|
inSync,
|
|
accountCount: accountPlanIds.length,
|
|
pluginCount: pluginPlanIds.length,
|
|
mismatches: {
|
|
inAccountNotPlugin,
|
|
inPluginNotAccount
|
|
}
|
|
};
|
|
} catch (error) {
|
|
logger.error('Error verifying sync', error);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Example integration with TimeSafari's searchStarred method
|
|
*
|
|
* This shows how to integrate the starred plans manager with the existing
|
|
* TimeSafari searchStarred method.
|
|
*/
|
|
export async function integrateWithSearchStarred(
|
|
plugin: DailyNotification,
|
|
accountSettings: { starredPlanHandleIds?: string[] }
|
|
): Promise<void> {
|
|
const manager = new TimeSafariStarredPlansManager(plugin);
|
|
|
|
try {
|
|
// Get starred plan IDs from account settings
|
|
const starredIds = accountSettings.starredPlanHandleIds || [];
|
|
|
|
if (starredIds.length === 0) {
|
|
logger.info('No starred plans to sync');
|
|
return;
|
|
}
|
|
|
|
// Sync to plugin
|
|
await manager.syncStarredPlansFromAccount(starredIds);
|
|
|
|
// Verify sync (optional, for debugging)
|
|
const syncStatus = await manager.verifySync(starredIds);
|
|
if (!syncStatus.inSync) {
|
|
logger.warn('Starred plans sync verification failed', syncStatus);
|
|
// Optionally retry sync if verification fails
|
|
await manager.syncStarredPlansFromAccount(starredIds);
|
|
} else {
|
|
logger.info('Starred plans sync verified');
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error integrating with searchStarred', error);
|
|
// Don't throw - allow searchStarred to continue even if plugin sync fails
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Example: Hook into star/unstar actions
|
|
*
|
|
* This shows how to update the plugin when users star or unstar projects.
|
|
*/
|
|
export async function handleStarAction(
|
|
plugin: DailyNotification,
|
|
planHandleId: string,
|
|
isStarring: boolean
|
|
): Promise<void> {
|
|
const manager = new TimeSafariStarredPlansManager(plugin);
|
|
|
|
try {
|
|
if (isStarring) {
|
|
await manager.addStarredPlan(planHandleId);
|
|
} else {
|
|
await manager.removeStarredPlan(planHandleId);
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error handling star action', error);
|
|
// Don't throw - allow star action to complete even if plugin update fails
|
|
}
|
|
}
|
|
|
|
|