diff --git a/app/src/main/java/de/kuschku/libquassel/client/Client.java b/app/src/main/java/de/kuschku/libquassel/client/Client.java index a94de792c009797f6d3f543073490696252599ce..c089bab105d2efdad630ca617225a40071d800c0 100644 --- a/app/src/main/java/de/kuschku/libquassel/client/Client.java +++ b/app/src/main/java/de/kuschku/libquassel/client/Client.java @@ -101,6 +101,7 @@ public class Client extends AClient { this.backlogStorage = backlogStorage; backlogStorage.setClient(this); this.backlogManager = new BacklogManager(this, backlogStorage); + this.backlogManager.init("", provider, this); this.notificationManager = new NotificationManager(this); } @@ -365,7 +366,6 @@ public class Client extends AClient { public void initBacklog(int id) { backlogRequests.remove((Integer) id); - requestInitBacklog(id, 0); if (backlogRequests.isEmpty()) setConnectionStatus(ConnectionChangeEvent.Status.CONNECTED); } diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogmanagers/BacklogFilter.java b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java similarity index 93% rename from app/src/main/java/de/kuschku/libquassel/localtypes/backlogmanagers/BacklogFilter.java rename to app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java index 63dee1ad264f3af0cf2bcec4a66026aa85c3882b..efa3d08c803ac023805e5dd7739874801daf6019 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogmanagers/BacklogFilter.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java @@ -19,7 +19,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -package de.kuschku.libquassel.localtypes.backlogmanagers; +package de.kuschku.libquassel.localtypes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -35,16 +35,16 @@ import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.primitives.types.BufferInfo; import de.kuschku.libquassel.syncables.types.interfaces.QNetwork; import de.kuschku.util.observables.callbacks.UICallback; -import de.kuschku.util.observables.lists.ObservableSortedList; +import de.kuschku.util.observables.lists.ObservableComparableSortedList; public class BacklogFilter implements UICallback { @NonNull private final Client client; private final int bufferId; @NonNull - private final ObservableSortedList<Message> unfiltered; + private final ObservableComparableSortedList<Message> unfiltered; @NonNull - private final ObservableSortedList<Message> filtered; + private final ObservableComparableSortedList<Message> filtered; @NonNull private final Set<Message.Type> filteredTypes = new HashSet<>(); @@ -52,7 +52,7 @@ public class BacklogFilter implements UICallback { @Nullable private DateTime earliestMessage; - public BacklogFilter(@NonNull Client client, int bufferId, @NonNull ObservableSortedList<Message> unfiltered, @NonNull ObservableSortedList<Message> filtered) { + public BacklogFilter(@NonNull Client client, int bufferId, @NonNull ObservableComparableSortedList<Message> unfiltered, @NonNull ObservableComparableSortedList<Message> filtered) { this.client = client; this.bufferId = bufferId; this.unfiltered = unfiltered; diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java index 7f7dc0ab94477ca82f00ff626af06ce74f6b9436..0907bd1f8ec07ba8e4200f28496161c75adc6aac 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/BacklogStorage.java @@ -25,16 +25,16 @@ import android.support.annotation.IntRange; import android.support.annotation.NonNull; import de.kuschku.libquassel.client.Client; -import de.kuschku.libquassel.localtypes.backlogmanagers.BacklogFilter; +import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.message.Message; -import de.kuschku.util.observables.lists.ObservableSortedList; +import de.kuschku.util.observables.lists.ObservableComparableSortedList; public interface BacklogStorage { @NonNull - ObservableSortedList<Message> getUnfiltered(@IntRange(from = 0) int bufferid); + ObservableComparableSortedList<Message> getUnfiltered(@IntRange(from = 0) int bufferid); @NonNull - ObservableSortedList<Message> getFiltered(@IntRange(from = 0) int bufferid); + ObservableComparableSortedList<Message> getFiltered(@IntRange(from = 0) int bufferid); @NonNull BacklogFilter getFilter(@IntRange(from = 0) int bufferid); diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java index c1720e105334bd6ceb44f4b10cfbd17dba3fa7c5..ee0e0c3f4e2ab44a657513d9f5f41131f9336155 100644 --- a/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java +++ b/app/src/main/java/de/kuschku/libquassel/localtypes/backlogstorage/MemoryBacklogStorage.java @@ -26,18 +26,17 @@ import android.support.annotation.NonNull; import android.util.SparseArray; import de.kuschku.libquassel.client.Client; -import de.kuschku.libquassel.localtypes.backlogmanagers.BacklogFilter; +import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.message.Message; import de.kuschku.util.observables.lists.ObservableComparableSortedList; -import de.kuschku.util.observables.lists.ObservableSortedList; import static de.kuschku.util.AndroidAssert.assertNotNull; public class MemoryBacklogStorage implements BacklogStorage { @NonNull - private final SparseArray<ObservableSortedList<Message>> backlogs = new SparseArray<>(); + private final SparseArray<ObservableComparableSortedList<Message>> backlogs = new SparseArray<>(); @NonNull - private final SparseArray<ObservableSortedList<Message>> filteredBacklogs = new SparseArray<>(); + private final SparseArray<ObservableComparableSortedList<Message>> filteredBacklogs = new SparseArray<>(); @NonNull private final SparseArray<BacklogFilter> filters = new SparseArray<>(); @@ -45,14 +44,14 @@ public class MemoryBacklogStorage implements BacklogStorage { @NonNull @Override - public ObservableSortedList<Message> getUnfiltered(@IntRange(from = -1) int bufferid) { + public ObservableComparableSortedList<Message> getUnfiltered(@IntRange(from = -1) int bufferid) { ensureExisting(bufferid); return backlogs.get(bufferid); } @NonNull @Override - public ObservableSortedList<Message> getFiltered(@IntRange(from = -1) int bufferid) { + public ObservableComparableSortedList<Message> getFiltered(@IntRange(from = -1) int bufferid) { ensureExisting(bufferid); return filteredBacklogs.get(bufferid); } @@ -73,9 +72,9 @@ public class MemoryBacklogStorage implements BacklogStorage { @Override public void insertMessages(@NonNull Message... messages) { - if (messages.length > 0) { - int bufferId = messages[0].bufferInfo.id(); - insertMessages(bufferId, messages); + for (Message message : messages) { + ensureExisting(message.bufferInfo.id()); + backlogs.get(message.bufferInfo.id()).add(message); } } diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java index 5a674da8d409e57953380314d0a6926c71bb9208..0913f4ea4554995bd85d6e8be5551092e329d5dd 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java @@ -26,7 +26,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Observable; @@ -39,6 +38,8 @@ import de.kuschku.libquassel.syncables.types.interfaces.QSyncableObject; import de.kuschku.util.backports.Objects; import static de.kuschku.util.AndroidAssert.assertNotNull; +import static de.kuschku.util.AndroidAssert.assertTrue; +import static junit.framework.Assert.assertEquals; public abstract class SyncableObject<T extends SyncableObject<T>> extends Observable implements QSyncableObject<T> { @Nullable @@ -53,9 +54,23 @@ public abstract class SyncableObject<T extends SyncableObject<T>> extends Observ } public void sync(@NonNull String methodName, @NonNull Object[] params) { + assertTrue(initialized); assertNotNull(provider); - provider.dispatch(new SyncFunction<>(getClassName(), getObjectName(), methodName, Arrays.asList(params))); + provider.dispatch(new SyncFunction<>(getClassName(), getObjectName(), methodName, toVariantList(params))); + } + + public void sync(@NonNull String methodName, @NonNull String[] strings, @NonNull Object[] objects) { + assertTrue(initialized); + assertNotNull(provider); + assertEquals(strings.length, objects.length); + + List<QVariant> params = new ArrayList<>(); + for (int i = 0; i < strings.length; i++) { + params.add(new QVariant<>(strings[i], objects[i])); + } + + provider.dispatch(new SyncFunction<>(getClassName(), getObjectName(), methodName, params)); } @NonNull @@ -90,6 +105,7 @@ public abstract class SyncableObject<T extends SyncableObject<T>> extends Observ } public void rpc(@NonNull String procedureName, @NonNull List<QVariant> params) { + assertTrue(initialized); assertNotNull(provider); RpcCallFunction function = new RpcCallFunction(procedureName, params); diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java index 88c01477760197b76a741aa4fb409bc741f6d653..09b4c6e23e42a783a181b9253ac50adef5164d67 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java @@ -24,31 +24,34 @@ package de.kuschku.libquassel.syncables.types.abstracts; import java.util.List; import de.kuschku.libquassel.message.Message; +import de.kuschku.libquassel.primitives.QMetaType; import de.kuschku.libquassel.syncables.types.SyncableObject; import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager; -public abstract class ABacklogManager<T extends ABacklogManager<T>> extends SyncableObject<T> implements QBacklogManager { +public abstract class ABacklogManager<T extends ABacklogManager<T>> extends SyncableObject<T> implements QBacklogManager<T> { + static String intName = QMetaType.Type.Int.getSerializableName(); + @Override public void requestBacklog(int id, int first, int last, int limit, int additional) { _requestBacklog(id, first, last, limit, additional); - syncVar("requestBacklog", id, first, last, limit, additional); + sync("requestBacklog", new String[]{"BufferId", "MsgId", "MsgId", intName, intName}, new Object[]{id, first, last, limit, additional}); } @Override public void receiveBacklog(int id, int first, int last, int limit, int additional, List<Message> messages) { _receiveBacklog(id, first, last, limit, additional, messages); - syncVar("receiveBacklog", id, first, last, limit, additional, messages); + sync("receiveBacklog", new String[]{"BufferId", "MsgId", "MsgId", intName, intName}, new Object[]{id, first, last, limit, additional, messages}); } @Override public void requestBacklogAll(int first, int last, int limit, int additional) { _requestBacklogAll(first, last, limit, additional); - syncVar("requestBacklogAll", first, last, limit, additional); + sync("requestBacklogAll", new String[]{"MsgId", "MsgId", intName, intName}, new Object[]{first, last, limit, additional}); } @Override public void receiveBacklogAll(int first, int last, int limit, int additional, List<Message> messages) { _receiveBacklogAll(first, last, limit, additional, messages); - syncVar("receiveBacklogAll", first, last, limit, additional, messages); + sync("receiveBacklogAll", new String[]{"MsgId", "MsgId", intName, intName}, new Object[]{first, last, limit, additional, messages}); } } diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java index e732e424be0be5dc87ff063b05d91815e57691ba..1d0bb6287543f0e599bb5bc356dae5b588093924 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java @@ -23,18 +23,25 @@ package de.kuschku.libquassel.syncables.types.impl; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.util.Log; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import de.kuschku.libquassel.BusProvider; import de.kuschku.libquassel.client.Client; -import de.kuschku.libquassel.localtypes.backlogmanagers.BacklogFilter; +import de.kuschku.libquassel.events.BacklogReceivedEvent; +import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.localtypes.backlogstorage.BacklogStorage; import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.primitives.types.QVariant; import de.kuschku.libquassel.syncables.types.abstracts.ABacklogManager; import de.kuschku.util.observables.lists.ObservableComparableSortedList; +import static de.kuschku.util.AndroidAssert.assertNotNull; + public class BacklogManager extends ABacklogManager<BacklogManager> { private final Client client; private final BacklogStorage storage; @@ -46,56 +53,75 @@ public class BacklogManager extends ABacklogManager<BacklogManager> { @Override public void requestMoreBacklog(int bufferId, int amount) { - + Log.d("libquassel", "request more backlog for id " + bufferId + ": " + amount); + Message last; + if (storage.getUnfiltered(bufferId).isEmpty() || null == (last = storage.getUnfiltered(bufferId).last())) + requestBacklogInitial(bufferId, amount); + else { + requestBacklog(bufferId, -1, last.messageId, amount, 0); + } } @Override public void requestBacklogInitial(int id, int amount) { + Log.d("libquassel", "request initial backlog for id " + id + ": " + amount); requestBacklog(id, -1, -1, amount, 0); } @Override public void _requestBacklog(int id, int first, int last, int limit, int additional) { // Do nothing, we are on the client + Log.d("libquassel", "request backlog for id " + id); } @Override public void _receiveBacklog(int id, int first, int last, int limit, int additional, @NonNull List<Message> messages) { + assertNotNull(provider); + storage.insertMessages(id, messages.toArray(new Message[messages.size()])); client.initBacklog(id); + provider.sendEvent(new BacklogReceivedEvent(id)); + + Log.d("libquassel", "received backlog for id " + id); } @Override public void _requestBacklogAll(int first, int last, int limit, int additional) { // Do nothing, we are on the client + Log.d("libquassel", "request backlog for all"); } @Override public void _receiveBacklogAll(int first, int last, int limit, int additional, @NonNull List<Message> messages) { + assertNotNull(provider); + + Set<Integer> buffers = new HashSet<>(); for (Message message : messages) { storage.insertMessages(message.bufferInfo.id(), message); + buffers.add(message.bufferInfo.id()); + } + for (int id : buffers) { + provider.sendEvent(new BacklogReceivedEvent(id)); + Log.d("libquassel", "received backlog for id " + id); } } - // FIXME: Implement @Nullable @Override public BacklogFilter filter(int id) { - return null; + return storage.getFilter(id); } - // FIXME: Implement @Nullable @Override public ObservableComparableSortedList<Message> unfiltered(int id) { - return new ObservableComparableSortedList<>(Message.class); + return storage.getUnfiltered(id); } - // FIXME: Implement @Nullable @Override public ObservableComparableSortedList<Message> filtered(int id) { - return new ObservableComparableSortedList<>(Message.class); + return storage.getFiltered(id); } @Override @@ -107,4 +133,9 @@ public class BacklogManager extends ABacklogManager<BacklogManager> { public void update(BacklogManager from) { } + + @Override + public void init(@NonNull String objectName, @NonNull BusProvider provider, @NonNull Client client) { + super.init(objectName, provider, client); + } } diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java index 4a4c44eb0b2ad342b4e35827ed6e6ee9b1e05fe0..be65a64fc7e50f7f0bde786d67ed13e4723f4a66 100644 --- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java +++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java @@ -25,12 +25,12 @@ import android.support.annotation.Nullable; import java.util.List; -import de.kuschku.libquassel.localtypes.backlogmanagers.BacklogFilter; +import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.message.Message; import de.kuschku.libquassel.syncables.Synced; import de.kuschku.util.observables.lists.ObservableComparableSortedList; -public interface QBacklogManager { +public interface QBacklogManager<T extends QSyncableObject<T>> extends QSyncableObject<T> { void requestMoreBacklog(int bufferId, int amount); void requestBacklogInitial(int id, int amount); diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java index c6724ed5a3d4ce6b59448694be060137761cb803..b8cda329ade58affe59ea98ef895443dead8f444 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java @@ -80,7 +80,7 @@ import de.kuschku.libquassel.events.GeneralErrorEvent; import de.kuschku.libquassel.events.LagChangedEvent; import de.kuschku.libquassel.events.LoginRequireEvent; import de.kuschku.libquassel.events.UnknownCertificateEvent; -import de.kuschku.libquassel.localtypes.backlogmanagers.BacklogFilter; +import de.kuschku.libquassel.localtypes.BacklogFilter; import de.kuschku.libquassel.localtypes.buffers.Buffer; import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer; import de.kuschku.libquassel.message.Message; diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java index a18cc03104657f3940a74fc055b82c214490e574..5c8f238deed871b6ccd9e48de306a2607ab4aefe 100644 --- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java +++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java @@ -24,6 +24,7 @@ package de.kuschku.quasseldroid_ng.ui.chat.chatview; import android.support.annotation.NonNull; import android.support.annotation.UiThread; import android.support.v7.widget.RecyclerView; +import android.text.method.LinkMovementMethod; import android.view.View; import android.widget.TextView; @@ -46,5 +47,6 @@ public class MessageViewHolder extends RecyclerView.ViewHolder { public MessageViewHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this, itemView); + content.setMovementMethod(LinkMovementMethod.getInstance()); } } diff --git a/app/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java b/app/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java index 27b1f7a57f02c26256b1031343eca03853b561f1..ad9999231d6afcf1155c21800dd1ff5ef344766c 100644 --- a/app/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java +++ b/app/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java @@ -87,7 +87,7 @@ public class IrcFormatHelper { SpannableString str = new SpannableString(MessageUtil.parseStyleCodes(context.themeUtil(), message, context.settings().mircColors.get())); Matcher urlMatcher = urlPattern.matcher(str); while (urlMatcher.find()) { - spans.add(new FutureClickableSpan(new CustomURLSpan(urlMatcher.toString()), urlMatcher.start(), urlMatcher.end())); + spans.add(new FutureClickableSpan(new CustomURLSpan(urlMatcher.group()), urlMatcher.start(), urlMatcher.end())); } for (FutureClickableSpan span : spans) { str.setSpan(span.span, span.start, span.end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); @@ -137,8 +137,6 @@ public class IrcFormatHelper { @Override public void onClick(@NonNull View widget) { - Log.e("TEST", "THIS IS A TEST"); - Uri uri = Uri.parse(getURL()); Context context = widget.getContext(); Intent intent = new Intent(Intent.ACTION_VIEW, uri);