Coder Social home page Coder Social logo

android-chat-component's Introduction

Chat component

Chat component SDK is a collection of modules that can be added to any project to simplify the development of basic chat functionality. It is an easily extendable solution that is built on top of Firebase and allows for easy UI customization.

Technical details

  • Multiple backend support
  • Cloud Storage support
  • Kotlin-first
  • API Level 21+ (compatible with 85% of Android devices)

Features

Adding the Chat component SDK to your project

Add Jitpack repository in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Core features

implementation "com.github.strvcom.android-research-chat-component:core:1.0.0-beta01"

You should use the core module if you want to have custom backend implementation. In this case, you will be forced to implement all the required interfaces on your own.

Firestore

implementation "com.github.strvcom.android-research-chat-component:firestore:1.0.0-beta01"

You should use firestore module if you want to use the default Cloud Firestore implementation for your backend.

Firestore structure

The database structure required for using the default Firestore implementation is described in Firestore docs.

Extension methods

There are two convenient extension methods for an Activity in activity.kt available to simplify work with opening a camera and gallery in case only the basic functionality is required:

  • Activity.openCamera(imageUri: Uri)
  • Activity.openGalleryPhotoPicker(title: String)
Sample app

In order to run the sample app, you need to add your own google-services.json file to the app-level directory of the app module.

Firebase Cloud Storage

implementation "com.github.strvcom.android-research-chat-component:storage:1.0.0-beta01"

You should use storage module if you want to use the default Firebase Cloud implementation as your media storage.

Initializing Chat component

Use ChatComponent.init() function to configure and initialize the Chat component SDK in your application.

class App : Application() {

    override fun onCreate() {
        super.onCreate()

        // initialize Chat component
        ChatComponent.init(
            //application context
            this,
            //configuration
            Configuration(
                //ChatClient - provides interactions with the message source of data
                chatClient,
                //ConversationClient - provides interactions with the conversation source of data
                conversationClient,
                //MemberClient - provides information about the current user and other members
                memberClient,
                //MediaClient - provides interaction with a storage service
                mediaClient,
                //notification configuration - for a complete list of available attributes see Notification configuration in Send widget section
                serviceConfig(CHANNEL_ID)
            )
        )
    }
}

Task interface

Task API is widely used in Chat component SDK to represent a promise that computation will be done. It is a wrapper around a result of an asynchronous call.

There are three kinds of Task:

  • Task<Result, Error>
    • Represents a single result of an asynchronous call that returns <Result> type in case of success and <Error> in case of error.
  • ProgressTask<Result, Error>
    • Represents a single result of an asynchronous call and periodically notifies about progress of the call. It returns <Result> type in case of success and <Error> in case of error.
  • ObservableTask<Result, Error>
    • Represents a stream with real time updates of the result of type <Result>. Returns <Error> when an error occurs.

Handling task results

Task<Result, Error>

To be notified when the task succeeds, call onSuccess:

task.onSuccess { result ->
    Log.d("TAG", "Task completed successfully with a result: $result")
}

To be notified when the task fails, call onError:

task.onError { error ->
    Log.e("TAG", "Task failed with an exception: ${error.localizedMessage ?: "Unknown error"}")
}

ProgressTask<Result, Error>

To be notified when the task succeeds, call onSuccess:

progressTask.onSuccess { result ->
    Log.d("TAG", "Task completed successfully with a result: $result")
}

To be notified when the task fails, call onError:

progressTask.onError { error ->
    Log.e("TAG", "Task failed with an exception: ${error.localizedMessage ?: "Unknown error"}")
}

To be repeatedly notified about the progress, call onProgress:

progressTask.onProgress { progress ->
    Log.d("TAG", "Task progress is: $progress")
}

ObservableTask<Result, Error>

To subscribe to the source of data, call onNext"

observableTask.onNext { result ->
    Log.d("TAG", "Task has a new result: $result")
}

To be notified when the task fails, call onError:

observableTask.onError { error ->
    Log.e("TAG", "Task failed with an exception: ${error.localizedMessage ?: "Unknown error"}")
}

Create your own task

You can convert any existing callback-based API to the Task API via

  • task
  • observableTask
  • progressTask

builder functions.

task

In this function, both invokeSuccess and invokeError can be used to complete the task with a success or an error state. Repeated invocation of any completing function is ignored.

interface Callback<T> {
    fun onSuccess(result: T)
    fun onError(e: Exception)
}

fun <T> taskCallback(block: (Callback<T>) -> Unit): Task<T, Throwable> = task<T, Throwable> {
    block(object : Callback<T> {
        override fun onSuccess(result: T) {
            invokeSuccess(result)
        }

        override fun onError(e: Exception) {
            invokeError(e)
        }
    })
}

observableTask

In this function, invokeNext can be used to emit a value to the stream behind. invokeError completes the task with an error state. Repeated invocation of invokeError function is ignored.

fun subscribe(): ObservableTask<List<Entity>, Throwable> =
    observableTask<List<Entity>, Throwable>(::unsubscribe) {
        listenerRegistration =
            queryAource.addSnapshotListener { result, exception ->
                if (exception != null) {
                    invokeError(exception)
                } else {
                    val list = arrayListOf<Entity>()

                    result?.mapTo(list) { snapShot ->
                        snapShot.toObject(clazz).also { item ->
                            item.id = snapShot.id
                        }
                    }

                    invokeNext(list)
                }
            }
    }

progressTask

In this function, invokeProgress can be used to notify about the progress of the asynchronous call. invokeSuccess and invokeError complete the task with a success or an error state. Repeated invocation of any completing function is ignored.

fun uploadImage(bitmap: Bitmap, uploadUrl: String, contentType: String) =
    progressTask<DownloadUrl, Throwable> {
        val metadata = storageMetadata {
            this.contentType = contentType
        }

        val bos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos)

        val imagePath = path(firebaseStorage, uploadUrl)

        imagePath.putBytes(bos.toByteArray(), metadata)
            .addOnSuccessListener() {
                logD("File was uploaded")
            }.addOnFailureListener {
                invokeError(it)
            }.addOnProgressListener { snapshot ->
                invokeProgress((100.0 * snapshot.bytesTransferred / snapshot.totalByteCount).toInt())
            }.continueWithTask {
                imagePath.downloadUrl
            }.addOnSuccessListener { uri ->
                invokeSuccess(uri)
            }.addOnFailureListener {
                invokeError(it)
            }
    }

Task operators

Task operators were created to provide users with the option to smoothly transform task data. You can find the list of the supported operators here.

License

See the LICENSE file for license rights and limitations (APLv2).

android-chat-component's People

Contributors

boska avatar lindakrestanova avatar schwarja avatar ywett02 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

lindakrestanova

android-chat-component's Issues

Library distribution

I think that distribution via Bintray would be better than Jitpack for 2 reasons: developers don't have to explicitly declare Maven repository and we would avoid "com.github" prefix in the package name, "com.strv" package looks more professional.

Screenshots in README

I suggest to add some screenshots in README.md so it's easier to imagine what the library does.

Name of the library

It would be nice to have a name for the library so it is easy to remember it a refer to it. Chat Component is too generic name.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.