GetStream / stream-chat-android

:speech_balloon: Android Chat SDK ➜ Stream Chat API. UI component libraries for chat apps. Kotlin & Jetpack Compose messaging SDK for Android chat
https://getstream.io/chat/sdk/android/
Other
1.45k stars 272 forks source link

When i am inside the channel activity page and i receive the message, the message does not get read. How can i make the message be read? I am using custom messageViewHolder #854

Closed abhirup-patra closed 3 years ago

abhirup-patra commented 3 years ago

First time when i am entering the channel, all the received messages gets read. but while inside and i receive any message, that message is not getting read and as a result the unread count is showing wrong data.

abhirup-patra commented 3 years ago

for your preference, attaching the channel activity class and custom messageviewholder class codes here

***channel activity class****

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // we're using data binding in this example
        binding = DataBindingUtil.setContentView(this, R.layout.activity_channel);
        // most the business logic of the chat is handled in the ChannelViewModel view model
        binding.setLifecycleOwner(this);
        binding.messageList.setMessageViewHolderFactory(new BubbleMessageViewHolderFactory(this));

//        if (savedInstanceState != null) {
//            String messageText = savedInstanceState.getString(STATE_TEXT);
//            try {
//                binding.messageInput.setMessageText(messageText);
//            }
//            catch (Exception e){
//                e.printStackTrace();
//            }
//
//        }

        client = ChatClient.instance();

        getIntentData();
        initViewModel();

    }

private void getIntentData() {
        // receive the intent and create a channel object
        Intent intent = getIntent();
        Bundle b = this.getIntent().getExtras();

        if (b!=null){
            from = b.getString("from");
            channelType = b.getString(ChannelListFragment.EXTRA_CHANNEL_TYPE);
            channelId = b.getString(ChannelListFragment.EXTRA_CHANNEL_ID);
            cid = channelType + ":" + channelId;
            ad_id = b.getString("ad_id");
            ad_title = b.getString("ad_title");
            //  ad_memeber_id = intent.getStringExtra("ad_memeber_id");
            ad_member_image = b.getString("ad_member_image");
            ad_member_name = b.getString("ad_member_name");
            ad_owner_user_id = b.getString("ad_owner_user_id");
            adImage = b.getString("adImage");
            location = b.getString("location");
            currency_code = b.getString("currency_code");
            price = b.getString("price");
            ad_type = b.getString("ad_type");
            is_job = b.getString("is_job");
            if (ad_type.equalsIgnoreCase("wanted")){
                binding.ivAdImage.setVisibility(View.GONE);
            }

            if (is_job.equalsIgnoreCase("y")){
                binding.tvAdMoney.setVisibility(View.GONE);
            }

            created_date = b.getString("created_date");
            ad_slug = b.getString("ad_slug");
            display_slug = b.getString("display_slug");
            coming_from = b.getString("coming_from");
        }

        if(intent!=null) {
            from = intent.getStringExtra("from");
            channelType = intent.getStringExtra(ChannelListFragment.EXTRA_CHANNEL_TYPE);
            channelId = intent.getStringExtra(ChannelListFragment.EXTRA_CHANNEL_ID);
            cid = channelType + ":" + channelId;
            ad_id = intent.getStringExtra("ad_id");
            ad_title = intent.getStringExtra("ad_title");
          //  ad_memeber_id = intent.getStringExtra("ad_memeber_id");
            ad_member_image = intent.getStringExtra("ad_member_image");
            ad_member_name = intent.getStringExtra("ad_member_name");
            ad_owner_user_id = intent.getStringExtra("ad_owner_user_id");
            adImage = intent.getStringExtra("adImage");
            location = intent.getStringExtra("location");
            currency_code = intent.getStringExtra("currency_code");
            price = intent.getStringExtra("price");
            ad_type = intent.getStringExtra("ad_type");
            is_job = intent.getStringExtra("is_job");
            if (ad_type.equalsIgnoreCase("wanted")){
                binding.ivAdImage.setVisibility(View.GONE);
            }

            if (is_job.equalsIgnoreCase("y")){
                 binding.tvAdMoney.setVisibility(View.GONE);
            }

            created_date = intent.getStringExtra("created_date");
            ad_slug = intent.getStringExtra("ad_slug");
            display_slug = intent.getStringExtra("display_slug");
            coming_from = intent.getStringExtra("coming_from");
           // ad_image = intent.getStringExtra("ad_image");

          //  Client client = StreamChat.getInstance(getApplication());

            Log.e( "ad_owner_user_id: ",ad_owner_user_id+".Display_Slug="+display_slug );
          //  Log.e( "adImage: ",adImage);

        }
        AppPreferences.getInstance().setNewPushEnable(false);
        setDataInChatDetails();
    }

