mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-28 04:20:20 +02:00
fix(better_location): suspend location updates
Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
This commit is contained in:
parent
a633f913d3
commit
0688c276bb
@ -255,6 +255,42 @@ class BetterLocationRoot : Routes.Route() {
|
||||
.fillMaxSize()
|
||||
.clipToBounds()
|
||||
) {
|
||||
|
||||
item {
|
||||
@Composable
|
||||
fun ConfigToggle(
|
||||
text: String,
|
||||
state: MutableState<Boolean>,
|
||||
onCheckedChange: (Boolean) -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(text = text)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Switch(
|
||||
checked = state.value,
|
||||
onCheckedChange = {
|
||||
state.value = it
|
||||
onCheckedChange(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
ConfigToggle(
|
||||
translation["spoof_location_toggle"],
|
||||
remember { mutableStateOf(context.config.root.global.betterLocation.spoofLocation.get()) }
|
||||
) {
|
||||
context.config.root.global.betterLocation.spoofLocation.set(it)
|
||||
}
|
||||
ConfigToggle(
|
||||
translation["suspend_location_updates"],
|
||||
remember { mutableStateOf(context.config.root.global.betterLocation.suspendLocationUpdates.get()) }
|
||||
) {
|
||||
context.config.root.global.betterLocation.suspendLocationUpdates.set(it)
|
||||
}
|
||||
}
|
||||
item {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@ -271,23 +307,6 @@ class BetterLocationRoot : Routes.Route() {
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
Row(
|
||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(text = translation["spoof_location_toggle"])
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
var isSpoofing by remember { mutableStateOf(context.config.root.global.betterLocation.spoofLocation.get()) }
|
||||
Switch(
|
||||
checked = isSpoofing,
|
||||
onCheckedChange = {
|
||||
isSpoofing = it
|
||||
context.config.root.global.betterLocation.spoofLocation.set(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
item {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
|
@ -150,7 +150,7 @@
|
||||
"no_files_hint": "Here you can import files for use in Snapchat. Press the button below to import a file."
|
||||
},
|
||||
"better_location": {
|
||||
"spoofed_coordinates_title": "Spoofed Coordinates\nLat {latitude}, Lng {longitude}",
|
||||
"spoofed_coordinates_title": "Lat {latitude}, Lng {longitude}",
|
||||
"save_coordinates_dialog_title": "Save Coordinates",
|
||||
"saved_name_dialog_hint": "Saved Name",
|
||||
"latitude_dialog_hint": "Latitude",
|
||||
@ -159,6 +159,7 @@
|
||||
"choose_location_button": "Choose Location",
|
||||
"teleport_to_friend_button": "Teleport to Friend",
|
||||
"spoof_location_toggle": "Spoof Location",
|
||||
"suspend_location_updates": "Suspend Location Updates",
|
||||
"saved_coordinates_title": "Saved Coordinates",
|
||||
"no_saved_coordinates_hint": "No saved coordinates",
|
||||
"delete_dialog_title": "Delete Saved Coordinate",
|
||||
@ -778,7 +779,7 @@
|
||||
},
|
||||
"suspend_location_updates": {
|
||||
"name": "Suspend Location Updates",
|
||||
"description": "Adds a button in map settings to suspend location updates"
|
||||
"description": "Prevents your location from being updated"
|
||||
},
|
||||
"spoof_battery_level": {
|
||||
"name": "Spoof Battery Level",
|
||||
@ -1624,9 +1625,6 @@
|
||||
"bitmoji_scene_changed": "{username} has changed their Bitmoji scene"
|
||||
},
|
||||
|
||||
"suspend_location_updates": {
|
||||
"switch_text": "Suspend Location Updates"
|
||||
},
|
||||
"material3_strings": {
|
||||
"date_range_picker_start_headline": "From",
|
||||
"date_range_picker_end_headline": "To",
|
||||
|
@ -30,7 +30,6 @@ enum class InternalFileHandleType(
|
||||
CONFIG("config", "config.json"),
|
||||
MAPPINGS("mappings", "mappings.json"),
|
||||
MESSAGE_LOGGER("message_logger", "message_logger.db", isDatabase = true),
|
||||
SUSPEND_LOCATION_STATE("suspend_location_state", "suspend_location_state.txt"),
|
||||
PINNED_BEST_FRIEND("pinned_best_friend", "pinned_best_friend.txt");
|
||||
|
||||
|
||||
|
@ -20,11 +20,11 @@ class Global : ConfigContainer() {
|
||||
}
|
||||
|
||||
inner class BetterLocationConfig : ConfigContainer(hasGlobalState = true) {
|
||||
val spoofLocation = boolean("spoof_location") { requireRestart() }
|
||||
val spoofLocation = boolean("spoof_location")
|
||||
val coordinates = mapCoordinates("coordinates", 0.0 to 0.0) { addFlags(ConfigFlag.SENSITIVE) } // lat, long
|
||||
val walkRadius = string("walk_radius") { requireRestart(); inputCheck = { it.toDoubleOrNull()?.isFinite() == true && it.toDouble() >= 0.0 } }
|
||||
val alwaysUpdateLocation = boolean("always_update_location") { requireRestart() }
|
||||
val suspendLocationUpdates = boolean("suspend_location_updates") { requireRestart() }
|
||||
val suspendLocationUpdates = boolean("suspend_location_updates")
|
||||
val spoofBatteryLevel = string("spoof_battery_level") { requireRestart(); inputCheck = { it.isEmpty() || it.toIntOrNull() in 0..100 } }
|
||||
val spoofHeadphones = boolean("spoof_headphones") { requireRestart() }
|
||||
}
|
||||
|
@ -107,7 +107,6 @@ class FeatureManager(
|
||||
MessageIndicators(),
|
||||
EditTextOverride(),
|
||||
PreventForcedLogout(),
|
||||
SuspendLocationUpdates(),
|
||||
ConversationToolbox(),
|
||||
SpotlightCommentsUsername(),
|
||||
OperaViewerParamsOverride(),
|
||||
|
@ -26,7 +26,6 @@ import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent
|
||||
import me.rhunk.snapenhance.core.event.events.impl.UnaryCallEvent
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
import me.rhunk.snapenhance.core.features.FeatureLoadParams
|
||||
import me.rhunk.snapenhance.core.features.impl.global.SuspendLocationUpdates
|
||||
import me.rhunk.snapenhance.core.util.RandomWalking
|
||||
import me.rhunk.snapenhance.core.util.hook.HookStage
|
||||
import me.rhunk.snapenhance.core.util.hook.hook
|
||||
@ -35,7 +34,6 @@ import me.rhunk.snapenhance.core.util.ktx.isDarkTheme
|
||||
import me.rhunk.snapenhance.mapper.impl.CallbackMapper
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.UUID
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
data class FriendLocation(
|
||||
val userId: String,
|
||||
@ -91,11 +89,10 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams
|
||||
remove(7)
|
||||
addVarInt(7, System.currentTimeMillis()) // timestamp
|
||||
}
|
||||
}
|
||||
|
||||
if (context.feature(SuspendLocationUpdates::class).isSuspended()) {
|
||||
remove(7)
|
||||
addVarInt(7, System.currentTimeMillis() - 15.days.inWholeMilliseconds)
|
||||
}
|
||||
if (context.config.global.betterLocation.suspendLocationUpdates.get()) {
|
||||
remove(1)
|
||||
}
|
||||
|
||||
// SCVSDeviceData
|
||||
@ -172,19 +169,18 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams
|
||||
override fun init() {
|
||||
if (context.config.global.betterLocation.globalState != true) return
|
||||
|
||||
if (context.config.global.betterLocation.spoofLocation.get()) {
|
||||
LocationManager::class.java.apply {
|
||||
hook("isProviderEnabled", HookStage.BEFORE) { it.setResult(true) }
|
||||
hook("isProviderEnabledForUser", HookStage.BEFORE) { it.setResult(true) }
|
||||
}
|
||||
Location::class.java.apply {
|
||||
hook("getLatitude", HookStage.BEFORE) { it.setResult(getLat()) }
|
||||
hook("getLongitude", HookStage.BEFORE) { it.setResult(getLong()) }
|
||||
}
|
||||
val canSpoofLocation = { context.config.global.betterLocation.spoofLocation.get() }
|
||||
|
||||
LocationManager::class.java.apply {
|
||||
hook("isProviderEnabled", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(true) }
|
||||
hook("isProviderEnabledForUser", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(true) }
|
||||
}
|
||||
Location::class.java.apply {
|
||||
hook("getLatitude", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(getLat()) }
|
||||
hook("getLongitude", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(getLong()) }
|
||||
}
|
||||
|
||||
val mapFeaturesRootId = context.resources.getId("map_features_root")
|
||||
val mapLayerSelectorId = context.resources.getId("map_layer_selector")
|
||||
|
||||
context.event.subscribe(AddViewEvent::class) { event ->
|
||||
if (event.view.id != mapFeaturesRootId) return@subscribe
|
||||
@ -234,10 +230,10 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams
|
||||
|
||||
context.mappings.useMapper(CallbackMapper::class) {
|
||||
callbacks.getClass("ServerStreamingEventHandler")?.hook("onEvent", HookStage.BEFORE) { param ->
|
||||
val buffer = param.arg<ByteBuffer>(1).let {
|
||||
val buffer = param.argNullable<ByteBuffer>(1)?.let {
|
||||
it.position(0)
|
||||
ByteArray(it.capacity()).also { buffer -> it.get(buffer); it.position(0) }
|
||||
}
|
||||
} ?: return@hook
|
||||
onLocationEvent(ProtoReader(buffer))
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
package me.rhunk.snapenhance.core.features.impl.global
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Switch
|
||||
import me.rhunk.snapenhance.common.bridge.InternalFileHandleType
|
||||
import me.rhunk.snapenhance.core.event.events.impl.LayoutInflateEvent
|
||||
import me.rhunk.snapenhance.core.features.BridgeFileFeature
|
||||
import me.rhunk.snapenhance.core.features.FeatureLoadParams
|
||||
import me.rhunk.snapenhance.core.ui.ViewAppearanceHelper
|
||||
import me.rhunk.snapenhance.core.util.ktx.getId
|
||||
import me.rhunk.snapenhance.core.util.ktx.getLayoutId
|
||||
|
||||
class SuspendLocationUpdates : BridgeFileFeature(
|
||||
"Suspend Location Updates",
|
||||
loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC, bridgeFileType = InternalFileHandleType.SUSPEND_LOCATION_STATE) {
|
||||
fun isSuspended() = exists("true")
|
||||
private fun setSuspended(suspended: Boolean) = setState("true", suspended)
|
||||
|
||||
override fun onActivityCreate() {
|
||||
if (context.config.global.betterLocation.takeIf { it.globalState == true }?.suspendLocationUpdates?.get() != true) return
|
||||
reload()
|
||||
|
||||
val locationSharingSettingsContainerId = context.resources.getLayoutId("v3_screen_location_sharing_settings")
|
||||
val recyclerViewContainerId = context.resources.getId("recycler_view_container")
|
||||
|
||||
context.event.subscribe(LayoutInflateEvent::class) { event ->
|
||||
if (event.layoutId != locationSharingSettingsContainerId) return@subscribe
|
||||
val viewGroup = event.view as? ViewGroup ?: return@subscribe
|
||||
viewGroup.post {
|
||||
val container = viewGroup.findViewById<ViewGroup>(recyclerViewContainerId)
|
||||
container.addView(Switch(event.view.context).apply {
|
||||
isChecked = isSuspended()
|
||||
ViewAppearanceHelper.applyTheme(this)
|
||||
text = this@SuspendLocationUpdates.context.translation["suspend_location_updates.switch_text"]
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
setSuspended(isChecked)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user