Skip to content

Commit d4c6f40

Browse files
committed
- Updated applications to SDK 5.1.0
1 parent 9913c5d commit d4c6f40

File tree

8 files changed

+114
-89
lines changed

8 files changed

+114
-89
lines changed

samplejava/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ android {
3030

3131
dependencies {
3232
// Add new dependencies
33-
implementation "io.getstream:stream-chat-android-ui-components:4.28.2"
34-
implementation "com.google.android.material:material:1.4.0"
33+
implementation "io.getstream:stream-chat-android-ui-components:5.1.0"
34+
implementation "com.google.android.material:material:1.6.0"
3535
implementation "androidx.activity:activity-ktx:1.4.0"
3636
implementation "io.coil-kt:coil:1.4.0"
3737
}

samplejava/src/main/java/com/example/chattutorial/ChannelActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
6060

6161
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
6262
MessageListHeaderViewModelBinding.bind(messageListHeaderViewModel, binding.messageListHeaderView, this);
63-
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this);
63+
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this, true);
6464
MessageInputViewModelBinding.bind(messageInputViewModel, binding.messageInputView, this);
6565

6666
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread

samplejava/src/main/java/com/example/chattutorial/ChannelActivity2.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Thread;
1717
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.State.NavigateUp;
1818

19+
import java.util.ArrayList;
20+
import java.util.List;
21+
1922
import io.getstream.chat.android.client.models.Channel;
2023
import io.getstream.chat.android.client.models.Message;
2124
import io.getstream.chat.android.ui.message.input.viewmodel.MessageInputViewModelBinding;
25+
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentFactoryManager;
2226
import io.getstream.chat.android.ui.message.list.header.MessageListHeaderView;
2327
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModel;
2428
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModelBinding;
@@ -56,12 +60,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
5660
MessageListViewModel messageListViewModel = provider.get(MessageListViewModel.class);
5761
MessageInputViewModel messageInputViewModel = provider.get(MessageInputViewModel.class);
5862

59-
// Set view factory for Imgur attachments
60-
binding.messageListView.setAttachmentViewFactory(new ImgurAttachmentViewFactory());
63+
// Set view factory manager for Imgur attachments
64+
ImgurAttachmentViewFactory imgurAttachmentViewFactory = new ImgurAttachmentViewFactory();
65+
66+
List<ImgurAttachmentViewFactory> imgurAttachmentViewFactories = new ArrayList<ImgurAttachmentViewFactory>();
67+
imgurAttachmentViewFactories.add(imgurAttachmentViewFactory);
68+
69+
AttachmentFactoryManager attachmentFactoryManager = new AttachmentFactoryManager(imgurAttachmentViewFactories);
70+
binding.messageListView.setAttachmentFactoryManager(attachmentFactoryManager);
6171

6272
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
6373
MessageListHeaderViewModelBinding.bind(messageListHeaderViewModel, binding.messageListHeaderView, this);
64-
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this);
74+
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this, true);
6575
MessageInputViewModelBinding.bind(messageInputViewModel, binding.messageInputView, this);
6676

6777
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread

samplejava/src/main/java/com/example/chattutorial/ChannelActivity3.java

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@
1818
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Thread;
1919
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.State.NavigateUp;
2020

21-
import java.util.LinkedList;
21+
import java.util.ArrayList;
2222
import java.util.List;
2323

2424
import io.getstream.chat.android.client.models.Channel;
2525
import io.getstream.chat.android.client.models.Message;
26-
import io.getstream.chat.android.client.models.User;
27-
import io.getstream.chat.android.livedata.ChatDomain;
28-
import io.getstream.chat.android.livedata.controller.ChannelController;
2926
import io.getstream.chat.android.ui.message.input.viewmodel.MessageInputViewModelBinding;
27+
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentFactoryManager;
3028
import io.getstream.chat.android.ui.message.list.header.MessageListHeaderView;
3129
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModel;
3230
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModelBinding;
@@ -64,12 +62,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
6462
MessageListViewModel messageListViewModel = provider.get(MessageListViewModel.class);
6563
MessageInputViewModel messageInputViewModel = provider.get(MessageInputViewModel.class);
6664

67-
// Set view factory for Imgur attachments
68-
binding.messageListView.setAttachmentViewFactory(new ImgurAttachmentViewFactory());
65+
// Set view factory manager for Imgur attachments
66+
ImgurAttachmentViewFactory imgurAttachmentViewFactory = new ImgurAttachmentViewFactory();
67+
68+
List<ImgurAttachmentViewFactory> imgurAttachmentViewFactories = new ArrayList<ImgurAttachmentViewFactory>();
69+
imgurAttachmentViewFactories.add(imgurAttachmentViewFactory);
70+
71+
AttachmentFactoryManager attachmentFactoryManager = new AttachmentFactoryManager(imgurAttachmentViewFactories);
72+
binding.messageListView.setAttachmentFactoryManager(attachmentFactoryManager);
6973

