From d1ec6eb7f9faf1c0e9cfbeaea64d87f890b80c58 Mon Sep 17 00:00:00 2001 From: Ben Smiley Date: Mon, 7 Jan 2019 15:21:41 +0100 Subject: [PATCH 1/4] Add ability to register custom handlers --- .../java/co/chatsdk/android/app/AppObj.java | 10 +++++++ .../chatsdk/core/base/BaseNetworkAdapter.java | 13 +++++++++ .../java/co/chatsdk/core/dao/DaoMaster.java | 6 ++-- .../java/co/chatsdk/core/dao/DaoSession.java | 28 +++++++++---------- gradle.properties | 4 +-- 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/co/chatsdk/android/app/AppObj.java b/app/src/main/java/co/chatsdk/android/app/AppObj.java index 1b3f6f052..5778e59ee 100644 --- a/app/src/main/java/co/chatsdk/android/app/AppObj.java +++ b/app/src/main/java/co/chatsdk/android/app/AppObj.java @@ -1,15 +1,22 @@ package co.chatsdk.android.app; import android.content.Context; + +import com.google.firebase.auth.EmailAuthProvider; +import com.google.firebase.auth.PhoneAuthProvider; + import androidx.multidex.MultiDex; import androidx.multidex.MultiDexApplication; +import co.chatsdk.core.dao.User; import co.chatsdk.core.error.ChatSDKException; import co.chatsdk.core.session.ChatSDK; import co.chatsdk.core.session.Configuration; +import co.chatsdk.core.session.NetworkManager; import co.chatsdk.firebase.FirebaseNetworkAdapter; import co.chatsdk.firebase.file_storage.FirebaseFileStorageModule; import co.chatsdk.firebase.push.FirebasePushModule; +import co.chatsdk.firebase.ui.FirebaseUIModule; import co.chatsdk.ui.manager.BaseInterfaceAdapter; /** @@ -24,6 +31,7 @@ public void onCreate() { Context context = getApplicationContext(); Configuration.Builder config = new Configuration.Builder(context); + // builder.firebaseRootPath("firebase_v4_web_new_4"); config.firebaseRootPath("18_12_bug"); config.googleMaps("AIzaSyCwwtZrlY9Rl8paM0R6iDNBEit_iexQ1aE"); @@ -40,6 +48,8 @@ public void onCreate() { FirebaseFileStorageModule.activate(); FirebasePushModule.activate(); + + // FirebaseUIModule.activate(context, EmailAuthProvider.PROVIDER_ID, PhoneAuthProvider.PROVIDER_ID); diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java b/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java index a95288729..2bd5df3ea 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java @@ -1,5 +1,8 @@ package co.chatsdk.core.base; +import java.util.ArrayList; +import java.util.HashMap; + import co.chatsdk.core.handlers.AudioMessageHandler; import co.chatsdk.core.handlers.AuthenticationHandler; import co.chatsdk.core.handlers.BlockingHandler; @@ -56,4 +59,14 @@ public class BaseNetworkAdapter { public HookHandler hook = new BaseHookHandler(); public EncryptionHandler encryption; + private HashMap handlers = new HashMap<>(); + + public void setHandler(Object handler, String name) { + handlers.put(name, handler); + } + + public Object getHandler (String name) { + return handlers.get(name); + } + } diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoMaster.java b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoMaster.java index b35dd449f..c025b8680 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoMaster.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoMaster.java @@ -27,11 +27,11 @@ public static void createAllTables(Database db, boolean ifNotExists) { LinkedAccountDao.createTable(db, ifNotExists); ThreadMetaValueDao.createTable(db, ifNotExists); FollowerLinkDao.createTable(db, ifNotExists); + MessageMetaValueDao.createTable(db, ifNotExists); ContactLinkDao.createTable(db, ifNotExists); ThreadDao.createTable(db, ifNotExists); UserMetaValueDao.createTable(db, ifNotExists); ReadReceiptUserLinkDao.createTable(db, ifNotExists); - MessageMetaValueDao.createTable(db, ifNotExists); } /** Drops underlying database table using DAOs. */ @@ -42,11 +42,11 @@ public static void dropAllTables(Database db, boolean ifExists) { LinkedAccountDao.dropTable(db, ifExists); ThreadMetaValueDao.dropTable(db, ifExists); FollowerLinkDao.dropTable(db, ifExists); + MessageMetaValueDao.dropTable(db, ifExists); ContactLinkDao.dropTable(db, ifExists); ThreadDao.dropTable(db, ifExists); UserMetaValueDao.dropTable(db, ifExists); ReadReceiptUserLinkDao.dropTable(db, ifExists); - MessageMetaValueDao.dropTable(db, ifExists); } /** @@ -71,11 +71,11 @@ public DaoMaster(Database db) { registerDaoClass(LinkedAccountDao.class); registerDaoClass(ThreadMetaValueDao.class); registerDaoClass(FollowerLinkDao.class); + registerDaoClass(MessageMetaValueDao.class); registerDaoClass(ContactLinkDao.class); registerDaoClass(ThreadDao.class); registerDaoClass(UserMetaValueDao.class); registerDaoClass(ReadReceiptUserLinkDao.class); - registerDaoClass(MessageMetaValueDao.class); } public DaoSession newSession() { diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoSession.java b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoSession.java index d694a2be0..fe4d1ce64 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoSession.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/DaoSession.java @@ -14,11 +14,11 @@ import co.chatsdk.core.dao.LinkedAccount; import co.chatsdk.core.dao.ThreadMetaValue; import co.chatsdk.core.dao.FollowerLink; +import co.chatsdk.core.dao.MessageMetaValue; import co.chatsdk.core.dao.ContactLink; import co.chatsdk.core.dao.Thread; import co.chatsdk.core.dao.UserMetaValue; import co.chatsdk.core.dao.ReadReceiptUserLink; -import co.chatsdk.core.dao.MessageMetaValue; import co.chatsdk.core.dao.MessageDao; import co.chatsdk.core.dao.UserThreadLinkDao; @@ -26,11 +26,11 @@ import co.chatsdk.core.dao.LinkedAccountDao; import co.chatsdk.core.dao.ThreadMetaValueDao; import co.chatsdk.core.dao.FollowerLinkDao; +import co.chatsdk.core.dao.MessageMetaValueDao; import co.chatsdk.core.dao.ContactLinkDao; import co.chatsdk.core.dao.ThreadDao; import co.chatsdk.core.dao.UserMetaValueDao; import co.chatsdk.core.dao.ReadReceiptUserLinkDao; -import co.chatsdk.core.dao.MessageMetaValueDao; // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. @@ -47,11 +47,11 @@ public class DaoSession extends AbstractDaoSession { private final DaoConfig linkedAccountDaoConfig; private final DaoConfig threadMetaValueDaoConfig; private final DaoConfig followerLinkDaoConfig; + private final DaoConfig messageMetaValueDaoConfig; private final DaoConfig contactLinkDaoConfig; private final DaoConfig threadDaoConfig; private final DaoConfig userMetaValueDaoConfig; private final DaoConfig readReceiptUserLinkDaoConfig; - private final DaoConfig messageMetaValueDaoConfig; private final MessageDao messageDao; private final UserThreadLinkDao userThreadLinkDao; @@ -59,11 +59,11 @@ public class DaoSession extends AbstractDaoSession { private final LinkedAccountDao linkedAccountDao; private final ThreadMetaValueDao threadMetaValueDao; private final FollowerLinkDao followerLinkDao; + private final MessageMetaValueDao messageMetaValueDao; private final ContactLinkDao contactLinkDao; private final ThreadDao threadDao; private final UserMetaValueDao userMetaValueDao; private final ReadReceiptUserLinkDao readReceiptUserLinkDao; - private final MessageMetaValueDao messageMetaValueDao; public DaoSession(Database db, IdentityScopeType type, Map>, DaoConfig> daoConfigMap) { @@ -87,6 +87,9 @@ public DaoSession(Database db, IdentityScopeType type, Map Date: Wed, 9 Jan 2019 16:04:55 +0100 Subject: [PATCH 2/4] This is the bugfix to the numbers not showing up in the chat. The Message.java was altered to convert integers, floats and doubles to strings when reading them from firebase. --- .../src/main/java/co/chatsdk/core/dao/Message.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java index 8462e7b3b..001e292d7 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java @@ -194,6 +194,18 @@ public String stringForKey (String key) { if (value instanceof String) { return (String) value; } + else if (value instanceof Double) { + String string = value.toString(); + return string; + } + else if (value instanceof Integer) { + String string = value.toString(); + return string; + } + else if (value instanceof Float) { + String string = value.toString(); + return string; + } else { return ""; } From 085a4e74b200df2a7eeb8dd2bd435b6cc5c714c1 Mon Sep 17 00:00:00 2001 From: thecmart Date: Wed, 9 Jan 2019 16:13:42 +0100 Subject: [PATCH 3/4] This is the bugfix to the numbers not showing up in the chat. The Message.java was altered to convert integers, floats and doubles to strings when reading them from firebase. Now with more compact code. --- .../src/main/java/co/chatsdk/core/dao/Message.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java index 001e292d7..7568b764a 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java @@ -194,20 +194,8 @@ public String stringForKey (String key) { if (value instanceof String) { return (String) value; } - else if (value instanceof Double) { - String string = value.toString(); - return string; - } - else if (value instanceof Integer) { - String string = value.toString(); - return string; - } - else if (value instanceof Float) { - String string = value.toString(); - return string; - } else { - return ""; + return value.toString(); } } From 500bc08fd80680d2129bcbfd26158a268452038a Mon Sep 17 00:00:00 2001 From: Ben Smiley Date: Thu, 10 Jan 2019 16:28:48 +0100 Subject: [PATCH 4/4] Major update --- README.md | 2 +- app/build.gradle | 2 +- app/release.keystore | Bin 0 -> 2258 bytes .../java/co/chatsdk/android/app/AppObj.java | 4 +- build.gradle | 5 +- chat-sdk-core/build.gradle | 2 +- .../core/base/AbstractMessageViewHolder.java | 49 ++ .../core/base/AbstractThreadHandler.java | 8 +- .../co/chatsdk/core/base/BaseHookHandler.java | 12 +- .../chatsdk/core/base/BaseNetworkAdapter.java | 17 +- .../java/co/chatsdk/core/dao/Message.java | 15 +- ...r.java => AudioMessageDisplayHandler.java} | 4 +- .../core/handlers/AuthenticationHandler.java | 2 +- ...er.java => FileMessageDisplayHandler.java} | 4 +- ...java => StickerMessageDisplayHandler.java} | 4 +- ...r.java => VideoMessageDisplayHandler.java} | 4 +- .../core/interfaces/CustomMessageHandler.java | 15 - .../core/interfaces/InterfaceAdapter.java | 10 +- .../interfaces/MessageDisplayHandler.java | 22 + .../java/co/chatsdk/core/session/ChatSDK.java | 18 +- .../main/java/co/chatsdk/core/session/NM.java | 16 +- .../java/co/chatsdk/core/types/Defines.java | 3 - .../co/chatsdk/core/types/MessageType.java | 80 ++- .../java/co/chatsdk/core/utils/Strings.java | 26 +- .../FirebaseAuthenticationHandler.java | 8 +- .../firebase/FirebaseEventHandler.java | 2 +- .../firebase/wrappers/ThreadWrapper.java | 4 +- chat-sdk-ui/build.gradle | 2 +- .../ui/chat/BaseMessageViewHolder.java | 291 ++++++++++ .../java/co/chatsdk/ui/chat/ChatActivity.java | 4 +- .../chatsdk/ui/chat/MessageListAdapter.java | 224 ++++++++ .../co/chatsdk/ui/chat/MessageListItem.java | 78 --- .../chatsdk/ui/chat/MessagesListAdapter.java | 514 ------------------ .../AbstractMessageDisplayHandler.java | 22 + .../handlers/ImageMessageDisplayHandler.java | 30 + .../LocationMessageDisplayHandler.java | 30 + .../handlers/TextMessageDisplayHandler.java | 29 + .../viewholder/ImageMessageViewHolder.java | 66 +++ .../viewholder/LocationMessageViewHolder.java | 47 ++ .../viewholder/TextMessageViewHolder.java | 25 + .../ui/manager/BaseInterfaceAdapter.java | 36 +- .../ui/threads/ThreadsListAdapter.java | 1 + gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 44 files changed, 1011 insertions(+), 732 deletions(-) create mode 100644 app/release.keystore create mode 100644 chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractMessageViewHolder.java rename chat-sdk-core/src/main/java/co/chatsdk/core/handlers/{AudioMessageHandler.java => AudioMessageDisplayHandler.java} (74%) rename chat-sdk-core/src/main/java/co/chatsdk/core/handlers/{FileMessageHandler.java => FileMessageDisplayHandler.java} (71%) rename chat-sdk-core/src/main/java/co/chatsdk/core/handlers/{StickerMessageHandler.java => StickerMessageDisplayHandler.java} (70%) rename chat-sdk-core/src/main/java/co/chatsdk/core/handlers/{VideoMessageHandler.java => VideoMessageDisplayHandler.java} (73%) delete mode 100644 chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/CustomMessageHandler.java create mode 100644 chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/MessageDisplayHandler.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/BaseMessageViewHolder.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListAdapter.java delete mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessagesListAdapter.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/AbstractMessageDisplayHandler.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/ImageMessageDisplayHandler.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/LocationMessageDisplayHandler.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/TextMessageDisplayHandler.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/ImageMessageViewHolder.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/LocationMessageViewHolder.java create mode 100644 chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/TextMessageViewHolder.java diff --git a/README.md b/README.md index 9e8761eea..9865ebe58 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Chat SDK is a fully featured open source instant messaging framework for Android - **Full control of the data.** You have full and exclusive access to the user's chat data - **Quick integration.** Chat SDK is fully featured out of the box -- **Demo Versions.** **[Firebase](https://i.diawi.com/NUcnaL)** or **[XMPP](https://i.diawi.com/ZpPscm)** open this link on your Android phone to install +- **Demo Versions.** **[Firebase](https://i.diawi.com/r6P7of)** or **[XMPP](https://i.diawi.com/boXf6U)** open this link on your Android phone to install - **Scalable.** Supports millons of daily users [[1](https://firebase.google.com/docs/database/usage/limits), [2](https://blog.process-one.net/ejabberd-massive-scalability-1node-2-million-concurrent-users/)] - **Backend agnostic.** Chat SDK can be customized to [support any backend](https://github.com/chat-sdk/chat-sdk-android#backend-agnostic-architecture) diff --git a/app/build.gradle b/app/build.gradle index 42968936c..a182f6c0e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -69,7 +69,7 @@ android { dependencies { // implementation fileTree(include: ['*.jar'], dir: 'libs') // implementation project(path: ':chat-sdk-core') - implementation 'androidx.multidex:multidex:2.0.0' + implementation "androidx.multidex:multidex:$androidxMultidexVersion" implementation project(path: ':chat-sdk-ui') implementation project(path: ':chat-sdk-firebase-adapter') implementation project(path: ':chat-sdk-firebase-push') diff --git a/app/release.keystore b/app/release.keystore new file mode 100644 index 0000000000000000000000000000000000000000..dfb53b8e191c999c955ba486abf53563b9996e42 GIT binary patch literal 2258 zcmcgt={wX58=l_`V{67TnQTL4$xHN`n2GFW?8{h7w$O~wSR1kpH5d+M8KIn_)Ul)x zBT-7LnIhS*8?a9FETQzVCJZg7?Gy;l7{e!*kuwbKTF@($*3L0)g%T_#2Y` zVdSXrU~&|NO7TBSIYWutsRZfS9D4_W2*N;yz&414i)z9F0YC#P2>^l+0fxZm6e{6K z^0{ZOi8hgx`C9#U)%$iNDe8ff;|R{BtRZu@%%$r;W<5T+*BdkCJmM$pyw}zv^uIYa zMqtWvS_#rQU*vr2@-7yIkAB>8u|Tw*@wfuHw2?k#Pkv{kKUS{ zVY0(*D;l%7M4W z#6DUeCV1|YvIQfqez=%R_u)S8-!sUDW~OI_prPEJy^J= zZ=l&CyRav<*ZOj8>_*uA-xN#L;;yIQr5y^_W>`yJQPj$-?qYhKilcHzYBi}1I%jjA zMYhwlhJgop z_ktp(tH7X1lea(go@kk_{uyvLitCR*Z!*$UGv193jZg8a8}O}&{q+7%+sex!Lu+57 zS@R_AnvM%_Vg15J{4(!_^?__s)?FvB;y16@9_idnwN9h$Q<-^IBxm4kg%%er_jM&| zl=$fFVOr_Nf{AyU>^n;%6{1p9(4l>q*8xr9inxP(E^Sh@np=Nsmpu_$V_=_JN=WVL zzN;aeX|FW&crxcXtf}b?uoGCj_16zy4MoT`^h8W zxO`oc+ZA$|ltt)K)`Mp^4&ADK)*Sr=6&S{OklPsIX#}&?!^=;;FY4|L)9jTDs2Nf~ zXgbg3NNN+Gp#wQr4y;FJxQ@rg*Sayi`NI2gN_TafuEnuL1(Sfq1PgH6{bGVdMm9I8}DTj>%h@?^0{`?-0>FjICHjV%?`nk@hijQTJD>Dwes60 z==cw#9Lmvpp=yQopMvBXu4>TRe-^))aH|FV%8m3}LQE&ezncu`&Kjp+MBd=a7q{~! z49=AHe^aywn?58?Ct{ZFPE_V7*{d}->vSZAJT=p~*e&#y?CSQ@;zh|&>QvDhG@&jR6s3cQu*xQ(I-tkXmz_|ydpzHtRAVO zm7pZ%Fd@oU?oTT6Zay_|-7^1yVb&4LJ8CSJm*qx8rvtG;Ud1*1_s!4Fp8K|AJ7_K0 z?~`Me0AB6+2VU23qzl;rF9{KXT)bCrOSaTJ(nzv#@V;o@v8j=7j1ZQBXjNu4OQEn|v zt+VldhI780X898J4%CrisiVO+&fBRAMOF74ca6#TS)eFCFRz_HACTfh2w>mCzx$rs zPTs^2{!U3j4{aQ%4}rkwAOjW$GNAr9U{C-G74WXQ90DTXA{tC<<~jlZ!~`K=C{_#< zfy3Md;3z230xP~#-yy;%xH%!3LFnp&SWx#r z^#45$1K9shLv|hpi~)#4Kn5TRWdH!A2(;0$pVaB;Dz8*TR1Z)OcL^Vqi&qGD+0!^N zoaN{{H^;f{zECn(n`aDM7Vq)2#g#M+mdvOwkD}qNX{f0Ls2P_(nmXR=t5TkE&^|Vw zEi=$od@O!(G2b&q{aC4s^suo!bLK~OsMNXMu7jGl&iM2-)fSO-2hq1`o~BbJbU8(& zX!W3%*~;EePiIw|R^M=Nx+I}F)t^qszR2HK>bspl8zL^1@);4Ynxq?d(nQ;R1?%2+ zUf46N1ooI;)~mHR+)6)bDa)EYzTPgu#t4V|aTAV2bKkQ(LLb5_4xFJcsYCZOHZgpNfCPByV$F#BUG#_u~(qs&w3>F-^MK zV&pfLyq632a=w(_sWDpY6WpvA=8X|5U1hfT0SdBl#tRzFyxmBs;%~O}_Kmd8oNpet4AEJ|i zlt@W(DIsx&M*fu_#1+fflo491f>z%oUmn~h>}tnx#1@1{%7qSP7qq?bp_lWyo=M%l g*Lln%P97CQ{`Mi^mY?~l#F=x^)=xa`Xv6rw0R6nrW&i*H literal 0 HcmV?d00001 diff --git a/app/src/main/java/co/chatsdk/android/app/AppObj.java b/app/src/main/java/co/chatsdk/android/app/AppObj.java index 5778e59ee..b8c3009d6 100644 --- a/app/src/main/java/co/chatsdk/android/app/AppObj.java +++ b/app/src/main/java/co/chatsdk/android/app/AppObj.java @@ -33,14 +33,14 @@ public void onCreate() { Configuration.Builder config = new Configuration.Builder(context); // builder.firebaseRootPath("firebase_v4_web_new_4"); - config.firebaseRootPath("18_12_bug"); + config.firebaseRootPath("19_01"); config.googleMaps("AIzaSyCwwtZrlY9Rl8paM0R6iDNBEit_iexQ1aE"); config.publicRoomCreationEnabled(false); config.pushNotificationSound("default"); // config.pushNotificationsForPublicChatRoomsEnabled(true); try { - ChatSDK.initialize(config.build(), new BaseInterfaceAdapter(context), new FirebaseNetworkAdapter()); + ChatSDK.initialize(config.build(), new FirebaseNetworkAdapter(), new BaseInterfaceAdapter(context)); } catch (ChatSDKException e) { diff --git a/build.gradle b/build.gradle index 18ea5c687..f3f9931b6 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' - classpath 'com.google.gms:google-services:4.0.1' + classpath 'com.google.gms:google-services:4.2.0' classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$bintrayVersion" } } @@ -18,9 +18,10 @@ ext { bintrayVersion = "1.8.4" mavenGradleVersion = "2.1" androidxAppcompatVersion = "1.0.2" - androidxConstraintLayoutVersion = "2.0.0-alpha2" + androidxConstraintLayoutVersion = "2.0.0-alpha3" androidxLifecycleExtensionsVersion = "2.0.0" androidxRecyclerViewVersion = "1.0.0" + androidxMultidexVersion = "2.0.1" materialVersion = "1.0.0" playAuthVersion = "16.0.1" playMapsVersion = "16.0.0" diff --git a/chat-sdk-core/build.gradle b/chat-sdk-core/build.gradle index 78ff34f9b..36c8a7da5 100644 --- a/chat-sdk-core/build.gradle +++ b/chat-sdk-core/build.gradle @@ -50,7 +50,7 @@ dependencies { api "io.reactivex.rxjava2:rxjava:$rxJavaVersion" implementation "org.apache.commons:commons-lang3:$apacheCommonsVersion" api "com.google.android.gms:play-services-maps:$playMapsVersion" - + implementation "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion" implementation "com.facebook.fresco:fresco:$frescoVersion" implementation "id.zelory:compressor:$compressorVersion" diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractMessageViewHolder.java b/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractMessageViewHolder.java new file mode 100644 index 000000000..9e1098fc6 --- /dev/null +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractMessageViewHolder.java @@ -0,0 +1,49 @@ +package co.chatsdk.core.base; + +import android.app.Activity; +import android.view.View; +import android.widget.LinearLayout; + +import androidx.recyclerview.widget.RecyclerView; +import co.chatsdk.core.dao.Message; + +public abstract class AbstractMessageViewHolder extends RecyclerView.ViewHolder { + + protected Activity activity; + protected Message message; + + protected View.OnClickListener onClickListener = null; + protected View.OnLongClickListener onLongClickListener = null; + + public AbstractMessageViewHolder(View itemView, Activity activity) { + super(itemView); + this.activity = activity; + } + + public abstract void showProgressBar(); + public abstract void showProgressBar(float progress); + public abstract void hideProgressBar (); + + public abstract void setIconSize(int width, int height); + public abstract void setImageSize(int width, int height); + public abstract void setBubbleHidden (boolean hidden); + public abstract void setIconHidden (boolean hidden); + public abstract void setImageHidden (boolean hidden); + public abstract void setTextHidden (boolean hidden); + public abstract View viewForClassType (Class classType); + public abstract void setAlpha (float alpha); + public abstract LinearLayout getExtraLayout(); + + public void setMessage (Message message) { + this.message = message; + } + + public void setOnClickListener (View.OnClickListener listener) { + onClickListener = listener; + } + + public void setOnLongClickListener (View.OnLongClickListener listener) { + onLongClickListener = listener; + } + +} diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractThreadHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractThreadHandler.java index 7344e9434..9d9e14681 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractThreadHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/base/AbstractThreadHandler.java @@ -72,17 +72,21 @@ public Observable sendMessageWithText(final String text, fi } - public static Message newMessage (MessageType type, Thread thread) { + public static Message newMessage (int type, Thread thread) { Message message = StorageManager.shared().createEntity(Message.class); message.setSender(ChatSDK.currentUser()); message.setMessageStatus(MessageSendStatus.Sending); message.setDate(new DateTime(System.currentTimeMillis())); message.setEntityID(UUID.randomUUID().toString()); - message.setMessageType(type); + message.setType(type); thread.addMessage(message); return message; } + public static Message newMessage (MessageType type, Thread thread) { + return newMessage(type.ordinal(), thread); + } + /** /* Convenience method to save the message to the database then pass it to the token network adapter * send method so it can be sent via the network diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseHookHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseHookHandler.java index ff05452b0..d89472def 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseHookHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseHookHandler.java @@ -12,18 +12,16 @@ public class BaseHookHandler implements HookHandler { - public static String UserAuthFinished = "UserAuthFinished"; - public static String UserAuthFinished_User = "UserAuthFinished_User"; + public static String DidAuthenticate = "DidAuthenticate"; public static String UserOn = "UserOn"; - public static String UserOn_User = "UserOn_User"; public static String MessageReceived = "MessageReceived"; - public static String MessageReceived_Message = "MessageReceived_Message"; - public static String MessageIsNew_Bool = "MessageIsNew_Bool"; + public static String Message = "Message"; + public static String IsNew_Boolean = "IsNew_Boolean"; - public static String Logout = "Logout"; - public static String Logout_User = "Logout_User"; + public static String DidLogout = "DidLogout"; + public static String User = "User"; public static String SetUserOnline = "SetUserOnline"; public static String SetUserOffline = "SetUserOffline"; diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java b/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java index 2bd5df3ea..4a22ddb78 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/base/BaseNetworkAdapter.java @@ -1,9 +1,8 @@ package co.chatsdk.core.base; -import java.util.ArrayList; import java.util.HashMap; -import co.chatsdk.core.handlers.AudioMessageHandler; +import co.chatsdk.core.handlers.AudioMessageDisplayHandler; import co.chatsdk.core.handlers.AuthenticationHandler; import co.chatsdk.core.handlers.BlockingHandler; import co.chatsdk.core.handlers.ContactHandler; @@ -21,12 +20,12 @@ import co.chatsdk.core.handlers.ReadReceiptHandler; import co.chatsdk.core.handlers.SearchHandler; import co.chatsdk.core.handlers.SocialLoginHandler; -import co.chatsdk.core.handlers.StickerMessageHandler; -import co.chatsdk.core.handlers.FileMessageHandler; +import co.chatsdk.core.handlers.StickerMessageDisplayHandler; +import co.chatsdk.core.handlers.FileMessageDisplayHandler; import co.chatsdk.core.handlers.ThreadHandler; import co.chatsdk.core.handlers.TypingIndicatorHandler; import co.chatsdk.core.handlers.UploadHandler; -import co.chatsdk.core.handlers.VideoMessageHandler; +import co.chatsdk.core.handlers.VideoMessageDisplayHandler; /** * Created by benjaminsmiley-andrews on 02/05/2017. @@ -39,8 +38,8 @@ public class BaseNetworkAdapter { public PushHandler push; public UploadHandler upload; public ThreadHandler thread; - public VideoMessageHandler videoMessage; - public AudioMessageHandler audioMessage; + public VideoMessageDisplayHandler videoMessage; + public AudioMessageDisplayHandler audioMessage; public ImageMessageHandler imageMessage = new BaseImageMessageHandler(); public LocationMessageHandler locationMessage = new BaseLocationMessageHandler(); public ContactHandler contact = new BaseContactHandler(); @@ -52,8 +51,8 @@ public class BaseNetworkAdapter { public LastOnlineHandler lastOnline; public NearbyUsersHandler nearbyUsers; public ReadReceiptHandler readReceipts; - public StickerMessageHandler stickerMessage; - public FileMessageHandler fileMessage; + public StickerMessageDisplayHandler stickerMessage; + public FileMessageDisplayHandler fileMessage; public SocialLoginHandler socialLogin; public EventHandler events; public HookHandler hook = new BaseHookHandler(); diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java index 8462e7b3b..6f2edbcdb 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/dao/Message.java @@ -260,25 +260,16 @@ public Integer getType () { public MessageType getMessageType() { if(this.type != null) { - return MessageType.values()[this.type]; + return new MessageType(this.type); } - return MessageType.None; - } - - public boolean messageTypeIs (MessageType... types) { - for (MessageType type : types) { - if (getMessageType().equals(type)) { - return true; - } - } - return false; + return new MessageType(MessageType.None); } public void setType(Integer type) { this.type = type; } public void setMessageType(MessageType type) { - this.type = type.ordinal(); + this.type = type.value(); } public Integer getStatus() { diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AudioMessageHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AudioMessageDisplayHandler.java similarity index 74% rename from chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AudioMessageHandler.java rename to chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AudioMessageDisplayHandler.java index fe96f0893..f17089993 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AudioMessageHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AudioMessageDisplayHandler.java @@ -2,7 +2,7 @@ import co.chatsdk.core.audio.Recording; import co.chatsdk.core.dao.Thread; -import co.chatsdk.core.interfaces.CustomMessageHandler; +import co.chatsdk.core.interfaces.MessageDisplayHandler; import co.chatsdk.core.types.MessageSendProgress; import io.reactivex.Observable; @@ -10,7 +10,7 @@ * Created by SimonSmiley-Andrews on 01/05/2017. */ -public interface AudioMessageHandler extends CustomMessageHandler { +public interface AudioMessageDisplayHandler extends MessageDisplayHandler { /** * Send an audio message diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AuthenticationHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AuthenticationHandler.java index 63fa5443c..e27f79cd9 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AuthenticationHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/AuthenticationHandler.java @@ -32,7 +32,7 @@ public interface AuthenticationHandler { Boolean userAuthenticatedThisSession(); /** - * Logout the user from the current account + * DidLogout the user from the current account */ Completable logout(); diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/FileMessageHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/FileMessageDisplayHandler.java similarity index 71% rename from chat-sdk-core/src/main/java/co/chatsdk/core/handlers/FileMessageHandler.java rename to chat-sdk-core/src/main/java/co/chatsdk/core/handlers/FileMessageDisplayHandler.java index a8450b0d1..83ca15ff1 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/FileMessageHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/FileMessageDisplayHandler.java @@ -1,7 +1,7 @@ package co.chatsdk.core.handlers; import co.chatsdk.core.dao.Thread; -import co.chatsdk.core.interfaces.CustomMessageHandler; +import co.chatsdk.core.interfaces.MessageDisplayHandler; import co.chatsdk.core.types.MessageSendProgress; import io.reactivex.Observable; @@ -9,7 +9,7 @@ * Created by Pepe Becker on 01/05/2018. */ -public interface FileMessageHandler extends CustomMessageHandler { +public interface FileMessageDisplayHandler extends MessageDisplayHandler { Observable sendMessageWithFile(String name, String mimeType, byte[] data, final Thread thread); diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/StickerMessageHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/StickerMessageDisplayHandler.java similarity index 70% rename from chat-sdk-core/src/main/java/co/chatsdk/core/handlers/StickerMessageHandler.java rename to chat-sdk-core/src/main/java/co/chatsdk/core/handlers/StickerMessageDisplayHandler.java index 21f9356c6..78d8499a6 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/StickerMessageHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/StickerMessageDisplayHandler.java @@ -1,6 +1,6 @@ package co.chatsdk.core.handlers; -import co.chatsdk.core.interfaces.CustomMessageHandler; +import co.chatsdk.core.interfaces.MessageDisplayHandler; import co.chatsdk.core.types.MessageSendProgress; import io.reactivex.Observable; import co.chatsdk.core.dao.Thread; @@ -9,7 +9,7 @@ * Created by SimonSmiley-Andrews on 01/05/2017. */ -public interface StickerMessageHandler extends CustomMessageHandler { +public interface StickerMessageDisplayHandler extends MessageDisplayHandler { Observable sendMessageWithSticker(String stickerImageName, final Thread thread); diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/VideoMessageHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/VideoMessageDisplayHandler.java similarity index 73% rename from chat-sdk-core/src/main/java/co/chatsdk/core/handlers/VideoMessageHandler.java rename to chat-sdk-core/src/main/java/co/chatsdk/core/handlers/VideoMessageDisplayHandler.java index 63923b47f..28e22b44b 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/VideoMessageHandler.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/handlers/VideoMessageDisplayHandler.java @@ -1,7 +1,7 @@ package co.chatsdk.core.handlers; import co.chatsdk.core.dao.Thread; -import co.chatsdk.core.interfaces.CustomMessageHandler; +import co.chatsdk.core.interfaces.MessageDisplayHandler; import co.chatsdk.core.types.MessageSendProgress; import io.reactivex.Observable; @@ -9,7 +9,7 @@ * Created by SimonSmiley-Andrews on 01/05/2017. */ -public interface VideoMessageHandler extends CustomMessageHandler { +public interface VideoMessageDisplayHandler extends MessageDisplayHandler { /** * Send a video message diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/CustomMessageHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/CustomMessageHandler.java deleted file mode 100644 index a54fe6463..000000000 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/CustomMessageHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package co.chatsdk.core.interfaces; - -import android.content.Context; - -import co.chatsdk.core.dao.Message; - -/** - * Created by ben on 10/11/17. - */ - -public interface CustomMessageHandler { - - void updateMessageCellView (Message message, Object viewHolder, Context context); - -} diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/InterfaceAdapter.java b/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/InterfaceAdapter.java index d8cec194e..487feca62 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/InterfaceAdapter.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/InterfaceAdapter.java @@ -5,12 +5,14 @@ import android.content.Intent; import androidx.fragment.app.Fragment; +import java.util.Collection; import java.util.HashMap; import java.util.List; import co.chatsdk.core.Tab; import co.chatsdk.core.dao.Thread; import co.chatsdk.core.dao.User; +import co.chatsdk.core.types.MessageType; import co.chatsdk.core.types.SearchActivityType; import co.chatsdk.core.utils.NotificationDisplayHandler; @@ -65,9 +67,11 @@ public interface InterfaceAdapter { void setChatOptionsHandler (ChatOptionsHandler handler); ChatOptionsHandler getChatOptionsHandler (ChatOptionsDelegate delegate); - void addCustomMessageHandler (CustomMessageHandler handler); - void removeCustomMessageHandler (CustomMessageHandler handler); - List getCustomMessageHandlers(); + void setMessageHandler(MessageDisplayHandler handler, MessageType type); + void removeMessageHandler(MessageType type); + MessageDisplayHandler getMessageHandler(MessageType type); + + Collection getMessageHandlers(); boolean showLocalNotifications(Thread thread); void setLocalNotificationHandler(LocalNotificationHandler handler); diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/MessageDisplayHandler.java b/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/MessageDisplayHandler.java new file mode 100644 index 000000000..f1d120b13 --- /dev/null +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/interfaces/MessageDisplayHandler.java @@ -0,0 +1,22 @@ +package co.chatsdk.core.interfaces; + +import android.app.Activity; +import android.content.Context; +import android.view.LayoutInflater; + +import androidx.recyclerview.widget.RecyclerView; +import co.chatsdk.core.base.AbstractMessageViewHolder; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.types.MessageType; + +/** + * Created by ben on 10/11/17. + */ + +public interface MessageDisplayHandler { + + void updateMessageCellView (Message message, AbstractMessageViewHolder viewHolder, Context context); + String displayName (Message message); + AbstractMessageViewHolder newViewHolder(boolean isReply, Activity activity); + +} diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/session/ChatSDK.java b/chat-sdk-core/src/main/java/co/chatsdk/core/session/ChatSDK.java index 642bb9db8..6962c60fb 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/session/ChatSDK.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/session/ChatSDK.java @@ -16,14 +16,14 @@ import co.chatsdk.core.error.ChatSDKException; import co.chatsdk.core.events.EventType; import co.chatsdk.core.events.NetworkEvent; -import co.chatsdk.core.handlers.AudioMessageHandler; +import co.chatsdk.core.handlers.AudioMessageDisplayHandler; import co.chatsdk.core.handlers.AuthenticationHandler; import co.chatsdk.core.handlers.BlockingHandler; import co.chatsdk.core.handlers.ContactHandler; import co.chatsdk.core.handlers.CoreHandler; import co.chatsdk.core.handlers.EncryptionHandler; import co.chatsdk.core.handlers.EventHandler; -import co.chatsdk.core.handlers.FileMessageHandler; +import co.chatsdk.core.handlers.FileMessageDisplayHandler; import co.chatsdk.core.handlers.HookHandler; import co.chatsdk.core.handlers.ImageMessageHandler; import co.chatsdk.core.handlers.LastOnlineHandler; @@ -33,11 +33,11 @@ import co.chatsdk.core.handlers.ReadReceiptHandler; import co.chatsdk.core.handlers.SearchHandler; import co.chatsdk.core.handlers.SocialLoginHandler; -import co.chatsdk.core.handlers.StickerMessageHandler; +import co.chatsdk.core.handlers.StickerMessageDisplayHandler; import co.chatsdk.core.handlers.ThreadHandler; import co.chatsdk.core.handlers.TypingIndicatorHandler; import co.chatsdk.core.handlers.UploadHandler; -import co.chatsdk.core.handlers.VideoMessageHandler; +import co.chatsdk.core.handlers.VideoMessageDisplayHandler; import co.chatsdk.core.interfaces.InterfaceAdapter; import co.chatsdk.core.interfaces.LocalNotificationHandler; import co.chatsdk.core.interfaces.ThreadType; @@ -71,7 +71,7 @@ public static ChatSDK initialize (Configuration config) throws ChatSDKException return initialize(config, null, null); } - public static ChatSDK initialize (Configuration config, InterfaceAdapter interfaceAdapter, BaseNetworkAdapter networkAdapter) throws ChatSDKException { + public static ChatSDK initialize (Configuration config, BaseNetworkAdapter networkAdapter, InterfaceAdapter interfaceAdapter) throws ChatSDKException { shared().setContext(config.context.get()); shared().config = config; @@ -255,11 +255,11 @@ public static LastOnlineHandler lastOnline () { return a().lastOnline; } - public static AudioMessageHandler audioMessage () { + public static AudioMessageDisplayHandler audioMessage () { return a().audioMessage; } - public static VideoMessageHandler videoMessage () { + public static VideoMessageDisplayHandler videoMessage () { return a().videoMessage; } @@ -271,11 +271,11 @@ public static SocialLoginHandler socialLogin () { return a().socialLogin; } - public static StickerMessageHandler stickerMessage () { + public static StickerMessageDisplayHandler stickerMessage () { return a().stickerMessage; } - public static FileMessageHandler fileMessage () { + public static FileMessageDisplayHandler fileMessage () { return a().fileMessage; } diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/session/NM.java b/chat-sdk-core/src/main/java/co/chatsdk/core/session/NM.java index 1d136a408..821c1c97c 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/session/NM.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/session/NM.java @@ -2,7 +2,7 @@ import co.chatsdk.core.base.BaseNetworkAdapter; import co.chatsdk.core.dao.User; -import co.chatsdk.core.handlers.AudioMessageHandler; +import co.chatsdk.core.handlers.AudioMessageDisplayHandler; import co.chatsdk.core.handlers.AuthenticationHandler; import co.chatsdk.core.handlers.BlockingHandler; import co.chatsdk.core.handlers.ContactHandler; @@ -18,12 +18,12 @@ import co.chatsdk.core.handlers.ReadReceiptHandler; import co.chatsdk.core.handlers.SearchHandler; import co.chatsdk.core.handlers.SocialLoginHandler; -import co.chatsdk.core.handlers.StickerMessageHandler; -import co.chatsdk.core.handlers.FileMessageHandler; +import co.chatsdk.core.handlers.StickerMessageDisplayHandler; +import co.chatsdk.core.handlers.FileMessageDisplayHandler; import co.chatsdk.core.handlers.ThreadHandler; import co.chatsdk.core.handlers.TypingIndicatorHandler; import co.chatsdk.core.handlers.UploadHandler; -import co.chatsdk.core.handlers.VideoMessageHandler; +import co.chatsdk.core.handlers.VideoMessageDisplayHandler; import co.chatsdk.core.interfaces.InterfaceAdapter; /** @@ -83,11 +83,11 @@ public static LastOnlineHandler lastOnline () { return a().lastOnline; } - public static AudioMessageHandler audioMessage () { + public static AudioMessageDisplayHandler audioMessage () { return a().audioMessage; } - public static VideoMessageHandler videoMessage () { + public static VideoMessageDisplayHandler videoMessage () { return a().videoMessage; } @@ -99,11 +99,11 @@ public static SocialLoginHandler socialLogin () { return a().socialLogin; } - public static StickerMessageHandler stickerMessage () { + public static StickerMessageDisplayHandler stickerMessage () { return a().stickerMessage; } - public static FileMessageHandler fileMessage () { + public static FileMessageDisplayHandler fileMessage () { return a().fileMessage; } diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/types/Defines.java b/chat-sdk-core/src/main/java/co/chatsdk/core/types/Defines.java index c76835bce..e9190f40d 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/types/Defines.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/types/Defines.java @@ -13,9 +13,6 @@ public class Defines { public static final String DIVIDER = ","; public static final class MessageDateFormat { - public static final String YearOldMessageFormat = "MM/yy"; - public static final String DayOldFormat = "MMM dd"; - public static final String LessThenDayFormat = "HH:mm"; } public static final String FROM_PUSH = "from_push"; diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/types/MessageType.java b/chat-sdk-core/src/main/java/co/chatsdk/core/types/MessageType.java index cec7e93fa..592161863 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/types/MessageType.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/types/MessageType.java @@ -4,17 +4,73 @@ * Created by ben on 9/29/17. */ -public enum MessageType { - - Text, - Location, - Image, - Audio, - Video, - System, - Sticker, - File, - Custom, - None, +//public enum MessageType { +// +// Text, +// Location, +// Image, +// Audio, +// Video, +// System, +// Sticker, +// File, +// Custom, +// None, +// +//} + +public class MessageType { + + public static final int None = -1; + public static final int Text = 0; + public static final int Location = 1; + public static final int Image = 2; + public static final int Audio = 3; + public static final int Video = 4; + public static final int System = 5; + public static final int Sticker = 6; + public static final int File = 7; + public static final int Max = 100000; + + private int value; + + public MessageType (int type) { + assert (type < MessageType.Max); + value = type; + } + + public int value () { + return value; + } + + public int ordinal () { + return value; + } + + public boolean is (MessageType type) { + return is(type.value()); + } + + public boolean is (MessageType... types) { + for (MessageType type : types) { + if (value() == type.value()) { + return true; + } + } + return false; + } + + public boolean is (int type) { + return value() == type; + } + + public boolean is (int... types) { + for (int type : types) { + if (value() == type) { + return true; + } + } + return false; + } } diff --git a/chat-sdk-core/src/main/java/co/chatsdk/core/utils/Strings.java b/chat-sdk-core/src/main/java/co/chatsdk/core/utils/Strings.java index f3f0d1982..00f4868c8 100644 --- a/chat-sdk-core/src/main/java/co/chatsdk/core/utils/Strings.java +++ b/chat-sdk-core/src/main/java/co/chatsdk/core/utils/Strings.java @@ -11,6 +11,7 @@ import co.chatsdk.core.dao.Message; import co.chatsdk.core.dao.Thread; import co.chatsdk.core.dao.User; +import co.chatsdk.core.interfaces.MessageDisplayHandler; import co.chatsdk.core.interfaces.ThreadType; import co.chatsdk.core.session.ChatSDK; @@ -29,26 +30,11 @@ public static String t (int resId) { } public static String payloadAsString (Message message) { - if (message.getType() != null) { - switch (message.getMessageType()) { - case Text: - case System: - return message.getText(); - case Image: - return t(R.string.image_message); - case Location: - return t(R.string.location_message); - case Audio: - return t(R.string.audio_message); - case Video: - return t(R.string.video_message); - case Sticker: - return t(R.string.sticker_message); - case File: - return t(R.string.file_message); - } - } - return t(R.string.unknown_message); + MessageDisplayHandler handler = ChatSDK.ui().getMessageHandler(message.getMessageType()); + if (handler != null) { + return handler.displayName(message); + } + return t(R.string.unknown_message); } public static String dateTime (Date date) { diff --git a/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseAuthenticationHandler.java b/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseAuthenticationHandler.java index 151385263..fa9e98682 100644 --- a/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseAuthenticationHandler.java +++ b/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseAuthenticationHandler.java @@ -131,8 +131,8 @@ public Completable authenticateWithUser(final FirebaseUser user) { if (ChatSDK.hook() != null) { HashMap data = new HashMap<>(); - data.put(BaseHookHandler.UserAuthFinished_User, userWrapper.getModel()); - ChatSDK.hook().executeHook(BaseHookHandler.UserAuthFinished, data); + data.put(BaseHookHandler.User, userWrapper.getModel()); + ChatSDK.hook().executeHook(BaseHookHandler.DidAuthenticate, data); } ChatSDK.core().setUserOnline().subscribe(new CrashReportingCompletableObserver()); @@ -196,8 +196,8 @@ public Completable logout() { if (ChatSDK.hook() != null) { HashMap data = new HashMap<>(); - data.put(BaseHookHandler.Logout_User, user); - ChatSDK.hook().executeHook(BaseHookHandler.Logout, data); + data.put(BaseHookHandler.User, user); + ChatSDK.hook().executeHook(BaseHookHandler.DidLogout, data); } authenticatedThisSession = false; diff --git a/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseEventHandler.java b/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseEventHandler.java index d6faace7f..4954e6996 100644 --- a/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseEventHandler.java +++ b/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/FirebaseEventHandler.java @@ -58,7 +58,7 @@ public void currentUserOn(final String entityID){ if(ChatSDK.hook() != null) { HashMap data = new HashMap<>(); - data.put(BaseHookHandler.UserOn_User, user); + data.put(BaseHookHandler.User, user); ChatSDK.hook().executeHook(BaseHookHandler.UserOn, data); } diff --git a/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/wrappers/ThreadWrapper.java b/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/wrappers/ThreadWrapper.java index 4425b3359..0f195ee84 100644 --- a/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/wrappers/ThreadWrapper.java +++ b/chat-sdk-firebase-adapter/src/main/java/co/chatsdk/firebase/wrappers/ThreadWrapper.java @@ -287,8 +287,8 @@ public Observable messagesOn() { if(ChatSDK.hook() != null) { HashMap data = new HashMap<>(); - data.put(BaseHookHandler.MessageReceived_Message, message.getModel()); - data.put(BaseHookHandler.MessageIsNew_Bool, newMessage); + data.put(BaseHookHandler.Message, message.getModel()); + data.put(BaseHookHandler.IsNew_Boolean, newMessage); ChatSDK.hook().executeHook(BaseHookHandler.MessageReceived, data); } diff --git a/chat-sdk-ui/build.gradle b/chat-sdk-ui/build.gradle index cb69ed610..ce7b84535 100644 --- a/chat-sdk-ui/build.gradle +++ b/chat-sdk-ui/build.gradle @@ -41,7 +41,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') api project(':chat-sdk-core') api "androidx.appcompat:appcompat:$androidxAppcompatVersion" - api "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion" + implementation "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion" api "androidx.constraintlayout:constraintlayout:$androidxConstraintLayoutVersion" api "com.google.android.material:material:$materialVersion" implementation "com.google.android.gms:play-services-places:$playPlacesVersion" diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/BaseMessageViewHolder.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/BaseMessageViewHolder.java new file mode 100644 index 000000000..aafa49caf --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/BaseMessageViewHolder.java @@ -0,0 +1,291 @@ +package co.chatsdk.ui.chat; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.graphics.PorterDuff; +import android.text.util.Linkify; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.facebook.drawee.view.SimpleDraweeView; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import androidx.constraintlayout.widget.ConstraintLayout; +import co.chatsdk.core.base.AbstractMessageViewHolder; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.interfaces.ThreadType; +import co.chatsdk.core.session.ChatSDK; +import co.chatsdk.core.types.MessageSendStatus; +import co.chatsdk.core.types.ReadStatus; +import co.chatsdk.core.utils.CrashReportingCompletableObserver; +import co.chatsdk.ui.R; + +public class BaseMessageViewHolder extends AbstractMessageViewHolder { + + public static final String MoreThanYearFormat = "MM/yy"; + public static final String MoreThanDayFormat = "MMM dd"; + + protected SimpleDraweeView avatarImageView; + protected TextView timeTextView; + protected SimpleDraweeView messageImageView; + protected ConstraintLayout messageBubble; + protected TextView messageTextView; + protected ImageView messageIconView; + protected LinearLayout extraLayout; + protected ImageView readReceiptImageView; + protected ProgressBar progressBar; + + public BaseMessageViewHolder(View itemView, Activity activity) { + super(itemView, activity); + + timeTextView = itemView.findViewById(R.id.txt_time); + avatarImageView = itemView.findViewById(R.id.avatar); + messageBubble = itemView.findViewById(R.id.message_bubble); + messageTextView = itemView.findViewById(R.id.txt_content); + messageIconView = itemView.findViewById(R.id.icon); + messageImageView = itemView.findViewById(R.id.image); + extraLayout = itemView.findViewById(R.id.extra_layout); + readReceiptImageView = itemView.findViewById(R.id.read_receipt); + progressBar = itemView.findViewById(R.id.progress_bar); + + itemView.setOnClickListener(v -> { + onClick(v); + }); + + itemView.setOnLongClickListener(v -> { + return onLongClick(v); + }); + + if(readReceiptImageView != null) { + readReceiptImageView.setVisibility(ChatSDK.readReceipts() != null ? View.VISIBLE : View.INVISIBLE); + } + + // Enable linkify + messageTextView.setAutoLinkMask(Linkify.ALL); + + } + + public void onClick (View v) { + if (onClickListener != null) { + onClickListener.onClick(v); + } + } + + public boolean onLongClick (View v) { + if (onLongClickListener != null) { + onLongClickListener.onLongClick(v); + } else if (message != null && !message.getSender().isMe()) { + + Context context = v.getContext(); + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(itemView.getContext().getString(R.string.delete_message)); + + // Set up the buttons + builder.setPositiveButton(context.getString(R.string.delete), (dialog, which) -> { + try { + ChatSDK.thread().deleteMessage(message).subscribe( new CrashReportingCompletableObserver()); + } + catch (NoSuchMethodError e) { + ChatSDK.logError(e); + } + }); + builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.cancel()); + + builder.show(); + + } + return false; + } + + public void setMessage (Message message) { + super.setMessage(message); + + setBubbleHidden(true); + setTextHidden(true); + setIconHidden(true); + setImageHidden(true); + + float alpha = message.getMessageStatus() == MessageSendStatus.Sent || message.getMessageStatus() == MessageSendStatus.Delivered ? 1.0f : 0.7f; + setAlpha(alpha); + + String time = String.valueOf(getTimeFormat(message).format(message.getDate().toDate())); + timeTextView.setText(time); + + avatarImageView.setImageURI(message.getSender().getAvatarURL()); + + if (message.getSender().isMe()) { + messageTextView.setTextColor(ChatSDK.config().messageTextColorMe); + messageTextView.setPadding(4,0,4,0); + messageBubble.getBackground().setColorFilter(ChatSDK.config().messageColorMe, PorterDuff.Mode.MULTIPLY); + } + else { + messageTextView.setTextColor(ChatSDK.config().messageTextColorReply); + messageTextView.setPadding(4,0,4,0); + messageBubble.getBackground().setColorFilter(ChatSDK.config().messageColorReply, PorterDuff.Mode.MULTIPLY); + } + + updateReadStatus(); + } + + protected void updateReadStatus () { + if (message != null) { + int resource = R.drawable.ic_message_received; + ReadStatus status = message.getReadStatus(); + + // Hide the read receipt for public threads + if(message.getThread().typeIs(ThreadType.Public) || ChatSDK.readReceipts() == null) { + status = ReadStatus.hide(); + } + + if(status.is(ReadStatus.delivered())) { + resource = R.drawable.ic_message_delivered; + } + if(status.is(ReadStatus.read())) { + resource = R.drawable.ic_message_read; + } + if(readReceiptImageView != null) { + readReceiptImageView.setImageResource(resource); + readReceiptImageView.setVisibility(status.is(ReadStatus.hide()) ? View.INVISIBLE : View.VISIBLE); + } + } + } + + public void setAlpha (float alpha) { + messageImageView.setAlpha(alpha); + messageTextView.setAlpha(alpha); + extraLayout.setAlpha(alpha); + } + + @Override + public LinearLayout getExtraLayout() { + return extraLayout; + } + + public int maxWidth () { + return activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_image_message_width); + } + + public int maxHeight () { + return activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_image_message_height); + } + + public void showProgressBar () { + progressBar.setVisibility(View.VISIBLE); + progressBar.setIndeterminate(true); + progressBar.bringToFront(); + } + + public void showProgressBar (float progress) { + if (progress == 0) { + showProgressBar(); + } + else { + progressBar.setVisibility(View.VISIBLE); + progressBar.setIndeterminate(false); + progressBar.setMax(100); + progressBar.setProgress((int) Math.ceil(progress * progressBar.getMax())); + progressBar.bringToFront(); + } + } + + public void hideProgressBar () { + progressBar.setVisibility(View.GONE); + } + + public void setIconSize(int width, int height) { + messageIconView.getLayoutParams().width = width; + messageIconView.getLayoutParams().height = height; + messageIconView.requestLayout(); + } + + public void setImageSize(int width, int height) { + messageImageView.getLayoutParams().width = width; + messageImageView.getLayoutParams().height = height; + messageImageView.requestLayout(); + } + + public void setBubbleHidden (boolean hidden) { + messageBubble.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); + messageBubble.getLayoutParams().width = hidden ? 0 : ViewGroup.LayoutParams.WRAP_CONTENT; + messageBubble.getLayoutParams().height = hidden ? 0 : ViewGroup.LayoutParams.WRAP_CONTENT; + messageBubble.requestLayout(); + } + + public void setIconHidden (boolean hidden) { + messageIconView.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); + if (hidden) { + setIconSize(0, 0); + } else { + setIconSize(activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_icon_message_width), activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_icon_message_height)); + } + messageBubble.requestLayout(); + } + + public void setImageHidden (boolean hidden) { + messageImageView.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); + if (hidden) { + setImageSize(0, 0); + } else { +// setImageSize(maxWidth(), maxHeight()); + setImageSize(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + } + + } + + public void setTextHidden (boolean hidden) { + messageTextView.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); + ConstraintLayout.LayoutParams textLayoutParams = (ConstraintLayout.LayoutParams) messageTextView.getLayoutParams(); + if(hidden) { + textLayoutParams.width = 0; + textLayoutParams.height = 0; + } + else { + textLayoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; + textLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + } + messageTextView.setLayoutParams(textLayoutParams); + messageTextView.requestLayout(); + messageBubble.requestLayout(); + } + + public View viewForClassType (Class classType) { + for (int i = 0; i < extraLayout.getChildCount(); i++) { + View view = extraLayout.getChildAt(i); + if (classType.isInstance(view)) { + return view; + } + } + return null; + } + + protected SimpleDateFormat getTimeFormat(Message message){ + + Date curTime = new Date(); + long interval = (curTime.getTime() - message.getDate().toDate().getTime()) / 1000L; + + String dateFormat = ChatSDK.config().messageTimeFormat; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat, Locale.getDefault()); + + // More then a day ago + if (interval < 3600 * 24) { + return simpleDateFormat; + } + else if (interval < 3600 * 24 * 365) { + simpleDateFormat.applyPattern(dateFormat + " " +MoreThanDayFormat); + } + else { + simpleDateFormat.applyPattern(dateFormat + " " +MoreThanYearFormat); + } + return simpleDateFormat; + } + +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/ChatActivity.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/ChatActivity.java index cfe019554..7b00e0a0a 100644 --- a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/ChatActivity.java +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/ChatActivity.java @@ -104,7 +104,7 @@ protected enum ListPosition { protected TextInputView textInputView; protected RecyclerView recyclerView; - protected MessagesListAdapter messageListAdapter; + protected MessageListAdapter messageListAdapter; protected Thread thread; protected TextView subtitleTextView; @@ -268,7 +268,7 @@ public void onLayoutChange(View v, int left, int top, int right, int bottom, int }); if (messageListAdapter == null) { - messageListAdapter = new MessagesListAdapter(ChatActivity.this); + messageListAdapter = new MessageListAdapter(ChatActivity.this); } recyclerView.setAdapter(messageListAdapter); diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListAdapter.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListAdapter.java new file mode 100644 index 000000000..77ff3d3f6 --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListAdapter.java @@ -0,0 +1,224 @@ +/* + * Created by Itzik Braun on 12/3/2015. + * Copyright (c) 2015 deluge. All rights reserved. + * + * Last Modification at: 3/12/15 4:27 PM + */ + +package co.chatsdk.ui.chat; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.RecyclerView; + +import android.view.ViewGroup; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import co.chatsdk.core.base.AbstractMessageViewHolder; +import co.chatsdk.core.dao.DaoCore; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.interfaces.MessageDisplayHandler; +import co.chatsdk.core.session.ChatSDK; +import co.chatsdk.core.types.MessageSendStatus; +import co.chatsdk.core.types.MessageType; +import co.chatsdk.core.types.Progress; +import timber.log.Timber; + +public class MessageListAdapter extends RecyclerView.Adapter { + + public static int ViewTypeMine = 1; + public static int ViewTypeReply = 2; + + protected AppCompatActivity activity; + + protected List messageItems = new ArrayList<>(); + + public MessageListAdapter(AppCompatActivity activity) { + this.activity = activity; + } + + @Override + public AbstractMessageViewHolder onCreateViewHolder(ViewGroup parent, int type) { + int viewType = (int) Math.ceil(type / MessageType.Max); + int messageType = type - viewType * MessageType.Max; + + MessageDisplayHandler handler = ChatSDK.ui().getMessageHandler(new MessageType(messageType)); + return handler.newViewHolder(viewType == ViewTypeReply, activity); + } + + @Override + public void onBindViewHolder(AbstractMessageViewHolder holder, int position) { + + MessageListItem messageItem = getMessageItems().get(position); + Message message = messageItem.getMessage(); + + holder.setMessage(message); + + if (message.getMessageStatus().equals(MessageSendStatus.Uploading) || (messageItem.progress > 0 && messageItem.progress < 1)) { + holder.showProgressBar(messageItem.progress); + } + else { + holder.hideProgressBar(); + } + + for(MessageDisplayHandler handler : ChatSDK.ui().getMessageHandlers()) { + handler.updateMessageCellView(messageItem.message, holder, activity); + } + } + + @Override + public int getItemViewType(int position) { + Message message = messageItems.get(position).getMessage(); + int viewType = message.getSender().isMe() ? ViewTypeMine : ViewTypeReply; + int messageType = message.getType(); + + // Multiply by message.max so the two types don't clash + return viewType * MessageType.Max + messageType; + } + + @Override + public long getItemId(int i) { + return messageItems.get(i).getMessage().getId(); + } + + @Override + public int getItemCount() { + return messageItems.size(); + } + + + + public List getMessageItems() { + return messageItems; + } + + protected boolean addRow(MessageListItem item, boolean sort, boolean notify){ + if (item == null) + return false; + + // Don't add message that does not have entity id and the status of the message is not sending. + if (item.getMessage().getEntityID() == null) { + return false; + } + + Timber.d("Add Message Item: " + item.message.getText()); + messageItems.add(item); + + if(sort) { + sort(); + } + + if(notify) { + notifyDataSetChanged(); + } + + return true; + } + + public void sort () { + Collections.sort(messageItems, new MessageItemSorter(DaoCore.ORDER_DESC)); + } + + public void sortAndNotify () { + sort(); + notifyDataSetChanged(); + } + + /** + * Add a new message to the list. + * @return true if the item is added to the list. + * */ + public boolean addRow(Message message){ + return addRow(message, true, true); + } + + public boolean addRow(Message message, boolean sort, boolean notify, Progress progress){ + MessageListItem item = messageItemForMessage(message); + boolean returnStatus = false; + if (item == null) { + item = new MessageListItem(message); + returnStatus = addRow(item, sort, notify); + } + if (progress != null) { + item.progress = progress.asFraction(); + } + return returnStatus; + } + + public boolean addRow(Message message, boolean sort, boolean notify) { + return addRow(message, sort, notify, null); + } + + public boolean removeRow (Message message, boolean notify) { + MessageListItem item = messageItemForMessage(message); + if (item != null) { + messageItems.remove(item); + if (notify) { + notifyDataSetChanged(); + } + return true; + } + return false; + } + + protected boolean messageExists (Message message) { + return messageItemForMessage(message) != null; + } + + protected MessageListItem messageItemForMessage (Message message) { + for(MessageListItem i : messageItems) { + if(i.message.getEntityID().equals(message.getEntityID())) { + return i; + } + } + return null; + } + + + /** + * Clear the messages list. + * */ + public void clear() { + clear(true); + } + + public void clear(boolean notify) { + messageItems.clear(); + if(notify) { + notifyDataSetChanged(); + } + } + + public void setMessages(List messages) { + clear(false); + for (Message message : messages) { + addRow(message, false, false); + } + sortAndNotify(); + } + + // Untested because upload progress doesn't work + public void setProgressForMessage (Message message, float progress) { + MessageListItem item = messageListItemForMessage(message); + if(item != null) { + item.progress = progress; + } + notifyDataSetChanged(); + } + + public MessageListItem messageListItemForMessage (Message message) { + for(MessageListItem i : messageItems) { + if(i.message.equals(message)) { + return i; + } + } + return null; + } + + public int size () { + return messageItems.size(); + } + +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListItem.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListItem.java index c06026fc6..414f0aebf 100644 --- a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListItem.java +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessageListItem.java @@ -1,98 +1,20 @@ package co.chatsdk.ui.chat; -import com.google.android.gms.maps.model.LatLng; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import co.chatsdk.core.dao.Keys; import co.chatsdk.core.dao.Message; -import co.chatsdk.core.session.ChatSDK; -import co.chatsdk.core.types.Defines; -import co.chatsdk.core.types.MessageSendStatus; public class MessageListItem { - protected static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ChatSDK.config().messageTimeFormat); - public Message message; public float progress; public MessageListItem (Message message) { - - // If null that means no custom format was added to the adapter so we use the default. - if (simpleDateFormat == null) { - simpleDateFormat = getFormat(message); - } - this.message = message; - - } - - public String getEntityID () { - return message.getEntityID(); - } - - public String getTime () { - return String.valueOf(simpleDateFormat.format(message.getDate().toDate())); - } - - public long getId () { - return message.getId(); - } - - public boolean statusIs (MessageSendStatus status) { - return getMessage().getMessageStatus() == status; - } - - public String getImageURL () { - return message.stringForKey(Keys.MessageImageURL); - } - - public MessageSendStatus status () { - return message.getMessageStatus(); - } - - public LatLng getLatLng() { - double longitude = message.doubleForKey(Keys.MessageLongitude); - double latitude = message.doubleForKey(Keys.MessageLatitude); - return new LatLng(latitude, longitude); } public Message getMessage () { return message; } - protected static SimpleDateFormat getFormat(Message message){ - - Date curTime = new Date(); - long interval = (curTime.getTime() - message.getDate().toDate().getTime()) / 1000L; - - // More then a day ago - if (interval > 3600 * 24) - { - // More then a year - if (interval > 3600 * 24 * 365) - { - simpleDateFormat.applyPattern(Defines.MessageDateFormat.YearOldMessageFormat); - return simpleDateFormat; - } - else { - simpleDateFormat.applyPattern(Defines.MessageDateFormat.DayOldFormat); - return simpleDateFormat; - } - } - else - { - simpleDateFormat.applyPattern(Defines.MessageDateFormat.LessThenDayFormat); - return simpleDateFormat; - } - } - - public boolean equals (MessageListItem item) { - return item.message.equals(message); - } - public long getTimeInMillis() { return message.getDate().toDate().getTime(); } diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessagesListAdapter.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessagesListAdapter.java deleted file mode 100644 index 4975853f5..000000000 --- a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/MessagesListAdapter.java +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Created by Itzik Braun on 12/3/2015. - * Copyright (c) 2015 deluge. All rights reserved. - * - * Last Modification at: 3/12/15 4:27 PM - */ - -package co.chatsdk.ui.chat; - -import android.app.AlertDialog; -import android.content.Context; -import android.graphics.PorterDuff; -import android.net.Uri; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.RecyclerView; -import android.text.util.Linkify; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.facebook.drawee.backends.pipeline.Fresco; -import com.facebook.drawee.view.SimpleDraweeView; -import com.facebook.imagepipeline.common.ResizeOptions; -import com.facebook.imagepipeline.request.ImageRequest; -import com.facebook.imagepipeline.request.ImageRequestBuilder; -import com.google.android.gms.maps.model.LatLng; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import co.chatsdk.core.dao.DaoCore; -import co.chatsdk.core.dao.Message; -import co.chatsdk.core.interfaces.CustomMessageHandler; -import co.chatsdk.core.interfaces.ThreadType; -import co.chatsdk.core.session.ChatSDK; -import co.chatsdk.core.types.MessageSendStatus; -import co.chatsdk.core.types.MessageType; -import co.chatsdk.core.types.Progress; -import co.chatsdk.core.types.ReadStatus; -import co.chatsdk.core.utils.CrashReportingCompletableObserver; -import co.chatsdk.core.utils.GoogleUtils; -import co.chatsdk.ui.R; -import timber.log.Timber; - -public class MessagesListAdapter extends RecyclerView.Adapter { - - public static int ViewTypeMine = 1; - public static int ViewTypeReply = 2; - - public class MessageViewHolder extends RecyclerView.ViewHolder { - - public SimpleDraweeView avatarImageView; - public TextView timeTextView; - public SimpleDraweeView messageImageView; - public ConstraintLayout messageBubble; - public TextView messageTextView; - public ImageView messageIconView; - public LinearLayout extraLayout; - public ImageView readReceiptImageView; - public MessageListItem messageItem; - public ProgressBar progressBar; - protected View.OnClickListener onClickListener = null; - protected View.OnLongClickListener onLongClickListener = null; - - public MessageViewHolder(View itemView) { - super(itemView); - - timeTextView = itemView.findViewById(R.id.txt_time); - avatarImageView = itemView.findViewById(R.id.avatar); - messageBubble = itemView.findViewById(R.id.message_bubble); - messageTextView = itemView.findViewById(R.id.txt_content); - messageIconView = itemView.findViewById(R.id.icon); - messageImageView = itemView.findViewById(R.id.image); - extraLayout = itemView.findViewById(R.id.extra_layout); - readReceiptImageView = itemView.findViewById(R.id.read_receipt); - progressBar = itemView.findViewById(R.id.progress_bar); - - itemView.setOnClickListener(view -> { - if (onClickListener != null) { - onClickListener.onClick(view); - } - else if (messageItem.getMessage().getMessageType() == MessageType.Location) { - LocationMessageOnClickHandler.onClick(activity, messageItem.getLatLng()); - } - else if (messageItem.getMessage().getMessageType() == MessageType.Image) { - ImageMessageOnClickHandler.onClick(activity, view, messageItem.getImageURL()); - } - }); - - itemView.setOnLongClickListener(v -> { - - if (onLongClickListener != null) { - return onLongClickListener.onLongClick(v); - } - else { - - if (!messageItem.message.getSender().isMe()) { - return false; - } - - Context context = v.getContext(); - - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(itemView.getContext().getString(R.string.delete_message)); - - // Set up the buttons - builder.setPositiveButton(context.getString(R.string.delete), (dialog, which) -> { - try { - ChatSDK.thread().deleteMessage(messageItem.message).subscribe( new CrashReportingCompletableObserver()); - } - catch (NoSuchMethodError e) { - ChatSDK.logError(e); - } - }); - builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.cancel()); - - builder.show(); - - return false; - } - }); - - } - - public void showProgressBar () { - progressBar.setVisibility(View.VISIBLE); - progressBar.setIndeterminate(true); - progressBar.bringToFront(); - } - - public void showProgressBar (float progress) { - if (progress == 0) { - showProgressBar(); - } - else { - progressBar.setVisibility(View.VISIBLE); - progressBar.setIndeterminate(false); - progressBar.setMax(100); - progressBar.setProgress((int) Math.ceil(progress * progressBar.getMax())); - progressBar.bringToFront(); - } - } - - public void hideProgressBar () { - progressBar.setVisibility(View.GONE); - } - - public void setOnClickListener (View.OnClickListener listener) { - onClickListener = listener; - } - - public void setOnLongClickListener (View.OnLongClickListener listener) { - onLongClickListener = listener; - } - - public void setIconSize(int width, int height) { - messageIconView.getLayoutParams().width = width; - messageIconView.getLayoutParams().height = height; - messageIconView.requestLayout(); - } - - public void setImageSize(int width, int height) { - messageImageView.getLayoutParams().width = width; - messageImageView.getLayoutParams().height = height; - messageImageView.requestLayout(); - } - - public void setBubbleHidden (boolean hidden) { - messageBubble.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); - messageBubble.getLayoutParams().width = hidden ? 0 : ViewGroup.LayoutParams.WRAP_CONTENT; - messageBubble.getLayoutParams().height = hidden ? 0 : ViewGroup.LayoutParams.WRAP_CONTENT; - messageBubble.requestLayout(); - } - - public void setIconHidden (boolean hidden) { - messageIconView.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); - if (hidden) { - setIconSize(0, 0); - } else { - setIconSize(activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_icon_message_width), activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_icon_message_height)); - } - messageBubble.requestLayout(); - } - - public void setImageHidden (boolean hidden) { - messageImageView.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); - if (hidden) { - setImageSize(0, 0); - } else { -// setImageSize(maxWidth(), maxHeight()); - setImageSize(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - } - - } - - public void setTextHidden (boolean hidden) { - messageTextView.setVisibility(hidden ? View.INVISIBLE : View.VISIBLE); - ConstraintLayout.LayoutParams textLayoutParams = (ConstraintLayout.LayoutParams) messageTextView.getLayoutParams(); - if(hidden) { - textLayoutParams.width = 0; - textLayoutParams.height = 0; - } - else { - textLayoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; - textLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; - } - messageTextView.setLayoutParams(textLayoutParams); - messageTextView.requestLayout(); - messageBubble.requestLayout(); - } - } - - protected AppCompatActivity activity; - - protected List messageItems = new ArrayList<>(); - - public MessagesListAdapter(AppCompatActivity activity) { - this.activity = activity; - } - - @Override - public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - View row = null; - if(viewType == ViewTypeMine) { - row = inflater.inflate(R.layout.chat_sdk_row_message_me , null); - } - if(viewType == ViewTypeReply) { - row = inflater.inflate(R.layout.chat_sdk_row_message_reply , null); - } - return new MessageViewHolder(row); - } - - @Override - public void onBindViewHolder(MessageViewHolder holder, int position) { - - MessageListItem messageItem = getMessageItems().get(position); - holder.messageItem = messageItem; - - // Enable linkify - holder.messageTextView.setAutoLinkMask(Linkify.ALL); - - holder.setBubbleHidden(true); - holder.setTextHidden(true); - holder.setIconHidden(true); - holder.setImageHidden(true); - - if (messageItem.status().equals(MessageSendStatus.Uploading) || (messageItem.progress > 0 && messageItem.progress < 1)) { - holder.showProgressBar(messageItem.progress); - } - else { - holder.hideProgressBar(); - } - - if(holder.readReceiptImageView != null) { - holder.readReceiptImageView.setVisibility(ChatSDK.readReceipts() != null ? View.VISIBLE : View.INVISIBLE); - } - - if (messageItem.getMessage().getMessageType() == MessageType.Text) { - holder.messageTextView.setText(messageItem.getMessage().getText() == null ? "" : messageItem.getMessage().getText()); - holder.setBubbleHidden(false); - holder.setTextHidden(false); - } - else if (messageItem.getMessage().messageTypeIs(MessageType.Location, MessageType.Image)) { - - holder.setImageHidden(false); - - int viewWidth = maxWidth(); - int viewHeight = maxHeight(); - - if (messageItem.getMessage().getMessageType() == MessageType.Location) { - LatLng latLng = messageItem.getLatLng(); - holder.messageImageView.setImageURI(GoogleUtils.getMapImageURL(latLng, viewWidth, viewHeight)); - } - - if (messageItem.getMessage().getMessageType() == MessageType.Image) { - - String url = messageItem.getImageURL(); - - Timber.d(messageItem.status().name()); - - if(url != null && url.length() > 0) { - ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url)) - .setResizeOptions(new ResizeOptions(viewWidth, viewHeight)) - .build(); - - holder.messageImageView.setController( - Fresco.newDraweeControllerBuilder() - .setOldController(holder.messageImageView.getController()) - .setImageRequest(request) - .build()); - } - else { - // Loads the placeholder - holder.messageImageView.setActualImageResource(R.drawable.icn_200_image_message_loading); -// holder.messageImageView.setImageURI(url); - } - } - } - else if (messageItem.getMessage().getMessageType() == MessageType.File) { - holder.setBubbleHidden(false); - holder.setTextHidden(false); - holder.setIconHidden(false); - } - - for(CustomMessageHandler handler : ChatSDK.ui().getCustomMessageHandlers()) { - handler.updateMessageCellView(messageItem.message, holder, activity); - } - - // Set the time of the sending. - holder.timeTextView.setText(messageItem.getTime()); - - float alpha = messageItem.statusIs(MessageSendStatus.Sent) || messageItem.statusIs(MessageSendStatus.Delivered) ? 1.0f : 0.7f; - holder.messageImageView.setAlpha(alpha); - holder.messageTextView.setAlpha(alpha); - holder.extraLayout.setAlpha(alpha); - - holder.avatarImageView.setImageURI(messageItem.getMessage().getSender().getAvatarURL()); - - if (messageItem.message.getSender().isMe()) { - holder.messageTextView.setTextColor(ChatSDK.config().messageTextColorMe); - holder.messageTextView.setPadding(4,0,4,0); - holder.messageBubble.getBackground().setColorFilter(ChatSDK.config().messageColorMe, PorterDuff.Mode.MULTIPLY); - } - else { - holder.messageTextView.setTextColor(ChatSDK.config().messageTextColorReply); - holder.messageTextView.setPadding(4,0,4,0); - holder.messageBubble.getBackground().setColorFilter(ChatSDK.config().messageColorReply, PorterDuff.Mode.MULTIPLY); - } - - updateReadStatus(holder, messageItem.message); - } - - @Override - public int getItemViewType(int position) { - return messageItems.get(position).getMessage().getSender().isMe() ? ViewTypeMine : ViewTypeReply; - } - - @Override - public long getItemId(int i) { - return messageItems.get(i).getId(); - } - - @Override - public int getItemCount() { - return messageItems.size(); - } - - protected void updateReadStatus (MessageViewHolder holder, Message message) { - int resource = R.drawable.ic_message_received; - ReadStatus status = message.getReadStatus(); - - // Hide the read receipt for public threads - if(message.getThread().typeIs(ThreadType.Public) || ChatSDK.readReceipts() == null) { - status = ReadStatus.hide(); - } - - if(status.is(ReadStatus.delivered())) { - resource = R.drawable.ic_message_delivered; - } - if(status.is(ReadStatus.read())) { - resource = R.drawable.ic_message_read; - } - if(holder.readReceiptImageView != null) { - holder.readReceiptImageView.setImageResource(resource); - holder.readReceiptImageView.setVisibility(status.is(ReadStatus.hide()) ? View.INVISIBLE : View.VISIBLE); - } - } - - public List getMessageItems() { - return messageItems; - } - - protected boolean addRow(MessageListItem item, boolean sort, boolean notify){ - if (item == null) - return false; - - // Don't add message that does not have entity id and the status of the message is not sending. - if (item.getEntityID() == null) { - return false; - } - - Timber.d("Add Message Item: " + item.message.getText()); - messageItems.add(item); - - if(sort) { - sort(); - } - - if(notify) { - notifyDataSetChanged(); - } - - return true; - } - - public void sort () { - Collections.sort(messageItems, new MessageItemSorter(DaoCore.ORDER_DESC)); - } - - public void sortAndNotify () { - sort(); - notifyDataSetChanged(); - } - - /** - * Add a new message to the list. - * @return true if the item is added to the list. - * */ - public boolean addRow(Message message){ - return addRow(message, true, true); - } - - public boolean addRow(Message message, boolean sort, boolean notify, Progress progress){ - MessageListItem item = messageItemForMessage(message); - boolean returnStatus = false; - if (item == null) { - item = new MessageListItem(message); - returnStatus = addRow(item, sort, notify); - } - if (progress != null) { - item.progress = progress.asFraction(); - } - return returnStatus; - } - - public boolean addRow(Message message, boolean sort, boolean notify) { - return addRow(message, sort, notify, null); - } - - public boolean removeRow (Message message, boolean notify) { - MessageListItem item = messageItemForMessage(message); - if (item != null) { - messageItems.remove(item); - if (notify) { - notifyDataSetChanged(); - } - return true; - } - return false; - } - - protected boolean messageExists (Message message) { - return messageItemForMessage(message) != null; - } - - protected MessageListItem messageItemForMessage (Message message) { - for(MessageListItem i : messageItems) { - if(i.message.getEntityID().equals(message.getEntityID())) { - return i; - } - } - return null; - } - - public int maxWidth () { - return activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_image_message_width); - } - - public int maxHeight () { - return activity.getResources().getDimensionPixelSize(R.dimen.chat_sdk_max_image_message_height); - } - - /** - * Clear the messages list. - * */ - public void clear() { - clear(true); - } - - public void clear(boolean notify) { - messageItems.clear(); - if(notify) { - notifyDataSetChanged(); - } - } - - public void setMessages(List messages) { - clear(false); - for (Message message : messages) { - addRow(message, false, false); - } - sortAndNotify(); - } - - // Untested because upload progress doesn't work - public void setProgressForMessage (Message message, float progress) { - MessageListItem item = messageListItemForMessage(message); - if(item != null) { - item.progress = progress; - } - notifyDataSetChanged(); - } - - public MessageListItem messageListItemForMessage (Message message) { - for(MessageListItem i : messageItems) { - if(i.message.equals(message)) { - return i; - } - } - return null; - } - - public int size () { - return messageItems.size(); - } - -} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/AbstractMessageDisplayHandler.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/AbstractMessageDisplayHandler.java new file mode 100644 index 000000000..390efbe53 --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/AbstractMessageDisplayHandler.java @@ -0,0 +1,22 @@ +package co.chatsdk.ui.chat.handlers; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; + +import co.chatsdk.core.interfaces.MessageDisplayHandler; +import co.chatsdk.ui.R; + +public abstract class AbstractMessageDisplayHandler implements MessageDisplayHandler { + + protected View row (boolean isReply, Activity activity) { + View row; + LayoutInflater inflater = LayoutInflater.from(activity); + if(isReply) { + row = inflater.inflate(R.layout.chat_sdk_row_message_reply , null); + } else { + row = inflater.inflate(R.layout.chat_sdk_row_message_me , null); + } + return row; + } +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/ImageMessageDisplayHandler.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/ImageMessageDisplayHandler.java new file mode 100644 index 000000000..bc0f35fac --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/ImageMessageDisplayHandler.java @@ -0,0 +1,30 @@ +package co.chatsdk.ui.chat.handlers; + +import android.app.Activity; +import android.content.Context; +import android.view.View; + +import co.chatsdk.core.base.AbstractMessageViewHolder; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.session.ChatSDK; +import co.chatsdk.core.types.MessageType; +import co.chatsdk.ui.R; +import co.chatsdk.ui.chat.viewholder.ImageMessageViewHolder; + +public class ImageMessageDisplayHandler extends AbstractMessageDisplayHandler { + @Override + public void updateMessageCellView(Message message, AbstractMessageViewHolder viewHolder, Context context) { + + } + + @Override + public String displayName(Message message) { + return ChatSDK.shared().context().getString(R.string.image_message); + } + + @Override + public AbstractMessageViewHolder newViewHolder(boolean isReply, Activity activity) { + View row = row(isReply, activity); + return new ImageMessageViewHolder(row, activity); + } +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/LocationMessageDisplayHandler.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/LocationMessageDisplayHandler.java new file mode 100644 index 000000000..f5e703da7 --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/LocationMessageDisplayHandler.java @@ -0,0 +1,30 @@ +package co.chatsdk.ui.chat.handlers; + +import android.app.Activity; +import android.content.Context; +import android.view.View; + +import co.chatsdk.core.base.AbstractMessageViewHolder; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.session.ChatSDK; +import co.chatsdk.core.types.MessageType; +import co.chatsdk.ui.R; +import co.chatsdk.ui.chat.viewholder.LocationMessageViewHolder; + +public class LocationMessageDisplayHandler extends AbstractMessageDisplayHandler { + @Override + public void updateMessageCellView(Message message, AbstractMessageViewHolder viewHolder, Context context) { + + } + + @Override + public String displayName(Message message) { + return ChatSDK.shared().context().getString(R.string.location_message); + } + + @Override + public AbstractMessageViewHolder newViewHolder(boolean isReply, Activity activity) { + View row = row(isReply, activity); + return new LocationMessageViewHolder(row, activity); + } +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/TextMessageDisplayHandler.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/TextMessageDisplayHandler.java new file mode 100644 index 000000000..4b72f812c --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/handlers/TextMessageDisplayHandler.java @@ -0,0 +1,29 @@ +package co.chatsdk.ui.chat.handlers; + +import android.app.Activity; +import android.content.Context; +import android.view.View; + +import co.chatsdk.core.base.AbstractMessageViewHolder; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.types.MessageType; +import co.chatsdk.ui.chat.viewholder.TextMessageViewHolder; + +public class TextMessageDisplayHandler extends AbstractMessageDisplayHandler { + + @Override + public void updateMessageCellView(Message message, AbstractMessageViewHolder viewHolder, Context context) { + + } + + @Override + public String displayName(Message message) { + return message.getText(); + } + + @Override + public AbstractMessageViewHolder newViewHolder(boolean isReply, Activity activity) { + View row = row(isReply, activity); + return new TextMessageViewHolder(row, activity); + } +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/ImageMessageViewHolder.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/ImageMessageViewHolder.java new file mode 100644 index 000000000..6bc394713 --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/ImageMessageViewHolder.java @@ -0,0 +1,66 @@ +package co.chatsdk.ui.chat.viewholder; + +import android.app.Activity; +import android.net.Uri; +import android.view.View; + +import com.facebook.drawee.backends.pipeline.Fresco; +import com.facebook.imagepipeline.common.ResizeOptions; +import com.facebook.imagepipeline.request.ImageRequest; +import com.facebook.imagepipeline.request.ImageRequestBuilder; +import com.google.android.gms.maps.model.LatLng; + +import co.chatsdk.core.dao.Keys; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.types.MessageType; +import co.chatsdk.core.utils.GoogleUtils; +import co.chatsdk.ui.R; +import co.chatsdk.ui.chat.BaseMessageViewHolder; +import co.chatsdk.ui.chat.ImageMessageOnClickHandler; +import co.chatsdk.ui.chat.LocationMessageOnClickHandler; +import timber.log.Timber; + +public class ImageMessageViewHolder extends BaseMessageViewHolder { + public ImageMessageViewHolder(View itemView, Activity activity) { + super(itemView, activity); + } + + @Override + public void setMessage(Message message) { + super.setMessage(message); + + setImageHidden(false); + + int viewWidth = maxWidth(); + int viewHeight = maxHeight(); + + String url = getImageURL(); + + if (url != null && url.length() > 0) { + ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url)) + .setResizeOptions(new ResizeOptions(viewWidth, viewHeight)) + .build(); + + messageImageView.setController( + Fresco.newDraweeControllerBuilder() + .setOldController(messageImageView.getController()) + .setImageRequest(request) + .build()); + } else { + // Loads the placeholder + messageImageView.setActualImageResource(R.drawable.icn_200_image_message_loading); + } + } + + @Override + public void onClick (View v) { + super.onClick(v); + if (message != null) { + ImageMessageOnClickHandler.onClick(activity, v, getImageURL()); + } + } + + public String getImageURL () { + return message.stringForKey(Keys.MessageImageURL); + } +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/LocationMessageViewHolder.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/LocationMessageViewHolder.java new file mode 100644 index 000000000..1c616b8a0 --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/LocationMessageViewHolder.java @@ -0,0 +1,47 @@ +package co.chatsdk.ui.chat.viewholder; + +import android.app.Activity; +import android.view.View; + +import com.google.android.gms.maps.model.LatLng; + +import co.chatsdk.core.dao.Keys; +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.utils.GoogleUtils; +import co.chatsdk.ui.chat.BaseMessageViewHolder; +import co.chatsdk.ui.chat.LocationMessageOnClickHandler; + +public class LocationMessageViewHolder extends BaseMessageViewHolder { + public LocationMessageViewHolder(View itemView, Activity activity) { + super(itemView, activity); + } + + @Override + public void setMessage(Message message) { + super.setMessage(message); + + setImageHidden(false); + + int viewWidth = maxWidth(); + int viewHeight = maxHeight(); + + LatLng latLng = getLatLng(); + messageImageView.setImageURI(GoogleUtils.getMapImageURL(latLng, viewWidth, viewHeight)); + + } + + @Override + public void onClick (View v) { + super.onClick(v); + if (message != null) { + LocationMessageOnClickHandler.onClick(activity, getLatLng()); + } + } + + public LatLng getLatLng() { + double longitude = message.doubleForKey(Keys.MessageLongitude); + double latitude = message.doubleForKey(Keys.MessageLatitude); + return new LatLng(latitude, longitude); + } + +} diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/TextMessageViewHolder.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/TextMessageViewHolder.java new file mode 100644 index 000000000..4d929ebaa --- /dev/null +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/chat/viewholder/TextMessageViewHolder.java @@ -0,0 +1,25 @@ +package co.chatsdk.ui.chat.viewholder; + +import android.app.Activity; +import android.view.View; + +import co.chatsdk.core.dao.Message; +import co.chatsdk.core.types.MessageType; +import co.chatsdk.ui.chat.BaseMessageViewHolder; + +public class TextMessageViewHolder extends BaseMessageViewHolder { + + public TextMessageViewHolder(View itemView, Activity activity) { + super(itemView, activity); + } + + @Override + public void setMessage(Message message) { + super.setMessage(message); + + messageTextView.setText(message.getText() == null ? "" : message.getText()); + setBubbleHidden(false); + setTextHidden(false); + + } +} \ No newline at end of file diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/manager/BaseInterfaceAdapter.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/manager/BaseInterfaceAdapter.java index 37e3ef6c7..30d5a3fc4 100644 --- a/chat-sdk-ui/src/main/java/co/chatsdk/ui/manager/BaseInterfaceAdapter.java +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/manager/BaseInterfaceAdapter.java @@ -2,6 +2,7 @@ import android.content.Context; import android.content.Intent; + import androidx.fragment.app.Fragment; import androidx.appcompat.app.AppCompatActivity; @@ -12,10 +13,12 @@ import com.facebook.imagepipeline.listener.RequestListener; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import co.chatsdk.core.Tab; @@ -24,15 +27,19 @@ import co.chatsdk.core.interfaces.ChatOption; import co.chatsdk.core.interfaces.ChatOptionsDelegate; import co.chatsdk.core.interfaces.ChatOptionsHandler; -import co.chatsdk.core.interfaces.CustomMessageHandler; +import co.chatsdk.core.interfaces.MessageDisplayHandler; import co.chatsdk.core.interfaces.InterfaceAdapter; import co.chatsdk.core.interfaces.LocalNotificationHandler; import co.chatsdk.core.session.ChatSDK; import co.chatsdk.core.session.InterfaceManager; +import co.chatsdk.core.types.MessageType; import co.chatsdk.core.types.SearchActivityType; import co.chatsdk.core.utils.NotificationDisplayHandler; import co.chatsdk.ui.R; import co.chatsdk.ui.chat.ChatActivity; +import co.chatsdk.ui.chat.handlers.ImageMessageDisplayHandler; +import co.chatsdk.ui.chat.handlers.LocationMessageDisplayHandler; +import co.chatsdk.ui.chat.handlers.TextMessageDisplayHandler; import co.chatsdk.ui.chat.options.DialogChatOptionsHandler; import co.chatsdk.ui.chat.options.LocationChatOption; import co.chatsdk.ui.chat.options.MediaChatOption; @@ -53,7 +60,7 @@ public class BaseInterfaceAdapter implements InterfaceAdapter { public List searchActivities = new ArrayList<>(); public List chatOptions = new ArrayList<>(); public ChatOptionsHandler chatOptionsHandler = null; - public List customMessageHandlers = new ArrayList<>(); + public Map messageHandlers = new HashMap<>(); public boolean defaultChatOptionsAdded = false; public LocalNotificationHandler localNotificationHandler; public NotificationDisplayHandler notificationDisplayHandler; @@ -79,6 +86,9 @@ public BaseInterfaceAdapter (Context context) { Fresco.initialize(context, config); // FLog.setMinimumLoggingLevel(FLog.VERBOSE); + setMessageHandler(new TextMessageDisplayHandler(), new MessageType(MessageType.Text)); + setMessageHandler(new ImageMessageDisplayHandler(), new MessageType(MessageType.Image)); + setMessageHandler(new LocationMessageDisplayHandler(), new MessageType(MessageType.Location)); } @@ -317,22 +327,26 @@ public ChatOptionsHandler getChatOptionsHandler(ChatOptionsDelegate delegate) { } @Override - public void addCustomMessageHandler(CustomMessageHandler handler) { - if(!customMessageHandlers.contains(handler)) { - customMessageHandlers.add(handler); - } + public void setMessageHandler(MessageDisplayHandler handler, MessageType type) { + messageHandlers.put(type.value(), handler); } @Override - public void removeCustomMessageHandler(CustomMessageHandler handler) { - if(customMessageHandlers.contains(handler)) { - customMessageHandlers.remove(handler); + public void removeMessageHandler(MessageType type) { + MessageDisplayHandler handler = getMessageHandler(type); + if (handler != null) { + messageHandlers.remove(handler); } } @Override - public List getCustomMessageHandlers() { - return customMessageHandlers; + public Collection getMessageHandlers() { + return messageHandlers.values(); + } + + @Override + public MessageDisplayHandler getMessageHandler(MessageType type) { + return messageHandlers.get(type.value()); } @Override diff --git a/chat-sdk-ui/src/main/java/co/chatsdk/ui/threads/ThreadsListAdapter.java b/chat-sdk-ui/src/main/java/co/chatsdk/ui/threads/ThreadsListAdapter.java index e63099e2a..61ab6463c 100644 --- a/chat-sdk-ui/src/main/java/co/chatsdk/ui/threads/ThreadsListAdapter.java +++ b/chat-sdk-ui/src/main/java/co/chatsdk/ui/threads/ThreadsListAdapter.java @@ -116,6 +116,7 @@ public String getLastMessageDateAsString (Date date) { public String getLastMessageText (Message lastMessage) { String messageText = Strings.t(R.string.no_messages); if (lastMessage != null) { + messageText = Strings.payloadAsString(lastMessage); } return messageText; diff --git a/gradle.properties b/gradle.properties index e559785d4..0d6d5a64c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx3000m +org.gradle.jvmargs=-Xmx6g # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit @@ -24,7 +24,7 @@ ANDROID_BUILD_TARGET_SDK_VERSION = 25 ANDROID_COMPILE_SDK_VERSION = 28 ANDROID_SUPPORT_VERSION = 28.0.0 -CHAT_SDK_VERSION = 4.4.9 +CHAT_SDK_VERSION = 4.5.7 CHAT_SDK_BUILD_NUMBER = 040409 CHAT_SDK_GROUP = co.chatsdk.chatsdk diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cae47cbcd..d13ac1958 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip