Make notification channels on adding account

This commit is contained in:
Matthieu 2021-09-25 13:43:04 +02:00
parent dc03e52568
commit 2fe37a1691
4 changed files with 67 additions and 52 deletions

View File

@ -9,6 +9,8 @@ import android.os.Bundle
import android.view.View import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import org.pixeldroid.app.databinding.ActivityLoginBinding import org.pixeldroid.app.databinding.ActivityLoginBinding
import org.pixeldroid.app.utils.* import org.pixeldroid.app.utils.*
import org.pixeldroid.app.utils.api.PixelfedAPI import org.pixeldroid.app.utils.api.PixelfedAPI
@ -16,6 +18,9 @@ import org.pixeldroid.app.utils.api.objects.*
import org.pixeldroid.app.utils.db.addUser import org.pixeldroid.app.utils.db.addUser
import org.pixeldroid.app.utils.db.storeInstance import org.pixeldroid.app.utils.db.storeInstance
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.pixeldroid.app.utils.notificationsWorker.NotificationsWorker
import org.pixeldroid.app.utils.notificationsWorker.makeChannelGroupId
import org.pixeldroid.app.utils.notificationsWorker.makeNotificationChannels
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException import java.io.IOException
import java.lang.IllegalArgumentException import java.lang.IllegalArgumentException
@ -340,6 +345,12 @@ class LoginActivity : BaseActivity() {
} catch (exception: NullPointerException) { } catch (exception: NullPointerException) {
return failedRegistration(getString(R.string.login_notifications)) return failedRegistration(getString(R.string.login_notifications))
} }
makeNotificationChannels(
applicationContext,
user.fullHandle,
makeChannelGroupId(user)
)
} }
} }

View File

@ -312,7 +312,7 @@ class MainActivity : BaseActivity() {
iconUrl = user.avatar_static iconUrl = user.avatar_static
isNameShown = true isNameShown = true
identifier = user.user_id.toLong() identifier = user.user_id.toLong()
descriptionText = "@${user.username}@${user.instance_uri.removePrefix("https://")}" descriptionText = user.fullHandle
} }
}.toMutableList() }.toMutableList()

View File

@ -28,4 +28,7 @@ data class UserDatabaseEntity(
val refreshToken: String?, val refreshToken: String?,
val clientId: String, val clientId: String,
val clientSecret: String val clientSecret: String
): Serializable ): Serializable {
val fullHandle: String
get() = "@${username}@${instance_uri.removePrefix("https://")}"
}

View File

@ -51,7 +51,8 @@ class NotificationsWorker(
val uniqueUserId = makeChannelGroupId(user) val uniqueUserId = makeChannelGroupId(user)
val notificationsEnabledForUser = makeNotificationChannels( val notificationsEnabledForUser = makeNotificationChannels(
"@${user.username}@${user.instance_uri.removePrefix("https://")}", applicationContext,
user.fullHandle,
uniqueUserId uniqueUserId
) )
@ -176,54 +177,6 @@ class NotificationsWorker(
} }
} }
private fun makeNotificationChannels(handle: String, channelGroupId: String): Boolean {
val notificationManager: NotificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// The id of the group, hashed (since when creating the group, it may be truncated if too long)
val hashedGroupId = channelGroupId.hashCode().toString()
notificationManager.createNotificationChannelGroup(NotificationChannelGroup(hashedGroupId, handle))
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channels: List<NotificationChannel> = listOf(
NotificationChannel(makeChannelId(channelGroupId, follow), applicationContext.getString(R.string.followed_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, mention), applicationContext.getString(R.string.mention_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, reblog), applicationContext.getString(R.string.shared_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, favourite), applicationContext.getString(R.string.liked_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, comment), applicationContext.getString(R.string.comment_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, poll), applicationContext.getString(R.string.poll_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, null), applicationContext.getString(R.string.other_notification_channel), importance),
).map {
it.apply { group = hashedGroupId }
}
// Register the channels with the system
notificationManager.createNotificationChannels(channels)
//Return true if notifications are enabled, false if disabled
return notificationManager.areNotificationsEnabled() and
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val channelGroup =
notificationManager.getNotificationChannelGroup(hashedGroupId)
!channelGroup.isBlocked
} else true) and
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
!notificationManager.areNotificationsPaused()
} else true) and
!channels.all {
notificationManager.getNotificationChannel(it.id).importance <= NotificationManager.IMPORTANCE_NONE
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
notificationManager.areNotificationsEnabled()
} else {
true
}
}
companion object { companion object {
const val SHOW_NOTIFICATION_TAG = "org.pixeldroid.app.SHOW_NOTIFICATION" const val SHOW_NOTIFICATION_TAG = "org.pixeldroid.app.SHOW_NOTIFICATION"
const val INSTANCE_NOTIFICATION_TAG = "org.pixeldroid.app.USER_NOTIFICATION" const val INSTANCE_NOTIFICATION_TAG = "org.pixeldroid.app.USER_NOTIFICATION"
@ -234,6 +187,54 @@ class NotificationsWorker(
} }
fun makeNotificationChannels(context: Context, handle: String, channelGroupId: String): Boolean {
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// The id of the group, hashed (since when creating the group, it may be truncated if too long)
val hashedGroupId = channelGroupId.hashCode().toString()
notificationManager.createNotificationChannelGroup(NotificationChannelGroup(hashedGroupId, handle))
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channels: List<NotificationChannel> = listOf(
NotificationChannel(makeChannelId(channelGroupId, follow), context.getString(R.string.followed_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, mention), context.getString(R.string.mention_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, reblog), context.getString(R.string.shared_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, favourite), context.getString(R.string.liked_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, comment), context.getString(R.string.comment_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, poll), context.getString(R.string.poll_notification_channel), importance),
NotificationChannel(makeChannelId(channelGroupId, null), context.getString(R.string.other_notification_channel), importance),
).map {
it.apply { group = hashedGroupId }
}
// Register the channels with the system
notificationManager.createNotificationChannels(channels)
//Return true if notifications are enabled, false if disabled
return notificationManager.areNotificationsEnabled() and
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val channelGroup =
notificationManager.getNotificationChannelGroup(hashedGroupId)
!channelGroup.isBlocked
} else true) and
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
!notificationManager.areNotificationsPaused()
} else true) and
!channels.all {
notificationManager.getNotificationChannel(it.id).importance <= NotificationManager.IMPORTANCE_NONE
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
notificationManager.areNotificationsEnabled()
} else {
true
}
}
/** /**
* [channelGroupId] is the id used to uniquely identify the group: for us it is a unique id * [channelGroupId] is the id used to uniquely identify the group: for us it is a unique id
* identifying a user consisting of the concatenation of the instance uri and user id. * identifying a user consisting of the concatenation of the instance uri and user id.
@ -241,7 +242,7 @@ class NotificationsWorker(
private fun makeChannelId(channelGroupId: String, type: Notification.NotificationType?): String = private fun makeChannelId(channelGroupId: String, type: Notification.NotificationType?): String =
(channelGroupId + (type ?: NotificationsWorker.otherNotificationType)).hashCode().toString() (channelGroupId + (type ?: NotificationsWorker.otherNotificationType)).hashCode().toString()
private fun makeChannelGroupId(user: UserDatabaseEntity) = user.instance_uri + user.user_id fun makeChannelGroupId(user: UserDatabaseEntity) = user.instance_uri + user.user_id
fun removeNotificationChannelsFromAccount(context: Context, user: UserDatabaseEntity?) = user?.let { fun removeNotificationChannelsFromAccount(context: Context, user: UserDatabaseEntity?) = user?.let {