/ services / tips / tipScheduler.ts
tipScheduler.ts
 1  import { getSettings_DEPRECATED } from '../../utils/settings/settings.js'
 2  import {
 3    type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
 4    logEvent,
 5  } from '../analytics/index.js'
 6  import { getSessionsSinceLastShown, recordTipShown } from './tipHistory.js'
 7  import { getRelevantTips } from './tipRegistry.js'
 8  import type { Tip, TipContext } from './types.js'
 9  
10  export function selectTipWithLongestTimeSinceShown(
11    availableTips: Tip[],
12  ): Tip | undefined {
13    if (availableTips.length === 0) {
14      return undefined
15    }
16  
17    if (availableTips.length === 1) {
18      return availableTips[0]
19    }
20  
21    // Sort tips by sessions since last shown (descending) and take the first one
22    // This is the tip that hasn't been shown for the longest time
23    const tipsWithSessions = availableTips.map(tip => ({
24      tip,
25      sessions: getSessionsSinceLastShown(tip.id),
26    }))
27  
28    tipsWithSessions.sort((a, b) => b.sessions - a.sessions)
29    return tipsWithSessions[0]?.tip
30  }
31  
32  export async function getTipToShowOnSpinner(
33    context?: TipContext,
34  ): Promise<Tip | undefined> {
35    // Check if tips are disabled (default to true if not set)
36    if (getSettings_DEPRECATED().spinnerTipsEnabled === false) {
37      return undefined
38    }
39  
40    const tips = await getRelevantTips(context)
41    if (tips.length === 0) {
42      return undefined
43    }
44  
45    return selectTipWithLongestTimeSinceShown(tips)
46  }
47  
48  export function recordShownTip(tip: Tip): void {
49    // Record in history
50    recordTipShown(tip.id)
51  
52    // Log event for analytics
53    logEvent('tengu_tip_shown', {
54      tipIdLength:
55        tip.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
56      cooldownSessions: tip.cooldownSessions,
57    })
58  }