mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Merge branch 'client-versioning-events' into 'master'
Update image attachment UI when new client version is received from contact Closes #1638 See merge request briar/briar!1195
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package org.briarproject.bramble.api.versioning;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class ClientVersion implements Comparable<ClientVersion> {
|
||||
|
||||
private final ClientMajorVersion majorVersion;
|
||||
private final int minorVersion;
|
||||
|
||||
public ClientVersion(ClientMajorVersion majorVersion,
|
||||
int minorVersion) {
|
||||
this.majorVersion = majorVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
}
|
||||
|
||||
public ClientVersion(ClientId clientId, int majorVersion,
|
||||
int minorVersion) {
|
||||
this(new ClientMajorVersion(clientId, majorVersion), minorVersion);
|
||||
}
|
||||
|
||||
public ClientMajorVersion getClientMajorVersion() {
|
||||
return majorVersion;
|
||||
}
|
||||
|
||||
public ClientId getClientId() {
|
||||
return majorVersion.getClientId();
|
||||
}
|
||||
|
||||
public int getMajorVersion() {
|
||||
return majorVersion.getMajorVersion();
|
||||
}
|
||||
|
||||
public int getMinorVersion() {
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ClientVersion) {
|
||||
ClientVersion cv = (ClientVersion) o;
|
||||
return majorVersion.equals(cv.majorVersion)
|
||||
&& minorVersion == cv.minorVersion;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return majorVersion.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ClientVersion cv) {
|
||||
int compare = majorVersion.compareTo(cv.majorVersion);
|
||||
if (compare != 0) return compare;
|
||||
return minorVersion - cv.minorVersion;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.briarproject.bramble.api.versioning.event;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersion;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event that is broadcast when we receive a client versioning update from
|
||||
* a contact.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class ClientVersionUpdatedEvent extends Event {
|
||||
|
||||
private final ContactId contactId;
|
||||
private final ClientVersion clientVersion;
|
||||
|
||||
public ClientVersionUpdatedEvent(ContactId contactId,
|
||||
ClientVersion clientVersion) {
|
||||
this.contactId = contactId;
|
||||
this.clientVersion = clientVersion;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
public ClientVersion getClientVersion() {
|
||||
return clientVersion;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,9 @@ import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.versioning.ClientMajorVersion;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersion;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||
import org.briarproject.bramble.api.versioning.event.ClientVersionUpdatedEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -80,9 +82,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
@Override
|
||||
public void registerClient(ClientId clientId, int majorVersion,
|
||||
int minorVersion, ClientVersioningHook hook) {
|
||||
ClientMajorVersion cv = new ClientMajorVersion(clientId, majorVersion);
|
||||
clients.add(new ClientVersion(cv, minorVersion));
|
||||
hooks.put(cv, hook);
|
||||
ClientMajorVersion cmv = new ClientMajorVersion(clientId, majorVersion);
|
||||
clients.add(new ClientVersion(cmv, minorVersion));
|
||||
hooks.put(cmv, hook);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,9 +98,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
|
||||
Map<ClientMajorVersion, Visibility> visibilities =
|
||||
getVisibilities(localUpdate.states, remoteUpdate.states);
|
||||
ClientMajorVersion cv =
|
||||
ClientMajorVersion key =
|
||||
new ClientMajorVersion(clientId, majorVersion);
|
||||
Visibility v = visibilities.get(cv);
|
||||
Visibility v = visibilities.get(key);
|
||||
return v == null ? INVISIBLE : v;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
@@ -112,10 +114,11 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
LatestUpdates latest = findLatestUpdates(txn, contactId);
|
||||
if (latest == null || latest.remote == null) return -1;
|
||||
Update remoteUpdate = loadUpdate(txn, latest.remote.messageId);
|
||||
ClientMajorVersion cv =
|
||||
ClientMajorVersion key =
|
||||
new ClientMajorVersion(clientId, majorVersion);
|
||||
for (ClientState remote : remoteUpdate.states) {
|
||||
if (remote.majorVersion.equals(cv)) return remote.minorVersion;
|
||||
if (remote.clientVersion.getClientMajorVersion().equals(key))
|
||||
return remote.clientVersion.getMinorVersion();
|
||||
}
|
||||
return -1;
|
||||
} catch (FormatException e) {
|
||||
@@ -226,9 +229,21 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
Map<ClientMajorVersion, Visibility> after =
|
||||
getVisibilities(newLocalStates, newRemoteStates);
|
||||
// Call hooks for any visibilities that have changed
|
||||
ContactId c = getContactId(txn, m.getGroupId());
|
||||
if (!before.equals(after)) {
|
||||
Contact c = getContact(txn, m.getGroupId());
|
||||
callVisibilityHooks(txn, c, before, after);
|
||||
Contact contact = db.getContact(txn, c);
|
||||
callVisibilityHooks(txn, contact, before, after);
|
||||
}
|
||||
// Broadcast events for any new client versions
|
||||
Set<ClientVersion> oldRemoteVersions = new HashSet<>();
|
||||
for (ClientState cs : oldRemoteStates) {
|
||||
oldRemoteVersions.add(cs.clientVersion);
|
||||
}
|
||||
for (ClientState cs : newRemoteStates) {
|
||||
if (!oldRemoteVersions.contains(cs.clientVersion)) {
|
||||
txn.attach(new ClientVersionUpdatedEvent(c,
|
||||
cs.clientVersion));
|
||||
}
|
||||
}
|
||||
} catch (FormatException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
@@ -256,8 +271,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
}
|
||||
|
||||
private BdfList encodeClientVersion(ClientVersion cv) {
|
||||
return BdfList.of(cv.majorVersion.getClientId().getString(),
|
||||
cv.majorVersion.getMajorVersion(), cv.minorVersion);
|
||||
return BdfList.of(cv.getClientId().getString(), cv.getMajorVersion(),
|
||||
cv.getMinorVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,8 +313,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
ClientId clientId = new ClientId(cv.getString(0));
|
||||
int majorVersion = cv.getLong(1).intValue();
|
||||
int minorVersion = cv.getLong(2).intValue();
|
||||
parsed.add(new ClientVersion(clientId, majorVersion,
|
||||
minorVersion));
|
||||
parsed.add(new ClientVersion(clientId, majorVersion, minorVersion));
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
@@ -418,13 +432,15 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
private List<ClientState> updateStatesFromLocalVersions(
|
||||
List<ClientState> oldStates, List<ClientVersion> newVersions) {
|
||||
Map<ClientMajorVersion, ClientState> oldMap = new HashMap<>();
|
||||
for (ClientState cs : oldStates) oldMap.put(cs.majorVersion, cs);
|
||||
for (ClientState cs : oldStates) {
|
||||
oldMap.put(cs.clientVersion.getClientMajorVersion(), cs);
|
||||
}
|
||||
List<ClientState> newStates = new ArrayList<>(newVersions.size());
|
||||
for (ClientVersion newVersion : newVersions) {
|
||||
ClientState oldState = oldMap.get(newVersion.majorVersion);
|
||||
ClientMajorVersion key = newVersion.getClientMajorVersion();
|
||||
ClientState oldState = oldMap.get(key);
|
||||
boolean active = oldState != null && oldState.active;
|
||||
newStates.add(new ClientState(newVersion.majorVersion,
|
||||
newVersion.minorVersion, active));
|
||||
newStates.add(new ClientState(newVersion, active));
|
||||
}
|
||||
return newStates;
|
||||
}
|
||||
@@ -451,21 +467,25 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
}
|
||||
|
||||
private BdfList encodeClientState(ClientState cs) {
|
||||
return BdfList.of(cs.majorVersion.getClientId().getString(),
|
||||
cs.majorVersion.getMajorVersion(), cs.minorVersion, cs.active);
|
||||
ClientVersion cv = cs.clientVersion;
|
||||
return BdfList.of(cv.getClientId().getString(), cv.getMajorVersion(),
|
||||
cv.getMinorVersion(), cs.active);
|
||||
}
|
||||
|
||||
private Map<ClientMajorVersion, Visibility> getVisibilities(
|
||||
List<ClientState> localStates, List<ClientState> remoteStates) {
|
||||
Map<ClientMajorVersion, ClientState> remoteMap = new HashMap<>();
|
||||
for (ClientState cs : remoteStates) remoteMap.put(cs.majorVersion, cs);
|
||||
for (ClientState cs : remoteStates) {
|
||||
remoteMap.put(cs.clientVersion.getClientMajorVersion(), cs);
|
||||
}
|
||||
Map<ClientMajorVersion, Visibility> visibilities = new HashMap<>();
|
||||
for (ClientState local : localStates) {
|
||||
ClientState remote = remoteMap.get(local.majorVersion);
|
||||
if (remote == null) visibilities.put(local.majorVersion, INVISIBLE);
|
||||
else if (remote.active)
|
||||
visibilities.put(local.majorVersion, SHARED);
|
||||
else visibilities.put(local.majorVersion, VISIBLE);
|
||||
ClientMajorVersion key =
|
||||
local.clientVersion.getClientMajorVersion();
|
||||
ClientState remote = remoteMap.get(key);
|
||||
if (remote == null) visibilities.put(key, INVISIBLE);
|
||||
else if (remote.active) visibilities.put(key, SHARED);
|
||||
else visibilities.put(key, VISIBLE);
|
||||
}
|
||||
return visibilities;
|
||||
}
|
||||
@@ -486,9 +506,9 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
}
|
||||
}
|
||||
|
||||
private void callVisibilityHook(Transaction txn, ClientMajorVersion cv,
|
||||
private void callVisibilityHook(Transaction txn, ClientMajorVersion cmv,
|
||||
Contact c, Visibility v) throws DbException {
|
||||
ClientVersioningHook hook = hooks.get(cv);
|
||||
ClientVersioningHook hook = hooks.get(cmv);
|
||||
if (hook != null) hook.onClientVisibilityChanging(txn, c, v);
|
||||
}
|
||||
|
||||
@@ -496,18 +516,17 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
List<ClientVersion> versions) throws DbException {
|
||||
List<ClientState> states = new ArrayList<>(versions.size());
|
||||
for (ClientVersion cv : versions) {
|
||||
states.add(new ClientState(cv.majorVersion, cv.minorVersion,
|
||||
false));
|
||||
states.add(new ClientState(cv, false));
|
||||
}
|
||||
storeUpdate(txn, g, states, 1);
|
||||
}
|
||||
|
||||
private Contact getContact(Transaction txn, GroupId g) throws DbException {
|
||||
private ContactId getContactId(Transaction txn, GroupId g)
|
||||
throws DbException {
|
||||
try {
|
||||
BdfDictionary meta =
|
||||
clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||
int id = meta.getLong(GROUP_KEY_CONTACT_ID).intValue();
|
||||
return db.getContact(txn, new ContactId(id));
|
||||
return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@@ -516,13 +535,16 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
private List<ClientState> updateStatesFromRemoteStates(
|
||||
List<ClientState> oldLocalStates, List<ClientState> remoteStates) {
|
||||
Set<ClientMajorVersion> remoteSet = new HashSet<>();
|
||||
for (ClientState cs : remoteStates) remoteSet.add(cs.majorVersion);
|
||||
for (ClientState cs : remoteStates) {
|
||||
remoteSet.add(cs.clientVersion.getClientMajorVersion());
|
||||
}
|
||||
List<ClientState> newLocalStates =
|
||||
new ArrayList<>(oldLocalStates.size());
|
||||
for (ClientState oldState : oldLocalStates) {
|
||||
boolean active = remoteSet.contains(oldState.majorVersion);
|
||||
newLocalStates.add(new ClientState(oldState.majorVersion,
|
||||
oldState.minorVersion, active));
|
||||
ClientMajorVersion cmv =
|
||||
oldState.clientVersion.getClientMajorVersion();
|
||||
boolean active = remoteSet.contains(cmv);
|
||||
newLocalStates.add(new ClientState(oldState.clientVersion, active));
|
||||
}
|
||||
return newLocalStates;
|
||||
}
|
||||
@@ -561,61 +583,19 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClientVersion implements Comparable<ClientVersion> {
|
||||
|
||||
private final ClientMajorVersion majorVersion;
|
||||
private final int minorVersion;
|
||||
|
||||
private ClientVersion(ClientMajorVersion majorVersion,
|
||||
int minorVersion) {
|
||||
this.majorVersion = majorVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
}
|
||||
|
||||
private ClientVersion(ClientId clientId, int majorVersion,
|
||||
int minorVersion) {
|
||||
this(new ClientMajorVersion(clientId, majorVersion), minorVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ClientVersion) {
|
||||
ClientVersion cv = (ClientVersion) o;
|
||||
return majorVersion.equals(cv.majorVersion)
|
||||
&& minorVersion == cv.minorVersion;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return majorVersion.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ClientVersion cv) {
|
||||
int compare = majorVersion.compareTo(cv.majorVersion);
|
||||
if (compare != 0) return compare;
|
||||
return minorVersion - cv.minorVersion;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClientState {
|
||||
|
||||
private final ClientMajorVersion majorVersion;
|
||||
private final int minorVersion;
|
||||
private final ClientVersion clientVersion;
|
||||
private final boolean active;
|
||||
|
||||
private ClientState(ClientMajorVersion majorVersion, int minorVersion,
|
||||
boolean active) {
|
||||
this.majorVersion = majorVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
private ClientState(ClientVersion clientVersion, boolean active) {
|
||||
this.clientVersion = clientVersion;
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
private ClientState(ClientId clientId, int majorVersion,
|
||||
int minorVersion, boolean active) {
|
||||
this(new ClientMajorVersion(clientId, majorVersion), minorVersion,
|
||||
this(new ClientVersion(clientId, majorVersion, minorVersion),
|
||||
active);
|
||||
}
|
||||
|
||||
@@ -623,8 +603,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ClientState) {
|
||||
ClientState cs = (ClientState) o;
|
||||
return majorVersion.equals(cs.majorVersion)
|
||||
&& minorVersion == cs.minorVersion
|
||||
return clientVersion.equals(cs.clientVersion)
|
||||
&& active == cs.active;
|
||||
}
|
||||
return false;
|
||||
@@ -632,7 +611,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return majorVersion.hashCode();
|
||||
return clientVersion.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
private final ClientId clientId = getClientId();
|
||||
private final long now = System.currentTimeMillis();
|
||||
private final Transaction txn = new Transaction(null, false);
|
||||
private final BdfDictionary groupMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_CONTACT_ID, contact.getId().getInt()));
|
||||
|
||||
private ClientVersioningManagerImpl createInstance() {
|
||||
context.checking(new Expectations() {{
|
||||
@@ -107,8 +109,6 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
}
|
||||
|
||||
private void expectAddingContact() throws Exception {
|
||||
BdfDictionary groupMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_CONTACT_ID, contact.getId().getInt()));
|
||||
long now = System.currentTimeMillis();
|
||||
BdfList localUpdateBody = BdfList.of(new BdfList(), 1L);
|
||||
Message localUpdate = getMessage(contactGroup.getId());
|
||||
@@ -459,6 +459,10 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
// Delete the old remote update
|
||||
oneOf(db).deleteMessage(txn, oldRemoteUpdateId);
|
||||
oneOf(db).deleteMessageMetadata(txn, oldRemoteUpdateId);
|
||||
// Get contact ID
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(groupMeta));
|
||||
// No states or visibilities have changed
|
||||
}});
|
||||
|
||||
@@ -488,6 +492,10 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
||||
// Load the latest local update
|
||||
oneOf(clientHelper).getMessageAsList(txn, oldLocalUpdateId);
|
||||
will(returnValue(oldLocalUpdateBody));
|
||||
// Get client ID
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(groupMeta));
|
||||
// No states or visibilities have changed
|
||||
}});
|
||||
|
||||
|
||||
@@ -46,9 +46,11 @@ import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.ConnectionRegistry;
|
||||
import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.event.MessagesAckedEvent;
|
||||
import org.briarproject.bramble.api.sync.event.MessagesSentEvent;
|
||||
import org.briarproject.bramble.api.versioning.event.ClientVersionUpdatedEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
@@ -99,7 +101,6 @@ import javax.inject.Inject;
|
||||
import de.hdodenhof.circleimageview.CircleImageView;
|
||||
import im.delight.android.identicons.IdenticonDrawable;
|
||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.PromptStateChangeListener;
|
||||
|
||||
import static android.arch.lifecycle.Lifecycle.State.STARTED;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
@@ -130,8 +131,6 @@ import static org.briarproject.briar.android.util.UiUtils.getBulbTransitionName;
|
||||
import static org.briarproject.briar.android.util.UiUtils.observeOnce;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH;
|
||||
import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.STATE_DISMISSED;
|
||||
import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.STATE_FINISHED;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -263,11 +262,15 @@ public class ConversationActivity extends BriarActivity
|
||||
ImagePreview imagePreview = findViewById(R.id.imagePreview);
|
||||
sendController = new TextAttachmentController(textInputView,
|
||||
imagePreview, this, viewModel);
|
||||
observeOnce(viewModel.hasImageSupport(), this, hasSupport -> {
|
||||
if (hasSupport != null && hasSupport) {
|
||||
// TODO: remove cast when removing feature flag
|
||||
((TextAttachmentController) sendController)
|
||||
.setImagesSupported();
|
||||
viewModel.hasImageSupport().observe(this, new Observer<Boolean>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable Boolean hasSupport) {
|
||||
if (hasSupport != null && hasSupport) {
|
||||
// TODO: remove cast when removing feature flag
|
||||
((TextAttachmentController) sendController)
|
||||
.setImagesSupported();
|
||||
viewModel.hasImageSupport().removeObserver(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -649,6 +652,15 @@ public class ConversationActivity extends BriarActivity
|
||||
LOG.info("Contact disconnected");
|
||||
displayContactOnlineStatus();
|
||||
}
|
||||
} else if (e instanceof ClientVersionUpdatedEvent) {
|
||||
ClientVersionUpdatedEvent c = (ClientVersionUpdatedEvent) e;
|
||||
if (c.getContactId().equals(contactId)) {
|
||||
ClientId clientId = c.getClientVersion().getClientId();
|
||||
if (clientId.equals(MessagingManager.CLIENT_ID)) {
|
||||
LOG.info("Contact's messaging client was updated");
|
||||
viewModel.recheckFeaturesAndOnboarding(contactId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,9 +841,7 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
private void showImageOnboarding() {
|
||||
// TODO: remove cast when removing feature flag
|
||||
((TextAttachmentController) sendController)
|
||||
.showImageOnboarding(this, () ->
|
||||
viewModel.onImageOnboardingSeen());
|
||||
((TextAttachmentController) sendController).showImageOnboarding(this);
|
||||
}
|
||||
|
||||
private void showIntroductionOnboarding(@Nullable Boolean show) {
|
||||
@@ -865,11 +875,6 @@ public class ConversationActivity extends BriarActivity
|
||||
return;
|
||||
}
|
||||
|
||||
PromptStateChangeListener listener = (prompt, state) -> {
|
||||
if (state == STATE_DISMISSED || state == STATE_FINISHED) {
|
||||
viewModel.onIntroductionOnboardingSeen();
|
||||
}
|
||||
};
|
||||
new MaterialTapTargetPrompt.Builder(ConversationActivity.this,
|
||||
R.style.OnboardingDialogTheme).setTarget(target)
|
||||
.setPrimaryText(R.string.introduction_onboarding_title)
|
||||
@@ -877,7 +882,6 @@ public class ConversationActivity extends BriarActivity
|
||||
.setIcon(R.drawable.ic_more_vert_accent)
|
||||
.setBackgroundColour(
|
||||
ContextCompat.getColor(this, R.color.briar_primary))
|
||||
.setPromptStateChangeListener(listener)
|
||||
.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -231,47 +231,24 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
boolean introductionSupported = contacts.size() > 1;
|
||||
showIntroductionAction.postValue(introductionSupported);
|
||||
|
||||
// we only show one onboarding dialog at a time
|
||||
Settings settings = settingsManager.getSettings(SETTINGS_NAMESPACE);
|
||||
if (imagesSupported &&
|
||||
settings.getBoolean(SHOW_ONBOARDING_IMAGE, true)) {
|
||||
// check if we should show onboarding, only if images are supported
|
||||
onOnboardingShown(SHOW_ONBOARDING_IMAGE);
|
||||
showImageOnboarding.postEvent(true);
|
||||
// allow observer to stop listening for changes
|
||||
showIntroductionOnboarding.postEvent(false);
|
||||
} else {
|
||||
// allow observer to stop listening for changes
|
||||
showImageOnboarding.postEvent(false);
|
||||
// we only show one onboarding dialog at a time
|
||||
if (introductionSupported &&
|
||||
settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION, true)) {
|
||||
showIntroductionOnboarding.postEvent(true);
|
||||
} else {
|
||||
// allow observer to stop listening for changes
|
||||
showIntroductionOnboarding.postEvent(false);
|
||||
}
|
||||
} else if (introductionSupported &&
|
||||
settings.getBoolean(SHOW_ONBOARDING_INTRODUCTION, true)) {
|
||||
onOnboardingShown(SHOW_ONBOARDING_INTRODUCTION);
|
||||
showIntroductionOnboarding.postEvent(true);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void onImageOnboardingSeen() {
|
||||
onOnboardingSeen(SHOW_ONBOARDING_IMAGE);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void onIntroductionOnboardingSeen() {
|
||||
onOnboardingSeen(SHOW_ONBOARDING_INTRODUCTION);
|
||||
}
|
||||
|
||||
private void onOnboardingSeen(String key) {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
Settings settings = new Settings();
|
||||
settings.putBoolean(key, false);
|
||||
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
@DatabaseExecutor
|
||||
private void onOnboardingShown(String key) throws DbException {
|
||||
Settings settings = new Settings();
|
||||
settings.putBoolean(key, false);
|
||||
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE);
|
||||
}
|
||||
|
||||
private void createMessage(GroupId groupId, @Nullable String text,
|
||||
@@ -352,4 +329,14 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
return addedHeader;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void recheckFeaturesAndOnboarding(ContactId contactId) {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
checkFeaturesAndOnboarding(contactId);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.PromptStateChangeListener;
|
||||
|
||||
import static android.arch.lifecycle.Lifecycle.State.DESTROYED;
|
||||
import static android.content.Intent.ACTION_GET_CONTENT;
|
||||
@@ -44,8 +43,6 @@ import static android.widget.Toast.LENGTH_LONG;
|
||||
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.IMAGE_MIME_TYPES;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE;
|
||||
import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.STATE_DISMISSED;
|
||||
import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.STATE_FINISHED;
|
||||
|
||||
@UiThread
|
||||
@NotNullByDefault
|
||||
@@ -269,13 +266,7 @@ public class TextAttachmentController extends TextSendController
|
||||
reset();
|
||||
}
|
||||
|
||||
public void showImageOnboarding(Activity activity,
|
||||
Runnable onOnboardingSeen) {
|
||||
PromptStateChangeListener listener = (prompt, state) -> {
|
||||
if (state == STATE_DISMISSED || state == STATE_FINISHED) {
|
||||
onOnboardingSeen.run();
|
||||
}
|
||||
};
|
||||
public void showImageOnboarding(Activity activity) {
|
||||
int color = resolveColorAttribute(activity, R.attr.colorControlNormal);
|
||||
new MaterialTapTargetPrompt.Builder(activity,
|
||||
R.style.OnboardingDialogTheme).setTarget(sendButton)
|
||||
@@ -284,7 +275,6 @@ public class TextAttachmentController extends TextSendController
|
||||
.setBackgroundColour(getColor(activity, R.color.briar_primary))
|
||||
.setIcon(R.drawable.ic_image)
|
||||
.setIconDrawableColourFilter(color)
|
||||
.setPromptStateChangeListener(listener)
|
||||
.show();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user