diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/MainActivity.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/MainActivity.kt index 8a287aee..defbd7dd 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/MainActivity.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/MainActivity.kt @@ -9,6 +9,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import dagger.hilt.android.AndroidEntryPoint import dev.msfjarvis.claw.android.ui.LobstersApp +import dev.msfjarvis.claw.common.comments.HTMLConverter import dev.msfjarvis.claw.common.urllauncher.UrlLauncher import javax.inject.Inject @@ -16,6 +17,7 @@ import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject lateinit var urlLauncher: UrlLauncher + @Inject lateinit var htmlConverter: HTMLConverter private var webUri: String? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -25,6 +27,7 @@ class MainActivity : ComponentActivity() { setContent { LobstersApp( urlLauncher = urlLauncher, + htmlConverter = htmlConverter, ) { url -> webUri = url } } } diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/injection/HTMLConverterModule.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/injection/HTMLConverterModule.kt new file mode 100644 index 00000000..55a90cb4 --- /dev/null +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/injection/HTMLConverterModule.kt @@ -0,0 +1,23 @@ +package dev.msfjarvis.claw.android.injection + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import dev.msfjarvis.claw.common.comments.HTMLConverter +import io.github.furstenheim.CopyDown + +@Module +@InstallIn(SingletonComponent::class) +object HTMLConverterModule { + + @Provides + fun provideHTMLConverter() = + object : HTMLConverter { + private val copydown = CopyDown() + + override fun convertHTMLToMarkdown(html: String): String { + return copydown.convert(html) + } + } +} diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt index 248232e4..ac3d035b 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt @@ -31,11 +31,12 @@ import com.google.accompanist.insets.statusBarsPadding import com.google.accompanist.systemuicontroller.rememberSystemUiController import dev.msfjarvis.claw.android.viewmodel.ClawViewModel import dev.msfjarvis.claw.common.comments.CommentsPage +import dev.msfjarvis.claw.common.comments.HTMLConverter +import dev.msfjarvis.claw.common.comments.LocalHTMLConverter import dev.msfjarvis.claw.common.posts.PostActions import dev.msfjarvis.claw.common.theme.LobstersTheme import dev.msfjarvis.claw.common.urllauncher.UrlLauncher import dev.msfjarvis.claw.database.local.SavedPost -import io.github.furstenheim.CopyDown private const val ScrollDelta = 50 @@ -44,9 +45,9 @@ private const val ScrollDelta = 50 fun LobstersApp( viewModel: ClawViewModel = viewModel(), urlLauncher: UrlLauncher, + htmlConverter: HTMLConverter, setWebUri: (String) -> Unit, ) { - val copydown = remember { CopyDown() } val systemUiController = rememberSystemUiController() val scaffoldState = rememberScaffoldState() val listState = rememberLazyListState() @@ -93,7 +94,11 @@ fun LobstersApp( } LobstersTheme( darkTheme = isSystemInDarkTheme(), - providedValues = arrayOf(LocalUriHandler provides urlLauncher), + providedValues = + arrayOf( + LocalUriHandler provides urlLauncher, + LocalHTMLConverter provides htmlConverter, + ), ) { ProvideWindowInsets { val useDarkIcons = MaterialTheme.colors.isLight @@ -134,7 +139,6 @@ fun LobstersApp( CommentsPage( postId = postId, getDetails = viewModel::getPostComments, - htmlToMarkdown = { source -> copydown.convert(source) }, paddingValues = paddingValues, ) } diff --git a/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt b/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt index c21f5e5b..2de30f68 100644 --- a/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt +++ b/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt @@ -23,8 +23,8 @@ import dev.msfjarvis.claw.model.LobstersPostDetails @Composable fun CommentsHeader( postDetails: LobstersPostDetails, - htmlToMarkdown: (html: String) -> String, ) { + val htmlConverter = LocalHTMLConverter.current Surface { Column( modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp).fillMaxWidth(), @@ -33,7 +33,7 @@ fun CommentsHeader( PostDetails( post = postDetails.toDbModel(), ) - MaterialRichText { Markdown(htmlToMarkdown(postDetails.description)) } + MaterialRichText { Markdown(htmlConverter.convertHTMLToMarkdown(postDetails.description)) } } } } @@ -41,8 +41,8 @@ fun CommentsHeader( @Composable fun CommentEntry( comment: Comment, - htmlToMarkdown: (html: String) -> String, ) { + val htmlConverter = LocalHTMLConverter.current Divider(color = Color.Gray.copy(0.4f)) Row(modifier = Modifier.wrapContentHeight()) { Column(modifier = Modifier.padding(start = 12.dp, end = 8.dp, top = 4.dp, bottom = 4.dp)) { @@ -52,7 +52,7 @@ fun CommentEntry( contentDescription = "User avatar for ${comment.user.username}", ) MaterialRichText(modifier = Modifier.padding(top = 8.dp)) { - Markdown(htmlToMarkdown(comment.comment)) + Markdown(htmlConverter.convertHTMLToMarkdown(comment.comment)) } } } diff --git a/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/Comments.kt b/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/Comments.kt index fea7b875..8240eecf 100644 --- a/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/Comments.kt +++ b/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/Comments.kt @@ -28,15 +28,14 @@ import dev.msfjarvis.lobsters.ui.comments.NetworkState @Composable private fun CommentsPageInternal( details: LobstersPostDetails, - htmlToMarkdown: (html: String) -> String, bottomPadding: Dp, ) { LazyColumn(Modifier.padding(bottom = bottomPadding)) { - item { CommentsHeader(postDetails = details, htmlToMarkdown = htmlToMarkdown) } + item { CommentsHeader(postDetails = details) } item { Spacer(modifier = Modifier.height(8.dp)) } - items(details.comments) { item -> CommentEntry(item, htmlToMarkdown) } + items(details.comments) { item -> CommentEntry(item) } item { Divider(color = Color.Gray.copy(0.4f)) } } @@ -47,7 +46,6 @@ private fun CommentsPageInternal( fun CommentsPage( postId: String, getDetails: suspend (String) -> LobstersPostDetails, - htmlToMarkdown: (html: String) -> String, paddingValues: PaddingValues, ) { var postDetails: NetworkState by remember { mutableStateOf(NetworkState.Loading) } @@ -58,7 +56,6 @@ fun CommentsPage( is NetworkState.Success<*> -> { CommentsPageInternal( (postDetails as NetworkState.Success).data, - htmlToMarkdown, paddingValues.calculateBottomPadding(), ) } diff --git a/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/HTMLConverter.kt b/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/HTMLConverter.kt new file mode 100644 index 00000000..e1b5ceb5 --- /dev/null +++ b/common/src/commonMain/kotlin/dev/msfjarvis/claw/common/comments/HTMLConverter.kt @@ -0,0 +1,10 @@ +package dev.msfjarvis.claw.common.comments + +import androidx.compose.runtime.staticCompositionLocalOf + +/** Defines a contract to convert strings of HTML to Markdown. */ +fun interface HTMLConverter { + fun convertHTMLToMarkdown(html: String): String +} + +val LocalHTMLConverter = staticCompositionLocalOf { error("To be provided") }