├── .gitignore
├── LICENSE.md
├── README.md
├── app
├── .gitignore
├── build.gradle
├── debug.keystore
├── google-services.json
├── keystore
│ ├── debug.keystore
│ └── debug.keystore.properties
├── proguard-rules.txt
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sdk
│ │ └── chat
│ │ ├── MainApplication.java
│ │ └── StartActivity.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── values-es
│ └── strings.xml
│ ├── values-nl
│ └── strings.xml
│ ├── values-pt
│ └── strings.xml
│ ├── values-zh
│ └── strings.xml
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── demo
├── .gitignore
├── build.gradle
├── google-services.json
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sdk
│ │ └── chat
│ │ └── demo
│ │ ├── ChatActivity.java
│ │ ├── MainApplication.java
│ │ ├── Message.java
│ │ ├── MessageMemoryStore.java
│ │ ├── StartActivity.java
│ │ ├── Thread.java
│ │ └── User.java
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── layout
│ ├── activity_chat.xml
│ └── activity_start.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── firestream-firestore
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── firestream
│ │ └── chat
│ │ └── firestore
│ │ ├── FirestoreChatHandler.java
│ │ ├── FirestoreCoreHandler.java
│ │ ├── FirestoreService.java
│ │ └── Ref.java
│ └── res
│ └── values
│ └── strings.xml
├── firestream-realtime
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── firestream
│ │ └── chat
│ │ └── realtime
│ │ ├── RealtimeChatHandler.java
│ │ ├── RealtimeCoreHandler.java
│ │ ├── RealtimeService.java
│ │ └── Ref.java
│ └── res
│ └── values
│ └── strings.xml
├── firestream
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── firestream
│ │ └── chat
│ │ ├── FireStream.java
│ │ ├── FirestreamConfig.java
│ │ ├── chat
│ │ ├── AbstractChat.java
│ │ ├── Chat.java
│ │ ├── Events.java
│ │ ├── Meta.java
│ │ └── User.java
│ │ ├── events
│ │ ├── ConnectionEvent.java
│ │ ├── ListData.java
│ │ └── UserEvent.java
│ │ ├── filter
│ │ └── Filter.java
│ │ ├── firebase
│ │ ├── rx
│ │ │ └── MultiRelay.java
│ │ └── service
│ │ │ ├── FirebaseChatHandler.java
│ │ │ ├── FirebaseCoreHandler.java
│ │ │ ├── FirebaseService.java
│ │ │ ├── Keys.java
│ │ │ ├── Path.java
│ │ │ └── Paths.java
│ │ ├── interfaces
│ │ ├── IAbstractChat.java
│ │ ├── IChat.java
│ │ └── IFireStream.java
│ │ ├── message
│ │ ├── BaseMessage.java
│ │ ├── Body.java
│ │ ├── CustomMessage.java
│ │ ├── DeliveryReceipt.java
│ │ ├── Invitation.java
│ │ ├── Message.java
│ │ ├── Presence.java
│ │ ├── Sendable.java
│ │ ├── TextMessage.java
│ │ └── TypingState.java
│ │ ├── namespace
│ │ ├── Fire.java
│ │ ├── FireStreamMessage.java
│ │ └── FireStreamUser.java
│ │ ├── test
│ │ ├── Result.java
│ │ ├── Test.java
│ │ ├── TestScript.java
│ │ ├── chat
│ │ │ ├── CreateChatTest.java
│ │ │ ├── MessageChatTest.java
│ │ │ └── ModifyChatTest.java
│ │ └── contact
│ │ │ ├── AddContactTest.java
│ │ │ ├── DeleteContactTest.java
│ │ │ ├── GetContactAddedTest.java
│ │ │ └── GetContactRemovedTest.java
│ │ ├── types
│ │ ├── BaseType.java
│ │ ├── ContactType.java
│ │ ├── DeliveryReceiptType.java
│ │ ├── InvitationType.java
│ │ ├── PresenceType.java
│ │ ├── RoleType.java
│ │ ├── SendableType.java
│ │ └── TypingStateType.java
│ │ └── util
│ │ ├── Typing.java
│ │ └── TypingMap.java
│ └── res
│ └── values
│ └── strings.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── graphics
├── android-phone-images.png
├── chat-sdk-play.png
└── en_badge_web_generic.png
├── issue_template.md
├── sdk-guru-common
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sdk
│ │ └── guru
│ │ └── common
│ │ ├── BaseConfig.java
│ │ ├── BiAction.java
│ │ ├── DisposableMap.java
│ │ ├── Event.java
│ │ ├── EventType.java
│ │ ├── Optional.java
│ │ └── RX.java
│ └── res
│ └── values
│ └── strings.xml
├── sdk-guru-firestore
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sdk
│ │ └── guru
│ │ └── firestore
│ │ └── RXFirestore.java
│ └── res
│ └── values
│ └── strings.xml
├── sdk-guru-licensing
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sdk
│ │ └── chat
│ │ └── licensing
│ │ └── Report.java
│ └── res
│ └── values
│ └── strings.xml
├── sdk-guru-realtime
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sdk
│ │ └── guru
│ │ └── realtime
│ │ ├── DocumentChange.java
│ │ ├── Generic.java
│ │ ├── RXRealtime.java
│ │ ├── RealtimeEventListener.java
│ │ └── RealtimeReferenceManager.java
│ └── res
│ └── values
│ └── strings.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local configuration files
2 | /local.properties
3 | /.idea/workspace.xml
4 | .DS_Store
5 |
6 | # Generated files
7 | **/bin/
8 | **/gen/
9 | **/out/
10 | **/build/
11 | .project
12 | .classpath
13 | org.eclipse.buildship.core.prefs
14 |
15 | #Gradle files
16 | .gradle/
17 | build/
18 |
19 | # Files for the Dalvik VM
20 | *.dex
21 |
22 | # Intellij
23 | *.iml
24 | .idea
25 | /out/
26 | /captures
27 | app/release
28 |
29 | # Java .class files
30 | **/*.class
31 | *.diff
32 |
33 | # Premium Modules
34 | chat-sdk-audio-message
35 | chat-sdk-contact-book
36 | chat-sdk-file-message
37 | chat-sdk-firebase-blocking
38 | chat-sdk-firebase-nearby-users
39 | chat-sdk-read-receipts
40 | chat-sdk-sticker-message
41 | chat-sdk-typing-indicator
42 | chat-sdk-video-message
43 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /release
3 | /development
4 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'com.google.gms.google-services'
3 | apply plugin: 'com.google.firebase.crashlytics'
4 | apply plugin: 'com.google.firebase.firebase-perf'
5 |
6 | android {
7 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
8 |
9 | defaultConfig {
10 | applicationId "sdk.chat.android.live"
11 |
12 | multiDexEnabled = true
13 | minSdkVersion Integer.parseInt(project.MIN_SDK)
14 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
15 |
16 | versionName CHAT_SDK_VERSION
17 | versionCode CHAT_SDK_BUILD_NUMBER as int
18 | }
19 |
20 | signingConfigs {
21 | debug {
22 | keyAlias 'androiddebugkey'
23 | keyPassword 'D3bug123'
24 | storeFile file('debug.keystore')
25 | storePassword 'D3bug123'
26 | }
27 | }
28 |
29 | if(project.hasProperty('devBuild')) {
30 | splits.abi.enable = false
31 | splits.density.enable = false
32 | aaptOptions.cruncherEnabled = false
33 | }
34 |
35 | buildTypes {
36 | // release {
37 | // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
38 | // signingConfig signingConfigs.release
39 | // debuggable false
40 | // jniDebuggable false
41 | // zipAlignEnabled true
42 | // }
43 | debug {
44 | debuggable true
45 | jniDebuggable true
46 | ext.alwaysUpdateBuildId = false
47 | }
48 | }
49 |
50 | packagingOptions {
51 | exclude 'META-INF/DEPENDENCIES'
52 | exclude 'META-INF/NOTICE'
53 | exclude 'META-INF/LICENSE'
54 | exclude 'META-INF/LICENSE.txt'
55 | exclude 'META-INF/NOTICE.txt'
56 | }
57 |
58 | dexOptions {
59 | javaMaxHeapSize "6g"
60 | preDexLibraries = false
61 | }
62 |
63 | flavorDimensions "default"
64 | productFlavors {
65 | development {
66 | dimension "default"
67 | minSdkVersion 21
68 | resConfigs("en", "xxhdpi")
69 | }
70 | }
71 |
72 | compileOptions {
73 | sourceCompatibility JavaVersion.VERSION_1_8
74 | targetCompatibility JavaVersion.VERSION_1_8
75 | }
76 |
77 | lintOptions {
78 | abortOnError false
79 | checkReleaseBuilds false
80 | lintConfig file('lint.xml')
81 | }
82 | }
83 |
84 | dependencies {
85 | implementation project(':firestream')
86 | implementation project(':firestream-realtime')
87 | implementation project(':firestream-firestore')
88 |
89 | api "com.google.android.material:material:$materialVersion"
90 | implementation "com.firebaseui:firebase-ui-auth:$firebaseUiVersion"
91 |
92 | }
93 |
94 |
95 | task copyDependencies(type: Copy) {
96 | from configurations.compile
97 | into 'dependencies'
98 | }
99 |
--------------------------------------------------------------------------------
/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/app/debug.keystore
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "1088435112418",
4 | "firebase_url": "https://chat-sdk-v4.firebaseio.com",
5 | "project_id": "chat-sdk-v4",
6 | "storage_bucket": "chat-sdk-v4.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:1088435112418:android:813ea9bf20e0a13f5611bb",
12 | "android_client_info": {
13 | "package_name": "sdk.chat.android.live"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "1088435112418-900e65u7oloc6tvbf9cl9qv5fjctv4t7.apps.googleusercontent.com",
19 | "client_type": 1,
20 | "android_info": {
21 | "package_name": "sdk.chat.android.live",
22 | "certificate_hash": "e4e36b1e2f9ac7d7b8e867e08c94cb1dbfaaf9c4"
23 | }
24 | },
25 | {
26 | "client_id": "1088435112418-e3t77t8jl2ucs8efeqs72o696in8soui.apps.googleusercontent.com",
27 | "client_type": 3
28 | }
29 | ],
30 | "api_key": [
31 | {
32 | "current_key": "AIzaSyAf-dkxZw1m-mP_E-jpTvk1lFtGioev6m0"
33 | }
34 | ],
35 | "services": {
36 | "appinvite_service": {
37 | "other_platform_oauth_client": [
38 | {
39 | "client_id": "1088435112418-7gfr9061rqnlg5fj1d510unql3mu5qjp.apps.googleusercontent.com",
40 | "client_type": 3
41 | },
42 | {
43 | "client_id": "1088435112418-94j149s4i4q32u4m8s0dqt5ctdpfd235.apps.googleusercontent.com",
44 | "client_type": 2,
45 | "ios_info": {
46 | "bundle_id": "org.cocoapods.FireStream-Tests"
47 | }
48 | }
49 | ]
50 | }
51 | }
52 | }
53 | ],
54 | "configuration_version": "1"
55 | }
--------------------------------------------------------------------------------
/app/keystore/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/app/keystore/debug.keystore
--------------------------------------------------------------------------------
/app/keystore/debug.keystore.properties:
--------------------------------------------------------------------------------
1 | store.file=debug.keystore
2 | key.alias=androiddebugkey
3 | key.alias.password=android
4 | key.store.password=android
5 |
--------------------------------------------------------------------------------
/app/proguard-rules.txt:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in E:/Work/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the ProGuard
5 | # include property in project.properties.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView from JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | -dontwarn org.joda.convert.**
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/sdk/chat/MainApplication.java:
--------------------------------------------------------------------------------
1 | package sdk.chat;
2 |
3 | import android.app.Application;
4 |
5 | import com.google.firebase.auth.FirebaseAuth;
6 |
7 | import firestream.chat.firestore.FirestoreService;
8 | import firestream.chat.namespace.Fire;
9 | import firestream.chat.test.TestScript;
10 | import firestream.chat.types.ContactType;
11 |
12 | /**
13 | * Created by Ben Smiley on 6/8/2014.
14 | */
15 | //public class MainApplication extends MultiDexApplication {
16 | public class MainApplication extends Application {
17 |
18 | @Override
19 | public void onCreate() {
20 | super.onCreate();
21 |
22 | TestScript ts = new TestScript(new FirestoreService(), this, "firestream");
23 | ts.onFinish = () -> {
24 | Fire.stream().block(TestScript.testUser1()).subscribe();
25 | Fire.stream().addContact(TestScript.testUser1(), ContactType.contact()).subscribe();
26 | };
27 |
28 | FirebaseAuth.getInstance().addAuthStateListener(firebaseAuth -> {
29 | // We are connecting for the first time
30 | if (firebaseAuth.getCurrentUser() == null) {
31 | firebaseAuth.signInAnonymously().addOnCompleteListener(task -> {
32 |
33 | });
34 | }
35 | });
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/sdk/chat/StartActivity.java:
--------------------------------------------------------------------------------
1 | package sdk.chat;
2 |
3 | import android.app.Activity;
4 |
5 | public class StartActivity extends Activity {
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chat SDK
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-nl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chat SDK
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pt/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chat SDK
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chat SDK
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Firestream
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | import org.gradle.internal.os.OperatingSystem
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.6.3'
11 | classpath "com.google.gms:google-services:4.3.3"
12 | classpath 'com.novoda:bintray-release:0.9.2'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.71"
14 | classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1'
15 | classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
16 | classpath 'com.google.firebase:perf-plugin:1.3.1'
17 | }
18 | }
19 |
20 | ext {
21 | bintrayVersion = "1.8.4"
22 | mavenGradleVersion = "2.1"
23 | androidxAppcompatVersion = "1.1.0"
24 | androidxConstraintLayoutVersion = "2.0.0-beta5"
25 | androidxLifecycleExtensionsVersion = "2.2.0"
26 | androidxRecyclerViewVersion = "1.1.0"
27 | androidxMultidexVersion = "2.0.1"
28 | materialVersion = "1.1.0"
29 | playAuthVersion = "17.0.0"
30 | playMapsVersion = "17.0.0"
31 | playLocationVersion = "17.0.0"
32 | firebaseUiVersion = "6.2.0"
33 | firebaseCoreVersion = "17.4.1"
34 | firebaseDatabaseVersion = "19.3.0"
35 | firebaseFirestoreVersion = "21.4.3"
36 | firebaseAuthVersion = "19.3.1"
37 | firebaseStorageVersion = "19.1.1"
38 | firebaseMessagingVersion = "20.1.7"
39 | firebaseFunctionsVersion = "19.0.2"
40 | firebaseIIDVersion = "18.0.0"
41 | firebasePerformanceVersion = "19.0.7"
42 | firebaseCrashlyticsVersion = "17.0.0"
43 | firebaseAnalyticsVersion = "17.4.1"
44 | greenDaoVersion = "3.2.2"
45 | frescoVersion = "1.13.0"
46 | rxJavaVersion = "2.2.17"
47 | rxAndroidVersion = "2.1.1"
48 | rxRelayVersion = "2.1.1"
49 | rxQueueVersion = "2.0.0"
50 | compressorVersion = "2.1.0"
51 | okHttpVersion = "3.11.0"
52 | okHttpDownloaderVersion = "1.1.0"
53 | prettyTimeVersion = "4.0.1.Final"
54 | imageCropperVersion = "2.8.0"
55 | photoViewVersion = "2.3.0"
56 | androidDatabaseSQLCipher = "4.3.0"
57 | matisseVersion = "0.5.3-beta3b1"
58 | chatKit = "0.3.3b11"
59 | shapeImageViewVersion = "0.9.+@aar"
60 | circleImageViewVersion = "3.1.0"
61 | dexterVersion = "6.0.2"
62 | tinyLogVersion = "1.3.6"
63 | butterKnifeVersion = "10.2.1"
64 |
65 | iconicsVersion = "5.0.0-a01"
66 | materialDrawerVersion = "8.0.0-a07"
67 | // iconicsMaterialDesignIconsVersion = "5.0.1.0-kotlin@aar"
68 | iconicsGoogleMaterialIconsVersion = "3.0.1.4.original-kotlin@aar"
69 | iconicsFontAwesomeTypefaceVersion = "5.3.1.2-kotlin@aar"
70 | materialSearchVersion = "1.4.0"
71 | materialSpinnerVersion = "1.3.1"
72 | keyboardVisibilityEventVersion = "3.0.0-RC2"
73 | androidAudioRecorderVersion = "0.3.0"
74 | glideVersion = "4.11.0"
75 | exoplayerVersion = "2.11.3"
76 | androidAudioConverterVersion = "0.0.8"
77 |
78 | // Used by file messages
79 | androidNetworkingVersion = "1.0.2"
80 | pdfiumVersion = "1.9.0"
81 |
82 | smackVersion = "4.3.4"
83 |
84 | }
85 |
86 | allprojects {
87 | if (OperatingSystem.current().isWindows()) {
88 | buildDir = "C:/tmp/${rootProject.name}/${project.name}"
89 | }
90 | repositories {
91 | google()
92 | maven { url "https://jitpack.io" }
93 | jcenter()
94 | maven { url "http://dl.bintray.com/chat-sdk/chat-sdk-android" }
95 | }
96 | }
97 |
98 | subprojects {
99 | tasks.withType(Javadoc).all { enabled = false }
100 | }
101 |
102 |
103 |
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'com.google.gms.google-services'
3 | apply plugin: 'com.jakewharton.butterknife'
4 |
5 | android {
6 |
7 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
8 |
9 | defaultConfig {
10 | applicationId "sdk.chat.android.live"
11 |
12 | multiDexEnabled = true
13 | minSdkVersion Integer.parseInt(project.MIN_SDK)
14 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
15 |
16 | versionName CHAT_SDK_VERSION
17 | versionCode CHAT_SDK_BUILD_NUMBER as int
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 |
27 | compileOptions {
28 | sourceCompatibility JavaVersion.VERSION_1_8
29 | targetCompatibility JavaVersion.VERSION_1_8
30 | }
31 |
32 | }
33 |
34 | dependencies {
35 | implementation fileTree(dir: 'libs', include: ['*.jar'])
36 |
37 | implementation "com.firebaseui:firebase-ui-auth:$firebaseUiVersion"
38 | implementation 'com.github.stfalcon:chatkit:0.3.3'
39 |
40 | implementation "com.jakewharton:butterknife:$butterKnifeVersion"
41 | annotationProcessor "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
42 | implementation 'androidmads.library.qrgenearator:QRGenearator:1.0.4'
43 | api "androidx.constraintlayout:constraintlayout:$androidxConstraintLayoutVersion"
44 | implementation 'com.github.blikoon:QRCodeScanner:0.1.2'
45 | implementation "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion"
46 | implementation "com.karumi:dexter:$dexterVersion"
47 |
48 | implementation project(':firestream')
49 | implementation project(':firestream-realtime')
50 | implementation project(':firestream-firestore')
51 |
52 |
53 | // implementation "sdk.chat:firestream:5.0.4"
54 | // implementation "sdk.chat:firestream-realtime:5.0.4"
55 | // implementation "sdk.chat:firestream-firestore:5.0.4"
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/demo/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "1088435112418",
4 | "firebase_url": "https://chat-sdk-v4.firebaseio.com",
5 | "project_id": "chat-sdk-v4",
6 | "storage_bucket": "chat-sdk-v4.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:1088435112418:android:813ea9bf20e0a13f5611bb",
12 | "android_client_info": {
13 | "package_name": "sdk.chat.android.live"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "1088435112418-900e65u7oloc6tvbf9cl9qv5fjctv4t7.apps.googleusercontent.com",
19 | "client_type": 1,
20 | "android_info": {
21 | "package_name": "sdk.chat.android.live",
22 | "certificate_hash": "e4e36b1e2f9ac7d7b8e867e08c94cb1dbfaaf9c4"
23 | }
24 | },
25 | {
26 | "client_id": "1088435112418-e3t77t8jl2ucs8efeqs72o696in8soui.apps.googleusercontent.com",
27 | "client_type": 3
28 | }
29 | ],
30 | "api_key": [
31 | {
32 | "current_key": "AIzaSyAf-dkxZw1m-mP_E-jpTvk1lFtGioev6m0"
33 | }
34 | ],
35 | "services": {
36 | "appinvite_service": {
37 | "other_platform_oauth_client": [
38 | {
39 | "client_id": "1088435112418-7gfr9061rqnlg5fj1d510unql3mu5qjp.apps.googleusercontent.com",
40 | "client_type": 3
41 | },
42 | {
43 | "client_id": "1088435112418-94j149s4i4q32u4m8s0dqt5ctdpfd235.apps.googleusercontent.com",
44 | "client_type": 2,
45 | "ios_info": {
46 | "bundle_id": "org.cocoapods.FireStream-Tests"
47 | }
48 | }
49 | ]
50 | }
51 | }
52 | }
53 | ],
54 | "configuration_version": "1"
55 | }
--------------------------------------------------------------------------------
/demo/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/demo/src/main/java/sdk/chat/demo/ChatActivity.java:
--------------------------------------------------------------------------------
1 | package sdk.chat.demo;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.widget.ImageView;
6 |
7 | import androidx.annotation.Nullable;
8 |
9 | import com.stfalcon.chatkit.commons.ImageLoader;
10 | import com.stfalcon.chatkit.dialogs.DialogsListAdapter;
11 | import com.stfalcon.chatkit.messages.MessageInput;
12 | import com.stfalcon.chatkit.messages.MessagesList;
13 | import com.stfalcon.chatkit.messages.MessagesListAdapter;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | import androidmads.library.qrgenearator.QRGContents;
19 | import androidmads.library.qrgenearator.QRGEncoder;
20 | import butterknife.BindView;
21 | import butterknife.ButterKnife;
22 | import firestream.chat.message.Body;
23 | import firestream.chat.message.Sendable;
24 | import firestream.chat.message.TextMessage;
25 | import firestream.chat.namespace.Fire;
26 | import io.reactivex.disposables.Disposable;
27 | import io.reactivex.functions.Consumer;
28 | import sdk.guru.common.DisposableMap;
29 | import sdk.guru.common.Event;
30 | import sdk.guru.common.RX;
31 |
32 | import static firestream.chat.message.TextMessage.TextKey;
33 |
34 | public class ChatActivity extends Activity {
35 |
36 | @BindView(R.id.messagesList)
37 | MessagesList messagesList;
38 | @BindView(R.id.input)
39 | MessageInput input;
40 |
41 | MessagesListAdapter adapter;
42 |
43 | String otherUserId;
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 |
49 | otherUserId = getIntent().getStringExtra("id");
50 | if (otherUserId == null || otherUserId.isEmpty()) {
51 | finish();
52 | }
53 |
54 | setContentView(R.layout.activity_chat);
55 | ButterKnife.bind(this);
56 |
57 | adapter = new MessagesListAdapter<>(Fire.stream().currentUserId(), new ImageLoader() {
58 | @Override
59 | public void loadImage(ImageView imageView, @Nullable String url, @Nullable Object payload) {
60 | QRGEncoder qrgEncoder = new QRGEncoder(url, null, QRGContents.Type.TEXT, 200);
61 | imageView.setImageBitmap(qrgEncoder.getBitmap());
62 | }
63 | });
64 | messagesList.setAdapter(adapter);
65 |
66 | input.setInputListener(input -> {
67 | //validate and send message
68 | Fire.stream().sendMessageWithText(otherUserId, input.toString(), s -> {
69 | Sendable sendable = new Sendable(s, Fire.stream().currentUserId());
70 | TextMessage message = TextMessage.fromSendable(sendable);
71 | message.getBody().put(TextKey, input.toString());
72 | MessageMemoryStore.instance.addMessage(otherUserId, message);
73 | RX.main().scheduleDirect(this::reload);
74 | }).subscribe();
75 | return true;
76 | });
77 |
78 | Disposable d = Fire.stream().getSendableEvents().getMessages().observeOn(RX.main()).subscribe(messageEvent -> {
79 | if (messageEvent.isAdded()) {
80 | MessageMemoryStore.instance.addMessage(otherUserId, messageEvent.get());
81 | }
82 | reload();
83 | });
84 |
85 | reload();
86 |
87 | }
88 |
89 | public void reload() {
90 | adapter.clear();
91 | for (Sendable s: MessageMemoryStore.instance.sendablesForUser(otherUserId)) {
92 | adapter.addToStart(new Message(s), true);
93 | }
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/demo/src/main/java/sdk/chat/demo/MainApplication.java:
--------------------------------------------------------------------------------
1 | package sdk.chat.demo;
2 |
3 | import android.app.Application;
4 |
5 | import firestream.chat.FirestreamConfig;
6 | import firestream.chat.firestore.FirestoreService;
7 | import firestream.chat.namespace.Fire;
8 | import sdk.guru.common.DisposableMap;
9 |
10 | /**
11 | * Created by Ben Smiley on 6/8/2014.
12 | */
13 | //public class MainApplication extends MultiDexApplication {
14 | public class MainApplication extends Application {
15 |
16 | protected DisposableMap dm = new DisposableMap();
17 |
18 | @Override
19 | public void onCreate() {
20 | super.onCreate();
21 |
22 | Fire.stream().initialize(this, new FirestreamConfig(this).setRoot("firestream").setSandbox("demo"), new FirestoreService());
23 |
24 |
25 | // Fire.stream().sendMessageWithText("userId", "Hello World!");
26 | //
27 | // Disposable d = Fire.stream().getSendableEvents().getMessages().pastAndNewEvents().subscribe(messageEvent -> {
28 | // if (messageEvent.isAdded()) {
29 | // // Message received
30 | // String text = messageEvent.get().toTextMessage().getText();
31 | // Logger.debug(text);
32 | // }
33 | // if (messageEvent.isRemoved()) {
34 | // // Message removed
35 | // }
36 | // });
37 | //
38 | // // If you want to stop listening
39 | // d.dispose();
40 | //
41 | // // Get the current user's id
42 | // Fire.stream().currentUserId();
43 | //
44 | // // Create a new chat room
45 | // dm.add(Fire.stream().createChat("name", "url", new User("1"), new User("2")).subscribe(chat -> {
46 | //
47 | // // Send a message
48 | // chat.sendMessageWithText("Hello World!");
49 | //
50 | // // Add a user
51 | // chat.addUser(true, new User("3")).subscribe();
52 | //
53 | // // Make a user an admin
54 | // chat.setRole(new User("2"), RoleType.admin()).subscribe();
55 | //
56 | // }));
57 | //
58 | // // Listen for new chat rooms we have been added to
59 | // dm.add(Fire.stream().getChatEvents().pastAndNewEvents().subscribe(chatEvent -> {
60 | // if (chatEvent.isAdded()) {
61 | // IChat chat = chatEvent.get();
62 | //
63 | // // Get a message listener
64 | // chat.manage(chat.getSendableEvents().getMessages().pastAndNewEvents().subscribe(messageEvent -> {
65 | // String text = messageEvent.get().toTextMessage().getText();
66 | // Logger.debug(text);
67 | // }));
68 | // }
69 | // }));
70 |
71 |
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/demo/src/main/java/sdk/chat/demo/Message.java:
--------------------------------------------------------------------------------
1 | package sdk.chat.demo;
2 |
3 | import com.stfalcon.chatkit.commons.models.IMessage;
4 | import com.stfalcon.chatkit.commons.models.IUser;
5 |
6 | import java.util.Date;
7 |
8 | import firestream.chat.message.Sendable;
9 |
10 | public class Message implements IMessage {
11 |
12 | Sendable sendable;
13 |
14 | public Message(Sendable sendable) {
15 | this.sendable = sendable;
16 | }
17 |
18 | @Override
19 | public String getId() {
20 | return sendable.getId();
21 | }
22 |
23 | @Override
24 | public String getText() {
25 | return sendable.toTextMessage().getText();
26 | }
27 |
28 | @Override
29 | public IUser getUser() {
30 | return new User(sendable.getFrom());
31 | }
32 |
33 | @Override
34 | public Date getCreatedAt() {
35 | return sendable.getDate();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/demo/src/main/java/sdk/chat/demo/MessageMemoryStore.java:
--------------------------------------------------------------------------------
1 | package sdk.chat.demo;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | import firestream.chat.message.Sendable;
9 |
10 | public class MessageMemoryStore {
11 |
12 | public static final MessageMemoryStore instance = new MessageMemoryStore();
13 | Map> messages = new HashMap<>();
14 |
15 | public void addMessage(String userId, Sendable sendable) {
16 | List list = messages.get(userId);
17 | if (list == null) {
18 | list = new ArrayList<>();
19 | messages.put(userId, list);
20 | }
21 | for (Sendable s: list) {
22 | if (s.getId().equals(sendable.getId())) {
23 | return;
24 | }
25 | }
26 | list.add(sendable);
27 | }
28 |
29 | public List sendablesForUser(String userId) {
30 | List sendables = messages.get(userId);
31 | if (sendables == null) {
32 | return new ArrayList<>();
33 | }
34 | return messages.get(userId);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/demo/src/main/java/sdk/chat/demo/Thread.java:
--------------------------------------------------------------------------------
1 | package sdk.chat.demo;
2 |
3 | import com.stfalcon.chatkit.commons.models.IDialog;
4 | import com.stfalcon.chatkit.commons.models.IUser;
5 |
6 | import java.util.Arrays;
7 | import java.util.List;
8 |
9 | import firestream.chat.message.Sendable;
10 | import firestream.chat.namespace.Fire;
11 |
12 | public class Thread implements IDialog {
13 |
14 | String id;
15 | Message lastMessage;
16 |
17 | public Thread(String id) {
18 | this.id = id;
19 | }
20 |
21 |
22 | @Override
23 | public String getId() {
24 | return id;
25 | }
26 |
27 | @Override
28 | public String getDialogPhoto() {
29 | return id;
30 | }
31 |
32 | @Override
33 | public String getDialogName() {
34 | return id;
35 | }
36 |
37 | @Override
38 | public List extends IUser> getUsers() {
39 | return Arrays.asList(new User(id));
40 | }
41 |
42 | @Override
43 | public Message getLastMessage() {
44 | List sendables = MessageMemoryStore.instance.sendablesForUser(id);
45 | if (sendables != null && sendables.size() > 0) {
46 | return new Message(sendables.get(sendables.size() - 1));
47 | }
48 | return null;
49 | }
50 |
51 | @Override
52 | public void setLastMessage(Message message) {
53 | lastMessage = message;
54 | }
55 |
56 | @Override
57 | public int getUnreadCount() {
58 | return 0;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/demo/src/main/java/sdk/chat/demo/User.java:
--------------------------------------------------------------------------------
1 | package sdk.chat.demo;
2 |
3 | import com.stfalcon.chatkit.commons.models.IUser;
4 |
5 | public class User implements IUser {
6 |
7 | public User(String id) {
8 | this.id = id;
9 | }
10 |
11 | String id;
12 |
13 | @Override
14 | public String getId() {
15 | return id;
16 | }
17 |
18 | @Override
19 | public String getName() {
20 | return id;
21 | }
22 |
23 | @Override
24 | public String getAvatar() {
25 | return id;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
22 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_start.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
13 |
14 |
19 |
20 |
24 |
25 |
32 |
33 |
40 |
41 |
42 |
43 |
44 |
45 |
49 |
50 |
51 |
52 |
53 |
60 |
61 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Firestream Demo
3 |
4 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/firestream-firestore/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/firestream-firestore/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
6 |
7 | defaultConfig {
8 | minSdkVersion Integer.parseInt(project.MIN_SDK)
9 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
10 | }
11 |
12 | buildTypes {
13 | debug {
14 | minifyEnabled project.hasProperty('minifyDebug')
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | release {
18 | minifyEnabled project.hasProperty('minifyRelease')
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 |
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 |
28 | lintOptions {
29 | abortOnError false
30 | checkReleaseBuilds false
31 | lintConfig file('lint.xml')
32 | }
33 | }
34 |
35 | ext {
36 | libraryName = 'FireStreamFirestore'
37 | artifact = 'firestream-firestore'
38 | libraryDescription = 'FireStream: Messaging Framework for Firebase and Firestore'
39 | }
40 |
41 | publish {
42 | userOrg = BINTRAY_USER_ORG
43 | groupId = CHAT_SDK_GROUP
44 | artifactId = artifact
45 | repoName = BINTRAY_REPO
46 | publishVersion = CHAT_SDK_VERSION
47 | desc = libraryDescription
48 | licences = ["GPL-3.0"]
49 | uploadName = libraryName
50 | website = GIT_URL
51 | }
52 |
53 | dependencies {
54 | implementation fileTree(dir: 'libs', include: ['*.jar'])
55 | api project(':firestream')
56 | api project(':sdk-guru-firestore')
57 | }
58 |
--------------------------------------------------------------------------------
/firestream-firestore/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/firestream-firestore/consumer-rules.pro
--------------------------------------------------------------------------------
/firestream-firestore/proguard-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/firestream-firestore/proguard-rules.pro
--------------------------------------------------------------------------------
/firestream-firestore/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/firestream-firestore/src/main/java/firestream/chat/firestore/FirestoreChatHandler.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firestore;
2 |
3 | import com.google.firebase.firestore.DocumentSnapshot;
4 |
5 | import java.util.Date;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | import javax.annotation.Nullable;
10 |
11 | import firestream.chat.chat.Meta;
12 | import firestream.chat.chat.User;
13 | import firestream.chat.firebase.service.FirebaseChatHandler;
14 | import firestream.chat.firebase.service.Keys;
15 | import firestream.chat.firebase.service.Path;
16 | import firestream.chat.firebase.service.Paths;
17 | import io.reactivex.Completable;
18 | import io.reactivex.Observable;
19 | import io.reactivex.Single;
20 | import io.reactivex.functions.Consumer;
21 | import sdk.guru.firestore.RXFirestore;
22 |
23 | public class FirestoreChatHandler extends FirebaseChatHandler {
24 |
25 | @Override
26 | public Completable leaveChat(String chatId) {
27 | return new RXFirestore().delete(Ref.document(Paths.userGroupChatPath(chatId)));
28 | }
29 |
30 | @Override
31 | public Completable joinChat(String chatId) {
32 | return new RXFirestore().set(Ref.document(Paths.userGroupChatPath(chatId)), User.dateDataProvider().data(null));
33 | }
34 |
35 | public Completable setMetaField(String chatId, String key, Object value) {
36 | Path chatMetaPath = Paths.chatMetaPath(chatId);
37 | chatMetaPath.normalizeForDocument();
38 |
39 | return new RXFirestore().update(Ref.document(chatMetaPath), new HashMap() {{
40 | put(chatMetaPath.dotPath(key), value);
41 | }});
42 | }
43 |
44 | @Override
45 | public Observable metaOn(String chatId) {
46 | return new RXFirestore().on(Ref.document(Paths.chatPath(chatId))).map(snapshot -> {
47 | Meta meta = new Meta();
48 |
49 | String base = Keys.Meta + ".";
50 |
51 | meta.setName(snapshot.get(base + Keys.Name, String.class));
52 | meta.setCreated(snapshot.get(base + Keys.Created, Date.class, DocumentSnapshot.ServerTimestampBehavior.ESTIMATE));
53 | meta.setImageURL(snapshot.get(base + Keys.ImageURL, String.class));
54 |
55 | Map data = new HashMap<>();
56 |
57 | Object dataObject = snapshot.get(base + Keys.Data);
58 | if (dataObject instanceof HashMap) {
59 | Map dataMap = (HashMap) dataObject;
60 | for (Object key: dataMap.keySet()) {
61 | if (key instanceof String) {
62 | data.put((String) key, dataMap.get(key));
63 | }
64 | }
65 | }
66 | meta.setData(data);
67 |
68 | return meta;
69 | });
70 | }
71 |
72 | @Override
73 | public Single add(Map data, @Nullable Consumer newId) {
74 | return new RXFirestore().add(Ref.collection(Paths.chatsPath()), data, newId);
75 | }
76 |
77 | @Override
78 | public Completable delete(String chatId) {
79 | return new RXFirestore().delete(Ref.document(Paths.chatPath(chatId)));
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/firestream-firestore/src/main/java/firestream/chat/firestore/FirestoreService.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firestore;
2 |
3 | import firestream.chat.firebase.service.FirebaseService;
4 |
5 | public class FirestoreService extends FirebaseService {
6 |
7 | public FirestoreService() {
8 | core = new FirestoreCoreHandler();
9 | chat = new FirestoreChatHandler();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/firestream-firestore/src/main/java/firestream/chat/firestore/Ref.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firestore;
2 |
3 | import com.google.firebase.firestore.CollectionReference;
4 | import com.google.firebase.firestore.DocumentReference;
5 | import com.google.firebase.firestore.FirebaseFirestore;
6 |
7 | import firestream.chat.firebase.service.Path;
8 | import firestream.chat.namespace.Fire;
9 |
10 |
11 | public class Ref {
12 |
13 | public static CollectionReference collection(Path path) {
14 | Object ref = referenceFromPath(path);
15 | if (ref instanceof CollectionReference) {
16 | return (CollectionReference) ref;
17 | } else {
18 | Fire.internal().debug((Fire.internal().context().getString(R.string.error_mismatched_col_reference)));
19 | return null;
20 | }
21 | }
22 |
23 | public static DocumentReference document(Path path) {
24 | Object ref = referenceFromPath(path);
25 | if (ref instanceof DocumentReference) {
26 | return (DocumentReference) ref;
27 | } else {
28 | Fire.internal().debug(Fire.internal().context().getString(R.string.error_mismatched_doc_reference));
29 | return null;
30 | }
31 | }
32 |
33 | public static Object referenceFromPath(Path path) {
34 | Object ref = db().collection(path.first());
35 |
36 | for (int i = 1; i < path.size(); i++) {
37 | String component = path.get(i);
38 |
39 | if (ref instanceof DocumentReference) {
40 | ref = ((DocumentReference) ref).collection(component);
41 | } else {
42 | ref = ((CollectionReference) ref).document(component);
43 | }
44 | }
45 | return ref;
46 | }
47 |
48 | public static FirebaseFirestore db() {
49 | return FirebaseFirestore.getInstance();
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/firestream-firestore/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Firestream for Firestore
3 | Snapshot is null
4 | Firebase must be authenticated to connect
5 | You need to call FireStream.api().initialize(…)
6 | Null data returned
7 | No value present
8 | DocumentReference expected but path points to collection
9 | CollectionReference expected but path points to document
10 | You must be a group owner to perform this action
11 | You must be a group admin to perform this action
12 | You must be a group member to perform this action
13 | Write cancelled
14 | Invalid path, path can only contain letters, numbers and underscores
15 | Remove the other users before you can delete the group
16 |
17 | Owner
18 | Admin
19 | Member
20 | Watcher
21 | Banned
22 |
23 |
24 |
--------------------------------------------------------------------------------
/firestream-realtime/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/firestream-realtime/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
6 |
7 | defaultConfig {
8 | minSdkVersion Integer.parseInt(project.MIN_SDK)
9 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
10 | }
11 |
12 | buildTypes {
13 | debug {
14 | minifyEnabled project.hasProperty('minifyDebug')
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | release {
18 | minifyEnabled project.hasProperty('minifyRelease')
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 |
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 |
28 | lintOptions {
29 | abortOnError false
30 | checkReleaseBuilds false
31 | lintConfig file('lint.xml')
32 | }
33 | }
34 |
35 | ext {
36 | libraryName = 'FireStreamRealtime'
37 | artifact = 'firestream-realtime'
38 | libraryDescription = 'FireStream: Messaging Framework for Firebase and Firestore'
39 | }
40 |
41 | publish {
42 | userOrg = BINTRAY_USER_ORG
43 | groupId = CHAT_SDK_GROUP
44 | artifactId = artifact
45 | repoName = BINTRAY_REPO
46 | publishVersion = CHAT_SDK_VERSION
47 | desc = libraryDescription
48 | licences = ["GPL-3.0"]
49 | uploadName = libraryName
50 | website = GIT_URL
51 | }
52 |
53 | dependencies {
54 | implementation fileTree(dir: 'libs', include: ['*.jar'])
55 | api project(':firestream')
56 | api project(':sdk-guru-realtime')
57 | }
58 |
--------------------------------------------------------------------------------
/firestream-realtime/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/firestream-realtime/consumer-rules.pro
--------------------------------------------------------------------------------
/firestream-realtime/proguard-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/firestream-realtime/proguard-rules.pro
--------------------------------------------------------------------------------
/firestream-realtime/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/firestream-realtime/src/main/java/firestream/chat/realtime/RealtimeChatHandler.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.realtime;
2 |
3 | import androidx.annotation.Nullable;
4 |
5 | import com.google.firebase.database.DataSnapshot;
6 |
7 | import java.util.Date;
8 | import java.util.Map;
9 |
10 | import firestream.chat.chat.Meta;
11 | import firestream.chat.chat.User;
12 | import firestream.chat.firebase.service.FirebaseChatHandler;
13 | import firestream.chat.firebase.service.Keys;
14 | import firestream.chat.firebase.service.Paths;
15 | import io.reactivex.Completable;
16 | import io.reactivex.Maybe;
17 | import io.reactivex.Observable;
18 | import io.reactivex.Single;
19 | import io.reactivex.functions.Consumer;
20 | import sdk.guru.realtime.Generic;
21 | import sdk.guru.realtime.RXRealtime;
22 |
23 | public class RealtimeChatHandler extends FirebaseChatHandler {
24 |
25 | @Override
26 | public Completable leaveChat(String chatId) {
27 | return new RXRealtime().delete(Ref.get(Paths.userGroupChatPath(chatId)));
28 | }
29 |
30 | @Override
31 | public Completable joinChat(String chatId) {
32 | return new RXRealtime().set(Ref.get(Paths.userGroupChatPath(chatId)), User.dateDataProvider().data(null));
33 | }
34 |
35 | @Override
36 | public Completable setMetaField(String chatId, String key, Object value) {
37 | return new RXRealtime().set(Ref.get(Paths.chatMetaPath(chatId).child(key)), value);
38 | }
39 |
40 | @Override
41 | public Observable metaOn(String chatId) {
42 | return new RXRealtime().on(Ref.get(Paths.chatPath(chatId))).flatMapMaybe(change -> {
43 | DataSnapshot snapshot = change.getSnapshot();
44 | if (snapshot.hasChild(Keys.Meta)) {
45 | snapshot = snapshot.child(Keys.Meta);
46 |
47 | Meta meta = new Meta();
48 |
49 | if (snapshot.hasChild(Keys.Name)) {
50 | meta.setName(snapshot.child(Keys.Name).getValue(String.class));
51 | }
52 | if (snapshot.hasChild(Keys.Created)) {
53 | Long date = snapshot.child(Keys.Created).getValue(Long.class);
54 | if (date != null) {
55 | meta.setCreated(new Date(date));
56 | }
57 | }
58 | if (snapshot.hasChild(Keys.ImageURL)) {
59 | meta.setImageURL(snapshot.child(Keys.ImageURL).getValue(String.class));
60 | }
61 | if (snapshot.hasChild(Keys.Data)) {
62 | Map data = snapshot.child(Keys.Data).getValue(Generic.hashMapStringObject());
63 | meta.setData(data);
64 | }
65 | return Maybe.just(meta);
66 | }
67 | return Maybe.empty();
68 | });
69 | }
70 |
71 | @Override
72 | public Single add(Map data, @Nullable Consumer newId) {
73 | return new RXRealtime().add(Ref.get(Paths.chatsPath()), data, newId);
74 | }
75 |
76 | @Override
77 | public Completable delete(String chatId) {
78 | return new RXRealtime().delete(Ref.get(Paths.chatPath(chatId)));
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/firestream-realtime/src/main/java/firestream/chat/realtime/RealtimeService.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.realtime;
2 |
3 | import firestream.chat.firebase.service.FirebaseService;
4 |
5 | public class RealtimeService extends FirebaseService {
6 |
7 | public RealtimeService() {
8 | core = new RealtimeCoreHandler();
9 | chat = new RealtimeChatHandler();
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/firestream-realtime/src/main/java/firestream/chat/realtime/Ref.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.realtime;
2 |
3 | import com.google.firebase.database.DatabaseReference;
4 | import com.google.firebase.database.FirebaseDatabase;
5 |
6 | import firestream.chat.firebase.service.Path;
7 |
8 | public class Ref {
9 |
10 | public static DatabaseReference get(Path path){
11 | DatabaseReference ref = db().getReference(path.first());
12 | for (int i = 1; i < path.size(); i++) {
13 | ref = ref.child(path.get(i));
14 | }
15 | return ref;
16 | }
17 |
18 | public static FirebaseDatabase db() {
19 | return FirebaseDatabase.getInstance();
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/firestream-realtime/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Firestream for Firestore
3 | Snapshot is null
4 | Firebase must be authenticated to connect
5 | You need to call FireStream.api().initialize(…)
6 | Null data returned
7 | No value present
8 | DocumentReference expected but path points to collection
9 | CollectionReference expected but path points to document
10 | You must be a group owner to perform this action
11 | You must be a group admin to perform this action
12 | You must be a group member to perform this action
13 | Write cancelled
14 | Invalid path, path can only contain letters, numbers and underscores
15 | Remove the other users before you can delete the group
16 |
17 | Owner
18 | Admin
19 | Member
20 | Watcher
21 | Banned
22 |
23 |
24 |
--------------------------------------------------------------------------------
/firestream/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/firestream/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
6 |
7 | defaultConfig {
8 | minSdkVersion Integer.parseInt(project.MIN_SDK)
9 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
10 | }
11 |
12 | buildTypes {
13 | debug {
14 | minifyEnabled project.hasProperty('minifyDebug')
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | release {
18 | minifyEnabled project.hasProperty('minifyRelease')
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 |
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 |
28 | lintOptions {
29 | abortOnError false
30 | checkReleaseBuilds false
31 | lintConfig file('lint.xml')
32 | }
33 | }
34 |
35 | ext {
36 | libraryName = 'FireStream'
37 | artifact = 'firestream'
38 | libraryDescription = 'FireStream: Messaging Framework for Firebase and Firestore'
39 | }
40 |
41 | publish {
42 | userOrg = BINTRAY_USER_ORG
43 | groupId = CHAT_SDK_GROUP
44 | artifactId = artifact
45 | repoName = BINTRAY_REPO
46 | publishVersion = CHAT_SDK_VERSION
47 | desc = libraryDescription
48 | licences = ["GPL-3.0"]
49 | uploadName = libraryName
50 | website = GIT_URL
51 | }
52 |
53 | dependencies {
54 | implementation fileTree(dir: 'libs', include: ['*.jar'])
55 | api project(':sdk-guru-common')
56 | // api project(':sdk-guru-realtime')
57 |
58 | // implementation "com.google.firebase:firebase-firestore:$firebaseFirestoreVersion"
59 | implementation "com.google.firebase:firebase-auth:$firebaseAuthVersion"
60 | // implementation "com.google.firebase:firebase-database:$firebaseDatabaseVersion"
61 | implementation "com.victorrendina:rxqueue2:$rxQueueVersion"
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/firestream/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/firestream/consumer-rules.pro
--------------------------------------------------------------------------------
/firestream/proguard-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/firestream/proguard-rules.pro
--------------------------------------------------------------------------------
/firestream/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/FirestreamConfig.java:
--------------------------------------------------------------------------------
1 | package firestream.chat;
2 |
3 | import org.pmw.tinylog.Logger;
4 |
5 | import sdk.guru.common.BaseConfig;
6 |
7 | public class FirestreamConfig extends BaseConfig {
8 |
9 | public FirestreamConfig(T onBuild) {
10 | super(onBuild);
11 | }
12 |
13 | public boolean deliveryReceiptsEnabled = true;
14 | public boolean autoMarkReceived = true;
15 | public boolean autoAcceptChatInvite = true;
16 | public boolean deleteMessagesOnReceipt = false;
17 | public boolean emitEventForLastMessage = false;
18 | protected String root = "firestream";
19 | protected String sandbox = "prod";
20 |
21 | // Debug and testing settings
22 | public boolean debugEnabled = false;
23 | public boolean deleteDeliveryReceiptsOnReceipt = true;
24 |
25 | /**
26 | * This will be the root of the FireStream Firebase database i.e.
27 | * /root/[sandbox]/users
28 | */
29 | public FirestreamConfig setRoot(String root) {
30 | String path = validatePath(root);
31 | if (path != null) {
32 | this.root = path;
33 | }
34 | return this;
35 | }
36 |
37 | public FirestreamConfig setSandbox(String sandbox) {
38 | String path = validatePath(sandbox);
39 | if (path != null) {
40 | this.sandbox = path;
41 | }
42 | return this;
43 | }
44 |
45 | /**
46 | * Should the framework automatically send a delivery receipt when
47 | * a message type received
48 | */
49 | public FirestreamConfig setDeliveryReceiptsEnabled(boolean value) {
50 | this.deliveryReceiptsEnabled = value;
51 | return this;
52 | }
53 |
54 | /**
55 | * Should the framework send the received receipt automatically
56 | */
57 | public FirestreamConfig setAutoMarkReceivedEnabled(boolean value) {
58 | this.autoMarkReceived = value;
59 | return this;
60 | }
61 |
62 | /**
63 | * Are chat chat invites accepted automatically
64 | */
65 | public FirestreamConfig setAutoAcceptChatInviteEnabled(boolean value) {
66 | this.autoAcceptChatInvite = value;
67 | return this;
68 | }
69 |
70 | /**
71 | * If this type enabled, each time a message type received, it will be
72 | * deleted from our inbound message queue childOn Firestore. Even if this
73 | * type set to false, typing indicator messages and presence messages will
74 | * always be deleted as they don't have any use in the message archive
75 | * this flag only affects 1-to-1 messages.
76 | */
77 | public FirestreamConfig setDeleteMessagesOnReceiptEnabled(boolean value) {
78 | this.deleteMessagesOnReceipt = value;
79 | return this;
80 | }
81 |
82 | /**
83 | * If this is set to true, an event will be emitted for the last message received
84 | * this may be a duplicate.
85 | */
86 | public FirestreamConfig setEmitEventForLastMessage(boolean enabled) {
87 | emitEventForLastMessage = enabled;
88 | return this;
89 | }
90 |
91 | /**
92 | * Should debug log messages be shown?
93 | */
94 | public FirestreamConfig setDebugEnabled(boolean enabled) {
95 | debugEnabled = enabled;
96 | return this;
97 | }
98 |
99 | /**
100 | * Should debug log messages be shown?
101 | */
102 | public FirestreamConfig setDeleteDeliveryReceiptsOnReceipt(boolean enabled) {
103 | deleteDeliveryReceiptsOnReceipt = enabled;
104 | return this;
105 | }
106 |
107 | protected String validatePath(String path) {
108 | if (path != null) {
109 | String validPath = path.replaceAll("[^a-zA-Z0-9_]", "");
110 | if (!validPath.isEmpty()) {
111 | if (!validPath.equals(path)) {
112 | Logger.warn("The root path cannot contain special characters, they were removed so your new root path is: " + validPath);
113 | }
114 | return validPath;
115 | } else {
116 | Logger.warn("The root path cannot contain special characters, when removed your root path was empty so the default was used instead");
117 | }
118 | } else {
119 | Logger.warn("The root path provided cannot be null, the default was used instead");
120 | }
121 | return null;
122 | }
123 |
124 | public String getRoot() {
125 | return root;
126 | }
127 |
128 | public String getSandbox() {
129 | return sandbox;
130 | }
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/chat/Events.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.chat;
2 |
3 | import com.jakewharton.rxrelay2.PublishRelay;
4 |
5 | import firestream.chat.firebase.rx.MultiRelay;
6 | import firestream.chat.message.DeliveryReceipt;
7 | import firestream.chat.message.Invitation;
8 | import firestream.chat.message.Message;
9 | import firestream.chat.message.Presence;
10 | import firestream.chat.message.Sendable;
11 | import firestream.chat.message.TypingState;
12 | import firestream.chat.namespace.FireStreamMessage;
13 | import io.reactivex.Observable;
14 | import sdk.guru.common.Event;
15 |
16 | public class Events {
17 |
18 | protected MultiRelay> messages = MultiRelay.create();
19 | protected MultiRelay> deliveryReceipts = MultiRelay.create();
20 | protected MultiRelay> typingStates = MultiRelay.create();
21 | protected MultiRelay> presences = MultiRelay.create();
22 | protected MultiRelay> invitations = MultiRelay.create();
23 |
24 | /**
25 | * The sendable event stream provides the most information. It passes a sendable event
26 | * when will include the kind of action that has been performed.
27 | */
28 | protected MultiRelay> sendables = MultiRelay.create();
29 |
30 | protected PublishRelay errors = PublishRelay.create();
31 |
32 |
33 | /**
34 | * Note: when you send a message, that will trigger both a message added event and a
35 | * message updated event. As soon as the message is added to the Firebase cache, the
36 | * message added event will be triggered and the message will have an estimated time
37 | * stamp. Then when the message has been written to the server, it will be updated
38 | * with the server timestamp.
39 | * @return
40 | */
41 | public MultiRelay> getMessages() {
42 | return messages;
43 | }
44 |
45 | /**
46 | * A FireStream Message type no different from a Message. The reason this method
47 | * exists type because Message type a very common class name. If for any reason
48 | * your project already has a Message object, you can use the FireStreamMessage
49 | * to avoid a naming clash
50 | * @return events of messages
51 | */
52 | public Observable> getFireStreamMessages() {
53 | return messages.map(messageEvent -> messageEvent.to(FireStreamMessage.fromMessage(messageEvent.get()))).hide();
54 | }
55 |
56 | /**
57 | * Get a stream of errors from the chat
58 | * @return
59 | */
60 | public Observable getErrors() {
61 | return errors.hide();
62 | }
63 |
64 | public MultiRelay> getDeliveryReceipts() {
65 | return deliveryReceipts;
66 | }
67 |
68 | public MultiRelay> getTypingStates() {
69 | return typingStates;
70 | }
71 |
72 | public MultiRelay> getSendables() {
73 | return sendables;
74 | }
75 |
76 |
77 | public MultiRelay> getPresences() {
78 | return presences;
79 | }
80 | public MultiRelay> getInvitations() {
81 | return invitations;
82 | }
83 |
84 | public PublishRelay publishThrowable() {
85 | return errors;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/chat/Meta.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.chat;
2 |
3 | import java.util.Date;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import firestream.chat.firebase.service.Keys;
8 | import firestream.chat.namespace.Fire;
9 |
10 | public class Meta {
11 |
12 | protected String name = "";
13 | protected String imageURL = "";
14 | protected Date created;
15 | protected Map data;
16 | protected Object timestamp;
17 | protected boolean wrap = false;
18 |
19 | public Meta() {
20 | }
21 |
22 | public Meta(String name, String imageURL) {
23 | this(name, imageURL, null);
24 | }
25 |
26 | public Meta(String name, String imageURL, Map data) {
27 | this(name, imageURL, null, data);
28 | }
29 |
30 | public Meta(String name, String imageURL, Date created, Map data) {
31 | this.name = name;
32 | this.imageURL = imageURL;
33 | this.created = created;
34 | this.data = data;
35 | }
36 |
37 | public String getName() {
38 | return name;
39 | }
40 |
41 | public Meta setName(String name) {
42 | this.name = name;
43 | return this;
44 | }
45 |
46 | public String getImageURL() {
47 | return imageURL;
48 | }
49 |
50 | public Meta setImageURL(String imageURL) {
51 | this.imageURL = imageURL;
52 | return this;
53 | }
54 |
55 | public Meta setData(Map data) {
56 | this.data = data;
57 | return this;
58 | }
59 |
60 | public Map getData() {
61 | return data;
62 | }
63 |
64 | public Meta addTimestamp() {
65 | timestamp = Fire.stream().getFirebaseService().core.timestamp();
66 | return this;
67 | }
68 |
69 | public Meta wrap() {
70 | wrap = true;
71 | return this;
72 | }
73 |
74 | public Date getCreated() {
75 | return created;
76 | }
77 |
78 | public void setCreated(Date created) {
79 | this.created = created;
80 | }
81 |
82 | public static Map nameData(String name) {
83 | return new HashMap(){{
84 | put(Keys.Name, name);
85 | }};
86 | }
87 |
88 | public static Map imageURLData(String imageURL) {
89 | return new HashMap(){{
90 | put(Keys.ImageURL, imageURL);
91 | }};
92 | }
93 |
94 | public static Map dataData(Map data) {
95 | return new HashMap(){{
96 | put(Keys.Data, data);
97 | }};
98 | }
99 |
100 | public Map toData() {
101 | Map data = new HashMap<>();
102 |
103 | if (name != null) {
104 | data.put(Keys.Name, name);
105 | }
106 | if (imageURL != null) {
107 | data.put(Keys.ImageURL, imageURL);
108 | }
109 | if (this.data != null) {
110 | data.put(Keys.Data, this.data);
111 | }
112 | if (timestamp != null) {
113 | data.put(Keys.Created, timestamp);
114 | }
115 | if (wrap) {
116 | return wrap(data);
117 | }
118 | return data;
119 | }
120 |
121 | protected static Map wrap(Map map) {
122 | return new HashMap() {{
123 | put(Keys.Meta, map);
124 | }};
125 | }
126 |
127 | public Meta copy() {
128 | Meta meta = new Meta(name, imageURL);
129 | meta.created = created;
130 | meta.data = data;
131 | return meta;
132 | }
133 |
134 | public static Meta from(String name, String imageURL) {
135 | return new Meta(name, imageURL);
136 | }
137 |
138 | public static Meta from(String name, String imageURL, Map data) {
139 | return new Meta(name, imageURL, data);
140 | }
141 |
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/chat/User.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.chat;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import firestream.chat.events.ListData;
7 | import firestream.chat.firebase.service.Keys;
8 | import firestream.chat.namespace.Fire;
9 | import firestream.chat.types.ContactType;
10 | import firestream.chat.types.RoleType;
11 | import sdk.guru.common.Event;
12 |
13 | public class User {
14 |
15 | protected String id;
16 | protected RoleType roleType;
17 | protected ContactType contactType;
18 |
19 | public User(String id) {
20 | this.id = id;
21 | }
22 |
23 | public User(String id, RoleType roleType) {
24 | this(id);
25 | this.roleType = roleType;
26 | }
27 |
28 | public User(String id, ContactType contactType) {
29 | this(id);
30 | this.contactType = contactType;
31 | }
32 |
33 | public String getId() {
34 | return id;
35 | }
36 |
37 | public void setId(String id) {
38 | this.id = id;
39 | }
40 |
41 | public RoleType getRoleType() {
42 | return roleType;
43 | }
44 |
45 | public void setRoleType(RoleType roleType) {
46 | this.roleType = roleType;
47 | }
48 |
49 | public ContactType getContactType() {
50 | return contactType;
51 | }
52 |
53 | public void setContactType(ContactType contactType) {
54 | this.contactType = contactType;
55 | }
56 |
57 | public boolean equalsRoleType(RoleType rt) {
58 | return this.roleType.equals(rt);
59 | }
60 |
61 | public boolean equalsRoleType(User user) {
62 | return this.roleType.equals(user.getRoleType());
63 | }
64 |
65 | public boolean equalsContactType(User user) {
66 | return this.contactType.equals(user.getContactType());
67 | }
68 |
69 | public boolean equalsContactType(ContactType ct) {
70 | return this.contactType.equals(ct);
71 | }
72 |
73 | @Override
74 | public boolean equals(Object user) {
75 | if (user instanceof User) {
76 | return id.equals(((User) user).id);
77 | }
78 | return false;
79 | }
80 |
81 | public boolean isMe() {
82 | return id.equals(Fire.stream().currentUserId());
83 | }
84 |
85 | public static User currentUser(RoleType role) {
86 | return new User(Fire.stream().currentUserId(), role);
87 | }
88 |
89 | public static User currentUser() {
90 | return currentUser(null);
91 | }
92 |
93 | public interface DataProvider {
94 | Map data(User user);
95 | }
96 |
97 | public static DataProvider dateDataProvider() {
98 | return user -> {
99 | Map data = new HashMap<>();
100 | data.put(Keys.Date, Fire.stream().getFirebaseService().core.timestamp());
101 | return data;
102 | };
103 | }
104 |
105 | public static DataProvider roleTypeDataProvider() {
106 | return user -> user.roleType.data();
107 | }
108 |
109 | public static DataProvider contactTypeDataProvider() {
110 | return user -> user.contactType.data();
111 | }
112 |
113 | public static User from(Event event) {
114 | if (event.get().get(Keys.Role) instanceof String) {
115 | return new User(event.get().getId(), new RoleType((String) event.get().get(Keys.Role)));
116 | }
117 | if (event.get().get(Keys.Type) instanceof String) {
118 | return new User(event.get().getId(), new ContactType((String) event.get().get(Keys.Type)));
119 | }
120 | return new User(event.get().getId());
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/events/ConnectionEvent.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.events;
2 |
3 | public class ConnectionEvent {
4 |
5 | public enum Type {
6 | WillConnect,
7 | DidConnect,
8 | WillDisconnect,
9 | DidDisconnect
10 | }
11 |
12 | protected Type type;
13 |
14 | protected ConnectionEvent(Type type) {
15 | this.type = type;
16 | }
17 |
18 | public static ConnectionEvent willConnect() {
19 | return new ConnectionEvent(Type.WillConnect);
20 | }
21 |
22 | public static ConnectionEvent didConnect() {
23 | return new ConnectionEvent(Type.DidConnect);
24 | }
25 |
26 | public static ConnectionEvent willDisconnect() {
27 | return new ConnectionEvent(Type.WillDisconnect);
28 | }
29 |
30 | public static ConnectionEvent didDisconnect() {
31 | return new ConnectionEvent(Type.DidDisconnect);
32 | }
33 |
34 | public Type getType() {
35 | return type;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/events/ListData.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.events;
2 |
3 | import java.util.Map;
4 |
5 | public class ListData {
6 |
7 | protected String id;
8 | protected Map data;
9 |
10 | public ListData(String id, Map data) {
11 | this.id = id;
12 | this.data = data;
13 | }
14 |
15 | public Object get(String key) {
16 | if (data != null) {
17 | return data.get(key);
18 | }
19 | return null;
20 | }
21 |
22 | public String getId() {
23 | return id;
24 | }
25 |
26 | public Map getData() {
27 | return data;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/events/UserEvent.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.events;
2 |
3 | import firestream.chat.chat.User;
4 | import firestream.chat.namespace.FireStreamUser;
5 | import sdk.guru.common.Event;
6 | import sdk.guru.common.EventType;
7 |
8 | public class UserEvent extends Event {
9 |
10 | public User user;
11 |
12 | public UserEvent(User user, EventType type) {
13 | super(type);
14 | this.user = user;
15 | }
16 |
17 | public static UserEvent added(User user) {
18 | return new UserEvent(user, EventType.Added);
19 | }
20 |
21 | public static UserEvent removed(User user) {
22 | return new UserEvent(user, EventType.Removed);
23 | }
24 |
25 | public static UserEvent modified(User user) {
26 | return new UserEvent(user, EventType.Modified);
27 | }
28 |
29 | public FireStreamUser getFireStreamUser() {
30 | return FireStreamUser.fromUser(user);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/filter/Filter.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.filter;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | import sdk.guru.common.Event;
7 | import sdk.guru.common.EventType;
8 | import firestream.chat.namespace.Fire;
9 |
10 | import firestream.chat.message.Sendable;
11 | import firestream.chat.types.SendableType;
12 | import io.reactivex.functions.Predicate;
13 |
14 | public class Filter {
15 |
16 | public static Predicate> bySendableType(final SendableType... types) {
17 | return e -> {
18 | for (SendableType type : types) {
19 | if (e.get().getType().equals(type.get())) {
20 | return true;
21 | }
22 | }
23 | return false;
24 | };
25 | }
26 |
27 | public static Predicate> notFromMe() {
28 | return e -> !e.get().getFrom().equals(Fire.stream().currentUserId());
29 | }
30 |
31 | public static Predicate> byEventType(final EventType... types) {
32 | return e -> {
33 | for (EventType type : types) {
34 | if (e.getType().equals(type)) {
35 | return true;
36 | }
37 | }
38 | return false;
39 | };
40 | }
41 |
42 | public static Predicate> eventBySendableType(final SendableType... types) {
43 | return eventBySendableType(Arrays.asList(types));
44 | }
45 |
46 | public static Predicate> eventBySendableType(final List types) {
47 | return e -> {
48 | for (SendableType type : types) {
49 | if (e.get().getType().equals(type.get())) {
50 | return true;
51 | }
52 | }
53 | return false;
54 | };
55 | }
56 |
57 | public static Predicate> and(Predicate>... predicates) {
58 | return and(Arrays.asList(predicates));
59 | }
60 |
61 | public static Predicate> and(List>> predicates) {
62 | return event -> {
63 | for (Predicate> p: predicates) {
64 | if (!p.test(event)) {
65 | return false;
66 | }
67 | }
68 | return true;
69 | };
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/rx/MultiRelay.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.rx;
2 |
3 | import com.jakewharton.rxrelay2.BehaviorRelay;
4 | import com.jakewharton.rxrelay2.PublishRelay;
5 | import com.jakewharton.rxrelay2.Relay;
6 | import com.jakewharton.rxrelay2.ReplayRelay;
7 |
8 | import io.reactivex.Observable;
9 | import io.reactivex.Observer;
10 | import sdk.guru.common.RX;
11 |
12 |
13 | public class MultiRelay extends Relay {
14 |
15 | protected final PublishRelay publishRelay = PublishRelay.create();
16 | protected final BehaviorRelay behaviorRelay = BehaviorRelay.create();
17 | protected final ReplayRelay replayRelay = ReplayRelay.create();
18 |
19 | public static MultiRelay create() {
20 | return new MultiRelay();
21 | }
22 |
23 | @Override
24 | public void accept(T t) {
25 |
26 | // Allow them to only subscribe to new events
27 | publishRelay.accept(t);
28 |
29 | // Allow them to get a behavior subject too
30 | behaviorRelay.accept(t);
31 |
32 | // Allow them to replay all events
33 | replayRelay.accept(t);
34 |
35 | }
36 |
37 | @Override
38 | public boolean hasObservers() {
39 | return publishRelay.hasObservers() || behaviorRelay.hasObservers() || replayRelay.hasObservers();
40 | }
41 |
42 | /**
43 | * Get a events of only new events. For example in the sequence: 1, 2, [subscribed], 3, 4,
44 | * only 3 and 4 would be emitted to teh observer
45 | * @return a events of new events
46 | */
47 | public Observable newEvents() {
48 | return publishRelay
49 | .hide().observeOn(RX.main());
50 | }
51 |
52 | /**
53 | * Get a events of all events. For example in the sequence: 1, 2, [subscribed], 3, 4,
54 | * 1, 2, 3, 4 would be emitted
55 | * @return a events of all events past and future
56 | */
57 | public Observable pastAndNewEvents() {
58 | return replayRelay.hide().observeOn(RX.main());
59 | }
60 |
61 | /**
62 | * Get a events of the last and all future events. For example in the sequence: 1, 2, [subscribed], 3, 4,
63 | * 2, 3, 4 would be emitted
64 | * @return a events of the last emitted event and all future events
65 | */
66 | public Observable currentAndNewEvents() {
67 | return behaviorRelay.hide().observeOn(RX.main());
68 | }
69 |
70 | @Override
71 | protected void subscribeActual(Observer super T> observer) {
72 |
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/service/FirebaseChatHandler.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.service;
2 |
3 | import java.util.Map;
4 |
5 | import firestream.chat.chat.Meta;
6 | import io.reactivex.Completable;
7 | import io.reactivex.Observable;
8 | import io.reactivex.Single;
9 | import io.reactivex.annotations.Nullable;
10 | import io.reactivex.functions.Consumer;
11 |
12 | public abstract class FirebaseChatHandler {
13 |
14 | public abstract Completable leaveChat(String chatId);
15 | public abstract Completable joinChat(String chatId);
16 |
17 | /**
18 | * Note in this case, we don't provide the path to the chat/meta
19 | * we provide it to the chat. This type because of differences between
20 | * Realtime and Firestore. The realtime database stores the data at
21 | * - chat/meta/...
22 | * But in Firestore meta/... type stored as a field on the chat document
23 | * So we need to link to the chat document in both cases
24 | * @param chatId chat room id
25 | * @return stream of data when chat meta changes
26 | */
27 | public abstract Observable metaOn(String chatId);
28 |
29 | public abstract Completable setMetaField(String chatId, String key, Object value);
30 |
31 | public abstract Single add(Map data, @Nullable Consumer newId);
32 |
33 | public Single add(Map data) {
34 | return add(data, null);
35 | }
36 |
37 | public abstract Completable delete(String chatId);
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/service/FirebaseCoreHandler.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.service;
2 |
3 | import androidx.annotation.Nullable;
4 |
5 | import java.util.Date;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | import firestream.chat.chat.User;
10 | import firestream.chat.events.ListData;
11 | import firestream.chat.message.Sendable;
12 | import io.reactivex.Completable;
13 | import io.reactivex.Observable;
14 | import io.reactivex.Single;
15 | import io.reactivex.functions.Consumer;
16 | import sdk.guru.common.Event;
17 | import sdk.guru.common.Optional;
18 |
19 | public abstract class FirebaseCoreHandler {
20 |
21 | /**
22 | * Listen for changes in the value of a list reference
23 | *
24 | * @param path to listen to
25 | * @return events of list events
26 | */
27 | public abstract Observable> listChangeOn(Path path);
28 |
29 | /**
30 | * Delete a sendable from our queue
31 | *
32 | * @param messagesPath
33 | * @return completion
34 | */
35 | public abstract Completable deleteSendable(Path messagesPath);
36 |
37 | /**
38 | * Send a message to a messages ref
39 | *
40 | * @param messagesPath Firestore reference for message collection
41 | * @param sendable item to be sent
42 | * @param newId get the id of the new message before it's sent
43 | * @return completion
44 | */
45 | public abstract Completable send(Path messagesPath, Sendable sendable, Consumer newId);
46 |
47 | /**
48 | * Add users to a reference
49 | *
50 | * @param path for users
51 | * @param dataProvider a callback to extract the data to add from the user
52 | * this allows us to use one method to write to multiple different places
53 | * @param users to add
54 | * @return completion
55 | */
56 | public abstract Completable addUsers(Path path, User.DataProvider dataProvider, List extends User> users);
57 |
58 | /**
59 | * Remove users from a reference
60 | *
61 | * @param path for users
62 | * @param users to remove
63 | * @return completion
64 | */
65 | public abstract Completable removeUsers(Path path, List extends User> users);
66 |
67 | /**
68 | * Update users for a reference
69 | * @param path for users
70 | * @param dataProvider a callback to extract the data to add from the user
71 | * this allows us to use one method to write to multiple different places
72 | * @param users to update
73 | * @return completion
74 | */
75 | public abstract Completable updateUsers(Path path, User.DataProvider dataProvider, List extends User> users);
76 |
77 | /**
78 | * Get a updateBatch of messages once
79 | * @param messagesPath
80 | * @param fromDate get messages from this date
81 | * @param toDate get messages until this date
82 | * @param limit limit the maximum number of messages
83 | * @return a events of message results
84 | */
85 | public abstract Single> loadMoreMessages(Path messagesPath, @Nullable Date fromDate, @Nullable Date toDate, @Nullable Integer limit);
86 |
87 | /**
88 | * This method gets the date of the last delivery receipt that we sent - i.e. the
89 | * last message WE received.
90 | * @param messagesPath
91 | * @return single date
92 | */
93 | public abstract Single> lastMessage(Path messagesPath);
94 |
95 | /**
96 | * Start listening to the current message reference and pass the messages to the events
97 | * @param messagesPath
98 | * @param newerThan only listen for messages after this date
99 | * @return a events of message results
100 | */
101 | public abstract Observable> messagesOn(Path messagesPath, Date newerThan);
102 |
103 | /**
104 | * Return a Firebase timestamp object
105 | * @return appropriate server timestamp object
106 | */
107 | public abstract Object timestamp();
108 |
109 | public abstract Completable mute(Path path, Map data);
110 | public abstract Completable unmute(Path path);
111 |
112 | }
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/service/FirebaseService.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.service;
2 |
3 | public class FirebaseService {
4 |
5 | public FirebaseCoreHandler core;
6 | public FirebaseChatHandler chat;
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/service/Keys.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.service;
2 |
3 | public class Keys {
4 |
5 | public static String Type = "type";
6 | public static String From = "from";
7 | public static String Date = "date";
8 | public static String Body = "body";
9 |
10 | public static String Name = "name";
11 | public static String ImageURL = "image-url";
12 | public static String Created = "created";
13 | public static String Role = "role";
14 | public static String Data = "data";
15 |
16 | public static String Users = "users";
17 | public static String Messages = "messages";
18 | public static String Contacts = "contacts";
19 | public static String Blocked = "blocked";
20 | public static String Chats = "chats";
21 | public static String Meta = "meta";
22 | public static String Muted = "muted";
23 | }
24 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/service/Path.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.service;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | public class Path {
8 |
9 | protected List components = new ArrayList<>();
10 |
11 | /**
12 | * The remainder type used to fix an issue which arises with Firestore. In Firestore
13 | * there are documents and collections. But sometimes we want to reference information
14 | * that type at a path within a document for example:
15 | * chats/id/meta
16 | * Here the id, type a document but if we generated a path from this, it would point to a
17 | * collection. Therefore if the path we pass in to the ref doesn't point to the correct
18 | * reference type, we truncate it by one and set the remainder
19 | */
20 | protected String remainder = null;
21 |
22 | public Path(List path) {
23 | for (String s: path) {
24 | if (s!= null) {
25 | components.add(s);
26 | }
27 | }
28 | }
29 |
30 | public Path(String path) {
31 | this(Arrays.asList(path.split("/")));
32 | }
33 |
34 | public Path(String... path) {
35 | this(Arrays.asList(path));
36 | }
37 |
38 | public String first() {
39 | return components.get(0);
40 | }
41 |
42 | public String last() {
43 | return components.get(size()-1);
44 | }
45 |
46 | public int size() {
47 | return components.size();
48 | }
49 |
50 | public String get(int index) {
51 | if (components.size() > index) {
52 | return components.get(index);
53 | }
54 | return null;
55 | }
56 |
57 | @Override
58 | public String toString() {
59 | StringBuilder path = new StringBuilder();
60 | for (String component: components) {
61 | path.append(component).append("/");
62 | }
63 | path.deleteCharAt(path.length() - 1);
64 | return path.toString();
65 | }
66 |
67 | public Path child(String child) {
68 | components.add(child);
69 | return this;
70 | }
71 |
72 | public Path children(String... children) {
73 | components.addAll(Arrays.asList(children));
74 | return this;
75 | }
76 |
77 | public Path removeLast() {
78 | if (components.size() > 0) {
79 | components.remove(components.size() - 1);
80 | }
81 | return this;
82 | }
83 |
84 | public boolean isDocument() {
85 | return size() % 2 == 0;
86 | }
87 |
88 | public List getComponents() {
89 | return components;
90 | }
91 |
92 | public String getRemainder() {
93 | return remainder;
94 | }
95 |
96 | public void normalizeForDocument() {
97 | if (!isDocument()) {
98 | remainder = last();
99 | removeLast();
100 | }
101 | }
102 |
103 | public void normalizeForCollection() {
104 | if (isDocument()) {
105 | remainder = last();
106 | removeLast();
107 | }
108 | }
109 |
110 | /**
111 | * For Firestore to update nested fields on a document, you need to use a
112 | * dot notation. This method returns the remainder if it exists plus a
113 | * dotted path component
114 | * @param component path to extend
115 | * @return dotted components
116 | */
117 | public String dotPath(String component) {
118 | if (remainder == null) {
119 | return component;
120 | } else {
121 | return remainder + "." + component;
122 | }
123 | }
124 |
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/firebase/service/Paths.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.firebase.service;
2 |
3 | import firestream.chat.namespace.Fire;
4 |
5 |
6 | public class Paths extends Keys {
7 |
8 | public static Path root() {
9 | return new Path(Fire.stream().getConfig().getRoot(), Fire.stream().getConfig().getSandbox());
10 | }
11 |
12 | public static Path usersPath() {
13 | return root().child(Users);
14 | }
15 |
16 | public static Path userPath(String uid) {
17 | return usersPath().child(uid);
18 | }
19 |
20 | public static Path userPath() {
21 | return userPath(currentUserId());
22 | }
23 |
24 | public static Path messagesPath(String uid) {
25 | return userPath(uid).child(Messages);
26 | }
27 |
28 | public static Path messagesPath() {
29 | return messagesPath(currentUserId());
30 | }
31 |
32 | public static Path userChatsPath() {
33 | return userPath(currentUserId()).child(Keys.Chats);
34 | }
35 |
36 | public static Path userMutedPath() {
37 | return userPath(currentUserId()).child(Keys.Muted);
38 | }
39 |
40 | public static Path userGroupChatPath(String chatId) {
41 | return userChatsPath().child(chatId);
42 | }
43 |
44 | public static Path messagePath(String messageId) {
45 | return messagePath(currentUserId(), messageId);
46 | }
47 |
48 | public static Path messagePath(String uid, String messageId) {
49 | return messagesPath(uid).child(messageId);
50 | }
51 |
52 | protected static String currentUserId() {
53 | return Fire.stream().currentUserId();
54 | }
55 |
56 | public static Path contactsPath() {
57 | return userPath().child(Contacts);
58 | }
59 |
60 | public static Path blockedPath() {
61 | return userPath().child(Blocked);
62 | }
63 |
64 | public static Path chatsPath() {
65 | return root().child(Chats);
66 | }
67 |
68 | public static Path chatPath(String chatId) {
69 | return chatsPath().child(chatId);
70 | }
71 |
72 | public static Path chatMetaPath(String chatId) {
73 | return chatsPath().child(chatId).child(Meta);
74 | }
75 |
76 | public static Path chatMessagesPath(String chatId) {
77 | return chatPath(chatId).child(Messages);
78 | }
79 |
80 | public static Path chatUsersPath(String chatId) {
81 | return chatPath(chatId).child(Users);
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/interfaces/IAbstractChat.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.interfaces;
2 |
3 | import java.util.Date;
4 | import java.util.List;
5 |
6 | import firestream.chat.chat.Events;
7 | import firestream.chat.message.Sendable;
8 | import firestream.chat.types.SendableType;
9 | import io.reactivex.CompletableObserver;
10 | import io.reactivex.Single;
11 | import io.reactivex.disposables.Disposable;
12 | import io.reactivex.functions.Consumer;
13 | import sdk.guru.common.DisposableMap;
14 |
15 | public interface IAbstractChat extends Consumer, CompletableObserver {
16 |
17 | /**
18 | * Connect to the chat
19 | * @throws Exception error if we are not connected
20 | */
21 | void connect() throws Exception;
22 |
23 | /**
24 | * Disconnect from a chat. This does not affect our membership but we will
25 | * no longer receive any updates unless we log out / log in again
26 | */
27 | void disconnect();
28 |
29 | /**
30 | * When we leave / disconnect from a chat or when we log out, any disposables
31 | * will be disposed of automatically
32 | * @param disposable to manage
33 | */
34 | void manage(Disposable disposable);
35 |
36 | /**
37 | * Get the managed disposable map. This map will be disposed of when we leave / disconnect
38 | * from the chat or when we log out. Use this to store any disposables that you want to be
39 | * disposed of then. This type slightly more flexible than the manage method because it allows
40 | * you to store and retrieve disposables from an ID.
41 | * @return a pointer to the managed disposable map
42 | */
43 | DisposableMap getDisposableMap();
44 |
45 | /**
46 | * Get a list of all sendables received
47 | * @return a list of sendables
48 | */
49 | List getSendables();
50 |
51 | /**
52 | * Get a list of sendables given a class
53 | * @param clazz of sendable
54 | * @return list of sendables
55 | */
56 | List getSendables(Class clazz);
57 |
58 | /**
59 | * Get a list of sendables filtered by type
60 | * @param type of sendable
61 | * @return a filtered list of sendables
62 | */
63 | List getSendables(SendableType type);
64 |
65 | /**
66 | * Get a sendable for a particular ID
67 | * @param id of sendable
68 | * @return sendable or null
69 | */
70 | Sendable getSendable(String id);
71 |
72 | /**
73 | * Get access to the events object which provides access to observables for sendable events
74 | * @return events holder
75 | */
76 | Events getSendableEvents();
77 |
78 | /**
79 | * Load a batch of historic messages
80 | *
81 | * @param fromDate load messages AFTER this date
82 | * @param toDate load message TO AND INCLUDING this date
83 | * @return a stream of messages
84 | */
85 | Single> loadMoreMessages(Date fromDate, Date toDate, boolean desc);
86 |
87 | /**
88 | * Load a batch of historic messages
89 | *
90 | * @param fromDate load messages AFTER this date
91 | * @param limit the number of messages returned
92 | * @return a stream of messages
93 | */
94 | Single> loadMoreMessagesFrom(Date fromDate, Integer limit, boolean desc);
95 |
96 | /**
97 | * Load a batch of historic messages
98 | *
99 | * @param toDate load message TO AND INCLUDING this date
100 | * @param limit the number of messages returned
101 | * @return a stream of messages
102 | */
103 | Single> loadMoreMessagesTo(Date toDate, Integer limit, boolean desc);
104 |
105 | /**
106 | * Load a batch of historic messages
107 | *
108 | * @param toDate load message TO this date
109 | * @param limit the number of messages returned
110 | * @return a stream of messages
111 | */
112 | Single> loadMoreMessagesBefore(Date toDate, Integer limit, boolean desc);
113 |
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/interfaces/IFireStream.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.interfaces;
2 |
3 | import android.content.Context;
4 |
5 | import java.util.Date;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | import firestream.chat.FirestreamConfig;
10 | import firestream.chat.chat.Chat;
11 | import firestream.chat.chat.User;
12 | import firestream.chat.events.ConnectionEvent;
13 | import firestream.chat.firebase.rx.MultiRelay;
14 | import firestream.chat.firebase.service.FirebaseService;
15 | import firestream.chat.message.Body;
16 | import firestream.chat.message.Sendable;
17 | import firestream.chat.types.ContactType;
18 | import firestream.chat.types.DeliveryReceiptType;
19 | import firestream.chat.types.InvitationType;
20 | import firestream.chat.types.PresenceType;
21 | import io.reactivex.Completable;
22 | import io.reactivex.Observable;
23 | import io.reactivex.Single;
24 | import io.reactivex.annotations.Nullable;
25 | import io.reactivex.functions.Consumer;
26 | import io.reactivex.functions.Predicate;
27 | import sdk.guru.common.Event;
28 |
29 | public interface IFireStream extends IAbstractChat {
30 |
31 | /**
32 | *
33 | * @param context
34 | * @param config
35 | * @param service - Firestore or Realtime service
36 | */
37 | void initialize(Context context, @Nullable FirestreamConfig config, FirebaseService service);
38 | void initialize(Context context, FirebaseService service);
39 | boolean isInitialized();
40 |
41 | /**
42 | * @return authenticated user
43 | */
44 | User currentUser();
45 |
46 | /**
47 | * @return id of authenticated user
48 | */
49 | String currentUserId();
50 |
51 | // Messages
52 |
53 | /**
54 | * Send a delivery receipt to a user. If delivery receipts are enabled,
55 | * a 'received' status will be returned as soon as a message type delivered
56 | * and then you can then manually send a 'read' status when the user
57 | * actually reads the message
58 | * @param userId - the recipient user id
59 | * @param type - the status getTypingStateType
60 | * @return - subscribe to get a completion, error update from the method
61 | */
62 | Completable sendDeliveryReceipt(String userId, DeliveryReceiptType type, String messageId);
63 | Completable sendDeliveryReceipt(String userId, DeliveryReceiptType type, String messageId, @Nullable Consumer newId);
64 |
65 | Completable sendInvitation(String userId, InvitationType type, String id);
66 | Completable sendInvitation(String userId, InvitationType type, String groupId, @Nullable Consumer newId);
67 |
68 | Completable send(String toUserId, Sendable sendable);
69 | Completable send(String toUserId, Sendable sendable, @Nullable Consumer newId);
70 |
71 | /**
72 | * Messages can always be deleted locally. Messages can only be deleted remotely
73 | * for recent messages. Specifically, when the client connects, it will add a
74 | * message listener to get an update for "new" messages. By default, we listen
75 | * to messages that were added after we last sent a message or a received delivery
76 | * receipt. This is the dateOfLastDeliveryReceipt. A client will only pick up
77 | * remote delivery receipts if the date of delivery is after this date.
78 | * @param sendable to be deleted
79 | * @return completion
80 | */
81 | Completable deleteSendable(Sendable sendable);
82 | Completable deleteSendable(String toUserId, Sendable sendable);
83 | Completable deleteSendable(String sendableId);
84 | Completable deleteSendable(String toUserId, String sendableId);
85 |
86 | Completable sendPresence(String userId, PresenceType type);
87 | Completable sendPresence(String userId, PresenceType type, @Nullable Consumer newId);
88 |
89 | Completable sendMessageWithText(String userId, String text);
90 | Completable sendMessageWithText(String userId, String text, @Nullable Consumer newId);
91 |
92 | Completable sendMessageWithBody(String userId, Body body);
93 | Completable sendMessageWithBody(String userId, Body body, @Nullable Consumer newId);
94 |
95 | /**
96 | * Send a typing indicator update to a user. This should be sent when the user
97 | * starts or stops typing
98 | * @param userId - the recipient user id
99 | * @return - subscribe to get a completion, error update from the method
100 | */
101 | Completable startTyping(String userId);
102 |
103 | /**
104 | * Send a typing indicator update to a user. This should be sent when the user
105 | * starts or stops typing
106 | * @param userId - the recipient user id
107 | * @return - subscribe to get a completion, error update from the method
108 | */
109 | Completable stopTyping(String userId);
110 | // Blocked
111 |
112 | Completable block(User user);
113 | Completable unblock(User user);
114 | List getBlocked();
115 | boolean isBlocked(User user);
116 |
117 | // Contacts
118 |
119 | Completable addContact(User user, ContactType type);
120 | Completable removeContact(User user);
121 | List getContacts();
122 |
123 | // Chats
124 |
125 | Single createChat(@Nullable String name, @Nullable String imageURL, User... users);
126 | Single createChat(@Nullable String name, @Nullable String imageURL, @Nullable Map customData, User... users);
127 | Single createChat(@Nullable String name, @Nullable String imageURL, List extends User> users);
128 | Single createChat(@Nullable String name, @Nullable String imageURL, @Nullable Map customData, List extends User> users);
129 |
130 | /**
131 | * Leave the chat. When you leave, you will be removed from the
132 | * chat's roster
133 | * @param chat to leave
134 | * @return completion
135 | */
136 | Completable leaveChat(IChat chat);
137 |
138 | /**
139 | * Join the chat. To join you must already be in the chat roster
140 | * @param chat to join
141 | * @return completion
142 | */
143 | Completable joinChat(IChat chat);
144 |
145 | IChat getChat(String chatId);
146 | List getChats();
147 |
148 | // Events
149 |
150 | MultiRelay> getChatEvents();
151 | MultiRelay> getBlockedEvents();
152 | MultiRelay> getContactEvents();
153 | Observable getConnectionEvents();
154 |
155 | Completable markReceived(String fromUserId, String sendableId);
156 | Completable markRead(String fromUserId, String sendableId);
157 |
158 | /**
159 | * If you set the
160 | * @param filter
161 | */
162 | void setMarkReceivedFilter(Predicate> filter);
163 |
164 | /**
165 | * Mute notifications for a user
166 | * @param user to mute
167 | * @return completion
168 | */
169 | Completable mute(User user);
170 |
171 | /**
172 | * Mute notifications until a future date
173 | * @param user to mute
174 | * @param until to mute until
175 | * @return completion
176 | */
177 | Completable mute(User user, Date until);
178 |
179 | /**
180 | * Unmute notifications for a user
181 | * @param user to unmute
182 | * @return completion
183 | */
184 | Completable unmute(User user);
185 |
186 | /**
187 | * Use this method to find out if the user is muted and until when
188 | * @param user to check
189 | * @return date or null if not muted
190 | */
191 | Date mutedUntil(User user);
192 |
193 | /**
194 | * Is a user muted?
195 | * @param user to mute
196 | * @return true / false
197 | */
198 | boolean muted(User user);
199 |
200 | /**
201 | * Get the current FireStream configuration
202 | * @return
203 | */
204 | FirestreamConfig getConfig();
205 |
206 | /**
207 | * Get the current Firebase service
208 | * @return
209 | */
210 | FirebaseService getFirebaseService();
211 | }
212 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/BaseMessage.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import java.util.Date;
4 |
5 | import firestream.chat.types.SendableType;
6 |
7 | public class BaseMessage {
8 |
9 | protected String from;
10 | protected Date date = new Date();
11 | protected Body body = new Body();
12 | protected String type;
13 |
14 | public BaseMessage() {
15 |
16 | }
17 |
18 | public String getFrom() {
19 | return from;
20 | }
21 |
22 | public void setFrom(String from) {
23 | this.from = from;
24 | }
25 |
26 | public Date getDate() {
27 | return date;
28 | }
29 |
30 | public void setDate(Date date) {
31 | this.date = date;
32 | }
33 |
34 | public Body getBody() {
35 | return body;
36 | }
37 |
38 | public void setBody(Body body) {
39 | this.body = body;
40 | }
41 |
42 | public String getType() {
43 | return type;
44 | }
45 |
46 | public void setType(String type) {
47 | this.type = type;
48 | }
49 |
50 | public boolean isType(SendableType type) {
51 | return getType().equals(type.get());
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/Body.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import firestream.chat.firebase.service.Keys;
7 | import firestream.chat.types.BaseType;
8 |
9 | public class Body {
10 |
11 | protected BaseType type;
12 | protected Map values;
13 |
14 | public Body() {
15 | values = new HashMap<>();
16 | type = BaseType.none();
17 | }
18 |
19 | public Body(Map data) {
20 | Object type = data.get(Keys.Type);
21 | if (type instanceof String) {
22 | setType((String) type);
23 | }
24 | data.remove(Keys.Type);
25 | values = data;
26 | }
27 |
28 | public BaseType getType() {
29 | return type;
30 | }
31 |
32 | public void setType(BaseType type) {
33 | this.type = type;
34 | }
35 |
36 | public void setType(String type) {
37 | this.type = new BaseType(type);
38 | }
39 |
40 | public String stringForKey(String key) {
41 | Object value = values.get(key);
42 | if (value instanceof String) {
43 | return (String) value;
44 | }
45 | return null;
46 | }
47 |
48 | public Object get(String key) {
49 | return values.get(key);
50 | }
51 |
52 | public void put(String key, Object value){
53 | values.put(key, value);
54 | }
55 |
56 | public Map get() {
57 | Map data = new HashMap<>(values);
58 | data.put(Keys.Type, type.get());
59 | return data;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/CustomMessage.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | public class CustomMessage extends Message {
4 |
5 | public CustomMessage (Body body) {
6 | super();
7 | this.body = body;
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/DeliveryReceipt.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import firestream.chat.types.DeliveryReceiptType;
4 | import firestream.chat.types.SendableType;
5 |
6 | public class DeliveryReceipt extends Sendable {
7 |
8 | public static String MessageId = "id";
9 |
10 | public DeliveryReceipt() {
11 | type = SendableType.DeliveryReceipt;
12 | }
13 |
14 | public DeliveryReceipt(DeliveryReceiptType type, String messageUid) {
15 | this();
16 | setBodyType(type);
17 | body.put(MessageId, messageUid);
18 | }
19 |
20 | public String getMessageId() {
21 | return getBodyString(MessageId);
22 | }
23 |
24 | public DeliveryReceiptType getDeliveryReceiptType() {
25 | return new DeliveryReceiptType(super.getBodyType());
26 | }
27 |
28 | public static DeliveryReceipt fromSendable(Sendable sendable) {
29 | DeliveryReceipt deliveryReceipt = new DeliveryReceipt();
30 | sendable.copyTo(deliveryReceipt);
31 | return deliveryReceipt;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/Invitation.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import firestream.chat.chat.Chat;
4 | import firestream.chat.namespace.Fire;
5 | import io.reactivex.Completable;
6 |
7 | import firestream.chat.types.InvitationType;
8 | import firestream.chat.types.SendableType;
9 |
10 | public class Invitation extends Sendable {
11 |
12 | public static String ChatId = "id";
13 |
14 | public Invitation() {
15 | type = SendableType.Invitation;
16 | }
17 |
18 | public Invitation(InvitationType type, String chatId) {
19 | this();
20 | super.setBodyType(type);
21 | body.put(ChatId, chatId);
22 | }
23 |
24 | public InvitationType getBodyType() {
25 | return new InvitationType(super.getBodyType());
26 | }
27 |
28 | public String getChatId() {
29 | return getBodyString(ChatId);
30 | }
31 |
32 | public Completable accept() {
33 | if (getBodyType().equals(InvitationType.chat())) {
34 | try {
35 | return Fire.stream().joinChat(new Chat(getChatId()));
36 | } catch (Exception e) {
37 | return Completable.error(e);
38 | }
39 | }
40 | return Completable.complete();
41 | }
42 |
43 | public static Invitation fromSendable(Sendable sendable) {
44 | Invitation invitation = new Invitation();
45 | sendable.copyTo(invitation);
46 | return invitation;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/Message.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import firestream.chat.types.SendableType;
4 |
5 | public class Message extends Sendable {
6 |
7 | public Message () {
8 | type = SendableType.Message;
9 | }
10 |
11 | public Message (Body body) {
12 | this();
13 | this.body = body;
14 | }
15 |
16 | public Message (String id, Body body) {
17 | this(body);
18 | this.id = id;
19 | }
20 |
21 | public static Message fromSendable(Sendable sendable) {
22 | Message message = new Message();
23 | sendable.copyTo(message);
24 | return message;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/Presence.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import firestream.chat.types.PresenceType;
4 | import firestream.chat.types.SendableType;
5 |
6 | public class Presence extends Sendable {
7 |
8 | public static String PresenceKey = "presence";
9 |
10 | public Presence() {
11 | type = SendableType.Presence;
12 | }
13 |
14 | public Presence(PresenceType type) {
15 | this();
16 | super.setBodyType(type);
17 | }
18 |
19 | public PresenceType getBodyType() {
20 | return new PresenceType(super.getBodyType());
21 | }
22 |
23 | public static Presence fromSendable(Sendable sendable) {
24 | Presence presence = new Presence();
25 | sendable.copyTo(presence);
26 | return presence;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/Sendable.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import org.pmw.tinylog.Logger;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Date;
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | import firestream.chat.firebase.service.Keys;
12 | import firestream.chat.namespace.Fire;
13 | import firestream.chat.types.BaseType;
14 |
15 | public class Sendable extends BaseMessage {
16 |
17 | protected String id;
18 |
19 | public Sendable() {
20 | from = Fire.stream().currentUserId();
21 | }
22 |
23 | public Sendable(String sendableId, String fromUserId) {
24 | from = fromUserId;
25 | id = sendableId;
26 | }
27 |
28 | public Sendable(String id, Map data) {
29 | this.id = id;
30 |
31 | if (data.get(Keys.From) instanceof String) {
32 | from = (String) data.get(Keys.From);
33 | }
34 | if (data.get(Keys.Date) instanceof Date) {
35 | date = (Date) data.get(Keys.Date);
36 | }
37 | if (data.get(Keys.Body) instanceof Body) {
38 | body = (Body) data.get(Keys.Body);
39 | }
40 | if (data.get(Keys.Type) instanceof String) {
41 | type = (String) data.get(Keys.Type);
42 | }
43 | }
44 |
45 | public boolean valid() {
46 | return from != null && date != null && body != null && type != null;
47 | }
48 |
49 | public void setBodyType(BaseType type) {
50 | body.setType(type.get());
51 | }
52 |
53 | public BaseType getBodyType() {
54 | return body.getType();
55 | }
56 |
57 | public String getBodyString(String key) {
58 | return body.stringForKey(key);
59 | }
60 |
61 | public void copyTo(Sendable sendable) {
62 | sendable.setId(id);
63 | sendable.setFrom(from);
64 | sendable.setBody(body);
65 | sendable.setDate(date);
66 | }
67 |
68 | public BaseMessage toBaseMessage() {
69 | BaseMessage message = new BaseMessage();
70 | message.from = from;
71 | message.body = body;
72 | message.date = date;
73 | message.type = type;
74 | return message;
75 | }
76 |
77 | public Map toData() {
78 | Map data = new HashMap<>();
79 | data.put(Keys.From, from);
80 | data.put(Keys.Body, body.get());
81 | data.put(Keys.Date, Fire.stream().getFirebaseService().core.timestamp());
82 | data.put(Keys.Type, type);
83 | return data;
84 | }
85 |
86 | public static class Converter {
87 |
88 | protected Class clazz;
89 |
90 | public Converter(Class clazz) {
91 | this.clazz = clazz;
92 | }
93 |
94 | public T convert(Sendable s) {
95 | try {
96 | T instance = clazz.newInstance();
97 | s.copyTo(instance);
98 | return instance;
99 | } catch (Exception e) {
100 | return null;
101 | }
102 | }
103 |
104 | public List convert(List sendables) {
105 | List list = new ArrayList<>();
106 | for (Sendable sendable: sendables) {
107 | if (clazz.isInstance(sendable)) {
108 | list.add(convert(sendable));
109 | }
110 | }
111 | return list;
112 | }
113 |
114 | }
115 |
116 | public Message toMessage() {
117 | return new Converter<>(Message.class).convert(this);
118 | }
119 |
120 | public TypingState toTypingState() {
121 | return new Converter<>(TypingState.class).convert(this);
122 | }
123 |
124 | public DeliveryReceipt toDeliveryReceipt() {
125 | return new Converter<>(DeliveryReceipt.class).convert(this);
126 | }
127 |
128 | public Invitation toInvitation() {
129 | return new Converter<>(Invitation.class).convert(this);
130 | }
131 |
132 | public Presence toPresence() {
133 | return new Converter<>(Presence.class).convert(this);
134 | }
135 |
136 | public TextMessage toTextMessage() {
137 | return new Converter<>(TextMessage.class).convert(this);
138 | }
139 |
140 | public void setId(String id) {
141 | this.id = id;
142 | }
143 |
144 | public String getId() {
145 | return id;
146 | }
147 |
148 | public boolean equals(Sendable message) {
149 | return getId().equals(message.getId());
150 | }
151 |
152 | public static List debugList(List list) {
153 | List text = new ArrayList<>();
154 | for(Sendable m: list) {
155 | String t = m.getDate() + " : " + m.getId() + " - " + m.getBody().get().toString();
156 | text.add(t);
157 | Logger.debug(t);
158 | }
159 | return text;
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/TextMessage.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | public class TextMessage extends Message {
4 |
5 | public static String TextKey = "text";
6 |
7 | public TextMessage() {
8 |
9 | }
10 |
11 | public TextMessage(String text) {
12 | body.put(TextKey, text);
13 | }
14 |
15 | public String getText() {
16 | return (String) body.get(TextKey);
17 | }
18 |
19 | public static TextMessage fromSendable(Sendable sendable) {
20 | TextMessage message = new TextMessage();
21 | sendable.copyTo(message);
22 | return message;
23 | }
24 |
25 |
26 | }
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/message/TypingState.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.message;
2 |
3 | import firestream.chat.types.SendableType;
4 | import firestream.chat.types.TypingStateType;
5 |
6 | public class TypingState extends Sendable {
7 |
8 | public TypingState() {
9 | type = SendableType.TypingState;
10 | }
11 |
12 | public TypingState(TypingStateType type) {
13 | this();
14 | setBodyType(type);
15 | }
16 |
17 | public TypingStateType getTypingStateType() {
18 | return new TypingStateType(super.getBodyType());
19 | }
20 |
21 | public static TypingState fromSendable(Sendable sendable) {
22 | TypingState typingState = new TypingState();
23 | sendable.copyTo(typingState);
24 | return typingState;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/namespace/Fire.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.namespace;
2 |
3 | import firestream.chat.FireStream;
4 | import firestream.chat.interfaces.IFireStream;
5 |
6 | /**
7 | * Just a convenience method to make invocations of FireStream more compact
8 | * Fire.fly.sendMessage()
9 | * instead of
10 | * FireStream.shared().sendMessage()
11 | */
12 | public class Fire {
13 | public static FireStream internal() {
14 | return FireStream.shared();
15 | }
16 | public static IFireStream stream() {
17 | return FireStream.shared();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/namespace/FireStreamMessage.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.namespace;
2 |
3 | import firestream.chat.message.Message;
4 | import firestream.chat.message.Sendable;
5 |
6 | public class FireStreamMessage extends Message {
7 |
8 | public static FireStreamMessage fromMessage(Message message) {
9 | FireStreamMessage firestreamMessage = new FireStreamMessage();
10 | message.copyTo(firestreamMessage);
11 | return firestreamMessage;
12 | }
13 |
14 | public static FireStreamMessage fromSendable(Sendable sendable) {
15 | FireStreamMessage message = new FireStreamMessage();
16 | sendable.copyTo(message);
17 | return message;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/namespace/FireStreamUser.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.namespace;
2 |
3 | import firestream.chat.chat.User;
4 | import firestream.chat.types.RoleType;
5 |
6 | public class FireStreamUser extends User {
7 |
8 | public FireStreamUser(String id) {
9 | super(id);
10 | }
11 |
12 | public FireStreamUser(String id, RoleType roleType) {
13 | super(id, roleType);
14 | }
15 |
16 | public static FireStreamUser fromUser(User user) {
17 | FireStreamUser mu = new FireStreamUser(user.getId());
18 | mu.setContactType(user.getContactType());
19 | mu.setRoleType(user.getRoleType());
20 | return mu;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/Result.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test;
2 |
3 | public class Result {
4 |
5 | public String errorMessage;
6 | public Test test;
7 |
8 | public Result(Test test, String errorMessage) {
9 | this.test = test;
10 | this.errorMessage = errorMessage;
11 | }
12 |
13 | public static Result success(Test test) {
14 | return new Result(test, null);
15 | }
16 |
17 | public static Result failure(Test test, String message) {
18 | return new Result(test, message);
19 | }
20 |
21 | public boolean isSuccess() {
22 | return errorMessage == null;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/Test.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test;
2 |
3 | import sdk.guru.common.DisposableMap;
4 | import io.reactivex.Emitter;
5 | import io.reactivex.Observable;
6 | import io.reactivex.functions.Consumer;
7 |
8 | public abstract class Test implements Consumer {
9 |
10 | protected String name;
11 | protected DisposableMap dm = new DisposableMap();
12 | protected Emitter emitter;
13 | protected boolean failed = false;
14 |
15 | public Test(String name) {
16 | this.name = name;
17 | }
18 |
19 | public abstract Observable run();
20 |
21 | public void failure(String message) {
22 | if (emitter != null) {
23 | emitter.onNext(Result.failure(this, message));
24 | }
25 | failed = true;
26 | }
27 |
28 | public void complete() {
29 | if (emitter != null) {
30 | if (!failed) {
31 | emitter.onNext(Result.success(this));
32 | }
33 | emitter.onComplete();
34 | }
35 | dispose();
36 | }
37 |
38 | public void dispose() {
39 | dm.dispose();
40 | }
41 |
42 | public void manage(Emitter emitter) {
43 | this.emitter = emitter;
44 | }
45 |
46 | @Override
47 | public void accept(Throwable throwable) throws Exception {
48 | failure(throwable.getLocalizedMessage());
49 | complete();
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/TestScript.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test;
2 |
3 | import android.content.Context;
4 |
5 | import org.pmw.tinylog.Logger;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import firestream.chat.FirestreamConfig;
11 | import firestream.chat.chat.User;
12 | import firestream.chat.events.ConnectionEvent;
13 | import firestream.chat.firebase.service.FirebaseService;
14 | import firestream.chat.interfaces.IFireStream;
15 | import firestream.chat.namespace.Fire;
16 | import firestream.chat.test.chat.CreateChatTest;
17 | import firestream.chat.test.chat.MessageChatTest;
18 | import firestream.chat.test.chat.ModifyChatTest;
19 | import firestream.chat.test.contact.AddContactTest;
20 | import firestream.chat.test.contact.GetContactAddedTest;
21 | import firestream.chat.test.contact.GetContactRemovedTest;
22 | import io.reactivex.Observable;
23 | import io.reactivex.disposables.Disposable;
24 | import sdk.guru.common.DisposableMap;
25 |
26 | public class TestScript {
27 |
28 | DisposableMap dm = new DisposableMap();
29 |
30 | public ArrayList tests = new ArrayList<>();
31 |
32 | public ArrayList results = new ArrayList<>();
33 |
34 | public Runnable onFinish = null;
35 |
36 | public TestScript(FirebaseService service, Context context, String rootPath) {
37 |
38 | FirestreamConfig config = new FirestreamConfig<>(Fire.stream());
39 | try {
40 | config.setRoot(rootPath);
41 | } catch (Exception e) {
42 | e.printStackTrace();
43 | }
44 | config.deleteMessagesOnReceipt = false;
45 | config.debugEnabled = true;
46 |
47 | Fire.internal().initialize(context, config, service);
48 |
49 | tests.add(new AddContactTest());
50 | tests.add(new GetContactAddedTest());
51 | // tests.add(new DeleteContactTest());
52 |
53 | tests.add(new GetContactRemovedTest());
54 | tests.add(new CreateChatTest());
55 | tests.add(new ModifyChatTest());
56 | tests.add(new MessageChatTest());
57 |
58 | Disposable d = Fire.stream().getConnectionEvents().subscribe(connectionEvent -> {
59 | if (connectionEvent.getType() == ConnectionEvent.Type.DidConnect) {
60 | start();
61 | }
62 | if (connectionEvent.getType() == ConnectionEvent.Type.WillDisconnect) {
63 | stop();
64 | }
65 | });
66 |
67 | }
68 |
69 | public void start() {
70 |
71 | ArrayList> testObservables = new ArrayList<>();
72 | for (Test test: tests) {
73 | testObservables.add(test.run());
74 | }
75 |
76 | dm.add(Observable.concat(testObservables).doOnComplete(() -> {
77 |
78 | String output = "\n";
79 |
80 | for (Result result : results) {
81 | if (result.isSuccess()) {
82 | output += result.test.name + " - success";
83 | } else {
84 | output += result.test.name + " - fail: " + result.errorMessage;
85 | }
86 | output += "\n";
87 | }
88 |
89 | log(output);
90 | }).subscribe(result -> {
91 | results.add(result);
92 | }));
93 | }
94 |
95 | public void stop() {
96 | dm.dispose();
97 | log("Stop");
98 | if (onFinish != null) {
99 | onFinish.run();
100 | }
101 | }
102 |
103 | public void log(String text) {
104 | Logger.debug(text);
105 | }
106 |
107 | public static User testUser1() {
108 | return new User("6TB34PbMqdU67KHvIuGrekMCIOk2");
109 | }
110 |
111 | public static User testUser2() {
112 | return new User("9tJUx1iT5LQ1bC1J952No6sNZjZ2");
113 | }
114 |
115 | public static User testUser3() {
116 | return new User("NX6mGPCkR3NcNiJJxBzNrsR2Anz2");
117 | }
118 |
119 | public static List usersNotMe() {
120 | ArrayList users = new ArrayList<>();
121 | for (User u: users()) {
122 | if (!u.getId().equals(Fire.stream().currentUserId())) {
123 | users.add(u);
124 | }
125 | }
126 | return users;
127 | }
128 |
129 | public static ArrayList users() {
130 | ArrayList users = new ArrayList<>();
131 | users.add(TestScript.testUser1());
132 | users.add(TestScript.testUser2());
133 | users.add(TestScript.testUser3());
134 | return users;
135 | }
136 |
137 | public static void run(FirebaseService service, Context context, String rootPath) {
138 | new TestScript(service, context, rootPath);
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/chat/CreateChatTest.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test.chat;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.List;
6 |
7 | import firestream.chat.chat.User;
8 | import firestream.chat.namespace.Fire;
9 | import firestream.chat.test.Result;
10 | import firestream.chat.test.Test;
11 | import firestream.chat.test.TestScript;
12 | import firestream.chat.types.RoleType;
13 | import io.reactivex.Observable;
14 | import io.reactivex.ObservableOnSubscribe;
15 | import sdk.guru.common.RX;
16 |
17 | public class CreateChatTest extends Test {
18 |
19 | public CreateChatTest() {
20 | super("CreateChat");
21 | }
22 |
23 | /**
24 | * We ge:
25 | * - Creating a chat
26 | * - Name correct
27 | * - Image URL correct
28 | * - Custom data correct
29 | * - Users and roles correct
30 | */
31 | @Override
32 | public Observable run() {
33 | return Observable.create((ObservableOnSubscribe) emitter -> {
34 | manage(emitter);
35 | final List users = users();
36 | dm.add(Fire.stream().createChat(chatName(), chatImageURL(), customData(), users).subscribe(chat -> {
37 | // Check the name matches
38 | if (!chat.getName().equals(chatName())) {
39 | failure("Name mismatch");
40 | }
41 |
42 | if (!chat.getImageURL().equals(chatImageURL())) {
43 | failure("Image url mismatch");
44 | }
45 |
46 | // Check the ID type set
47 | if (chat.getId() == null || chat.getId().isEmpty()) {
48 | failure("Chat id not set");
49 | }
50 |
51 | if (chat.getCustomData() != null) {
52 | if (!chat.getCustomData().equals(customData())) {
53 | failure("Custom data value mismatch");
54 | }
55 | } else {
56 | failure("Custom data type null");
57 | }
58 |
59 | // Check the users
60 | for (User user: chat.getUsers()) {
61 | for (User u: users) {
62 | if (user.equals(u) && !user.isMe()) {
63 | if (!user.equalsRoleType(u)) {
64 | failure("Role type mismatch");
65 | }
66 | }
67 | }
68 | if (user.isMe() && !user.equalsRoleType(RoleType.owner())) {
69 | failure("Creator user not owner");
70 | }
71 | }
72 |
73 | complete();
74 |
75 | }, this));
76 | }).subscribeOn(RX.io());
77 | }
78 |
79 | public static String chatName() {
80 | return "Test";
81 | }
82 |
83 | public static String chatImageURL() {
84 | return "https://chatsdk.co/wp-content/uploads/2017/01/image_message-407x389.jpg";
85 | }
86 |
87 | public static HashMap customData() {
88 | HashMap data = new HashMap<>();
89 |
90 | data.put("TestKey", "TestValue");
91 | data.put("Key2", 999L);
92 |
93 | return data;
94 | }
95 |
96 | public static List users() {
97 | ArrayList users = new ArrayList<>(TestScript.usersNotMe());
98 | for (User u: users) {
99 | if (u.equals(TestScript.testUser1())) {
100 | u.setRoleType(RoleType.watcher());
101 | }
102 | if (u.equals(TestScript.testUser2())) {
103 | u.setRoleType(RoleType.admin());
104 | }
105 | if (u.equals(TestScript.testUser3())) {
106 | u.setRoleType(RoleType.banned());
107 | }
108 | }
109 | return users;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/contact/AddContactTest.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test.contact;
2 |
3 | import java.util.List;
4 |
5 | import firestream.chat.chat.User;
6 | import firestream.chat.namespace.Fire;
7 | import firestream.chat.test.Result;
8 | import firestream.chat.test.Test;
9 | import firestream.chat.test.TestScript;
10 | import firestream.chat.types.ContactType;
11 | import io.reactivex.Observable;
12 | import io.reactivex.ObservableOnSubscribe;
13 | import sdk.guru.common.RX;
14 |
15 | public class AddContactTest extends Test {
16 |
17 | public AddContactTest() {
18 | super("AddContact");
19 | }
20 |
21 | @Override
22 | public Observable run() {
23 | return Observable.create((ObservableOnSubscribe) emitter -> {
24 | manage(emitter);
25 | User user = TestScript.testUser1();
26 | dm.add(Fire.stream().addContact(user, ContactType.contact()).subscribe(() -> {
27 | // Check that it exists in the contact list
28 | List contacts = Fire.stream().getContacts();
29 |
30 | if (contacts.size() != 1) {
31 | failure("Contact size must be 1");
32 | } else if (!contacts.get(0).equals(user)) {
33 | failure("Correct user not added to contacts");
34 | } else {
35 | complete();
36 | }
37 | }, this));
38 | }).subscribeOn(RX.io());
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/contact/DeleteContactTest.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test.contact;
2 |
3 | import java.util.List;
4 |
5 | import firestream.chat.chat.User;
6 | import firestream.chat.namespace.Fire;
7 | import firestream.chat.test.Result;
8 | import firestream.chat.test.Test;
9 | import firestream.chat.test.TestScript;
10 | import io.reactivex.Observable;
11 | import io.reactivex.ObservableOnSubscribe;
12 | import sdk.guru.common.RX;
13 |
14 | public class DeleteContactTest extends Test {
15 |
16 | public DeleteContactTest() {
17 | super("DeleteContact");
18 | }
19 |
20 | @Override
21 | public Observable run() {
22 | return Observable.create((ObservableOnSubscribe) emitter -> {
23 | // Remove the contact
24 | manage(emitter);
25 | dm.add(Fire.stream().removeContact(TestScript.testUser1()).subscribe(() -> {
26 | // Check that it exists in the contact list
27 | List contacts = Fire.stream().getContacts();
28 |
29 | if (contacts.size() != 0) {
30 | failure("Contact size must be 0");
31 | } else {
32 | complete();
33 | }
34 |
35 | }, this));
36 | }).subscribeOn(RX.io());
37 | }}
38 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/contact/GetContactAddedTest.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test.contact;
2 |
3 | import firestream.chat.namespace.Fire;
4 | import io.reactivex.Observable;
5 | import firestream.chat.test.Result;
6 | import firestream.chat.test.Test;
7 | import firestream.chat.test.TestScript;
8 |
9 | public class GetContactAddedTest extends Test {
10 |
11 | public GetContactAddedTest() {
12 | super("GetContactAdded");
13 | }
14 |
15 | @Override
16 | public Observable run() {
17 | return Observable.create(emitter -> {
18 | manage(emitter);
19 | dm.add(Fire.stream().getContactEvents().currentAndNewEvents().subscribe(userEvent -> {
20 | if (userEvent.isAdded()) {
21 | if (userEvent.get().equals(TestScript.testUser1())) {
22 | complete();
23 | } else {
24 | failure("Wrong user added");
25 | }
26 | } else {
27 | failure("No contact added");
28 | }
29 | complete();
30 | }, this));
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/test/contact/GetContactRemovedTest.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.test.contact;
2 |
3 | import firestream.chat.namespace.Fire;
4 | import io.reactivex.Observable;
5 | import io.reactivex.ObservableOnSubscribe;
6 | import firestream.chat.test.Result;
7 | import firestream.chat.test.Test;
8 | import firestream.chat.test.TestScript;
9 | import sdk.guru.common.RX;
10 |
11 | public class GetContactRemovedTest extends Test {
12 |
13 | public GetContactRemovedTest() {
14 | super("GetContactRemoved");
15 | }
16 |
17 | @Override
18 | public Observable run() {
19 | return Observable.create((ObservableOnSubscribe) emitter -> {
20 | manage(emitter);
21 | dm.add(Fire.stream().getContactEvents().currentAndNewEvents().subscribe(userEvent -> {
22 | if (userEvent.isRemoved()) {
23 | if (userEvent.get().equals(TestScript.testUser1())) {
24 | complete();
25 | } else {
26 | failure("Wrong user removed");
27 | }
28 | } else {
29 | failure("No contact removed");
30 | }
31 | complete();
32 | }, this));
33 | }).subscribeOn(RX.io());
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/BaseType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | public class BaseType {
4 |
5 | protected String type;
6 |
7 | public BaseType(String type) {
8 | if (type != null) {
9 | this.type = type;
10 | } else {
11 | this.type = "";
12 | }
13 | }
14 |
15 | public BaseType(BaseType type) {
16 | this.type = type.get();
17 | }
18 |
19 | public String get() {
20 | return type;
21 | }
22 |
23 | public boolean equals(BaseType type) {
24 | return this.get().equals(type.get());
25 | }
26 |
27 | public static BaseType none() {
28 | return new BaseType("");
29 | }
30 |
31 | public boolean is(BaseType type) {
32 | return equals(type);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/ContactType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import firestream.chat.firebase.service.Keys;
7 |
8 | public class ContactType extends BaseType {
9 |
10 | /**
11 | * They have full access rights, can add and remove admins
12 | */
13 | public static String Contact = "contact";
14 |
15 | public ContactType(String type) {
16 | super(type);
17 | }
18 |
19 | public ContactType(BaseType type) {
20 | super(type);
21 | }
22 |
23 | public static ContactType contact() {
24 | return new ContactType(Contact);
25 | }
26 |
27 | public Map data () {
28 | Map data = new HashMap<>();
29 | data.put(Keys.Type, get());
30 | return data;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/DeliveryReceiptType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | public class DeliveryReceiptType extends BaseType {
4 |
5 | public static String Received = "received";
6 | public static String Read = "read";
7 |
8 | public DeliveryReceiptType (String type) {
9 | super(type);
10 | }
11 |
12 | public DeliveryReceiptType (BaseType type) {
13 | super(type);
14 | }
15 |
16 | public static DeliveryReceiptType received() {
17 | return new DeliveryReceiptType(Received);
18 | }
19 |
20 | public static DeliveryReceiptType read() {
21 | return new DeliveryReceiptType(Read);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/InvitationType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | public class InvitationType extends BaseType {
4 |
5 | public static String Chat = "chat";
6 |
7 | public InvitationType(String type) {
8 | super(type);
9 | }
10 |
11 | public InvitationType(BaseType type) {
12 | super(type);
13 | }
14 |
15 | public static InvitationType chat() {
16 | return new InvitationType(Chat);
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/PresenceType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | public class PresenceType extends BaseType {
4 |
5 | public static String Unavailable = "unavailable";
6 | public static String Busy = "busy";
7 | public static String ExtendedAway = "xa";
8 | public static String Available = "available";
9 |
10 | public PresenceType(String type) {
11 | super(type);
12 | }
13 |
14 | public PresenceType(BaseType type) {
15 | super(type);
16 | }
17 |
18 | public static PresenceType unavailable() {
19 | return new PresenceType(Unavailable);
20 | }
21 |
22 | public static PresenceType busy() {
23 | return new PresenceType(Busy);
24 | }
25 |
26 | public static PresenceType extendedAway() {
27 | return new PresenceType(ExtendedAway);
28 | }
29 |
30 | public static PresenceType available() {
31 | return new PresenceType(Available);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/RoleType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | import firestream.chat.R;
9 | import firestream.chat.firebase.service.Keys;
10 | import firestream.chat.namespace.Fire;
11 |
12 | public class RoleType extends BaseType {
13 |
14 | /**
15 | * They have full access rights, can add and remove admins
16 | */
17 | public static String Owner = "owner";
18 |
19 | /**
20 | * An admin can change the status of any lower member, also update the name, image and custom data
21 | */
22 | public static String Admin = "admin";
23 |
24 | /**
25 | * Standard member of the chat, has write access but can't change roles
26 | */
27 | public static String Member = "member";
28 |
29 | /**
30 | * Read-only access
31 | */
32 | public static String Watcher = "watcher";
33 |
34 | /**
35 | * Cannot access the chat, cannot be added
36 | */
37 |
38 | public static String Banned = "banned";
39 |
40 | public RoleType(String type) {
41 | super(type);
42 | }
43 |
44 | public RoleType(BaseType type) {
45 | super(type);
46 | }
47 |
48 | public static RoleType owner() {
49 | return new RoleType(Owner);
50 | }
51 |
52 | public static RoleType admin() {
53 | return new RoleType(Admin);
54 | }
55 |
56 | public static RoleType member() {
57 | return new RoleType(Member);
58 | }
59 |
60 | public static RoleType watcher() {
61 | return new RoleType(Watcher);
62 | }
63 |
64 | public static RoleType banned() {
65 | return new RoleType(Banned);
66 | }
67 |
68 | public Map data () {
69 | Map data = new HashMap<>();
70 | data.put(Keys.Role, get());
71 | return data;
72 | }
73 |
74 | public boolean ge(RoleType permission) {
75 | return toLevel() <= permission.toLevel();
76 | }
77 |
78 | protected int toLevel() {
79 | if (type != null) {
80 | if (type.equals(Owner)) {
81 | return 0;
82 | }
83 | if (type.equals(Admin)) {
84 | return 1;
85 | }
86 | if (type.equals(Member)) {
87 | return 2;
88 | }
89 | if (type.equals(Watcher)) {
90 | return 3;
91 | }
92 | if (type.equals(Banned)) {
93 | return 4;
94 | }
95 | }
96 | return 5;
97 | }
98 |
99 | public String stringValue() {
100 | int resId = -1;
101 |
102 | if (equals(RoleType.owner())) {
103 | resId = R.string.owner;
104 | }
105 | if (equals(RoleType.admin())) {
106 | resId = R.string.admin;
107 | }
108 | if (equals(RoleType.member())) {
109 | resId = R.string.member;
110 | }
111 | if (equals(RoleType.watcher())) {
112 | resId = R.string.watcher;
113 | }
114 | if (equals(RoleType.banned())) {
115 | resId = R.string.banned;
116 | }
117 |
118 | if (resId != -1) {
119 | return Fire.internal().context().getString(resId);
120 | }
121 | return null;
122 | }
123 |
124 | public static List allStringValues() {
125 | return allStringValuesExcluding();
126 | }
127 |
128 | public static List allStringValuesExcluding(RoleType... excluding) {
129 | return rolesToStringValues(allExcluding(excluding));
130 | }
131 |
132 | public static List all() {
133 | return allExcluding();
134 | }
135 |
136 | public static List allExcluding(RoleType... excluding) {
137 | List list = new ArrayList() {{
138 | add(RoleType.owner());
139 | add(RoleType.admin());
140 | add(RoleType.member());
141 | add(RoleType.watcher());
142 | add(RoleType.banned());
143 | }};
144 | for (RoleType rt: excluding) {
145 | list.remove(rt);
146 | }
147 | return list;
148 | }
149 |
150 | public static List rolesToStringValues(List roleTypes) {
151 | List stringValues = new ArrayList<>();
152 |
153 | for (RoleType rt: roleTypes) {
154 | stringValues.add(rt.stringValue());
155 | }
156 |
157 | return stringValues;
158 | }
159 |
160 | public static Map reverseMap() {
161 | Map map = new HashMap<>();
162 | for (RoleType rt: all()) {
163 | map.put(rt.stringValue(), rt);
164 | }
165 | return map;
166 | }
167 |
168 | @Override
169 | public boolean equals(Object roleType) {
170 | return roleType instanceof RoleType && get().equals(((RoleType)roleType).get());
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/SendableType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | public class SendableType extends BaseType {
4 |
5 | public static String Message = "message";
6 | public static String DeliveryReceipt = "receipt";
7 | public static String TypingState = "typing";
8 | public static String Presence = "presence";
9 | public static String Invitation = "invitation";
10 |
11 | public SendableType(String type) {
12 | super(type);
13 | }
14 |
15 | public SendableType(BaseType type) {
16 | super(type);
17 | }
18 |
19 | public static SendableType message() {
20 | return new SendableType(Message);
21 | }
22 |
23 | public static SendableType deliveryReceipt() {
24 | return new SendableType(DeliveryReceipt);
25 | }
26 |
27 | public static SendableType typingState() {
28 | return new SendableType(TypingState);
29 | }
30 |
31 | public static SendableType presence() {
32 | return new SendableType(Presence);
33 | }
34 |
35 | public static SendableType invitation() {
36 | return new SendableType(Invitation);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/types/TypingStateType.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.types;
2 |
3 | public class TypingStateType extends BaseType {
4 |
5 | public static String Typing = "typing";
6 |
7 | public TypingStateType(String type) {
8 | super(type);
9 | }
10 |
11 | public TypingStateType(BaseType type) {
12 | super(type);
13 | }
14 |
15 | public static TypingStateType typing() {
16 | return new TypingStateType(Typing);
17 | }
18 |
19 | public static TypingStateType none() {
20 | return new TypingStateType("");
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/util/Typing.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.util;
2 |
3 | public class Typing {
4 | public boolean isTyping = false;
5 | public String sendableId;
6 | }
7 |
--------------------------------------------------------------------------------
/firestream/src/main/java/firestream/chat/util/TypingMap.java:
--------------------------------------------------------------------------------
1 | package firestream.chat.util;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class TypingMap {
7 |
8 | Map typingMap = new HashMap<>();
9 |
10 | public Typing get(String userId) {
11 | Typing typing = typingMap.get(userId);
12 | if (typing == null) {
13 | typing = new Typing();
14 | typingMap.put(userId, typing);
15 | }
16 | return typing;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/firestream/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Firestream for Firestore
3 | Snapshot is null
4 | Firebase must be authenticated to connect
5 | You need to call FireStream.api().initialize(…)
6 | Null data returned
7 | No value present
8 | DocumentReference expected but path points to collection
9 | CollectionReference expected but path points to document
10 | You must be a group owner to perform this action
11 | You must be a group admin to perform this action
12 | You must be a group member to perform this action
13 | Write cancelled
14 | Invalid path, path can only contain letters, numbers and underscores
15 | Remove the other users before you can delete the group
16 |
17 | Owner
18 | Admin
19 | Member
20 | Watcher
21 | Banned
22 |
23 |
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx6g
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | org.gradle.parallel=true
18 |
19 | android.useAndroidX=true
20 | android.enableJetifier=true
21 |
22 | MIN_SDK = 16
23 | ANDROID_BUILD_TARGET_SDK_VERSION = 25
24 | ANDROID_COMPILE_SDK_VERSION = 28
25 | ANDROID_SUPPORT_VERSION = 28.0.3
26 |
27 | CHAT_SDK_VERSION = 5.0.0rc7
28 | CHAT_SDK_DEMO_VERSION = 5.0.0rc7
29 |
30 | CHAT_SDK_BUILD_NUMBER = 050000
31 | CHAT_SDK_GROUP = sdk.chat
32 | BINTRAY_REPO=chat-sdk-android
33 | BINTRAY_USER_ORG=chat-sdk
34 | SITE_URL=https://chatsdk.co
35 | GIT_URL=https://github.com/chat-sdk/chat-sdk-android.git
36 | DEVELOPER_ID=bensmiley
37 | DEVELOPER_NAME=Ben Smiley Andrews
38 | DEVELOPER_EMAIL=ben@chatsdk.co
39 | LICENSE_NAME=Chat SDK License
40 | LICENSE_URL=https://chatsdk.co/chat-sdk-license/
41 | DESCRIPTION='Chat SDK is a flexible, backend agnostic messaging client'
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Mar 18 18:02:08 CET 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/graphics/android-phone-images.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/graphics/android-phone-images.png
--------------------------------------------------------------------------------
/graphics/chat-sdk-play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/graphics/chat-sdk-play.png
--------------------------------------------------------------------------------
/graphics/en_badge_web_generic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/graphics/en_badge_web_generic.png
--------------------------------------------------------------------------------
/issue_template.md:
--------------------------------------------------------------------------------
1 | 1. **Is the bug present in the demo Chat SDK project?**
2 |
3 | 2. **What modifications have you made to the Chat SDK?**
4 |
5 | 3. **Android Version:**
6 |
7 | 4. **Steps taken to reproduce the problem:**
8 |
9 | 5. **Expected result:**
10 |
11 | 6. **Actual result:**
12 |
13 | 7. **Comments:**
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sdk-guru-common/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sdk-guru-common/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | android {
5 | compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
6 |
7 | defaultConfig {
8 | minSdkVersion Integer.parseInt(project.MIN_SDK)
9 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
10 | }
11 |
12 | buildTypes {
13 | debug {
14 | minifyEnabled project.hasProperty('minifyDebug')
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | release {
18 | minifyEnabled project.hasProperty('minifyRelease')
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 |
23 | compileOptions {
24 | sourceCompatibility JavaVersion.VERSION_1_8
25 | targetCompatibility JavaVersion.VERSION_1_8
26 | }
27 |
28 | lintOptions {
29 | abortOnError false
30 | checkReleaseBuilds false
31 | lintConfig file('lint.xml')
32 | }
33 |
34 | }
35 |
36 | dependencies {
37 | implementation fileTree(dir: 'libs', include: ['*.jar'])
38 | api "androidx.appcompat:appcompat:$androidxAppcompatVersion"
39 | api "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
40 | api "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
41 | api "com.jakewharton.rxrelay2:rxrelay:$rxRelayVersion"
42 | api "org.tinylog:tinylog:$tinyLogVersion"
43 |
44 | }
45 |
46 | ext {
47 | libraryName = 'GuruCommon'
48 | artifact = 'guru-common'
49 | libraryDescription = 'Guru Common'
50 | }
51 |
52 | publish {
53 | userOrg = BINTRAY_USER_ORG
54 | groupId = CHAT_SDK_GROUP
55 | artifactId = artifact
56 | repoName = BINTRAY_REPO
57 | publishVersion = CHAT_SDK_VERSION
58 | desc = libraryDescription
59 | licences = ["GPL-3.0"]
60 | uploadName = libraryName
61 | website = GIT_URL
62 | }
63 |
--------------------------------------------------------------------------------
/sdk-guru-common/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/sdk-guru-common/consumer-rules.pro
--------------------------------------------------------------------------------
/sdk-guru-common/proguard-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chat-sdk/firestream-android/334b2e74b098277a3a3ab0e1632f04f3e01b04f0/sdk-guru-common/proguard-rules.pro
--------------------------------------------------------------------------------
/sdk-guru-common/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sdk-guru-common/src/main/java/sdk/guru/common/BaseConfig.java:
--------------------------------------------------------------------------------
1 | package sdk.guru.common;
2 |
3 | public class BaseConfig {
4 |
5 | protected T onBuild;
6 |
7 | public BaseConfig(T onBuild) {
8 | this.onBuild = onBuild;
9 | }
10 |
11 | public T build() {
12 | return onBuild;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/sdk-guru-common/src/main/java/sdk/guru/common/BiAction.java:
--------------------------------------------------------------------------------
1 | package sdk.guru.common;
2 |
3 | import androidx.annotation.Nullable;
4 |
5 | import io.reactivex.CompletableObserver;
6 | import sdk.guru.common.RX;
7 | import io.reactivex.disposables.Disposable;
8 | import io.reactivex.functions.Action;
9 | import io.reactivex.functions.Consumer;
10 |
11 | public class BiAction implements CompletableObserver {
12 |
13 | protected Consumer onComplete;
14 |
15 | public BiAction(@Nullable Consumer onComplete) {
16 | this.onComplete = onComplete;
17 | }
18 |
19 | @Override
20 | public void onSubscribe(Disposable d) {
21 |
22 | }
23 |
24 | @Override
25 | public void onComplete() {
26 | accept(null);
27 | }
28 |
29 | @Override
30 | public void onError(Throwable e) {
31 | accept(e);
32 | }
33 |
34 | public void accept(Throwable e) {
35 | if (onComplete != null) {
36 | try {
37 | onComplete.accept(e);
38 | } catch (Exception error) {}
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/sdk-guru-common/src/main/java/sdk/guru/common/DisposableMap.java:
--------------------------------------------------------------------------------
1 | package sdk.guru.common;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.HashMap;
6 | import java.util.List;
7 |
8 | import io.reactivex.disposables.Disposable;
9 |
10 | public class DisposableMap {
11 |
12 | protected class DisposableList {
13 | private final List disposables = Collections.synchronizedList(new ArrayList<>());
14 |
15 | public void add (Disposable d) {
16 | disposables.add(d);
17 | }
18 |
19 | public void remove (Disposable d) {
20 | disposables.remove(d);
21 | }
22 |
23 | public void dispose () {
24 | synchronized (disposables) {
25 | for (Disposable disposable : disposables) {
26 | disposable.dispose();
27 | }
28 | disposables.clear();
29 | }
30 | }
31 |
32 | }
33 |
34 | protected static String DefaultKey = "def";
35 |
36 | protected HashMap