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

Added a lot of chat view related code

parent 84438b3d
Branches
Tags
No related merge requests found
Showing
with 635 additions and 156 deletions
......@@ -12,7 +12,7 @@
<service android:name=".QuasselService" />
<activity
android:name=".MainActivity"
android:name=".ui.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
......
......@@ -18,17 +18,14 @@ public class BusProvider {
}
public void handle(Object o) {
//Log.d("HANDLE", o.getClass().getSimpleName());
this.handle.post(o);
}
public void dispatch(Object o) {
//Log.d("DISPATCH", o.getClass().getSimpleName());
this.dispatch.post(o);
}
public void sendEvent(Object o) {
//Log.d("EVENT", o.getClass().getSimpleName());
this.event.post(o);
}
}
......@@ -17,7 +17,7 @@ import de.kuschku.libquassel.localtypes.Buffers;
import de.kuschku.libquassel.objects.types.ClientInitAck;
import de.kuschku.libquassel.objects.types.SessionState;
import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.primitives.types.Message;
import de.kuschku.libquassel.message.Message;
import de.kuschku.libquassel.primitives.types.QVariant;
import de.kuschku.libquassel.syncables.types.BufferSyncer;
import de.kuschku.libquassel.syncables.types.BufferViewManager;
......@@ -33,6 +33,8 @@ public class Client {
private final BacklogManager backlogManager;
private final BusProvider busProvider;
public int lag;
public int openBuffer;
public int openBufferView;
private ConnectionChangeEvent.Status connectionStatus;
private ClientInitAck core;
private SessionState state;
......
......@@ -24,7 +24,7 @@ import de.kuschku.libquassel.primitives.types.Protocol;
import de.kuschku.libquassel.protocols.DatastreamPeer;
import de.kuschku.libquassel.protocols.LegacyPeer;
import de.kuschku.libquassel.protocols.RemotePeer;
import de.kuschku.quasseldroid_ng.utils.ServerAddress;
import de.kuschku.quasseldroid_ng.util.ServerAddress;
import de.kuschku.util.niohelpers.WrappedChannel;
import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt;
......@@ -62,11 +62,12 @@ public class CoreConnection {
* This method opens a socket to the specified address and starts the connection process.
*
* @throws IOException
* @param supportsKeepAlive
*/
public void open() throws IOException {
public void open(boolean supportsKeepAlive) throws IOException {
// Intialize socket
socket = new Socket();
socket.setKeepAlive(true);
if (supportsKeepAlive) socket.setKeepAlive(true);
socket.connect(new InetSocketAddress(address.host, address.port), 10000);
// Wrap socket in channel for nio functions
......
......@@ -5,7 +5,7 @@ import android.support.v7.widget.RecyclerView;
import java.util.List;
import de.kuschku.libquassel.primitives.types.Message;
import de.kuschku.libquassel.message.Message;
import de.kuschku.libquassel.syncables.types.SyncableObject;
import de.kuschku.util.ObservableList;
......@@ -19,4 +19,6 @@ public abstract class BacklogManager extends SyncableObject {
public abstract ObservableList<Message> get(int bufferId);
public abstract void bind(int bufferId, @Nullable RecyclerView.Adapter adapter);
public abstract void requestMoreBacklog(int bufferId, int count);
}
......@@ -10,9 +10,10 @@ import java.util.List;
import de.kuschku.libquassel.BusProvider;
import de.kuschku.libquassel.Client;
import de.kuschku.libquassel.events.BacklogReceivedEvent;
import de.kuschku.libquassel.functions.types.InitDataFunction;
import de.kuschku.libquassel.functions.types.SyncFunction;
import de.kuschku.libquassel.primitives.types.Message;
import de.kuschku.libquassel.message.Message;
import de.kuschku.libquassel.primitives.types.QVariant;
import de.kuschku.util.ObservableList;
......@@ -36,6 +37,8 @@ public class SimpleBacklogManager extends BacklogManager {
public void receiveBacklog(int bufferId, int from, int to, int count, int extra, List<Message> messages) {
get(bufferId).list.addAll(messages);
busProvider.sendEvent(new BacklogReceivedEvent(bufferId));
}
@Override
......@@ -50,6 +53,17 @@ public class SimpleBacklogManager extends BacklogManager {
get(bufferId).setCallback(new ObservableList.RecyclerViewAdapterCallback(adapter));
}
@Override
public void requestMoreBacklog(int bufferId, int count) {
ObservableList<Message> backlog = backlogs.get(bufferId);
int messageId =
(backlog == null) ? -1 :
(backlog.first() == null) ? -1 :
backlog.first().messageId;
requestBacklog(bufferId, -1, -1, count, 0);
}
public ObservableList<Message> get(int bufferId) {
if (backlogs.get(bufferId) == null)
backlogs.put(bufferId, new ObservableList<>(Message.class));
......
package de.kuschku.libquassel.events;
public class BacklogReceivedEvent {
public final int bufferId;
public BacklogReceivedEvent(int bufferId) {
this.bufferId = bufferId;
}
}
......@@ -4,7 +4,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.syncables.types.IrcChannel;
import de.kuschku.quasseldroid_ng.BufferDrawerItem;
import de.kuschku.quasseldroid_ng.ui.BufferDrawerItem;
public class ChannelBuffer implements Buffer {
private final BufferInfo info;
......
......@@ -4,7 +4,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.syncables.types.IrcUser;
import de.kuschku.quasseldroid_ng.BufferDrawerItem;
import de.kuschku.quasseldroid_ng.ui.BufferDrawerItem;
public class QueryBuffer implements Buffer {
private final BufferInfo info;
......
......@@ -4,7 +4,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.syncables.types.Network;
import de.kuschku.quasseldroid_ng.BufferDrawerItem;
import de.kuschku.quasseldroid_ng.ui.BufferDrawerItem;
public class StatusBuffer implements Buffer {
private final BufferInfo info;
......
package de.kuschku.libquassel.primitives.types;
package de.kuschku.libquassel.message;
import android.support.annotation.NonNull;
......@@ -7,6 +7,7 @@ import org.joda.time.DateTime;
import java.io.Serializable;
import java.util.Comparator;
import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.util.ContentComparable;
public class Message implements ContentComparable<Message> {
......
......@@ -33,7 +33,7 @@ import de.kuschku.libquassel.primitives.serializers.VariantSerializer;
import de.kuschku.libquassel.primitives.serializers.VariantVariantListSerializer;
import de.kuschku.libquassel.primitives.serializers.VoidSerializer;
import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.primitives.types.Message;
import de.kuschku.libquassel.message.Message;
import de.kuschku.libquassel.primitives.types.QVariant;
import de.kuschku.libquassel.syncables.serializers.IdentitySerializer;
import de.kuschku.libquassel.syncables.types.Identity;
......
......@@ -6,7 +6,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import de.kuschku.libquassel.primitives.types.Message;
import de.kuschku.libquassel.message.Message;
public class MessageSerializer implements PrimitiveSerializer<Message> {
@Override
......
......@@ -8,7 +8,8 @@ import de.kuschku.libquassel.CoreConnection;
import de.kuschku.libquassel.ProtocolHandler;
import de.kuschku.libquassel.events.GeneralErrorEvent;
import de.kuschku.libquassel.protocols.RemotePeer;
import de.kuschku.quasseldroid_ng.utils.ServerAddress;
import de.kuschku.quasseldroid_ng.util.CompatibilityUtils;
import de.kuschku.quasseldroid_ng.util.ServerAddress;
public class ClientBackgroundThread implements Runnable {
public static final ClientData CLIENT_DATA = new ClientData(
......@@ -33,7 +34,7 @@ public class ClientBackgroundThread implements Runnable {
@Override
public void run() {
try {
connection.open();
connection.open(!CompatibilityUtils.isChromiumDevice());
} catch (IOException e) {
provider.sendEvent(new GeneralErrorEvent(e));
}
......
......@@ -6,7 +6,7 @@ import android.os.Binder;
import android.os.IBinder;
import de.kuschku.libquassel.BusProvider;
import de.kuschku.quasseldroid_ng.utils.ServerAddress;
import de.kuschku.quasseldroid_ng.util.ServerAddress;
public class QuasselService extends Service {
private final IBinder binder = new LocalBinder();
......
package de.kuschku.quasseldroid_ng;
package de.kuschku.quasseldroid_ng.ui;
import com.mikepenz.materialdrawer.holder.ImageHolder;
import com.mikepenz.materialdrawer.holder.StringHolder;
......@@ -6,6 +6,7 @@ import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import de.kuschku.libquassel.localtypes.Buffer;
import de.kuschku.libquassel.localtypes.ChannelBuffer;
import de.kuschku.quasseldroid_ng.R;
public class BufferDrawerItem extends SecondaryDrawerItem {
final Buffer buffer;
......
package de.kuschku.quasseldroid_ng.ui;
import android.content.Context;
import android.text.SpannableString;
import android.text.TextUtils;
import org.joda.time.format.DateTimeFormatter;
import java.util.Locale;
import de.kuschku.libquassel.Client;
import de.kuschku.libquassel.message.Message;
import de.kuschku.quasseldroid_ng.R;
import de.kuschku.quasseldroid_ng.util.DateFormatHelper;
import de.kuschku.quasseldroid_ng.util.IrcFormatHelper;
import de.kuschku.quasseldroid_ng.util.IrcUserUtils;
import de.kuschku.quasseldroid_ng.util.SpanFormatter;
import de.kuschku.quasseldroid_ng.util.ThemeUtil;
public class ChatMessageRenderer {
private final ThemeUtil themeUtil;
private final DateTimeFormatter format;
private final FormatStrings strings;
private final IrcFormatHelper helper;
private Client client;
private boolean fullHostmask = false;
public ChatMessageRenderer(Context ctx) {
this.themeUtil = new ThemeUtil(ctx);
this.format = DateFormatHelper.getTimeFormatter(ctx);
this.strings = new FormatStrings(ctx);
this.helper = new IrcFormatHelper(themeUtil.colors);
}
public void setClient(Client client) {
this.client = client;
}
private void setColors(MessageViewHolder holder, boolean highlight) {
if (highlight) {
holder.content.setTextColor(themeUtil.colors.colorForegroundHighlight);
holder.time.setTextColor(themeUtil.colors.colorForegroundHighlight);
holder.itemView.setBackgroundColor(themeUtil.colors.colorBackgroundHighlight);
} else {
holder.content.setTextColor(themeUtil.colors.colorForeground);
holder.time.setTextColor(themeUtil.colors.colorForegroundSecondary);
holder.itemView.setBackgroundColor(themeUtil.colors.transparent);
}
}
private CharSequence formatNick(String hostmask, boolean full) {
CharSequence formattedNick = helper.formatUserNick(IrcUserUtils.getNick(hostmask));
if (full) {
return strings.formatUsername(formattedNick, IrcUserUtils.getMask(hostmask));
} else {
return formattedNick;
}
}
private CharSequence formatNick(String hostmask) {
return formatNick(hostmask, fullHostmask);
}
public void onBindPlain(MessageViewHolder holder, Message message) {
holder.content.setText(
strings.formatPlain(
formatNick(message.sender, false),
helper.formatIrcMessage(message.content)
)
);
}
public void onBindNotice(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindAction(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindNick(MessageViewHolder holder, Message message) {
if (message.flags.Self)
holder.content.setText(strings.formatNick(
formatNick(message.sender, false)
));
else
holder.content.setText(strings.formatNick(
formatNick(message.sender, false),
helper.formatUserNick(message.content)
));
}
public void onBindMode(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindJoin(MessageViewHolder holder, Message message) {
holder.content.setText(strings.formatJoin(
formatNick(message.sender),
client.getBuffer(message.bufferInfo.id).getName()
));
}
public void onBindPart(MessageViewHolder holder, Message message) {
holder.content.setText(strings.formatPart(
formatNick(message.sender),
client.getBuffer(message.bufferInfo.id).getName(),
message.content
));
}
public void onBindQuit(MessageViewHolder holder, Message message) {
holder.content.setText(strings.formatQuit(
formatNick(message.sender),
message.content
));
}
public void onBindKick(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindKill(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindServer(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindInfo(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindError(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindDayChange(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindTopic(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindNetsplitJoin(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindNetsplitQuit(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBindInvite(MessageViewHolder holder, Message message) {
holder.content.setText(message.toString());
}
public void onBind(MessageViewHolder holder, Message message) {
setColors(holder, message.flags.Highlight);
holder.time.setText(format.print(message.time));
switch (message.type) {
case Plain:
onBindPlain(holder, message);
break;
case Notice:
onBindNotice(holder, message);
break;
case Action:
onBindAction(holder, message);
break;
case Nick:
onBindNick(holder, message);
break;
case Mode:
onBindMode(holder, message);
break;
case Join:
onBindJoin(holder, message);
break;
case Part:
onBindPart(holder, message);
break;
case Quit:
onBindQuit(holder, message);
break;
case Kick:
onBindKick(holder, message);
break;
case Kill:
onBindKill(holder, message);
break;
case Server:
onBindServer(holder, message);
break;
case Info:
onBindInfo(holder, message);
break;
case Error:
onBindError(holder, message);
break;
case DayChange:
onBindDayChange(holder, message);
break;
case Topic:
onBindTopic(holder, message);
break;
case NetsplitJoin:
onBindNetsplitJoin(holder, message);
break;
case NetsplitQuit:
onBindNetsplitQuit(holder, message);
break;
case Invite:
onBindInvite(holder, message);
break;
}
}
private static class FormatStrings {
private final String username_hostmask;
private final String message_plain;
private final String message_join;
private final String message_part;
private final String message_part_extra;
private final String message_quit;
private final String message_quit_extra;
private final String message_kill;
private final String message_kick;
private final String message_kick_extra;
private final String message_mode;
private final String message_nick_self;
private final String message_nick_other;
private final String message_daychange;
private final String message_action;
public FormatStrings(Context ctx) {
username_hostmask = ctx.getString(R.string.username_hostmask);
message_plain = ctx.getString(R.string.message_plain);
message_join = ctx.getString(R.string.message_join);
message_part = ctx.getString(R.string.message_part);
message_part_extra = ctx.getString(R.string.message_part_extra);
message_quit = ctx.getString(R.string.message_quit);
message_quit_extra = ctx.getString(R.string.message_quit_extra);
message_kill = ctx.getString(R.string.message_kill);
message_kick = ctx.getString(R.string.message_kick);
message_kick_extra = ctx.getString(R.string.message_kick_extra);
message_mode = ctx.getString(R.string.message_mode);
message_nick_self = ctx.getString(R.string.message_nick_self);
message_nick_other = ctx.getString(R.string.message_nick_other);
message_daychange = ctx.getString(R.string.message_daychange);
message_action = ctx.getString(R.string.message_action);
}
public CharSequence formatUsername(CharSequence nick, CharSequence hostmask) {
return SpanFormatter.format(username_hostmask, nick, hostmask);
}
public CharSequence formatJoin(CharSequence user, CharSequence channel) {
return SpanFormatter.format(message_join, user, channel);
}
public CharSequence formatPart(CharSequence user, CharSequence channel) {
return SpanFormatter.format(message_part, user, channel);
}
public CharSequence formatPart(CharSequence user, CharSequence channel, CharSequence reason) {
if (reason == null || reason.length() == 0) return formatPart(user, channel);
return SpanFormatter.format(message_part_extra, user, channel, reason);
}
public CharSequence formatQuit(CharSequence user) {
return SpanFormatter.format(message_quit, user);
}
public CharSequence formatQuit(CharSequence user, CharSequence reason) {
if (reason == null || reason.length() == 0) return formatQuit(user);
return SpanFormatter.format(message_quit_extra, user, reason);
}
public CharSequence formatKill(CharSequence user, CharSequence channel) {
return SpanFormatter.format(message_kill, user, channel);
}
public CharSequence formatKick(CharSequence user, CharSequence kicked) {
return SpanFormatter.format(message_kick, user, kicked);
}
public CharSequence formatKick(CharSequence user, CharSequence kicked, CharSequence reason) {
if (reason == null || reason.length() == 0) return formatKick(user, kicked);
return SpanFormatter.format(message_kick_extra, user, kicked, reason);
}
public CharSequence formatMode(CharSequence mode, CharSequence user) {
return SpanFormatter.format(message_mode, mode, user);
}
public CharSequence formatNick(CharSequence newNick) {
return SpanFormatter.format(message_nick_self, newNick);
}
public CharSequence formatNick(CharSequence oldNick, CharSequence newNick) {
if (newNick == null || newNick.length() == 0) return formatNick(oldNick);
return SpanFormatter.format(message_nick_other, oldNick, newNick);
}
public CharSequence formatDayChange(CharSequence day) {
return SpanFormatter.format(message_daychange, day);
}
public CharSequence formatAction(CharSequence user, CharSequence channel) {
return SpanFormatter.format(message_action, user, channel);
}
public CharSequence formatPlain(CharSequence nick, CharSequence message) {
return SpanFormatter.format(message_plain, nick, message);
}
}
}
package de.kuschku.quasseldroid_ng.ui;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import de.kuschku.libquassel.Client;
import de.kuschku.libquassel.message.Message;
import de.kuschku.quasseldroid_ng.R;
import de.kuschku.util.ObservableList;
public class MessageAdapter extends RecyclerView.Adapter<MessageViewHolder> {
private ObservableList<Message> messageList = new ObservableList<>(Message.class);
private ChatMessageRenderer renderer;
private LayoutInflater inflater;
public MessageAdapter(Context ctx) {
this.inflater = LayoutInflater.from(ctx);
this.renderer = new ChatMessageRenderer(ctx);
}
public void setClient(Client client) {
renderer.setClient(client);
}
public void setMessageList(ObservableList<Message> messageList) {
this.messageList.setCallback(null);
this.messageList = messageList;
this.messageList.setCallback(new ObservableList.RecyclerViewAdapterCallback(this));
notifyDataSetChanged();
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MessageViewHolder(inflater.inflate(R.layout.widget_chatmessage, parent, false));
}
// TODO: REWRITE THIS
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
Message msg = messageList.list.get(position);
renderer.onBind(holder, msg);
}
@Override
public int getItemCount() {
return messageList.list.size();
}
}
package de.kuschku.quasseldroid_ng.ui;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
import de.kuschku.quasseldroid_ng.R;
class MessageViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.time)
TextView time;
@Bind(R.id.content)
TextView content;
public MessageViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment