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

Added proper backlog filtering, refactored some stuff

parent bc57c06a
No related branches found
No related tags found
No related merge requests found
Showing
with 423 additions and 55 deletions
...@@ -46,14 +46,10 @@ android { ...@@ -46,14 +46,10 @@ android {
} }
dependencies { dependencies {
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
compile('com.mikepenz:materialdrawer:5.0.0.fastAdapter.b5-SNAPSHOT@aar') { compile('com.mikepenz:materialdrawer:5.0.0.b21-SNAPSHOT@aar') {
transitive = true
}
compile('com.mikepenz:fastadapter:0.4.2-SNAPSHOT@aar') {
transitive = true transitive = true
} }
compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') { compile('com.github.afollestad.material-dialogs:core:0.8.5.3@aar') {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
android:name=".ui.chat.ChatActivity" android:name=".ui.chat.ChatActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleTask" android:launchMode="singleTask"
android:theme="@style/AppTheme.Light"> android:theme="@style/Quassel">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
......
...@@ -2,6 +2,7 @@ package de.kuschku.libquassel; ...@@ -2,6 +2,7 @@ package de.kuschku.libquassel;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
...@@ -9,28 +10,33 @@ import java.util.HashMap; ...@@ -9,28 +10,33 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import de.kuschku.libquassel.backlogmanagers.BacklogManager; import de.kuschku.libquassel.events.LagChangedEvent;
import de.kuschku.libquassel.backlogmanagers.SimpleBacklogManager; import de.kuschku.libquassel.localtypes.NotificationManager;
import de.kuschku.libquassel.localtypes.backlogmanagers.BacklogManager;
import de.kuschku.libquassel.localtypes.backlogmanagers.SimpleBacklogManager;
import de.kuschku.libquassel.events.ConnectionChangeEvent; import de.kuschku.libquassel.events.ConnectionChangeEvent;
import de.kuschku.libquassel.events.StatusMessageEvent; import de.kuschku.libquassel.events.StatusMessageEvent;
import de.kuschku.libquassel.functions.types.HandshakeFunction;
import de.kuschku.libquassel.functions.types.InitRequestFunction; import de.kuschku.libquassel.functions.types.InitRequestFunction;
import de.kuschku.libquassel.functions.types.RpcCallFunction; import de.kuschku.libquassel.functions.types.RpcCallFunction;
import de.kuschku.libquassel.localtypes.Buffer; import de.kuschku.libquassel.localtypes.Buffer;
import de.kuschku.libquassel.localtypes.Buffers; import de.kuschku.libquassel.localtypes.Buffers;
import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.message.Message;
import de.kuschku.libquassel.objects.types.ClientInitAck; import de.kuschku.libquassel.objects.types.ClientInitAck;
import de.kuschku.libquassel.objects.types.ClientLogin;
import de.kuschku.libquassel.objects.types.SessionState; import de.kuschku.libquassel.objects.types.SessionState;
import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.primitives.types.QVariant; import de.kuschku.libquassel.primitives.types.QVariant;
import de.kuschku.libquassel.syncables.types.BufferSyncer; import de.kuschku.libquassel.syncables.types.BufferSyncer;
import de.kuschku.libquassel.syncables.types.BufferViewConfig;
import de.kuschku.libquassel.syncables.types.BufferViewManager; import de.kuschku.libquassel.syncables.types.BufferViewManager;
import de.kuschku.libquassel.syncables.types.IgnoreListManager;
import de.kuschku.libquassel.syncables.types.IrcChannel;
import de.kuschku.libquassel.syncables.types.IrcUser;
import de.kuschku.libquassel.syncables.types.Network; import de.kuschku.libquassel.syncables.types.Network;
import de.kuschku.libquassel.syncables.types.SyncableObject; import de.kuschku.libquassel.syncables.types.SyncableObject;
import de.kuschku.quasseldroid_ng.ui.chat.drawer.NetworkWrapper;
import de.kuschku.util.backports.Stream; import de.kuschku.util.backports.Stream;
import de.kuschku.util.observables.callbacks.UICallback; import de.kuschku.util.observables.lists.ObservableElementList;
import de.kuschku.util.observables.lists.IObservableList;
import de.kuschku.util.observables.lists.ObservableComparableSortedList;
import static de.kuschku.util.AndroidAssert.assertNotNull; import static de.kuschku.util.AndroidAssert.assertNotNull;
...@@ -39,7 +45,7 @@ public class Client { ...@@ -39,7 +45,7 @@ public class Client {
@NonNull @NonNull
private final Map<Integer, Network> networks = new HashMap<>(); private final Map<Integer, Network> networks = new HashMap<>();
@NonNull @NonNull
private final IObservableList<UICallback, NetworkWrapper> networkList = new ObservableComparableSortedList<>(NetworkWrapper.class); private final ObservableElementList<Integer> networkList = new ObservableElementList<>();
@NonNull @NonNull
private final Map<Integer, Buffer> buffers = new HashMap<>(); private final Map<Integer, Buffer> buffers = new HashMap<>();
@NonNull @NonNull
...@@ -47,8 +53,10 @@ public class Client { ...@@ -47,8 +53,10 @@ public class Client {
@NonNull @NonNull
private final BacklogManager backlogManager; private final BacklogManager backlogManager;
@NonNull @NonNull
private final NotificationManager notificationManager = new NotificationManager();
@NonNull
private final BusProvider busProvider; private final BusProvider busProvider;
public int lag; private long lag;
private ConnectionChangeEvent.Status connectionStatus; private ConnectionChangeEvent.Status connectionStatus;
private ClientInitAck core; private ClientInitAck core;
@Nullable @Nullable
...@@ -56,6 +64,7 @@ public class Client { ...@@ -56,6 +64,7 @@ public class Client {
private BufferViewManager bufferViewManager; private BufferViewManager bufferViewManager;
private BufferSyncer bufferSyncer; private BufferSyncer bufferSyncer;
private ClientData clientData; private ClientData clientData;
private IgnoreListManager ignoreListManager;
public Client(@NonNull final BusProvider busProvider) { public Client(@NonNull final BusProvider busProvider) {
this(new SimpleBacklogManager(busProvider), busProvider); this(new SimpleBacklogManager(busProvider), busProvider);
...@@ -64,6 +73,7 @@ public class Client { ...@@ -64,6 +73,7 @@ public class Client {
public Client(@NonNull final BacklogManager backlogManager, @NonNull final BusProvider busProvider) { public Client(@NonNull final BacklogManager backlogManager, @NonNull final BusProvider busProvider) {
this.backlogManager = backlogManager; this.backlogManager = backlogManager;
this.busProvider = busProvider; this.busProvider = busProvider;
this.backlogManager.setClient(this);
} }
public void sendInput(@NonNull final BufferInfo info, @NonNull final String input) { public void sendInput(@NonNull final BufferInfo info, @NonNull final String input) {
...@@ -86,6 +96,7 @@ public class Client { ...@@ -86,6 +96,7 @@ public class Client {
assertNotNull(state); assertNotNull(state);
networks.put(network.getNetworkId(), network); networks.put(network.getNetworkId(), network);
networkList.add(network.getNetworkId());
for (BufferInfo info : state.BufferInfos) { for (BufferInfo info : state.BufferInfos) {
if (info.networkId == network.getNetworkId()) { if (info.networkId == network.getNetworkId()) {
...@@ -104,6 +115,7 @@ public class Client { ...@@ -104,6 +115,7 @@ public class Client {
public void putBuffer(@NonNull final Buffer buffer) { public void putBuffer(@NonNull final Buffer buffer) {
this.buffers.put(buffer.getInfo().id, buffer); this.buffers.put(buffer.getInfo().id, buffer);
this.notificationManager.init(buffer.getInfo().id);
} }
@Nullable @Nullable
...@@ -111,11 +123,11 @@ public class Client { ...@@ -111,11 +123,11 @@ public class Client {
return this.buffers.get(bufferId); return this.buffers.get(bufferId);
} }
void sendInitRequest(@NonNull final String className, @Nullable final String objectName) { public void sendInitRequest(@NonNull final String className, @Nullable final String objectName) {
sendInitRequest(className, objectName, false); sendInitRequest(className, objectName, false);
} }
void sendInitRequest(@NonNull final String className, @Nullable final String objectName, boolean addToList) { public void sendInitRequest(@NonNull final String className, @Nullable final String objectName, boolean addToList) {
busProvider.dispatch(new InitRequestFunction(className, objectName)); busProvider.dispatch(new InitRequestFunction(className, objectName));
if (addToList) if (addToList)
...@@ -135,33 +147,40 @@ public class Client { ...@@ -135,33 +147,40 @@ public class Client {
} }
@Nullable @Nullable
public SyncableObject getObjectByIdentifier(@NonNull final String className, @NonNull final String objectName) { public SyncableObject getObjectByIdentifier(@NonNull final String className, @Nullable final String objectName) {
switch (className) { switch (className) {
case "BacklogManager": case "BacklogManager":
return getBacklogManager(); return getBacklogManager();
case "IrcChannel": { case "IrcChannel": {
assertNotNull(objectName);
final int networkId = Integer.parseInt(objectName.split("/")[0]); final int networkId = Integer.parseInt(objectName.split("/")[0]);
final String channelname = objectName.split("/")[1]; final String channelname = objectName.split("/")[1];
// Assert that networkId is valid // Assert that networkId is valid
Network network = getNetwork(networkId); Network network = getNetwork(networkId);
assertNotNull(network); assertNotNull(network);
return network.getChannels().get(channelname); IrcChannel channel = network.getChannels().get(channelname);
assertNotNull("Channel " + channelname + " not found in " + network.getChannels().keySet(), channel);
return channel;
} }
case "BufferSyncer": case "BufferSyncer":
return bufferSyncer; return bufferSyncer;
case "BufferViewConfig": case "BufferViewConfig":
assertNotNull(getBufferViewManager()); assertNotNull(getBufferViewManager());
assertNotNull(objectName);
return getBufferViewManager().BufferViews.get(Integer.valueOf(objectName)); return getBufferViewManager().BufferViews.get(Integer.valueOf(objectName));
case "IrcUser": { case "IrcUser": {
assertNotNull(objectName);
final int networkId = Integer.parseInt(objectName.split("/")[0]); final int networkId = Integer.parseInt(objectName.split("/")[0]);
final String username = objectName.split("/")[1]; final String username = objectName.split("/")[1];
Network network = getNetwork(networkId); Network network = getNetwork(networkId);
assertNotNull(network); assertNotNull(network);
return network.getUser(username); IrcUser networkUser = network.getUser(username);
assertNotNull("User " + username + " not found in " + network.getUsers().keySet(), networkUser);
return networkUser;
} }
case "Network": { case "Network": {
assertNotNull(objectName);
return getNetwork(Integer.parseInt(objectName)); return getNetwork(Integer.parseInt(objectName));
} }
default: default:
...@@ -184,7 +203,7 @@ public class Client { ...@@ -184,7 +203,7 @@ public class Client {
} }
@NonNull @NonNull
public BacklogManager getBacklogManager() { public BacklogManager<?> getBacklogManager() {
return backlogManager; return backlogManager;
} }
...@@ -226,8 +245,8 @@ public class Client { ...@@ -226,8 +245,8 @@ public class Client {
} }
@NonNull @NonNull
public Collection<Network> getNetworks() { public ObservableElementList<Integer> getNetworks() {
return networks.values(); return networkList;
} }
@NonNull @NonNull
...@@ -240,8 +259,31 @@ public class Client { ...@@ -240,8 +259,31 @@ public class Client {
busProvider.sendEvent(new ConnectionChangeEvent(connectionStatus)); busProvider.sendEvent(new ConnectionChangeEvent(connectionStatus));
} }
public void login(String username, String password) {
busProvider.dispatch(new HandshakeFunction(new ClientLogin(
username, password
)));
}
@NonNull @NonNull
public IObservableList<UICallback, NetworkWrapper> getNetworkList() { public NotificationManager getNotificationManager() {
return networkList; return notificationManager;
}
public void setLag(long l) {
lag = l;
busProvider.sendEvent(new LagChangedEvent(lag));
}
public long getLag() {
return lag;
}
public IgnoreListManager getIgnoreListManager() {
return ignoreListManager;
}
public void setIgnoreListManager(IgnoreListManager ignoreListManager) {
this.ignoreListManager = ignoreListManager;
} }
} }
...@@ -5,6 +5,8 @@ import android.support.annotation.NonNull; ...@@ -5,6 +5,8 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import org.joda.time.DateTime;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
...@@ -20,6 +22,7 @@ import de.kuschku.libquassel.events.ConnectionChangeEvent; ...@@ -20,6 +22,7 @@ import de.kuschku.libquassel.events.ConnectionChangeEvent;
import de.kuschku.libquassel.events.GeneralErrorEvent; import de.kuschku.libquassel.events.GeneralErrorEvent;
import de.kuschku.libquassel.events.HandshakeFailedEvent; import de.kuschku.libquassel.events.HandshakeFailedEvent;
import de.kuschku.libquassel.functions.types.HandshakeFunction; import de.kuschku.libquassel.functions.types.HandshakeFunction;
import de.kuschku.libquassel.functions.types.Heartbeat;
import de.kuschku.libquassel.objects.types.ClientInit; import de.kuschku.libquassel.objects.types.ClientInit;
import de.kuschku.libquassel.primitives.QMetaTypeRegistry; import de.kuschku.libquassel.primitives.QMetaTypeRegistry;
import de.kuschku.libquassel.primitives.serializers.ProtocolSerializer; import de.kuschku.libquassel.primitives.serializers.ProtocolSerializer;
...@@ -50,7 +53,9 @@ public class CoreConnection { ...@@ -50,7 +53,9 @@ public class CoreConnection {
@Nullable @Nullable
private ExecutorService outputExecutor; private ExecutorService outputExecutor;
@Nullable @Nullable
private ExecutorService inputExecutor; private EndableThread inputThread;
@Nullable
private EndableThread heartbeatThread;
@Nullable @Nullable
private RemotePeer remotePeer; private RemotePeer remotePeer;
@Nullable @Nullable
...@@ -95,7 +100,6 @@ public class CoreConnection { ...@@ -95,7 +100,6 @@ public class CoreConnection {
// Create executor for write events // Create executor for write events
outputExecutor = Executors.newSingleThreadExecutor(); outputExecutor = Executors.newSingleThreadExecutor();
inputExecutor = Executors.newSingleThreadExecutor();
// Execute handshake // Execute handshake
handshake(); handshake();
...@@ -112,7 +116,8 @@ public class CoreConnection { ...@@ -112,7 +116,8 @@ public class CoreConnection {
client.setConnectionStatus(ConnectionChangeEvent.Status.DISCONNECTED); client.setConnectionStatus(ConnectionChangeEvent.Status.DISCONNECTED);
// We can do this because we clean up the file handles ourselves // We can do this because we clean up the file handles ourselves
if (inputExecutor != null) inputExecutor.shutdownNow(); if (inputThread != null) inputThread.end();
if (heartbeatThread != null) heartbeatThread.end();
if (outputExecutor != null) outputExecutor.shutdownNow(); if (outputExecutor != null) outputExecutor.shutdownNow();
// Which we do exactly here // Which we do exactly here
...@@ -154,7 +159,6 @@ public class CoreConnection { ...@@ -154,7 +159,6 @@ public class CoreConnection {
*/ */
private void handshake() throws IOException { private void handshake() throws IOException {
assertNotNull(channel); assertNotNull(channel);
assertNotNull(inputExecutor);
// Start protocol handshake with magic version and feature flags // Start protocol handshake with magic version and feature flags
QMetaTypeRegistry.serialize(UInt, channel, 0x42b33f00 | clientData.flags.flags); QMetaTypeRegistry.serialize(UInt, channel, 0x42b33f00 | clientData.flags.flags);
...@@ -166,7 +170,10 @@ public class CoreConnection { ...@@ -166,7 +170,10 @@ public class CoreConnection {
QMetaTypeRegistry.serialize(UInt, channel, 0x01 << 31); QMetaTypeRegistry.serialize(UInt, channel, 0x01 << 31);
// Spawn and start a new read thread // Spawn and start a new read thread
inputExecutor.submit(new ReadRunnable()); inputThread = new ReadThread();
heartbeatThread = new HeartbeatThread();
inputThread.start();
heartbeatThread.start();
} }
public void onEventAsync(HandshakeFailedEvent event) { public void onEventAsync(HandshakeFailedEvent event) {
...@@ -192,14 +199,20 @@ public class CoreConnection { ...@@ -192,14 +199,20 @@ public class CoreConnection {
/** /**
* A runnable that reads from the channel and calls the functions responsible for processing the read data. * A runnable that reads from the channel and calls the functions responsible for processing the read data.
*/ */
private class ReadRunnable implements Runnable { private class ReadThread extends EndableThread {
private boolean running = true;
public ReadThread() {
setName(getClass().getSimpleName());
}
@Override @Override
public void run() { public void run() {
assertNotNull(client); assertNotNull(client);
try { try {
boolean hasReadPreHandshake = false; boolean hasReadPreHandshake = false;
while (true) { while (running) {
if (!hasReadPreHandshake) { if (!hasReadPreHandshake) {
final ByteBuffer buffer = ByteBuffer.allocate(4); final ByteBuffer buffer = ByteBuffer.allocate(4);
assertNotNull(buffer); assertNotNull(buffer);
...@@ -248,5 +261,42 @@ public class CoreConnection { ...@@ -248,5 +261,42 @@ public class CoreConnection {
busProvider.sendEvent(new GeneralErrorEvent(e)); busProvider.sendEvent(new GeneralErrorEvent(e));
} }
} }
@Override
public void end() {
running = false;
}
}
private class HeartbeatThread extends EndableThread {
private boolean running = true;
public HeartbeatThread() {
setName(getClass().getSimpleName());
}
@Override
public void run() {
try {
assertNotNull(client);
while (running) {
busProvider.dispatch(new Heartbeat(DateTime.now()));
Thread.sleep(30 * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void end() {
running = false;
}
}
private abstract class EndableThread extends Thread {
public abstract void end();
} }
} }
...@@ -21,15 +21,15 @@ public interface IProtocolHandler { ...@@ -21,15 +21,15 @@ public interface IProtocolHandler {
void onEventMainThread(SyncFunction packedFunc); void onEventMainThread(SyncFunction packedFunc);
void onEventMainThread(ClientInitReject message); void onEvent(ClientInitReject message);
void onEventMainThread(ClientInitAck message); void onEvent(ClientInitAck message);
void onEventMainThread(ClientLoginAck message); void onEvent(ClientLoginAck message);
void onEventMainThread(ClientLoginReject message); void onEvent(ClientLoginReject message);
void onEventMainThread(SessionInit message); void onEvent(SessionInit message);
@NonNull @NonNull
Client getClient(); Client getClient();
......
...@@ -3,12 +3,16 @@ package de.kuschku.libquassel; ...@@ -3,12 +3,16 @@ package de.kuschku.libquassel;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import org.joda.time.DateTime;
import de.kuschku.libquassel.events.ConnectionChangeEvent; import de.kuschku.libquassel.events.ConnectionChangeEvent;
import de.kuschku.libquassel.events.GeneralErrorEvent; import de.kuschku.libquassel.events.GeneralErrorEvent;
import de.kuschku.libquassel.events.HandshakeFailedEvent; import de.kuschku.libquassel.events.HandshakeFailedEvent;
import de.kuschku.libquassel.events.LoginFailedEvent; import de.kuschku.libquassel.events.LoginFailedEvent;
import de.kuschku.libquassel.events.LoginSuccessfulEvent; import de.kuschku.libquassel.events.LoginSuccessfulEvent;
import de.kuschku.libquassel.exceptions.UnknownTypeException; import de.kuschku.libquassel.exceptions.UnknownTypeException;
import de.kuschku.libquassel.functions.types.Heartbeat;
import de.kuschku.libquassel.functions.types.HeartbeatReply;
import de.kuschku.libquassel.functions.types.InitDataFunction; import de.kuschku.libquassel.functions.types.InitDataFunction;
import de.kuschku.libquassel.functions.types.InitRequestFunction; import de.kuschku.libquassel.functions.types.InitRequestFunction;
import de.kuschku.libquassel.functions.types.RpcCallFunction; import de.kuschku.libquassel.functions.types.RpcCallFunction;
...@@ -20,10 +24,13 @@ import de.kuschku.libquassel.objects.types.ClientLoginReject; ...@@ -20,10 +24,13 @@ import de.kuschku.libquassel.objects.types.ClientLoginReject;
import de.kuschku.libquassel.objects.types.SessionInit; import de.kuschku.libquassel.objects.types.SessionInit;
import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.libquassel.primitives.types.BufferInfo;
import de.kuschku.libquassel.syncables.SyncableRegistry; import de.kuschku.libquassel.syncables.SyncableRegistry;
import de.kuschku.libquassel.syncables.types.BufferViewConfig;
import de.kuschku.libquassel.syncables.types.SyncableObject; import de.kuschku.libquassel.syncables.types.SyncableObject;
import de.kuschku.util.AndroidAssert; import de.kuschku.util.AndroidAssert;
import de.kuschku.util.ReflectionUtils; import de.kuschku.util.ReflectionUtils;
import static de.kuschku.util.AndroidAssert.assertNotNull;
public class ProtocolHandler implements IProtocolHandler { public class ProtocolHandler implements IProtocolHandler {
@NonNull @NonNull
public final Client client; public final Client client;
...@@ -51,7 +58,7 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -51,7 +58,7 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
SyncableObject object = SyncableRegistry.from(packedFunc); SyncableObject object = SyncableRegistry.from(packedFunc);
AndroidAssert.assertNotNull(object); assertNotNull(object);
object.init(packedFunc, busProvider, client); object.init(packedFunc, busProvider, client);
} catch (Exception e) { } catch (Exception e) {
...@@ -79,21 +86,21 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -79,21 +86,21 @@ public class ProtocolHandler implements IProtocolHandler {
public void onEventMainThread(@NonNull SyncFunction packedFunc) { public void onEventMainThread(@NonNull SyncFunction packedFunc) {
try { try {
final Object syncable = client.getObjectByIdentifier(packedFunc.className, packedFunc.objectName); final Object syncable = client.getObjectByIdentifier(packedFunc.className, packedFunc.objectName);
if (syncable != null) { AndroidAssert.assertNotNull("Object not found: " + packedFunc.className+":"+packedFunc.objectName, syncable);
ReflectionUtils.invokeMethod(syncable, packedFunc.methodName, packedFunc.params); ReflectionUtils.invokeMethod(syncable, packedFunc.methodName, packedFunc.params);
} else {
busProvider.sendEvent(new GeneralErrorEvent(new UnknownTypeException(packedFunc.className)));
}
} catch (Exception e) { } catch (Exception e) {
busProvider.sendEvent(new GeneralErrorEvent(e)); busProvider.sendEvent(new GeneralErrorEvent(e, packedFunc.toString()));
} catch (Error e) {
e.printStackTrace();
Log.e("EVENT", packedFunc.toString());
} }
} }
public void onEventMainThread(@NonNull ClientInitReject message) { public void onEvent(@NonNull ClientInitReject message) {
busProvider.sendEvent(new HandshakeFailedEvent(message.Error)); busProvider.sendEvent(new HandshakeFailedEvent(message.Error));
} }
public void onEventMainThread(ClientInitAck message) { public void onEvent(ClientInitAck message) {
client.setCore(message); client.setCore(message);
if (client.getCore().Configured) { if (client.getCore().Configured) {
...@@ -105,16 +112,16 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -105,16 +112,16 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
public void onEventMainThread(ClientLoginAck message) { public void onEvent(ClientLoginAck message) {
busProvider.sendEvent(new LoginSuccessfulEvent()); busProvider.sendEvent(new LoginSuccessfulEvent());
client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTING); client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTING);
} }
public void onEventMainThread(@NonNull ClientLoginReject message) { public void onEvent(@NonNull ClientLoginReject message) {
busProvider.sendEvent(new LoginFailedEvent(message.Error)); busProvider.sendEvent(new LoginFailedEvent(message.Error));
} }
public void onEventMainThread(@NonNull SessionInit message) { public void onEvent(@NonNull SessionInit message) {
client.setState(message.SessionState); client.setState(message.SessionState);
client.setConnectionStatus(ConnectionChangeEvent.Status.INITIALIZING_DATA); client.setConnectionStatus(ConnectionChangeEvent.Status.INITIALIZING_DATA);
...@@ -134,6 +141,17 @@ public class ProtocolHandler implements IProtocolHandler { ...@@ -134,6 +141,17 @@ public class ProtocolHandler implements IProtocolHandler {
} }
} }
public void onEvent(@NonNull Heartbeat heartbeat) {
busProvider.dispatch(new HeartbeatReply(heartbeat.dateTime));
}
public void onEventMainThread(@NonNull HeartbeatReply heartbeat) {
long roundtrip = DateTime.now().getMillis() - heartbeat.dateTime.getMillis();
long lag = (long) (roundtrip * 0.5);
client.setLag(lag);
}
@NonNull @NonNull
@Override @Override
public Client getClient() { public Client getClient() {
......
...@@ -4,7 +4,7 @@ import android.support.annotation.IntRange; ...@@ -4,7 +4,7 @@ import android.support.annotation.IntRange;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class BacklogReceivedEvent { public class BacklogReceivedEvent {
@IntRange(from = 0) @IntRange(from = -1)
public final int bufferId; public final int bufferId;
public BacklogReceivedEvent(int bufferId) { public BacklogReceivedEvent(int bufferId) {
......
...@@ -13,11 +13,18 @@ public class GeneralErrorEvent { ...@@ -13,11 +13,18 @@ public class GeneralErrorEvent {
this.exception = exception; this.exception = exception;
} }
public GeneralErrorEvent(Exception exception, String debugInfo) {
this.debugInfo = debugInfo;
this.exception = exception;
}
@Override @Override
public String toString() { public String toString() {
if (debugInfo == null) if (debugInfo == null)
return String.format("%s: %s", exception.getClass().getSimpleName(), exception.getLocalizedMessage()); return String.format("%s: %s", exception.getClass().getSimpleName(), exception.getLocalizedMessage());
else else if (exception == null)
return debugInfo; return debugInfo;
else
return String.format("%s: %s\n%s", exception.getClass().getSimpleName(), exception.getLocalizedMessage(), debugInfo);
} }
} }
package de.kuschku.libquassel.events;
public class LagChangedEvent {
public final long lag;
public LagChangedEvent(long lag) {
this.lag = lag;
}
@Override
public String toString() {
return "LagChangedEvent{" +
"lag=" + lag +
'}';
}
}
...@@ -4,9 +4,15 @@ import android.support.annotation.Nullable; ...@@ -4,9 +4,15 @@ import android.support.annotation.Nullable;
public class UnknownTypeException extends IllegalArgumentException { public class UnknownTypeException extends IllegalArgumentException {
public final String typeName; public final String typeName;
public final String additionalData;
public UnknownTypeException(String typeName) { public UnknownTypeException(String typeName) {
this(typeName, null);
}
public UnknownTypeException(String typeName, Object additionalData) {
this.typeName = typeName; this.typeName = typeName;
this.additionalData = String.valueOf(additionalData);
} }
@Nullable @Nullable
...@@ -17,6 +23,6 @@ public class UnknownTypeException extends IllegalArgumentException { ...@@ -17,6 +23,6 @@ public class UnknownTypeException extends IllegalArgumentException {
@Override @Override
public String getMessage() { public String getMessage() {
return String.format("Unknown type: %s", typeName); return String.format("Unknown type: %s; %s", typeName, additionalData);
} }
} }
package de.kuschku.libquassel.functions.serializers;
import android.support.annotation.NonNull;
import org.joda.time.DateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import de.kuschku.libquassel.functions.FunctionType;
import de.kuschku.libquassel.functions.types.Heartbeat;
import de.kuschku.libquassel.functions.types.HeartbeatReply;
import de.kuschku.libquassel.primitives.types.QVariant;
import static de.kuschku.util.AndroidAssert.assertTrue;
public class HeartbeatReplySerializer implements FunctionSerializer<HeartbeatReply> {
@NonNull
private static final HeartbeatReplySerializer serializer = new HeartbeatReplySerializer();
private HeartbeatReplySerializer() {
}
@NonNull
public static HeartbeatReplySerializer get() {
return serializer;
}
@NonNull
@Override
public List serialize(@NonNull HeartbeatReply data) {
return Arrays.asList(
FunctionType.HEARTBEATREPLY.id,
new QVariant<>(data.dateTime)
);
}
@NonNull
@Override
public HeartbeatReply deserialize(@NonNull List packedFunc) {
assertTrue(packedFunc.size() == 1);
return new HeartbeatReply((DateTime) ((QVariant) packedFunc.remove(0)).data);
}
}
package de.kuschku.libquassel.functions.serializers;
import android.support.annotation.NonNull;
import org.joda.time.DateTime;
import java.util.Arrays;
import java.util.List;
import de.kuschku.libquassel.functions.FunctionType;
import de.kuschku.libquassel.functions.types.Heartbeat;
import de.kuschku.libquassel.primitives.types.QVariant;
import static de.kuschku.util.AndroidAssert.assertTrue;
public class HeartbeatSerializer implements FunctionSerializer<Heartbeat> {
@NonNull
private static final HeartbeatSerializer serializer = new HeartbeatSerializer();
private HeartbeatSerializer() {
}
@NonNull
public static HeartbeatSerializer get() {
return serializer;
}
@NonNull
@Override
public List serialize(@NonNull Heartbeat data) {
return Arrays.asList(
FunctionType.HEARTBEAT.id,
new QVariant<>(data.dateTime)
);
}
@NonNull
@Override
public Heartbeat deserialize(@NonNull List packedFunc) {
assertTrue(packedFunc.size() == 1);
return new Heartbeat((DateTime) ((QVariant) packedFunc.remove(0)).data);
}
}
package de.kuschku.libquassel.functions.types;
import org.joda.time.DateTime;
public class Heartbeat {
public final DateTime dateTime;
public Heartbeat(DateTime dateTime) {
this.dateTime = dateTime;
}
@Override
public String toString() {
return "Heartbeat{" +
"dateTime=" + dateTime +
'}';
}
}
package de.kuschku.libquassel.functions.types;
import org.joda.time.DateTime;
public class HeartbeatReply {
public final DateTime dateTime;
public HeartbeatReply(DateTime dateTime) {
this.dateTime = dateTime;
}
@Override
public String toString() {
return "HeartbeatReply{" +
"dateTime=" + dateTime +
'}';
}
}
...@@ -11,4 +11,6 @@ public interface Buffer { ...@@ -11,4 +11,6 @@ public interface Buffer {
@Nullable @Nullable
String getName(); String getName();
boolean isActive();
} }
...@@ -9,10 +9,10 @@ import de.kuschku.libquassel.syncables.types.IrcChannel; ...@@ -9,10 +9,10 @@ import de.kuschku.libquassel.syncables.types.IrcChannel;
public class ChannelBuffer implements Buffer { public class ChannelBuffer implements Buffer {
@NonNull @NonNull
private final BufferInfo info; private final BufferInfo info;
@NonNull @Nullable
private final IrcChannel channel; private final IrcChannel channel;
public ChannelBuffer(@NonNull BufferInfo info, @NonNull IrcChannel channel) { public ChannelBuffer(@NonNull BufferInfo info, @Nullable IrcChannel channel) {
this.info = info; this.info = info;
this.channel = channel; this.channel = channel;
} }
...@@ -29,7 +29,12 @@ public class ChannelBuffer implements Buffer { ...@@ -29,7 +29,12 @@ public class ChannelBuffer implements Buffer {
return getInfo().name; return getInfo().name;
} }
@NonNull @Override
public boolean isActive() {
return channel != null;
}
@Nullable
public IrcChannel getChannel() { public IrcChannel getChannel() {
return channel; return channel;
} }
......
package de.kuschku.libquassel.localtypes;
import android.util.SparseArray;
import de.kuschku.libquassel.message.Message;
import de.kuschku.util.observables.lists.ObservableComparableSortedList;
public class NotificationManager {
private SparseArray<ObservableComparableSortedList<Message>> notifications = new SparseArray<>();
public ObservableComparableSortedList<Message> getNotifications(int bufferid) {
return notifications.get(bufferid);
}
public void init(int id) {
notifications.put(id, new ObservableComparableSortedList<>(Message.class));
}
}
...@@ -29,6 +29,11 @@ public class QueryBuffer implements Buffer { ...@@ -29,6 +29,11 @@ public class QueryBuffer implements Buffer {
return getInfo().name; return getInfo().name;
} }
@Override
public boolean isActive() {
return user != null;
}
@Nullable @Nullable
public IrcUser getUser() { public IrcUser getUser() {
return user; return user;
......
...@@ -29,6 +29,11 @@ public class StatusBuffer implements Buffer { ...@@ -29,6 +29,11 @@ public class StatusBuffer implements Buffer {
return network.getNetworkName(); return network.getNetworkName();
} }
@Override
public boolean isActive() {
return network.isConnected();
}
@NonNull @NonNull
@Override @Override
public String toString() { public String toString() {
......
package de.kuschku.libquassel.localtypes.backlogmanagers;
import android.support.annotation.NonNull;
import com.android.internal.util.Predicate;
import de.kuschku.libquassel.Client;
import de.kuschku.libquassel.message.Message;
import de.kuschku.quasseldroid_ng.ui.AppContext;
import de.kuschku.util.observables.callbacks.UICallback;
import de.kuschku.util.observables.lists.ObservableSortedList;
public class BacklogFilter implements UICallback {
@NonNull
private final Client client;
@NonNull
private final ObservableSortedList<Message> unfiltered;
@NonNull
private final ObservableSortedList<Message> filtered;
public BacklogFilter(@NonNull Client client, @NonNull ObservableSortedList<Message> unfiltered, @NonNull ObservableSortedList<Message> filtered) {
this.client = client;
this.unfiltered = unfiltered;
this.filtered = filtered;
}
@Override
public void notifyItemInserted(int position) {
Message message = unfiltered.get(position);
if (filterItem(message)) filtered.add(message);
}
private boolean filterItem(Message message) {
return !client.getIgnoreListManager().matches(message);
}
@Override
public void notifyItemChanged(int position) {
filtered.notifyItemChanged(position);
}
@Override
public void notifyItemRemoved(int position) {
filtered.remove(position);
}
@Override
public void notifyItemMoved(int from, int to) {
// Can’t occur: Sorted List
}
@Override
public void notifyItemRangeInserted(int position, int count) {
for (int i = position; i < position + count; i++) {
notifyItemInserted(i);
}
}
@Override
public void notifyItemRangeChanged(int position, int count) {
for (int i = position; i < position + count; i++) {
notifyItemChanged(i);
}
}
@Override
public void notifyItemRangeRemoved(int position, int count) {
for (int i = position; i < position + count; i++) {
notifyItemRemoved(i);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment