diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a092edb2e4f3365b1a362ef8199abf1741989200..e9fa358c13a691cbb586898509509776b3e18689 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,16 +36,22 @@ </intent-filter> </activity> <activity - android:name=".ui.chat.info.InfoActivity" + android:name=".ui.chat.info.user.UserInfoActivity" android:exported="false" - android:label="@string/label_details" + android:label="@string/label_info_user" + android:parentActivityName=".ui.chat.ChatActivity" + android:windowSoftInputMode="adjustResize" /> + <activity + android:name=".ui.chat.info.channel.ChannelInfoActivity" + android:exported="false" + android:label="@string/label_info_channel" android:parentActivityName=".ui.chat.ChatActivity" android:windowSoftInputMode="adjustResize" /> <activity android:name=".ui.chat.topic.TopicActivity" android:exported="false" android:label="@string/label_topic" - android:parentActivityName=".ui.chat.info.InfoActivity" + android:parentActivityName=".ui.chat.info.channel.ChannelInfoActivity" android:windowSoftInputMode="adjustResize" /> <!-- Client Settings --> diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt index 193c776129355b91da732aed6a93d44f31ce0cfd..4ad51f943851fee1886be713ef0e23ba0db9fbed 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt @@ -6,8 +6,10 @@ import de.kuschku.quasseldroid.service.QuasselService import de.kuschku.quasseldroid.ui.chat.ChatActivity import de.kuschku.quasseldroid.ui.chat.ChatActivityModule import de.kuschku.quasseldroid.ui.chat.ChatFragmentProvider -import de.kuschku.quasseldroid.ui.chat.info.InfoActivity -import de.kuschku.quasseldroid.ui.chat.info.InfoFragmentProvider +import de.kuschku.quasseldroid.ui.chat.info.channel.ChannelInfoActivity +import de.kuschku.quasseldroid.ui.chat.info.channel.ChannelInfoFragmentProvider +import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity +import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoFragmentProvider import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity import de.kuschku.quasseldroid.ui.chat.topic.TopicFragmentProvider import de.kuschku.quasseldroid.ui.clientsettings.about.AboutSettingsActivity @@ -37,8 +39,11 @@ abstract class ActivityModule { @ContributesAndroidInjector(modules = [ChatActivityModule::class, ChatFragmentProvider::class]) abstract fun bindChatActivity(): ChatActivity - @ContributesAndroidInjector(modules = [InfoFragmentProvider::class]) - abstract fun bindInfoActivity(): InfoActivity + @ContributesAndroidInjector(modules = [UserInfoFragmentProvider::class]) + abstract fun bindUserInfoActivity(): UserInfoActivity + + @ContributesAndroidInjector(modules = [ChannelInfoFragmentProvider::class]) + abstract fun bindChannelInfoActivity(): ChannelInfoActivity @ContributesAndroidInjector(modules = [TopicFragmentProvider::class]) abstract fun bindTopicActivity(): TopicActivity 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 0c38ca0e057198616c50bb7faab7868e1bc746a0..5928f4594fa911d96c894bd96be43e0b0a815997 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 @@ -87,6 +87,11 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc when { intent.type == "text/plain" -> { chatlineFragment?.editorHelper?.replaceText(intent.getStringExtra(Intent.EXTRA_TEXT)) + drawerLayout.closeDrawers() + } + intent.hasExtra("bufferId") -> { + viewModel.buffer.onNext(intent.getIntExtra("bufferId", -1)) + drawerLayout.closeDrawers() } } } @@ -230,19 +235,24 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc viewModel.connectionProgress_liveData.observe(this, Observer { val (state, progress, max) = it ?: Triple(ConnectionState.DISCONNECTED, 0, 0) when (state) { - ConnectionState.CONNECTED, + ConnectionState.CONNECTED -> { + if (resources.getBoolean(R.bool.buffer_drawer_exists) && viewModel.buffer.value == -1) { + drawerLayout.openDrawer(Gravity.START) + } + progressBar.visibility = View.INVISIBLE + } ConnectionState.DISCONNECTED, - ConnectionState.CLOSED -> { + ConnectionState.CLOSED -> { progressBar.visibility = View.INVISIBLE } - ConnectionState.INIT -> { + ConnectionState.INIT -> { progressBar.visibility = View.VISIBLE // Show indeterminate when no progress has been made yet progressBar.isIndeterminate = progress == 0 || max == 0 progressBar.progress = progress progressBar.max = max } - else -> { + else -> { progressBar.visibility = View.VISIBLE progressBar.isIndeterminate = true } @@ -260,10 +270,10 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc invalidateOptionsMenu() }) + onNewIntent(intent) + editorPanel.panelState = SlidingUpPanelLayout.PanelState.COLLAPSED chatlineFragment?.panelSlideListener?.let(editorPanel::addPanelSlideListener) - - onNewIntent(intent) } var bufferData: BufferData? = null diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt index 7f0e96b92e4e16b59251609583585da0383ad8cc..68e1d88b3ae52294f12badaa8dd47adb104e336d 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt @@ -16,9 +16,8 @@ import de.kuschku.libquassel.util.helpers.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.MessageSettings -import de.kuschku.quasseldroid.ui.chat.info.InfoActivity -import de.kuschku.quasseldroid.ui.chat.info.InfoDescriptor -import de.kuschku.quasseldroid.ui.chat.info.InfoType +import de.kuschku.quasseldroid.ui.chat.info.channel.ChannelInfoActivity +import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity import de.kuschku.quasseldroid.util.helper.combineLatest import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.helper.visibleIf @@ -100,29 +99,20 @@ class ToolbarFragment : ServiceBoundFragment() { actionArea.setOnClickListener { viewModel.bufferData.value?.info?.let { info -> when (info.type.toInt()) { - BufferInfo.Type.QueryBuffer.toInt() -> InfoDescriptor( - type = InfoType.User, - nick = info.bufferName, - buffer = info.bufferId, - network = info.networkId - ) - BufferInfo.Type.ChannelBuffer.toInt() -> InfoDescriptor( - type = InfoType.Channel, - channel = info.bufferName, - buffer = info.bufferId, - network = info.networkId - ) - BufferInfo.Type.StatusBuffer.toInt() -> InfoDescriptor( - type = InfoType.Network, - buffer = info.bufferId, - network = info.networkId - ) + BufferInfo.Type.QueryBuffer.toInt() -> { + val intent = Intent(requireContext(), UserInfoActivity::class.java) + intent.putExtra("bufferId", info.bufferId) + intent.putExtra("openBuffer", true) + startActivity(intent) + } + BufferInfo.Type.ChannelBuffer.toInt() -> { + val intent = Intent(requireContext(), ChannelInfoActivity::class.java) + intent.putExtra("bufferId", info.bufferId) + intent.putExtra("openBuffer", true) + startActivity(intent) + } else -> null } - }?.let { infoDescriptor -> - val intent = Intent(requireContext(), InfoActivity::class.java) - intent.putExtra("info", infoDescriptor) - startActivity(intent) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt deleted file mode 100644 index bae8074b29ff95b78b9c30a9cafdefee85fd0ca4..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoActivity.kt +++ /dev/null @@ -1,5 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import de.kuschku.quasseldroid.util.ui.SettingsActivity - -class InfoActivity : SettingsActivity(InfoFragment()) \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoData.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoData.kt deleted file mode 100644 index de024f9ec432c259b792bf598b1e929253bda7ff..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoData.kt +++ /dev/null @@ -1,13 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import de.kuschku.libquassel.quassel.syncables.IrcChannel -import de.kuschku.libquassel.quassel.syncables.IrcUser -import de.kuschku.libquassel.quassel.syncables.Network - -data class InfoData( - val type: InfoType, - val user: IrcUser? = null, - val channel: IrcChannel? = null, - val network: Network, - val properties: List<InfoGroup> = emptyList() -) \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoDescriptor.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoDescriptor.kt deleted file mode 100644 index 95c5a772e1d0b5dcc239b95ee4f7544f55022fb5..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoDescriptor.kt +++ /dev/null @@ -1,11 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import java.io.Serializable - -data class InfoDescriptor( - val type: InfoType, - val nick: String? = null, - val channel: String? = null, - val buffer: Int, - val network: Int -) : Serializable diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragment.kt deleted file mode 100644 index 4d2df684dd09c2ad2287d69f9a945750b1cabcbb..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragment.kt +++ /dev/null @@ -1,132 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import android.arch.lifecycle.Observer -import android.content.Intent -import android.os.Bundle -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.libquassel.util.Optional -import de.kuschku.libquassel.util.compatibility.LoggingHandler -import de.kuschku.quasseldroid.R -import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity -import de.kuschku.quasseldroid.util.helper.toLiveData -import de.kuschku.quasseldroid.util.irc.format.ContentFormatter -import de.kuschku.quasseldroid.util.service.ServiceBoundFragment -import io.reactivex.Observable -import javax.inject.Inject - -class InfoFragment : ServiceBoundFragment() { - @BindView(R.id.groups) - lateinit var groups: RecyclerView - - @Inject - lateinit var contentFormatter: ContentFormatter - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { - val view = inflater.inflate(R.layout.fragment_info, container, false) - ButterKnife.bind(this, view) - - val adapter = InfoGroupAdapter() - groups.layoutManager = LinearLayoutManager(requireContext()) - groups.adapter = adapter - - val info = arguments?.getSerializable("info") as? InfoDescriptor - viewModel.session.switchMap { sessionOptional -> - val network = sessionOptional.orNull()?.networks?.get(info?.network) - if (info == null || network == null) { - Observable.just(Optional.empty()) - } else { - when (info.type) { - InfoType.User -> { - network.liveIrcUser(info.nick).switchMap { - it.updates().map { user -> - Optional.of(InfoData( - type = info.type, - user = user, - network = network, - properties = listOf( - InfoGroup( - name = getString(R.string.property_group_ircuser_identity), - properties = listOf( - InfoProperty( - name = getString(R.string.property_ircuser_nick), - value = user.nick() - ), - InfoProperty( - name = getString(R.string.property_ircuser_user), - value = user.user() - ), - InfoProperty( - name = getString(R.string.property_ircuser_host), - value = user.host() - ), - InfoProperty( - name = getString(R.string.property_ircuser_realname), - value = contentFormatter.format(requireContext(), user.realName()) - ), - InfoProperty( - name = getString(R.string.property_ircuser_account), - value = user.account() - ) - ) - ) - ) - )) - } - } - } - InfoType.Channel -> { - network.liveIrcChannel(info.channel).map { channel -> - Optional.of(InfoData( - type = info.type, - channel = channel, - network = network, - properties = listOf( - InfoGroup( - name = getString(R.string.property_group_ircchannel_channel), - properties = listOf( - InfoProperty( - name = getString(R.string.property_ircchannel_topic), - value = contentFormatter.format(requireContext(), channel.topic()), - actions = listOf( - InfoPropertyAction( - name = getString(R.string.property_ircchannel_topic_action_edit), - featured = true, - onClick = { - val intent = Intent(requireContext(), TopicActivity::class.java) - intent.putExtra("buffer", info.buffer) - startActivity(intent) - } - ) - ) - ) - ) - ) - ) - )) - } - } - InfoType.Network -> { - network.live_connectionState.map { - Optional.of(InfoData( - type = info.type, - network = network - )) - } - } - } - } - }.toLiveData().observe(this, Observer { - LoggingHandler.log(LoggingHandler.LogLevel.ERROR, "DEBUG", "data: $it") - adapter.submitList(it?.orNull()?.properties.orEmpty()) - }) - - return view - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt deleted file mode 100644 index 898bd179e08a1d576db8298ad6ede990484b17bb..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoFragmentProvider.kt +++ /dev/null @@ -1,10 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import dagger.Module -import dagger.android.ContributesAndroidInjector - -@Module -abstract class InfoFragmentProvider { - @ContributesAndroidInjector - abstract fun bindInfoFragment(): InfoFragment -} \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroup.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroup.kt deleted file mode 100644 index 0aa745099819dce3bf49e6a296ae829c5c049448..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroup.kt +++ /dev/null @@ -1,7 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -data class InfoGroup( - val name: CharSequence, - val properties: List<InfoProperty> -) - diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroupAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroupAdapter.kt deleted file mode 100644 index dac37f9133c66ed8503610723c2aea71516d124c..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoGroupAdapter.kt +++ /dev/null @@ -1,58 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import android.support.v7.recyclerview.extensions.ListAdapter -import android.support.v7.util.DiffUtil -import android.support.v7.widget.DividerItemDecoration -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R - -class InfoGroupAdapter : - ListAdapter<InfoGroup, InfoGroupAdapter.InfoGroupViewHolder>( - object : DiffUtil.ItemCallback<InfoGroup>() { - override fun areItemsTheSame(oldItem: InfoGroup, newItem: InfoGroup) = - oldItem.name == newItem.name - - override fun areContentsTheSame(oldItem: InfoGroup, newItem: InfoGroup) = - oldItem == newItem - } - ) { - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = InfoGroupViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_info_group, parent, false) - ) - - override fun onBindViewHolder(holder: InfoGroupViewHolder, position: Int) = - holder.bind(getItem(position)) - - class InfoGroupViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.title) - lateinit var title: TextView - - @BindView(R.id.properties) - lateinit var properties: RecyclerView - - private val adapter = InfoPropertyAdapter() - - init { - ButterKnife.bind(this, itemView) - - properties.layoutManager = LinearLayoutManager(itemView.context) - properties.adapter = adapter - properties.addItemDecoration( - DividerItemDecoration(itemView.context, DividerItemDecoration.VERTICAL) - ) - } - - fun bind(item: InfoGroup) { - title.text = item.name - adapter.submitList(item.properties) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoProperty.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoProperty.kt deleted file mode 100644 index 4ad5d5d7043b93d25d6702c1a6763599857d257e..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoProperty.kt +++ /dev/null @@ -1,10 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import android.support.annotation.DrawableRes - -data class InfoProperty( - val name: CharSequence? = null, - @DrawableRes val icon: Int? = null, - val value: CharSequence, - val actions: List<InfoPropertyAction> = emptyList() -) \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAction.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAction.kt deleted file mode 100644 index c8608d7cc5d6ad24b25acc892b86a9cdf60e9527..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAction.kt +++ /dev/null @@ -1,7 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -data class InfoPropertyAction( - val name: CharSequence, - val featured: Boolean = false, - val onClick: () -> Unit -) \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyActionAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyActionAdapter.kt deleted file mode 100644 index 69fbf011abcfd19e1c02835044c103733c6b49a1..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyActionAdapter.kt +++ /dev/null @@ -1,66 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import android.support.v7.recyclerview.extensions.ListAdapter -import android.support.v7.util.DiffUtil -import android.support.v7.widget.RecyclerView -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R - -class InfoPropertyActionAdapter : - ListAdapter<InfoPropertyAction, InfoPropertyActionAdapter.InfoPropertyActionViewHolder>( - object : DiffUtil.ItemCallback<InfoPropertyAction>() { - override fun areItemsTheSame(oldItem: InfoPropertyAction, newItem: InfoPropertyAction) = - oldItem.name == newItem.name - - override fun areContentsTheSame(oldItem: InfoPropertyAction, newItem: InfoPropertyAction) = - oldItem == newItem - } - ) { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = InfoPropertyActionViewHolder( - LayoutInflater.from(parent.context).inflate( - if (viewType == VIEWTYPE_FEATURED) - R.layout.widget_info_action_main - else - R.layout.widget_info_action, - parent, - false - ) - ) - - override fun onBindViewHolder(holder: InfoPropertyActionViewHolder, position: Int) { - holder.bind(getItem(position)) - } - - override fun getItemViewType(position: Int) = - if (getItem(position).featured) VIEWTYPE_FEATURED else VIEWTYPE_NORMAL - - class InfoPropertyActionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.button) - lateinit var button: Button - - private var onClick: (() -> Unit)? = null - - init { - ButterKnife.bind(this, itemView) - button.setOnClickListener { - onClick?.invoke() - } - } - - fun bind(item: InfoPropertyAction) { - this.onClick = item.onClick - - button.text = item.name - } - } - - companion object { - const val VIEWTYPE_NORMAL = 0 - const val VIEWTYPE_FEATURED = 1 - } -} \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAdapter.kt deleted file mode 100644 index 601e6cfe77d97578265d5194d6cf777bd32d0170..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoPropertyAdapter.kt +++ /dev/null @@ -1,72 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -import android.support.v7.recyclerview.extensions.ListAdapter -import android.support.v7.util.DiffUtil -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import butterknife.BindView -import butterknife.ButterKnife -import de.kuschku.quasseldroid.R -import de.kuschku.quasseldroid.util.helper.visibleIf -import me.saket.bettermovementmethod.BetterLinkMovementMethod - -class InfoPropertyAdapter : - ListAdapter<InfoProperty, InfoPropertyAdapter.InfoPropertyViewHolder>( - object : DiffUtil.ItemCallback<InfoProperty>() { - override fun areItemsTheSame(oldItem: InfoProperty, newItem: InfoProperty) = - oldItem.name == newItem.name - - override fun areContentsTheSame(oldItem: InfoProperty, newItem: InfoProperty) = - oldItem == newItem - } - ) { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = InfoPropertyViewHolder( - LayoutInflater.from(parent.context).inflate(R.layout.widget_info_property, parent, false) - ) - - override fun onBindViewHolder(holder: InfoPropertyViewHolder, position: Int) = - holder.bind(getItem(position)) - - class InfoPropertyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.icon_frame) - lateinit var iconFrame: View - - @BindView(R.id.icon) - lateinit var icon: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.value) - lateinit var value: TextView - - @BindView(R.id.actions) - lateinit var actions: RecyclerView - - private val adapter = InfoPropertyActionAdapter() - - init { - ButterKnife.bind(this, itemView) - - actions.layoutManager = LinearLayoutManager(itemView.context, RecyclerView.HORIZONTAL, false) - actions.adapter = adapter - - value.movementMethod = BetterLinkMovementMethod.getInstance() - } - - fun bind(item: InfoProperty) { - item.icon?.let(icon::setImageResource) - name.text = item.name - value.text = item.value - - adapter.submitList(item.actions) - - iconFrame.visibleIf(item.icon != null) - } - } -} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoType.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoType.kt deleted file mode 100644 index dbff4d7234a3d4593535682fda86277ecd8f2c91..0000000000000000000000000000000000000000 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/InfoType.kt +++ /dev/null @@ -1,7 +0,0 @@ -package de.kuschku.quasseldroid.ui.chat.info - -enum class InfoType { - User, - Channel, - Network -} \ No newline at end of file diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..c64c7f76221cd5c411f74144b4c9d3cb779eb0ca --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoActivity.kt @@ -0,0 +1,5 @@ +package de.kuschku.quasseldroid.ui.chat.info.channel + +import de.kuschku.quasseldroid.util.ui.SettingsActivity + +class ChannelInfoActivity : SettingsActivity(ChannelInfoFragment()) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..b544546463242d7b092bb6c504ed83b7a4269eef --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragment.kt @@ -0,0 +1,94 @@ +package de.kuschku.quasseldroid.ui.chat.info.channel + +import android.arch.lifecycle.Observer +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import butterknife.BindView +import butterknife.ButterKnife +import de.kuschku.libquassel.protocol.Buffer_Type +import de.kuschku.libquassel.quassel.syncables.IrcChannel +import de.kuschku.libquassel.util.helpers.value +import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity +import de.kuschku.quasseldroid.util.helper.combineLatest +import de.kuschku.quasseldroid.util.helper.toLiveData +import de.kuschku.quasseldroid.util.irc.format.ContentFormatter +import de.kuschku.quasseldroid.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid.util.ui.LinkLongClickMenuHelper +import me.saket.bettermovementmethod.BetterLinkMovementMethod +import javax.inject.Inject + +class ChannelInfoFragment : ServiceBoundFragment() { + + @BindView(R.id.name) + lateinit var name: TextView + + @BindView(R.id.topic) + lateinit var topic: TextView + + @BindView(R.id.action_edit_topic) + lateinit var actionEditTopic: Button + + @BindView(R.id.action_part) + lateinit var actionPart: Button + + @Inject + lateinit var contentFormatter: ContentFormatter + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + val view = inflater.inflate(R.layout.fragment_info_channel, container, false) + ButterKnife.bind(this, view) + + val openBuffer = arguments?.getBoolean("openBuffer") + + combineLatest(viewModel.session, viewModel.networks).map { (sessionOptional, networks) -> + if (openBuffer == true) { + val session = sessionOptional?.orNull() + val bufferSyncer = session?.bufferSyncer + val bufferInfo = bufferSyncer?.bufferInfo(arguments?.getInt("bufferId") ?: -1) + bufferInfo?.let { + networks[it.networkId]?.ircChannel(it.bufferName) + } + } else { + networks[arguments?.getInt("networkId")]?.ircChannel(arguments?.getString("nick")) + } ?: IrcChannel.NULL + }.filter { + it != IrcChannel.NULL + }.switchMap(IrcChannel::updates).firstElement().toLiveData().observe(this, Observer { channel -> + if (channel != null) { + name.text = channel.name() + topic.text = contentFormatter.format(requireContext(), channel.topic()) + + actionEditTopic.setOnClickListener { + val intent = Intent(requireContext(), TopicActivity::class.java) + intent.putExtra("buffer", arguments?.getInt("bufferId") ?: -1) + startActivity(intent) + } + + actionPart.setOnClickListener { + viewModel.session.value?.orNull()?.let { session -> + session.bufferSyncer?.find( + networkId = channel.network().networkId(), + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.let { statusInfo -> + session.rpcHandler?.sendInput(statusInfo, "/part ${channel.name()}") + requireActivity().finish() + } + } + } + } + }) + + val movementMethod = BetterLinkMovementMethod.newInstance() + movementMethod.setOnLinkLongClickListener(LinkLongClickMenuHelper()) + topic.movementMethod = movementMethod + + return view + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragmentProvider.kt new file mode 100644 index 0000000000000000000000000000000000000000..6bca755dfb3ec200e4f9291657ea4a396ca923c4 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/channel/ChannelInfoFragmentProvider.kt @@ -0,0 +1,10 @@ +package de.kuschku.quasseldroid.ui.chat.info.channel + +import dagger.Module +import dagger.android.ContributesAndroidInjector + +@Module +abstract class ChannelInfoFragmentProvider { + @ContributesAndroidInjector + abstract fun bindChannelInfoFragment(): ChannelInfoFragment +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..3cc0d54c02584b3c1a27ff22f53cb75d6ab105b2 --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoActivity.kt @@ -0,0 +1,5 @@ +package de.kuschku.quasseldroid.ui.chat.info.user + +import de.kuschku.quasseldroid.util.ui.SettingsActivity + +class UserInfoActivity : SettingsActivity(UserInfoFragment()) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..d51d1e07b2a5141fb6465f2120eb7ba8f6cf2f7c --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt @@ -0,0 +1,214 @@ +package de.kuschku.quasseldroid.ui.chat.info.user + +import android.arch.lifecycle.Observer +import android.content.Intent +import android.os.Bundle +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 android.widget.Toast +import butterknife.BindView +import butterknife.ButterKnife +import de.kuschku.libquassel.protocol.Buffer_Type +import de.kuschku.libquassel.quassel.syncables.IrcUser +import de.kuschku.libquassel.util.IrcUserUtils +import de.kuschku.quasseldroid.GlideApp +import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.ui.chat.ChatActivity +import de.kuschku.quasseldroid.ui.chat.input.AutoCompleteHelper.Companion.IGNORED_CHARS +import de.kuschku.quasseldroid.util.helper.* +import de.kuschku.quasseldroid.util.irc.format.ContentFormatter +import de.kuschku.quasseldroid.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid.util.ui.LinkLongClickMenuHelper +import de.kuschku.quasseldroid.util.ui.TextDrawable +import me.saket.bettermovementmethod.BetterLinkMovementMethod +import javax.inject.Inject + +class UserInfoFragment : ServiceBoundFragment() { + @BindView(R.id.avatar) + lateinit var avatar: ImageView + + @BindView(R.id.nick) + lateinit var nick: TextView + + @BindView(R.id.real_name) + lateinit var realName: TextView + + @BindView(R.id.action_query) + lateinit var actionQuery: Button + + @BindView(R.id.action_ignore) + lateinit var actionIgnore: Button + + @BindView(R.id.action_mention) + lateinit var actionMention: Button + + @BindView(R.id.away_container) + lateinit var awayContainer: ViewGroup + + @BindView(R.id.away_message) + lateinit var awayMessage: TextView + + @BindView(R.id.account_container) + lateinit var accountContainer: ViewGroup + + @BindView(R.id.account) + lateinit var account: TextView + + @BindView(R.id.ident_container) + lateinit var identContainer: ViewGroup + + @BindView(R.id.ident) + lateinit var ident: TextView + + @BindView(R.id.host_container) + lateinit var hostContainer: ViewGroup + + @BindView(R.id.host) + lateinit var host: TextView + + @BindView(R.id.server_container) + lateinit var serverContainer: ViewGroup + + @BindView(R.id.server) + lateinit var server: TextView + + @Inject + lateinit var contentFormatter: ContentFormatter + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + val view = inflater.inflate(R.layout.fragment_info_user, container, false) + ButterKnife.bind(this, view) + + val openBuffer = arguments?.getBoolean("openBuffer") + + 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 networkId = arguments?.getInt("networkId") + val nickName = arguments?.getString("nick") + combineLatest(viewModel.session, viewModel.networks).map { (sessionOptional, networks) -> + if (openBuffer == true) { + val session = sessionOptional?.orNull() + val bufferSyncer = session?.bufferSyncer + val bufferInfo = bufferSyncer?.bufferInfo(arguments?.getInt("bufferId") ?: -1) + bufferInfo?.let { + networks[it.networkId]?.ircUser(it.bufferName) + } + } else { + networks[networkId]?.ircUser(nickName) + } ?: IrcUser.NULL + }.filter { + it != IrcUser.NULL + }.switchMap(IrcUser::updates).firstElement().toLiveData().observe(this, Observer { user -> + if (user != null) { + val senderColorIndex = IrcUserUtils.senderColor(user.nick()) + val rawInitial = user.nick().trimStart(*IGNORED_CHARS).firstOrNull() + ?: user.nick().firstOrNull() + val initial = rawInitial?.toUpperCase().toString() + val senderColor = senderColors[senderColorIndex] + + val fallbackDrawable = TextDrawable.builder().buildRect(initial, senderColor) + + val avatarUrl = Regex("[us]id(\\d+)").matchEntire(user.user())?.groupValues?.lastOrNull()?.let { + "https://www.irccloud.com/avatar-redirect/$it" + } + if (avatarUrl != null) { + GlideApp.with(avatar) + .load(avatarUrl) + .placeholder(fallbackDrawable) + .into(avatar) + } else { + avatar.setImageDrawable(fallbackDrawable) + } + + nick.text = user.nick() + realName.text = contentFormatter.format(requireContext(), user.realName()) + realName.visibleIf(user.realName().isNotBlank() && user.realName() != user.nick()) + + awayMessage.text = user.awayMessage() + awayContainer.visibleIf(user.awayMessage().isNotBlank()) + + account.text = user.user() + accountContainer.visibleIf(user.account().isNotBlank()) + + ident.text = user.user() + identContainer.visibleIf(user.user().isNotBlank()) + + host.text = user.host() + hostContainer.visibleIf(user.host().isNotBlank()) + + server.text = user.server() + serverContainer.visibleIf(user.server().isNotBlank()) + + actionQuery.setOnClickListener { + viewModel.session { + it.orNull()?.let { session -> + val info = session.bufferSyncer?.find( + bufferName = user.nick(), + networkId = user.network().networkId(), + type = Buffer_Type.of(Buffer_Type.QueryBuffer) + ) + + val intent = Intent(requireContext(), ChatActivity::class.java) + if (info != null) { + intent.putExtra("bufferId", info.bufferId) + startActivity(intent) + } else { + viewModel.allBuffers.map { + listOfNotNull(it.find { + it.networkId == user.network().networkId() && it.bufferName == user.nick() + }) + }.filter { + it.isNotEmpty() + }.firstElement().toLiveData().observe(this, Observer { + it?.firstOrNull()?.let { info -> + intent.putExtra("bufferId", info.bufferId) + startActivity(intent) + } + }) + + session.bufferSyncer?.find( + networkId = networkId, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.let { statusInfo -> + session.rpcHandler?.sendInput(statusInfo, "/query ${user.nick()}") + } + } + } + } + } + + actionMention.setOnClickListener { + val intent = Intent(requireContext(), ChatActivity::class.java) + intent.type = "text/plain" + intent.putExtra(Intent.EXTRA_TEXT, "${user.nick()}: ") + startActivity(intent) + } + actionMention.visibleIf(arguments?.getBoolean("openBuffer") == false) + + actionIgnore.setOnClickListener { + Toast.makeText(requireContext(), "Not Implemented", Toast.LENGTH_SHORT).show() + } + } + }) + + val movementMethod = BetterLinkMovementMethod.newInstance() + movementMethod.setOnLinkLongClickListener(LinkLongClickMenuHelper()) + realName.movementMethod = movementMethod + + return view + } +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragmentProvider.kt new file mode 100644 index 0000000000000000000000000000000000000000..994507160756e1b3a47666fc025a1bdd66e316ab --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragmentProvider.kt @@ -0,0 +1,10 @@ +package de.kuschku.quasseldroid.ui.chat.info.user + +import dagger.Module +import dagger.android.ContributesAndroidInjector + +@Module +abstract class UserInfoFragmentProvider { + @ContributesAndroidInjector + abstract fun bindUserInfoFragment(): UserInfoFragment +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt index 7b16060cc2dfc00769ce33d7c5fbc0c50ef086ac..abfe089374e67264cc3579a4cae46b89a6853217 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt @@ -10,7 +10,6 @@ import android.os.Bundle import android.support.design.widget.FloatingActionButton import android.support.v4.widget.SwipeRefreshLayout import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.PopupMenu import android.support.v7.widget.RecyclerView import android.text.SpannableStringBuilder import android.util.TypedValue @@ -33,6 +32,7 @@ import de.kuschku.quasseldroid.settings.BacklogSettings import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.service.ServiceBoundFragment +import de.kuschku.quasseldroid.util.ui.LinkLongClickMenuHelper import de.kuschku.quasseldroid.util.ui.SpanFormatter import io.reactivex.BackpressureStrategy import org.threeten.bp.ZoneId @@ -176,7 +176,6 @@ class MessageListFragment : ServiceBoundFragment() { linearLayoutManager = LinearLayoutManager(context) linearLayoutManager.reverseLayout = true - var linkMenu: PopupMenu? = null adapter.setOnClickListener { msg -> if (actionMode != null) { if (!viewModel.selectedMessagesToggle(msg.id, msg)) { @@ -192,43 +191,7 @@ class MessageListFragment : ServiceBoundFragment() { actionMode?.finish() } } - adapter.setOnUrlLongClickListener { textView, url -> - if (linkMenu == null) { - linkMenu = PopupMenu(requireContext(), textView).also { menu -> - linkMenu?.dismiss() - menu.menuInflater.inflate(R.menu.context_link, menu.menu) - menu.setOnMenuItemClickListener { - when (it.itemId) { - R.id.action_copy -> { - val clipboard = requireContext().systemService<ClipboardManager>() - val clip = ClipData.newPlainText(null, url) - clipboard.primaryClip = clip - menu.dismiss() - linkMenu = null - true - } - R.id.action_share -> { - val intent = Intent(Intent.ACTION_SEND) - intent.type = "text/plain" - intent.putExtra(Intent.EXTRA_TEXT, url) - requireContext().startActivity( - Intent.createChooser(intent, requireContext().getString(R.string.label_share)) - ) - menu.dismiss() - linkMenu = null - true - } - else -> false - } - } - menu.setOnDismissListener { - linkMenu = null - } - menu.show() - } - } - true - } + adapter.setOnUrlLongClickListener(LinkLongClickMenuHelper()) messageList.adapter = adapter messageList.layoutManager = linearLayoutManager @@ -240,7 +203,7 @@ class MessageListFragment : ServiceBoundFragment() { 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(16) { + IntArray(length()) { getColor(it, 0) } } 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 92d862977c2ad2ab9de2deb4775912a3d2f96603..94caac56406a66c7b18d42872902c5b950b9f2d4 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 @@ -93,6 +93,7 @@ class NickListAdapter( .placeholder(data.fallbackDrawable) .into(avatar) } else { + GlideApp.with(itemView).clear(avatar) avatar.setImageDrawable(data.fallbackDrawable) } } 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 8d0362fbfceb852ccf3dc4d49a2f30d98d7de447..e86cb6717ab67ff5129da142586c00520d23c3fb 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 @@ -28,9 +28,7 @@ import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.MessageSettings -import de.kuschku.quasseldroid.ui.chat.info.InfoActivity -import de.kuschku.quasseldroid.ui.chat.info.InfoDescriptor -import de.kuschku.quasseldroid.ui.chat.info.InfoType +import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer @@ -70,7 +68,7 @@ class NickListFragment : ServiceBoundFragment() { 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(16) { + IntArray(length()) { getColor(it, 0) } } @@ -154,17 +152,17 @@ class NickListFragment : ServiceBoundFragment() { private val clickListener: ((String) -> Unit)? = { nick -> viewModel.session.value?.orNull()?.bufferSyncer?.let { bufferSyncer -> viewModel.bufferData.value?.info?.let(BufferInfo::networkId)?.let { networkId -> - val intent = Intent(requireContext(), InfoActivity::class.java) - intent.putExtra("info", InfoDescriptor( - type = InfoType.User, - nick = nick, - buffer = bufferSyncer.find( - bufferName = nick, - networkId = networkId, - type = Buffer_Type.of(Buffer_Type.QueryBuffer) - )?.bufferId ?: -1, - network = networkId - )) + val intent = Intent(requireContext(), UserInfoActivity::class.java) + bufferSyncer.find( + bufferName = nick, + networkId = networkId, + type = Buffer_Type.of(Buffer_Type.QueryBuffer) + )?.let { + intent.putExtra("bufferId", it.bufferId) + } + intent.putExtra("nick", nick) + intent.putExtra("networkId", networkId) + intent.putExtra("openBuffer", false) startActivity(intent) } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/LinkLongClickMenuHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/LinkLongClickMenuHelper.kt new file mode 100644 index 0000000000000000000000000000000000000000..89685a9842a34d0b12cc4241665ffecb9ceb06aa --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/LinkLongClickMenuHelper.kt @@ -0,0 +1,55 @@ +package de.kuschku.quasseldroid.util.ui + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Intent +import android.support.v7.widget.PopupMenu +import android.widget.TextView +import de.kuschku.quasseldroid.R +import de.kuschku.quasseldroid.util.helper.systemService +import me.saket.bettermovementmethod.BetterLinkMovementMethod + +class LinkLongClickMenuHelper : + BetterLinkMovementMethod.OnLinkLongClickListener, + ((TextView, String) -> Boolean) { + private var linkMenu: PopupMenu? = null + + override fun invoke(anchor: TextView, url: String) = onLongClick(anchor, url) + override fun onLongClick(anchor: TextView, url: String?): Boolean { + if (linkMenu == null) { + linkMenu = PopupMenu(anchor.context, anchor).also { menu -> + linkMenu?.dismiss() + menu.menuInflater.inflate(R.menu.context_link, menu.menu) + menu.setOnMenuItemClickListener { + when (it.itemId) { + R.id.action_copy -> { + val clipboard = anchor.context.systemService<ClipboardManager>() + val clip = ClipData.newPlainText(null, url) + clipboard.primaryClip = clip + menu.dismiss() + linkMenu = null + true + } + R.id.action_share -> { + val intent = Intent(Intent.ACTION_SEND) + intent.type = "text/plain" + intent.putExtra(Intent.EXTRA_TEXT, url) + anchor.context.startActivity( + Intent.createChooser(intent, anchor.context.getString(R.string.label_share)) + ) + menu.dismiss() + linkMenu = null + true + } + else -> false + } + } + menu.setOnDismissListener { + linkMenu = null + } + menu.show() + } + } + return true + } +} diff --git a/app/src/main/res/drawable/ic_account_minus.xml b/app/src/main/res/drawable/ic_account_minus.xml new file mode 100644 index 0000000000000000000000000000000000000000..dc0f1f32950c905017c84e3b23f23b5f17f5acfc --- /dev/null +++ b/app/src/main/res/drawable/ic_account_minus.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#000" + android:pathData="M15,14C12.33,14 7,15.33 7,18V20H23V18C23,15.33 17.67,14 15,14M1,10V12H9V10M15,12A4,4 0 0,0 19,8A4,4 0 0,0 15,4A4,4 0 0,0 11,8A4,4 0 0,0 15,12Z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_account_plus.xml b/app/src/main/res/drawable/ic_account_plus.xml new file mode 100644 index 0000000000000000000000000000000000000000..fbc381a4469f5ec484343f138d5e382fe59fe34c --- /dev/null +++ b/app/src/main/res/drawable/ic_account_plus.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#000" + android:pathData="M15,14C12.33,14 7,15.33 7,18V20H23V18C23,15.33 17.67,14 15,14M6,10V7H4V10H1V12H4V15H6V12H9V10M15,12A4,4 0 0,0 19,8A4,4 0 0,0 15,4A4,4 0 0,0 11,8A4,4 0 0,0 15,12Z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_eye_off.xml b/app/src/main/res/drawable/ic_eye_off.xml new file mode 100644 index 0000000000000000000000000000000000000000..41ae207439efeab44e18e50476b196c7d757b013 --- /dev/null +++ b/app/src/main/res/drawable/ic_eye_off.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#000" + android:pathData="M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8b47f8192b3ac613eb0f0b070cb27185c7c2267 --- /dev/null +++ b/app/src/main/res/drawable/ic_info.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#000" + android:pathData="M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_share_alternative.xml b/app/src/main/res/drawable/ic_share_alternative.xml new file mode 100644 index 0000000000000000000000000000000000000000..bea42a3496b91d83bec3924d801c7e0f3786608e --- /dev/null +++ b/app/src/main/res/drawable/ic_share_alternative.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:fillColor="#000" + android:pathData="M21,11L14,4V8C7,9 4,14 3,19C5.5,15.5 9,13.9 14,13.9V18L21,11Z" /> +</vector> diff --git a/app/src/main/res/layout/fragment_info.xml b/app/src/main/res/layout/fragment_info.xml deleted file mode 100644 index dc7eecec160578e0f13a10fbc101fdceddf75570..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/fragment_info.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/groups" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingTop="12dp" - tools:listitem="@layout/widget_info_group" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_info_channel.xml b/app/src/main/res/layout/fragment_info_channel.xml new file mode 100644 index 0000000000000000000000000000000000000000..b32e0e625fbcd4103a25663b08b3de4c2c0d2c1a --- /dev/null +++ b/app/src/main/res/layout/fragment_info_channel.xml @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?listPreferredItemHeight" + android:orientation="vertical" + android:paddingBottom="8dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="8dp"> + + <TextView + android:id="@+id/name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.AppCompat.Headline" + tools:text="#quassel" /> + + <TextView + android:id="@+id/topic" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:textAppearance="@style/TextAppearance.AppCompat.Medium" + tools:text="Quassel IRC - https://quassel-irc.org || Latest: 0.12.4 || Mailing Lists: https://lists.quassel-irc.org || Tracker: https://bugs.quassel-irc.org || Activity RSS: #quassel-announce || German: #quassel.de || Quassel on Android: #quasseldroid; on iOS: #woboquassel || Server migration complete; new IPs may still need some time to propagate" /> + </LinearLayout> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?colorDivider" /> + + <HorizontalScrollView + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft"> + + <android.support.v7.widget.AppCompatButton + android:id="@+id/action_edit_topic" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?backgroundMenuItem" + android:drawablePadding="4dp" + android:drawableTop="@drawable/ic_pencil" + android:fontFamily="sans-serif" + android:minWidth="96dp" + android:paddingBottom="12dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="12dp" + android:text="@string/label_edit_topic" + android:textAllCaps="false" + android:textStyle="normal" /> + + <android.support.v7.widget.AppCompatButton + android:id="@+id/action_part" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?backgroundMenuItem" + android:drawablePadding="4dp" + android:drawableTop="@drawable/ic_account_minus" + android:fontFamily="sans-serif" + android:minWidth="96dp" + android:paddingBottom="12dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="12dp" + android:text="@string/label_part" + android:textAllCaps="false" + android:textStyle="normal" /> + </LinearLayout> + </HorizontalScrollView> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?colorDivider" /> + </LinearLayout> +</android.support.v4.widget.NestedScrollView> diff --git a/app/src/main/res/layout/fragment_info_user.xml b/app/src/main/res/layout/fragment_info_user.xml new file mode 100644 index 0000000000000000000000000000000000000000..3b5ba6ff7dfeb4ace7940c8234aceb455bc34807 --- /dev/null +++ b/app/src/main/res/layout/fragment_info_user.xml @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <android.support.constraint.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/avatar" + android:layout_width="match_parent" + android:layout_height="0dp" + android:scaleType="centerCrop" + app:layout_constraintDimensionRatio="H,1.77:1" + tools:src="@tools:sample/avatars" /> + + </android.support.constraint.ConstraintLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?listPreferredItemHeight" + android:orientation="vertical" + android:paddingBottom="8dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="8dp"> + + <TextView + android:id="@+id/nick" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.AppCompat.Headline" + tools:text="justJanne" /> + + <TextView + android:id="@+id/real_name" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:textAppearance="@style/TextAppearance.AppCompat.Medium" + tools:text="Janne Koschinski https://kuschku.de/" /> + </LinearLayout> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?colorDivider" /> + + <HorizontalScrollView + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft"> + + <android.support.v7.widget.AppCompatButton + android:id="@+id/action_query" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?backgroundMenuItem" + android:drawablePadding="4dp" + android:drawableTop="@drawable/ic_message_bulleted" + android:fontFamily="sans-serif" + android:minWidth="96dp" + android:paddingBottom="12dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="12dp" + android:text="@string/label_query" + android:textAllCaps="false" + android:textStyle="normal" /> + + <android.support.v7.widget.AppCompatButton + android:id="@+id/action_ignore" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?backgroundMenuItem" + android:drawablePadding="4dp" + android:drawableTop="@drawable/ic_eye_off" + android:fontFamily="sans-serif" + android:minWidth="96dp" + android:paddingBottom="12dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="12dp" + android:text="@string/label_ignore" + android:textAllCaps="false" + android:textStyle="normal" /> + + <android.support.v7.widget.AppCompatButton + android:id="@+id/action_mention" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?backgroundMenuItem" + android:drawablePadding="4dp" + android:drawableTop="@drawable/ic_share_alternative" + android:fontFamily="sans-serif" + android:minWidth="96dp" + android:paddingBottom="12dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="12dp" + android:text="@string/label_mention" + android:textAllCaps="false" + android:textStyle="normal" /> + </LinearLayout> + </HorizontalScrollView> + + <LinearLayout + android:id="@+id/away_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?colorDivider" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="48dp" + android:paddingBottom="8dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="8dp" + android:text="@string/label_user_away" + android:textColor="?colorTextPrimary" + android:textStyle="bold" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="16dp"> + + <TextView + android:id="@+id/away_message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="?colorTextPrimary" + android:textSize="16sp" + tools:text="~justJanne" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_user_away_reason" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?colorTextSecondary" /> + </LinearLayout> + </LinearLayout> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?colorDivider" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="48dp" + android:paddingBottom="8dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="8dp" + android:text="@string/label_user_identity" + android:textColor="?colorTextPrimary" + android:textStyle="bold" /> + + <LinearLayout + android:id="@+id/account_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="16dp"> + + <TextView + android:id="@+id/account" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="?colorTextPrimary" + android:textSize="16sp" + tools:text="kuschku" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_user_account" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?colorTextSecondary" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/ident_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="16dp"> + + <TextView + android:id="@+id/ident" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="?colorTextPrimary" + android:textSize="16sp" + tools:text="~justJanne" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_user_ident" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?colorTextSecondary" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/host_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="16dp"> + + <TextView + android:id="@+id/host" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="?colorTextPrimary" + android:textSize="16sp" + tools:text="lithium.kuschku.de" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_user_host" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?colorTextSecondary" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/server_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingEnd="?android:attr/listPreferredItemPaddingRight" + android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" + android:paddingRight="?android:attr/listPreferredItemPaddingRight" + android:paddingStart="?android:attr/listPreferredItemPaddingLeft" + android:paddingTop="16dp"> + + <TextView + android:id="@+id/server" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="?colorTextPrimary" + android:textSize="16sp" + tools:text="irc.freenode.org" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_user_server" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?colorTextSecondary" /> + </LinearLayout> + </LinearLayout> +</android.support.v4.widget.NestedScrollView> diff --git a/app/src/main/res/layout/fragment_topic.xml b/app/src/main/res/layout/fragment_topic.xml index 0cbc3a0de9506a45fdaf522151df6acb8c987bbd..dedaeaddadaecf745ba7f45ae4714d151207588b 100644 --- a/app/src/main/res/layout/fragment_topic.xml +++ b/app/src/main/res/layout/fragment_topic.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:minHeight="240dp" android:orientation="vertical"> <ScrollView diff --git a/app/src/main/res/layout/widget_info_action.xml b/app/src/main/res/layout/widget_info_action.xml deleted file mode 100644 index e856cbc5b64a345113d53e7e70a4c6f9dcf267b1..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/widget_info_action.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Button xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/button" - style="@style/Widget.Button.Borderless" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - tools:text="Change Topic" /> \ No newline at end of file diff --git a/app/src/main/res/layout/widget_info_action_main.xml b/app/src/main/res/layout/widget_info_action_main.xml deleted file mode 100644 index 7738bf5d6a2c16bc4cc420d628fcc8fa870c9076..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/widget_info_action_main.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Button xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/button" - style="@style/Widget.Button.Borderless.Colored" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - tools:text="Change Topic" /> \ No newline at end of file diff --git a/app/src/main/res/layout/widget_info_group.xml b/app/src/main/res/layout/widget_info_group.xml deleted file mode 100644 index f2d46a3678060db1c10224a45d883370b4d4514a..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/widget_info_group.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center_vertical" - android:minHeight="?android:attr/listPreferredItemHeightSmall" - android:paddingBottom="8dp" - android:paddingEnd="?android:attr/listPreferredItemPaddingRight" - android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" - android:paddingRight="?android:attr/listPreferredItemPaddingRight" - android:paddingStart="?android:attr/listPreferredItemPaddingLeft" - android:paddingTop="8dp" - android:textColor="?colorAccent" - android:textSize="16sp" - android:textStyle="bold" - tools:text="@sample/userinfo_groups.json/data/name" /> - - <android.support.v7.widget.RecyclerView - android:id="@+id/properties" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:itemCount="3" - tools:listitem="@layout/widget_info_property" /> - -</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/widget_info_property.xml b/app/src/main/res/layout/widget_info_property.xml deleted file mode 100644 index af097757a8c948a9fa5f8b8717e73a99b076af53..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/widget_info_property.xml +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="?android:attr/selectableItemBackground" - android:baselineAligned="false" - android:clipToPadding="false" - android:focusable="true" - android:gravity="center_vertical" - android:minHeight="?android:attr/listPreferredItemHeightSmall" - android:paddingEnd="?android:attr/listPreferredItemPaddingRight" - android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" - android:paddingRight="?android:attr/listPreferredItemPaddingRight" - android:paddingStart="?android:attr/listPreferredItemPaddingLeft"> - - <FrameLayout - android:id="@+id/icon_frame" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginLeft="-4dp" - android:layout_marginStart="-4dp" - android:gravity="start|center_vertical" - android:minWidth="60dp" - android:orientation="horizontal" - android:paddingBottom="4dp" - android:paddingEnd="12dp" - android:paddingLeft="0dp" - android:paddingRight="12dp" - android:paddingStart="0dp" - android:paddingTop="4dp"> - - <android.support.v7.internal.widget.PreferenceImageView - android:id="@+id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:maxHeight="48dp" - app:maxWidth="48dp" /> - </FrameLayout> - - <LinearLayout - android:layout_width="0dip" - android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical" - android:paddingBottom="16dp" - android:paddingTop="16dp"> - - <TextView - android:id="@+id/name" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="marquee" - android:singleLine="true" - android:textColor="?colorTextPrimary" - android:textSize="16sp" - tools:text="@sample/userinfo_basic.json/data/name" /> - - <TextView - android:id="@+id/value" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="10" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="?colorTextSecondary" - tools:text="@sample/userinfo_basic.json/data/value" /> - - <android.support.v7.widget.RecyclerView - android:id="@+id/actions" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginLeft="-4dp" - android:layout_marginStart="-4dp" - android:orientation="horizontal" - tools:listitem="@layout/widget_info_action_main" /> - </LinearLayout> -</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 594b7cfcd47b3592cf62d194b6c5c65424270da7..a0544427b0393935e1a37684bcd91ce4c839c515 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -21,17 +21,20 @@ <string name="label_crashes">Absturzberichte</string> <string name="label_delete">Löschen</string> <string name="label_delete_all">Alle Löschen</string> - <string name="label_details">Details</string> <string name="label_disconnect">Verbindung trennen</string> <string name="label_edit_nick">Spitznamen bearbeiten</string> <string name="label_filter_messages">Nachrichten filtern</string> <string name="label_github">GitHub</string> <string name="label_hide_perm">Permanent ausblenden</string> <string name="label_hide_temp">Temporär ausblenden</string> + <string name="label_ignore">Ignorieren</string> + <string name="label_info_channel">Kanalinformationen</string> + <string name="label_info_user">Benutzerinformationen</string> <string name="label_input_history">Eingabeverlauf</string> <string name="label_join">Verbinden</string> <string name="label_libraries">Bibliotheken</string> <string name="label_license">Lizenz</string> + <string name="label_mention">Erwähnen</string> <string name="label_new_account">Account hinzufügen</string> <string name="label_new_chatlist">Chatliste hinzufügen</string> <string name="label_new_identity">Identität hinzufügen</string> @@ -44,6 +47,7 @@ <string name="label_part">Verlassen</string> <string name="label_placeholder_message">Nachricht schreiben…</string> <string name="label_placeholder_topic">Beschreib das Thema des Kanals…</string> + <string name="label_query">Dialog</string> <string name="label_rename">Umbenennen</string> <string name="label_save">Speichern</string> <string name="label_select">Auswählen</string> @@ -56,6 +60,7 @@ <string name="label_topic">Kanal-Thema</string> <string name="label_unhide">Nicht mehr ausblenden</string> <string name="label_website">Webseite</string> + <string name="label_whois">Whois</string> <string name="label_yes">Ja</string> <string name="notification_channel_connection_title">Verbindung</string> diff --git a/app/src/main/res/values-de/strings_info.xml b/app/src/main/res/values-de/strings_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..561fc16dc1db68bf5446c62922d6d787363e249a --- /dev/null +++ b/app/src/main/res/values-de/strings_info.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="label_user_away">Abwesend</string> + <string name="label_user_away_reason">Grund</string> + <string name="label_user_identity">Identität</string> + <string name="label_user_account">Account</string> + <string name="label_user_ident">Ident</string> + <string name="label_user_host">Host</string> + <string name="label_user_server">Server</string> + + <string name="property_group_ircchannel_channel">Kanal</string> + <string name="property_ircchannel_topic">Thema</string> + <string name="property_ircchannel_topic_action_edit">Thema ändern</string> + <string name="property_ircchannel_topic_default">Kein Thema gesetzt</string> +</resources> diff --git a/app/src/main/res/values-de/strings_properties.xml b/app/src/main/res/values-de/strings_properties.xml deleted file mode 100644 index 4da1e38c6ec897ba3d3eb0404d25020a8d5b760c..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-de/strings_properties.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="property_group_ircuser_identity">Identität</string> - <string name="property_ircuser_nick">Spitzname</string> - <string name="property_ircuser_user">Ident</string> - <string name="property_ircuser_host">Host</string> - <string name="property_ircuser_realname">Realname</string> - <string name="property_ircuser_account">Account</string> - - <string name="property_group_ircchannel_channel">Kanal</string> - <string name="property_ircchannel_topic">Thema</string> - <string name="property_ircchannel_topic_action_edit">Thema ändern</string> - <string name="property_ircchannel_topic_default">Kein Thema gesetzt</string> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1aecf7ac075df24bcf1262113ace5ab690c56683..c5e98cd75a44563306ce7535d692a51b03e6d017 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,17 +21,21 @@ <string name="label_crashes">Crashes</string> <string name="label_delete">Delete</string> <string name="label_delete_all">Delete All</string> - <string name="label_details">Details</string> <string name="label_disconnect">Disconnect</string> <string name="label_edit_nick">Edit nickname</string> + <string name="label_edit_topic">Edit Topic</string> <string name="label_filter_messages">Filter Messages</string> <string name="label_github">GitHub</string> <string name="label_hide_perm">Hide Permanently</string> <string name="label_hide_temp">Hide Temporarily</string> + <string name="label_ignore">Ignore</string> + <string name="label_info_channel">Channel Details</string> + <string name="label_info_user">User Details</string> <string name="label_input_history">Input History</string> <string name="label_join">Join</string> <string name="label_libraries">Libraries</string> <string name="label_license">License</string> + <string name="label_mention">Mention</string> <string name="label_new_account">New Account</string> <string name="label_new_chatlist">New Chatlist</string> <string name="label_new_identity">New Identity</string> @@ -41,9 +45,10 @@ <string name="label_no">No</string> <string name="label_reset">Reset</string> <string name="label_open">Open</string> - <string name="label_part">Part</string> + <string name="label_part">Leave</string> <string name="label_placeholder_message">Write a message…</string> <string name="label_placeholder_topic">Describe the channel topic…</string> + <string name="label_query">Query</string> <string name="label_rename">Rename</string> <string name="label_save">Save</string> <string name="label_select">Select</string> @@ -56,6 +61,7 @@ <string name="label_topic">Channel Topic</string> <string name="label_unhide">Make Visible</string> <string name="label_website">Website</string> + <string name="label_whois">Whois</string> <string name="label_yes">Yes</string> <string name="notification_channel_background" translatable="false">background</string> diff --git a/app/src/main/res/values/strings_info.xml b/app/src/main/res/values/strings_info.xml new file mode 100644 index 0000000000000000000000000000000000000000..75bd6c2bcb16d59768a22d199b83c9d11543c880 --- /dev/null +++ b/app/src/main/res/values/strings_info.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="label_user_away">Away</string> + <string name="label_user_away_reason">Reason</string> + <string name="label_user_identity">Identity</string> + <string name="label_user_account">Account</string> + <string name="label_user_ident">Ident</string> + <string name="label_user_host">Host</string> + <string name="label_user_server">Server</string> + + <string name="property_group_ircchannel_channel">Channel</string> + <string name="property_ircchannel_topic">Topic</string> + <string name="property_ircchannel_topic_action_edit">Edit Topic</string> + <string name="property_ircchannel_topic_default">No Topic Set</string> +</resources> diff --git a/app/src/main/res/values/strings_properties.xml b/app/src/main/res/values/strings_properties.xml deleted file mode 100644 index f83a021cbb032ea9a6293653135346e19833550d..0000000000000000000000000000000000000000 --- a/app/src/main/res/values/strings_properties.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="property_group_ircuser_identity">Identity</string> - <string name="property_ircuser_nick">Nickname</string> - <string name="property_ircuser_user">Ident</string> - <string name="property_ircuser_host">Host</string> - <string name="property_ircuser_realname">Real Name</string> - <string name="property_ircuser_account">Account</string> - - <string name="property_group_ircchannel_channel">Channel</string> - <string name="property_ircchannel_topic">Topic</string> - <string name="property_ircchannel_topic_action_edit">Edit Topic</string> - <string name="property_ircchannel_topic_default">No Topic Set</string> -</resources> \ No newline at end of file diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt index d24621833df896e373c6ab5dd31f70e33545b628..f40c8f2f8e6265c30e4849247c6f6cfb53a84c49 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt @@ -33,4 +33,8 @@ class BacklogManager( messages: QVariantList) { backlogStorage.storeMessages(messages.mapNotNull(QVariant_::value), initialLoad = true) } + + fun removeBuffer(buffer: BufferId) { + backlogStorage.clearMessages(buffer) + } } diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt index c8b76ac359e0b4cc2b4c1e3ed92eeb6a5fc514be..e1b29a81974fb2db0140e403eeabfa11f252234b 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt @@ -6,6 +6,7 @@ import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.interfaces.IBufferSyncer import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.SignalProxy +import de.kuschku.libquassel.util.irc.IrcCaseMappers import io.reactivex.Observable import io.reactivex.subjects.BehaviorSubject @@ -151,6 +152,7 @@ class BufferSyncer constructor( _bufferActivities.remove(buffer);live_bufferActivities.onNext(_bufferActivities) _highlightCounts.remove(buffer);live_highlightCounts.onNext(_highlightCounts) _bufferInfos.remove(buffer);live_bufferInfos.onNext(_bufferInfos) + session.backlogManager?.removeBuffer(buffer) } override fun renameBuffer(buffer: BufferId, newName: String) { @@ -222,7 +224,7 @@ class BufferSyncer constructor( }.filter { groupId == null || it.groupId == groupId }.filter { - bufferName == null || it.bufferName == bufferName + bufferName == null || IrcCaseMappers.unicode.equalsIgnoreCaseNullable(it.bufferName, bufferName) } fun find( diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt index 6f3f03d3922491d127b23cfc0c9cb4a8ffe44d46..1e664bc809246d44a70d0f951afb4000c572d47d 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt @@ -116,7 +116,7 @@ class IrcChannel( fun userModes(nick: String) = network().ircUser(nick)?.let { userModes(it) } ?: "" fun liveUserModes(nick: String) = network().ircUser(nick)?.let { userModes(it) } ?: "" - fun liveUpdates(): Observable<IrcChannel> = live_updates.map { this } + fun updates(): Observable<IrcChannel> = live_updates.map { this } fun hasMode(mode: Char) = when (network().channelModeType(mode)) { INetwork.ChannelModeType.A_CHANMODE -> diff --git a/lib/src/main/java/de/kuschku/libquassel/util/irc/IrcCaseMappers.kt b/lib/src/main/java/de/kuschku/libquassel/util/irc/IrcCaseMappers.kt index 0939f7b2bc23a849f149954c2fc6be9d652f6130..efad8589c4d729e73c2ee8d0f72b66bf4cd5e76e 100644 --- a/lib/src/main/java/de/kuschku/libquassel/util/irc/IrcCaseMappers.kt +++ b/lib/src/main/java/de/kuschku/libquassel/util/irc/IrcCaseMappers.kt @@ -8,6 +8,12 @@ object IrcCaseMappers { interface IrcCaseMapper { fun equalsIgnoreCase(a: String, b: String): Boolean + fun equalsIgnoreCaseNullable(a: String?, b: String?) = when { + a === null && b === null -> true + a === null -> false + b === null -> false + else -> this.equalsIgnoreCase(a, b) + } fun toLowerCase(value: String): String fun toLowerCaseNullable(value: String?): String? = value?.let(this@IrcCaseMapper::toLowerCase) diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/EditorViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/EditorViewModel.kt index b785ae2d9a0157cd46794235e86fb267872c5124..f77ff9678282a6611322875b2d555ca1ea2b5fc5 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/EditorViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/EditorViewModel.kt @@ -57,7 +57,7 @@ class EditorViewModel : ViewModel() { network.liveIrcChannel( info.bufferName ).switchMap { channel -> - channel.liveUpdates().map { + channel.updates().map { AutoCompleteItem.ChannelItem( info = info, network = network.networkInfo(), diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt index 53d8762cbab0a9f9adcd2b15c10d426004956c07..232fbd13f678ac722b11dc91d1a7c434e6faeebd 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt @@ -89,6 +89,11 @@ class QuasselViewModel : ViewModel() { it.map(ISession::liveIdentities).orElse(Observable.just(emptyMap())) } + val bufferSyncer = session.mapMapNullable(ISession::bufferSyncer) + val allBuffers = bufferSyncer.mapSwitchMap { + it.liveBufferInfos().map(Map<BufferId, BufferInfo>::values) + }.mapOrElse(emptyList()) + /** * An observable of the changes of the markerline, as pairs of `(old, new)` */ @@ -136,7 +141,7 @@ class QuasselViewModel : ViewModel() { network.liveIrcChannel( info.bufferName ).switchMap { channel -> - channel.liveUpdates().map { + channel.updates().map { BufferData( info = info, network = network, @@ -349,7 +354,7 @@ class QuasselViewModel : ViewModel() { BufferInfo.Type.ChannelBuffer.toInt() -> { network.liveNetworkInfo().switchMap { networkInfo -> network.liveIrcChannel(info.bufferName).switchMap { channel -> - channel.liveUpdates().map { + channel.updates().map { BufferProps( info = info, network = networkInfo,