Feat: Add about screen
This commit is contained in:
parent
9e730ff20e
commit
584e5e8b3b
15 changed files with 538 additions and 5 deletions
|
@ -14,8 +14,8 @@ android {
|
|||
applicationId = "dev.beefers.vendetta.manager"
|
||||
minSdk = 24
|
||||
targetSdk = 33
|
||||
versionCode = 1040
|
||||
versionName = "1.0.4"
|
||||
versionCode = 1050
|
||||
versionName = "1.0.5"
|
||||
|
||||
buildConfigField("String", "GIT_BRANCH", "\"${getCurrentBranch()}\"")
|
||||
buildConfigField("String", "GIT_COMMIT", "\"${getLatestCommit()}\"")
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
package dev.beefers.vendetta.manager.ui.screen.about
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
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.filled.ArrowBack
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import coil.compose.AsyncImage
|
||||
import dev.beefers.vendetta.manager.BuildConfig
|
||||
import dev.beefers.vendetta.manager.R
|
||||
import dev.beefers.vendetta.manager.ui.widgets.about.LinkItem
|
||||
import dev.beefers.vendetta.manager.ui.widgets.about.ListItem
|
||||
import dev.beefers.vendetta.manager.ui.widgets.about.UserEntry
|
||||
import dev.beefers.vendetta.manager.utils.Constants
|
||||
import dev.beefers.vendetta.manager.utils.getBitmap
|
||||
|
||||
class AboutScreen: Screen {
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
override fun Content() {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
||||
val ctx = LocalContext.current
|
||||
val bitmap = remember {
|
||||
ctx.getBitmap(R.drawable.ic_launcher, 60).asImageBitmap()
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = { TitleBar(scrollBehavior) },
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(it)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp, bottom = 20.dp)
|
||||
) {
|
||||
Image(
|
||||
bitmap = bitmap,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(60.dp)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
|
||||
Text(
|
||||
stringResource(R.string.app_name),
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})",
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = LocalContentColor.current.copy(alpha = 0.5f),
|
||||
modifier = Modifier.clickable { }
|
||||
)
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
LinkItem(
|
||||
icon = R.drawable.ic_github,
|
||||
label = R.string.label_github,
|
||||
link = "https://github.com/vendetta-mod"
|
||||
)
|
||||
|
||||
LinkItem(
|
||||
icon = R.drawable.ic_discord,
|
||||
label = R.string.label_discord,
|
||||
link = "https://discord.gg/n9QQ4XhhJP"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 16.dp, bottom = 20.dp)
|
||||
) {
|
||||
UserEntry("Fiery", "Lead dev\niOS", "FieryFlames")
|
||||
UserEntry("Beef", "Creator\nVendetta", "Beefers", isLarge = true)
|
||||
UserEntry("Wing", "Lead dev\nManager", "wingio")
|
||||
}
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.label_team),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
modifier = Modifier.padding(16.dp),
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
) {
|
||||
ElevatedCard {
|
||||
Constants.TEAM_MEMBERS.forEachIndexed { i, member ->
|
||||
ListItem(
|
||||
text = member.name,
|
||||
subtext = member.role,
|
||||
imageUrl = "https://github.com/${member.username}.png",
|
||||
onClick = {
|
||||
uriHandler.openUri("https://github.com/${member.username}")
|
||||
}
|
||||
)
|
||||
if(i != Constants.TEAM_MEMBERS.lastIndex) {
|
||||
Divider(
|
||||
thickness = 0.5.dp,
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.label_special_thanks),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
modifier = Modifier.padding(16.dp),
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
) {
|
||||
ElevatedCard {
|
||||
ListItem(
|
||||
text = "Rushii",
|
||||
subtext = "for some of the installer code",
|
||||
imageUrl = "https://github.com/rushiiMachine.png",
|
||||
onClick = {
|
||||
uriHandler.openUri("https://github.com/rushiiMachine")
|
||||
}
|
||||
)
|
||||
Divider(
|
||||
thickness = 0.5.dp,
|
||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f),
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
)
|
||||
ListItem(
|
||||
text = "Xinto",
|
||||
subtext = "for the preference manager",
|
||||
imageUrl = "https://github.com/X1nto.png",
|
||||
onClick = {
|
||||
uriHandler.openUri("https://github.com/X1nto")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
ElevatedCard {
|
||||
ListItem(
|
||||
text = stringResource(R.string.label_translate),
|
||||
subtext = stringResource(R.string.msg_coming_soon)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
private fun TitleBar(
|
||||
scrollBehavior: TopAppBarScrollBehavior
|
||||
) {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.title_about)) },
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { navigator.pop() }) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.action_back)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
|
@ -19,11 +19,16 @@ import androidx.compose.material.icons.filled.Delete
|
|||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.filled.OpenInNew
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material.icons.filled.RestartAlt
|
||||
import androidx.compose.material.icons.outlined.Home
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
|
@ -46,8 +51,10 @@ import cafe.adriel.voyager.navigator.tab.TabOptions
|
|||
import dev.beefers.vendetta.manager.R
|
||||
import dev.beefers.vendetta.manager.domain.manager.PreferenceManager
|
||||
import dev.beefers.vendetta.manager.ui.components.SegmentedButton
|
||||
import dev.beefers.vendetta.manager.ui.screen.about.AboutScreen
|
||||
import dev.beefers.vendetta.manager.ui.screen.installer.InstallerScreen
|
||||
import dev.beefers.vendetta.manager.ui.viewmodel.home.HomeViewModel
|
||||
import dev.beefers.vendetta.manager.ui.viewmodel.main.MainViewModel
|
||||
import dev.beefers.vendetta.manager.ui.widgets.home.Commit
|
||||
import dev.beefers.vendetta.manager.utils.DiscordVersion
|
||||
import dev.beefers.vendetta.manager.utils.ManagerTab
|
||||
|
@ -234,6 +241,21 @@ class HomeScreen : ManagerTab {
|
|||
|
||||
@Composable
|
||||
override fun Actions() {
|
||||
val viewModel: HomeViewModel = getScreenModel()
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
IconButton(onClick = { viewModel.getDiscordVersions() }) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Refresh,
|
||||
contentDescription = stringResource(R.string.action_reload)
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { navigator.navigate(AboutScreen()) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Info,
|
||||
contentDescription = stringResource(R.string.action_open_about)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -6,12 +6,17 @@ import androidx.compose.foundation.rememberScrollState
|
|||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.outlined.Info
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import dev.beefers.vendetta.manager.R
|
||||
import dev.beefers.vendetta.manager.domain.manager.PreferenceManager
|
||||
|
@ -20,9 +25,11 @@ import dev.beefers.vendetta.manager.ui.components.settings.SettingsHeader
|
|||
import dev.beefers.vendetta.manager.ui.components.settings.SettingsItemChoice
|
||||
import dev.beefers.vendetta.manager.ui.components.settings.SettingsSwitch
|
||||
import dev.beefers.vendetta.manager.ui.components.settings.SettingsTextField
|
||||
import dev.beefers.vendetta.manager.ui.screen.about.AboutScreen
|
||||
import dev.beefers.vendetta.manager.ui.viewmodel.settings.SettingsViewModel
|
||||
import dev.beefers.vendetta.manager.utils.ManagerTab
|
||||
import dev.beefers.vendetta.manager.utils.TabOptions
|
||||
import dev.beefers.vendetta.manager.utils.navigate
|
||||
import org.koin.androidx.compose.get
|
||||
|
||||
class SettingsScreen : ManagerTab {
|
||||
|
@ -101,5 +108,13 @@ class SettingsScreen : ManagerTab {
|
|||
|
||||
@Composable
|
||||
override fun Actions() {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
IconButton(onClick = { navigator.navigate(AboutScreen()) }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Info,
|
||||
contentDescription = stringResource(R.string.action_open_about)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ class HomeViewModel(
|
|||
getDiscordVersions()
|
||||
}
|
||||
|
||||
private fun getDiscordVersions() {
|
||||
fun getDiscordVersions() {
|
||||
coroutineScope.launch {
|
||||
discordVersions = repo.getLatestDiscordVersions().dataOrNull
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class MainViewModel(
|
|||
checkForUpdate()
|
||||
}
|
||||
|
||||
private fun checkForUpdate() {
|
||||
fun checkForUpdate() {
|
||||
coroutineScope.launch {
|
||||
release = repo.getLatestRelease("VendettaManager").dataOrNull
|
||||
release?.let {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package dev.beefers.vendetta.manager.ui.widgets.about
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun LinkItem(
|
||||
@DrawableRes icon: Int,
|
||||
@StringRes label: Int,
|
||||
link: String
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = { uriHandler.openUri(link) },
|
||||
indication = rememberRipple(bounded = false, radius = 40.dp),
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(icon),
|
||||
contentDescription = stringResource(label),
|
||||
modifier = Modifier.size(30.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(label),
|
||||
style = MaterialTheme.typography.labelMedium
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package dev.beefers.vendetta.manager.ui.widgets.about
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
|
||||
@Composable
|
||||
fun ListItem(
|
||||
text: String,
|
||||
subtext: String? = null,
|
||||
imageUrl: String? = null,
|
||||
onClick: (() -> Unit)? = null
|
||||
) {
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
enabled = onClick != null,
|
||||
onClick = onClick ?: { -> }
|
||||
)
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
imageUrl?.let {
|
||||
AsyncImage(
|
||||
model = it,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(35.dp)
|
||||
.clip(CircleShape)
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
subtext?.let {
|
||||
Text(
|
||||
text = it,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = LocalContentColor.current.copy(alpha = 0.5f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package dev.beefers.vendetta.manager.ui.widgets.about
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.AsyncImage
|
||||
|
||||
@Composable
|
||||
fun UserEntry(
|
||||
name: String,
|
||||
roles: String,
|
||||
username: String = name,
|
||||
isLarge: Boolean = false
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = { uriHandler.openUri("https://github.com/$username") },
|
||||
indication = rememberRipple(bounded = false, radius = 90.dp),
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
)
|
||||
.widthIn(min = 100.dp)
|
||||
) {
|
||||
AsyncImage(
|
||||
modifier = Modifier
|
||||
.size(if(isLarge) 70.dp else 50.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)),
|
||||
model = "https://github.com/$username.png",
|
||||
contentDescription = username
|
||||
)
|
||||
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
style = MaterialTheme.typography.titleMedium.copy(
|
||||
fontSize = 18.sp
|
||||
)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = roles,
|
||||
style = MaterialTheme.typography.titleSmall.copy(
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
|
||||
),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package dev.beefers.vendetta.manager.utils
|
||||
|
||||
object Constants {
|
||||
|
||||
val TEAM_MEMBERS = listOf(
|
||||
TeamMember("Pylix", "Developer - Vendetta", "amsyarasyiq"),
|
||||
TeamMember("Kasi", "Developer - Xposed Module", "redstonekasi")
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
data class TeamMember(
|
||||
val name: String,
|
||||
val role: String,
|
||||
val username: String = name
|
||||
)
|
|
@ -13,6 +13,7 @@ import com.google.accompanist.pager.ExperimentalPagerApi
|
|||
import dev.beefers.vendetta.manager.ui.screen.home.HomeScreen
|
||||
import dev.beefers.vendetta.manager.ui.screen.main.LocalPagerState
|
||||
import dev.beefers.vendetta.manager.ui.screen.settings.SettingsScreen
|
||||
import dev.beefers.vendetta.manager.ui.viewmodel.main.MainViewModel
|
||||
|
||||
enum class MainTab(val tab: ManagerTab) {
|
||||
HOME(HomeScreen()),
|
||||
|
|
|
@ -3,8 +3,11 @@ package dev.beefers.vendetta.manager.utils
|
|||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import dev.beefers.vendetta.manager.BuildConfig
|
||||
|
||||
fun Context.copyText(text: String) {
|
||||
|
@ -19,4 +22,27 @@ fun Context.showToast(@StringRes res: Int, vararg params: Any, short: Boolean =
|
|||
getString(res, *params),
|
||||
if (short) Toast.LENGTH_SHORT else Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
|
||||
private val cachedBitmaps: MutableMap<Int, MutableMap<Int, Bitmap>> = mutableMapOf()
|
||||
|
||||
context(Context)
|
||||
private val Int.dp: Int
|
||||
get() = (45 * this@Context.resources.displayMetrics.density + 0.5f).toInt()
|
||||
|
||||
fun Context.getBitmap(@DrawableRes icon: Int, size: Int): Bitmap {
|
||||
cachedBitmaps[icon]?.let { it[size]?.let { bitmap -> return bitmap } }
|
||||
val sizePx = size.dp
|
||||
|
||||
val bitmap = getDrawable(icon)!!.toBitmap(
|
||||
height = sizePx,
|
||||
width = sizePx
|
||||
)
|
||||
|
||||
cachedBitmaps[icon] = mutableMapOf()
|
||||
cachedBitmaps[icon]?.let {
|
||||
it[size] = bitmap
|
||||
}
|
||||
|
||||
return bitmap
|
||||
}
|
7
app/src/main/res/drawable/ic_discord.xml
Normal file
7
app/src/main/res/drawable/ic_discord.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<vector android:height="24dp" android:viewportHeight="512"
|
||||
android:viewportWidth="512" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group>
|
||||
<clip-path android:pathData="M0,0h512v512h-512z"/>
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M420.81,104.8C390.5,90.88 358,80.65 324,74.78C323.39,74.67 322.78,74.94 322.45,75.5C318.28,82.94 313.63,92.64 310.39,100.27C273.85,94.8 237.48,94.8 201.67,100.27C198.43,92.48 193.62,82.94 189.43,75.5C189.11,74.96 188.5,74.68 187.87,74.78C153.9,80.61 121.4,90.87 91.07,104.8C90.8,104.91 90.57,105.1 90.43,105.35C28.78,197.46 11.88,287.31 20.17,376.05C20.2,376.48 20.44,376.88 20.78,377.16C61.47,407.03 100.88,425.17 139.55,437.18C140.16,437.37 140.83,437.15 141.21,436.63C150.35,424.15 158.51,410.98 165.51,397.12C165.93,396.31 165.52,395.34 164.69,395.02C151.76,390.12 139.44,384.14 127.59,377.35C126.65,376.8 126.57,375.45 127.43,374.82C129.93,372.95 132.43,371 134.8,369.03C135.23,368.68 135.83,368.61 136.34,368.84C214.18,404.37 298.43,404.37 375.35,368.84C375.86,368.58 376.46,368.66 376.91,369.02C379.28,370.98 381.78,372.95 384.3,374.82C385.15,375.45 385.1,376.8 384.17,377.35C372.32,384.27 360,390.12 347.04,395C346.2,395.33 345.83,396.31 346.23,397.12C353.38,410.95 361.53,424.12 370.51,436.61C370.88,437.15 371.56,437.37 372.19,437.18C411.04,425.17 450.44,407.03 491.14,377.16C491.49,376.88 491.71,376.5 491.75,376.06C501.66,273.48 475.14,184.36 421.42,105.36C421.3,105.1 421.07,104.91 420.81,104.8ZM177.13,322.01C153.69,322.01 134.39,300.5 134.39,274.08C134.39,247.65 153.32,226.15 177.13,226.15C201.12,226.15 220.24,247.85 219.87,274.08C219.87,300.5 200.94,322.01 177.13,322.01ZM335.16,322.01C311.73,322.01 292.42,300.5 292.42,274.08C292.42,247.65 311.35,226.15 335.16,226.15C359.16,226.15 378.28,247.85 377.9,274.08C377.9,300.5 359.16,322.01 335.16,322.01Z"/>
|
||||
</group>
|
||||
</vector>
|
7
app/src/main/res/drawable/ic_github.xml
Normal file
7
app/src/main/res/drawable/ic_github.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<group>
|
||||
<clip-path android:pathData="M0,0h1024v1024h-1024z"/>
|
||||
<path android:fillColor="#000000" android:pathData="M512,83.4C278.9,83.4 88.1,274.1 88.1,507.2C88.1,687.4 201.2,841 358.3,902.9C374.2,899.3 388.4,885.2 388.4,867.5L388.4,789.8L342.5,789.8C308.9,789.8 280.6,773.9 266.5,749.2C263,742.1 259.4,733.3 255.9,724.5C248.8,705.1 240,683.9 222.4,671.5C215.3,666.2 211.8,655.6 213.5,646.8C217.1,637.9 225.9,630.9 241.8,632.6C259.4,634.4 285.9,653.8 301.8,675C316,692.7 326.6,703.3 347.7,703.3L353,703.3C368.9,703.3 407.8,703.3 414.9,696.2C420.2,689.2 423.7,683.9 429,678.6C323,657.4 263,595.6 263,501.9C263,470.2 271.8,438.4 291.2,410.1C284.2,383.6 268.3,314.7 301.8,284.7L307.1,279.4L314.2,279.4C360.1,279.4 393.7,298.8 414.9,314.7C476.7,291.8 547.3,291.8 609.1,314.7C628.6,298.8 662.1,279.4 709.8,279.4L716.9,279.4L722.2,284.7C755.7,316.5 739.8,383.6 732.8,410.1C750.4,438.4 761,470.2 761,501.9C761,595.6 701,657.4 596.8,678.6C623.3,706.8 637.4,749.2 637.4,782.8L637.4,869.3C637.4,887 649.8,901.1 667.4,904.6C822.8,841 935.9,687.4 935.9,507.2C935.9,274.1 745.1,83.4 512,83.4Z"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -2,6 +2,8 @@
|
|||
<string name="app_name">Vendetta Manager</string>
|
||||
|
||||
<string name="msg_cleared_cache">Cache cleared successfully</string>
|
||||
<string name="msg_load_fail">Failed to load commits</string>
|
||||
<string name="msg_coming_soon">Coming soon</string>
|
||||
|
||||
<string name="group_download">Download APKs</string>
|
||||
<string name="group_patch">Patching</string>
|
||||
|
@ -43,6 +45,8 @@
|
|||
<string name="action_uninstall">Uninstall</string>
|
||||
<string name="action_info">Info</string>
|
||||
<string name="action_retry">Retry</string>
|
||||
<string name="action_reload">Reload</string>
|
||||
<string name="action_open_about">Open about</string>
|
||||
|
||||
<string name="installer_cached">Cached</string>
|
||||
|
||||
|
@ -50,6 +54,7 @@
|
|||
<string name="title_home">Home</string>
|
||||
<string name="title_settings">Settings</string>
|
||||
<string name="title_update">Update available!</string>
|
||||
<string name="title_about">About</string>
|
||||
|
||||
<string name="theme_system">System</string>
|
||||
<string name="theme_light">Light</string>
|
||||
|
@ -72,5 +77,10 @@
|
|||
<string name="channel_beta">Beta</string>
|
||||
<string name="channel_alpha">Alpha</string>
|
||||
|
||||
<string name="msg_load_fail">Failed to load commits</string>
|
||||
<string name="label_github">Github</string>
|
||||
<string name="label_discord">Discord</string>
|
||||
<string name="label_team">Team</string>
|
||||
<string name="label_special_thanks">Special thanks</string>
|
||||
<string name="label_licenses">Open source licenses</string>
|
||||
<string name="label_translate">Translate</string>
|
||||
</resources>
|
Loading…
Reference in a new issue