Files
buzz/mobile/lib/shared/reminders/reminder_time_presets.dart
T
cls 9dfa06ffee
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
feat: import Chinese-localized Buzz source snapshot
Signed-off-by: cls_宁波本机 <908705107@qq.com>
2026-08-13 18:34:25 +08:00

92 lines
2.7 KiB
Dart

/// Reminder time presets shared by the "Remind me later" sheet.
///
/// Mirrors `desktop/src/features/reminders/lib/timePresets.ts` — same labels,
/// same "always strictly in the future" guarantee.
library;
class ReminderTimePreset {
final ReminderTimePresetId id;
final String label;
final int Function() getTimestamp;
const ReminderTimePreset({
this.id = ReminderTimePresetId.legacy,
required this.label,
required this.getTimestamp,
});
}
/// Stable identifiers let the sheet localize labels without putting UI
/// strings into the reminder scheduling model.
enum ReminderTimePresetId {
legacy,
in30Minutes,
in1Hour,
in3Hours,
tomorrow9am,
nextMonday9am,
}
int _nowSeconds() => DateTime.now().millisecondsSinceEpoch ~/ 1000;
/// Next occurrence of [dayOffset] days from now at 9am local time. If that
/// instant is already past, roll to the following day so the result is
/// always in the future.
int nextDayAt9am(int dayOffset, {DateTime? now}) {
final current = now ?? DateTime.now();
var target = DateTime(
current.year,
current.month,
current.day + dayOffset,
9,
);
if (!target.isAfter(current)) {
target = DateTime(target.year, target.month, target.day + 1, 9);
}
return target.millisecondsSinceEpoch ~/ 1000;
}
/// Days until next Monday (1-7), matching the desktop preset semantics.
int daysUntilNextMonday(DateTime now) {
final days = (DateTime.monday - now.weekday) % 7;
return days == 0 ? 7 : days;
}
final List<ReminderTimePreset> reminderTimePresets = [
ReminderTimePreset(
id: ReminderTimePresetId.in30Minutes,
label: 'In 30 minutes',
getTimestamp: () => _nowSeconds() + 30 * 60,
),
ReminderTimePreset(
id: ReminderTimePresetId.in1Hour,
label: 'In 1 hour',
getTimestamp: () => _nowSeconds() + 60 * 60,
),
ReminderTimePreset(
id: ReminderTimePresetId.in3Hours,
label: 'In 3 hours',
getTimestamp: () => _nowSeconds() + 3 * 60 * 60,
),
ReminderTimePreset(
id: ReminderTimePresetId.tomorrow9am,
label: 'Tomorrow at 9am',
getTimestamp: () => nextDayAt9am(1),
),
ReminderTimePreset(
id: ReminderTimePresetId.nextMonday9am,
label: 'Next Monday at 9am',
getTimestamp: () => nextDayAt9am(daysUntilNextMonday(DateTime.now())),
),
];
/// Combine a picked date and time into a future Unix timestamp (seconds), or
/// null when the instant is not strictly in the future — the shared guard for
/// the custom picker so a past time never fires immediately.
int? combineCustomDateTime(DateTime date, int hour, int minute) {
final target = DateTime(date.year, date.month, date.day, hour, minute);
final timestamp = target.millisecondsSinceEpoch ~/ 1000;
if (timestamp <= _nowSeconds()) return null;
return timestamp;
}