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
43 changes: 43 additions & 0 deletions app/src/main/java/com/chiller3/basicsync/Notifications.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ class Notifications(private val context: Context) {
private const val CHANNEL_ID_PERSISTENT = "persistent"
private const val CHANNEL_ID_FAILURE = "failure"
private const val CHANNEL_ID_CONFLICTS = "conflicts"
private const val CHANNEL_ID_ALERTS = "alerts"

private val LEGACY_CHANNEL_IDS = arrayOf<String>()

const val ID_PERSISTENT = -1
private const val ID_FAILURE = -2
private const val ID_CONFLICTS = -3
private const val ID_ALERTS = -4
}

private val notificationManager = context.getSystemService(NotificationManager::class.java)
Expand Down Expand Up @@ -62,6 +64,14 @@ class Notifications(private val context: Context) {
description = context.getString(R.string.notification_channel_conflicts_desc)
}

private fun createSyncthingAlertsChannel() = NotificationChannel(
CHANNEL_ID_ALERTS,
context.getString(R.string.notification_channel_alerts_name),
NotificationManager.IMPORTANCE_HIGH,
).apply {
description = context.getString(R.string.notification_channel_alerts_desc)
}

/**
* Ensure notification channels are up-to-date.
*
Expand All @@ -72,6 +82,7 @@ class Notifications(private val context: Context) {
createPersistentChannel(),
createFailureAlertsChannel(),
createConflictsAlertsChannel(),
createSyncthingAlertsChannel(),
))
LEGACY_CHANNEL_IDS.forEach { notificationManager.deleteNotificationChannel(it) }
}
Expand Down Expand Up @@ -240,4 +251,36 @@ class Notifications(private val context: Context) {

notificationManager.notify(ID_CONFLICTS, notification)
}

fun sendOrClearAlertsNotification(alertCount: Int) {
if (alertCount == 0) {
notificationManager.cancel(ID_ALERTS)
return
}

val notification = Notification.Builder(context, CHANNEL_ID_ALERTS).run {
setContentTitle(context.resources.getQuantityString(
R.plurals.notification_syncthing_alerts_title,
alertCount,
alertCount,
))
setSmallIcon(R.drawable.ic_notifications)
setOnlyAlertOnce(true)

val intent = Intent(context, WebUiActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
val pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
)
setContentIntent(pendingIntent)

build()
}

notificationManager.notify(ID_ALERTS, notification)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,15 @@ class SyncthingService : Service(), SyncthingStatusReceiver, DeviceStateListener
notifications.sendOrClearConflictsNotification(conflicts)
}
}
@GuardedBy("stateLock")
private var syncthingAlerts = 0
set(count) {
if (field != count) {
field = count

notifications.sendOrClearAlertsNotification(count)
}
}

private val isResumed: Boolean
@GuardedBy("stateLock")
Expand Down Expand Up @@ -577,6 +586,7 @@ class SyncthingService : Service(), SyncthingStatusReceiver, DeviceStateListener
deviceStateTracker.updateConnectedDevices(0)

syncthingConflicts = emptyList()
syncthingAlerts = 0
syncthingApp = null

stateChanged()
Expand All @@ -599,6 +609,13 @@ class SyncthingService : Service(), SyncthingStatusReceiver, DeviceStateListener
}
}

@WorkerThread
override fun onAlertsUpdated(count: Int) {
synchronized(stateLock) {
syncthingAlerts = count
}
}

@WorkerThread
override fun onBusyFoldersUpdated(count: Int) {
deviceStateTracker.updateBusyFolders(count)
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@
<string name="notification_channel_conflicts_name">Sync conflicts</string>
<!-- Description of the Android notification channel for notifications about sync conflicts. -->
<string name="notification_channel_conflicts_desc">Alerts for conflicts encountered during syncing</string>
<!-- Name of the Android notification channel for Syncthing's in-app alerts. -->
<string name="notification_channel_alerts_name">Syncthing alerts</string>
<!-- Description of the Android notification channel for Syncthing's in-app alerts. -->
<string name="notification_channel_alerts_desc">Device/folder requests and other alerts reported by Syncthing</string>
<!-- Status text indicating that Syncthing is running and ready to sync. -->
<string name="notification_persistent_running_title">Syncthing is running</string>
<!-- Status text indicating that Syncthing is not running at all (not just paused). -->
Expand All @@ -251,6 +255,11 @@
<item quantity="one">%d sync conflict found</item>
<item quantity="other">%d sync conflicts found</item>
</plurals>
<!-- Title of the notification shown when Syncthing sends an in-app alert. -->
<plurals name="notification_syncthing_alerts_title">
<item quantity="one">%d Syncthing alert</item>
<item quantity="other">%d Syncthing alerts</item>
</plurals>
<!-- Button shown in the persistent notification to switch from manual mode to auto mode. -->
<string name="notification_action_auto_mode">Auto mode</string>
<!-- Button shown in the persistent notification to switch from auto mode to manual mode. -->
Expand Down
Loading