Add DisplayText and FeedBackIconButton
This commit is contained in:
parent
5f11616c6a
commit
43bbb87280
51
app/src/main/java/me/ash/reader/ui/component/DisplayText.kt
Normal file
51
app/src/main/java/me/ash/reader/ui/component/DisplayText.kt
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package me.ash.reader.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.animation.*
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DisplayText(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
text: String,
|
||||||
|
desc: String,
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(
|
||||||
|
start = 24.dp,
|
||||||
|
top = 48.dp,
|
||||||
|
end = 24.dp,
|
||||||
|
bottom = 24.dp,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
style = MaterialTheme.typography.displaySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = desc.isNotEmpty(),
|
||||||
|
enter = fadeIn() + expandVertically(),
|
||||||
|
exit = fadeOut() + shrinkVertically(),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = desc,
|
||||||
|
style = MaterialTheme.typography.labelMedium,
|
||||||
|
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package me.ash.reader.ui.component
|
||||||
|
|
||||||
|
import android.view.HapticFeedbackConstants
|
||||||
|
import android.view.SoundEffectConstants
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FeedbackIconButton(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
imageVector: ImageVector,
|
||||||
|
contentDescription: String?,
|
||||||
|
tint: Color = LocalContentColor.current,
|
||||||
|
isHaptic: Boolean? = true,
|
||||||
|
isSound: Boolean? = true,
|
||||||
|
onClick: () -> Unit = {},
|
||||||
|
) {
|
||||||
|
val view = LocalView.current
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
if (isHaptic == true) view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
if (isSound == true) view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
modifier = modifier,
|
||||||
|
imageVector = imageVector,
|
||||||
|
contentDescription = contentDescription,
|
||||||
|
tint = tint,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,21 @@
|
||||||
package me.ash.reader.ui.ext
|
package me.ash.reader.ui.ext
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.HapticFeedbackConstants
|
||||||
|
import android.view.SoundEffectConstants
|
||||||
|
import androidx.compose.foundation.*
|
||||||
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.interaction.PressInteraction
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.lerp
|
import androidx.compose.ui.unit.lerp
|
||||||
|
@ -48,3 +58,70 @@ fun Modifier.roundClick(onClick: () -> Unit = {}) = this
|
||||||
fun Modifier.paddingFixedHorizontal(top: Dp = 0.dp, bottom: Dp = 0.dp) = this
|
fun Modifier.paddingFixedHorizontal(top: Dp = 0.dp, bottom: Dp = 0.dp) = this
|
||||||
.padding(horizontal = 10.dp)
|
.padding(horizontal = 10.dp)
|
||||||
.padding(top = top, bottom = bottom)
|
.padding(top = top, bottom = bottom)
|
||||||
|
|
||||||
|
@OptIn(
|
||||||
|
ExperimentalFoundationApi::class,
|
||||||
|
androidx.compose.ui.ExperimentalComposeUiApi::class
|
||||||
|
)
|
||||||
|
@Composable
|
||||||
|
@SuppressLint("ComposableModifierFactory")
|
||||||
|
fun Modifier.combinedFeedbackClickable(
|
||||||
|
isHaptic: Boolean? = false,
|
||||||
|
isSound: Boolean? = false,
|
||||||
|
onPressDown: (() -> Unit)? = null,
|
||||||
|
onPressUp: (() -> Unit)? = null,
|
||||||
|
onLongClick: (() -> Unit)? = null,
|
||||||
|
onDoubleClick: (() -> Unit)? = null,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
): Modifier {
|
||||||
|
val view = LocalView.current
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
return if (onPressDown != null || onPressUp != null) {
|
||||||
|
indication(interactionSource, LocalIndication.current)
|
||||||
|
.pointerInput(Unit) {
|
||||||
|
detectTapGestures(
|
||||||
|
onPress = { offset ->
|
||||||
|
onPressDown?.let {
|
||||||
|
if (isHaptic == true) view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
val press = PressInteraction.Press(offset)
|
||||||
|
interactionSource.emit(press)
|
||||||
|
tryAwaitRelease()
|
||||||
|
interactionSource.emit(PressInteraction.Release(press))
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTap = {
|
||||||
|
onPressUp?.let {
|
||||||
|
if (isHaptic == true) view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
if (isSound == true) view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
combinedClickable(
|
||||||
|
onClick = {
|
||||||
|
onClick?.let {
|
||||||
|
if (isHaptic == true) view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
if (isSound == true) view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongClick = {
|
||||||
|
onLongClick?.let {
|
||||||
|
if (isHaptic == true) view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
if (isSound == true) view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDoubleClick = {
|
||||||
|
onDoubleClick?.let {
|
||||||
|
if (isHaptic == true) view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
if (isSound == true) view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
package me.ash.reader.ui.page.home
|
package me.ash.reader.ui.page.home
|
||||||
|
|
||||||
|
import android.view.SoundEffectConstants
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
|
@ -17,6 +19,8 @@ fun FilterBar(
|
||||||
filter: Filter,
|
filter: Filter,
|
||||||
filterOnClick: (Filter) -> Unit = {},
|
filterOnClick: (Filter) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
|
val view = LocalView.current
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.height(60.dp)
|
modifier = Modifier.height(60.dp)
|
||||||
) {
|
) {
|
||||||
|
@ -45,7 +49,11 @@ fun FilterBar(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
selected = filter == item,
|
selected = filter == item,
|
||||||
onClick = { filterOnClick(item) },
|
onClick = {
|
||||||
|
// view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
|
||||||
|
view.playSoundEffect(SoundEffectConstants.CLICK)
|
||||||
|
filterOnClick(item)
|
||||||
|
},
|
||||||
// colors = NavigationBarItemDefaults.colors(
|
// colors = NavigationBarItemDefaults.colors(
|
||||||
// selectedIconColor = MaterialTheme.colorScheme.onSecondaryContainer,
|
// selectedIconColor = MaterialTheme.colorScheme.onSecondaryContainer,
|
||||||
// unselectedIconColor = MaterialTheme.colorScheme.outline,
|
// unselectedIconColor = MaterialTheme.colorScheme.outline,
|
||||||
|
|
|
@ -2,7 +2,6 @@ package me.ash.reader.ui.page.home.feeds
|
||||||
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.animation.*
|
|
||||||
import androidx.compose.animation.core.*
|
import androidx.compose.animation.core.*
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
|
@ -12,8 +11,8 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.KeyboardArrowRight
|
import androidx.compose.material.icons.outlined.KeyboardArrowRight
|
||||||
import androidx.compose.material.icons.rounded.Add
|
import androidx.compose.material.icons.rounded.Add
|
||||||
import androidx.compose.material.icons.rounded.ArrowBack
|
|
||||||
import androidx.compose.material.icons.rounded.Refresh
|
import androidx.compose.material.icons.rounded.Refresh
|
||||||
|
import androidx.compose.material.icons.rounded.Tune
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -22,7 +21,6 @@ import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
@ -31,6 +29,8 @@ import androidx.work.WorkInfo
|
||||||
import me.ash.reader.R
|
import me.ash.reader.R
|
||||||
import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing
|
import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing
|
||||||
import me.ash.reader.ui.component.Banner
|
import me.ash.reader.ui.component.Banner
|
||||||
|
import me.ash.reader.ui.component.DisplayText
|
||||||
|
import me.ash.reader.ui.component.FeedbackIconButton
|
||||||
import me.ash.reader.ui.component.Subtitle
|
import me.ash.reader.ui.component.Subtitle
|
||||||
import me.ash.reader.ui.ext.collectAsStateValue
|
import me.ash.reader.ui.ext.collectAsStateValue
|
||||||
import me.ash.reader.ui.ext.getDesc
|
import me.ash.reader.ui.ext.getDesc
|
||||||
|
@ -104,39 +104,35 @@ fun FeedsPage(
|
||||||
SmallTopAppBar(
|
SmallTopAppBar(
|
||||||
title = {},
|
title = {},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = {
|
FeedbackIconButton(
|
||||||
|
isHaptic = false,
|
||||||
|
imageVector = Icons.Rounded.Tune,
|
||||||
|
contentDescription = stringResource(R.string.settings),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
|
) {
|
||||||
onScrollToPage(0)
|
onScrollToPage(0)
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.ArrowBack,
|
|
||||||
contentDescription = stringResource(R.string.back),
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = {
|
FeedbackIconButton(
|
||||||
|
isHaptic = false,
|
||||||
|
modifier = Modifier.rotate(if (isSyncing) angle else 0f),
|
||||||
|
imageVector = Icons.Rounded.Refresh,
|
||||||
|
contentDescription = stringResource(R.string.refresh),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
|
) {
|
||||||
if (!isSyncing) {
|
if (!isSyncing) {
|
||||||
onSyncClick()
|
onSyncClick()
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier.rotate(if (isSyncing) angle else 0f),
|
|
||||||
imageVector = Icons.Rounded.Refresh,
|
|
||||||
contentDescription = stringResource(R.string.refresh),
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
IconButton(onClick = {
|
FeedbackIconButton(
|
||||||
|
isHaptic = false,
|
||||||
|
imageVector = Icons.Rounded.Add,
|
||||||
|
contentDescription = stringResource(R.string.subscribe),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
|
) {
|
||||||
subscribeViewModel.dispatch(SubscribeViewAction.Show)
|
subscribeViewModel.dispatch(SubscribeViewAction.Show)
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.Add,
|
|
||||||
contentDescription = stringResource(R.string.subscribe),
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -144,48 +140,18 @@ fun FeedsPage(
|
||||||
SubscribeDialog()
|
SubscribeDialog()
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
item {
|
item {
|
||||||
Text(
|
DisplayText(
|
||||||
modifier = Modifier
|
modifier = Modifier.pointerInput(Unit) {
|
||||||
.padding(
|
detectTapGestures(
|
||||||
start = 24.dp,
|
onLongPress = {
|
||||||
top = 48.dp,
|
launcher.launch("ReadYou.opml")
|
||||||
end = 24.dp,
|
}
|
||||||
// bottom = 24.dp
|
|
||||||
)
|
)
|
||||||
.pointerInput(Unit) {
|
},
|
||||||
detectTapGestures(
|
|
||||||
onLongPress = {
|
|
||||||
launcher.launch("ReadYou.opml")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
text = viewState.account?.name ?: stringResource(R.string.unknown),
|
text = viewState.account?.name ?: stringResource(R.string.unknown),
|
||||||
style = MaterialTheme.typography.displaySmall,
|
desc = if (isSyncing) stringResource(R.string.syncing) else "",
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = isSyncing,
|
|
||||||
enter = fadeIn() + expandVertically(),
|
|
||||||
exit = fadeOut() + shrinkVertically(),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(
|
|
||||||
start = 24.dp,
|
|
||||||
top = 0.dp,
|
|
||||||
end = 24.dp,
|
|
||||||
bottom = 0.dp
|
|
||||||
),
|
|
||||||
text = stringResource(R.string.syncing),
|
|
||||||
style = MaterialTheme.typography.labelMedium,
|
|
||||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
|
||||||
}
|
|
||||||
item {
|
item {
|
||||||
Banner(
|
Banner(
|
||||||
title = filterState.filter.getName(),
|
title = filterState.filter.getName(),
|
||||||
|
|
|
@ -10,14 +10,16 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.ArrowBack
|
import androidx.compose.material.icons.rounded.ArrowBack
|
||||||
import androidx.compose.material.icons.rounded.DoneAll
|
import androidx.compose.material.icons.rounded.DoneAll
|
||||||
import androidx.compose.material.icons.rounded.Search
|
import androidx.compose.material.icons.rounded.Search
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.SmallTopAppBar
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
@ -29,6 +31,8 @@ import kotlinx.coroutines.launch
|
||||||
import me.ash.reader.R
|
import me.ash.reader.R
|
||||||
import me.ash.reader.data.entity.ArticleWithFeed
|
import me.ash.reader.data.entity.ArticleWithFeed
|
||||||
import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing
|
import me.ash.reader.data.repository.SyncWorker.Companion.getIsSyncing
|
||||||
|
import me.ash.reader.ui.component.DisplayText
|
||||||
|
import me.ash.reader.ui.component.FeedbackIconButton
|
||||||
import me.ash.reader.ui.ext.collectAsStateValue
|
import me.ash.reader.ui.ext.collectAsStateValue
|
||||||
import me.ash.reader.ui.ext.getName
|
import me.ash.reader.ui.ext.getName
|
||||||
import me.ash.reader.ui.page.home.FilterBar
|
import me.ash.reader.ui.page.home.FilterBar
|
||||||
|
@ -87,12 +91,13 @@ fun FlowPage(
|
||||||
SmallTopAppBar(
|
SmallTopAppBar(
|
||||||
title = {},
|
title = {},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = { onScrollToPage(0) }) {
|
FeedbackIconButton(
|
||||||
Icon(
|
isHaptic = false,
|
||||||
imageVector = Icons.Rounded.ArrowBack,
|
imageVector = Icons.Rounded.ArrowBack,
|
||||||
contentDescription = stringResource(R.string.back),
|
contentDescription = stringResource(R.string.back),
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
tint = MaterialTheme.colorScheme.onSurface
|
||||||
)
|
) {
|
||||||
|
onScrollToPage(0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
|
@ -101,29 +106,28 @@ fun FlowPage(
|
||||||
enter = fadeIn() + expandVertically(),
|
enter = fadeIn() + expandVertically(),
|
||||||
exit = fadeOut() + shrinkVertically(),
|
exit = fadeOut() + shrinkVertically(),
|
||||||
) {
|
) {
|
||||||
IconButton(onClick = {
|
FeedbackIconButton(
|
||||||
|
isHaptic = false,
|
||||||
|
imageVector = Icons.Rounded.DoneAll,
|
||||||
|
contentDescription = stringResource(R.string.mark_all_as_read),
|
||||||
|
tint = if (markAsRead) {
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
} else {
|
||||||
|
MaterialTheme.colorScheme.onSurface
|
||||||
|
},
|
||||||
|
) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
viewState.listState.scrollToItem(0)
|
viewState.listState.scrollToItem(0)
|
||||||
markAsRead = !markAsRead
|
markAsRead = !markAsRead
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.DoneAll,
|
|
||||||
contentDescription = stringResource(R.string.mark_all_as_read),
|
|
||||||
tint = if (markAsRead) {
|
|
||||||
MaterialTheme.colorScheme.primary
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.onSurface
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton(onClick = {}) {
|
FeedbackIconButton(
|
||||||
Icon(
|
isHaptic = false,
|
||||||
imageVector = Icons.Rounded.Search,
|
imageVector = Icons.Rounded.Search,
|
||||||
contentDescription = stringResource(R.string.search),
|
contentDescription = stringResource(R.string.search),
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
)
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -142,46 +146,16 @@ fun FlowPage(
|
||||||
state = viewState.listState,
|
state = viewState.listState,
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Text(
|
DisplayText(
|
||||||
modifier = Modifier
|
modifier = Modifier.padding(start = 30.dp),
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(
|
|
||||||
start = if (true) 54.dp else 24.dp,
|
|
||||||
top = 48.dp,
|
|
||||||
end = 24.dp,
|
|
||||||
// bottom = 24.dp
|
|
||||||
),
|
|
||||||
text = when {
|
text = when {
|
||||||
filterState.group != null -> filterState.group.name
|
filterState.group != null -> filterState.group.name
|
||||||
filterState.feed != null -> filterState.feed.name
|
filterState.feed != null -> filterState.feed.name
|
||||||
else -> filterState.filter.getName()
|
else -> filterState.filter.getName()
|
||||||
},
|
},
|
||||||
style = MaterialTheme.typography.displaySmall,
|
desc = if (isSyncing) stringResource(R.string.syncing) else "",
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = isSyncing,
|
|
||||||
enter = fadeIn() + expandVertically(),
|
|
||||||
exit = fadeOut() + shrinkVertically(),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(
|
|
||||||
start = if (true) 54.dp else 24.dp,
|
|
||||||
top = 0.dp,
|
|
||||||
end = 24.dp,
|
|
||||||
bottom = 0.dp
|
|
||||||
),
|
|
||||||
text = stringResource(R.string.syncing),
|
|
||||||
style = MaterialTheme.typography.labelMedium,
|
|
||||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
|
||||||
}
|
|
||||||
item {
|
item {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = markAsRead,
|
visible = markAsRead,
|
||||||
|
|
|
@ -22,6 +22,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import me.ash.reader.R
|
import me.ash.reader.R
|
||||||
import me.ash.reader.data.entity.ArticleWithFeed
|
import me.ash.reader.data.entity.ArticleWithFeed
|
||||||
|
import me.ash.reader.ui.component.FeedbackIconButton
|
||||||
import me.ash.reader.ui.component.WebView
|
import me.ash.reader.ui.component.WebView
|
||||||
import me.ash.reader.ui.ext.collectAsStateValue
|
import me.ash.reader.ui.ext.collectAsStateValue
|
||||||
|
|
||||||
|
@ -143,34 +144,33 @@ private fun TopBar(
|
||||||
),
|
),
|
||||||
title = {},
|
title = {},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = {
|
FeedbackIconButton(
|
||||||
|
isHaptic = false,
|
||||||
|
imageVector = Icons.Rounded.Close,
|
||||||
|
contentDescription = stringResource(R.string.back),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface
|
||||||
|
) {
|
||||||
onScrollToPage(1) {
|
onScrollToPage(1) {
|
||||||
onClearArticle()
|
onClearArticle()
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Rounded.Close,
|
|
||||||
contentDescription = stringResource(R.string.back),
|
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (isShowActions) {
|
if (isShowActions) {
|
||||||
IconButton(onClick = {}) {
|
FeedbackIconButton(
|
||||||
Icon(
|
isHaptic = false,
|
||||||
modifier = Modifier.size(22.dp),
|
modifier = Modifier.size(22.dp),
|
||||||
imageVector = Icons.Outlined.Headphones,
|
imageVector = Icons.Outlined.Headphones,
|
||||||
contentDescription = stringResource(R.string.mark_all_as_read),
|
contentDescription = stringResource(R.string.mark_all_as_read),
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
)
|
) {
|
||||||
}
|
}
|
||||||
IconButton(onClick = {}) {
|
FeedbackIconButton(
|
||||||
Icon(
|
isHaptic = false,
|
||||||
imageVector = Icons.Outlined.MoreVert,
|
imageVector = Icons.Outlined.MoreVert,
|
||||||
contentDescription = stringResource(R.string.search),
|
contentDescription = stringResource(R.string.search),
|
||||||
tint = MaterialTheme.colorScheme.onSurface,
|
tint = MaterialTheme.colorScheme.onSurface,
|
||||||
)
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<string name="unknown">未知</string>
|
<string name="unknown">未知</string>
|
||||||
<string name="back">返回</string>
|
<string name="back">返回</string>
|
||||||
<string name="go_to">转到</string>
|
<string name="go_to">转到</string>
|
||||||
|
<string name="settings">设置</string>
|
||||||
<string name="refresh">刷新</string>
|
<string name="refresh">刷新</string>
|
||||||
<string name="search">搜索</string>
|
<string name="search">搜索</string>
|
||||||
<string name="searching">搜索中…</string>
|
<string name="searching">搜索中…</string>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<string name="unknown">Unknown</string>
|
<string name="unknown">Unknown</string>
|
||||||
<string name="back">Back</string>
|
<string name="back">Back</string>
|
||||||
<string name="go_to">Goto</string>
|
<string name="go_to">Goto</string>
|
||||||
|
<string name="settings">Settings</string>
|
||||||
<string name="refresh">Refresh</string>
|
<string name="refresh">Refresh</string>
|
||||||
<string name="search">Search</string>
|
<string name="search">Search</string>
|
||||||
<string name="searching">Searching…</string>
|
<string name="searching">Searching…</string>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user