mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 14:49:53 +01:00
Merge branch '373-slow-contact-list' into 'master'
Use new group metadata for showing lists What was supposed to be a minimal change turned into a rather large MR. I did my best to keep things in separate commits, so I can still split this into smaller MRs if desired. While making use of the new group metadata in the contact and forum list, I noticed some other things in need of improvement to get rid of needing to load all messages: * Refactor `SharingManager` so its events provide message headers that can be used to update list items * Add `GroupId` to conversation items, so the metadata of the respective group can be updated as well when marking the items read * Create a very basic `ConversationManager` so the GroupCount for the various clients can be queried in one go without needing to know all their groups per contact * Fix a nasty bug that caused forum and blog invitation to not update their read state * Fix some bugs related to displaying the forum list with proper unread count Some casual measurements with just a few contacts and messages showed a reduction of the contact list load time by one third. See merge request !343
This commit is contained in:
@@ -17,6 +17,7 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.forum.ForumModule;
|
import org.briarproject.forum.ForumModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
@@ -46,7 +47,8 @@ import dagger.Component;
|
|||||||
SharingModule.class,
|
SharingModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
TransportModule.class
|
TransportModule.class,
|
||||||
|
MessagingModule.class
|
||||||
})
|
})
|
||||||
interface BlogSharingIntegrationTestComponent {
|
interface BlogSharingIntegrationTestComponent {
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.forum.ForumModule;
|
import org.briarproject.forum.ForumModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
@@ -46,7 +47,8 @@ import dagger.Component;
|
|||||||
SharingModule.class,
|
SharingModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
TransportModule.class
|
TransportModule.class,
|
||||||
|
MessagingModule.class
|
||||||
})
|
})
|
||||||
interface ForumManagerTestComponent {
|
interface ForumManagerTestComponent {
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.forum.ForumModule;
|
import org.briarproject.forum.ForumModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
@@ -50,7 +51,8 @@ import dagger.Component;
|
|||||||
SharingModule.class,
|
SharingModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
TransportModule.class
|
TransportModule.class,
|
||||||
|
MessagingModule.class
|
||||||
})
|
})
|
||||||
interface ForumSharingIntegrationTestComponent {
|
interface ForumSharingIntegrationTestComponent {
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.briarproject.db.DatabaseModule;
|
|||||||
import org.briarproject.event.EventModule;
|
import org.briarproject.event.EventModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
import org.briarproject.system.SystemModule;
|
import org.briarproject.system.SystemModule;
|
||||||
@@ -46,7 +47,8 @@ import dagger.Component;
|
|||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
DataModule.class,
|
DataModule.class,
|
||||||
PropertiesModule.class
|
PropertiesModule.class,
|
||||||
|
MessagingModule.class
|
||||||
})
|
})
|
||||||
public interface IntroductionIntegrationTestComponent {
|
public interface IntroductionIntegrationTestComponent {
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.briarproject.api.keyagreement.PayloadEncoder;
|
|||||||
import org.briarproject.api.keyagreement.PayloadParser;
|
import org.briarproject.api.keyagreement.PayloadParser;
|
||||||
import org.briarproject.api.lifecycle.IoExecutor;
|
import org.briarproject.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
import org.briarproject.api.messaging.MessagingManager;
|
import org.briarproject.api.messaging.MessagingManager;
|
||||||
import org.briarproject.api.messaging.PrivateMessageFactory;
|
import org.briarproject.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.api.plugins.ConnectionRegistry;
|
import org.briarproject.api.plugins.ConnectionRegistry;
|
||||||
@@ -86,6 +87,8 @@ public interface AndroidComponent extends CoreEagerSingletons {
|
|||||||
|
|
||||||
ContactManager contactManager();
|
ContactManager contactManager();
|
||||||
|
|
||||||
|
ConversationManager conversationManager();
|
||||||
|
|
||||||
MessagingManager messagingManager();
|
MessagingManager messagingManager();
|
||||||
|
|
||||||
PrivateMessageFactory privateMessageFactory();
|
PrivateMessageFactory privateMessageFactory();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import org.briarproject.api.event.ForumPostReceivedEvent;
|
|||||||
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.IntroductionSucceededEvent;
|
import org.briarproject.api.event.IntroductionSucceededEvent;
|
||||||
import org.briarproject.api.event.InvitationReceivedEvent;
|
import org.briarproject.api.event.InvitationRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.PrivateMessageReceivedEvent;
|
import org.briarproject.api.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.api.event.SettingsUpdatedEvent;
|
import org.briarproject.api.event.SettingsUpdatedEvent;
|
||||||
@@ -235,8 +235,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
ContactId c = ((IntroductionResponseReceivedEvent) e).getContactId();
|
ContactId c = ((IntroductionResponseReceivedEvent) e).getContactId();
|
||||||
showNotificationForPrivateConversation(c);
|
showNotificationForPrivateConversation(c);
|
||||||
} else if (e instanceof InvitationReceivedEvent) {
|
} else if (e instanceof InvitationRequestReceivedEvent) {
|
||||||
ContactId c = ((InvitationReceivedEvent) e).getContactId();
|
ContactId c = ((InvitationRequestReceivedEvent) e).getContactId();
|
||||||
showNotificationForPrivateConversation(c);
|
showNotificationForPrivateConversation(c);
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
} else if (e instanceof InvitationResponseReceivedEvent) {
|
||||||
ContactId c = ((InvitationResponseReceivedEvent) e).getContactId();
|
ContactId c = ((InvitationResponseReceivedEvent) e).getContactId();
|
||||||
|
|||||||
@@ -50,10 +50,8 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (item.getGroupId() != null) {
|
ViewCompat.setTransitionName(ui.avatar, "avatar" +
|
||||||
ViewCompat.setTransitionName(ui.avatar, "avatar" +
|
StringUtils.toHexString(item.getGroupId().getBytes()));
|
||||||
StringUtils.toHexString(item.getGroupId().getBytes()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -96,8 +94,9 @@ public abstract class BaseContactListAdapter<VH extends BaseContactListAdapter.B
|
|||||||
int count = getItemCount();
|
int count = getItemCount();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
ContactListItem item = getItemAt(i);
|
ContactListItem item = getItemAt(i);
|
||||||
if (item != null && item.getGroupId().equals(g))
|
if (item != null && item.getGroupId().equals(g)) {
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return INVALID_POSITION; // Not found
|
return INVALID_POSITION; // Not found
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,12 @@ import org.briarproject.android.api.AndroidNotificationManager;
|
|||||||
import org.briarproject.android.fragment.BaseFragment;
|
import org.briarproject.android.fragment.BaseFragment;
|
||||||
import org.briarproject.android.keyagreement.KeyAgreementActivity;
|
import org.briarproject.android.keyagreement.KeyAgreementActivity;
|
||||||
import org.briarproject.android.view.BriarRecyclerView;
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.NoSuchContactException;
|
import org.briarproject.api.db.NoSuchContactException;
|
||||||
import org.briarproject.api.event.ContactAddedEvent;
|
|
||||||
import org.briarproject.api.event.ContactConnectedEvent;
|
import org.briarproject.api.event.ContactConnectedEvent;
|
||||||
import org.briarproject.api.event.ContactDisconnectedEvent;
|
import org.briarproject.api.event.ContactDisconnectedEvent;
|
||||||
import org.briarproject.api.event.ContactRemovedEvent;
|
import org.briarproject.api.event.ContactRemovedEvent;
|
||||||
@@ -37,24 +36,21 @@ import org.briarproject.api.event.EventBus;
|
|||||||
import org.briarproject.api.event.EventListener;
|
import org.briarproject.api.event.EventListener;
|
||||||
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.InvitationReceivedEvent;
|
import org.briarproject.api.event.InvitationRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.PrivateMessageReceivedEvent;
|
import org.briarproject.api.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.api.forum.ForumSharingManager;
|
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.introduction.IntroductionManager;
|
|
||||||
import org.briarproject.api.introduction.IntroductionMessage;
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
import org.briarproject.api.introduction.IntroductionRequest;
|
||||||
import org.briarproject.api.introduction.IntroductionResponse;
|
import org.briarproject.api.introduction.IntroductionResponse;
|
||||||
import org.briarproject.api.messaging.MessagingManager;
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
import org.briarproject.api.messaging.PrivateMessageHeader;
|
||||||
import org.briarproject.api.plugins.ConnectionRegistry;
|
import org.briarproject.api.plugins.ConnectionRegistry;
|
||||||
import org.briarproject.api.sharing.InvitationMessage;
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
|
import org.briarproject.api.sharing.InvitationResponse;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -88,13 +84,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
@Inject
|
@Inject
|
||||||
protected volatile IdentityManager identityManager;
|
protected volatile IdentityManager identityManager;
|
||||||
@Inject
|
@Inject
|
||||||
protected volatile MessagingManager messagingManager;
|
protected volatile ConversationManager conversationManager;
|
||||||
@Inject
|
|
||||||
protected volatile IntroductionManager introductionManager;
|
|
||||||
@Inject
|
|
||||||
protected volatile ForumSharingManager forumSharingManager;
|
|
||||||
@Inject
|
|
||||||
protected volatile BlogSharingManager blogSharingManager;
|
|
||||||
|
|
||||||
public static ContactListFragment newInstance() {
|
public static ContactListFragment newInstance() {
|
||||||
|
|
||||||
@@ -130,7 +120,6 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
new ContactListAdapter.OnItemClickListener() {
|
new ContactListAdapter.OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(View view, ContactListItem item) {
|
public void onItemClick(View view, ContactListItem item) {
|
||||||
|
|
||||||
GroupId groupId = item.getGroupId();
|
GroupId groupId = item.getGroupId();
|
||||||
Intent i = new Intent(getActivity(),
|
Intent i = new Intent(getActivity(),
|
||||||
ConversationActivity.class);
|
ConversationActivity.class);
|
||||||
@@ -215,15 +204,15 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
try {
|
try {
|
||||||
ContactId id = c.getId();
|
ContactId id = c.getId();
|
||||||
GroupId groupId =
|
GroupId groupId =
|
||||||
messagingManager.getConversationId(id);
|
conversationManager.getConversationId(id);
|
||||||
Collection<ConversationItem> messages =
|
GroupCount count =
|
||||||
getMessages(id);
|
conversationManager.getGroupCount(id);
|
||||||
boolean connected =
|
boolean connected =
|
||||||
connectionRegistry.isConnected(c.getId());
|
connectionRegistry.isConnected(c.getId());
|
||||||
LocalAuthor localAuthor = identityManager
|
LocalAuthor localAuthor = identityManager
|
||||||
.getLocalAuthor(c.getLocalAuthorId());
|
.getLocalAuthor(c.getLocalAuthorId());
|
||||||
contacts.add(new ContactListItem(c, localAuthor,
|
contacts.add(new ContactListItem(c, localAuthor,
|
||||||
connected, groupId, messages));
|
connected, groupId, count));
|
||||||
} catch (NoSuchContactException e) {
|
} catch (NoSuchContactException e) {
|
||||||
// Continue
|
// Continue
|
||||||
}
|
}
|
||||||
@@ -252,14 +241,9 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof ContactAddedEvent) {
|
if (e instanceof ContactStatusChangedEvent) {
|
||||||
if (((ContactAddedEvent) e).isActive()) {
|
|
||||||
LOG.info("Contact added as active, reloading");
|
|
||||||
loadContacts();
|
|
||||||
}
|
|
||||||
} else if (e instanceof ContactStatusChangedEvent) {
|
|
||||||
LOG.info("Contact Status changed, reloading");
|
LOG.info("Contact Status changed, reloading");
|
||||||
// TODO We can update the contact state without needing to reload
|
// is also broadcast when contact was added
|
||||||
loadContacts();
|
loadContacts();
|
||||||
} else if (e instanceof ContactConnectedEvent) {
|
} else if (e instanceof ContactConnectedEvent) {
|
||||||
setConnected(((ContactConnectedEvent) e).getContactId(), true);
|
setConnected(((ContactConnectedEvent) e).getContactId(), true);
|
||||||
@@ -285,50 +269,20 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
(IntroductionResponseReceivedEvent) e;
|
(IntroductionResponseReceivedEvent) e;
|
||||||
IntroductionResponse ir = m.getIntroductionResponse();
|
IntroductionResponse ir = m.getIntroductionResponse();
|
||||||
updateItem(m.getContactId(), ConversationItem.from(ir));
|
updateItem(m.getContactId(), ConversationItem.from(ir));
|
||||||
} else if (e instanceof InvitationReceivedEvent) {
|
} else if (e instanceof InvitationRequestReceivedEvent) {
|
||||||
LOG.info("Invitation received, reloading conversation...");
|
LOG.info("Invitation Request received, update contact");
|
||||||
InvitationReceivedEvent m = (InvitationReceivedEvent) e;
|
InvitationRequestReceivedEvent m = (InvitationRequestReceivedEvent) e;
|
||||||
reloadConversation(m.getContactId());
|
InvitationRequest ir = m.getRequest();
|
||||||
|
updateItem(m.getContactId(), ConversationItem.from(ir));
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
} else if (e instanceof InvitationResponseReceivedEvent) {
|
||||||
LOG.info("Invitation Response received, reloading ...");
|
LOG.info("Invitation Response received, update contact");
|
||||||
InvitationResponseReceivedEvent m =
|
InvitationResponseReceivedEvent m =
|
||||||
(InvitationResponseReceivedEvent) e;
|
(InvitationResponseReceivedEvent) e;
|
||||||
reloadConversation(m.getContactId());
|
InvitationResponse ir = m.getResponse();
|
||||||
|
updateItem(m.getContactId(), ConversationItem.from(ir));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadConversation(final ContactId c) {
|
|
||||||
listener.runOnDbThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Collection<ConversationItem> messages = getMessages(c);
|
|
||||||
updateItem(c, messages);
|
|
||||||
} catch (NoSuchContactException e) {
|
|
||||||
LOG.info("Contact removed");
|
|
||||||
} catch (DbException e) {
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateItem(final ContactId c,
|
|
||||||
final Collection<ConversationItem> messages) {
|
|
||||||
listener.runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int position = adapter.findItemPosition(c);
|
|
||||||
ContactListItem item = adapter.getItemAt(position);
|
|
||||||
if (item != null) {
|
|
||||||
item.setMessages(messages);
|
|
||||||
adapter.updateItemAt(position, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateItem(final ContactId c, final ConversationItem m) {
|
private void updateItem(final ContactId c, final ConversationItem m) {
|
||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -382,50 +336,4 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to be called from the DB thread
|
|
||||||
// Do not call getActivty() here as it might return null
|
|
||||||
private Collection<ConversationItem> getMessages(ContactId id)
|
|
||||||
throws DbException {
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
Collection<ConversationItem> messages = new ArrayList<>();
|
|
||||||
|
|
||||||
Collection<PrivateMessageHeader> headers =
|
|
||||||
messagingManager.getMessageHeaders(id);
|
|
||||||
for (PrivateMessageHeader h : headers) {
|
|
||||||
messages.add(ConversationItem.from(h));
|
|
||||||
}
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading message headers took " + duration + " ms");
|
|
||||||
|
|
||||||
now = System.currentTimeMillis();
|
|
||||||
Collection<IntroductionMessage> introductions =
|
|
||||||
introductionManager
|
|
||||||
.getIntroductionMessages(id);
|
|
||||||
for (IntroductionMessage m : introductions) {
|
|
||||||
messages.add(ConversationItem.from(m));
|
|
||||||
}
|
|
||||||
duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading introduction messages took " + duration + " ms");
|
|
||||||
|
|
||||||
now = System.currentTimeMillis();
|
|
||||||
Collection<InvitationMessage> forumInvitations =
|
|
||||||
forumSharingManager.getInvitationMessages(id);
|
|
||||||
for (InvitationMessage i : forumInvitations) {
|
|
||||||
messages.add(ConversationItem.from(i));
|
|
||||||
}
|
|
||||||
Collection<InvitationMessage> blogInvitations =
|
|
||||||
blogSharingManager.getInvitationMessages(id);
|
|
||||||
for (InvitationMessage i : blogInvitations) {
|
|
||||||
messages.add(ConversationItem.from(i));
|
|
||||||
}
|
|
||||||
duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading invitations took " + duration + " ms");
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import static org.briarproject.android.contact.ConversationItem.IncomingItem;
|
import static org.briarproject.android.contact.ConversationItem.IncomingItem;
|
||||||
|
|
||||||
// This class is not thread-safe
|
// This class is NOT thread-safe
|
||||||
public class ContactListItem {
|
public class ContactListItem {
|
||||||
|
|
||||||
private final Contact contact;
|
private final Contact contact;
|
||||||
@@ -18,26 +18,16 @@ public class ContactListItem {
|
|||||||
private long timestamp;
|
private long timestamp;
|
||||||
private int unread;
|
private int unread;
|
||||||
|
|
||||||
public ContactListItem(Contact contact, LocalAuthor localAuthor,
|
public ContactListItem(@NotNull Contact contact,
|
||||||
boolean connected,
|
@NotNull LocalAuthor localAuthor, boolean connected,
|
||||||
GroupId groupId,
|
@NotNull GroupId groupId, @NotNull GroupCount count) {
|
||||||
Collection<ConversationItem> messages) {
|
|
||||||
this.contact = contact;
|
this.contact = contact;
|
||||||
this.localAuthor = localAuthor;
|
this.localAuthor = localAuthor;
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
this.connected = connected;
|
this.connected = connected;
|
||||||
setMessages(messages);
|
this.empty = count.getMsgCount() == 0;
|
||||||
}
|
this.unread = count.getUnreadCount();
|
||||||
|
this.timestamp = count.getLatestMsgTime();
|
||||||
void setMessages(Collection<ConversationItem> messages) {
|
|
||||||
empty = messages == null || messages.isEmpty();
|
|
||||||
timestamp = 0;
|
|
||||||
unread = 0;
|
|
||||||
if (!empty) {
|
|
||||||
for (ConversationItem i : messages) {
|
|
||||||
addMessage(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMessage(ConversationItem message) {
|
void addMessage(ConversationItem message) {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import org.briarproject.android.view.TextInputView;
|
|||||||
import org.briarproject.android.view.TextInputView.TextInputListener;
|
import org.briarproject.android.view.TextInputView.TextInputListener;
|
||||||
import org.briarproject.api.FormatException;
|
import org.briarproject.api.FormatException;
|
||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
import org.briarproject.api.blogs.BlogSharingManager;
|
||||||
|
import org.briarproject.api.clients.BaseMessageHeader;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
@@ -50,7 +51,7 @@ import org.briarproject.api.event.EventBus;
|
|||||||
import org.briarproject.api.event.EventListener;
|
import org.briarproject.api.event.EventListener;
|
||||||
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.InvitationReceivedEvent;
|
import org.briarproject.api.event.InvitationRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.MessagesAckedEvent;
|
import org.briarproject.api.event.MessagesAckedEvent;
|
||||||
import org.briarproject.api.event.MessagesSentEvent;
|
import org.briarproject.api.event.MessagesSentEvent;
|
||||||
@@ -76,7 +77,7 @@ import org.briarproject.util.StringUtils;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -476,28 +477,28 @@ public class ConversationActivity extends BriarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void markMessagesRead() {
|
private void markMessagesRead() {
|
||||||
List<MessageId> unread = new ArrayList<>();
|
Map<MessageId, GroupId> unread = new HashMap<>();
|
||||||
SparseArray<IncomingItem> list = adapter.getIncomingMessages();
|
SparseArray<IncomingItem> list = adapter.getIncomingMessages();
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
IncomingItem item = list.valueAt(i);
|
IncomingItem item = list.valueAt(i);
|
||||||
if (!item.isRead()) unread.add(item.getId());
|
if (!item.isRead())
|
||||||
|
unread.put(item.getId(), item.getGroupId());
|
||||||
}
|
}
|
||||||
if (unread.isEmpty()) return;
|
if (unread.isEmpty()) return;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Marking " + unread.size() + " messages read");
|
LOG.info("Marking " + unread.size() + " messages read");
|
||||||
markMessagesRead(Collections.unmodifiableList(unread));
|
markMessagesRead(unread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markMessagesRead(final Collection<MessageId> unread) {
|
private void markMessagesRead(final Map<MessageId, GroupId> unread) {
|
||||||
runOnDbThread(new Runnable() {
|
runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
for (MessageId m : unread)
|
for (Map.Entry<MessageId, GroupId> e : unread.entrySet())
|
||||||
// not really clean, but the messaging manager can
|
messagingManager
|
||||||
// handle introduction messages as well
|
.setReadFlag(e.getValue(), e.getKey(), true);
|
||||||
messagingManager.setReadFlag(groupId, m, true);
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Marking read took " + duration + " ms");
|
LOG.info("Marking read took " + duration + " ms");
|
||||||
@@ -560,6 +561,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
IntroductionRequest ir = event.getIntroductionRequest();
|
IntroductionRequest ir = event.getIntroductionRequest();
|
||||||
ConversationItem item = new ConversationIntroductionInItem(ir);
|
ConversationItem item = new ConversationIntroductionInItem(ir);
|
||||||
addConversationItem(item);
|
addConversationItem(item);
|
||||||
|
markMessageReadIfNew(ir);
|
||||||
}
|
}
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
IntroductionResponseReceivedEvent event =
|
IntroductionResponseReceivedEvent event =
|
||||||
@@ -570,25 +572,33 @@ public class ConversationActivity extends BriarActivity
|
|||||||
ConversationItem item =
|
ConversationItem item =
|
||||||
ConversationItem.from(this, contactName, ir);
|
ConversationItem.from(this, contactName, ir);
|
||||||
addConversationItem(item);
|
addConversationItem(item);
|
||||||
|
markMessageReadIfNew(ir);
|
||||||
}
|
}
|
||||||
} else if (e instanceof InvitationReceivedEvent) {
|
} else if (e instanceof InvitationRequestReceivedEvent) {
|
||||||
InvitationReceivedEvent event =
|
InvitationRequestReceivedEvent event =
|
||||||
(InvitationReceivedEvent) e;
|
(InvitationRequestReceivedEvent) e;
|
||||||
if (event.getContactId().equals(contactId)) {
|
if (event.getContactId().equals(contactId)) {
|
||||||
LOG.info("Invitation received, reloading...");
|
LOG.info("Invitation received, adding...");
|
||||||
loadMessages();
|
InvitationRequest ir = event.getRequest();
|
||||||
|
ConversationItem item = ConversationItem.from(ir);
|
||||||
|
addConversationItem(item);
|
||||||
|
markMessageReadIfNew(ir);
|
||||||
}
|
}
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
} else if (e instanceof InvitationResponseReceivedEvent) {
|
||||||
InvitationResponseReceivedEvent event =
|
InvitationResponseReceivedEvent event =
|
||||||
(InvitationResponseReceivedEvent) e;
|
(InvitationResponseReceivedEvent) e;
|
||||||
if (event.getContactId().equals(contactId)) {
|
if (event.getContactId().equals(contactId)) {
|
||||||
LOG.info("Invitation response received, reloading...");
|
LOG.info("Invitation response received, adding...");
|
||||||
loadMessages();
|
InvitationResponse ir = event.getResponse();
|
||||||
|
ConversationItem item =
|
||||||
|
ConversationItem.from(this, contactName, ir);
|
||||||
|
addConversationItem(item);
|
||||||
|
markMessageReadIfNew(ir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markMessageReadIfNew(final PrivateMessageHeader h) {
|
private void markMessageReadIfNew(final BaseMessageHeader h) {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -597,22 +607,23 @@ public class ConversationActivity extends BriarActivity
|
|||||||
// Mark the message read if it's the newest message
|
// Mark the message read if it's the newest message
|
||||||
long lastMsgTime = item.getTime();
|
long lastMsgTime = item.getTime();
|
||||||
long newMsgTime = h.getTimestamp();
|
long newMsgTime = h.getTimestamp();
|
||||||
if (newMsgTime > lastMsgTime) markNewMessageRead(h.getId());
|
if (newMsgTime > lastMsgTime)
|
||||||
|
markNewMessageRead(h.getGroupId(), h.getId());
|
||||||
else loadMessages();
|
else loadMessages();
|
||||||
} else {
|
} else {
|
||||||
// mark the message as read as well if it is the first one
|
// mark the message as read as well if it is the first one
|
||||||
markNewMessageRead(h.getId());
|
markNewMessageRead(h.getGroupId(), h.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markNewMessageRead(final MessageId m) {
|
private void markNewMessageRead(final GroupId g, final MessageId m) {
|
||||||
runOnDbThread(new Runnable() {
|
runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
messagingManager.setReadFlag(groupId, m, true);
|
messagingManager.setReadFlag(g, m, true);
|
||||||
loadMessages();
|
loadMessages();
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
@@ -681,11 +692,10 @@ public class ConversationActivity extends BriarActivity
|
|||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Storing message took " + duration + " ms");
|
LOG.info("Storing message took " + duration + " ms");
|
||||||
|
|
||||||
MessageId id = m.getMessage().getId();
|
MessageId id = m.getMessage().getId();
|
||||||
PrivateMessageHeader h = new PrivateMessageHeader(id,
|
PrivateMessageHeader h = new PrivateMessageHeader(id,
|
||||||
m.getMessage().getTimestamp(), m.getContentType(),
|
groupId, m.getMessage().getTimestamp(),
|
||||||
true, false, false, false);
|
m.getContentType(), true, false, false, false);
|
||||||
ConversationMessageItem item = ConversationItem.from(h);
|
ConversationMessageItem item = ConversationItem.from(h);
|
||||||
item.setBody(body);
|
item.setBody(body);
|
||||||
bodyCache.put(id, body);
|
bodyCache.put(id, body);
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.android.contact.ConversationItem.IncomingItem;
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
import org.briarproject.api.introduction.IntroductionRequest;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
// This class is not thread-safe
|
// This class is not thread-safe
|
||||||
class ConversationIntroductionInItem extends ConversationIntroductionItem
|
class ConversationIntroductionInItem extends ConversationIntroductionItem
|
||||||
implements ConversationItem.IncomingItem {
|
implements IncomingItem {
|
||||||
|
|
||||||
private boolean read;
|
private boolean read;
|
||||||
|
|
||||||
ConversationIntroductionInItem(IntroductionRequest ir) {
|
ConversationIntroductionInItem(@NotNull IntroductionRequest ir) {
|
||||||
super(ir);
|
super(ir);
|
||||||
|
|
||||||
this.read = ir.isRead();
|
this.read = ir.isRead();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
import org.briarproject.api.introduction.IntroductionRequest;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
// This class is not thread-safe
|
// This class is not thread-safe
|
||||||
abstract class ConversationIntroductionItem extends ConversationItem {
|
abstract class ConversationIntroductionItem extends ConversationItem {
|
||||||
@@ -8,13 +9,14 @@ abstract class ConversationIntroductionItem extends ConversationItem {
|
|||||||
private final IntroductionRequest ir;
|
private final IntroductionRequest ir;
|
||||||
private boolean answered;
|
private boolean answered;
|
||||||
|
|
||||||
ConversationIntroductionItem(IntroductionRequest ir) {
|
ConversationIntroductionItem(@NotNull IntroductionRequest ir) {
|
||||||
super(ir.getMessageId(), ir.getTimestamp());
|
super(ir.getMessageId(), ir.getGroupId(), ir.getTimestamp());
|
||||||
|
|
||||||
this.ir = ir;
|
this.ir = ir;
|
||||||
this.answered = ir.wasAnswered();
|
this.answered = ir.wasAnswered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
IntroductionRequest getIntroductionRequest() {
|
IntroductionRequest getIntroductionRequest() {
|
||||||
return ir;
|
return ir;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import org.briarproject.api.messaging.PrivateMessageHeader;
|
|||||||
import org.briarproject.api.sharing.InvitationMessage;
|
import org.briarproject.api.sharing.InvitationMessage;
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
import org.briarproject.api.sharing.InvitationResponse;
|
import org.briarproject.api.sharing.InvitationResponse;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
// This class is not thread-safe
|
// This class is not thread-safe
|
||||||
public abstract class ConversationItem {
|
public abstract class ConversationItem {
|
||||||
@@ -30,20 +32,29 @@ public abstract class ConversationItem {
|
|||||||
final static int BLOG_INVITATION_IN = 9;
|
final static int BLOG_INVITATION_IN = 9;
|
||||||
final static int BLOG_INVITATION_OUT = 10;
|
final static int BLOG_INVITATION_OUT = 10;
|
||||||
|
|
||||||
private MessageId id;
|
final private MessageId id;
|
||||||
private long time;
|
final private GroupId groupId;
|
||||||
|
final private long time;
|
||||||
|
|
||||||
public ConversationItem(MessageId id, long time) {
|
public ConversationItem(@NotNull MessageId id, @NotNull GroupId groupId,
|
||||||
|
long time) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.groupId = groupId;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract int getType();
|
abstract int getType();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public MessageId getId() {
|
public MessageId getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public GroupId getGroupId() {
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
long getTime() {
|
long getTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
@@ -78,8 +89,9 @@ public abstract class ConversationItem {
|
|||||||
R.string.introduction_response_declined_sent,
|
R.string.introduction_response_declined_sent,
|
||||||
ir.getName());
|
ir.getName());
|
||||||
}
|
}
|
||||||
return new ConversationNoticeOutItem(ir.getMessageId(), text,
|
return new ConversationNoticeOutItem(ir.getMessageId(),
|
||||||
ir.getTimestamp(), ir.isSent(), ir.isSeen());
|
ir.getGroupId(), text, ir.getTimestamp(), ir.isSent(),
|
||||||
|
ir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
String text;
|
String text;
|
||||||
if (ir.wasAccepted()) {
|
if (ir.wasAccepted()) {
|
||||||
@@ -97,8 +109,8 @@ public abstract class ConversationItem {
|
|||||||
contactName, ir.getName());
|
contactName, ir.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ConversationNoticeInItem(ir.getMessageId(), text,
|
return new ConversationNoticeInItem(ir.getMessageId(),
|
||||||
ir.getTimestamp(), ir.isRead());
|
ir.getGroupId(), text, ir.getTimestamp(), ir.isRead());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +149,8 @@ public abstract class ConversationItem {
|
|||||||
R.string.forum_invitation_response_declined_sent,
|
R.string.forum_invitation_response_declined_sent,
|
||||||
contactName);
|
contactName);
|
||||||
}
|
}
|
||||||
return new ConversationNoticeOutItem(fir.getId(), text,
|
return new ConversationNoticeOutItem(fir.getId(), fir.getGroupId(),
|
||||||
fir.getTimestamp(), fir.isSent(), fir.isSeen());
|
text, fir.getTimestamp(), fir.isSent(), fir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
String text;
|
String text;
|
||||||
if (fir.wasAccepted()) {
|
if (fir.wasAccepted()) {
|
||||||
@@ -150,8 +162,8 @@ public abstract class ConversationItem {
|
|||||||
R.string.forum_invitation_response_declined_received,
|
R.string.forum_invitation_response_declined_received,
|
||||||
contactName);
|
contactName);
|
||||||
}
|
}
|
||||||
return new ConversationNoticeInItem(fir.getId(), text,
|
return new ConversationNoticeInItem(fir.getId(), fir.getGroupId(),
|
||||||
fir.getTimestamp(), fir.isRead());
|
text, fir.getTimestamp(), fir.isRead());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +181,8 @@ public abstract class ConversationItem {
|
|||||||
R.string.blogs_sharing_response_declined_sent,
|
R.string.blogs_sharing_response_declined_sent,
|
||||||
contactName);
|
contactName);
|
||||||
}
|
}
|
||||||
return new ConversationNoticeOutItem(fir.getId(), text,
|
return new ConversationNoticeOutItem(fir.getId(), fir.getGroupId(),
|
||||||
fir.getTimestamp(), fir.isSent(), fir.isSeen());
|
text, fir.getTimestamp(), fir.isSent(), fir.isSeen());
|
||||||
} else {
|
} else {
|
||||||
String text;
|
String text;
|
||||||
if (fir.wasAccepted()) {
|
if (fir.wasAccepted()) {
|
||||||
@@ -182,8 +194,8 @@ public abstract class ConversationItem {
|
|||||||
R.string.blogs_sharing_response_declined_received,
|
R.string.blogs_sharing_response_declined_received,
|
||||||
contactName);
|
contactName);
|
||||||
}
|
}
|
||||||
return new ConversationNoticeInItem(fir.getId(), text,
|
return new ConversationNoticeInItem(fir.getId(), fir.getGroupId(),
|
||||||
fir.getTimestamp(), fir.isRead());
|
text, fir.getTimestamp(), fir.isRead());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,10 +205,10 @@ public abstract class ConversationItem {
|
|||||||
*/
|
*/
|
||||||
public static ConversationItem from(IntroductionMessage im) {
|
public static ConversationItem from(IntroductionMessage im) {
|
||||||
if (im.isLocal())
|
if (im.isLocal())
|
||||||
return new ConversationNoticeOutItem(im.getMessageId(), "",
|
return new ConversationNoticeOutItem(im.getMessageId(),
|
||||||
im.getTimestamp(), false, false);
|
im.getGroupId(), "", im.getTimestamp(), false, false);
|
||||||
return new ConversationNoticeInItem(im.getMessageId(), "",
|
return new ConversationNoticeInItem(im.getMessageId(), im.getGroupId(),
|
||||||
im.getTimestamp(), im.isRead());
|
"", im.getTimestamp(), im.isRead());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,14 +217,15 @@ public abstract class ConversationItem {
|
|||||||
*/
|
*/
|
||||||
public static ConversationItem from(InvitationMessage im) {
|
public static ConversationItem from(InvitationMessage im) {
|
||||||
if (im.isLocal())
|
if (im.isLocal())
|
||||||
return new ConversationNoticeOutItem(im.getId(), "",
|
return new ConversationNoticeOutItem(im.getId(), im.getGroupId(),
|
||||||
im.getTimestamp(), false, false);
|
"", im.getTimestamp(), false, false);
|
||||||
return new ConversationNoticeInItem(im.getId(), "",
|
return new ConversationNoticeInItem(im.getId(), im.getGroupId(), "",
|
||||||
im.getTimestamp(), im.isRead());
|
im.getTimestamp(), im.isRead());
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OutgoingItem {
|
interface OutgoingItem {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
MessageId getId();
|
MessageId getId();
|
||||||
|
|
||||||
boolean isSent();
|
boolean isSent();
|
||||||
@@ -226,8 +239,12 @@ public abstract class ConversationItem {
|
|||||||
|
|
||||||
interface IncomingItem {
|
interface IncomingItem {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
MessageId getId();
|
MessageId getId();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
GroupId getGroupId();
|
||||||
|
|
||||||
boolean isRead();
|
boolean isRead();
|
||||||
|
|
||||||
void setRead(boolean read);
|
void setRead(boolean read);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ abstract class ConversationMessageItem extends ConversationItem {
|
|||||||
private byte[] body;
|
private byte[] body;
|
||||||
|
|
||||||
ConversationMessageItem(PrivateMessageHeader header) {
|
ConversationMessageItem(PrivateMessageHeader header) {
|
||||||
super(header.getId(), header.getTimestamp());
|
super(header.getId(), header.getGroupId(), header.getTimestamp());
|
||||||
|
|
||||||
this.header = header;
|
this.header = header;
|
||||||
body = null;
|
body = null;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
// This class is not thread-safe
|
// This class is not thread-safe
|
||||||
@@ -8,9 +9,9 @@ class ConversationNoticeInItem extends ConversationNoticeItem
|
|||||||
|
|
||||||
private boolean read;
|
private boolean read;
|
||||||
|
|
||||||
ConversationNoticeInItem(MessageId id, String text, long time,
|
ConversationNoticeInItem(MessageId id, GroupId groupId, String text,
|
||||||
boolean read) {
|
long time, boolean read) {
|
||||||
super(id, text, time);
|
super(id, groupId, text, time);
|
||||||
|
|
||||||
this.read = read;
|
this.read = read;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
abstract class ConversationNoticeItem extends ConversationItem {
|
abstract class ConversationNoticeItem extends ConversationItem {
|
||||||
|
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
ConversationNoticeItem(MessageId id, String text, long time) {
|
ConversationNoticeItem(MessageId id, GroupId groupId, String text,
|
||||||
super(id, time);
|
long time) {
|
||||||
|
super(id, groupId, time);
|
||||||
|
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.android.contact;
|
package org.briarproject.android.contact;
|
||||||
|
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
// This class is not thread-safe
|
// This class is not thread-safe
|
||||||
@@ -8,9 +9,9 @@ class ConversationNoticeOutItem extends ConversationNoticeItem
|
|||||||
|
|
||||||
private boolean sent, seen;
|
private boolean sent, seen;
|
||||||
|
|
||||||
ConversationNoticeOutItem(MessageId id, String text, long time,
|
ConversationNoticeOutItem(MessageId id, GroupId groupId, String text,
|
||||||
boolean sent, boolean seen) {
|
long time, boolean sent, boolean seen) {
|
||||||
super(id, text, time);
|
super(id, groupId, text, time);
|
||||||
|
|
||||||
this.sent = sent;
|
this.sent = sent;
|
||||||
this.seen = seen;
|
this.seen = seen;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ abstract class ConversationShareableInvitationItem extends ConversationItem {
|
|||||||
private final InvitationRequest fim;
|
private final InvitationRequest fim;
|
||||||
|
|
||||||
ConversationShareableInvitationItem(InvitationRequest fim) {
|
ConversationShareableInvitationItem(InvitationRequest fim) {
|
||||||
super(fim.getId(), fim.getTimestamp());
|
super(fim.getId(), fim.getGroupId(), fim.getTimestamp());
|
||||||
|
|
||||||
this.fim = fim;
|
this.fim = fim;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.briarproject.android.forum;
|
|
||||||
|
|
||||||
import org.briarproject.api.forum.ForumPostHeader;
|
|
||||||
|
|
||||||
// This class is not thread-safe
|
|
||||||
class ForumItem {
|
|
||||||
|
|
||||||
private final ForumPostHeader header;
|
|
||||||
private byte[] body;
|
|
||||||
|
|
||||||
ForumItem(ForumPostHeader header) {
|
|
||||||
this.header = header;
|
|
||||||
body = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ForumPostHeader getHeader() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] getBody() {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBody(byte[] body) {
|
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package org.briarproject.android.forum;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
class ForumItemComparator implements Comparator<ForumItem> {
|
|
||||||
|
|
||||||
static final ForumItemComparator INSTANCE = new ForumItemComparator();
|
|
||||||
|
|
||||||
public int compare(ForumItem a, ForumItem b) {
|
|
||||||
// The oldest message comes first
|
|
||||||
long aTime = a.getHeader().getTimestamp();
|
|
||||||
long bTime = b.getHeader().getTimestamp();
|
|
||||||
if (aTime < bTime) return -1;
|
|
||||||
if (aTime > bTime) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,6 +17,7 @@ import org.briarproject.android.view.TextAvatarView;
|
|||||||
import org.briarproject.api.forum.Forum;
|
import org.briarproject.api.forum.Forum;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import static android.support.v7.util.SortedList.INVALID_POSITION;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static org.briarproject.android.BriarActivity.GROUP_ID;
|
import static org.briarproject.android.BriarActivity.GROUP_ID;
|
||||||
@@ -104,7 +105,7 @@ class ForumListAdapter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(ForumListItem a, ForumListItem b) {
|
public boolean areContentsTheSame(ForumListItem a, ForumListItem b) {
|
||||||
return a.getForum().equals(b.getForum()) &&
|
return a.isEmpty() == b.isEmpty() &&
|
||||||
a.getTimestamp() == b.getTimestamp() &&
|
a.getTimestamp() == b.getTimestamp() &&
|
||||||
a.getUnreadCount() == b.getUnreadCount();
|
a.getUnreadCount() == b.getUnreadCount();
|
||||||
}
|
}
|
||||||
@@ -125,10 +126,14 @@ class ForumListAdapter
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateItem(ForumListItem item) {
|
int findItemPosition(GroupId g) {
|
||||||
ForumListItem oldItem = findItem(item.getForum().getGroup().getId());
|
int count = getItemCount();
|
||||||
int position = items.indexOf(oldItem);
|
for (int i = 0; i < count; i++) {
|
||||||
items.updateItemAt(position, item);
|
ForumListItem item = getItemAt(i);
|
||||||
|
if (item != null && item.getForum().getGroup().getId().equals(g))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return INVALID_POSITION; // Not found
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ForumViewHolder extends RecyclerView.ViewHolder {
|
static class ForumViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.briarproject.android.api.AndroidNotificationManager;
|
|||||||
import org.briarproject.android.fragment.BaseEventFragment;
|
import org.briarproject.android.fragment.BaseEventFragment;
|
||||||
import org.briarproject.android.sharing.InvitationsForumActivity;
|
import org.briarproject.android.sharing.InvitationsForumActivity;
|
||||||
import org.briarproject.android.view.BriarRecyclerView;
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.NoSuchGroupException;
|
import org.briarproject.api.db.NoSuchGroupException;
|
||||||
import org.briarproject.api.event.ContactRemovedEvent;
|
import org.briarproject.api.event.ContactRemovedEvent;
|
||||||
@@ -47,11 +48,8 @@ import static java.util.logging.Level.WARNING;
|
|||||||
public class ForumListFragment extends BaseEventFragment implements
|
public class ForumListFragment extends BaseEventFragment implements
|
||||||
OnClickListener {
|
OnClickListener {
|
||||||
|
|
||||||
public final static String TAG = "ForumListFragment";
|
public final static String TAG = ForumListFragment.class.getName();
|
||||||
|
private final static Logger LOG = Logger.getLogger(TAG);
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(ForumListFragment.class.getName());
|
|
||||||
|
|
||||||
|
|
||||||
private BriarRecyclerView list;
|
private BriarRecyclerView list;
|
||||||
private ForumListAdapter adapter;
|
private ForumListAdapter adapter;
|
||||||
@@ -118,7 +116,7 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
|
|
||||||
notificationManager.blockAllForumPostNotifications();
|
notificationManager.blockAllForumPostNotifications();
|
||||||
notificationManager.clearAllForumPostNotifications();
|
notificationManager.clearAllForumPostNotifications();
|
||||||
loadForumHeaders();
|
loadForums();
|
||||||
loadAvailableForums();
|
loadAvailableForums();
|
||||||
list.startPeriodicUpdate();
|
list.startPeriodicUpdate();
|
||||||
}
|
}
|
||||||
@@ -153,7 +151,7 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadForumHeaders() {
|
private void loadForums() {
|
||||||
listener.runOnDbThread(new Runnable() {
|
listener.runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -163,14 +161,14 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
Collection<ForumListItem> forums = new ArrayList<>();
|
Collection<ForumListItem> forums = new ArrayList<>();
|
||||||
for (Forum f : forumManager.getForums()) {
|
for (Forum f : forumManager.getForums()) {
|
||||||
try {
|
try {
|
||||||
Collection<ForumPostHeader> headers =
|
GroupCount count =
|
||||||
forumManager.getPostHeaders(f.getId());
|
forumManager.getGroupCount(f.getId());
|
||||||
forums.add(new ForumListItem(f, headers));
|
forums.add(new ForumListItem(f, count));
|
||||||
} catch (NoSuchGroupException e) {
|
} catch (NoSuchGroupException e) {
|
||||||
// Continue
|
// Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayForumHeaders(forums);
|
displayForums(forums);
|
||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Full load took " + duration + " ms");
|
LOG.info("Full load took " + duration + " ms");
|
||||||
@@ -182,7 +180,7 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayForumHeaders(final Collection<ForumListItem> forums) {
|
private void displayForums(final Collection<ForumListItem> forums) {
|
||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -238,7 +236,7 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
GroupAddedEvent g = (GroupAddedEvent) e;
|
GroupAddedEvent g = (GroupAddedEvent) e;
|
||||||
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
|
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
|
||||||
LOG.info("Forum added, reloading forums");
|
LOG.info("Forum added, reloading forums");
|
||||||
loadForumHeaders();
|
loadForums();
|
||||||
}
|
}
|
||||||
} else if (e instanceof GroupRemovedEvent) {
|
} else if (e instanceof GroupRemovedEvent) {
|
||||||
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
GroupRemovedEvent g = (GroupRemovedEvent) e;
|
||||||
@@ -248,39 +246,23 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
}
|
}
|
||||||
} else if (e instanceof ForumPostReceivedEvent) {
|
} else if (e instanceof ForumPostReceivedEvent) {
|
||||||
ForumPostReceivedEvent m = (ForumPostReceivedEvent) e;
|
ForumPostReceivedEvent m = (ForumPostReceivedEvent) e;
|
||||||
LOG.info("Forum post added, reloading");
|
LOG.info("Forum post added, updating...");
|
||||||
loadForumHeaders(m.getGroupId());
|
updateItem(m.getGroupId(), m.getForumPostHeader());
|
||||||
} else if (e instanceof ForumInvitationReceivedEvent) {
|
} else if (e instanceof ForumInvitationReceivedEvent) {
|
||||||
loadAvailableForums();
|
loadAvailableForums();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadForumHeaders(final GroupId g) {
|
private void updateItem(final GroupId g, final ForumPostHeader m) {
|
||||||
listener.runOnDbThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
Forum f = forumManager.getForum(g);
|
|
||||||
Collection<ForumPostHeader> headers =
|
|
||||||
forumManager.getPostHeaders(g);
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Partial load took " + duration + " ms");
|
|
||||||
updateForum(new ForumListItem(f, headers));
|
|
||||||
} catch (DbException e) {
|
|
||||||
if (LOG.isLoggable(WARNING))
|
|
||||||
LOG.log(WARNING, e.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateForum(final ForumListItem item) {
|
|
||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
adapter.updateItem(item);
|
int position = adapter.findItemPosition(g);
|
||||||
|
ForumListItem item = adapter.getItemAt(position);
|
||||||
|
if (item != null) {
|
||||||
|
item.addHeader(m);
|
||||||
|
adapter.updateItemAt(position, item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -289,7 +271,8 @@ public class ForumListFragment extends BaseEventFragment implements
|
|||||||
listener.runOnUiThread(new Runnable() {
|
listener.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ForumListItem item = adapter.findItem(g);
|
int position = adapter.findItemPosition(g);
|
||||||
|
ForumListItem item = adapter.getItemAt(position);
|
||||||
if (item != null) adapter.remove(item);
|
if (item != null) adapter.remove(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,40 +1,27 @@
|
|||||||
package org.briarproject.android.forum;
|
package org.briarproject.android.forum;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.forum.Forum;
|
import org.briarproject.api.forum.Forum;
|
||||||
import org.briarproject.api.forum.ForumPostHeader;
|
import org.briarproject.api.forum.ForumPostHeader;
|
||||||
|
|
||||||
import java.util.Collection;
|
// This class is NOT thread-safe
|
||||||
|
|
||||||
class ForumListItem {
|
class ForumListItem {
|
||||||
|
|
||||||
private final Forum forum;
|
private final Forum forum;
|
||||||
private final boolean empty;
|
private int postCount, unread;
|
||||||
private final int postCount;
|
private long timestamp;
|
||||||
private final long timestamp;
|
|
||||||
private final int unread;
|
|
||||||
|
|
||||||
ForumListItem(Forum forum, Collection<ForumPostHeader> headers) {
|
ForumListItem(Forum forum, GroupCount count) {
|
||||||
this.forum = forum;
|
this.forum = forum;
|
||||||
empty = headers.isEmpty();
|
this.postCount = count.getMsgCount();
|
||||||
if (empty) {
|
this.unread = count.getUnreadCount();
|
||||||
postCount = 0;
|
this.timestamp = count.getLatestMsgTime();
|
||||||
timestamp = 0;
|
}
|
||||||
unread = 0;
|
|
||||||
} else {
|
void addHeader(ForumPostHeader h) {
|
||||||
ForumPostHeader newest = null;
|
postCount++;
|
||||||
long timestamp = -1;
|
if (!h.isRead()) unread++;
|
||||||
int unread = 0;
|
if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp();
|
||||||
for (ForumPostHeader h : headers) {
|
|
||||||
if (h.getTimestamp() > timestamp) {
|
|
||||||
timestamp = h.getTimestamp();
|
|
||||||
newest = h;
|
|
||||||
}
|
|
||||||
if (!h.isRead()) unread++;
|
|
||||||
}
|
|
||||||
this.postCount = headers.size();
|
|
||||||
this.timestamp = newest.getTimestamp();
|
|
||||||
this.unread = unread;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Forum getForum() {
|
Forum getForum() {
|
||||||
@@ -42,7 +29,7 @@ class ForumListItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isEmpty() {
|
boolean isEmpty() {
|
||||||
return empty;
|
return postCount == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getPostCount() {
|
int getPostCount() {
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ import org.briarproject.R;
|
|||||||
import org.briarproject.android.ActivityComponent;
|
import org.briarproject.android.ActivityComponent;
|
||||||
import org.briarproject.android.contact.ContactListAdapter;
|
import org.briarproject.android.contact.ContactListAdapter;
|
||||||
import org.briarproject.android.contact.ContactListItem;
|
import org.briarproject.android.contact.ContactListItem;
|
||||||
import org.briarproject.android.contact.ConversationItem;
|
|
||||||
import org.briarproject.android.fragment.BaseFragment;
|
import org.briarproject.android.fragment.BaseFragment;
|
||||||
import org.briarproject.android.view.BriarRecyclerView;
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
@@ -25,21 +25,16 @@ import org.briarproject.api.db.DbException;
|
|||||||
import org.briarproject.api.identity.AuthorId;
|
import org.briarproject.api.identity.AuthorId;
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.introduction.IntroductionManager;
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
import org.briarproject.api.introduction.IntroductionMessage;
|
|
||||||
import org.briarproject.api.messaging.MessagingManager;
|
|
||||||
import org.briarproject.api.messaging.PrivateMessageHeader;
|
|
||||||
import org.briarproject.api.plugins.ConnectionRegistry;
|
import org.briarproject.api.plugins.ConnectionRegistry;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
public class ContactChooserFragment extends BaseFragment {
|
public class ContactChooserFragment extends BaseFragment {
|
||||||
@@ -61,9 +56,7 @@ public class ContactChooserFragment extends BaseFragment {
|
|||||||
@Inject
|
@Inject
|
||||||
protected volatile IdentityManager identityManager;
|
protected volatile IdentityManager identityManager;
|
||||||
@Inject
|
@Inject
|
||||||
protected volatile MessagingManager messagingManager;
|
protected volatile ConversationManager conversationManager;
|
||||||
@Inject
|
|
||||||
protected volatile IntroductionManager introductionManager;
|
|
||||||
@Inject
|
@Inject
|
||||||
protected volatile ConnectionRegistry connectionRegistry;
|
protected volatile ConnectionRegistry connectionRegistry;
|
||||||
|
|
||||||
@@ -159,23 +152,23 @@ public class ContactChooserFragment extends BaseFragment {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
List<ContactListItem> contacts = new ArrayList<>();
|
List<ContactListItem> contacts = new ArrayList<>();
|
||||||
AuthorId localAuthorId = null;
|
AuthorId localAuthorId =
|
||||||
|
identityManager.getLocalAuthor().getId();
|
||||||
for (Contact c : contactManager.getActiveContacts()) {
|
for (Contact c : contactManager.getActiveContacts()) {
|
||||||
if (c.getId().getInt() == contactId) {
|
if (c.getId().getInt() == contactId) {
|
||||||
c1 = c;
|
c1 = c;
|
||||||
localAuthorId = c1.getLocalAuthorId();
|
|
||||||
} else {
|
} else {
|
||||||
ContactId id = c.getId();
|
ContactId id = c.getId();
|
||||||
GroupId groupId =
|
GroupId groupId =
|
||||||
messagingManager.getConversationId(id);
|
conversationManager.getConversationId(id);
|
||||||
Collection<ConversationItem> messages =
|
GroupCount count =
|
||||||
getMessages(id);
|
conversationManager.getGroupCount(id);
|
||||||
boolean connected =
|
boolean connected =
|
||||||
connectionRegistry.isConnected(c.getId());
|
connectionRegistry.isConnected(c.getId());
|
||||||
LocalAuthor localAuthor = identityManager
|
LocalAuthor localAuthor = identityManager
|
||||||
.getLocalAuthor(c.getLocalAuthorId());
|
.getLocalAuthor(c.getLocalAuthorId());
|
||||||
contacts.add(new ContactListItem(c, localAuthor,
|
contacts.add(new ContactListItem(c, localAuthor,
|
||||||
connected, groupId, messages));
|
connected, groupId, count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayContacts(localAuthorId, contacts);
|
displayContacts(localAuthorId, contacts);
|
||||||
@@ -220,36 +213,4 @@ public class ContactChooserFragment extends BaseFragment {
|
|||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This needs to be called from the DbThread
|
|
||||||
*/
|
|
||||||
private Collection<ConversationItem> getMessages(ContactId id)
|
|
||||||
throws DbException {
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
Collection<ConversationItem> messages = new ArrayList<>();
|
|
||||||
|
|
||||||
Collection<PrivateMessageHeader> headers =
|
|
||||||
messagingManager.getMessageHeaders(id);
|
|
||||||
for (PrivateMessageHeader h : headers) {
|
|
||||||
messages.add(ConversationItem.from(h));
|
|
||||||
}
|
|
||||||
long duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading message headers took " + duration + " ms");
|
|
||||||
|
|
||||||
now = System.currentTimeMillis();
|
|
||||||
Collection<IntroductionMessage> introductions =
|
|
||||||
introductionManager
|
|
||||||
.getIntroductionMessages(id);
|
|
||||||
for (IntroductionMessage m : introductions) {
|
|
||||||
messages.add(ConversationItem.from(m));
|
|
||||||
}
|
|
||||||
duration = System.currentTimeMillis() - now;
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading introduction messages took " + duration + " ms");
|
|
||||||
|
|
||||||
return messages;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.android.sharing;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.transition.Fade;
|
import android.transition.Fade;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -39,6 +40,7 @@ import static java.util.logging.Level.INFO;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.android.sharing.ShareActivity.CONTACTS;
|
import static org.briarproject.android.sharing.ShareActivity.CONTACTS;
|
||||||
import static org.briarproject.android.sharing.ShareActivity.getContactsFromIds;
|
import static org.briarproject.android.sharing.ShareActivity.getContactsFromIds;
|
||||||
|
import static org.briarproject.android.sharing.ShareActivity.getContactsFromIntegers;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
import static org.briarproject.api.sharing.SharingConstants.GROUP_ID;
|
||||||
|
|
||||||
public class ContactSelectorFragment extends BaseFragment implements
|
public class ContactSelectorFragment extends BaseFragment implements
|
||||||
@@ -122,8 +124,9 @@ public class ContactSelectorFragment extends BaseFragment implements
|
|||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
ArrayList<Integer> intContacts =
|
ArrayList<Integer> intContacts =
|
||||||
savedInstanceState.getIntegerArrayList(CONTACTS);
|
savedInstanceState.getIntegerArrayList(CONTACTS);
|
||||||
selectedContacts = ShareActivity.getContactsFromIntegers(
|
if (intContacts != null) {
|
||||||
intContacts);
|
selectedContacts = getContactsFromIntegers(intContacts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentView;
|
return contentView;
|
||||||
@@ -185,7 +188,7 @@ public class ContactSelectorFragment extends BaseFragment implements
|
|||||||
updateMenuItem();
|
updateMenuItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadContacts(final Collection<ContactId> selection) {
|
private void loadContacts(@Nullable final Collection<ContactId> selection) {
|
||||||
shareActivity.runOnDbThread(new Runnable() {
|
shareActivity.runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.briarproject.android.sharing;
|
package org.briarproject.android.sharing;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
import org.briarproject.android.contact.ContactListItem;
|
import org.briarproject.android.contact.ContactListItem;
|
||||||
import org.briarproject.android.contact.ConversationItem;
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
import java.util.Collections;
|
// This class is NOT thread-safe
|
||||||
|
|
||||||
// This class is not thread-safe
|
|
||||||
public class SelectableContactListItem extends ContactListItem {
|
public class SelectableContactListItem extends ContactListItem {
|
||||||
|
|
||||||
private boolean selected, disabled;
|
private boolean selected, disabled;
|
||||||
@@ -16,8 +16,7 @@ public class SelectableContactListItem extends ContactListItem {
|
|||||||
public SelectableContactListItem(Contact contact, LocalAuthor localAuthor,
|
public SelectableContactListItem(Contact contact, LocalAuthor localAuthor,
|
||||||
GroupId groupId, boolean selected, boolean disabled) {
|
GroupId groupId, boolean selected, boolean disabled) {
|
||||||
|
|
||||||
super(contact, localAuthor, false, groupId,
|
super(contact, localAuthor, false, groupId, new GroupCount(0, 0, 0));
|
||||||
Collections.<ConversationItem>emptyList());
|
|
||||||
|
|
||||||
this.selected = selected;
|
this.selected = selected;
|
||||||
this.disabled = disabled;
|
this.disabled = disabled;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.briarproject.R;
|
|||||||
import org.briarproject.android.BriarActivity;
|
import org.briarproject.android.BriarActivity;
|
||||||
import org.briarproject.android.contact.ContactListItem;
|
import org.briarproject.android.contact.ContactListItem;
|
||||||
import org.briarproject.android.view.BriarRecyclerView;
|
import org.briarproject.android.view.BriarRecyclerView;
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
@@ -105,8 +106,8 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
LocalAuthor localAuthor = identityManager
|
LocalAuthor localAuthor = identityManager
|
||||||
.getLocalAuthor(c.getLocalAuthorId());
|
.getLocalAuthor(c.getLocalAuthorId());
|
||||||
ContactListItem item =
|
ContactListItem item =
|
||||||
new ContactListItem(c, localAuthor, false, null,
|
new ContactListItem(c, localAuthor, false,
|
||||||
null);
|
groupId, new GroupCount(0, 0, 0));
|
||||||
contactItems.add(item);
|
contactItems.add(item);
|
||||||
}
|
}
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -141,8 +142,8 @@ abstract class SharingStatusActivity extends BriarActivity {
|
|||||||
LocalAuthor localAuthor = identityManager
|
LocalAuthor localAuthor = identityManager
|
||||||
.getLocalAuthor(c.getLocalAuthorId());
|
.getLocalAuthor(c.getLocalAuthorId());
|
||||||
ContactListItem item =
|
ContactListItem item =
|
||||||
new ContactListItem(c, localAuthor, false, null,
|
new ContactListItem(c, localAuthor, false,
|
||||||
null);
|
groupId, new GroupCount(0, 0, 0));
|
||||||
contactItems.add(item);
|
contactItems.add(item);
|
||||||
}
|
}
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
|
|||||||
@@ -48,11 +48,12 @@ public class TextAvatarView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setUnreadCount(int count) {
|
public void setUnreadCount(int count) {
|
||||||
|
unreadCount = count;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
this.unreadCount = count;
|
|
||||||
badge.setBackgroundResource(R.drawable.bubble);
|
badge.setBackgroundResource(R.drawable.bubble);
|
||||||
badge.setText(String.valueOf(count));
|
badge.setText(String.valueOf(count));
|
||||||
badge.setTextColor(ContextCompat.getColor(getContext(), R.color.briar_text_primary_inverse));
|
badge.setTextColor(ContextCompat.getColor(getContext(),
|
||||||
|
R.color.briar_text_primary_inverse));
|
||||||
badge.setVisibility(VISIBLE);
|
badge.setVisibility(VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
badge.setVisibility(INVISIBLE);
|
badge.setVisibility(INVISIBLE);
|
||||||
@@ -63,12 +64,11 @@ public class TextAvatarView extends FrameLayout {
|
|||||||
if (problem) {
|
if (problem) {
|
||||||
badge.setBackgroundResource(R.drawable.bubble_problem);
|
badge.setBackgroundResource(R.drawable.bubble_problem);
|
||||||
badge.setText("!");
|
badge.setText("!");
|
||||||
badge.setTextColor(ContextCompat.getColor(getContext(), R.color.briar_primary));
|
badge.setTextColor(ContextCompat
|
||||||
|
.getColor(getContext(), R.color.briar_primary));
|
||||||
badge.setVisibility(VISIBLE);
|
badge.setVisibility(VISIBLE);
|
||||||
} else if (unreadCount > 0) {
|
|
||||||
setUnreadCount(unreadCount);
|
|
||||||
} else {
|
} else {
|
||||||
badge.setVisibility(INVISIBLE);
|
setUnreadCount(unreadCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,13 @@ import android.support.annotation.CallSuper;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.StringRes;
|
import android.support.annotation.StringRes;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v7.widget.AppCompatImageButton;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
||||||
@@ -32,7 +27,6 @@ import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
public class TextInputView extends KeyboardAwareLinearLayout
|
public class TextInputView extends KeyboardAwareLinearLayout
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package org.briarproject.api.blogs;
|
|||||||
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.sharing.InvitationMessage;
|
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
public class BlogInvitationRequest extends InvitationRequest {
|
public class BlogInvitationRequest extends InvitationRequest {
|
||||||
@@ -11,12 +11,12 @@ public class BlogInvitationRequest extends InvitationRequest {
|
|||||||
private final String blogAuthorName;
|
private final String blogAuthorName;
|
||||||
|
|
||||||
public BlogInvitationRequest(MessageId id, SessionId sessionId,
|
public BlogInvitationRequest(MessageId id, SessionId sessionId,
|
||||||
ContactId contactId, String blogAuthorName, String message,
|
GroupId groupId, ContactId contactId, String blogAuthorName,
|
||||||
boolean available, long time, boolean local, boolean sent,
|
String message, boolean available, long time, boolean local,
|
||||||
boolean seen, boolean read) {
|
boolean sent, boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, sessionId, contactId, message, available, time, local, sent,
|
super(id, sessionId, groupId, contactId, message, available, time,
|
||||||
seen, read);
|
local, sent, seen, read);
|
||||||
this.blogAuthorName = blogAuthorName;
|
this.blogAuthorName = blogAuthorName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,18 @@ package org.briarproject.api.blogs;
|
|||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.sharing.InvitationResponse;
|
import org.briarproject.api.sharing.InvitationResponse;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class BlogInvitationResponse extends InvitationResponse {
|
public class BlogInvitationResponse extends InvitationResponse {
|
||||||
|
|
||||||
public BlogInvitationResponse(MessageId id, SessionId sessionId,
|
public BlogInvitationResponse(@NotNull MessageId id, SessionId sessionId,
|
||||||
ContactId contactId, boolean accept, long time, boolean local,
|
GroupId groupId, ContactId contactId, boolean accept, long time,
|
||||||
boolean sent, boolean seen, boolean read) {
|
boolean local, boolean sent, boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, sessionId, contactId, accept, time, local, sent, seen, read);
|
super(id, sessionId, groupId, contactId, accept, time, local, sent,
|
||||||
|
seen, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY;
|
|||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG;
|
import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
|
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.TIME;
|
||||||
|
|
||||||
public interface BlogSharingMessage {
|
public interface BlogSharingMessage {
|
||||||
|
|
||||||
@@ -25,9 +26,9 @@ public interface BlogSharingMessage {
|
|||||||
|
|
||||||
public BlogInvitation(GroupId groupId, SessionId sessionId,
|
public BlogInvitation(GroupId groupId, SessionId sessionId,
|
||||||
String blogTitle, String blogDesc, String blogAuthorName,
|
String blogTitle, String blogDesc, String blogAuthorName,
|
||||||
byte[] blogPublicKey, String message) {
|
byte[] blogPublicKey, long time, String message) {
|
||||||
|
|
||||||
super(groupId, sessionId, message);
|
super(groupId, sessionId, time, message);
|
||||||
|
|
||||||
this.blogTitle = blogTitle;
|
this.blogTitle = blogTitle;
|
||||||
this.blogDesc = blogDesc;
|
this.blogDesc = blogDesc;
|
||||||
@@ -65,9 +66,10 @@ public interface BlogSharingMessage {
|
|||||||
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
||||||
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
||||||
String message = d.getOptionalString(INVITATION_MSG);
|
String message = d.getOptionalString(INVITATION_MSG);
|
||||||
|
long time = d.getLong(TIME);
|
||||||
|
|
||||||
return new BlogInvitation(groupId, sessionId, blogTitle,
|
return new BlogInvitation(groupId, sessionId, blogTitle,
|
||||||
blogDesc, blogAuthorName, blogPublicKey, message);
|
blogDesc, blogAuthorName, blogPublicKey, time, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBlogTitle() {
|
public String getBlogTitle() {
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package org.briarproject.api.clients;
|
package org.briarproject.api.clients;
|
||||||
|
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class BaseMessageHeader {
|
public abstract class BaseMessageHeader {
|
||||||
|
|
||||||
private final MessageId id;
|
private final MessageId id;
|
||||||
|
private final GroupId groupId;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
private final boolean local, read, sent, seen;
|
private final boolean local, read, sent, seen;
|
||||||
|
|
||||||
public BaseMessageHeader(MessageId id, long timestamp, boolean local,
|
public BaseMessageHeader(@NotNull MessageId id, @NotNull GroupId groupId,
|
||||||
boolean read, boolean sent, boolean seen) {
|
long timestamp, boolean local, boolean read, boolean sent,
|
||||||
|
boolean seen) {
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.groupId = groupId;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.local = local;
|
this.local = local;
|
||||||
this.read = read;
|
this.read = read;
|
||||||
@@ -19,10 +24,16 @@ public abstract class BaseMessageHeader {
|
|||||||
this.seen = seen;
|
this.seen = seen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public MessageId getId() {
|
public MessageId getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public GroupId getGroupId() {
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
public long getTimestamp() {
|
public long getTimestamp() {
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
@@ -42,4 +53,5 @@ public abstract class BaseMessageHeader {
|
|||||||
public boolean isSeen() {
|
public boolean isSeen() {
|
||||||
return seen;
|
return seen;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package org.briarproject.api.clients;
|
package org.briarproject.api.clients;
|
||||||
|
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Transaction;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.Message;
|
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
public interface MessageTracker {
|
public interface MessageTracker {
|
||||||
@@ -20,19 +18,20 @@ public interface MessageTracker {
|
|||||||
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
||||||
|
|
||||||
class GroupCount {
|
class GroupCount {
|
||||||
private final long msgCount, unreadCount, latestMsgTime;
|
private final int msgCount, unreadCount;
|
||||||
|
private final long latestMsgTime;
|
||||||
|
|
||||||
public GroupCount(long msgCount, long unreadCount, long latestMsgTime) {
|
public GroupCount(int msgCount, int unreadCount, long latestMsgTime) {
|
||||||
this.msgCount = msgCount;
|
this.msgCount = msgCount;
|
||||||
this.unreadCount = unreadCount;
|
this.unreadCount = unreadCount;
|
||||||
this.latestMsgTime = latestMsgTime;
|
this.latestMsgTime = latestMsgTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMsgCount() {
|
public int getMsgCount() {
|
||||||
return msgCount;
|
return msgCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getUnreadCount() {
|
public int getUnreadCount() {
|
||||||
return unreadCount;
|
return unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ package org.briarproject.api.event;
|
|||||||
|
|
||||||
import org.briarproject.api.blogs.Blog;
|
import org.briarproject.api.blogs.Blog;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
|
|
||||||
public class BlogInvitationReceivedEvent extends InvitationReceivedEvent {
|
public class BlogInvitationReceivedEvent extends
|
||||||
|
InvitationRequestReceivedEvent {
|
||||||
|
|
||||||
private final Blog blog;
|
private final Blog blog;
|
||||||
|
|
||||||
public BlogInvitationReceivedEvent(Blog blog, ContactId contactId) {
|
public BlogInvitationReceivedEvent(Blog blog, ContactId contactId,
|
||||||
super(contactId);
|
InvitationRequest request) {
|
||||||
|
super(contactId, request);
|
||||||
this.blog = blog;
|
this.blog = blog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.api.event;
|
package org.briarproject.api.event;
|
||||||
|
|
||||||
|
import org.briarproject.api.blogs.BlogInvitationResponse;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
|
||||||
public class BlogInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent {
|
public class BlogInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent {
|
||||||
@@ -7,8 +8,8 @@ public class BlogInvitationResponseReceivedEvent extends InvitationResponseRecei
|
|||||||
private final String blogTitle;
|
private final String blogTitle;
|
||||||
|
|
||||||
public BlogInvitationResponseReceivedEvent(String blogTitle,
|
public BlogInvitationResponseReceivedEvent(String blogTitle,
|
||||||
ContactId contactId) {
|
ContactId contactId, BlogInvitationResponse response) {
|
||||||
super(contactId);
|
super(contactId, response);
|
||||||
this.blogTitle = blogTitle;
|
this.blogTitle = blogTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,17 +2,21 @@ package org.briarproject.api.event;
|
|||||||
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.forum.Forum;
|
import org.briarproject.api.forum.Forum;
|
||||||
|
import org.briarproject.api.forum.ForumInvitationRequest;
|
||||||
|
|
||||||
public class ForumInvitationReceivedEvent extends InvitationReceivedEvent {
|
public class ForumInvitationReceivedEvent extends
|
||||||
|
InvitationRequestReceivedEvent {
|
||||||
|
|
||||||
private final Forum forum;
|
private final Forum forum;
|
||||||
|
|
||||||
public ForumInvitationReceivedEvent(Forum forum, ContactId contactId) {
|
public ForumInvitationReceivedEvent(Forum forum, ContactId contactId,
|
||||||
super(contactId);
|
ForumInvitationRequest request) {
|
||||||
|
super(contactId, request);
|
||||||
this.forum = forum;
|
this.forum = forum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Forum getForum() {
|
public Forum getForum() {
|
||||||
return forum;
|
return forum;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package org.briarproject.api.event;
|
package org.briarproject.api.event;
|
||||||
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.forum.ForumInvitationResponse;
|
||||||
|
|
||||||
public class ForumInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent {
|
public class ForumInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent {
|
||||||
|
|
||||||
private final String forumName;
|
private final String forumName;
|
||||||
|
|
||||||
public ForumInvitationResponseReceivedEvent(String forumName,
|
public ForumInvitationResponseReceivedEvent(String forumName,
|
||||||
ContactId contactId) {
|
ContactId contactId, ForumInvitationResponse response) {
|
||||||
super(contactId);
|
super(contactId, response);
|
||||||
this.forumName = forumName;
|
this.forumName = forumName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package org.briarproject.api.event;
|
|
||||||
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
|
|
||||||
public abstract class InvitationReceivedEvent extends Event {
|
|
||||||
|
|
||||||
private final ContactId contactId;
|
|
||||||
|
|
||||||
InvitationReceivedEvent(ContactId contactId) {
|
|
||||||
this.contactId = contactId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContactId getContactId() {
|
|
||||||
return contactId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.briarproject.api.event;
|
||||||
|
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
|
|
||||||
|
public abstract class InvitationRequestReceivedEvent extends Event {
|
||||||
|
|
||||||
|
private final ContactId contactId;
|
||||||
|
private final InvitationRequest request;
|
||||||
|
|
||||||
|
InvitationRequestReceivedEvent(ContactId contactId,
|
||||||
|
InvitationRequest request) {
|
||||||
|
this.contactId = contactId;
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactId getContactId() {
|
||||||
|
return contactId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvitationRequest getRequest() {
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,24 @@
|
|||||||
package org.briarproject.api.event;
|
package org.briarproject.api.event;
|
||||||
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.sharing.InvitationResponse;
|
||||||
|
|
||||||
public abstract class InvitationResponseReceivedEvent extends Event {
|
public abstract class InvitationResponseReceivedEvent extends Event {
|
||||||
|
|
||||||
private final ContactId contactId;
|
private final ContactId contactId;
|
||||||
|
private final InvitationResponse response;
|
||||||
|
|
||||||
public InvitationResponseReceivedEvent(ContactId contactId) {
|
public InvitationResponseReceivedEvent(ContactId contactId,
|
||||||
|
InvitationResponse response) {
|
||||||
this.contactId = contactId;
|
this.contactId = contactId;
|
||||||
|
this.response = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContactId getContactId() {
|
public ContactId getContactId() {
|
||||||
return contactId;
|
return contactId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InvitationResponse getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,21 @@ package org.briarproject.api.forum;
|
|||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.sharing.InvitationRequest;
|
import org.briarproject.api.sharing.InvitationRequest;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class ForumInvitationRequest extends InvitationRequest {
|
public class ForumInvitationRequest extends InvitationRequest {
|
||||||
|
|
||||||
private final String forumName;
|
private final String forumName;
|
||||||
|
|
||||||
public ForumInvitationRequest(MessageId id, SessionId sessionId,
|
public ForumInvitationRequest(MessageId id, SessionId sessionId,
|
||||||
ContactId contactId, String forumName, String message,
|
GroupId groupId, ContactId contactId, String forumName, String message,
|
||||||
boolean available, long time, boolean local, boolean sent,
|
boolean available, long time, boolean local, boolean sent,
|
||||||
boolean seen, boolean read) {
|
boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, sessionId, contactId, message, available, time, local, sent,
|
super(id, sessionId, groupId, contactId, message, available, time,
|
||||||
seen, read);
|
local, sent, seen, read);
|
||||||
this.forumName = forumName;
|
this.forumName = forumName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,19 @@ package org.briarproject.api.forum;
|
|||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.sharing.InvitationResponse;
|
import org.briarproject.api.sharing.InvitationResponse;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class ForumInvitationResponse extends InvitationResponse {
|
public class ForumInvitationResponse extends InvitationResponse {
|
||||||
|
|
||||||
public ForumInvitationResponse(MessageId id, SessionId sessionId,
|
public ForumInvitationResponse(@NotNull MessageId id, SessionId sessionId,
|
||||||
ContactId contactId, boolean accept, long time, boolean local,
|
GroupId groupId, ContactId contactId, boolean accept, long time, boolean local,
|
||||||
boolean sent, boolean seen, boolean read) {
|
boolean sent, boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, sessionId, contactId, accept, time, local, sent, seen, read);
|
super(id, sessionId, groupId, contactId, accept, time, local, sent,
|
||||||
|
seen, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
|||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG;
|
import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
|
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.TIME;
|
||||||
|
|
||||||
public interface ForumSharingMessage {
|
public interface ForumSharingMessage {
|
||||||
|
|
||||||
@@ -20,9 +21,9 @@ public interface ForumSharingMessage {
|
|||||||
private final byte[] forumSalt;
|
private final byte[] forumSalt;
|
||||||
|
|
||||||
public ForumInvitation(GroupId groupId, SessionId sessionId,
|
public ForumInvitation(GroupId groupId, SessionId sessionId,
|
||||||
String forumName, byte[] forumSalt, String message) {
|
String forumName, byte[] forumSalt, long time, String message) {
|
||||||
|
|
||||||
super(groupId, sessionId, message);
|
super(groupId, sessionId, time, message);
|
||||||
|
|
||||||
this.forumName = forumName;
|
this.forumName = forumName;
|
||||||
this.forumSalt = forumSalt;
|
this.forumSalt = forumSalt;
|
||||||
@@ -53,9 +54,10 @@ public interface ForumSharingMessage {
|
|||||||
String forumName = d.getString(FORUM_NAME);
|
String forumName = d.getString(FORUM_NAME);
|
||||||
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
||||||
String message = d.getOptionalString(INVITATION_MSG);
|
String message = d.getOptionalString(INVITATION_MSG);
|
||||||
|
long time = d.getLong(TIME);
|
||||||
|
|
||||||
return new ForumInvitation(groupId, sessionId, forumName, forumSalt,
|
return new ForumInvitation(groupId, sessionId, forumName, forumSalt,
|
||||||
message);
|
time, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getForumName() {
|
public String getForumName() {
|
||||||
|
|||||||
@@ -1,32 +1,36 @@
|
|||||||
package org.briarproject.api.introduction;
|
package org.briarproject.api.introduction;
|
||||||
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
|
||||||
import org.briarproject.api.clients.BaseMessageHeader;
|
import org.briarproject.api.clients.BaseMessageHeader;
|
||||||
|
import org.briarproject.api.clients.SessionId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCEE;
|
|
||||||
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCER;
|
import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRODUCER;
|
||||||
|
|
||||||
public class IntroductionMessage extends BaseMessageHeader {
|
public class IntroductionMessage extends BaseMessageHeader {
|
||||||
|
|
||||||
private final SessionId sessionId;
|
private final SessionId sessionId;
|
||||||
private final MessageId messageId;
|
private final MessageId messageId;
|
||||||
private final int role;
|
private final int role;
|
||||||
|
|
||||||
public IntroductionMessage(SessionId sessionId, MessageId messageId,
|
public IntroductionMessage(@NotNull SessionId sessionId,
|
||||||
int role, long time, boolean local, boolean sent, boolean seen,
|
@NotNull MessageId messageId, @NotNull GroupId groupId, int role,
|
||||||
|
long time, boolean local, boolean sent, boolean seen,
|
||||||
boolean read) {
|
boolean read) {
|
||||||
|
|
||||||
super(messageId, time, local, read, sent, seen);
|
super(messageId, groupId, time, local, read, sent, seen);
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.messageId = messageId;
|
this.messageId = messageId;
|
||||||
this.role = role;
|
this.role = role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public SessionId getSessionId() {
|
public SessionId getSessionId() {
|
||||||
return sessionId;
|
return sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public MessageId getMessageId() {
|
public MessageId getMessageId() {
|
||||||
return messageId;
|
return messageId;
|
||||||
}
|
}
|
||||||
@@ -35,9 +39,4 @@ import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRO
|
|||||||
return role == ROLE_INTRODUCER;
|
return role == ROLE_INTRODUCER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isIntroducee() {
|
|
||||||
return role == ROLE_INTRODUCEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,25 @@ package org.briarproject.api.introduction;
|
|||||||
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.identity.AuthorId;
|
import org.briarproject.api.identity.AuthorId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class IntroductionRequest extends IntroductionResponse {
|
public class IntroductionRequest extends IntroductionResponse {
|
||||||
|
|
||||||
private final String message;
|
private final String message;
|
||||||
private final boolean answered, exists, introducesOtherIdentity;
|
private final boolean answered, exists, introducesOtherIdentity;
|
||||||
|
|
||||||
public IntroductionRequest(SessionId sessionId, MessageId messageId,
|
public IntroductionRequest(@NotNull SessionId sessionId,
|
||||||
int role, long time, boolean local, boolean sent, boolean seen,
|
@NotNull MessageId messageId, @NotNull GroupId groupId, int role,
|
||||||
boolean read, AuthorId authorId, String name, boolean accepted,
|
long time, boolean local, boolean sent, boolean seen, boolean read,
|
||||||
String message, boolean answered, boolean exists,
|
AuthorId authorId, String name, boolean accepted,
|
||||||
|
@Nullable String message, boolean answered, boolean exists,
|
||||||
boolean introducesOtherIdentity) {
|
boolean introducesOtherIdentity) {
|
||||||
|
|
||||||
super(sessionId, messageId, role, time, local, sent, seen, read,
|
super(sessionId, messageId, groupId, role, time, local, sent, seen,
|
||||||
authorId, name, accepted);
|
read, authorId, name, accepted);
|
||||||
|
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.answered = answered;
|
this.answered = answered;
|
||||||
@@ -24,6 +28,7 @@ public class IntroductionRequest extends IntroductionResponse {
|
|||||||
this.introducesOtherIdentity = introducesOtherIdentity;
|
this.introducesOtherIdentity = introducesOtherIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package org.briarproject.api.introduction;
|
|||||||
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.identity.AuthorId;
|
import org.briarproject.api.identity.AuthorId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class IntroductionResponse extends IntroductionMessage {
|
public class IntroductionResponse extends IntroductionMessage {
|
||||||
|
|
||||||
@@ -10,12 +12,13 @@ public class IntroductionResponse extends IntroductionMessage {
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final boolean accepted;
|
private final boolean accepted;
|
||||||
|
|
||||||
public IntroductionResponse(SessionId sessionId, MessageId messageId,
|
public IntroductionResponse(@NotNull SessionId sessionId,
|
||||||
int role, long time, boolean local, boolean sent, boolean seen,
|
@NotNull MessageId messageId, @NotNull GroupId groupId, int role,
|
||||||
boolean read, AuthorId remoteAuthorId, String name,
|
long time, boolean local, boolean sent, boolean seen, boolean read,
|
||||||
boolean accepted) {
|
AuthorId remoteAuthorId, String name, boolean accepted) {
|
||||||
|
|
||||||
super(sessionId, messageId, role, time, local, sent, seen, read);
|
super(sessionId, messageId, groupId, role, time, local, sent, seen,
|
||||||
|
read);
|
||||||
|
|
||||||
this.remoteAuthorId = remoteAuthorId;
|
this.remoteAuthorId = remoteAuthorId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.briarproject.api.messaging;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.Transaction;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
public interface ConversationManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clients that present messages in a private conversation need to
|
||||||
|
* register themselves here.
|
||||||
|
*/
|
||||||
|
void registerConversationClient(ConversationClient client);
|
||||||
|
|
||||||
|
/** Get the main group ID that represents this conversation */
|
||||||
|
GroupId getConversationId(ContactId contactId) throws DbException;
|
||||||
|
|
||||||
|
/** Get the unified group count for all private conversation messages. */
|
||||||
|
GroupCount getGroupCount(ContactId contactId) throws DbException;
|
||||||
|
|
||||||
|
interface ConversationClient {
|
||||||
|
GroupCount getGroupCount(Transaction txn, ContactId contactId)
|
||||||
|
throws DbException;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,17 +1,18 @@
|
|||||||
package org.briarproject.api.messaging;
|
package org.briarproject.api.messaging;
|
||||||
|
|
||||||
import org.briarproject.api.clients.BaseMessageHeader;
|
import org.briarproject.api.clients.BaseMessageHeader;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
public class PrivateMessageHeader extends BaseMessageHeader {
|
public class PrivateMessageHeader extends BaseMessageHeader {
|
||||||
|
|
||||||
private final String contentType;
|
private final String contentType;
|
||||||
|
|
||||||
public PrivateMessageHeader(MessageId id, long timestamp,
|
public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp,
|
||||||
String contentType, boolean local, boolean read, boolean sent,
|
String contentType, boolean local, boolean read, boolean sent,
|
||||||
boolean seen) {
|
boolean seen) {
|
||||||
|
|
||||||
super(id, timestamp, local, read, sent, seen);
|
super(id, groupId, timestamp, local, read, sent, seen);
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,33 @@
|
|||||||
package org.briarproject.api.sharing;
|
package org.briarproject.api.sharing;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.BaseMessageHeader;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.clients.BaseMessageHeader;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class InvitationMessage extends BaseMessageHeader {
|
public abstract class InvitationMessage extends BaseMessageHeader {
|
||||||
|
|
||||||
private final SessionId sessionId;
|
private final SessionId sessionId;
|
||||||
private final ContactId contactId;
|
private final ContactId contactId;
|
||||||
|
|
||||||
public InvitationMessage(MessageId id, SessionId sessionId,
|
public InvitationMessage(@NotNull MessageId id,
|
||||||
ContactId contactId, long time, boolean local, boolean sent,
|
@NotNull SessionId sessionId, @NotNull GroupId groupId,
|
||||||
boolean seen, boolean read) {
|
@NotNull ContactId contactId, long time, boolean local,
|
||||||
|
boolean sent, boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, time, local, read, sent, seen);
|
super(id, groupId, time, local, read, sent, seen);
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.contactId = contactId;
|
this.contactId = contactId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public SessionId getSessionId() {
|
public SessionId getSessionId() {
|
||||||
return sessionId;
|
return sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public ContactId getContactId() {
|
public ContactId getContactId() {
|
||||||
return contactId;
|
return contactId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,28 @@ package org.briarproject.api.sharing;
|
|||||||
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public abstract class InvitationRequest extends InvitationMessage {
|
public abstract class InvitationRequest extends InvitationMessage {
|
||||||
|
|
||||||
private final String message;
|
private final String message;
|
||||||
private final boolean available;
|
private final boolean available;
|
||||||
|
|
||||||
public InvitationRequest(MessageId id, SessionId sessionId,
|
public InvitationRequest(@NotNull MessageId id,
|
||||||
ContactId contactId, String message,
|
@NotNull SessionId sessionId, @NotNull GroupId groupId,
|
||||||
|
@NotNull ContactId contactId, @Nullable String message,
|
||||||
boolean available, long time, boolean local, boolean sent,
|
boolean available, long time, boolean local, boolean sent,
|
||||||
boolean seen, boolean read) {
|
boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, sessionId, contactId, time, local, read, sent, seen);
|
super(id, sessionId, groupId, contactId, time, local, sent, seen, read);
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.available = available;
|
this.available = available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,19 @@ package org.briarproject.api.sharing;
|
|||||||
|
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class InvitationResponse extends InvitationMessage {
|
public abstract class InvitationResponse extends InvitationMessage {
|
||||||
|
|
||||||
private final boolean accept;
|
private final boolean accept;
|
||||||
|
|
||||||
public InvitationResponse(MessageId id, SessionId sessionId,
|
public InvitationResponse(@NotNull MessageId id, SessionId sessionId,
|
||||||
ContactId contactId, boolean accept, long time, boolean local,
|
GroupId groupId, ContactId contactId, boolean accept, long time,
|
||||||
boolean sent, boolean seen, boolean read) {
|
boolean local, boolean sent, boolean seen, boolean read) {
|
||||||
|
|
||||||
super(id, sessionId, contactId, time, local, read, sent, seen);
|
super(id, sessionId, groupId, contactId, time, local, sent, seen, read);
|
||||||
this.accept = accept;
|
this.accept = accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public interface SharingConstants {
|
|||||||
String IS_SHARER = "isSharer";
|
String IS_SHARER = "isSharer";
|
||||||
String SHAREABLE_ID = "shareableId";
|
String SHAREABLE_ID = "shareableId";
|
||||||
String INVITATION_MSG = "invitationMsg";
|
String INVITATION_MSG = "invitationMsg";
|
||||||
|
String INVITATION_ID = "invitationId";
|
||||||
|
String RESPONSE_ID = "responseId";
|
||||||
int SHARE_MSG_TYPE_INVITATION = 1;
|
int SHARE_MSG_TYPE_INVITATION = 1;
|
||||||
int SHARE_MSG_TYPE_ACCEPT = 2;
|
int SHARE_MSG_TYPE_ACCEPT = 2;
|
||||||
int SHARE_MSG_TYPE_DECLINE = 3;
|
int SHARE_MSG_TYPE_DECLINE = 3;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEP
|
|||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.TIME;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.TYPE;
|
import static org.briarproject.api.sharing.SharingConstants.TYPE;
|
||||||
|
|
||||||
public interface SharingMessage {
|
public interface SharingMessage {
|
||||||
@@ -21,10 +22,12 @@ public interface SharingMessage {
|
|||||||
abstract class BaseMessage {
|
abstract class BaseMessage {
|
||||||
private final GroupId groupId;
|
private final GroupId groupId;
|
||||||
private final SessionId sessionId;
|
private final SessionId sessionId;
|
||||||
|
private final long time;
|
||||||
|
|
||||||
BaseMessage(GroupId groupId, SessionId sessionId) {
|
BaseMessage(GroupId groupId, SessionId sessionId, long time) {
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfList toBdfList() {
|
public BdfList toBdfList() {
|
||||||
@@ -62,16 +65,20 @@ public interface SharingMessage {
|
|||||||
public SessionId getSessionId() {
|
public SessionId getSessionId() {
|
||||||
return sessionId;
|
return sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Invitation extends BaseMessage {
|
abstract class Invitation extends BaseMessage {
|
||||||
|
|
||||||
protected final String message;
|
protected final String message;
|
||||||
|
|
||||||
public Invitation(GroupId groupId, SessionId sessionId,
|
public Invitation(GroupId groupId, SessionId sessionId, long time,
|
||||||
String message) {
|
String message) {
|
||||||
|
|
||||||
super(groupId, sessionId);
|
super(groupId, sessionId, time);
|
||||||
|
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
@@ -90,8 +97,9 @@ public interface SharingMessage {
|
|||||||
|
|
||||||
private final long type;
|
private final long type;
|
||||||
|
|
||||||
public SimpleMessage(long type, GroupId groupId, SessionId sessionId) {
|
public SimpleMessage(long type, GroupId groupId, SessionId sessionId,
|
||||||
super(groupId, sessionId);
|
long time) {
|
||||||
|
super(groupId, sessionId, time);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +122,8 @@ public interface SharingMessage {
|
|||||||
type != SHARE_MSG_TYPE_ABORT) throw new FormatException();
|
type != SHARE_MSG_TYPE_ABORT) throw new FormatException();
|
||||||
|
|
||||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||||
return new SimpleMessage(type, groupId, sessionId);
|
long time = d.getLong(TIME);
|
||||||
|
return new SimpleMessage(type, groupId, sessionId, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
|
|||||||
protected void trackMessage(Transaction txn, GroupId g, long time,
|
protected void trackMessage(Transaction txn, GroupId g, long time,
|
||||||
boolean read) throws DbException {
|
boolean read) throws DbException {
|
||||||
GroupCount c = getGroupCount(txn, g);
|
GroupCount c = getGroupCount(txn, g);
|
||||||
long msgCount = c.getMsgCount() + 1;
|
int msgCount = c.getMsgCount() + 1;
|
||||||
long unreadCount = c.getUnreadCount() + (read ? 0 : 1);
|
int unreadCount = c.getUnreadCount() + (read ? 0 : 1);
|
||||||
long latestTime =
|
long latestTime =
|
||||||
time > c.getLatestMsgTime() ? time : c.getLatestMsgTime();
|
time > c.getLatestMsgTime() ? time : c.getLatestMsgTime();
|
||||||
storeGroupCount(txn, g,
|
storeGroupCount(txn, g,
|
||||||
@@ -103,14 +103,14 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GroupCount getGroupCount(Transaction txn, GroupId g)
|
protected GroupCount getGroupCount(Transaction txn, GroupId g)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
GroupCount count;
|
GroupCount count;
|
||||||
try {
|
try {
|
||||||
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||||
count = new GroupCount(
|
count = new GroupCount(
|
||||||
d.getLong(GROUP_KEY_MSG_COUNT, 0L),
|
d.getLong(GROUP_KEY_MSG_COUNT, 0L).intValue(),
|
||||||
d.getLong(GROUP_KEY_UNREAD_COUNT, 0L),
|
d.getLong(GROUP_KEY_UNREAD_COUNT, 0L).intValue(),
|
||||||
d.getLong(GROUP_KEY_LATEST_MSG, 0L)
|
d.getLong(GROUP_KEY_LATEST_MSG, 0L)
|
||||||
);
|
);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.briarproject.clients;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.ClientHelper;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.data.MetadataParser;
|
||||||
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.Transaction;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager.ConversationClient;
|
||||||
|
import org.briarproject.api.sync.Group;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
public abstract class ConversationClientImpl extends BdfIncomingMessageHook
|
||||||
|
implements ConversationClient {
|
||||||
|
|
||||||
|
protected ConversationClientImpl(DatabaseComponent db,
|
||||||
|
ClientHelper clientHelper, MetadataParser metadataParser) {
|
||||||
|
super(db, clientHelper, metadataParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Group getContactGroup(Contact contact);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
|
||||||
|
throws DbException {
|
||||||
|
Contact contact = db.getContact(txn, contactId);
|
||||||
|
GroupId groupId = getContactGroup(contact).getId();
|
||||||
|
return getGroupCount(txn, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import org.briarproject.api.introduction.IntroduceeAction;
|
|||||||
import org.briarproject.api.introduction.IntroduceeProtocolState;
|
import org.briarproject.api.introduction.IntroduceeProtocolState;
|
||||||
import org.briarproject.api.introduction.IntroductionRequest;
|
import org.briarproject.api.introduction.IntroductionRequest;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -343,6 +344,7 @@ public class IntroduceeEngine
|
|||||||
|
|
||||||
SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID));
|
SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID));
|
||||||
MessageId messageId = new MessageId(msg.getRaw(MESSAGE_ID));
|
MessageId messageId = new MessageId(msg.getRaw(MESSAGE_ID));
|
||||||
|
GroupId groupId = new GroupId(msg.getRaw(GROUP_ID));
|
||||||
long time = msg.getLong(MESSAGE_TIME);
|
long time = msg.getLong(MESSAGE_TIME);
|
||||||
String name = msg.getString(NAME);
|
String name = msg.getString(NAME);
|
||||||
String message = msg.getOptionalString(MSG);
|
String message = msg.getOptionalString(MSG);
|
||||||
@@ -351,8 +353,9 @@ public class IntroduceeEngine
|
|||||||
localState.getBoolean(REMOTE_AUTHOR_IS_US);
|
localState.getBoolean(REMOTE_AUTHOR_IS_US);
|
||||||
|
|
||||||
IntroductionRequest ir = new IntroductionRequest(sessionId, messageId,
|
IntroductionRequest ir = new IntroductionRequest(sessionId, messageId,
|
||||||
ROLE_INTRODUCEE, time, false, false, false, false, authorId,
|
groupId, ROLE_INTRODUCEE, time, false, false, false, false,
|
||||||
name, false, message, false, exists, introducesOtherIdentity);
|
authorId, name, false, message, false, exists,
|
||||||
|
introducesOtherIdentity);
|
||||||
return new IntroductionRequestReceivedEvent(contactId, ir);
|
return new IntroductionRequestReceivedEvent(contactId, ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.briarproject.api.introduction.IntroducerAction;
|
|||||||
import org.briarproject.api.introduction.IntroducerProtocolState;
|
import org.briarproject.api.introduction.IntroducerProtocolState;
|
||||||
import org.briarproject.api.introduction.IntroductionResponse;
|
import org.briarproject.api.introduction.IntroductionResponse;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -298,14 +299,15 @@ public class IntroducerEngine
|
|||||||
|
|
||||||
SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID));
|
SessionId sessionId = new SessionId(localState.getRaw(SESSION_ID));
|
||||||
MessageId messageId = new MessageId(msg.getRaw(MESSAGE_ID));
|
MessageId messageId = new MessageId(msg.getRaw(MESSAGE_ID));
|
||||||
|
GroupId groupId = new GroupId(msg.getRaw(GROUP_ID));
|
||||||
long time = msg.getLong(MESSAGE_TIME);
|
long time = msg.getLong(MESSAGE_TIME);
|
||||||
String name = getOtherContact(localState, msg);
|
String name = getOtherContact(localState, msg);
|
||||||
boolean accept = msg.getBoolean(ACCEPT);
|
boolean accept = msg.getBoolean(ACCEPT);
|
||||||
|
|
||||||
IntroductionResponse ir =
|
IntroductionResponse ir =
|
||||||
new IntroductionResponse(sessionId, messageId, ROLE_INTRODUCER,
|
new IntroductionResponse(sessionId, messageId, groupId,
|
||||||
time, false, false, false, false, authorId, name,
|
ROLE_INTRODUCER, time, false, false, false, false,
|
||||||
accept);
|
authorId, name, accept);
|
||||||
return new IntroductionResponseReceivedEvent(contactId, ir);
|
return new IntroductionResponseReceivedEvent(contactId, ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import org.briarproject.api.sync.GroupId;
|
|||||||
import org.briarproject.api.sync.Message;
|
import org.briarproject.api.sync.Message;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.sync.MessageStatus;
|
import org.briarproject.api.sync.MessageStatus;
|
||||||
import org.briarproject.clients.BdfIncomingMessageHook;
|
import org.briarproject.clients.ConversationClientImpl;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -76,7 +76,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUE
|
|||||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||||
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
||||||
|
|
||||||
class IntroductionManagerImpl extends BdfIncomingMessageHook
|
class IntroductionManagerImpl extends ConversationClientImpl
|
||||||
implements IntroductionManager, Client, AddContactHook,
|
implements IntroductionManager, Client, AddContactHook,
|
||||||
RemoveContactHook {
|
RemoveContactHook {
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||||
try {
|
try {
|
||||||
// Create an introduction group for sending introduction messages
|
// Create an introduction group for sending introduction messages
|
||||||
Group g = introductionGroupFactory.createIntroductionGroup(c);
|
Group g = getContactGroup(c);
|
||||||
// Return if we've already set things up for this contact
|
// Return if we've already set things up for this contact
|
||||||
if (db.containsGroup(txn, g.getId())) return;
|
if (db.containsGroup(txn, g.getId())) return;
|
||||||
// Store the group and share it with the contact
|
// Store the group and share it with the contact
|
||||||
@@ -196,7 +196,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
|
|
||||||
// remove the group (all messages will be removed with it)
|
// remove the group (all messages will be removed with it)
|
||||||
// this contact won't get our abort message, but the other will
|
// this contact won't get our abort message, but the other will
|
||||||
db.removeGroup(txn, introductionGroupFactory.createIntroductionGroup(c));
|
db.removeGroup(txn, getContactGroup(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -288,6 +288,11 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Group getContactGroup(Contact contact) {
|
||||||
|
return introductionGroupFactory.createIntroductionGroup(contact);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void makeIntroduction(Contact c1, Contact c2, String msg,
|
public void makeIntroduction(Contact c1, Contact c2, String msg,
|
||||||
final long timestamp)
|
final long timestamp)
|
||||||
@@ -296,8 +301,8 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp);
|
introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp);
|
||||||
Group g1 = introductionGroupFactory.createIntroductionGroup(c1);
|
Group g1 = getContactGroup(c1);
|
||||||
Group g2 = introductionGroupFactory.createIntroductionGroup(c2);
|
Group g2 = getContactGroup(c2);
|
||||||
trackMessage(txn, g1.getId(), timestamp, true);
|
trackMessage(txn, g1.getId(), timestamp, true);
|
||||||
trackMessage(txn, g2.getId(), timestamp, true);
|
trackMessage(txn, g2.getId(), timestamp, true);
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
@@ -314,7 +319,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
Contact c = db.getContact(txn, contactId);
|
Contact c = db.getContact(txn, contactId);
|
||||||
Group g = introductionGroupFactory.createIntroductionGroup(c);
|
Group g = getContactGroup(c);
|
||||||
BdfDictionary state =
|
BdfDictionary state =
|
||||||
getSessionState(txn, g.getId(), sessionId.getBytes());
|
getSessionState(txn, g.getId(), sessionId.getBytes());
|
||||||
|
|
||||||
@@ -334,7 +339,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
Contact c = db.getContact(txn, contactId);
|
Contact c = db.getContact(txn, contactId);
|
||||||
Group g = introductionGroupFactory.createIntroductionGroup(c);
|
Group g = getContactGroup(c);
|
||||||
BdfDictionary state =
|
BdfDictionary state =
|
||||||
getSessionState(txn, g.getId(), sessionId.getBytes());
|
getSessionState(txn, g.getId(), sessionId.getBytes());
|
||||||
|
|
||||||
@@ -358,9 +363,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
Transaction txn = db.startTransaction(true);
|
Transaction txn = db.startTransaction(true);
|
||||||
try {
|
try {
|
||||||
// get messages and their status
|
// get messages and their status
|
||||||
GroupId g = introductionGroupFactory
|
GroupId g = getContactGroup(db.getContact(txn, contactId)).getId();
|
||||||
.createIntroductionGroup(db.getContact(txn, contactId))
|
|
||||||
.getId();
|
|
||||||
metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
|
metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||||
statuses = db.getMessageStatus(txn, contactId, g);
|
statuses = db.getMessageStatus(txn, contactId, g);
|
||||||
|
|
||||||
@@ -415,7 +418,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
name = state.getString(NAME);
|
name = state.getString(NAME);
|
||||||
}
|
}
|
||||||
IntroductionResponse ir = new IntroductionResponse(
|
IntroductionResponse ir = new IntroductionResponse(
|
||||||
sessionId, messageId, role, time, local,
|
sessionId, messageId, g, role, time, local,
|
||||||
s.isSent(), s.isSeen(), read, authorId, name,
|
s.isSent(), s.isSeen(), read, authorId, name,
|
||||||
accepted);
|
accepted);
|
||||||
list.add(ir);
|
list.add(ir);
|
||||||
@@ -445,7 +448,7 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook
|
|||||||
state.getBoolean(REMOTE_AUTHOR_IS_US);
|
state.getBoolean(REMOTE_AUTHOR_IS_US);
|
||||||
}
|
}
|
||||||
IntroductionRequest ir = new IntroductionRequest(
|
IntroductionRequest ir = new IntroductionRequest(
|
||||||
sessionId, messageId, role, time, local,
|
sessionId, messageId, g, role, time, local,
|
||||||
s.isSent(), s.isSeen(), read, authorId, name,
|
s.isSent(), s.isSeen(), read, authorId, name,
|
||||||
accepted, message, answered, exists,
|
accepted, message, answered, exists,
|
||||||
introducesOtherIdentity);
|
introducesOtherIdentity);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.briarproject.api.contact.ContactManager;
|
|||||||
import org.briarproject.api.data.MetadataEncoder;
|
import org.briarproject.api.data.MetadataEncoder;
|
||||||
import org.briarproject.api.introduction.IntroductionManager;
|
import org.briarproject.api.introduction.IntroductionManager;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -47,6 +48,7 @@ public class IntroductionModule {
|
|||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager,
|
||||||
ContactManager contactManager,
|
ContactManager contactManager,
|
||||||
MessageQueueManager messageQueueManager,
|
MessageQueueManager messageQueueManager,
|
||||||
|
ConversationManager conversationManager,
|
||||||
IntroductionManagerImpl introductionManager) {
|
IntroductionManagerImpl introductionManager) {
|
||||||
|
|
||||||
lifecycleManager.registerClient(introductionManager);
|
lifecycleManager.registerClient(introductionManager);
|
||||||
@@ -55,6 +57,7 @@ public class IntroductionModule {
|
|||||||
messageQueueManager.registerIncomingMessageHook(
|
messageQueueManager.registerIncomingMessageHook(
|
||||||
introductionManager.getClientId(),
|
introductionManager.getClientId(),
|
||||||
introductionManager);
|
introductionManager);
|
||||||
|
conversationManager.registerConversationClient(introductionManager);
|
||||||
|
|
||||||
return introductionManager;
|
return introductionManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package org.briarproject.messaging;
|
||||||
|
|
||||||
|
import org.briarproject.api.clients.ContactGroupFactory;
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
|
import org.briarproject.api.contact.Contact;
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.Transaction;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
|
import org.briarproject.api.sync.Group;
|
||||||
|
import org.briarproject.api.sync.GroupId;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
class ConversationManagerImpl implements ConversationManager {
|
||||||
|
|
||||||
|
private final DatabaseComponent db;
|
||||||
|
private final ContactGroupFactory contactGroupFactory;
|
||||||
|
private final Set<ConversationClient> clients;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ConversationManagerImpl(DatabaseComponent db,
|
||||||
|
ContactGroupFactory contactGroupFactory) {
|
||||||
|
this.db = db;
|
||||||
|
this.contactGroupFactory = contactGroupFactory;
|
||||||
|
clients = new CopyOnWriteArraySet<ConversationClient>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerConversationClient(ConversationClient client) {
|
||||||
|
if (!clients.add(client)) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"This client is already registered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupId getConversationId(ContactId contactId) throws DbException {
|
||||||
|
// TODO we should probably transition this to its own group
|
||||||
|
// and/or work with the ContactId in the UI instead
|
||||||
|
Contact contact;
|
||||||
|
Transaction txn = db.startTransaction(true);
|
||||||
|
try {
|
||||||
|
contact = db.getContact(txn, contactId);
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
Group group = contactGroupFactory
|
||||||
|
.createContactGroup(MessagingManagerImpl.CLIENT_ID, contact);
|
||||||
|
return group.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupCount getGroupCount(ContactId contactId)
|
||||||
|
throws DbException {
|
||||||
|
|
||||||
|
int msgCount = 0, unreadCount = 0;
|
||||||
|
long latestTime = 0;
|
||||||
|
Transaction txn = db.startTransaction(true);
|
||||||
|
try {
|
||||||
|
for (ConversationClient client : clients) {
|
||||||
|
GroupCount count = client.getGroupCount(txn, contactId);
|
||||||
|
msgCount += count.getMsgCount();
|
||||||
|
unreadCount += count.getUnreadCount();
|
||||||
|
if (count.getLatestMsgTime() > latestTime)
|
||||||
|
latestTime = count.getLatestMsgTime();
|
||||||
|
}
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
return new GroupCount(msgCount, unreadCount, latestTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ import org.briarproject.api.sync.GroupId;
|
|||||||
import org.briarproject.api.sync.Message;
|
import org.briarproject.api.sync.Message;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.sync.MessageStatus;
|
import org.briarproject.api.sync.MessageStatus;
|
||||||
import org.briarproject.clients.BdfIncomingMessageHook;
|
import org.briarproject.clients.ConversationClientImpl;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -35,7 +35,7 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
||||||
|
|
||||||
class MessagingManagerImpl extends BdfIncomingMessageHook
|
class MessagingManagerImpl extends ConversationClientImpl
|
||||||
implements MessagingManager, Client, AddContactHook, RemoveContactHook {
|
implements MessagingManager, Client, AddContactHook, RemoveContactHook {
|
||||||
|
|
||||||
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
||||||
@@ -77,7 +77,8 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Group getContactGroup(Contact c) {
|
@Override
|
||||||
|
protected Group getContactGroup(Contact c) {
|
||||||
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
|
return contactGroupFactory.createContactGroup(CLIENT_ID, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +102,8 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
|
|||||||
boolean local = meta.getBoolean("local");
|
boolean local = meta.getBoolean("local");
|
||||||
boolean read = meta.getBoolean(MSG_KEY_READ);
|
boolean read = meta.getBoolean(MSG_KEY_READ);
|
||||||
PrivateMessageHeader header = new PrivateMessageHeader(
|
PrivateMessageHeader header = new PrivateMessageHeader(
|
||||||
m.getId(), timestamp, contentType, local, read, false, false);
|
m.getId(), m.getGroupId(), timestamp, contentType, local, read,
|
||||||
|
false, false);
|
||||||
PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent(
|
PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent(
|
||||||
header, groupId);
|
header, groupId);
|
||||||
txn.attach(event);
|
txn.attach(event);
|
||||||
@@ -159,9 +161,10 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
|
|||||||
throws DbException {
|
throws DbException {
|
||||||
Map<MessageId, BdfDictionary> metadata;
|
Map<MessageId, BdfDictionary> metadata;
|
||||||
Collection<MessageStatus> statuses;
|
Collection<MessageStatus> statuses;
|
||||||
|
GroupId g;
|
||||||
Transaction txn = db.startTransaction(true);
|
Transaction txn = db.startTransaction(true);
|
||||||
try {
|
try {
|
||||||
GroupId g = getContactGroup(db.getContact(txn, c)).getId();
|
g = getContactGroup(db.getContact(txn, c)).getId();
|
||||||
metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
|
metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||||
statuses = db.getMessageStatus(txn, c, g);
|
statuses = db.getMessageStatus(txn, c, g);
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
@@ -181,8 +184,8 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
|
|||||||
String contentType = meta.getString("contentType");
|
String contentType = meta.getString("contentType");
|
||||||
boolean local = meta.getBoolean("local");
|
boolean local = meta.getBoolean("local");
|
||||||
boolean read = meta.getBoolean("read");
|
boolean read = meta.getBoolean("read");
|
||||||
headers.add(new PrivateMessageHeader(id, timestamp, contentType,
|
headers.add(new PrivateMessageHeader(id, g, timestamp,
|
||||||
local, read, s.isSent(), s.isSeen()));
|
contentType, local, read, s.isSent(), s.isSeen()));
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -201,4 +204,14 @@ class MessagingManagerImpl extends BdfIncomingMessageHook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
|
||||||
|
throws DbException {
|
||||||
|
|
||||||
|
Contact contact = db.getContact(txn, contactId);
|
||||||
|
GroupId groupId = getContactGroup(contact).getId();
|
||||||
|
|
||||||
|
return getGroupCount(txn, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.api.clients.ClientHelper;
|
|||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.data.MetadataEncoder;
|
import org.briarproject.api.data.MetadataEncoder;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
import org.briarproject.api.messaging.MessagingManager;
|
import org.briarproject.api.messaging.MessagingManager;
|
||||||
import org.briarproject.api.messaging.PrivateMessageFactory;
|
import org.briarproject.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.api.sync.ValidationManager;
|
import org.briarproject.api.sync.ValidationManager;
|
||||||
@@ -22,6 +23,7 @@ public class MessagingModule {
|
|||||||
|
|
||||||
public static class EagerSingletons {
|
public static class EagerSingletons {
|
||||||
@Inject MessagingManager messagingManager;
|
@Inject MessagingManager messagingManager;
|
||||||
|
@Inject ConversationManager conversationManager;
|
||||||
@Inject PrivateMessageValidator privateMessageValidator;
|
@Inject PrivateMessageValidator privateMessageValidator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +48,22 @@ public class MessagingModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
MessagingManager getMessagingManager(LifecycleManager lifecycleManager,
|
MessagingManager getMessagingManager(LifecycleManager lifecycleManager,
|
||||||
ContactManager contactManager, ValidationManager validationManager,
|
ContactManager contactManager, ValidationManager validationManager,
|
||||||
|
ConversationManager conversationManager,
|
||||||
MessagingManagerImpl messagingManager) {
|
MessagingManagerImpl messagingManager) {
|
||||||
lifecycleManager.registerClient(messagingManager);
|
lifecycleManager.registerClient(messagingManager);
|
||||||
contactManager.registerAddContactHook(messagingManager);
|
contactManager.registerAddContactHook(messagingManager);
|
||||||
contactManager.registerRemoveContactHook(messagingManager);
|
contactManager.registerRemoveContactHook(messagingManager);
|
||||||
validationManager
|
validationManager
|
||||||
.registerIncomingMessageHook(CLIENT_ID, messagingManager);
|
.registerIncomingMessageHook(CLIENT_ID, messagingManager);
|
||||||
|
conversationManager.registerConversationClient(messagingManager);
|
||||||
return messagingManager;
|
return messagingManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ConversationManager getConversationManager(
|
||||||
|
ConversationManagerImpl conversationManager) {
|
||||||
|
return conversationManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
|
||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
|
||||||
@@ -21,8 +23,9 @@ public class BlogInviteeSessionState extends InviteeSessionState {
|
|||||||
public BlogInviteeSessionState(SessionId sessionId, MessageId storageId,
|
public BlogInviteeSessionState(SessionId sessionId, MessageId storageId,
|
||||||
GroupId groupId, State state, ContactId contactId, GroupId blogId,
|
GroupId groupId, State state, ContactId contactId, GroupId blogId,
|
||||||
String blogTitle, String blogDesc, String blogAuthorName,
|
String blogTitle, String blogDesc, String blogAuthorName,
|
||||||
byte[] blogPublicKey) {
|
byte[] blogPublicKey, @NotNull MessageId invitationId) {
|
||||||
super(sessionId, storageId, groupId, state, contactId, blogId);
|
super(sessionId, storageId, groupId, state, contactId, blogId,
|
||||||
|
invitationId);
|
||||||
|
|
||||||
this.blogTitle = blogTitle;
|
this.blogTitle = blogTitle;
|
||||||
this.blogDesc = blogDesc;
|
this.blogDesc = blogDesc;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
|
||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
|
||||||
@@ -21,8 +22,9 @@ public class BlogSharerSessionState extends SharerSessionState {
|
|||||||
public BlogSharerSessionState(SessionId sessionId, MessageId storageId,
|
public BlogSharerSessionState(SessionId sessionId, MessageId storageId,
|
||||||
GroupId groupId, State state, ContactId contactId, GroupId blogId,
|
GroupId groupId, State state, ContactId contactId, GroupId blogId,
|
||||||
String blogTitle, String blogDesc, String blogAuthorName,
|
String blogTitle, String blogDesc, String blogAuthorName,
|
||||||
byte[] blogPublicKey) {
|
byte[] blogPublicKey, @Nullable MessageId responseId) {
|
||||||
super(sessionId, storageId, groupId, state, contactId, blogId);
|
super(sessionId, storageId, groupId, state, contactId, blogId,
|
||||||
|
responseId);
|
||||||
|
|
||||||
this.blogTitle = blogTitle;
|
this.blogTitle = blogTitle;
|
||||||
this.blogDesc = blogDesc;
|
this.blogDesc = blogDesc;
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import org.briarproject.api.blogs.BlogManager.RemoveBlogHook;
|
|||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
import org.briarproject.api.blogs.BlogSharingManager;
|
||||||
import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation;
|
import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation;
|
||||||
import org.briarproject.api.clients.ClientHelper;
|
import org.briarproject.api.clients.ClientHelper;
|
||||||
import org.briarproject.api.clients.MessageQueueManager;
|
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
import org.briarproject.api.clients.ContactGroupFactory;
|
||||||
|
import org.briarproject.api.clients.MessageQueueManager;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
@@ -43,6 +43,8 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
|
|||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
|
||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY;
|
||||||
import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE;
|
import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.RESPONSE_ID;
|
||||||
|
|
||||||
class BlogSharingManagerImpl extends
|
class BlogSharingManagerImpl extends
|
||||||
SharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent>
|
SharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent>
|
||||||
@@ -108,17 +110,18 @@ class BlogSharingManagerImpl extends
|
|||||||
BlogInvitation msg, ContactId contactId, boolean available,
|
BlogInvitation msg, ContactId contactId, boolean available,
|
||||||
long time, boolean local, boolean sent, boolean seen,
|
long time, boolean local, boolean sent, boolean seen,
|
||||||
boolean read) {
|
boolean read) {
|
||||||
return new BlogInvitationRequest(id, msg.getSessionId(), contactId,
|
return new BlogInvitationRequest(id, msg.getSessionId(),
|
||||||
msg.getBlogAuthorName(), msg.getMessage(), available, time,
|
msg.getGroupId(), contactId, msg.getBlogAuthorName(),
|
||||||
local, sent, seen, read);
|
msg.getMessage(), available, time, local, sent, seen, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InvitationMessage createInvitationResponse(MessageId id,
|
protected InvitationMessage createInvitationResponse(MessageId id,
|
||||||
SessionId sessionId, ContactId contactId, boolean accept, long time,
|
SessionId sessionId, GroupId groupId, ContactId contactId,
|
||||||
|
boolean accept, long time,
|
||||||
boolean local, boolean sent, boolean seen, boolean read) {
|
boolean local, boolean sent, boolean seen, boolean read) {
|
||||||
return new BlogInvitationResponse(id, sessionId, contactId, accept,
|
return new BlogInvitationResponse(id, sessionId, groupId, contactId,
|
||||||
time, local, sent, seen, read);
|
accept, time, local, sent, seen, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -163,7 +166,7 @@ class BlogSharingManagerImpl extends
|
|||||||
private final BlogFactory blogFactory;
|
private final BlogFactory blogFactory;
|
||||||
private final BlogManager blogManager;
|
private final BlogManager blogManager;
|
||||||
|
|
||||||
SFactory(AuthorFactory authorFactory, BlogFactory BlogFactory,
|
private SFactory(AuthorFactory authorFactory, BlogFactory BlogFactory,
|
||||||
BlogManager BlogManager) {
|
BlogManager BlogManager) {
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
this.blogFactory = BlogFactory;
|
this.blogFactory = BlogFactory;
|
||||||
@@ -230,11 +233,13 @@ class BlogSharingManagerImpl extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlogInvitation build(BlogSharerSessionState localState) {
|
public BlogInvitation build(BlogSharerSessionState localState,
|
||||||
|
long time) {
|
||||||
return new BlogInvitation(localState.getGroupId(),
|
return new BlogInvitation(localState.getGroupId(),
|
||||||
localState.getSessionId(), localState.getBlogTitle(),
|
localState.getSessionId(), localState.getBlogTitle(),
|
||||||
localState.getBlogDesc(), localState.getBlogAuthorName(),
|
localState.getBlogDesc(), localState.getBlogAuthorName(),
|
||||||
localState.getBlogPublicKey(), localState.getMessage());
|
localState.getBlogPublicKey(), time,
|
||||||
|
localState.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,20 +254,21 @@ class BlogSharingManagerImpl extends
|
|||||||
String blogDesc = d.getString(BLOG_DESC);
|
String blogDesc = d.getString(BLOG_DESC);
|
||||||
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
||||||
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
||||||
|
MessageId invitationId = new MessageId(d.getRaw(INVITATION_ID));
|
||||||
return new BlogInviteeSessionState(sessionId, storageId,
|
return new BlogInviteeSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, blogId, blogTitle, blogDesc,
|
groupId, state, contactId, blogId, blogTitle, blogDesc,
|
||||||
blogAuthorName, blogPublicKey);
|
blogAuthorName, blogPublicKey, invitationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlogInviteeSessionState build(SessionId sessionId,
|
public BlogInviteeSessionState build(SessionId sessionId,
|
||||||
MessageId storageId, GroupId groupId,
|
MessageId storageId, GroupId groupId,
|
||||||
InviteeSessionState.State state, ContactId contactId,
|
InviteeSessionState.State state, ContactId contactId,
|
||||||
Blog blog) {
|
Blog blog, MessageId invitationId) {
|
||||||
return new BlogInviteeSessionState(sessionId, storageId,
|
return new BlogInviteeSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, blog.getId(), blog.getName(),
|
groupId, state, contactId, blog.getId(), blog.getName(),
|
||||||
blog.getDescription(), blog.getAuthor().getName(),
|
blog.getDescription(), blog.getAuthor().getName(),
|
||||||
blog.getAuthor().getPublicKey());
|
blog.getAuthor().getPublicKey(), invitationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,9 +283,13 @@ class BlogSharingManagerImpl extends
|
|||||||
String blogDesc = d.getString(BLOG_DESC);
|
String blogDesc = d.getString(BLOG_DESC);
|
||||||
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
||||||
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
||||||
|
MessageId responseId = null;
|
||||||
|
byte[] responseIdBytes = d.getOptionalRaw(RESPONSE_ID);
|
||||||
|
if (responseIdBytes != null)
|
||||||
|
responseId = new MessageId(responseIdBytes);
|
||||||
return new BlogSharerSessionState(sessionId, storageId,
|
return new BlogSharerSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, blogId, blogTitle, blogDesc,
|
groupId, state, contactId, blogId, blogTitle, blogDesc,
|
||||||
blogAuthorName, blogPublicKey);
|
blogAuthorName, blogPublicKey, responseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -290,7 +300,7 @@ class BlogSharingManagerImpl extends
|
|||||||
return new BlogSharerSessionState(sessionId, storageId,
|
return new BlogSharerSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, blog.getId(), blog.getName(),
|
groupId, state, contactId, blog.getId(), blog.getName(),
|
||||||
blog.getDescription(), blog.getAuthor().getName(),
|
blog.getDescription(), blog.getAuthor().getName(),
|
||||||
blog.getAuthor().getPublicKey());
|
blog.getAuthor().getPublicKey(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,16 +309,21 @@ class BlogSharingManagerImpl extends
|
|||||||
|
|
||||||
private final SFactory sFactory;
|
private final SFactory sFactory;
|
||||||
|
|
||||||
IRFactory(SFactory sFactory) {
|
private IRFactory(SFactory sFactory) {
|
||||||
this.sFactory = sFactory;
|
this.sFactory = sFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlogInvitationReceivedEvent build(
|
public BlogInvitationReceivedEvent build(
|
||||||
BlogInviteeSessionState localState) {
|
BlogInviteeSessionState localState, long time, String msg) {
|
||||||
Blog blog = sFactory.parse(localState);
|
Blog blog = sFactory.parse(localState);
|
||||||
ContactId contactId = localState.getContactId();
|
ContactId contactId = localState.getContactId();
|
||||||
return new BlogInvitationReceivedEvent(blog, contactId);
|
BlogInvitationRequest request =
|
||||||
|
new BlogInvitationRequest(localState.getInvitationId(),
|
||||||
|
localState.getSessionId(), localState.getGroupId(),
|
||||||
|
contactId, blog.getAuthor().getName(), msg, true,
|
||||||
|
time, false, false, false, false);
|
||||||
|
return new BlogInvitationReceivedEvent(blog, contactId, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,10 +331,18 @@ class BlogSharingManagerImpl extends
|
|||||||
InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> {
|
InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> {
|
||||||
@Override
|
@Override
|
||||||
public BlogInvitationResponseReceivedEvent build(
|
public BlogInvitationResponseReceivedEvent build(
|
||||||
BlogSharerSessionState localState) {
|
BlogSharerSessionState localState, boolean accept, long time) {
|
||||||
String title = localState.getBlogTitle();
|
String title = localState.getBlogTitle();
|
||||||
ContactId c = localState.getContactId();
|
ContactId c = localState.getContactId();
|
||||||
return new BlogInvitationResponseReceivedEvent(title, c);
|
MessageId responseId = localState.getResponseId();
|
||||||
|
if (responseId == null)
|
||||||
|
throw new IllegalStateException("No responseId");
|
||||||
|
BlogInvitationResponse response =
|
||||||
|
new BlogInvitationResponse(responseId,
|
||||||
|
localState.getSessionId(), localState.getGroupId(),
|
||||||
|
localState.getContactId(), accept, time, false,
|
||||||
|
false, false, false);
|
||||||
|
return new BlogInvitationResponseReceivedEvent(title, c, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
||||||
@@ -16,8 +17,10 @@ public class ForumInviteeSessionState extends InviteeSessionState {
|
|||||||
|
|
||||||
public ForumInviteeSessionState(SessionId sessionId, MessageId storageId,
|
public ForumInviteeSessionState(SessionId sessionId, MessageId storageId,
|
||||||
GroupId groupId, State state, ContactId contactId, GroupId forumId,
|
GroupId groupId, State state, ContactId contactId, GroupId forumId,
|
||||||
String forumName, byte[] forumSalt) {
|
String forumName, byte[] forumSalt,
|
||||||
super(sessionId, storageId, groupId, state, contactId, forumId);
|
@NotNull MessageId invitationId) {
|
||||||
|
super(sessionId, storageId, groupId, state, contactId, forumId,
|
||||||
|
invitationId);
|
||||||
|
|
||||||
this.forumName = forumName;
|
this.forumName = forumName;
|
||||||
this.forumSalt = forumSalt;
|
this.forumSalt = forumSalt;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
||||||
@@ -16,8 +17,10 @@ class ForumSharerSessionState extends SharerSessionState {
|
|||||||
|
|
||||||
ForumSharerSessionState(SessionId sessionId, MessageId storageId,
|
ForumSharerSessionState(SessionId sessionId, MessageId storageId,
|
||||||
GroupId groupId, State state, ContactId contactId, GroupId forumId,
|
GroupId groupId, State state, ContactId contactId, GroupId forumId,
|
||||||
String forumName, byte[] forumSalt) {
|
String forumName, byte[] forumSalt,
|
||||||
super(sessionId, storageId, groupId, state, contactId, forumId);
|
@Nullable MessageId responseId) {
|
||||||
|
super(sessionId, storageId, groupId, state, contactId, forumId,
|
||||||
|
responseId);
|
||||||
|
|
||||||
this.forumName = forumName;
|
this.forumName = forumName;
|
||||||
this.forumSalt = forumSalt;
|
this.forumSalt = forumSalt;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package org.briarproject.sharing;
|
|||||||
|
|
||||||
import org.briarproject.api.FormatException;
|
import org.briarproject.api.FormatException;
|
||||||
import org.briarproject.api.clients.ClientHelper;
|
import org.briarproject.api.clients.ClientHelper;
|
||||||
import org.briarproject.api.clients.MessageQueueManager;
|
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
import org.briarproject.api.clients.ContactGroupFactory;
|
||||||
|
import org.briarproject.api.clients.MessageQueueManager;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
@@ -35,6 +35,8 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.RESPONSE_ID;
|
||||||
|
|
||||||
class ForumSharingManagerImpl extends
|
class ForumSharingManagerImpl extends
|
||||||
SharingManagerImpl<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent>
|
SharingManagerImpl<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent>
|
||||||
@@ -82,17 +84,18 @@ class ForumSharingManagerImpl extends
|
|||||||
ForumInvitation msg, ContactId contactId, boolean available,
|
ForumInvitation msg, ContactId contactId, boolean available,
|
||||||
long time, boolean local, boolean sent, boolean seen,
|
long time, boolean local, boolean sent, boolean seen,
|
||||||
boolean read) {
|
boolean read) {
|
||||||
return new ForumInvitationRequest(id, msg.getSessionId(), contactId,
|
return new ForumInvitationRequest(id, msg.getSessionId(),
|
||||||
msg.getForumName(), msg.getMessage(), available, time, local,
|
msg.getGroupId(), contactId, msg.getForumName(),
|
||||||
sent, seen, read);
|
msg.getMessage(), available, time, local, sent, seen, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InvitationMessage createInvitationResponse(MessageId id,
|
protected InvitationMessage createInvitationResponse(MessageId id,
|
||||||
SessionId sessionId, ContactId contactId, boolean accept,
|
SessionId sessionId, GroupId groupId, ContactId contactId,
|
||||||
long time, boolean local, boolean sent, boolean seen, boolean read) {
|
boolean accept, long time, boolean local, boolean sent,
|
||||||
return new ForumInvitationResponse(id, sessionId, contactId, accept,
|
boolean seen, boolean read) {
|
||||||
time, local, sent, seen, read);
|
return new ForumInvitationResponse(id, sessionId, groupId, contactId,
|
||||||
|
accept, time, local, sent, seen, read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -136,7 +139,7 @@ class ForumSharingManagerImpl extends
|
|||||||
private final ForumFactory forumFactory;
|
private final ForumFactory forumFactory;
|
||||||
private final ForumManager forumManager;
|
private final ForumManager forumManager;
|
||||||
|
|
||||||
SFactory(ForumFactory forumFactory, ForumManager forumManager) {
|
private SFactory(ForumFactory forumFactory, ForumManager forumManager) {
|
||||||
this.forumFactory = forumFactory;
|
this.forumFactory = forumFactory;
|
||||||
this.forumManager = forumManager;
|
this.forumManager = forumManager;
|
||||||
}
|
}
|
||||||
@@ -185,10 +188,11 @@ class ForumSharingManagerImpl extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ForumInvitation build(ForumSharerSessionState localState) {
|
public ForumInvitation build(ForumSharerSessionState localState,
|
||||||
|
long time) {
|
||||||
return new ForumInvitation(localState.getGroupId(),
|
return new ForumInvitation(localState.getGroupId(),
|
||||||
localState.getSessionId(), localState.getForumName(),
|
localState.getSessionId(), localState.getForumName(),
|
||||||
localState.getForumSalt(), localState.getMessage());
|
localState.getForumSalt(), time, localState.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,18 +205,20 @@ class ForumSharingManagerImpl extends
|
|||||||
GroupId forumId, BdfDictionary d) throws FormatException {
|
GroupId forumId, BdfDictionary d) throws FormatException {
|
||||||
String forumName = d.getString(FORUM_NAME);
|
String forumName = d.getString(FORUM_NAME);
|
||||||
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
||||||
|
MessageId invitationId = new MessageId(d.getRaw(INVITATION_ID));
|
||||||
return new ForumInviteeSessionState(sessionId, storageId,
|
return new ForumInviteeSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, forumId, forumName, forumSalt);
|
groupId, state, contactId, forumId, forumName, forumSalt,
|
||||||
|
invitationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ForumInviteeSessionState build(SessionId sessionId,
|
public ForumInviteeSessionState build(SessionId sessionId,
|
||||||
MessageId storageId, GroupId groupId,
|
MessageId storageId, GroupId groupId,
|
||||||
InviteeSessionState.State state, ContactId contactId,
|
InviteeSessionState.State state, ContactId contactId,
|
||||||
Forum forum) {
|
Forum forum, MessageId invitationId) {
|
||||||
return new ForumInviteeSessionState(sessionId, storageId,
|
return new ForumInviteeSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, forum.getId(), forum.getName(),
|
groupId, state, contactId, forum.getId(), forum.getName(),
|
||||||
forum.getSalt());
|
forum.getSalt(), invitationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,8 +231,13 @@ class ForumSharingManagerImpl extends
|
|||||||
GroupId forumId, BdfDictionary d) throws FormatException {
|
GroupId forumId, BdfDictionary d) throws FormatException {
|
||||||
String forumName = d.getString(FORUM_NAME);
|
String forumName = d.getString(FORUM_NAME);
|
||||||
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
||||||
|
MessageId responseId = null;
|
||||||
|
byte[] responseIdBytes = d.getOptionalRaw(RESPONSE_ID);
|
||||||
|
if (responseIdBytes != null)
|
||||||
|
responseId = new MessageId(responseIdBytes);
|
||||||
return new ForumSharerSessionState(sessionId, storageId,
|
return new ForumSharerSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, forumId, forumName, forumSalt);
|
groupId, state, contactId, forumId, forumName, forumSalt,
|
||||||
|
responseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -236,7 +247,7 @@ class ForumSharingManagerImpl extends
|
|||||||
Forum forum) {
|
Forum forum) {
|
||||||
return new ForumSharerSessionState(sessionId, storageId,
|
return new ForumSharerSessionState(sessionId, storageId,
|
||||||
groupId, state, contactId, forum.getId(), forum.getName(),
|
groupId, state, contactId, forum.getId(), forum.getName(),
|
||||||
forum.getSalt());
|
forum.getSalt(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,16 +256,20 @@ class ForumSharingManagerImpl extends
|
|||||||
|
|
||||||
private final SFactory sFactory;
|
private final SFactory sFactory;
|
||||||
|
|
||||||
IRFactory(SFactory sFactory) {
|
private IRFactory(SFactory sFactory) {
|
||||||
this.sFactory = sFactory;
|
this.sFactory = sFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ForumInvitationReceivedEvent build(
|
public ForumInvitationReceivedEvent build(
|
||||||
ForumInviteeSessionState localState) {
|
ForumInviteeSessionState localState, long time, String msg) {
|
||||||
Forum forum = sFactory.parse(localState);
|
Forum forum = sFactory.parse(localState);
|
||||||
ContactId contactId = localState.getContactId();
|
ContactId contactId = localState.getContactId();
|
||||||
return new ForumInvitationReceivedEvent(forum, contactId);
|
ForumInvitationRequest request = new ForumInvitationRequest(
|
||||||
|
localState.getInvitationId(), localState.getSessionId(),
|
||||||
|
localState.getGroupId(), contactId, forum.getName(), msg,
|
||||||
|
true, time, false, false, false, false);
|
||||||
|
return new ForumInvitationReceivedEvent(forum, contactId, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,10 +277,17 @@ class ForumSharingManagerImpl extends
|
|||||||
InvitationResponseReceivedEventFactory<ForumSharerSessionState, ForumInvitationResponseReceivedEvent> {
|
InvitationResponseReceivedEventFactory<ForumSharerSessionState, ForumInvitationResponseReceivedEvent> {
|
||||||
@Override
|
@Override
|
||||||
public ForumInvitationResponseReceivedEvent build(
|
public ForumInvitationResponseReceivedEvent build(
|
||||||
ForumSharerSessionState localState) {
|
ForumSharerSessionState localState, boolean accept, long time) {
|
||||||
String name = localState.getForumName();
|
String name = localState.getForumName();
|
||||||
ContactId c = localState.getContactId();
|
ContactId c = localState.getContactId();
|
||||||
return new ForumInvitationResponseReceivedEvent(name, c);
|
MessageId responseId = localState.getResponseId();
|
||||||
|
if (responseId == null)
|
||||||
|
throw new IllegalStateException("No responseId");
|
||||||
|
ForumInvitationResponse response = new ForumInvitationResponse(
|
||||||
|
responseId, localState.getSessionId(),
|
||||||
|
localState.getGroupId(), localState.getContactId(), accept,
|
||||||
|
time, false, false, false, false);
|
||||||
|
return new ForumInvitationResponseReceivedEvent(name, c, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ import org.briarproject.api.sharing.SharingMessage;
|
|||||||
public interface InvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState> extends
|
public interface InvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState> extends
|
||||||
org.briarproject.api.sharing.InvitationFactory<I> {
|
org.briarproject.api.sharing.InvitationFactory<I> {
|
||||||
|
|
||||||
I build(SS localState);
|
I build(SS localState, long time);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.briarproject.sharing;
|
package org.briarproject.sharing;
|
||||||
|
|
||||||
import org.briarproject.api.event.InvitationReceivedEvent;
|
import org.briarproject.api.event.InvitationRequestReceivedEvent;
|
||||||
|
|
||||||
public interface InvitationReceivedEventFactory<IS extends InviteeSessionState, IR extends InvitationReceivedEvent> {
|
public interface InvitationReceivedEventFactory<IS extends InviteeSessionState, IR extends InvitationRequestReceivedEvent> {
|
||||||
|
|
||||||
IR build(IS localState);
|
IR build(IS localState, long time, String msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
|||||||
|
|
||||||
public interface InvitationResponseReceivedEventFactory<SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> {
|
public interface InvitationResponseReceivedEventFactory<SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> {
|
||||||
|
|
||||||
IRR build(SS localState);
|
IRR build(SS localState, boolean accept, long time);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package org.briarproject.sharing;
|
|||||||
import org.briarproject.api.FormatException;
|
import org.briarproject.api.FormatException;
|
||||||
import org.briarproject.api.clients.ProtocolEngine;
|
import org.briarproject.api.clients.ProtocolEngine;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.InvitationReceivedEvent;
|
import org.briarproject.api.event.InvitationRequestReceivedEvent;
|
||||||
|
import org.briarproject.api.sharing.SharingMessage.Invitation;
|
||||||
|
import org.briarproject.api.system.Clock;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -23,16 +25,20 @@ import static org.briarproject.api.sharing.SharingConstants.TASK_UNSHARE_SHAREAB
|
|||||||
import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
|
import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
|
||||||
import static org.briarproject.api.sharing.SharingMessage.SimpleMessage;
|
import static org.briarproject.api.sharing.SharingMessage.SimpleMessage;
|
||||||
|
|
||||||
class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceivedEvent>
|
class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationRequestReceivedEvent>
|
||||||
implements ProtocolEngine<InviteeSessionState.Action, IS, BaseMessage> {
|
implements ProtocolEngine<InviteeSessionState.Action, IS, BaseMessage> {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(InviteeEngine.class.getName());
|
Logger.getLogger(InviteeEngine.class.getName());
|
||||||
|
|
||||||
private final InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory;
|
private final InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory;
|
||||||
|
private final Clock clock;
|
||||||
|
|
||||||
InviteeEngine(InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory) {
|
InviteeEngine(
|
||||||
|
InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory,
|
||||||
|
Clock clock) {
|
||||||
this.invitationReceivedEventFactory = invitationReceivedEventFactory;
|
this.invitationReceivedEventFactory = invitationReceivedEventFactory;
|
||||||
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -63,19 +69,22 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
|
|||||||
if (action == InviteeSessionState.Action.LOCAL_ACCEPT) {
|
if (action == InviteeSessionState.Action.LOCAL_ACCEPT) {
|
||||||
localState.setTask(TASK_ADD_SHARED_SHAREABLE);
|
localState.setTask(TASK_ADD_SHARED_SHAREABLE);
|
||||||
msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT,
|
msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT,
|
||||||
localState.getGroupId(), localState.getSessionId());
|
localState.getGroupId(), localState.getSessionId(),
|
||||||
|
clock.currentTimeMillis());
|
||||||
} else {
|
} else {
|
||||||
localState.setTask(
|
localState.setTask(
|
||||||
TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US);
|
TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US);
|
||||||
msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE,
|
msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE,
|
||||||
localState.getGroupId(), localState.getSessionId());
|
localState.getGroupId(), localState.getSessionId(),
|
||||||
|
clock.currentTimeMillis());
|
||||||
}
|
}
|
||||||
messages = Collections.singletonList(msg);
|
messages = Collections.singletonList(msg);
|
||||||
logLocalAction(currentState, localState, msg);
|
logLocalAction(currentState, localState, msg);
|
||||||
}
|
}
|
||||||
else if (action == InviteeSessionState.Action.LOCAL_LEAVE) {
|
else if (action == InviteeSessionState.Action.LOCAL_LEAVE) {
|
||||||
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
|
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
|
||||||
localState.getGroupId(), localState.getSessionId());
|
localState.getGroupId(), localState.getSessionId(),
|
||||||
|
clock.currentTimeMillis());
|
||||||
messages = Collections.singletonList(msg);
|
messages = Collections.singletonList(msg);
|
||||||
logLocalAction(currentState, localState, msg);
|
logLocalAction(currentState, localState, msg);
|
||||||
}
|
}
|
||||||
@@ -133,7 +142,9 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
|
|||||||
// we have just received our invitation
|
// we have just received our invitation
|
||||||
else if (action == InviteeSessionState.Action.REMOTE_INVITATION) {
|
else if (action == InviteeSessionState.Action.REMOTE_INVITATION) {
|
||||||
localState.setTask(TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US);
|
localState.setTask(TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US);
|
||||||
Event event = invitationReceivedEventFactory.build(localState);
|
Invitation invitation = (Invitation) msg;
|
||||||
|
Event event = invitationReceivedEventFactory.build(localState,
|
||||||
|
msg.getTime(), invitation.getMessage());
|
||||||
events = Collections.singletonList(event);
|
events = Collections.singletonList(event);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -203,7 +214,7 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
|
|||||||
localState.setState(InviteeSessionState.State.ERROR);
|
localState.setState(InviteeSessionState.State.ERROR);
|
||||||
BaseMessage msg =
|
BaseMessage msg =
|
||||||
new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getGroupId(),
|
new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getGroupId(),
|
||||||
localState.getSessionId());
|
localState.getSessionId(), clock.currentTimeMillis());
|
||||||
List<BaseMessage> messages = Collections.singletonList(msg);
|
List<BaseMessage> messages = Collections.singletonList(msg);
|
||||||
|
|
||||||
List<Event> events = Collections.emptyList();
|
List<Event> events = Collections.emptyList();
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
|
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||||
@@ -21,19 +23,23 @@ import static org.briarproject.sharing.InviteeSessionState.Action.REMOTE_LEAVE;
|
|||||||
public abstract class InviteeSessionState extends SharingSessionState {
|
public abstract class InviteeSessionState extends SharingSessionState {
|
||||||
|
|
||||||
private State state;
|
private State state;
|
||||||
|
@NotNull
|
||||||
|
private final MessageId invitationId;
|
||||||
|
|
||||||
public InviteeSessionState(SessionId sessionId, MessageId storageId,
|
public InviteeSessionState(SessionId sessionId, MessageId storageId,
|
||||||
GroupId groupId, State state, ContactId contactId,
|
GroupId groupId, State state, ContactId contactId,
|
||||||
GroupId shareableId) {
|
GroupId shareableId, @NotNull MessageId invitationId) {
|
||||||
|
|
||||||
super(sessionId, storageId, groupId, contactId, shareableId);
|
super(sessionId, storageId, groupId, contactId, shareableId);
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
this.invitationId = invitationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary toBdfDictionary() {
|
public BdfDictionary toBdfDictionary() {
|
||||||
BdfDictionary d = super.toBdfDictionary();
|
BdfDictionary d = super.toBdfDictionary();
|
||||||
d.put(STATE, getState().getValue());
|
d.put(STATE, getState().getValue());
|
||||||
d.put(IS_SHARER, false);
|
d.put(IS_SHARER, false);
|
||||||
|
d.put(INVITATION_ID, invitationId);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +51,11 @@ public abstract class InviteeSessionState extends SharingSessionState {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public MessageId getInvitationId() {
|
||||||
|
return invitationId;
|
||||||
|
}
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
ERROR(0),
|
ERROR(0),
|
||||||
AWAIT_INVITATION(1) {
|
AWAIT_INVITATION(1) {
|
||||||
|
|||||||
@@ -15,5 +15,6 @@ public interface InviteeSessionStateFactory<S extends Shareable, IS extends Invi
|
|||||||
GroupId shareableId, BdfDictionary d) throws FormatException;
|
GroupId shareableId, BdfDictionary d) throws FormatException;
|
||||||
|
|
||||||
IS build(SessionId sessionId, MessageId storageId, GroupId groupId,
|
IS build(SessionId sessionId, MessageId storageId, GroupId groupId,
|
||||||
InviteeSessionState.State state, ContactId contactId, S shareable);
|
InviteeSessionState.State state, ContactId contactId, S shareable,
|
||||||
|
MessageId invitationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
|
|||||||
import org.briarproject.api.clients.ProtocolEngine;
|
import org.briarproject.api.clients.ProtocolEngine;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
||||||
|
import org.briarproject.api.system.Clock;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -22,6 +23,8 @@ import static org.briarproject.api.sharing.SharingConstants.TASK_UNSHARE_SHAREAB
|
|||||||
import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
|
import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
|
||||||
import static org.briarproject.api.sharing.SharingMessage.Invitation;
|
import static org.briarproject.api.sharing.SharingMessage.Invitation;
|
||||||
import static org.briarproject.api.sharing.SharingMessage.SimpleMessage;
|
import static org.briarproject.api.sharing.SharingMessage.SimpleMessage;
|
||||||
|
import static org.briarproject.sharing.SharerSessionState.Action.REMOTE_ACCEPT;
|
||||||
|
import static org.briarproject.sharing.SharerSessionState.Action.REMOTE_DECLINE;
|
||||||
|
|
||||||
class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent>
|
class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent>
|
||||||
implements ProtocolEngine<SharerSessionState.Action, SS, BaseMessage> {
|
implements ProtocolEngine<SharerSessionState.Action, SS, BaseMessage> {
|
||||||
@@ -32,12 +35,15 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
|
|||||||
private final InvitationFactory<I, SS> invitationFactory;
|
private final InvitationFactory<I, SS> invitationFactory;
|
||||||
private final InvitationResponseReceivedEventFactory<SS, IRR>
|
private final InvitationResponseReceivedEventFactory<SS, IRR>
|
||||||
invitationResponseReceivedEventFactory;
|
invitationResponseReceivedEventFactory;
|
||||||
|
private final Clock clock;
|
||||||
|
|
||||||
SharerEngine(InvitationFactory<I, SS> invitationFactory,
|
SharerEngine(InvitationFactory<I, SS> invitationFactory,
|
||||||
InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory) {
|
InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory,
|
||||||
|
Clock clock) {
|
||||||
this.invitationFactory = invitationFactory;
|
this.invitationFactory = invitationFactory;
|
||||||
this.invitationResponseReceivedEventFactory =
|
this.invitationResponseReceivedEventFactory =
|
||||||
invitationResponseReceivedEventFactory;
|
invitationResponseReceivedEventFactory;
|
||||||
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -65,7 +71,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
|
|||||||
List<Event> events = Collections.emptyList();
|
List<Event> events = Collections.emptyList();
|
||||||
|
|
||||||
if (action == SharerSessionState.Action.LOCAL_INVITATION) {
|
if (action == SharerSessionState.Action.LOCAL_INVITATION) {
|
||||||
BaseMessage msg = invitationFactory.build(localState);
|
BaseMessage msg = invitationFactory.build(localState,
|
||||||
|
clock.currentTimeMillis());
|
||||||
messages = Collections.singletonList(msg);
|
messages = Collections.singletonList(msg);
|
||||||
logLocalAction(currentState, nextState, msg);
|
logLocalAction(currentState, nextState, msg);
|
||||||
|
|
||||||
@@ -74,7 +81,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
|
|||||||
.setTask(TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US);
|
.setTask(TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US);
|
||||||
} else if (action == SharerSessionState.Action.LOCAL_LEAVE) {
|
} else if (action == SharerSessionState.Action.LOCAL_LEAVE) {
|
||||||
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
|
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
|
||||||
localState.getGroupId(), localState.getSessionId());
|
localState.getGroupId(), localState.getSessionId(),
|
||||||
|
clock.currentTimeMillis());
|
||||||
messages = Collections.singletonList(msg);
|
messages = Collections.singletonList(msg);
|
||||||
logLocalAction(currentState, nextState, msg);
|
logLocalAction(currentState, nextState, msg);
|
||||||
} else {
|
} else {
|
||||||
@@ -122,9 +130,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
|
|||||||
deleteMsg = true;
|
deleteMsg = true;
|
||||||
}
|
}
|
||||||
// we have sent our invitation and just got a response
|
// we have sent our invitation and just got a response
|
||||||
else if (action == SharerSessionState.Action.REMOTE_ACCEPT ||
|
else if (action == REMOTE_ACCEPT || action == REMOTE_DECLINE) {
|
||||||
action == SharerSessionState.Action.REMOTE_DECLINE) {
|
if (action == REMOTE_ACCEPT) {
|
||||||
if (action == SharerSessionState.Action.REMOTE_ACCEPT) {
|
|
||||||
localState.setTask(TASK_SHARE_SHAREABLE);
|
localState.setTask(TASK_SHARE_SHAREABLE);
|
||||||
} else {
|
} else {
|
||||||
// this ensures that the forum can be shared again
|
// this ensures that the forum can be shared again
|
||||||
@@ -132,7 +139,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
|
|||||||
TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US);
|
TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US);
|
||||||
}
|
}
|
||||||
Event event = invitationResponseReceivedEventFactory
|
Event event = invitationResponseReceivedEventFactory
|
||||||
.build(localState);
|
.build(localState, action == REMOTE_ACCEPT,
|
||||||
|
msg.getTime());
|
||||||
events = Collections.singletonList(event);
|
events = Collections.singletonList(event);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Bad state");
|
throw new IllegalArgumentException("Bad state");
|
||||||
@@ -204,7 +212,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
|
|||||||
|
|
||||||
localState.setState(SharerSessionState.State.ERROR);
|
localState.setState(SharerSessionState.State.ERROR);
|
||||||
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT,
|
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT,
|
||||||
localState.getGroupId(), localState.getSessionId());
|
localState.getGroupId(), localState.getSessionId(),
|
||||||
|
clock.currentTimeMillis());
|
||||||
List<BaseMessage> messages = Collections.singletonList(msg);
|
List<BaseMessage> messages = Collections.singletonList(msg);
|
||||||
|
|
||||||
List<Event> events = Collections.emptyList();
|
List<Event> events = Collections.emptyList();
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import org.briarproject.api.contact.ContactId;
|
|||||||
import org.briarproject.api.data.BdfDictionary;
|
import org.briarproject.api.data.BdfDictionary;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
|
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
|
||||||
|
import static org.briarproject.api.sharing.SharingConstants.RESPONSE_ID;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||||
@@ -22,20 +24,25 @@ import static org.briarproject.sharing.SharerSessionState.Action.REMOTE_LEAVE;
|
|||||||
public abstract class SharerSessionState extends SharingSessionState {
|
public abstract class SharerSessionState extends SharingSessionState {
|
||||||
|
|
||||||
private State state;
|
private State state;
|
||||||
|
@Nullable
|
||||||
private String msg = null;
|
private String msg = null;
|
||||||
|
@Nullable
|
||||||
|
private MessageId responseId;
|
||||||
|
|
||||||
public SharerSessionState(SessionId sessionId, MessageId storageId,
|
public SharerSessionState(SessionId sessionId, MessageId storageId,
|
||||||
GroupId groupId, State state, ContactId contactId,
|
GroupId groupId, State state, ContactId contactId,
|
||||||
GroupId shareableId) {
|
GroupId shareableId, @Nullable MessageId responseId) {
|
||||||
|
|
||||||
super(sessionId, storageId, groupId, contactId, shareableId);
|
super(sessionId, storageId, groupId, contactId, shareableId);
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
this.responseId = responseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary toBdfDictionary() {
|
public BdfDictionary toBdfDictionary() {
|
||||||
BdfDictionary d = super.toBdfDictionary();
|
BdfDictionary d = super.toBdfDictionary();
|
||||||
d.put(STATE, getState().getValue());
|
d.put(STATE, getState().getValue());
|
||||||
d.put(IS_SHARER, true);
|
d.put(IS_SHARER, true);
|
||||||
|
if (responseId != null) d.put(RESPONSE_ID, responseId);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +62,15 @@ public abstract class SharerSessionState extends SharingSessionState {
|
|||||||
return this.msg;
|
return this.msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResponseId(@Nullable MessageId responseId) {
|
||||||
|
this.responseId = responseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public MessageId getResponseId() {
|
||||||
|
return responseId;
|
||||||
|
}
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
ERROR(0),
|
ERROR(0),
|
||||||
PREPARE_INVITATION(1) {
|
PREPARE_INVITATION(1) {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import org.briarproject.api.Bytes;
|
|||||||
import org.briarproject.api.FormatException;
|
import org.briarproject.api.FormatException;
|
||||||
import org.briarproject.api.clients.Client;
|
import org.briarproject.api.clients.Client;
|
||||||
import org.briarproject.api.clients.ClientHelper;
|
import org.briarproject.api.clients.ClientHelper;
|
||||||
import org.briarproject.api.clients.MessageQueueManager;
|
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
import org.briarproject.api.clients.ContactGroupFactory;
|
||||||
|
import org.briarproject.api.clients.MessageQueueManager;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
@@ -22,7 +22,7 @@ import org.briarproject.api.db.Metadata;
|
|||||||
import org.briarproject.api.db.NoSuchMessageException;
|
import org.briarproject.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.InvitationReceivedEvent;
|
import org.briarproject.api.event.InvitationRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
import org.briarproject.api.event.InvitationResponseReceivedEvent;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.sharing.InvitationItem;
|
import org.briarproject.api.sharing.InvitationItem;
|
||||||
@@ -36,7 +36,7 @@ import org.briarproject.api.sync.Message;
|
|||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.sync.MessageStatus;
|
import org.briarproject.api.sync.MessageStatus;
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.clients.BdfIncomingMessageHook;
|
import org.briarproject.clients.ConversationClientImpl;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -85,8 +85,8 @@ import static org.briarproject.api.sharing.SharingMessage.Invitation;
|
|||||||
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
|
||||||
import static org.briarproject.sharing.InviteeSessionState.State.AWAIT_LOCAL_RESPONSE;
|
import static org.briarproject.sharing.InviteeSessionState.State.AWAIT_LOCAL_RESPONSE;
|
||||||
|
|
||||||
abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS extends InviteeSessionState, SS extends SharerSessionState, IR extends InvitationReceivedEvent, IRR extends InvitationResponseReceivedEvent>
|
abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS extends InviteeSessionState, SS extends SharerSessionState, IR extends InvitationRequestReceivedEvent, IRR extends InvitationResponseReceivedEvent>
|
||||||
extends BdfIncomingMessageHook
|
extends ConversationClientImpl
|
||||||
implements SharingManager<S>, Client, AddContactHook,
|
implements SharingManager<S>, Client, AddContactHook,
|
||||||
RemoveContactHook {
|
RemoveContactHook {
|
||||||
|
|
||||||
@@ -117,13 +117,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
|
|
||||||
public abstract ClientId getClientId();
|
public abstract ClientId getClientId();
|
||||||
|
|
||||||
protected abstract InvitationMessage createInvitationRequest(MessageId id, I msg,
|
protected abstract InvitationMessage createInvitationRequest(MessageId id,
|
||||||
ContactId contactId, boolean available, long time, boolean local,
|
I msg, ContactId contactId, boolean available, long time,
|
||||||
boolean sent, boolean seen, boolean read);
|
boolean local, boolean sent, boolean seen, boolean read);
|
||||||
|
|
||||||
protected abstract InvitationMessage createInvitationResponse(MessageId id,
|
protected abstract InvitationMessage createInvitationResponse(MessageId id,
|
||||||
SessionId sessionId, ContactId contactId, boolean accept, long time,
|
SessionId sessionId, GroupId groupId, ContactId contactId,
|
||||||
boolean local, boolean sent, boolean seen, boolean read);
|
boolean accept, long time, boolean local, boolean sent,
|
||||||
|
boolean seen, boolean read);
|
||||||
|
|
||||||
protected abstract ShareableFactory<S, I, IS, SS> getSFactory();
|
protected abstract ShareableFactory<S, I, IS, SS> getSFactory();
|
||||||
|
|
||||||
@@ -219,9 +220,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
checkForRaceCondition(txn, f, contact);
|
checkForRaceCondition(txn, f, contact);
|
||||||
|
|
||||||
// initialize state and process invitation
|
// initialize state and process invitation
|
||||||
IS state = initializeInviteeState(txn, contactId, invitation);
|
IS state = initializeInviteeState(txn, contactId, invitation,
|
||||||
|
m.getId());
|
||||||
InviteeEngine<IS, IR> engine =
|
InviteeEngine<IS, IR> engine =
|
||||||
new InviteeEngine<IS, IR>(getIRFactory());
|
new InviteeEngine<IS, IR>(getIRFactory(), clock);
|
||||||
processInviteeStateUpdate(txn, m.getId(),
|
processInviteeStateUpdate(txn, m.getId(),
|
||||||
engine.onMessageReceived(state, msg));
|
engine.onMessageReceived(state, msg));
|
||||||
trackIncomingMessage(txn, m);
|
trackIncomingMessage(txn, m);
|
||||||
@@ -233,9 +235,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
msg.getType() == SHARE_MSG_TYPE_DECLINE) {
|
msg.getType() == SHARE_MSG_TYPE_DECLINE) {
|
||||||
// we are a sharer who just received a response
|
// we are a sharer who just received a response
|
||||||
SS state = getSessionStateForSharer(txn, sessionId);
|
SS state = getSessionStateForSharer(txn, sessionId);
|
||||||
|
state.setResponseId(m.getId());
|
||||||
SharerEngine<I, SS, IRR> engine =
|
SharerEngine<I, SS, IRR> engine =
|
||||||
new SharerEngine<I, SS, IRR>(getIFactory(),
|
new SharerEngine<I, SS, IRR>(getIFactory(),
|
||||||
getIRRFactory());
|
getIRRFactory(), clock);
|
||||||
processSharerStateUpdate(txn, m.getId(),
|
processSharerStateUpdate(txn, m.getId(),
|
||||||
engine.onMessageReceived(state, msg));
|
engine.onMessageReceived(state, msg));
|
||||||
trackIncomingMessage(txn, m);
|
trackIncomingMessage(txn, m);
|
||||||
@@ -248,14 +251,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
SS state = (SS) s;
|
SS state = (SS) s;
|
||||||
SharerEngine<I, SS, IRR> engine =
|
SharerEngine<I, SS, IRR> engine =
|
||||||
new SharerEngine<I, SS, IRR>(getIFactory(),
|
new SharerEngine<I, SS, IRR>(getIFactory(),
|
||||||
getIRRFactory());
|
getIRRFactory(), clock);
|
||||||
processSharerStateUpdate(txn, m.getId(),
|
processSharerStateUpdate(txn, m.getId(),
|
||||||
engine.onMessageReceived(state, msg));
|
engine.onMessageReceived(state, msg));
|
||||||
} else {
|
} else {
|
||||||
// we are an invitee and the sharer wants to leave or abort
|
// we are an invitee and the sharer wants to leave or abort
|
||||||
IS state = (IS) s;
|
IS state = (IS) s;
|
||||||
InviteeEngine<IS, IR> engine =
|
InviteeEngine<IS, IR> engine =
|
||||||
new InviteeEngine<IS, IR>(getIRFactory());
|
new InviteeEngine<IS, IR>(getIRFactory(), clock);
|
||||||
processInviteeStateUpdate(txn, m.getId(),
|
processInviteeStateUpdate(txn, m.getId(),
|
||||||
engine.onMessageReceived(state, msg));
|
engine.onMessageReceived(state, msg));
|
||||||
}
|
}
|
||||||
@@ -285,13 +288,15 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
// start engine and process its state update
|
// start engine and process its state update
|
||||||
SharerEngine<I, SS, IRR> engine =
|
SharerEngine<I, SS, IRR> engine =
|
||||||
new SharerEngine<I, SS, IRR>(getIFactory(),
|
new SharerEngine<I, SS, IRR>(getIFactory(),
|
||||||
getIRRFactory());
|
getIRRFactory(), clock);
|
||||||
processSharerStateUpdate(txn, null,
|
StateUpdate<SS, BaseMessage> update =
|
||||||
engine.onLocalAction(localState,
|
engine.onLocalAction(localState,
|
||||||
SharerSessionState.Action.LOCAL_INVITATION));
|
SharerSessionState.Action.LOCAL_INVITATION);
|
||||||
|
processSharerStateUpdate(txn, null, update);
|
||||||
|
|
||||||
// track message
|
// track message
|
||||||
long time = clock.currentTimeMillis();
|
// TODO handle this properly without engine hacks (#376)
|
||||||
|
long time = update.toSend.get(0).getTime();
|
||||||
trackMessage(txn, localState.getGroupId(), time, true);
|
trackMessage(txn, localState.getGroupId(), time, true);
|
||||||
|
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
@@ -321,12 +326,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
|
|
||||||
// start engine and process its state update
|
// start engine and process its state update
|
||||||
InviteeEngine<IS, IR> engine =
|
InviteeEngine<IS, IR> engine =
|
||||||
new InviteeEngine<IS, IR>(getIRFactory());
|
new InviteeEngine<IS, IR>(getIRFactory(), clock);
|
||||||
processInviteeStateUpdate(txn, null,
|
StateUpdate<IS, BaseMessage> update =
|
||||||
engine.onLocalAction(localState, localAction));
|
engine.onLocalAction(localState, localAction);
|
||||||
|
processInviteeStateUpdate(txn, null, update);
|
||||||
|
|
||||||
// track message
|
// track message
|
||||||
long time = clock.currentTimeMillis();
|
// TODO handle this properly without engine hacks (#376)
|
||||||
|
long time = update.toSend.get(0).getTime();
|
||||||
trackMessage(txn, localState.getGroupId(), time, true);
|
trackMessage(txn, localState.getGroupId(), time, true);
|
||||||
|
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
@@ -387,8 +394,9 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
.from(getIFactory(), group.getId(), d);
|
.from(getIFactory(), group.getId(), d);
|
||||||
SessionId sessionId = msg.getSessionId();
|
SessionId sessionId = msg.getSessionId();
|
||||||
InvitationMessage im = createInvitationResponse(
|
InvitationMessage im = createInvitationResponse(
|
||||||
m.getKey(), sessionId, contactId, accept, time,
|
m.getKey(), sessionId, group.getId(), contactId,
|
||||||
local, status.isSent(), status.isSeen(), read);
|
accept, time, local, status.isSent(),
|
||||||
|
status.isSeen(), read);
|
||||||
list.add(im);
|
list.add(im);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -555,6 +563,16 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
|
||||||
|
throws DbException {
|
||||||
|
|
||||||
|
Contact contact = db.getContact(txn, contactId);
|
||||||
|
GroupId groupId = getContactGroup(contact).getId();
|
||||||
|
|
||||||
|
return getGroupCount(txn, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
void removingShareable(Transaction txn, S f) throws DbException {
|
void removingShareable(Transaction txn, S f) throws DbException {
|
||||||
try {
|
try {
|
||||||
for (Contact c : db.getContacts(txn)) {
|
for (Contact c : db.getContacts(txn)) {
|
||||||
@@ -642,7 +660,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IS initializeInviteeState(Transaction txn,
|
private IS initializeInviteeState(Transaction txn,
|
||||||
ContactId contactId, I msg)
|
ContactId contactId, I msg, MessageId id)
|
||||||
throws FormatException, DbException {
|
throws FormatException, DbException {
|
||||||
|
|
||||||
Contact c = db.getContact(txn, contactId);
|
Contact c = db.getContact(txn, contactId);
|
||||||
@@ -656,9 +674,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
Message m = clientHelper.createMessage(localGroup.getId(), now,
|
Message m = clientHelper.createMessage(localGroup.getId(), now,
|
||||||
BdfList.of(mSalt));
|
BdfList.of(mSalt));
|
||||||
|
|
||||||
IS s = getISFactory().build(msg.getSessionId(),
|
IS s = getISFactory()
|
||||||
m.getId(), group.getId(),
|
.build(msg.getSessionId(), m.getId(), group.getId(),
|
||||||
InviteeSessionState.State.AWAIT_INVITATION, contactId, f);
|
InviteeSessionState.State.AWAIT_INVITATION, contactId,
|
||||||
|
f, id);
|
||||||
|
|
||||||
// save local state to database
|
// save local state to database
|
||||||
BdfDictionary d = s.toBdfDictionary();
|
BdfDictionary d = s.toBdfDictionary();
|
||||||
@@ -898,19 +917,19 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
|
|
||||||
byte[] body = clientHelper.toByteArray(m.toBdfList());
|
byte[] body = clientHelper.toByteArray(m.toBdfList());
|
||||||
Group group = db.getGroup(txn, m.getGroupId());
|
Group group = db.getGroup(txn, m.getGroupId());
|
||||||
long timestamp = clock.currentTimeMillis();
|
|
||||||
|
|
||||||
// add message itself as metadata
|
// add message itself as metadata
|
||||||
BdfDictionary d = m.toBdfDictionary();
|
BdfDictionary d = m.toBdfDictionary();
|
||||||
d.put(LOCAL, true);
|
d.put(LOCAL, true);
|
||||||
d.put(TIME, timestamp);
|
d.put(TIME, m.getTime());
|
||||||
Metadata meta = metadataEncoder.encode(d);
|
Metadata meta = metadataEncoder.encode(d);
|
||||||
|
|
||||||
messageQueueManager
|
messageQueueManager
|
||||||
.sendMessage(txn, group, timestamp, body, meta);
|
.sendMessage(txn, group, m.getTime(), body, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Group getContactGroup(Contact c) {
|
@Override
|
||||||
|
protected Group getContactGroup(Contact c) {
|
||||||
return contactGroupFactory.createContactGroup(getClientId(), c);
|
return contactGroupFactory.createContactGroup(getClientId(), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,14 +949,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
|
|||||||
SharerSessionState.Action.LOCAL_LEAVE;
|
SharerSessionState.Action.LOCAL_LEAVE;
|
||||||
SharerEngine<I, SS, IRR> engine =
|
SharerEngine<I, SS, IRR> engine =
|
||||||
new SharerEngine<I, SS, IRR>(getIFactory(),
|
new SharerEngine<I, SS, IRR>(getIFactory(),
|
||||||
getIRRFactory());
|
getIRRFactory(), clock);
|
||||||
processSharerStateUpdate(txn, null,
|
processSharerStateUpdate(txn, null,
|
||||||
engine.onLocalAction((SS) state, action));
|
engine.onLocalAction((SS) state, action));
|
||||||
} else {
|
} else {
|
||||||
InviteeSessionState.Action action =
|
InviteeSessionState.Action action =
|
||||||
InviteeSessionState.Action.LOCAL_LEAVE;
|
InviteeSessionState.Action.LOCAL_LEAVE;
|
||||||
InviteeEngine<IS, IR> engine =
|
InviteeEngine<IS, IR> engine =
|
||||||
new InviteeEngine<IS, IR>(getIRFactory());
|
new InviteeEngine<IS, IR>(getIRFactory(), clock);
|
||||||
processInviteeStateUpdate(txn, null,
|
processInviteeStateUpdate(txn, null,
|
||||||
engine.onLocalAction((IS) state, action));
|
engine.onLocalAction((IS) state, action));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.briarproject.api.data.MetadataEncoder;
|
|||||||
import org.briarproject.api.forum.ForumManager;
|
import org.briarproject.api.forum.ForumManager;
|
||||||
import org.briarproject.api.forum.ForumSharingManager;
|
import org.briarproject.api.forum.ForumSharingManager;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.api.messaging.ConversationManager;
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -52,6 +53,7 @@ public class SharingModule {
|
|||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager,
|
||||||
ContactManager contactManager,
|
ContactManager contactManager,
|
||||||
MessageQueueManager messageQueueManager,
|
MessageQueueManager messageQueueManager,
|
||||||
|
ConversationManager conversationManager,
|
||||||
BlogManager blogManager,
|
BlogManager blogManager,
|
||||||
BlogSharingManagerImpl blogSharingManager) {
|
BlogSharingManagerImpl blogSharingManager) {
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ public class SharingModule {
|
|||||||
contactManager.registerRemoveContactHook(blogSharingManager);
|
contactManager.registerRemoveContactHook(blogSharingManager);
|
||||||
messageQueueManager.registerIncomingMessageHook(
|
messageQueueManager.registerIncomingMessageHook(
|
||||||
BlogSharingManagerImpl.CLIENT_ID, blogSharingManager);
|
BlogSharingManagerImpl.CLIENT_ID, blogSharingManager);
|
||||||
|
conversationManager.registerConversationClient(blogSharingManager);
|
||||||
blogManager.registerRemoveBlogHook(blogSharingManager);
|
blogManager.registerRemoveBlogHook(blogSharingManager);
|
||||||
|
|
||||||
return blogSharingManager;
|
return blogSharingManager;
|
||||||
@@ -86,6 +89,7 @@ public class SharingModule {
|
|||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager,
|
||||||
ContactManager contactManager,
|
ContactManager contactManager,
|
||||||
MessageQueueManager messageQueueManager,
|
MessageQueueManager messageQueueManager,
|
||||||
|
ConversationManager conversationManager,
|
||||||
ForumManager forumManager,
|
ForumManager forumManager,
|
||||||
ForumSharingManagerImpl forumSharingManager) {
|
ForumSharingManagerImpl forumSharingManager) {
|
||||||
|
|
||||||
@@ -94,6 +98,7 @@ public class SharingModule {
|
|||||||
contactManager.registerRemoveContactHook(forumSharingManager);
|
contactManager.registerRemoveContactHook(forumSharingManager);
|
||||||
messageQueueManager.registerIncomingMessageHook(
|
messageQueueManager.registerIncomingMessageHook(
|
||||||
ForumSharingManagerImpl.CLIENT_ID, forumSharingManager);
|
ForumSharingManagerImpl.CLIENT_ID, forumSharingManager);
|
||||||
|
conversationManager.registerConversationClient(forumSharingManager);
|
||||||
forumManager.registerRemoveForumHook(forumSharingManager);
|
forumManager.registerRemoveForumHook(forumSharingManager);
|
||||||
|
|
||||||
return forumSharingManager;
|
return forumSharingManager;
|
||||||
|
|||||||
@@ -96,13 +96,13 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
|||||||
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||||
);
|
);
|
||||||
metadataBefore = BdfDictionary.of(
|
metadataBefore = BdfDictionary.of(
|
||||||
new BdfEntry(GROUP_KEY_MSG_COUNT, 41L),
|
new BdfEntry(GROUP_KEY_MSG_COUNT, 41),
|
||||||
new BdfEntry(GROUP_KEY_UNREAD_COUNT, 0L),
|
new BdfEntry(GROUP_KEY_UNREAD_COUNT, 0),
|
||||||
new BdfEntry(GROUP_KEY_LATEST_MSG, 0L)
|
new BdfEntry(GROUP_KEY_LATEST_MSG, 0)
|
||||||
);
|
);
|
||||||
metadataAfter = BdfDictionary.of(
|
metadataAfter = BdfDictionary.of(
|
||||||
new BdfEntry(GROUP_KEY_MSG_COUNT, 42L),
|
new BdfEntry(GROUP_KEY_MSG_COUNT, 42),
|
||||||
new BdfEntry(GROUP_KEY_UNREAD_COUNT, 0L),
|
new BdfEntry(GROUP_KEY_UNREAD_COUNT, 0),
|
||||||
new BdfEntry(GROUP_KEY_LATEST_MSG, time)
|
new BdfEntry(GROUP_KEY_LATEST_MSG, time)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -273,8 +273,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
|||||||
final BdfDictionary state = new BdfDictionary();
|
final BdfDictionary state = new BdfDictionary();
|
||||||
txn = new Transaction(null, false);
|
txn = new Transaction(null, false);
|
||||||
|
|
||||||
metadataBefore.put(GROUP_KEY_UNREAD_COUNT, 1L);
|
metadataBefore.put(GROUP_KEY_UNREAD_COUNT, 1);
|
||||||
metadataAfter.put(GROUP_KEY_UNREAD_COUNT, 2L);
|
metadataAfter.put(GROUP_KEY_UNREAD_COUNT, 2);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(introduceeManager)
|
oneOf(introduceeManager)
|
||||||
@@ -314,8 +314,8 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
|||||||
|
|
||||||
txn = new Transaction(null, false);
|
txn = new Transaction(null, false);
|
||||||
|
|
||||||
metadataBefore.put(GROUP_KEY_UNREAD_COUNT, 41L);
|
metadataBefore.put(GROUP_KEY_UNREAD_COUNT, 41);
|
||||||
metadataAfter.put(GROUP_KEY_UNREAD_COUNT, 42L);
|
metadataAfter.put(GROUP_KEY_UNREAD_COUNT, 42);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, sessionId);
|
||||||
|
|||||||
Reference in New Issue
Block a user