add overflow menu action to delete own avatar
This commit is contained in:
parent
ddd08bfe5f
commit
e439c223ee
|
@ -708,11 +708,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteOmemoIdentity() {
|
public void deleteOmemoIdentity() {
|
||||||
final String node = AxolotlService.PEP_BUNDLES + ":" + getOwnDeviceId();
|
mXmppConnectionService.deletePepNode(
|
||||||
final IqPacket deleteBundleNode = mXmppConnectionService.getIqGenerator().deleteNode(node);
|
account, AxolotlService.PEP_BUNDLES + ":" + getOwnDeviceId());
|
||||||
mXmppConnectionService.sendIqPacket(account, deleteBundleNode, null);
|
|
||||||
final Set<Integer> ownDeviceIds = getOwnDeviceIds();
|
final Set<Integer> ownDeviceIds = getOwnDeviceIds();
|
||||||
publishDeviceIdsAndRefineAccessModel(ownDeviceIds == null ? Collections.emptySet() : ownDeviceIds);
|
publishDeviceIdsAndRefineAccessModel(
|
||||||
|
ownDeviceIds == null ? Collections.emptySet() : ownDeviceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Jid> getCryptoTargets(Conversation conversation) {
|
public List<Jid> getCryptoTargets(Conversation conversation) {
|
||||||
|
|
|
@ -156,9 +156,9 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
public IqPacket publishAvatar(Avatar avatar, Bundle options) {
|
public IqPacket publishAvatar(Avatar avatar, Bundle options) {
|
||||||
final Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
final Element data = item.addChild("data", "urn:xmpp:avatar:data");
|
final Element data = item.addChild("data", Namespace.AVATAR_DATA);
|
||||||
data.setContent(avatar.image);
|
data.setContent(avatar.image);
|
||||||
return publish("urn:xmpp:avatar:data", item, options);
|
return publish(Namespace.AVATAR_DATA, item, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket publishElement(final String namespace, final Element element, String id, final Bundle options) {
|
public IqPacket publishElement(final String namespace, final Element element, String id, final Bundle options) {
|
||||||
|
@ -172,20 +172,20 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
final Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
final Element metadata = item
|
final Element metadata = item
|
||||||
.addChild("metadata", "urn:xmpp:avatar:metadata");
|
.addChild("metadata", Namespace.AVATAR_METADATA);
|
||||||
final Element info = metadata.addChild("info");
|
final Element info = metadata.addChild("info");
|
||||||
info.setAttribute("bytes", avatar.size);
|
info.setAttribute("bytes", avatar.size);
|
||||||
info.setAttribute("id", avatar.sha1sum);
|
info.setAttribute("id", avatar.sha1sum);
|
||||||
info.setAttribute("height", avatar.height);
|
info.setAttribute("height", avatar.height);
|
||||||
info.setAttribute("width", avatar.height);
|
info.setAttribute("width", avatar.height);
|
||||||
info.setAttribute("type", avatar.type);
|
info.setAttribute("type", avatar.type);
|
||||||
return publish("urn:xmpp:avatar:metadata", item, options);
|
return publish(Namespace.AVATAR_METADATA, item, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IqPacket retrievePepAvatar(final Avatar avatar) {
|
public IqPacket retrievePepAvatar(final Avatar avatar) {
|
||||||
final Element item = new Element("item");
|
final Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
final IqPacket packet = retrieve("urn:xmpp:avatar:data", item);
|
final IqPacket packet = retrieve(Namespace.AVATAR_DATA, item);
|
||||||
packet.setTo(avatar.owner);
|
packet.setTo(avatar.owner);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,13 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IqPacket retrieveVcardAvatar(final Jid to) {
|
||||||
|
final IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
|
||||||
|
packet.setTo(to);
|
||||||
|
packet.addChild("vCard", "vcard-temp");
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
public IqPacket retrieveAvatarMetaData(final Jid to) {
|
public IqPacket retrieveAvatarMetaData(final Jid to) {
|
||||||
final IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null);
|
final IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null);
|
||||||
if (to != null) {
|
if (to != null) {
|
||||||
|
|
|
@ -279,6 +279,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
} else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
|
} else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
|
||||||
account.setBookmarks(Collections.emptyMap());
|
account.setBookmarks(Collections.emptyMap());
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmarks node");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmarks node");
|
||||||
|
} else if (Namespace.AVATAR_METADATA.equals(node) && account.getJid().asBareJid().equals(from)) {
|
||||||
|
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": deleted avatar metadata node");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ import android.preference.PreferenceManager;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.security.KeyChain;
|
import android.security.KeyChain;
|
||||||
import android.telephony.PhoneStateListener;
|
import android.telephony.PhoneStateListener;
|
||||||
import android.telephony.TelephonyCallback;
|
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
@ -48,6 +47,7 @@ import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.BoolRes;
|
import androidx.annotation.BoolRes;
|
||||||
import androidx.annotation.IntegerRes;
|
import androidx.annotation.IntegerRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.app.RemoteInput;
|
import androidx.core.app.RemoteInput;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
@ -2792,7 +2792,6 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void joinMuc(Conversation conversation) {
|
public void joinMuc(Conversation conversation) {
|
||||||
joinMuc(conversation, null, false);
|
joinMuc(conversation, null, false);
|
||||||
}
|
}
|
||||||
|
@ -3010,6 +3009,71 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteAvatar(final Account account) {
|
||||||
|
final AtomicBoolean executed = new AtomicBoolean(false);
|
||||||
|
final Runnable onDeleted =
|
||||||
|
() -> {
|
||||||
|
if (executed.compareAndSet(false, true)) {
|
||||||
|
account.setAvatar(null);
|
||||||
|
databaseBackend.updateAccount(account);
|
||||||
|
getAvatarService().clear(account);
|
||||||
|
updateAccountUi();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
deleteVcardAvatar(account, onDeleted);
|
||||||
|
deletePepNode(account, Namespace.AVATAR_DATA);
|
||||||
|
deletePepNode(account, Namespace.AVATAR_METADATA, onDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deletePepNode(final Account account, final String node) {
|
||||||
|
deletePepNode(account, node, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deletePepNode(final Account account, final String node, final Runnable runnable) {
|
||||||
|
final IqPacket request = mIqGenerator.deleteNode(node);
|
||||||
|
sendIqPacket(account, request, (a, packet) -> {
|
||||||
|
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
||||||
|
Log.d(Config.LOGTAG,a.getJid().asBareJid()+": successfully deleted pep node "+node);
|
||||||
|
if (runnable != null) {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG,a.getJid().asBareJid()+": failed to delete "+ packet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteVcardAvatar(final Account account, @NonNull final Runnable runnable) {
|
||||||
|
final IqPacket retrieveVcard = mIqGenerator.retrieveVcardAvatar(account.getJid().asBareJid());
|
||||||
|
sendIqPacket(account, retrieveVcard, (a, response) -> {
|
||||||
|
if (response.getType() != IqPacket.TYPE.RESULT) {
|
||||||
|
Log.d(Config.LOGTAG,a.getJid().asBareJid()+": no vCard set. nothing to do");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Element vcard = response.findChild("vCard", "vcard-temp");
|
||||||
|
if (vcard == null) {
|
||||||
|
Log.d(Config.LOGTAG,a.getJid().asBareJid()+": no vCard set. nothing to do");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Element photo = vcard.findChild("PHOTO");
|
||||||
|
if (photo == null) {
|
||||||
|
photo = vcard.addChild("PHOTO");
|
||||||
|
}
|
||||||
|
photo.clearChildren();
|
||||||
|
IqPacket publication = new IqPacket(IqPacket.TYPE.SET);
|
||||||
|
publication.setTo(a.getJid().asBareJid());
|
||||||
|
publication.addChild(vcard);
|
||||||
|
sendIqPacket(account, publication, (a1, publicationResponse) -> {
|
||||||
|
if (publicationResponse.getType() == IqPacket.TYPE.RESULT) {
|
||||||
|
Log.d(Config.LOGTAG,a1.getJid().asBareJid()+": successfully deleted vcard avatar");
|
||||||
|
runnable.run();
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, "failed to publish vcard " + publicationResponse.getErrorCondition());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasEnabledAccounts() {
|
private boolean hasEnabledAccounts() {
|
||||||
if (this.accounts == null) {
|
if (this.accounts == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -3598,7 +3662,7 @@ public class XmppConnectionService extends Service {
|
||||||
if (result.getType() == IqPacket.TYPE.RESULT) {
|
if (result.getType() == IqPacket.TYPE.RESULT) {
|
||||||
publishAvatarMetadata(account, avatar, options, true, callback);
|
publishAvatarMetadata(account, avatar, options, true, callback);
|
||||||
} else if (retry && PublishOptions.preconditionNotMet(result)) {
|
} else if (retry && PublishOptions.preconditionNotMet(result)) {
|
||||||
pushNodeConfiguration(account, "urn:xmpp:avatar:data", options, new OnConfigurationPushed() {
|
pushNodeConfiguration(account, Namespace.AVATAR_DATA, options, new OnConfigurationPushed() {
|
||||||
@Override
|
@Override
|
||||||
public void onPushSucceeded() {
|
public void onPushSucceeded() {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": changed node configuration for avatar node");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": changed node configuration for avatar node");
|
||||||
|
@ -3638,7 +3702,7 @@ public class XmppConnectionService extends Service {
|
||||||
callback.onAvatarPublicationSucceeded();
|
callback.onAvatarPublicationSucceeded();
|
||||||
}
|
}
|
||||||
} else if (retry && PublishOptions.preconditionNotMet(result)) {
|
} else if (retry && PublishOptions.preconditionNotMet(result)) {
|
||||||
pushNodeConfiguration(account, "urn:xmpp:avatar:metadata", options, new OnConfigurationPushed() {
|
pushNodeConfiguration(account, Namespace.AVATAR_METADATA, options, new OnConfigurationPushed() {
|
||||||
@Override
|
@Override
|
||||||
public void onPushSucceeded() {
|
public void onPushSucceeded() {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": changed node configuration for avatar meta data node");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": changed node configuration for avatar meta data node");
|
||||||
|
|
|
@ -7,6 +7,8 @@ import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnLongClickListener;
|
import android.view.View.OnLongClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
@ -14,6 +16,7 @@ import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
import com.theartofdev.edmodo.cropper.CropImage;
|
import com.theartofdev.edmodo.cropper.CropImage;
|
||||||
|
@ -120,7 +123,25 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public boolean onCreateOptionsMenu(@NonNull final Menu menu) {
|
||||||
|
getMenuInflater().inflate(R.menu.activity_publish_profile_picture, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.action_delete_avatar) {
|
||||||
|
if (xmppConnectionService != null && account != null) {
|
||||||
|
xmppConnectionService.deleteAvatar(account);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||||
if (this.avatarUri != null) {
|
if (this.avatarUri != null) {
|
||||||
outState.putParcelable("uri", this.avatarUri);
|
outState.putParcelable("uri", this.avatarUri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ public final class Namespace {
|
||||||
public static final String BOOKMARKS_CONVERSION = "urn:xmpp:bookmarks-conversion:0";
|
public static final String BOOKMARKS_CONVERSION = "urn:xmpp:bookmarks-conversion:0";
|
||||||
public static final String BOOKMARKS = "storage:bookmarks";
|
public static final String BOOKMARKS = "storage:bookmarks";
|
||||||
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
|
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
|
||||||
|
public static final String AVATAR_DATA = "urn:xmpp:avatar:data";
|
||||||
|
public static final String AVATAR_METADATA = "urn:xmpp:avatar:metadata";
|
||||||
public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
|
public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
|
||||||
public static final String JINGLE = "urn:xmpp:jingle:1";
|
public static final String JINGLE = "urn:xmpp:jingle:1";
|
||||||
public static final String JINGLE_ERRORS = "urn:xmpp:jingle:errors:1";
|
public static final String JINGLE_ERRORS = "urn:xmpp:jingle:errors:1";
|
||||||
|
|
10
src/main/res/menu/activity_publish_profile_picture.xml
Normal file
10
src/main/res/menu/activity_publish_profile_picture.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_delete_avatar"
|
||||||
|
android:title="@string/delete_avatar"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
</menu>
|
|
@ -979,5 +979,6 @@
|
||||||
<string name="account_registrations_are_not_supported">Account registrations are not supported</string>
|
<string name="account_registrations_are_not_supported">Account registrations are not supported</string>
|
||||||
<string name="no_xmpp_adddress_found">No XMPP address found</string>
|
<string name="no_xmpp_adddress_found">No XMPP address found</string>
|
||||||
<string name="account_status_temporary_auth_failure">Temporary authentication failure</string>
|
<string name="account_status_temporary_auth_failure">Temporary authentication failure</string>
|
||||||
|
<string name="delete_avatar">Delete avatar</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue