Ad and purchases enabled (still need actual testing)

This commit is contained in:
Courtney Arnold 2026-08-16 18:27:56 -05:00
parent 2fcc6dcab7
commit faf319322a
35 changed files with 1676 additions and 34 deletions

View file

@ -65,7 +65,7 @@ class DatabaseService {
final dbPath = p.join(_rootDirectory.path, dbFileName);
_db = await openDatabase(
dbPath,
version: 4,
version: 5,
onCreate: _onCreate,
onUpgrade: _onUpgrade,
);
@ -75,6 +75,7 @@ class DatabaseService {
await db.execute(createVehiclesTableSql);
await db.execute(createFuelEntriesTableSql);
await db.execute(createFuelEntriesIndexSql);
await db.execute(createAdFreeEntitlementTableSql);
}
/// Versions 2/3 (VIN as primary key, then dropping license plate) were
@ -90,6 +91,9 @@ class DatabaseService {
if (oldVersion < 4) {
await _migrateToVehicleIdSchema(db);
}
if (oldVersion < 5) {
await db.execute(createAdFreeEntitlementTableSql);
}
}
Future<void> _migrateToVehicleIdSchema(Database db) async {
@ -157,6 +161,33 @@ class DatabaseService {
return rows.map(FuelEntry.fromMap).toList();
}
/// The furthest-known "ads disabled until" date — null if no purchase
/// has ever been recorded (locally or merged in from another synced
/// device). See [createAdFreeEntitlementTableSql] for why this is its
/// own small synced table rather than a local-only preference.
Future<DateTime?> getAdFreeUntil() async {
final rows = await _db.query('ad_free_entitlement', where: 'id = 1', limit: 1);
if (rows.isEmpty) return null;
final millis = rows.single['ad_free_until'] as int?;
return millis == null ? null : DateTime.fromMillisecondsSinceEpoch(millis, isUtc: true);
}
/// Records a purchase's grant (or extension) of ad-free time. [until] is
/// intentionally not compared against any existing value here — the
/// caller (a fresh purchase) always means "now plus a year", which is
/// always further out than whatever was there before.
Future<void> setAdFreeUntil(DateTime until, DateTime updatedAt) async {
await _db.insert(
'ad_free_entitlement',
{
'id': 1,
'ad_free_until': until.toUtc().millisecondsSinceEpoch,
'updated_at': updatedAt.toUtc().millisecondsSinceEpoch,
},
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
/// True if an active (non-deleted) vehicle other than [excludeId] already
/// has this VIN. VIN must stay unique even though it's editable, so
/// callers adding a new vehicle (no [excludeId]) or changing an existing