Skip to content
Snippets Groups Projects
Commit 8c4a5a7b authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Better markerline, First message expanding + selecting code

parent e8ad19e8
No related branches found
No related tags found
No related merge requests found
package de.kuschku.quasseldroid.ui.chat.messages
import de.kuschku.libquassel.protocol.MsgId
import de.kuschku.quasseldroid.persistence.QuasselDatabase
data class DisplayMessage(
val content: QuasselDatabase.DatabaseMessage,
val isSelected: Boolean,
val isExpanded: Boolean,
val isMarkerLine: Boolean
) {
data class Tag(
val id: MsgId,
val isSelected: Boolean,
val isExpanded: Boolean,
val isMarkerLine: Boolean
)
val tag = Tag(content.messageId, isSelected, isExpanded, isMarkerLine)
}
\ No newline at end of file
...@@ -5,26 +5,25 @@ import android.support.v7.util.DiffUtil ...@@ -5,26 +5,25 @@ import android.support.v7.util.DiffUtil
import android.util.LruCache import android.util.LruCache
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.protocol.Message_Flag
import de.kuschku.libquassel.protocol.Message_Flags
import de.kuschku.libquassel.protocol.Message_Type
import de.kuschku.libquassel.protocol.Message_Types
import de.kuschku.libquassel.util.hasFlag import de.kuschku.libquassel.util.hasFlag
import de.kuschku.quasseldroid.persistence.QuasselDatabase.DatabaseMessage
import de.kuschku.quasseldroid.util.helper.getOrPut import de.kuschku.quasseldroid.util.helper.getOrPut
class MessageAdapter( class MessageAdapter(
private val messageRenderer: MessageRenderer, private val messageRenderer: MessageRenderer
var markerLinePosition: Pair<MsgId, MsgId>? = null ) : PagedListAdapter<DisplayMessage, QuasselMessageViewHolder>(
) : PagedListAdapter<DatabaseMessage, QuasselMessageViewHolder>( object : DiffUtil.ItemCallback<DisplayMessage>() {
object : DiffUtil.ItemCallback<DatabaseMessage>() { override fun areItemsTheSame(oldItem: DisplayMessage, newItem: DisplayMessage) =
override fun areItemsTheSame(oldItem: DatabaseMessage, newItem: DatabaseMessage) = oldItem.content.messageId == newItem.content.messageId
oldItem.messageId == newItem.messageId
override fun areContentsTheSame(oldItem: DatabaseMessage, newItem: DatabaseMessage) = override fun areContentsTheSame(oldItem: DisplayMessage, newItem: DisplayMessage) =
oldItem == newItem && oldItem == newItem
oldItem.messageId != markerLinePosition?.first &&
oldItem.messageId != markerLinePosition?.second
}) { }) {
private val messageCache = LruCache<Int, FormattedMessage>(512) private val messageCache = LruCache<DisplayMessage.Tag, FormattedMessage>(512)
fun clearCache() { fun clearCache() {
messageCache.evictAll() messageCache.evictAll()
...@@ -34,24 +33,15 @@ class MessageAdapter( ...@@ -34,24 +33,15 @@ class MessageAdapter(
getItem(position)?.let { getItem(position)?.let {
messageRenderer.bind( messageRenderer.bind(
holder, holder,
if (it.messageId == markerLinePosition?.second || it.messageId == markerLinePosition?.first) { messageCache.getOrPut(it.tag) {
val value = messageRenderer.render( messageRenderer.render(holder.itemView.context, it)
holder.itemView.context, it, markerLinePosition?.second ?: -1
)
messageCache.put(it.messageId, value)
value
} else {
messageCache.getOrPut(it.messageId) {
messageRenderer.render(
holder.itemView.context, it, markerLinePosition?.second ?: -1
)
} }
}) )
} }
} }
override fun getItemViewType(position: Int) = getItem(position)?.let { override fun getItemViewType(position: Int) = getItem(position)?.let {
viewType(Message_Flags.of(it.type), Message_Flags.of(it.flag)) viewType(Message_Flags.of(it.content.type), Message_Flags.of(it.content.flag))
} ?: 0 } ?: 0
private fun viewType(type: Message_Types, flags: Message_Flags) = private fun viewType(type: Message_Types, flags: Message_Flags) =
...@@ -62,7 +52,7 @@ class MessageAdapter( ...@@ -62,7 +52,7 @@ class MessageAdapter(
} }
override fun getItemId(position: Int): Long { override fun getItemId(position: Int): Long {
return getItem(position)?.messageId?.toLong() ?: 0L return getItem(position)?.content?.messageId?.toLong() ?: 0L
} }
private fun messageType(viewType: Int): Message_Type? = private fun messageType(viewType: Int): Message_Type? =
......
...@@ -21,10 +21,7 @@ import de.kuschku.quasseldroid.R ...@@ -21,10 +21,7 @@ import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.persistence.QuasselDatabase import de.kuschku.quasseldroid.persistence.QuasselDatabase
import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AppearanceSettings
import de.kuschku.quasseldroid.settings.BacklogSettings import de.kuschku.quasseldroid.settings.BacklogSettings
import de.kuschku.quasseldroid.util.helper.invoke import de.kuschku.quasseldroid.util.helper.*
import de.kuschku.quasseldroid.util.helper.switchMapNotNull
import de.kuschku.quasseldroid.util.helper.toggle
import de.kuschku.quasseldroid.util.helper.zip
import de.kuschku.quasseldroid.util.service.ServiceBoundFragment import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
import de.kuschku.quasseldroid.viewmodel.QuasselViewModel import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
import javax.inject.Inject import javax.inject.Inject
...@@ -62,9 +59,10 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -62,9 +59,10 @@ class MessageListFragment : ServiceBoundFragment() {
} }
private val boundaryCallback = object : private val boundaryCallback = object :
PagedList.BoundaryCallback<QuasselDatabase.DatabaseMessage>() { PagedList.BoundaryCallback<DisplayMessage>() {
override fun onItemAtFrontLoaded(itemAtFront: QuasselDatabase.DatabaseMessage) = Unit override fun onItemAtFrontLoaded(itemAtFront: DisplayMessage) = Unit
override fun onItemAtEndLoaded(itemAtEnd: QuasselDatabase.DatabaseMessage) = loadMore() override fun onItemAtEndLoaded(itemAtEnd: DisplayMessage) =
loadMore(lastMessageId = itemAtEnd.content.messageId)
} }
override fun onCreateView( override fun onCreateView(
...@@ -103,10 +101,21 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -103,10 +101,21 @@ class MessageListFragment : ServiceBoundFragment() {
} }
}) })
val data = viewModel.buffer_liveData.switchMapNotNull { buffer -> val data = combineLatest(viewModel.buffer,
viewModel.selectedMessages,
viewModel.expandedMessages,
viewModel.markerLine)
.toLiveData().switchMapNotNull { (buffer, selected, expanded, markerLine) ->
database.filtered().listen(accountId, buffer).switchMapNotNull { filtered -> database.filtered().listen(accountId, buffer).switchMapNotNull { filtered ->
LivePagedListBuilder( LivePagedListBuilder(
database.message().findByBufferIdPaged(buffer, filtered), database.message().findByBufferIdPaged(buffer, filtered).map {
DisplayMessage(
content = it,
isSelected = selected.contains(it.messageId),
isExpanded = expanded.contains(it.messageId),
isMarkerLine = markerLine.orNull() == it.messageId
)
},
PagedList.Config.Builder() PagedList.Config.Builder()
.setPageSize(backlogSettings.pageSize) .setPageSize(backlogSettings.pageSize)
.setPrefetchDistance(backlogSettings.pageSize) .setPrefetchDistance(backlogSettings.pageSize)
...@@ -123,7 +132,6 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -123,7 +132,6 @@ class MessageListFragment : ServiceBoundFragment() {
viewModel.sessionManager_liveData.zip(lastMessageId).observe( viewModel.sessionManager_liveData.zip(lastMessageId).observe(
this, Observer { this, Observer {
val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
runInBackground { runInBackground {
val session = it?.first?.orNull() val session = it?.first?.orNull()
val message = it?.second val message = it?.second
...@@ -135,13 +143,6 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -135,13 +143,6 @@ class MessageListFragment : ServiceBoundFragment() {
} }
}) })
viewModel.markerLine_liveData.observe(this, Observer {
it?.ifPresent {
adapter.markerLinePosition = it
adapter.notifyDataSetChanged()
}
})
fun checkScroll() { fun checkScroll() {
if (linearLayoutManager.findFirstVisibleItemPosition() < 2 && !isScrolling) { if (linearLayoutManager.findFirstVisibleItemPosition() < 2 && !isScrolling) {
messageList.scrollToPosition(0) messageList.scrollToPosition(0)
...@@ -156,7 +157,7 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -156,7 +157,7 @@ class MessageListFragment : ServiceBoundFragment() {
var lastBuffer = -1 var lastBuffer = -1
data.observe(this, Observer { list -> data.observe(this, Observer { list ->
val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition() val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
val firstVisibleMessageId = adapter[firstVisibleItemPosition]?.messageId val firstVisibleMessageId = adapter[firstVisibleItemPosition]?.content?.messageId
runInBackground { runInBackground {
activity?.runOnUiThread { activity?.runOnUiThread {
list?.let(adapter::submitList) list?.let(adapter::submitList)
...@@ -200,7 +201,7 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -200,7 +201,7 @@ class MessageListFragment : ServiceBoundFragment() {
override fun onPause() { override fun onPause() {
val previous = lastBuffer val previous = lastBuffer
val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition() val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
val messageId = adapter[firstVisibleItemPosition]?.messageId val messageId = adapter[firstVisibleItemPosition]?.content?.messageId
val bufferSyncer = viewModel.session.value?.orNull()?.bufferSyncer val bufferSyncer = viewModel.session.value?.orNull()?.bufferSyncer
if (previous != null && messageId != null) { if (previous != null && messageId != null) {
bufferSyncer?.requestSetMarkerLine(previous, messageId) bufferSyncer?.requestSetMarkerLine(previous, messageId)
...@@ -208,13 +209,13 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -208,13 +209,13 @@ class MessageListFragment : ServiceBoundFragment() {
super.onPause() super.onPause()
} }
private fun loadMore(initial: Boolean = false) { private fun loadMore(initial: Boolean = false, lastMessageId: MsgId? = null) {
runInBackground { runInBackground {
viewModel.buffer { bufferId -> viewModel.buffer { bufferId ->
viewModel.session { viewModel.session {
it.orNull()?.backlogManager?.requestBacklog( it.orNull()?.backlogManager?.requestBacklog(
bufferId = bufferId, bufferId = bufferId,
last = database.message().findFirstByBufferId( last = lastMessageId ?: database.message().findFirstByBufferId(
bufferId bufferId
)?.messageId ?: -1, )?.messageId ?: -1,
limit = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize limit = if (initial) backlogSettings.initialAmount else backlogSettings.pageSize
...@@ -223,4 +224,5 @@ class MessageListFragment : ServiceBoundFragment() { ...@@ -223,4 +224,5 @@ class MessageListFragment : ServiceBoundFragment() {
} }
} }
} }
} }
\ No newline at end of file
...@@ -3,17 +3,13 @@ package de.kuschku.quasseldroid.ui.chat.messages ...@@ -3,17 +3,13 @@ package de.kuschku.quasseldroid.ui.chat.messages
import android.content.Context import android.content.Context
import android.support.annotation.LayoutRes import android.support.annotation.LayoutRes
import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.protocol.Message_Type
import de.kuschku.libquassel.protocol.MsgId
import de.kuschku.quasseldroid.persistence.QuasselDatabase
interface MessageRenderer { interface MessageRenderer {
@LayoutRes @LayoutRes
fun layout(type: Message_Type?, hasHighlight: Boolean): Int fun layout(type: Message_Type?, hasHighlight: Boolean): Int
fun bind(holder: QuasselMessageViewHolder, message: FormattedMessage) fun bind(holder: QuasselMessageViewHolder, message: FormattedMessage)
fun render(context: Context, fun render(context: Context, message: DisplayMessage): FormattedMessage
message: QuasselDatabase.DatabaseMessage,
markerLine: MsgId): FormattedMessage
fun init(viewHolder: QuasselMessageViewHolder, fun init(viewHolder: QuasselMessageViewHolder,
messageType: Message_Type?, messageType: Message_Type?,
......
...@@ -12,10 +12,8 @@ import android.util.TypedValue ...@@ -12,10 +12,8 @@ import android.util.TypedValue
import de.kuschku.libquassel.protocol.Message.MessageType.* import de.kuschku.libquassel.protocol.Message.MessageType.*
import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Flag
import de.kuschku.libquassel.protocol.Message_Type import de.kuschku.libquassel.protocol.Message_Type
import de.kuschku.libquassel.protocol.MsgId
import de.kuschku.libquassel.util.hasFlag import de.kuschku.libquassel.util.hasFlag
import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.persistence.QuasselDatabase
import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AppearanceSettings
import de.kuschku.quasseldroid.settings.AppearanceSettings.ColorizeNicknamesMode import de.kuschku.quasseldroid.settings.AppearanceSettings.ColorizeNicknamesMode
import de.kuschku.quasseldroid.settings.AppearanceSettings.ShowPrefixMode import de.kuschku.quasseldroid.settings.AppearanceSettings.ShowPrefixMode
...@@ -95,8 +93,7 @@ class QuasselMessageRenderer @Inject constructor( ...@@ -95,8 +93,7 @@ class QuasselMessageRenderer @Inject constructor(
} }
override fun render(context: Context, override fun render(context: Context,
message: QuasselDatabase.DatabaseMessage, message: DisplayMessage): FormattedMessage {
markerLine: MsgId): FormattedMessage {
context.theme.styledAttributes( context.theme.styledAttributes(
R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3, 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.senderColor4, R.attr.senderColor5, R.attr.senderColor6, R.attr.senderColor7,
...@@ -108,224 +105,224 @@ class QuasselMessageRenderer @Inject constructor( ...@@ -108,224 +105,224 @@ class QuasselMessageRenderer @Inject constructor(
} }
} }
val self = Message_Flag.of(message.flag).hasFlag(Message_Flag.Self) val self = Message_Flag.of(message.content.flag).hasFlag(Message_Flag.Self)
val highlight = Message_Flag.of(message.flag).hasFlag(Message_Flag.Highlight) val highlight = Message_Flag.of(message.content.flag).hasFlag(Message_Flag.Highlight)
return when (Message_Type.of(message.type).enabledValues().firstOrNull()) { return when (Message_Type.of(message.content.type).enabledValues().firstOrNull()) {
Message_Type.Plain -> FormattedMessage( Message_Type.Plain -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_plain), context.getString(R.string.message_format_plain),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, false), formatNick(message.content.sender, self, highlight, false),
formatContent(context, message.content, highlight) formatContent(context, message.content.content, highlight)
), ),
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Action -> FormattedMessage( Message_Type.Action -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_action), context.getString(R.string.message_format_action),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, false), formatNick(message.content.sender, self, highlight, false),
formatContent(context, message.content, highlight) formatContent(context, message.content.content, highlight)
), ),
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Notice -> FormattedMessage( Message_Type.Notice -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_notice), context.getString(R.string.message_format_notice),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, false), formatNick(message.content.sender, self, highlight, false),
formatContent(context, message.content, highlight) formatContent(context, message.content.content, highlight)
), ),
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Nick -> { Message_Type.Nick -> {
val nickSelf = message.sender == message.content || self val nickSelf = message.content.sender == message.content.content || self
FormattedMessage( FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
if (nickSelf) { if (nickSelf) {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_nick_self), context.getString(R.string.message_format_nick_self),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, nickSelf, highlight, false) formatNick(message.content.sender, nickSelf, highlight, false)
) )
} else { } else {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_nick), context.getString(R.string.message_format_nick),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, nickSelf, highlight, false), formatNick(message.content.sender, nickSelf, highlight, false),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.content, nickSelf, highlight, false) formatNick(message.content.content, nickSelf, highlight, false)
) )
}, },
message.messageId == markerLine message.isMarkerLine
) )
} }
Message_Type.Mode -> FormattedMessage( Message_Type.Mode -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_mode), context.getString(R.string.message_format_mode),
message.content, message.content.content,
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, false) formatNick(message.content.sender, self, highlight, false)
), ),
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Join -> FormattedMessage( Message_Type.Join -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_join), context.getString(R.string.message_format_join),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true), formatNick(message.content.sender, self, highlight, true),
message.content message.content.content
), ),
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Part -> FormattedMessage( Message_Type.Part -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
if (message.content.isBlank()) { if (message.content.content.isBlank()) {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_part_1), context.getString(R.string.message_format_part_1),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true) formatNick(message.content.sender, self, highlight, true)
) )
} else { } else {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_part_2), context.getString(R.string.message_format_part_2),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true), formatNick(message.content.sender, self, highlight, true),
formatContent(context, message.content, highlight) formatContent(context, message.content.content, highlight)
) )
}, },
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Quit -> FormattedMessage( Message_Type.Quit -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
if (message.content.isBlank()) { if (message.content.content.isBlank()) {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_quit_1), context.getString(R.string.message_format_quit_1),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true) formatNick(message.content.sender, self, highlight, true)
) )
} else { } else {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_quit_2), context.getString(R.string.message_format_quit_2),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true), formatNick(message.content.sender, self, highlight, true),
formatContent(context, message.content, highlight) formatContent(context, message.content.content, highlight)
) )
}, },
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Kick -> { Message_Type.Kick -> {
val (user, reason) = message.content.split(' ', limit = 2) + listOf("", "") val (user, reason) = message.content.content.split(' ', limit = 2) + listOf("", "")
FormattedMessage( FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
if (reason.isBlank()) { if (reason.isBlank()) {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_kick_1), context.getString(R.string.message_format_kick_1),
formatNick(user, false, highlight, false), formatNick(user, false, highlight, false),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true) formatNick(message.content.sender, self, highlight, true)
) )
} else { } else {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_kick_2), context.getString(R.string.message_format_kick_2),
formatNick(user, false, highlight, false), formatNick(user, false, highlight, false),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true), formatNick(message.content.sender, self, highlight, true),
formatContent(context, reason, highlight) formatContent(context, reason, highlight)
) )
}, },
message.messageId == markerLine message.isMarkerLine
) )
} }
Message_Type.Kill -> { Message_Type.Kill -> {
val (user, reason) = message.content.split(' ', limit = 2) + listOf("", "") val (user, reason) = message.content.content.split(' ', limit = 2) + listOf("", "")
FormattedMessage( FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
if (reason.isBlank()) { if (reason.isBlank()) {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_kill_1), context.getString(R.string.message_format_kill_1),
formatNick(user, false, highlight, false), formatNick(user, false, highlight, false),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true) formatNick(message.content.sender, self, highlight, true)
) )
} else { } else {
SpanFormatter.format( SpanFormatter.format(
context.getString(R.string.message_format_kill_2), context.getString(R.string.message_format_kill_2),
formatNick(user, false, highlight, false), formatNick(user, false, highlight, false),
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true), formatNick(message.content.sender, self, highlight, true),
formatContent(context, reason, highlight) formatContent(context, reason, highlight)
) )
}, },
message.messageId == markerLine message.isMarkerLine
) )
} }
Message_Type.NetsplitJoin -> { Message_Type.NetsplitJoin -> {
val split = message.content.split("#:#") val split = message.content.content.split("#:#")
val (server1, server2) = split.last().split(' ') val (server1, server2) = split.last().split(' ')
val usersAffected = split.size - 1 val usersAffected = split.size - 1
FormattedMessage( FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
context.resources.getQuantityString( context.resources.getQuantityString(
R.plurals.message_netsplit_join, usersAffected, server1, server2, usersAffected R.plurals.message_netsplit_join, usersAffected, server1, server2, usersAffected
), ),
message.messageId == markerLine message.isMarkerLine
) )
} }
Message_Type.NetsplitQuit -> { Message_Type.NetsplitQuit -> {
val split = message.content.split("#:#") val split = message.content.content.split("#:#")
val (server1, server2) = split.last().split(' ') val (server1, server2) = split.last().split(' ')
val usersAffected = split.size - 1 val usersAffected = split.size - 1
FormattedMessage( FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
context.resources.getQuantityString( context.resources.getQuantityString(
R.plurals.message_netsplit_quit, usersAffected, server1, server2, usersAffected R.plurals.message_netsplit_quit, usersAffected, server1, server2, usersAffected
), ),
message.messageId == markerLine message.isMarkerLine
) )
} }
Message_Type.Server, Message_Type.Server,
Message_Type.Info, Message_Type.Info,
Message_Type.Error -> FormattedMessage( Message_Type.Error -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
formatContent(context, message.content, highlight), formatContent(context, message.content.content, highlight),
message.messageId == markerLine message.isMarkerLine
) )
Message_Type.Topic -> FormattedMessage( Message_Type.Topic -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
formatContent(context, message.content, highlight), formatContent(context, message.content.content, highlight),
message.messageId == markerLine message.isMarkerLine
) )
else -> FormattedMessage( else -> FormattedMessage(
message.messageId, message.content.messageId,
timeFormatter.format(message.time.atZone(zoneId)), timeFormatter.format(message.content.time.atZone(zoneId)),
SpanFormatter.format( SpanFormatter.format(
"[%d] %s%s: %s", "[%d] %s%s: %s",
message.type, message.content.type,
formatPrefix(message.senderPrefixes, highlight), formatPrefix(message.content.senderPrefixes, highlight),
formatNick(message.sender, self, highlight, true), formatNick(message.content.sender, self, highlight, true),
message.content message.content.content
), ),
message.messageId == markerLine message.isMarkerLine
) )
} }
} }
......
...@@ -20,12 +20,37 @@ inline fun <reified A, B, C> combineLatest( ...@@ -20,12 +20,37 @@ inline fun <reified A, B, C> combineLatest(
a: ObservableSource<A>, a: ObservableSource<A>,
b: ObservableSource<B>, b: ObservableSource<B>,
c: ObservableSource<C> c: ObservableSource<C>
): Observable<Triple<A, B, C>> = Observable.combineLatest(listOf(a, b, c), { (t0, t1, t2) -> ): Observable<Triple<A, B, C>> = Observable.combineLatest(
listOf(a, b, c),
{ (t0, t1, t2) ->
Triple(t0, t1, t2) as Triple<A, B, C> Triple(t0, t1, t2) as Triple<A, B, C>
}) }
)
inline fun <reified A, B, C, D> combineLatest(
a: ObservableSource<A>,
b: ObservableSource<B>,
c: ObservableSource<C>,
d: ObservableSource<D>
): Observable<Tuple4<A, B, C, D>> = Observable.combineLatest(
listOf(a, b, c, d),
{ (t0, t1, t2, t3) ->
Tuple4(t0,
t1,
t2,
t3) as Tuple4<A, B, C, D>
}
)
inline fun <reified T> combineLatest(sources: Iterable<ObservableSource<out T>?>) = inline fun <reified T> combineLatest(sources: Iterable<ObservableSource<out T>?>) =
Observable.combineLatest(sources) { t -> t.toList() as List<T> } Observable.combineLatest(sources) { t -> t.toList() as List<T> }
inline operator fun <T, U> Observable<T>.invoke(f: (T) -> U?) = inline operator fun <T, U> Observable<T>.invoke(f: (T) -> U?) =
blockingLatest().firstOrNull()?.let(f) blockingLatest().firstOrNull()?.let(f)
data class Tuple4<out A, out B, out C, out D>(
val first: A,
val second: B,
val third: C,
val fourth: D
)
\ No newline at end of file
...@@ -3,6 +3,7 @@ package de.kuschku.quasseldroid.viewmodel ...@@ -3,6 +3,7 @@ package de.kuschku.quasseldroid.viewmodel
import android.arch.lifecycle.ViewModel import android.arch.lifecycle.ViewModel
import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.protocol.BufferId
import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.Buffer_Type
import de.kuschku.libquassel.protocol.MsgId
import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.protocol.NetworkId
import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.BufferInfo
import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
...@@ -27,6 +28,9 @@ import java.util.concurrent.TimeUnit ...@@ -27,6 +28,9 @@ import java.util.concurrent.TimeUnit
class QuasselViewModel : ViewModel() { class QuasselViewModel : ViewModel() {
val backendWrapper = BehaviorSubject.createDefault(Observable.empty<Optional<Backend>>()) val backendWrapper = BehaviorSubject.createDefault(Observable.empty<Optional<Backend>>())
val selectedMessages = BehaviorSubject.createDefault(emptyList<MsgId>())
val expandedMessages = BehaviorSubject.createDefault(emptyList<MsgId>())
val buffer = BehaviorSubject.createDefault(-1) val buffer = BehaviorSubject.createDefault(-1)
val buffer_liveData = buffer.toLiveData() val buffer_liveData = buffer.toLiveData()
...@@ -69,8 +73,7 @@ class QuasselViewModel : ViewModel() { ...@@ -69,8 +73,7 @@ class QuasselViewModel : ViewModel() {
val markerLine = session.mapSwitchMap { currentSession -> val markerLine = session.mapSwitchMap { currentSession ->
buffer.switchMap { currentBuffer -> buffer.switchMap { currentBuffer ->
// Get a stream of the latest marker line // Get a stream of the latest marker line
val raw = currentSession.bufferSyncer?.liveMarkerLine(currentBuffer) ?: Observable.empty() currentSession.bufferSyncer?.liveMarkerLine(currentBuffer) ?: Observable.empty()
raw.scan(Pair(-1, -1)) { (_, previous), next -> Pair(previous, next) }
} }
} }
val markerLine_liveData = markerLine.toLiveData() val markerLine_liveData = markerLine.toLiveData()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment