Skip to content

Commit 14888f9

Browse files
Axelen123Aunali321
authored andcommitted
feat: better installer ui (#29)
based cossale Co-authored-by: Aunali321 <aunvakil.aa@gmail.com>
1 parent 9675a27 commit 14888f9

2 files changed

Lines changed: 161 additions & 28 deletions

File tree

app/src/main/java/app/revanced/manager/compose/ui/screen/InstallerScreen.kt

Lines changed: 160 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,40 @@ package app.revanced.manager.compose.ui.screen
22

33
import androidx.activity.compose.rememberLauncherForActivityResult
44
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
5-
import androidx.compose.foundation.layout.Column
6-
import androidx.compose.foundation.layout.fillMaxSize
7-
import androidx.compose.foundation.layout.padding
8-
import androidx.compose.material3.Button
9-
import androidx.compose.material3.ExperimentalMaterial3Api
10-
import androidx.compose.material3.MaterialTheme
11-
import androidx.compose.material3.Text
5+
import androidx.compose.animation.AnimatedVisibility
6+
import androidx.compose.foundation.background
7+
import androidx.compose.foundation.layout.*
8+
import androidx.compose.foundation.shape.RoundedCornerShape
9+
import androidx.compose.material.icons.Icons
10+
import androidx.compose.material.icons.filled.Cancel
11+
import androidx.compose.material.icons.filled.CheckCircle
12+
import androidx.compose.material.icons.filled.KeyboardArrowDown
13+
import androidx.compose.material.icons.filled.KeyboardArrowUp
14+
import androidx.compose.material.icons.outlined.HelpOutline
15+
import androidx.compose.material.icons.outlined.MoreVert
16+
import androidx.compose.material3.*
1217
import androidx.compose.runtime.Composable
18+
import androidx.compose.runtime.getValue
19+
import androidx.compose.runtime.mutableStateOf
20+
import androidx.compose.runtime.saveable.rememberSaveable
21+
import androidx.compose.runtime.setValue
22+
import androidx.compose.ui.Alignment
1323
import androidx.compose.ui.Modifier
24+
import androidx.compose.ui.draw.clip
1425
import androidx.compose.ui.res.stringResource
26+
import androidx.compose.ui.semantics.contentDescription
27+
import androidx.compose.ui.semantics.semantics
28+
import androidx.compose.ui.text.style.TextOverflow
29+
import androidx.compose.ui.unit.Dp
30+
import androidx.compose.ui.unit.dp
1531
import app.revanced.manager.compose.R
32+
import app.revanced.manager.compose.patcher.worker.StepGroup
33+
import app.revanced.manager.compose.patcher.worker.StepStatus
1634
import app.revanced.manager.compose.ui.component.AppScaffold
1735
import app.revanced.manager.compose.ui.component.AppTopBar
1836
import app.revanced.manager.compose.ui.viewmodel.InstallerScreenViewModel
1937
import app.revanced.manager.compose.util.APK_MIMETYPE
38+
import kotlin.math.floor
2039

2140
@OptIn(ExperimentalMaterial3Api::class)
2241
@Composable
@@ -31,6 +50,14 @@ fun InstallerScreen(
3150
AppTopBar(
3251
title = stringResource(R.string.installer),
3352
onBackClick = onBackClick,
53+
actions = {
54+
IconButton(onClick = {}) {
55+
Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
56+
}
57+
IconButton(onClick = {}) {
58+
Icon(Icons.Outlined.MoreVert, stringResource(R.string.more))
59+
}
60+
}
3461
)
3562
}
3663
) { paddingValues ->
@@ -40,34 +67,139 @@ fun InstallerScreen(
4067
.fillMaxSize()
4168
) {
4269
vm.stepGroups.forEach {
43-
Column {
44-
Text(
45-
text = "${stringResource(it.name)}: ${it.status}",
46-
style = MaterialTheme.typography.titleLarge
47-
)
70+
InstallGroup(it)
71+
}
72+
Spacer(modifier = Modifier.weight(1f))
73+
Row(
74+
verticalAlignment = Alignment.Bottom,
75+
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.End),
76+
modifier = Modifier
77+
.fillMaxWidth()
78+
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
79+
) {
80+
Button(
81+
onClick = { exportApkLauncher.launch("${vm.packageName}.apk") },
82+
enabled = vm.canInstall
83+
) {
84+
Text(stringResource(R.string.export_app))
85+
}
4886

49-
it.steps.forEach {
50-
Text(
51-
text = "${it.name}: ${it.status}",
52-
style = MaterialTheme.typography.titleMedium
53-
)
54-
}
87+
Button(
88+
onClick = vm::installApk,
89+
enabled = vm.canInstall
90+
) {
91+
Text(stringResource(R.string.install_app))
5592
}
5693
}
94+
}
95+
}
96+
}
5797

