Skip to content

Commit

Permalink
Another big pass at About header and other unrelated things (#876)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZacSweers authored Aug 11, 2023
1 parent 15f9347 commit 1d2e8eb
Show file tree
Hide file tree
Showing 16 changed files with 309 additions and 270 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ plugins {
alias(libs.plugins.bugsnag)
alias(libs.plugins.sqldelight)
alias(libs.plugins.baselineprofile)
alias(libs.plugins.moshix)
// alias(libs.plugins.playPublisher)
}

Expand Down
17 changes: 9 additions & 8 deletions app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
~ limitations under the License.
-->

<manifest
xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<!-- For Flipper -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

</manifest>
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@
android:name=".ui.activity.MainActivity"
android:launchMode="singleTask"
android:configChanges="colorMode|density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode"
android:exported="true"
>

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="catchup" />
</intent-filter>
</activity>

<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class ClickableItemState {
val interactionSource = MutableInteractionSource()
var enabled by mutableStateOf(true)
var contentColor by mutableStateOf(Color.Unspecified)
var focused by mutableStateOf(true)
var focused by mutableStateOf(false)
}

@OptIn(ExperimentalFoundationApi::class)
Expand Down
27 changes: 16 additions & 11 deletions app/src/main/kotlin/dev/zacsweers/catchup/service/TextServiceUi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
Expand Down Expand Up @@ -80,7 +81,7 @@ fun TextServiceUi(

// Only animate items in on first load
var animatePlacement by remember { mutableStateOf(true) }
var expandedItemIndex by remember { mutableStateOf(-1) }
var expandedItemIndex by remember { mutableIntStateOf(-1) }
LazyColumn(
modifier = modifier,
state = state,
Expand Down Expand Up @@ -181,13 +182,14 @@ fun TextItem(
item: CatchUpItem,
themeColor: Color,
modifier: Modifier = Modifier,
showDescription: Boolean = true,
onMarkClick: () -> Unit = {}
) {
Row(
modifier = modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
DetailColumn(item, themeColor)
DetailColumn(item, themeColor, showDescription = showDescription)
item.mark?.let { mark ->
Column(
modifier =
Expand Down Expand Up @@ -232,6 +234,7 @@ fun RowScope.DetailColumn(
item: CatchUpItem,
themeColor: Color,
modifier: Modifier = Modifier,
showDescription: Boolean = true,
) {
Column(modifier = modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(4.dp)) {
// Score, tag, timestamp
Expand All @@ -244,15 +247,17 @@ fun RowScope.DetailColumn(
color = MaterialTheme.colorScheme.onSurface
)
// Description
item.description?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
overflow = TextOverflow.Ellipsis,
maxLines = 5,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = ContentAlphas.Medium)
)
}
item.description
?.takeIf { showDescription }
?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
overflow = TextOverflow.Ellipsis,
maxLines = 5,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = ContentAlphas.Medium)
)
}
// Author, source
ItemFooter(item)
}
Expand Down
69 changes: 54 additions & 15 deletions app/src/main/kotlin/io/sweers/catchup/ui/about/AboutScreen.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.sweers.catchup.ui.about

import androidx.annotation.StringRes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
Expand All @@ -13,7 +13,7 @@ import androidx.compose.material3.TabRow
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -25,47 +25,86 @@ import com.slack.circuit.foundation.CircuitContent
import com.slack.circuit.runtime.CircuitUiState
import com.slack.circuit.runtime.Screen
import com.slack.circuit.runtime.presenter.Presenter
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dev.zacsweers.catchup.appconfig.AppConfig
import dev.zacsweers.catchup.di.AppScope
import io.sweers.catchup.R
import javax.inject.Inject
import java.util.Locale
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import timber.log.Timber

@Parcelize
object AboutScreen : Screen {
data class State(val version: String) : CircuitUiState
data class AboutScreen(val selectedTab: AboutScreenComponent = AboutScreenComponent.DEFAULT) :
Screen {
data class State(
val initialPage: Int,
val version: String,
) : CircuitUiState

enum class AboutScreenComponent(
val screen: Screen,
@StringRes val titleRes: Int,
) {
Licenses(LicensesScreen, R.string.licenses),
Changelog(ChangelogScreen, R.string.changelog);

companion object {
internal val DEFAULT = Licenses

fun componentFor(path: String?): AboutScreenComponent {
return when (path?.lowercase(Locale.US)) {
"licenses" -> Licenses
"changelog" -> Changelog
else -> {
Timber.d("Unknown path $path, defaulting to $DEFAULT")
DEFAULT
}
}
}
}
}
}

@CircuitInject(AboutScreen::class, AppScope::class)
class AboutPresenter @Inject constructor(private val appConfig: AppConfig) :
class AboutPresenter
@AssistedInject
constructor(@Assisted val screen: AboutScreen, private val appConfig: AppConfig) :
Presenter<AboutScreen.State> {
@Composable override fun present() = AboutScreen.State(appConfig.versionName)
}
@Composable
override fun present() = AboutScreen.State(screen.selectedTab.ordinal, appConfig.versionName)

private val SCREENS = listOf(LicensesScreen, ChangelogScreen)
private val SCREEN_TITLES = intArrayOf(R.string.licenses, R.string.changelog)
@CircuitInject(AboutScreen::class, AppScope::class)
@AssistedFactory
interface Factory {
fun create(screen: AboutScreen): AboutPresenter
}
}

@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@CircuitInject(AboutScreen::class, AppScope::class)
@Composable
fun About(state: AboutScreen.State, modifier: Modifier = Modifier) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
contentWindowInsets = WindowInsets(0, 0, 0, 0),
containerColor = Color.Transparent,
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = { CollapsingAboutHeader(state.version, scrollBehavior = scrollBehavior) }
) { paddingValues ->
Column(Modifier.padding(paddingValues)) {
val pagerState = rememberPagerState { 2 }
val components = remember { AboutScreen.AboutScreenComponent.entries.toImmutableList() }
val pagerState = rememberPagerState(initialPage = state.initialPage) { 2 }
TabRow(
// Our selected tab is our current page
selectedTabIndex = pagerState.currentPage,
) {
// Add tabs for all of our pages
val coroutinesScope = rememberCoroutineScope()
SCREEN_TITLES.forEachIndexed { index, titleRes ->
components.forEach { component ->
val index = component.ordinal
val titleRes = component.titleRes
Tab(
text = { Text(stringResource(titleRes)) },
selected = pagerState.currentPage == index,
Expand All @@ -84,7 +123,7 @@ fun About(state: AboutScreen.State, modifier: Modifier = Modifier) {
state = pagerState,
verticalAlignment = Alignment.Top,
) { page ->
CircuitContent(SCREENS[page])
CircuitContent(components[page].screen)
}
}
}
Expand Down
27 changes: 24 additions & 3 deletions app/src/main/kotlin/io/sweers/catchup/ui/about/ChangelogScreen.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package io.sweers.catchup.ui.about

import android.graphics.Color
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand All @@ -22,10 +28,12 @@ import com.slack.circuit.runtime.CircuitUiState
import com.slack.circuit.runtime.Screen
import com.slack.circuit.runtime.presenter.Presenter
import com.squareup.anvil.annotations.ContributesBinding
import dev.zacsweers.catchup.compose.LocalDynamicTheme
import dev.zacsweers.catchup.di.AppScope
import dev.zacsweers.catchup.service.ClickableItem
import dev.zacsweers.catchup.service.ErrorItem
import dev.zacsweers.catchup.service.TextItem
import dev.zacsweers.catchup.service.rememberClickableItemState
import io.sweers.catchup.R
import io.sweers.catchup.data.LinkManager
import io.sweers.catchup.data.github.RepoReleasesQuery
Expand Down Expand Up @@ -80,6 +88,13 @@ constructor(
@CircuitInject(ChangelogScreen::class, AppScope::class)
@Composable
fun Changelog(state: ChangelogScreen.State, modifier: Modifier = Modifier) {
var expandedItemIndex by remember { mutableIntStateOf(-1) }
val themeColor =
if (LocalDynamicTheme.current) {
MaterialTheme.colorScheme.primary
} else {
colorResource(R.color.colorAccent)
}
LazyColumn(modifier = modifier) {
val items = state.items
if (items == null) {
Expand All @@ -104,11 +119,17 @@ fun Changelog(state: ChangelogScreen.State, modifier: Modifier = Modifier) {
key = { items[it].id },
) { index ->
val item = items[index]
val clickableItemState = rememberClickableItemState()
clickableItemState.focused = expandedItemIndex == index
ClickableItem(
modifier = Modifier.animateItemPlacement(),
state = clickableItemState,
onClick = { state.eventSink(ChangelogScreen.Event.Click(item.clickUrl!!)) },
onLongClick = { expandedItemIndex = if (expandedItemIndex == index) -1 else index }
) {
TextItem(item, colorResource(R.color.colorAccent))
Column(Modifier.animateContentSize()) {
TextItem(item, themeColor, showDescription = expandedItemIndex == index)
}
}
}
}
Expand Down Expand Up @@ -152,8 +173,8 @@ constructor(
tag = tag.name,
source = tag.target.abbreviatedOid, // sha
itemClickUrl = url.toString(),
// TODO revisit when we have expandable items and markdown support
// description = markdownConverter.replaceMarkdownEmojisIn(description!!),
// TODO render markdown at some point?
description = markdownConverter.replaceMarkdownEmojisIn(description!!),
serviceId = "changelog",
indexInResponse = index,
// Not summarizable
Expand Down
Loading

0 comments on commit 1d2e8eb

Please sign in to comment.