Add feed's icon in articles list

This commit is contained in:
Ash 2022-03-03 20:25:04 +08:00
parent 8d296b4b01
commit bfe1307b27
12 changed files with 238 additions and 143 deletions

View File

@ -19,7 +19,7 @@ data class Feed(
@ColumnInfo @ColumnInfo
val name: String, val name: String,
@ColumnInfo @ColumnInfo
var icon: String? = null, var icon: ByteArray? = null,
@ColumnInfo @ColumnInfo
val url: String, val url: String,
@ColumnInfo(index = true) @ColumnInfo(index = true)
@ -31,4 +31,37 @@ data class Feed(
) { ) {
@Ignore @Ignore
var important: Int? = 0 var important: Int? = 0
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Feed
if (id != other.id) return false
if (name != other.name) return false
if (icon != null) {
if (other.icon == null) return false
if (!icon.contentEquals(other.icon)) return false
} else if (other.icon != null) return false
if (url != other.url) return false
if (groupId != other.groupId) return false
if (accountId != other.accountId) return false
if (isFullContent != other.isFullContent) return false
if (important != other.important) return false
return true
}
override fun hashCode(): Int {
var result = id ?: 0
result = 31 * result + name.hashCode()
result = 31 * result + (icon?.contentHashCode() ?: 0)
result = 31 * result + url.hashCode()
result = 31 * result + groupId
result = 31 * result + accountId
result = 31 * result + isFullContent.hashCode()
result = 31 * result + (important ?: 0)
return result
}
} }

View File

@ -93,7 +93,6 @@ class RssRepository @Inject constructor(
Constraints.Builder() Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true) .setRequiresCharging(true)
.setRequiresDeviceIdle(true)
.build() .build()
).addTag("sync").build() ).addTag("sync").build()
workManager.enqueue(syncWorkerRequest) workManager.enqueue(syncWorkerRequest)
@ -161,18 +160,18 @@ class RssRepository @Inject constructor(
val articles = mutableListOf<Article>() val articles = mutableListOf<Article>()
chunked[it].forEach { feed -> chunked[it].forEach { feed ->
val latest = articleDao.queryLatestByFeedId(accountId, feed.id ?: 0) val latest = articleDao.queryLatestByFeedId(accountId, feed.id ?: 0)
// if (feed.icon == null) {
// queryRssIcon(feedDao, feed, latest?.link)
// }
articles.addAll( articles.addAll(
queryRssXml( queryRssXml(
rssNetworkDataSource, rssNetworkDataSource,
accountId, accountId,
feed, feed,
latest?.title, latest?.title,
) ).also {
if (feed.icon == null && it.isNotEmpty()) {
queryRssIcon(feedDao, feed, it.first().link)
}
}
) )
syncState.update { syncState.update {
it.copy( it.copy(
feedCount = feeds.size, feedCount = feeds.size,
@ -280,34 +279,44 @@ class RssRepository @Inject constructor(
articleLink: String?, articleLink: String?,
) { ) {
if (articleLink == null) return if (articleLink == null) return
val exe = OkHttpClient() val execute = OkHttpClient()
.newCall(Request.Builder().url(articleLink).build()).execute() .newCall(Request.Builder().url(articleLink).build())
val content = exe.body?.string() .execute()
Log.i("rlog", "queryRssIcon: $content") val content = execute.body?.string()
val regex = val regex =
Regex("""<link(.+?)rel="shortcut icon"(.+?)type="image/x-icon"(.+?)href="(.+?)"""") Regex("""<link(.+?)rel="shortcut icon"(.+?)href="(.+?)"""")
if (content != null) { if (content != null) {
var iconLink = regex var iconLink = regex
.find(content) .find(content)
?.groups?.get(4) ?.groups?.get(3)
?.value ?.value
Log.i("rlog", "queryRssIcon: $iconLink")
if (iconLink != null) { if (iconLink != null) {
if (iconLink.startsWith("//")) { if (iconLink.startsWith("//")) {
iconLink = "http:$iconLink" iconLink = "http:$iconLink"
} }
if (iconLink.startsWith("/")) {
val domainRegex =
Regex("""http(s)?://(([\w-]+\.)+\w+(:\d{1,5})?)""")
iconLink =
"http://${domainRegex.find(articleLink)?.groups?.get(2)?.value}$iconLink"
}
saveRssIcon(feedDao, feed, iconLink) saveRssIcon(feedDao, feed, iconLink)
} else { } else {
saveRssIcon(feedDao, feed, "") // saveRssIcon(feedDao, feed, "")
} }
} else { } else {
saveRssIcon(feedDao, feed, "") // saveRssIcon(feedDao, feed, "")
} }
} }
private suspend fun saveRssIcon(feedDao: FeedDao, feed: Feed, iconLink: String) { private suspend fun saveRssIcon(feedDao: FeedDao, feed: Feed, iconLink: String) {
val execute = OkHttpClient()
.newCall(Request.Builder().url(iconLink).build())
.execute()
feedDao.update( feedDao.update(
feed.apply { feed.apply {
icon = iconLink icon = execute.body?.bytes()
} }
) )
} }

View File

@ -1,11 +1,15 @@
package me.ash.reader.ui.page.home.article package me.ash.reader.ui.page.home.article
import android.graphics.BitmapFactory
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBackIosNew import androidx.compose.material.icons.rounded.ArrowBackIosNew
import androidx.compose.material.icons.rounded.DoneAll import androidx.compose.material.icons.rounded.DoneAll
@ -17,7 +21,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -31,6 +38,7 @@ import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import me.ash.reader.DateTimeExt import me.ash.reader.DateTimeExt
import me.ash.reader.DateTimeExt.toString import me.ash.reader.DateTimeExt.toString
import me.ash.reader.R
import me.ash.reader.data.article.ArticleWithFeed import me.ash.reader.data.article.ArticleWithFeed
import me.ash.reader.data.repository.RssRepository import me.ash.reader.data.repository.RssRepository
import me.ash.reader.ui.data.Filter import me.ash.reader.ui.data.Filter
@ -97,7 +105,7 @@ fun ArticlePage(
"${viewState.filterImportant}${filterState.filter.description}" "${viewState.filterImportant}${filterState.filter.description}"
}, },
listState = viewState.listState, listState = viewState.listState,
startOffset = Offset(20f, 72f), startOffset = Offset(if (true) 52f else 20f, 72f),
startHeight = 50f, startHeight = 50f,
startTitleFontSize = 24f, startTitleFontSize = 24f,
startDescriptionFontSize = 14f, startDescriptionFontSize = 14f,
@ -161,7 +169,7 @@ fun ArticlePage(
item { Spacer(modifier = Modifier.height(40.dp)) } item { Spacer(modifier = Modifier.height(40.dp)) }
} }
stickyHeader { stickyHeader {
ArticleDateHeader(currentItemDay) ArticleDateHeader(currentItemDay, true)
} }
} }
item { item {
@ -214,6 +222,7 @@ private fun ArticleItem(
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
Text( Text(
modifier = Modifier.padding(start = 32.dp),
text = articleWithFeed.feed.name, text = articleWithFeed.feed.name,
fontSize = 13.sp, fontSize = 13.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
@ -232,32 +241,72 @@ private fun ArticleItem(
) )
} }
Spacer(modifier = modifier.height(1.dp)) Spacer(modifier = modifier.height(1.dp))
Text( if (true) {
text = articleWithFeed.article.title, Box(
fontSize = 18.sp, modifier = Modifier
fontWeight = FontWeight.Bold, .padding(top = 3.dp)
color = if (isStarredFilter || articleWithFeed.article.isUnread) { .size(24.dp)
MaterialTheme.colorScheme.onPrimaryContainer .border(
} else { 2.dp,
MaterialTheme.colorScheme.outline MaterialTheme.colorScheme.inverseOnSurface,
}, RoundedCornerShape(4.dp)
maxLines = 2, ),
overflow = TextOverflow.Ellipsis ) {
) if (articleWithFeed.feed.icon == null) {
Spacer(modifier = modifier.height(1.dp)) Icon(
Text( painter = painterResource(id = R.drawable.default_folder),
text = articleWithFeed.article.shortDescription, contentDescription = "icon",
fontSize = 18.sp, modifier = modifier
color = MaterialTheme.colorScheme.outline, .fillMaxSize()
maxLines = 2, .padding(2.dp),
overflow = TextOverflow.Ellipsis tint = MaterialTheme.colorScheme.onPrimaryContainer,
) )
} else {
Image(
painter = BitmapPainter(
BitmapFactory.decodeByteArray(
articleWithFeed.feed.icon,
0,
articleWithFeed.feed.icon!!.size
).asImageBitmap()
),
contentDescription = "icon",
modifier = modifier
.fillMaxSize()
.padding(2.dp),
)
}
}
Spacer(modifier = Modifier.width(8.dp))
}
Column {
Text(
text = articleWithFeed.article.title,
fontSize = 18.sp,
fontWeight = FontWeight.Bold,
color = if (isStarredFilter || articleWithFeed.article.isUnread) {
MaterialTheme.colorScheme.onPrimaryContainer
} else {
MaterialTheme.colorScheme.outline
},
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
Spacer(modifier = modifier.height(1.dp))
Text(
text = articleWithFeed.article.shortDescription,
fontSize = 18.sp,
color = MaterialTheme.colorScheme.outline,
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
} }
} }
} }
@Composable @Composable
private fun ArticleDateHeader(date: String) { private fun ArticleDateHeader(date: String, isDisplayIcon: Boolean) {
Row( Row(
modifier = Modifier modifier = Modifier
.height(28.dp) .height(28.dp)
@ -269,7 +318,7 @@ private fun ArticleDateHeader(date: String) {
text = date, text = date,
fontSize = 13.sp, fontSize = 13.sp,
color = MaterialTheme.colorScheme.secondary, color = MaterialTheme.colorScheme.secondary,
modifier = Modifier.padding(horizontal = 20.dp), modifier = Modifier.padding(start = (if (isDisplayIcon) 52 else 20).dp),
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
) )
} }

View File

@ -1,5 +1,6 @@
package me.ash.reader.ui.page.home.feed package me.ash.reader.ui.page.home.feed
import android.graphics.BitmapFactory
import android.util.Log import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@ -20,15 +21,15 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
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 com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.ExperimentalPagerApi
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import me.ash.reader.DateTimeExt import me.ash.reader.DateTimeExt
import me.ash.reader.DateTimeExt.toString import me.ash.reader.DateTimeExt.toString
import me.ash.reader.R
import me.ash.reader.data.feed.Feed import me.ash.reader.data.feed.Feed
import me.ash.reader.data.group.Group import me.ash.reader.data.group.Group
import me.ash.reader.data.group.GroupWithFeed import me.ash.reader.data.group.GroupWithFeed
@ -239,10 +240,21 @@ private fun ColumnScope.FeedList(
) { ) {
Column(modifier = Modifier.animateContentSize()) { Column(modifier = Modifier.animateContentSize()) {
feeds.forEach { feed -> feeds.forEach { feed ->
Log.i("RLog", "FeedList: ${feed.icon}")
BarButton( BarButton(
barButtonType = ItemType( barButtonType = ItemType(
// icon = feed.icon ?: "", // icon = feed.icon ?: "",
icon = painterResource(id = R.drawable.default_folder), icon = if (feed.icon == null) {
null
} else {
BitmapPainter(
BitmapFactory.decodeByteArray(
feed.icon,
0,
feed.icon!!.size
).asImageBitmap()
)
},
content = feed.name, content = feed.name,
important = feed.important ?: 0 important = feed.important ?: 0
) )

View File

@ -168,6 +168,7 @@ private fun Header(
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth()
.roundClick { .roundClick {
context.startActivity( context.startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse(article.link)) Intent(Intent.ACTION_VIEW, Uri.parse(article.link))

View File

@ -0,0 +1,5 @@
package me.ash.reader.ui.util
object Symbol {
const val nothing: String = "null"
}

View File

@ -1,5 +1,6 @@
package me.ash.reader.ui.widget package me.ash.reader.ui.widget
import android.view.HapticFeedbackConstants
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.FastOutLinearInEasing import androidx.compose.animation.core.FastOutLinearInEasing
@ -27,6 +28,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -83,7 +85,9 @@ fun AppNavigationBar(
} }
} }
Divider(modifier = Modifier.alpha(0.3f)) Divider(
modifier = Modifier.alpha(0.3f),
)
Box( Box(
modifier = modifier modifier = modifier
.background(MaterialTheme.colorScheme.surface) .background(MaterialTheme.colorScheme.surface)
@ -141,6 +145,7 @@ private fun FilterBar(
filter: Filter, filter: Filter,
onSelected: (Filter) -> Unit = {}, onSelected: (Filter) -> Unit = {},
) { ) {
val view = LocalView.current
Row( Row(
modifier = modifier, modifier = modifier,
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
@ -168,6 +173,7 @@ private fun FilterBar(
) )
.clip(CircleShape) .clip(CircleShape)
.clickable(onClick = { .clickable(onClick = {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
onSelected( onSelected(
when (index) { when (index) {
0 -> Filter.Starred 0 -> Filter.Starred
@ -237,6 +243,7 @@ private fun ReaderBar(
starredOnClick: (afterIsStarred: Boolean) -> Unit = {}, starredOnClick: (afterIsStarred: Boolean) -> Unit = {},
fullContentOnClick: (afterIsFullContent: Boolean) -> Unit = {}, fullContentOnClick: (afterIsFullContent: Boolean) -> Unit = {},
) { ) {
val view = LocalView.current
var fullContent by remember { mutableStateOf(isFullContent) } var fullContent by remember { mutableStateOf(isFullContent) }
Row( Row(
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@ -246,6 +253,7 @@ private fun ReaderBar(
.padding(horizontal = 8.dp) .padding(horizontal = 8.dp)
) { ) {
CanBeDisabledIconButton( CanBeDisabledIconButton(
modifier = Modifier.size(18.dp),
disabled = disabled, disabled = disabled,
imageVector = if (isUnread) { imageVector = if (isUnread) {
Icons.Rounded.Circle Icons.Rounded.Circle
@ -255,6 +263,7 @@ private fun ReaderBar(
contentDescription = "Mark Unread", contentDescription = "Mark Unread",
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) { ) {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
unreadOnClick(!isUnread) unreadOnClick(!isUnread)
} }
CanBeDisabledIconButton( CanBeDisabledIconButton(
@ -268,6 +277,7 @@ private fun ReaderBar(
contentDescription = "Starred", contentDescription = "Starred",
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) { ) {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
starredOnClick(!isStarred) starredOnClick(!isStarred)
} }
CanBeDisabledIconButton( CanBeDisabledIconButton(
@ -277,7 +287,7 @@ private fun ReaderBar(
contentDescription = "Next Article", contentDescription = "Next Article",
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) { ) {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
} }
CanBeDisabledIconButton( CanBeDisabledIconButton(
disabled = disabled, disabled = disabled,
@ -285,7 +295,7 @@ private fun ReaderBar(
contentDescription = "Add Tag", contentDescription = "Add Tag",
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) { ) {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
} }
CanBeDisabledIconButton( CanBeDisabledIconButton(
disabled = disabled, disabled = disabled,
@ -298,6 +308,7 @@ private fun ReaderBar(
contentDescription = "Full Content Parsing", contentDescription = "Full Content Parsing",
tint = MaterialTheme.colorScheme.primary, tint = MaterialTheme.colorScheme.primary,
) { ) {
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
val afterIsFullContent = !fullContent val afterIsFullContent = !fullContent
fullContent = afterIsFullContent fullContent = afterIsFullContent
fullContentOnClick(afterIsFullContent) fullContentOnClick(afterIsFullContent)

View File

@ -1,6 +1,8 @@
package me.ash.reader.ui.widget package me.ash.reader.ui.widget
import android.graphics.BitmapFactory
import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@ -12,11 +14,17 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
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.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import me.ash.reader.R
import me.ash.reader.ui.util.paddingFixedHorizontal import me.ash.reader.ui.util.paddingFixedHorizontal
import me.ash.reader.ui.util.roundClick import me.ash.reader.ui.util.roundClick
@ -43,60 +51,73 @@ fun BarButton(
end = if (barButtonType is FirstExpandType) 2.dp else 10.dp end = if (barButtonType is FirstExpandType) 2.dp else 10.dp
) )
) { ) {
Row(verticalAlignment = Alignment.CenterVertically) { when (barButtonType) {
when (barButtonType) { is SecondExpandType -> {
is SecondExpandType -> { Icon(
Icon( imageVector = barButtonType.img,
imageVector = barButtonType.img as ImageVector, contentDescription = "icon",
contentDescription = "icon", modifier = Modifier
modifier = Modifier .padding(end = 4.dp)
.padding(end = 4.dp) .clip(CircleShape)
.clip(CircleShape) .clickable(onClick = iconOnClickListener),
.clickable(onClick = iconOnClickListener), tint = MaterialTheme.colorScheme.onPrimaryContainer,
tint = MaterialTheme.colorScheme.onPrimaryContainer, )
) }
} is ItemType -> {
is ItemType -> { val modifier = Modifier
val modifier = Modifier Row(
Row( modifier = modifier
modifier = modifier .padding(start = 28.dp, end = 4.dp)
.padding(start = 28.dp, end = 4.dp) .size(24.dp)
.size(24.dp) .background(
// .background(if (barButtonType.img.isBlank()) MaterialTheme.colorScheme.inversePrimary else Color.Unspecified), if (barButtonType.icon != null) Color.Unspecified
.background(MaterialTheme.colorScheme.inversePrimary), else MaterialTheme.colorScheme.inversePrimary
horizontalArrangement = Arrangement.Center, ),
verticalAlignment = Alignment.CenterVertically, // .background(MaterialTheme.colorScheme.inversePrimary),
) { horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
if (barButtonType.icon == null) {
Icon( Icon(
// painter = rememberImagePainter(barButtonType.img), painter = painterResource(id = R.drawable.default_folder),
painter = barButtonType.img,
contentDescription = "icon", contentDescription = "icon",
modifier = modifier.fillMaxSize(), modifier = modifier.fillMaxSize(),
tint = MaterialTheme.colorScheme.onPrimaryContainer, tint = MaterialTheme.colorScheme.onPrimaryContainer,
) )
} else {
Image(
painter = barButtonType.icon,
contentDescription = "icon",
modifier = modifier.fillMaxSize(),
)
} }
} }
} }
when (barButtonType) { }
is ButtonType -> { when (barButtonType) {
AnimatedText( is ButtonType -> {
text = barButtonType.text, AnimatedText(
fontSize = 22.sp, modifier = Modifier.weight(1f),
fontWeight = FontWeight.Bold, text = barButtonType.text,
color = MaterialTheme.colorScheme.primary, fontSize = 22.sp,
) fontWeight = FontWeight.Bold,
} color = MaterialTheme.colorScheme.primary,
else -> { )
Text( }
text = barButtonType.text, else -> {
fontSize = if (barButtonType is FirstExpandType) 22.sp else 18.sp, Text(
fontWeight = if (barButtonType is FirstExpandType) FontWeight.Bold else FontWeight.SemiBold, modifier = Modifier
color = if (barButtonType is FirstExpandType) .weight(1f)
MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onPrimaryContainer, .padding(end = 20.dp),
) maxLines = 1,
} overflow = TextOverflow.Ellipsis,
text = barButtonType.text,
fontSize = if (barButtonType is FirstExpandType) 22.sp else 18.sp,
fontWeight = if (barButtonType is FirstExpandType) FontWeight.Bold else FontWeight.SemiBold,
color = if (barButtonType is FirstExpandType)
MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onPrimaryContainer,
)
} }
} }
when (barButtonType) { when (barButtonType) {
is ButtonType, is ItemType, is SecondExpandType -> { is ButtonType, is ItemType, is SecondExpandType -> {
@ -163,13 +184,15 @@ class SecondExpandType(
class ItemType( class ItemType(
// private val icon: String, // private val icon: String,
private val icon: Painter, val icon: BitmapPainter?,
private val content: String, private val content: String,
private val important: Int, private val important: Int,
) : BarButtonType { ) : BarButtonType {
// override val img: String // override val img: String
override val img: Painter override val img: Painter
get() = icon get() = icon ?: BitmapPainter(
BitmapFactory.decodeByteArray(byteArrayOf(), 0, 0).asImageBitmap()
)
override val text: String override val text: String
get() = content get() = content
override val additional: Any override val additional: Any

View File

@ -73,7 +73,7 @@ fun BoxScope.TopTitleBox(
interactionSource = MutableInteractionSource(), interactionSource = MutableInteractionSource(),
indication = null, indication = null,
onClickLabel = "回到顶部", onClickLabel = "回到顶部",
onClick = clickable ?: {} onClick = clickable
), ),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
@ -86,6 +86,7 @@ fun BoxScope.TopTitleBox(
) )
Spacer(modifier = Modifier.height(SpacerHeight.dp)) Spacer(modifier = Modifier.height(SpacerHeight.dp))
AnimatedText( AnimatedText(
modifier = Modifier.width(200.dp),
text = description, text = description,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
fontSize = descriptionFontSize.sp, fontSize = descriptionFontSize.sp,

View File

@ -1,8 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:pathData="M0,0H28V28H0V0Z"/>
</vector>

View File

@ -1,5 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="44dp"
android:height="44dp"
android:viewportWidth="44"
android:viewportHeight="44" />

View File

@ -1,36 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="647.6362dp"
android:height="632.1738dp"
android:viewportWidth="647.6362"
android:viewportHeight="632.1738">
<path
android:pathData="M411.146,142.174L236.636,142.174a15.018,15.018 0,0 0,-15 15v387.85l-2,0.61 -42.81,13.11a8.007,8.007 0,0 1,-9.99 -5.31L39.496,137.484a8.003,8.003 0,0 1,5.31 -9.99l65.97,-20.2 191.25,-58.54 65.97,-20.2a7.989,7.989 0,0 1,9.99 5.3l32.55,106.32Z"
android:fillColor="#f2f2f2"/>
<path
android:pathData="M449.226,140.174l-39.23,-128.14a16.994,16.994 0,0 0,-21.23 -11.28l-92.75,28.39L104.776,87.694l-92.75,28.4a17.015,17.015 0,0 0,-11.28 21.23l134.08,437.93a17.027,17.027 0,0 0,16.26 12.03,16.789 16.789,0 0,0 4.97,-0.75l63.58,-19.46 2,-0.62v-2.09l-2,0.61 -64.17,19.65a15.015,15.015 0,0 1,-18.73 -9.95l-134.07,-437.94a14.979,14.979 0,0 1,9.95 -18.73l92.75,-28.4 191.24,-58.54 92.75,-28.4a15.156,15.156 0,0 1,4.41 -0.66,15.015 15.015,0 0,1 14.32,10.61l39.05,127.56 0.62,2h2.08Z"
android:fillColor="#3f3d56"/>
<path
android:pathData="M122.681,127.821a9.016,9.016 0,0 1,-8.611 -6.367l-12.88,-42.072a8.999,8.999 0,0 1,5.971 -11.24l175.939,-53.864a9.009,9.009 0,0 1,11.241 5.971l12.88,42.072a9.01,9.01 0,0 1,-5.971 11.241L125.31,127.426A8.976,8.976 0,0 1,122.681 127.821Z"
android:fillColor="#6c63ff"/>
<path
android:pathData="M190.154,24.955m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
android:fillColor="#6c63ff"/>
<path
android:pathData="M190.154,24.955m-12.665,0a12.665,12.665 0,1 1,25.329 0a12.665,12.665 0,1 1,-25.329 0"
android:fillColor="#fff"/>
<path
android:pathData="M602.636,582.174h-338a8.51,8.51 0,0 1,-8.5 -8.5v-405a8.51,8.51 0,0 1,8.5 -8.5h338a8.51,8.51 0,0 1,8.5 8.5v405A8.51,8.51 0,0 1,602.636 582.174Z"
android:fillColor="#e6e6e6"/>
<path
android:pathData="M447.136,140.174h-210.5a17.024,17.024 0,0 0,-17 17v407.8l2,-0.61v-407.19a15.018,15.018 0,0 1,15 -15L447.756,142.174ZM630.636,140.174h-394a17.024,17.024 0,0 0,-17 17v458a17.024,17.024 0,0 0,17 17h394a17.024,17.024 0,0 0,17 -17v-458A17.024,17.024 0,0 0,630.636 140.174ZM645.636,615.174a15.018,15.018 0,0 1,-15 15h-394a15.018,15.018 0,0 1,-15 -15v-458a15.018,15.018 0,0 1,15 -15h394a15.018,15.018 0,0 1,15 15Z"
android:fillColor="#3f3d56"/>
<path
android:pathData="M525.636,184.174h-184a9.01,9.01 0,0 1,-9 -9v-44a9.01,9.01 0,0 1,9 -9h184a9.01,9.01 0,0 1,9 9v44A9.01,9.01 0,0 1,525.636 184.174Z"
android:fillColor="#6c63ff"/>
<path
android:pathData="M433.636,105.174m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0"
android:fillColor="#6c63ff"/>
<path
android:pathData="M433.636,105.174m-12.182,0a12.182,12.182 0,1 1,24.364 0a12.182,12.182 0,1 1,-24.364 0"
android:fillColor="#fff"/>
</vector>