diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt index 27865643ea69d591bc002008304fd5727ff46963..f36be6163c7bbe2999b11ac7cd494d3753ca6ac3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt @@ -29,6 +29,9 @@ class SettingsModule { @Provides fun provideAppearanceSettings(context: Context) = Settings.appearance(context) + @Provides + fun provideRedirectionSettings(context: Context) = Settings.redirection(context) + @Provides fun provideMessageSettings(context: Context) = Settings.message(context) diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt index 78ca8cf0c84a94d5cae2bfa11b94926a332e7792..47c7338c12b11726fcee9616a1a3ce081368013b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/AsyncBackend.kt @@ -19,6 +19,7 @@ package de.kuschku.quasseldroid.service +import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.util.compatibility.HandlerService import de.kuschku.quasseldroid.Backend @@ -68,4 +69,6 @@ class AsyncBackend( override fun requestConnectNewNetwork() { backend.requestConnectNewNetwork() } + + override fun setCurrentBuffer(id: BufferId) = backend.setCurrentBuffer(id) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt index b7bd8c1482a4ce066f8e557d4fec538841d7ca54..9bb2a051ececdf804b0c55bac04e73f399d6f79a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt @@ -67,6 +67,7 @@ import de.kuschku.quasseldroid.util.compatibility.AndroidHandlerService import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer import de.kuschku.quasseldroid.util.ui.LocaleHelper +import io.reactivex.subjects.BehaviorSubject import org.threeten.bp.Instant import javax.inject.Inject import javax.net.ssl.X509TrustManager @@ -332,6 +333,10 @@ class QuasselService : DaggerLifecycleService(), }) } } + + override fun setCurrentBuffer(id: BufferId) { + service?.currentBuffer?.onNext(id) + } } private val backendImplementation = BackendImplementation() @@ -346,6 +351,8 @@ class QuasselService : DaggerLifecycleService(), @Inject lateinit var accountDatabase: AccountDatabase + lateinit var currentBuffer: BehaviorSubject<BufferId> + private fun disconnectFromCore() { getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE).editCommit { putBoolean(Keys.Status.reconnect, false) @@ -364,9 +371,11 @@ class QuasselService : DaggerLifecycleService(), hostnameVerifier = QuasselHostnameVerifier(QuasselHostnameManager(database.hostnameWhitelist())) trustManager = QuasselTrustManager(certificateManager) + val backlogStorage = QuasselBacklogStorage(database) + currentBuffer = backlogStorage.currentBuffer sessionManager = SessionManager( ISession.NULL, - QuasselBacklogStorage(database), + backlogStorage, notificationBackend, handlerService, ::AndroidHeartBeatRunner, diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/RedirectionSettings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/RedirectionSettings.kt new file mode 100644 index 0000000000000000000000000000000000000000..a1ac1a313a08c7b5451faf53e09f52ceb779757b --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/settings/RedirectionSettings.kt @@ -0,0 +1,30 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Mareike Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.settings + +data class RedirectionSettings( + val userNotices: Boolean = true, + val serverNotices: Boolean = true, + val errors: Boolean = false +) { + companion object { + val DEFAULT = RedirectionSettings() + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt index fd17b1204c3134b61049ed3fe6675360b0c68536..cb243d1da8e40ca1bcbff907dfd7ac44f7b154bf 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/settings/Settings.kt @@ -55,6 +55,23 @@ object Settings { ) } + fun redirection(context: Context) = context.sharedPreferences { + RedirectionSettings( + userNotices = getBoolean( + context.getString(R.string.preference_redirection_user_notices_key), + RedirectionSettings.DEFAULT.userNotices + ), + serverNotices = getBoolean( + context.getString(R.string.preference_redirection_server_notices_key), + RedirectionSettings.DEFAULT.serverNotices + ), + errors = getBoolean( + context.getString(R.string.preference_redirection_errors_key), + RedirectionSettings.DEFAULT.errors + ) + ) + } + fun message(context: Context) = context.sharedPreferences { MessageSettings( useMonospace = getBoolean( diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt index 69979218595b957f5f01c28a25e1729bb1c7f57c..94085c3479649621efaebd91133f363ed4ae310a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt @@ -41,10 +41,7 @@ import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader import com.bumptech.glide.util.FixedPreloadSizeProvider import com.google.android.material.floatingactionbutton.FloatingActionButton import de.kuschku.libquassel.connection.ConnectionState -import de.kuschku.libquassel.protocol.BufferId -import de.kuschku.libquassel.protocol.Buffer_Type -import de.kuschku.libquassel.protocol.Message_Type -import de.kuschku.libquassel.protocol.MsgId +import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.BufferSyncer import de.kuschku.libquassel.session.SessionManager @@ -58,10 +55,7 @@ import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase import de.kuschku.quasseldroid.persistence.models.MessageData import de.kuschku.quasseldroid.service.BacklogRequester -import de.kuschku.quasseldroid.settings.AppearanceSettings -import de.kuschku.quasseldroid.settings.AutoCompleteSettings -import de.kuschku.quasseldroid.settings.BacklogSettings -import de.kuschku.quasseldroid.settings.MessageSettings +import de.kuschku.quasseldroid.settings.* import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.ui.info.user.UserInfoActivity import de.kuschku.quasseldroid.util.Patterns @@ -101,6 +95,9 @@ class MessageListFragment : ServiceBoundFragment() { @Inject lateinit var messageSettings: MessageSettings + @Inject + lateinit var redirectionSettings: RedirectionSettings + @Inject lateinit var database: QuasselDatabase @@ -367,17 +364,30 @@ class MessageListFragment : ServiceBoundFragment() { } } - val data = combineLatest(modelHelper.chat.bufferId, + val data = combineLatest(modelHelper.bufferSyncer, + modelHelper.chat.bufferId, modelHelper.chat.selectedMessages, modelHelper.chat.expandedMessages, modelHelper.markerLine) - .toLiveData().switchMapNotNull { (buffer, selected, expanded, markerLine) -> + .toLiveData().switchMapNotNull { (bufferSyncer, buffer, selected, expanded, markerLine) -> + val network = bufferSyncer.orNull()?.bufferInfo(buffer)?.networkId ?: NetworkId(0) + val serverBuffer = bufferSyncer.orNull()?.find( + networkId = network, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.bufferId ?: BufferId(0) + accountDatabase.accounts().listen(accountId).safeSwitchMap { database.filtered().listen(accountId, buffer, it.defaultFiltered).switchMapNotNull { filtered -> LivePagedListBuilder( - database.message().findByBufferIdPaged(buffer, filtered).mapByPage { + database.message().findByBufferIdPaged(network, + serverBuffer, + buffer, + filtered, + redirectionSettings.userNotices, + redirectionSettings.serverNotices, + redirectionSettings.errors).mapByPage { processMessages(it, selected.keys, expanded, markerLine.orNull()) }, PagedList.Config.Builder() @@ -401,17 +411,31 @@ class MessageListFragment : ServiceBoundFragment() { swipeRefreshLayout.isEnabled = (bufferId != null || bufferId?.isValidId() == true) }) - modelHelper.sessionManager.mapSwitchMap(SessionManager::state).distinctUntilChanged().toLiveData().observe( - this, Observer { - if (it?.orNull() == ConnectionState.CONNECTED) { + combineLatest(modelHelper.bufferSyncer, + modelHelper.sessionManager.mapSwitchMap(SessionManager::state).distinctUntilChanged()) + .toLiveData().observe(this, Observer { (bufferSyncer, state) -> + if (state?.orNull() == ConnectionState.CONNECTED) { runInBackgroundDelayed(16) { modelHelper.chat.bufferId { bufferId -> + val currentNetwork = bufferSyncer.orNull()?.bufferInfo(bufferId)?.networkId + ?: NetworkId(0) + val currentServerBuffer = bufferSyncer.orNull()?.find( + networkId = currentNetwork, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.bufferId ?: BufferId(0) + val filtered = database.filtered().get(accountId, bufferId, accountDatabase.accounts().findById(accountId)?.defaultFiltered ?: 0) // Try loading messages when switching to isEmpty bufferId - val hasVisibleMessages = database.message().hasVisibleMessages(bufferId, filtered) + val hasVisibleMessages = database.message().hasVisibleMessages(currentNetwork, + currentServerBuffer, + bufferId, + filtered, + redirectionSettings.userNotices, + redirectionSettings.serverNotices, + redirectionSettings.errors) if (!hasVisibleMessages) { if (bufferId.isValidId() && bufferId != BufferId.MAX_VALUE) { loadMore(initial = true) @@ -504,11 +528,23 @@ class MessageListFragment : ServiceBoundFragment() { val buffer = modelHelper.chat.bufferId.value ?: BufferId(-1) + val network = modelHelper.bufferSyncer.value?.orNull()?.bufferInfo(buffer)?.networkId + ?: NetworkId(0) + val serverBuffer = modelHelper.bufferSyncer.value?.orNull()?.find( + networkId = network, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.bufferId ?: BufferId(0) if (buffer != lastBuffer) { adapter.clearCache() modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> - onBufferChange(lastBuffer, buffer, firstVisibleMessageId, bufferSyncer) + onBufferChange(lastBuffer, + network, + buffer, + serverBuffer, + firstVisibleMessageId, + bufferSyncer) } + modelHelper.backend.value?.orNull()?.setCurrentBuffer(buffer) lastBuffer = buffer } } @@ -531,7 +567,11 @@ class MessageListFragment : ServiceBoundFragment() { } private fun onBufferChange( - previous: BufferId?, current: BufferId, lastMessageId: MsgId?, + previous: BufferId?, + currentNetwork: NetworkId, + current: BufferId, + currentServerBuffer: BufferId, + lastMessageId: MsgId?, bufferSyncer: BufferSyncer ) { if (previous != null && lastMessageId != null) { @@ -542,7 +582,13 @@ class MessageListFragment : ServiceBoundFragment() { current, accountDatabase.accounts().findById(accountId)?.defaultFiltered ?: 0) - val hasVisibleMessages = database.message().hasVisibleMessages(current, filtered) + val hasVisibleMessages = database.message().hasVisibleMessages(currentNetwork, + currentServerBuffer, + current, + filtered, + redirectionSettings.userNotices, + redirectionSettings.serverNotices, + redirectionSettings.errors) if (!hasVisibleMessages) { if (current.isValidId() && current != BufferId.MAX_VALUE) { loadMore(initial = true) diff --git a/app/src/main/res/values/strings_preferences.xml b/app/src/main/res/values/strings_preferences.xml index 63c59b008ab734b5459db4a36a476f88401760a8..cbd5b4766e3d6cd112e867280b677a018d39d59e 100644 --- a/app/src/main/res/values/strings_preferences.xml +++ b/app/src/main/res/values/strings_preferences.xml @@ -118,6 +118,21 @@ </string-array> + <string name="preference_redirection_title">Message Redirection</string> + + <string name="preference_redirection_user_notices_key" translatable="false">redirection_user_notices</string> + <string name="preference_redirection_user_notices_title">Redirect User Notices</string> + <string name="preference_redirection_user_notices_summary">Displays user notices in the currently open channel</string> + + <string name="preference_redirection_server_notices_key" translatable="false">redirection_user_notices</string> + <string name="preference_redirection_server_notices_title">Redirect Server Notices</string> + <string name="preference_redirection_server_notices_summary">Displays server notices in the currently open channel</string> + + <string name="preference_redirection_errors_key" translatable="false">redirection_errors</string> + <string name="preference_redirection_errors_title">Redirect Errors</string> + <string name="preference_redirection_errors_summary">Displays errors in the currently open channel</string> + + <string name="preference_notifications_title">Notifications</string> <string name="preference_notification_query_key" translatable="false">notification_query</string> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 8a34ddbf60a407c8c8af4608824b47be92f90479..00fa6b304e859ad4edddd8c362c53446610b74f6 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -62,6 +62,25 @@ android:title="@string/preference_language_title" /> </PreferenceCategory> + <PreferenceCategory android:layout="@layout/widget_preference_divider" /> + <PreferenceCategory android:title="@string/preference_redirection_title"> + <SwitchPreference + android:defaultValue="true" + android:key="@string/preference_redirection_user_notices_key" + android:summary="@string/preference_redirection_user_notices_summary" + android:title="@string/preference_redirection_user_notices_title" /> + <SwitchPreference + android:defaultValue="true" + android:key="@string/preference_redirection_server_notices_key" + android:summary="@string/preference_redirection_server_notices_summary" + android:title="@string/preference_redirection_server_notices_title" /> + <SwitchPreference + android:defaultValue="false" + android:key="@string/preference_redirection_errors_key" + android:summary="@string/preference_redirection_errors_summary" + android:title="@string/preference_redirection_errors_title" /> + </PreferenceCategory> + <PreferenceCategory android:layout="@layout/widget_preference_divider" /> <PreferenceCategory android:title="@string/preference_notifications_title"> diff --git a/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt b/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt index 00503a7df742e0d15712e31a96c671a4c9828590..1cb8198ca029cdd28dd7ff062eee7f0d83b0d395 100644 --- a/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt +++ b/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt @@ -37,6 +37,7 @@ class AvatarHelperTest { flag = Message_Flag.of(), bufferId = BufferId(0), networkId = NetworkId(0), + currentBufferId = BufferId(0), sender = "justJanne", senderPrefixes = "", realName = "Janne Mareike Koschinski <janne@kuschku.de>", @@ -77,6 +78,7 @@ class AvatarHelperTest { flag = Message_Flag.of(), bufferId = BufferId(0), networkId = NetworkId(0), + currentBufferId = BufferId(0), sender = "jwheare!sid2@irccloud.com", senderPrefixes = "", realName = "James Wheare", @@ -117,6 +119,7 @@ class AvatarHelperTest { flag = Message_Flag.of(), bufferId = BufferId(0), networkId = NetworkId(0), + currentBufferId = BufferId(0), sender = "jwheare!sid2@irccloud.com", senderPrefixes = "", realName = "James Wheare", diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/MessageDao.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/MessageDao.kt index 354ea693e67778e533bd918dcd83bbcbd17e77d4..a28e46b587873ee509f6f005fa2cc76ffd3d3243 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/MessageDao.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/MessageDao.kt @@ -26,10 +26,7 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import de.kuschku.libquassel.protocol.BufferId -import de.kuschku.libquassel.protocol.BufferId_Type -import de.kuschku.libquassel.protocol.MsgId -import de.kuschku.libquassel.protocol.MsgId_Type +import de.kuschku.libquassel.protocol.* import de.kuschku.quasseldroid.persistence.models.MessageData import io.reactivex.Flowable @@ -47,9 +44,11 @@ interface MessageDao { @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId ASC") fun _findByBufferId(bufferId: BufferId_Type): List<MessageData> - @Query("SELECT * FROM message WHERE bufferId = :bufferId AND type & ~ :type > 0 AND ignored = 0 ORDER BY messageId DESC") - fun _findByBufferIdPaged(bufferId: BufferId_Type, - type: Int): DataSource.Factory<Int, MessageData> + @Query("SELECT * FROM message WHERE (bufferId = :bufferId AND type & ~ :type > 0 AND ignored = 0) OR (networkId = :networkId AND type & 2 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showUserNotices != 0) OR (bufferId = :serverBufferId AND type & 2 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showServerNotices != 0) OR (bufferId = :serverBufferId AND type & 4096 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showErrors != 0) ORDER BY messageId DESC") + fun _findByBufferIdPaged(networkId: NetworkId_Type, serverBufferId: BufferId_Type, + bufferId: BufferId_Type, type: Int, + showUserNotices: Boolean, showServerNotices: Boolean, + showErrors: Boolean): DataSource.Factory<Int, MessageData> @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId DESC LIMIT 1") fun _findLastByBufferId(bufferId: BufferId_Type): MessageData? @@ -60,14 +59,20 @@ interface MessageDao { @Query("SELECT messageId FROM message WHERE bufferId = :bufferId ORDER BY messageId ASC LIMIT 1") fun _firstMsgId(bufferId: BufferId_Type): Flowable<MsgId_Type> - @Query("SELECT messageId FROM message WHERE bufferId = :bufferId AND type & ~ :type > 0 AND ignored = 0 ORDER BY messageId ASC LIMIT 1") - fun _firstVisibleMsgId(bufferId: BufferId_Type, type: Int): MsgId_Type? + @Query("SELECT messageId FROM message WHERE (bufferId = :bufferId AND type & ~ :type > 0 AND ignored = 0) OR (networkId = :networkId AND type & 2 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showUserNotices != 0) OR (bufferId = :serverBufferId AND type & 2 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showServerNotices != 0) OR (bufferId = :serverBufferId AND type & 4096 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showErrors != 0) ORDER BY messageId ASC LIMIT 1") + fun _firstVisibleMsgId(networkId: NetworkId_Type, serverBufferId: BufferId_Type, + bufferId: BufferId_Type, type: Int, + showUserNotices: Boolean, showServerNotices: Boolean, + showErrors: Boolean): MsgId_Type? @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId ASC LIMIT 1") fun _findFirstByBufferId(bufferId: BufferId_Type): MessageData? - @Query("SELECT EXISTS(SELECT 1 FROM message WHERE bufferId = :bufferId AND type & ~ :type > 0 AND ignored = 0)") - fun _hasVisibleMessages(bufferId: BufferId_Type, type: Int): Boolean + @Query("SELECT EXISTS(SELECT 1 FROM message WHERE (bufferId = :bufferId AND type & ~ :type > 0 AND ignored = 0) OR (networkId = :networkId AND type & 2 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showUserNotices != 0) OR (bufferId = :serverBufferId AND type & 2 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showServerNotices != 0) OR (bufferId = :serverBufferId AND type & 4096 > 0 AND ignored = 0 AND currentBufferId = :bufferId AND :showErrors != 0))") + fun _hasVisibleMessages(networkId: NetworkId_Type, serverBufferId: BufferId_Type, + bufferId: BufferId_Type, type: Int, + showUserNotices: Boolean, showServerNotices: Boolean, + showErrors: Boolean): Boolean @Insert(onConflict = OnConflictStrategy.REPLACE) fun save(vararg entities: MessageData) @@ -96,8 +101,16 @@ inline fun MessageDao.buffers() = inline fun MessageDao.findByBufferId(bufferId: BufferId) = _findByBufferId(bufferId.id) -inline fun MessageDao.findByBufferIdPaged(bufferId: BufferId, type: Int) = - _findByBufferIdPaged(bufferId.id, type) +inline fun MessageDao.findByBufferIdPaged(networkId: NetworkId, serverBufferId: BufferId, + bufferId: BufferId, type: Int, showServerNotices: Boolean, + showUserNotices: Boolean, showErrors: Boolean) = + _findByBufferIdPaged(networkId.id, + serverBufferId.id, + bufferId.id, + type, + showServerNotices, + showUserNotices, + showErrors) inline fun MessageDao.findLastByBufferId(bufferId: BufferId) = _findLastByBufferId(bufferId.id) @@ -108,14 +121,30 @@ inline fun MessageDao.lastMsgId(bufferId: BufferId) = inline fun MessageDao.firstMsgId(bufferId: BufferId) = _firstMsgId(bufferId.id).map(::MsgId) -inline fun MessageDao.firstVisibleMsgId(bufferId: BufferId, type: Int) = - _firstVisibleMsgId(bufferId.id, type)?.let(::MsgId) +inline fun MessageDao.firstVisibleMsgId(networkId: NetworkId, serverBufferId: BufferId, + bufferId: BufferId, type: Int, showUserNotices: Boolean, + showServerNotices: Boolean, showErrors: Boolean) = + _firstVisibleMsgId(networkId.id, + serverBufferId.id, + bufferId.id, + type, + showUserNotices, + showServerNotices, + showErrors)?.let(::MsgId) inline fun MessageDao.findFirstByBufferId(bufferId: BufferId) = _findFirstByBufferId(bufferId.id) -inline fun MessageDao.hasVisibleMessages(bufferId: BufferId, type: Int) = - _hasVisibleMessages(bufferId.id, type) +inline fun MessageDao.hasVisibleMessages(networkId: NetworkId, serverBufferId: BufferId, + bufferId: BufferId, type: Int, showUserNotices: Boolean, + showServerNotices: Boolean, showErrors: Boolean) = + _hasVisibleMessages(networkId.id, + serverBufferId.id, + bufferId.id, + type, + showUserNotices, + showServerNotices, + showErrors) inline fun MessageDao.merge(bufferId1: BufferId, bufferId2: BufferId) = _merge(bufferId1.id, bufferId2.id) diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/db/QuasselDatabase.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/db/QuasselDatabase.kt index 436127c53cddba913fe881500c95f7135d8b7e85..3fe069ad214377f9dc7aeb6adab6d0465cd43db6 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/db/QuasselDatabase.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/db/QuasselDatabase.kt @@ -30,7 +30,7 @@ import de.kuschku.quasseldroid.persistence.models.* import de.kuschku.quasseldroid.persistence.util.MessageTypeConverter @Database(entities = [MessageData::class, Filtered::class, SslValidityWhitelistEntry::class, SslHostnameWhitelistEntry::class, NotificationData::class], - version = 19) + version = 20) @TypeConverters(MessageTypeConverter::class) abstract class QuasselDatabase : RoomDatabase() { abstract fun message(): MessageDao @@ -157,6 +157,13 @@ abstract class QuasselDatabase : RoomDatabase() { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE `notification` ADD `networkName` TEXT DEFAULT '' NOT NULL;") } + }, + object : Migration(19, 20) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE message ADD currentBufferId INT DEFAULT 0 NOT NULL;") + database.execSQL("CREATE INDEX index_message_currentBufferId ON message(currentBufferId);") + database.execSQL("CREATE INDEX index_message_networkId ON message(networkId);") + } } ).build() } diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/MessageData.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/MessageData.kt index 9587202562073935d4dbc6838536e146c2a6e040..292aacbb47906d54873cf32728d1ba49915a21e8 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/MessageData.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/MessageData.kt @@ -28,7 +28,7 @@ import de.kuschku.libquassel.protocol.* import org.threeten.bp.Instant import java.io.Serializable -@Entity(tableName = "message", indices = [Index("bufferId"), Index("ignored")]) +@Entity(tableName = "message", indices = [Index("bufferId"), Index("ignored"), Index("currentBufferId"), Index("networkId")]) data class MessageData( @PrimaryKey @ColumnInfo(name = "messageId") @@ -38,6 +38,8 @@ data class MessageData( var flag: Message_Flags, @ColumnInfo(name = "bufferId") var rawBufferId: BufferId_Type, + @ColumnInfo(name = "currentBufferId") + var rawCurrentBufferId: BufferId_Type, @ColumnInfo(name = "networkId") var rawNetworkId: NetworkId_Type, var sender: String, @@ -51,6 +53,8 @@ data class MessageData( get() = MsgId(rawMessageId) inline val bufferId get() = BufferId(rawBufferId) + inline val currentBufferId + get() = BufferId(rawCurrentBufferId) inline val networkId get() = NetworkId(rawNetworkId) @@ -62,6 +66,7 @@ data class MessageData( flag: Message_Flags, bufferId: BufferId, networkId: NetworkId, + currentBufferId: BufferId, sender: String, senderPrefixes: String, realName: String, @@ -74,6 +79,7 @@ data class MessageData( type, flag, bufferId.id, + currentBufferId.id, networkId.id, sender, senderPrefixes, diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt index 6dd1c83371d293d0e5990e3e2eef005ce9a38072..ad9d468607a5cb6dece769ba06bb7e9707e0d53b 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt @@ -27,8 +27,11 @@ import de.kuschku.libquassel.session.BacklogStorage import de.kuschku.libquassel.session.ISession import de.kuschku.quasseldroid.persistence.db.QuasselDatabase import de.kuschku.quasseldroid.persistence.models.MessageData +import io.reactivex.subjects.BehaviorSubject class QuasselBacklogStorage(private val db: QuasselDatabase) : BacklogStorage { + val currentBuffer = BehaviorSubject.createDefault(BufferId(0)) + override fun updateIgnoreRules(session: ISession) { db.message().save( *db.message().all().map { @@ -50,15 +53,14 @@ class QuasselBacklogStorage(private val db: QuasselDatabase) : BacklogStorage { type = it.type, flag = it.flag, bufferId = it.bufferInfo.bufferId, + currentBufferId = currentBuffer.value, networkId = it.bufferInfo.networkId, sender = it.sender, senderPrefixes = it.senderPrefixes, realName = it.realName, avatarUrl = it.avatarUrl, content = it.content, - ignored = isIgnored( - session, - it) + ignored = isIgnored(session, it) ) }.toTypedArray()) } diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt index 85ee918b94cd0935824bfc2ca2371f1232093ec4..7758cdb0d64e0e1afe5067e7b5f009643ba71502 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/Backend.kt @@ -20,6 +20,7 @@ package de.kuschku.quasseldroid import de.kuschku.libquassel.connection.SocketAddress +import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.session.SessionManager interface Backend { @@ -35,6 +36,8 @@ interface Backend { fun updateUserDataAndLogin(user: String, pass: String) fun requestConnectNewNetwork() + fun setCurrentBuffer(id: BufferId) + data class ConnectionInfo( val address: SocketAddress, val username: String,