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 @@ -629,8 +629,16 @@ class SettingsRepository(
const val KEY_ISLAND_MEDIA_SHOW_LIKE = "island_media_show_like"
const val KEY_ISLAND_NOTIF_COMPACT_HEADS_UP = "island_notif_compact_heads_up"
const val KEY_ISLAND_NOTIF_CONDENSED_INFO = "island_notif_condensed_info"
const val KEY_ISLAND_NOTIF_PEEK_STYLE = "island_notif_peek_style"
const val ISLAND_NOTIF_PEEK_STYLE_FULL = "full"
const val ISLAND_NOTIF_PEEK_STYLE_COMPACT = "compact"
const val ISLAND_NOTIF_PEEK_STYLE_MINIMAL = "minimal"
const val KEY_ISLAND_NOTIF_KEEP_PROGRESS = "island_notif_keep_progress"
const val KEY_ISLAND_NOTIF_QUEUE = "island_notif_queue"
const val KEY_ISLAND_NOTIF_QUEUE_STYLE = "island_notif_queue_style"
const val ISLAND_NOTIF_QUEUE_STYLE_STACK = "stack"
const val ISLAND_NOTIF_QUEUE_STYLE_OVERLAP = "overlap"
const val KEY_ISLAND_NOTIF_QUEUE_INLINE = "island_notif_queue_inline"
const val KEY_ISLAND_NOTIF_SKIP_SILENT = "island_notif_skip_silent"
const val KEY_ISLAND_NOTIF_FOLLOW_DND = "island_notif_follow_dnd"
const val KEY_ISLAND_NOTIF_FILTER_APPS = "island_notif_filter_apps"
Expand Down Expand Up @@ -4154,6 +4162,14 @@ class SettingsRepository(
fun isIslandNotifQueueEnabled(): Boolean = getBoolean(KEY_ISLAND_NOTIF_QUEUE, true)
fun setIslandNotifQueueEnabled(enabled: Boolean) = putBoolean(KEY_ISLAND_NOTIF_QUEUE, enabled)

fun getIslandNotifQueueStyle(): String =
if (getString(KEY_ISLAND_NOTIF_QUEUE_STYLE, null) == ISLAND_NOTIF_QUEUE_STYLE_OVERLAP) ISLAND_NOTIF_QUEUE_STYLE_OVERLAP
else ISLAND_NOTIF_QUEUE_STYLE_STACK
fun setIslandNotifQueueStyle(style: String) = putString(KEY_ISLAND_NOTIF_QUEUE_STYLE, style)

fun isIslandNotifQueueInlineEnabled(): Boolean = getBoolean(KEY_ISLAND_NOTIF_QUEUE_INLINE, false)
fun setIslandNotifQueueInlineEnabled(enabled: Boolean) = putBoolean(KEY_ISLAND_NOTIF_QUEUE_INLINE, enabled)

fun isFaceUnlockBrightnessEnabled(): Boolean = getBoolean(KEY_FACE_UNLOCK_BRIGHTNESS_ENABLED, false)
fun setFaceUnlockBrightnessEnabled(enabled: Boolean) = putBoolean(KEY_FACE_UNLOCK_BRIGHTNESS_ENABLED, enabled)

Expand Down Expand Up @@ -4190,8 +4206,10 @@ class SettingsRepository(
fun isIslandNotifCompactHeadsUpEnabled(): Boolean = getBoolean(KEY_ISLAND_NOTIF_COMPACT_HEADS_UP, true)
fun setIslandNotifCompactHeadsUpEnabled(enabled: Boolean) = putBoolean(KEY_ISLAND_NOTIF_COMPACT_HEADS_UP, enabled)

fun isIslandNotifCondensedInfoEnabled(): Boolean = getBoolean(KEY_ISLAND_NOTIF_CONDENSED_INFO, false)
fun setIslandNotifCondensedInfoEnabled(enabled: Boolean) = putBoolean(KEY_ISLAND_NOTIF_CONDENSED_INFO, enabled)
fun getIslandNotifPeekStyle(): String =
getString(KEY_ISLAND_NOTIF_PEEK_STYLE, null)
?: if (getBoolean(KEY_ISLAND_NOTIF_CONDENSED_INFO, false)) ISLAND_NOTIF_PEEK_STYLE_COMPACT else ISLAND_NOTIF_PEEK_STYLE_FULL
fun setIslandNotifPeekStyle(style: String) = putString(KEY_ISLAND_NOTIF_PEEK_STYLE, style)

fun isIslandNotifKeepProgressEnabled(): Boolean = getBoolean(KEY_ISLAND_NOTIF_KEEP_PROGRESS, true)
fun setIslandNotifKeepProgressEnabled(enabled: Boolean) = putBoolean(KEY_ISLAND_NOTIF_KEEP_PROGRESS, enabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1000,14 +1000,24 @@ object FeatureRegistry {
),
SearchSetting(
R.string.island_notif_condensed_info_title,
R.string.island_notif_condensed_info_desc,
"island_notif_condensed_info",
R.string.island_notif_peek_style_search_desc,
"island_notif_peek_style",
),
SearchSetting(
R.string.island_notif_queue_title,
R.string.island_notif_queue_desc,
"island_notif_queue",
),
SearchSetting(
R.string.island_notif_queue_style_title,
R.string.island_notif_queue_style_search_desc,
"island_notif_queue_style",
),
SearchSetting(
R.string.island_notif_queue_inline_title,
R.string.island_notif_queue_inline_desc,
"island_notif_queue_inline",
),
SearchSetting(
R.string.island_notif_tap_to_open_title,
R.string.island_notif_tap_to_open_desc,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class IslandItem(
val bypassLauncherOnly: Boolean = false,

val stack: List<StackIcon> = emptyList(),
val queued: List<StackIcon>? = null,
val priorityGroup: String? = null,
) {
var userPriority: Int? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import com.sameerasw.essentials.island.plugins.BaseIslandPlugin
import com.sameerasw.essentials.island.plugins.launchPackage
import com.sameerasw.essentials.island.plugins.sendPendingIntent
import com.sameerasw.essentials.island.plugins.soften
import com.sameerasw.essentials.island.ui.IslandStackBubble
import com.sameerasw.essentials.island.ui.IslandStackOverlap
import com.sameerasw.essentials.island.ui.components.IslandBitmap
import com.sameerasw.essentials.services.NotificationListener
import com.sameerasw.essentials.utils.HapticUtil
Expand All @@ -37,7 +39,9 @@ class NotificationsPlugin : BaseIslandPlugin() {
override val settingKeys = setOf(
SettingsRepository.KEY_ISLAND_CATCH_UP_ENABLED,
SettingsRepository.KEY_ISLAND_NOTIF_COMPACT_HEADS_UP,
SettingsRepository.KEY_ISLAND_NOTIF_CONDENSED_INFO,
SettingsRepository.KEY_ISLAND_NOTIF_PEEK_STYLE,
SettingsRepository.KEY_ISLAND_NOTIF_QUEUE_STYLE,
SettingsRepository.KEY_ISLAND_NOTIF_QUEUE_INLINE,
SettingsRepository.KEY_ISLAND_LINE_STAGE_ENABLED,
SettingsRepository.KEY_ISLAND_SHOW_GLOW,
SettingsRepository.KEY_ISLAND_NOTIF_QUEUE,
Expand Down Expand Up @@ -90,6 +94,12 @@ class NotificationsPlugin : BaseIslandPlugin() {

private fun currentAlert(): ActiveNotificationAlert? = alerts.getOrNull(currentIndex.coerceIn(0, (alerts.size - 1).coerceAtLeast(0)))

private fun waitingInOrder(current: ActiveNotificationAlert): List<ActiveNotificationAlert> {
val index = alerts.indexOf(current)
if (index < 0) return alerts.filter { it !== current }
return alerts.drop(index + 1) + alerts.take(index).asReversed()
}

private fun removeCurrent() {
if (alerts.isEmpty()) return
alerts.removeAt(currentIndex.coerceIn(0, alerts.size - 1))
Expand Down Expand Up @@ -198,6 +208,12 @@ class NotificationsPlugin : BaseIslandPlugin() {
manualPick = false
val cap = if (queueEnabled()) MAX_QUEUE else 1
while (alerts.size > cap) alerts.removeLast()
if (minimal()) {
pendingPopUp = false
holdMinimal()
render()
return
}
if (busyElsewhere()) {
pendingPopUp = true
cancelTimers()
Expand All @@ -217,6 +233,7 @@ class NotificationsPlugin : BaseIslandPlugin() {

private fun popUp() {
val c = ctx ?: return
if (minimal()) return
val lineAvailable = settings.isIslandLineStageEnabled() && settings.isIslandNotifCompactHeadsUpEnabled()
c.request(
if (lineAvailable) PluginRequest.Peek(ITEM_KEY, settings.getIslandTimeoutMs(), sticky = true)
Expand Down Expand Up @@ -267,6 +284,17 @@ class NotificationsPlugin : BaseIslandPlugin() {
clearAll()
}

private fun holdMinimal() {
val c = ctx ?: return
if (!settings.isIslandCatchUpEnabled()) {
scheduleTimeout()
return
}
cancelTimers()
catchingUp = true
if (!settings.isIslandCatchUpInfinite()) c.mainHandler.postDelayed(catchUpRunnable, settings.getIslandCatchUpTimeoutMs())
}

private fun scheduleTimeout() {
val handler = ctx?.mainHandler ?: return
handler.removeCallbacks(timeoutRunnable)
Expand Down Expand Up @@ -309,36 +337,71 @@ class NotificationsPlugin : BaseIslandPlugin() {
val index = alerts.indexOf(alert)
val next = if (queueEnabled()) alerts.getOrNull(index + 1) ?: alerts.getOrNull(index - 1) else null
val stack = alerts.map { stackIconFor(it, current = it === alert) }
val bubble = if (settings.isIslandCatchUpEnabled()) {
SideBubble(
val queued = waitingInOrder(alert).map { stackIconFor(it, current = false) }
val minimal = minimal()
val waiting = if (minimal) queued else emptyList()
val inlineQueue = minimal && waiting.isNotEmpty() && settings.isIslandNotifQueueInlineEnabled()
val bubble = when {
minimal && waiting.isNotEmpty() && !inlineQueue -> SideBubble(
priority = SideBubblePriority.NOTIFICATION,
icons = waiting,
onOpen = { select(waiting.first().key) },
onDismiss = { clearWaiting() },
)
minimal -> null
settings.isIslandCatchUpEnabled() -> SideBubble(
priority = SideBubblePriority.NOTIFICATION,
icons = alerts.map { stackIconFor(it, current = false) },
onOpen = { select(alert.key) },
onDismiss = { clearAll() },
)
} else {
null
else -> null
}
publish(
itemFor(alert).let { current ->
current.withStack(
sideBubble = bubble,
compactVisible = minimal || bubble == null,
leadingCell = if (inlineQueue) queueCell(waiting) else null,
queue = next?.let {
QueueInfo(
next = itemFor(it).withStack(null, alerts.map { a -> stackIconFor(a, current = a === it) }),
onAdvance = { popCurrent(reExpand = false) },
)
},
stack = stack,
queued = queued,
)
},
)
}

private fun queueEnabled() = settings.isIslandNotifQueueEnabled()

private fun condensedLine() = settings.isIslandNotifCondensedInfoEnabled() &&
settings.isIslandLineStageEnabled() && settings.isIslandNotifCompactHeadsUpEnabled()
private fun queueCell(icons: List<StackIcon>): CompactCell = CompactCell("notif.queue") {
when (settings.getIslandNotifQueueStyle()) {
SettingsRepository.ISLAND_NOTIF_QUEUE_STYLE_OVERLAP -> IslandStackOverlap(icons, 22.dp)
else -> IslandStackBubble(icons, 26.dp)
}
}

private fun clearWaiting() {
val current = currentAlert() ?: return
alerts.removeAll { it !== current }
currentIndex = 0
render()
}

private fun peekStyle(): String =
if (settings.isIslandLineStageEnabled() && settings.isIslandNotifCompactHeadsUpEnabled()) {
settings.getIslandNotifPeekStyle()
} else {
SettingsRepository.ISLAND_NOTIF_PEEK_STYLE_FULL
}

private fun condensedLine() = peekStyle() == SettingsRepository.ISLAND_NOTIF_PEEK_STYLE_COMPACT

private fun minimal() = peekStyle() == SettingsRepository.ISLAND_NOTIF_PEEK_STYLE_MINIMAL

private fun itemFor(alert: ActiveNotificationAlert): IslandItem {
if (concealed()) return concealedItemFor(alert)
Expand All @@ -358,7 +421,7 @@ class NotificationsPlugin : BaseIslandPlugin() {
},
)
val appIcon = alert.appIcon
if (alert.chatIcon != null && appIcon != null) {
if (!minimal() && alert.chatIcon != null && appIcon != null) {
add(CompactCell("notif.app", soloOnly = true) { IslandBitmap(appIcon, 22.dp, circle = true) })
}
},
Expand Down Expand Up @@ -415,7 +478,7 @@ class NotificationsPlugin : BaseIslandPlugin() {
},
)
val appIcon = alert.appIcon
if (!hideChat && alert.chatIcon != null && appIcon != null) {
if (!minimal() && !hideChat && alert.chatIcon != null && appIcon != null) {
add(CompactCell("notif.app", soloOnly = true) { IslandBitmap(appIcon, 22.dp, circle = true) })
}
},
Expand Down Expand Up @@ -445,11 +508,18 @@ class NotificationsPlugin : BaseIslandPlugin() {
}
}

private fun IslandItem.withStack(queue: QueueInfo?, stack: List<StackIcon>, sideBubble: SideBubble? = null) = IslandItem(
private fun IslandItem.withStack(
queue: QueueInfo?,
stack: List<StackIcon>,
sideBubble: SideBubble? = null,
compactVisible: Boolean = sideBubble == null,
leadingCell: CompactCell? = null,
queued: List<StackIcon>? = null,
) = IslandItem(
key = key,
priority = priority,
placement = placement,
compact = compact,
compact = if (leadingCell != null) listOf(leadingCell) + compact.take(1) else compact,
line = line,
expanded = expanded,
accent = accent,
Expand All @@ -461,7 +531,8 @@ class NotificationsPlugin : BaseIslandPlugin() {
sourcePackage = sourcePackage,
contentId = contentId,
stack = stack,
compactVisible = sideBubble == null,
queued = queued,
compactVisible = compactVisible,
sideBubble = sideBubble,
)

Expand Down
Loading
Loading