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

/**
* 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
}
}