mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 11:49:04 +01:00
Merge branch '707-implement-ux-for-showing-and-answering-private-group-invitations' into 'master'
Implement UX for showing and answering private group invitations As usual, this MR contains several logically separate commits that could be split out into smaller MRs if desired. It consists of two main parts: * Showing open invitations in the list of private groups with a snackbar * Showing invitations and responses in the private conversation For both parts, the existing code was refactored to allow for a smooth implementation and to leave maintainable code behind.    Closes #707 See merge request !357
This commit is contained in:
@@ -1,21 +1,26 @@
|
||||
package org.briarproject.api.clients;
|
||||
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public abstract class BaseMessage {
|
||||
|
||||
private final Message message;
|
||||
@Nullable
|
||||
private final MessageId parent;
|
||||
|
||||
public BaseMessage(@NotNull Message message, @Nullable MessageId parent) {
|
||||
public BaseMessage(Message message, @Nullable MessageId parent) {
|
||||
this.message = message;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Message getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@@ -5,17 +5,11 @@ import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.sharing.InvitationRequest;
|
||||
|
||||
public class BlogInvitationReceivedEvent extends
|
||||
InvitationRequestReceivedEvent {
|
||||
|
||||
private final Blog blog;
|
||||
InvitationRequestReceivedEvent<Blog> {
|
||||
|
||||
public BlogInvitationReceivedEvent(Blog blog, ContactId contactId,
|
||||
InvitationRequest request) {
|
||||
super(contactId, request);
|
||||
this.blog = blog;
|
||||
super(blog, contactId, request);
|
||||
}
|
||||
|
||||
public Blog getBlog() {
|
||||
return blog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,11 @@ import org.briarproject.api.forum.Forum;
|
||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
||||
|
||||
public class ForumInvitationReceivedEvent extends
|
||||
InvitationRequestReceivedEvent {
|
||||
|
||||
private final Forum forum;
|
||||
InvitationRequestReceivedEvent<Forum> {
|
||||
|
||||
public ForumInvitationReceivedEvent(Forum forum, ContactId contactId,
|
||||
ForumInvitationRequest request) {
|
||||
super(contactId, request);
|
||||
this.forum = forum;
|
||||
}
|
||||
|
||||
public Forum getForum() {
|
||||
return forum;
|
||||
super(forum, contactId, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
||||
import org.briarproject.api.privategroup.PrivateGroup;
|
||||
import org.briarproject.api.privategroup.invitation.GroupInvitationRequest;
|
||||
|
||||
public class GroupInvitationReceivedEvent extends
|
||||
InvitationRequestReceivedEvent<PrivateGroup> {
|
||||
|
||||
public GroupInvitationReceivedEvent(PrivateGroup group, ContactId contactId,
|
||||
GroupInvitationRequest request) {
|
||||
super(group, contactId, request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,14 +2,18 @@ package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.sharing.InvitationRequest;
|
||||
import org.briarproject.api.sharing.Shareable;
|
||||
|
||||
public abstract class InvitationRequestReceivedEvent extends Event {
|
||||
public abstract class InvitationRequestReceivedEvent<S extends Shareable>
|
||||
extends Event {
|
||||
|
||||
private final S shareable;
|
||||
private final ContactId contactId;
|
||||
private final InvitationRequest request;
|
||||
|
||||
InvitationRequestReceivedEvent(ContactId contactId,
|
||||
InvitationRequestReceivedEvent(S shareable, ContactId contactId,
|
||||
InvitationRequest request) {
|
||||
this.shareable = shareable;
|
||||
this.contactId = contactId;
|
||||
this.request = request;
|
||||
}
|
||||
@@ -21,4 +25,8 @@ public abstract class InvitationRequestReceivedEvent extends Event {
|
||||
public InvitationRequest getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
public S getShareable() {
|
||||
return shareable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,15 @@ import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.sharing.InvitationRequest;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ForumInvitationRequest extends InvitationRequest {
|
||||
|
||||
private final String forumName;
|
||||
|
||||
public ForumInvitationRequest(MessageId id, SessionId sessionId,
|
||||
GroupId groupId, ContactId contactId, String forumName, String message,
|
||||
boolean available, long time, boolean local, boolean sent,
|
||||
boolean seen, boolean read) {
|
||||
GroupId groupId, ContactId contactId, String forumName,
|
||||
String message, boolean available, long time, boolean local,
|
||||
boolean sent, boolean seen, boolean read) {
|
||||
|
||||
super(id, sessionId, groupId, contactId, message, available, time,
|
||||
local, sent, seen, read);
|
||||
|
||||
@@ -2,17 +2,22 @@ package org.briarproject.api.privategroup;
|
||||
|
||||
import org.briarproject.api.clients.BaseMessage;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class GroupMessage extends BaseMessage {
|
||||
|
||||
private final Author author;
|
||||
|
||||
public GroupMessage(@NotNull Message message, @Nullable MessageId parent,
|
||||
@NotNull Author author) {
|
||||
public GroupMessage(Message message, @Nullable MessageId parent,
|
||||
Author author) {
|
||||
super(message, parent);
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.api.privategroup;
|
||||
import org.briarproject.api.clients.NamedGroup;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.sharing.Shareable;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -10,7 +11,7 @@ import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class PrivateGroup extends NamedGroup {
|
||||
public class PrivateGroup extends NamedGroup implements Shareable {
|
||||
|
||||
private final Author author;
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.briarproject.api.privategroup.invitation;
|
||||
|
||||
public interface GroupInvitationConstants {
|
||||
|
||||
// Group Metadata Keys
|
||||
String CONTACT_ID = "contactId";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.briarproject.api.privategroup.invitation;
|
||||
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.privategroup.PrivateGroup;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class GroupInvitationItem extends InvitationItem<PrivateGroup> {
|
||||
|
||||
private final Contact creator;
|
||||
|
||||
public GroupInvitationItem(PrivateGroup shareable, boolean subscribed,
|
||||
Contact creator) {
|
||||
super(shareable, subscribed);
|
||||
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public Contact getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.briarproject.api.privategroup.invitation;
|
||||
|
||||
import org.briarproject.api.clients.MessageTracker;
|
||||
import org.briarproject.api.clients.SessionId;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.privategroup.PrivateGroup;
|
||||
import org.briarproject.api.sharing.InvitationMessage;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface GroupInvitationManager extends MessageTracker {
|
||||
|
||||
/** Returns the unique ID of the private group invitation client. */
|
||||
ClientId getClientId();
|
||||
|
||||
/**
|
||||
* Sends an invitation to share the given forum with the given contact
|
||||
* and sends an optional message along with it.
|
||||
*/
|
||||
void sendInvitation(GroupId groupId, ContactId contactId,
|
||||
String message) throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to a pending private group invitation
|
||||
*/
|
||||
void respondToInvitation(PrivateGroup g, Contact c, boolean accept)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to a pending private group invitation
|
||||
*/
|
||||
void respondToInvitation(SessionId id, boolean accept) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all private group invitation messages related to the contact
|
||||
* identified by contactId.
|
||||
*/
|
||||
Collection<InvitationMessage> getInvitationMessages(
|
||||
ContactId contactId) throws DbException;
|
||||
|
||||
/** Returns all private groups to which the user has been invited. */
|
||||
Collection<GroupInvitationItem> getInvitations() throws DbException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.briarproject.api.privategroup.invitation;
|
||||
|
||||
import org.briarproject.api.clients.SessionId;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.sharing.InvitationRequest;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class GroupInvitationRequest extends InvitationRequest {
|
||||
|
||||
private final String groupName;
|
||||
private final Author creator;
|
||||
|
||||
public GroupInvitationRequest(MessageId id, SessionId sessionId,
|
||||
GroupId groupId, Author creator, ContactId contactId,
|
||||
String groupName, String message, boolean available, long time,
|
||||
boolean local, boolean sent, boolean seen, boolean read) {
|
||||
super(id, sessionId, groupId, contactId, message, available, time,
|
||||
local, sent, seen, read);
|
||||
this.groupName = groupName;
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public Author getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.briarproject.api.privategroup.invitation;
|
||||
|
||||
import org.briarproject.api.clients.SessionId;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.sharing.InvitationResponse;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class GroupInvitationResponse extends InvitationResponse {
|
||||
|
||||
private final String groupName;
|
||||
private final Author creator;
|
||||
|
||||
public GroupInvitationResponse(MessageId id, SessionId sessionId,
|
||||
GroupId groupId, String groupName, Author creator,
|
||||
ContactId contactId, boolean accept, long time, boolean local,
|
||||
boolean sent, boolean seen, boolean read) {
|
||||
super(id, sessionId, groupId, contactId, accept, time, local, sent,
|
||||
seen, read);
|
||||
this.groupName = groupName;
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
public Author getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +1,36 @@
|
||||
package org.briarproject.api.sharing;
|
||||
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
|
||||
import java.util.Collection;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
public class InvitationItem {
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public abstract class InvitationItem<S extends Shareable> {
|
||||
|
||||
private final Shareable shareable;
|
||||
private final S shareable;
|
||||
private final boolean subscribed;
|
||||
private final Collection<Contact> newSharers;
|
||||
|
||||
public InvitationItem(Shareable shareable, boolean subscribed,
|
||||
Collection<Contact> newSharers) {
|
||||
|
||||
public InvitationItem(S shareable, boolean subscribed) {
|
||||
this.shareable = shareable;
|
||||
this.subscribed = subscribed;
|
||||
this.newSharers = newSharers;
|
||||
}
|
||||
|
||||
public Shareable getShareable() {
|
||||
public S getShareable() {
|
||||
return shareable;
|
||||
}
|
||||
|
||||
public GroupId getId() {
|
||||
return shareable.getId();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return shareable.getName();
|
||||
}
|
||||
|
||||
public boolean isSubscribed() {
|
||||
return subscribed;
|
||||
}
|
||||
|
||||
public Collection<Contact> getNewSharers() {
|
||||
return newSharers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,7 @@ public interface Shareable {
|
||||
GroupId getId();
|
||||
|
||||
Group getGroup();
|
||||
|
||||
String getName();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.briarproject.api.sharing;
|
||||
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class SharingInvitationItem extends InvitationItem<Shareable> {
|
||||
|
||||
private final Collection<Contact> newSharers;
|
||||
|
||||
public SharingInvitationItem(Shareable shareable, boolean subscribed,
|
||||
Collection<Contact> newSharers) {
|
||||
super(shareable, subscribed);
|
||||
|
||||
this.newSharers = newSharers;
|
||||
}
|
||||
|
||||
public Collection<Contact> getNewSharers() {
|
||||
return newSharers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.api.sharing;
|
||||
|
||||
import org.briarproject.api.clients.MessageTracker;
|
||||
import org.briarproject.api.clients.SessionId;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.db.DbException;
|
||||
@@ -30,7 +31,14 @@ public interface SharingManager<S extends Shareable> extends MessageTracker {
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all group sharing messages sent by the given contact.
|
||||
* Responds to a pending group invitation
|
||||
*/
|
||||
void respondToInvitation(SessionId id, boolean accept)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all group sharing messages sent by the Contact
|
||||
* identified by contactId.
|
||||
*/
|
||||
Collection<InvitationMessage> getInvitationMessages(
|
||||
ContactId contactId) throws DbException;
|
||||
@@ -38,7 +46,7 @@ public interface SharingManager<S extends Shareable> extends MessageTracker {
|
||||
/**
|
||||
* Returns all invitations to groups.
|
||||
*/
|
||||
Collection<InvitationItem> getInvitations() throws DbException;
|
||||
Collection<SharingInvitationItem> getInvitations() throws DbException;
|
||||
|
||||
/**
|
||||
* Returns all contacts who are sharing the given group with us.
|
||||
|
||||
Reference in New Issue
Block a user