Skip to content

Commit d3d1b16

Browse files
committed
Migrate Kotlin tutorial samples to Stream Chat SDK v6
1 parent 1f14695 commit d3d1b16

18 files changed

+210
-219
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ buildscript {
44
mavenCentral()
55
}
66
dependencies {
7-
classpath "com.android.tools.build:gradle:7.2.2"
8-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
7+
classpath "com.android.tools.build:gradle:8.1.1"
8+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
99
}
1010
}
1111

gradle/wrapper/gradle-wrapper.jar

285 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

samplejava/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ plugins {
33
}
44

55
android {
6-
compileSdk 33
6+
compileSdk 34
7+
namespace "com.example.chattutorial"
78

89
defaultConfig {
910
applicationId "com.example.chattutorial"
1011
minSdk 21
11-
targetSdk 33
12+
targetSdk 34
1213
versionCode 1
1314
versionName "1.0"
1415

samplekotlin/build.gradle

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ plugins {
44
}
55

66
android {
7-
compileSdk 33
7+
compileSdk 34
8+
namespace "com.example.chattutorial"
89

910
defaultConfig {
1011
applicationId "com.example.chattutorial"
1112
minSdk 21
12-
targetSdk 33
13+
targetSdk 34
1314
versionCode 1
1415
versionName "1.0"
1516
}
@@ -18,13 +19,23 @@ android {
1819
buildFeatures {
1920
viewBinding true
2021
}
22+
23+
compileOptions {
24+
sourceCompatibility = JavaVersion.VERSION_11
25+
targetCompatibility = JavaVersion.VERSION_11
26+
}
27+
28+
kotlinOptions {
29+
jvmTarget = "11"
30+
}
2131
}
2232

2333
dependencies {
2434
// Add new dependencies
25-
implementation "io.getstream:stream-chat-android-ui-components:5.12.0"
26-
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"
27-
implementation "com.google.android.material:material:1.6.1"
28-
implementation "androidx.activity:activity-ktx:1.5.1"
29-
implementation "io.coil-kt:coil:2.1.0"
35+
implementation "io.getstream:stream-chat-android-ui-components:6.0.2"
36+
implementation "io.getstream:stream-chat-android-offline:6.0.2"
37+
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
38+
implementation "com.google.android.material:material:1.9.0"
39+
implementation "androidx.activity:activity-ktx:1.7.2"
40+
implementation "io.coil-kt:coil:2.4.0"
3041
}

samplekotlin/src/main/java/com/example/chattutorial/ChannelActivity.kt

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,14 @@ import androidx.activity.addCallback
77
import androidx.activity.viewModels
88
import androidx.appcompat.app.AppCompatActivity
99
import com.example.chattutorial.databinding.ActivityChannelBinding
10-
import com.getstream.sdk.chat.viewmodel.MessageInputViewModel
11-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel
12-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Normal
13-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Thread
14-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.State.NavigateUp
15-
import io.getstream.chat.android.client.models.Channel
16-
import io.getstream.chat.android.ui.message.input.viewmodel.bindView
17-
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModel
18-
import io.getstream.chat.android.ui.message.list.header.viewmodel.bindView
19-
import io.getstream.chat.android.ui.message.list.viewmodel.bindView
20-
import io.getstream.chat.android.ui.message.list.viewmodel.factory.MessageListViewModelFactory
10+
import io.getstream.chat.android.models.Channel
11+
import io.getstream.chat.android.ui.common.state.messages.Edit
12+
import io.getstream.chat.android.ui.common.state.messages.MessageMode
13+
import io.getstream.chat.android.ui.viewmodel.messages.MessageComposerViewModel
14+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListHeaderViewModel
15+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListViewModel
16+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListViewModelFactory
17+
import io.getstream.chat.android.ui.viewmodel.messages.bindView
2118

2219
class ChannelActivity : AppCompatActivity() {
2320

@@ -36,38 +33,41 @@ class ChannelActivity : AppCompatActivity() {
3633

3734
// Step 1 - Create three separate ViewModels for the views so it's easy
3835
// to customize them individually
39-
val factory = MessageListViewModelFactory(cid)
36+
val factory = MessageListViewModelFactory(this, cid)
4037
val messageListHeaderViewModel: MessageListHeaderViewModel by viewModels { factory }
4138
val messageListViewModel: MessageListViewModel by viewModels { factory }
42-
val messageInputViewModel: MessageInputViewModel by viewModels { factory }
39+
val messageComposerViewModel: MessageComposerViewModel by viewModels { factory }
4340

4441
// TODO set custom Imgur attachment factory
4542

4643
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
4744
messageListHeaderViewModel.bindView(binding.messageListHeaderView, this)
4845
messageListViewModel.bindView(binding.messageListView, this)
49-
messageInputViewModel.bindView(binding.messageInputView, this)
46+
messageComposerViewModel.bindView(binding.messageComposerView, this)
5047

5148
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread
5249
messageListViewModel.mode.observe(this) { mode ->
5350
when (mode) {
54-
is Thread -> {
51+
is MessageMode.MessageThread -> {
5552
messageListHeaderViewModel.setActiveThread(mode.parentMessage)
56-
messageInputViewModel.setActiveThread(mode.parentMessage)
53+
messageComposerViewModel.setMessageMode(MessageMode.MessageThread(mode.parentMessage))
5754
}
58-
Normal -> {
55+
56+
is MessageMode.Normal -> {
5957
messageListHeaderViewModel.resetThread()
60-
messageInputViewModel.resetThread()
58+
messageComposerViewModel.leaveThread()
6159
}
6260
}
6361
}
6462

6563
// Step 4 - Let the message input know when we are editing a message
66-
binding.messageListView.setMessageEditHandler(messageInputViewModel::postMessageToEdit)
64+
binding.messageListView.setMessageEditHandler { message ->
65+
messageComposerViewModel.performMessageAction(Edit(message))
66+
}
6767

6868
// Step 5 - Handle navigate up state
6969
messageListViewModel.state.observe(this) { state ->
70-
if (state is NavigateUp) {
70+
if (state is MessageListViewModel.State.NavigateUp) {
7171
finish()
7272
}
7373
}

samplekotlin/src/main/java/com/example/chattutorial/ChannelActivity2.kt

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,15 @@ import androidx.activity.addCallback
77
import androidx.activity.viewModels
88
import androidx.appcompat.app.AppCompatActivity
99
import com.example.chattutorial.databinding.ActivityChannel2Binding
10-
import com.getstream.sdk.chat.viewmodel.MessageInputViewModel
11-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel
12-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Normal
13-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Thread
14-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.State.NavigateUp
15-
import io.getstream.chat.android.client.models.Channel
16-
import io.getstream.chat.android.ui.message.input.viewmodel.bindView
17-
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentFactoryManager
18-
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModel
19-
import io.getstream.chat.android.ui.message.list.header.viewmodel.bindView
20-
import io.getstream.chat.android.ui.message.list.viewmodel.bindView
21-
import io.getstream.chat.android.ui.message.list.viewmodel.factory.MessageListViewModelFactory
10+
import io.getstream.chat.android.models.Channel
11+
import io.getstream.chat.android.ui.common.state.messages.Edit
12+
import io.getstream.chat.android.ui.common.state.messages.MessageMode
13+
import io.getstream.chat.android.ui.feature.messages.list.adapter.viewholder.attachment.AttachmentFactoryManager
14+
import io.getstream.chat.android.ui.viewmodel.messages.MessageComposerViewModel
15+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListHeaderViewModel
16+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListViewModel
17+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListViewModelFactory
18+
import io.getstream.chat.android.ui.viewmodel.messages.bindView
2219

2320
class ChannelActivity2 : AppCompatActivity() {
2421

@@ -37,10 +34,10 @@ class ChannelActivity2 : AppCompatActivity() {
3734

3835
// Step 1 - Create three separate ViewModels for the views so it's easy
3936
// to customize them individually
40-
val factory = MessageListViewModelFactory(cid)
37+
val factory = MessageListViewModelFactory(this, cid)
4138
val messageListHeaderViewModel: MessageListHeaderViewModel by viewModels { factory }
4239
val messageListViewModel: MessageListViewModel by viewModels { factory }
43-
val messageInputViewModel: MessageInputViewModel by viewModels { factory }
40+
val messageComposerViewModel: MessageComposerViewModel by viewModels { factory }
4441

4542
// Set a view factory manager for Imgur attachments
4643
val imgurAttachmentViewFactory = ImgurAttachmentFactory()
@@ -50,28 +47,31 @@ class ChannelActivity2 : AppCompatActivity() {
5047
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
5148
messageListHeaderViewModel.bindView(binding.messageListHeaderView, this)
5249
messageListViewModel.bindView(binding.messageListView, this)
53-
messageInputViewModel.bindView(binding.messageInputView, this)
50+
messageComposerViewModel.bindView(binding.messageComposerView, this)
5451

5552
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread
5653
messageListViewModel.mode.observe(this) { mode ->
5754
when (mode) {
58-
is Thread -> {
55+
is MessageMode.MessageThread -> {
5956
messageListHeaderViewModel.setActiveThread(mode.parentMessage)
60-
messageInputViewModel.setActiveThread(mode.parentMessage)
57+
messageComposerViewModel.setMessageMode(MessageMode.MessageThread(mode.parentMessage))
6158
}
62-
Normal -> {
59+
60+
is MessageMode.Normal -> {
6361
messageListHeaderViewModel.resetThread()
64-
messageInputViewModel.resetThread()
62+
messageComposerViewModel.leaveThread()
6563
}
6664
}
6765
}
6866

6967
// Step 4 - Let the message input know when we are editing a message
70-
binding.messageListView.setMessageEditHandler(messageInputViewModel::postMessageToEdit)
68+
binding.messageListView.setMessageEditHandler { message ->
69+
messageComposerViewModel.performMessageAction(Edit(message))
70+
}
7171

7272
// Step 5 - Handle navigate up state
7373
messageListViewModel.state.observe(this) { state ->
74-
if (state is NavigateUp) {
74+
if (state is MessageListViewModel.State.NavigateUp) {
7575
finish()
7676
}
7777
}

samplekotlin/src/main/java/com/example/chattutorial/ChannelActivity3.kt

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,24 @@ import android.os.Bundle
66
import androidx.activity.addCallback
77
import androidx.activity.viewModels
88
import androidx.appcompat.app.AppCompatActivity
9+
import androidx.lifecycle.Lifecycle
910
import androidx.lifecycle.lifecycleScope
11+
import androidx.lifecycle.repeatOnLifecycle
1012
import com.example.chattutorial.databinding.ActivityChannel3Binding
11-
import com.getstream.sdk.chat.viewmodel.MessageInputViewModel
12-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel
13-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Normal
14-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Thread
15-
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.State.NavigateUp
1613
import io.getstream.chat.android.client.ChatClient
17-
import io.getstream.chat.android.client.models.Channel
18-
import io.getstream.chat.android.offline.extensions.watchChannelAsState
19-
import io.getstream.chat.android.ui.message.input.viewmodel.bindView
20-
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentFactoryManager
21-
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModel
22-
import io.getstream.chat.android.ui.message.list.header.viewmodel.bindView
23-
import io.getstream.chat.android.ui.message.list.viewmodel.bindView
24-
import io.getstream.chat.android.ui.message.list.viewmodel.factory.MessageListViewModelFactory
14+
import io.getstream.chat.android.models.Channel
15+
import io.getstream.chat.android.state.extensions.watchChannelAsState
16+
import io.getstream.chat.android.ui.common.state.messages.Edit
17+
import io.getstream.chat.android.ui.common.state.messages.MessageMode
18+
import io.getstream.chat.android.ui.feature.messages.list.adapter.viewholder.attachment.AttachmentFactoryManager
19+
import io.getstream.chat.android.ui.viewmodel.messages.MessageComposerViewModel
20+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListHeaderViewModel
21+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListViewModel
22+
import io.getstream.chat.android.ui.viewmodel.messages.MessageListViewModelFactory
23+
import io.getstream.chat.android.ui.viewmodel.messages.bindView
2524
import kotlinx.coroutines.flow.filterNotNull
2625
import kotlinx.coroutines.flow.flatMapLatest
26+
import kotlinx.coroutines.launch
2727

2828
class ChannelActivity3 : AppCompatActivity() {
2929

@@ -42,10 +42,10 @@ class ChannelActivity3 : AppCompatActivity() {
4242

4343
// Step 1 - Create three separate ViewModels for the views so it's easy
4444
// to customize them individually
45-
val factory = MessageListViewModelFactory(cid)
45+
val factory = MessageListViewModelFactory(this, cid)
4646
val messageListHeaderViewModel: MessageListHeaderViewModel by viewModels { factory }
4747
val messageListViewModel: MessageListViewModel by viewModels { factory }
48-
val messageInputViewModel: MessageInputViewModel by viewModels { factory }
48+
val messageComposerViewModel: MessageComposerViewModel by viewModels { factory }
4949

5050
// Set a view factory manager for Imgur attachments
5151
val imgurAttachmentViewFactory = ImgurAttachmentFactory()
@@ -55,28 +55,31 @@ class ChannelActivity3 : AppCompatActivity() {
5555
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
5656
messageListHeaderViewModel.bindView(binding.messageListHeaderView, this)
5757
messageListViewModel.bindView(binding.messageListView, this)
58-
messageInputViewModel.bindView(binding.messageInputView, this)
58+
messageComposerViewModel.bindView(binding.messageComposerView, this)
5959

6060
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread
6161
messageListViewModel.mode.observe(this) { mode ->
6262
when (mode) {
63-
is Thread -> {
63+
is MessageMode.MessageThread -> {
6464
messageListHeaderViewModel.setActiveThread(mode.parentMessage)
65-
messageInputViewModel.setActiveThread(mode.parentMessage)
65+
messageComposerViewModel.setMessageMode(MessageMode.MessageThread(mode.parentMessage))
6666
}
67-
Normal -> {
67+
68+
is MessageMode.Normal -> {
6869
messageListHeaderViewModel.resetThread()
69-
messageInputViewModel.resetThread()
70+
messageComposerViewModel.leaveThread()
7071
}
7172
}
7273
}
7374

7475
// Step 4 - Let the message input know when we are editing a message
75-
binding.messageListView.setMessageEditHandler(messageInputViewModel::postMessageToEdit)
76+
binding.messageListView.setMessageEditHandler { message ->
77+
messageComposerViewModel.performMessageAction(Edit(message))
78+
}
7679

7780
// Step 5 - Handle navigate up state
7881
messageListViewModel.state.observe(this) { state ->
79-
if (state is NavigateUp) {
82+
if (state is MessageListViewModel.State.NavigateUp) {
8083
finish()
8184
}
8285
}
@@ -95,15 +98,18 @@ class ChannelActivity3 : AppCompatActivity() {
9598
binding.typingHeaderView.text = nobodyTyping
9699

97100
// Observe typing events and update typing header depending on its state.
98-
lifecycleScope.launchWhenStarted {
99-
ChatClient.instance().watchChannelAsState(cid, 30)
100-
.filterNotNull()
101-
.flatMapLatest { it.typing }
102-
.collect {
103-
binding.typingHeaderView.text = when {
104-
it.users.isNotEmpty() -> it.users.joinToString(prefix = "typing: ") { user -> user.name }
105-
else -> nobodyTyping
106-
}
101+
102+
lifecycleScope.launch {
103+
repeatOnLifecycle(Lifecycle.State.STARTED) {
104+
ChatClient.instance().watchChannelAsState(cid, 30)
105+
.filterNotNull()
106+
.flatMapLatest { it.typing }
107+
.collect {
108+
binding.typingHeaderView.text = when {
109+
it.users.isNotEmpty() -> it.users.joinToString(prefix = "typing: ") { user -> user.name }
110+
else -> nobodyTyping
111+
}
112+
}
107113
}
108114
}
109115
}

0 commit comments

Comments
 (0)