chromium/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupListView.java

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.tasks.tab_management;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.util.Consumer;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;

import org.chromium.chrome.tab_ui.R;
import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
import org.chromium.components.browser_ui.widget.selectable_list.SelectableListLayout;

/** Conditionally displays empty state for the tab group pane. */
public class TabGroupListView extends FrameLayout {
    private RecyclerView mRecyclerView;
    private View mEmptyStateContainer;
    private TextView mEmptyStateSubheading;
    private UiConfig mUiConfig;

    /** Constructor for inflation. */
    public TabGroupListView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        Context context = getContext();
        mRecyclerView = findViewById(R.id.tab_group_list_recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(context));

        mEmptyStateContainer = findViewById(R.id.empty_state_container);

        ImageView emptyStateIllustration = findViewById(R.id.empty_state_icon);
        Drawable illustration =
                AppCompatResources.getDrawable(
                        context, R.drawable.tab_group_list_empty_state_illustration);
        emptyStateIllustration.setImageDrawable(illustration);

        TextView emptyStateHeading = findViewById(R.id.empty_state_text_title);
        emptyStateHeading.setText(R.string.tab_groups_empty_header);
        mEmptyStateSubheading = findViewById(R.id.empty_state_text_description);

        mUiConfig = new UiConfig(this);
        mUiConfig.addObserver(this::onDisplayStyleChanged);
    }

    void setRecyclerViewAdapter(RecyclerView.Adapter adapter) {
        mRecyclerView.setAdapter(adapter);
    }

    void setOnIsScrolledChanged(Consumer<Boolean> onIsScrolledMaybeChanged) {
        // Layout listener is for when items are removed that stops the view from being scrollable.
        mRecyclerView.addOnLayoutChangeListener(
                (view, i, i1, i2, i3, i4, i5, i6, i7) ->
                        onIsScrolledMaybeChanged.accept(
                                mRecyclerView.computeVerticalScrollOffset() != 0));
        mRecyclerView.addOnScrollListener(
                new OnScrollListener() {
                    @Override
                    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                        onIsScrolledMaybeChanged.accept(
                                mRecyclerView.computeVerticalScrollOffset() != 0);
                    }
                });
    }

    void setEmptyStateVisible(boolean visible) {
        mEmptyStateContainer.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
        mRecyclerView.setVisibility(visible ? View.INVISIBLE : View.VISIBLE);
    }

    void setSyncEnabled(boolean enabled) {
        mEmptyStateSubheading.setText(
                enabled
                        ? R.string.tab_groups_empty_state_description
                        : R.string.tab_groups_empty_state_description_no_sync);
    }

    private void onDisplayStyleChanged(UiConfig.DisplayStyle newDisplayStyle) {
        int padding =
                SelectableListLayout.getPaddingForDisplayStyle(newDisplayStyle, getResources());
        mRecyclerView.setPaddingRelative(
                padding, mRecyclerView.getPaddingTop(), padding, mRecyclerView.getPaddingBottom());
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        if (mUiConfig != null) mUiConfig.updateDisplayStyle();
    }
}