Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56ee6b5c authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Automerger Merge Worker
Browse files

Merge "Move click handler from XML to ViewModel (1/2)" into tm-qpr-dev am: 28aa7dd5

parents df12910f 28aa7dd5
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -54,7 +54,6 @@
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_gravity="center"
        android:background="@drawable/rounded_bg_full_large_radius"
        android:background="@drawable/rounded_bg_full_large_radius"
        android:onClick="dismissActivity"
        android:text="@string/got_it"
        android:text="@string/got_it"
        android:textColor="?androidprv:attr/textColorOnAccent"
        android:textColor="?androidprv:attr/textColorOnAccent"
        android:layout_marginBottom="60dp"
        android:layout_marginBottom="60dp"
+16 −24
Original line number Original line Diff line number Diff line
@@ -22,7 +22,6 @@ import static android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID;
import android.content.Intent;
import android.content.Intent;
import android.os.Bundle;
import android.os.Bundle;
import android.util.Log;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;


import androidx.activity.ComponentActivity;
import androidx.activity.ComponentActivity;
@@ -40,7 +39,6 @@ public class PeopleSpaceActivity extends ComponentActivity {
    private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
    private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;


    private final PeopleViewModel.Factory mViewModelFactory;
    private final PeopleViewModel.Factory mViewModelFactory;
    private PeopleViewModel mViewModel;


    @Inject
    @Inject
    public PeopleSpaceActivity(PeopleViewModel.Factory viewModelFactory) {
    public PeopleSpaceActivity(PeopleViewModel.Factory viewModelFactory) {
@@ -52,38 +50,32 @@ public class PeopleSpaceActivity extends ComponentActivity {
    protected void onCreate(Bundle savedInstanceState) {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        setResult(RESULT_CANCELED);
        setResult(RESULT_CANCELED);
        mViewModel = new ViewModelProvider(this, mViewModelFactory).get(PeopleViewModel.class);

        PeopleViewModel viewModel = new ViewModelProvider(this, mViewModelFactory).get(
                PeopleViewModel.class);


        // Update the widget ID coming from the intent.
        // Update the widget ID coming from the intent.
        int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
        int widgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID);
        mViewModel.onWidgetIdChanged(widgetId);
        viewModel.onWidgetIdChanged(widgetId);


        ViewGroup view = PeopleViewBinder.create(this);
        ViewGroup view = PeopleViewBinder.create(this);
        PeopleViewBinder.bind(view, mViewModel, /* lifecycleOwner= */ this,
        PeopleViewBinder.bind(view, viewModel, /* lifecycleOwner= */ this,
                () -> {
                (result) -> {
                    finishActivity();
                    finishActivity(result);
                    return null;
                    return null;
                });
                });
        setContentView(view);
        setContentView(view);
    }
    }


    /** Finish activity with a successful widget configuration result. */
    private void finishActivity(PeopleViewModel.Result result) {
    private void finishActivity() {
        if (result instanceof PeopleViewModel.Result.Success) {
            if (DEBUG) Log.d(TAG, "Widget added!");
            if (DEBUG) Log.d(TAG, "Widget added!");
        setActivityResult(RESULT_OK);
            Intent data = ((PeopleViewModel.Result.Success) result).getData();
        finish();
            setResult(RESULT_OK, data);
    }
        } else {

    /** Finish activity without choosing a widget. */
    public void dismissActivity(View v) {
            if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
            if (DEBUG) Log.d(TAG, "Activity dismissed with no widgets added!");
            setResult(RESULT_CANCELED);
            setResult(RESULT_CANCELED);
        finish();
        }
        }

        finish();
    private void setActivityResult(int result) {
        Intent resultValue = new Intent();
        resultValue.putExtra(EXTRA_APPWIDGET_ID, mViewModel.getAppWidgetId().getValue());
        setResult(result, resultValue);
    }
    }
}
}
+13 −9
Original line number Original line Diff line number Diff line
@@ -41,7 +41,7 @@ import kotlinx.coroutines.launch


