From e411ea5a63c41614ef5b0f59ec808d288b4ee861 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Wed, 18 Apr 2018 20:31:46 +0200 Subject: [PATCH] Allow full functionality for joining networks --- .../chat/buffers/BufferViewConfigFragment.kt | 19 ++++- .../quasseldroid/util/ui/SettingsActivity.kt | 4 +- app/src/main/res/menu/context_buffer.xml | 5 +- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../persistence/QuasselDatabase.kt | 36 ++++++++- .../viewmodel/QuasselViewModel.kt | 74 ++++++++++++++++--- 7 files changed, 122 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt index 236aa7b55..dd287dadb 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt @@ -22,6 +22,7 @@ import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.QuasselDatabase import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.MessageSettings +import de.kuschku.quasseldroid.ui.coresettings.network.NetworkEditActivity import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.helper.toLiveData @@ -68,6 +69,13 @@ class BufferViewConfigFragment : ServiceBoundFragment() { return if (info != null && session != null) { when (item?.itemId) { + R.id.action_configure -> { + network?.let { + NetworkEditActivity.launch(requireContext(), network = it.networkId()) + } + actionMode?.finish() + true + } R.id.action_connect -> { network?.requestConnect() actionMode?.finish() @@ -294,6 +302,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { val menu = actionMode?.menu if (menu != null) { val allActions = setOf( + R.id.action_configure, R.id.action_connect, R.id.action_disconnect, R.id.action_join, @@ -323,10 +332,14 @@ class BufferViewConfigFragment : ServiceBoundFragment() { val availableActions = when (buffer.info?.type?.enabledValues()?.firstOrNull()) { Buffer_Type.StatusBuffer -> { when (buffer.connectionState) { - INetwork.ConnectionState.Disconnected -> setOf(R.id.action_connect) - INetwork.ConnectionState.Initialized -> setOf(R.id.action_disconnect) + INetwork.ConnectionState.Disconnected -> setOf( + R.id.action_configure, R.id.action_connect + ) + INetwork.ConnectionState.Initialized -> setOf( + R.id.action_configure, R.id.action_disconnect + ) else -> setOf( - R.id.action_connect, R.id.action_disconnect + R.id.action_configure, R.id.action_connect, R.id.action_disconnect ) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt index 06d18039d..91725f7df 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/SettingsActivity.kt @@ -2,7 +2,6 @@ package de.kuschku.quasseldroid.util.ui import android.os.Bundle import android.support.v4.app.Fragment -import android.support.v4.app.NavUtils import android.support.v7.widget.Toolbar import android.view.MenuItem import butterknife.BindView @@ -68,7 +67,8 @@ abstract class SettingsActivity(private val fragment: Fragment? = null) : Servic if (supportParentActivityIntent == null) { super.onBackPressed() } else { - NavUtils.navigateUpFromSameTask(this) + startActivity(supportParentActivityIntent) + finish() } } true diff --git a/app/src/main/res/menu/context_buffer.xml b/app/src/main/res/menu/context_buffer.xml index 246eb68ef..a5c05a243 100644 --- a/app/src/main/res/menu/context_buffer.xml +++ b/app/src/main/res/menu/context_buffer.xml @@ -1,6 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/action_configure" + android:title="@string/label_configure" /> <item android:id="@+id/action_connect" android:title="@string/label_connect" /> @@ -31,4 +34,4 @@ android:id="@+id/action_hide_perm" android:title="@string/label_hide_perm" app:showAsAction="never" /> -</menu> \ No newline at end of file +</menu> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 09415fbd4..8052c0cc1 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -15,6 +15,7 @@ <string name="label_close">Schließen</string> <string name="label_colors_custom">Anpassen</string> <string name="label_colors_mirc">mIRC</string> + <string name="label_configure">Konfigurieren</string> <string name="label_connect">Verbinden</string> <string name="label_contributors">Mitwirkende</string> <string name="label_copy">Kopieren</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb8bdcf66..1d1d3f458 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,6 +15,7 @@ <string name="label_close">Close</string> <string name="label_colors_custom">Custom</string> <string name="label_colors_mirc">mIRC</string> + <string name="label_configure">Configure</string> <string name="label_connect">Connect</string> <string name="label_contributors">Contributors</string> <string name="label_copy">Copy</string> diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt index 0902d97fe..9ba9c3abf 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/QuasselDatabase.kt @@ -10,16 +10,16 @@ import android.support.annotation.IntRange import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.protocol.MsgId -import de.kuschku.quasseldroid.persistence.QuasselDatabase.DatabaseMessage -import de.kuschku.quasseldroid.persistence.QuasselDatabase.Filtered +import de.kuschku.quasseldroid.persistence.QuasselDatabase.* import io.reactivex.Flowable import org.threeten.bp.Instant -@Database(entities = [DatabaseMessage::class, Filtered::class], version = 8) +@Database(entities = [DatabaseMessage::class, Filtered::class, SslException::class], version = 9) @TypeConverters(DatabaseMessage.MessageTypeConverters::class) abstract class QuasselDatabase : RoomDatabase() { abstract fun message(): MessageDao abstract fun filtered(): FilteredDao + abstract fun sslExceptions(): SslExceptionDao @Entity(tableName = "message", indices = [Index("bufferId"), Index("ignored")]) data class DatabaseMessage( @@ -142,6 +142,31 @@ abstract class QuasselDatabase : RoomDatabase() { fun clear(accountId: Long, bufferId: Int) } + @Entity(tableName = "ssl_exception", primaryKeys = ["accountId", "certificateFingerprint"]) + data class SslException( + var accountId: Long, + var certificateFingerprint: String, + var ignoreValidityDate: Boolean + ) + + @Dao + interface SslExceptionDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun save(vararg entities: SslException) + + @Query("SELECT * FROM ssl_exception WHERE accountId = :accountId AND certificateFingerprint = :certificateFingerprint") + fun all(accountId: Long, certificateFingerprint: String): List<SslException> + + @Query("DELETE FROM ssl_exception") + fun clear() + + @Query("DELETE FROM ssl_exception WHERE accountId = :accountId") + fun clear(accountId: Long) + + @Query("DELETE FROM ssl_exception WHERE accountId = :accountId AND certificateFingerprint = :certificateFingerprint") + fun clear(accountId: Long, certificateFingerprint: String) + } + object Creator { private var database: QuasselDatabase? = null @@ -193,6 +218,11 @@ abstract class QuasselDatabase : RoomDatabase() { database.execSQL("CREATE INDEX index_message_bufferId ON message(bufferId);") database.execSQL("CREATE INDEX index_message_ignored ON message(ignored);") } + }, + object : Migration(8, 9) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("create table ssl_exception (accountId INTEGER not null, certificateFingerprint TEXT not null, ignoreValidityDate INTEGER not null, primary key(accountId, certificateFingerprint));") + } } ).build() } diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt index 8e8e54401..d9a4ce4e9 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt @@ -1,10 +1,7 @@ package de.kuschku.quasseldroid.viewmodel import android.arch.lifecycle.ViewModel -import de.kuschku.libquassel.protocol.BufferId -import de.kuschku.libquassel.protocol.Buffer_Type -import de.kuschku.libquassel.protocol.MsgId -import de.kuschku.libquassel.protocol.NetworkId +import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.IrcChannel @@ -248,7 +245,15 @@ class QuasselViewModel : ViewModel() { BufferHiddenState.VISIBLE } - val info = bufferSyncer.bufferInfo(buffer) + val info = if (buffer < 0) networks[-buffer]?.let { + BufferInfo( + bufferId = buffer, + networkId = it.networkId(), + groupId = 0, + bufferName = it.networkName(), + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + ) + } else bufferSyncer.bufferInfo(buffer) if (info != null) { val network = networks[info.networkId] when (info.type.enabledValues().firstOrNull()) { @@ -308,7 +313,7 @@ class QuasselViewModel : ViewModel() { currentConfig.networkId() <= 0 || currentConfig.networkId() == it.networkId }.filter { (currentConfig.allowedBufferTypes() and it.type).isNotEmpty() || - it.type.hasFlag(Buffer_Type.StatusBuffer) + (it.type.hasFlag(Buffer_Type.StatusBuffer) && currentConfig.networkId() < 0) }.mapNotNull { val network = networks[it.networkId] if (network == null) { @@ -396,13 +401,62 @@ class QuasselViewModel : ViewModel() { } } + fun missingStatusBuffers( + list: Collection<BufferId>): Sequence<Observable<BufferProps>?> { + val totalNetworks = networks.keys + val wantedNetworks = if (currentConfig.networkId() <= 0) totalNetworks + else listOf(currentConfig.networkId()) + + val availableNetworks = list.asSequence().mapNotNull { id -> + bufferSyncer.bufferInfo(id) + }.filter { + it.type.hasFlag(Buffer_Type.StatusBuffer) + }.map { + it.networkId + } + + val missingNetworks = wantedNetworks - availableNetworks + + return missingNetworks.asSequence().filter { + currentConfig.networkId() <= 0 || currentConfig.networkId() == it + }.filter { + currentConfig.allowedBufferTypes().hasFlag(Buffer_Type.StatusBuffer) + }.mapNotNull { + networks[it] + }.filter { + !config.hideInactiveNetworks() || it.isConnected() + }.map<Network, Observable<BufferProps>?> { network -> + network.liveNetworkInfo().switchMap { networkInfo -> + network.live_connectionState.map { + BufferProps( + info = BufferInfo( + bufferId = -networkInfo.networkId, + networkId = networkInfo.networkId, + groupId = 0, + bufferName = networkInfo.networkName, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + ), + network = networkInfo, + bufferStatus = BufferStatus.OFFLINE, + description = "", + activity = Message_Type.of(), + highlights = 0, + hiddenState = BufferHiddenState.VISIBLE + ) + } + } + } + } + bufferSyncer.liveBufferInfos().switchMap { val buffers = if (showHidden) { transformIds(ids, BufferHiddenState.VISIBLE) + transformIds(temp - ids, BufferHiddenState.HIDDEN_TEMPORARY) + - transformIds(perm - temp - ids, BufferHiddenState.HIDDEN_PERMANENT) + transformIds(perm - temp - ids, BufferHiddenState.HIDDEN_PERMANENT) + + missingStatusBuffers(ids + temp + perm) } else { - transformIds(ids.distinct(), BufferHiddenState.VISIBLE) + transformIds(ids, BufferHiddenState.VISIBLE) + + missingStatusBuffers(ids) } combineLatest<BufferProps>(buffers.toList()).map { list -> @@ -417,7 +471,9 @@ class QuasselViewModel : ViewModel() { it.sortedBy { IrcCaseMappers.unicode.toLowerCaseNullable(it.info.bufferName) } .sortedByDescending { it.hiddenState == BufferHiddenState.VISIBLE } else it - }.distinctBy { it.info.bufferId }.toList() + }.distinctBy { + it.info.bufferId + }.toList() ) } } -- GitLab