From c7e7cd9c1ab337b9280729cd5e65c113105280e8 Mon Sep 17 00:00:00 2001 From: Benjamin Halko Date: Thu, 21 Sep 2023 15:56:36 -0700 Subject: [PATCH 01/29] feat: add social links --- app/build.gradle.kts | 3 ++ .../ui/screen/settings/AboutSettingsScreen.kt | 50 ++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0e7ea14e77..08a8da0d42 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -161,4 +161,7 @@ dependencies { // Markdown to HTML implementation(libs.markdown) + + // Icons + implementation("br.com.devsrsouza.compose.icons:font-awesome:1.1.0") } diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index b47e8fd519..3311a3ea45 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -5,9 +5,9 @@ import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Code import androidx.compose.material.icons.outlined.FavoriteBorder import androidx.compose.material.icons.outlined.Language import androidx.compose.material.icons.outlined.MailOutline @@ -25,6 +25,14 @@ import app.revanced.manager.ui.component.AppTopBar import app.revanced.manager.ui.destination.SettingsDestination import app.revanced.manager.util.openUrl import com.google.accompanist.drawablepainter.rememberDrawablePainter +import compose.icons.FontAwesomeIcons +import compose.icons.fontawesomeicons.Brands +import compose.icons.fontawesomeicons.brands.Discord +import compose.icons.fontawesomeicons.brands.Github +import compose.icons.fontawesomeicons.brands.Reddit +import compose.icons.fontawesomeicons.brands.Telegram +import compose.icons.fontawesomeicons.brands.Twitter +import compose.icons.fontawesomeicons.brands.Youtube import dev.olshevski.navigation.reimagined.NavController import dev.olshevski.navigation.reimagined.navigate @@ -48,7 +56,7 @@ fun AboutSettingsScreen( ) val outlinedButton = listOf( - Triple(Icons.Outlined.Code, stringResource(R.string.github), third = { + Triple(FontAwesomeIcons.Brands.Github, stringResource(R.string.github), third = { context.openUrl("https://revanced.app/github") }), Triple(Icons.Outlined.MailOutline, stringResource(R.string.contact), third = { @@ -56,6 +64,24 @@ fun AboutSettingsScreen( }), ) + val socialButtons = listOf( + Pair(FontAwesomeIcons.Brands.Discord) { + context.openUrl("https://revanced.app/discord") + }, + Pair(FontAwesomeIcons.Brands.Telegram) { + context.openUrl("https://t.me/app_revanced") + }, + Pair(FontAwesomeIcons.Brands.Reddit) { + context.openUrl("https://reddit.com/r/app_revanced") + }, + Pair(FontAwesomeIcons.Brands.Twitter) { + context.openUrl("https://twitter.com/@revancedapp") + }, + Pair(FontAwesomeIcons.Brands.Youtube) { + context.openUrl("https://youtube.com/@revancedapp") + }, + ) + val listItems = listOf( Triple(stringResource(R.string.submit_feedback), stringResource(R.string.submit_feedback_description), third = { /*TODO*/ }), @@ -126,6 +152,7 @@ fun AboutSettingsScreen( Button( onClick = onClick, modifier = Modifier.padding(end = 8.dp), + colors = ButtonDefaults.buttonColors( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSecondaryContainer @@ -152,6 +179,25 @@ fun AboutSettingsScreen( } } } + + Row( + modifier = Modifier.padding(top = 12.dp) + ) { + socialButtons.forEach { (icon, onClick) -> + IconButton( + onClick = onClick, + modifier = Modifier.padding(end = 8.dp), + ) { + Icon( + icon, + contentDescription = null, + modifier = Modifier + .size(28.dp), + tint = MaterialTheme.colorScheme.primary + ) + } + } + } } Box( From 9250df831af3fdd9311933be47125f0dbec567f2 Mon Sep 17 00:00:00 2001 From: Benjamin Halko Date: Thu, 21 Sep 2023 16:02:05 -0700 Subject: [PATCH 02/29] removed unused shape import --- .../revanced/manager/ui/screen/settings/AboutSettingsScreen.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index 3311a3ea45..feb5e9a28e 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.FavoriteBorder From b5b491ac22efc392ffd22b0724ea6863c704ce45 Mon Sep 17 00:00:00 2001 From: Benjamin <73490201+BenjaminHalko@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:18:15 -0700 Subject: [PATCH 03/29] update from twitter to x Co-authored-by: Pun Butrach --- .../revanced/manager/ui/screen/settings/AboutSettingsScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index feb5e9a28e..dd06e325e6 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -74,7 +74,7 @@ fun AboutSettingsScreen( context.openUrl("https://reddit.com/r/app_revanced") }, Pair(FontAwesomeIcons.Brands.Twitter) { - context.openUrl("https://twitter.com/@revancedapp") + context.openUrl("https://x.com/@revancedapp") }, Pair(FontAwesomeIcons.Brands.Youtube) { context.openUrl("https://youtube.com/@revancedapp") From 12da6eb893d95278368adc46218df40e5d5c4a43 Mon Sep 17 00:00:00 2001 From: Benjamin Halko Date: Thu, 28 Sep 2023 09:39:22 -0700 Subject: [PATCH 04/29] Switch to API --- .../revanced/manager/di/ViewModelModule.kt | 18 ++++++++- .../manager/network/api/ReVancedAPI.kt | 5 +-- .../manager/network/dto/ReVancedSocials.kt | 14 +++++++ .../network/service/ReVancedService.kt | 12 +++++- .../ui/screen/settings/AboutSettingsScreen.kt | 37 +++++++++---------- .../manager/ui/viewmodel/AboutViewModel.kt | 23 ++++++++++++ 6 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/viewmodel/AboutViewModel.kt diff --git a/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt b/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt index 5f12a2adaf..ef39bb408a 100644 --- a/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt +++ b/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt @@ -1,6 +1,21 @@ package app.revanced.manager.di -import app.revanced.manager.ui.viewmodel.* +import app.revanced.manager.ui.viewmodel.AboutViewModel +import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel +import app.revanced.manager.ui.viewmodel.AppInfoViewModel +import app.revanced.manager.ui.viewmodel.AppSelectorViewModel +import app.revanced.manager.ui.viewmodel.ContributorViewModel +import app.revanced.manager.ui.viewmodel.DashboardViewModel +import app.revanced.manager.ui.viewmodel.DownloadsViewModel +import app.revanced.manager.ui.viewmodel.ImportExportViewModel +import app.revanced.manager.ui.viewmodel.InstalledAppsViewModel +import app.revanced.manager.ui.viewmodel.InstallerViewModel +import app.revanced.manager.ui.viewmodel.MainViewModel +import app.revanced.manager.ui.viewmodel.ManagerUpdateChangelogViewModel +import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel +import app.revanced.manager.ui.viewmodel.SettingsViewModel +import app.revanced.manager.ui.viewmodel.UpdateProgressViewModel +import app.revanced.manager.ui.viewmodel.VersionSelectorViewModel import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.dsl.module @@ -16,6 +31,7 @@ val viewModelModule = module { viewModelOf(::UpdateProgressViewModel) viewModelOf(::ManagerUpdateChangelogViewModel) viewModelOf(::ImportExportViewModel) + viewModelOf(::AboutViewModel) viewModelOf(::ContributorViewModel) viewModelOf(::DownloadsViewModel) viewModelOf(::InstalledAppsViewModel) diff --git a/app/src/main/java/app/revanced/manager/network/api/ReVancedAPI.kt b/app/src/main/java/app/revanced/manager/network/api/ReVancedAPI.kt index 3367bcf257..cf9a44ef56 100644 --- a/app/src/main/java/app/revanced/manager/network/api/ReVancedAPI.kt +++ b/app/src/main/java/app/revanced/manager/network/api/ReVancedAPI.kt @@ -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( @@ -18,6 +15,8 @@ class ReVancedAPI( suspend fun getRelease(name: String) = service.getRelease(apiUrl(), name).transform { it.release } + suspend fun getSocials() = service.getSocials(apiUrl()).transform { it.socials } + companion object Extensions { fun ReVancedRelease.findAssetByType(mime: String) = assets.singleOrNull { it.contentType == mime } ?: throw MissingAssetException(mime) } diff --git a/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt b/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt new file mode 100644 index 0000000000..3464c72e90 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt @@ -0,0 +1,14 @@ +package app.revanced.manager.network.dto + +import kotlinx.serialization.Serializable + +@Serializable +data class ReVancedSocials( + val socials: List, +) + +@Serializable +data class ReVancedSocial( + val name: String, + val url: String, +) diff --git a/app/src/main/java/app/revanced/manager/network/service/ReVancedService.kt b/app/src/main/java/app/revanced/manager/network/service/ReVancedService.kt index b5681afef2..c145f45674 100644 --- a/app/src/main/java/app/revanced/manager/network/service/ReVancedService.kt +++ b/app/src/main/java/app/revanced/manager/network/service/ReVancedService.kt @@ -1,9 +1,10 @@ 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.ReVancedLatestRelease +import app.revanced.manager.network.dto.ReVancedSocials import app.revanced.manager.network.utils.APIResponse -import io.ktor.client.request.* +import io.ktor.client.request.url import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -23,4 +24,11 @@ class ReVancedService( url("$api/contributors") } } + + suspend fun getSocials(api: String): APIResponse = + withContext(Dispatchers.IO) { + client.request { + url("$api/v2/socials") + } + } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index dd06e325e6..52b948a7e6 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp import app.revanced.manager.BuildConfig import app.revanced.manager.R import app.revanced.manager.ui.component.AppTopBar -import app.revanced.manager.ui.destination.SettingsDestination +import app.revanced.manager.ui.viewmodel.AboutViewModel import app.revanced.manager.util.openUrl import com.google.accompanist.drawablepainter.rememberDrawablePainter import compose.icons.FontAwesomeIcons @@ -32,8 +32,7 @@ import compose.icons.fontawesomeicons.brands.Reddit import compose.icons.fontawesomeicons.brands.Telegram import compose.icons.fontawesomeicons.brands.Twitter import compose.icons.fontawesomeicons.brands.Youtube -import dev.olshevski.navigation.reimagined.NavController -import dev.olshevski.navigation.reimagined.navigate +import org.koin.androidx.compose.getViewModel @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -41,6 +40,7 @@ fun AboutSettingsScreen( onBackClick: () -> Unit, onContributorsClick: () -> Unit, onLicensesClick: () -> Unit, + viewModel: AboutViewModel = getViewModel() ) { val context = LocalContext.current val icon = rememberDrawablePainter(context.packageManager.getApplicationIcon(context.packageName)) @@ -63,24 +63,23 @@ fun AboutSettingsScreen( }), ) - val socialButtons = listOf( - Pair(FontAwesomeIcons.Brands.Discord) { - context.openUrl("https://revanced.app/discord") - }, - Pair(FontAwesomeIcons.Brands.Telegram) { - context.openUrl("https://t.me/app_revanced") - }, - Pair(FontAwesomeIcons.Brands.Reddit) { - context.openUrl("https://reddit.com/r/app_revanced") - }, - Pair(FontAwesomeIcons.Brands.Twitter) { - context.openUrl("https://x.com/@revancedapp") - }, - Pair(FontAwesomeIcons.Brands.Youtube) { - context.openUrl("https://youtube.com/@revancedapp") - }, + val socialIcons = mapOf( + "Contact" to Icons.Outlined.MailOutline, + "Discord" to FontAwesomeIcons.Brands.Discord, + "Donate" to Icons.Outlined.FavoriteBorder, + "GitHub" to FontAwesomeIcons.Brands.Github, + "Reddit" to FontAwesomeIcons.Brands.Reddit, + "Telegram" to FontAwesomeIcons.Brands.Telegram, + "Twitter" to FontAwesomeIcons.Brands.Twitter, + "YouTube" to FontAwesomeIcons.Brands.Youtube, ) + val socialButtons = viewModel.socials.map { + Pair(socialIcons[it.name] ?: Icons.Outlined.Language) { + context.openUrl(it.url) + } + } + val listItems = listOf( Triple(stringResource(R.string.submit_feedback), stringResource(R.string.submit_feedback_description), third = { /*TODO*/ }), diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/AboutViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/AboutViewModel.kt new file mode 100644 index 0000000000..52c215f72b --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/AboutViewModel.kt @@ -0,0 +1,23 @@ +package app.revanced.manager.ui.viewmodel + +import androidx.compose.runtime.mutableStateListOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import app.revanced.manager.network.api.ReVancedAPI +import app.revanced.manager.network.dto.ReVancedSocial +import app.revanced.manager.network.utils.getOrNull +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class AboutViewModel(private val reVancedAPI: ReVancedAPI) : ViewModel() { + val socials = mutableStateListOf() + + init { + viewModelScope.launch { + withContext(Dispatchers.IO) { reVancedAPI.getSocials().getOrNull() }?.let( + socials::addAll + ) + } + } +} \ No newline at end of file From f60275859d6c5d8c3ef7019e96131d8b7238e4c2 Mon Sep 17 00:00:00 2001 From: Benjamin Halko Date: Thu, 28 Sep 2023 09:40:39 -0700 Subject: [PATCH 05/29] reset ViewModelModule --- .../app/revanced/manager/di/ViewModelModule.kt | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt b/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt index ef39bb408a..bd0d2e10e5 100644 --- a/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt +++ b/app/src/main/java/app/revanced/manager/di/ViewModelModule.kt @@ -1,21 +1,6 @@ package app.revanced.manager.di -import app.revanced.manager.ui.viewmodel.AboutViewModel -import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel -import app.revanced.manager.ui.viewmodel.AppInfoViewModel -import app.revanced.manager.ui.viewmodel.AppSelectorViewModel -import app.revanced.manager.ui.viewmodel.ContributorViewModel -import app.revanced.manager.ui.viewmodel.DashboardViewModel -import app.revanced.manager.ui.viewmodel.DownloadsViewModel -import app.revanced.manager.ui.viewmodel.ImportExportViewModel -import app.revanced.manager.ui.viewmodel.InstalledAppsViewModel -import app.revanced.manager.ui.viewmodel.InstallerViewModel -import app.revanced.manager.ui.viewmodel.MainViewModel -import app.revanced.manager.ui.viewmodel.ManagerUpdateChangelogViewModel -import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel -import app.revanced.manager.ui.viewmodel.SettingsViewModel -import app.revanced.manager.ui.viewmodel.UpdateProgressViewModel -import app.revanced.manager.ui.viewmodel.VersionSelectorViewModel +import app.revanced.manager.ui.viewmodel.* import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.dsl.module From 5a915942e988a8fa1a7caa79b23aecf7201fe89a Mon Sep 17 00:00:00 2001 From: Benjamin <73490201+BenjaminHalko@users.noreply.github.com> Date: Thu, 5 Oct 2023 16:36:10 -0700 Subject: [PATCH 06/29] Update app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt Co-authored-by: oSumAtrIX --- .../revanced/manager/ui/screen/settings/AboutSettingsScreen.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index 52b948a7e6..05ba3906e1 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -71,6 +71,7 @@ fun AboutSettingsScreen( "Reddit" to FontAwesomeIcons.Brands.Reddit, "Telegram" to FontAwesomeIcons.Brands.Telegram, "Twitter" to FontAwesomeIcons.Brands.Twitter, + "X" to FontAwesomeIcons.Brands.Twitter, "YouTube" to FontAwesomeIcons.Brands.Youtube, ) From dfab47bf172e2428ed4c10b2975a8dc32fca177c Mon Sep 17 00:00:00 2001 From: Benjamin Halko Date: Wed, 1 Nov 2023 12:37:41 -0700 Subject: [PATCH 07/29] Use preferred param for socials --- .../manager/network/dto/ReVancedSocials.kt | 1 + .../ui/screen/settings/AboutSettingsScreen.kt | 68 +++++-------------- 2 files changed, 18 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt b/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt index 3464c72e90..f832dde6a4 100644 --- a/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt +++ b/app/src/main/java/app/revanced/manager/network/dto/ReVancedSocials.kt @@ -11,4 +11,5 @@ data class ReVancedSocials( data class ReVancedSocial( val name: String, val url: String, + val preferred: Boolean, ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index 04fda27e72..ed3eee13a6 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -22,7 +22,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import app.revanced.manager.BuildConfig import app.revanced.manager.R +import app.revanced.manager.network.dto.ReVancedSocial import app.revanced.manager.ui.component.AppTopBar +import app.revanced.manager.ui.viewmodel.AboutViewModel import app.revanced.manager.util.isDebuggable import app.revanced.manager.util.openUrl import com.google.accompanist.drawablepainter.rememberDrawablePainter @@ -36,7 +38,7 @@ import compose.icons.fontawesomeicons.brands.Twitter import compose.icons.fontawesomeicons.brands.Youtube import org.koin.androidx.compose.getViewModel -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun AboutSettingsScreen( onBackClick: () -> Unit, @@ -50,24 +52,6 @@ fun AboutSettingsScreen( AppCompatResources.getDrawable(context, R.drawable.ic_logo_ring) }) - val filledButton = listOf( - Triple(Icons.Outlined.FavoriteBorder, stringResource(R.string.donate)) { - context.openUrl("https://revanced.app/donate") - }, - Triple(Icons.Outlined.Language, stringResource(R.string.website), third = { - context.openUrl("https://revanced.app") - }), - ) - - val outlinedButton = listOf( - Triple(FontAwesomeIcons.Brands.Github, stringResource(R.string.github), third = { - context.openUrl("https://revanced.app/github") - }), - Triple(Icons.Outlined.MailOutline, stringResource(R.string.contact), third = { - context.openUrl("mailto:nosupport@revanced.app") - }), - ) - val socialIcons = mapOf( "Contact" to Icons.Outlined.MailOutline, "Discord" to FontAwesomeIcons.Brands.Discord, @@ -80,7 +64,13 @@ fun AboutSettingsScreen( "YouTube" to FontAwesomeIcons.Brands.Youtube, ) - val socialButtons = viewModel.socials.map { + val outlinedButton = viewModel.socials.filter(ReVancedSocial::preferred).map { + Triple(socialIcons[it.name] ?: Icons.Outlined.Language, it.name, third = { + context.openUrl(it.url) + }) + } + + val socialButtons = viewModel.socials.filterNot(ReVancedSocial::preferred).map { Pair(socialIcons[it.name] ?: Icons.Outlined.Language) { context.openUrl(it.url) } @@ -134,36 +124,11 @@ fun AboutSettingsScreen( text = stringResource(R.string.version) + " " + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")", style = MaterialTheme.typography.bodyMedium ) - Row( - modifier = Modifier.padding(top = 12.dp) - ) { - filledButton.forEach { (icon, text, onClick) -> - FilledTonalButton( - onClick = onClick, - modifier = Modifier.padding(end = 8.dp) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - icon, - contentDescription = null, - modifier = Modifier - .size(28.dp) - .padding(end = 8.dp), - tint = MaterialTheme.colorScheme.primary - ) - Text( - text, - style = MaterialTheme.typography.labelLarge, - ) - } - } - } - } - Row( - modifier = Modifier.padding(top = 12.dp) + FlowRow( + modifier = Modifier.padding(top = 12.dp), + horizontalArrangement = Arrangement.Center, + verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.Top), ) { outlinedButton.forEach { (icon, text, onClick) -> Button( @@ -197,8 +162,9 @@ fun AboutSettingsScreen( } } - Row( - modifier = Modifier.padding(top = 12.dp) + FlowRow( + modifier = Modifier.padding(top = 12.dp), + horizontalArrangement = Arrangement.Center ) { socialButtons.forEach { (icon, onClick) -> IconButton( From bef4964bd150025588806d38a9a541f2ed4b155a Mon Sep 17 00:00:00 2001 From: Benjamin Date: Fri, 3 Nov 2023 11:32:11 -0700 Subject: [PATCH 08/29] Merge remote-tracking branch 'upstream/compose-dev' into social-links --- app/build.gradle.kts | 4 +- .../1.json | 111 ++++++++++- .../revanced/manager/data/room/AppDatabase.kt | 6 +- .../manager/data/room/options/Option.kt | 23 +++ .../manager/data/room/options/OptionDao.kt | 51 +++++ .../manager/data/room/options/OptionGroup.kt | 24 +++ .../data/room/selection/SelectionDao.kt | 2 +- .../revanced/manager/di/RepositoryModule.kt | 1 + .../revanced/manager/di/ViewModelModule.kt | 2 +- .../domain/bundles/RemotePatchBundle.kt | 2 +- .../repository/PatchOptionsRepository.kt | 89 +++++++++ .../manager/network/api/ReVancedAPI.kt | 4 +- .../manager/network/dto/ReVancedRelease.kt | 6 + .../network/service/ReVancedService.kt | 10 +- .../manager/patcher/worker/PatcherWorker.kt | 6 +- .../manager/ui/component/GroupHeader.kt | 2 +- .../revanced/manager/ui/component/Markdown.kt | 123 +++--------- .../manager/ui/component/NotificationCard.kt | 163 +++++++++++++--- .../component/bundle/BundlePatchesDialog.kt | 13 +- .../ui/component/settings/BooleanItem.kt | 8 +- .../ui/component/settings/SettingsListItem.kt | 47 +++++ .../ui/destination/SettingsDestination.kt | 2 +- .../ui/screen/InstalledAppInfoScreen.kt | 36 ++-- .../manager/ui/screen/InstalledAppsScreen.kt | 22 +-- .../manager/ui/screen/InstallerScreen.kt | 83 ++++---- .../ui/screen/PatchesSelectorScreen.kt | 5 +- .../ui/screen/SelectedAppInfoScreen.kt | 23 ++- .../manager/ui/screen/SettingsScreen.kt | 76 ++------ .../ui/screen/settings/AboutSettingsScreen.kt | 147 +++++++-------- .../screen/settings/AdvancedSettingsScreen.kt | 40 ++-- .../settings/DownloadsSettingsScreen.kt | 9 +- .../screen/settings/GeneralSettingsScreen.kt | 9 +- .../settings/ImportExportSettingsScreen.kt | 116 +++++++++++- .../settings/update/ChangelogsScreen.kt | 178 ++++++++++++++++++ .../settings/update/ManagerUpdateChangelog.kt | 100 ---------- .../settings/update/UpdatesSettingsScreen.kt | 66 +------ .../ui/viewmodel/ChangelogsViewModel.kt | 44 +++++ .../ui/viewmodel/ImportExportViewModel.kt | 18 +- .../ui/viewmodel/InstallerViewModel.kt | 2 +- .../ManagerUpdateChangelogViewModel.kt | 53 ------ .../ui/viewmodel/PatchesSelectorViewModel.kt | 9 - .../ui/viewmodel/SelectedAppInfoViewModel.kt | 64 ++++++- .../ui/viewmodel/UpdateProgressViewModel.kt | 4 +- .../java/app/revanced/manager/util/Util.kt | 57 ++++++ app/src/main/res/values/strings.xml | 21 ++- gradle/libs.versions.toml | 4 +- 46 files changed, 1239 insertions(+), 646 deletions(-) create mode 100644 app/src/main/java/app/revanced/manager/data/room/options/Option.kt create mode 100644 app/src/main/java/app/revanced/manager/data/room/options/OptionDao.kt create mode 100644 app/src/main/java/app/revanced/manager/data/room/options/OptionGroup.kt create mode 100644 app/src/main/java/app/revanced/manager/domain/repository/PatchOptionsRepository.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/component/settings/SettingsListItem.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/screen/settings/update/ChangelogsScreen.kt delete mode 100644 app/src/main/java/app/revanced/manager/ui/screen/settings/update/ManagerUpdateChangelog.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/viewmodel/ChangelogsViewModel.kt delete mode 100644 app/src/main/java/app/revanced/manager/ui/viewmodel/ManagerUpdateChangelogViewModel.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 10ab6333e6..6ef4a5a9c1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,8 +156,8 @@ dependencies { implementation(libs.ktor.content.negotiation) implementation(libs.ktor.serialization) - // Markdown to HTML - implementation(libs.markdown) + // Markdown + implementation(libs.markdown.renderer) // Icons implementation("br.com.devsrsouza.compose.icons:font-awesome:1.1.0") diff --git a/app/schemas/app.revanced.manager.data.room.AppDatabase/1.json b/app/schemas/app.revanced.manager.data.room.AppDatabase/1.json index 041d1dea4e..0fb6425d6d 100644 --- a/app/schemas/app.revanced.manager.data.room.AppDatabase/1.json +++ b/app/schemas/app.revanced.manager.data.room.AppDatabase/1.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "371c7a84b122a2de8b660b35e6e9ce14", + "identityHash": "802fa2fda94b930bf0ebb85d195f1022", "entities": [ { "tableName": "patch_bundles", @@ -295,12 +295,119 @@ ] } ] + }, + { + "tableName": "option_groups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER NOT NULL, `patch_bundle` INTEGER NOT NULL, `package_name` TEXT NOT NULL, PRIMARY KEY(`uid`), FOREIGN KEY(`patch_bundle`) REFERENCES `patch_bundles`(`uid`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "patchBundle", + "columnName": "patch_bundle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "packageName", + "columnName": "package_name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "uid" + ] + }, + "indices": [ + { + "name": "index_option_groups_patch_bundle_package_name", + "unique": true, + "columnNames": [ + "patch_bundle", + "package_name" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_option_groups_patch_bundle_package_name` ON `${TABLE_NAME}` (`patch_bundle`, `package_name`)" + } + ], + "foreignKeys": [ + { + "table": "patch_bundles", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "patch_bundle" + ], + "referencedColumns": [ + "uid" + ] + } + ] + }, + { + "tableName": "options", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`group` INTEGER NOT NULL, `patch_name` TEXT NOT NULL, `key` TEXT NOT NULL, `value` TEXT NOT NULL, PRIMARY KEY(`group`, `patch_name`, `key`), FOREIGN KEY(`group`) REFERENCES `option_groups`(`uid`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "group", + "columnName": "group", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "patchName", + "columnName": "patch_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "group", + "patch_name", + "key" + ] + }, + "indices": [], + "foreignKeys": [ + { + "table": "option_groups", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "group" + ], + "referencedColumns": [ + "uid" + ] + } + ] } ], "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '371c7a84b122a2de8b660b35e6e9ce14')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '802fa2fda94b930bf0ebb85d195f1022')" ] } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/data/room/AppDatabase.kt b/app/src/main/java/app/revanced/manager/data/room/AppDatabase.kt index e1a0f81bd5..0440a7c29b 100644 --- a/app/src/main/java/app/revanced/manager/data/room/AppDatabase.kt +++ b/app/src/main/java/app/revanced/manager/data/room/AppDatabase.kt @@ -13,15 +13,19 @@ import app.revanced.manager.data.room.selection.SelectedPatch import app.revanced.manager.data.room.selection.SelectionDao import app.revanced.manager.data.room.bundles.PatchBundleDao import app.revanced.manager.data.room.bundles.PatchBundleEntity +import app.revanced.manager.data.room.options.Option +import app.revanced.manager.data.room.options.OptionDao +import app.revanced.manager.data.room.options.OptionGroup import kotlin.random.Random -@Database(entities = [PatchBundleEntity::class, PatchSelection::class, SelectedPatch::class, DownloadedApp::class, InstalledApp::class, AppliedPatch::class], version = 1) +@Database(entities = [PatchBundleEntity::class, PatchSelection::class, SelectedPatch::class, DownloadedApp::class, InstalledApp::class, AppliedPatch::class, OptionGroup::class, Option::class], version = 1) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { abstract fun patchBundleDao(): PatchBundleDao abstract fun selectionDao(): SelectionDao abstract fun downloadedAppDao(): DownloadedAppDao abstract fun installedAppDao(): InstalledAppDao + abstract fun optionDao(): OptionDao companion object { fun generateUid() = Random.Default.nextInt() diff --git a/app/src/main/java/app/revanced/manager/data/room/options/Option.kt b/app/src/main/java/app/revanced/manager/data/room/options/Option.kt new file mode 100644 index 0000000000..3a70a9a56e --- /dev/null +++ b/app/src/main/java/app/revanced/manager/data/room/options/Option.kt @@ -0,0 +1,23 @@ +package app.revanced.manager.data.room.options + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey + +@Entity( + tableName = "options", + primaryKeys = ["group", "patch_name", "key"], + foreignKeys = [ForeignKey( + OptionGroup::class, + parentColumns = ["uid"], + childColumns = ["group"], + onDelete = ForeignKey.CASCADE + )] +) +data class Option( + @ColumnInfo(name = "group") val group: Int, + @ColumnInfo(name = "patch_name") val patchName: String, + @ColumnInfo(name = "key") val key: String, + // Encoded as Json. + @ColumnInfo(name = "value") val value: String, +) \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/data/room/options/OptionDao.kt b/app/src/main/java/app/revanced/manager/data/room/options/OptionDao.kt new file mode 100644 index 0000000000..fa343a6db6 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/data/room/options/OptionDao.kt @@ -0,0 +1,51 @@ +package app.revanced.manager.data.room.options + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.MapInfo +import androidx.room.Query +import androidx.room.Transaction +import kotlinx.coroutines.flow.Flow + +@Dao +abstract class OptionDao { + @Transaction + @MapInfo(keyColumn = "patch_bundle") + @Query( + "SELECT patch_bundle, `group`, patch_name, `key`, value FROM option_groups" + + " LEFT JOIN options ON uid = options.`group`" + + " WHERE package_name = :packageName" + ) + abstract suspend fun getOptions(packageName: String): Map> + + @Query("SELECT uid FROM option_groups WHERE patch_bundle = :bundleUid AND package_name = :packageName") + abstract suspend fun getGroupId(bundleUid: Int, packageName: String): Int? + + @Query("SELECT package_name FROM option_groups") + abstract fun getPackagesWithOptions(): Flow> + + @Insert + abstract suspend fun createOptionGroup(group: OptionGroup) + + @Query("DELETE FROM option_groups WHERE patch_bundle = :uid") + abstract suspend fun clearForPatchBundle(uid: Int) + + @Query("DELETE FROM option_groups WHERE package_name = :packageName") + abstract suspend fun clearForPackage(packageName: String) + + @Query("DELETE FROM option_groups") + abstract suspend fun reset() + + @Insert + protected abstract suspend fun insertOptions(patches: List