58-
Button(
59-
onClick = vm::installApk,
60-
enabled = vm.canInstall
61-
) {
62-
Text(stringResource(R.string.install_app))
98+
// Credits: https://github.com/Aliucord/AliucordManager/blob/main/app/src/main/kotlin/com/aliucord/manager/ui/component/installer/InstallGroup.kt
99+
100+
@Composable
101+
fun InstallGroup(group: StepGroup) {
102+
var expanded by rememberSaveable { mutableStateOf(true) }
103+
Column(
104+
modifier = Modifier
105+
.padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp)
106+
.fillMaxWidth()
107+
.clip(RoundedCornerShape(16.dp))
108+
.run {
109+
if (expanded) {
110+
background(MaterialTheme.colorScheme.secondaryContainer)
111+
} else this
63112
}
113+
) {
114+
Row(
115+
verticalAlignment = Alignment.CenterVertically,
116+
horizontalArrangement = Arrangement.spacedBy(12.dp),
117+
modifier = Modifier
118+
.fillMaxWidth()
119+
.padding(start = 16.dp, end = 16.dp)
120+
.run { if (expanded) {
121+
background(MaterialTheme.colorScheme.secondaryContainer)
122+
} else
123+
background(MaterialTheme.colorScheme.surface)
124+
}
125+
) {
126+
StepIcon(group.status, 24.dp)
127+
128+
Text(text = stringResource(group.name), style = MaterialTheme.typography.titleMedium)
129+
130+
Spacer(modifier = Modifier.weight(1f))
64131

65-
Button(
66-
onClick = { exportApkLauncher.launch("${vm.packageName}.apk") },
67-
enabled = vm.canInstall
132+
IconButton(onClick = { expanded = !expanded }) {
133+
if (expanded) {
134+
Icon(
135+
imageVector = Icons.Filled.KeyboardArrowUp,
136+
contentDescription = "collapse"
137+
)
138+
} else {
139+
Icon(
140+
imageVector = Icons.Filled.KeyboardArrowDown,
141+
contentDescription = "expand"
142+
)
143+
}
144+
}
145+
}
146+
147+
AnimatedVisibility(visible = expanded) {
148+
Column(
149+
verticalArrangement = Arrangement.spacedBy(16.dp),
150+
modifier = Modifier
151+
.background(MaterialTheme.colorScheme.background.copy(0.6f))
152+
.fillMaxWidth()
153+
.padding(16.dp)
154+
.padding(start = 4.dp)
68155
) {
69-
Text(stringResource(R.string.export_app))
156+
group.steps.forEach {
157+
Row(
158+
verticalAlignment = Alignment.CenterVertically,
159+
horizontalArrangement = Arrangement.spacedBy(16.dp),
160+
) {
161+
StepIcon(it.status, size = 18.dp)
162+
163+
Text(
164+
text = it.name,
165+
style = MaterialTheme.typography.titleSmall,
166+
maxLines = 1,
167+
overflow = TextOverflow.Ellipsis,
168+
modifier = Modifier.weight(1f, true),
169+
)
170+
}
171+
}
70172
}
71173
}
72174
}
73-
}
175+
}
176+
177+
@Composable
178+
fun StepIcon(status: StepStatus, size: Dp) {
179+
val strokeWidth = Dp(floor(size.value / 10) + 1)
180+
181+
when (status) {
182+
StepStatus.COMPLETED -> Icon(
183+
Icons.Filled.CheckCircle,
184+
contentDescription = "success",
185+
tint = MaterialTheme.colorScheme.surfaceTint,
186+
modifier = Modifier.size(size)
187+
)
188+
189+
StepStatus.FAILURE -> Icon(
190+
Icons.Filled.Cancel,
191+
contentDescription = "failed",
192+
tint = MaterialTheme.colorScheme.error,
193+
modifier = Modifier.size(size)
194+
)
195+
196+
StepStatus.WAITING -> CircularProgressIndicator(
197+
strokeWidth = strokeWidth,
198+
modifier = Modifier
199+
.size(size)
200+
.semantics {
201+
contentDescription = "waiting"
202+
}
203+
)
204+
}
205+
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<string name="patcher_step_group_patching">Patching</string>
7777
<string name="patcher_step_group_saving">Saving</string>
7878
<string name="patcher_step_write_patched">Write patched Apk</string>
79+
<string name="more">More</string>
7980
<string name="donate">Donate</string>
8081
<string name="website">Website</string>
8182
<string name="github">GitHub</string>

0 commit comments

Comments
 (0)