manage_feeds: convert SubscribeToFeedActivity to compose
authorDa Risk <da_risk@geekorum.com>
Mon, 19 Jun 2023 14:15:06 -0400
changeset 1068 554913a8da67
parent 1067 1b161ddfa3ac
child 1069 90363a8aba06
manage_feeds: convert SubscribeToFeedActivity to compose
app/src/main/res/values/dimens.xml
manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/DisplayErrorFragment.kt
manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/EnterFeedUrlFragment.kt
manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/Navigation.kt
manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/SubscribeToFeedActivity.kt
manage_feeds/src/main/res/layout/activity_subscribe_to_feed.xml
--- a/app/src/main/res/values/dimens.xml	Mon Jun 19 01:22:16 2023 -0400
+++ b/app/src/main/res/values/dimens.xml	Mon Jun 19 14:15:06 2023 -0400
@@ -24,7 +24,7 @@
 <resources>
     <dimen name="minimumTouchSize" >48dp</dimen>
     <dimen name="article_list_spacing">16dp</dimen>
-    <dimen name="app_bar_height">192dp</dimen>
+    <dimen name="app_bar_height">128dp</dimen>
     <dimen name="fab_margin">16dp</dimen>
     <dimen name="activity_horizontal_margin">16dp</dimen>
     <dimen name="activity_vertical_margin">16dp</dimen>
--- a/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/DisplayErrorFragment.kt	Mon Jun 19 01:22:16 2023 -0400
+++ b/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/DisplayErrorFragment.kt	Mon Jun 19 14:15:06 2023 -0400
@@ -20,10 +20,6 @@
  */
 package com.geekorum.ttrss.manage_feeds.add_feed
 
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
 import androidx.annotation.StringRes
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
@@ -32,32 +28,13 @@
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.ComposeView
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import androidx.fragment.app.Fragment
-import androidx.navigation.fragment.navArgs
 import com.geekorum.ttrss.manage_feeds.R
 import com.geekorum.ttrss.ui.AppTheme
 
 
