Merge pull request #5166 from k9mail/unified_inbox_fixes

Refactor MessageList.decodeExtras()
This commit is contained in:
cketti 2021-02-23 13:52:03 +01:00 committed by GitHub
commit e8446a4f42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -155,6 +155,7 @@ open class MessageList :
}
if (isDrawerEnabled) {
configureDrawer()
drawer!!.updateUserAccountsAndFolders(account)
}
@ -195,6 +196,7 @@ open class MessageList :
}
if (isDrawerEnabled) {
configureDrawer()
drawer!!.updateUserAccountsAndFolders(account)
}
@ -305,115 +307,28 @@ open class MessageList :
}
private fun decodeExtras(intent: Intent): Boolean {
val action = intent.action
if (Intent.ACTION_VIEW == action && intent.data != null) {
val uri = intent.data!!
val segmentList = uri.pathSegments
val launchData = decodeExtrasToLaunchData(intent)
val accountId = segmentList[0]
val accounts = preferences.availableAccounts
for (account in accounts) {
if (account.accountNumber.toString() == accountId) {
val folderId = segmentList[1].toLong()
val messageUid = segmentList[2]
messageReference = MessageReference(account.uuid, folderId, messageUid, null)
break
}
}
} else if (ACTION_SHORTCUT == action) {
// Handle shortcut intents
val specialFolder = intent.getStringExtra(EXTRA_SPECIAL_FOLDER)
if (SearchAccount.UNIFIED_INBOX == specialFolder) {
search = SearchAccount.createUnifiedInboxAccount().relatedSearch
}
} else if (intent.getStringExtra(SearchManager.QUERY) != null) {
// check if this intent comes from the system search ( remote )
if (Intent.ACTION_SEARCH == intent.action) {
// Query was received from Search Dialog
val query = intent.getStringExtra(SearchManager.QUERY).trim()
search = LocalSearch(getString(R.string.search_results))
search!!.isManualSearch = true
noThreading = true
search!!.or(SearchCondition(SearchField.SENDER, SearchSpecification.Attribute.CONTAINS, query))
search!!.or(SearchCondition(SearchField.SUBJECT, SearchSpecification.Attribute.CONTAINS, query))
search!!.or(SearchCondition(SearchField.MESSAGE_CONTENTS, SearchSpecification.Attribute.CONTAINS, query))
val appData = intent.getBundleExtra(SearchManager.APP_DATA)
if (appData != null) {
val searchAccountUuid = appData.getString(EXTRA_SEARCH_ACCOUNT)
if (searchAccountUuid != null) {
search!!.addAccountUuid(searchAccountUuid)
// searches started from a folder list activity will provide an account, but no folder
if (appData.containsKey(EXTRA_SEARCH_FOLDER)) {
val folderId = appData.getLong(EXTRA_SEARCH_FOLDER)
search!!.addAllowedFolder(folderId)
}
} else if (BuildConfig.DEBUG) {
throw AssertionError("Invalid app data in search intent")
}
}
}
// If Unified Inbox was disabled show default account instead
val search = if (launchData.search.isUnifiedInbox && !K9.isShowUnifiedInbox) {
createDefaultLocalSearch()
} else {
// regular LocalSearch object was passed
search = if (intent.hasExtra(EXTRA_SEARCH)) {
ParcelableUtil.unmarshall(intent.getByteArrayExtra(EXTRA_SEARCH), LocalSearch.CREATOR)
} else {
null
}
noThreading = intent.getBooleanExtra(EXTRA_NO_THREADING, false)
launchData.search
}
if (messageReference == null) {
val messageReferenceString = intent.getStringExtra(EXTRA_MESSAGE_REFERENCE)
messageReference = MessageReference.parse(messageReferenceString)
val account = search.firstAccount()
if (account == null) {
finish()
return false
}
if (messageReference != null) {
search = LocalSearch()
search!!.addAccountUuid(messageReference!!.accountUuid)
val folderId = messageReference!!.folderId
search!!.addAllowedFolder(folderId)
}
this.account = account
this.search = search
singleFolderMode = search.folderIds.size == 1
noThreading = launchData.noThreading
messageReference = launchData.messageReference
// Edge case: the Unified Inbox was disabled while it was being displayed
if (search != null && search!!.id == SearchAccount.UNIFIED_INBOX && !K9.isShowUnifiedInbox) {
search = null
}
if (search == null) {
val accountUuid = intent.getStringExtra("account")
if (accountUuid != null) {
// We've most likely been started by an old unread widget or accounts shortcut
val folderServerId = intent.getStringExtra("folder")
val folderId: Long
if (folderServerId == null) {
account = preferences.getAccount(accountUuid)
folderId = defaultFolderProvider.getDefaultFolder(account!!)
} else {
// FIXME: load folder ID for folderServerId
folderId = 0
}
search = LocalSearch()
search!!.addAccountUuid(accountUuid)
search!!.addAllowedFolder(folderId)
} else {
account = preferences.defaultAccount
if (K9.isShowUnifiedInbox) {
search = SearchAccount.createUnifiedInboxAccount().relatedSearch
} else {
search = LocalSearch()
search!!.addAccountUuid(account!!.uuid)
val folderId = defaultFolderProvider.getDefaultFolder(account!!)
search!!.addAllowedFolder(folderId)
}
}
}
initializeFromLocalSearch(search)
if (account != null && !account!!.isAvailable(this)) {
if (!account.isAvailable(this)) {
onAccountUnavailable()
return false
}
@ -421,6 +336,111 @@ open class MessageList :
return true
}
private fun decodeExtrasToLaunchData(intent: Intent): LaunchData {
val action = intent.action
val data = intent.data
val queryString = intent.getStringExtra(SearchManager.QUERY)
if (action == Intent.ACTION_VIEW && data != null && data.pathSegments.size >= 3) {
val segmentList = data.pathSegments
val accountId = segmentList[0]
for (account in preferences.accounts) {
if (account.accountNumber.toString() == accountId) {
val folderId = segmentList[1].toLong()
val messageUid = segmentList[2]
val messageReference = MessageReference(account.uuid, folderId, messageUid, null)
return LaunchData(
search = messageReference.toLocalSearch(),
messageReference = messageReference
)
}
}
} else if (action == ACTION_SHORTCUT) {
// Handle shortcut intents
val specialFolder = intent.getStringExtra(EXTRA_SPECIAL_FOLDER)
if (SearchAccount.UNIFIED_INBOX == specialFolder) {
return LaunchData(search = SearchAccount.createUnifiedInboxAccount().relatedSearch)
}
} else if (action == Intent.ACTION_SEARCH && queryString != null) {
// Query was received from Search Dialog
val query = queryString.trim()
val search = LocalSearch(getString(R.string.search_results)).apply {
isManualSearch = true
or(SearchCondition(SearchField.SENDER, SearchSpecification.Attribute.CONTAINS, query))
or(SearchCondition(SearchField.SUBJECT, SearchSpecification.Attribute.CONTAINS, query))
or(SearchCondition(SearchField.MESSAGE_CONTENTS, SearchSpecification.Attribute.CONTAINS, query))
}
val appData = intent.getBundleExtra(SearchManager.APP_DATA)
if (appData != null) {
val searchAccountUuid = appData.getString(EXTRA_SEARCH_ACCOUNT)
if (searchAccountUuid != null) {
search.addAccountUuid(searchAccountUuid)
// searches started from a folder list activity will provide an account, but no folder
if (appData.containsKey(EXTRA_SEARCH_FOLDER)) {
val folderId = appData.getLong(EXTRA_SEARCH_FOLDER)
search.addAllowedFolder(folderId)
}
} else if (BuildConfig.DEBUG) {
throw AssertionError("Invalid app data in search intent")
}
}
return LaunchData(
search = search,
noThreading = true
)
} else if (intent.hasExtra(EXTRA_SEARCH)) {
// regular LocalSearch object was passed
val search = ParcelableUtil.unmarshall(intent.getByteArrayExtra(EXTRA_SEARCH), LocalSearch.CREATOR)
val noThreading = intent.getBooleanExtra(EXTRA_NO_THREADING, false)
return LaunchData(search = search, noThreading = noThreading)
} else if (intent.hasExtra(EXTRA_MESSAGE_REFERENCE)) {
val messageReferenceString = intent.getStringExtra(EXTRA_MESSAGE_REFERENCE)
val messageReference = MessageReference.parse(messageReferenceString)
if (messageReference != null) {
return LaunchData(
search = messageReference.toLocalSearch(),
messageReference = messageReference
)
}
} else if (intent.hasExtra("account")) {
val accountUuid = intent.getStringExtra("account")
if (accountUuid != null) {
// We've most likely been started by an old unread widget or accounts shortcut
val account = preferences.getAccount(accountUuid)
val folderId = defaultFolderProvider.getDefaultFolder(account)
val search = LocalSearch().apply {
addAccountUuid(accountUuid)
addAllowedFolder(folderId)
}
return LaunchData(search = search)
}
}
// Default action
val search = if (K9.isShowUnifiedInbox) {
SearchAccount.createUnifiedInboxAccount().relatedSearch
} else {
createDefaultLocalSearch()
}
return LaunchData(search)
}
private fun createDefaultLocalSearch(): LocalSearch {
val account = preferences.defaultAccount
return LocalSearch().apply {
addAccountUuid(account.uuid)
addAllowedFolder(defaultFolderProvider.getDefaultFolder(account))
}
}
private fun checkAndRequestPermissions() {
if (!hasPermission(Permission.READ_CONTACTS)) {
requestPermissionOrShowRationale(Permission.READ_CONTACTS)
@ -1430,6 +1450,25 @@ open class MessageList :
configureDrawer()
}
private fun LocalSearch.firstAccount(): Account? {
return if (searchAllAccounts()) {
preferences.defaultAccount
} else {
val accountUuid = accountUuids.first()
preferences.getAccount(accountUuid)
}
}
private val LocalSearch.isUnifiedInbox: Boolean
get() = id == SearchAccount.UNIFIED_INBOX
private fun MessageReference.toLocalSearch(): LocalSearch {
return LocalSearch().apply {
addAccountUuid(accountUuid)
addAllowedFolder(folderId)
}
}
private fun configureDrawer() {
val drawer = drawer ?: return
when {
@ -1467,6 +1506,12 @@ open class MessageList :
MESSAGE_LIST, MESSAGE_VIEW, SPLIT_VIEW
}
private class LaunchData(
val search: LocalSearch,
val messageReference: MessageReference? = null,
val noThreading: Boolean = false
)
companion object : KoinComponent {
private const val EXTRA_SEARCH = "search_bytes"
private const val EXTRA_NO_THREADING = "no_threading"