7074
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
7175
MessageListHeaderViewModelBinding.bind(messageListHeaderViewModel, binding.messageListHeaderView, this);
72-
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this);
76+
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this, true);
7377
MessageInputViewModelBinding.bind(messageInputViewModel, binding.messageInputView, this);
7478

7579
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread
@@ -111,25 +115,7 @@ public void handleOnBackPressed() {
111115
String nobodyTyping = "nobody is typing";
112116
typingHeaderView.setText(nobodyTyping);
113117

114-
// Obtain a ChannelController
115-
ChatDomain.instance()
116-
.getChannelController(cid)
117-
.enqueue((result) -> {
118-
ChannelController channelController = result.data();
119-
120-
// Observe typing users
121-
channelController.getTyping().observe(this, typingState -> {
122-
if (typingState.getUsers().isEmpty()) {
123-
typingHeaderView.setText(nobodyTyping);
124-
} else {
125-
List<String> userNames = new LinkedList<>();
126-
for (User user : typingState.getUsers()) {
127-
userNames.add(user.getName());
128-
}
129-
String typing = "typing: " + TextUtils.join(", ", userNames);
130-
typingHeaderView.setText(typing);
131-
}
132-
});
133-
});
118+
//TODO implemet an OP based solution here once the Core team introduces extensions for StateFlow
119+
// based values
134120
}
135121
}

samplejava/src/main/java/com/example/chattutorial/ChannelActivity4.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.Mode.Thread;
1919
import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel.State.NavigateUp;
2020

21+
import java.util.ArrayList;
2122
import java.util.HashSet;
23+
import java.util.List;
2224
import java.util.Set;
2325

2426
import io.getstream.chat.android.client.ChatClient;
@@ -28,6 +30,7 @@
2830
import io.getstream.chat.android.client.models.Message;
2931
import io.getstream.chat.android.client.models.User;
3032
import io.getstream.chat.android.ui.message.input.viewmodel.MessageInputViewModelBinding;
33+
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentFactoryManager;
3134
import io.getstream.chat.android.ui.message.list.header.MessageListHeaderView;
3235
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModel;
3336
import io.getstream.chat.android.ui.message.list.header.viewmodel.MessageListHeaderViewModelBinding;
@@ -65,12 +68,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
6568
MessageListViewModel messageListViewModel = provider.get(MessageListViewModel.class);
6669
MessageInputViewModel messageInputViewModel = provider.get(MessageInputViewModel.class);
6770

68-
// Set view factory for Imgur attachments
69-
binding.messageListView.setAttachmentViewFactory(new ImgurAttachmentViewFactory());
71+
// Set view factory manager for Imgur attachments
72+
ImgurAttachmentViewFactory imgurAttachmentViewFactory = new ImgurAttachmentViewFactory();
73+
74+
List<ImgurAttachmentViewFactory> imgurAttachmentViewFactories = new ArrayList<ImgurAttachmentViewFactory>();
75+
imgurAttachmentViewFactories.add(imgurAttachmentViewFactory);
76+
77+
AttachmentFactoryManager attachmentFactoryManager = new AttachmentFactoryManager(imgurAttachmentViewFactories);
78+
binding.messageListView.setAttachmentFactoryManager(attachmentFactoryManager);
7079

7180
// Step 2 - Bind the view and ViewModels, they are loosely coupled so it's easy to customize
7281
MessageListHeaderViewModelBinding.bind(messageListHeaderViewModel, binding.messageListHeaderView, this);
73-
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this);
82+
MessageListViewModelBinding.bind(messageListViewModel, binding.messageListView, this, true);
7483
MessageInputViewModelBinding.bind(messageInputViewModel, binding.messageInputView, this);
7584

7685
// Step 3 - Let both MessageListHeaderView and MessageInputView know when we open a thread
Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,75 @@
11
package com.example.chattutorial;
22

33
import android.view.LayoutInflater;
4-
import android.view.View;
54
import android.view.ViewGroup;
65

6+
import androidx.annotation.NonNull;
7+
import androidx.annotation.Nullable;
8+
79
import com.example.chattutorial.databinding.AttachmentImgurBinding;
8-
import com.getstream.sdk.chat.adapter.MessageListItem;
910
import com.google.android.material.shape.ShapeAppearanceModel;
1011

