aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian.schneppe@pix-art.de>2019-10-26 18:10:48 +0200
committerChristian Schneppe <christian.schneppe@pix-art.de>2019-10-26 18:10:48 +0200
commit35df965b58a9505f27be34c3a68309211c2e6d88 (patch)
tree0747dfdf4d3421249489d4b3140195d053cf7c2f
parent8d7727fcdc400dcd05babe4ec9b78fa0d1f56717 (diff)
Bookmarks2: support retraction
-rw-r--r--src/main/java/de/pixart/messenger/entities/Account.java56
-rw-r--r--src/main/java/de/pixart/messenger/entities/Bookmark.java20
-rw-r--r--src/main/java/de/pixart/messenger/generator/IqGenerator.java1
-rw-r--r--src/main/java/de/pixart/messenger/parser/MessageParser.java28
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java16
-rw-r--r--src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java1
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java20
-rw-r--r--src/main/java/de/pixart/messenger/ui/StartConversationActivity.java4
8 files changed, 87 insertions, 59 deletions
diff --git a/src/main/java/de/pixart/messenger/entities/Account.java b/src/main/java/de/pixart/messenger/entities/Account.java
index 0590c9d72..fe31dbf07 100644
--- a/src/main/java/de/pixart/messenger/entities/Account.java
+++ b/src/main/java/de/pixart/messenger/entities/Account.java
@@ -16,11 +16,12 @@ import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import de.pixart.messenger.Config;
@@ -92,7 +93,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
private XmppConnection xmppConnection = null;
private long mEndGracePeriod = 0L;
private String otrFingerprint;
- private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
+ private final Map<Jid, Bookmark> bookmarks = new HashMap<>();
private Presence.Status presenceStatus = Presence.Status.ONLINE;
private String presenceStatusMessage = null;
@@ -502,36 +503,51 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
return this.roster;
}
- public List<Bookmark> getBookmarks() {
- return this.bookmarks;
+ public Collection<Bookmark> getBookmarks() {
+ return this.bookmarks.values();
}
- public void setBookmarks(final CopyOnWriteArrayList<Bookmark> bookmarks) {
- this.bookmarks = bookmarks;
+ public void setBookmarks(Map<Jid, Bookmark> bookmarks) {
+ synchronized (this.bookmarks) {
+ this.bookmarks.clear();
+ this.bookmarks.putAll(bookmarks);
+ }
+ }
+
+ public void putBookmark(Bookmark bookmark) {
+ synchronized (this.bookmarks) {
+ this.bookmarks.put(bookmark.getJid(), bookmark);
+ }
+ }
+
+ public void removeBookmark(Bookmark bookmark) {
+ synchronized (this.bookmarks) {
+ this.bookmarks.remove(bookmark.getJid());
+ }
+ }
+
+ public void removeBookmark(Jid jid) {
+ synchronized (this.bookmarks) {
+ this.bookmarks.remove(jid);
+ }
}
public Set<Jid> getBookmarkedJids() {
- final Set<Jid> jids = new HashSet<>();
- for (final Bookmark bookmark : this.bookmarks) {
- final Jid jid = bookmark.getJid();
- if (jid != null) {
- jids.add(jid.asBareJid());
- }
+ synchronized (this.bookmarks) {
+ return new HashSet<>(this.bookmarks.keySet());
}
- return jids;
}
- public boolean hasBookmarkFor(final Jid conferenceJid) {
- return getBookmark(conferenceJid) != null;
+ public boolean hasBookmarkFor(final Jid jid) {
+ synchronized (this.bookmarks) {
+ return this.bookmarks.containsKey(jid.asBareJid());
+ }
}
Bookmark getBookmark(final Jid jid) {
- for (final Bookmark bookmark : this.bookmarks) {
- if (bookmark.getJid() != null && jid.asBareJid().equals(bookmark.getJid().asBareJid())) {
- return bookmark;
- }
+ synchronized (this.bookmarks) {
+ return this.bookmarks.get(jid.asBareJid());
}
- return null;
}
public boolean setAvatar(final String filename) {
diff --git a/src/main/java/de/pixart/messenger/entities/Bookmark.java b/src/main/java/de/pixart/messenger/entities/Bookmark.java
index c7f33af3e..d017eefed 100644
--- a/src/main/java/de/pixart/messenger/entities/Bookmark.java
+++ b/src/main/java/de/pixart/messenger/entities/Bookmark.java
@@ -7,11 +7,11 @@ import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import de.pixart.messenger.utils.Namespace;
import de.pixart.messenger.utils.StringUtils;
@@ -38,43 +38,43 @@ public class Bookmark extends Element implements ListItem {
this.account = account;
}
- public static Collection<Bookmark> parseFromStorage(Element storage, Account account) {
+ public static Map<Jid, Bookmark> parseFromStorage(Element storage, Account account) {
if (storage == null) {
- return Collections.emptyList();
+ return Collections.emptyMap();
}
final HashMap<Jid, Bookmark> bookmarks = new HashMap<>();
for (final Element item : storage.getChildren()) {
if (item.getName().equals("conference")) {
final Bookmark bookmark = Bookmark.parse(item, account);
if (bookmark != null) {
- final Bookmark old = bookmarks.put(bookmark.getJid(), bookmark);
+ final Bookmark old = bookmarks.put(bookmark.jid, bookmark);
if (old != null && old.getBookmarkName() != null && bookmark.getBookmarkName() == null) {
bookmark.setBookmarkName(old.getBookmarkName());
}
}
}
}
- return bookmarks.values();
+ return bookmarks;
}
- public static Collection<Bookmark> parseFromPubsub(Element pubsub, Account account) {
+ public static Map<Jid, Bookmark> parseFromPubsub(Element pubsub, Account account) {
if (pubsub == null) {
- return Collections.emptyList();
+ return Collections.emptyMap();
}
final Element items = pubsub.findChild("items");
if (items != null && Namespace.BOOKMARK.equals(items.getAttribute("node"))) {
- final List<Bookmark> bookmarks = new ArrayList<>();
+ final Map<Jid, Bookmark> bookmarks = new HashMap<>();
for (Element item : items.getChildren()) {
if (item.getName().equals("item")) {
final Bookmark bookmark = Bookmark.parseFromItem(item, account);
if (bookmark != null) {
- bookmarks.add(bookmark);
+ bookmarks.put(bookmark.jid, bookmark);
}
}
}
return bookmarks;
}
- return Collections.emptyList();
+ return Collections.emptyMap();
}
public static Bookmark parse(Element element, Account account) {
diff --git a/src/main/java/de/pixart/messenger/generator/IqGenerator.java b/src/main/java/de/pixart/messenger/generator/IqGenerator.java
index bb6355688..4e9edeac9 100644
--- a/src/main/java/de/pixart/messenger/generator/IqGenerator.java
+++ b/src/main/java/de/pixart/messenger/generator/IqGenerator.java
@@ -147,6 +147,7 @@ public class IqGenerator extends AbstractGenerator {
final Element pubsub = packet.addChild("pubsub", Namespace.PUBSUB);
final Element retract = pubsub.addChild("retract");
retract.setAttribute("node", node);
+ retract.setAttribute("notify", "true");
retract.addChild("item").setAttribute("id", id);
return packet;
}
diff --git a/src/main/java/de/pixart/messenger/parser/MessageParser.java b/src/main/java/de/pixart/messenger/parser/MessageParser.java
index 0fc7e8bac..8e96d9b6f 100644
--- a/src/main/java/de/pixart/messenger/parser/MessageParser.java
+++ b/src/main/java/de/pixart/messenger/parser/MessageParser.java
@@ -12,11 +12,11 @@ import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -319,14 +319,30 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
if (account.getXmppConnection().getFeatures().bookmarksConversion()) {
final Element i = items.findChild("item");
final Element storage = i == null ? null : i.findChild("storage", Namespace.BOOKMARKS);
- new Thread(() -> {
- Collection<Bookmark> bookmarks = Bookmark.parseFromStorage(storage, account);
- mXmppConnectionService.processBookmarksInitial(account, bookmarks, true);
- Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": processing bookmark PEP event");
- }).start();
+ Map<Jid, Bookmark> bookmarks = Bookmark.parseFromStorage(storage, account);
+ mXmppConnectionService.processBookmarksInitial(account, bookmarks, true);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": processing bookmark PEP event");
} else {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignoring bookmark PEP event because bookmark conversion was not detected");
}
+ } else if (Namespace.BOOKMARK.equals(node) && account.getJid().asBareJid().equals(from)) {
+ final Element item = items.findChild("item");
+ final Element retract = items.findChild("retract");
+ if (item != null) {
+ final Bookmark bookmark = Bookmark.parseFromItem(item, account);
+ if (bookmark != null) {
+ //TODO find conversation
+ account.putBookmark(bookmark);
+ //TODO handle autojoin
+ }
+ }
+ if (retract != null) {
+ final Jid id = InvalidJid.getNullForInvalid(retract.getAttributeAsJid("id"));
+ if (id != null) {
+ account.removeBookmark(id);
+ Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmark for " + id);
+ }
+ }
} else {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + " received pubsub notification for node=" + node);
}
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index 77f3bb78f..b47fbdf1b 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -1804,7 +1804,7 @@ public class XmppConnectionService extends Service {
if (response.getType() == IqPacket.TYPE.RESULT) {
final Element query1 = response.query();
final Element storage = query1.findChild("storage", "storage:bookmarks");
- Collection<Bookmark> bookmarks = Bookmark.parseFromStorage(storage, account);
+ Map<Jid, Bookmark> bookmarks = Bookmark.parseFromStorage(storage, account);
processBookmarksInitial(a, bookmarks, false);
} else {
Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": could not fetch bookmarks");
@@ -1820,17 +1820,17 @@ public class XmppConnectionService extends Service {
public void onIqPacketReceived(final Account account, final IqPacket response) {
if (response.getType() == IqPacket.TYPE.RESULT) {
final Element pubsub = response.findChild("pubsub", Namespace.PUBSUB);
- final Collection<Bookmark> bookmarks = Bookmark.parseFromPubsub(pubsub, account);
+ final Map<Jid, Bookmark> bookmarks = Bookmark.parseFromPubsub(pubsub, account);
processBookmarksInitial(account, bookmarks, true);
}
}
});
}
- public void processBookmarksInitial(Account account, Collection<Bookmark> bookmarks, final boolean pep) {
+ public void processBookmarksInitial(Account account, Map<Jid, Bookmark> bookmarks, final boolean pep) {
final Set<Jid> previousBookmarks = account.getBookmarkedJids();
final boolean synchronizeWithBookmarks = synchronizeWithBookmarks();
- for (Bookmark bookmark : bookmarks) {
+ for (Bookmark bookmark : bookmarks.values()) {
previousBookmarks.remove(bookmark.getJid().asBareJid());
Conversation conversation = find(bookmark);
if (conversation != null) {
@@ -1857,10 +1857,11 @@ public class XmppConnectionService extends Service {
}
}
}
- account.setBookmarks(new CopyOnWriteArrayList<>(bookmarks));
+ account.setBookmarks(bookmarks);
}
public void createBookmark(final Account account, final Bookmark bookmark) {
+ account.putBookmark(bookmark);
final XmppConnection connection = account.getXmppConnection();
if (connection.getFeatures().bookmarks2()) {
final Element item = mIqGenerator.publishBookmarkItem(bookmark);
@@ -1873,6 +1874,7 @@ public class XmppConnectionService extends Service {
}
public void deleteBookmark(final Account account, final Bookmark bookmark) {
+ account.removeBookmark(bookmark);
final XmppConnection connection = account.getXmppConnection();
if (connection.getFeatures().bookmarksConversion()) {
IqPacket request = mIqGenerator.deleteItem(Namespace.BOOKMARK, bookmark.getJid().asBareJid().toEscapedString());
@@ -2358,12 +2360,11 @@ public class XmppConnectionService extends Service {
getMessageArchiveService().kill(conversation);
if (conversation.getMode() == Conversation.MODE_MULTI) {
if (conversation.getAccount().getStatus() == Account.State.ONLINE) {
- Bookmark bookmark = conversation.getBookmark();
+ final Bookmark bookmark = conversation.getBookmark();
if (maySynchronizeWithBookmarks && bookmark != null && synchronizeWithBookmarks()) {
if (conversation.getMucOptions().getError() == MucOptions.Error.DESTROYED) {
Account account = bookmark.getAccount();
bookmark.setConversation(null);
- account.getBookmarks().remove(bookmark);
deleteBookmark(account, bookmark);
} else if (bookmark.autojoin()) {
bookmark.setAutojoin(false);
@@ -4860,7 +4861,6 @@ public class XmppConnectionService extends Service {
bookmark.setBookmarkName(name);
}
bookmark.setAutojoin(getPreferences().getBoolean("autojoin", getResources().getBoolean(R.bool.autojoin)));
- account.getBookmarks().add(bookmark);
createBookmark(account, bookmark);
bookmark.setConversation(conversation);
}
diff --git a/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java b/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java
index 9e4cdc680..7d28edf13 100644
--- a/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ChannelDiscoveryActivity.java
@@ -235,7 +235,6 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O
} else {
bookmark = new Bookmark(account, conversation.getJid().asBareJid());
bookmark.setAutojoin(syncAutoJoin);
- account.getBookmarks().add(bookmark);
xmppConnectionService.createBookmark(account, bookmark);
}
switchToConversation(conversation);
diff --git a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
index 6fdd8c50a..297467558 100644
--- a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
@@ -3,11 +3,8 @@ package de.pixart.messenger.ui;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import androidx.databinding.DataBindingUtil;
import android.graphics.PorterDuff;
import android.os.Bundle;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.widget.Toolbar;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
@@ -18,6 +15,10 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.widget.Toolbar;
+import androidx.databinding.DataBindingUtil;
+
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -246,7 +247,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
final Bookmark bookmark = mConversation.getBookmark();
if (bookmark != null) {
bookmark.setAutojoin(this.binding.autojoinCheckbox.isChecked());
- xmppConnectionService.pushBookmarks(bookmark.getAccount());
+ xmppConnectionService.createBookmark(mConversation.getAccount(), bookmark);
updateView();
}
}
@@ -419,13 +420,10 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
protected void deleteBookmark() {
- Account account = mConversation.getAccount();
- Bookmark bookmark = mConversation.getBookmark();
- if (bookmark != null) {
- account.getBookmarks().remove(bookmark);
- bookmark.setConversation(null);
- }
- xmppConnectionService.pushBookmarks(account);
+ final Account account = mConversation.getAccount();
+ final Bookmark bookmark = mConversation.getBookmark();
+ bookmark.setConversation(null);
+ xmppConnectionService.deleteBookmark(account, bookmark);
updateView();
}
diff --git a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
index e34dacb2a..574995e36 100644
--- a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
@@ -471,8 +471,7 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
builder.setMessage(JidDialog.style(this, R.string.remove_bookmark_text, bookmark.getJid().toEscapedString()));
builder.setPositiveButton(R.string.delete, (dialog, which) -> {
bookmark.setConversation(null);
- Account account = bookmark.getAccount();
- account.getBookmarks().remove(bookmark);
+ final Account account = bookmark.getAccount();
xmppConnectionService.deleteBookmark(account, bookmark);
filter(mSearchEditText.getText().toString());
});
@@ -1023,7 +1022,6 @@ public class StartConversationActivity extends XmppActivity implements XmppConne
if (nick != null && !nick.isEmpty() && !nick.equals(MucOptions.defaultNick(account))) {
bookmark.setNick(nick);
}
- account.getBookmarks().add(bookmark);
xmppConnectionService.createBookmark(account, bookmark);
final Conversation conversation = xmppConnectionService
.findOrCreateConversation(account, conferenceJid, true, true, true);