From 00c5d60b7bed2be798fd84de1c5a718178c20339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=9ET=CE=9ERNAL?= Date: Sat, 28 Mar 2026 02:42:33 +0530 Subject: [PATCH] v1.5.8 --- .../purrfectsnap/ui/util/AlertDialogs.kt | 54 +++++++++ build.gradle.kts | 4 +- changelogs-stable.txt | 14 +++ .../purrfectsnap/core/SecurityFeatures.kt | 111 ++++++++++++------ gradle.properties | 4 +- 5 files changed, 148 insertions(+), 39 deletions(-) diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt index 50b7e5bc..f6a2b3fa 100644 --- a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt @@ -3,6 +3,7 @@ package me.eternal.purrfectsnap.ui.util import android.content.Context import android.view.MotionEvent import android.widget.Toast +import androidx.activity.compose.BackHandler import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.ScrollState import androidx.compose.foundation.background @@ -29,6 +30,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction @@ -56,6 +59,10 @@ import me.eternal.purrfectsnap.ui.manager.theme.PurrfectPalette import okhttp3.OkHttpClient import okhttp3.Request import org.osmdroid.config.Configuration +import org.osmdroid.events.MapEventsReceiver +import org.osmdroid.events.MapListener +import org.osmdroid.events.ScrollEvent +import org.osmdroid.events.ZoomEvent import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase import org.osmdroid.tileprovider.tilesource.TileSourceFactory import org.osmdroid.util.GeoPoint @@ -63,6 +70,7 @@ import org.osmdroid.util.MapTileIndex import org.osmdroid.views.CustomZoomButtonsController import org.osmdroid.views.MapView import org.osmdroid.views.overlay.Marker +import org.osmdroid.views.overlay.MapEventsOverlay import org.osmdroid.views.overlay.Overlay import java.io.File import me.eternal.purrfectsnap.ui.util.purrfectSwitchColors @@ -606,6 +614,13 @@ class AlertDialogs( } } val context = LocalContext.current + val focusManager = LocalFocusManager.current + val keyboardController = LocalSoftwareKeyboardController.current + + fun dismissKeyboard() { + keyboardController?.hide() + focusManager.clearFocus(force = true) + } mapView.value = remember { Configuration.getInstance().apply { @@ -642,12 +657,37 @@ class AlertDialogs( overlays.add(object: Overlay() { override fun onSingleTapConfirmed(e: MotionEvent, mapView: MapView): Boolean { + dismissKeyboard() marker.value?.position = mapView.projection.fromPixels(e.x.toInt(), e.y.toInt()) as GeoPoint mapView.invalidate() return true } }) + overlays.add(MapEventsOverlay(object : MapEventsReceiver { + override fun singleTapConfirmedHelper(p: GeoPoint?): Boolean { + dismissKeyboard() + return false + } + + override fun longPressHelper(p: GeoPoint?): Boolean { + dismissKeyboard() + return false + } + })) + + addMapListener(object : MapListener { + override fun onScroll(event: ScrollEvent?): Boolean { + dismissKeyboard() + return false + } + + override fun onZoom(event: ZoomEvent?): Boolean { + dismissKeyboard() + return false + } + }) + overlays.add(marker.value) } } @@ -702,6 +742,19 @@ class AlertDialogs( var searchJob by remember { mutableStateOf(null) } val resultsScrollState = rememberScrollState() + BackHandler { + val shouldDismissKeyboard = locationName.isNotEmpty() || addressResults.isNotEmpty() + if (shouldDismissKeyboard) { + dismissKeyboard() + locationName = "" + addressResults = emptyList() + searchJob?.cancel() + searchJob = null + } else { + dismiss() + } + } + suspend fun search() { if (locationSearchProvider == "google_maps") { // Google Maps Search @@ -946,6 +999,7 @@ class AlertDialogs( modifier = Modifier .fillMaxWidth() .clickable { + dismissKeyboard() marker.value?.position = GeoPoint(address.second.toDouble(), address.third.toDouble()) mapView.value?.controller?.setCenter(marker.value?.position) mapView.value?.invalidate() diff --git a/build.gradle.kts b/build.gradle.kts index f312ab5c..0d5bffa6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,8 +33,8 @@ tasks.register("getVersion") { } // You can still set these for legacy use by submodules or scripts: -rootProject.ext.set("appVersionName", providers.gradleProperty("APP_VERSION_NAME").orElse("1.5.6").get()) -rootProject.ext.set("appVersionCode", providers.gradleProperty("APP_VERSION_CODE").orElse("304").get().toInt()) +rootProject.ext.set("appVersionName", providers.gradleProperty("APP_VERSION_NAME").orElse("1.5.8").get()) +rootProject.ext.set("appVersionCode", providers.gradleProperty("APP_VERSION_CODE").orElse("306").get().toInt()) rootProject.ext.set("applicationId", "me.eternal.purrfectsnap") // buildHash: when PurrfectSnap or Snapchat is updated, mappings become outdated and auto-regenerate. // Include version code so each release has a different hash; use random for uniqueness within same version. diff --git a/changelogs-stable.txt b/changelogs-stable.txt index 0a85dd40..31e0ed33 100644 --- a/changelogs-stable.txt +++ b/changelogs-stable.txt @@ -1,3 +1,17 @@ +## v1.5.8 +- New: Implemented 30Mbps Video and 320kbps/48kHz Audio bitrates(tq to Kaladin) +- Fix: Advanced hardware ISP processing modes for superior dynamic range and less noisy video footage(tq to Kaladin) +- Fix: Optimized 1MB socket buffers for high-speed throughput which should upload the video/snap faster then before(tq to Kaladin) +- New: Aphelion Task page went full layout overhaul with segmented "Active" and "Scheduled" tab views(tq to Kaladin) +- FixL Auto-Open Status Card: Restored real-time visibility of processed snaps and queue status(tq to Kaladin) +- New: Smart trickle which has background processing with resource awareness (Paused/Trickle/Normal states)(tq to Kaladin) +- New: Four different states for auto open processing so that the device can be usable with auto open in the background(tq to Kaladin) +- Fix: memory hogging of the auto open queues, now the device should run much faster without any lag or stuttures(tq to Kaladin) +- Fix: "dot in username issue" with the implementation of unique incrementing ((1).jpg), where previously it was overwriting the previous file(tq to Kaladin) +- Fix: Lock Indicator for the snaps, which should now accurately be working on all versions(tq to Kaladin) +- Fix: Pressing back while keyboard is open in spoofed coordinates would close the dialog +- Fix: Not able to scroll in the "Can't Login?" dialog + ## v1.5.6 - New: Add "Can't login" hint directly in the login screen diff --git a/core/src/main/kotlin/me/eternal/purrfectsnap/core/SecurityFeatures.kt b/core/src/main/kotlin/me/eternal/purrfectsnap/core/SecurityFeatures.kt index 3a94b6e6..7e9eb4a1 100644 --- a/core/src/main/kotlin/me/eternal/purrfectsnap/core/SecurityFeatures.kt +++ b/core/src/main/kotlin/me/eternal/purrfectsnap/core/SecurityFeatures.kt @@ -7,8 +7,10 @@ import androidx.compose.foundation.background 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.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.HelpOutline @@ -153,6 +155,8 @@ class SecurityFeatures( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(14.dp) ) { + val scrollState = rememberScrollState() + Icon( Icons.Filled.Info, contentDescription = null, @@ -169,41 +173,78 @@ class SecurityFeatures( textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth() ) - Text( - text = context.translation["setup.mappings.notice_intro"], - color = PurrfectOverlayPalette.textSecondary, - textAlign = TextAlign.Start - ) - Text( - text = "For non-rooted users:", - color = PurrfectOverlayPalette.textPrimary, - fontWeight = FontWeight.SemiBold - ) - Text( - text = context.translation["setup.mappings.notice_step_1"], - color = PurrfectOverlayPalette.textSecondary, - textAlign = TextAlign.Start - ) - Text( - text = context.translation["setup.mappings.notice_step_2"], - color = PurrfectOverlayPalette.textSecondary, - textAlign = TextAlign.Start - ) - Text( - text = context.translation["setup.mappings.notice_step_3"], - color = PurrfectOverlayPalette.textSecondary, - textAlign = TextAlign.Start - ) - Text( - text = context.translation["setup.mappings.notice_rooted_title"], - color = PurrfectOverlayPalette.textPrimary, - fontWeight = FontWeight.SemiBold - ) - Text( - text = context.translation["setup.mappings.notice_rooted_body"], - color = PurrfectOverlayPalette.textSecondary, - textAlign = TextAlign.Start - ) + Box( + modifier = Modifier + .fillMaxWidth() + .heightIn(max = 360.dp) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(end = 10.dp) + .verticalScroll(scrollState), + verticalArrangement = Arrangement.spacedBy(14.dp) + ) { + Text( + text = context.translation["setup.mappings.notice_intro"], + color = PurrfectOverlayPalette.textSecondary, + textAlign = TextAlign.Start + ) + Text( + text = "For non-rooted users:", + color = PurrfectOverlayPalette.textPrimary, + fontWeight = FontWeight.SemiBold + ) + Text( + text = context.translation["setup.mappings.notice_step_1"], + color = PurrfectOverlayPalette.textSecondary, + textAlign = TextAlign.Start + ) + Text( + text = context.translation["setup.mappings.notice_step_2"], + color = PurrfectOverlayPalette.textSecondary, + textAlign = TextAlign.Start + ) + Text( + text = context.translation["setup.mappings.notice_step_3"], + color = PurrfectOverlayPalette.textSecondary, + textAlign = TextAlign.Start + ) + Text( + text = context.translation["setup.mappings.notice_rooted_title"], + color = PurrfectOverlayPalette.textPrimary, + fontWeight = FontWeight.SemiBold + ) + Text( + text = context.translation["setup.mappings.notice_rooted_body"], + color = PurrfectOverlayPalette.textSecondary, + textAlign = TextAlign.Start + ) + } + + val maxScroll = scrollState.maxValue + val thumbRatio = if (maxScroll > 0) { + ((scrollState.value.toFloat() / maxScroll.toFloat()) * 0.7f).coerceIn(0f, 0.7f) + } else 0f + Box( + modifier = Modifier + .align(Alignment.CenterEnd) + .width(4.dp) + .fillMaxHeight() + .background(Color.White.copy(alpha = 0.08f), RoundedCornerShape(999.dp)) + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(if (maxScroll > 0) 0.28f else 1f) + .offset(y = (320.dp * thumbRatio)) + .background( + PurrfectOverlayPalette.glowSecondary.copy(alpha = 0.75f), + RoundedCornerShape(999.dp) + ) + ) + } + } Button( onClick = onDismiss, colors = ButtonDefaults.buttonColors( diff --git a/gradle.properties b/gradle.properties index e28dc4bf..2612a4c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,8 +7,8 @@ org.gradle.configuration-cache=true org.gradle.configuration-cache.problems=warn nativeAbis=arm64-v8a -APP_VERSION_NAME=1.5.6 -APP_VERSION_CODE=304 +APP_VERSION_NAME=1.5.8 +APP_VERSION_CODE=306 debug_build_hash=18fe2a814d0e2eb5 psIntegrityPinnedSha256= EXPECTED_CERT_SHA256=0f188cb17d8ea4902ee15ce98f4928ba4226a4790fa3c52f62d776b08e46ca1c