From c740cc39edd34637a259ba246eba72b698c303a7 Mon Sep 17 00:00:00 2001 From: Gian <47775302+gpunto@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:37:17 +0200 Subject: [PATCH] Update tutorial code to use Chat v7 --- README.md | 17 +- app/build.gradle | 16 +- app/src/main/AndroidManifest.xml | 10 +- .../example/chattutorial/ChannelActivity.kt | 62 +++++ .../example/chattutorial/ChannelActivity2.kt | 60 +++++ .../example/chattutorial/ChannelActivity3.kt | 165 ++++++++++++ .../example/chattutorial/ChannelActivity4.kt | 186 ++++++++++++++ .../com/example/chattutorial/MainActivity.kt | 65 +++-- .../example/chattutorial/MessagesActivity.kt | 49 ---- .../example/chattutorial/MessagesActivity2.kt | 63 ----- .../example/chattutorial/MessagesActivity3.kt | 194 -------------- .../example/chattutorial/MessagesActivity4.kt | 239 ------------------ .../example/chattutorial/ui/theme/Color.kt | 8 - .../example/chattutorial/ui/theme/Shape.kt | 11 - .../example/chattutorial/ui/theme/Theme.kt | 47 ---- .../com/example/chattutorial/ui/theme/Type.kt | 28 -- build.gradle | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 18 files changed, 528 insertions(+), 700 deletions(-) create mode 100644 app/src/main/java/com/example/chattutorial/ChannelActivity.kt create mode 100644 app/src/main/java/com/example/chattutorial/ChannelActivity2.kt create mode 100644 app/src/main/java/com/example/chattutorial/ChannelActivity3.kt create mode 100644 app/src/main/java/com/example/chattutorial/ChannelActivity4.kt delete mode 100644 app/src/main/java/com/example/chattutorial/MessagesActivity.kt delete mode 100644 app/src/main/java/com/example/chattutorial/MessagesActivity2.kt delete mode 100644 app/src/main/java/com/example/chattutorial/MessagesActivity3.kt delete mode 100644 app/src/main/java/com/example/chattutorial/MessagesActivity4.kt delete mode 100644 app/src/main/java/com/example/chattutorial/ui/theme/Color.kt delete mode 100644 app/src/main/java/com/example/chattutorial/ui/theme/Shape.kt delete mode 100644 app/src/main/java/com/example/chattutorial/ui/theme/Theme.kt delete mode 100644 app/src/main/java/com/example/chattutorial/ui/theme/Type.kt diff --git a/README.md b/README.md index ec39b49..25a3667 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The project is pre-configured with a shared [Stream](https://getstream.io) accou ## Quick start 1. Clone the repository -2. Open the project in Android Studio (Arctic Fox or later) +2. Open the project in the latest stable version of Android Studio 3. Run the _app_ 4. Make sure to check the [Details](#details) section below for the different steps @@ -18,19 +18,18 @@ The project is pre-configured with a shared [Stream](https://getstream.io) accou The tutorial app consists of two screens: * `MainActivity`: Shows the list of available channels. -* `MessagesActivity`: Shows the selected channel view, which includes the header, message list, and message input view. +* `ChannelActivity`: Shows the selected channel view, which includes the header, message list, and message input view. -There are a handful of `MessagesActivity` implementations, which correspond to the steps of the tutorial. You can easily swap them by changing the `onChannelClick` handler located in `MainActivity`: +`ChannelActivity` follows the published tutorial step-by-step and includes a colors customization on `ChatTheme`. Three additional `ChannelActivity*` implementations show alternative customization techniques and screen compositions. To try one, point `MainActivity`'s `onChannelClick` at it: ```kotlin onChannelClick = { channel -> - startActivity(MessagesActivity4.getIntent(this, channel.cid)) + startActivity(ChannelActivity4.getIntent(this, channel.cid)) }, ``` -You can choose from four different `MessagesActivity` implementations: +You can choose from three alternative `ChannelActivity` implementations: -* `MessagesActivity` - a basic _Message Screen_ implementation -* `MessagesActivity2` - includes customization of the screen by using `ChatTheme` -* `MessagesActivity3` - uses bound and stateless components to build the chat screen, with further customization -* `MessagesActivity4` - uses a custom message composer component for extended customization +* `ChannelActivity2` - customizes typography via `ChatTheme` +* `ChannelActivity3` - uses bound and stateless components to build the chat screen +* `ChannelActivity4` - uses a custom message composer component diff --git a/app/build.gradle b/app/build.gradle index b7a96c3..31d8705 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,13 +5,13 @@ plugins { } android { - compileSdk 35 + compileSdk 36 namespace "com.example.chattutorial" defaultConfig { applicationId "com.example.chattutorial" - minSdk 21 - targetSdk 34 + minSdk 24 + targetSdk 36 versionCode 1 versionName "1.0" @@ -45,15 +45,13 @@ android { } dependencies { - implementation "io.getstream:stream-chat-android-compose:6.12.1" - implementation "io.getstream:stream-chat-android-offline:6.12.1" + implementation "io.getstream:stream-chat-android-compose:7.3.0" - implementation(platform("androidx.compose:compose-bom:2024.06.00")) - implementation("androidx.activity:activity-compose:1.10.1") + implementation(platform("androidx.compose:compose-bom:2025.08.01")) + implementation("androidx.activity:activity-compose:1.9.3") implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-tooling") implementation("androidx.compose.runtime:runtime") implementation("androidx.compose.foundation:foundation") - implementation("androidx.compose.material:material") - implementation("androidx.compose.material:material-icons-extended") + implementation("androidx.compose.material3:material3") } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b940d2b..52b0985 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,19 +14,19 @@ android:supportsRtl="true" android:theme="@style/Theme.ChatTutorial"> - \ No newline at end of file + diff --git a/app/src/main/java/com/example/chattutorial/ChannelActivity.kt b/app/src/main/java/com/example/chattutorial/ChannelActivity.kt new file mode 100644 index 0000000..139913e --- /dev/null +++ b/app/src/main/java/com/example/chattutorial/ChannelActivity.kt @@ -0,0 +1,62 @@ +package com.example.chattutorial + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.ui.graphics.Color +import io.getstream.chat.android.compose.ui.messages.ChannelScreen +import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.compose.ui.theme.StreamDesign +import io.getstream.chat.android.compose.viewmodel.messages.ChannelViewModelFactory +import io.getstream.chat.android.compose.viewmodel.messages.MessageListOptions + +class ChannelActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + // Load the ID of the selected channel from Intent Extras. + // If there is no channelId, then we finish the Activity and return. + val channelId = intent.getStringExtra(KEY_CHANNEL_ID) + if (channelId == null) { + finish() + return + } + + // Set the UI + setContent { + val baseColors = if (isSystemInDarkTheme()) { + StreamDesign.Colors.defaultDark() + } else { + StreamDesign.Colors.default() + } + ChatTheme( + colors = baseColors.copy( + accentPrimary = Color(0xFF005FFF), + ) + ) { + ChannelScreen( + viewModelFactory = ChannelViewModelFactory( + context = this, + channelId = channelId, + messageListOptions = MessageListOptions(messageLimit = 30), + ), + onBackPressed = { finish() } + ) + } + } + } + + // Define a helper function to build an Intent for this Activity. + companion object { + private const val KEY_CHANNEL_ID = "channelId" + + fun getIntent(context: Context, channelId: String): Intent { + return Intent(context, ChannelActivity::class.java).apply { + putExtra(KEY_CHANNEL_ID, channelId) + } + } + } +} diff --git a/app/src/main/java/com/example/chattutorial/ChannelActivity2.kt b/app/src/main/java/com/example/chattutorial/ChannelActivity2.kt new file mode 100644 index 0000000..bf279ba --- /dev/null +++ b/app/src/main/java/com/example/chattutorial/ChannelActivity2.kt @@ -0,0 +1,60 @@ +package com.example.chattutorial + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import io.getstream.chat.android.compose.ui.messages.ChannelScreen +import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.compose.ui.theme.StreamDesign +import io.getstream.chat.android.compose.viewmodel.messages.ChannelViewModelFactory +import io.getstream.chat.android.compose.viewmodel.messages.MessageListOptions + +/** + * Demonstrates customizing the [ChatTheme] typography. The same pattern works for any + * [StreamDesign.Typography] field; here we swap the font family and weights on a few text styles + * via [copy]. + */ +class ChannelActivity2 : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val channelId = intent.getStringExtra(KEY_CHANNEL_ID) + if (channelId == null) { + finish() + return + } + + setContent { + val baseTypography = StreamDesign.Typography.default(fontFamily = FontFamily.Serif) + ChatTheme( + typography = baseTypography.copy( + bodyEmphasis = baseTypography.bodyEmphasis.copy(fontWeight = FontWeight.Bold), + headingMedium = baseTypography.headingMedium.copy(fontWeight = FontWeight.Black), + ) + ) { + ChannelScreen( + viewModelFactory = ChannelViewModelFactory( + context = this, + channelId = channelId, + messageListOptions = MessageListOptions(messageLimit = 30), + ), + onBackPressed = { finish() } + ) + } + } + } + + companion object { + private const val KEY_CHANNEL_ID = "channelId" + + fun getIntent(context: Context, channelId: String): Intent { + return Intent(context, ChannelActivity2::class.java).apply { + putExtra(KEY_CHANNEL_ID, channelId) + } + } + } +} diff --git a/app/src/main/java/com/example/chattutorial/ChannelActivity3.kt b/app/src/main/java/com/example/chattutorial/ChannelActivity3.kt new file mode 100644 index 0000000..616fc7a --- /dev/null +++ b/app/src/main/java/com/example/chattutorial/ChannelActivity3.kt @@ -0,0 +1,165 @@ +package com.example.chattutorial + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.viewModels +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import io.getstream.chat.android.compose.ui.components.messageactions.MessageActions +import io.getstream.chat.android.compose.ui.components.messageactions.ReactionsMenu +import io.getstream.chat.android.compose.ui.components.messageoptions.defaultMessageOptionsState +import io.getstream.chat.android.compose.ui.messages.attachments.AttachmentPickerMenu +import io.getstream.chat.android.compose.ui.messages.composer.MessageComposer +import io.getstream.chat.android.compose.ui.messages.list.MessageList +import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.compose.viewmodel.messages.AttachmentsPickerViewModel +import io.getstream.chat.android.compose.viewmodel.messages.ChannelViewModelFactory +import io.getstream.chat.android.compose.viewmodel.messages.MessageComposerViewModel +import io.getstream.chat.android.compose.viewmodel.messages.MessageListViewModel +import io.getstream.chat.android.compose.viewmodel.messages.MessageListOptions +import io.getstream.chat.android.ui.common.state.messages.MessageMode +import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageOptionsState +import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageReactionsState + +/** + * Demonstrates building the chat screen from low-level, bound + stateless components instead of + * using [io.getstream.chat.android.compose.ui.messages.ChannelScreen]. The selected-message + * overlay is rendered with [MessageActions] / [ReactionsMenu]. + */ +class ChannelActivity3 : ComponentActivity() { + + private val factory by lazy { + ChannelViewModelFactory( + context = this, + channelId = intent.getStringExtra(KEY_CHANNEL_ID) ?: "", + messageListOptions = MessageListOptions(messageLimit = 30), + ) + } + + private val listViewModel: MessageListViewModel by viewModels { factory } + private val attachmentsPickerViewModel: AttachmentsPickerViewModel by viewModels { factory } + private val composerViewModel: MessageComposerViewModel by viewModels { factory } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val channelId = intent.getStringExtra(KEY_CHANNEL_ID) + if (channelId == null) { + finish() + return + } + + setContent { + ChatTheme { + MyCustomUi() + } + } + } + + @Composable + private fun MyCustomUi() { + val messagesState by listViewModel.currentMessagesState + val selectedMessageState = messagesState.selectedMessageState + val user by listViewModel.user.collectAsState() + + Box( + modifier = Modifier + .fillMaxSize() + .safeDrawingPadding() + .consumeWindowInsets(WindowInsets.ime), + ) { + Scaffold( + modifier = Modifier.fillMaxSize(), + containerColor = ChatTheme.colors.backgroundCoreApp, + bottomBar = { + Column { + MessageComposer( + viewModel = composerViewModel, + onAttachmentsClick = { + attachmentsPickerViewModel.setPickerVisible(true) + } + ) + AttachmentPickerMenu( + attachmentsPickerViewModel = attachmentsPickerViewModel, + composerViewModel = composerViewModel, + ) + } + } + ) { contentPadding -> + MessageList( + modifier = Modifier + .background(ChatTheme.colors.backgroundCoreApp) + .padding(contentPadding) + .fillMaxSize(), + viewModel = listViewModel, + onThreadClick = { message -> + composerViewModel.setMessageMode(MessageMode.MessageThread(message)) + listViewModel.openMessageThread(message) + } + ) + } + + if (selectedMessageState is SelectedMessageOptionsState) { + val selectedMessage = selectedMessageState.message + MessageActions( + message = selectedMessage, + messageOptions = defaultMessageOptionsState( + selectedMessage = selectedMessage, + currentUser = user, + isInThread = listViewModel.isInThread, + channel = selectedMessageState.channel, + ), + ownCapabilities = selectedMessageState.ownCapabilities, + onMessageAction = { action -> + composerViewModel.performMessageAction(action) + listViewModel.performMessageAction(action) + }, + onShowMoreReactionsSelected = { + listViewModel.selectExtendedReactions(selectedMessage) + }, + onDismiss = { listViewModel.removeOverlay() }, + currentUser = user, + ) + } else if (selectedMessageState is SelectedMessageReactionsState) { + val selectedMessage = selectedMessageState.message + ReactionsMenu( + message = selectedMessage, + currentUser = user, + ownCapabilities = selectedMessageState.ownCapabilities, + onMessageAction = { action -> + composerViewModel.performMessageAction(action) + listViewModel.performMessageAction(action) + }, + onShowMoreReactionsSelected = { + listViewModel.selectExtendedReactions(selectedMessage) + }, + onDismiss = { listViewModel.removeOverlay() }, + ) + } + } + } + + companion object { + private const val KEY_CHANNEL_ID = "channelId" + + fun getIntent(context: Context, channelId: String): Intent { + return Intent(context, ChannelActivity3::class.java).apply { + putExtra(KEY_CHANNEL_ID, channelId) + } + } + } +} diff --git a/app/src/main/java/com/example/chattutorial/ChannelActivity4.kt b/app/src/main/java/com/example/chattutorial/ChannelActivity4.kt new file mode 100644 index 0000000..1eefa79 --- /dev/null +++ b/app/src/main/java/com/example/chattutorial/ChannelActivity4.kt @@ -0,0 +1,186 @@ +package com.example.chattutorial + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.viewModels +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.getstream.chat.android.compose.ui.components.composer.MessageInput +import io.getstream.chat.android.compose.ui.components.messageactions.MessageActions +import io.getstream.chat.android.compose.ui.components.messageactions.ReactionsMenu +import io.getstream.chat.android.compose.ui.components.messageoptions.defaultMessageOptionsState +import io.getstream.chat.android.compose.ui.messages.attachments.AttachmentPickerMenu +import io.getstream.chat.android.compose.ui.messages.composer.MessageComposer +import io.getstream.chat.android.compose.ui.messages.list.MessageList +import io.getstream.chat.android.compose.ui.theme.ChatTheme +import io.getstream.chat.android.compose.viewmodel.messages.AttachmentsPickerViewModel +import io.getstream.chat.android.compose.viewmodel.messages.ChannelViewModelFactory +import io.getstream.chat.android.compose.viewmodel.messages.MessageComposerViewModel +import io.getstream.chat.android.compose.viewmodel.messages.MessageListOptions +import io.getstream.chat.android.compose.viewmodel.messages.MessageListViewModel +import io.getstream.chat.android.ui.common.state.messages.MessageMode +import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageOptionsState +import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageReactionsState + +/** + * Same low-level screen as [ChannelActivity3], but supplies a custom `input` slot to + * [MessageComposer] wired to a hand-placed [MessageInput]. + */ +class ChannelActivity4 : ComponentActivity() { + + private val factory by lazy { + ChannelViewModelFactory( + context = this, + channelId = intent.getStringExtra(KEY_CHANNEL_ID) ?: "", + messageListOptions = MessageListOptions(messageLimit = 30), + ) + } + + private val listViewModel: MessageListViewModel by viewModels { factory } + private val attachmentsPickerViewModel: AttachmentsPickerViewModel by viewModels { factory } + private val composerViewModel: MessageComposerViewModel by viewModels { factory } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val channelId = intent.getStringExtra(KEY_CHANNEL_ID) + if (channelId == null) { + finish() + return + } + + setContent { + ChatTheme { + MyCustomUi() + } + } + } + + @Composable + private fun MyCustomUi() { + val messagesState by listViewModel.currentMessagesState + val selectedMessageState = messagesState.selectedMessageState + val user by listViewModel.user.collectAsState() + + Box( + modifier = Modifier + .fillMaxSize() + .safeDrawingPadding() + .consumeWindowInsets(WindowInsets.ime), + ) { + Scaffold( + modifier = Modifier.fillMaxSize(), + containerColor = ChatTheme.colors.backgroundCoreApp, + bottomBar = { + Column { + MyCustomComposer() + AttachmentPickerMenu( + attachmentsPickerViewModel = attachmentsPickerViewModel, + composerViewModel = composerViewModel, + ) + } + } + ) { contentPadding -> + MessageList( + modifier = Modifier + .background(ChatTheme.colors.backgroundCoreApp) + .padding(contentPadding) + .fillMaxSize(), + viewModel = listViewModel, + onThreadClick = { message -> + composerViewModel.setMessageMode(MessageMode.MessageThread(message)) + listViewModel.openMessageThread(message) + } + ) + } + + if (selectedMessageState is SelectedMessageOptionsState) { + val selectedMessage = selectedMessageState.message + MessageActions( + message = selectedMessage, + messageOptions = defaultMessageOptionsState( + selectedMessage = selectedMessage, + currentUser = user, + isInThread = listViewModel.isInThread, + channel = selectedMessageState.channel, + ), + ownCapabilities = selectedMessageState.ownCapabilities, + onMessageAction = { action -> + composerViewModel.performMessageAction(action) + listViewModel.performMessageAction(action) + }, + onShowMoreReactionsSelected = { + listViewModel.selectExtendedReactions(selectedMessage) + }, + onDismiss = { listViewModel.removeOverlay() }, + currentUser = user, + ) + } else if (selectedMessageState is SelectedMessageReactionsState) { + val selectedMessage = selectedMessageState.message + ReactionsMenu( + message = selectedMessage, + currentUser = user, + ownCapabilities = selectedMessageState.ownCapabilities, + onMessageAction = { action -> + composerViewModel.performMessageAction(action) + listViewModel.performMessageAction(action) + }, + onShowMoreReactionsSelected = { + listViewModel.selectExtendedReactions(selectedMessage) + }, + onDismiss = { listViewModel.removeOverlay() }, + ) + } + } + } + + @Composable + private fun MyCustomComposer() { + MessageComposer( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), + viewModel = composerViewModel, + onAttachmentsClick = { attachmentsPickerViewModel.setPickerVisible(true) }, + input = { inputState -> + MessageInput( + modifier = Modifier + .weight(1f) + .padding(horizontal = 8.dp) + .align(Alignment.CenterVertically), + messageComposerState = inputState, + onValueChange = { composerViewModel.setMessageInput(it) }, + onAttachmentRemoved = { composerViewModel.removeAttachment(it) }, + ) + } + ) + } + + companion object { + private const val KEY_CHANNEL_ID = "channelId" + + fun getIntent(context: Context, channelId: String): Intent { + return Intent(context, ChannelActivity::class.java).apply { + putExtra(KEY_CHANNEL_ID, channelId) + } + } + } +} diff --git a/app/src/main/java/com/example/chattutorial/MainActivity.kt b/app/src/main/java/com/example/chattutorial/MainActivity.kt index e3de8ac..c9ce683 100644 --- a/app/src/main/java/com/example/chattutorial/MainActivity.kt +++ b/app/src/main/java/com/example/chattutorial/MainActivity.kt @@ -3,44 +3,33 @@ package com.example.chattutorial import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.material3.Text +import androidx.compose.ui.Modifier import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.res.stringResource import io.getstream.chat.android.client.ChatClient import io.getstream.chat.android.client.logger.ChatLogLevel import io.getstream.chat.android.compose.ui.channels.ChannelsScreen +import io.getstream.chat.android.compose.ui.channels.SearchMode import io.getstream.chat.android.compose.ui.theme.ChatTheme import io.getstream.chat.android.models.InitializationState import io.getstream.chat.android.models.User -import io.getstream.chat.android.offline.plugin.factory.StreamOfflinePluginFactory -import io.getstream.chat.android.state.plugin.config.StatePluginConfig -import io.getstream.chat.android.state.plugin.factory.StreamStatePluginFactory class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // 1 - Set up the OfflinePlugin for offline storage - val offlinePluginFactory = StreamOfflinePluginFactory( - appContext = applicationContext, - ) - val statePluginFactory = StreamStatePluginFactory( - config = StatePluginConfig( - backgroundSyncEnabled = true, - userPresence = true, - ), - appContext = this, - ) - - // 2 - Set up the client for API calls and with the plugin for offline storage + // Set up the client for API calls with offline storage and state management val client = ChatClient.Builder("uun7ywwamhs9", applicationContext) - .withPlugins(offlinePluginFactory, statePluginFactory) .logLevel(ChatLogLevel.ALL) // Set to NOTHING in prod .build() - // 3 - Authenticate and connect the user + // Authenticate and connect the user val user = User( id = "tutorial-droid", name = "Tutorial Droid", @@ -57,21 +46,29 @@ class MainActivity : ComponentActivity() { val clientInitialisationState by client.clientState.initializationState.collectAsState() ChatTheme { - when (clientInitialisationState) { - InitializationState.COMPLETE -> { - ChannelsScreen( - title = stringResource(id = R.string.app_name), - onChannelClick = { channel -> - startActivity(MessagesActivity4.getIntent(this@MainActivity, channel.cid)) - }, - onBackPressed = { finish() } - ) - } - InitializationState.INITIALIZING -> { - Text(text = "Initialising...") - } - InitializationState.NOT_INITIALIZED -> { - Text(text = "Not initialized...") + Box( + modifier = Modifier + .fillMaxSize() + .safeDrawingPadding(), + ) { + when (clientInitialisationState) { + InitializationState.COMPLETE -> { + ChannelsScreen( + title = stringResource(id = R.string.app_name), + isShowingHeader = true, + searchMode = SearchMode.Messages, + onChannelClick = { channel -> + startActivity(ChannelActivity.getIntent(this@MainActivity, channel.cid)) + }, + onBackPressed = { finish() } + ) + } + InitializationState.INITIALIZING -> { + Text(text = "Initializing...") + } + InitializationState.NOT_INITIALIZED -> { + Text(text = "Not initialized...") + } } } } diff --git a/app/src/main/java/com/example/chattutorial/MessagesActivity.kt b/app/src/main/java/com/example/chattutorial/MessagesActivity.kt deleted file mode 100644 index 0423ac9..0000000 --- a/app/src/main/java/com/example/chattutorial/MessagesActivity.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.example.chattutorial - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import io.getstream.chat.android.compose.ui.messages.MessagesScreen -import io.getstream.chat.android.compose.ui.theme.ChatTheme -import io.getstream.chat.android.compose.viewmodel.messages.MessagesViewModelFactory - -class MessagesActivity : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - // 1 - Load the ID of the selected channel - val channelId = intent.getStringExtra(KEY_CHANNEL_ID) - - if (channelId == null) { - finish() - return - } - - // 2 - Add the MessagesScreen to your UI - setContent { - ChatTheme { - MessagesScreen( - viewModelFactory = MessagesViewModelFactory( - context = this, - channelId = channelId, - messageLimit = 30 - ), - onBackPressed = { finish() } - ) - } - } - } - - // 3 - Create an intent to start this Activity, with a given channelId - companion object { - private const val KEY_CHANNEL_ID = "channelId" - - fun getIntent(context: Context, channelId: String): Intent { - return Intent(context, MessagesActivity::class.java).apply { - putExtra(KEY_CHANNEL_ID, channelId) - } - } - } -} diff --git a/app/src/main/java/com/example/chattutorial/MessagesActivity2.kt b/app/src/main/java/com/example/chattutorial/MessagesActivity2.kt deleted file mode 100644 index a28f6db..0000000 --- a/app/src/main/java/com/example/chattutorial/MessagesActivity2.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.example.chattutorial - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.unit.dp -import io.getstream.chat.android.compose.ui.messages.MessagesScreen -import io.getstream.chat.android.compose.ui.theme.ChatTheme -import io.getstream.chat.android.compose.ui.theme.StreamShapes -import io.getstream.chat.android.compose.viewmodel.messages.MessagesViewModelFactory - -class MessagesActivity2 : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - // 1 - Load the ID of the selected channel - val channelId = intent.getStringExtra(KEY_CHANNEL_ID) - - if (channelId == null) { - finish() - return - } - - // 2 - Add the MessagesScreen to your UI - setContent { - ChatTheme( - shapes = StreamShapes - .defaultShapes() - .copy( - avatar = RoundedCornerShape(8.dp), - attachment = RoundedCornerShape(16.dp), - myMessageBubble = RoundedCornerShape(16.dp), - otherMessageBubble = RoundedCornerShape(16.dp), - inputField = RectangleShape - ) - ) { - MessagesScreen( - viewModelFactory = MessagesViewModelFactory( - context = this, - channelId = channelId, - messageLimit = 30 - ), - onBackPressed = { finish() } - ) - } - } - } - - // 3 - Create an intent to start this Activity, with a given channelId - companion object { - private const val KEY_CHANNEL_ID = "channelId" - - fun getIntent(context: Context, channelId: String): Intent { - return Intent(context, MessagesActivity2::class.java).apply { - putExtra(KEY_CHANNEL_ID, channelId) - } - } - } -} diff --git a/app/src/main/java/com/example/chattutorial/MessagesActivity3.kt b/app/src/main/java/com/example/chattutorial/MessagesActivity3.kt deleted file mode 100644 index e971768..0000000 --- a/app/src/main/java/com/example/chattutorial/MessagesActivity3.kt +++ /dev/null @@ -1,194 +0,0 @@ -package com.example.chattutorial - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.viewModels -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.unit.dp -import io.getstream.chat.android.compose.ui.components.messageoptions.defaultMessageOptionsState -import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedMessageMenu -import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedReactionsMenu -import io.getstream.chat.android.compose.ui.messages.attachments.AttachmentsPicker -import io.getstream.chat.android.compose.ui.messages.composer.MessageComposer -import io.getstream.chat.android.compose.ui.messages.list.MessageList -import io.getstream.chat.android.compose.ui.theme.ChatTheme -import io.getstream.chat.android.compose.ui.theme.StreamShapes -import io.getstream.chat.android.compose.viewmodel.messages.AttachmentsPickerViewModel -import io.getstream.chat.android.compose.viewmodel.messages.MessageComposerViewModel -import io.getstream.chat.android.compose.viewmodel.messages.MessageListViewModel -import io.getstream.chat.android.compose.viewmodel.messages.MessagesViewModelFactory -import io.getstream.chat.android.ui.common.state.messages.MessageMode -import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageOptionsState -import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageReactionsState - -class MessagesActivity3 : ComponentActivity() { - - // Build the ViewModel factory - private val factory by lazy { - MessagesViewModelFactory( - context = this, - channelId = intent.getStringExtra(KEY_CHANNEL_ID) ?: "", - ) - } - - // Build the required ViewModels, using the 'factory' - private val listViewModel: MessageListViewModel by viewModels { factory } - private val attachmentsPickerViewModel: AttachmentsPickerViewModel by viewModels { factory } - private val composerViewModel: MessageComposerViewModel by viewModels { factory } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - // 1 - Load the ID of the selected channel - val channelId = intent.getStringExtra(KEY_CHANNEL_ID) - - if (channelId == null) { - finish() - return - } - - // 2 - Add the MessagesScreen to your UI - setContent { - ChatTheme( - shapes = StreamShapes - .defaultShapes() - .copy( - avatar = RoundedCornerShape(8.dp), - attachment = RoundedCornerShape(16.dp), - myMessageBubble = RoundedCornerShape(16.dp), - otherMessageBubble = RoundedCornerShape(16.dp), - inputField = RectangleShape - ) - ) { - MyCustomUi() - } - } - } - - @Composable - fun MyCustomUi() { - // 1 - Load the data - val isShowingAttachments = attachmentsPickerViewModel.isShowingAttachments - val selectedMessageState = listViewModel.currentMessagesState.selectedMessageState - val user by listViewModel.user.collectAsState() - - Box(modifier = Modifier.fillMaxSize()) { // 2 - Define the root - Scaffold( - modifier = Modifier.fillMaxSize(), - bottomBar = { - MessageComposer( // 3 - Add a composer - composerViewModel, - onAttachmentsClick = { - attachmentsPickerViewModel.changeAttachmentState(true) - } - ) - } - ) { - MessageList( // 4 - Build the MessageList and connect the actions - modifier = Modifier - .background(ChatTheme.colors.appBackground) - .padding(it) - .fillMaxSize(), - viewModel = listViewModel, - onThreadClick = { message -> - composerViewModel.setMessageMode(MessageMode.MessageThread(message)) - listViewModel.openMessageThread(message) - } - ) - } - - // 5 - Show attachments when necessary - if (isShowingAttachments) { - AttachmentsPicker( - attachmentsPickerViewModel = attachmentsPickerViewModel, - modifier = Modifier - .align(Alignment.BottomCenter) - .height(350.dp), - onAttachmentsSelected = { attachments -> - attachmentsPickerViewModel.changeAttachmentState(false) - composerViewModel.addSelectedAttachments(attachments) - }, - onDismiss = { - attachmentsPickerViewModel.changeAttachmentState(false) - attachmentsPickerViewModel.dismissAttachments() - }, - onTabClick = { _, _ -> /* Not needed for this example */ } - ) - } - - // 6 - Show the overlay if we've selected a message - if (selectedMessageState != null) { - val selectedMessage = selectedMessageState.message - if (selectedMessageState is SelectedMessageOptionsState) { - SelectedMessageMenu( - modifier = Modifier - .align(Alignment.Center) - .padding(horizontal = 20.dp) - .wrapContentSize(), - shape = ChatTheme.shapes.attachment, - messageOptions = defaultMessageOptionsState( - selectedMessage, - user, - selectedMessageState.ownCapabilities - ), - message = selectedMessage, - onMessageAction = { action -> - composerViewModel.performMessageAction(action) - listViewModel.performMessageAction(action) - }, - onShowMoreReactionsSelected = { - listViewModel.selectExtendedReactions(selectedMessage) - }, - onDismiss = { listViewModel.removeOverlay() }, - ownCapabilities = selectedMessageState.ownCapabilities - ) - } else if (selectedMessageState is SelectedMessageReactionsState) { - SelectedReactionsMenu( - modifier = Modifier - .align(Alignment.Center) - .padding(horizontal = 20.dp) - .wrapContentSize(), - shape = ChatTheme.shapes.attachment, - message = selectedMessage, - currentUser = user, - onMessageAction = { action -> - composerViewModel.performMessageAction(action) - listViewModel.performMessageAction(action) - }, - onShowMoreReactionsSelected = { - listViewModel.selectExtendedReactions(selectedMessage) - }, - onDismiss = { listViewModel.removeOverlay() }, - ownCapabilities = selectedMessageState.ownCapabilities - ) - } - } - } - } - - // 3 - Create an intent to start this Activity, with a given channelId - companion object { - private const val KEY_CHANNEL_ID = "channelId" - - fun getIntent(context: Context, channelId: String): Intent { - return Intent(context, MessagesActivity3::class.java).apply { - putExtra(KEY_CHANNEL_ID, channelId) - } - } - } -} diff --git a/app/src/main/java/com/example/chattutorial/MessagesActivity4.kt b/app/src/main/java/com/example/chattutorial/MessagesActivity4.kt deleted file mode 100644 index f302067..0000000 --- a/app/src/main/java/com/example/chattutorial/MessagesActivity4.kt +++ /dev/null @@ -1,239 +0,0 @@ -package com.example.chattutorial - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.viewModels -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Icon -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Keyboard -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.unit.dp -import io.getstream.chat.android.compose.ui.components.composer.MessageInput -import io.getstream.chat.android.compose.ui.components.messageoptions.defaultMessageOptionsState -import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedMessageMenu -import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedReactionsMenu -import io.getstream.chat.android.compose.ui.messages.attachments.AttachmentsPicker -import io.getstream.chat.android.compose.ui.messages.composer.MessageComposer -import io.getstream.chat.android.compose.ui.messages.list.MessageList -import io.getstream.chat.android.compose.ui.theme.ChatTheme -import io.getstream.chat.android.compose.ui.theme.StreamShapes -import io.getstream.chat.android.compose.viewmodel.messages.AttachmentsPickerViewModel -import io.getstream.chat.android.compose.viewmodel.messages.MessageComposerViewModel -import io.getstream.chat.android.compose.viewmodel.messages.MessageListViewModel -import io.getstream.chat.android.compose.viewmodel.messages.MessagesViewModelFactory -import io.getstream.chat.android.ui.common.state.messages.MessageMode -import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageOptionsState -import io.getstream.chat.android.ui.common.state.messages.list.SelectedMessageReactionsState - -class MessagesActivity4 : ComponentActivity() { - - // Build the ViewModel factory - private val factory by lazy { - MessagesViewModelFactory( - context = this, - channelId = intent.getStringExtra(KEY_CHANNEL_ID) ?: "", - ) - } - - // Build the required ViewModels, using the 'factory' - private val listViewModel: MessageListViewModel by viewModels { factory } - private val attachmentsPickerViewModel: AttachmentsPickerViewModel by viewModels { factory } - private val composerViewModel: MessageComposerViewModel by viewModels { factory } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - // 1 - Load the ID of the selected channel - val channelId = intent.getStringExtra(KEY_CHANNEL_ID) - - if (channelId == null) { - finish() - return - } - - // 2 - Add the MessagesScreen to your UI - setContent { - ChatTheme( - shapes = StreamShapes - .defaultShapes() - .copy( - avatar = RoundedCornerShape(8.dp), - attachment = RoundedCornerShape(16.dp), - myMessageBubble = RoundedCornerShape(16.dp), - otherMessageBubble = RoundedCornerShape(16.dp), - inputField = RectangleShape - ) - ) { - MyCustomUi() - } - } - } - - @Composable - fun MyCustomUi() { - // 1 - Load the data - val isShowingAttachments = attachmentsPickerViewModel.isShowingAttachments - val selectedMessageState = listViewModel.currentMessagesState.selectedMessageState - val user by listViewModel.user.collectAsState() - - Box(modifier = Modifier.fillMaxSize()) { // 2 - Define the root - Scaffold( - modifier = Modifier.fillMaxSize(), - bottomBar = { - MyCustomComposer() // <-- - } - ) { - MessageList( // 4 - Build the MessageList and connect the actions - modifier = Modifier - .background(ChatTheme.colors.appBackground) - .padding(it) - .fillMaxSize(), - viewModel = listViewModel, - onThreadClick = { message -> - composerViewModel.setMessageMode(MessageMode.MessageThread(message)) - listViewModel.openMessageThread(message) - } - ) - } - - // 5 - Show attachments when necessary - if (isShowingAttachments) { - AttachmentsPicker( - attachmentsPickerViewModel = attachmentsPickerViewModel, - modifier = Modifier - .align(Alignment.BottomCenter) - .height(350.dp), - onAttachmentsSelected = { attachments -> - attachmentsPickerViewModel.changeAttachmentState(false) - composerViewModel.addSelectedAttachments(attachments) - }, - onDismiss = { - attachmentsPickerViewModel.changeAttachmentState(false) - attachmentsPickerViewModel.dismissAttachments() - }, - onTabClick = { _, _ -> /* Not needed for this example */ } - ) - } - - // 6 - Show the overlay if we've selected a message - if (selectedMessageState != null) { - val selectedMessage = selectedMessageState.message - if (selectedMessageState is SelectedMessageOptionsState) { - SelectedMessageMenu( - modifier = Modifier - .align(Alignment.Center) - .padding(horizontal = 20.dp) - .wrapContentSize(), - shape = ChatTheme.shapes.attachment, - messageOptions = defaultMessageOptionsState( - selectedMessage, - user, - selectedMessageState.ownCapabilities - ), - message = selectedMessage, - onMessageAction = { action -> - composerViewModel.performMessageAction(action) - listViewModel.performMessageAction(action) - }, - onShowMoreReactionsSelected = { - listViewModel.selectExtendedReactions(selectedMessage) - }, - onDismiss = { listViewModel.removeOverlay() }, - ownCapabilities = selectedMessageState.ownCapabilities - ) - } else if (selectedMessageState is SelectedMessageReactionsState) { - SelectedReactionsMenu( - modifier = Modifier - .align(Alignment.Center) - .padding(horizontal = 20.dp) - .wrapContentSize(), - shape = ChatTheme.shapes.attachment, - message = selectedMessage, - currentUser = user, - onMessageAction = { action -> - composerViewModel.performMessageAction(action) - listViewModel.performMessageAction(action) - }, - onShowMoreReactionsSelected = { - listViewModel.selectExtendedReactions(selectedMessage) - }, - onDismiss = { listViewModel.removeOverlay() }, - ownCapabilities = selectedMessageState.ownCapabilities - ) - } - } - } - } - - @Composable - fun MyCustomComposer() { - MessageComposer( // 1 - Use our MessageComposer as the base component - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight(), - viewModel = composerViewModel, - integrations = {}, // 2 - Remove integrations from the composer - input = { inputState ->// 3 - Add a custom message input - MessageInput( - modifier = Modifier - .fillMaxWidth() - .weight(7f) - .padding(start = 8.dp) - .align(Alignment.CenterVertically), - messageComposerState = inputState, - onValueChange = { composerViewModel.setMessageInput(it) }, - onAttachmentRemoved = { composerViewModel.removeSelectedAttachment(it) }, - label = { // 4 - Override the label to show a custom icon and a text - Row( - Modifier.wrapContentWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = Icons.Default.Keyboard, - contentDescription = null, - tint = ChatTheme.colors.textLowEmphasis - ) - - Text( - modifier = Modifier.padding(start = 4.dp), - text = "Type something", - color = ChatTheme.colors.textLowEmphasis - ) - } - } - ) - } - ) - } - - // 3 - Create an intent to start this Activity, with a given channelId - companion object { - private const val KEY_CHANNEL_ID = "channelId" - - fun getIntent(context: Context, channelId: String): Intent { - return Intent(context, MessagesActivity4::class.java).apply { - putExtra(KEY_CHANNEL_ID, channelId) - } - } - } -} diff --git a/app/src/main/java/com/example/chattutorial/ui/theme/Color.kt b/app/src/main/java/com/example/chattutorial/ui/theme/Color.kt deleted file mode 100644 index 173234a..0000000 --- a/app/src/main/java/com/example/chattutorial/ui/theme/Color.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.example.chattutorial.ui.theme - -import androidx.compose.ui.graphics.Color - -val Purple200 = Color(0xFFBB86FC) -val Purple500 = Color(0xFF6200EE) -val Purple700 = Color(0xFF3700B3) -val Teal200 = Color(0xFF03DAC5) \ No newline at end of file diff --git a/app/src/main/java/com/example/chattutorial/ui/theme/Shape.kt b/app/src/main/java/com/example/chattutorial/ui/theme/Shape.kt deleted file mode 100644 index 5d7ef3b..0000000 --- a/app/src/main/java/com/example/chattutorial/ui/theme/Shape.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.chattutorial.ui.theme - -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Shapes -import androidx.compose.ui.unit.dp - -val Shapes = Shapes( - small = RoundedCornerShape(4.dp), - medium = RoundedCornerShape(4.dp), - large = RoundedCornerShape(0.dp) -) \ No newline at end of file diff --git a/app/src/main/java/com/example/chattutorial/ui/theme/Theme.kt b/app/src/main/java/com/example/chattutorial/ui/theme/Theme.kt deleted file mode 100644 index 30a9d4c..0000000 --- a/app/src/main/java/com/example/chattutorial/ui/theme/Theme.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.example.chattutorial.ui.theme - -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material.MaterialTheme -import androidx.compose.material.darkColors -import androidx.compose.material.lightColors -import androidx.compose.runtime.Composable - -private val DarkColorPalette = darkColors( - primary = Purple200, - primaryVariant = Purple700, - secondary = Teal200 -) - -private val LightColorPalette = lightColors( - primary = Purple500, - primaryVariant = Purple700, - secondary = Teal200 - - /* Other default colors to override - background = Color.White, - surface = Color.White, - onPrimary = Color.White, - onSecondary = Color.Black, - onBackground = Color.Black, - onSurface = Color.Black, - */ -) - -@Composable -fun ChatTutorialTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - content: @Composable() () -> Unit -) { - val colors = if (darkTheme) { - DarkColorPalette - } else { - LightColorPalette - } - - MaterialTheme( - colors = colors, - typography = Typography, - shapes = Shapes, - content = content - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/example/chattutorial/ui/theme/Type.kt b/app/src/main/java/com/example/chattutorial/ui/theme/Type.kt deleted file mode 100644 index 7eb9a22..0000000 --- a/app/src/main/java/com/example/chattutorial/ui/theme/Type.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.chattutorial.ui.theme - -import androidx.compose.material.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -// Set of Material typography styles to start with -val Typography = Typography( - body1 = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp - ) - /* Other default text styles to override - button = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.W500, - fontSize = 14.sp - ), - caption = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 12.sp - ) - */ -) \ No newline at end of file diff --git a/build.gradle b/build.gradle index ace9a6b..e7cd049 100644 --- a/build.gradle +++ b/build.gradle @@ -4,9 +4,9 @@ buildscript { mavenCentral() } dependencies { - classpath "com.android.tools.build:gradle:8.8.2" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.21" - classpath "org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.0.21" + classpath "com.android.tools.build:gradle:8.10.1" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0" + classpath "org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.2.0" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fbf6762..6591053 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Sep 15 12:53:53 KST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists