From e2f886d121826df2a97d9f71bc7feab9f6dd52c2 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 14 Jul 2014 11:47:42 +0200 Subject: [PATCH] fetch bookmarks from server --- res/layout/join_conference_dialog.xml | 3 +- res/menu/conference_context.xml | 11 +++ res/values/strings.xml | 1 + .../siacs/conversations/entities/Account.java | 12 +++ .../conversations/entities/Bookmark.java | 94 +++++++++++++++++++ .../conversations/entities/Conversation.java | 6 ++ .../services/XmppConnectionService.java | 53 ++++++++++- .../conversations/ui/StartConversation.java | 91 +++++++++++++++--- 8 files changed, 254 insertions(+), 17 deletions(-) create mode 100644 res/menu/conference_context.xml create mode 100644 src/eu/siacs/conversations/entities/Bookmark.java diff --git a/res/layout/join_conference_dialog.xml b/res/layout/join_conference_dialog.xml index 2a0e300a2..431bf59e7 100644 --- a/res/layout/join_conference_dialog.xml +++ b/res/layout/join_conference_dialog.xml @@ -41,6 +41,7 @@ android:layout_marginTop="8dp" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@string/save_as_bookmark" /> + android:text="@string/save_as_bookmark" + android:checked="true" /> diff --git a/res/menu/conference_context.xml b/res/menu/conference_context.xml new file mode 100644 index 000000000..fd898580a --- /dev/null +++ b/res/menu/conference_context.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 417d838ef..9308bba11 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -267,4 +267,5 @@ Conference address room@conference.example.com Save as bookmark + Delete bookmark \ No newline at end of file diff --git a/src/eu/siacs/conversations/entities/Account.java b/src/eu/siacs/conversations/entities/Account.java index a73d49f91..20abddcd0 100644 --- a/src/eu/siacs/conversations/entities/Account.java +++ b/src/eu/siacs/conversations/entities/Account.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.entities; import java.security.interfaces.DSAPublicKey; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import net.java.otr4j.crypto.OtrCryptoEngineImpl; @@ -67,6 +69,8 @@ public class Account extends AbstractEntity{ private String otrFingerprint; private Roster roster = null; + + private List bookmarks = new ArrayList(); public Account() { this.uuid = "0"; @@ -297,4 +301,12 @@ public class Account extends AbstractEntity{ } return this.roster; } + + public void setBookmarks(List bookmarks) { + this.bookmarks = bookmarks; + } + + public List getBookmarks() { + return this.bookmarks; + } } diff --git a/src/eu/siacs/conversations/entities/Bookmark.java b/src/eu/siacs/conversations/entities/Bookmark.java new file mode 100644 index 000000000..1b97c5730 --- /dev/null +++ b/src/eu/siacs/conversations/entities/Bookmark.java @@ -0,0 +1,94 @@ +package eu.siacs.conversations.entities; + +import java.util.Locale; + +import eu.siacs.conversations.xml.Element; + +public class Bookmark implements ListItem { + + private Account account; + private String jid; + private String nick; + private String displayName; + private boolean autojoin; + + public Bookmark(Account account) { + this.account = account; + } + + public static Bookmark parse(Element element, Account account) { + Bookmark bookmark = new Bookmark(account); + bookmark.setJid(element.getAttribute("jid")); + bookmark.setDisplayName(element.getAttribute("name")); + String autojoin = element.getAttribute("autojoin"); + if (autojoin!=null && (autojoin.equals("true")||autojoin.equals("1"))) { + bookmark.setAutojoin(true); + } else { + bookmark.setAutojoin(false); + } + Element nick = element.findChild("nick"); + if (nick!=null) { + bookmark.setNick(nick.getContent()); + } + return bookmark; + } + + public void setAutojoin(boolean autojoin) { + this.autojoin = autojoin; + } + + public void setDisplayName(String name) { + this.displayName = name; + } + + public void setJid(String jid) { + this.jid = jid; + } + + public void setNick(String nick) { + this.nick = nick; + } + + @Override + public int compareTo(ListItem another) { + return this.getDisplayName().compareToIgnoreCase(another.getDisplayName()); + } + + @Override + public String getDisplayName() { + if (displayName!=null) { + return displayName; + } else { + return this.jid.split("@")[0]; + } + } + + @Override + public String getJid() { + return this.jid.toLowerCase(Locale.US); + } + + public String getNick() { + return this.nick; + } + + public boolean autojoin() { + return autojoin; + } + + @Override + public String getProfilePhoto() { + return null; + } + + public boolean match(String needle) { + return needle == null + || getJid().contains(needle.toLowerCase(Locale.US)) + || getDisplayName().toLowerCase(Locale.US) + .contains(needle.toLowerCase(Locale.US)); + } + + public Account getAccount() { + return this.account; + } +} diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index 23ab382f8..fbd87f3f6 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -64,6 +64,8 @@ public class Conversation extends AbstractEntity { private boolean otrSessionNeedsStarting = false; + private Bookmark bookmark; + public Conversation(String name, Account account, String contactJid, int mode) { this(java.util.UUID.randomUUID().toString(), name, null, account @@ -375,4 +377,8 @@ public class Conversation extends AbstractEntity { public byte[] getSymmetricKey() { return this.symmetricKey; } + + public void setBookmark(Bookmark bookmark) { + this.bookmark = bookmark; + } } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 0f90f725b..3fa263ab3 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -20,6 +20,7 @@ import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -245,9 +246,13 @@ public class XmppConnectionService extends Service { return message; } - public Conversation findMuc(String name, Account account) { + public Conversation findMuc(Bookmark bookmark) { + return findMuc(bookmark.getJid(), bookmark.getAccount()); + } + + public Conversation findMuc(String jid, Account account) { for (Conversation conversation : this.conversations) { - if (conversation.getContactJid().split("/")[0].equals(name) + if (conversation.getContactJid().split("/")[0].equals(jid) && (conversation.getAccount() == account)) { return conversation; } @@ -466,6 +471,7 @@ public class XmppConnectionService extends Service { account.getRoster().clearPresences(); account.clearPresences(); // self presences fetchRosterFromServer(account); + fetchBookmarks(account); sendPresencePacket(account, mPresenceGenerator.sendPresence(account)); connectMultiModeConversations(account); updateConversationUi(); @@ -660,6 +666,45 @@ public class XmppConnectionService extends Service { } }); } + + public void fetchBookmarks(Account account) { + IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); + Element query = iqPacket.query("jabber:iq:private"); + query.addChild("storage", "storage:bookmarks"); + OnIqPacketReceived callback = new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + Element query = packet.query(); + List bookmarks = new ArrayList(); + Element storage = query.findChild("storage", "storage:bookmarks"); + if (storage!=null) { + for(Element item : storage.getChildren()) { + if (item.getName().equals("conference")) { + Log.d(LOGTAG,item.toString()); + Bookmark bookmark = Bookmark.parse(item,account); + bookmarks.add(bookmark); + if (bookmark.autojoin()) { + Log.d(LOGTAG,"has autojoin"); + Conversation conversation = findMuc(bookmark); + if (conversation!=null) { + Log.d(LOGTAG,"conversation existed. adding bookmark"); + conversation.setBookmark(bookmark); + } else { + Log.d(LOGTAG,"creating new conversation"); + conversation = findOrCreateConversation(account, bookmark.getJid(), true); + conversation.setBookmark(bookmark); + } + } + } + } + } + account.setBookmarks(bookmarks); + } + }; + sendIqPacket(account, iqPacket, callback); + + } private void mergePhoneContactsWithRoster() { PhoneHelper.loadPhoneContacts(getApplicationContext(), @@ -1297,6 +1342,10 @@ public class XmppConnectionService extends Service { account.getXmppConnection().sendPresencePacket(packet); } + public void sendIqPacket(Account account, IqPacket packet, OnIqPacketReceived callback) { + account.getXmppConnection().sendIqPacket(packet, callback); + } + public MessageGenerator getMessageGenerator() { return this.mMessageGenerator; } diff --git a/src/eu/siacs/conversations/ui/StartConversation.java b/src/eu/siacs/conversations/ui/StartConversation.java index b37d2d07e..99b3385cd 100644 --- a/src/eu/siacs/conversations/ui/StartConversation.java +++ b/src/eu/siacs/conversations/ui/StartConversation.java @@ -37,6 +37,7 @@ import android.widget.Spinner; import android.widget.TextView; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.ListItem; @@ -63,6 +64,9 @@ public class StartConversation extends XmppActivity { private List mKnownConferenceHosts; private EditText mSearchEditText; + + public int conference_context_id; + public int contact_context_id; private TabListener mTabListener = new TabListener() { @@ -115,7 +119,7 @@ public class StartConversation extends XmppActivity { imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); mSearchEditText.setText(""); - filterContacts(null); + filter(null); return true; } }; @@ -123,7 +127,7 @@ public class StartConversation extends XmppActivity { @Override public void afterTextChanged(Editable editable) { - filterContacts(editable.toString()); + filter(editable.toString()); } @Override @@ -172,9 +176,19 @@ public class StartConversation extends XmppActivity { mConferenceAdapter = new ListItemAdapter(conferences); mConferenceListFragment.setListAdapter(mConferenceAdapter); + mConferenceListFragment.setContextMenu(R.menu.conference_context); + mConferenceListFragment.setOnListItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView arg0, View arg1, + int position, long arg3) { + openConversationForBookmark(position); + } + }); mContactsAdapter = new ListItemAdapter(contacts); mContactsListFragment.setListAdapter(mContactsAdapter); + mContactsListFragment.setContextMenu(R.menu.contact_context); mContactsListFragment .setOnListItemClickListener(new OnItemClickListener() { @@ -192,18 +206,35 @@ public class StartConversation extends XmppActivity { Conversation conversation = xmppConnectionService .findOrCreateConversation(contact.getAccount(), contact.getJid(), false); - switchToConversation(conversation, null, false); + switchToConversation(conversation); + } + + protected void openConversationForContact() { + int position = contact_context_id; + openConversationForContact(position); + } + + protected void openConversationForBookmark() { + openConversationForBookmark(conference_context_id); + } + + protected void openConversationForBookmark(int position) { + Bookmark bookmark = (Bookmark) conferences.get(position); + Conversation conversation = xmppConnectionService.findOrCreateConversation(bookmark.getAccount(), bookmark.getJid(), true); + switchToConversation(conversation); } - protected void openDetailsForContact(int position) { + protected void openDetailsForContact() { + int position = contact_context_id; Contact contact = (Contact) contacts.get(position); switchToContactDetails(contact); } - protected void deleteContact(int position) { + protected void deleteContact() { + int position = contact_context_id; Contact contact = (Contact) contacts.get(position); xmppConnectionService.deleteContactOnServer(contact); - filterContacts(mSearchEditText.getText().toString()); + filter(mSearchEditText.getText().toString()); } protected void showCreateContactDialog() { @@ -339,9 +370,9 @@ public class StartConversation extends XmppActivity { @Override void onBackendConnected() { if (mSearchEditText != null) { - filterContacts(mSearchEditText.getText().toString()); + filter(mSearchEditText.getText().toString()); } else { - filterContacts(null); + filter(null); } this.mActivatedAccounts.clear(); for (Account account : xmppConnectionService.getAccounts()) { @@ -353,6 +384,11 @@ public class StartConversation extends XmppActivity { this.mKnownConferenceHosts = xmppConnectionService .getKnownConferenceHosts(); } + + protected void filter(String needle) { + this.filterContacts(needle); + this.filterConferences(needle); + } protected void filterContacts(String needle) { this.contacts.clear(); @@ -368,6 +404,21 @@ public class StartConversation extends XmppActivity { Collections.sort(this.contacts); mContactsAdapter.notifyDataSetChanged(); } + + protected void filterConferences(String needle) { + this.conferences.clear(); + for (Account account : xmppConnectionService.getAccounts()) { + if (account.getStatus() != Account.STATUS_DISABLED) { + for(Bookmark bookmark : account.getBookmarks()) { + if (bookmark.match(needle)) { + this.conferences.add(bookmark); + } + } + } + } + Collections.sort(this.conferences); + mConferenceAdapter.notifyDataSetChanged(); + } private void onTabChanged() { invalidateOptionsMenu(); @@ -403,7 +454,11 @@ public class StartConversation extends XmppActivity { public static class MyListFragment extends ListFragment { private AdapterView.OnItemClickListener mOnItemClickListener; - private int mContextPosition = -1; + private int mResContextMenu; + + public void setContextMenu(int res) { + this.mResContextMenu = res; + } @Override public void onListItemClick(ListView l, View v, int position, long id) { @@ -426,10 +481,15 @@ public class StartConversation extends XmppActivity { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); - getActivity().getMenuInflater().inflate(R.menu.contact_context, + StartConversation activity = (StartConversation) getActivity(); + activity.getMenuInflater().inflate(mResContextMenu, menu); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; - this.mContextPosition = acmi.position; + if (mResContextMenu == R.menu.conference_context) { + activity.conference_context_id = acmi.position; + } else { + activity.contact_context_id = acmi.position; + } } @Override @@ -437,13 +497,16 @@ public class StartConversation extends XmppActivity { StartConversation activity = (StartConversation) getActivity(); switch (item.getItemId()) { case R.id.context_start_conversation: - activity.openConversationForContact(mContextPosition); + activity.openConversationForContact(); break; case R.id.context_contact_details: - activity.openDetailsForContact(mContextPosition); + activity.openDetailsForContact(); break; case R.id.context_delete_contact: - activity.deleteContact(mContextPosition); + activity.deleteContact(); + break; + case R.id.context_join_conference: + activity.openConversationForBookmark(); break; } return true;