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