private void initViewModel() {

        // setup the viewmodel, remember to also set the channel

        ChannelController channelController = client.channel(channelType, channelId);

        MessageViewHolderFactory factory = new MessageViewHolderFactory();
//        viewModel = new ViewModelProvider(this, (ViewModelProvider.Factory) factory).get(MessageListViewModel.class);
        messageListViewModel = new MessageListViewModel(cid, StreamChat.chatDomain, StreamChat.client);
        MessageInputViewModel messageInputViewModel = new MessageInputViewModel(cid, StreamChat.chatDomain);
        uploadViewModel = new ViewModelProvider(this).get(CustomPostAdViewModel.class);

        Channel channel2 = messageListViewModel.getChannel();

        //abhirup changed 6/8/20
        MessageListViewModelBinding.bind(messageListViewModel, binding.messageList, this);

        ChannelActivity activity = this;

        clickListeners(activity);

//        binding.setViewModel(viewModel);
        binding.messageList.setAttachmentClickListener(activity);
//        binding.messageInput.setPermissionRequestListener(activity);

//        binding.messageList.setViewModel(viewModel, activity);
        binding.messageInput.setViewModel(messageInputViewModel, activity, this);

//        messageListViewModel.get.getInitialized().observe(this, channel -> {

        if (from.equalsIgnoreCase("adDetails")) {

            binding.tvUserStatus.setText("Online");
        } else {

            if (channel2.getMembers().size() >= 2) {

                String u1 = channel2.getMembers().get(0).getUserId().substring(4);
                String u2 = channel2.getMembers().get(1).getUserId().substring(4);

//

                int userNumber = 0;

                if (!u1.equalsIgnoreCase(String.valueOf(AppPreferences.getInstance().getLoginUserDetails().getData().getUser_details().getUser_id()))) {
                    userNumber = 0;
                } else if (!u2.equalsIgnoreCase(String.valueOf(AppPreferences.getInstance().getLoginUserDetails().getData().getUser_details().getUser_id()))) {
                    userNumber = 1;
                }

                if (channel2.getMembers().get(userNumber).getUser().getOnline()) {
                    binding.tvUserStatus.setText("ONLINE");
                } else {
                    try {
                        Date date = channel2.getMembers().get(0).getUser().getLastActive();
                        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                        String strDate = dateFormat.format(date);
                        // System.out.println("Converted String: " + strDate);
                        getTimeFromDate(strDate);
                        //getTimeFromDate((CharSequence)channel.createdBy.getLastActive());
                    }
                    catch (Exception e){
                        Utils.showToast("Date data not received, Please refresh to see it",this);
                    }

                }
            }

        }

//        });

    }

* customMessageviewholder class***

public BaseMessageListItemViewHolder<?> createMessageViewHolder(
            @NotNull ViewGroup parent,
            int viewType,
            @NotNull MessageListViewStyle style,
            @NotNull Channel channel) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_list_new, parent, false);

        BaseMessageListItemViewHolder holder = new BaseMessageListItemViewHolder(v) {

            @Override
            protected void bind(@NotNull MessageListItem messageListItem) {

                headerSpace = itemView.findViewById(R.id.space_header);
                text = itemView.findViewById(R.id.tv_text);
                GifImageView typing = itemView.findViewById(R.id.typingLoader);
                tvAttachment = itemView.findViewById(R.id.tv_attachment_text);
                iv = itemView.findViewById(R.id.iv_attachment_message);
                String ownID = "user"+AppPreferences.getInstance().getLoginUserDetails().getData().getUser_details().getUser_id();

                //abhirup changed 6/8/20
                if (messageListItem instanceof MessageListItem.MessageItem){

                    handleMessageItem((MessageListItem.MessageItem) messageListItem, activity, ownID);

                }

                if (viewType == MessageViewHolderFactory.MESSAGEITEM_TYPING){
                    typing.setVisibility(View.VISIBLE);
                }
                else
                    typing.setVisibility(View.GONE);

                //abhirup changed 6/8/20
                if (messageListItem instanceof MessageListItem.DateSeparatorItem) {

//                    read1.setVisibility(View.GONE);
//                    read2.setVisibility(View.GONE);
//                    read3.setVisibility(View.GONE);
                    text.setText(DateFormat
                            .getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT)
                            .format(((MessageListItem.DateSeparatorItem) messageListItem).getDate()));
                }
//                else
//                    headerSpace.setVisibility(View.GONE);
//                    text.setVisibility(View.GONE);

                itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        //abhirup changed 6/8/20
                        if (messageListItem instanceof MessageListItem.MessageItem) {
                            clickEvent((MessageListItem.MessageItem) messageListItem,activity);
                        }
                    }
                });

            }
        };

        return holder;
    }
