diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bad294e320af8e5fee73f28fe58ce5c59f685b26..aab8c846f4f45607c74a4b7a142efda604ab3e71 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -38,7 +38,7 @@ android { } defaultConfig { - minSdkVersion(16) + minSdkVersion(20) targetSdkVersion(28) applicationId = "com.iskrembilen.quasseldroid" @@ -69,7 +69,6 @@ android { isZipAlignEnabled = true isMinifyEnabled = true isShrinkResources = true - isUseProguard = false multiDexEnabled = false @@ -99,38 +98,42 @@ android { isWarningsAsErrors = true setLintConfig(file("../lint.xml")) } + + viewBinding { + isEnabled = true + } } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) // App Compat implementation("com.google.android.material", "material", "1.1.0-alpha10") implementation("androidx.appcompat", "appcompat", "1.1.0") - implementation("androidx.browser", "browser", "1.2.0-alpha07") + implementation("androidx.browser", "browser", "1.2.0") implementation("androidx.cardview", "cardview", "1.0.0") - implementation("androidx.recyclerview", "recyclerview", "1.1.0-beta04") - implementation("androidx.swiperefreshlayout", "swiperefreshlayout", "1.1.0-alpha02") - implementation("androidx.preference", "preference", "1.0.0") + implementation("androidx.recyclerview", "recyclerview", "1.1.0") + implementation("androidx.swiperefreshlayout", "swiperefreshlayout", "1.1.0-beta01") + implementation("androidx.preference", "preference", "1.1.0") // Only needed for ringtone preference implementation("androidx.legacy", "legacy-preference-v14", "1.0.0") - implementation("androidx.constraintlayout", "constraintlayout", "2.0.0-beta1") + implementation("androidx.constraintlayout", "constraintlayout", "2.0.0-beta4") - withVersion("2.2.0-rc01") { + withVersion("2.2.5") { implementation("androidx.room", "room-runtime", version) kapt("androidx.room", "room-compiler", version) implementation("androidx.room", "room-rxjava2", version) testImplementation("androidx.room", "room-testing", version) } - withVersion("2.1.0") { + withVersion("2.2.0") { implementation("androidx.lifecycle", "lifecycle-extensions", version) implementation("androidx.lifecycle", "lifecycle-reactivestreams", version) } testImplementation("androidx.arch.core", "core-testing", "2.1.0") implementation(project(":lifecycle-ktx")) - implementation("androidx.paging", "paging-runtime", "2.1.0") + implementation("androidx.paging", "paging-runtime", "2.1.2") implementation("androidx.multidex", "multidex", "2.0.1") diff --git a/app/src/main/java/de/kuschku/quasseldroid/app/QuasseldroidReleaseDelegate.kt b/app/src/main/java/de/kuschku/quasseldroid/app/QuasseldroidReleaseDelegate.kt index a8a34ca2119a9c4df6200302b6be975188ea4842..612a8e22ad2d970342d2c077a9f65ed42e1093e3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/app/QuasseldroidReleaseDelegate.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/app/QuasseldroidReleaseDelegate.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -26,9 +26,11 @@ import de.kuschku.malheur.CrashHandler import de.kuschku.quasseldroid.BuildConfig import de.kuschku.quasseldroid.Quasseldroid import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.dao.create import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.LegacyAccountDatabase import de.kuschku.quasseldroid.persistence.models.Account +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.SettingsMigration import de.kuschku.quasseldroid.settings.SettingsMigrationManager @@ -53,8 +55,8 @@ class QuasseldroidReleaseDelegate(private val app: Quasseldroid) : QuasseldroidB val accountDatabase = AccountDatabase.Creator.init(app) accountDatabase.accounts().create(*accounts.map { - Account( - id = it.id, + Account.of( + id = AccountId(it.id), host = it.host, port = it.port, user = it.user, diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt b/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt index 9f33cdc3dafbe47d9a9ecdcc29d90e73408e440a..38215a15d45b7ce83e0a6f1ec96325e14199387e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/BacklogRequester.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -27,10 +27,12 @@ import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG import de.kuschku.libquassel.util.helper.value +import de.kuschku.quasseldroid.persistence.dao.findById import de.kuschku.quasseldroid.persistence.dao.findFirstByBufferId import de.kuschku.quasseldroid.persistence.dao.get import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.persistence.util.QuasselBacklogStorage import io.reactivex.Observable @@ -39,7 +41,7 @@ class BacklogRequester( private val database: QuasselDatabase, private val accountDatabase: AccountDatabase ) { - fun loadMore(accountId: Long, buffer: BufferId, amount: Int, pageSize: Int, + fun loadMore(accountId: AccountId, buffer: BufferId, amount: Int, pageSize: Int, lastMessageId: MsgId? = null, untilAllVisible: Boolean = false, finishCallback: () -> Unit) { @@ -49,10 +51,11 @@ class BacklogRequester( var missing = amount session.value?.orNull()?.let { session: ISession -> session.backlogManager.let { - val filtered = database.filtered().get(accountId, - buffer, - accountDatabase.accounts().findById(accountId)?.defaultFiltered - ?: 0) + val filtered = database.filtered().get( + accountId, + buffer, + accountDatabase.accounts().findById(accountId)?.defaultFiltered ?: 0 + ) it.requestBacklog( bufferId = buffer, last = lastMessageId 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 0b5a021a731f8da91f7928e4b8754d39c40bc21f..9ae2298125159bce4bb62ccc8d2531c35990cc91 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -48,12 +48,10 @@ import de.kuschku.quasseldroid.BuildConfig import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.Defaults -import de.kuschku.quasseldroid.persistence.dao.buffers -import de.kuschku.quasseldroid.persistence.dao.clear -import de.kuschku.quasseldroid.persistence.dao.markHidden -import de.kuschku.quasseldroid.persistence.dao.markReadNormal +import de.kuschku.quasseldroid.persistence.dao.* import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.persistence.util.QuasselBacklogStorage import de.kuschku.quasseldroid.settings.ConnectionSettings import de.kuschku.quasseldroid.settings.NotificationSettings @@ -99,7 +97,7 @@ class QuasselService : DaggerLifecycleService(), val (accountId, reconnect) = this.sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) { Pair( - getLong(Keys.Status.selectedAccount, -1), + AccountId(getLong(Keys.Status.selectedAccount, -1)), getBoolean(Keys.Status.reconnect, false) ) } @@ -108,7 +106,7 @@ class QuasselService : DaggerLifecycleService(), this.reconnect = reconnect handlerService.backend { - val account = if (accountId != -1L && reconnect) { + val account = if (accountId.isValidId() && reconnect) { accountDatabase.accounts().findById(accountId) } else { null @@ -129,7 +127,7 @@ class QuasselService : DaggerLifecycleService(), ) } } - } else if (accountId == -1L || !reconnect) { + } else if (!accountId.isValidId() || !reconnect) { handlerService.backend { backendImplementation.disconnect(true) stopSelf() @@ -137,12 +135,12 @@ class QuasselService : DaggerLifecycleService(), } } - private var accountId: Long = -1 + private var accountId: AccountId = AccountId(-1) set(value) { field = value liveAccountId.onNext(value) } - private var liveAccountId = BehaviorSubject.createDefault(-1L) + private var liveAccountId = BehaviorSubject.createDefault(AccountId(-1L)) private var reconnect: Boolean = false @Inject @@ -169,13 +167,15 @@ class QuasselService : DaggerLifecycleService(), } } - override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val result = super.onStartCommand(intent, flags, startId) handleIntent(intent) return result } - private fun handleIntent(intent: Intent) { + private fun handleIntent(intent: Intent?) { + if (intent == null) return + if (intent.getBooleanExtra("disconnect", false)) { sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) { editApply { @@ -493,7 +493,7 @@ class QuasselService : DaggerLifecycleService(), super.onDestroy() } - override fun onBind(intent: Intent): QuasselBinder { + override fun onBind(intent: Intent?): QuasselBinder { super.onBind(intent) return QuasselBinder(asyncBackend) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt index c3df0ced20f64ce99f30906957fee068d32546a1..5ee29db9ac3813498e54133b3dcd8a2742c9ea05 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -65,14 +65,13 @@ import de.kuschku.libquassel.util.helper.* import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.defaults.DefaultNetworkServer -import de.kuschku.quasseldroid.persistence.dao.clear -import de.kuschku.quasseldroid.persistence.dao.get -import de.kuschku.quasseldroid.persistence.dao.setFiltered +import de.kuschku.quasseldroid.persistence.dao.* import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase import de.kuschku.quasseldroid.persistence.models.Filtered import de.kuschku.quasseldroid.persistence.models.SslHostnameWhitelistEntry import de.kuschku.quasseldroid.persistence.models.SslValidityWhitelistEntry +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.settings.NotificationSettings @@ -163,7 +162,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc private var chatlineFragment: ChatlineFragment? = null - private var connectedAccount = -1L + private var connectedAccount = AccountId(-1L) private var restoredDrawerState = false @@ -182,12 +181,12 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc chatViewModel.bufferId.onNext(BufferId(intent.getIntExtra(KEY_BUFFER_ID, -1))) chatViewModel.bufferOpened.onNext(Unit) if (intent.hasExtra(KEY_ACCOUNT_ID)) { - val accountId = intent.getLongExtra(ChatActivity.KEY_ACCOUNT_ID, -1) + val accountId = AccountId(intent.getLongExtra(KEY_ACCOUNT_ID, -1L)) if (accountId != this.accountId) { resetAccount() connectToAccount(accountId) startedSelection = false - connectedAccount = -1L + connectedAccount = AccountId(-1L) checkConnection() recreate() } @@ -848,18 +847,17 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc editorBottomSheet.state = BottomSheetBehavior.STATE_COLLAPSED chatlineFragment?.panelSlideListener?.let(editorBottomSheet::setBottomSheetCallback) - chatlineFragment?.historyBottomSheet?.setBottomSheetCallback( - object : BottomSheetBehavior.BottomSheetCallback() { - override fun onSlide(bottomSheet: View, slideOffset: Float) { - val opacity = (1.0f - slideOffset) / 2.0f - chatlineFragment?.editorContainer?.alpha = opacity - } + chatlineFragment?.historyBottomSheet?.bottomSheetCallback = object : + BottomSheetBehavior.BottomSheetCallback() { + override fun onSlide(bottomSheet: View, slideOffset: Float) { + val opacity = (1.0f - slideOffset) / 2.0f + chatlineFragment?.editorContainer?.alpha = opacity + } - override fun onStateChanged(bottomSheet: View, newState: Int) { - editorBottomSheet.allowDragging = newState == BottomSheetBehavior.STATE_HIDDEN - } + override fun onStateChanged(bottomSheet: View, newState: Int) { + editorBottomSheet.allowDragging = newState == BottomSheetBehavior.STATE_HIDDEN } - ) + } combineLatest(modelHelper.allBuffers, modelHelper.chat.chatToJoin).map { (buffers, chatToJoinOptional) -> @@ -933,7 +931,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc super.onSaveInstanceState(outState) chatViewModel.onSaveInstanceState(outState) - outState.putLong(KEY_CONNECTED_ACCOUNT, connectedAccount) + outState.putLong(KEY_CONNECTED_ACCOUNT, connectedAccount.id) outState.putBoolean(KEY_OPEN_DRAWER_START, drawerLayout.isDrawerOpen(GravityCompat.START)) outState.putBoolean(KEY_OPEN_DRAWER_END, drawerLayout.isDrawerOpen(GravityCompat.END)) } @@ -944,7 +942,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc chatViewModel.onRestoreInstanceState(savedInstanceState) } - connectedAccount = savedInstanceState?.getLong(KEY_CONNECTED_ACCOUNT, -1L) ?: -1L + connectedAccount = AccountId(savedInstanceState?.getLong(KEY_CONNECTED_ACCOUNT, -1L) ?: -1L) if (savedInstanceState?.getBoolean(KEY_OPEN_DRAWER_START) == true && resources.getBoolean(R.bool.buffer_drawer_exists)) { @@ -1108,7 +1106,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc if (requestCode == REQUEST_SELECT_ACCOUNT) { startedSelection = false - connectedAccount = -1L + connectedAccount = AccountId(-1L) if (resultCode == Activity.RESULT_CANCELED) { finish() @@ -1118,7 +1116,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc private fun resetAccount() { startedSelection = true - connectedAccount = -1L + connectedAccount = AccountId(-1L) restoredDrawerState = false ChatActivity.launch(this, bufferId = BufferId.MAX_VALUE) chatViewModel.resetAccount() diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/NetworkAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/NetworkAdapter.kt index 8cfcd6157ae9bcfcdd87d20faadf597d5a915b52..27ecf649507e7cfb654a07a7316086797f35cbfb 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/NetworkAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/NetworkAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.chat.add import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.NetworkId -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -59,8 +55,7 @@ class NetworkAdapter : RecyclerSpinnerAdapter<NetworkAdapter.NetworkViewHolder>( else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) - return NetworkViewHolder(view) + return NetworkViewHolder(WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false)) } fun indexOf(id: NetworkId): Int? { @@ -76,17 +71,11 @@ class NetworkAdapter : RecyclerSpinnerAdapter<NetworkAdapter.NetworkViewHolder>( override fun getItemId(position: Int) = getItem(position)?.id?.id?.toLong() ?: 0L override fun hasStableIds() = true override fun getCount() = data.size - class NetworkViewHolder(itemView: View) : - RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class NetworkViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(network: NetworkItem) { - text.text = network.name + binding.text1.text = network.name } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt index 51871d359da83065f87faa631f86efdc981c7d01..2178edf34702d20f866e1531f8e3b0cb1a2ba45d 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -33,6 +33,8 @@ import de.kuschku.libquassel.util.helper.combineLatest import de.kuschku.libquassel.util.helper.safeValue import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.dao.listenDefaultFiltered +import de.kuschku.quasseldroid.persistence.dao.listenRx import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase import de.kuschku.quasseldroid.persistence.models.Filtered @@ -164,11 +166,11 @@ class ArchiveFragment : ServiceBoundFragment() { content = getString(R.string.label_permanently_archived_empty) )) } - }.toLiveData().observe(this, Observer { processedList -> + }.toLiveData().observe(viewLifecycleOwner, Observer { processedList -> listAdapter.submitList(processedList) }) - modelHelper.selectedBuffer.toLiveData().observe(this, Observer { buffer -> + modelHelper.selectedBuffer.toLiveData().observe(viewLifecycleOwner, Observer { buffer -> actionMode?.let { BufferContextPresenter.present(it, buffer) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt index 96ec44e92f18971cafe442f87fca8898847e7378..eba0b698ea57c2457bd73e2daea3d4d36fd49e85 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -24,17 +24,17 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.helper.safeValue import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetArchivePlaceholderBinding +import de.kuschku.quasseldroid.databinding.WidgetBufferBinding +import de.kuschku.quasseldroid.databinding.WidgetHeaderBinding +import de.kuschku.quasseldroid.databinding.WidgetNetworkBinding import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.lists.ListAdapter @@ -112,45 +112,32 @@ class ArchiveListAdapter( val viewType = ViewType(viewType.toUInt()) return when (viewType.type) { ArchiveListItem.Type.HEADER -> ArchiveViewHolder.HeaderViewHolder( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_header, parent, false - ) + WidgetHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) ArchiveListItem.Type.PLACEHOLDER -> ArchiveViewHolder.PlaceholderViewHolder( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_archive_placeholder, parent, false - ) + WidgetArchivePlaceholderBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) ArchiveListItem.Type.BUFFER -> when (viewType.bufferType?.enabledValues()?.firstOrNull()) { BufferInfo.Type.ChannelBuffer -> ArchiveViewHolder.BufferViewHolder.ChannelBuffer( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_buffer, parent, false - ), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, dragListener = dragListener ) BufferInfo.Type.QueryBuffer -> ArchiveViewHolder.BufferViewHolder.QueryBuffer( - LayoutInflater.from(parent.context).inflate( - if (viewType.bufferStatus == BufferStatus.AWAY) R.layout.widget_buffer_away - else R.layout.widget_buffer, parent, false - ), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, dragListener = dragListener ) BufferInfo.Type.GroupBuffer -> ArchiveViewHolder.BufferViewHolder.GroupBuffer( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_buffer, parent, false - ), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, dragListener = dragListener ) BufferInfo.Type.StatusBuffer -> ArchiveViewHolder.BufferViewHolder.StatusBuffer( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_network, parent, false - ), + WidgetNetworkBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, expansionListener = ::expandListener @@ -204,36 +191,19 @@ class ArchiveListAdapter( sealed class ArchiveViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class HeaderViewHolder( - itemView: View - ) : ArchiveViewHolder(itemView) { - @BindView(R.id.title) - lateinit var title: TextView - - @BindView(R.id.content) - lateinit var content: TextView - - init { - ButterKnife.bind(this, itemView) - } - + private val binding: WidgetHeaderBinding + ) : ArchiveViewHolder(binding.root) { fun bind(item: ArchiveListItem.Header) { - title.text = item.title - content.text = item.content + binding.title.text = item.title + binding.content.text = item.content } } class PlaceholderViewHolder( - itemView: View - ) : ArchiveViewHolder(itemView) { - @BindView(R.id.content) - lateinit var content: TextView - - init { - ButterKnife.bind(this, itemView) - } - + private val binding: WidgetArchivePlaceholderBinding + ) : ArchiveViewHolder(binding.root) { fun bind(item: ArchiveListItem.Placeholder) { - content.text = item.content + binding.content.text = item.content } } @@ -241,17 +211,11 @@ class ArchiveListAdapter( abstract fun bind(item: BufferListItem, messageSettings: MessageSettings) class StatusBuffer( - itemView: View, + private val binding: WidgetNetworkBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val expansionListener: ((NetworkId, Boolean) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null var networkId: NetworkId? = null @@ -263,7 +227,6 @@ class ArchiveListAdapter( private var expanded: Boolean = false init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -280,7 +243,7 @@ class ArchiveListAdapter( } } - status.setOnClickListener { + binding.status.setOnClickListener { val network = networkId if (network != null) expansionListener?.invoke(network, !expanded) @@ -298,11 +261,11 @@ class ArchiveListAdapter( } override fun bind(item: BufferListItem, messageSettings: MessageSettings) { - name.text = item.props.name + binding.name.text = item.props.name bufferId = item.props.info.bufferId networkId = item.props.info.networkId - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -316,31 +279,19 @@ class ArchiveListAdapter( itemView.isSelected = item.state.selected if (item.state.networkExpanded) { - status.setImageResource(R.drawable.ic_chevron_up) + binding.status.setImageResource(R.drawable.ic_chevron_up) } else { - status.setImageResource(R.drawable.ic_chevron_down) + binding.status.setImageResource(R.drawable.ic_chevron_down) } } } class GroupBuffer( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val dragListener: ((BufferViewHolder) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null private val online: Drawable? @@ -352,7 +303,6 @@ class ArchiveListAdapter( private var highlight: Int = 0 init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -369,7 +319,7 @@ class ArchiveListAdapter( } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -397,10 +347,10 @@ class ArchiveListAdapter( override fun bind(item: BufferListItem, messageSettings: MessageSettings) { bufferId = item.props.info.bufferId - name.text = item.props.name - description.text = item.props.description + binding.name.text = item.props.name + binding.description.text = item.props.description - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -411,11 +361,11 @@ class ArchiveListAdapter( itemView.isSelected = item.state.selected - handle.visibleIf(item.state.showHandle) + binding.handle.visibleIf(item.state.showHandle) - description.visibleIf(item.props.description.isNotBlank()) + binding.description.visibleIf(item.props.description.isNotBlank()) - status.setImageDrawable( + binding.status.setImageDrawable( when (item.props.bufferStatus) { BufferStatus.ONLINE -> online else -> offline @@ -425,23 +375,11 @@ class ArchiveListAdapter( } class ChannelBuffer( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val dragListener: ((BufferViewHolder) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null private var none: Int = 0 @@ -450,7 +388,6 @@ class ArchiveListAdapter( private var highlight: Int = 0 init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -467,7 +404,7 @@ class ArchiveListAdapter( } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -488,10 +425,10 @@ class ArchiveListAdapter( override fun bind(item: BufferListItem, messageSettings: MessageSettings) { bufferId = item.props.info.bufferId - name.text = item.props.name - description.text = item.props.description + binding.name.text = item.props.name + binding.description.text = item.props.description - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -502,32 +439,20 @@ class ArchiveListAdapter( itemView.isSelected = item.state.selected - handle.visibleIf(item.state.showHandle) + binding.handle.visibleIf(item.state.showHandle) - description.visibleIf(item.props.description.isNotBlank()) + binding.description.visibleIf(item.props.description.isNotBlank()) - status.setImageDrawable(item.props.fallbackDrawable) + binding.status.setImageDrawable(item.props.fallbackDrawable) } } class QueryBuffer( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val dragListener: ((BufferViewHolder) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null private var none: Int = 0 @@ -536,7 +461,6 @@ class ArchiveListAdapter( private var highlight: Int = 0 init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -553,7 +477,7 @@ class ArchiveListAdapter( } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -574,10 +498,10 @@ class ArchiveListAdapter( override fun bind(item: BufferListItem, messageSettings: MessageSettings) { bufferId = item.props.info.bufferId - name.text = item.props.name - description.text = item.props.description + binding.name.text = item.props.name + binding.description.text = item.props.description - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -588,11 +512,11 @@ class ArchiveListAdapter( itemView.isSelected = item.state.selected - handle.visibleIf(item.state.showHandle) + binding.handle.visibleIf(item.state.showHandle) - description.visibleIf(item.props.description.isNotBlank()) + binding.description.visibleIf(item.props.description.isNotBlank()) - status.loadAvatars(item.props.avatarUrls, + binding.status.loadAvatars(item.props.avatarUrls, item.props.fallbackDrawable, crop = !messageSettings.squareAvatars) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt index d11f847579be380cad0113910a62a09d7ab0b631..f799c2342258a2617d6a1c47e6c471f2e9dc88e8 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -24,17 +24,16 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.helper.safeValue import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetBufferAwayBinding +import de.kuschku.quasseldroid.databinding.WidgetBufferBinding +import de.kuschku.quasseldroid.databinding.WidgetNetworkBinding import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.lists.ListAdapter @@ -94,34 +93,38 @@ class BufferListAdapter( val viewType = ViewType(viewType.toUInt()) return when (viewType.bufferType?.enabledValues()?.firstOrNull()) { BufferInfo.Type.ChannelBuffer -> BufferViewHolder.ChannelBuffer( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_buffer, parent, false - ), - clickListener = clickListener, - longClickListener = longClickListener, - dragListener = dragListener - ) - BufferInfo.Type.QueryBuffer -> BufferViewHolder.QueryBuffer( - LayoutInflater.from(parent.context).inflate( - if (viewType.bufferStatus == BufferStatus.AWAY) R.layout.widget_buffer_away - else R.layout.widget_buffer, parent, false - ), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, dragListener = dragListener ) + BufferInfo.Type.QueryBuffer -> if (viewType.bufferStatus == BufferStatus.AWAY) { + BufferViewHolder.QueryAwayBuffer( + WidgetBufferAwayBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ), + clickListener = clickListener, + longClickListener = longClickListener, + dragListener = dragListener + ) + } else { + BufferViewHolder.QueryBuffer( + WidgetBufferBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ), + clickListener = clickListener, + longClickListener = longClickListener, + dragListener = dragListener + ) + } BufferInfo.Type.GroupBuffer -> BufferViewHolder.GroupBuffer( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_buffer, parent, false - ), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, dragListener = dragListener ) BufferInfo.Type.StatusBuffer -> BufferViewHolder.StatusBuffer( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_network, parent, false - ), + WidgetNetworkBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener, longClickListener = longClickListener, expansionListener = ::expandListener @@ -162,17 +165,11 @@ class BufferListAdapter( abstract fun bind(item: BufferListItem, messageSettings: MessageSettings) class StatusBuffer( - itemView: View, + private val binding: WidgetNetworkBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val expansionListener: ((NetworkId, Boolean) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null var networkId: NetworkId? = null @@ -184,7 +181,6 @@ class BufferListAdapter( private var expanded: Boolean = false init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -201,7 +197,7 @@ class BufferListAdapter( } } - status.setOnClickListener { + binding.status.setOnClickListener { val network = networkId if (network != null) expansionListener?.invoke(network, !expanded) @@ -219,11 +215,11 @@ class BufferListAdapter( } override fun bind(item: BufferListItem, messageSettings: MessageSettings) { - name.text = item.props.name + binding.name.text = item.props.name bufferId = item.props.info.bufferId networkId = item.props.info.networkId - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -237,31 +233,19 @@ class BufferListAdapter( itemView.isSelected = item.state.selected if (item.state.networkExpanded) { - status.setImageResource(R.drawable.ic_chevron_up) + binding.status.setImageResource(R.drawable.ic_chevron_up) } else { - status.setImageResource(R.drawable.ic_chevron_down) + binding.status.setImageResource(R.drawable.ic_chevron_down) } } } class GroupBuffer( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val dragListener: ((BufferViewHolder) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null private val online: Drawable? @@ -273,7 +257,6 @@ class BufferListAdapter( private var highlight: Int = 0 init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -290,7 +273,7 @@ class BufferListAdapter( } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -318,10 +301,10 @@ class BufferListAdapter( override fun bind(item: BufferListItem, messageSettings: MessageSettings) { bufferId = item.props.info.bufferId - name.text = item.props.name - description.text = item.props.description + binding.name.text = item.props.name + binding.description.text = item.props.description - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -332,11 +315,11 @@ class BufferListAdapter( itemView.isSelected = item.state.selected - handle.visibleIf(item.state.showHandle) + binding.handle.visibleIf(item.state.showHandle) - description.visibleIf(item.props.description.isNotBlank()) + binding.description.visibleIf(item.props.description.isNotBlank()) - status.setImageDrawable( + binding.status.setImageDrawable( when (item.props.bufferStatus) { BufferStatus.ONLINE -> online else -> offline @@ -346,23 +329,11 @@ class BufferListAdapter( } class ChannelBuffer( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val dragListener: ((BufferViewHolder) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null private var none: Int = 0 @@ -371,7 +342,6 @@ class BufferListAdapter( private var highlight: Int = 0 init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -388,7 +358,7 @@ class BufferListAdapter( } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -409,10 +379,10 @@ class BufferListAdapter( override fun bind(item: BufferListItem, messageSettings: MessageSettings) { bufferId = item.props.info.bufferId - name.text = item.props.name - description.text = item.props.description + binding.name.text = item.props.name + binding.description.text = item.props.description - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -423,32 +393,95 @@ class BufferListAdapter( itemView.isSelected = item.state.selected - handle.visibleIf(item.state.showHandle) + binding.handle.visibleIf(item.state.showHandle) - description.visibleIf(item.props.description.isNotBlank()) + binding.description.visibleIf(item.props.description.isNotBlank()) - status.setImageDrawable(item.props.fallbackDrawable) + binding.status.setImageDrawable(item.props.fallbackDrawable) } } class QueryBuffer( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((BufferId) -> Unit)? = null, private val longClickListener: ((BufferId) -> Unit)? = null, private val dragListener: ((BufferViewHolder) -> Unit)? = null - ) : BufferViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView + ) : BufferViewHolder(binding.root) { + var bufferId: BufferId? = null + + private var none: Int = 0 + private var activity: Int = 0 + private var message: Int = 0 + private var highlight: Int = 0 + + init { + itemView.setOnClickListener { + val buffer = bufferId + if (buffer != null) + clickListener?.invoke(buffer) + } + + itemView.setOnLongClickListener { + val buffer = bufferId + if (buffer != null) { + longClickListener?.invoke(buffer) + true + } else { + false + } + } + + binding.handle.setOnTouchListener { _, event -> + if (event.action == MotionEvent.ACTION_DOWN) { + dragListener?.invoke(this) + } + false + } + + itemView.context.theme.styledAttributes( + R.attr.colorTextPrimary, R.attr.colorTintActivity, R.attr.colorTintMessage, + R.attr.colorTintHighlight + ) { + none = getColor(0, 0) + activity = getColor(1, 0) + message = getColor(2, 0) + highlight = getColor(3, 0) + } + } - @BindView(R.id.name) - lateinit var name: TextView + override fun bind(item: BufferListItem, messageSettings: MessageSettings) { + bufferId = item.props.info.bufferId - @BindView(R.id.description) - lateinit var description: TextView + binding.name.text = item.props.info.bufferName + binding.description.text = item.props.description - @BindView(R.id.handle) - lateinit var handle: View + binding.name.setTextColor( + when { + item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight + item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message + item.props.bufferActivity.hasFlag(Buffer_Activity.OtherActivity) -> activity + else -> none + } + ) + itemView.isSelected = item.state.selected + + binding.handle.visibleIf(item.state.showHandle) + + binding.description.visibleIf(item.props.description.isNotBlank()) + + binding.status.loadAvatars(item.props.avatarUrls, + item.props.fallbackDrawable, + crop = !messageSettings.squareAvatars) + } + } + + class QueryAwayBuffer( + private val binding: WidgetBufferAwayBinding, + private val clickListener: ((BufferId) -> Unit)? = null, + private val longClickListener: ((BufferId) -> Unit)? = null, + private val dragListener: ((BufferViewHolder) -> Unit)? = null + ) : BufferViewHolder(binding.root) { var bufferId: BufferId? = null private var none: Int = 0 @@ -457,7 +490,6 @@ class BufferListAdapter( private var highlight: Int = 0 init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val buffer = bufferId if (buffer != null) @@ -474,7 +506,7 @@ class BufferListAdapter( } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -495,10 +527,10 @@ class BufferListAdapter( override fun bind(item: BufferListItem, messageSettings: MessageSettings) { bufferId = item.props.info.bufferId - name.text = item.props.info.bufferName - description.text = item.props.description + binding.name.text = item.props.info.bufferName + binding.description.text = item.props.description - name.setTextColor( + binding.name.setTextColor( when { item.props.bufferActivity.hasFlag(Buffer_Activity.Highlight) -> highlight item.props.bufferActivity.hasFlag(Buffer_Activity.NewMessage) -> message @@ -509,11 +541,11 @@ class BufferListAdapter( itemView.isSelected = item.state.selected - handle.visibleIf(item.state.showHandle) + binding.handle.visibleIf(item.state.showHandle) - description.visibleIf(item.props.description.isNotBlank()) + binding.description.visibleIf(item.props.description.isNotBlank()) - status.loadAvatars(item.props.avatarUrls, + binding.status.loadAvatars(item.props.avatarUrls, item.props.fallbackDrawable, crop = !messageSettings.squareAvatars) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt index 9388b791d5c94048b01fb87d540eb2d7ac745b97..f42664d5e4458ad53e4cbbd72014f491f1ba3d3a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,16 +20,12 @@ package de.kuschku.quasseldroid.ui.chat.buffers import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.BufferViewConfig -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemToolbarBinding import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter class BufferViewConfigAdapter : @@ -63,9 +59,8 @@ class BufferViewConfigAdapter : if (dropDown) ContextThemeWrapper(parent.context, dropDownViewTheme) else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_toolbar, parent, false) return BufferViewConfigViewHolder( - view + WidgetSpinnerItemToolbarBinding.inflate(inflater, parent, false) ) } @@ -80,16 +75,11 @@ class BufferViewConfigAdapter : override fun getCount() = data.size - class BufferViewConfigViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class BufferViewConfigViewHolder( + private val binding: WidgetSpinnerItemToolbarBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(bufferViewConfig: BufferViewConfig?) { - text.text = bufferViewConfig?.bufferViewName() ?: "" + binding.text1.text = bufferViewConfig?.bufferViewName() ?: "" } } } 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 8b9b1b01d10dd54238a9bb219a6f015d1c1ebb16..cb9b27d4a16e2a758adaf5fdc9f8c5d0755a1da1 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 @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -45,6 +45,8 @@ import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.util.helper.* import de.kuschku.quasseldroid.BuildConfig import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.dao.listenDefaultFiltered +import de.kuschku.quasseldroid.persistence.dao.listenRx import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.db.QuasselDatabase import de.kuschku.quasseldroid.persistence.models.Filtered diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt index 6c88633fd5dea9c67adcc41adfc6dbee10b760f0..2cd66d65d01426d0f24f7f63f9cfb5e7adde54ab 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,16 +22,11 @@ package de.kuschku.quasseldroid.ui.chat.input import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.* import de.kuschku.quasseldroid.settings.MessageSettings -import de.kuschku.quasseldroid.ui.chat.nicks.NickListAdapter.Companion.VIEWTYPE_AWAY import de.kuschku.quasseldroid.util.helper.loadAvatars import de.kuschku.quasseldroid.util.helper.visibleIf import de.kuschku.quasseldroid.util.ui.SpanFormatter @@ -56,33 +51,23 @@ class AutoCompleteAdapter @Inject constructor( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) { VIEWTYPE_CHANNEL -> AutoCompleteViewHolder.ChannelViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.widget_buffer, parent, false), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), + clickListener = clickListener + ) + VIEWTYPE_NICK_ACTIVE, VIEWTYPE_NICK_AWAY -> AutoCompleteViewHolder.NickViewHolder( + WidgetNickBinding.inflate(LayoutInflater.from(parent.context), parent, false), + clickListener = clickListener + ) + VIEWTYPE_NICK_AWAY -> AutoCompleteViewHolder.NickAwayViewHolder( + WidgetNickAwayBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener ) - VIEWTYPE_NICK_ACTIVE, VIEWTYPE_NICK_AWAY -> { - val holder = AutoCompleteViewHolder.NickViewHolder( - LayoutInflater.from(parent.context).inflate( - when (viewType) { - VIEWTYPE_AWAY -> R.layout.widget_nick_away - else -> R.layout.widget_nick - }, parent, false - ), - clickListener = clickListener - ) - - holder.avatar.visibleIf(messageSettings.showAvatars) - - holder - } VIEWTYPE_ALIAS -> AutoCompleteViewHolder.AliasViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.widget_alias, parent, false), + WidgetAliasBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener ) VIEWTYPE_EMOJI -> AutoCompleteViewHolder.EmojiViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.widget_emoji, parent, false), + WidgetEmojiBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener ) else -> throw IllegalArgumentException( @@ -118,22 +103,39 @@ class AutoCompleteAdapter @Inject constructor( } class NickViewHolder( - itemView: View, + private val binding: WidgetNickBinding, private val clickListener: ((String, String) -> Unit)? = null - ) : AutoCompleteViewHolder(itemView) { - @BindView(R.id.avatar) - lateinit var avatar: ImageView + ) : AutoCompleteViewHolder(binding.root) { + var value: AutoCompleteItem? = null - @BindView(R.id.nick) - lateinit var nick: TextView + init { + itemView.setOnClickListener { + val value = value + if (value != null) + clickListener?.invoke(value.name, value.suffix) + } + } - @BindView(R.id.realname) - lateinit var realname: TextView + fun bindImpl(data: AutoCompleteItem.UserItem, messageSettings: MessageSettings) { + value = data + + binding.nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) + binding.realname.text = data.realname + binding.avatar.visibleIf(messageSettings.showAvatars) + binding.avatar.loadAvatars(data.avatarUrls, + data.fallbackDrawable, + crop = !messageSettings.squareAvatars) + } + } + + class NickAwayViewHolder( + private val binding: WidgetNickAwayBinding, + private val clickListener: ((String, String) -> Unit)? = null + ) : AutoCompleteViewHolder(binding.root) { var value: AutoCompleteItem? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val value = value if (value != null) @@ -144,32 +146,23 @@ class AutoCompleteAdapter @Inject constructor( fun bindImpl(data: AutoCompleteItem.UserItem, messageSettings: MessageSettings) { value = data - nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) - realname.text = data.realname + binding.nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) + binding.realname.text = data.realname - avatar.loadAvatars(data.avatarUrls, + binding.avatar.visibleIf(messageSettings.showAvatars) + binding.avatar.loadAvatars(data.avatarUrls, data.fallbackDrawable, crop = !messageSettings.squareAvatars) } } class ChannelViewHolder( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((String, String) -> Unit)? = null - ) : AutoCompleteViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - + ) : AutoCompleteViewHolder(binding.root) { var value: AutoCompleteItem? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val value = value if (value != null) @@ -180,29 +173,22 @@ class AutoCompleteAdapter @Inject constructor( fun bindImpl(data: AutoCompleteItem.ChannelItem, messageSettings: MessageSettings) { value = data - name.text = data.info.bufferName - description.text = data.description + binding.name.text = data.info.bufferName + binding.description.text = data.description - description.visibleIf(data.description.isNotBlank()) + binding.description.visibleIf(data.description.isNotBlank()) - status.setImageDrawable(data.icon) + binding.status.setImageDrawable(data.icon) } } class AliasViewHolder( - itemView: View, + private val binding: WidgetAliasBinding, private val clickListener: ((String, String) -> Unit)? = null - ) : AutoCompleteViewHolder(itemView) { - @BindView(R.id.alias) - lateinit var alias: TextView - - @BindView(R.id.expansion) - lateinit var expansion: TextView - + ) : AutoCompleteViewHolder(binding.root) { var value: AutoCompleteItem? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val value = value if (value != null) @@ -213,25 +199,18 @@ class AutoCompleteAdapter @Inject constructor( fun bindImpl(data: AutoCompleteItem.AliasItem, messageSettings: MessageSettings) { value = data - alias.text = data.alias - expansion.text = data.expansion + binding.alias.text = data.alias + binding.expansion.text = data.expansion } } class EmojiViewHolder( - itemView: View, + private val binding: WidgetEmojiBinding, private val clickListener: ((String, String) -> Unit)? = null - ) : AutoCompleteViewHolder(itemView) { - @BindView(R.id.emoji) - lateinit var emoji: TextView - - @BindView(R.id.shortCode) - lateinit var shortCode: TextView - + ) : AutoCompleteViewHolder(binding.root) { var value: AutoCompleteItem? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val value = value if (value != null) @@ -242,8 +221,8 @@ class AutoCompleteAdapter @Inject constructor( fun bindImpl(data: AutoCompleteItem.EmojiItem, messageSettings: MessageSettings) { value = data - emoji.text = data.replacement - shortCode.text = data.shortCodes.joinToString(", ") + binding.emoji.text = data.replacement + binding.shortCode.text = data.shortCodes.joinToString(", ") } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/MessageHistoryAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/MessageHistoryAdapter.kt index 43e5354fca6fb54c8d974106436c3573bca631a1..1a5e35449993c638020c6a556aab1fd13cd38ef3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/MessageHistoryAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/MessageHistoryAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,14 +21,10 @@ package de.kuschku.quasseldroid.ui.chat.input import android.text.TextUtils import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetHistoryMessageBinding import de.kuschku.quasseldroid.util.lists.ListAdapter class MessageHistoryAdapter : ListAdapter<CharSequence, MessageHistoryAdapter.MessageViewHolder>( @@ -52,7 +48,7 @@ class MessageHistoryAdapter : ListAdapter<CharSequence, MessageHistoryAdapter.Me override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = MessageViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_history_message, parent, false), + WidgetHistoryMessageBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener ) @@ -64,16 +60,12 @@ class MessageHistoryAdapter : ListAdapter<CharSequence, MessageHistoryAdapter.Me holder.bind(getItem(position)) class MessageViewHolder( - itemView: View, + private val binding: WidgetHistoryMessageBinding, private val clickListener: ((CharSequence) -> Unit)? = null - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.content) - lateinit var content: TextView - + ) : RecyclerView.ViewHolder(binding.root) { var value: CharSequence? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { val value = value if (value != null) @@ -83,7 +75,7 @@ class MessageHistoryAdapter : ListAdapter<CharSequence, MessageHistoryAdapter.Me fun bind(data: CharSequence) { value = data - content.text = data + binding.content.text = data } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt index 2d2e3fc2404a8f988b758d1cc2b4ffe33f9e72ae..6c682499f840547233b7b57e27c5a9a188706e5b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -29,8 +29,6 @@ import android.widget.TextView import androidx.paging.PagedListAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.util.flag.hasFlag @@ -46,7 +44,7 @@ import de.kuschku.quasseldroid.viewmodel.data.FormattedMessage import javax.inject.Inject class MessageAdapter @Inject constructor( - private val messageRenderer: MessageRenderer + private val messageRenderer: QuasselMessageRenderer ) : PagedListAdapter<DisplayMessage, MessageAdapter.QuasselMessageViewHolder>( object : DiffUtil.ItemCallback<DisplayMessage>() { override fun areItemsTheSame(oldItem: DisplayMessage, newItem: DisplayMessage) = @@ -185,45 +183,16 @@ class MessageAdapter @Inject constructor( expansionListener: ((MessageData) -> Unit)? = null, movementMethod: BetterLinkMovementMethod ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.daychange_container) - @JvmField - var daychangeContainer: View? = null - - @BindView(R.id.daychange) - @JvmField - var daychange: TextView? = null - - @BindView(R.id.message_container) - @JvmField - var messageContainer: View? = null - - @BindView(R.id.time_left) - @JvmField - var timeLeft: TextView? = null - - @BindView(R.id.time_right) - @JvmField - var timeRight: TextView? = null - - @BindView(R.id.avatar) - @JvmField - var avatar: ImageView? = null - - @BindView(R.id.name) - @JvmField - var name: TextView? = null - - @BindView(R.id.realname) - @JvmField - var realname: TextView? = null - - @BindView(R.id.content) - @JvmField - var content: TextView? = null - - @BindView(R.id.combined) - @JvmField - var combined: TextView? = null + val daychangeContainer: View? = itemView.findViewById(R.id.daychange_container) + val daychange: TextView? = itemView.findViewById(R.id.daychange) + val messageContainer: View? = itemView.findViewById(R.id.message_container) + val timeLeft: TextView? = itemView.findViewById(R.id.time_left) + val timeRight: TextView? = itemView.findViewById(R.id.time_right) + val avatar: ImageView? = itemView.findViewById(R.id.avatar) + val name: TextView? = itemView.findViewById(R.id.name) + val realname: TextView? = itemView.findViewById(R.id.realname) + val content: TextView? = itemView.findViewById(R.id.content) + val combined: TextView? = itemView.findViewById(R.id.combined) private var message: FormattedMessage? = null private var original: MessageData? = null @@ -254,7 +223,6 @@ class MessageAdapter @Inject constructor( } init { - ButterKnife.bind(this, itemView) content?.movementMethod = movementMethod combined?.movementMethod = movementMethod diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt index ca9421adab0b0172aa8dbdd2679b9754fa313292..199a10486e6cb8465d1480aea013b411f384f63b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,16 +22,13 @@ package de.kuschku.quasseldroid.ui.chat.nicks import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.util.helper.nullIf -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetNickAwayBinding +import de.kuschku.quasseldroid.databinding.WidgetNickBinding import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.helper.letIf import de.kuschku.quasseldroid.util.helper.loadAvatars @@ -56,20 +53,15 @@ class NickListAdapter( (it.initial.nullIf(String?::isNullOrBlank) ?: "123") } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NickViewHolder { - val holder = NickViewHolder( - LayoutInflater.from(parent.context).inflate( - when (viewType) { - VIEWTYPE_AWAY -> R.layout.widget_nick_away - else -> R.layout.widget_nick - }, parent, false - ), + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) { + VIEWTYPE_AWAY -> NickViewHolder.Away( + WidgetNickAwayBinding.inflate(LayoutInflater.from(parent.context), parent, false), + clickListener = clickListener + ) + else -> NickViewHolder.Active( + WidgetNickBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener ) - - holder.avatar.visibleIf(messageSettings.showAvatars) - - return holder } operator fun get(position: Int): IrcUserItem? = super.getItem(position) @@ -83,39 +75,61 @@ class NickListAdapter( VIEWTYPE_ACTIVE } - class NickViewHolder( - itemView: View, - private val clickListener: ((NetworkId, String) -> Unit)? = null - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.avatar) - lateinit var avatar: ImageView - - @BindView(R.id.nick) - lateinit var nick: TextView + sealed class NickViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + abstract fun bind(data: IrcUserItem, messageSettings: MessageSettings) + + class Active( + private val binding: WidgetNickBinding, + private val clickListener: ((NetworkId, String) -> Unit)? = null + ) : NickViewHolder(binding.root) { + var user: IrcUserItem? = null + + init { + itemView.setOnClickListener { + val nick = user + if (nick != null) + clickListener?.invoke(nick.networkId, nick.nick) + } + } - @BindView(R.id.realname) - lateinit var realname: TextView + override fun bind(data: IrcUserItem, messageSettings: MessageSettings) { + user = data - var user: IrcUserItem? = null + binding.nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) + binding.realname.text = data.realname - init { - ButterKnife.bind(this, itemView) - itemView.setOnClickListener { - val nick = user - if (nick != null) - clickListener?.invoke(nick.networkId, nick.nick) + binding.avatar.visibleIf(messageSettings.showAvatars) + binding.avatar.loadAvatars(data.avatarUrls, + data.fallbackDrawable, + crop = !messageSettings.squareAvatars) } } - fun bind(data: IrcUserItem, messageSettings: MessageSettings) { - user = data + class Away( + private val binding: WidgetNickAwayBinding, + private val clickListener: ((NetworkId, String) -> Unit)? = null + ) : NickViewHolder(binding.root) { + var user: IrcUserItem? = null + + init { + itemView.setOnClickListener { + val nick = user + if (nick != null) + clickListener?.invoke(nick.networkId, nick.nick) + } + } + + override fun bind(data: IrcUserItem, messageSettings: MessageSettings) { + user = data - nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) - realname.text = data.realname + binding.nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) + binding.realname.text = data.realname - avatar.loadAvatars(data.avatarUrls, - data.fallbackDrawable, - crop = !messageSettings.squareAvatars) + binding.avatar.visibleIf(messageSettings.showAvatars) + binding.avatar.loadAvatars(data.avatarUrls, + data.fallbackDrawable, + crop = !messageSettings.squareAvatars) + } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt index b95fde5ea811a3c5c96b933441536be8cee019dd..239348782174f4cefdba5b798e2000413aa2273e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -210,7 +210,7 @@ class AboutFragment : DaggerFragment() { ), Library( name = "Kotlin Standard Library", - version = "1.3.50", + version = "1.3.61", license = apache2, url = "https://kotlinlang.org/" ), diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/ContributorAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/ContributorAdapter.kt index 0d653187426a0d8e9bbd68e4f0151c0803b376b3..18a2a987a90c5a74aec4ec4b0e068830e5108600 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/ContributorAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/ContributorAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,18 +20,14 @@ package de.kuschku.quasseldroid.ui.clientsettings.about import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetContributorBinding class ContributorAdapter(private val contributors: List<Contributor>) : RecyclerView.Adapter<ContributorAdapter.ContributorViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ContributorViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_contributor, parent, false) + WidgetContributorBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) override fun getItemCount() = contributors.size @@ -40,24 +36,13 @@ class ContributorAdapter(private val contributors: List<Contributor>) : holder.bind(contributors[position]) } - class ContributorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.nickname) - lateinit var nickName: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class ContributorViewHolder( + private val binding: WidgetContributorBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: Contributor) { - this.name.text = item.name - this.nickName.text = item.nickName - this.description.text = item.description + binding.name.text = item.name + binding.nickname.text = item.nickName + binding.description.text = item.description } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/LibraryAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/LibraryAdapter.kt index 6aa04b99b6c3292bfb852e7fa0ecbc04aabaf304..580a3346092216c3a0abb4735a74b2388ded48ab 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/LibraryAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/LibraryAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,20 +20,16 @@ package de.kuschku.quasseldroid.ui.clientsettings.about import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetLibraryBinding import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseActivity import de.kuschku.quasseldroid.util.helper.visibleIf class LibraryAdapter(private val libraries: List<Library>) : RecyclerView.Adapter<LibraryAdapter.LibraryViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = LibraryViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_library, parent, false) + WidgetLibraryBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) override fun getItemCount() = libraries.size @@ -42,20 +38,12 @@ class LibraryAdapter(private val libraries: List<Library>) : holder.bind(libraries[position]) } - class LibraryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.version) - lateinit var version: TextView - - @BindView(R.id.license) - lateinit var license: TextView - + class LibraryViewHolder( + private val binding: WidgetLibraryBinding + ) : RecyclerView.ViewHolder(binding.root) { private var item: Library? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { this.item?.run { LicenseActivity.launch(itemView.context, @@ -67,10 +55,10 @@ class LibraryAdapter(private val libraries: List<Library>) : fun bind(item: Library) { this.item = item - this.name.text = item.name - this.version.text = item.version - this.version.visibleIf(!item.version.isNullOrBlank()) - this.license.text = item.license.shortName + binding.name.text = item.name + binding.version.text = item.version + binding.version.visibleIf(!item.version.isNullOrBlank()) + binding.license.text = item.license.shortName } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/TranslatorAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/TranslatorAdapter.kt index 551caf0f5b5791968c79175325071db810545f53..eed99ce24ff7aab979063bf71b4b3bde39be1955 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/TranslatorAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/TranslatorAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,18 +20,16 @@ package de.kuschku.quasseldroid.ui.clientsettings.about import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetTranslatorBinding class TranslatorAdapter(private val translators: List<Translator>) : RecyclerView.Adapter<TranslatorAdapter.TranslatorViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = TranslatorViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_translator, parent, false) + WidgetTranslatorBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) ) override fun getItemCount() = translators.size @@ -40,20 +38,12 @@ class TranslatorAdapter(private val translators: List<Translator>) : holder.bind(translators[position]) } - class TranslatorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.language) - lateinit var language: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class TranslatorViewHolder( + private val binding: WidgetTranslatorBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: Translator) { - this.name.text = item.name - this.language.text = itemView.resources.getString(item.language) + binding.name.text = item.name + binding.language.text = itemView.resources.getString(item.language) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt index afda307d98997674386b90167f9e54ca2d3dd500..6e575a30c512bdb3b45fb714dd9f503f5825c5ae 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -66,13 +66,13 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(), override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.preferences, rootKey) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - findPreference(getString(R.string.preference_notification_sound_key)).isVisible = false - findPreference(getString(R.string.preference_notification_vibration_key)).isVisible = false - findPreference(getString(R.string.preference_notification_light_key)).isVisible = false + findPreference<Preference>(getString(R.string.preference_notification_sound_key))?.isVisible = false + findPreference<Preference>(getString(R.string.preference_notification_vibration_key))?.isVisible = false + findPreference<Preference>(getString(R.string.preference_notification_light_key))?.isVisible = false } else { - findPreference(getString(R.string.preference_notification_configure_key)).isVisible = false + findPreference<Preference>(getString(R.string.preference_notification_configure_key))?.isVisible = false } - findPreference(getString(R.string.preference_clear_cache_key)).setOnPreferenceClickListener { + findPreference<Preference>(getString(R.string.preference_clear_cache_key))?.setOnPreferenceClickListener { activity?.let { handler.post { QuasselDatabase.Creator.init(it).message().clearMessages() @@ -93,8 +93,8 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(), super.onStop() } - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - updateSummary(findPreference(key)) + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String) { + updateSummary(findPreference<ListPreference>(key)) val appearanceSettings = Settings.appearance(context!!) if (this.appearanceSettings.theme != appearanceSettings.theme || this.appearanceSettings.language != appearanceSettings.language) { @@ -102,8 +102,8 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(), } } - private fun updateSummary(preference: Preference) { - if (preference is ListPreference) { + private fun updateSummary(preference: ListPreference?) { + if (preference != null) { preference.summary = preference.entry } } @@ -111,7 +111,7 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(), private fun initSummary(preference: Preference) { if (preference is PreferenceGroup) { (0 until preference.preferenceCount).asSequence().map(preference::getPreference).forEach(::initSummary) - } else { + } else if (preference is ListPreference) { updateSummary(preference) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashAdapter.kt index 70337ec0e25eef821936458542c709ca6f8b8cc0..f53335c5ac4fedde064ce77831bae2bed08d95d3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,40 +22,37 @@ package de.kuschku.quasseldroid.ui.clientsettings.crash import android.content.Intent import android.net.Uri import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.malheur.data.Report import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetCrashBinding import de.kuschku.quasseldroid.util.lists.ListAdapter import org.threeten.bp.Instant import org.threeten.bp.ZoneId import org.threeten.bp.format.DateTimeFormatter -class CrashAdapter : ListAdapter<Pair<Report, Uri>, CrashAdapter.CrashViewHolder>( - object : DiffUtil.ItemCallback<Pair<Report, Uri>>() { - override fun areItemsTheSame(oldItem: Pair<Report, Uri>, newItem: Pair<Report, Uri>) = +class CrashAdapter : ListAdapter<Pair<Report?, Uri>, CrashAdapter.CrashViewHolder>( + object : DiffUtil.ItemCallback<Pair<Report?, Uri>>() { + override fun areItemsTheSame(oldItem: Pair<Report?, Uri>, newItem: Pair<Report?, Uri>) = oldItem.second == newItem.second - override fun areContentsTheSame(oldItem: Pair<Report, Uri>, newItem: Pair<Report, Uri>) = + override fun areContentsTheSame(oldItem: Pair<Report?, Uri>, newItem: Pair<Report?, Uri>) = oldItem == newItem } ) { - private var onUpdateListener: ((List<Pair<Report, Uri>>) -> Unit)? = null - fun setOnUpdateListener(listener: ((List<Pair<Report, Uri>>) -> Unit)?) { + private var onUpdateListener: ((List<Pair<Report?, Uri>>) -> Unit)? = null + fun setOnUpdateListener(listener: ((List<Pair<Report?, Uri>>) -> Unit)?) { onUpdateListener = listener } - override fun onUpdateFinished(list: List<Pair<Report, Uri>>) { + override fun onUpdateFinished(list: List<Pair<Report?, Uri>>) { onUpdateListener?.invoke(list) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = CrashViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_crash, parent, false) + WidgetCrashBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) override fun onBindViewHolder(holder: CrashViewHolder, position: Int) { @@ -63,23 +60,16 @@ class CrashAdapter : ListAdapter<Pair<Report, Uri>, CrashAdapter.CrashViewHolder holder.bind(report, uri) } - class CrashViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.crash_time) - lateinit var crashTime: TextView + class CrashViewHolder( + private val binding: WidgetCrashBinding + ) : RecyclerView.ViewHolder(binding.root) { - @BindView(R.id.version_name) - lateinit var versionName: TextView - - @BindView(R.id.error) - lateinit var error: TextView - - var item: Report? = null - var uri: Uri? = null + private var item: Report? = null + private var uri: Uri? = null private val dateTimeFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss") init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { uri?.let { itemView.context.startActivity( @@ -96,15 +86,15 @@ class CrashAdapter : ListAdapter<Pair<Report, Uri>, CrashAdapter.CrashViewHolder } } - fun bind(item: Report, uri: Uri) { + fun bind(item: Report?, uri: Uri) { this.item = item this.uri = uri - this.crashTime.text = item.environment?.crashTime?.let { + binding.crashTime.text = item?.environment?.crashTime?.let { dateTimeFormatter.format(Instant.ofEpochMilli(it).atZone(ZoneId.systemDefault())) - } - this.versionName.text = "${item.application?.versionName}" - this.error.text = "${item.crash?.exception?.lines()?.firstOrNull()}" + } ?: "null" + binding.versionName.text = item?.application?.versionName ?: "null" + binding.error.text = item?.crash?.exception?.lines()?.firstOrNull() ?: "null" } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt index f7f29a269e47d1d6ccc4e5834206848af8322a7e..2e3f47d5e340ba5e40896404aa6a8a22d3484443 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/crash/CrashFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -33,6 +33,7 @@ import androidx.recyclerview.widget.RecyclerView import butterknife.BindView import butterknife.ButterKnife import com.google.gson.Gson +import com.google.gson.JsonSyntaxException import dagger.android.support.DaggerFragment import de.kuschku.malheur.CrashHandler import de.kuschku.malheur.data.Report @@ -78,15 +79,19 @@ class CrashFragment : DaggerFragment() { if (crashDir != null && context != null) { crashDir.mkdirs() - val list: List<Pair<Report, Uri>> = crashDir.listFiles() + val list: List<Pair<Report?, Uri>> = crashDir.listFiles() .orEmpty() .map { - Pair<Report, Uri>( - gson.fromJson(it.readText()), + Pair<Report?, Uri>( + try { + gson.fromJson<Report>(it.readText()) + } catch (e: JsonSyntaxException) { + null + }, FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.fileprovider", it) ) } - .sortedByDescending { it.first.environment?.crashTime } + .sortedByDescending { it.first?.environment?.crashTime } activity?.runOnUiThread { this.adapter?.submitList(list) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt index 397e67314b8a2ec5c28a61e71ac88e936b4c857d..4e25c57d65e0c3041eaf14c4bbefa0d5a7c23a66 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/license/LicenseActivity.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,7 +21,7 @@ package de.kuschku.quasseldroid.ui.clientsettings.license import android.content.Context import android.content.Intent -import androidx.annotation.StringRes +import androidx.annotation.RawRes import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity class LicenseActivity : SettingsActivity(LicenseFragment()) { @@ -29,13 +29,13 @@ class LicenseActivity : SettingsActivity(LicenseFragment()) { fun launch( context: Context, license_name: String, - @StringRes license_text: Int + @RawRes license_text: Int ) = context.startActivity(intent(context, license_name, license_text)) fun intent( context: Context, license_name: String, - @StringRes license_text: Int + @RawRes license_text: Int ) = Intent(context, LicenseActivity::class.java).apply { putExtra("license_name", license_name) putExtra("license_text", license_text) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistCertificateAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistCertificateAdapter.kt index 56d8049458317527b938d4baf97ac89dae2ebe35..b9c33fc215d7e40a21dbff7adea9054693abda9f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistCertificateAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistCertificateAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,14 +20,9 @@ package de.kuschku.quasseldroid.ui.clientsettings.whitelist import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.AppCompatImageButton import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.PreferencesWhitelistCertificateItemBinding import de.kuschku.quasseldroid.persistence.models.SslValidityWhitelistEntry import de.kuschku.quasseldroid.util.helper.setTooltip import de.kuschku.quasseldroid.util.helper.visibleIf @@ -83,9 +78,9 @@ class WhitelistCertificateAdapter : override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = WhitelistItemViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.preferences_whitelist_certificate_item, - parent, - false), + PreferencesWhitelistCertificateItemBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ), ::remove ) @@ -94,34 +89,24 @@ class WhitelistCertificateAdapter : } class WhitelistItemViewHolder( - itemView: View, + private val binding: PreferencesWhitelistCertificateItemBinding, clickListener: ((SslValidityWhitelistEntry) -> Unit)? - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.fingerprint) - lateinit var fingerprint: TextView - - @BindView(R.id.ignore_date) - lateinit var ignoreDate: View - - @BindView(R.id.action_delete) - lateinit var delete: AppCompatImageButton - + ) : RecyclerView.ViewHolder(binding.root) { private var item: SslValidityWhitelistEntry? = null init { - ButterKnife.bind(this, itemView) - delete.setOnClickListener { + binding.actionDelete.setOnClickListener { item?.let { clickListener?.invoke(it) } } - delete.setTooltip() + binding.actionDelete.setTooltip() } fun bind(item: SslValidityWhitelistEntry) { this.item = item - fingerprint.text = item.fingerprint - ignoreDate.visibleIf(item.ignoreDate) + binding.fingerprint.text = item.fingerprint + binding.ignoreDate.visibleIf(item.ignoreDate) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistHostnameAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistHostnameAdapter.kt index fe3d5e1c87d0ffd96300b24403e2a1ad02711a31..c257748ecb336f0b7b468e371e25c2aec1019f49 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistHostnameAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/whitelist/WhitelistHostnameAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,14 +20,9 @@ package de.kuschku.quasseldroid.ui.clientsettings.whitelist import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.AppCompatImageButton import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.PreferencesWhitelistHostnameItemBinding import de.kuschku.quasseldroid.persistence.models.SslHostnameWhitelistEntry import de.kuschku.quasseldroid.util.helper.setTooltip @@ -77,9 +72,9 @@ class WhitelistHostnameAdapter : override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = WhitelistItemViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.preferences_whitelist_hostname_item, - parent, - false), + PreferencesWhitelistHostnameItemBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ), ::remove ) @@ -88,34 +83,24 @@ class WhitelistHostnameAdapter : } class WhitelistItemViewHolder( - itemView: View, + private val binding: PreferencesWhitelistHostnameItemBinding, clickListener: ((SslHostnameWhitelistEntry) -> Unit)? - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.hostname) - lateinit var hostname: TextView - - @BindView(R.id.fingerprint) - lateinit var fingerprint: TextView - - @BindView(R.id.action_delete) - lateinit var delete: AppCompatImageButton - + ) : RecyclerView.ViewHolder(binding.root) { private var item: SslHostnameWhitelistEntry? = null init { - ButterKnife.bind(this, itemView) - delete.setOnClickListener { + binding.actionDelete.setOnClickListener { item?.let { clickListener?.invoke(it) } } - delete.setTooltip() + binding.actionDelete.setTooltip() } fun bind(item: SslHostnameWhitelistEntry) { this.item = item - hostname.text = item.hostname - fingerprint.text = item.fingerprint + binding.hostname.text = item.hostname + binding.fingerprint.text = item.fingerprint } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsItemAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsItemAdapter.kt index be6bed9606022d5e2e3f27be01400571636ac711..c23439f3e5a8ba1b3f31980689317cbf7d96baf3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsItemAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/SettingsItemAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.coresettings import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.SettingsItemBinding class SettingsItemAdapter<T>(private val clickListener: (T) -> Unit) : ListAdapter<SettingsItem<T>, SettingsItemAdapter.SettingsItemViewHolder<T>>( @@ -41,7 +37,7 @@ class SettingsItemAdapter<T>(private val clickListener: (T) -> Unit) : } ) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = SettingsItemViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.settings_item, parent, false), + SettingsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener ) @@ -49,15 +45,13 @@ class SettingsItemAdapter<T>(private val clickListener: (T) -> Unit) : holder.bind(getItem(position)) } - class SettingsItemViewHolder<T>(itemView: View, clickListener: (T) -> Unit) : - RecyclerView.ViewHolder(itemView) { - @BindView(R.id.title) - lateinit var title: TextView - + class SettingsItemViewHolder<T>( + private val binding: SettingsItemBinding, + clickListener: (T) -> Unit + ) : RecyclerView.ViewHolder(binding.root) { var id: T? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { id?.let(clickListener::invoke) } @@ -65,7 +59,7 @@ class SettingsItemAdapter<T>(private val clickListener: (T) -> Unit) : fun bind(item: SettingsItem<T>) { this.id = item.id - this.title.text = item.name + binding.title.text = item.name } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListAdapter.kt index e9e4d5535d907d9bb5f4bc3bf8d59f47c1e997c4..0421df00601d852688ffd11518a51f3371985a92 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliaslist/AliasListAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,14 +21,10 @@ package de.kuschku.quasseldroid.ui.coresettings.aliaslist import android.view.LayoutInflater import android.view.MotionEvent -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.SettingsAliaslistItemBinding import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer import java.util.* import javax.inject.Inject @@ -84,7 +80,7 @@ class AliasListAdapter @Inject constructor( override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = AliasItemViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.settings_aliaslist_item, parent, false), + SettingsAliaslistItemBinding.inflate(LayoutInflater.from(parent.context), parent, false), formatDeserializer, clickListener, dragListener @@ -95,30 +91,20 @@ class AliasListAdapter @Inject constructor( } class AliasItemViewHolder( - itemView: View, + private val binding: SettingsAliaslistItemBinding, private val formatDeserializer: IrcFormatDeserializer, clickListener: ((IAliasManager.Alias) -> Unit)?, dragListener: ((AliasItemViewHolder) -> Unit)? - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.expansion) - lateinit var expansion: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : RecyclerView.ViewHolder(binding.root) { private var item: IAliasManager.Alias? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { item?.let { clickListener?.invoke(it) } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener?.invoke(this) } @@ -128,8 +114,8 @@ class AliasListAdapter @Inject constructor( fun bind(item: IAliasManager.Alias) { this.item = item - name.text = item.name - expansion.text = formatDeserializer.formatString(item.expansion, true) + binding.name.text = item.name + binding.expansion.text = formatDeserializer.formatString(item.expansion, true) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt index 1e1c1b3344b87f9b9a0d36653f1b85b5bb4b58a1..5d3c46ea7bc2609a614358f55964a7fdc3160085 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/ChatListBaseFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -126,7 +126,7 @@ abstract class ChatListBaseFragment(private val initDefault: Boolean) : combineLatest(it.values.map(Network::liveNetworkInfo)).map { it.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, INetwork.NetworkInfo::networkName)) } - }.toLiveData().observe(this, Observer { + }.toLiveData().observe(viewLifecycleOwner, Observer { if (it != null) { val selectOriginal = networkId.selectedItemId == Spinner.INVALID_ROW_ID networkAdapter.submitList(listOf(null) + it) @@ -143,7 +143,7 @@ abstract class ChatListBaseFragment(private val initDefault: Boolean) : .filter(Optional<ISession>::isPresent) .map(Optional<ISession>::get) .firstElement() - .toLiveData().observe(this, Observer { + .toLiveData().observe(viewLifecycleOwner, Observer { it?.let { update(Defaults.bufferViewConfig(requireContext(), it.proxy), minimumActivityAdapter, @@ -155,7 +155,7 @@ abstract class ChatListBaseFragment(private val initDefault: Boolean) : .filter(Optional<BufferViewConfig>::isPresent) .map(Optional<BufferViewConfig>::get) .firstElement() - .toLiveData().observe(this, Observer { + .toLiveData().observe(viewLifecycleOwner, Observer { it?.let { update(it, minimumActivityAdapter, networkAdapter) } @@ -169,11 +169,11 @@ abstract class ChatListBaseFragment(private val initDefault: Boolean) : } override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - if (id == -1L) { + if (NetworkId(id.toInt()).isValidId()) { + showStatusBuffer.isEnabled = true + } else { showStatusBuffer.isChecked = true showStatusBuffer.isEnabled = false - } else { - showStatusBuffer.isEnabled = true } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/MinimumActivityAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/MinimumActivityAdapter.kt index 0d74323e8f42bff223b0c7bdc1fe98fe095f668e..303f053e520c4d2bdbfbef0551014414cf766a1b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/MinimumActivityAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/MinimumActivityAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.coresettings.chatlist import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.Buffer_Activities -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -49,9 +45,8 @@ class MinimumActivityAdapter(val data: List<MinimumActivityItem>) : else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) return MinimumActivityViewHolder( - view + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) ) } @@ -72,17 +67,12 @@ class MinimumActivityAdapter(val data: List<MinimumActivityItem>) : return null } - class MinimumActivityViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class MinimumActivityViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(activity: MinimumActivityItem?) { activity?.let { - text.setText(it.name) + binding.text1.setText(it.name) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/NetworkAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/NetworkAdapter.kt index 0bd71bc604d3cf647cc148b34f77508a4c62006c..c937b7b8ab64e69d096a1ee82bfefee4e926279d 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/NetworkAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/chatlist/NetworkAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,17 +20,13 @@ package de.kuschku.quasseldroid.ui.coresettings.chatlist import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.annotation.StringRes import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -57,13 +53,13 @@ class NetworkAdapter(@StringRes private val fallbackName: Int) : else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) - return NetworkViewHolder(fallbackName, view) + return NetworkViewHolder(fallbackName, + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false)) } fun indexOf(id: NetworkId): Int? { for ((key, item) in data.withIndex()) { - if (item?.networkId ?: -1 == id) { + if (item?.networkId ?: 0 == id) { return key } } @@ -71,20 +67,15 @@ class NetworkAdapter(@StringRes private val fallbackName: Int) : } override fun getItem(position: Int): INetwork.NetworkInfo? = data[position] - override fun getItemId(position: Int) = getItem(position)?.networkId?.id?.toLong() ?: -1 + override fun getItemId(position: Int) = getItem(position)?.networkId?.id?.toLong() ?: 0 override fun hasStableIds() = true override fun getCount() = data.size - class NetworkViewHolder(@StringRes private val fallbackName: Int, itemView: View) : - RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class NetworkViewHolder( + @StringRes private val fallbackName: Int, + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(network: INetwork.NetworkInfo?) { - text.text = network?.networkName ?: itemView.context.getString(fallbackName) + binding.text1.text = network?.networkName ?: itemView.context.getString(fallbackName) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt index cee4362f78e493e2dd5f9e85af6a89745a261ddc..6fcba82d71ad181b84c865125064f372fddf0d5b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightNickTypeAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.coresettings.highlightlist import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.interfaces.IHighlightRuleManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -49,9 +45,8 @@ class HighlightNickTypeAdapter(val data: List<HighlightNickTypeItem>) : else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) return HighlightNickTypeViewHolder( - view + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) ) } @@ -72,17 +67,12 @@ class HighlightNickTypeAdapter(val data: List<HighlightNickTypeItem>) : return null } - class HighlightNickTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class HighlightNickTypeViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(activity: HighlightNickTypeItem?) { activity?.let { - text.setText(it.name) + binding.text1.setText(it.name) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt index 27ab704d3270a1cb0691a472e141900c366d0cf2..6617cd3480e2b92486a7f1b9f4e37104f5e49973 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/highlightlist/HighlightRuleAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,15 +21,10 @@ package de.kuschku.quasseldroid.ui.coresettings.highlightlist import android.view.LayoutInflater import android.view.MotionEvent -import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.SwitchCompat import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.HighlightRuleManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.SettingsHighlightlistRuleBinding import de.kuschku.quasseldroid.util.helper.visibleIf import java.util.* @@ -79,8 +74,7 @@ class HighlightRuleAdapter( override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = HighlightRuleViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.settings_highlightlist_rule, parent, false), + SettingsHighlightlistRuleBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener, ::toggle, dragListener @@ -91,53 +85,25 @@ class HighlightRuleAdapter( } class HighlightRuleViewHolder( - itemView: View, + private val binding: SettingsHighlightlistRuleBinding, clickListener: (HighlightRuleManager.HighlightRule) -> Unit, toggleListener: (HighlightRuleManager.HighlightRule, Boolean) -> Unit, dragListener: (HighlightRuleViewHolder) -> Unit - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.name_row) - lateinit var nameRow: View - - @BindView(R.id.sender) - lateinit var sender: TextView - - @BindView(R.id.sender_row) - lateinit var senderRow: View - - @BindView(R.id.channel) - lateinit var channel: TextView - - @BindView(R.id.channel_row) - lateinit var channelRow: View - - @BindView(R.id.match_all) - lateinit var matchAll: View - - @BindView(R.id.toggle) - lateinit var toggle: SwitchCompat - - @BindView(R.id.handle) - lateinit var handle: View - + ) : RecyclerView.ViewHolder(binding.root) { private var item: HighlightRuleManager.HighlightRule? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { item?.let { clickListener(it) } } - toggle.setOnCheckedChangeListener { _, isChecked -> + binding.toggle.setOnCheckedChangeListener { _, isChecked -> item?.let { toggleListener.invoke(it, isChecked) } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener.invoke(this) } @@ -147,15 +113,15 @@ class HighlightRuleAdapter( fun bind(item: HighlightRuleManager.HighlightRule) { this.item = item - name.text = item.name - nameRow.visibleIf(item.name.isNotBlank()) - sender.text = item.sender - senderRow.visibleIf(item.sender.isNotBlank()) - channel.text = item.channel - channelRow.visibleIf(item.channel.isNotBlank()) - matchAll.visibleIf(item.name.isBlank() && item.sender.isBlank() && item.channel.isBlank()) - - toggle.isChecked = item.isEnabled + binding.name.text = item.name + binding.nameRow.visibleIf(item.name.isNotBlank()) + binding.sender.text = item.sender + binding.senderRow.visibleIf(item.sender.isNotBlank()) + binding.channel.text = item.channel + binding.channelRow.visibleIf(item.channel.isNotBlank()) + binding.matchAll.visibleIf(item.name.isBlank() && item.sender.isBlank() && item.channel.isBlank()) + + binding.toggle.isChecked = item.isEnabled } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityNicksAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityNicksAdapter.kt index a88eca11133f26e9efb165fe1881b02fce7a3d99..9c93b6ed6454d7e08d8b6620afc4b21c49b45c66 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityNicksAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/identity/IdentityNicksAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,13 +21,9 @@ package de.kuschku.quasseldroid.ui.coresettings.identity import android.view.LayoutInflater import android.view.MotionEvent -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.SettingsIdentityNickBinding import java.util.* class IdentityNicksAdapter( @@ -70,8 +66,7 @@ class IdentityNicksAdapter( override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = IdentityNickViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.settings_identity_nick, parent, false), + SettingsIdentityNickBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener, dragListener ) @@ -81,27 +76,19 @@ class IdentityNicksAdapter( } class IdentityNickViewHolder( - itemView: View, + private val binding: SettingsIdentityNickBinding, private val clickListener: (Int, String) -> Unit, dragListener: (IdentityNickViewHolder) -> Unit - ) : - RecyclerView.ViewHolder(itemView) { - @BindView(R.id.nick) - lateinit var nick: TextView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : RecyclerView.ViewHolder(binding.root) { private var item: String? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { item?.let { clickListener(adapterPosition, it) } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener.invoke(this) } @@ -111,7 +98,7 @@ class IdentityNicksAdapter( fun bind(item: String) { this.item = item - nick.text = item + binding.nick.text = item } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreTypeAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreTypeAdapter.kt index d1b9008ed6c50ab4075a87f8fdceca07545fab90..2edb86a3a48611be0275db652c0f7b1a29d8f0d4 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreTypeAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/IgnoreTypeAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.coresettings.ignoreitem import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.IgnoreListManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -49,9 +45,8 @@ class IgnoreTypeAdapter(val data: List<IgnoreTypeItem>) : else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) return IgnoreTypeViewHolder( - view + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) ) } @@ -72,17 +67,12 @@ class IgnoreTypeAdapter(val data: List<IgnoreTypeItem>) : return null } - class IgnoreTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class IgnoreTypeViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(activity: IgnoreTypeItem?) { activity?.let { - text.setText(it.name) + binding.text1.setText(it.name) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/ScopeTypeAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/ScopeTypeAdapter.kt index f039fe15c9e53a8b01f4b35ca0fe4a6f05288030..1d0f4a1b8e7facfe94dfa113529ad41febf24613 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/ScopeTypeAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/ScopeTypeAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.coresettings.ignoreitem import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.IgnoreListManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -49,9 +45,8 @@ class ScopeTypeAdapter(val data: List<ScopeTypeItem>) : else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) return ScopeTypeViewHolder( - view + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) ) } @@ -72,17 +67,12 @@ class ScopeTypeAdapter(val data: List<ScopeTypeItem>) : return null } - class ScopeTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class ScopeTypeViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(activity: ScopeTypeItem?) { activity?.let { - text.setText(it.name) + binding.text1.setText(it.name) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/StrictnessTypeAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/StrictnessTypeAdapter.kt index a9f1dcbc4a02c8edd5342c5548eabfe1bd70560b..4963c098e408abd55d8569457d407d769de4a56f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/StrictnessTypeAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignoreitem/StrictnessTypeAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.ui.coresettings.ignoreitem import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.IgnoreListManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -49,9 +45,8 @@ class StrictnessTypeAdapter(val data: List<StrictnessTypeItem>) : else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) return StrictnessTypeViewHolder( - view + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) ) } @@ -72,17 +67,12 @@ class StrictnessTypeAdapter(val data: List<StrictnessTypeItem>) : return null } - class StrictnessTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class StrictnessTypeViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(activity: StrictnessTypeItem?) { activity?.let { - text.setText(it.name) + binding.text1.setText(it.name) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt index cd8b17d2a77597f8b90d2ab2e747c0cfe145f24b..962ffd1bd71d4e3ef8db436e7cb1465101396474 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/ignorelist/IgnoreListAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,15 +21,10 @@ package de.kuschku.quasseldroid.ui.coresettings.ignorelist import android.view.LayoutInflater import android.view.MotionEvent -import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.SwitchCompat import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.IgnoreListManager -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.SettingsIgnorelistItemBinding import de.kuschku.quasseldroid.util.helper.visibleIf import java.util.* @@ -79,7 +74,7 @@ class IgnoreListAdapter( override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = IgnoreItemViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.settings_ignorelist_item, parent, false), + SettingsIgnorelistItemBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener, ::toggle, dragListener @@ -90,38 +85,25 @@ class IgnoreListAdapter( } class IgnoreItemViewHolder( - itemView: View, + private val binding: SettingsIgnorelistItemBinding, clickListener: (IgnoreListManager.IgnoreListItem) -> Unit, toggleListener: (IgnoreListManager.IgnoreListItem, Boolean) -> Unit, dragListener: (IgnoreItemViewHolder) -> Unit - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.ignore_rule) - lateinit var ignoreRule: TextView - - @BindView(R.id.scope_rule) - lateinit var scopeRule: TextView - - @BindView(R.id.toggle) - lateinit var toggle: SwitchCompat - - @BindView(R.id.handle) - lateinit var handle: View - + ) : RecyclerView.ViewHolder(binding.root) { private var item: IgnoreListManager.IgnoreListItem? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { item?.let { clickListener(it) } } - toggle.setOnCheckedChangeListener { _, isChecked -> + binding.toggle.setOnCheckedChangeListener { _, isChecked -> item?.let { toggleListener.invoke(it, isChecked) } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener.invoke(this) } @@ -131,10 +113,10 @@ class IgnoreListAdapter( fun bind(item: IgnoreListManager.IgnoreListItem) { this.item = item - ignoreRule.text = item.ignoreRule - scopeRule.text = item.scopeRule - scopeRule.visibleIf(item.scopeRule.isNotBlank() && item.scope != IgnoreListManager.ScopeType.GlobalScope) - toggle.isChecked = item.isActive + binding.ignoreRule.text = item.ignoreRule + binding.scopeRule.text = item.scopeRule + binding.scopeRule.visibleIf(item.scopeRule.isNotBlank() && item.scope != IgnoreListManager.ScopeType.GlobalScope) + binding.toggle.isChecked = item.isActive } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/IdentityAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/IdentityAdapter.kt index 4c9692791c068959a3f132919f3166b0d11a6238..4624ecadcde9c4cf997259c1ab19f6edb3a891c6 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/IdentityAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/IdentityAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,16 +20,12 @@ package de.kuschku.quasseldroid.ui.coresettings.network import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.IdentityId import de.kuschku.libquassel.quassel.syncables.Identity -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -47,12 +43,13 @@ class IdentityAdapter : RecyclerSpinnerAdapter<IdentityAdapter.NetworkViewHolder override fun onBindViewHolder(holder: NetworkViewHolder, position: Int) = holder.bind(getItem(position)) - override fun onCreateViewHolder(parent: ViewGroup, dropDown: Boolean) - : NetworkViewHolder { + override fun onCreateViewHolder(parent: ViewGroup, dropDown: Boolean): NetworkViewHolder { val inflater = LayoutInflater.from( if (dropDown) ContextThemeWrapper(parent.context, dropDownViewTheme) else parent.context ) - return NetworkViewHolder(inflater.inflate(R.layout.widget_spinner_item_material, parent, false)) + return NetworkViewHolder( + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) + ) } fun indexOf(id: IdentityId): Int? { @@ -73,16 +70,11 @@ class IdentityAdapter : RecyclerSpinnerAdapter<IdentityAdapter.NetworkViewHolder override fun getCount() = data.size - class NetworkViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class NetworkViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(network: Identity?) { - text.text = network?.identityName() + binding.text1.text = network?.identityName() } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkServerAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkServerAdapter.kt index 7b2832685ec60d680fda954e49b7a43da43ae1c8..30a2d4ff90ffe9959b8a45a85d1fbb1ddf5cd449 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkServerAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/network/NetworkServerAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,15 +22,11 @@ package de.kuschku.quasseldroid.ui.coresettings.network import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.MotionEvent -import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.SettingsNetworkServerBinding import de.kuschku.quasseldroid.util.helper.getVectorDrawableCompat import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.helper.tint @@ -86,7 +82,7 @@ class NetworkServerAdapter( override fun getItemCount() = data.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = NetworkServerViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.settings_network_server, parent, false), + SettingsNetworkServerBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener, dragListener ) @@ -96,22 +92,10 @@ class NetworkServerAdapter( } class NetworkServerViewHolder( - itemView: View, + private val binding: SettingsNetworkServerBinding, clickListener: (INetwork.Server) -> Unit, dragListener: (NetworkServerViewHolder) -> Unit - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.host) - lateinit var host: TextView - - @BindView(R.id.port) - lateinit var port: TextView - - @BindView(R.id.ssl_enabled) - lateinit var sslEnabled: ImageView - - @BindView(R.id.handle) - lateinit var handle: View - + ) : RecyclerView.ViewHolder(binding.root) { private var item: INetwork.Server? = null private val secure: Drawable? @@ -119,13 +103,12 @@ class NetworkServerAdapter( private val insecure: Drawable? init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { item?.let { clickListener(it) } } - handle.setOnTouchListener { _, event -> + binding.handle.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { dragListener.invoke(this) } @@ -147,9 +130,9 @@ class NetworkServerAdapter( fun bind(item: INetwork.Server) { this.item = item - host.text = item.host - port.text = item.port.toString() - sslEnabled.setImageDrawable( + binding.host.text = item.host + binding.port.text = item.port.toString() + binding.sslEnabled.setImageDrawable( when { item.useSsl && item.sslVerify -> secure item.useSsl -> partiallySecure diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/ProxyTypeAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/ProxyTypeAdapter.kt index e45e17ec20e0db343a8188544906b39153bae95c..62a974ac8e6086cb0415466a86ea537498e2cfb9 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/ProxyTypeAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/networkserver/ProxyTypeAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,14 +20,10 @@ package de.kuschku.quasseldroid.ui.coresettings.networkserver import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper import de.kuschku.quasseldroid.util.ui.RecyclerSpinnerAdapter @@ -47,7 +43,7 @@ class ProxyTypeAdapter(val data: List<ProxyTypeItem>) : else parent.context ) return ProxyTypeViewHolder( - inflater.inflate(R.layout.widget_spinner_item_material, parent, false) + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) ) } @@ -68,17 +64,12 @@ class ProxyTypeAdapter(val data: List<ProxyTypeItem>) : return null } - class ProxyTypeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class ProxyTypeViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(activity: ProxyTypeItem?) { activity?.let { - text.setText(it.name) + binding.text1.setText(it.name) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt index 6bb3d6fa373284afa8793ebd092431f7a33f2f9b..1f6c77c5e5e9a512bc3b50fca9ba5c5437b98492 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/passwordchange/PasswordChangeFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -38,6 +38,7 @@ import de.kuschku.libquassel.util.helper.mapMapNullable import de.kuschku.libquassel.util.helper.mapSwitchMap import de.kuschku.libquassel.util.helper.value import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.dao.findById import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.models.Account import de.kuschku.quasseldroid.util.TextValidator diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt index 7b2881f2a4cf2606ce1dc10b67913440a7025924..d79a732d9916d02fb05cde1ddffb88fe6348e99b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/channellist/ChannelListAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,17 +22,13 @@ package de.kuschku.quasseldroid.ui.info.channellist import android.content.Context import android.graphics.drawable.Drawable import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.syncables.IrcListHelper import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetChannelSearchBinding import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.util.ColorContext import de.kuschku.quasseldroid.util.helper.styledAttributes @@ -63,7 +59,7 @@ class ChannelListAdapter @Inject constructor( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelViewHolder { return ChannelViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_channel_search, parent, false), + WidgetChannelSearchBinding.inflate(LayoutInflater.from(parent.context), parent, false), contentFormatter, fallbackDrawable ) @@ -74,27 +70,14 @@ class ChannelListAdapter @Inject constructor( } class ChannelViewHolder( - itemView: View, + private val binding: WidgetChannelSearchBinding, private val contentFormatter: ContentFormatter, fallbackDrawable: Drawable - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.users) - lateinit var users: TextView - - @BindView(R.id.topic) - lateinit var topic: TextView - + ) : RecyclerView.ViewHolder(binding.root) { private var data: IrcListHelper.ChannelDescription? = null init { - ButterKnife.bind(this, itemView) - status.setImageDrawable(fallbackDrawable) + binding.status.setImageDrawable(fallbackDrawable) itemView.setOnClickListener { data?.let { ChatActivity.launch( @@ -107,13 +90,13 @@ class ChannelListAdapter @Inject constructor( } fun bind(data: IrcListHelper.ChannelDescription) { - name.text = data.channelName + binding.name.text = data.channelName val (content, hasSpoilers) = contentFormatter.formatContent( data.topic, networkId = data.netId ) - topic.text = content - users.text = itemView.context.resources.getQuantityString(R.plurals.label_user_count, + binding.topic.text = content + binding.users.text = itemView.context.resources.getQuantityString(R.plurals.label_user_count, data.userCount.toInt(), data.userCount.toInt()) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt index 4c6c7f6da791a2ce164d3c33dd35cff1f98a373b..a504286ac928dfdd9c3c932f0ac17979933e3ef3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/core/ClientAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,19 +22,14 @@ package de.kuschku.quasseldroid.ui.info.core import android.graphics.drawable.Drawable import android.text.Html import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.Button -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.quassel.ExtendedFeature import de.kuschku.libquassel.quassel.syncables.CoreInfo import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetClientBinding import de.kuschku.quasseldroid.util.helper.getVectorDrawableCompat import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.helper.tint @@ -71,7 +66,7 @@ class ClientAdapter : ListAdapter<CoreInfo.ConnectedClientData, ClientAdapter.Cl } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ClientViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_client, parent, false), + WidgetClientBinding.inflate(LayoutInflater.from(parent.context), parent, false), dateTimeFormatter, dateFormatter, ::disconnect, @@ -85,30 +80,12 @@ class ClientAdapter : ListAdapter<CoreInfo.ConnectedClientData, ClientAdapter.Cl holder.bind(getItem(position)) class ClientViewHolder( - itemView: View, + private val binding: WidgetClientBinding, private val dateTimeFormatter: DateTimeFormatter, private val dateFormatter: DateTimeFormatter, private val disconnectListener: (Int) -> Unit, movementMethod: BetterLinkMovementMethod - ) : RecyclerView.ViewHolder(itemView) { - - @BindView(R.id.ip) - lateinit var ip: TextView - - @BindView(R.id.version) - lateinit var version: TextView - - @BindView(R.id.uptime) - lateinit var uptime: TextView - - @BindView(R.id.location) - lateinit var location: TextView - - @BindView(R.id.secure_icon) - lateinit var secureIcon: ImageView - - @BindView(R.id.disconnect) - lateinit var disconnect: Button + ) : RecyclerView.ViewHolder(binding.root) { private var id: Int? = null @@ -116,9 +93,8 @@ class ClientAdapter : ListAdapter<CoreInfo.ConnectedClientData, ClientAdapter.Cl private val insecure: Drawable? init { - ButterKnife.bind(this, itemView) - version.movementMethod = movementMethod - disconnect.setOnClickListener { + binding.version.movementMethod = movementMethod + binding.disconnect.setOnClickListener { id?.let(disconnectListener::invoke) } @@ -136,21 +112,21 @@ class ClientAdapter : ListAdapter<CoreInfo.ConnectedClientData, ClientAdapter.Cl fun bind(data: CoreInfo.ConnectedClientData) { id = data.id - ip.text = data.remoteAddress + binding.ip.text = data.remoteAddress val versionTime = data.clientVersionDate.toLongOrNull() val formattedVersionTime = if (versionTime != null) dateFormatter.format(Instant.ofEpochSecond(versionTime).atZone(ZoneId.systemDefault())) else data.clientVersionDate - version.text = Html.fromHtml(data.clientVersion + " ($formattedVersionTime)") + binding.version.text = Html.fromHtml(data.clientVersion + " ($formattedVersionTime)") val connectedSinceFormatted = dateTimeFormatter.format(data.connectedSince.atZone(ZoneId.systemDefault())) - uptime.text = itemView.context.getString(R.string.label_core_connected_since, - connectedSinceFormatted) - location.text = data.location - location.visibleIf(data.location.isNotBlank()) + binding.uptime.text = itemView.context.getString(R.string.label_core_connected_since, + connectedSinceFormatted) + binding.location.text = data.location + binding.location.visibleIf(data.location.isNotBlank()) - secureIcon.setImageDrawable(if (data.secure) secure else insecure) - disconnect.visibleIf(data.features.hasFeature(ExtendedFeature.RemoteDisconnect)) + binding.secureIcon.setImageDrawable(if (data.secure) secure else insecure) + binding.disconnect.visibleIf(data.features.hasFeature(ExtendedFeature.RemoteDisconnect)) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/ChannelAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/ChannelAdapter.kt index d58c3b103dc538c2268699c435bf60e24804b2fc..365450c1d74bb594f3636c4d11c05b6069af46e0 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/ChannelAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/ChannelAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,17 +20,12 @@ package de.kuschku.quasseldroid.ui.info.user import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetBufferBinding import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.util.helper.visibleIf import de.kuschku.quasseldroid.util.lists.ListAdapter @@ -51,9 +46,7 @@ class ChannelAdapter : ListAdapter<BufferProps, ChannelAdapter.ChannelViewHolder } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ChannelViewHolder( - LayoutInflater.from(parent.context).inflate( - R.layout.widget_buffer, parent, false - ), + WidgetBufferBinding.inflate(LayoutInflater.from(parent.context), parent, false), clickListener = clickListener ) @@ -61,22 +54,12 @@ class ChannelAdapter : ListAdapter<BufferProps, ChannelAdapter.ChannelViewHolder holder.bind(getItem(position)) class ChannelViewHolder( - itemView: View, + private val binding: WidgetBufferBinding, private val clickListener: ((NetworkId, String) -> Unit)? = null - ) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.status) - lateinit var status: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - + ) : RecyclerView.ViewHolder(binding.root) { var info: BufferInfo? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { info?.let { ChatActivity.launch( @@ -91,12 +74,12 @@ class ChannelAdapter : ListAdapter<BufferProps, ChannelAdapter.ChannelViewHolder fun bind(props: BufferProps) { info = props.info - name.text = props.info.bufferName - description.text = props.description + binding.name.text = props.info.bufferName + binding.description.text = props.description - description.visibleIf(props.description.isNotBlank()) + binding.description.visibleIf(props.description.isNotBlank()) - status.setImageDrawable(props.fallbackDrawable) + binding.status.setImageDrawable(props.fallbackDrawable) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt index 6c31f7e48a0ca5472a79c6122e7cc8cef8f8e7ba..0ef69a9d417536a31a1ba5f05c4eafe61fd25edb 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -21,20 +21,21 @@ package de.kuschku.quasseldroid.ui.setup.accounts.edit import android.content.Context import android.content.Intent +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity class AccountEditActivity : SettingsActivity(AccountEditFragment()) { companion object { fun launch( context: Context, - account: Long + account: AccountId ) = context.startActivity(intent(context, account)) fun intent( context: Context, - account: Long + account: AccountId ) = Intent(context, AccountEditActivity::class.java).apply { - putExtra("account", account) + putExtra("account", account.id) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt index f2edca7219eb486d5aeea2e5f88cff4d81a7eb5d..1b35c06b80cc021f6ea36f20c9b12b878ec4bad3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -35,8 +35,10 @@ import butterknife.ButterKnife import com.google.android.material.textfield.TextInputLayout import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.dao.findById import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.models.Account +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.util.Patterns import de.kuschku.quasseldroid.util.TextValidator import de.kuschku.quasseldroid.util.helper.editCommit @@ -79,7 +81,7 @@ class AccountEditFragment : SettingsFragment(), Changeable, Savable, Deletable { lateinit var database: AccountDatabase private var account: Account? = null - private var accountId: Long = -1L + private var accountId: AccountId = AccountId(-1L) private lateinit var handlerThread: HandlerThread private lateinit var handler: Handler @@ -104,8 +106,8 @@ class AccountEditFragment : SettingsFragment(), Changeable, Savable, Deletable { setHasOptionsMenu(true) handler.post { - accountId = arguments?.getLong("account", -1) ?: -1 - if (accountId == -1L) { + accountId = AccountId(arguments?.getLong("account", -1L) ?: -1L) + if (!accountId.isValidId()) { activity?.setResult(Activity.RESULT_CANCELED) activity?.finish() } @@ -187,8 +189,8 @@ class AccountEditFragment : SettingsFragment(), Changeable, Savable, Deletable { handler.post { account?.let { val preferences = activity?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) - if (preferences?.getLong(Keys.Status.selectedAccount, -1) == it.id) { - preferences.editCommit { + if (AccountId(preferences?.getLong(Keys.Status.selectedAccount, -1) ?: -1) == it.id) { + preferences?.editCommit { remove(Keys.Status.selectedAccount) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt index 4d35029842ecb6b5890a83367353f1a33bf0f028..381b9e592c46a739dda5ecf4991d798c19b5be5c 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -19,117 +19,58 @@ package de.kuschku.quasseldroid.ui.setup.accounts.selection -import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.AppCompatImageButton -import androidx.appcompat.widget.AppCompatRadioButton -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetCoreAccountAddBinding +import de.kuschku.quasseldroid.databinding.WidgetCoreAccountBinding import de.kuschku.quasseldroid.persistence.models.Account -import de.kuschku.quasseldroid.util.helper.zip - -class AccountAdapter( - owner: LifecycleOwner, - liveData: LiveData<List<Account>>, - private val selectedItem: MutableLiveData<Pair<Long, Long>> -) : RecyclerView.Adapter<AccountAdapter.AccountViewHolder>() { - private val actionListeners = mutableSetOf<(Long) -> Unit>() - private val addListeners = mutableSetOf<() -> Unit>() - private val selectionListeners = mutableSetOf<(Long) -> Unit>() +import de.kuschku.quasseldroid.persistence.util.AccountId +import de.kuschku.quasseldroid.util.lists.ListAdapter - private val clickListener = object : - ItemListener { - override fun onAction(id: Long, pos: Int) { - selectionListener.invoke(id) - } +class AccountAdapter : ListAdapter<Pair<Account?, Boolean>, AccountAdapter.AccountViewHolder>( + object : DiffUtil.ItemCallback<Pair<Account?, Boolean>>() { + override fun areItemsTheSame(oldItem: Pair<Account?, Boolean>, + newItem: Pair<Account?, Boolean>) = + oldItem.first?.id == newItem.first?.id + + override fun areContentsTheSame(oldItem: Pair<Account?, Boolean>, + newItem: Pair<Account?, Boolean>) = + oldItem == newItem } +) { + private val actionListeners = mutableSetOf<(AccountId) -> Unit>() + private val addListeners = mutableSetOf<() -> Unit>() + private val clickListeners = mutableSetOf<(AccountId) -> Unit>() - private val actionListener = object : - ItemListener { - override fun onAction(id: Long, pos: Int) { + private val actionListener = object : ItemListener { + override fun onAction(id: AccountId, pos: Int) { for (actionListener in actionListeners) { actionListener.invoke(id) } } } - private fun updateSelection(id: Long) { - selectedItem.value = Pair(selectedItem.value?.second ?: -1, id) - } - - private val selectionListener = { id: Long -> - updateSelection(id) - for (selectionListener in selectionListeners) { - selectionListener.invoke(id) + private val addListener = object : AddListener { + override fun onAction() { + for (addListener in addListeners) { + addListener.invoke() + } } } - val selectedItemId - get() = selectedItem.value?.second - - private var list: List<Pair<Boolean, Account>> = emptyList() - - init { - selectedItem.value = Pair(-1, -1) - - liveData.zip(selectedItem).observe(owner, Observer { it -> - val list = it?.first - val oldSelected = it?.second?.first ?: -1 - val selected = it?.second?.second ?: -1 - - val oldList = this.list - val newList: List<Pair<Boolean, Account>> = list.orEmpty().map { - Pair(selected == it.id, it) + private val clickListener = object : ItemListener { + override fun onAction(id: AccountId, pos: Int) { + for (clickListener in clickListeners) { + clickListener.invoke(id) } - this.list = newList - - DiffUtil.calculateDiff(object : DiffUtil.Callback() { - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - val oldItem = oldList[oldItemPosition].second - val newItem = newList[newItemPosition].second - - return oldItem.id == newItem.id - } - - override fun getOldListSize(): Int { - return oldList.size - } - - override fun getNewListSize(): Int { - return newList.size - } - - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - val oldItem = oldList[oldItemPosition].second - val newItem = newList[newItemPosition].second - - return oldItem == newItem && - oldItem.id != selected && - newItem.id != selected && - oldItem.id != oldSelected && - newItem.id != oldSelected - } - }).dispatchUpdatesTo(this) - }) - } - - private val addListener = { - for (addListener in addListeners) { - addListener.invoke() } } - fun addEditListener(f: (Long) -> Unit) { + fun addEditListener(f: (AccountId) -> Unit) { actionListeners.add(f) } @@ -137,47 +78,30 @@ class AccountAdapter( addListeners.add(f) } - fun addSelectionListener(f: (Long) -> Unit) { - selectionListeners.add(f) + fun addClickListener(f: (AccountId) -> Unit) { + clickListeners.add(f) } - override fun onBindViewHolder(holder: AccountViewHolder, - @SuppressLint("RecyclerView") position: Int) { - when (holder) { - is AccountViewHolder.Item -> { - val item = list[position] - holder.bind(item.second, item.first) - } - is AccountViewHolder.Add -> { - } - } + override fun onBindViewHolder(holder: AccountViewHolder, position: Int) { + val (account, selected) = getItem(position) + holder.bind(account, selected) } - override fun getItemViewType(position: Int) = when (position) { - list.size -> TYPE_ADD - else -> TYPE_ACCOUNT + override fun getItemViewType(position: Int) = when (getItem(position).first) { + null -> TYPE_ADD + else -> TYPE_ACCOUNT } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccountViewHolder { - val inflater = LayoutInflater.from(parent.context) - val view = inflater.inflate( - when (viewType) { - TYPE_ADD -> R.layout.widget_core_account_add - else -> R.layout.widget_core_account - }, parent, false + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) { + TYPE_ADD -> AccountViewHolder.Add( + WidgetCoreAccountAddBinding.inflate(LayoutInflater.from(parent.context), parent, false), + addListener + ) + else -> AccountViewHolder.Item( + WidgetCoreAccountBinding.inflate(LayoutInflater.from(parent.context), parent, false), + actionListener, + clickListener ) - return when (viewType) { - TYPE_ADD -> AccountViewHolder.Add( - view, addListener - ) - else -> AccountViewHolder.Item( - view, actionListener, clickListener - ) - } - } - - override fun getItemCount(): Int { - return list.size + 1 } companion object { @@ -185,64 +109,54 @@ class AccountAdapter( private const val TYPE_ADD = 1 } - fun selectAccount(id: Long) { - selectionListener(id) + interface ItemListener { + fun onAction(id: AccountId, pos: Int) } - interface ItemListener { - fun onAction(id: Long, pos: Int) + interface AddListener { + fun onAction() } sealed class AccountViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - internal var data: Account? = null - - class Item(itemView: View, actionListener: ItemListener, clickListener: ItemListener) - : AccountViewHolder(itemView) { - @BindView(R.id.account_name) - lateinit var accountName: TextView - - @BindView(R.id.account_description) - lateinit var accountDescription: TextView + abstract fun bind(account: Account?, selected: Boolean) - @BindView(R.id.account_select) - lateinit var accountSelect: AppCompatRadioButton - - @BindView(R.id.account_edit) - lateinit var accountEdit: AppCompatImageButton + class Item( + private val binding: WidgetCoreAccountBinding, + actionListener: ItemListener, + clickListener: ItemListener + ) : AccountViewHolder(binding.root) { + private var data: Account? = null init { - ButterKnife.bind(this, itemView) - accountEdit.setOnClickListener { - actionListener.onAction(data?.id ?: -1L, adapterPosition) + binding.accountEdit.setOnClickListener { + actionListener.onAction(data?.id ?: AccountId(-1L), adapterPosition) } itemView.setOnClickListener { - clickListener.onAction(data?.id ?: -1L, adapterPosition) + clickListener.onAction(data?.id ?: AccountId(-1L), adapterPosition) } } - fun bind(account: Account, selected: Boolean) { + override fun bind(account: Account?, selected: Boolean) { data = account - accountName.text = account.name - accountDescription.text = itemView.context.resources.getString( - R.string.label_user_on_host, account.user, account.host, account.port + binding.accountName.text = account?.name + binding.accountDescription.text = itemView.context.resources.getString( + R.string.label_user_on_host, account?.user, account?.host, account?.port ) - accountSelect.isChecked = selected - } - - fun clear() { - data = null - accountName.text = "" - accountDescription.text = "" - accountSelect.isChecked = false + binding.accountSelect.isChecked = selected } } - class Add(itemView: View, clickListener: () -> Unit) : AccountViewHolder(itemView) { + class Add( + private val binding: WidgetCoreAccountAddBinding, + clickListener: AddListener + ) : AccountViewHolder(binding.root) { init { itemView.setOnClickListener { - clickListener.invoke() + clickListener.onAction() } } + + override fun bind(account: Account?, selected: Boolean) = Unit } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt index b2de628ce0e8a0d966a6a92c4df9cc3764611572..91dac04bed4d585a60b12994547a4ea9d33b95b1 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -31,13 +31,17 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import butterknife.BindView import butterknife.ButterKnife +import de.kuschku.libquassel.protocol.BufferId import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.models.Account +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.ui.setup.SlideFragment import de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditActivity import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity.Companion.REQUEST_CREATE_FIRST import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity.Companion.REQUEST_CREATE_NEW import de.kuschku.quasseldroid.ui.setup.accounts.setup.AccountSetupActivity +import de.kuschku.quasseldroid.util.helper.map +import de.kuschku.quasseldroid.util.helper.zip import javax.inject.Inject class AccountSelectionSlide : SlideFragment() { @@ -47,23 +51,26 @@ class AccountSelectionSlide : SlideFragment() { @Inject lateinit var accountViewModel: AccountViewModel - override fun isValid() = adapter?.selectedItemId ?: -1L != -1L + override fun isValid() = accountViewModel.selectedItem.value?.isValidId() == true override val title = R.string.slide_account_select_title override val description = R.string.slide_account_select_description override fun setData(data: Bundle) { - if (data.containsKey("selectedAccount")) - adapter?.selectAccount(data.getLong("selectedAccount")) + if (data.containsKey("selectedAccount")) { + accountViewModel.selectedItem.postValue(AccountId(data.getLong("selectedAccount"))) + } } override fun getData(data: Bundle) { - data.putLong("selectedAccount", adapter?.selectedItemId ?: -1L) + data.putLong("selectedAccount", accountViewModel.selectedItem.value?.id ?: -1L) } - private var adapter: AccountAdapter? = null + private val adapter = AccountAdapter() + override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + BufferId val view = inflater.inflate(R.layout.setup_select_account, container, false) ButterKnife.bind(this, view) val firstObserver = object : Observer<List<Account>?> { @@ -79,10 +86,6 @@ class AccountSelectionSlide : SlideFragment() { accountViewModel.accounts.observe(this, firstObserver) accountList.layoutManager = LinearLayoutManager(context) accountList.itemAnimator = DefaultItemAnimator() - val adapter = AccountAdapter( - this, accountViewModel.accounts, accountViewModel.selectedItem - ) - this.adapter = adapter accountList.adapter = adapter adapter.addAddListener { @@ -91,10 +94,16 @@ class AccountSelectionSlide : SlideFragment() { adapter.addEditListener { id -> startActivityForResult(AccountEditActivity.intent(requireContext(), id), REQUEST_CREATE_NEW) } - adapter.addSelectionListener { + adapter.addClickListener { updateValidity() } + accountViewModel.accounts.zip(accountViewModel.selectedItem).map { (accounts, selected) -> + accounts.map { Pair(it, it.id == selected) } + }.observe(this, Observer { + adapter.submitList((it ?: emptyList()) + Pair(null, false)) + }) + return view } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt index f3ca61e38c5aebfe1ed5e38d184bb4cb3a7a3234..881cc936f5441ec0cc33ec752f52a2211e89105a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -25,11 +25,12 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.models.Account +import de.kuschku.quasseldroid.persistence.util.AccountId class AccountViewModel(application: Application) : AndroidViewModel(application) { private val database: AccountDatabase = AccountDatabase.Creator.init( getApplication() ) val accounts: LiveData<List<Account>> = database.accounts().all() - val selectedItem = MutableLiveData<Pair<Long, Long>>() + val selectedItem = MutableLiveData<AccountId>() } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt index 8de4b8cadbeedfa935596891669650c91185989e..883b9c3e9cad75119d1602d23fe37a709c98d62e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -23,8 +23,10 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle +import de.kuschku.quasseldroid.persistence.dao.create import de.kuschku.quasseldroid.persistence.db.AccountDatabase import de.kuschku.quasseldroid.persistence.models.Account +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.ui.setup.SetupActivity import de.kuschku.quasseldroid.util.AndroidHandlerThread import org.threeten.bp.Instant @@ -37,8 +39,8 @@ class AccountSetupActivity : SetupActivity() { lateinit var database: AccountDatabase override fun onDone(data: Bundle) { - val account = Account( - id = 0, + val account = Account.of( + id = AccountId(-1L), host = data.getString("host", ""), port = data.getInt("port"), requireSsl = data.getBoolean("require_ssl"), diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendAdapter.kt index 1d8d2456729264ddcb957eaabffb840974e32813..a2969528138022bf8e98dfaf7240800da5fd8893 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/core/CoreBackendAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,16 +20,11 @@ package de.kuschku.quasseldroid.ui.setup.core import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.widget.AppCompatRadioButton import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.libquassel.protocol.coresetup.CoreSetupBackend -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetCoreBackendBinding class CoreBackendAdapter : RecyclerView.Adapter<CoreBackendAdapter.BackendViewHolder>() { private val selectionListeners = mutableSetOf<(CoreSetupBackend) -> Unit>() @@ -105,29 +100,21 @@ class CoreBackendAdapter : RecyclerView.Adapter<CoreBackendAdapter.BackendViewHo holder.bind(item.second, item.first) } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BackendViewHolder { - val inflater = LayoutInflater.from(parent.context) - val view = inflater.inflate(R.layout.widget_core_backend, parent, false) - return BackendViewHolder(view, clickListener) - } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = BackendViewHolder( + WidgetCoreBackendBinding.inflate(LayoutInflater.from(parent.context), parent, false), + clickListener + ) override fun getItemCount() = list.size - class BackendViewHolder(itemView: View, clickListener: (CoreSetupBackend) -> Unit) : - RecyclerView.ViewHolder(itemView) { - @BindView(R.id.backend_name) - lateinit var backendName: TextView - - @BindView(R.id.backend_description) - lateinit var backendDescription: TextView - - @BindView(R.id.backend_select) - lateinit var backendSelect: AppCompatRadioButton - + class BackendViewHolder( + private val binding: WidgetCoreBackendBinding, + clickListener: (CoreSetupBackend) -> Unit + ) : + RecyclerView.ViewHolder(binding.root) { private var item: CoreSetupBackend? = null init { - ButterKnife.bind(this, itemView) itemView.setOnClickListener { item?.let(clickListener) } @@ -135,16 +122,9 @@ class CoreBackendAdapter : RecyclerView.Adapter<CoreBackendAdapter.BackendViewHo fun bind(backend: CoreSetupBackend, selected: Boolean) { item = backend - backendName.text = backend.displayName - backendDescription.text = backend.description - backendSelect.isChecked = selected - } - - fun clear() { - item = null - backendName.text = "" - backendDescription.text = "" - backendSelect.isChecked = false + binding.backendName.text = backend.displayName + binding.backendDescription.text = backend.description + binding.backendSelect.isChecked = selected } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/DefaultNetworkAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/DefaultNetworkAdapter.kt index 9d34f609c0fc22743559626a5618094ccd6feee1..9f8ebb44701c196b310334303afc605b53ec2bcd 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/DefaultNetworkAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/user/DefaultNetworkAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,14 +20,11 @@ package de.kuschku.quasseldroid.ui.setup.user import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.appcompat.widget.ThemedSpinnerAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetSpinnerItemMaterialBinding import de.kuschku.quasseldroid.defaults.DefaultNetwork import de.kuschku.quasseldroid.defaults.DefaultNetworks import de.kuschku.quasseldroid.util.ui.ContextThemeWrapper @@ -43,16 +40,16 @@ class DefaultNetworkAdapter @Inject constructor(defaultNetworks: DefaultNetworks override fun onBindViewHolder(holder: DefaultNetworkViewHolder, position: Int) = holder.bind(getItem(position)) - override fun onCreateViewHolder(parent: ViewGroup, dropDown: Boolean) - : DefaultNetworkViewHolder { + override fun onCreateViewHolder(parent: ViewGroup, dropDown: Boolean): DefaultNetworkViewHolder { val inflater = LayoutInflater.from( if (dropDown) ContextThemeWrapper(parent.context, dropDownViewTheme) else parent.context ) - val view = inflater.inflate(R.layout.widget_spinner_item_material, parent, false) - return DefaultNetworkViewHolder(view) + return DefaultNetworkViewHolder( + WidgetSpinnerItemMaterialBinding.inflate(inflater, parent, false) + ) } override fun getItem(position: Int) = data[position] @@ -65,18 +62,13 @@ class DefaultNetworkAdapter @Inject constructor(defaultNetworks: DefaultNetworks override fun getItemId(position: Int) = position.toLong() - class DefaultNetworkViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(android.R.id.text1) - lateinit var text: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class DefaultNetworkViewHolder( + private val binding: WidgetSpinnerItemMaterialBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(network: DefaultNetwork?) { network?.let { - text.text = it.name - } ?: text.setText(R.string.label_network_custom) + binding.text1.text = it.name + } ?: binding.text1.setText(R.string.label_network_custom) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt index c7b2d883c5f0e316d593679ca98e886c07c3fb9f..77d31d5a1a712245e910dba237a9b3a5906aef3e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ShortcutCreationHelper.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -27,7 +27,7 @@ import android.graphics.drawable.Drawable import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat -import com.bumptech.glide.request.target.SimpleTarget +import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.quassel.BufferInfo @@ -36,6 +36,7 @@ import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.util.avatars.AvatarHelper @@ -46,9 +47,11 @@ import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper.Companion. object ShortcutCreationHelper { fun create(context: Context, messageSettings: MessageSettings, - accountId: Long, + accountId: AccountId, info: BufferInfo, ircUser: IrcUser? = null) { + val bitmapSize = context.resources.getInteger(R.integer.shortcut_image_size) + val callback: (IconCompat) -> Unit = { icon -> ShortcutManagerCompat.requestPinShortcut( context, @@ -59,7 +62,7 @@ object ShortcutCreationHelper { ChatActivity.intent( context, bufferId = info.bufferId, - accountId = accountId + accountId = accountId.id ).setAction(Intent.ACTION_VIEW) ) .build(), @@ -68,7 +71,7 @@ object ShortcutCreationHelper { } val resultAvailable: (Drawable) -> Unit = { resource -> - val bitmap = Bitmap.createBitmap(432, 432, Bitmap.Config.ARGB_8888) + val bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888) val canvas = Canvas(bitmap) resource.setBounds(0, 0, canvas.width, canvas.height) resource.draw(canvas) @@ -103,7 +106,7 @@ object ShortcutCreationHelper { .buildRect(initial, senderColor) val urls = ircUser?.let { - AvatarHelper.avatar(messageSettings, it, 432) + AvatarHelper.avatar(messageSettings, it, bitmapSize) } if (urls == null || urls.isEmpty()) { @@ -112,7 +115,7 @@ object ShortcutCreationHelper { GlideApp.with(context) .loadWithFallbacks(urls) ?.placeholder(fallback) - ?.into(object : SimpleTarget<Drawable>(432, 432) { + ?.into(object : CustomTarget<Drawable>(bitmapSize, bitmapSize) { override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) { resultAvailable(resource) @@ -121,6 +124,10 @@ object ShortcutCreationHelper { override fun onLoadFailed(errorDrawable: Drawable?) { resultAvailable(errorDrawable!!) } + + override fun onLoadCleared(placeholder: Drawable?) { + // do nothing, as we’ve already processed the drawable + } }) } } else { diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt index f584b2417a6f61c6d158a3419b997b5b489a8549..a3a13b760c572091ac8c9327686d42bf0f9d6192 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -19,10 +19,10 @@ package de.kuschku.quasseldroid.util.backport -import androidx.lifecycle.LifecycleService import dagger.android.AndroidInjection +import de.kuschku.quasseldroid.util.compatibility.FixedLifecycleService -abstract class DaggerLifecycleService : LifecycleService() { +abstract class DaggerLifecycleService : FixedLifecycleService() { override fun onCreate() { AndroidInjection.inject(this) super.onCreate() diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/FixedLifecycleService.java b/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/FixedLifecycleService.java new file mode 100644 index 0000000000000000000000000000000000000000..9fac9df26919a32d811e8b44985871354688e31d --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/FixedLifecycleService.java @@ -0,0 +1,103 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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/>. + */ + +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.kuschku.quasseldroid.util.compatibility; + +import android.annotation.SuppressLint; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ServiceLifecycleDispatcher; + +/** + * A Service that is also a {@link LifecycleOwner}. + */ +@SuppressLint("Registered") +public class FixedLifecycleService extends Service implements LifecycleOwner { + + private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this); + + @CallSuper + @Override + public void onCreate() { + mDispatcher.onServicePreSuperOnCreate(); + super.onCreate(); + } + + @CallSuper + @Nullable + @Override + public IBinder onBind(@Nullable Intent intent) { + mDispatcher.onServicePreSuperOnBind(); + return null; + } + + @SuppressWarnings("deprecation") + @CallSuper + @Override + public void onStart(@Nullable Intent intent, int startId) { + mDispatcher.onServicePreSuperOnStart(); + super.onStart(intent, startId); + } + + // this method is added only to annotate it with @CallSuper. + // In usual service super.onStartCommand is no-op, but in LifecycleService + // it results in mDispatcher.onServicePreSuperOnStart() call, because + // super.onStartCommand calls onStart(). + @CallSuper + @Override + public int onStartCommand(@Nullable Intent intent, int flags, int startId) { + return super.onStartCommand(intent, flags, startId); + } + + @CallSuper + @Override + public void onDestroy() { + mDispatcher.onServicePreSuperOnDestroy(); + super.onDestroy(); + } + + @Override + @NonNull + public Lifecycle getLifecycle() { + return mDispatcher.getLifecycle(); + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/AccountDaoHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/AccountDaoHelper.kt index 94871dbc37db4ad7e0957d65386e50ed371c59d2..2393a835add88abc1e94341fe685dc75b2714394 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/helper/AccountDaoHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/AccountDaoHelper.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,11 +20,12 @@ package de.kuschku.quasseldroid.util.helper import de.kuschku.quasseldroid.persistence.dao.AccountDao +import de.kuschku.quasseldroid.persistence.dao.create import de.kuschku.quasseldroid.persistence.models.Account fun AccountDao.new(vararg entities: Account) { val ids = create(*entities) - for (i in 0 until entities.size) { + for (i in entities.indices) { entities[i].id = ids[i] } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesAdapter.kt index b8b32192543b167aeb5fad6284ded038357feca4..3194924c42392e0493e5dc5fa1222dc6b9d74002 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/missingfeatures/MissingFeaturesAdapter.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -20,15 +20,11 @@ package de.kuschku.quasseldroid.util.missingfeatures import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.databinding.WidgetMissingFeatureBinding class MissingFeaturesAdapter : ListAdapter<MissingFeature, MissingFeaturesAdapter.MissingFeatureViewHolder>( @@ -41,26 +37,18 @@ class MissingFeaturesAdapter : } ) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = MissingFeatureViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_missing_feature, parent, false) + WidgetMissingFeatureBinding.inflate(LayoutInflater.from(parent.context), parent, false) ) override fun onBindViewHolder(holder: MissingFeatureViewHolder, position: Int) = holder.bind(getItem(position)) - class MissingFeatureViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.description) - lateinit var description: TextView - - init { - ButterKnife.bind(this, itemView) - } - + class MissingFeatureViewHolder( + private val binding: WidgetMissingFeatureBinding + ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: MissingFeature) { - name.text = item.feature.name - description.setText(item.description) + binding.name.text = item.feature.name + binding.description.setText(item.description) } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt index b9f5211f9305ce222cb666e23a0f58b6a5867021..de466fa46e17bac35d45aeea572b0e5fc2ed7822 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -34,6 +34,7 @@ import de.kuschku.libquassel.util.helper.safeValue import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.Keys import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.settings.ConnectionSettings import de.kuschku.quasseldroid.settings.Settings import de.kuschku.quasseldroid.util.helper.editCommit @@ -70,12 +71,12 @@ abstract class ServiceBoundActivity : } } - fun connectToAccount(accountId: Long) { + fun connectToAccount(accountId: AccountId) { getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE).editCommit { putBoolean(Keys.Status.reconnect, false) } getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE).editCommit { - putLong(Keys.Status.selectedAccount, accountId) + putLong(Keys.Status.selectedAccount, accountId.id) putBoolean(Keys.Status.reconnect, true) } } @@ -86,7 +87,7 @@ abstract class ServiceBoundActivity : @Inject lateinit var quasselViewModel: QuasselViewModel - protected var accountId: Long = -1 + protected var accountId: AccountId = AccountId(-1L) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -143,14 +144,13 @@ abstract class ServiceBoundActivity : checkConnection() protected fun checkConnection() { - accountId = getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) - ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 + accountId = AccountId(getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) + ?.getLong(Keys.Status.selectedAccount, -1) ?: -1) val reconnect = sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) { getBoolean(Keys.Status.reconnect, false) } - val accountIdValid = accountId != -1L - if (!reconnect || !accountIdValid) { + if (!reconnect || !accountId.isValidId()) { onSelectAccount() } else { if (!connection.start()) diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt index 9c712a33455b32d9a531011b1bcc47ef8144f6d4..1a30474a47f5b2a516066e4a019ae807a3f160a9 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -26,6 +26,7 @@ import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.helper.safeValue import de.kuschku.quasseldroid.Backend import de.kuschku.quasseldroid.Keys +import de.kuschku.quasseldroid.persistence.util.AccountId import de.kuschku.quasseldroid.viewmodel.QuasselViewModel import io.reactivex.subjects.BehaviorSubject import javax.inject.Inject @@ -50,11 +51,11 @@ abstract class ServiceBoundFragment : DaggerFragment() { } } - protected var accountId: Long = -1 + protected var accountId = AccountId(-1L) override fun onCreate(savedInstanceState: Bundle?) { - accountId = context?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) - ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 + accountId = AccountId(context?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) + ?.getLong(Keys.Status.selectedAccount, -1) ?: -1) connection.context = context lifecycle.addObserver(connection) @@ -63,8 +64,8 @@ abstract class ServiceBoundFragment : DaggerFragment() { override fun onStart() { super.onStart() - accountId = context?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) - ?.getLong(Keys.Status.selectedAccount, -1) ?: -1 + accountId = AccountId(context?.getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) + ?.getLong(Keys.Status.selectedAccount, -1) ?: -1) } override fun onDestroy() { diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt index 834e4980ae45acdeaf5c7accf9dba5b199e7992d..4e9e9fdba3858e42d2ab1ef67eba30eb384f108e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/RingtonePreference.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -54,7 +54,7 @@ open class RingtonePreference : DialogPreference, this(context, null) constructor(context: Context, attrs: AttributeSet?) : - this(context, attrs, R.attr.ringtonePreferenceStyle) + this(context, attrs, android.R.attr.ringtonePreferenceStyle) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0) diff --git a/app/src/main/res/values/ints.xml b/app/src/main/res/values/ints.xml new file mode 100644 index 0000000000000000000000000000000000000000..98e199b176b4a6e5d88531c27c862ed70b42335d --- /dev/null +++ b/app/src/main/res/values/ints.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Quasseldroid - Quassel client for Android + + Copyright (c) 2020 Janne Mareike Koschinski + Copyright (c) 2020 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/>. + --> + +<resources> + <integer name="shortcut_image_size">432</integer> +</resources> diff --git a/app/src/main/res/values/themes_base.xml b/app/src/main/res/values/themes_base.xml index b5be66c92ecaeec57ff95225d6e61b9b140ce1c2..15d454569f5c2eb6ad3cfa72fc3573deda8f42f1 100644 --- a/app/src/main/res/values/themes_base.xml +++ b/app/src/main/res/values/themes_base.xml @@ -1,8 +1,8 @@ <!-- Quasseldroid - Quassel client for Android - Copyright (c) 2019 Janne Mareike Koschinski - Copyright (c) 2019 The Quassel Project + Copyright (c) 2020 Janne Mareike Koschinski + Copyright (c) 2020 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 @@ -87,7 +87,7 @@ <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="actionBarPopupTheme">@style/Widget.PopupOverlay</item> - <item name="ringtonePreferenceStyle">@style/Widget.RingtonePreference</item> + <item name="android:ringtonePreferenceStyle">@style/Widget.RingtonePreference</item> <item name="backgroundMenuItem">@drawable/bg_menuitem_dark</item> <item name="backgroundMenuItemRounded">@drawable/bg_menuitem_rounded_dark</item> @@ -136,7 +136,7 @@ <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="actionBarPopupTheme">@style/Widget.PopupOverlay.Light</item> - <item name="ringtonePreferenceStyle">@style/Widget.RingtonePreference</item> + <item name="android:ringtonePreferenceStyle">@style/Widget.RingtonePreference</item> <item name="backgroundMenuItem">@drawable/bg_menuitem_light</item> <item name="backgroundMenuItemRounded">@drawable/bg_menuitem_rounded_light</item> diff --git a/build.gradle.kts b/build.gradle.kts index aba1b9de15b7f9efdefd7190286374aa92aed21d..930b49a56908f9e9ddb99e8207133b52b8130fe9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,8 +25,8 @@ buildscript { jcenter() } dependencies { - classpath("com.android.tools.build:gradle:3.4.2") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50") + classpath("com.android.tools.build:gradle:3.6.1") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61") } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f9ec95f434db0fffd15f500b9c77294439394353..c5052237fa3ea762db4ef9fb2e2f84f8732dd6e0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -18,4 +18,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-5.3.1-all.zip +distributionUrl=https://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/invokergenerator/build.gradle.kts b/invokergenerator/build.gradle.kts index 5894f28fc8cf3d21cd8e0d43ed68c73d6b87c737..f261b90d3ef91829d4de3f758bb2005974feb4b6 100644 --- a/invokergenerator/build.gradle.kts +++ b/invokergenerator/build.gradle.kts @@ -29,9 +29,9 @@ tasks.withType<KotlinCompile> { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation(project(":invokerannotations")) - implementation("org.jetbrains.kotlin", "kotlin-compiler-embeddable", "1.3.50") + implementation("org.jetbrains.kotlin", "kotlin-compiler-embeddable", "1.3.61") implementation("com.squareup", "kotlinpoet", "1.3.0") implementation("com.google.auto.service:auto-service:1.0-rc6") kapt("com.google.auto.service:auto-service:1.0-rc6") diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index a30531f7d715c5b1ff197264737d9ac58331862e..279ac550b11786a9a0b1bcd8f6912572fa62c900 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -23,7 +23,7 @@ plugins { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation("androidx.annotation", "annotation", "1.1.0") diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt index be241b870d789d306658e3df5970e2a932a8612f..faf831fe3243b9261485c0fbe83cd52916b041a2 100644 --- a/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt +++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -25,8 +25,7 @@ enum class QType(val typeName: String, val serializer: Serializer<*>, val type: Type = Type.UserType) { BufferId("BufferId", BufferIdSerializer), BufferInfo("BufferInfo", BufferInfoSerializer), - DccConfig_IpDetectionMode("DccConfig::IpDetectionMode", - DccConfig_IpDetectionModeSerializer), + DccConfig_IpDetectionMode("DccConfig::IpDetectionMode", DccConfig_IpDetectionModeSerializer), DccConfig_PortSelectionMode("DccConfig::PortSelectionMode", DccConfig_PortSelectionModeSerializer), IrcUser("IrcUser", VariantMapSerializer), diff --git a/lib/src/main/java/de/kuschku/libquassel/util/rxjava/ReusableUnicastSubject.java b/lib/src/main/java/de/kuschku/libquassel/util/rxjava/ReusableUnicastSubject.java index 38ab36b1d0b5862805b9fbf60c483b7dc7d9bcb7..86c4a242ba0d973e15fb7d17dd9aa564cf9a85fd 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/rxjava/ReusableUnicastSubject.java +++ b/lib/src/main/java/de/kuschku/libquassel/util/rxjava/ReusableUnicastSubject.java @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -206,7 +206,7 @@ public final class ReusableUnicastSubject<T> extends Subject<T> { this.delayError = delayError; this.actual = new AtomicReference<>(); this.once = new AtomicBoolean(); - this.wip = new ReusableUnicastSubject.UnicastQueueDisposable(); + this.wip = new ReusableUnicastSubject<T>.UnicastQueueDisposable(); } /** @@ -236,7 +236,7 @@ public final class ReusableUnicastSubject<T> extends Subject<T> { this.delayError = delayError; this.actual = new AtomicReference<Observer<? super T>>(); this.once = new AtomicBoolean(); - this.wip = new ReusableUnicastSubject.UnicastQueueDisposable(); + this.wip = new ReusableUnicastSubject<T>.UnicastQueueDisposable(); } /** diff --git a/lifecycle-ktx/build.gradle.kts b/lifecycle-ktx/build.gradle.kts index 04ea573ec3cf5cca194d41221546269c64ff6ec6..552bd4187190415c3c4d1bfbcf8f651aaea8d544 100644 --- a/lifecycle-ktx/build.gradle.kts +++ b/lifecycle-ktx/build.gradle.kts @@ -22,7 +22,7 @@ plugins { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation("androidx.annotation", "annotation", "1.1.0") diff --git a/malheur/build.gradle.kts b/malheur/build.gradle.kts index 239f49c2c8ba2b22411c71d095c7dd268be8ebe2..70914cadc35deceac6d6aa92e747d2684217b0a9 100644 --- a/malheur/build.gradle.kts +++ b/malheur/build.gradle.kts @@ -26,7 +26,7 @@ android { compileSdkVersion(28) defaultConfig { - minSdkVersion(14) + minSdkVersion(20) targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro") @@ -44,7 +44,7 @@ android { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation("com.google.code.gson", "gson", "2.8.5") implementation("androidx.annotation", "annotation", "1.1.0") diff --git a/persistence/build.gradle.kts b/persistence/build.gradle.kts index 409b7adf9123f26cd0aab736e01ea5c48c56d309..43dd728e2099b30326392bfbfeb6e98465c2e05a 100644 --- a/persistence/build.gradle.kts +++ b/persistence/build.gradle.kts @@ -27,7 +27,7 @@ android { compileSdkVersion(28) defaultConfig { - minSdkVersion(16) + minSdkVersion(20) targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro") @@ -51,18 +51,18 @@ android { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation("androidx.appcompat", "appcompat", "1.1.0") - withVersion("2.2.0-rc01") { + withVersion("2.2.5") { implementation("androidx.room", "room-runtime", version) kapt("androidx.room", "room-compiler", version) implementation("androidx.room", "room-rxjava2", version) testImplementation("androidx.room", "room-testing", version) } - implementation("androidx.paging", "paging-runtime", "2.1.0") + implementation("androidx.paging", "paging-runtime", "2.1.2") // Utility implementation("org.threeten", "threetenbp", "1.4.0", classifier = "no-tzdb") diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt index aa7fc973f40712ae815492364f4e0b7338dd2283..ccc784296df66e0b8fab0a5f5ae57280d93652bd 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/AccountDao.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.persistence.dao import androidx.lifecycle.LiveData import androidx.room.* import de.kuschku.quasseldroid.persistence.models.Account +import de.kuschku.quasseldroid.persistence.util.AccountId import io.reactivex.Flowable @Dao @@ -30,16 +31,16 @@ interface AccountDao { fun save(vararg entities: Account) @Insert(onConflict = OnConflictStrategy.IGNORE) - fun create(vararg entities: Account): Array<Long> + fun _create(vararg entities: Account): Array<Long> @Query("SELECT * FROM account WHERE id = :id") - fun findById(id: Long): Account? + fun _findById(id: Long): Account? @Query("SELECT * FROM account WHERE id = :id") - fun listen(id: Long): LiveData<Account?> + fun _listen(id: Long): LiveData<Account?> @Query("SELECT IFNULL(t.defaultFiltered, :defaultValue) FROM (SELECT defaultFiltered FROM account WHERE id = :id UNION SELECT NULL ORDER BY defaultFiltered DESC LIMIT 1) t") - fun listenDefaultFiltered(id: Long, defaultValue: Int): Flowable<Int> + fun _listenDefaultFiltered(id: Long, defaultValue: Int): Flowable<Int> @Query("SELECT * FROM account ORDER BY lastUsed DESC") fun all(): LiveData<List<Account>> @@ -48,8 +49,24 @@ interface AccountDao { fun delete(account: Account) @Query("UPDATE account SET defaultFiltered = :defaultFiltered WHERE id = :id") - fun setFiltered(id: Long, defaultFiltered: Int) + fun _setFiltered(id: Long, defaultFiltered: Int) @Query("DELETE FROM account") fun clear() } + + +fun AccountDao.create(vararg entities: Account): List<AccountId> = + _create(*entities).map(::AccountId) + +fun AccountDao.findById(id: AccountId): Account? = + _findById(id.id) + +fun AccountDao.listen(id: AccountId): LiveData<Account?> = + _listen(id.id) + +fun AccountDao.listenDefaultFiltered(id: AccountId, defaultValue: Int): Flowable<Int> = + _listenDefaultFiltered(id.id, defaultValue) + +fun AccountDao.setFiltered(id: AccountId, defaultFiltered: Int) = + _setFiltered(id.id, defaultFiltered) diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt index e88c50e4f59ef3d1851d452f390c9927add4c47e..862d4ca5f782c8a91f526a517da26e5e1aac0945 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/dao/FilteredDao.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -28,6 +28,7 @@ import androidx.room.Query import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.protocol.BufferId_Type import de.kuschku.quasseldroid.persistence.models.Filtered +import de.kuschku.quasseldroid.persistence.util.AccountId import io.reactivex.Flowable @Dao @@ -44,36 +45,45 @@ interface FilteredDao { @Query("SELECT IFNULL(t.filtered, :defaultValue) FROM (SELECT filtered FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId UNION SELECT NULL ORDER BY filtered DESC LIMIT 1) t") fun _get(accountId: Long, bufferId: BufferId_Type, defaultValue: Int): Int - @Query("SELECT IFNULL(t.filtered, :defaultValue) FROM (SELECT filtered FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId UNION SELECT NULL ORDER BY filtered DESC LIMIT 1) t") - fun _listen(accountId: Long, bufferId: BufferId_Type, defaultValue: Int): LiveData<Int> - @Query("SELECT * FROM filtered WHERE accountId = :accountId") - fun listen(accountId: Long): LiveData<List<Filtered>> + fun _listen(accountId: Long): LiveData<List<Filtered>> @Query("SELECT * FROM filtered WHERE accountId = :accountId") - fun listenRx(accountId: Long): Flowable<List<Filtered>> + fun _listenRx(accountId: Long): Flowable<List<Filtered>> + + @Query("SELECT IFNULL(t.filtered, :defaultValue) FROM (SELECT filtered FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId UNION SELECT NULL ORDER BY filtered DESC LIMIT 1) t") + fun _listen(accountId: Long, bufferId: BufferId_Type, defaultValue: Int): LiveData<Int> @Query("DELETE FROM filtered") fun clear() @Query("DELETE FROM filtered WHERE accountId = :accountId") - fun clear(accountId: Long) + fun _clear(accountId: Long) @Query("DELETE FROM filtered WHERE bufferId = :bufferId AND accountId = :accountId") fun _clear(accountId: Long, bufferId: BufferId_Type) } -inline fun FilteredDao.buffers(accountId: Long) = - _buffers(accountId).map(::BufferId) +inline fun FilteredDao.buffers(accountId: AccountId) = + _buffers(accountId.id).map(::BufferId) + +inline fun FilteredDao.setFiltered(accountId: AccountId, bufferId: BufferId, filtered: Int) = + _setFiltered(accountId.id, bufferId.id, filtered) + +inline fun FilteredDao.get(accountId: AccountId, bufferId: BufferId, defaultValue: Int) = + _get(accountId.id, bufferId.id, defaultValue) + +inline fun FilteredDao.listen(accountId: AccountId) = + _listen(accountId.id) -inline fun FilteredDao.setFiltered(accountId: Long, bufferId: BufferId, filtered: Int) = - _setFiltered(accountId, bufferId.id, filtered) +inline fun FilteredDao.listenRx(accountId: AccountId) = + _listenRx(accountId.id) -inline fun FilteredDao.get(accountId: Long, bufferId: BufferId, defaultValue: Int) = - _get(accountId, bufferId.id, defaultValue) +inline fun FilteredDao.listen(accountId: AccountId, bufferId: BufferId, defaultValue: Int) = + _listen(accountId.id, bufferId.id, defaultValue) -inline fun FilteredDao.listen(accountId: Long, bufferId: BufferId, defaultValue: Int) = - _listen(accountId, bufferId.id, defaultValue) +inline fun FilteredDao.clear(accountId: AccountId) = + _clear(accountId.id) -inline fun FilteredDao.clear(accountId: Long, bufferId: BufferId) = - _clear(accountId, bufferId.id) +inline fun FilteredDao.clear(accountId: AccountId, bufferId: BufferId) = + _clear(accountId.id, bufferId.id) diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Account.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Account.kt index c2fa8b60419b628974577e8b0391754ad31c3fed..51b84d242ce6c481662390529112e74db7878eea 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Account.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Account.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -19,13 +19,16 @@ package de.kuschku.quasseldroid.persistence.models +import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import de.kuschku.quasseldroid.persistence.util.AccountId @Entity(tableName = "Account") data class Account( @PrimaryKey(autoGenerate = true) - var id: Long, + @ColumnInfo(name = "id") + var rawId: Long, var host: String, var port: Int, var requireSsl: Boolean, @@ -35,4 +38,36 @@ data class Account( var lastUsed: Long, var acceptedMissingFeatures: Boolean, var defaultFiltered: Int -) +) { + inline var id + get() = AccountId(rawId) + set(value) { + rawId = value.id + } + + companion object { + inline fun of( + id: AccountId, + host: String, + port: Int, + requireSsl: Boolean, + user: String, + pass: String, + name: String, + lastUsed: Long, + acceptedMissingFeatures: Boolean, + defaultFiltered: Int + ) = Account( + id.id, + host, + port, + requireSsl, + user, + pass, + name, + lastUsed, + acceptedMissingFeatures, + defaultFiltered + ) + } +} diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Filtered.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Filtered.kt index ffd755a205e22997b925c54e187dce71e4af505a..3fda2b2fc99cf689828f24aa1cbaa454f32cb168 100644 --- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Filtered.kt +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/models/Filtered.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2019 Janne Mareike Koschinski - * Copyright (c) 2019 The Quassel Project + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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 @@ -23,6 +23,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.protocol.BufferId_Type +import de.kuschku.quasseldroid.persistence.util.AccountId @Entity(tableName = "filtered", primaryKeys = ["accountId", "bufferId"]) data class Filtered( @@ -36,11 +37,11 @@ data class Filtered( companion object { inline fun of( - accountId: Long, + accountId: AccountId, bufferId: BufferId, filtered: Int ) = Filtered( - accountId, + accountId.id, bufferId.id, filtered ) diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/AccountId.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/AccountId.kt new file mode 100644 index 0000000000000000000000000000000000000000..d6cc4d995924fc3f1b993184b29eee14d01995c2 --- /dev/null +++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/AccountId.kt @@ -0,0 +1,38 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2020 Janne Mareike Koschinski + * Copyright (c) 2020 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.persistence.util + +import java.io.Serializable + +typealias AccountId_Type = Long + +inline class AccountId(val id: AccountId_Type) : Comparable<AccountId>, Serializable { + override fun compareTo(other: AccountId) = id.compareTo(other.id) + inline fun isValidId() = id >= 0 + + override fun toString(): String { + return "AccountId($id)" + } + + companion object { + val MIN_VALUE = AccountId(AccountId_Type.MIN_VALUE) + val MAX_VALUE = AccountId(AccountId_Type.MAX_VALUE) + } +} diff --git a/ui_spinner/build.gradle.kts b/ui_spinner/build.gradle.kts index f64f04c70a456469cafb319bc6937288df4dbe2b..d44f61b855e6e11a400aaafb9f08862893e813e3 100644 --- a/ui_spinner/build.gradle.kts +++ b/ui_spinner/build.gradle.kts @@ -26,7 +26,7 @@ android { compileSdkVersion(28) defaultConfig { - minSdkVersion(16) + minSdkVersion(20) targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro") @@ -44,6 +44,6 @@ android { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation("androidx.appcompat", "appcompat", "1.1.0") } diff --git a/viewmodel/build.gradle.kts b/viewmodel/build.gradle.kts index 5800e98c8a8069802d4c4533e9296d06db0cbc7d..7ae12ace91e74ecdc97860ef282981f9b269cab2 100644 --- a/viewmodel/build.gradle.kts +++ b/viewmodel/build.gradle.kts @@ -26,7 +26,7 @@ android { compileSdkVersion(28) defaultConfig { - minSdkVersion(16) + minSdkVersion(20) targetSdkVersion(28) consumerProguardFiles("proguard-rules.pro") @@ -44,10 +44,10 @@ android { } dependencies { - implementation(kotlin("stdlib", "1.3.50")) + implementation(kotlin("stdlib", "1.3.61")) implementation("androidx.appcompat", "appcompat", "1.1.0") - withVersion("2.1.0") { + withVersion("2.2.0") { implementation("androidx.lifecycle", "lifecycle-extensions", version) implementation("androidx.lifecycle", "lifecycle-reactivestreams", version) }