1112
import org.jetbrains.annotations.NotNull;
12-
import org.jetbrains.annotations.Nullable;
1313

1414
import coil.Coil;
1515
import coil.request.ImageRequest;
1616
import io.getstream.chat.android.client.models.Attachment;
17-
import io.getstream.chat.android.ui.message.list.MessageListItemStyle;
17+
import io.getstream.chat.android.client.models.Message;
1818
import io.getstream.chat.android.ui.message.list.adapter.MessageListListenerContainer;
19-
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentViewFactory;
19+
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.AttachmentFactory;
20+
import io.getstream.chat.android.ui.message.list.adapter.viewholder.attachment.InnerAttachmentViewHolder;
21+
22+
public class ImgurAttachmentViewFactory implements AttachmentFactory {
2023

21-
public class ImgurAttachmentViewFactory extends AttachmentViewFactory {
2224

23-
@NotNull
2425
@Override
25-
public View createAttachmentView(@NotNull MessageListItem.MessageItem data,
26-
@Nullable MessageListListenerContainer listeners,
27-
@NotNull MessageListItemStyle style,
28-
@NotNull ViewGroup parent) {
29-
Attachment imgurAttachment = null;
30-
for (Attachment attachment : data.getMessage().getAttachments()) {
31-
String imageUrl = attachment.getImageUrl();
32-
if (imageUrl != null && imageUrl.contains("imgur")) {
33-
imgurAttachment = attachment;
34-
break;
26+
public boolean canHandle(@NonNull Message message) {
27+
return containsImgurAttachments(message) != null;
28+
}
29+
30+
@NonNull
31+
@Override
32+
public InnerAttachmentViewHolder createViewHolder(@NonNull Message message, @Nullable MessageListListenerContainer messageListListenerContainer, @NonNull ViewGroup viewGroup) {
33+
Attachment imgurAttachment = containsImgurAttachments(message);
34+
35+
AttachmentImgurBinding attachmentImgurBinding = AttachmentImgurBinding.inflate(LayoutInflater.from(viewGroup.getContext()), null, false);
36+
37+
return new ImgurAttachmentViewHolder(attachmentImgurBinding, imgurAttachment);
38+
}
39+
40+
private Attachment containsImgurAttachments(@NotNull Message message) {
41+
for (int i = 0; i < message.getAttachments().size(); i++) {
42+
boolean containsAttachments = message.getAttachments().get(i).getImageUrl().contains("imgur");
43+
44+
if (containsAttachments) {
45+
return message.getAttachments().get(i);
3546
}
3647
}
3748

38-
if (imgurAttachment != null) {
39-
return createImgurAttachmentView(imgurAttachment, parent);
40-
} else {
41-
return super.createAttachmentView(data, listeners, style, parent);
42-
}
49+
return null;
4350
}
4451

45-
private View createImgurAttachmentView(Attachment imgurAttachment, ViewGroup parent) {
46-
AttachmentImgurBinding binding = AttachmentImgurBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
47-
48-
float cornerRadius = binding.getRoot()
49-
.getResources()
50-
.getDimension(R.dimen.stream_ui_selected_attachment_corner_radius);
51-
ShapeAppearanceModel model = binding.ivMediaThumb.getShapeAppearanceModel()
52-
.toBuilder()
53-
.setAllCornerSizes(cornerRadius)
54-
.build();
55-
binding.ivMediaThumb.setShapeAppearanceModel(model);
56-
57-
ImageRequest imageRequest = new ImageRequest.Builder(parent.getContext())
58-
.data(imgurAttachment.getImageUrl())
59-
.allowHardware(false)
60-
.crossfade(true)
61-
.placeholder(R.drawable.stream_ui_picture_placeholder)
62-
.target(binding.ivMediaThumb)
63-
.build();
64-
Coil.imageLoader(parent.getContext()).enqueue(imageRequest);
65-
66-
return binding.getRoot();
52+
private class ImgurAttachmentViewHolder extends InnerAttachmentViewHolder {
53+
54+
public ImgurAttachmentViewHolder(AttachmentImgurBinding binding,
55+
Attachment imgurAttachment) {
56+
super(binding.getRoot());
57+
58+
ShapeAppearanceModel shapeAppearanceModel = binding.ivMediaThumb.getShapeAppearanceModel()
59+
.toBuilder()
60+
.setAllCornerSizes(binding.ivMediaThumb.getResources().getDimension(R.dimen.stream_ui_selected_attachment_corner_radius))
61+
.build();
62+
63+
binding.ivMediaThumb.setShapeAppearanceModel(shapeAppearanceModel);
64+
65+
ImageRequest imageRequest = new ImageRequest.Builder(binding.getRoot().getContext())
66+
.data(imgurAttachment.getImageUrl())
67+
.allowHardware(false)
68+
.crossfade(true)
69+
.placeholder(R.drawable.stream_ui_picture_placeholder)
70+
.target(binding.ivMediaThumb)
71+
.build();
72+
Coil.imageLoader(binding.getRoot().getContext()).enqueue(imageRequest);
73+
}
6774
}
6875
}

samplejava/src/main/java/com/example/chattutorial/MainActivity.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
import io.getstream.chat.android.client.logger.ChatLogLevel;
1515
import io.getstream.chat.android.client.models.Filters;
1616
import io.getstream.chat.android.client.models.User;
17-
import io.getstream.chat.android.livedata.ChatDomain;
17+
import io.getstream.chat.android.offline.model.message.attachments.UploadAttachmentsNetworkType;
18+
import io.getstream.chat.android.offline.plugin.configuration.Config;
19+
import io.getstream.chat.android.offline.plugin.factory.StreamOfflinePluginFactory;
1820
import io.getstream.chat.android.ui.channel.list.viewmodel.ChannelListViewModel;
1921
import io.getstream.chat.android.ui.channel.list.viewmodel.ChannelListViewModelBinding;
2022
import io.getstream.chat.android.ui.channel.list.viewmodel.factory.ChannelListViewModelFactory;
@@ -30,13 +32,24 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
3032
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
3133
setContentView(binding.getRoot());
3234

33-
// Step 1 - Set up the client for API calls and the domain for offline storage
35+
// Step 1 - Set up the OfflinePlugin for offline storage
36+
StreamOfflinePluginFactory streamOfflinePluginFactory = new StreamOfflinePluginFactory(
37+
new Config(
38+
true,
39+
true,
40+
true,
41+
UploadAttachmentsNetworkType.NOT_ROAMING
42+
),
43+
getApplicationContext()
44+
);
45+
46+
// Step 2 - Set up the client for API calls with the plugin for offline storage
3447
ChatClient client = new ChatClient.Builder("b67pax5b2wdq", getApplicationContext())
48+
.withPlugin(streamOfflinePluginFactory)
3549
.logLevel(ChatLogLevel.ALL) // Set to NOTHING in prod
3650
.build();
37-
new ChatDomain.Builder(client, getApplicationContext()).build();
3851

39-
// Step 2 - Authenticate and connect the user
52+
// Step 3 - Authenticate and connect the user
4053
User user = new User();
4154
user.setId("tutorial-droid");
4255
user.setName("Tutorial Droid");
@@ -47,7 +60,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
4760
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoidHV0b3JpYWwtZHJvaWQifQ.NhEr0hP9W9nwqV7ZkdShxvi02C5PR7SJE7Cs4y7kyqg"
4861
).enqueue();
4962

50-
// Step 3 - Set the channel list filter and order
63+
// Step 4 - Set the channel list filter and order
5164
// This can be read as requiring only channels whose "type" is "messaging" AND
5265
// whose "members" include our "user.id"
5366
FilterObject filter = Filters.and(
@@ -63,7 +76,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
6376
ChannelListViewModel channelsViewModel =
6477
new ViewModelProvider(this, factory).get(ChannelListViewModel.class);
6578

66-
// Step 4 - Connect the ChannelListViewModel to the ChannelListView, loose
79+
// Step 5 - Connect the ChannelListViewModel to the ChannelListView, loose
6780
// coupling makes it easy to customize
6881
ChannelListViewModelBinding.bind(channelsViewModel, binding.channelListView, this);
6982
binding.channelListView.setChannelItemClickListener(

samplekotlin/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
plugins {
22
id 'com.android.application'
3-
id 'kotlin-android'
3+
id 'org.jetbrains.kotlin.android'
44
}
55

66
android {
@@ -22,9 +22,9 @@ android {
2222

2323
dependencies {
2424
// Add new dependencies
25-
implementation "io.getstream:stream-chat-android-ui-components:5.0.1"
25+
implementation "io.getstream:stream-chat-android-ui-components:5.1.0"
2626
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1"
27-
implementation "com.google.android.material:material:1.5.0"
27+
implementation "com.google.android.material:material:1.6.0"
2828
implementation "androidx.activity:activity-ktx:1.4.0"
2929
implementation "io.coil-kt:coil:1.4.0"
3030
}

0 commit comments

Comments
 (0)