Skip to content

Commit

Permalink
Add the possibility of changing the font size on reader mode
Browse files Browse the repository at this point in the history
  • Loading branch information
prof18 committed Aug 30, 2024
1 parent bb9136f commit bd9a334
Show file tree
Hide file tree
Showing 25 changed files with 507 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import com.prof18.feedflow.shared.domain.feedsync.FeedSyncRepository
import com.prof18.feedflow.shared.ui.utils.coilImageLoader
import com.prof18.feedflow.shared.utils.enableKmpCrashlytics
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.androidx.workmanager.koin.workManagerFactory
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

class FeedFlowApp : Application() {
Expand Down Expand Up @@ -62,6 +62,7 @@ class FeedFlowApp : Application() {
viewModel {
ReaderModeViewModel(
readerModeExtractor = get(),
settingsRepository = get(),
)
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,17 @@ class MainActivity : ComponentActivity() {

composable(Screen.ReaderMode.name) {
val readerModeState by readerModeViewModel.readerModeState.collectAsStateWithLifecycle()
val fontSizeState by readerModeViewModel.readerFontSizeState.collectAsStateWithLifecycle()

ReaderModeScreen(
readerModeState = readerModeState,
fontSize = fontSizeState,
navigateBack = {
navController.popBackStack()
},
onUpdateFontSize = { newFontSize ->
readerModeViewModel.updateFontSize(newFontSize)
},
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import org.koin.compose.koinInject
@Composable
internal fun ReaderModeScreen(
readerModeState: ReaderModeState,
fontSize: Int,
onUpdateFontSize: (Int) -> Unit,
navigateBack: () -> Unit,
) {
val browserManager = koinInject<BrowserManager>()
Expand All @@ -38,13 +40,23 @@ internal fun ReaderModeScreen(

ReaderModeContent(
readerModeState = readerModeState,
fontSize = fontSize,
navigateBack = {
if (navigator.canGoBack) {
navigator.navigateBack()
} else {
navigateBack()
}
},
onFontSizeChange = { newFontSize ->
navigator.evaluateJavaScript(
"""
document.getElementById("container").style.fontSize = "$newFontSize" + "px";
document.getElementById("container").style.lineHeight = "1.5em";
""".trimIndent(),
)
onUpdateFontSize(newFontSize)
},
openInBrowser = { url ->
browserManager.openUrlWithFavoriteBrowser(url, context)
},
Expand Down Expand Up @@ -93,6 +105,7 @@ private fun ReaderMode(
colors = colors,
content = readerModeState.readerModeData.content,
title = readerModeState.readerModeData.title,
fontSize = readerModeState.readerModeData.fontSize,
)

val jsBridge = rememberWebViewJsBridge()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@ import androidx.lifecycle.viewModelScope
import com.prof18.feedflow.core.model.FeedItemUrlInfo
import com.prof18.feedflow.core.model.ReaderModeState
import com.prof18.feedflow.shared.domain.ReaderModeExtractor
import com.prof18.feedflow.shared.domain.settings.SettingsRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

class ReaderModeViewModel internal constructor(
private val readerModeExtractor: ReaderModeExtractor,
private val settingsRepository: SettingsRepository,
) : ViewModel() {

private val readerModeMutableState: MutableStateFlow<ReaderModeState> = MutableStateFlow(
ReaderModeState.Loading,
)
val readerModeState = readerModeMutableState.asStateFlow()

private val readerFontSizeMutableState: MutableStateFlow<Int> = MutableStateFlow(
settingsRepository.getReaderModeFontSize(),
)
val readerFontSizeState = readerFontSizeMutableState.asStateFlow()

fun getReaderModeHtml(urlInfo: FeedItemUrlInfo) {
viewModelScope.launch {
readerModeMutableState.value = ReaderModeState.Loading
Expand All @@ -29,4 +37,9 @@ class ReaderModeViewModel internal constructor(
}
}
}

fun updateFontSize(newFontSize: Int) {
settingsRepository.setReaderModeFontSize(newFontSize)
readerFontSizeMutableState.update { newFontSize }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import FeedFlowTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
Expand Down Expand Up @@ -35,7 +36,7 @@ fun LicensesScreen(
},
) {
Icon(
imageVector = Icons.Default.ArrowBack,
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = null,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ data class ReaderModeData(
val title: String?,
val content: String,
val url: String,
val fontSize: Int,
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.prof18.feedflow.shared.di.initKoinDesktop
import com.prof18.feedflow.shared.ui.utils.coilImageLoader
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter
import org.koin.core.Koin
import org.koin.core.module.dsl.factoryOf
import org.koin.dsl.module

object DI {
Expand Down Expand Up @@ -41,12 +42,7 @@ object DI {
)
}

factory {
ReaderModeViewModel(
readerModeExtractor = get(),
markdownToHtmlConverter = get(),
)
}
factoryOf(::ReaderModeViewModel)

factory {
BrowserManager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ internal data class ReaderModeScreen(
override fun Content() {
val readerModeViewModel = desktopViewModel { DI.koin.get<ReaderModeViewModel>() }
val state by readerModeViewModel.readerModeState.collectAsState()
val fontSize by readerModeViewModel.readerFontSizeState.collectAsState()
val navigator = LocalNavigator.currentOrThrow

LaunchedEffect(feedItemUrlInfo) {
Expand Down Expand Up @@ -74,13 +75,19 @@ internal data class ReaderModeScreen(
)
}
},
fontSize = fontSize,
onFontSizeChange = {


readerModeViewModel.updateFontSize(it)
},
readerModeSuccessView = { contentPadding, successState ->
Column(
modifier = Modifier
.padding(contentPadding)
.verticalScroll(rememberScrollState()),

) {
) {
Text(
modifier = Modifier
.fillMaxWidth()
Expand All @@ -102,7 +109,8 @@ internal data class ReaderModeScreen(
h5 = MaterialTheme.typography.titleMedium,
h6 = MaterialTheme.typography.titleMedium,
paragraph = MaterialTheme.typography.bodyLarge.copy(
lineHeight = 26.sp,
lineHeight = (fontSize + 15).sp,
fontSize = fontSize.sp,
),
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,28 @@ import com.prof18.feedflow.core.model.FeedItemUrlInfo
import com.prof18.feedflow.core.model.ReaderModeState
import com.prof18.feedflow.shared.domain.ReaderModeExtractor
import com.prof18.feedflow.shared.domain.getReaderModeStyledHtml
import com.prof18.feedflow.shared.domain.settings.SettingsRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

class ReaderModeViewModel internal constructor(
private val readerModeExtractor: ReaderModeExtractor,
private val markdownToHtmlConverter: MarkdownToHtmlConverter,
private val settingsRepository: SettingsRepository,
) : ViewModel() {

private val readerModeMutableState: MutableStateFlow<ReaderModeState> = MutableStateFlow(
ReaderModeState.Loading,
)
val readerModeState = readerModeMutableState.asStateFlow()

private val readerFontSizeMutableState: MutableStateFlow<Int> = MutableStateFlow(
settingsRepository.getReaderModeFontSize(),
)
val readerFontSizeState = readerFontSizeMutableState.asStateFlow()

fun getReaderModeHtml(urlInfo: FeedItemUrlInfo) {
viewModelScope.launch {
readerModeMutableState.value = ReaderModeState.Loading
Expand All @@ -35,6 +43,7 @@ class ReaderModeViewModel internal constructor(
colors = null,
content = readerModeData.content,
title = title,
fontSize = settingsRepository.getReaderModeFontSize(),
)
val markdown = markdownToHtmlConverter.convertToMarkdown(html)
readerModeMutableState.value = ReaderModeState.Success(
Expand All @@ -47,4 +56,9 @@ class ReaderModeViewModel internal constructor(
}
}
}

fun updateFontSize(newFontSize: Int) {
settingsRepository.setReaderModeFontSize(newFontSize)
readerFontSizeMutableState.update { newFontSize }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ expect fun String.format(vararg args: Any): String

@Suppress("UnusedPrivateProperty")
// This is a trick to be sure that KSP re-generates the strings when there's no code updates
private const val StringsVersion = 45
private const val StringsVersion = 46
1 change: 1 addition & 0 deletions i18n/src/commonMain/resources/locale/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,5 @@
<string name="icloud_sync_success">Your iCloud account is successfully connected</string>
<string name="no_icloud_sync_yet">Data are not synced yet with iCloud. Click the backup button to trigger a sync</string>
<string name="settings_hide_duplicated_title_from_desc">Hide title from article description</string>
<string name="reader_mode_font_size">Font Size</string>
</resources>
41 changes: 24 additions & 17 deletions iosApp/FeedFlow.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
/* Begin PBXBuildFile section */
058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; };
058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; };
138093682C80B47B00E904FF /* Reeeed in Frameworks */ = {isa = PBXBuildFile; productRef = 138093672C80B47B00E904FF /* Reeeed */; };
1380936E2C826C9C00E904FF /* Reeeed in Frameworks */ = {isa = PBXBuildFile; productRef = 1380936D2C826C9C00E904FF /* Reeeed */; };
139C09DC2C668E3700A5E3E8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = CC4B803F29D9A31E0004A0AB /* Collections */; };
139C09DD2C668E3700A5E3E8 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = CC4B804129D9A31E0004A0AB /* OrderedCollections */; };
13B651162C6007C70015D0A1 /* VMStoreOwner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B651152C6007C70015D0A1 /* VMStoreOwner.swift */; };
Expand Down Expand Up @@ -50,7 +52,6 @@
CC2DC9322C5577E800BFD2B9 /* AddAccountScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2DC9312C5577E800BFD2B9 /* AddAccountScreen.swift */; };
CC2DC9372C5595D400BFD2B9 /* ICloudSyncScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2DC9362C5595D400BFD2B9 /* ICloudSyncScreen.swift */; };
CC2DC9392C564FF600BFD2B9 /* ICloudSyncScreenContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2DC9382C564FF600BFD2B9 /* ICloudSyncScreenContent.swift */; };
CC3F46E32BD1C435005DC259 /* Reeeed in Frameworks */ = {isa = PBXBuildFile; productRef = CC3F46E22BD1C435005DC259 /* Reeeed */; };
CC4B803B29D98BB20004A0AB /* Nuke in Frameworks */ = {isa = PBXBuildFile; productRef = CC4B803A29D98BB20004A0AB /* Nuke */; };
CC4B803D29D98BB20004A0AB /* NukeUI in Frameworks */ = {isa = PBXBuildFile; productRef = CC4B803C29D98BB20004A0AB /* NukeUI */; };
CC4B804429DA03460004A0AB /* HomeListIndexHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4B804329DA03460004A0AB /* HomeListIndexHolder.swift */; };
Expand Down Expand Up @@ -203,9 +204,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
138093682C80B47B00E904FF /* Reeeed in Frameworks */,
139C09DD2C668E3700A5E3E8 /* OrderedCollections in Frameworks */,
139C09DC2C668E3700A5E3E8 /* Collections in Frameworks */,
CC3F46E32BD1C435005DC259 /* Reeeed in Frameworks */,
1380936E2C826C9C00E904FF /* Reeeed in Frameworks */,
CC4B803D29D98BB20004A0AB /* NukeUI in Frameworks */,
CC23293C29D85208005D0E06 /* SwiftSoup in Frameworks */,
CCEA11BE2A6D2BA600C661AC /* FirebaseCrashlytics in Frameworks */,
Expand Down Expand Up @@ -557,8 +559,9 @@
CC4B803F29D9A31E0004A0AB /* Collections */,
CC4B804129D9A31E0004A0AB /* OrderedCollections */,
CCEA11BD2A6D2BA600C661AC /* FirebaseCrashlytics */,
CC3F46E22BD1C435005DC259 /* Reeeed */,
CC0799412C29B74600067E06 /* SwiftyDropbox */,
138093672C80B47B00E904FF /* Reeeed */,
1380936D2C826C9C00E904FF /* Reeeed */,
);
productName = iosApp;
productReference = 7555FF7B242A565900829871 /* FeedFlow.app */;
Expand Down Expand Up @@ -608,8 +611,8 @@
CC4B803929D98BB20004A0AB /* XCRemoteSwiftPackageReference "Nuke" */,
CC4B803E29D9A31E0004A0AB /* XCRemoteSwiftPackageReference "swift-collections" */,
CCEA11BC2A6D2BA600C661AC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
CC3F46E12BD1C435005DC259 /* XCRemoteSwiftPackageReference "reeeed" */,
CC0799402C29B74600067E06 /* XCRemoteSwiftPackageReference "SwiftyDropbox" */,
1380936C2C826C9C00E904FF /* XCRemoteSwiftPackageReference "reeeed" */,
);
productRefGroup = 7555FF7C242A565900829871 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -1071,6 +1074,14 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
1380936C2C826C9C00E904FF /* XCRemoteSwiftPackageReference "reeeed" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/prof18/reeeed";
requirement = {
branch = main;
kind = branch;
};
};
CC0799402C29B74600067E06 /* XCRemoteSwiftPackageReference "SwiftyDropbox" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/dropbox/SwiftyDropbox.git";
Expand All @@ -1087,14 +1098,6 @@
version = 2.7.2;
};
};
CC3F46E12BD1C435005DC259 /* XCRemoteSwiftPackageReference "reeeed" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/prof18/reeeed";
requirement = {
branch = main;
kind = branch;
};
};
CC4B803929D98BB20004A0AB /* XCRemoteSwiftPackageReference "Nuke" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/kean/Nuke";
Expand Down Expand Up @@ -1122,6 +1125,15 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
138093672C80B47B00E904FF /* Reeeed */ = {
isa = XCSwiftPackageProductDependency;
productName = Reeeed;
};
1380936D2C826C9C00E904FF /* Reeeed */ = {
isa = XCSwiftPackageProductDependency;
package = 1380936C2C826C9C00E904FF /* XCRemoteSwiftPackageReference "reeeed" */;
productName = Reeeed;
};
CC0799412C29B74600067E06 /* SwiftyDropbox */ = {
isa = XCSwiftPackageProductDependency;
package = CC0799402C29B74600067E06 /* XCRemoteSwiftPackageReference "SwiftyDropbox" */;
Expand All @@ -1132,11 +1144,6 @@
package = CC23293A29D85208005D0E06 /* XCRemoteSwiftPackageReference "SwiftSoup" */;
productName = SwiftSoup;
};
CC3F46E22BD1C435005DC259 /* Reeeed */ = {
isa = XCSwiftPackageProductDependency;
package = CC3F46E12BD1C435005DC259 /* XCRemoteSwiftPackageReference "reeeed" */;
productName = Reeeed;
};
CC4B803A29D98BB20004A0AB /* Nuke */ = {
isa = XCSwiftPackageProductDependency;
package = CC4B803929D98BB20004A0AB /* XCRemoteSwiftPackageReference "Nuke" */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "dfe837f41ec6117df1db5fb2e4c398f72de98bbe1a2691621f938eae93b09eba",
"originHash" : "78f2fd386d6da8935ac36d6e045d968acf274645af5783c5acb8cf13d29234d1",
"pins" : [
{
"identity" : "abseil-cpp-binary",
Expand Down Expand Up @@ -133,7 +133,7 @@
"location" : "https://github.com/prof18/reeeed",
"state" : {
"branch" : "main",
"revision" : "59bf8f2642fc578040e26d05054373953850e621"
"revision" : "95d3c38057aeeea87cb72c58c5bd7e31ed5b5f94"
}
},
{
Expand Down
Loading

0 comments on commit bd9a334

Please sign in to comment.