Skip to content

Latest commit

 

History

History

Jetchat

README.md

Jetchat sample

Jetchat is a sample chat app built with Jetpack Compose.

To try out this sample app, use the latest stable version of Android Studio. You can clone this repository or import the project from Android Studio following the steps here.

This sample showcases:

  • UI state management
  • Integration with Architecture Components: Navigation 3, ViewModel
  • Back button handling
  • Text Input and focus management
  • Multiple types of animations and transitions
  • Saved state across configuration changes
  • Material Design 3 theming and Material You dynamic color
  • UI tests

Screenshots

Status: 🚧 In progress

Jetchat is still in under development, and some features are not yet implemented.

Features

UI State management

The ConversationContent composable is the entry point to this screen and takes a ConversationUiState that defines the data to be displayed. This doesn't mean all the state is served from a single point: composables can have their own state too. For an example, see scrollState in ConversationContent or currentInputSelector in UserInput

Architecture Components

JetchatApp hosts the screens in a Navigation 3 NavDisplay. The destinations are the typed keys defined in JetchatNavKeys: opening a profile pushes a Profile(userId) key onto the back stack, which is created with rememberNavBackStack so that it survives configuration changes and process death. The back stack is the single source of truth for navigation: the drawer derives its selected item from the key on top of it. The profile entry passes the userId of its key to a ViewModel that is scoped to that entry with rememberViewModelStoreNavEntryDecorator, and observes its state served via LiveData.

Back button handling

When the Emoji selector is shown, pressing back in the app closes it, intercepting any navigation events. The implementation can be found in UserInput.

Text Input and focus management

When the Emoji panel is shown the keyboard must be hidden and vice versa. This is achieved with a combination of the FocusRequester and onFocusChanged APIs.

Multiple types of animations and transitions

This sample uses animations ranging from simple AnimatedVisibility in FunctionalityNotAvailablePanel to choreographed transitions found in the FloatingActionButton of the Profile screen and implemented in AnimatingFabContent

Edge-to-edge UI with synchronized IME transitions

This sample is laid out edge-to-edge, drawing its content behind the system bars for a more immersive look.

The sample also supports synchronized IME transitions when running on API 30+ devices. See the use of Modifier.navigationBarsPadding().imePadding() in ConversationContent.

Saved state across configuration changes

Some composable state survives activity or process recreation, like currentInputSelector in UserInput. The navigation back stack is saved too, see rememberNavBackStack in JetchatApp.

Material Design 3 theming and Material You dynamic color

Jetchat follows the Material Design 3 principles and uses the MaterialTheme composable and M3 components. On Android 12+ Jetchat supports Material You dynamic color, which extracts a custom color scheme from the device wallpaper. Jetchat uses a custom, branded color scheme as a fallback. It also implements custom typography using the Karla and Montserrat font families.

UI tests

In androidTest you'll find a suite of UI tests that showcase interesting patterns in Compose:

UI tests for the Conversation screen. Includes a test that checks the behavior of the app when dark mode changes.

Checks the navigation flows of the app (opening profiles from the drawer, going back, popping the back stack) by asserting on what is displayed.

Checks that the user input composable, including extended controls, behave as expected showing and hiding the keyboard.

Known issues

  1. If the emoji selector is shown, clicking on the TextField can sometimes show both input methods. Tracked in https://issuetracker.google.com/164859446

  2. There are only two profiles, clicking on anybody except "me" will show the same data.

License

Copyright 2020 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.