From 6fa0ecb10abff5a947134924201d1a60750e9a5d Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Thu, 1 Sep 2022 17:29:41 -0700 Subject: [PATCH 1/4] add system bars padding modifier --- .../app/omnivore/omnivore/MainActivity.kt | 9 +++++++- .../app/omnivore/omnivore/ui/home/HomeView.kt | 6 +++-- .../app/omnivore/omnivore/ui/root/RootView.kt | 23 +++++++++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt index 274cef68e..07a207e2e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt @@ -5,6 +5,8 @@ import android.view.View import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.ui.Modifier import app.omnivore.omnivore.ui.theme.OmnivoreTheme import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat @@ -24,7 +26,12 @@ class MainActivity : ComponentActivity() { setContent { OmnivoreTheme { - RootView(loginViewModel, homeViewModel) + RootView( + loginViewModel, + homeViewModel, + modifier = Modifier + .systemBarsPadding() + ) } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt index accd3acec..ef7159cf2 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt @@ -25,7 +25,8 @@ import kotlinx.coroutines.flow.distinctUntilChanged @Composable fun HomeView( homeViewModel: HomeViewModel, - navController: NavHostController + navController: NavHostController, + modifier: Modifier ) { Scaffold( topBar = { @@ -41,7 +42,8 @@ fun HomeView( } } ) - } + }, + modifier = modifier ) { paddingValues -> HomeViewContent( homeViewModel, diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt index ac8e5e907..6c8bb7ae0 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt @@ -4,6 +4,7 @@ import SettingsView import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -15,28 +16,42 @@ import app.omnivore.omnivore.ui.home.HomeViewModel import app.omnivore.omnivore.ui.reader.ArticleWebView @Composable -fun RootView(loginViewModel: LoginViewModel, homeViewModel: HomeViewModel) { +fun RootView( + loginViewModel: LoginViewModel, + homeViewModel: HomeViewModel, + modifier: Modifier +) { val hasAuthToken: Boolean by loginViewModel.hasAuthTokenLiveData.observeAsState(false) if (hasAuthToken) { - PrimaryNavigator(loginViewModel = loginViewModel, homeViewModel = homeViewModel) + PrimaryNavigator( + loginViewModel = loginViewModel, + homeViewModel = homeViewModel, + modifier = modifier + ) } else { WelcomeScreen(viewModel = loginViewModel) } } @Composable -fun PrimaryNavigator(loginViewModel: LoginViewModel, homeViewModel: HomeViewModel){ +fun PrimaryNavigator( + loginViewModel: LoginViewModel, + homeViewModel: HomeViewModel, + modifier: Modifier +) { val navController = rememberNavController() NavHost(navController = navController, startDestination = Routes.Home.route) { composable(Routes.Home.route) { HomeView( homeViewModel = homeViewModel, - navController = navController + navController = navController, + modifier = modifier ) } + // TODO: add modifiers composable("WebReader/{slug}") { ArticleWebView( it.arguments?.getString("slug") ?: "", From 687352920cbdfbb90b2abe7da06ca9b026119290 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Thu, 1 Sep 2022 22:42:30 -0700 Subject: [PATCH 2/4] set status and nav bar background to black --- .../app/omnivore/omnivore/MainActivity.kt | 16 +++--- .../omnivore/ui/auth/WelcomeScreen.kt | 1 - .../app/omnivore/omnivore/ui/home/HomeView.kt | 53 +++++++++---------- .../omnivore/ui/reader/WebAppReader.kt | 1 + .../app/omnivore/omnivore/ui/root/RootView.kt | 50 ++++++++++++----- .../omnivore/ui/settings/SettingsContent.kt | 2 +- .../app/omnivore/omnivore/ui/theme/Theme.kt | 2 +- 7 files changed, 75 insertions(+), 50 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt index 07a207e2e..e4bc977bc 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt @@ -5,8 +5,11 @@ import android.view.View import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels -import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import app.omnivore.omnivore.ui.theme.OmnivoreTheme import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat @@ -26,12 +29,13 @@ class MainActivity : ComponentActivity() { setContent { OmnivoreTheme { - RootView( - loginViewModel, - homeViewModel, + Box( modifier = Modifier - .systemBarsPadding() - ) + .fillMaxSize() + .background(color = Color.Black) + ) { + RootView(loginViewModel, homeViewModel) + } } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt index f839361cf..8f9c5fe8a 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt @@ -50,7 +50,6 @@ fun WelcomeScreenContent(viewModel: LoginViewModel) { horizontalAlignment = Alignment.Start, modifier = Modifier .fillMaxSize() - .navigationBarsPadding() .padding(horizontal = 16.dp) .clickable { focusManager.clearFocus() } ) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt index ef7159cf2..849615447 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeView.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import app.omnivore.omnivore.Routes @@ -25,36 +26,34 @@ import kotlinx.coroutines.flow.distinctUntilChanged @Composable fun HomeView( homeViewModel: HomeViewModel, - navController: NavHostController, - modifier: Modifier + navController: NavHostController ) { - Scaffold( - topBar = { - TopAppBar( - title = { Text("Home") }, - backgroundColor = MaterialTheme.colorScheme.surfaceVariant, - actions = { - IconButton(onClick = { navController.navigate(Routes.Settings.route) }) { - Icon( - imageVector = Icons.Default.Menu, - contentDescription = null - ) + Scaffold( + topBar = { + TopAppBar( + title = { Text("Home") }, + backgroundColor = MaterialTheme.colorScheme.surfaceVariant, + actions = { + IconButton(onClick = { navController.navigate(Routes.Settings.route) }) { + Icon( + imageVector = Icons.Default.Menu, + contentDescription = null + ) + } } - } - ) - }, - modifier = modifier - ) { paddingValues -> - HomeViewContent( - homeViewModel, - navController, - modifier = Modifier - .padding( - top = paddingValues.calculateTopPadding(), - bottom = paddingValues.calculateBottomPadding() ) - ) - } + } + ) { paddingValues -> + HomeViewContent( + homeViewModel, + navController, + modifier = Modifier + .padding( + top = paddingValues.calculateTopPadding(), + bottom = paddingValues.calculateBottomPadding() + ) + ) + } } @Composable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebAppReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebAppReader.kt index 1b1091bbe..b09157fd0 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebAppReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebAppReader.kt @@ -6,6 +6,7 @@ import android.webkit.CookieManager import android.webkit.WebView import android.webkit.WebViewClient import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView @SuppressLint("SetJavaScriptEnabled") diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt index 6c8bb7ae0..6f3c8e376 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt @@ -1,10 +1,15 @@ package app.omnivore.omnivore.ui.root import SettingsView +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -14,31 +19,50 @@ import app.omnivore.omnivore.ui.auth.WelcomeScreen import app.omnivore.omnivore.ui.home.HomeView import app.omnivore.omnivore.ui.home.HomeViewModel import app.omnivore.omnivore.ui.reader.ArticleWebView +import com.google.accompanist.systemuicontroller.rememberSystemUiController @Composable fun RootView( loginViewModel: LoginViewModel, - homeViewModel: HomeViewModel, - modifier: Modifier + homeViewModel: HomeViewModel ) { val hasAuthToken: Boolean by loginViewModel.hasAuthTokenLiveData.observeAsState(false) + // Remember a SystemUiController + val systemUiController = rememberSystemUiController() + val useDarkIcons = !isSystemInDarkTheme() - if (hasAuthToken) { - PrimaryNavigator( - loginViewModel = loginViewModel, - homeViewModel = homeViewModel, - modifier = modifier + DisposableEffect(systemUiController, useDarkIcons) { + // Update all of the system bar colors to be transparent, and use + // dark icons if we're in light theme + systemUiController.setSystemBarsColor( + color = Color.Black, + darkIcons = false ) - } else { - WelcomeScreen(viewModel = loginViewModel) + + // setStatusBarColor() and setNavigationBarColor() also exist + + onDispose {} + } + + Box( + modifier = Modifier + .systemBarsPadding() + ) { + if (hasAuthToken) { + PrimaryNavigator( + loginViewModel = loginViewModel, + homeViewModel = homeViewModel + ) + } else { + WelcomeScreen(viewModel = loginViewModel) + } } } @Composable fun PrimaryNavigator( loginViewModel: LoginViewModel, - homeViewModel: HomeViewModel, - modifier: Modifier + homeViewModel: HomeViewModel ) { val navController = rememberNavController() @@ -46,12 +70,10 @@ fun PrimaryNavigator( composable(Routes.Home.route) { HomeView( homeViewModel = homeViewModel, - navController = navController, - modifier = modifier + navController = navController ) } - // TODO: add modifiers composable("WebReader/{slug}") { ArticleWebView( it.arguments?.getString("slug") ?: "", diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt index 64d0b4bf8..6cd329ed5 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt @@ -23,7 +23,7 @@ import com.google.android.gms.auth.api.signin.GoogleSignInOptions @Composable fun SettingsView( loginViewModel: LoginViewModel, - navController: NavHostController + navController: NavHostController, ) { Scaffold( topBar = { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt index 38c6bc295..dd10f6c73 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt @@ -77,7 +77,7 @@ fun OmnivoreTheme( val context = LocalContext.current if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) } else { - if (darkTheme) DarkColors else LightColors + if (darkTheme) darkColorScheme() else lightColorScheme() } MaterialTheme( From a0b56f43a10b390544342b4fe25d48d788183f46 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Fri, 2 Sep 2022 10:26:12 -0700 Subject: [PATCH 3/4] update android feed card layout --- .../omnivore/ui/home/HomeViewModel.kt | 13 ++- .../omnivore/ui/home/LinkedItemCard.kt | 83 ++++++++++++------- .../app/omnivore/omnivore/ui/root/RootView.kt | 5 -- 3 files changed, 63 insertions(+), 38 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeViewModel.kt index be3f1227a..49c91433e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/HomeViewModel.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.window.Dialog +import androidx.core.net.toUri import androidx.lifecycle.* import app.omnivore.omnivore.AppleConstants import app.omnivore.omnivore.Constants @@ -67,6 +68,8 @@ class HomeViewModel @Inject constructor( readingProgressAnchor = it.node.readingProgressAnchorIndex, imageURLString = it.node.image, descriptionText = it.node.description, + publisherURLString = it.node.originalArticleUrl, + author = it.node.author, slug = it.node.slug ) } @@ -90,12 +93,16 @@ public data class LinkedItem( // public val documentDirectoryPath: String?, // public val pageURLString: String, public val descriptionText: String?, -// public val publisherURLString: String?, + public val publisherURLString: String?, // public val siteName: String?, -// public val author: String?, + public val author: String?, // public val publishDate: Any?, public val slug: String, // public val isArchived: Boolean, // public val contentReader: String?, // public val originalHtml: String?, -) +) { + fun publisherDisplayName(): String? { + return publisherURLString?.toUri()?.host + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt index c4ab6d4ed..1d901cd95 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt @@ -2,52 +2,75 @@ package app.omnivore.omnivore.ui.home import androidx.compose.foundation.layout.* import androidx.compose.foundation.Image -import androidx.compose.material3.Card -import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.foundation.clickable +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Divider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import coil.compose.rememberAsyncImagePainter -@OptIn(ExperimentalMaterial3Api::class) @Composable -fun LinkedItemCard( - item: LinkedItem, - onClickHandler: () -> Unit, - modifier: Modifier = Modifier -) { - Card( - onClick = { onClickHandler() }, - shape = MaterialTheme.shapes.medium, - modifier = modifier - .fillMaxWidth() - .padding(15.dp) - ) { - Row { - Image( - painter = rememberAsyncImagePainter(item.imageURLString), - contentDescription = "Image associated with linked item", - modifier = Modifier.size(100.dp) - ) +fun LinkedItemCard(item: LinkedItem, onClickHandler: () -> Unit) { + val publisherDisplayName = item.publisherDisplayName() - Column(modifier = Modifier.padding(8.dp)) { + Column { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.Top, + modifier = Modifier + .fillMaxWidth() + .padding(12.dp) + .clickable(onClick = onClickHandler) + ) { + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier + .weight(1f, fill = false) + .padding(end = 8.dp) + ) { Text( text = item.title, style = MaterialTheme.typography.titleMedium, - maxLines = 2, - overflow = TextOverflow.Ellipsis + lineHeight = 20.sp ) - Text( - text = item.descriptionText ?: "", - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = MaterialTheme.typography.bodyMedium - ) + if (item.author != null) { + Text( + text = "By ${item.author}", + style = MaterialTheme.typography.bodyMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + + if (publisherDisplayName != null) { + Text( + text = publisherDisplayName, + style = MaterialTheme.typography.bodyMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } } + + Image( + painter = rememberAsyncImagePainter(item.imageURLString), + contentDescription = "Image associated with linked item", + modifier = Modifier + .padding(top = 6.dp) + .clip(RoundedCornerShape(6.dp)) + .size(80.dp) + ) } + + Divider(color = MaterialTheme.colorScheme.outlineVariant, thickness = 1.dp) } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt index 6f3c8e376..6eb12ee04 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt @@ -27,20 +27,15 @@ fun RootView( homeViewModel: HomeViewModel ) { val hasAuthToken: Boolean by loginViewModel.hasAuthTokenLiveData.observeAsState(false) - // Remember a SystemUiController val systemUiController = rememberSystemUiController() val useDarkIcons = !isSystemInDarkTheme() DisposableEffect(systemUiController, useDarkIcons) { - // Update all of the system bar colors to be transparent, and use - // dark icons if we're in light theme systemUiController.setSystemBarsColor( color = Color.Black, darkIcons = false ) - // setStatusBarColor() and setNavigationBarColor() also exist - onDispose {} } From f1eedbf03d7fa36f8ff7edba8a816cc7c402b9cb Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Fri, 2 Sep 2022 14:01:58 -0700 Subject: [PATCH 4/4] check if image url is null --- .../omnivore/ui/home/LinkedItemCard.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt index 1d901cd95..71e4d41e4 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/home/LinkedItemCard.kt @@ -61,14 +61,16 @@ fun LinkedItemCard(item: LinkedItem, onClickHandler: () -> Unit) { } } - Image( - painter = rememberAsyncImagePainter(item.imageURLString), - contentDescription = "Image associated with linked item", - modifier = Modifier - .padding(top = 6.dp) - .clip(RoundedCornerShape(6.dp)) - .size(80.dp) - ) + if (item.imageURLString != null) { + Image( + painter = rememberAsyncImagePainter(item.imageURLString), + contentDescription = "Image associated with linked item", + modifier = Modifier + .padding(top = 6.dp) + .clip(RoundedCornerShape(6.dp)) + .size(80.dp) + ) + } } Divider(color = MaterialTheme.colorScheme.outlineVariant, thickness = 1.dp)