feat(native): home and lock screen widgets in the TREK look

Four widgets instead of one plain text block, drawn in the phone tokens
(warm paper by day, near black by night) with contour lines and a route arc
as the travel motif:

- Trip (small, medium, large, lock screen): the cover photo, a countdown ring
  and a plane on its arc before the trip; the day of the trip as segments,
  the weather and the next stops on frosted glass while it runs
- Today (medium, large): the day as a timeline in its category colours, with
  a now line, the day's progress and the weather
- Bookings (small, medium, large, lock screen): flights, trains, hotels and
  tables ahead as coloured tiles, the next one featured, status dots
- To-dos (small, medium, large, lock screen): to-dos and packing as nested
  rings, the most pressing open to-dos with priority and due dates

The app now sends the destination, a small cover JPEG, the weather where the
trip is, the bookings ahead, the open to-dos and the packing count; every
new field is optional on both sides, so older binaries and servers keep
working. Timelines step every quarter hour so the now line moves without
the app. client/ios/WidgetPreviews renders every widget in every size, light
and dark, on the CI's Mac, uploaded as the widget-previews artifact.
This commit is contained in:
Maurice
2026-11-06 19:01:08 +01:00
parent 3466556849
commit b1037dec62
48 changed files with 3033 additions and 127 deletions
+4
View File
@@ -89,6 +89,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'غدًا',
'native.widget.nothingPlanned': 'لا شيء مخطط لليوم',
'native.widget.dayDone': 'انتهى كل شيء لليوم',
'native.widget.noBookings': 'لا توجد حجوزات قادمة',
'native.widget.noTodos': 'لم يتبق شيء',
'native.widget.now': 'الآن',
'native.widget.travellers': 'مسافرون',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Sabah',
'native.widget.nothingPlanned': 'Bu gün üçün plan yoxdur',
'native.widget.dayDone': 'Bu gün üçün hər şey bitdi',
'native.widget.noBookings': 'Qarşıda bron yoxdur',
'native.widget.noTodos': 'Görüləsi iş qalmayıb',
'native.widget.now': 'İndi',
'native.widget.travellers': 'səyyah',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Amanhã',
'native.widget.nothingPlanned': 'Nada planejado para hoje',
'native.widget.dayDone': 'Tudo feito por hoje',
'native.widget.noBookings': 'Nenhuma reserva pela frente',
'native.widget.noTodos': 'Nada pendente',
'native.widget.now': 'Agora',
'native.widget.travellers': 'viajantes',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Demà',
'native.widget.nothingPlanned': 'Res planificat per avui',
'native.widget.dayDone': 'Tot fet per avui',
'native.widget.noBookings': 'Cap reserva pendent',
'native.widget.noTodos': 'No queda res per fer',
'native.widget.now': 'Ara',
'native.widget.travellers': 'viatgers',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Zítra',
'native.widget.nothingPlanned': 'Na dnešek nic naplánováno',
'native.widget.dayDone': 'Na dnešek hotovo',
'native.widget.noBookings': 'Žádné nadcházející rezervace',
'native.widget.noTodos': 'Vše hotovo',
'native.widget.now': 'Teď',
'native.widget.travellers': 'cestovatelů',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Morgen',
'native.widget.nothingPlanned': 'Für heute nichts geplant',
'native.widget.dayDone': 'Für heute alles geschafft',
'native.widget.noBookings': 'Keine anstehenden Buchungen',
'native.widget.noTodos': 'Alles erledigt',
'native.widget.now': 'Jetzt',
'native.widget.travellers': 'Reisende',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Tomorrow',
'native.widget.nothingPlanned': 'Nothing planned for today',
'native.widget.dayDone': 'All done for today',
'native.widget.noBookings': 'No bookings ahead',
'native.widget.noTodos': 'Nothing left to do',
'native.widget.now': 'Now',
'native.widget.travellers': 'travellers',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Mañana',
'native.widget.nothingPlanned': 'Nada planeado para hoy',
'native.widget.dayDone': 'Todo hecho por hoy',
'native.widget.noBookings': 'No hay reservas próximas',
'native.widget.noTodos': 'No queda nada pendiente',
'native.widget.now': 'Ahora',
'native.widget.travellers': 'viajeros',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Homme',
'native.widget.nothingPlanned': 'Tänaseks pole midagi planeeritud',
'native.widget.dayDone': 'Tänaseks kõik tehtud',
'native.widget.noBookings': 'Eesootavaid broneeringuid pole',
'native.widget.noTodos': 'Kõik on tehtud',
'native.widget.now': 'Praegu',
'native.widget.travellers': 'reisijat',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Demain',
'native.widget.nothingPlanned': 'Rien de prévu aujourd’hui',
'native.widget.dayDone': 'Tout est fait pour aujourd’hui',
'native.widget.noBookings': 'Aucune réservation à venir',
'native.widget.noTodos': 'Plus rien à faire',
'native.widget.now': 'Maintenant',
'native.widget.travellers': 'voyageurs',
};
export default native;
+4
View File
@@ -94,6 +94,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Αύριο',
'native.widget.nothingPlanned': 'Τίποτα προγραμματισμένο για σήμερα',
'native.widget.dayDone': 'Όλα έγιναν για σήμερα',
'native.widget.noBookings': 'Καμία επερχόμενη κράτηση',
'native.widget.noTodos': 'Δεν απομένει τίποτα',
'native.widget.now': 'Τώρα',
'native.widget.travellers': 'ταξιδιώτες',
};
export default native;
+4
View File
@@ -89,6 +89,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'מחר',
'native.widget.nothingPlanned': 'אין תוכניות להיום',
'native.widget.dayDone': 'הכול הושלם להיום',
'native.widget.noBookings': 'אין הזמנות קרובות',
'native.widget.noTodos': 'לא נשאר מה לעשות',
'native.widget.now': 'עכשיו',
'native.widget.travellers': 'מטיילים',
};
export default native;
+4
View File
@@ -93,6 +93,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Holnap',
'native.widget.nothingPlanned': 'Mára nincs semmi tervezve',
'native.widget.dayDone': 'Mára minden kész',
'native.widget.noBookings': 'Nincs közelgő foglalás',
'native.widget.noTodos': 'Minden kész',
'native.widget.now': 'Most',
'native.widget.travellers': 'utazó',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Besok',
'native.widget.nothingPlanned': 'Tidak ada rencana hari ini',
'native.widget.dayDone': 'Semua selesai hari ini',
'native.widget.noBookings': 'Tidak ada pemesanan mendatang',
'native.widget.noTodos': 'Semua beres',
'native.widget.now': 'Sekarang',
'native.widget.travellers': 'pelancong',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Domani',
'native.widget.nothingPlanned': 'Niente in programma oggi',
'native.widget.dayDone': 'Tutto fatto per oggi',
'native.widget.noBookings': 'Nessuna prenotazione in arrivo',
'native.widget.noTodos': 'Niente da fare',
'native.widget.now': 'Adesso',
'native.widget.travellers': 'viaggiatori',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': '明日',
'native.widget.nothingPlanned': '今日の予定はありません',
'native.widget.dayDone': '今日の予定はすべて完了',
'native.widget.noBookings': '今後の予約はありません',
'native.widget.noTodos': 'やることはありません',
'native.widget.now': '現在',
'native.widget.travellers': '旅行者',
};
export default native;
+4
View File
@@ -90,6 +90,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': '내일',
'native.widget.nothingPlanned': '오늘은 계획이 없습니다',
'native.widget.dayDone': '오늘 일정 완료',
'native.widget.noBookings': '예정된 예약이 없습니다',
'native.widget.noTodos': '남은 할 일이 없습니다',
'native.widget.now': '지금',
'native.widget.travellers': '여행자',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Morgen',
'native.widget.nothingPlanned': 'Niets gepland voor vandaag',
'native.widget.dayDone': 'Alles gedaan voor vandaag',
'native.widget.noBookings': 'Geen komende boekingen',
'native.widget.noTodos': 'Niets meer te doen',
'native.widget.now': 'Nu',
'native.widget.travellers': 'reizigers',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Jutro',
'native.widget.nothingPlanned': 'Na dziś nic nie zaplanowano',
'native.widget.dayDone': 'Na dziś wszystko zrobione',
'native.widget.noBookings': 'Brak nadchodzących rezerwacji',
'native.widget.noTodos': 'Wszystko zrobione',
'native.widget.now': 'Teraz',
'native.widget.travellers': 'podróżnych',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Завтра',
'native.widget.nothingPlanned': 'На сегодня ничего не запланировано',
'native.widget.dayDone': 'На сегодня всё',
'native.widget.noBookings': 'Предстоящих бронирований нет',
'native.widget.noTodos': 'Всё сделано',
'native.widget.now': 'Сейчас',
'native.widget.travellers': 'путешественников',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Zajtra',
'native.widget.nothingPlanned': 'Na dnes nič naplánované',
'native.widget.dayDone': 'Na dnes hotovo',
'native.widget.noBookings': 'Žiadne nadchádzajúce rezervácie',
'native.widget.noTodos': 'Všetko hotové',
'native.widget.now': 'Teraz',
'native.widget.travellers': 'cestovateľov',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'I morgon',
'native.widget.nothingPlanned': 'Inget planerat i dag',
'native.widget.dayDone': 'Allt klart för i dag',
'native.widget.noBookings': 'Inga kommande bokningar',
'native.widget.noTodos': 'Inget kvar att göra',
'native.widget.now': 'Nu',
'native.widget.travellers': 'resenärer',
};
export default native;
+4
View File
@@ -89,6 +89,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'พรุ่งนี้',
'native.widget.nothingPlanned': 'วันนี้ไม่มีแผน',
'native.widget.dayDone': 'วันนี้เสร็จหมดแล้ว',
'native.widget.noBookings': 'ไม่มีการจองที่กำลังจะมาถึง',
'native.widget.noTodos': 'ไม่มีอะไรค้างแล้ว',
'native.widget.now': 'ตอนนี้',
'native.widget.travellers': 'ผู้เดินทาง',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Yarın',
'native.widget.nothingPlanned': 'Bugün için plan yok',
'native.widget.dayDone': 'Bugünlük her şey tamam',
'native.widget.noBookings': 'Yaklaşan rezervasyon yok',
'native.widget.noTodos': 'Yapılacak bir şey kalmadı',
'native.widget.now': 'Şimdi',
'native.widget.travellers': 'gezgin',
};
export default native;
+4
View File
@@ -91,6 +91,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Завтра',
'native.widget.nothingPlanned': 'На сьогодні нічого не заплановано',
'native.widget.dayDone': 'На сьогодні все',
'native.widget.noBookings': 'Майбутніх бронювань немає',
'native.widget.noTodos': 'Усе зроблено',
'native.widget.now': 'Зараз',
'native.widget.travellers': 'мандрівників',
};
export default native;
+4
View File
@@ -92,6 +92,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': 'Ngày mai',
'native.widget.nothingPlanned': 'Hôm nay không có kế hoạch',
'native.widget.dayDone': 'Hôm nay đã xong',
'native.widget.noBookings': 'Không có đặt chỗ sắp tới',
'native.widget.noTodos': 'Không còn việc gì',
'native.widget.now': 'Bây giờ',
'native.widget.travellers': 'du khách',
};
export default native;
+4
View File
@@ -89,6 +89,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': '明天',
'native.widget.nothingPlanned': '今天沒有安排',
'native.widget.dayDone': '今天的行程已全部完成',
'native.widget.noBookings': '沒有即將到來的預訂',
'native.widget.noTodos': '沒有待辦事項',
'native.widget.now': '現在',
'native.widget.travellers': '旅客',
};
export default native;
+4
View File
@@ -89,6 +89,10 @@ const native: TranslationStrings = {
'native.widget.tomorrow': '明天',
'native.widget.nothingPlanned': '今天没有安排',
'native.widget.dayDone': '今天的行程已全部完成',
'native.widget.noBookings': '没有即将到来的预订',
'native.widget.noTodos': '没有待办事项',
'native.widget.now': '现在',
'native.widget.travellers': '旅行者',
};
export default native;