Merge remote-tracking branch 'upstream/yeh'

This commit is contained in:
litleck 2022-01-18 19:07:21 -05:00
commit b05ae80894
11 changed files with 268 additions and 26 deletions

View file

@ -51,7 +51,7 @@ android {
dependencies {
// core dependencies
implementation("androidx.appcompat:appcompat:1.3.1")
implementation("androidx.appcompat:appcompat:1.4.0")
implementation("androidx.core:core-ktx:1.7.0")
implementation("com.google.android.material:material:1.4.0")
@ -60,8 +60,8 @@ dependencies {
implementation("androidx.compose.ui:ui:${composeVersion}")
implementation("androidx.compose.material:material:${composeVersion}")
implementation("androidx.compose.ui:ui-tooling:${composeVersion}")
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.0-rc01")
implementation("androidx.navigation:navigation-compose:2.4.0-beta02")
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.0-rc02")
implementation("androidx.navigation:navigation-compose:2.4.0-rc01")
// accompanist dependencies
implementation("com.google.accompanist:accompanist-systemuicontroller:${accompanistVersion}")
@ -69,4 +69,6 @@ dependencies {
// other dependencies
implementation("com.google.code.gson:gson:2.8.7")
implementation("io.coil-kt:coil-compose:1.4.0")
}

View file

@ -0,0 +1,3 @@
package com.aliucord.manager.models
data class GithubUser(val login: String, val contributions: Int)

View file

@ -9,5 +9,7 @@ import android.os.Environment
val themePreference = intPreference("theme")
val replaceBgPreference = boolPreference("replace_bg", true)
val devModePreference = boolPreference("dev_mode", false)
val debuggablePreference = boolPreference("debuggable", false)
val useDexFromStoragePreference = boolPreference("use_dex_from_storage")
val dexLocationPreference = stringPreference("dex_location", Environment.getExternalStorageDirectory().absolutePath + "/Aliucord/Aliucord.dex")

View file

@ -123,13 +123,21 @@ fun MainActivityLayout() {
)
}
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) {
DropdownMenuItem(onClick = {
isMenuExpanded = false
navController.navigate(Screen.About.route) {
popUpTo(Screen.Home.route) { saveState = true }
}
}) {
Text(stringResource(Screen.About.displayName))
}
DropdownMenuItem(onClick = {
isMenuExpanded = false
navController.navigate(Screen.Settings.route) {
popUpTo(Screen.Home.route) { saveState = true }
}
}) {
Text(stringResource(id = Screen.Settings.displayName))
Text(stringResource(Screen.Settings.displayName))
}
}
}

View file

@ -9,6 +9,7 @@ import androidx.annotation.StringRes
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.runtime.Composable
import com.aliucord.manager.R
import com.aliucord.manager.ui.screens.AboutScreen
import com.aliucord.manager.ui.screens.HomeScreen
import com.aliucord.manager.ui.screens.PluginsScreen
import com.aliucord.manager.ui.screens.SettingsScreen
@ -20,7 +21,7 @@ sealed class Screen(
) {
companion object {
// NOTE: without lazy it doesn't work, kotlin moment https://youtrack.jetbrains.com/issue/KT-8970
val SCREENS by lazy { listOf(Home, Settings, Plugins) }
val SCREENS by lazy { listOf(Home, Settings, Plugins, About) }
}
object Home : Screen(
@ -29,6 +30,12 @@ sealed class Screen(
{ HomeScreen() }
)
object About : Screen(
"About",
R.string.about,
{ AboutScreen() }
)
object Settings : Screen(
"settings",
R.string.settings,

View file

@ -0,0 +1,136 @@
package com.aliucord.manager.ui.screens
import android.util.Log
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.GridCells
import androidx.compose.foundation.lazy.LazyVerticalGrid
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.rememberImagePainter
import coil.transform.CircleCropTransformation
import com.aliucord.manager.BuildConfig
import com.aliucord.manager.R
import com.aliucord.manager.models.GithubUser
import com.aliucord.manager.utils.Github
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ExperimentalFoundationApi
@OptIn(ExperimentalMaterialApi::class)
@Composable
@Preview
fun AboutScreen() {
val coroutineScope = rememberCoroutineScope { Dispatchers.IO }
val modifier = Modifier.padding(8.dp)
val contributors = remember { mutableStateOf<Array<GithubUser>?>(null) }
Column(modifier = Modifier.padding(16.dp)) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
stringResource(R.string.team),
style = MaterialTheme.typography.h4,
)
UserEntry("Juby210", "Fox")
UserEntry("torvalds", "Epic")
UserEntry("cyyynthia", "PSA: Uninstall Client mods by Cynthia")
}
Column(
modifier = modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
stringResource(R.string.contributors),
style = MaterialTheme.typography.h4,
)
if (contributors.value == null) {
Text(
stringResource(R.string.loading)
)
LaunchedEffect(null) {
coroutineScope.launch {
try {
contributors.value = Github.contributors
} catch (err: Throwable) {
Log.e(BuildConfig.TAG, "Failed to load contributors", err)
}
}
}
} else {
LazyVerticalGrid(
cells = GridCells.Adaptive(48.dp)
) {
items(contributors.value!!) {
ContributorEntry(it.login)
}
}
}
}
}
}
@Composable
fun UserEntry(name: String, roles: String) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 8.dp), shape = RoundedCornerShape(15.dp)
) {
Column(modifier = Modifier.padding(16.dp, 8.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
painter = rememberImagePainter(
data = "https://github.com/$name.png",
builder = {
transformations(CircleCropTransformation())
}
),
contentDescription = null,
modifier = Modifier
.size(48.dp)
.padding(end = 8.dp)
)
Column {
Text(
name,
style = MaterialTheme.typography.h6,
)
Text(roles)
}
}
}
}
}
@Composable
fun ContributorEntry(name: String) {
val handler = LocalUriHandler.current
Image(
painter = rememberImagePainter(
data = "https://github.com/$name.png",
),
contentDescription = null,
modifier = Modifier
.size(48.dp)
.clickable { handler.openUri("https://github.com/$name") }
)
}

View file

@ -154,4 +154,4 @@ fun PluginsScreen() {
}
}
}
}
}

View file

