Skip to content

Commit

Permalink
[feature] Support resizing font size on reading page
Browse files Browse the repository at this point in the history
  • Loading branch information
SkyD666 committed Sep 3, 2024
1 parent 206ba28 commit 7a2b093
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 6 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ android {
minSdk = 24
targetSdk = 35
versionCode = 24
versionName = "2.1-alpha29"
versionName = "2.1-alpha30"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/skyd/anivu/ext/PreferenceExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.media.MediaShowThumbnailPreference
import com.skyd.anivu.model.preference.appearance.read.ReadTextSizePreference
import com.skyd.anivu.model.preference.appearance.search.SearchItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.search.SearchListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchTopBarTonalElevationPreference
Expand Down Expand Up @@ -76,6 +77,7 @@ fun Preferences.toSettings(): Settings {
articleItemMinWidth = ArticleItemMinWidthPreference.fromPreferences(this),
searchItemMinWidth = SearchItemMinWidthPreference.fromPreferences(this),
mediaShowThumbnail = MediaShowThumbnailPreference.fromPreferences(this),
readTextSize = ReadTextSizePreference.fromPreferences(this),

// Update
ignoreUpdateVersion = IgnoreUpdateVersionPreference.fromPreferences(this),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ data class ArticleBean(
@ColumnInfo(name = IS_FAVORITE_COLUMN)
var isFavorite: Boolean = false,
@ColumnInfo(name = CATEGORIES_COLUMN)
var catrgories: Categories? = null,
var categories: Categories? = null,
) : BaseBean, Parcelable {

@Parcelize
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/skyd/anivu/model/preference/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.media.MediaShowThumbnailPreference
import com.skyd.anivu.model.preference.appearance.read.ReadTextSizePreference
import com.skyd.anivu.model.preference.appearance.search.SearchItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.search.SearchListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchTopBarTonalElevationPreference
Expand Down Expand Up @@ -97,6 +98,7 @@ import com.skyd.anivu.ui.local.LocalProxyPassword
import com.skyd.anivu.ui.local.LocalProxyPort
import com.skyd.anivu.ui.local.LocalProxyType
import com.skyd.anivu.ui.local.LocalProxyUsername
import com.skyd.anivu.ui.local.LocalReadTextSize
import com.skyd.anivu.ui.local.LocalRssSyncBatteryNotLowConstraint
import com.skyd.anivu.ui.local.LocalRssSyncChargingConstraint
import com.skyd.anivu.ui.local.LocalRssSyncFrequency
Expand Down Expand Up @@ -134,6 +136,7 @@ data class Settings(
val articleItemMinWidth: Float = ArticleItemMinWidthPreference.default,
val searchItemMinWidth: Float = SearchItemMinWidthPreference.default,
val mediaShowThumbnail: Boolean = MediaShowThumbnailPreference.default,
val readTextSize: Float = ReadTextSizePreference.default,
// Update
val ignoreUpdateVersion: Long = IgnoreUpdateVersionPreference.default,
// Behavior
Expand Down Expand Up @@ -204,6 +207,7 @@ fun SettingsProvider(
LocalArticleItemMinWidth provides settings.articleItemMinWidth,
LocalSearchItemMinWidth provides settings.searchItemMinWidth,
LocalMediaShowThumbnail provides settings.mediaShowThumbnail,
LocalReadTextSize provides settings.readTextSize,
// Update
LocalIgnoreUpdateVersion provides settings.ignoreUpdateVersion,
// Behavior
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.skyd.anivu.model.preference.appearance.read

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.floatPreferencesKey
import com.skyd.anivu.base.BasePreference
import com.skyd.anivu.ext.dataStore
import com.skyd.anivu.ext.put
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

object ReadTextSizePreference : BasePreference<Float> {
private const val READ_TEXT_SIZE = "readTextSize"
override val default = 16f

val key = floatPreferencesKey(READ_TEXT_SIZE)

fun put(context: Context, scope: CoroutineScope, value: Float) {
scope.launch(Dispatchers.IO) {
context.dataStore.put(key, value)
}
}

override fun fromPreferences(preferences: Preferences): Float = preferences[key] ?: default
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class RssHelper @Inject constructor(
link = syndEntry.link,
guid = syndEntry.uri,
updateAt = Date().time,
catrgories = ArticleBean.Categories(
categories = ArticleBean.Categories(
categories = syndEntry.categories.map { it.name }.filter { it.isNotBlank() }
)
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.skyd.anivu.ui.component.html

import android.text.Html
import android.text.method.LinkMovementMethod
import android.util.TypedValue
import android.widget.TextView
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
Expand All @@ -13,6 +14,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
import androidx.core.text.parseAsHtml
Expand All @@ -23,11 +26,13 @@ fun HtmlText(
modifier: Modifier = Modifier,
htmlFlags: Int = FROM_HTML_MODE_LEGACY,
text: String,
fontSize: TextUnit = TextUnit.Unspecified,
onImageClick: ((String) -> Unit)? = null,
) {
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
val textColor = LocalContentColor.current
val textSize = with(LocalDensity.current) { fontSize.toPx() }
var componentWidth by remember { mutableIntStateOf(0) }
AndroidView(
modifier = modifier.onGloballyPositioned {
Expand All @@ -43,6 +48,7 @@ fun HtmlText(
}
},
update = { textView ->
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
textView.text = text.parseAsHtml(
htmlFlags,
imageGetter = ImageGetter(
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/skyd/anivu/ui/local/LocalValue.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.feed.FeedTopBarTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.media.MediaShowThumbnailPreference
import com.skyd.anivu.model.preference.appearance.read.ReadTextSizePreference
import com.skyd.anivu.model.preference.appearance.search.SearchItemMinWidthPreference
import com.skyd.anivu.model.preference.appearance.search.SearchListTonalElevationPreference
import com.skyd.anivu.model.preference.appearance.search.SearchTopBarTonalElevationPreference
Expand Down Expand Up @@ -90,6 +91,7 @@ val LocalShowArticlePullRefresh = compositionLocalOf { ShowArticlePullRefreshPre
val LocalArticleItemMinWidth = compositionLocalOf { ArticleItemMinWidthPreference.default }
val LocalSearchItemMinWidth = compositionLocalOf { SearchItemMinWidthPreference.default }
val LocalMediaShowThumbnail = compositionLocalOf { MediaShowThumbnailPreference.default }
val LocalReadTextSize = compositionLocalOf { ReadTextSizePreference.default }

// Update
val LocalIgnoreUpdateVersion = compositionLocalOf { IgnoreUpdateVersionPreference.default }
Expand Down
93 changes: 90 additions & 3 deletions app/src/main/java/com/skyd/anivu/ui/screen/read/ReadScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,29 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AttachFile
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.FormatSize
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.PlayCircleOutline
import androidx.compose.material.icons.outlined.Public
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Slider
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
Expand All @@ -61,6 +68,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
Expand All @@ -83,6 +91,7 @@ import com.skyd.anivu.model.bean.article.ArticleBean
import com.skyd.anivu.model.bean.article.ArticleWithEnclosureBean
import com.skyd.anivu.model.bean.article.EnclosureBean
import com.skyd.anivu.model.bean.article.RssMediaBean
import com.skyd.anivu.model.preference.appearance.read.ReadTextSizePreference
import com.skyd.anivu.ui.activity.PlayActivity
import com.skyd.anivu.ui.component.AniVuFloatingActionButton
import com.skyd.anivu.ui.component.AniVuIconButton
Expand All @@ -92,9 +101,11 @@ import com.skyd.anivu.ui.component.AniVuTopBarStyle
import com.skyd.anivu.ui.component.dialog.WaitingDialog
import com.skyd.anivu.ui.component.html.HtmlText
import com.skyd.anivu.ui.component.rememberAniVuImageLoader
import com.skyd.anivu.ui.local.LocalReadTextSize
import com.skyd.anivu.ui.screen.article.enclosure.EnclosureBottomSheet
import com.skyd.anivu.ui.screen.article.enclosure.getEnclosuresList
import com.skyd.anivu.util.ShareUtil
import java.util.Locale


const val READ_SCREEN_ROUTE = "readScreen"
Expand All @@ -117,7 +128,9 @@ fun ReadScreen(articleId: String, viewModel: ReadViewModel = hiltViewModel()) {
val context = LocalContext.current

val snackbarHostState = remember { SnackbarHostState() }
var openMoreMenu by rememberSaveable { mutableStateOf(false) }
var openEnclosureBottomSheet by rememberSaveable { mutableStateOf<List<Any>?>(null) }
var openReadTextSizeSliderDialog by rememberSaveable { mutableStateOf(false) }

val uiState by viewModel.viewState.collectAsStateWithLifecycle()
val dispatcher = viewModel.getDispatcher(startWith = ReadIntent.Init(articleId))
Expand All @@ -128,7 +141,7 @@ fun ReadScreen(articleId: String, viewModel: ReadViewModel = hiltViewModel()) {
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = {
AniVuTopBar(
style = AniVuTopBarStyle.CenterAligned,
style = AniVuTopBarStyle.Small,
scrollBehavior = scrollBehavior,
title = { Text(text = stringResource(R.string.read_screen_name)) },
actions = {
Expand Down Expand Up @@ -164,6 +177,16 @@ fun ReadScreen(articleId: String, viewModel: ReadViewModel = hiltViewModel()) {
imageVector = Icons.Outlined.Share,
contentDescription = stringResource(R.string.share),
)
AniVuIconButton(
onClick = { openMoreMenu = true },
imageVector = Icons.Outlined.MoreVert,
contentDescription = stringResource(R.string.more),
)
MoreMenu(
expanded = openMoreMenu,
onDismissRequest = { openMoreMenu = false },
onReadTextSizeClick = { openReadTextSizeSliderDialog = true },
)
}
)
},
Expand Down Expand Up @@ -243,6 +266,12 @@ fun ReadScreen(articleId: String, viewModel: ReadViewModel = hiltViewModel()) {
dataList = openEnclosureBottomSheet.orEmpty()
)
}

if (openReadTextSizeSliderDialog) {
ReadTextSizeSliderDialog(
onDismissRequest = { openReadTextSizeSliderDialog = false },
)
}
}
}

Expand Down Expand Up @@ -325,10 +354,11 @@ private fun Content(
text = article.article.content.ifNullOfBlank {
article.article.description.orEmpty()
},
fontSize = LocalReadTextSize.current.sp,
onImageClick = { imageUrl -> openImageSheet = imageUrl }
)
article.article.catrgories?.let { catrgories ->
CategoryArea(catrgories)
article.article.categories?.let { categories ->
CategoryArea(categories)
}

if (openImageSheet != null) {
Expand All @@ -342,6 +372,63 @@ private fun Content(
}
}

@Composable
private fun MoreMenu(
expanded: Boolean,
onDismissRequest: () -> Unit,
onReadTextSizeClick: () -> Unit,
) {
DropdownMenu(expanded = expanded, onDismissRequest = onDismissRequest) {
DropdownMenuItem(
text = { Text(text = stringResource(R.string.read_screen_text_size)) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.FormatSize,
contentDescription = null,
)
},
onClick = {
onDismissRequest()
onReadTextSizeClick()
},
)
}
}

@Composable
private fun ReadTextSizeSliderDialog(
modifier: Modifier = Modifier,
onDismissRequest: () -> Unit,
) {
ModalBottomSheet(
onDismissRequest = onDismissRequest,
sheetState = rememberModalBottomSheetState()
) {
Column(
modifier = modifier.padding(bottom = 12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val textSize = LocalReadTextSize.current
Text(
modifier = Modifier.padding(start = 16.dp),
text = String.format(Locale.getDefault(), "%.2f Sp", textSize),
style = MaterialTheme.typography.titleMedium,
)
Spacer(modifier = Modifier.height(12.dp))
Slider(
modifier = Modifier.padding(horizontal = 16.dp),
valueRange = 12f..50f,
value = textSize,
onValueChange = {
ReadTextSizePreference.put(context = context, scope = scope, value = it)
},
)
}
}
}

@Composable
private fun RssMediaEpisode(modifier: Modifier = Modifier, rssMedia: RssMediaBean) {
val episode = rssMedia.episode
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
<string name="request_headers_screen_key">键</string>
<string name="request_headers_screen_value">值</string>
<string name="player_config_screen_show_progress_indicator">进度指示</string>
<string name="read_screen_text_size">文字大小</string>
<plurals name="feed_screen_read_all_result">
<item quantity="other">已读 %d 项</item>
</plurals>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@
<string name="request_headers_screen_key">Key</string>
<string name="request_headers_screen_value">Value</string>
<string name="player_config_screen_show_progress_indicator">Progress indicator</string>
<string name="read_screen_text_size">Text size</string>
<plurals name="feed_screen_read_all_result">
<item quantity="one">Read %d item</item>
<item quantity="other">Read %d items</item>
Expand Down

0 comments on commit 7a2b093

Please sign in to comment.