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
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,28 @@ public data class TimelinePin(
* Description of the values to populate the layout when the user views the pin.
*/
val layout: TimelineLayout,

/**
* Optional reminders that buzz the watch before this pin's start time.
* Each reminder is inserted into BlobDatabase.Reminder and linked to this pin.
*/
val reminders: List<TimelineReminder> = emptyList(),
) {
public companion object
}

/**
* A reminder that fires before a [TimelinePin] and buzzes the watch.
*
* Use [TimelineLayoutType.GENERIC_REMINDER] for the layout type, and
* `system://images/NOTIFICATION_REMINDER` as the icon.
*
* @param time absolute time at which the reminder fires (e.g. pin.startTime - 15.minutes)
* @param layout layout shown on the watch when the reminder fires
*/
public data class TimelineReminder(
val time: Instant,
val layout: TimelineLayout,
) {
public companion object
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,23 @@ import kotlin.time.Duration
import kotlin.time.Instant

public fun TimelinePin.Companion.fromBundle(bundle: Bundle): TimelinePin {
val reminderCount = bundle.getInt(KEY_REMINDERS_COUNT, 0)
val reminders = (0 until reminderCount).map { i ->
TimelineReminder.fromBundle(bundle.getBundle("$KEY_REMINDER_PREFIX$i") ?: Bundle())
}
return TimelinePin(
id = bundle.getString(KEY_ID) ?: error("missing id"),
startTime = Instant.parse(bundle.getString(KEY_START_TIME) ?: error("missing start time")),
duration = bundle.getString(KEY_DURATION)?.let { Duration.parse(it) },
layout = TimelineLayout.fromBundle(bundle),
reminders = reminders,
)
}

public fun TimelineReminder.Companion.fromBundle(bundle: Bundle): TimelineReminder {
return TimelineReminder(
time = Instant.parse(bundle.getString(KEY_REMINDER_TIME) ?: error("missing reminder time")),
layout = TimelineLayout.fromBundle(bundle),
)
}

Expand All @@ -20,22 +32,37 @@ public fun TimelinePin.toBundle(): Bundle {
putString(KEY_ID, id)
putString(KEY_START_TIME, startTime.toString())
duration?.let { putString(KEY_DURATION, it.toIsoString()) }
putString(KEY_LAYOUT_TYPE, layout.type.code)
layout.title?.let { putString(KEY_LAYOUT_TITLE, it) }
layout.subtitle?.let { putString(KEY_LAYOUT_SUBTITLE, it) }
layout.body?.let { putString(KEY_LAYOUT_BODY, it) }
layout.tinyIcon?.let { putString(KEY_LAYOUT_TINY_ICON, it) }
layout.smallIcon?.let { putString(KEY_LAYOUT_SMALL_ICON, it) }
layout.largeIcon?.let { putString(KEY_LAYOUT_LARGE_ICON, it) }
layout.primaryColor?.let { putString(KEY_LAYOUT_PRIMARY_COLOR, it) }
layout.secondaryColor?.let { putString(KEY_LAYOUT_SECONDARY_COLOR, it) }
layout.backgroundColor?.let { putString(KEY_LAYOUT_BACKGROUND_COLOR, it) }
layout.headings?.let { putStringArray(KEY_LAYOUT_HEADINGS, it.toTypedArray()) }
layout.paragraphs?.let { putStringArray(KEY_LAYOUT_PARAGRAPHS, it.toTypedArray()) }
layout.lastUpdated?.let { putString(KEY_LAYOUT_LAST_UPDATED, it.toString()) }
putLayoutFields(layout)
putInt(KEY_REMINDERS_COUNT, reminders.size)
reminders.forEachIndexed { i, reminder ->
putBundle("$KEY_REMINDER_PREFIX$i", reminder.toBundle())
}
}
}

public fun TimelineReminder.toBundle(): Bundle {
return Bundle().apply {
putString(KEY_REMINDER_TIME, time.toString())
putLayoutFields(layout)
}
}

private fun Bundle.putLayoutFields(layout: TimelineLayout) {
putString(KEY_LAYOUT_TYPE, layout.type.code)
layout.title?.let { putString(KEY_LAYOUT_TITLE, it) }
layout.subtitle?.let { putString(KEY_LAYOUT_SUBTITLE, it) }
layout.body?.let { putString(KEY_LAYOUT_BODY, it) }
layout.tinyIcon?.let { putString(KEY_LAYOUT_TINY_ICON, it) }
layout.smallIcon?.let { putString(KEY_LAYOUT_SMALL_ICON, it) }
layout.largeIcon?.let { putString(KEY_LAYOUT_LARGE_ICON, it) }
layout.primaryColor?.let { putString(KEY_LAYOUT_PRIMARY_COLOR, it) }
layout.secondaryColor?.let { putString(KEY_LAYOUT_SECONDARY_COLOR, it) }
layout.backgroundColor?.let { putString(KEY_LAYOUT_BACKGROUND_COLOR, it) }
layout.headings?.let { putStringArray(KEY_LAYOUT_HEADINGS, it.toTypedArray()) }
layout.paragraphs?.let { putStringArray(KEY_LAYOUT_PARAGRAPHS, it.toTypedArray()) }
layout.lastUpdated?.let { putString(KEY_LAYOUT_LAST_UPDATED, it.toString()) }
}

private fun TimelineLayout.Companion.fromBundle(bundle: Bundle): TimelineLayout {
val typeCode = bundle.getString(KEY_LAYOUT_TYPE) ?: ""
val type = TimelineLayoutType.entries.firstOrNull { it.code == typeCode }
Expand Down Expand Up @@ -77,3 +104,6 @@ private const val KEY_LAYOUT_BACKGROUND_COLOR = "LAYOUT_BACKGROUND_COLOR"
private const val KEY_LAYOUT_HEADINGS = "LAYOUT_HEADINGS"
private const val KEY_LAYOUT_PARAGRAPHS = "LAYOUT_PARAGRAPHS"
private const val KEY_LAYOUT_LAST_UPDATED = "LAYOUT_LAST_UPDATED"
private const val KEY_REMINDERS_COUNT = "REMINDERS_COUNT"
private const val KEY_REMINDER_PREFIX = "REMINDER_"
private const val KEY_REMINDER_TIME = "REMINDER_TIME"
Loading