Visitar URL original
feat(app): wait an hour after first launch before the first tip (#63760) · anomalyco/opencode@152115d · GitHub
Skip to content

Commit 152115d

Browse files
authored
feat(app): wait an hour after first launch before the first tip (#63760)
1 parent 507c939 commit 152115d

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

‎packages/app/src/tips/model.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Persist, persisted } from "@/runtime/persistence/storage"
77
import { usePlatform } from "@/runtime/platform/platform"
88
import { ServerConnection, useServers } from "@/runtime/server/registry"
99
import { useGlobal } from "@/runtime/server/runtime"
10-
import { selectTip, TIP_INTERVAL_MS, type Tip } from "./queue"
10+
import { FIRST_TIP_DELAY_MS, selectTip, TIP_INTERVAL_MS, type Tip } from "./queue"
1111

1212
const STARTUP_DELAY = 2 * 60 * 1000
1313

@@ -16,6 +16,7 @@ const History = Persistence.struct({
1616
shownAt: Schema.Finite,
1717
dismissed: Persistence.array(Schema.String),
1818
dismissedAt: Schema.Finite,
19+
firstSeen: Persistence.fallback(Schema.Finite, () => 0),
1920
})
2021

2122
export function createTipToasts() {
@@ -79,6 +80,11 @@ export function createTipToasts() {
7980
shownAt: 0,
8081
dismissed: [],
8182
dismissedAt: 0,
83+
firstSeen: 0,
84+
})
85+
86+
createEffect(() => {
87+
if (loaded() && !history.firstSeen) setHistory("firstSeen", Date.now())
8288
})
8389

8490
const [tick, setTick] = createSignal(0)
@@ -90,6 +96,7 @@ export function createTipToasts() {
9096

9197
const times = [
9298
Math.max(history.shownAt, history.dismissedAt) + TIP_INTERVAL_MS,
99+
history.firstSeen + FIRST_TIP_DELAY_MS,
93100
...tips.flatMap((tip) => [tip.start ?? 0, tip.end ?? 0]),
94101
]
95102

‎packages/app/src/tips/queue.test.ts‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
import { expect, test } from "bun:test"
22
import { selectTip, type Tip } from "./queue"
33

4-
const fresh = { current: "", shownAt: 0, dismissed: [], dismissedAt: 0 }
4+
const hours = 60 * 60 * 1000
5+
6+
// Installed an hour before time 0, so the first-tip delay has already passed.
7+
const fresh = { current: "", shownAt: 0, dismissed: [], dismissedAt: 0, firstSeen: -hours }
58

69
const first: Tip = { id: "first", title: "tips.browse.title", description: "tips.browse.description" }
710

811
const second: Tip = { ...first, id: "second" }
912

1013
const tips = [first, second]
1114

12-
const hours = 60 * 60 * 1000
15+
test("the first tip waits an hour after the app first ran", () => {
16+
const installed = { ...fresh, firstSeen: 10 * hours }
17+
expect(selectTip(tips, installed, 11 * hours - 1)).toBeUndefined()
18+
expect(selectTip(tips, installed, 11 * hours)).toBe(first)
19+
expect(selectTip(tips, { ...fresh, firstSeen: 0 }, 5 * hours)).toBeUndefined()
20+
expect(selectTip(tips, { ...installed, dismissed: [first.id], dismissedAt: 1 }, 25 * hours)).toBe(second)
21+
})
1322

1423
test("first eligible tip wins until it is handled or stops being eligible", () => {
1524
expect(selectTip(tips, fresh, 1)).toBe(first)

‎packages/app/src/tips/queue.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { useLanguage } from "@/runtime/i18n/language"
22

33
export const TIP_INTERVAL_MS = 24 * 60 * 60 * 1000
44

5+
export const FIRST_TIP_DELAY_MS = 60 * 60 * 1000
6+
57
type Text = Parameters<ReturnType<typeof useLanguage>["t"]>[0]
68

79
export type Tip = {
@@ -19,6 +21,7 @@ export type TipHistory = {
1921
shownAt: number
2022
dismissed: readonly string[]
2123
dismissedAt: number
24+
firstSeen: number
2225
}
2326

2427
/** Array order is priority. Dates are epoch milliseconds; the end is exclusive. */
@@ -37,5 +40,7 @@ export function selectTip(tips: readonly Tip[], history: TipHistory, now: number
3740

3841
if (last && now < last + TIP_INTERVAL_MS) return
3942

43+
if (!last && now < (history.firstSeen || now) + FIRST_TIP_DELAY_MS) return
44+
4045
return tips.find(eligible)
4146
}

0 commit comments

Comments
 (0)