|
1 |
| -##Jetchat |
| 1 | +<img src="screenshots/jetchatlogo.png"/> |
2 | 2 |
|
3 |
| -TODO |
| 3 | +# Jetchat sample |
4 | 4 |
|
5 |
| -### Known issues |
| 5 | +Jetchat is a sample chat app built with [Jetpack Compose][compose]. This sample showcases: |
| 6 | + |
| 7 | +* UI state management |
| 8 | +* Integration with Architecture Components: Navigation, Fragments, LiveData, ViewModel |
| 9 | +* Back button handling |
| 10 | +* Text Input and focus management |
| 11 | +* Multiple types of animations and transitions |
| 12 | +* Saved state across configuration changes |
| 13 | +* Basic Material Design theming |
| 14 | +* UI tests |
| 15 | + |
| 16 | +<img src="screenshots/jetchat.gif"/> |
| 17 | + |
| 18 | +### Status: 🚧 In progress |
| 19 | + |
| 20 | +Jetchat is still in under development, and some features are not yet implemented. |
| 21 | + |
| 22 | +## Features |
| 23 | + |
| 24 | +### UI State management |
| 25 | +The [ConversationContent](app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt) composable is the entry point to this screen and takes a [ConversationUiState](app/src/main/java/com/example/compose/jetchat/conversation/ConversationUiState.kt) 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](app/src/main/java/com/example/compose/jetchat/conversation/Conversation.kt) or `currentInputSelector` in [UserInput](app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt) |
| 26 | + |
| 27 | +### Architecture Components |
| 28 | +The [ProfileFragment](app/src/main/java/com/example/compose/jetchat/profile/ProfileFragment.kt) shows how to pass data between fragments with the [Navigation component](https://developer.android.com/guide/navigation) and observe state from a |
| 29 | +[ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel), served via [LiveData](https://developer.android.com/topic/libraries/architecture/livedata). |
| 30 | + |
| 31 | +### Back button handling |
| 32 | +When the Emoji selector is shown, pressing back in the app closes it, intercepting any navigation events. This feature shows a way to integrate Compose and APIs from the Android Framework like [OnBackPressedDispatcherOwner](https://developer.android.com/reference/androidx/activity/OnBackPressedDispatcher) via [Ambients](https://developer.android.com/reference/kotlin/androidx/compose/Ambient). The implementation can be found in [ConversationUiState](app/src/main/java/com/example/compose/jetchat/conversation/BackHandler.kt). |
| 33 | + |
| 34 | +### Text Input and focus management |
| 35 | +When the Emoji panel is shown the keyboard must be hidden and vice versa. This is achieved with a combination of the [FocusRequester](https://developer.android.com/reference/kotlin/androidx/compose/ui/focus/FocusRequester) and [FocusObserver](https://developer.android.com/reference/kotlin/androidx/compose/ui/FocusObserverModifier) APIs. |
| 36 | + |
| 37 | +### Multiple types of animations and transitions |
| 38 | +This sample uses animations ranging from simple `AnimatedVisibility` in [FunctionalityNotAvailablePanel](app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt) to choreographed transitions found in the [FloatingActionButton](https://material.io/develop/android/components/floating-action-button) of the Profile screen and implemented in [AnimatingFabContent](app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt) |
| 39 | + |
| 40 | +### Saved state across configuration changes |
| 41 | +Some composable state survives activity or process recreation, like `currentInputSelector` in [UserInput](app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt). |
| 42 | + |
| 43 | +### Basic Material Design theming |
| 44 | +Jetchat follows the Material Design principles and uses the `MaterialTheme` ambient, with custom light and dark themes. In some cases colors it might be necessary to create additional colors, that can be specified as an overlay or combination of two, or as a specific elevation in dark mode. Jetchat uses some convenient extensions on the Material palette and can be used as follows: |
| 45 | + |
| 46 | +[UserInput](app/src/main/java/com/example/compose/jetchat/conversation/UserInput.kt) |
| 47 | +```kotlin |
| 48 | +@Composable |
| 49 | +fun getSelectorExpandedColor(): Color { |
| 50 | + return if (MaterialTheme.colors.isLight) { |
| 51 | + MaterialTheme.colors.compositedOnSurface(0.04f) |
| 52 | + } else { |
| 53 | + MaterialTheme.colors.elevatedSurface(8.dp) |
| 54 | + } |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +### UI tests |
| 59 | +In [androidTest](app/src/androidTest/java/com/example/compose/jetchat) you'll find a suite of UI tests that showcase interesting patterns in Compose: |
| 60 | + |
| 61 | +#### [ConversationTest](app/src/androidTest/java/com/example/compose/jetchat/ConversationTest.kt) |
| 62 | +UI tests for the Conversation screen. Includes a test that checks the behavior of the app when dark mode changes. |
| 63 | + |
| 64 | +#### [NavigationTest](app/src/androidTest/java/com/example/compose/jetchat/NavigationTest.kt) |
| 65 | +Shows how to write tests that assert directly on the [Navigation Controller](https://developer.android.com/reference/androidx/navigation/NavController). |
| 66 | + |
| 67 | +#### [UserInputTest](app/src/androidTest/java/com/example/compose/jetchat/UserInputTest.kt) |
| 68 | +Checks that the user input composable, including extended controls, behave as expected showing and hiding the keyboard. |
| 69 | + |
| 70 | + |
| 71 | +## Known issues |
6 | 72 | 1. If the emoji selector is shown, clicking on the TextField can sometimes show both input methods.
|
7 | 73 | Tracked in https://issuetracker.google.com/164859446
|
8 | 74 |
|
9 |
| -2. There are only two profiles, clicking on anybody except "me" will show the same data. |
| 75 | +2. There are only two profiles, clicking on anybody except "me" will show the same data. |
| 76 | + |
| 77 | + |
| 78 | +## License |
| 79 | +``` |
| 80 | +Copyright 2020 The Android Open Source Project |
| 81 | +
|
| 82 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 83 | +you may not use this file except in compliance with the License. |
| 84 | +You may obtain a copy of the License at |
| 85 | +
|
| 86 | + https://www.apache.org/licenses/LICENSE-2.0 |
| 87 | +
|
| 88 | +Unless required by applicable law or agreed to in writing, software |
| 89 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 90 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 91 | +See the License for the specific language governing permissions and |
| 92 | +limitations under the License. |
| 93 | +``` |
| 94 | + |
| 95 | +[compose]: https://developer.android.com/jetpack/compose |
| 96 | +[coil-accompanist]: https://github.com/chrisbanes/accompanist |
0 commit comments