-class DisplayErrorFragment : Fragment() {
-
-    val args: DisplayErrorFragmentArgs by navArgs()
-
-    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
-        return ComposeView(requireContext()).apply {
-            setContent {
-                AppTheme {
-                    DisplayErrorScreen(errorMsgId = args.errorMsgId)
-                }
-            }
-        }
-    }
-}
-
-
 @Composable
 fun DisplayErrorScreen(@StringRes errorMsgId: Int) {
     Box(Modifier.padding(16.dp).fillMaxSize()) {
--- a/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/EnterFeedUrlFragment.kt	Mon Jun 19 01:22:16 2023 -0400
+++ b/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/EnterFeedUrlFragment.kt	Mon Jun 19 14:15:06 2023 -0400
@@ -20,10 +20,6 @@
  */
 package com.geekorum.ttrss.manage_feeds.add_feed
 
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -34,54 +30,18 @@
 import androidx.compose.runtime.*
 import androidx.compose.runtime.livedata.observeAsState
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.ComposeView
 import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.viewmodel.compose.viewModel
-import androidx.navigation.fragment.findNavController
 import com.geekorum.geekdroid.app.lifecycle.Event
 import com.geekorum.geekdroid.app.lifecycle.EventObserver
 import com.geekorum.ttrss.manage_feeds.R
 import com.geekorum.ttrss.ui.AppTheme
 import com.geekorum.ttrss.R as appR
 
-class EnterFeedUrlFragment : Fragment() {
-
-    private val viewModel: SubscribeToFeedViewModel by activityViewModels()
-    private val navController by lazy { findNavController() }
-
-
-    override fun onCreateView(
-        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
-    ): View {
-        return ComposeView(requireContext()).apply {
-            setContent {
-                AppTheme {
-                    EnterFeedUrlScreen(
-                        viewModel,
-                        navigateToDisplayError = {
-                            val action = EnterFeedUrlFragmentDirections.actionDisplayError(
-                                R.string.fragment_display_error_no_feeds_found
-                            )
-                            navController.navigate(action)
-                        },
-                        navigateToShowAvailableFeeds = {
-                            navController.navigate(EnterFeedUrlFragmentDirections.actionShowAvailableFeeds())
-                        },
-                        finishActivity = {
-                            requireActivity().finish()
-                        }
-                    )
-                }
-            }
-        }
-    }
-}
 
 @Composable
 fun EnterFeedUrlScreen(
--- a/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/Navigation.kt	Mon Jun 19 01:22:16 2023 -0400
+++ b/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/Navigation.kt	Mon Jun 19 14:15:06 2023 -0400
@@ -21,6 +21,7 @@
 package com.geekorum.ttrss.manage_feeds.add_feed
 
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
 import androidx.lifecycle.viewmodel.compose.viewModel
 import androidx.navigation.NavController
 import androidx.navigation.NavHostController
@@ -37,11 +38,12 @@
 
 @Composable
 fun SubscribeToFeedNavHost(
+    modifier: Modifier = Modifier,
     viewModel: SubscribeToFeedViewModel = viewModel(),
     navController: NavHostController = rememberNavController(),
     finishActivity: () -> Unit,
 ) {
-    NavHost(navController = navController, startDestination = ROUTE_ENTER_FEED_URL) {
+    NavHost(modifier = modifier, navController = navController, startDestination = ROUTE_ENTER_FEED_URL) {
         composable(ROUTE_ENTER_FEED_URL) {
             // TODO animation with navigation 1.7.x
             EnterFeedUrlScreen(viewModel,
--- a/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/SubscribeToFeedActivity.kt	Mon Jun 19 01:22:16 2023 -0400
+++ b/manage_feeds/src/main/java/com/geekorum/ttrss/manage_feeds/add_feed/SubscribeToFeedActivity.kt	Mon Jun 19 14:15:06 2023 -0400
@@ -21,78 +21,85 @@
 package com.geekorum.ttrss.manage_feeds.add_feed
 
 import android.os.Bundle
+import androidx.activity.compose.setContent
 import androidx.activity.viewModels
-import androidx.compose.runtime.LaunchedEffect
+import androidx.annotation.StringRes
+import androidx.compose.foundation.layout.*
+import androidx.compose.material.*
+import androidx.compose.runtime.Composable
 import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.getValue
-import androidx.databinding.DataBindingUtil
-import androidx.navigation.NavController
-import androidx.navigation.NavHostController
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.core.view.WindowCompat
 import androidx.navigation.compose.currentBackStackEntryAsState
 import androidx.navigation.compose.rememberNavController
-import androidx.navigation.findNavController
 import com.geekorum.ttrss.manage_feeds.BaseSessionActivity
 import com.geekorum.ttrss.manage_feeds.R
-import com.geekorum.ttrss.manage_feeds.databinding.ActivitySubscribeToFeedBinding
 import com.geekorum.ttrss.ui.AppTheme
 
 
 class SubscribeToFeedActivity : BaseSessionActivity() {
 
-    private lateinit var binding: ActivitySubscribeToFeedBinding
     private val viewModel: SubscribeToFeedViewModel by viewModels()
-    private lateinit var navController: NavHostController
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        binding = DataBindingUtil.setContentView(this, R.layout.activity_subscribe_to_feed)
-
-        binding.cancel.setOnClickListener {
-            if (!navController.popBackStack())
-                finish()
-        }
-
-        binding.composeNavHost.setContent {
+        WindowCompat.setDecorFitsSystemWindows(window, false)
+        setContent {
             AppTheme {
-                navController = rememberNavController()
-                SubscribeToFeedNavHost(
-                    viewModel = viewModel,
-                    navController = navController,
-                    finishActivity = {
-                        finish()
-                    }
-                )
-
+                val navController = rememberNavController()
                 val currentBackStackEntry by navController.currentBackStackEntryAsState()
-                    val destination = currentBackStackEntry?.destination
-                SideEffect {
-                    when (destination?.route) {
-                        ROUTE_ENTER_FEED_URL -> {
-                            binding.cancel.setText(R.string.activity_subscribe_feed_btn_cancel)
-                            binding.next.setText(R.string.activity_subscribe_feed_btn_subscribe)
-                            binding.next.setOnClickListener {
-                                viewModel.submitUrl(viewModel.urlTyped)
-                            }
-                            viewModel.resetAvailableFeeds()
+                val destination = currentBackStackEntry?.destination
+
+                SubscribeToFeedScaffold(
+                    bottomBar = {
+                        val cancelTxtId = when (destination?.route) {
+                            ROUTE_ENTER_FEED_URL -> R.string.activity_subscribe_feed_btn_cancel
+                            else -> R.string.activity_subscribe_feed_btn_back
                         }
-
-                        ROUTE_SELECT_FEED -> {
-                            binding.cancel.setText(R.string.activity_subscribe_feed_btn_back)
-                            binding.next.setText(R.string.activity_subscribe_feed_btn_subscribe)
-                            binding.next.setOnClickListener {
-                                if (viewModel.selectedFeed != null) {
-                                    viewModel.subscribeToFeed(viewModel.selectedFeed!!.toFeedInformation())
+                        val nextTxtId = when (destination?.route) {
+                            ROUTE_DISPLAY_ERROR -> R.string.activity_subscribe_feed_btn_close
+                            else -> R.string.activity_subscribe_feed_btn_subscribe
+                        }
+                        BottomButtonBar(
+                            nextTxtId = nextTxtId,
+                            cancelTxtId = cancelTxtId, onCancelClick = {
+                                if (!navController.popBackStack()) {
                                     finish()
                                 }
-                            }
+                            },
+                            onNextClick = {
+                                when (destination?.route) {
+                                    ROUTE_ENTER_FEED_URL -> {
+                                        viewModel.submitUrl(viewModel.urlTyped)
+                                    }
+                                    ROUTE_SELECT_FEED -> {
+                                        if (viewModel.selectedFeed != null) {
+                                            viewModel.subscribeToFeed(viewModel.selectedFeed!!.toFeedInformation())
+                                            finish()
+                                        }
+                                    }
+                                    ROUTE_DISPLAY_ERROR -> finish()
+                                    else -> Unit
+                                }
+                            })
+                    }) {
+                    SubscribeToFeedNavHost(
+                        modifier = Modifier.padding(it),
+                        viewModel = viewModel,
+                        navController = navController,
+                        finishActivity = {
+                            finish()
                         }
-
-                        ROUTE_DISPLAY_ERROR -> {
-                            binding.cancel.setText(R.string.activity_subscribe_feed_btn_back)
-                            binding.next.setText(R.string.activity_subscribe_feed_btn_close)
-                            binding.next.setOnClickListener {
-                                finish()
-                            }
+                    )
+                    SideEffect {
+                        if (destination?.route == ROUTE_ENTER_FEED_URL) {
+                            viewModel.resetAvailableFeeds()
                         }
                     }
                 }
@@ -100,3 +107,70 @@
         }
     }
 }
+
+
+@Composable
+private fun BottomButtonBar(
+    @StringRes cancelTxtId: Int,
+    @StringRes nextTxtId: Int,
+    onCancelClick: () -> Unit, onNextClick: () -> Unit) {
+    Row(Modifier.padding(8.dp)) {
+        TextButton(onClick = onCancelClick) {
+            Text(stringResource(cancelTxtId))
+        }
+        Spacer(Modifier.weight(1f))
+        Button(onClick = onNextClick) {
+            Text(stringResource(nextTxtId))
+        }
+    }
+}
+
+
+
+@Composable
+private fun SubscribeToFeedScaffold(
+    bottomBar: @Composable () -> Unit,
+    content: @Composable (PaddingValues) -> Unit
+) {
+    Scaffold(
+        topBar = {
+            LargeTitleBar()
+        },
+        bottomBar = {
+            Box(Modifier.navigationBarsPadding()) {
+                bottomBar()
+            }
+        },
+        content = content
+    )
+}
+
+@Composable
+private fun LargeTitleBar() {
+    Surface(color = MaterialTheme.colors.primarySurface) {
+        Box(modifier = Modifier
+            .height(128.dp)
+            .fillMaxWidth(), contentAlignment = Alignment.BottomStart) {
+            Text(stringResource(R.string.activity_add_feed_title),
+                style = MaterialTheme.typography.h6.copy(fontSize = 30.sp),
+                modifier = Modifier
+                    .padding(start = 32.dp)
+                    .paddingFromBaseline(bottom = 28.dp),
+                )
+        }
+    }
+}
+
+@Preview
+@Composable
+private fun PreviewSubscribeToFeedScaffold() {
+    AppTheme {
+        SubscribeToFeedScaffold(bottomBar = {
+            BottomButtonBar(
+                cancelTxtId = R.string.activity_subscribe_feed_btn_cancel,
+                nextTxtId = R.string.activity_subscribe_feed_btn_subscribe,
+                onCancelClick = {}, onNextClick = {}
+            )
+        }) {}
+    }
+}
\ No newline at end of file
--- a/manage_feeds/src/main/res/layout/activity_subscribe_to_feed.xml	Mon Jun 19 01:22:16 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
-    Geekttrss is a RSS feed reader application on the Android Platform.
-
-    Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
-
-    This file is part of Geekttrss.
-
-    Geekttrss is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Geekttrss is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
-
--->
-<layout xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <data>
-
-    </data>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-
-        <com.google.android.material.appbar.AppBarLayout
-                android:id="@+id/app_bar"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/app_bar_height"
-                app:layout_constraintTop_toTopOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:liftOnScroll="true">
-
-            <com.google.android.material.appbar.CollapsingToolbarLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
-                    app:title="Add Feed"
-                    style="?appBarCollapsingToolbarStyle">
-
-                <com.google.android.material.appbar.MaterialToolbar
-                        android:layout_width="match_parent"
-                        android:layout_height="84dp"
-                        app:layout_collapseMode="pin"
-                        />
-
-            </com.google.android.material.appbar.CollapsingToolbarLayout>
-
-        </com.google.android.material.appbar.AppBarLayout>
-
-
-        <androidx.compose.ui.platform.ComposeView
-            android:id="@+id/compose_nav_host"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/app_bar"
-            app:layout_constraintBottom_toTopOf="@id/next"
-            />
-
-
-        <Button android:id="@+id/next"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                android:layout_marginEnd="8dp"
-                android:layout_marginTop="8dp"
-                android:layout_marginBottom="8dp"
-                android:text="@string/activity_subscribe_feed_btn_subscribe" />
-
-
-        <Button android:id="@+id/cancel"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                android:layout_marginStart="8dp"
-                android:layout_marginBottom="8dp"
-                android:text="@string/activity_subscribe_feed_btn_cancel"
-                style="@style/Widget.MaterialComponents.Button.TextButton" />
-
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-</layout>