Change the way the message list widget listens to changes
Also change the code to only listen for message list changes when the message list widget has been added to the home screen.
This commit is contained in:
parent
eaa88f3c47
commit
da283a7c32
7 changed files with 139 additions and 79 deletions
|
@ -5,19 +5,32 @@ import java.util.concurrent.CopyOnWriteArraySet
|
|||
class MessageListRepository(
|
||||
private val messageStoreManager: MessageStoreManager
|
||||
) {
|
||||
private val listeners = CopyOnWriteArraySet<Pair<String, MessageListChangedListener>>()
|
||||
private val globalListeners = CopyOnWriteArraySet<MessageListChangedListener>()
|
||||
private val accountListeners = CopyOnWriteArraySet<Pair<String, MessageListChangedListener>>()
|
||||
|
||||
fun addListener(listener: MessageListChangedListener) {
|
||||
globalListeners.add(listener)
|
||||
}
|
||||
|
||||
fun addListener(accountUuid: String, listener: MessageListChangedListener) {
|
||||
listeners.add(accountUuid to listener)
|
||||
accountListeners.add(accountUuid to listener)
|
||||
}
|
||||
|
||||
fun removeListener(listener: MessageListChangedListener) {
|
||||
val entries = listeners.filter { it.second == listener }.toSet()
|
||||
listeners.removeAll(entries)
|
||||
globalListeners.remove(listener)
|
||||
|
||||
val accountEntries = accountListeners.filter { it.second == listener }.toSet()
|
||||
if (accountEntries.isNotEmpty()) {
|
||||
accountListeners.removeAll(accountEntries)
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyMessageListChanged(accountUuid: String) {
|
||||
for (listener in listeners) {
|
||||
for (listener in globalListeners) {
|
||||
listener.onMessageListChanged()
|
||||
}
|
||||
|
||||
for (listener in accountListeners) {
|
||||
if (listener.first == accountUuid) {
|
||||
listener.second.onMessageListChanged()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.fsck.k9
|
|||
import android.app.Application
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import app.k9mail.ui.widget.list.MessageListWidgetProvider
|
||||
import app.k9mail.ui.widget.list.MessageListWidgetManager
|
||||
import com.fsck.k9.activity.MessageCompose
|
||||
import com.fsck.k9.controller.MessagingController
|
||||
import com.fsck.k9.notification.NotificationChannelManager
|
||||
|
@ -28,6 +28,7 @@ class App : Application() {
|
|||
private val themeManager: ThemeManager by inject()
|
||||
private val appLanguageManager: AppLanguageManager by inject()
|
||||
private val notificationChannelManager: NotificationChannelManager by inject()
|
||||
private val messageListWidgetManager: MessageListWidgetManager by inject()
|
||||
private val appCoroutineScope: CoroutineScope = GlobalScope + Dispatchers.Main
|
||||
private var appLanguageManagerInitialized = false
|
||||
|
||||
|
@ -43,7 +44,7 @@ class App : Application() {
|
|||
initializeAppLanguage()
|
||||
updateNotificationChannelsOnAppLanguageChanges()
|
||||
themeManager.init()
|
||||
MessageListWidgetProvider.init(this)
|
||||
messageListWidgetManager.init()
|
||||
|
||||
messagingListenerProvider.listeners.forEach { listener ->
|
||||
messagingController.addListener(listener)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.fsck.k9
|
||||
|
||||
import app.k9mail.ui.widget.list.MessageListWidgetUpdateListener
|
||||
import app.k9mail.ui.widget.list.messageListWidgetModule
|
||||
import com.fsck.k9.auth.createOAuthConfigurationProvider
|
||||
import com.fsck.k9.backends.backendsModule
|
||||
|
@ -24,7 +23,6 @@ private val mainAppModule = module {
|
|||
MessagingListenerProvider(
|
||||
listOf(
|
||||
get<UnreadWidgetUpdateListener>(),
|
||||
get<MessageListWidgetUpdateListener>()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@ package app.k9mail.ui.widget.list
|
|||
import org.koin.dsl.module
|
||||
|
||||
val messageListWidgetModule = module {
|
||||
single { MessageListWidgetUpdateListener(context = get()) }
|
||||
single { MessageListWidgetManager(context = get(), messageListRepository = get(), config = get()) }
|
||||
factory { MessageListLoader(preferences = get(), messageListRepository = get(), messageHelper = get()) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package app.k9mail.ui.widget.list
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.fsck.k9.core.BuildConfig
|
||||
import com.fsck.k9.mailstore.MessageListChangedListener
|
||||
import com.fsck.k9.mailstore.MessageListRepository
|
||||
import timber.log.Timber
|
||||
|
||||
class MessageListWidgetManager(
|
||||
private val context: Context,
|
||||
private val messageListRepository: MessageListRepository,
|
||||
private val config: MessageListWidgetConfig,
|
||||
) {
|
||||
private lateinit var appWidgetManager: AppWidgetManager
|
||||
|
||||
private var listenerAdded = false
|
||||
private val listener = MessageListChangedListener {
|
||||
onMessageListChanged()
|
||||
}
|
||||
|
||||
fun init() {
|
||||
appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
if (isAtLeastOneMessageListWidgetAdded()) {
|
||||
resetMessageListWidget()
|
||||
registerMessageListChangedListener()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onMessageListChanged() {
|
||||
try {
|
||||
triggerMessageListWidgetUpdate()
|
||||
} catch (e: RuntimeException) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
throw e
|
||||
} else {
|
||||
Timber.e(e, "Error while updating message list widget")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun onWidgetAdded() {
|
||||
Timber.v("Message list widget added")
|
||||
|
||||
registerMessageListChangedListener()
|
||||
}
|
||||
|
||||
internal fun onWidgetRemoved() {
|
||||
Timber.v("Message list widget removed")
|
||||
|
||||
if (!isAtLeastOneMessageListWidgetAdded()) {
|
||||
unregisterMessageListChangedListener()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun registerMessageListChangedListener() {
|
||||
if (!listenerAdded) {
|
||||
listenerAdded = true
|
||||
messageListRepository.addListener(listener)
|
||||
|
||||
Timber.v("Message list widget is now listening for message list changes…")
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun unregisterMessageListChangedListener() {
|
||||
if (listenerAdded) {
|
||||
listenerAdded = false
|
||||
messageListRepository.removeListener(listener)
|
||||
|
||||
Timber.v("Message list widget stopped listening for message list changes.")
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAtLeastOneMessageListWidgetAdded(): Boolean {
|
||||
return getAppWidgetIds().isNotEmpty()
|
||||
}
|
||||
|
||||
private fun triggerMessageListWidgetUpdate() {
|
||||
val appWidgetIds = getAppWidgetIds()
|
||||
if (appWidgetIds.isNotEmpty()) {
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.listView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetMessageListWidget() {
|
||||
val appWidgetIds = getAppWidgetIds()
|
||||
if (appWidgetIds.isNotEmpty()) {
|
||||
val intent = Intent(context, config.providerClass).apply {
|
||||
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
|
||||
}
|
||||
|
||||
context.sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAppWidgetIds(): IntArray {
|
||||
val componentName = ComponentName(context, config.providerClass)
|
||||
return appWidgetManager.getAppWidgetIds(componentName)
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package app.k9mail.ui.widget.list
|
|||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViews
|
||||
|
@ -17,7 +16,17 @@ import org.koin.core.component.KoinComponent
|
|||
import org.koin.core.component.inject
|
||||
import com.fsck.k9.ui.R as UiR
|
||||
|
||||
open class MessageListWidgetProvider : AppWidgetProvider() {
|
||||
open class MessageListWidgetProvider : AppWidgetProvider(), KoinComponent {
|
||||
private val messageListWidgetManager: MessageListWidgetManager by inject()
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
messageListWidgetManager.onWidgetAdded()
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
messageListWidgetManager.onWidgetRemoved()
|
||||
}
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
|
@ -73,36 +82,4 @@ open class MessageListWidgetProvider : AppWidgetProvider() {
|
|||
}
|
||||
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
companion object : KoinComponent {
|
||||
private val messageListWidgetConfig: MessageListWidgetConfig by inject()
|
||||
|
||||
fun init(context: Context) {
|
||||
resetMessageListWidget(context)
|
||||
}
|
||||
|
||||
private fun resetMessageListWidget(context: Context) {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
val providerClass = messageListWidgetConfig.providerClass
|
||||
val componentName = ComponentName(context, providerClass)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
|
||||
|
||||
val intent = Intent(context, providerClass).apply {
|
||||
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
|
||||
}
|
||||
context.sendBroadcast(intent)
|
||||
}
|
||||
|
||||
fun triggerMessageListWidgetUpdate(context: Context) {
|
||||
val appWidgetManager = AppWidgetManager.getInstance(context)
|
||||
|
||||
val providerClass = messageListWidgetConfig.providerClass
|
||||
val componentName = ComponentName(context, providerClass)
|
||||
val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
|
||||
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.listView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
package app.k9mail.ui.widget.list
|
||||
|
||||
import android.content.Context
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.controller.SimpleMessagingListener
|
||||
import com.fsck.k9.core.BuildConfig
|
||||
import com.fsck.k9.mail.Message
|
||||
import timber.log.Timber
|
||||
|
||||
class MessageListWidgetUpdateListener(private val context: Context) : SimpleMessagingListener() {
|
||||
|
||||
private fun updateMailListWidget() {
|
||||
try {
|
||||
MessageListWidgetProvider.triggerMessageListWidgetUpdate(context)
|
||||
} catch (e: RuntimeException) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
throw e
|
||||
} else {
|
||||
Timber.e(e, "Error while updating message list widget")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun synchronizeMailboxRemovedMessage(account: Account, folderServerId: String, messageServerId: String) {
|
||||
updateMailListWidget()
|
||||
}
|
||||
|
||||
override fun synchronizeMailboxNewMessage(account: Account, folderServerId: String, message: Message) {
|
||||
updateMailListWidget()
|
||||
}
|
||||
|
||||
override fun folderStatusChanged(account: Account, folderId: Long) {
|
||||
updateMailListWidget()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue