mirror of
https://github.com/ArcaneChat/android.git
synced 2026-06-02 03:33:42 +02:00
Merge branch 'adb/use-spotless' of https://github.com/deltachat/deltachat-android into adb/use-spotless
This commit is contained in:
@@ -4,85 +4,106 @@ import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
public class DcChat {
|
||||
|
||||
public static final int DC_CHAT_TYPE_UNDEFINED = 0;
|
||||
public static final int DC_CHAT_TYPE_SINGLE = 100;
|
||||
public static final int DC_CHAT_TYPE_GROUP = 120;
|
||||
public static final int DC_CHAT_TYPE_MAILINGLIST = 140;
|
||||
public static final int DC_CHAT_TYPE_OUT_BROADCAST = 160;
|
||||
public static final int DC_CHAT_TYPE_IN_BROADCAST = 165;
|
||||
public static final int DC_CHAT_TYPE_UNDEFINED = 0;
|
||||
public static final int DC_CHAT_TYPE_SINGLE = 100;
|
||||
public static final int DC_CHAT_TYPE_GROUP = 120;
|
||||
public static final int DC_CHAT_TYPE_MAILINGLIST = 140;
|
||||
public static final int DC_CHAT_TYPE_OUT_BROADCAST = 160;
|
||||
public static final int DC_CHAT_TYPE_IN_BROADCAST = 165;
|
||||
|
||||
public static final int DC_CHAT_NO_CHAT = 0;
|
||||
public final static int DC_CHAT_ID_ARCHIVED_LINK = 6;
|
||||
public final static int DC_CHAT_ID_ALLDONE_HINT = 7;
|
||||
public final static int DC_CHAT_ID_LAST_SPECIAL = 9;
|
||||
public static final int DC_CHAT_NO_CHAT = 0;
|
||||
public static final int DC_CHAT_ID_ARCHIVED_LINK = 6;
|
||||
public static final int DC_CHAT_ID_ALLDONE_HINT = 7;
|
||||
public static final int DC_CHAT_ID_LAST_SPECIAL = 9;
|
||||
|
||||
public final static int DC_CHAT_VISIBILITY_NORMAL = 0;
|
||||
public final static int DC_CHAT_VISIBILITY_ARCHIVED = 1;
|
||||
public final static int DC_CHAT_VISIBILITY_PINNED = 2;
|
||||
public static final int DC_CHAT_VISIBILITY_NORMAL = 0;
|
||||
public static final int DC_CHAT_VISIBILITY_ARCHIVED = 1;
|
||||
public static final int DC_CHAT_VISIBILITY_PINNED = 2;
|
||||
|
||||
private int accountId;
|
||||
private int accountId;
|
||||
|
||||
public DcChat(int accountId, long chatCPtr) {
|
||||
this.accountId = accountId;
|
||||
this.chatCPtr = chatCPtr;
|
||||
public DcChat(int accountId, long chatCPtr) {
|
||||
this.accountId = accountId;
|
||||
this.chatCPtr = chatCPtr;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
unrefChatCPtr();
|
||||
chatCPtr = 0;
|
||||
}
|
||||
|
||||
public int getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public native int getId();
|
||||
|
||||
public native int getType();
|
||||
|
||||
public native int getVisibility();
|
||||
|
||||
public native String getName();
|
||||
|
||||
public native String getMailinglistAddr();
|
||||
|
||||
public native String getProfileImage();
|
||||
|
||||
public native int getColor();
|
||||
|
||||
public native boolean isEncrypted();
|
||||
|
||||
public native boolean isUnpromoted();
|
||||
|
||||
public native boolean isSelfTalk();
|
||||
|
||||
public native boolean isDeviceTalk();
|
||||
|
||||
public native boolean canSend();
|
||||
|
||||
public native boolean isSendingLocations();
|
||||
|
||||
public native boolean isMuted();
|
||||
|
||||
public native boolean isContactRequest();
|
||||
|
||||
// aliases and higher-level tools
|
||||
|
||||
public boolean isMultiUser() {
|
||||
int type = getType();
|
||||
return type != DC_CHAT_TYPE_SINGLE;
|
||||
}
|
||||
|
||||
public boolean shallLeaveBeforeDelete(DcContext dcContext) {
|
||||
if (isInBroadcast()) {
|
||||
final int[] members = dcContext.getChatContacts(getId());
|
||||
return Util.contains(members, DcContact.DC_CONTACT_ID_SELF);
|
||||
} else if (isMultiUser() && isEncrypted() && canSend() && !isOutBroadcast()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
unrefChatCPtr();
|
||||
chatCPtr = 0;
|
||||
}
|
||||
public boolean isMailingList() {
|
||||
return getType() == DC_CHAT_TYPE_MAILINGLIST;
|
||||
}
|
||||
|
||||
public int getAccountId () { return accountId; }
|
||||
public native int getId ();
|
||||
public native int getType ();
|
||||
public native int getVisibility ();
|
||||
public native String getName ();
|
||||
public native String getMailinglistAddr();
|
||||
public native String getProfileImage ();
|
||||
public native int getColor ();
|
||||
public native boolean isEncrypted ();
|
||||
public native boolean isUnpromoted ();
|
||||
public native boolean isSelfTalk ();
|
||||
public native boolean isDeviceTalk ();
|
||||
public native boolean canSend ();
|
||||
public native boolean isSendingLocations();
|
||||
public native boolean isMuted ();
|
||||
public native boolean isContactRequest ();
|
||||
public boolean isInBroadcast() {
|
||||
return getType() == DC_CHAT_TYPE_IN_BROADCAST;
|
||||
}
|
||||
|
||||
public boolean isOutBroadcast() {
|
||||
return getType() == DC_CHAT_TYPE_OUT_BROADCAST;
|
||||
}
|
||||
|
||||
// aliases and higher-level tools
|
||||
// working with raw c-data
|
||||
|
||||
public boolean isMultiUser() {
|
||||
int type = getType();
|
||||
return type != DC_CHAT_TYPE_SINGLE;
|
||||
}
|
||||
private long chatCPtr; // CAVE: the name is referenced in the JNI
|
||||
|
||||
public boolean shallLeaveBeforeDelete(DcContext dcContext) {
|
||||
if (isInBroadcast()) {
|
||||
final int[] members = dcContext.getChatContacts(getId());
|
||||
return Util.contains(members, DcContact.DC_CONTACT_ID_SELF);
|
||||
} else if (isMultiUser() && isEncrypted() && canSend() && !isOutBroadcast()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isMailingList() {
|
||||
return getType() == DC_CHAT_TYPE_MAILINGLIST;
|
||||
}
|
||||
|
||||
public boolean isInBroadcast() {
|
||||
return getType() == DC_CHAT_TYPE_IN_BROADCAST;
|
||||
}
|
||||
public boolean isOutBroadcast() {
|
||||
return getType() == DC_CHAT_TYPE_OUT_BROADCAST;
|
||||
}
|
||||
|
||||
// working with raw c-data
|
||||
|
||||
private long chatCPtr; // CAVE: the name is referenced in the JNI
|
||||
private native void unrefChatCPtr();
|
||||
public long getChatCPtr () { return chatCPtr; }
|
||||
private native void unrefChatCPtr();
|
||||
|
||||
public long getChatCPtr() {
|
||||
return chatCPtr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,67 +2,82 @@ package com.b44t.messenger;
|
||||
|
||||
public class DcContact {
|
||||
|
||||
public final static int DC_CONTACT_ID_SELF = 1;
|
||||
public final static int DC_CONTACT_ID_INFO = 2;
|
||||
public final static int DC_CONTACT_ID_DEVICE = 5;
|
||||
public final static int DC_CONTACT_ID_LAST_SPECIAL = 9;
|
||||
public final static int DC_CONTACT_ID_NEW_CLASSIC_CONTACT= -1; // used by the UI, not valid to the core
|
||||
public final static int DC_CONTACT_ID_NEW_GROUP = -2; // - " -
|
||||
public final static int DC_CONTACT_ID_ADD_MEMBER = -3; // - " -
|
||||
public final static int DC_CONTACT_ID_QR_INVITE = -4; // - " -
|
||||
public final static int DC_CONTACT_ID_NEW_BROADCAST = -5; // - " -
|
||||
public final static int DC_CONTACT_ID_ADD_ACCOUNT = -6; // - " -
|
||||
public final static int DC_CONTACT_ID_NEW_UNENCRYPTED_GROUP = -7; // - " -
|
||||
public static final int DC_CONTACT_ID_SELF = 1;
|
||||
public static final int DC_CONTACT_ID_INFO = 2;
|
||||
public static final int DC_CONTACT_ID_DEVICE = 5;
|
||||
public static final int DC_CONTACT_ID_LAST_SPECIAL = 9;
|
||||
public static final int DC_CONTACT_ID_NEW_CLASSIC_CONTACT =
|
||||
-1; // used by the UI, not valid to the core
|
||||
public static final int DC_CONTACT_ID_NEW_GROUP = -2; // - " -
|
||||
public static final int DC_CONTACT_ID_ADD_MEMBER = -3; // - " -
|
||||
public static final int DC_CONTACT_ID_QR_INVITE = -4; // - " -
|
||||
public static final int DC_CONTACT_ID_NEW_BROADCAST = -5; // - " -
|
||||
public static final int DC_CONTACT_ID_ADD_ACCOUNT = -6; // - " -
|
||||
public static final int DC_CONTACT_ID_NEW_UNENCRYPTED_GROUP = -7; // - " -
|
||||
|
||||
public DcContact(long contactCPtr) {
|
||||
this.contactCPtr = contactCPtr;
|
||||
public DcContact(long contactCPtr) {
|
||||
this.contactCPtr = contactCPtr;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
unrefContactCPtr();
|
||||
contactCPtr = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof DcContact)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
unrefContactCPtr();
|
||||
contactCPtr = 0;
|
||||
}
|
||||
DcContact that = (DcContact) other;
|
||||
return this.getId() == that.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof DcContact)) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return getAddr();
|
||||
}
|
||||
|
||||
DcContact that = (DcContact) other;
|
||||
return this.getId()==that.getId();
|
||||
}
|
||||
public native int getId();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getId();
|
||||
}
|
||||
public native String getName();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getAddr();
|
||||
}
|
||||
public native String getAuthName();
|
||||
|
||||
public native int getId ();
|
||||
public native String getName ();
|
||||
public native String getAuthName ();
|
||||
public native String getDisplayName ();
|
||||
public native String getAddr ();
|
||||
public native String getProfileImage();
|
||||
public native int getColor ();
|
||||
public native String getStatus ();
|
||||
public native long getLastSeen ();
|
||||
public native boolean wasSeenRecently();
|
||||
public native boolean isBlocked ();
|
||||
public native boolean isVerified ();
|
||||
public native boolean isKeyContact ();
|
||||
public native int getVerifierId ();
|
||||
public native boolean isBot ();
|
||||
public native String getDisplayName();
|
||||
|
||||
// working with raw c-data
|
||||
private long contactCPtr; // CAVE: the name is referenced in the JNI
|
||||
private native void unrefContactCPtr();
|
||||
public native String getAddr();
|
||||
|
||||
public native String getProfileImage();
|
||||
|
||||
public native int getColor();
|
||||
|
||||
public native String getStatus();
|
||||
|
||||
public native long getLastSeen();
|
||||
|
||||
public native boolean wasSeenRecently();
|
||||
|
||||
public native boolean isBlocked();
|
||||
|
||||
public native boolean isVerified();
|
||||
|
||||
public native boolean isKeyContact();
|
||||
|
||||
public native int getVerifierId();
|
||||
|
||||
public native boolean isBot();
|
||||
|
||||
// working with raw c-data
|
||||
private long contactCPtr; // CAVE: the name is referenced in the JNI
|
||||
|
||||
private native void unrefContactCPtr();
|
||||
}
|
||||
|
||||
@@ -2,273 +2,396 @@ package com.b44t.messenger;
|
||||
|
||||
public class DcContext {
|
||||
|
||||
public final static int DC_EVENT_INFO = 100;
|
||||
public final static int DC_EVENT_WARNING = 300;
|
||||
public final static int DC_EVENT_ERROR = 400;
|
||||
public final static int DC_EVENT_ERROR_SELF_NOT_IN_GROUP = 410;
|
||||
public final static int DC_EVENT_MSGS_CHANGED = 2000;
|
||||
public final static int DC_EVENT_REACTIONS_CHANGED = 2001;
|
||||
public final static int DC_EVENT_INCOMING_REACTION = 2002;
|
||||
public final static int DC_EVENT_INCOMING_WEBXDC_NOTIFY = 2003;
|
||||
public final static int DC_EVENT_INCOMING_MSG = 2005;
|
||||
public final static int DC_EVENT_MSGS_NOTICED = 2008;
|
||||
public final static int DC_EVENT_MSG_DELIVERED = 2010;
|
||||
public final static int DC_EVENT_MSG_FAILED = 2012;
|
||||
public final static int DC_EVENT_MSG_READ = 2015;
|
||||
public final static int DC_EVENT_MSG_DELETED = 2016;
|
||||
public final static int DC_EVENT_CHAT_MODIFIED = 2020;
|
||||
public final static int DC_EVENT_CHAT_EPHEMERAL_TIMER_MODIFIED = 2021;
|
||||
public final static int DC_EVENT_CHAT_DELETED = 2023;
|
||||
public final static int DC_EVENT_CONTACTS_CHANGED = 2030;
|
||||
public final static int DC_EVENT_LOCATION_CHANGED = 2035;
|
||||
public final static int DC_EVENT_CONFIGURE_PROGRESS = 2041;
|
||||
public final static int DC_EVENT_IMEX_PROGRESS = 2051;
|
||||
public final static int DC_EVENT_IMEX_FILE_WRITTEN = 2052;
|
||||
public final static int DC_EVENT_SECUREJOIN_INVITER_PROGRESS = 2060;
|
||||
public final static int DC_EVENT_SECUREJOIN_JOINER_PROGRESS = 2061;
|
||||
public final static int DC_EVENT_CONNECTIVITY_CHANGED = 2100;
|
||||
public final static int DC_EVENT_SELFAVATAR_CHANGED = 2110;
|
||||
public final static int DC_EVENT_WEBXDC_STATUS_UPDATE = 2120;
|
||||
public final static int DC_EVENT_WEBXDC_INSTANCE_DELETED = 2121;
|
||||
public final static int DC_EVENT_WEBXDC_REALTIME_DATA = 2150;
|
||||
public final static int DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE = 2200;
|
||||
public final static int DC_EVENT_INCOMING_CALL = 2550;
|
||||
public final static int DC_EVENT_INCOMING_CALL_ACCEPTED = 2560;
|
||||
public final static int DC_EVENT_OUTGOING_CALL_ACCEPTED = 2570;
|
||||
public final static int DC_EVENT_CALL_ENDED = 2580;
|
||||
public final static int DC_EVENT_TRANSPORTS_MODIFIED = 2600;
|
||||
public static final int DC_EVENT_INFO = 100;
|
||||
public static final int DC_EVENT_WARNING = 300;
|
||||
public static final int DC_EVENT_ERROR = 400;
|
||||
public static final int DC_EVENT_ERROR_SELF_NOT_IN_GROUP = 410;
|
||||
public static final int DC_EVENT_MSGS_CHANGED = 2000;
|
||||
public static final int DC_EVENT_REACTIONS_CHANGED = 2001;
|
||||
public static final int DC_EVENT_INCOMING_REACTION = 2002;
|
||||
public static final int DC_EVENT_INCOMING_WEBXDC_NOTIFY = 2003;
|
||||
public static final int DC_EVENT_INCOMING_MSG = 2005;
|
||||
public static final int DC_EVENT_MSGS_NOTICED = 2008;
|
||||
public static final int DC_EVENT_MSG_DELIVERED = 2010;
|
||||
public static final int DC_EVENT_MSG_FAILED = 2012;
|
||||
public static final int DC_EVENT_MSG_READ = 2015;
|
||||
public static final int DC_EVENT_MSG_DELETED = 2016;
|
||||
public static final int DC_EVENT_CHAT_MODIFIED = 2020;
|
||||
public static final int DC_EVENT_CHAT_EPHEMERAL_TIMER_MODIFIED = 2021;
|
||||
public static final int DC_EVENT_CHAT_DELETED = 2023;
|
||||
public static final int DC_EVENT_CONTACTS_CHANGED = 2030;
|
||||
public static final int DC_EVENT_LOCATION_CHANGED = 2035;
|
||||
public static final int DC_EVENT_CONFIGURE_PROGRESS = 2041;
|
||||
public static final int DC_EVENT_IMEX_PROGRESS = 2051;
|
||||
public static final int DC_EVENT_IMEX_FILE_WRITTEN = 2052;
|
||||
public static final int DC_EVENT_SECUREJOIN_INVITER_PROGRESS = 2060;
|
||||
public static final int DC_EVENT_SECUREJOIN_JOINER_PROGRESS = 2061;
|
||||
public static final int DC_EVENT_CONNECTIVITY_CHANGED = 2100;
|
||||
public static final int DC_EVENT_SELFAVATAR_CHANGED = 2110;
|
||||
public static final int DC_EVENT_WEBXDC_STATUS_UPDATE = 2120;
|
||||
public static final int DC_EVENT_WEBXDC_INSTANCE_DELETED = 2121;
|
||||
public static final int DC_EVENT_WEBXDC_REALTIME_DATA = 2150;
|
||||
public static final int DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE = 2200;
|
||||
public static final int DC_EVENT_INCOMING_CALL = 2550;
|
||||
public static final int DC_EVENT_INCOMING_CALL_ACCEPTED = 2560;
|
||||
public static final int DC_EVENT_OUTGOING_CALL_ACCEPTED = 2570;
|
||||
public static final int DC_EVENT_CALL_ENDED = 2580;
|
||||
public static final int DC_EVENT_TRANSPORTS_MODIFIED = 2600;
|
||||
|
||||
public final static int DC_IMEX_EXPORT_SELF_KEYS = 1;
|
||||
public final static int DC_IMEX_IMPORT_SELF_KEYS = 2;
|
||||
public final static int DC_IMEX_EXPORT_BACKUP = 11;
|
||||
public final static int DC_IMEX_IMPORT_BACKUP = 12;
|
||||
public static final int DC_IMEX_EXPORT_SELF_KEYS = 1;
|
||||
public static final int DC_IMEX_IMPORT_SELF_KEYS = 2;
|
||||
public static final int DC_IMEX_EXPORT_BACKUP = 11;
|
||||
public static final int DC_IMEX_IMPORT_BACKUP = 12;
|
||||
|
||||
public final static int DC_GCL_VERIFIED_ONLY = 1;
|
||||
public final static int DC_GCL_ADD_SELF = 2;
|
||||
public final static int DC_GCL_ADDRESS = 0x04;
|
||||
public final static int DC_GCL_ARCHIVED_ONLY = 0x01;
|
||||
public final static int DC_GCL_NO_SPECIALS = 0x02;
|
||||
public final static int DC_GCL_ADD_ALLDONE_HINT = 0x04;
|
||||
public final static int DC_GCL_FOR_FORWARDING = 0x08;
|
||||
public static final int DC_GCL_VERIFIED_ONLY = 1;
|
||||
public static final int DC_GCL_ADD_SELF = 2;
|
||||
public static final int DC_GCL_ADDRESS = 0x04;
|
||||
public static final int DC_GCL_ARCHIVED_ONLY = 0x01;
|
||||
public static final int DC_GCL_NO_SPECIALS = 0x02;
|
||||
public static final int DC_GCL_ADD_ALLDONE_HINT = 0x04;
|
||||
public static final int DC_GCL_FOR_FORWARDING = 0x08;
|
||||
|
||||
public final static int DC_GCM_ADDDAYMARKER = 0x01;
|
||||
public static final int DC_GCM_ADDDAYMARKER = 0x01;
|
||||
|
||||
public final static int DC_QR_ASK_VERIFYCONTACT = 200;
|
||||
public final static int DC_QR_ASK_VERIFYGROUP = 202;
|
||||
public final static int DC_QR_ASK_JOIN_BROADCAST= 204;
|
||||
public final static int DC_QR_FPR_OK = 210;
|
||||
public final static int DC_QR_FPR_MISMATCH = 220;
|
||||
public final static int DC_QR_FPR_WITHOUT_ADDR = 230;
|
||||
public final static int DC_QR_ACCOUNT = 250;
|
||||
public final static int DC_QR_BACKUP2 = 252;
|
||||
public final static int DC_QR_BACKUP_TOO_NEW = 255;
|
||||
public final static int DC_QR_WEBRTC = 260;
|
||||
public final static int DC_QR_PROXY = 271;
|
||||
public final static int DC_QR_ADDR = 320;
|
||||
public final static int DC_QR_TEXT = 330;
|
||||
public final static int DC_QR_URL = 332;
|
||||
public final static int DC_QR_ERROR = 400;
|
||||
public final static int DC_QR_WITHDRAW_VERIFYCONTACT = 500;
|
||||
public final static int DC_QR_WITHDRAW_VERIFYGROUP = 502;
|
||||
public final static int DC_QR_WITHDRAW_JOINBROADCAST = 504;
|
||||
public final static int DC_QR_REVIVE_VERIFYCONTACT = 510;
|
||||
public final static int DC_QR_REVIVE_VERIFYGROUP = 512;
|
||||
public final static int DC_QR_REVIVE_JOINBROADCAST = 514;
|
||||
public final static int DC_QR_LOGIN = 520;
|
||||
public static final int DC_QR_ASK_VERIFYCONTACT = 200;
|
||||
public static final int DC_QR_ASK_VERIFYGROUP = 202;
|
||||
public static final int DC_QR_ASK_JOIN_BROADCAST = 204;
|
||||
public static final int DC_QR_FPR_OK = 210;
|
||||
public static final int DC_QR_FPR_MISMATCH = 220;
|
||||
public static final int DC_QR_FPR_WITHOUT_ADDR = 230;
|
||||
public static final int DC_QR_ACCOUNT = 250;
|
||||
public static final int DC_QR_BACKUP2 = 252;
|
||||
public static final int DC_QR_BACKUP_TOO_NEW = 255;
|
||||
public static final int DC_QR_WEBRTC = 260;
|
||||
public static final int DC_QR_PROXY = 271;
|
||||
public static final int DC_QR_ADDR = 320;
|
||||
public static final int DC_QR_TEXT = 330;
|
||||
public static final int DC_QR_URL = 332;
|
||||
public static final int DC_QR_ERROR = 400;
|
||||
public static final int DC_QR_WITHDRAW_VERIFYCONTACT = 500;
|
||||
public static final int DC_QR_WITHDRAW_VERIFYGROUP = 502;
|
||||
public static final int DC_QR_WITHDRAW_JOINBROADCAST = 504;
|
||||
public static final int DC_QR_REVIVE_VERIFYCONTACT = 510;
|
||||
public static final int DC_QR_REVIVE_VERIFYGROUP = 512;
|
||||
public static final int DC_QR_REVIVE_JOINBROADCAST = 514;
|
||||
public static final int DC_QR_LOGIN = 520;
|
||||
|
||||
public final static int DC_SOCKET_AUTO = 0;
|
||||
public final static int DC_SOCKET_SSL = 1;
|
||||
public final static int DC_SOCKET_STARTTLS = 2;
|
||||
public final static int DC_SOCKET_PLAIN = 3;
|
||||
public static final int DC_SOCKET_AUTO = 0;
|
||||
public static final int DC_SOCKET_SSL = 1;
|
||||
public static final int DC_SOCKET_STARTTLS = 2;
|
||||
public static final int DC_SOCKET_PLAIN = 3;
|
||||
|
||||
public final static int DC_SHOW_EMAILS_OFF = 0;
|
||||
public final static int DC_SHOW_EMAILS_ACCEPTED_CONTACTS = 1;
|
||||
public final static int DC_SHOW_EMAILS_ALL = 2;
|
||||
public static final int DC_SHOW_EMAILS_OFF = 0;
|
||||
public static final int DC_SHOW_EMAILS_ACCEPTED_CONTACTS = 1;
|
||||
public static final int DC_SHOW_EMAILS_ALL = 2;
|
||||
|
||||
public final static int DC_MEDIA_QUALITY_BALANCED = 0;
|
||||
public final static int DC_MEDIA_QUALITY_WORSE = 1;
|
||||
public static final int DC_MEDIA_QUALITY_BALANCED = 0;
|
||||
public static final int DC_MEDIA_QUALITY_WORSE = 1;
|
||||
|
||||
public final static int DC_CONNECTIVITY_NOT_CONNECTED = 1000;
|
||||
public final static int DC_CONNECTIVITY_CONNECTING = 2000;
|
||||
public final static int DC_CONNECTIVITY_WORKING = 3000;
|
||||
public final static int DC_CONNECTIVITY_CONNECTED = 4000;
|
||||
public static final int DC_CONNECTIVITY_NOT_CONNECTED = 1000;
|
||||
public static final int DC_CONNECTIVITY_CONNECTING = 2000;
|
||||
public static final int DC_CONNECTIVITY_WORKING = 3000;
|
||||
public static final int DC_CONNECTIVITY_CONNECTED = 4000;
|
||||
|
||||
private static final String CONFIG_MUTE_MENTIONS_IF_MUTED = "ui.mute_mentions_if_muted";
|
||||
private static final String CONFIG_MUTE_MENTIONS_IF_MUTED = "ui.mute_mentions_if_muted";
|
||||
|
||||
// when using DcAccounts, use Rpc.addAccount() instead
|
||||
public DcContext(String osName, String dbfile) {
|
||||
contextCPtr = createContextCPtr(osName, dbfile);
|
||||
// when using DcAccounts, use Rpc.addAccount() instead
|
||||
public DcContext(String osName, String dbfile) {
|
||||
contextCPtr = createContextCPtr(osName, dbfile);
|
||||
}
|
||||
|
||||
public DcContext(long contextCPtr) {
|
||||
this.contextCPtr = contextCPtr;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return contextCPtr != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
if (contextCPtr != 0) {
|
||||
unrefContextCPtr();
|
||||
contextCPtr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public DcContext(long contextCPtr) {
|
||||
this.contextCPtr = contextCPtr;
|
||||
public native int getAccountId();
|
||||
|
||||
// when using DcAccounts, use DcAccounts.getEventEmitter() instead
|
||||
public DcEventEmitter getEventEmitter() {
|
||||
return new DcEventEmitter(getEventEmitterCPtr());
|
||||
}
|
||||
|
||||
public native void setStockTranslation(int stockId, String translation);
|
||||
|
||||
public native String getBlobdir();
|
||||
|
||||
public native String getLastError();
|
||||
|
||||
public native void stopOngoingProcess();
|
||||
|
||||
public native int isConfigured();
|
||||
|
||||
public native boolean open(String passphrase);
|
||||
|
||||
public native boolean isOpen();
|
||||
|
||||
// when using DcAccounts, use DcAccounts.startIo() instead
|
||||
public native void startIo();
|
||||
|
||||
// when using DcAccounts, use DcAccounts.stopIo() instead
|
||||
public native void stopIo();
|
||||
|
||||
// when using DcAccounts, use DcAccounts.maybeNetwork() instead
|
||||
public native void maybeNetwork();
|
||||
|
||||
public native void setConfig(String key, String value);
|
||||
|
||||
public void setConfigInt(String key, int value) {
|
||||
setConfig(key, Integer.toString(value));
|
||||
}
|
||||
|
||||
public native boolean setConfigFromQr(String qr);
|
||||
|
||||
public native String getConfig(String key);
|
||||
|
||||
public int getConfigInt(String key) {
|
||||
try {
|
||||
return Integer.parseInt(getConfig(key));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return contextCPtr != 0;
|
||||
public native String getInfo();
|
||||
|
||||
public native int getConnectivity();
|
||||
|
||||
public native String getConnectivityHtml();
|
||||
|
||||
public native String initiateKeyTransfer();
|
||||
|
||||
public native void imex(int what, String dir);
|
||||
|
||||
public native String imexHasBackup(String dir);
|
||||
|
||||
public DcBackupProvider newBackupProvider() {
|
||||
return new DcBackupProvider(newBackupProviderCPtr());
|
||||
}
|
||||
|
||||
public native boolean receiveBackup(String qr);
|
||||
|
||||
public native boolean mayBeValidAddr(String addr);
|
||||
|
||||
public native int lookupContactIdByAddr(String addr);
|
||||
|
||||
public native int[] getContacts(int flags, String query);
|
||||
|
||||
public native int[] getBlockedContacts();
|
||||
|
||||
public DcContact getContact(int contact_id) {
|
||||
return new DcContact(getContactCPtr(contact_id));
|
||||
}
|
||||
|
||||
public native int createContact(String name, String addr);
|
||||
|
||||
public native void blockContact(int id, int block);
|
||||
|
||||
public native String getContactEncrInfo(int contact_id);
|
||||
|
||||
public native boolean deleteContact(int id);
|
||||
|
||||
public native int addAddressBook(String adrbook);
|
||||
|
||||
public DcChatlist getChatlist(int listflags, String query, int queryId) {
|
||||
return new DcChatlist(getAccountId(), getChatlistCPtr(listflags, query, queryId));
|
||||
}
|
||||
|
||||
public DcChat getChat(int chat_id) {
|
||||
return new DcChat(getAccountId(), getChatCPtr(chat_id));
|
||||
}
|
||||
|
||||
public native String getChatEncrInfo(int chat_id);
|
||||
|
||||
public native void markseenMsgs(int msg_ids[]);
|
||||
|
||||
public native void marknoticedChat(int chat_id);
|
||||
|
||||
public native void setChatVisibility(int chat_id, int visibility);
|
||||
|
||||
public native int getChatIdByContactId(int contact_id);
|
||||
|
||||
public native int createChatByContactId(int contact_id);
|
||||
|
||||
public native int createGroupChat(String name);
|
||||
|
||||
public native int createBroadcastList();
|
||||
|
||||
public native boolean isContactInChat(int chat_id, int contact_id);
|
||||
|
||||
public native int addContactToChat(int chat_id, int contact_id);
|
||||
|
||||
public native int removeContactFromChat(int chat_id, int contact_id);
|
||||
|
||||
public native void setDraft(int chat_id, DcMsg msg /*null=delete*/);
|
||||
|
||||
public DcMsg getDraft(int chat_id) {
|
||||
return new DcMsg(getDraftCPtr(chat_id));
|
||||
}
|
||||
|
||||
public native int setChatName(int chat_id, String name);
|
||||
|
||||
public native int setChatProfileImage(int chat_id, String name);
|
||||
|
||||
public native int[] getChatMsgs(int chat_id, int flags, int marker1before);
|
||||
|
||||
public native int[] searchMsgs(int chat_id, String query);
|
||||
|
||||
public native int[] getFreshMsgs();
|
||||
|
||||
public native int[] getChatMedia(int chat_id, int type1, int type2, int type3);
|
||||
|
||||
public native int[] getChatContacts(int chat_id);
|
||||
|
||||
public native int getChatEphemeralTimer(int chat_id);
|
||||
|
||||
public native boolean setChatEphemeralTimer(int chat_id, int timer);
|
||||
|
||||
public native boolean setChatMuteDuration(int chat_id, long duration);
|
||||
|
||||
public native void deleteChat(int chat_id);
|
||||
|
||||
public native void blockChat(int chat_id);
|
||||
|
||||
public native void acceptChat(int chat_id);
|
||||
|
||||
public DcMsg getMsg(int msg_id) {
|
||||
return new DcMsg(getMsgCPtr(msg_id));
|
||||
}
|
||||
|
||||
public native void sendEditRequest(int msg_id, String text);
|
||||
|
||||
public native String getMsgInfo(int id);
|
||||
|
||||
public native String getMsgHtml(int msg_id);
|
||||
|
||||
public native void downloadFullMsg(int msg_id);
|
||||
|
||||
public native int getFreshMsgCount(int chat_id);
|
||||
|
||||
public native int estimateDeletionCount(boolean from_server, long seconds);
|
||||
|
||||
public native void deleteMsgs(int msg_ids[]);
|
||||
|
||||
public native void sendDeleteRequest(int msg_ids[]);
|
||||
|
||||
public native void forwardMsgs(int msg_ids[], int chat_id);
|
||||
|
||||
public native void saveMsgs(int msg_ids[]);
|
||||
|
||||
public native boolean resendMsgs(int msg_ids[]);
|
||||
|
||||
public native int sendMsg(int chat_id, DcMsg msg);
|
||||
|
||||
public native int sendTextMsg(int chat_id, String text);
|
||||
|
||||
public native boolean sendWebxdcStatusUpdate(int msg_id, String payload);
|
||||
|
||||
public native String getWebxdcStatusUpdates(int msg_id, int last_known_serial);
|
||||
|
||||
public native void setWebxdcIntegration(String file);
|
||||
|
||||
public native int initWebxdcIntegration(int chat_id);
|
||||
|
||||
public native int addDeviceMsg(String label, DcMsg msg);
|
||||
|
||||
public native boolean wasDeviceMsgEverAdded(String label);
|
||||
|
||||
public DcLot checkQr(String qr) {
|
||||
return new DcLot(checkQrCPtr(qr));
|
||||
}
|
||||
|
||||
public native String getSecurejoinQr(int chat_id);
|
||||
|
||||
public native String getSecurejoinQrSvg(int chat_id);
|
||||
|
||||
public native String createQrSvg(String payload);
|
||||
|
||||
public native int joinSecurejoin(String qr);
|
||||
|
||||
public native void sendLocationsToChat(int chat_id, int seconds);
|
||||
|
||||
public native boolean isSendingLocationsToChat(int chat_id);
|
||||
|
||||
public DcProvider getProviderFromEmailWithDns(String email) {
|
||||
long cptr = getProviderFromEmailWithDnsCPtr(email);
|
||||
return cptr != 0 ? new DcProvider(cptr) : null;
|
||||
}
|
||||
|
||||
public boolean isMentionsEnabled() {
|
||||
return getConfigInt(CONFIG_MUTE_MENTIONS_IF_MUTED) != 1;
|
||||
}
|
||||
|
||||
public void setMentionsEnabled(boolean enabled) {
|
||||
setConfigInt(CONFIG_MUTE_MENTIONS_IF_MUTED, enabled ? 0 : 1);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String displayname = getConfig("displayname");
|
||||
if (displayname.isEmpty()) {
|
||||
displayname = getConfig("addr");
|
||||
}
|
||||
return displayname;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
if (contextCPtr != 0) {
|
||||
unrefContextCPtr();
|
||||
contextCPtr = 0;
|
||||
}
|
||||
}
|
||||
public boolean isChatmail() {
|
||||
return getConfigInt("is_chatmail") == 1;
|
||||
}
|
||||
|
||||
public native int getAccountId ();
|
||||
public boolean isMuted() {
|
||||
return getConfigInt("is_muted") == 1;
|
||||
}
|
||||
|
||||
// when using DcAccounts, use DcAccounts.getEventEmitter() instead
|
||||
public DcEventEmitter getEventEmitter () { return new DcEventEmitter(getEventEmitterCPtr()); }
|
||||
public void setMuted(boolean muted) {
|
||||
setConfigInt("is_muted", muted ? 1 : 0);
|
||||
}
|
||||
|
||||
public native void setStockTranslation (int stockId, String translation);
|
||||
public native String getBlobdir ();
|
||||
public native String getLastError ();
|
||||
public native void stopOngoingProcess ();
|
||||
public native int isConfigured ();
|
||||
public native boolean open (String passphrase);
|
||||
public native boolean isOpen ();
|
||||
public void restartIo() {
|
||||
stopIo();
|
||||
startIo();
|
||||
}
|
||||
|
||||
// when using DcAccounts, use DcAccounts.startIo() instead
|
||||
public native void startIo ();
|
||||
/**
|
||||
* @return true if at least one chat has location streaming enabled
|
||||
*/
|
||||
public native boolean setLocation(float latitude, float longitude, float accuracy);
|
||||
|
||||
// when using DcAccounts, use DcAccounts.stopIo() instead
|
||||
public native void stopIo ();
|
||||
// working with raw c-data
|
||||
private long contextCPtr; // CAVE: the name is referenced in the JNI
|
||||
|
||||
// when using DcAccounts, use DcAccounts.maybeNetwork() instead
|
||||
public native void maybeNetwork ();
|
||||
private native long createContextCPtr(String osName, String dbfile);
|
||||
|
||||
public native void setConfig (String key, String value);
|
||||
public void setConfigInt (String key, int value) { setConfig(key, Integer.toString(value)); }
|
||||
public native boolean setConfigFromQr (String qr);
|
||||
public native String getConfig (String key);
|
||||
public int getConfigInt (String key) { try{return Integer.parseInt(getConfig(key));} catch(Exception e) {} return 0; }
|
||||
public native String getInfo ();
|
||||
public native int getConnectivity ();
|
||||
public native String getConnectivityHtml ();
|
||||
public native String initiateKeyTransfer ();
|
||||
public native void imex (int what, String dir);
|
||||
public native String imexHasBackup (String dir);
|
||||
public DcBackupProvider newBackupProvider () { return new DcBackupProvider(newBackupProviderCPtr()); }
|
||||
public native boolean receiveBackup (String qr);
|
||||
public native boolean mayBeValidAddr (String addr);
|
||||
public native int lookupContactIdByAddr(String addr);
|
||||
public native int[] getContacts (int flags, String query);
|
||||
public native int[] getBlockedContacts ();
|
||||
public DcContact getContact (int contact_id) { return new DcContact(getContactCPtr(contact_id)); }
|
||||
public native int createContact (String name, String addr);
|
||||
public native void blockContact (int id, int block);
|
||||
public native String getContactEncrInfo (int contact_id);
|
||||
public native boolean deleteContact (int id);
|
||||
public native int addAddressBook (String adrbook);
|
||||
public DcChatlist getChatlist (int listflags, String query, int queryId) { return new DcChatlist(getAccountId(), getChatlistCPtr(listflags, query, queryId)); }
|
||||
public DcChat getChat (int chat_id) { return new DcChat(getAccountId(), getChatCPtr(chat_id)); }
|
||||
public native String getChatEncrInfo (int chat_id);
|
||||
public native void markseenMsgs (int msg_ids[]);
|
||||
public native void marknoticedChat (int chat_id);
|
||||
public native void setChatVisibility (int chat_id, int visibility);
|
||||
public native int getChatIdByContactId (int contact_id);
|
||||
public native int createChatByContactId(int contact_id);
|
||||
public native int createGroupChat (String name);
|
||||
public native int createBroadcastList ();
|
||||
public native boolean isContactInChat (int chat_id, int contact_id);
|
||||
public native int addContactToChat (int chat_id, int contact_id);
|
||||
public native int removeContactFromChat(int chat_id, int contact_id);
|
||||
public native void setDraft (int chat_id, DcMsg msg/*null=delete*/);
|
||||
public DcMsg getDraft (int chat_id) { return new DcMsg(getDraftCPtr(chat_id)); }
|
||||
public native int setChatName (int chat_id, String name);
|
||||
public native int setChatProfileImage (int chat_id, String name);
|
||||
public native int[] getChatMsgs (int chat_id, int flags, int marker1before);
|
||||
public native int[] searchMsgs (int chat_id, String query);
|
||||
public native int[] getFreshMsgs ();
|
||||
public native int[] getChatMedia (int chat_id, int type1, int type2, int type3);
|
||||
public native int[] getChatContacts (int chat_id);
|
||||
public native int getChatEphemeralTimer (int chat_id);
|
||||
public native boolean setChatEphemeralTimer (int chat_id, int timer);
|
||||
public native boolean setChatMuteDuration (int chat_id, long duration);
|
||||
public native void deleteChat (int chat_id);
|
||||
public native void blockChat (int chat_id);
|
||||
public native void acceptChat (int chat_id);
|
||||
public DcMsg getMsg (int msg_id) { return new DcMsg(getMsgCPtr(msg_id)); }
|
||||
public native void sendEditRequest (int msg_id, String text);
|
||||
public native String getMsgInfo (int id);
|
||||
public native String getMsgHtml (int msg_id);
|
||||
public native void downloadFullMsg (int msg_id);
|
||||
public native int getFreshMsgCount (int chat_id);
|
||||
public native int estimateDeletionCount(boolean from_server, long seconds);
|
||||
public native void deleteMsgs (int msg_ids[]);
|
||||
public native void sendDeleteRequest (int msg_ids[]);
|
||||
public native void forwardMsgs (int msg_ids[], int chat_id);
|
||||
public native void saveMsgs (int msg_ids[]);
|
||||
public native boolean resendMsgs (int msg_ids[]);
|
||||
public native int sendMsg (int chat_id, DcMsg msg);
|
||||
public native int sendTextMsg (int chat_id, String text);
|
||||
public native boolean sendWebxdcStatusUpdate(int msg_id, String payload);
|
||||
public native String getWebxdcStatusUpdates(int msg_id, int last_known_serial);
|
||||
public native void setWebxdcIntegration (String file);
|
||||
public native int initWebxdcIntegration(int chat_id);
|
||||
public native int addDeviceMsg (String label, DcMsg msg);
|
||||
public native boolean wasDeviceMsgEverAdded(String label);
|
||||
public DcLot checkQr (String qr) { return new DcLot(checkQrCPtr(qr)); }
|
||||
public native String getSecurejoinQr (int chat_id);
|
||||
public native String getSecurejoinQrSvg (int chat_id);
|
||||
public native String createQrSvg (String payload);
|
||||
public native int joinSecurejoin (String qr);
|
||||
public native void sendLocationsToChat (int chat_id, int seconds);
|
||||
public native boolean isSendingLocationsToChat(int chat_id);
|
||||
public DcProvider getProviderFromEmailWithDns (String email) { long cptr = getProviderFromEmailWithDnsCPtr(email); return cptr!=0 ? new DcProvider(cptr) : null; }
|
||||
private native void unrefContextCPtr();
|
||||
|
||||
public boolean isMentionsEnabled() {
|
||||
return getConfigInt(CONFIG_MUTE_MENTIONS_IF_MUTED) != 1;
|
||||
}
|
||||
private native long getEventEmitterCPtr();
|
||||
|
||||
public void setMentionsEnabled(boolean enabled) {
|
||||
setConfigInt(CONFIG_MUTE_MENTIONS_IF_MUTED, enabled? 0 : 1);
|
||||
}
|
||||
public native long createMsgCPtr(int viewtype);
|
||||
|
||||
public String getName() {
|
||||
String displayname = getConfig("displayname");
|
||||
if (displayname.isEmpty()) {
|
||||
displayname = getConfig("addr");
|
||||
}
|
||||
return displayname;
|
||||
}
|
||||
private native long getChatlistCPtr(int listflags, String query, int queryId);
|
||||
|
||||
public boolean isChatmail() {
|
||||
return getConfigInt("is_chatmail") == 1;
|
||||
}
|
||||
private native long getChatCPtr(int chat_id);
|
||||
|
||||
public boolean isMuted() {
|
||||
return getConfigInt("is_muted") == 1;
|
||||
}
|
||||
private native long getMsgCPtr(int id);
|
||||
|
||||
public void setMuted(boolean muted) {
|
||||
setConfigInt("is_muted", muted? 1 : 0);
|
||||
}
|
||||
private native long getDraftCPtr(int id);
|
||||
|
||||
public void restartIo() {
|
||||
stopIo();
|
||||
startIo();
|
||||
}
|
||||
private native long getContactCPtr(int id);
|
||||
|
||||
/**
|
||||
* @return true if at least one chat has location streaming enabled
|
||||
*/
|
||||
public native boolean setLocation (float latitude, float longitude, float accuracy);
|
||||
private native long checkQrCPtr(String qr);
|
||||
|
||||
// working with raw c-data
|
||||
private long contextCPtr; // CAVE: the name is referenced in the JNI
|
||||
private native long createContextCPtr(String osName, String dbfile);
|
||||
private native void unrefContextCPtr ();
|
||||
private native long getEventEmitterCPtr();
|
||||
public native long createMsgCPtr (int viewtype);
|
||||
private native long getChatlistCPtr (int listflags, String query, int queryId);
|
||||
private native long getChatCPtr (int chat_id);
|
||||
private native long getMsgCPtr (int id);
|
||||
private native long getDraftCPtr (int id);
|
||||
private native long getContactCPtr (int id);
|
||||
private native long checkQrCPtr (String qr);
|
||||
private native long getProviderFromEmailWithDnsCPtr (String addr);
|
||||
private native long newBackupProviderCPtr();
|
||||
private native long getProviderFromEmailWithDnsCPtr(String addr);
|
||||
|
||||
private native long newBackupProviderCPtr();
|
||||
}
|
||||
|
||||
@@ -1,262 +1,320 @@
|
||||
package com.b44t.messenger;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class DcMsg {
|
||||
|
||||
public final static int DC_MSG_UNDEFINED = 0;
|
||||
public final static int DC_MSG_TEXT = 10;
|
||||
public final static int DC_MSG_IMAGE = 20;
|
||||
public final static int DC_MSG_GIF = 21;
|
||||
public final static int DC_MSG_STICKER = 23;
|
||||
public final static int DC_MSG_AUDIO = 40;
|
||||
public final static int DC_MSG_VOICE = 41;
|
||||
public final static int DC_MSG_VIDEO = 50;
|
||||
public final static int DC_MSG_FILE = 60;
|
||||
public final static int DC_MSG_CALL = 71;
|
||||
public final static int DC_MSG_WEBXDC = 80;
|
||||
public final static int DC_MSG_VCARD = 90;
|
||||
public static final int DC_MSG_UNDEFINED = 0;
|
||||
public static final int DC_MSG_TEXT = 10;
|
||||
public static final int DC_MSG_IMAGE = 20;
|
||||
public static final int DC_MSG_GIF = 21;
|
||||
public static final int DC_MSG_STICKER = 23;
|
||||
public static final int DC_MSG_AUDIO = 40;
|
||||
public static final int DC_MSG_VOICE = 41;
|
||||
public static final int DC_MSG_VIDEO = 50;
|
||||
public static final int DC_MSG_FILE = 60;
|
||||
public static final int DC_MSG_CALL = 71;
|
||||
public static final int DC_MSG_WEBXDC = 80;
|
||||
public static final int DC_MSG_VCARD = 90;
|
||||
|
||||
public final static int DC_INFO_UNKNOWN = 0;
|
||||
public final static int DC_INFO_GROUP_NAME_CHANGED = 2;
|
||||
public final static int DC_INFO_GROUP_IMAGE_CHANGED = 3;
|
||||
public final static int DC_INFO_MEMBER_ADDED_TO_GROUP = 4;
|
||||
public final static int DC_INFO_MEMBER_REMOVED_FROM_GROUP = 5;
|
||||
public final static int DC_INFO_AUTOCRYPT_SETUP_MESSAGE = 6;
|
||||
public final static int DC_INFO_SECURE_JOIN_MESSAGE = 7;
|
||||
public final static int DC_INFO_LOCATIONSTREAMING_ENABLED = 8;
|
||||
public final static int DC_INFO_LOCATION_ONLY = 9;
|
||||
public final static int DC_INFO_EPHEMERAL_TIMER_CHANGED = 10;
|
||||
public final static int DC_INFO_PROTECTION_ENABLED = 11;
|
||||
public final static int DC_INFO_INVALID_UNENCRYPTED_MAIL = 13;
|
||||
public final static int DC_INFO_WEBXDC_INFO_MESSAGE = 32;
|
||||
public final static int DC_INFO_CHAT_E2EE = 50;
|
||||
public final static int DC_INFO_CHAT_DESCRIPTION_CHANGED = 70;
|
||||
public static final int DC_INFO_UNKNOWN = 0;
|
||||
public static final int DC_INFO_GROUP_NAME_CHANGED = 2;
|
||||
public static final int DC_INFO_GROUP_IMAGE_CHANGED = 3;
|
||||
public static final int DC_INFO_MEMBER_ADDED_TO_GROUP = 4;
|
||||
public static final int DC_INFO_MEMBER_REMOVED_FROM_GROUP = 5;
|
||||
public static final int DC_INFO_AUTOCRYPT_SETUP_MESSAGE = 6;
|
||||
public static final int DC_INFO_SECURE_JOIN_MESSAGE = 7;
|
||||
public static final int DC_INFO_LOCATIONSTREAMING_ENABLED = 8;
|
||||
public static final int DC_INFO_LOCATION_ONLY = 9;
|
||||
public static final int DC_INFO_EPHEMERAL_TIMER_CHANGED = 10;
|
||||
public static final int DC_INFO_PROTECTION_ENABLED = 11;
|
||||
public static final int DC_INFO_INVALID_UNENCRYPTED_MAIL = 13;
|
||||
public static final int DC_INFO_WEBXDC_INFO_MESSAGE = 32;
|
||||
public static final int DC_INFO_CHAT_E2EE = 50;
|
||||
public static final int DC_INFO_CHAT_DESCRIPTION_CHANGED = 70;
|
||||
|
||||
public final static int DC_STATE_UNDEFINED = 0;
|
||||
public final static int DC_STATE_IN_FRESH = 10;
|
||||
public final static int DC_STATE_IN_NOTICED = 13;
|
||||
public final static int DC_STATE_IN_SEEN = 16;
|
||||
public final static int DC_STATE_OUT_PREPARING = 18;
|
||||
public final static int DC_STATE_OUT_DRAFT = 19;
|
||||
public final static int DC_STATE_OUT_PENDING = 20;
|
||||
public final static int DC_STATE_OUT_FAILED = 24;
|
||||
public final static int DC_STATE_OUT_DELIVERED = 26;
|
||||
public final static int DC_STATE_OUT_MDN_RCVD = 28;
|
||||
public static final int DC_STATE_UNDEFINED = 0;
|
||||
public static final int DC_STATE_IN_FRESH = 10;
|
||||
public static final int DC_STATE_IN_NOTICED = 13;
|
||||
public static final int DC_STATE_IN_SEEN = 16;
|
||||
public static final int DC_STATE_OUT_PREPARING = 18;
|
||||
public static final int DC_STATE_OUT_DRAFT = 19;
|
||||
public static final int DC_STATE_OUT_PENDING = 20;
|
||||
public static final int DC_STATE_OUT_FAILED = 24;
|
||||
public static final int DC_STATE_OUT_DELIVERED = 26;
|
||||
public static final int DC_STATE_OUT_MDN_RCVD = 28;
|
||||
|
||||
public final static int DC_DOWNLOAD_DONE = 0;
|
||||
public final static int DC_DOWNLOAD_AVAILABLE = 10;
|
||||
public final static int DC_DOWNLOAD_FAILURE = 20;
|
||||
public final static int DC_DOWNLOAD_UNDECIPHERABLE = 30;
|
||||
public final static int DC_DOWNLOAD_IN_PROGRESS = 1000;
|
||||
public static final int DC_DOWNLOAD_DONE = 0;
|
||||
public static final int DC_DOWNLOAD_AVAILABLE = 10;
|
||||
public static final int DC_DOWNLOAD_FAILURE = 20;
|
||||
public static final int DC_DOWNLOAD_UNDECIPHERABLE = 30;
|
||||
public static final int DC_DOWNLOAD_IN_PROGRESS = 1000;
|
||||
|
||||
public static final int DC_MSG_NO_ID = 0;
|
||||
public final static int DC_MSG_ID_MARKER1 = 1;
|
||||
public final static int DC_MSG_ID_DAYMARKER = 9;
|
||||
public static final int DC_MSG_NO_ID = 0;
|
||||
public static final int DC_MSG_ID_MARKER1 = 1;
|
||||
public static final int DC_MSG_ID_DAYMARKER = 9;
|
||||
|
||||
public final static int DC_VIDEOCHATTYPE_UNKNOWN = 0;
|
||||
public final static int DC_VIDEOCHATTYPE_BASICWEBRTC = 1;
|
||||
public static final int DC_VIDEOCHATTYPE_UNKNOWN = 0;
|
||||
public static final int DC_VIDEOCHATTYPE_BASICWEBRTC = 1;
|
||||
|
||||
private static final String TAG = DcMsg.class.getSimpleName();
|
||||
private static final String TAG = DcMsg.class.getSimpleName();
|
||||
|
||||
public DcMsg(DcContext context, int viewtype) {
|
||||
msgCPtr = context.createMsgCPtr(viewtype);
|
||||
public DcMsg(DcContext context, int viewtype) {
|
||||
msgCPtr = context.createMsgCPtr(viewtype);
|
||||
}
|
||||
|
||||
public DcMsg(long msgCPtr) {
|
||||
this.msgCPtr = msgCPtr;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return msgCPtr != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
unrefMsgCPtr();
|
||||
msgCPtr = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof DcMsg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DcMsg(long msgCPtr) {
|
||||
this.msgCPtr = msgCPtr;
|
||||
}
|
||||
DcMsg that = (DcMsg) other;
|
||||
return this.getId() == that.getId() && this.getId() != 0;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return msgCPtr != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
unrefMsgCPtr();
|
||||
msgCPtr = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof DcMsg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DcMsg that = (DcMsg) other;
|
||||
return this.getId()==that.getId() && this.getId()!=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If given a message, calculates the position of the message in the chat
|
||||
*/
|
||||
public static int getMessagePosition(DcMsg msg, DcContext dcContext) {
|
||||
int msgs[] = dcContext.getChatMsgs(msg.getChatId(), 0, 0);
|
||||
int startingPosition = -1;
|
||||
int msgId = msg.getId();
|
||||
for (int i = 0; i < msgs.length; i++) {
|
||||
if (msgs[i] == msgId) {
|
||||
startingPosition = msgs.length - 1 - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return startingPosition;
|
||||
}
|
||||
|
||||
public native int getId ();
|
||||
public native String getText ();
|
||||
public native String getSubject ();
|
||||
public native long getTimestamp ();
|
||||
public native long getSortTimestamp ();
|
||||
public native boolean hasDeviatingTimestamp();
|
||||
public native boolean hasLocation ();
|
||||
public native int getType ();
|
||||
public native int getInfoType ();
|
||||
public native int getInfoContactId ();
|
||||
public native int getState ();
|
||||
public native int getDownloadState ();
|
||||
public native int getChatId ();
|
||||
public native int getFromId ();
|
||||
public native int getWidth (int def);
|
||||
public native int getHeight (int def);
|
||||
public native int getDuration ();
|
||||
public native void lateFilingMediaSize(int width, int height, int duration);
|
||||
public DcLot getSummary (DcChat chat) { return new DcLot(getSummaryCPtr(chat.getChatCPtr())); }
|
||||
public native String getSummarytext (int approx_characters);
|
||||
public native int showPadlock ();
|
||||
public boolean hasFile () { String file = getFile(); return file!=null && !file.isEmpty(); }
|
||||
public native String getFile ();
|
||||
public native String getFilemime ();
|
||||
public native String getFilename ();
|
||||
public native long getFilebytes ();
|
||||
public native byte[] getWebxdcBlob (String filename);
|
||||
public JSONObject getWebxdcInfo () {
|
||||
try {
|
||||
String json = getWebxdcInfoJson();
|
||||
if (json != null && !json.isEmpty()) return new JSONObject(json);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
/** If given a message, calculates the position of the message in the chat */
|
||||
public static int getMessagePosition(DcMsg msg, DcContext dcContext) {
|
||||
int msgs[] = dcContext.getChatMsgs(msg.getChatId(), 0, 0);
|
||||
int startingPosition = -1;
|
||||
int msgId = msg.getId();
|
||||
for (int i = 0; i < msgs.length; i++) {
|
||||
if (msgs[i] == msgId) {
|
||||
startingPosition = msgs.length - 1 - i;
|
||||
break;
|
||||
}
|
||||
return new JSONObject();
|
||||
}
|
||||
public native String getWebxdcHref ();
|
||||
public native boolean isForwarded ();
|
||||
public native boolean isInfo ();
|
||||
public native boolean hasHtml ();
|
||||
public native String getSetupCodeBegin ();
|
||||
public native void setText (String text);
|
||||
public native void setFileAndDeduplicate(String file, String name, String filemime);
|
||||
public native void setDimension (int width, int height);
|
||||
public native void setDuration (int duration);
|
||||
public native void setLocation (float latitude, float longitude);
|
||||
public void setQuote (DcMsg quote) { setQuoteCPtr(quote.msgCPtr); }
|
||||
public native String getQuotedText ();
|
||||
public native String getError ();
|
||||
public native String getOverrideSenderName();
|
||||
public native boolean isEdited ();
|
||||
return startingPosition;
|
||||
}
|
||||
|
||||
public String getSenderName(DcContact dcContact) {
|
||||
String overrideName = getOverrideSenderName();
|
||||
if (overrideName != null) {
|
||||
return "~" + overrideName;
|
||||
} else {
|
||||
return dcContact.getDisplayName();
|
||||
}
|
||||
}
|
||||
public native int getId();
|
||||
|
||||
public DcMsg getQuotedMsg () {
|
||||
long cPtr = getQuotedMsgCPtr();
|
||||
return cPtr != 0 ? new DcMsg(cPtr) : null;
|
||||
}
|
||||
public native String getText();
|
||||
|
||||
public DcMsg getParent() {
|
||||
long cPtr = getParentCPtr();
|
||||
return cPtr != 0 ? new DcMsg(cPtr) : null;
|
||||
}
|
||||
public native String getSubject();
|
||||
|
||||
public native int getOriginalMsgId ();
|
||||
public native int getSavedMsgId ();
|
||||
public native long getTimestamp();
|
||||
|
||||
public boolean canSave() {
|
||||
// saving info-messages out of context results in confusion, see https://github.com/deltachat/deltachat-ios/issues/2567
|
||||
return !isInfo();
|
||||
}
|
||||
public native long getSortTimestamp();
|
||||
|
||||
public File getFileAsFile() {
|
||||
if(getFile()==null)
|
||||
throw new AssertionError("expected a file to be present.");
|
||||
return new File(getFile());
|
||||
}
|
||||
public native boolean hasDeviatingTimestamp();
|
||||
|
||||
// aliases and higher-level tools
|
||||
public static int[] msgSetToIds(final Set<DcMsg> dcMsgs) {
|
||||
if (dcMsgs == null) {
|
||||
return new int[0];
|
||||
}
|
||||
int[] ids = new int[dcMsgs.size()];
|
||||
int i = 0;
|
||||
for (DcMsg dcMsg : dcMsgs) {
|
||||
ids[i++] = dcMsg.getId();
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
public native boolean hasLocation();
|
||||
|
||||
public boolean isOutgoing() {
|
||||
return getFromId() == DcContact.DC_CONTACT_ID_SELF;
|
||||
}
|
||||
public native int getType();
|
||||
|
||||
public String getDisplayBody() {
|
||||
return getText();
|
||||
}
|
||||
public native int getInfoType();
|
||||
|
||||
public String getBody() {
|
||||
return getText();
|
||||
}
|
||||
public native int getInfoContactId();
|
||||
|
||||
public long getDateReceived() {
|
||||
return getTimestamp();
|
||||
}
|
||||
public native int getState();
|
||||
|
||||
public boolean isFailed() {
|
||||
return (getState() == DC_STATE_OUT_FAILED) || (!TextUtils.isEmpty(getError()));
|
||||
}
|
||||
public boolean isPreparing() {
|
||||
return getState() == DC_STATE_OUT_PREPARING;
|
||||
}
|
||||
public boolean isSecure() {
|
||||
return showPadlock()!=0;
|
||||
}
|
||||
public boolean isPending() {
|
||||
return getState() == DC_STATE_OUT_PENDING;
|
||||
}
|
||||
public boolean isDelivered() {
|
||||
return getState() == DC_STATE_OUT_DELIVERED;
|
||||
}
|
||||
public boolean isRemoteRead() {
|
||||
return getState() == DC_STATE_OUT_MDN_RCVD;
|
||||
}
|
||||
public boolean isSeen() {
|
||||
return getState() == DC_STATE_IN_SEEN;
|
||||
}
|
||||
public native int getDownloadState();
|
||||
|
||||
public native int getChatId();
|
||||
|
||||
// working with raw c-data
|
||||
private long msgCPtr; // CAVE: the name is referenced in the JNI
|
||||
private native void unrefMsgCPtr ();
|
||||
private native long getSummaryCPtr (long chatCPtr);
|
||||
private native void setQuoteCPtr (long quoteCPtr);
|
||||
private native long getQuotedMsgCPtr ();
|
||||
private native long getParentCPtr ();
|
||||
private native String getWebxdcInfoJson ();
|
||||
};
|
||||
public native int getFromId();
|
||||
|
||||
public native int getWidth(int def);
|
||||
|
||||
public native int getHeight(int def);
|
||||
|
||||
public native int getDuration();
|
||||
|
||||
public native void lateFilingMediaSize(int width, int height, int duration);
|
||||
|
||||
public DcLot getSummary(DcChat chat) {
|
||||
return new DcLot(getSummaryCPtr(chat.getChatCPtr()));
|
||||
}
|
||||
|
||||
public native String getSummarytext(int approx_characters);
|
||||
|
||||
public native int showPadlock();
|
||||
|
||||
public boolean hasFile() {
|
||||
String file = getFile();
|
||||
return file != null && !file.isEmpty();
|
||||
}
|
||||
|
||||
public native String getFile();
|
||||
|
||||
public native String getFilemime();
|
||||
|
||||
public native String getFilename();
|
||||
|
||||
public native long getFilebytes();
|
||||
|
||||
public native byte[] getWebxdcBlob(String filename);
|
||||
|
||||
public JSONObject getWebxdcInfo() {
|
||||
try {
|
||||
String json = getWebxdcInfoJson();
|
||||
if (json != null && !json.isEmpty()) return new JSONObject(json);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
public native String getWebxdcHref();
|
||||
|
||||
public native boolean isForwarded();
|
||||
|
||||
public native boolean isInfo();
|
||||
|
||||
public native boolean hasHtml();
|
||||
|
||||
public native String getSetupCodeBegin();
|
||||
|
||||
public native void setText(String text);
|
||||
|
||||
public native void setFileAndDeduplicate(String file, String name, String filemime);
|
||||
|
||||
public native void setDimension(int width, int height);
|
||||
|
||||
public native void setDuration(int duration);
|
||||
|
||||
public native void setLocation(float latitude, float longitude);
|
||||
|
||||
public void setQuote(DcMsg quote) {
|
||||
setQuoteCPtr(quote.msgCPtr);
|
||||
}
|
||||
|
||||
public native String getQuotedText();
|
||||
|
||||
public native String getError();
|
||||
|
||||
public native String getOverrideSenderName();
|
||||
|
||||
public native boolean isEdited();
|
||||
|
||||
public String getSenderName(DcContact dcContact) {
|
||||
String overrideName = getOverrideSenderName();
|
||||
if (overrideName != null) {
|
||||
return "~" + overrideName;
|
||||
} else {
|
||||
return dcContact.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
public DcMsg getQuotedMsg() {
|
||||
long cPtr = getQuotedMsgCPtr();
|
||||
return cPtr != 0 ? new DcMsg(cPtr) : null;
|
||||
}
|
||||
|
||||
public DcMsg getParent() {
|
||||
long cPtr = getParentCPtr();
|
||||
return cPtr != 0 ? new DcMsg(cPtr) : null;
|
||||
}
|
||||
|
||||
public native int getOriginalMsgId();
|
||||
|
||||
public native int getSavedMsgId();
|
||||
|
||||
public boolean canSave() {
|
||||
// saving info-messages out of context results in confusion, see
|
||||
// https://github.com/deltachat/deltachat-ios/issues/2567
|
||||
return !isInfo();
|
||||
}
|
||||
|
||||
public File getFileAsFile() {
|
||||
if (getFile() == null) throw new AssertionError("expected a file to be present.");
|
||||
return new File(getFile());
|
||||
}
|
||||
|
||||
// aliases and higher-level tools
|
||||
public static int[] msgSetToIds(final Set<DcMsg> dcMsgs) {
|
||||
if (dcMsgs == null) {
|
||||
return new int[0];
|
||||
}
|
||||
int[] ids = new int[dcMsgs.size()];
|
||||
int i = 0;
|
||||
for (DcMsg dcMsg : dcMsgs) {
|
||||
ids[i++] = dcMsg.getId();
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
public boolean isOutgoing() {
|
||||
return getFromId() == DcContact.DC_CONTACT_ID_SELF;
|
||||
}
|
||||
|
||||
public String getDisplayBody() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
public long getDateReceived() {
|
||||
return getTimestamp();
|
||||
}
|
||||
|
||||
public boolean isFailed() {
|
||||
return (getState() == DC_STATE_OUT_FAILED) || (!TextUtils.isEmpty(getError()));
|
||||
}
|
||||
|
||||
public boolean isPreparing() {
|
||||
return getState() == DC_STATE_OUT_PREPARING;
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return showPadlock() != 0;
|
||||
}
|
||||
|
||||
public boolean isPending() {
|
||||
return getState() == DC_STATE_OUT_PENDING;
|
||||
}
|
||||
|
||||
public boolean isDelivered() {
|
||||
return getState() == DC_STATE_OUT_DELIVERED;
|
||||
}
|
||||
|
||||
public boolean isRemoteRead() {
|
||||
return getState() == DC_STATE_OUT_MDN_RCVD;
|
||||
}
|
||||
|
||||
public boolean isSeen() {
|
||||
return getState() == DC_STATE_IN_SEEN;
|
||||
}
|
||||
|
||||
// working with raw c-data
|
||||
private long msgCPtr; // CAVE: the name is referenced in the JNI
|
||||
|
||||
private native void unrefMsgCPtr();
|
||||
|
||||
private native long getSummaryCPtr(long chatCPtr);
|
||||
|
||||
private native void setQuoteCPtr(long quoteCPtr);
|
||||
|
||||
private native long getQuotedMsgCPtr();
|
||||
|
||||
private native long getParentCPtr();
|
||||
|
||||
private native String getWebxdcInfoJson();
|
||||
}
|
||||
;
|
||||
|
||||
@@ -23,16 +23,20 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.b44t.messenger.DcChat;
|
||||
import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.thoughtcrime.securesms.ConversationAdapter.HeaderViewHolder;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
@@ -45,61 +49,50 @@ import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A DC adapter for a conversation thread. Ultimately
|
||||
* used by ConversationActivity to display a conversation
|
||||
* thread in a ListActivity.
|
||||
* A DC adapter for a conversation thread. Ultimately used by ConversationActivity to display a
|
||||
* conversation thread in a ListActivity.
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*
|
||||
*/
|
||||
// FIXME: this breaks type checks, that is why there are so many casts.
|
||||
public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
public class ConversationAdapter<V extends View & BindableConversationItem>
|
||||
extends RecyclerView.Adapter
|
||||
implements StickyHeaderDecoration.StickyHeaderAdapter<HeaderViewHolder>
|
||||
{
|
||||
implements StickyHeaderDecoration.StickyHeaderAdapter<HeaderViewHolder> {
|
||||
|
||||
private static final int MAX_CACHE_SIZE = 40;
|
||||
private final Map<Integer,SoftReference<DcMsg>> recordCache =
|
||||
Collections.synchronizedMap(new LRUCache<Integer,SoftReference<DcMsg>>(MAX_CACHE_SIZE));
|
||||
private final Map<Integer, SoftReference<DcMsg>> recordCache =
|
||||
Collections.synchronizedMap(new LRUCache<Integer, SoftReference<DcMsg>>(MAX_CACHE_SIZE));
|
||||
|
||||
private static final int MESSAGE_TYPE_OUTGOING = 0;
|
||||
private static final int MESSAGE_TYPE_INCOMING = 1;
|
||||
private static final int MESSAGE_TYPE_INFO = 2;
|
||||
private static final int MESSAGE_TYPE_AUDIO_OUTGOING = 3;
|
||||
private static final int MESSAGE_TYPE_AUDIO_INCOMING = 4;
|
||||
private static final int MESSAGE_TYPE_OUTGOING = 0;
|
||||
private static final int MESSAGE_TYPE_INCOMING = 1;
|
||||
private static final int MESSAGE_TYPE_INFO = 2;
|
||||
private static final int MESSAGE_TYPE_AUDIO_OUTGOING = 3;
|
||||
private static final int MESSAGE_TYPE_AUDIO_INCOMING = 4;
|
||||
private static final int MESSAGE_TYPE_THUMBNAIL_OUTGOING = 5;
|
||||
private static final int MESSAGE_TYPE_THUMBNAIL_INCOMING = 6;
|
||||
private static final int MESSAGE_TYPE_DOCUMENT_OUTGOING = 7;
|
||||
private static final int MESSAGE_TYPE_DOCUMENT_INCOMING = 8;
|
||||
private static final int MESSAGE_TYPE_STICKER_INCOMING = 9;
|
||||
private static final int MESSAGE_TYPE_STICKER_OUTGOING = 10;
|
||||
private static final int MESSAGE_TYPE_DOCUMENT_OUTGOING = 7;
|
||||
private static final int MESSAGE_TYPE_DOCUMENT_INCOMING = 8;
|
||||
private static final int MESSAGE_TYPE_STICKER_INCOMING = 9;
|
||||
private static final int MESSAGE_TYPE_STICKER_OUTGOING = 10;
|
||||
|
||||
private final Set<DcMsg> batchSelected = Collections.synchronizedSet(new HashSet<DcMsg>());
|
||||
|
||||
private final @Nullable ItemClickListener clickListener;
|
||||
private final @NonNull GlideRequests glideRequests;
|
||||
private final @NonNull Recipient recipient;
|
||||
private final @NonNull LayoutInflater inflater;
|
||||
private final @NonNull Context context;
|
||||
private final @NonNull Calendar calendar;
|
||||
private final @NonNull GlideRequests glideRequests;
|
||||
private final @NonNull Recipient recipient;
|
||||
private final @NonNull LayoutInflater inflater;
|
||||
private final @NonNull Context context;
|
||||
private final @NonNull Calendar calendar;
|
||||
|
||||
private final DcContext dcContext;
|
||||
private @NonNull DcChat dcChat;
|
||||
private @NonNull int[] dcMsgList = new int[0];
|
||||
private int positionToPulseHighlight = -1;
|
||||
private int positionCurrentlyPulseHighlighting = -1;
|
||||
private long pulseHighlightingSince = -1;
|
||||
private int lastSeenPosition = -1;
|
||||
private long lastSeen = -1;
|
||||
private final DcContext dcContext;
|
||||
private @NonNull DcChat dcChat;
|
||||
private @NonNull int[] dcMsgList = new int[0];
|
||||
private int positionToPulseHighlight = -1;
|
||||
private int positionCurrentlyPulseHighlighting = -1;
|
||||
private long pulseHighlightingSince = -1;
|
||||
private int lastSeenPosition = -1;
|
||||
private long lastSeen = -1;
|
||||
private AudioPlaybackViewModel playbackViewModel;
|
||||
private AudioView.OnActionListener audioPlayPauseListener;
|
||||
|
||||
@@ -110,7 +103,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends View & BindableConversationItem> V getView() {
|
||||
return (V)itemView;
|
||||
return (V) itemView;
|
||||
}
|
||||
|
||||
public BindableConversationItem getItem() {
|
||||
@@ -118,16 +111,14 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return dcMsgList.length > 0;
|
||||
}
|
||||
|
||||
public @NonNull DcChat getChat(){
|
||||
public @NonNull DcChat getChat() {
|
||||
return dcChat;
|
||||
}
|
||||
|
||||
|
||||
public void setLastSeen(long timestamp) {
|
||||
lastSeen = timestamp;
|
||||
}
|
||||
@@ -151,14 +142,14 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (position<0 || position>=dcMsgList.length) {
|
||||
if (position < 0 || position >= dcMsgList.length) {
|
||||
return 0;
|
||||
}
|
||||
return dcMsgList[dcMsgList.length-1-position];
|
||||
return dcMsgList[dcMsgList.length - 1 - position];
|
||||
}
|
||||
|
||||
public @NonNull DcMsg getMsg(int position) {
|
||||
if(position<0 || position>=dcMsgList.length) {
|
||||
if (position < 0 || position >= dcMsgList.length) {
|
||||
return new DcMsg(0);
|
||||
}
|
||||
|
||||
@@ -170,7 +161,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
}
|
||||
|
||||
final DcMsg fromDb = dcContext.getMsg((int)getItemId(position));
|
||||
final DcMsg fromDb = dcContext.getMsg((int) getItemId(position));
|
||||
recordCache.put(position, new SoftReference<>(fromDb));
|
||||
return fromDb;
|
||||
}
|
||||
@@ -183,12 +174,10 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
this.audioPlayPauseListener = audioPlayPauseListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the message with msgId in the chat list, counted from the top
|
||||
*/
|
||||
/** Returns the position of the message with msgId in the chat list, counted from the top */
|
||||
public int msgIdToPosition(int msgId) {
|
||||
for(int i=0; i<dcMsgList.length; i++ ) {
|
||||
if(dcMsgList[i]==msgId) {
|
||||
for (int i = 0; i < dcMsgList.length; i++) {
|
||||
if (dcMsgList[i] == msgId) {
|
||||
return dcMsgList.length - 1 - i;
|
||||
}
|
||||
}
|
||||
@@ -213,17 +202,18 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface ItemClickListener extends BindableConversationItem.EventListener {
|
||||
void onItemClick(DcMsg item);
|
||||
|
||||
void onItemLongClick(DcMsg item, View view);
|
||||
}
|
||||
|
||||
public ConversationAdapter(@NonNull Context context,
|
||||
@NonNull DcChat dcChat,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@Nullable ItemClickListener clickListener,
|
||||
@NonNull Recipient recipient) {
|
||||
public ConversationAdapter(
|
||||
@NonNull Context context,
|
||||
@NonNull DcChat dcChat,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@Nullable ItemClickListener clickListener,
|
||||
@NonNull Recipient recipient) {
|
||||
this.dcChat = dcChat;
|
||||
this.glideRequests = glideRequests;
|
||||
this.clickListener = clickListener;
|
||||
@@ -231,14 +221,14 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
this.context = context;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.calendar = Calendar.getInstance();
|
||||
this.dcContext = DcHelper.getContext(context);
|
||||
this.dcContext = DcHelper.getContext(context);
|
||||
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
|
||||
ConversationAdapter.ViewHolder holder = (ConversationAdapter.ViewHolder)viewHolder;
|
||||
ConversationAdapter.ViewHolder holder = (ConversationAdapter.ViewHolder) viewHolder;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (position == positionToPulseHighlight) {
|
||||
@@ -248,14 +238,25 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
|
||||
long elapsed = now - pulseHighlightingSince;
|
||||
boolean pulseHighlight = (positionCurrentlyPulseHighlighting == position && elapsed < PULSE_HIGHLIGHT_MILLIS);
|
||||
boolean pulseHighlight =
|
||||
(positionCurrentlyPulseHighlighting == position && elapsed < PULSE_HIGHLIGHT_MILLIS);
|
||||
|
||||
holder.getItem().bind(getMsg(position), dcChat, glideRequests, batchSelected, recipient, pulseHighlight, playbackViewModel, audioPlayPauseListener);
|
||||
holder
|
||||
.getItem()
|
||||
.bind(
|
||||
getMsg(position),
|
||||
dcChat,
|
||||
glideRequests,
|
||||
batchSelected,
|
||||
recipient,
|
||||
pulseHighlight,
|
||||
playbackViewModel,
|
||||
audioPlayPauseListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRecycled(@NonNull RecyclerView.ViewHolder viewHolder) {
|
||||
if (viewHolder.itemView instanceof ConversationItem) {
|
||||
if (viewHolder.itemView instanceof ConversationItem) {
|
||||
ConversationSwipeAnimationHelper.update((ConversationItem) viewHolder.itemView, 0, 1);
|
||||
}
|
||||
}
|
||||
@@ -263,17 +264,19 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final V itemView = ViewUtil.inflate(inflater, parent, getLayoutForViewType(viewType));
|
||||
itemView.setOnClickListener(view -> {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemClick(itemView.getMessageRecord());
|
||||
}
|
||||
});
|
||||
itemView.setOnLongClickListener(view -> {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemLongClick(itemView.getMessageRecord(), view);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
itemView.setOnClickListener(
|
||||
view -> {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemClick(itemView.getMessageRecord());
|
||||
}
|
||||
});
|
||||
itemView.setOnLongClickListener(
|
||||
view -> {
|
||||
if (clickListener != null) {
|
||||
clickListener.onItemLongClick(itemView.getMessageRecord(), view);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
itemView.setEventListener(clickListener);
|
||||
return new ViewHolder(itemView);
|
||||
}
|
||||
@@ -284,14 +287,19 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
case MESSAGE_TYPE_THUMBNAIL_OUTGOING:
|
||||
case MESSAGE_TYPE_DOCUMENT_OUTGOING:
|
||||
case MESSAGE_TYPE_STICKER_OUTGOING:
|
||||
case MESSAGE_TYPE_OUTGOING: return R.layout.conversation_item_sent;
|
||||
case MESSAGE_TYPE_OUTGOING:
|
||||
return R.layout.conversation_item_sent;
|
||||
case MESSAGE_TYPE_AUDIO_INCOMING:
|
||||
case MESSAGE_TYPE_THUMBNAIL_INCOMING:
|
||||
case MESSAGE_TYPE_DOCUMENT_INCOMING:
|
||||
case MESSAGE_TYPE_STICKER_INCOMING:
|
||||
case MESSAGE_TYPE_INCOMING: return R.layout.conversation_item_received;
|
||||
case MESSAGE_TYPE_INFO: return R.layout.conversation_item_update;
|
||||
default: throw new IllegalArgumentException("unsupported item view type given to ConversationAdapter");
|
||||
case MESSAGE_TYPE_INCOMING:
|
||||
return R.layout.conversation_item_received;
|
||||
case MESSAGE_TYPE_INFO:
|
||||
return R.layout.conversation_item_update;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"unsupported item view type given to ConversationAdapter");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,21 +309,18 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
int type = dcMsg.getType();
|
||||
if (dcMsg.isInfo()) {
|
||||
return MESSAGE_TYPE_INFO;
|
||||
}
|
||||
else if (type==DcMsg.DC_MSG_AUDIO || type==DcMsg.DC_MSG_VOICE) {
|
||||
return dcMsg.isOutgoing()? MESSAGE_TYPE_AUDIO_OUTGOING : MESSAGE_TYPE_AUDIO_INCOMING;
|
||||
}
|
||||
else if (type==DcMsg.DC_MSG_FILE) {
|
||||
return dcMsg.isOutgoing()? MESSAGE_TYPE_DOCUMENT_OUTGOING : MESSAGE_TYPE_DOCUMENT_INCOMING;
|
||||
}
|
||||
else if (type==DcMsg.DC_MSG_IMAGE || type==DcMsg.DC_MSG_GIF || type==DcMsg.DC_MSG_VIDEO) {
|
||||
return dcMsg.isOutgoing()? MESSAGE_TYPE_THUMBNAIL_OUTGOING : MESSAGE_TYPE_THUMBNAIL_INCOMING;
|
||||
}
|
||||
else if (type == DcMsg.DC_MSG_STICKER) {
|
||||
return dcMsg.isOutgoing()? MESSAGE_TYPE_STICKER_OUTGOING : MESSAGE_TYPE_STICKER_INCOMING;
|
||||
}
|
||||
else {
|
||||
return dcMsg.isOutgoing()? MESSAGE_TYPE_OUTGOING : MESSAGE_TYPE_INCOMING;
|
||||
} else if (type == DcMsg.DC_MSG_AUDIO || type == DcMsg.DC_MSG_VOICE) {
|
||||
return dcMsg.isOutgoing() ? MESSAGE_TYPE_AUDIO_OUTGOING : MESSAGE_TYPE_AUDIO_INCOMING;
|
||||
} else if (type == DcMsg.DC_MSG_FILE) {
|
||||
return dcMsg.isOutgoing() ? MESSAGE_TYPE_DOCUMENT_OUTGOING : MESSAGE_TYPE_DOCUMENT_INCOMING;
|
||||
} else if (type == DcMsg.DC_MSG_IMAGE
|
||||
|| type == DcMsg.DC_MSG_GIF
|
||||
|| type == DcMsg.DC_MSG_VIDEO) {
|
||||
return dcMsg.isOutgoing() ? MESSAGE_TYPE_THUMBNAIL_OUTGOING : MESSAGE_TYPE_THUMBNAIL_INCOMING;
|
||||
} else if (type == DcMsg.DC_MSG_STICKER) {
|
||||
return dcMsg.isOutgoing() ? MESSAGE_TYPE_STICKER_OUTGOING : MESSAGE_TYPE_STICKER_INCOMING;
|
||||
} else {
|
||||
return dcMsg.isOutgoing() ? MESSAGE_TYPE_OUTGOING : MESSAGE_TYPE_INCOMING;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,16 +343,16 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
|
||||
public void pulseHighlightItem(int position) {
|
||||
if (position>=0 && position < getItemCount()) {
|
||||
if (position >= 0 && position < getItemCount()) {
|
||||
positionToPulseHighlight = position;
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
|
||||
public long getSortTimestamp(int position) {
|
||||
if (!isActive()) return 0;
|
||||
if (!isActive()) return 0;
|
||||
if (position >= getItemCount()) return 0;
|
||||
if (position < 0) return 0;
|
||||
if (position < 0) return 0;
|
||||
|
||||
DcMsg msg = getMsg(position);
|
||||
return msg.getSortTimestamp();
|
||||
@@ -361,7 +366,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
@Override
|
||||
public long getHeaderId(int position) {
|
||||
if (position >= getItemCount()) return -1;
|
||||
if (position < 0) return -1;
|
||||
if (position < 0) return -1;
|
||||
|
||||
calendar.setTime(new Date(getSortTimestamp(position)));
|
||||
return Util.hashCode(calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
|
||||
@@ -369,18 +374,17 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
@Override
|
||||
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_header, parent, false));
|
||||
return new HeaderViewHolder(
|
||||
LayoutInflater.from(getContext())
|
||||
.inflate(R.layout.conversation_item_header, parent, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* date header view
|
||||
*/
|
||||
/** date header view */
|
||||
@Override
|
||||
public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
viewHolder.setText(DateUtils.getRelativeDate(getContext(), getSortTimestamp(position)));
|
||||
}
|
||||
|
||||
|
||||
public void changeData(@Nullable int[] dcMsgList) {
|
||||
// should be called when there are new messages
|
||||
this.dcMsgList = dcMsgList == null ? new int[0] : dcMsgList;
|
||||
@@ -400,12 +404,11 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
|
||||
private int findLastSeenPosition(long lastSeen) {
|
||||
if (lastSeen <= 0) return -1;
|
||||
if (!isActive()) return -1;
|
||||
if (lastSeen <= 0) return -1;
|
||||
if (!isActive()) return -1;
|
||||
|
||||
int count = getItemCount();
|
||||
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
DcMsg msg = getMsg(i);
|
||||
if (msg.isOutgoing() || msg.getTimestamp() <= lastSeen) {
|
||||
@@ -417,11 +420,16 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
|
||||
public HeaderViewHolder onCreateLastSeenViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_last_seen, parent, false));
|
||||
return new HeaderViewHolder(
|
||||
LayoutInflater.from(getContext())
|
||||
.inflate(R.layout.conversation_item_last_seen, parent, false));
|
||||
}
|
||||
|
||||
public void onBindLastSeenViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
viewHolder.setText(getContext().getResources().getQuantityString(R.plurals.chat_n_new_messages, (position + 1), (position + 1)));
|
||||
viewHolder.setText(
|
||||
getContext()
|
||||
.getResources()
|
||||
.getQuantityString(R.plurals.chat_n_new_messages, (position + 1), (position + 1)));
|
||||
}
|
||||
|
||||
static class LastSeenHeader extends StickyHeaderDecoration {
|
||||
@@ -429,32 +437,45 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
|
||||
LastSeenHeader(ConversationAdapter adapter) {
|
||||
super(adapter, false, false);
|
||||
this.adapter = adapter;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasHeader(RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
return adapter.isActive() && position == adapter.getLastSeenPosition();
|
||||
protected boolean hasHeader(
|
||||
RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
return adapter.isActive() && position == adapter.getLastSeenPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHeaderTop(RecyclerView parent, View child, View header, int adapterPos, int layoutPos) {
|
||||
protected int getHeaderTop(
|
||||
RecyclerView parent, View child, View header, int adapterPos, int layoutPos) {
|
||||
return parent.getLayoutManager().getDecoratedTop(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HeaderViewHolder getHeader(RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
protected HeaderViewHolder getHeader(
|
||||
RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
HeaderViewHolder viewHolder = adapter.onCreateLastSeenViewHolder(parent);
|
||||
adapter.onBindLastSeenViewHolder(viewHolder, position);
|
||||
|
||||
int widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
|
||||
int heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
|
||||
int widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
|
||||
int heightSpec =
|
||||
View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
|
||||
|
||||
int childWidth = ViewGroup.getChildMeasureSpec(widthSpec, parent.getPaddingLeft() + parent.getPaddingRight(), viewHolder.itemView.getLayoutParams().width);
|
||||
int childHeight = ViewGroup.getChildMeasureSpec(heightSpec, parent.getPaddingTop() + parent.getPaddingBottom(), viewHolder.itemView.getLayoutParams().height);
|
||||
int childWidth =
|
||||
ViewGroup.getChildMeasureSpec(
|
||||
widthSpec,
|
||||
parent.getPaddingLeft() + parent.getPaddingRight(),
|
||||
viewHolder.itemView.getLayoutParams().width);
|
||||
int childHeight =
|
||||
ViewGroup.getChildMeasureSpec(
|
||||
heightSpec,
|
||||
parent.getPaddingTop() + parent.getPaddingBottom(),
|
||||
viewHolder.itemView.getLayoutParams().height);
|
||||
|
||||
viewHolder.itemView.measure(childWidth, childHeight);
|
||||
viewHolder.itemView.layout(0, 0, viewHolder.itemView.getMeasuredWidth(), viewHolder.itemView.getMeasuredHeight());
|
||||
viewHolder.itemView.layout(
|
||||
0, 0, viewHolder.itemView.getMeasuredWidth(), viewHolder.itemView.getMeasuredHeight());
|
||||
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,14 +8,11 @@ import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
|
||||
import chat.delta.rpc.types.CallInfo;
|
||||
import chat.delta.rpc.types.CallState;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
|
||||
public class CallItemView extends FrameLayout {
|
||||
private static final String TAG = CallItemView.class.getSimpleName();
|
||||
@@ -43,11 +40,12 @@ public class CallItemView extends FrameLayout {
|
||||
this.title = findViewById(R.id.title);
|
||||
this.duration = findViewById(R.id.duration);
|
||||
|
||||
setOnClickListener(v -> {
|
||||
if (viewListener != null && callInfo != null) {
|
||||
viewListener.onClick(v, callInfo);
|
||||
}
|
||||
});
|
||||
setOnClickListener(
|
||||
v -> {
|
||||
if (viewListener != null && callInfo != null) {
|
||||
viewListener.onClick(v, callInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setCallClickListener(CallClickListener listener) {
|
||||
@@ -58,7 +56,9 @@ public class CallItemView extends FrameLayout {
|
||||
this.callInfo = callInfo;
|
||||
|
||||
if (callInfo.state instanceof CallState.Completed) {
|
||||
duration.setText(DateUtils.getFormattedCallDuration(getContext(), ((CallState.Completed) callInfo.state).duration));
|
||||
duration.setText(
|
||||
DateUtils.getFormattedCallDuration(
|
||||
getContext(), ((CallState.Completed) callInfo.state).duration));
|
||||
duration.setVisibility(VISIBLE);
|
||||
} else {
|
||||
duration.setVisibility(GONE);
|
||||
@@ -76,17 +76,20 @@ public class CallItemView extends FrameLayout {
|
||||
title.setText(R.string.audio_call);
|
||||
}
|
||||
|
||||
icon.setImageResource(callInfo.hasVideo? R.drawable.ic_videocam_white_24dp : R.drawable.baseline_call_24);
|
||||
icon.setImageResource(
|
||||
callInfo.hasVideo ? R.drawable.ic_videocam_white_24dp : R.drawable.baseline_call_24);
|
||||
|
||||
int[] attrs;
|
||||
if (isOutgoing) {
|
||||
attrs = new int[]{
|
||||
R.attr.conversation_item_outgoing_text_primary_color,
|
||||
};
|
||||
attrs =
|
||||
new int[] {
|
||||
R.attr.conversation_item_outgoing_text_primary_color,
|
||||
};
|
||||
} else {
|
||||
attrs = new int[]{
|
||||
R.attr.conversation_item_incoming_text_primary_color,
|
||||
};
|
||||
attrs =
|
||||
new int[] {
|
||||
R.attr.conversation_item_incoming_text_primary_color,
|
||||
};
|
||||
}
|
||||
try (TypedArray ta = getContext().obtainStyledAttributes(attrs)) {
|
||||
icon.setColorFilter(ta.getColor(0, Color.BLACK));
|
||||
@@ -94,7 +97,8 @@ public class CallItemView extends FrameLayout {
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return title.getText() + (duration.getVisibility()==VISIBLE ? ("\n" + duration.getText()) : "");
|
||||
return title.getText()
|
||||
+ (duration.getVisibility() == VISIBLE ? ("\n" + duration.getText()) : "");
|
||||
}
|
||||
|
||||
public interface CallClickListener {
|
||||
|
||||
@@ -4,55 +4,55 @@ import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.SoundPool;
|
||||
import android.util.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public class InChatSounds {
|
||||
private static final String TAG = InChatSounds.class.getSimpleName();
|
||||
private static volatile InChatSounds instance;
|
||||
private static final String TAG = InChatSounds.class.getSimpleName();
|
||||
private static volatile InChatSounds instance;
|
||||
|
||||
private SoundPool soundPool = null;
|
||||
private int soundIn = 0;
|
||||
private int soundOut = 0;
|
||||
private SoundPool soundPool = null;
|
||||
private int soundIn = 0;
|
||||
private int soundOut = 0;
|
||||
|
||||
static public InChatSounds getInstance(Context context) {
|
||||
public static InChatSounds getInstance(Context context) {
|
||||
if (instance == null) {
|
||||
synchronized (InChatSounds.class) {
|
||||
if (instance == null) {
|
||||
synchronized (InChatSounds.class) {
|
||||
if (instance == null) {
|
||||
instance = new InChatSounds(context);
|
||||
}
|
||||
}
|
||||
instance = new InChatSounds(context);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private InChatSounds(Context context) {
|
||||
try {
|
||||
AudioAttributes audioAttrs = new AudioAttributes.Builder()
|
||||
private InChatSounds(Context context) {
|
||||
try {
|
||||
AudioAttributes audioAttrs =
|
||||
new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.build();
|
||||
soundPool = new SoundPool.Builder().setMaxStreams(3).setAudioAttributes(audioAttrs).build();
|
||||
soundIn = soundPool.load(context, R.raw.sound_in, 1);
|
||||
soundOut = soundPool.load(context, R.raw.sound_out, 1);
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "cannot initialize sounds", e);
|
||||
}
|
||||
soundPool = new SoundPool.Builder().setMaxStreams(3).setAudioAttributes(audioAttrs).build();
|
||||
soundIn = soundPool.load(context, R.raw.sound_in, 1);
|
||||
soundOut = soundPool.load(context, R.raw.sound_out, 1);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "cannot initialize sounds", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void playSendSound() {
|
||||
try {
|
||||
soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f);
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "cannot play send sound", e);
|
||||
}
|
||||
public void playSendSound() {
|
||||
try {
|
||||
soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "cannot play send sound", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void playIncomingSound() {
|
||||
try {
|
||||
soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f);
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "cannot play incoming sound", e);
|
||||
}
|
||||
public void playIncomingSound() {
|
||||
try {
|
||||
soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "cannot play incoming sound", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,23 +24,17 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.core.app.RemoteInput;
|
||||
|
||||
import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
|
||||
/**
|
||||
* Get the response text from the Wearable Device and sends an message as a reply
|
||||
*/
|
||||
/** Get the response text from the Wearable Device and sends an message as a reply */
|
||||
public class RemoteReplyReceiver extends BroadcastReceiver {
|
||||
|
||||
public static final String TAG = RemoteReplyReceiver.class.getSimpleName();
|
||||
public static final String REPLY_ACTION = "org.thoughtcrime.securesms.notifications.WEAR_REPLY";
|
||||
public static final String TAG = RemoteReplyReceiver.class.getSimpleName();
|
||||
public static final String REPLY_ACTION = "org.thoughtcrime.securesms.notifications.WEAR_REPLY";
|
||||
public static final String ACCOUNT_ID_EXTRA = "account_id";
|
||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
public static final String MSG_ID_EXTRA = "msg_id";
|
||||
@@ -60,20 +54,21 @@ public class RemoteReplyReceiver extends BroadcastReceiver {
|
||||
final CharSequence responseText = remoteInput.getCharSequence(EXTRA_REMOTE_REPLY);
|
||||
|
||||
if (responseText != null) {
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
DcContext dcContext = DcHelper.getAccounts(context).getAccount(accountId);
|
||||
dcContext.marknoticedChat(chatId);
|
||||
dcContext.markseenMsgs(new int[]{msgId});
|
||||
if (dcContext.getChat(chatId).isContactRequest()) {
|
||||
dcContext.acceptChat(chatId);
|
||||
}
|
||||
Util.runOnAnyBackgroundThread(
|
||||
() -> {
|
||||
DcContext dcContext = DcHelper.getAccounts(context).getAccount(accountId);
|
||||
dcContext.marknoticedChat(chatId);
|
||||
dcContext.markseenMsgs(new int[] {msgId});
|
||||
if (dcContext.getChat(chatId).isContactRequest()) {
|
||||
dcContext.acceptChat(chatId);
|
||||
}
|
||||
|
||||
DcMsg msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT);
|
||||
msg.setText(responseText.toString());
|
||||
dcContext.sendMsg(chatId, msg);
|
||||
DcMsg msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT);
|
||||
msg.setText(responseText.toString());
|
||||
dcContext.sendMsg(chatId, msg);
|
||||
|
||||
DcHelper.getNotificationCenter(context).removeNotifications(accountId, chatId);
|
||||
});
|
||||
DcHelper.getNotificationCenter(context).removeNotifications(accountId, chatId);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,9 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.connect.ForegroundDetector;
|
||||
@@ -65,27 +63,31 @@ public final class FetchForegroundService extends Service {
|
||||
Log.i(TAG, "Creating fetch service");
|
||||
super.onCreate();
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(this, NotificationCenter.CH_GENERIC)
|
||||
.setContentTitle(getString(R.string.connectivity_updating))
|
||||
.setSmallIcon(R.drawable.notification_permanent)
|
||||
.build();
|
||||
Notification notification =
|
||||
new NotificationCompat.Builder(this, NotificationCenter.CH_GENERIC)
|
||||
.setContentTitle(getString(R.string.connectivity_updating))
|
||||
.setSmallIcon(R.drawable.notification_permanent)
|
||||
.build();
|
||||
|
||||
try {
|
||||
startForeground(NotificationCenter.ID_FETCH, notification);
|
||||
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
Log.i(TAG, "Starting fetch");
|
||||
if (!ApplicationContext.getDcAccounts().backgroundFetch(300)) { // as startForeground() was called, there is time
|
||||
FetchForegroundService.stop(this);
|
||||
} // else we stop FetchForegroundService on DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE
|
||||
});
|
||||
Util.runOnAnyBackgroundThread(
|
||||
() -> {
|
||||
Log.i(TAG, "Starting fetch");
|
||||
if (!ApplicationContext.getDcAccounts()
|
||||
.backgroundFetch(300)) { // as startForeground() was called, there is time
|
||||
FetchForegroundService.stop(this);
|
||||
} // else we stop FetchForegroundService on DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error calling startForeground()", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void fetchSynchronously() {
|
||||
// According to the documentation https://firebase.google.com/docs/cloud-messaging/android/receive,
|
||||
// According to the documentation
|
||||
// https://firebase.google.com/docs/cloud-messaging/android/receive,
|
||||
// we need to handle the message within 20s, and the time window may be even shorter than 20s,
|
||||
// so, use 10s to be safe.
|
||||
fetchingSynchronously = true;
|
||||
@@ -97,9 +99,11 @@ public final class FetchForegroundService extends Service {
|
||||
while (fetchingSynchronously) {
|
||||
try {
|
||||
// The `wait()` needs to be enclosed in a while loop because there may be
|
||||
// "spurious wake-ups", i.e. `wait()` may return even though `notifyAll()` wasn't called.
|
||||
// "spurious wake-ups", i.e. `wait()` may return even though `notifyAll()` wasn't
|
||||
// called.
|
||||
STOP_NOTIFIER.wait();
|
||||
} catch (InterruptedException ex) {}
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,5 +125,4 @@ public final class FetchForegroundService extends Service {
|
||||
ApplicationContext.getDcAccounts().stopBackgroundFetch();
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,23 +11,20 @@ import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat.Builder;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.DummyActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationCenter;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.thoughtcrime.securesms.DummyActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationCenter;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
|
||||
public final class GenericForegroundService extends Service {
|
||||
|
||||
@@ -35,17 +32,17 @@ public final class GenericForegroundService extends Service {
|
||||
|
||||
private final IBinder binder = new LocalBinder();
|
||||
|
||||
private static final String EXTRA_TITLE = "extra_title";
|
||||
private static final String EXTRA_CONTENT_TEXT = "extra_content_text";
|
||||
private static final String EXTRA_CHANNEL_ID = "extra_channel_id";
|
||||
private static final String EXTRA_ICON_RES = "extra_icon_res";
|
||||
private static final String EXTRA_ID = "extra_id";
|
||||
private static final String EXTRA_PROGRESS = "extra_progress";
|
||||
private static final String EXTRA_PROGRESS_MAX = "extra_progress_max";
|
||||
private static final String EXTRA_TITLE = "extra_title";
|
||||
private static final String EXTRA_CONTENT_TEXT = "extra_content_text";
|
||||
private static final String EXTRA_CHANNEL_ID = "extra_channel_id";
|
||||
private static final String EXTRA_ICON_RES = "extra_icon_res";
|
||||
private static final String EXTRA_ID = "extra_id";
|
||||
private static final String EXTRA_PROGRESS = "extra_progress";
|
||||
private static final String EXTRA_PROGRESS_MAX = "extra_progress_max";
|
||||
private static final String EXTRA_PROGRESS_INDETERMINATE = "extra_progress_indeterminate";
|
||||
|
||||
private static final String ACTION_START = "start";
|
||||
private static final String ACTION_STOP = "stop";
|
||||
private static final String ACTION_STOP = "stop";
|
||||
|
||||
private static final AtomicInteger NEXT_ID = new AtomicInteger();
|
||||
private static final AtomicBoolean CHANNEL_CREATED = new AtomicBoolean(false);
|
||||
@@ -54,7 +51,9 @@ public final class GenericForegroundService extends Service {
|
||||
|
||||
private final LinkedHashMap<Integer, Entry> allActiveMessages = new LinkedHashMap<>();
|
||||
|
||||
private static final Entry DEFAULTS = new Entry("", "", NotificationCenter.CH_GENERIC, R.drawable.icon_notification, -1, 0, 0, false);
|
||||
private static final Entry DEFAULTS =
|
||||
new Entry(
|
||||
"", "", NotificationCenter.CH_GENERIC, R.drawable.icon_notification, -1, 0, 0, false);
|
||||
|
||||
private @Nullable Entry lastPosted;
|
||||
|
||||
@@ -66,9 +65,11 @@ public final class GenericForegroundService extends Service {
|
||||
|
||||
synchronized (GenericForegroundService.class) {
|
||||
String action = intent.getAction();
|
||||
if (ACTION_START.equals(action)) handleStart(intent);
|
||||
else if (ACTION_STOP .equals(action)) handleStop(intent);
|
||||
else throw new IllegalStateException(String.format("Action needs to be %s or %s.", ACTION_START, ACTION_STOP));
|
||||
if (ACTION_START.equals(action)) handleStart(intent);
|
||||
else if (ACTION_STOP.equals(action)) handleStop(intent);
|
||||
else
|
||||
throw new IllegalStateException(
|
||||
String.format("Action needs to be %s or %s.", ACTION_START, ACTION_STOP));
|
||||
|
||||
updateNotification();
|
||||
|
||||
@@ -89,7 +90,6 @@ public final class GenericForegroundService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void handleStart(@NonNull Intent intent) {
|
||||
Entry entry = Entry.fromIntent(intent);
|
||||
|
||||
@@ -112,14 +112,18 @@ public final class GenericForegroundService extends Service {
|
||||
|
||||
private void postObligatoryForegroundNotification(@NonNull Entry active) {
|
||||
lastPosted = active;
|
||||
startForeground(NotificationCenter.ID_GENERIC, new Builder(this, active.channelId)
|
||||
.setSmallIcon(active.iconRes)
|
||||
.setContentTitle(active.title)
|
||||
.setTicker(active.contentText)
|
||||
.setContentText(active.contentText)
|
||||
.setProgress(active.progressMax, active.progress, active.indeterminate)
|
||||
.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, DummyActivity.class), IntentUtils.FLAG_MUTABLE()))
|
||||
.build());
|
||||
startForeground(
|
||||
NotificationCenter.ID_GENERIC,
|
||||
new Builder(this, active.channelId)
|
||||
.setSmallIcon(active.iconRes)
|
||||
.setContentTitle(active.title)
|
||||
.setTicker(active.contentText)
|
||||
.setContentText(active.contentText)
|
||||
.setProgress(active.progressMax, active.progress, active.indeterminate)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
this, 0, new Intent(this, DummyActivity.class), IntentUtils.FLAG_MUTABLE()))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,8 +131,8 @@ public final class GenericForegroundService extends Service {
|
||||
return binder;
|
||||
}
|
||||
|
||||
|
||||
public static NotificationController startForegroundTask(@NonNull Context context, @NonNull String task) {
|
||||
public static NotificationController startForegroundTask(
|
||||
@NonNull Context context, @NonNull String task) {
|
||||
startedCounter++;
|
||||
final int id = NEXT_ID.getAndIncrement();
|
||||
|
||||
@@ -151,14 +155,15 @@ public final class GenericForegroundService extends Service {
|
||||
intent.putExtra(EXTRA_ID, id);
|
||||
|
||||
ContextCompat.startForegroundService(context, intent);
|
||||
startedCounter = Math.max(startedCounter-1, 0);
|
||||
startedCounter = Math.max(startedCounter - 1, 0);
|
||||
}
|
||||
|
||||
public static boolean isForegroundTaskStarted() {
|
||||
return startedCounter > 0;
|
||||
}
|
||||
|
||||
synchronized void replaceProgress(int id, int progressMax, int progress, boolean indeterminate, String message) {
|
||||
synchronized void replaceProgress(
|
||||
int id, int progressMax, int progress, boolean indeterminate, String message) {
|
||||
Entry oldEntry = allActiveMessages.get(id);
|
||||
|
||||
if (oldEntry == null) {
|
||||
@@ -170,7 +175,16 @@ public final class GenericForegroundService extends Service {
|
||||
message = oldEntry.contentText;
|
||||
}
|
||||
|
||||
Entry newEntry = new Entry(oldEntry.title, message, oldEntry.channelId, oldEntry.iconRes, oldEntry.id, progressMax, progress, indeterminate);
|
||||
Entry newEntry =
|
||||
new Entry(
|
||||
oldEntry.title,
|
||||
message,
|
||||
oldEntry.channelId,
|
||||
oldEntry.iconRes,
|
||||
oldEntry.id,
|
||||
progressMax,
|
||||
progress,
|
||||
indeterminate);
|
||||
|
||||
if (oldEntry.equals(newEntry)) {
|
||||
Log.d(TAG, String.format("handleReplace() skip, no change %s", newEntry));
|
||||
@@ -185,36 +199,47 @@ public final class GenericForegroundService extends Service {
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
static public void createFgNotificationChannel(Context context) {
|
||||
if(!CHANNEL_CREATED.get() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
public static void createFgNotificationChannel(Context context) {
|
||||
if (!CHANNEL_CREATED.get() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
CHANNEL_CREATED.set(true);
|
||||
NotificationChannel channel = new NotificationChannel(NotificationCenter.CH_GENERIC,
|
||||
"Generic Background Service", NotificationManager.IMPORTANCE_MIN);
|
||||
channel.setDescription("Ensure app will not be killed while long ongoing background tasks are running.");
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(
|
||||
NotificationCenter.CH_GENERIC,
|
||||
"Generic Background Service",
|
||||
NotificationManager.IMPORTANCE_MIN);
|
||||
channel.setDescription(
|
||||
"Ensure app will not be killed while long ongoing background tasks are running.");
|
||||
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Entry {
|
||||
final @NonNull String title;
|
||||
final @NonNull String contentText;
|
||||
final @NonNull String channelId;
|
||||
final int id;
|
||||
final @DrawableRes int iconRes;
|
||||
final int progress;
|
||||
final int progressMax;
|
||||
final boolean indeterminate;
|
||||
final @NonNull String title;
|
||||
final @NonNull String contentText;
|
||||
final @NonNull String channelId;
|
||||
final int id;
|
||||
final @DrawableRes int iconRes;
|
||||
final int progress;
|
||||
final int progressMax;
|
||||
final boolean indeterminate;
|
||||
|
||||
private Entry(@NonNull String title, @NonNull String contentText, @NonNull String channelId, @DrawableRes int iconRes, int id, int progressMax, int progress, boolean indeterminate) {
|
||||
this.title = title;
|
||||
this.contentText = contentText;
|
||||
this.channelId = channelId;
|
||||
this.iconRes = iconRes;
|
||||
this.id = id;
|
||||
this.progress = progress;
|
||||
this.progressMax = progressMax;
|
||||
private Entry(
|
||||
@NonNull String title,
|
||||
@NonNull String contentText,
|
||||
@NonNull String channelId,
|
||||
@DrawableRes int iconRes,
|
||||
int id,
|
||||
int progressMax,
|
||||
int progress,
|
||||
boolean indeterminate) {
|
||||
this.title = title;
|
||||
this.contentText = contentText;
|
||||
this.channelId = channelId;
|
||||
this.iconRes = iconRes;
|
||||
this.id = id;
|
||||
this.progress = progress;
|
||||
this.progressMax = progressMax;
|
||||
this.indeterminate = indeterminate;
|
||||
}
|
||||
|
||||
@@ -230,17 +255,26 @@ public final class GenericForegroundService extends Service {
|
||||
String channelId = intent.getStringExtra(EXTRA_CHANNEL_ID);
|
||||
if (channelId == null) channelId = DEFAULTS.channelId;
|
||||
|
||||
int iconRes = intent.getIntExtra(EXTRA_ICON_RES, DEFAULTS.iconRes);
|
||||
int progress = intent.getIntExtra(EXTRA_PROGRESS, DEFAULTS.progress);
|
||||
int progressMax = intent.getIntExtra(EXTRA_PROGRESS_MAX, DEFAULTS.progressMax);
|
||||
boolean indeterminate = intent.getBooleanExtra(EXTRA_PROGRESS_INDETERMINATE, DEFAULTS.indeterminate);
|
||||
int iconRes = intent.getIntExtra(EXTRA_ICON_RES, DEFAULTS.iconRes);
|
||||
int progress = intent.getIntExtra(EXTRA_PROGRESS, DEFAULTS.progress);
|
||||
int progressMax = intent.getIntExtra(EXTRA_PROGRESS_MAX, DEFAULTS.progressMax);
|
||||
boolean indeterminate =
|
||||
intent.getBooleanExtra(EXTRA_PROGRESS_INDETERMINATE, DEFAULTS.indeterminate);
|
||||
|
||||
return new Entry(title, contentText, channelId, iconRes, id, progressMax, progress, indeterminate);
|
||||
return new Entry(
|
||||
title, contentText, channelId, iconRes, id, progressMax, progress, indeterminate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String toString() {
|
||||
return String.format(Locale.ENGLISH, "ChannelId: %s Id: %d Progress: %d/%d %s", channelId, id, progress, progressMax, indeterminate ? "indeterminate" : "determinate");
|
||||
return String.format(
|
||||
Locale.ENGLISH,
|
||||
"ChannelId: %s Id: %d Progress: %d/%d %s",
|
||||
channelId,
|
||||
id,
|
||||
progress,
|
||||
progressMax,
|
||||
indeterminate ? "indeterminate" : "determinate");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -249,14 +283,14 @@ public final class GenericForegroundService extends Service {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Entry entry = (Entry) o;
|
||||
return id == entry.id &&
|
||||
iconRes == entry.iconRes &&
|
||||
progress == entry.progress &&
|
||||
progressMax == entry.progressMax &&
|
||||
indeterminate == entry.indeterminate &&
|
||||
title.equals(entry.title) &&
|
||||
contentText.equals(entry.contentText) &&
|
||||
channelId.equals(entry.channelId);
|
||||
return id == entry.id
|
||||
&& iconRes == entry.iconRes
|
||||
&& progress == entry.progress
|
||||
&& progressMax == entry.progressMax
|
||||
&& indeterminate == entry.indeterminate
|
||||
&& title.equals(entry.title)
|
||||
&& contentText.equals(entry.contentText)
|
||||
&& channelId.equals(entry.channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,25 +5,20 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Class to control notifications triggered by GenericForeGroundService.
|
||||
*
|
||||
*/
|
||||
/** Class to control notifications triggered by GenericForeGroundService. */
|
||||
public final class NotificationController {
|
||||
|
||||
private final @NonNull Context context;
|
||||
private final int id;
|
||||
|
||||
private int progress;
|
||||
private int progressMax;
|
||||
private int progress;
|
||||
private int progressMax;
|
||||
private boolean indeterminate;
|
||||
private String message = "";
|
||||
private long percent = -1;
|
||||
private String message = "";
|
||||
private long percent = -1;
|
||||
|
||||
private final ServiceConnection serviceConnection;
|
||||
|
||||
@@ -31,26 +26,31 @@ public final class NotificationController {
|
||||
|
||||
NotificationController(@NonNull Context context, int id) {
|
||||
this.context = context;
|
||||
this.id = id;
|
||||
this.id = id;
|
||||
|
||||
serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
GenericForegroundService.LocalBinder binder = (GenericForegroundService.LocalBinder) service;
|
||||
GenericForegroundService genericForegroundService = binder.getService();
|
||||
serviceConnection =
|
||||
new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
GenericForegroundService.LocalBinder binder =
|
||||
(GenericForegroundService.LocalBinder) service;
|
||||
GenericForegroundService genericForegroundService = binder.getService();
|
||||
|
||||
NotificationController.this.service.set(genericForegroundService);
|
||||
NotificationController.this.service.set(genericForegroundService);
|
||||
|
||||
updateProgressOnService();
|
||||
}
|
||||
updateProgressOnService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
service.set(null);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
service.set(null);
|
||||
}
|
||||
};
|
||||
|
||||
context.bindService(new Intent(context, GenericForegroundService.class), serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
context.bindService(
|
||||
new Intent(context, GenericForegroundService.class),
|
||||
serviceConnection,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
@@ -61,7 +61,7 @@ public final class NotificationController {
|
||||
try {
|
||||
GenericForegroundService.stopForegroundTask(context, id);
|
||||
context.unbindService(serviceConnection);
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -74,16 +74,18 @@ public final class NotificationController {
|
||||
setProgress((int) newProgressMax, (int) newProgress, false, newMessage);
|
||||
}
|
||||
|
||||
private synchronized void setProgress(int newProgressMax, int newProgress, boolean indeterminant, @NonNull String newMessage) {
|
||||
private synchronized void setProgress(
|
||||
int newProgressMax, int newProgress, boolean indeterminant, @NonNull String newMessage) {
|
||||
int newPercent = newProgressMax != 0 ? 100 * newProgress / newProgressMax : -1;
|
||||
|
||||
boolean same = newPercent == percent && indeterminate == indeterminant && newMessage.equals(message);
|
||||
boolean same =
|
||||
newPercent == percent && indeterminate == indeterminant && newMessage.equals(message);
|
||||
|
||||
percent = newPercent;
|
||||
progress = newProgress;
|
||||
progressMax = newProgressMax;
|
||||
percent = newPercent;
|
||||
progress = newProgress;
|
||||
progressMax = newProgressMax;
|
||||
indeterminate = indeterminant;
|
||||
message = newMessage;
|
||||
message = newMessage;
|
||||
|
||||
if (same) return;
|
||||
|
||||
@@ -95,6 +97,6 @@ public final class NotificationController {
|
||||
|
||||
if (genericForegroundService == null) return;
|
||||
|
||||
genericForegroundService.replaceProgress(id, progressMax, progress, indeterminate, message);
|
||||
genericForegroundService.replaceProgress(id, progressMax, progress, indeterminate, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,42 +9,43 @@
|
||||
android:gravity="center_vertical"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/call_icon"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@null" />
|
||||
<ImageView
|
||||
android:id="@+id/call_icon"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
<LinearLayout android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="?conversation_item_outgoing_text_primary_color"
|
||||
tools:text="Incoming call" />
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="?conversation_item_incoming_text_secondary_color"
|
||||
tools:text="Incoming call" />
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="?conversation_item_outgoing_text_primary_color"
|
||||
tools:text="Incoming call" />
|
||||
|
||||
</LinearLayout>
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="?conversation_item_incoming_text_secondary_color"
|
||||
tools:text="Incoming call" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.CallItemView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/call_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/call_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -13,265 +13,263 @@
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/conversation_individual_right_gutter"
|
||||
android:layout_marginEnd="@dimen/conversation_individual_right_gutter"
|
||||
android:layout_marginBottom="@dimen/below_bubble"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingStart="6dp"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/jumpto_icon"
|
||||
>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/reply_icon"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignStart="@id/body_bubble"
|
||||
android:layout_alignTop="@id/body_bubble"
|
||||
android:layout_alignBottom="@id/body_bubble"
|
||||
android:alpha="0"
|
||||
app:srcCompat="?menu_reply_icon"
|
||||
android:tint="?icon_tint"
|
||||
android:layout_alignLeft="@id/body_bubble" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/contact_photo_container"
|
||||
android:layout_width="36dp"
|
||||
<RelativeLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignBottom="@id/body_bubble">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||
android:id="@+id/contact_photo"
|
||||
android:foreground="@drawable/contact_photo_background"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:cropToPadding="true"
|
||||
android:contentDescription="@string/pref_profile_photo" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/body_bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/message_bubble_edge_margin"
|
||||
android:layout_marginEnd="@dimen/message_bubble_edge_margin"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_toRightOf="@id/contact_photo_container"
|
||||
android:layout_toEndOf="@id/contact_photo_container"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginRight="@dimen/conversation_individual_right_gutter"
|
||||
android:layout_marginEnd="@dimen/conversation_individual_right_gutter"
|
||||
android:layout_marginBottom="@dimen/below_bubble"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingStart="6dp"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:background="@color/white"
|
||||
tools:backgroundTint="@color/core_light_10">
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/jumpto_icon">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/reply_icon"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignStart="@id/body_bubble"
|
||||
android:layout_alignTop="@id/body_bubble"
|
||||
android:layout_alignBottom="@id/body_bubble"
|
||||
android:alpha="0"
|
||||
app:srcCompat="?menu_reply_icon"
|
||||
android:tint="?icon_tint"
|
||||
android:layout_alignLeft="@id/body_bubble" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/contact_photo_container"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignBottom="@id/body_bubble">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||
android:id="@+id/contact_photo"
|
||||
android:foreground="@drawable/contact_photo_background"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:cropToPadding="true"
|
||||
android:contentDescription="@string/pref_profile_photo" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/group_sender_holder"
|
||||
android:id="@+id/body_bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
android:layout_marginRight="@dimen/message_bubble_edge_margin"
|
||||
android:layout_marginEnd="@dimen/message_bubble_edge_margin"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_toRightOf="@id/contact_photo_container"
|
||||
android:layout_toEndOf="@id/contact_photo_container"
|
||||
android:orientation="vertical"
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false"
|
||||
android:background="@color/white"
|
||||
tools:backgroundTint="@color/core_light_10">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/group_message_sender"
|
||||
<LinearLayout
|
||||
android:id="@+id/group_sender_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4sp"
|
||||
android:layout_marginEnd="4sp"
|
||||
style="@style/Signal.Text.Preview"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:visibility="visible"
|
||||
tools:text="Alice"/>
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/group_message_sender"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4sp"
|
||||
android:layout_marginEnd="4sp"
|
||||
style="@style/Signal.Text.Preview"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:visibility="visible"
|
||||
tools:text="Alice" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.QuoteView
|
||||
android:id="@+id/quote_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:visibility="gone"
|
||||
app:message_type="incoming"
|
||||
app:quote_colorPrimary="?attr/conversation_item_quote_text_color"
|
||||
app:quote_colorSecondary="?attr/conversation_item_quote_text_color"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/image_view_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_received_thumbnail" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/sticker_view_stub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_sticker" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/audio_view_stub"
|
||||
android:layout="@layout/conversation_item_received_audio"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/document_view_stub"
|
||||
android:layout="@layout/conversation_item_received_document"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/webxdc_view_stub"
|
||||
android:layout="@layout/conversation_item_webxdc"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/vcard_view_stub"
|
||||
android:layout="@layout/conversation_item_vcard"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/call_view_stub"
|
||||
android:layout="@layout/conversation_item_call"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.AutoScaledEmojiTextView
|
||||
android:id="@+id/conversation_item_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:paddingTop="@dimen/message_bubble_top_padding"
|
||||
android:textColor="?conversation_item_incoming_text_primary_color"
|
||||
android:textColorLink="?attr/colorAccent"
|
||||
android:importantForAccessibility="no"
|
||||
tools:text="Mango pickle lorem ipsum" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/msg_action_button"
|
||||
android:visibility="gone"
|
||||
style="@style/ButtonPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:padding="@dimen/message_bubble_showmore_padding"
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="0dp"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/show_full_button"
|
||||
android:visibility="gone"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:paddingTop="@dimen/message_bubble_showmore_padding"
|
||||
android:paddingBottom="@dimen/message_bubble_showmore_padding"
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="0dp"
|
||||
android:background="@drawable/touch_highlight_background_strong"
|
||||
android:textColor="@color/delta_accent_darker"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.ConversationItemFooter
|
||||
android:id="@+id/conversation_item_footer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_bottom_padding"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="end"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:alpha="0.7"
|
||||
app:footer_text_color="?conversation_item_incoming_text_secondary_color" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.QuoteView
|
||||
android:id="@+id/quote_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:visibility="gone"
|
||||
app:message_type="incoming"
|
||||
app:quote_colorPrimary="?attr/conversation_item_quote_text_color"
|
||||
app:quote_colorSecondary="?attr/conversation_item_quote_text_color"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/image_view_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_received_thumbnail" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/sticker_view_stub"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/conversation_item_sticker" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/audio_view_stub"
|
||||
android:layout="@layout/conversation_item_received_audio"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/document_view_stub"
|
||||
android:layout="@layout/conversation_item_received_document"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/webxdc_view_stub"
|
||||
android:layout="@layout/conversation_item_webxdc"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/vcard_view_stub"
|
||||
android:layout="@layout/conversation_item_vcard"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/call_view_stub"
|
||||
android:layout="@layout/conversation_item_call"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/message_bubble_top_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.AutoScaledEmojiTextView
|
||||
android:id="@+id/conversation_item_body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:paddingTop="@dimen/message_bubble_top_padding"
|
||||
android:textColor="?conversation_item_incoming_text_primary_color"
|
||||
android:textColorLink="?attr/colorAccent"
|
||||
android:importantForAccessibility="no"
|
||||
tools:text="Mango pickle lorem ipsum"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/msg_action_button"
|
||||
android:visibility="gone"
|
||||
style="@style/ButtonPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_collapsed_footer_padding"
|
||||
android:padding="@dimen/message_bubble_showmore_padding"
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="0dp"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/show_full_button"
|
||||
android:visibility="gone"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:paddingTop="@dimen/message_bubble_showmore_padding"
|
||||
android:paddingBottom="@dimen/message_bubble_showmore_padding"
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="0dp"
|
||||
android:background="@drawable/touch_highlight_background_strong"
|
||||
android:textColor="@color/delta_accent_darker"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ConversationItemFooter
|
||||
android:id="@+id/conversation_item_footer"
|
||||
<org.thoughtcrime.securesms.reactions.ReactionsConversationView
|
||||
android:id="@+id/reactions_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/body_bubble"
|
||||
android:layout_alignStart="@id/body_bubble"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:layout_marginLeft="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginRight="@dimen/message_bubble_horizontal_padding"
|
||||
android:layout_marginBottom="@dimen/message_bubble_bottom_padding"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="end"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:alpha="0.7"
|
||||
app:footer_text_color="?conversation_item_incoming_text_secondary_color"/>
|
||||
android:orientation="horizontal"
|
||||
app:message_type="incoming" />
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.reactions.ReactionsConversationView
|
||||
android:id="@+id/reactions_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/body_bubble"
|
||||
android:layout_alignStart="@id/body_bubble"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:orientation="horizontal"
|
||||
app:message_type="incoming" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/jumpto_icon"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="@dimen/conversation_individual_right_gutter"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/rounded_arrow_forward_24"
|
||||
android:background="@drawable/jumpto_btn_bg"
|
||||
android:contentDescription="@string/show_in_chat"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/jumpto_icon"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginEnd="@dimen/conversation_individual_right_gutter"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/rounded_arrow_forward_24"
|
||||
android:background="@drawable/jumpto_btn_bg"
|
||||
android:contentDescription="@string/show_in_chat"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</org.thoughtcrime.securesms.ConversationItem>
|
||||
|
||||
@@ -13,18 +13,17 @@
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/jumpto_icon"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/conversation_individual_left_gutter"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/rounded_arrow_forward_24"
|
||||
android:background="@drawable/jumpto_btn_bg"
|
||||
android:contentDescription="@string/show_in_chat"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/jumpto_icon"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/conversation_individual_left_gutter"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/rounded_arrow_forward_24"
|
||||
android:background="@drawable/jumpto_btn_bg"
|
||||
android:contentDescription="@string/show_in_chat"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/container"
|
||||
@@ -86,7 +85,7 @@
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
tools:visibility="visible"
|
||||
tools:text="Bob"/>
|
||||
tools:text="Bob" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -101,7 +100,7 @@
|
||||
app:message_type="incoming"
|
||||
app:quote_colorPrimary="?attr/conversation_item_quote_text_color"
|
||||
app:quote_colorSecondary="?attr/conversation_item_quote_text_color"
|
||||
tools:visibility="visible"/>
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/image_view_stub"
|
||||
@@ -176,7 +175,7 @@
|
||||
android:textColor="?conversation_item_outgoing_text_primary_color"
|
||||
android:textColorLink="?attr/colorAccent"
|
||||
android:importantForAccessibility="no"
|
||||
tools:text="Mango pickle lorem ipsum"/>
|
||||
tools:text="Mango pickle lorem ipsum" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/msg_action_button"
|
||||
@@ -192,7 +191,7 @@
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="0dp"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false"/>
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/show_full_button"
|
||||
@@ -210,7 +209,7 @@
|
||||
android:background="@drawable/touch_highlight_background_strong"
|
||||
android:textColor="@color/delta_accent_darker"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false"/>
|
||||
android:textAllCaps="false" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.ConversationItemFooter
|
||||
android:id="@+id/conversation_item_footer"
|
||||
@@ -224,7 +223,7 @@
|
||||
android:gravity="end"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:footer_text_color="?attr/conversation_item_outgoing_text_secondary_color"/>
|
||||
app:footer_text_color="?attr/conversation_item_outgoing_text_secondary_color" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -239,7 +238,7 @@
|
||||
app:message_type="outgoing" />
|
||||
|
||||
<!-- the following view is only left because it is used as a reference for positioning above.
|
||||
removing would require some re-layouting, it's just not done yet.-->
|
||||
removing would require some re-layouting, it's just not done yet. -->
|
||||
<View
|
||||
android:visibility="gone"
|
||||
android:id="@+id/indicators_parent"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.ConversationUpdateItem xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<org.thoughtcrime.securesms.ConversationUpdateItem
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -40,7 +41,7 @@
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!--Links should be clickable, see https://github.com/deltachat/deltachat-android/issues/1546-->
|
||||
<!--Links should be clickable, see https://github.com/deltachat/deltachat-android/issues/1546 -->
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/conversation_update_body"
|
||||
style="@style/Delta.Text.UpdateHeader"
|
||||
@@ -54,7 +55,8 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView android:id="@+id/delivery_indicator"
|
||||
<ImageView
|
||||
android:id="@+id/delivery_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<string-array name="pref_theme_entries" tools:ignore="InconsistentArrays">
|
||||
<item>@string/pref_system_default</item>
|
||||
<item>@string/pref_light_theme</item>
|
||||
<item>@string/pref_dark_theme</item>
|
||||
</string-array>
|
||||
<string-array
|
||||
name="pref_theme_entries"
|
||||
tools:ignore="InconsistentArrays">
|
||||
<item>@string/pref_system_default</item>
|
||||
<item>@string/pref_light_theme</item>
|
||||
<item>@string/pref_dark_theme</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_theme_values" translatable="false" tools:ignore="InconsistentArrays">
|
||||
<item>system</item>
|
||||
<item>light</item>
|
||||
<item>dark</item>
|
||||
</string-array>
|
||||
<string-array
|
||||
name="pref_theme_values"
|
||||
translatable="false"
|
||||
tools:ignore="InconsistentArrays">
|
||||
<item>system</item>
|
||||
<item>light</item>
|
||||
<item>dark</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user