diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Navigation.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Navigation.kt
index f37d9500..4aaecdaa 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Navigation.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Navigation.kt
@@ -65,7 +65,7 @@ class Navigation(
val currentSection = getCurrentSection(currentDestination)
TopAppBar(title = {
- Text(text = currentSection.sectionTopBarName())
+ currentSection.Title()
}, navigationIcon = {
val backButtonAnimation by animateFloatAsState(if (currentSection.canGoBack()) 1f else 0f,
label = "backButtonAnimation"
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Section.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Section.kt
index 1b421365..ed1f8242 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Section.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/Section.kt
@@ -3,6 +3,7 @@ package me.rhunk.snapenhance.ui.manager
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.navigation.NavController
@@ -70,6 +71,9 @@ open class Section {
open fun sectionTopBarName(): String = context.translation["manager.routes.${enumSection.route}"]
open fun canGoBack(): Boolean = false
+ @Composable
+ open fun Title() { Text(text = sectionTopBarName()) }
+
@Composable
open fun Content() { NotImplemented() }
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSection.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSection.kt
index 96a4fd1f..58e38a55 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSection.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSection.kt
@@ -4,16 +4,15 @@ import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollState
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.*
+import androidx.compose.material.icons.filled.BugReport
+import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
@@ -21,7 +20,11 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -30,12 +33,11 @@ import androidx.navigation.compose.composable
import androidx.navigation.navigation
import kotlinx.coroutines.launch
import me.rhunk.snapenhance.R
+import me.rhunk.snapenhance.common.BuildConfig
import me.rhunk.snapenhance.ui.manager.Section
import me.rhunk.snapenhance.ui.manager.data.InstallationSummary
import me.rhunk.snapenhance.ui.manager.data.Updater
-import me.rhunk.snapenhance.ui.setup.Requirements
import me.rhunk.snapenhance.ui.util.ActivityLauncherHelper
-import me.rhunk.snapenhance.ui.util.saveFile
import java.util.Locale
class HomeSection : Section() {
@@ -56,31 +58,6 @@ class HomeSection : Section() {
activityLauncherHelper = ActivityLauncherHelper(context.activity!!)
}
- @Composable
- private fun SummaryCardRow(icon: ImageVector? = null, title: String, action: @Composable () -> Unit) {
- Row(
- modifier = Modifier.padding(all = 16.dp),
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- icon?.let {
- Icon(
- imageVector = it,
- contentDescription = null,
- modifier = Modifier
- .padding(end = 10.dp)
- .align(Alignment.CenterVertically)
- )
- }
- Text(text = title, modifier = Modifier
- .weight(1f)
- .align(Alignment.CenterVertically)
- )
- Column {
- action()
- }
- }
- }
-
@Composable
private fun SummaryCards(installationSummary: InstallationSummary) {
val summaryInfo = remember {
@@ -130,35 +107,6 @@ class HomeSection : Section() {
}
}
}
-
- OutlinedCard(
- modifier = Modifier
- .padding(all = cardMargin)
- .fillMaxWidth()
- ) {
- SummaryCardRow(
- icon = Icons.Filled.Map,
- title = if (installationSummary.modInfo == null || installationSummary.modInfo.mappingsOutdated == true) {
- "Mappings ${if (installationSummary.modInfo == null) "not generated" else "outdated"}"
- } else {
- "Mappings are up-to-date"
- }
- ) {
- Button(onClick = {
- context.checkForRequirements(Requirements.MAPPINGS)
- }, modifier = Modifier.height(40.dp)) {
- Icon(Icons.Filled.Refresh, contentDescription = null)
- }
- }
-
- SummaryCardRow(icon = Icons.Filled.Language, title = userLocale ?: "Unknown") {
- Button(onClick = {
- context.checkForRequirements(Requirements.LANGUAGE)
- }, modifier = Modifier.height(40.dp)) {
- Icon(Icons.Filled.OpenInNew, contentDescription = null)
- }
- }
- }
}
override fun onResumed() {
@@ -173,7 +121,9 @@ class HomeSection : Section() {
context.longToast("SnapEnhance failed to load installation summary: ${it.message}")
}
runCatching {
- latestUpdate = Updater.checkForLatestRelease()
+ if (!BuildConfig.DEBUG) {
+ latestUpdate = Updater.checkForLatestRelease()
+ }
}.onFailure {
context.longToast("SnapEnhance failed to check for updates: ${it.message}")
}
@@ -211,48 +161,7 @@ class HomeSection : Section() {
}
}
LOGS_SECTION_ROUTE -> {
- var showDropDown by remember { mutableStateOf(false) }
-
- IconButton(onClick = {
- showDropDown = true
- }) {
- Icon(Icons.Filled.MoreVert, contentDescription = null)
- }
-
- DropdownMenu(
- expanded = showDropDown,
- onDismissRequest = { showDropDown = false },
- modifier = Modifier.align(Alignment.CenterVertically)
- ) {
- DropdownMenuItem(onClick = {
- context.log.clearLogs()
- navController.navigate(LOGS_SECTION_ROUTE)
- showDropDown = false
- }, text = {
- Text(
- text = context.translation["manager.sections.home.logs.clear_logs_button"]
- )
- })
-
- DropdownMenuItem(onClick = {
- activityLauncherHelper.saveFile("snapenhance-logs-${System.currentTimeMillis()}.zip", "application/zip") { uri ->
- context.androidContext.contentResolver.openOutputStream(Uri.parse(uri))?.use {
- runCatching {
- context.log.exportLogsToZip(it)
- context.longToast("Saved logs to $uri")
- }.onFailure {
- context.longToast("Failed to save logs to $uri!")
- context.log.error("Failed to save logs to $uri!", it)
- }
- }
- }
- showDropDown = false
- }, text = {
- Text(
- text = context.translation["manager.sections.home.logs.export_logs_button"]
- )
- })
- }
+ homeSubSection.LogsTopBarButtons(activityLauncherHelper, navController, this)
}
}
}
@@ -279,30 +188,84 @@ class HomeSection : Section() {
@Composable
@Preview
override fun Content() {
+ val avenirNextFontFamily = remember {
+ FontFamily(
+ Font(R.font.avenir_next_medium, FontWeight.Medium)
+ )
+ }
+
Column(
modifier = Modifier
.verticalScroll(ScrollState(0))
) {
- Column(
+
+ Image(
+ painter = painterResource(id = R.drawable.launcher_icon_monochrome),
+ contentDescription = null,
+ colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
+ contentScale = ContentScale.FillHeight,
modifier = Modifier
+ .fillMaxWidth()
+ .scale(1.8f)
+ .height(90.dp)
+ )
+
+ Text(
+ text = arrayOf("\u0020", "\u0065", "\u0063", "\u006e", "\u0061", "\u0068", "\u006e", "\u0045", "\u0070", "\u0061", "\u006e", "\u0053").reversed().joinToString(""),
+ fontSize = 30.sp,
+ fontFamily = avenirNextFontFamily,
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ )
+
+ Text(
+ text = "v" + BuildConfig.VERSION_NAME + " \u00b7 by rhunk",
+ fontSize = 12.sp,
+ fontFamily = avenirNextFontFamily,
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ )
+
+ Text(
+ text = "An Xposed module made to enhance your Snapchat experience",
+ modifier = Modifier
+ .padding(16.dp)
.fillMaxWidth(),
- horizontalAlignment = Alignment.CenterHorizontally
+ textAlign = TextAlign.Center,
+ )
+
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(15.dp, Alignment.CenterHorizontally),
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(all = 10.dp)
) {
- Image(
- painter = painterResource(id = R.drawable.launcher_icon_monochrome),
+ Icon(
+ imageVector = ImageVector.vectorResource(id = R.drawable.ic_github),
contentDescription = null,
- colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
- contentScale = ContentScale.FillHeight,
- modifier = Modifier
- .height(120.dp)
- .scale(1.75f)
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.size(32.dp).clickable {
+ context.activity?.startActivity(
+ Intent(Intent.ACTION_VIEW).apply {
+ data = Uri.parse("https://github.com/rhunk/SnapEnhance")
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ }
+ )
+ }
)
- Text(
- text = arrayOf("\u0065", "\u0063", "\u006e", "\u0061", "\u0068", "\u006e", "\u0045", "\u0070", "\u0061", "\u006e", "\u0053").reversed().joinToString(""),
- fontSize = 30.sp,
- modifier = Modifier.padding(16.dp),
+ Icon(
+ imageVector = ImageVector.vectorResource(id = R.drawable.ic_telegram),
+ contentDescription = null,
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.size(32.dp).clickable {
+ context.activity?.startActivity(
+ Intent(Intent.ACTION_VIEW).apply {
+ data = Uri.parse("https://t.me/snapenhance")
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ }
+ )
+ }
)
}
+ Spacer(modifier = Modifier.height(20.dp))
if (latestUpdate != null) {
OutlinedCard(
@@ -345,11 +308,6 @@ class HomeSection : Section() {
}
}
- Text(
- text = "An Xposed module made to enhance your Snapchat experience",
- modifier = Modifier.padding(16.dp)
- )
-
SummaryCards(installationSummary = installationSummary ?: return)
}
}
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSubSection.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSubSection.kt
index f797549b..dc537bd1 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSubSection.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/HomeSubSection.kt
@@ -1,5 +1,6 @@
package me.rhunk.snapenhance.ui.manager.sections.home
+import android.net.Uri
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
@@ -10,14 +11,12 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardDoubleArrowDown
import androidx.compose.material.icons.filled.KeyboardDoubleArrowUp
+import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.outlined.BugReport
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Report
import androidx.compose.material.icons.outlined.Warning
-import androidx.compose.material3.FilledIconButton
-import androidx.compose.material3.Icon
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
+import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -28,6 +27,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.navigation.NavController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -36,8 +36,10 @@ import me.rhunk.snapenhance.LogReader
import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.common.logger.LogChannel
import me.rhunk.snapenhance.common.logger.LogLevel
+import me.rhunk.snapenhance.ui.util.ActivityLauncherHelper
import me.rhunk.snapenhance.ui.util.pullrefresh.PullRefreshIndicator
import me.rhunk.snapenhance.ui.util.pullrefresh.rememberPullRefreshState
+import me.rhunk.snapenhance.ui.util.saveFile
class HomeSubSection(
private val context: RemoteSideContext
@@ -170,6 +172,54 @@ class HomeSubSection(
}
}
+ @Composable
+ fun LogsTopBarButtons(activityLauncherHelper: ActivityLauncherHelper, navController: NavController, rowScope: RowScope) {
+ var showDropDown by remember { mutableStateOf(false) }
+
+ IconButton(onClick = {
+ showDropDown = true
+ }) {
+ Icon(Icons.Filled.MoreVert, contentDescription = null)
+ }
+
+ rowScope.apply {
+ DropdownMenu(
+ expanded = showDropDown,
+ onDismissRequest = { showDropDown = false },
+ modifier = Modifier.align(Alignment.CenterVertically)
+ ) {
+ DropdownMenuItem(onClick = {
+ context.log.clearLogs()
+ navController.navigate(HomeSection.LOGS_SECTION_ROUTE)
+ showDropDown = false
+ }, text = {
+ Text(
+ text = context.translation["manager.sections.home.logs.clear_logs_button"]
+ )
+ })
+
+ DropdownMenuItem(onClick = {
+ activityLauncherHelper.saveFile("snapenhance-logs-${System.currentTimeMillis()}.zip", "application/zip") { uri ->
+ context.androidContext.contentResolver.openOutputStream(Uri.parse(uri))?.use {
+ runCatching {
+ context.log.exportLogsToZip(it)
+ context.longToast("Saved logs to $uri")
+ }.onFailure {
+ context.longToast("Failed to save logs to $uri!")
+ context.log.error("Failed to save logs to $uri!", it)
+ }
+ }
+ }
+ showDropDown = false
+ }, text = {
+ Text(
+ text = context.translation["manager.sections.home.logs.export_logs_button"]
+ )
+ })
+ }
+ }
+ }
+
@Composable
fun LogsActionButtons() {
val coroutineScope = rememberCoroutineScope()
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/SettingsSection.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/SettingsSection.kt
index bc0377d2..100ad436 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/SettingsSection.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/sections/home/SettingsSection.kt
@@ -21,6 +21,7 @@ import me.rhunk.snapenhance.common.Constants
import me.rhunk.snapenhance.common.action.EnumAction
import me.rhunk.snapenhance.common.bridge.types.BridgeFileType
import me.rhunk.snapenhance.ui.manager.Section
+import me.rhunk.snapenhance.ui.setup.Requirements
import me.rhunk.snapenhance.ui.util.ActivityLauncherHelper
import me.rhunk.snapenhance.ui.util.AlertDialogs
import me.rhunk.snapenhance.ui.util.saveFile
@@ -63,7 +64,7 @@ class SettingsSection(
ShiftedRow(
modifier = Modifier
.fillMaxWidth()
- .height(65.dp)
+ .height(55.dp)
.clickable {
takeAction()
},
@@ -116,6 +117,12 @@ class SettingsSection(
launchActionIntent(enumAction)
}
}
+ RowAction(title = "Regenerate Mappings") {
+ context.checkForRequirements(Requirements.MAPPINGS)
+ }
+ RowAction(title = "Change Language") {
+ context.checkForRequirements(Requirements.LANGUAGE)
+ }
RowTitle(title = "Message Logger")
ShiftedRow {
Column(
@@ -227,6 +234,7 @@ class SettingsSection(
Text(text = "Clear")
}
}
+ Spacer(modifier = Modifier.height(50.dp))
}
}
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_github.xml b/app/src/main/res/drawable/ic_github.xml
new file mode 100644
index 00000000..daa9e101
--- /dev/null
+++ b/app/src/main/res/drawable/ic_github.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_telegram.xml b/app/src/main/res/drawable/ic_telegram.xml
new file mode 100644
index 00000000..ab02ef56
--- /dev/null
+++ b/app/src/main/res/drawable/ic_telegram.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/action/EnumAction.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/action/EnumAction.kt
index b7aa535b..e31ea259 100644
--- a/common/src/main/kotlin/me/rhunk/snapenhance/common/action/EnumAction.kt
+++ b/common/src/main/kotlin/me/rhunk/snapenhance/common/action/EnumAction.kt
@@ -7,10 +7,10 @@ enum class EnumAction(
val exitOnFinish: Boolean = false,
val isCritical: Boolean = false,
) {
- CLEAN_CACHE("clean_snapchat_cache", exitOnFinish = true),
EXPORT_CHAT_MESSAGES("export_chat_messages"),
EXPORT_MEMORIES("export_memories"),
- BULK_MESSAGING_ACTION("bulk_messaging_action");
+ BULK_MESSAGING_ACTION("bulk_messaging_action"),
+ CLEAN_CACHE("clean_snapchat_cache", exitOnFinish = true);
companion object {
const val ACTION_PARAMETER = "se_action"