Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,19 @@ jobs:
with:
distribution: temurin
java-version: 17
# Caches ~/.gradle so the toolchain and dependencies are not re-downloaded every run.
cache: gradle

# Caches ~/.gradle so the toolchain and dependencies are not re-downloaded every run.
# Not setup-java's `cache: gradle`: that hashes *.gradle files at setup time, and
# android/ does not exist until prebuild, so it fails the job before anything builds.
# The lockfile and app.json are what actually decide the native dependency set.
- uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml', 'apps/mobile/app.json') }}
restore-keys: |
gradle-${{ runner.os }}-

- name: Install dependencies
run: pnpm install --frozen-lockfile
Expand Down
6 changes: 4 additions & 2 deletions apps/api/src/context/detectors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Types } from 'mongoose';
import {
SUGGEST_THRESHOLD,
addLocalDays,
localMinutesOfDay,
todayLocalDate,
type Evidence,
Expand Down Expand Up @@ -217,8 +218,9 @@ export async function runDetectors(
PersonalEventModel.find({ userId: uid, localDate }).lean<EventLean[]>(),
PersonalEventModel.find({
userId: uid,
localDate: { $lt: localDate },
timestamp: { $gte: new Date(Date.now() - 21 * 86_400_000) },
// Anchored on the day being evaluated, not the wall clock: a run for a past
// localDate must see the three weeks before THAT day, or its history is empty.
localDate: { $gte: addLocalDays(localDate, -21), $lt: localDate },
}).lean<EventLean[]>(),
UserPreferenceModel.findOne({ userId: uid }).lean(),
]);
Expand Down
9 changes: 8 additions & 1 deletion apps/mobile/src/theme/ThemeProvider.persistence.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,18 @@ describe('hydrate', () => {
});

describe('setPreference', () => {
it('applies the choice to memory immediately', () => {
it('applies the choice to memory immediately', async () => {
usePreferenceStore.getState().setPreference('dark');
// Synchronous on purpose: the theme must flip on the very next render, not once a
// device write has come back.
expect(usePreferenceStore.getState().preference).toBe('dark');

// Not part of the assertion — it keeps the unawaited write from outliving this test.
// The `beforeEach` drain is one macrotask, and on a loaded CI runner the store's
// `await import()` takes longer than that. Left in flight it overlaps the next test's
// import, and Vitest then resolves that second import to the REAL async-storage
// module (`window is not defined`, swallowed by the store), so its write never happens.
await vi.waitFor(() => expect(setItem).toHaveBeenCalledWith(STORAGE_KEY, 'dark'));
});

it('persists the choice under the documented key', async () => {
Expand Down
Loading