devUndef1ned commented 3 years ago

Hello, @abhirup-patra As I see from your code snippet you did MessageListViewModelBinding.bind it means that when you reach the end of the messages list it marks all messages in this channel read. Did you scroll to the bottom list?

abhirup-patra commented 3 years ago

it is already at the end of the bottom list. When i am typing and sending a message still the message is not getting read. I mean the received message

samiuelson commented 3 years ago

@abhirup-patra, what version of SDK are you working on?

abhirup-patra commented 3 years ago

@ogkuzmin 4.4.1

devUndef1ned commented 3 years ago

@abhirup-patra We experienced such an issue, but not anymore using the latest version. Could you check it via the latest one 4.4.2?

abhirup-patra commented 3 years ago

ok will let you know if the problem persists

abhirup-patra commented 3 years ago

@ogkuzmin found a problem -

When i am building the app with the new sdk, it is getting build without any issue but when trying to run the app this is the error that is getting popped up.

/home/nav15/.gradle/caches/transforms-2/files-2.1/5981c3726640edd18f42eda0dd5b07ec/material-1.2.1/res/values/values.xml:3296:5-3298:23: AAPT: error: duplicate value for resource 'attr/values' with config ''.

devUndef1ned commented 3 years ago

It seems there is some collisions in style attributes. Do you use some library with custom views, or maybe you created in your app custom attribute for custom view? Is there any other details in error output?

abhirup-patra commented 3 years ago

With the previous build this wasnt the case. With this new sdk i am facing this error. I am not using any custom styles as such with the value attribute

JcMinarro commented 3 years ago

Ey @abhirup-patra Could you share your build.gradle file with the different dependencies you are using in your project? By same reason it seems that it is an issue with the rest of the dependencies you are using

abhirup-patra commented 3 years ago

Sure, Here it is

dependencies {
    def lifecycle_version = "1.1.1"
    def retrofit_version = "2.6.0"
    def okhttp_version = "3.9.0"
    def glide_version = "4.9.0";
    def support_version = "28.0.0"
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

    // crashlytics abhirup
    implementation 'com.google.firebase:firebase-analytics:17.5.0'
    implementation 'com.google.firebase:firebase-crashlytics:17.2.2'

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5'

    /* implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"*/
    implementation("com.squareup.retrofit2:retrofit:$retrofit_version") {
        // exclude Retrofit’s OkHttp dependency module and define your own module import
        exclude module: 'okhttp'
    }

    implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
    implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
    implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    //implementation 'com.google.android.material:material:1.0.0'
    implementation 'com.google.android.material:material:1.2.0-alpha05'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    implementation 'com.google.android.play:core:1.7.3'

    //play store updation
    implementation 'org.jsoup:jsoup:1.10.2'

    implementation 'com.karumi:dexter:4.2.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation "com.github.bumptech.glide:glide:$glide_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    annotationProcessor "com.github.bumptech.glide:compiler:$glide_version"
    implementation 'com.google.firebase:firebase-messaging:20.1.0'
    implementation 'com.google.firebase:firebase-storage:19.1.1'
    implementation 'androidx.multidex:multidex:2.0.1'
    // implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'

    implementation 'com.daimajia.swipelayout:library:1.2.0@aar'

    // circular image view
    implementation 'de.hdodenhof:circleimageview:3.0.0'

    //shimmer
    implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'

    //Google Play services
    implementation 'com.google.android.gms:play-services-auth:17.0.0'

    implementation 'com.google.android.gms:play-services-location:17.0.0'
//implementation 'com.google.android.gms:play-services-places:16.0.0'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation('com.google.android.libraries.places:places:1.1.0') {
        exclude module: 'glide'
    }

    //Facebook
    // implementation 'com.facebook.android:facebook-login:[5,6)'
    implementation "com.facebook.android:facebook-android-sdk:5.11.0"

    //Tinder Like Swipe View Libary
    implementation 'com.github.Yalantis:Koloda-Android:v0.0.2-alpha'
    //Animation
    implementation 'com.daimajia.easing:library:2.0@aar'
    implementation 'com.daimajia.androidanimations:library:2.3@aar'

    //algolia
    implementation 'com.algolia:algoliasearch-android:3.+@aar'

    implementation 'com.algolia:instantsearch-android:1.13.0'
    implementation 'com.shuhart.bubblepagerindicator:bubblepagerindicator:1.1.2'
    //SeekBar
    implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'
    //Range Seekbar
    implementation('com.github.Innovattic:range-seek-bar:v1.0.6') {
        exclude module: 'glide'
    }
    // This will automatically update to the latest v1 release when you build.
    //File Compressor
    implementation 'id.zelory:compressor:2.1.0'
    // This will automatically update to the latest v1 release when you build.

    implementation 'com.github.aakira:expandable-layout:1.6.0@aar'
    //expandable layout implementation for tags

    implementation 'com.google.android:flexbox:0.3.1'

    //Crop
    implementation 'com.github.yalantis:ucrop:2.2.2'

    //loaderButton