@ -17,10 +17,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.aliucord.manager.R
import com.aliucord.manager.preferences.dexLocationPreference
import com.aliucord.manager.preferences.replaceBgPreference
import com.aliucord.manager.preferences.themePreference
import com.aliucord.manager.preferences.useDexFromStoragePreference
import com.aliucord.manager.preferences.*
import com.aliucord.manager.ui.components.ExposedDropdownMenu
private val themes = arrayOf("System", "Light", "Dark", "Black")
@ -52,23 +49,49 @@ fun SettingsScreen() {
},
modifier = modifier.clickable { replaceBgPreference.set(!replaceBgPreference.get()) }
)
val udfs = useDexFromStoragePreference.get()
val devModeOn = devModePreference.get()
ListItem(
text = { Text(stringResource(R.string.use_dex_from_storage)) },
text = { Text(stringResource(R.string.developer_mode)) },
trailing = {
Checkbox(
checked = udfs,
onCheckedChange = useDexFromStoragePreference::set
checked = devModeOn,
onCheckedChange = devModePreference::set
)
},
modifier = modifier.clickable { useDexFromStoragePreference.set(!useDexFromStoragePreference.get()) }
)
val color = if (udfs) Color.Unspecified else MaterialTheme.colors.onBackground.copy(ContentAlpha.disabled)
ListItem(
text = { Text(stringResource(R.string.dex_location), color = color) },
secondaryText = { Text(dexLocationPreference.get(), color = color) },
modifier = if (udfs) modifier.clickable { /*TODO*/ } else modifier
modifier = modifier
)
if (devModeOn) {
ListItem(
text = { Text(stringResource(R.string.debuggable)) },
trailing = {
Checkbox(
checked = debuggablePreference.get(),
onCheckedChange = debuggablePreference::set
)
},
modifier = modifier
)
val udfs = useDexFromStoragePreference.get()
ListItem(
text = { Text(stringResource(R.string.use_dex_from_storage)) },
trailing = {
Checkbox(
checked = udfs,
onCheckedChange = useDexFromStoragePreference::set
)
},
modifier = modifier.clickable { useDexFromStoragePreference.set(!useDexFromStoragePreference.get()) }
)
val color =
if (udfs) Color.Unspecified else MaterialTheme.colors.onBackground.copy(ContentAlpha.disabled)
ListItem(
text = { Text(stringResource(R.string.dex_location), color = color) },
secondaryText = { Text(dexLocationPreference.get(), color = color) },
modifier = if (udfs) modifier.clickable { /*TODO*/ } else modifier
)
}
Button(
onClick = { /*TODO*/ },
Modifier

View file

@ -0,0 +1,39 @@
package com.aliucord.manager.utils
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import java.io.File
import java.util.concurrent.CountDownLatch
object Downloader {
fun download(ctx: Context, url: String, file: File) {
val dm = ctx.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val latch = CountDownLatch(1)
with (DownloadReceiver(ctx, latch)) {
ctx.registerReceiver(this, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
downloadId = DownloadManager.Request(Uri.parse(url)).run {
setTitle("AliucordManager")
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
setDestinationUri(Uri.fromFile(file))
dm.enqueue(this)
}
}
latch.await()
}
}
class DownloadReceiver(private val ctx: Context, private val latch: CountDownLatch) : BroadcastReceiver() {
var downloadId = 0L
override fun onReceive(context: Context, intent: Intent) {
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (downloadId == id) {
latch.countDown()
ctx.unregisterReceiver(this)
}
}
}

View file

@ -6,6 +6,7 @@
package com.aliucord.manager.utils
import com.aliucord.manager.models.Commit
import com.aliucord.manager.models.GithubUser
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.io.InputStreamReader
@ -18,6 +19,7 @@ object Github {
private const val repo = "Aliucord"
private const val commitsUrl = "https://api.github.com/repos/$org/$repo/commits"
private const val contributorsUrl = "https://api.github.com/repos/$org/$repo/contributors"
private const val dataUrl = "https://raw.githubusercontent.com/$org/$repo/builds/data.json"
fun checkForUpdates() {
@ -30,21 +32,35 @@ object Github {
private val commitsCache = HashMap<String, Array<Commit>>()
private val commitsType = object : TypeToken<Array<Commit>>() {}.type
private val contributorsType = object : TypeToken<Array<GithubUser>>() {}.type
private val gson = Gson()
fun getCommits(params: Map<String, String>?): Array<Commit> {
// return emptyArray()
val query = params?.map { it.key + "=" + it.value }?.joinToString("&", "?") ?: ""
if (commitsCache.containsKey(query)) return commitsCache[query] ?: emptyArray()
val res = gson.fromJson<Array<Commit>>(
InputStreamReader(URL(commitsUrl + query).openStream()),
commitsType
)
val res = InputStreamReader(URL(commitsUrl + query).openStream()).use {
gson.fromJson<Array<Commit>>(
it,
commitsType
)
}
commitsCache[query] = res
return res
}
val contributors: Array<GithubUser> by lazy {
InputStreamReader(URL(contributorsUrl).openStream()).use { stream ->
gson.fromJson<Array<GithubUser>>(
stream,
contributorsType
).apply {
sortByDescending { it.contributions }
}
}
}
fun getDownloadUrl(ref: String, file: String): String {
return "'https://raw.githubusercontent.com/${org}/${repo}/${ref}/${file}";
return "https://raw.githubusercontent.com/${org}/${repo}/${ref}/${file}";
}
}

View file

@ -25,4 +25,10 @@
<string name="install">Install</string>
<string name="reinstall">Reinstall</string>
<string name="update">Update</string>
<string name="developer_mode">Enable Developer Mode</string>
<string name="debuggable">Make Aliucord debuggable</string>
<string name="about">About</string>
<string name="team">Team</string>
<string name="contributors">Contributors</string>
<string name="loading">Loading...</string>
</resources>