{"id":21512015,"url":"https://github.com/strvcom/android-chat-component","last_synced_at":"2025-03-17T15:26:03.314Z","repository":{"id":97727110,"uuid":"198620972","full_name":"strvcom/android-chat-component","owner":"strvcom","description":null,"archived":false,"fork":false,"pushed_at":"2020-05-01T11:53:27.000Z","size":674,"stargazers_count":0,"open_issues_count":3,"forks_count":1,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-01-24T01:43:40.928Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/strvcom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-24T11:21:02.000Z","updated_at":"2020-05-01T11:49:43.000Z","dependencies_parsed_at":"2023-05-23T20:45:28.417Z","dependency_job_id":null,"html_url":"https://github.com/strvcom/android-chat-component","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strvcom%2Fandroid-chat-component","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strvcom%2Fandroid-chat-component/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strvcom%2Fandroid-chat-component/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strvcom%2Fandroid-chat-component/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/strvcom","download_url":"https://codeload.github.com/strvcom/android-chat-component/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244056748,"owners_count":20390783,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-23T22:25:35.775Z","updated_at":"2025-03-17T15:26:03.289Z","avatar_url":"https://github.com/strvcom.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chat component\nChat component SDK is a collection of modules that can be added to any\nproject to simplify the development of basic chat functionality. It is an\neasily extendable solution that is built on top of\n[Firebase](https://firebase.google.com/) and allows for easy UI\ncustomization.\n\n#### Technical details\n  \n- **Multiple backend support**\n  - [Firestore](https://firebase.google.com/docs/firestore/)\n  - [Firebase](https://firebase.google.com/docs/database) (under \n    development)\n- **Cloud Storage support**\n  - [Cloud Firestore](https://firebase.google.com/docs/firestore)\n- **Kotlin-first**\n- **API Level 21+** (compatible with 85% of Android devices)\n\n#### Features\n- **Hook up to the selected backend support**\n- **Ready-to-use and customizable UI**\n  - [Conversations list](https://github.com/strvcom/android-research-chat-component/blob/master/component_conversations.md)\n  - [Messages list](https://github.com/strvcom/android-research-chat-component/blob/master/component_messages.md)\n  - [Sending widget](https://github.com/strvcom/android-research-chat-component/blob/master/component_send_widget.md)\n  - [Image detail widget](https://github.com/strvcom/android-research-chat-component/blob/master/component_image_detail.md)\n- **Various types of messages**\n  - Text message\n  - Image message (from camera or gallery)\n- **Notification about the state of an image upload**\n- **Tap to show the timestamp of the sent message**\n\n## Adding the Chat component SDK to your project\n\nAdd Jitpack repository in your root `build.gradle` at the end of repositories:\n```\nallprojects {\n    repositories {\n        ...\n        maven { url 'https://jitpack.io' }\n    }\n}\n```\n\n#### Core features\n\n``` \nimplementation \"com.github.strvcom.android-research-chat-component:core:1.0.0-beta01\"\n```\nYou should use the core module **if you want to have custom backend\nimplementation**. In this case, you will be forced to implement all the\nrequired interfaces on your own.\n\n#### Firestore\n\n``` \nimplementation \"com.github.strvcom.android-research-chat-component:firestore:1.0.0-beta01\"\n```\nYou should use firestore module **if you want to use the default [Cloud\nFirestore](https://firebase.google.com/docs/firestore/) implementation**\nfor your backend.\n\n##### Firestore structure\nThe database structure required for using the default Firestore\nimplementation is described in\n[Firestore docs](https://github.com/strvcom/android-research-chat-component/blob/master/firestore_structure.md).\n\n#### Extension methods\nThere are two convenient extension methods for an Activity in [activity.kt](https://github.com/strvcom/android-chat-component/blob/5d1303568169b8c5f9c1266c235e1d78286d9566/core/src/main/java/com/strv/chat/core/core/ui/extensions/activity.kt#L25) available to simplify work with opening a camera and gallery in case only the basic functionality is required:\n- `Activity.openCamera(imageUri: Uri)`\n- `Activity.openGalleryPhotoPicker(title: String)`\n\n##### Sample app\nIn order to run the sample app, you need to add your own\n[`google-services.json`](https://firebase.google.com/docs/android/setup#add-config-file)\nfile to the app-level directory of the `app` module.\n\n#### Firebase Cloud Storage\n\n```\nimplementation \"com.github.strvcom.android-research-chat-component:storage:1.0.0-beta01\"\n```\n\nYou should use storage module **if you want to use the default [Firebase\nCloud](https://firebase.google.com/docs/firestore) implementation** as\nyour media storage.\n\n### Initializing Chat component \n\nUse `ChatComponent.init()` function to configure and initialize the Chat\ncomponent SDK in your application.\n\n```kotlin\nclass App : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n\n        // initialize Chat component\n        ChatComponent.init(\n            //application context\n            this,\n            //configuration\n            Configuration(\n                //ChatClient - provides interactions with the message source of data\n                chatClient,\n                //ConversationClient - provides interactions with the conversation source of data\n                conversationClient,\n                //MemberClient - provides information about the current user and other members\n                memberClient,\n                //MediaClient - provides interaction with a storage service\n                mediaClient,\n                //notification configuration - for a complete list of available attributes see Notification configuration in Send widget section\n                serviceConfig(CHANNEL_ID)\n            )\n        )\n    }\n}\n```\n\n## Task interface\n`Task` API is widely used in Chat component SDK to represent a **promise\nthat computation will be done**. It is a wrapper around a **result of\nan asynchronous call**.\n\nThere are three kinds of Task:\n- `Task\u003cResult, Error\u003e` \n  - Represents a **single result of an asynchronous call** that returns\n    `\u003cResult\u003e` type in case of success and `\u003cError\u003e` in case of\n    error.\n- `ProgressTask\u003cResult, Error\u003e`\n  - Represents a **single result of an asynchronous call and\n    periodically notifies about progress of the call**. It returns\n    `\u003cResult\u003e` type in case of success and `\u003cError\u003e` in case of error.\n- `ObservableTask\u003cResult, Error\u003e`\n  - Represents a **stream with real time updates** of the result of type\n    `\u003cResult\u003e`. Returns `\u003cError\u003e` when an error occurs.\n\n#### Handling task results\n\n#### `Task\u003cResult, Error\u003e` \n\nTo be notified when the task **succeeds**, call `onSuccess`: \n```kotlin\ntask.onSuccess { result -\u003e\n    Log.d(\"TAG\", \"Task completed successfully with a result: $result\")\n}\n```\n\nTo be notified when the task **fails**, call `onError`:\n```kotlin\ntask.onError { error -\u003e\n    Log.e(\"TAG\", \"Task failed with an exception: ${error.localizedMessage ?: \"Unknown error\"}\")\n}\n```\n\n#### `ProgressTask\u003cResult, Error\u003e` \n\nTo be notified when the task **succeeds**, call `onSuccess`: \n```kotlin\nprogressTask.onSuccess { result -\u003e\n    Log.d(\"TAG\", \"Task completed successfully with a result: $result\")\n}\n```\n\nTo be notified when the task **fails**, call `onError`:\n```kotlin\nprogressTask.onError { error -\u003e\n    Log.e(\"TAG\", \"Task failed with an exception: ${error.localizedMessage ?: \"Unknown error\"}\")\n}\n```\n\nTo be repeatedly notified about the **progress**, call `onProgress`:\n```kotlin\nprogressTask.onProgress { progress -\u003e\n    Log.d(\"TAG\", \"Task progress is: $progress\")\n}\n```\n\n#### `ObservableTask\u003cResult, Error\u003e` \n\nTo **subscribe** to the source of data, call `onNext`\" \n```kotlin\nobservableTask.onNext { result -\u003e\n    Log.d(\"TAG\", \"Task has a new result: $result\")\n}\n```\n\nTo be notified when the task **fails**, call `onError`:\n```kotlin\nobservableTask.onError { error -\u003e\n    Log.e(\"TAG\", \"Task failed with an exception: ${error.localizedMessage ?: \"Unknown error\"}\")\n}\n```\n\n### Create your own task\nYou can convert any existing callback-based API to the Task API via \n- `task`\n- `observableTask`\n- `progressTask` \n\nbuilder functions.\n\n#### `task` \nIn this function, both `invokeSuccess` and `invokeError` can be used to\ncomplete the task with a success or an error state. Repeated invocation \nof any completing function is ignored.\n```kotlin\ninterface Callback\u003cT\u003e {\n    fun onSuccess(result: T)\n    fun onError(e: Exception)\n}\n\nfun \u003cT\u003e taskCallback(block: (Callback\u003cT\u003e) -\u003e Unit): Task\u003cT, Throwable\u003e = task\u003cT, Throwable\u003e {\n    block(object : Callback\u003cT\u003e {\n        override fun onSuccess(result: T) {\n            invokeSuccess(result)\n        }\n\n        override fun onError(e: Exception) {\n            invokeError(e)\n        }\n    })\n}\n```\n#### `observableTask` \nIn this function, `invokeNext` can be used to emit a value to the stream\nbehind. `invokeError` completes the task with an error state. Repeated\ninvocation of `invokeError` function is ignored.\n```kotlin\nfun subscribe(): ObservableTask\u003cList\u003cEntity\u003e, Throwable\u003e =\n    observableTask\u003cList\u003cEntity\u003e, Throwable\u003e(::unsubscribe) {\n        listenerRegistration =\n            queryAource.addSnapshotListener { result, exception -\u003e\n                if (exception != null) {\n                    invokeError(exception)\n                } else {\n                    val list = arrayListOf\u003cEntity\u003e()\n\n                    result?.mapTo(list) { snapShot -\u003e\n                        snapShot.toObject(clazz).also { item -\u003e\n                            item.id = snapShot.id\n                        }\n                    }\n\n                    invokeNext(list)\n                }\n            }\n    }\n```\n#### `progressTask` \nIn this function, `invokeProgress` can be used to notify about the\nprogress of the asynchronous call. `invokeSuccess` and `invokeError`\ncomplete the task with a success or an error state. Repeated invocation \nof any completing function is ignored.\n```kotlin\nfun uploadImage(bitmap: Bitmap, uploadUrl: String, contentType: String) =\n    progressTask\u003cDownloadUrl, Throwable\u003e {\n        val metadata = storageMetadata {\n            this.contentType = contentType\n        }\n\n        val bos = ByteArrayOutputStream()\n        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos)\n\n        val imagePath = path(firebaseStorage, uploadUrl)\n\n        imagePath.putBytes(bos.toByteArray(), metadata)\n            .addOnSuccessListener() {\n                logD(\"File was uploaded\")\n            }.addOnFailureListener {\n                invokeError(it)\n            }.addOnProgressListener { snapshot -\u003e\n                invokeProgress((100.0 * snapshot.bytesTransferred / snapshot.totalByteCount).toInt())\n            }.continueWithTask {\n                imagePath.downloadUrl\n            }.addOnSuccessListener { uri -\u003e\n                invokeSuccess(uri)\n            }.addOnFailureListener {\n                invokeError(it)\n            }\n    }\n```\n\n### Task operators\nTask operators were created to provide users with the option\nto smoothly **transform task data**. You can find the list of the supported\noperators\n[here](https://github.com/strvcom/android-research-chat-component/blob/master/chat-component-core/src/main/java/com/strv/chat/core/domain/task/operators.kt).\n\n## License\nSee the [LICENSE](https://github.com/strvcom/android-chat-component/blob/master/LICENSE.md) file for license rights and limitations (APLv2).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrvcom%2Fandroid-chat-component","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstrvcom%2Fandroid-chat-component","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrvcom%2Fandroid-chat-component/lists"}