/** A ViewBinder for [PeopleViewModel]. */
/** A ViewBinder for [PeopleViewModel]. */
object PeopleViewBinder {
object PeopleViewBinder {
    private const val TAG = "PeopleSpaceViewBinder"
    private const val TAG = "PeopleViewBinder"


    /**
    /**
     * The [ViewOutlineProvider] used to clip the corner radius of the recent and priority lists.
     * The [ViewOutlineProvider] used to clip the corner radius of the recent and priority lists.
@@ -72,15 +72,15 @@ object PeopleViewBinder {
        view: ViewGroup,
        view: ViewGroup,
        viewModel: PeopleViewModel,
        viewModel: PeopleViewModel,
        lifecycleOwner: LifecycleOwner,
        lifecycleOwner: LifecycleOwner,
        onFinish: () -> Unit,
        onResult: (PeopleViewModel.Result) -> Unit,
    ) {
    ) {
        // Call [onFinish] this activity when the ViewModel tells us so.
        // Call [onResult] as soon as a result is available.
        lifecycleOwner.lifecycleScope.launch {
        lifecycleOwner.lifecycleScope.launch {
            lifecycleOwner.repeatOnLifecycle(CREATED) {
            lifecycleOwner.repeatOnLifecycle(CREATED) {
                viewModel.isFinished.collect { isFinished ->
                viewModel.result.collect { result ->
                    if (isFinished) {
                    if (result != null) {
                        viewModel.clearIsFinished()
                        viewModel.clearResult()
                        onFinish()
                        onResult(result)
                    }
                    }
                }
                }
            }
            }
@@ -104,7 +104,7 @@ object PeopleViewBinder {
                                viewModel::onTileClicked,
                                viewModel::onTileClicked,
                            )
                            )
                        } else {
                        } else {
                            setNoConversationsContent(view)
                            setNoConversationsContent(view, viewModel::onUserJourneyCancelled)
                        }
                        }
                    }
                    }
            }
            }
@@ -119,7 +119,7 @@ object PeopleViewBinder {
        }
        }
    }
    }


    private fun setNoConversationsContent(view: ViewGroup) {
    private fun setNoConversationsContent(view: ViewGroup, onGotItClicked: () -> Unit) {
        // This should never happen.
        // This should never happen.
        if (view.childCount > 1) {
        if (view.childCount > 1) {
            error("view has ${view.childCount} children, it should have maximum 1")
            error("view has ${view.childCount} children, it should have maximum 1")
@@ -140,6 +140,10 @@ object PeopleViewBinder {
            LayoutInflater.from(context)
            LayoutInflater.from(context)
                .inflate(R.layout.people_space_activity_no_conversations, /* root= */ view)
                .inflate(R.layout.people_space_activity_no_conversations, /* root= */ view)


        noConversationsView.findViewById<View>(R.id.got_it_button).setOnClickListener {
            onGotItClicked()
        }

        // The Tile preview has colorBackground as its background. Change it so it's different than
        // The Tile preview has colorBackground as its background. Change it so it's different than
        // the activity's background.
        // the activity's background.
        val item = noConversationsView.findViewById<LinearLayout>(android.R.id.background)
        val item = noConversationsView.findViewById<LinearLayout>(android.R.id.background)
+28 −14
Original line number Original line Diff line number Diff line
@@ -16,8 +16,10 @@


package com.android.systemui.people.ui.viewmodel
package com.android.systemui.people.ui.viewmodel


import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
import android.appwidget.AppWidgetManager.INVALID_APPWIDGET_ID
import android.content.Context
import android.content.Context
import android.content.Intent
import android.util.Log
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider
@@ -32,6 +34,7 @@ import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow


/**
/**
 * Models UI state for the people space, allowing the user to select which conversation should be
 * Models UI state for the people space, allowing the user to select which conversation should be
@@ -49,7 +52,7 @@ class PeopleViewModel(
     * reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
     * reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
     */
     */
    private val _priorityTiles = MutableStateFlow(priorityTiles())
    private val _priorityTiles = MutableStateFlow(priorityTiles())
    val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles
    val priorityTiles: Flow<List<PeopleTileViewModel>> = _priorityTiles.asStateFlow()