//    implementation 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3'

    //gif loader
    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.19'

    //horizontally overlapped circular images.
    implementation 'com.kartik.stackimageview:stackimageview:0.0.2'

    //mp android chart
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

    /* GetStream:stream-chat*/
    // api 'com.github.GetStream:stream-chat-android-client:1.0.12'
    //  implementation 'com.github.bumptech.glide:glide:4.9.0'
//    implementation 'com.github.GetStream:stream-chat-android:4.0.13'
    implementation 'com.github.GetStream:stream-chat-android:4.4.1'
    //implementation 'com.github.GetStream:stream-chat-android-livedata:0.3.0'

    // pusher
//    implementation 'com.pusher:chatkit-android:1.3.3'
    implementation "me.leolin:ShortcutBadger:1.1.22@aar"

    implementation 'com.google.firebase:firebase-messaging-directboot:20.3.0'

    //Socket
    implementation('io.socket:socket.io-client:1.0.0') {
        // excluding org.json which is provided by Android
        exclude group: 'org.json', module: 'json'
    }
devUndef1ned commented 3 years ago

Hello, @abhirup-patra It seems this issue is introduced by artifact 'com.algolia:instantsearch-android:1.13.0'. It has attribute with name "values" (see here ) which is already in the material library from Google. (for component RangeSlider)

abhirup-patra commented 3 years ago

@ogkuzmin

What can be the solution? can you please suggest?

devUndef1ned commented 3 years ago

@abhirup-patra It depends on what you need. Right now it's not possible to use google material library with 'com.algolia:instantsearch-android:1.13.0'. So possible ways: 1) If it's not critical and it's no wide used in your project you can remove this dependency 2) I saw 1.13.0' is not the latest version of 'com.algolia:instantsearch-android'. They even have 2+ version. You can try to migrate to newer one 3) If it's critical to use this library and you can't migrate to a newer version you can create an issue at their Github/ask them to help you. Maybe they can give you some piece of advise how to solve this.

abhirup-patra commented 3 years ago

ok

On Thu, Nov 26, 2020 at 6:32 PM ogkuzmin notifications@github.com wrote:

@abhirup-patra https://github.com/abhirup-patra It depends on what you need. Right now it's not possible to use google material library with 'com.algolia:instantsearch-android:1.13.0'. So possible ways:

  1. If it's not critical and it's no wide used in your project you can remove this dependency
  2. I saw 1.13.0' is not the latest version of 'com.algolia:instantsearch-android'. They even have 2+ version. You can try to migrate to newer one
  3. If it's critical to use this library and you can't migrate to a newer version you can create an issue at their Github/ask them to help you. Maybe they can give you some piece of advise how to solve this.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/GetStream/stream-chat-android/issues/854#issuecomment-734286314, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANEGGBHUGNQVKYCIO7SIYPTSRZGXLANCNFSM4TUIZGXQ .