diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityBaseModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityBaseModule.kt index 04440909910ea632b9fc188346e687182bc2cb5d..1ea10c43e8175ef3f61985b1b933d6382da2e54a 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityBaseModule.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityBaseModule.kt @@ -29,6 +29,7 @@ import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountViewModel import de.kuschku.quasseldroid.viewmodel.ChatViewModel import de.kuschku.quasseldroid.viewmodel.EditorViewModel import de.kuschku.quasseldroid.viewmodel.QuasselViewModel +import de.kuschku.quasseldroid.viewmodel.QueryCreateViewModel @Module object ActivityBaseModule { @@ -65,4 +66,10 @@ object ActivityBaseModule { @JvmStatic fun provideAccountViewModel(viewModelProvider: ViewModelProvider) = viewModelProvider[AccountViewModel::class.java] + + @ActivityScope + @Provides + @JvmStatic + fun provideQueryCreateViewModel(viewModelProvider: ViewModelProvider) = + viewModelProvider[QueryCreateViewModel::class.java] } 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 708d270603f7963fac12582efe41a0a771a9fa76..0b964f74867619125569554be096ae8f721b2311 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 @@ -171,14 +171,14 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc super.onNewIntent(intent) if (intent != null) { when { - intent.type == "text/plain" -> { + intent.type == "text/plain" -> { val text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT) if (text != null) { chatlineFragment?.replaceText(text) drawerLayout.closeDrawers() } } - intent.hasExtra(KEY_BUFFER_ID) -> { + intent.hasExtra(KEY_BUFFER_ID) -> { chatViewModel.bufferId.onNext(BufferId(intent.getIntExtra(KEY_BUFFER_ID, -1))) chatViewModel.bufferOpened.onNext(Unit) if (intent.hasExtra(KEY_ACCOUNT_ID)) { @@ -193,17 +193,19 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc } } } - intent.hasExtra(KEY_AUTOCOMPLETE_TEXT) -> { + intent.hasExtra(KEY_AUTOCOMPLETE_TEXT) -> { chatlineFragment?.editorHelper?.appendText( intent.getStringExtra(KEY_AUTOCOMPLETE_TEXT), intent.getStringExtra(KEY_AUTOCOMPLETE_SUFFIX) ) drawerLayout.closeDrawers() } - intent.hasExtra(KEY_NETWORK_ID) && intent.hasExtra(KEY_CHANNEL) -> { + intent.hasExtra(KEY_NETWORK_ID) && intent.hasExtra(KEY_CHANNEL) -> { val networkId = NetworkId(intent.getIntExtra(KEY_NETWORK_ID, -1)) val channel = intent.getStringExtra(KEY_CHANNEL) + val forceJoin = intent.getBooleanExtra(KEY_FORCE_JOIN, false) + modelHelper.session.filter(Optional<ISession>::isPresent).firstElement().subscribe { it.orNull()?.also { session -> val info = session.bufferSyncer.find( @@ -212,7 +214,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc type = Buffer_Type.of(Buffer_Type.ChannelBuffer) ) - if (info != null) { + if (info != null && !forceJoin) { ChatActivity.launch(this, bufferId = info.bufferId) } else { modelHelper.allBuffers.map { @@ -241,8 +243,51 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc } } } + intent.hasExtra(KEY_NETWORK_ID) && intent.hasExtra(KEY_NICK_NAME) -> { + val networkId = NetworkId(intent.getIntExtra(KEY_NETWORK_ID, -1)) + val channel = intent.getStringExtra(KEY_NICK_NAME) + + val forceJoin = intent.getBooleanExtra(KEY_FORCE_JOIN, false) + + modelHelper.session.filter(Optional<ISession>::isPresent).firstElement().subscribe { + it.orNull()?.also { session -> + val info = session.bufferSyncer.find( + bufferName = channel, + networkId = networkId, + type = Buffer_Type.of(Buffer_Type.QueryBuffer) + ) + + if (info != null && !forceJoin) { + ChatActivity.launch(this, bufferId = info.bufferId) + } else { + modelHelper.allBuffers.map { + listOfNotNull(it.find { + it.networkId == networkId && + it.bufferName == channel && + it.type.hasFlag(Buffer_Type.QueryBuffer) + }) + }.filter { + it.isNotEmpty() + }.firstElement().toLiveData().observeForever { + it?.firstOrNull()?.let { info -> + ChatActivity.launch(this, bufferId = info.bufferId) + } + } + + session.bufferSyncer.find( + networkId = networkId, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.let { statusInfo -> + session.rpcHandler.sendInput( + statusInfo, "/query $channel" + ) + } + } + } + } + } intent.scheme == "irc" || - intent.scheme == "ircs" -> { + intent.scheme == "ircs" -> { val uri = intent.data if (uri != null) { val channelString = (uri.path.let { it ?: "" }.trimStart('/')) + @@ -1097,6 +1142,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc private const val KEY_ACCOUNT_ID = "account_id" private const val KEY_NETWORK_ID = "network_id" private const val KEY_CHANNEL = "channel" + private const val KEY_NICK_NAME = "nick_name" + private const val KEY_FORCE_JOIN = "force_join" // Instance state keys private const val KEY_OPEN_BUFFER = "open_buffer" @@ -1111,18 +1158,22 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc autoCompleteText: CharSequence? = null, autoCompleteSuffix: String? = null, channel: String? = null, + nickName: String? = null, networkId: NetworkId? = null, bufferId: BufferId? = null, - accountId: Long? = null + accountId: Long? = null, + forceJoin: Boolean? = null ) = context.startActivity( intent(context, sharedText, autoCompleteText, autoCompleteSuffix, channel, + nickName, networkId, bufferId, - accountId) + accountId, + forceJoin) ) fun intent( @@ -1131,9 +1182,11 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc autoCompleteText: CharSequence? = null, autoCompleteSuffix: String? = null, channel: String? = null, + nickName: String? = null, networkId: NetworkId? = null, bufferId: BufferId? = null, - accountId: Long? = null + accountId: Long? = null, + forceJoin: Boolean? = null ) = Intent(context, ChatActivity::class.java).apply { if (sharedText != null) { type = "text/plain" @@ -1154,6 +1207,12 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc if (networkId != null && channel != null) { putExtra(KEY_NETWORK_ID, networkId.id) putExtra(KEY_CHANNEL, channel) + } else if (networkId != null && nickName != null) { + putExtra(KEY_NETWORK_ID, networkId.id) + putExtra(KEY_NICK_NAME, nickName) + if (forceJoin != null) { + putExtra(KEY_NICK_NAME, nickName) + } } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt index e3baf6fb13f3bd4db350d46ec351db77589d915d..9b163bf382a4dc334faa3b35f0518a8c7659a631 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/create/ChannelCreateFragment.kt @@ -114,7 +114,7 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() { save.setText(R.string.label_saving) save.isEnabled = false - val networkId = NetworkId(network.selectedItemId.toInt()) + val selectedNetworkId = NetworkId(network.selectedItemId.toInt()) val channelName = name.text.toString().trim() val isInviteOnly = inviteOnly.isChecked @@ -124,16 +124,17 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() { modelHelper.bufferSyncer.value?.orNull()?.let { bufferSyncer -> val existingBuffer = bufferSyncer.find( - networkId = networkId, + networkId = selectedNetworkId, type = Buffer_Type.of(Buffer_Type.ChannelBuffer), bufferName = channelName ) - val existingChannel = modelHelper.networks.value?.get(networkId)?.ircChannel(channelName) + val existingChannel = modelHelper.networks.value?.get(selectedNetworkId)?.ircChannel( + channelName) .nullIf { it == IrcChannel.NULL } if (existingBuffer != null) { if (existingChannel == null) { bufferSyncer.find( - networkId = networkId, + networkId = selectedNetworkId, type = Buffer_Type.of(Buffer_Type.StatusBuffer) )?.let { statusBuffer -> modelHelper.session.value?.orNull()?.rpcHandler?.apply { @@ -150,13 +151,13 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() { } } else { bufferSyncer.find( - networkId = networkId, + networkId = selectedNetworkId, type = Buffer_Type.of(Buffer_Type.StatusBuffer) )?.let { statusBuffer -> modelHelper.session.value?.orNull()?.rpcHandler?.apply { sendInput(statusBuffer, "/join $channelName") modelHelper.networks.switchMap { - it[networkId]?.liveIrcChannel(channelName) + it[selectedNetworkId]?.liveIrcChannel(channelName) ?: Observable.empty() }.subscribe { if (it.ircUsers().size <= 1) { @@ -176,7 +177,7 @@ class ChannelCreateFragment : ServiceBoundSettingsFragment() { activity?.let { it.finish() ChatActivity.launch(it, - networkId = networkId, + networkId = selectedNetworkId, channel = channelName ) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt index a9184d2689b890dd5cb6d09bfcc6cbf15388cc9d..36d589679fa653649db858b30d660a1e82d15bc8 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/join/ChannelJoinFragment.kt @@ -29,10 +29,8 @@ import androidx.appcompat.widget.AppCompatSpinner import androidx.lifecycle.Observer import butterknife.BindView import butterknife.ButterKnife -import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.syncables.Network -import de.kuschku.libquassel.util.helpers.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.ui.chat.add.NetworkAdapter @@ -92,23 +90,17 @@ class ChannelJoinFragment : ServiceBoundFragment() { join.setText(R.string.label_saving) join.isEnabled = false - val networkId = NetworkId(network.selectedItemId.toInt()) + val selectedNetworkId = NetworkId(network.selectedItemId.toInt()) val channelName = name.text.toString().trim() - modelHelper.bufferSyncer.value?.orNull()?.let { bufferSyncer -> - bufferSyncer.find( - networkId = networkId, - type = Buffer_Type.of(Buffer_Type.StatusBuffer) - )?.let { statusBuffer -> - modelHelper.session.value?.orNull()?.rpcHandler?.apply { - sendInput(statusBuffer, "/join $channelName") - } - } - } - activity?.let { it.finish() - ChatActivity.launch(it, networkId = networkId, channel = channelName) + ChatActivity.launch( + it, + networkId = selectedNetworkId, + channel = channelName, + forceJoin = true + ) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt index 6c8b37e5267236354c018f90a20863717683d47d..9244535cab8d0c3bed65778656bb241248e4825e 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/add/query/QueryCreateFragment.kt @@ -19,21 +19,303 @@ package de.kuschku.quasseldroid.ui.chat.add.query +import android.graphics.Typeface import android.os.Bundle +import android.text.Editable +import android.text.SpannableString +import android.text.TextWatcher +import android.text.style.ForegroundColorSpan +import android.text.style.StyleSpan import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.Button +import android.widget.EditText +import androidx.appcompat.widget.AppCompatSpinner +import androidx.lifecycle.Observer +import androidx.recyclerview.widget.DefaultItemAnimator +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import butterknife.BindView import butterknife.ButterKnife +import com.bumptech.glide.Glide +import com.bumptech.glide.ListPreloader +import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader +import com.bumptech.glide.util.FixedPreloadSizeProvider +import de.kuschku.libquassel.protocol.NetworkId +import de.kuschku.libquassel.quassel.syncables.IrcUser +import de.kuschku.libquassel.quassel.syncables.Network +import de.kuschku.libquassel.util.Optional +import de.kuschku.libquassel.util.helpers.mapOrElse +import de.kuschku.libquassel.util.helpers.mapSwitchMap +import de.kuschku.libquassel.util.irc.IrcCaseMappers +import de.kuschku.libquassel.util.irc.SenderColorUtil +import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.settings.MessageSettings +import de.kuschku.quasseldroid.ui.chat.ChatActivity +import de.kuschku.quasseldroid.ui.chat.add.NetworkAdapter +import de.kuschku.quasseldroid.ui.chat.add.NetworkItem +import de.kuschku.quasseldroid.ui.chat.nicks.NickListAdapter +import de.kuschku.quasseldroid.util.ColorContext +import de.kuschku.quasseldroid.util.avatars.AvatarHelper +import de.kuschku.quasseldroid.util.helper.combineLatest +import de.kuschku.quasseldroid.util.helper.loadWithFallbacks +import de.kuschku.quasseldroid.util.helper.styledAttributes +import de.kuschku.quasseldroid.util.helper.toLiveData +import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid.viewmodel.data.Avatar +import de.kuschku.quasseldroid.viewmodel.data.IrcUserItem +import de.kuschku.quasseldroid.viewmodel.data.MatchMode +import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper +import de.kuschku.quasseldroid.viewmodel.helper.QueryCreateViewModelHelper +import io.reactivex.Observable +import java.util.concurrent.TimeUnit +import javax.inject.Inject class QueryCreateFragment : ServiceBoundFragment() { + @BindView(R.id.network) + lateinit var network: AppCompatSpinner + + @BindView(R.id.name) + lateinit var name: EditText + + @BindView(R.id.query) + lateinit var query: Button + + @BindView(R.id.list) + lateinit var list: RecyclerView + + @Inject + lateinit var ircFormatDeserializer: IrcFormatDeserializer + + @Inject + lateinit var messageSettings: MessageSettings + + @Inject + lateinit var modelHelper: QueryCreateViewModelHelper override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.add_query, container, false) ButterKnife.bind(this, view) + val networkId = NetworkId(arguments?.getInt("network_id", 0) ?: 0) + + val networkAdapter = NetworkAdapter() + network.adapter = networkAdapter + + network.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + modelHelper.queryCreate.networkId.onNext(NetworkId(0)) + } + + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + modelHelper.queryCreate.networkId.onNext(networkAdapter.getItem(position).id) + } + } + + var hasSetNetwork = false + modelHelper.networks.switchMap { + combineLatest(it.values.map(Network::liveNetworkInfo)).map { + it.map { + NetworkItem(it.networkId, it.networkName) + }.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, NetworkItem::name)) + } + }.toLiveData().observe(this, Observer { + if (it != null) { + networkAdapter.submitList(it) + if (!hasSetNetwork && networkId.isValidId() && it.isNotEmpty()) { + network.post { + val index = networkAdapter.indexOf(networkId) + if (index != null) { + network.setSelection(index) + } + } + hasSetNetwork = true + } + } + }) + + name.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + modelHelper.queryCreate.nickName.onNext(s?.toString() ?: "") + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit + }) + + val nickListAdapter = NickListAdapter(messageSettings, clickListener) + list.adapter = nickListAdapter + list.layoutManager = object : LinearLayoutManager(context) { + override fun supportsPredictiveItemAnimations() = false + } + list.itemAnimator = DefaultItemAnimator() + + val senderColors = requireContext().theme.styledAttributes( + R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3, + R.attr.senderColor4, R.attr.senderColor5, R.attr.senderColor6, R.attr.senderColor7, + R.attr.senderColor8, R.attr.senderColor9, R.attr.senderColorA, R.attr.senderColorB, + R.attr.senderColorC, R.attr.senderColorD, R.attr.senderColorE, R.attr.senderColorF + ) { + IntArray(length()) { + getColor(it, 0) + } + } + + val selfColor = requireContext().theme.styledAttributes(R.attr.colorForegroundSecondary) { + getColor(0, 0) + } + + val colorContext = ColorContext(requireContext(), messageSettings) + + val avatarSize = resources.getDimensionPixelSize(R.dimen.avatar_size) + + val sizeProvider = FixedPreloadSizeProvider<List<Avatar>>(avatarSize, avatarSize) + + val preloadModelProvider = object : ListPreloader.PreloadModelProvider<List<Avatar>> { + override fun getPreloadItems(position: Int) = listOfNotNull( + nickListAdapter[position]?.let { AvatarHelper.avatar(messageSettings, it) } + ) + + override fun getPreloadRequestBuilder(item: List<Avatar>) = + GlideApp.with(this@QueryCreateFragment).loadWithFallbacks(item)?.override(avatarSize) + } + + val preloader = RecyclerViewPreloader(Glide.with(this), preloadModelProvider, sizeProvider, 10) + + list.addOnScrollListener(preloader) + + val nickData = combineLatest(modelHelper.networks, modelHelper.queryCreate.networkId) + .map { (networks, networkId) -> + Optional.ofNullable(networks[networkId]) + }.mapSwitchMap { + it.liveIrcUsers() + }.mapOrElse(emptyList()).switchMap { + combineLatest<IrcUserItem>( + it.map<IrcUser, Observable<IrcUserItem>?> { + it.updates().map { user -> + IrcUserItem( + user.network().networkId(), + user.nick(), + "", + 0, + user.realName(), + user.hostMask(), + user.isAway(), + user.network().isMyNick(user.nick()), + user.network().support("CASEMAPPING") + ) + } + } + ) + } + + val searchedSortedNickData = combineLatest(modelHelper.queryCreate.nickName, nickData) + .map { (search, users) -> + users.filter { + it.nick.contains(search, ignoreCase = true) + }.map { + val matchMode = when { + it.nick.equals(search, ignoreCase = true) -> MatchMode.EXACT + it.nick.startsWith(search, ignoreCase = true) -> MatchMode.START + else -> MatchMode.CONTAINS + } + + Pair(matchMode, it) + }.sortedBy { (_, user) -> + IrcCaseMappers.unicode.toLowerCaseNullable(user.nick) + }.sortedBy { (matchMode, _) -> + matchMode.priority + }.map { (_, user) -> + user + } + } + + val nickDataThrottled = searchedSortedNickData + .distinctUntilChanged() + .throttleLast(100, TimeUnit.MILLISECONDS) + + nickDataThrottled.map { + it.asSequence().map { + val nickName = it.nick + val senderColorIndex = SenderColorUtil.senderColor(nickName) + val rawInitial = nickName.trimStart(*EditorViewModelHelper.IGNORED_CHARS) + .firstOrNull() ?: nickName.firstOrNull() + val initial = rawInitial?.toUpperCase().toString() + val useSelfColor = when (messageSettings.colorizeNicknames) { + MessageSettings.ColorizeNicknamesMode.ALL -> false + MessageSettings.ColorizeNicknamesMode.ALL_BUT_MINE -> it.self + MessageSettings.ColorizeNicknamesMode.NONE -> true + } + val senderColor = if (useSelfColor) selfColor else senderColors[senderColorIndex] + + fun formatNick(nick: CharSequence): CharSequence { + val spannableString = SpannableString(nick) + spannableString.setSpan( + ForegroundColorSpan(senderColor), + 0, + nick.length, + SpannableString.SPAN_INCLUSIVE_EXCLUSIVE + ) + spannableString.setSpan( + StyleSpan(Typeface.BOLD), + 0, + nick.length, + SpannableString.SPAN_INCLUSIVE_EXCLUSIVE + ) + return spannableString + } + it.copy( + displayNick = formatNick(it.nick), + fallbackDrawable = colorContext.buildTextDrawable(initial, senderColor), + initial = initial, + modes = when (messageSettings.showPrefix) { + MessageSettings.ShowPrefixMode.ALL -> + it.modes + else -> + it.modes.substring(0, Math.min(it.modes.length, 1)) + }, + realname = ircFormatDeserializer.formatString( + it.realname.toString(), messageSettings.colorizeMirc + ), + avatarUrls = AvatarHelper.avatar(messageSettings, it, avatarSize) + ) + }.sortedBy { + IrcCaseMappers[it.networkCasemapping].toLowerCase(it.nick.trimStart(*EditorViewModelHelper.IGNORED_CHARS)) + .trimStart(*EditorViewModelHelper.IGNORED_CHARS) + }.sortedBy { + it.lowestMode + }.toList() + }.toLiveData().observe(this, Observer { + nickListAdapter.submitList(it) + }) + + query.setOnClickListener { + val selectedNetworkId = NetworkId(network.selectedItemId.toInt()) + val nickName = name.text.toString().trim() + + clickListener(selectedNetworkId, nickName) + } + return view } + + private val clickListener: ((NetworkId, String) -> Unit) = { selectedNetworkId, nickName -> + query.setText(R.string.label_saving) + query.isEnabled = false + + activity?.let { + it.finish() + ChatActivity.launch( + it, + networkId = selectedNetworkId, + nickName = nickName, + forceJoin = true + ) + } + } } 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 2b9874b35ccc348c311350771a76cd447c5e13ad..fafed3b75d596afaae5af7f6e994eaa8ac0383a2 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 @@ -582,17 +582,15 @@ class BufferViewConfigFragment : ServiceBoundFragment() { .create() ) - if (BuildConfig.DEBUG) { - fab.addActionItem( - SpeedDialActionItem.Builder(R.id.fab_query, R.drawable.ic_account) - .setFabBackgroundColor(fabBackground2) - .setFabImageTintColor(0xffffffffu.toInt()) - .setLabel(R.string.label_query_medium) - .setLabelBackgroundColor(colorLabelBackground) - .setLabelColor(colorLabel) - .create() - ) - } + fab.addActionItem( + SpeedDialActionItem.Builder(R.id.fab_query, R.drawable.ic_account) + .setFabBackgroundColor(fabBackground2) + .setFabImageTintColor(0xffffffffu.toInt()) + .setLabel(R.string.label_query_medium) + .setLabelBackgroundColor(colorLabelBackground) + .setLabelColor(colorLabel) + .create() + ) fab.setOnActionSelectedListener { val networkId = modelHelper.bufferData?.value?.network?.networkId() 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 5f26f1f30691c28baf5d29058e2235ce212e0507..81d95bc2e23fbfa70db878eb0ed96a7f007b0bf5 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 @@ -29,6 +29,7 @@ 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.helpers.nullIf import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.MessageSettings @@ -41,7 +42,7 @@ import de.kuschku.quasseldroid.viewmodel.data.IrcUserItem class NickListAdapter( private val messageSettings: MessageSettings, - private val clickListener: ((String) -> Unit)? = null + private val clickListener: ((NetworkId, String) -> Unit)? = null ) : ListAdapter<IrcUserItem, NickListAdapter.NickViewHolder>( object : DiffUtil.ItemCallback<IrcUserItem>() { override fun areItemsTheSame(oldItem: IrcUserItem, newItem: IrcUserItem) = @@ -84,7 +85,7 @@ class NickListAdapter( class NickViewHolder( itemView: View, - private val clickListener: ((String) -> Unit)? = null + private val clickListener: ((NetworkId, String) -> Unit)? = null ) : RecyclerView.ViewHolder(itemView) { @BindView(R.id.avatar) lateinit var avatar: ImageView @@ -95,19 +96,19 @@ class NickListAdapter( @BindView(R.id.realname) lateinit var realname: TextView - var user: String? = null + var user: IrcUserItem? = null init { ButterKnife.bind(this, itemView) itemView.setOnClickListener { val nick = user if (nick != null) - clickListener?.invoke(nick) + clickListener?.invoke(nick.networkId, nick.nick) } } fun bind(data: IrcUserItem, messageSettings: MessageSettings) { - user = data.nick + user = data nick.text = SpanFormatter.format("%s%s", data.modes, data.displayNick ?: data.nick) realname.text = data.realname diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt index 997f840abb25755d2f4444bb22978151f943c2fe..2b81e90ff6519006fca863fded80ef24e0bc3697 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt @@ -38,6 +38,7 @@ import com.bumptech.glide.ListPreloader import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader import com.bumptech.glide.util.FixedPreloadSizeProvider import de.kuschku.libquassel.protocol.Buffer_Type +import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.util.helpers.value import de.kuschku.libquassel.util.irc.IrcCaseMappers @@ -191,21 +192,19 @@ class NickListFragment : ServiceBoundFragment() { outState.putParcelable(KEY_STATE_LIST, nickList.layoutManager?.onSaveInstanceState()) } - private val clickListener: ((String) -> Unit)? = { nick -> + private val clickListener: ((NetworkId, String) -> Unit) = { networkId, nick -> modelHelper.session.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> - modelHelper.bufferData.value?.info?.let(BufferInfo::networkId)?.let { networkId -> - UserInfoActivity.launch( - requireContext(), - openBuffer = false, - bufferId = bufferSyncer.find( - bufferName = nick, - networkId = networkId, - type = Buffer_Type.of(Buffer_Type.QueryBuffer) - )?.let(BufferInfo::bufferId), - nick = nick, - networkId = networkId - ) - } + UserInfoActivity.launch( + requireContext(), + openBuffer = false, + bufferId = bufferSyncer.find( + bufferName = nick, + networkId = networkId, + type = Buffer_Type.of(Buffer_Type.QueryBuffer) + )?.let(BufferInfo::bufferId), + nick = nick, + networkId = networkId + ) } } diff --git a/app/src/main/res/layout/add_join.xml b/app/src/main/res/layout/add_join.xml index 6b039888cf7b61d9164697d41c54ba9f80fc8cee..abbdb7e7a92e37550ed9d4bcba903f6bcbeb4b73 100644 --- a/app/src/main/res/layout/add_join.xml +++ b/app/src/main/res/layout/add_join.xml @@ -30,39 +30,34 @@ android:layout_height="0dip" android:layout_weight="1"> - <androidx.core.widget.NestedScrollView - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <LinearLayout style="@style/Widget.CoreSettings.Wrapper"> - - <de.kuschku.ui.spinner.MaterialSpinnerLayout - style="@style/Widget.CustomSpinnerLayout" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:hint="@string/label_network"> + <LinearLayout style="@style/Widget.CoreSettings.Wrapper"> - <androidx.appcompat.widget.AppCompatSpinner - android:id="@+id/network" - style="@style/Widget.MaterialSpinner" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:listitem="@layout/widget_spinner_item_material" /> - </de.kuschku.ui.spinner.MaterialSpinnerLayout> + <de.kuschku.ui.spinner.MaterialSpinnerLayout + style="@style/Widget.CustomSpinnerLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/label_network"> - <com.google.android.material.textfield.TextInputLayout - style="@style/Widget.CustomTextInput" + <androidx.appcompat.widget.AppCompatSpinner + android:id="@+id/network" + style="@style/Widget.MaterialSpinner" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/label_channel_name"> - - <com.google.android.material.textfield.TextInputEditText - android:id="@+id/name" - style="@style/Widget.CoreSettings.EditText" - tools:text="#trees" /> - </com.google.android.material.textfield.TextInputLayout> - </LinearLayout> - </androidx.core.widget.NestedScrollView> + tools:listitem="@layout/widget_spinner_item_material" /> + </de.kuschku.ui.spinner.MaterialSpinnerLayout> + + <com.google.android.material.textfield.TextInputLayout + style="@style/Widget.CustomTextInput" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/label_channel_name"> + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/name" + style="@style/Widget.CoreSettings.EditText" + tools:text="#trees" /> + </com.google.android.material.textfield.TextInputLayout> + </LinearLayout> <de.kuschku.quasseldroid.util.ui.view.ShadowView android:layout_width="match_parent" diff --git a/app/src/main/res/layout/add_query.xml b/app/src/main/res/layout/add_query.xml index 15419319cb9314f4d75880509de63a2256c6c3ee..36a7193fa66ead803c16710ab136dee4706316f3 100644 --- a/app/src/main/res/layout/add_query.xml +++ b/app/src/main/res/layout/add_query.xml @@ -21,32 +21,76 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - android:padding="16dp"> + android:orientation="vertical"> - <de.kuschku.ui.spinner.MaterialSpinnerLayout - style="@style/Widget.CustomSpinnerLayout" + <FrameLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:hint="@string/label_network"> + android:layout_height="0dip" + android:layout_weight="1"> - <androidx.appcompat.widget.AppCompatSpinner - android:id="@+id/network" - style="@style/Widget.MaterialSpinner" + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:listitem="@layout/widget_spinner_item_material" /> - </de.kuschku.ui.spinner.MaterialSpinnerLayout> + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout style="@style/Widget.CoreSettings.Wrapper"> + + <de.kuschku.ui.spinner.MaterialSpinnerLayout + style="@style/Widget.CustomSpinnerLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/label_network"> + + <androidx.appcompat.widget.AppCompatSpinner + android:id="@+id/network" + style="@style/Widget.MaterialSpinner" + android:layout_width="match_parent" + android:layout_height="wrap_content" + tools:listitem="@layout/widget_spinner_item_material" /> + </de.kuschku.ui.spinner.MaterialSpinnerLayout> + + <com.google.android.material.textfield.TextInputLayout + style="@style/Widget.CustomTextInput" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/label_nick"> - <com.google.android.material.textfield.TextInputLayout - style="@style/Widget.CustomTextInput" + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/name" + style="@style/Widget.CoreSettings.EditText" + tools:text="justJanne" /> + </com.google.android.material.textfield.TextInputLayout> + </LinearLayout> + + <de.kuschku.quasseldroid.util.ui.fastscroll.views.FastScrollRecyclerView + android:id="@+id/list" + style="@style/Widget.FastScroller" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:listitem="@layout/widget_nick" /> + </LinearLayout> + + <de.kuschku.quasseldroid.util.ui.view.ShadowView + android:layout_width="match_parent" + android:layout_height="@dimen/shadow_height" + android:layout_gravity="bottom" + android:gravity="bottom" /> + </FrameLayout> + + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/settings_aliasitem_name"> + android:gravity="end" + android:paddingLeft="16dp" + android:paddingTop="4dp" + android:paddingRight="16dp" + android:paddingBottom="4dp"> - <com.google.android.material.textfield.TextInputEditText - android:id="@+id/name" - style="@style/Widget.CoreSettings.EditText" - tools:text="back" /> - </com.google.android.material.textfield.TextInputLayout> + <com.google.android.material.button.MaterialButton + android:id="@+id/query" + style="@style/Widget.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_query_medium" /> + </LinearLayout> </LinearLayout> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ad475ad628c724f1026e181863c9a8e425f029e..cdb820c65d9fe5b3d70ccfcd4b41bc15f64ce6c5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,6 +88,7 @@ <string name="label_new_nick">New Nick</string> <string name="label_new_server">New Server</string> <string name="label_next">Next</string> + <string name="label_nick">Nick</string> <string name="label_nicklist">Nick List</string> <string name="label_no">No</string> <string name="label_no_away_message">No away message available</string> diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt index f5ea7a7540bafa50dcc78f1dda7475173058900d..41a5a1d01568b6bdfba7009fd6a3b61d82bde2e8 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt @@ -363,7 +363,7 @@ class Network constructor( } proxy.synchronize(ircUser) _ircUsers[nick] = ircUser - live_ircUsers.onNext(_ircUsers) + live_ircUsers.onNext(Unit) ircUser } else { user @@ -376,7 +376,15 @@ class Network constructor( }.distinctUntilChanged() fun ircUsers() = _ircUsers.values.toList() + fun liveIrcUsers() = live_ircUsers.map { + ircUsers() + } + fun ircUserCount(): UInt = _ircUsers.size.toUInt() + fun liveIrcUserCount() = live_ircUsers.map { + ircUserCount() + } + fun newIrcChannel(channelName: String, initData: QVariantMap = emptyMap(), index: Int? = null): IrcChannel = ircChannel(channelName).let { channel -> @@ -389,7 +397,7 @@ class Network constructor( } proxy.synchronize(ircChannel) _ircChannels[caseMapper.toLowerCase(channelName)] = ircChannel - live_ircChannels.onNext(_ircChannels) + live_ircChannels.onNext(Unit) ircChannel } else { channel @@ -404,7 +412,15 @@ class Network constructor( }.distinctUntilChanged() fun ircChannels() = _ircChannels.values.toList() + fun liveIrcChannels() = live_ircChannels.map { + ircChannels() + } + fun ircChannelCount(): UInt = _ircChannels.size.toUInt() + fun liveIrcChannelCount() = live_ircChannels.map { + ircChannelCount() + } + fun codecForServer(): String = _codecForServer fun codecForEncoding(): String = _codecForEncoding fun codecForDecoding(): String = _codecForDecoding @@ -824,18 +840,18 @@ class Network constructor( fun removeChansAndUsers() { _ircUsers.clear() _ircChannels.clear() - live_ircChannels.onNext(_ircChannels) - live_ircUsers.onNext(_ircUsers) + live_ircChannels.onNext(Unit) + live_ircUsers.onNext(Unit) } fun removeIrcUser(user: IrcUser) { _ircUsers.remove(caseMapper.toLowerCase(user.nick())) - live_ircUsers.onNext(_ircUsers) + live_ircUsers.onNext(Unit) } fun removeIrcChannel(channel: IrcChannel) { _ircChannels.remove(caseMapper.toLowerCase(channel.name())) - live_ircChannels.onNext(_ircChannels) + live_ircChannels.onNext(Unit) } fun copy(): Network { @@ -880,10 +896,10 @@ class Network constructor( private var _channelModes: Map<ChannelModeType, Set<Char>>? = null // stores all known nicks for the server private var _ircUsers: MutableMap<String, IrcUser> = mutableMapOf() - private val live_ircUsers = BehaviorSubject.createDefault(emptyMap<String, IrcUser>()) + private val live_ircUsers = BehaviorSubject.createDefault(Unit) // stores all known channels private var _ircChannels: MutableMap<String, IrcChannel> = mutableMapOf() - private val live_ircChannels = BehaviorSubject.createDefault(emptyMap<String, IrcChannel>()) + private val live_ircChannels = BehaviorSubject.createDefault(Unit) // stores results from RPL_ISUPPORT private var _supports: MutableMap<String, String?> = mutableMapOf() set (value) { diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QueryCreateViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QueryCreateViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..dd6a0e214b04a363d754676741ed1b7a54d998d4 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QueryCreateViewModel.kt @@ -0,0 +1,29 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.viewmodel + +import androidx.lifecycle.ViewModel +import de.kuschku.libquassel.protocol.NetworkId +import io.reactivex.subjects.BehaviorSubject + +class QueryCreateViewModel : ViewModel() { + val networkId = BehaviorSubject.createDefault(NetworkId(0)) + val nickName = BehaviorSubject.createDefault("") +} diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt index fafd4901aeda344ef274453a5667b5ea04b1fc4f..a183bc95efcf6b938e362787c2d2c4468cba4755 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt @@ -41,14 +41,8 @@ data class BufferProps( val ircUser: IrcUser? = null, val avatarUrls: List<Avatar> = emptyList(), val fallbackDrawable: Drawable? = null, - val matchMode: BufferMatchMode = BufferMatchMode.EXACT + val matchMode: MatchMode = MatchMode.EXACT ) { - enum class BufferMatchMode(val priority: Int) { - EXACT(0), - START(1), - CONTAINS(2); - } - override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/IrcUserItem.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/IrcUserItem.kt index 1c69bc98cc8e1832982aea0d7555dfa5d55c42ba..581f8132196b9af61fea6b7dd38835e36adac8f8 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/IrcUserItem.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/IrcUserItem.kt @@ -20,8 +20,10 @@ package de.kuschku.quasseldroid.viewmodel.data import android.graphics.drawable.Drawable +import de.kuschku.libquassel.protocol.NetworkId data class IrcUserItem( + val networkId: NetworkId, val nick: String, val modes: String, val lowestMode: Int, @@ -34,40 +36,4 @@ data class IrcUserItem( val initial: String? = "", val fallbackDrawable: Drawable? = null, val displayNick: CharSequence? = null -) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as IrcUserItem - - if (nick != other.nick) return false - if (modes != other.modes) return false - if (lowestMode != other.lowestMode) return false - if (realname != other.realname) return false - if (hostmask != other.hostmask) return false - if (away != other.away) return false - if (self != other.self) return false - if (networkCasemapping != other.networkCasemapping) return false - if (avatarUrls != other.avatarUrls) return false - if (initial != other.initial) return false - if (displayNick != other.displayNick) return false - - return true - } - - override fun hashCode(): Int { - var result = nick.hashCode() - result = 31 * result + modes.hashCode() - result = 31 * result + lowestMode - result = 31 * result + realname.hashCode() - result = 31 * result + hostmask.hashCode() - result = 31 * result + away.hashCode() - result = 31 * result + self.hashCode() - result = 31 * result + (networkCasemapping?.hashCode() ?: 0) - result = 31 * result + avatarUrls.hashCode() - result = 31 * result + (initial?.hashCode() ?: 0) - result = 31 * result + (displayNick?.hashCode() ?: 0) - return result - } -} +) diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/MatchMode.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/MatchMode.kt new file mode 100644 index 0000000000000000000000000000000000000000..c0c4afac35fae3a1441895ce891cbc2f6b0bd142 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/MatchMode.kt @@ -0,0 +1,26 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.viewmodel.data + +enum class MatchMode(val priority: Int) { + EXACT(0), + START(1), + CONTAINS(2); +} diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt index de1ce86a4575f906a7609fe552c784de946a3dc5..48a72a1283952065c64df7a892ae8e3b8a0172ca 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt @@ -156,6 +156,7 @@ open class ChatViewModelHelper @Inject constructor( }.min() ?: prefixModes.size IrcUserItem( + bufferInfo.networkId, user.nick(), network.modesToPrefixes(userModes), lowestMode, @@ -282,12 +283,9 @@ open class ChatViewModelHelper @Inject constructor( val name = info.bufferName?.trim() ?: "" val search = bufferSearch.trim() val matchMode = when { - name.equals(search, ignoreCase = true) -> - BufferProps.BufferMatchMode.EXACT - name.startsWith(search, ignoreCase = true) -> - BufferProps.BufferMatchMode.START - else -> - BufferProps.BufferMatchMode.CONTAINS + name.equals(search, ignoreCase = true) -> MatchMode.EXACT + name.startsWith(search, ignoreCase = true) -> MatchMode.START + else -> MatchMode.CONTAINS } when (info.type.toInt()) { BufferInfo.Type.QueryBuffer.toInt() -> { diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QueryCreateViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QueryCreateViewModelHelper.kt new file mode 100644 index 0000000000000000000000000000000000000000..c32e4005b8d85f8b9015f9b453b52d5207bab9c2 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QueryCreateViewModelHelper.kt @@ -0,0 +1,29 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2019 Janne Koschinski + * Copyright (c) 2019 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.viewmodel.helper + +import de.kuschku.quasseldroid.viewmodel.QuasselViewModel +import de.kuschku.quasseldroid.viewmodel.QueryCreateViewModel +import javax.inject.Inject + +open class QueryCreateViewModelHelper @Inject constructor( + val queryCreate: QueryCreateViewModel, + quassel: QuasselViewModel +) : QuasselViewModelHelper(quassel)