Skip to content

Commit

Permalink
feat(Changelogs): overall improvement (ReVanced#1429)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ushie authored Nov 3, 2023
1 parent 3c57762 commit 1a83315
Show file tree
Hide file tree
Showing 17 changed files with 336 additions and 272 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,6 @@ dependencies {
implementation(libs.ktor.content.negotiation)
implementation(libs.ktor.serialization)

// Markdown to HTML
implementation(libs.markdown)
// Markdown
implementation(libs.markdown.renderer)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ val viewModelModule = module {
viewModelOf(::VersionSelectorViewModel)
viewModelOf(::InstallerViewModel)
viewModelOf(::UpdateProgressViewModel)
viewModelOf(::ManagerUpdateChangelogViewModel)
viewModelOf(::ChangelogsViewModel)
viewModelOf(::ImportExportViewModel)
viewModelOf(::ContributorViewModel)
viewModelOf(::DownloadsViewModel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class APIPatchBundle(name: String, id: Int, directory: File, endpoint: String) :
override suspend fun getLatestInfo() = coroutineScope {
fun getAssetAsync(repo: String, mime: String) = async(Dispatchers.IO) {
api
.getRelease(repo)
.getLatestRelease(repo)
.getOrThrow()
.let {
BundleAsset(it.metadata.tag, it.findAssetByType(mime).downloadUrl)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package app.revanced.manager.network.api

import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.network.dto.Asset
import app.revanced.manager.network.dto.ReVancedLatestRelease
import app.revanced.manager.network.dto.ReVancedRelease
import app.revanced.manager.network.service.ReVancedService
import app.revanced.manager.network.utils.getOrThrow
import app.revanced.manager.network.utils.transform

class ReVancedAPI(
Expand All @@ -16,7 +13,9 @@ class ReVancedAPI(

suspend fun getContributors() = service.getContributors(apiUrl()).transform { it.repositories }

suspend fun getRelease(name: String) = service.getRelease(apiUrl(), name).transform { it.release }
suspend fun getLatestRelease(name: String) = service.getLatestRelease(apiUrl(), name).transform { it.release }

suspend fun getReleases(name: String) = service.getReleases(apiUrl(), name).transform { it.releases }

companion object Extensions {
fun ReVancedRelease.findAssetByType(mime: String) = assets.singleOrNull { it.contentType == mime } ?: throw MissingAssetException(mime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ data class ReVancedLatestRelease(
val release: ReVancedRelease,
)

@Serializable
data class ReVancedReleases(
val releases: List<ReVancedRelease>
)

@Serializable
data class ReVancedRelease(
val metadata: ReVancedReleaseMeta,
Expand All @@ -28,6 +33,7 @@ data class ReVancedReleaseMeta(
@Serializable
data class Asset(
val name: String,
@SerialName("download_count") val downloadCount: Int,
@SerialName("browser_download_url") val downloadUrl: String,
@SerialName("content_type") val contentType: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app.revanced.manager.network.service

import app.revanced.manager.network.dto.ReVancedLatestRelease
import app.revanced.manager.network.dto.ReVancedGitRepositories
import app.revanced.manager.network.dto.ReVancedReleases
import app.revanced.manager.network.utils.APIResponse
import io.ktor.client.request.*
import kotlinx.coroutines.Dispatchers
Expand All @@ -10,13 +11,20 @@ import kotlinx.coroutines.withContext
class ReVancedService(
private val client: HttpService,
) {
suspend fun getRelease(api: String, repo: String): APIResponse<ReVancedLatestRelease> =
suspend fun getLatestRelease(api: String, repo: String): APIResponse<ReVancedLatestRelease> =
withContext(Dispatchers.IO) {
client.request {
url("$api/v2/$repo/releases/latest")
}
}

suspend fun getReleases(api: String, repo: String): APIResponse<ReVancedReleases> =
withContext(Dispatchers.IO) {
client.request {
url("$api/v2/$repo/releases")
}
}

suspend fun getContributors(api: String): APIResponse<ReVancedGitRepositories> =
withContext(Dispatchers.IO) {
client.request {
Expand Down
123 changes: 21 additions & 102 deletions app/src/main/java/app/revanced/manager/ui/component/Markdown.kt
Original file line number Diff line number Diff line change
@@ -1,113 +1,32 @@
package app.revanced.manager.ui.component

import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import androidx.compose.foundation.background
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import app.revanced.manager.util.hexCode
import app.revanced.manager.util.openUrl
import com.google.accompanist.web.AccompanistWebViewClient
import com.google.accompanist.web.WebView
import com.google.accompanist.web.rememberWebViewStateWithHTMLData
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.mikepenz.markdown.compose.Markdown
import com.mikepenz.markdown.model.markdownColor
import com.mikepenz.markdown.model.markdownTypography

@Composable
@SuppressLint("ClickableViewAccessibility")
fun Markdown(
text: String,
modifier: Modifier = Modifier
text: String
) {
val ctx = LocalContext.current
val state = rememberWebViewStateWithHTMLData(data = generateMdHtml(source = text))
val client = remember {
object : AccompanistWebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
if (request != null) ctx.openUrl(request.url.toString())
return true
}
}
}
val markdown = text.trimIndent()

WebView(
state,
modifier = Modifier
.background(Color.Transparent)
.then(modifier),
client = client,
captureBackPresses = false,
onCreated = {
it.setBackgroundColor(android.graphics.Color.TRANSPARENT)
it.isVerticalScrollBarEnabled = false
it.isHorizontalScrollBarEnabled = false
it.setOnTouchListener { _, event -> event.action == MotionEvent.ACTION_MOVE }
it.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
Markdown(
content = markdown,
colors = markdownColor(
text = MaterialTheme.colorScheme.onSurfaceVariant,
codeBackground = MaterialTheme.colorScheme.secondaryContainer,
codeText = MaterialTheme.colorScheme.onSecondaryContainer
),
typography = markdownTypography(
h1 = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.Bold),
h2 = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.Bold),
h3 = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
text = MaterialTheme.typography.bodyMedium,
list = MaterialTheme.typography.bodyMedium
)
)
}

@Composable
fun generateMdHtml(
source: String,
wrap: Boolean = false,
headingColor: Color = MaterialTheme.colorScheme.onSurface,
textColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
linkColor: Color = MaterialTheme.colorScheme.primary
) = remember(source, wrap, headingColor, textColor, linkColor) {
"""<html>
<head>
<meta charset="utf-8" />
<title>Markdown</title>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
<style>
body {
color: #${textColor.hexCode};
}
a {
color: #${linkColor.hexCode}!important;
}
a.anchor {
display: none;
}
.highlight pre, pre {
word-wrap: ${if (wrap) "break-word" else "normal"};
white-space: ${if (wrap) "pre-wrap" else "pre"};
}
h2 {
color: #${headingColor.hexCode};
font-size: 18px;
font-weight: 500;
line-height: 24px;
letter-spacing: 0.15px;
}
ul {
margin-left: 0px;
padding-left: 18px;
}
li {
margin-left: 2px;
}
::marker {
font-size: 16px;
margin-right: 8px;
color: #${textColor.hexCode};
}
</style>
</head>
<body>
$source
</body>
</html>"""
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ sealed interface SettingsDestination : Parcelable {
object UpdateProgress : SettingsDestination

@Parcelize
object UpdateChangelog : SettingsDestination
object Changelogs : SettingsDestination

@Parcelize
object Contributors: SettingsDestination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.NotificationCard
import app.revanced.manager.ui.destination.SettingsDestination
import app.revanced.manager.ui.screen.settings.*
import app.revanced.manager.ui.screen.settings.update.ManagerUpdateChangelog
import app.revanced.manager.ui.screen.settings.update.ChangelogsScreen
import app.revanced.manager.ui.screen.settings.update.UpdateProgressScreen
import app.revanced.manager.ui.screen.settings.update.UpdatesSettingsScreen
import app.revanced.manager.ui.viewmodel.SettingsViewModel
Expand Down Expand Up @@ -102,7 +102,7 @@ fun SettingsScreen(

is SettingsDestination.Updates -> UpdatesSettingsScreen(
onBackClick = { navController.pop() },
onChangelogClick = { navController.navigate(SettingsDestination.UpdateChangelog) },
onChangelogClick = { navController.navigate(SettingsDestination.Changelogs) },
onUpdateClick = { navController.navigate(SettingsDestination.UpdateProgress) }
)

Expand All @@ -124,7 +124,7 @@ fun SettingsScreen(
onBackClick = { navController.pop() },
)

is SettingsDestination.UpdateChangelog -> ManagerUpdateChangelog(
is SettingsDestination.Changelogs -> ChangelogsScreen(
onBackClick = { navController.pop() },
)

Expand Down
Loading

0 comments on commit 1a83315

Please sign in to comment.