    /**
    /**
     * The list of the priority tiles/conversations.
     * The list of the priority tiles/conversations.
@@ -58,15 +61,15 @@ class PeopleViewModel(
     * reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
     * reactive and you have to manually call [onTileRefreshRequested] to refresh the tiles.
     */
     */
    private val _recentTiles = MutableStateFlow(recentTiles())
    private val _recentTiles = MutableStateFlow(recentTiles())
    val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles
    val recentTiles: Flow<List<PeopleTileViewModel>> = _recentTiles.asStateFlow()


    /** The ID of the widget currently being edited/added. */
    /** The ID of the widget currently being edited/added. */
    private val _appWidgetId = MutableStateFlow(INVALID_APPWIDGET_ID)
    private val _appWidgetId = MutableStateFlow(INVALID_APPWIDGET_ID)
    val appWidgetId: StateFlow<Int> = _appWidgetId
    val appWidgetId: StateFlow<Int> = _appWidgetId.asStateFlow()


    /** Whether the user journey is complete. */
    /** The result of this user journey. */
    private val _isFinished = MutableStateFlow(false)
    private val _result = MutableStateFlow<Result?>(null)
    val isFinished: StateFlow<Boolean> = _isFinished
    val result: StateFlow<Result?> = _result.asStateFlow()


    /** Refresh the [priorityTiles] and [recentTiles]. */
    /** Refresh the [priorityTiles] and [recentTiles]. */
    fun onTileRefreshRequested() {
    fun onTileRefreshRequested() {
@@ -79,22 +82,28 @@ class PeopleViewModel(
        _appWidgetId.value = widgetId
        _appWidgetId.value = widgetId
    }
    }


    /** Clear [isFinished], setting it to false. */
    /** Clear [result], setting it to null. */
    fun clearIsFinished() {
    fun clearResult() {
        _isFinished.value = false
        _result.value = null
    }
    }


    /** Called when a tile is clicked. */
    /** Called when a tile is clicked. */
    fun onTileClicked(tile: PeopleTileViewModel) {
    fun onTileClicked(tile: PeopleTileViewModel) {
        val widgetId = _appWidgetId.value
        if (PeopleSpaceUtils.DEBUG) {
        if (PeopleSpaceUtils.DEBUG) {
            Log.d(
            Log.d(
                TAG,
                TAG,
                "Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID: " +
                "Put ${tile.username}'s shortcut ID: ${tile.key.shortcutId} for widget ID $widgetId"
                    _appWidgetId.value
            )
            )
        }
        }
        widgetRepository.setWidgetTile(_appWidgetId.value, tile.key)
        widgetRepository.setWidgetTile(widgetId, tile.key)
        _isFinished.value = true
        _result.value =
            Result.Success(Intent().apply { putExtra(EXTRA_APPWIDGET_ID, appWidgetId.value) })
    }

    /** Called when this user journey is cancelled. */
    fun onUserJourneyCancelled() {
        _result.value = Result.Cancelled
    }
    }


    private fun priorityTiles(): List<PeopleTileViewModel> {
    private fun priorityTiles(): List<PeopleTileViewModel> {
@@ -143,7 +152,12 @@ class PeopleViewModel(
        }
        }
    }
    }


    sealed class Result {
        class Success(val data: Intent) : Result()
        object Cancelled : Result()
    }

    companion object {
    companion object {
        private const val TAG = "PeopleSpaceViewModel"
        private const val TAG = "PeopleViewModel"
    }
    }
}
}