mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-04-29 22:24:35 +02:00
refactor: reorganize (#15)
* refactor: organization (1/?) open for ideas and suggestions TODO: • Merge UI Hide Elements • Remove Longitude and Latitude from the menu and integrate into the MapActivity • Move New Map UI to Experimental • Shorten „Show Message Content in Notification“ And possibly even more * Merge hide UI Elements bugfix(?): merge overlay * add: download options * add: config listeners * fix(ci): debug remove prod as it's not getting built anymore * fix(messagelogger): clear database bug * update locale, reorganize config * add: set precise location dialog * config: better notifications --------- Co-authored-by: rhunk <101876869+rhunk@users.noreply.github.com>
This commit is contained in:
parent
cfb0ba5d65
commit
85335dafa8
5
.github/workflows/android.yml
vendored
5
.github/workflows/android.yml
vendored
@ -34,8 +34,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: app-armv7-release
|
name: app-armv7-release
|
||||||
path: app/build/outputs/apk/armv7/debug/*.apk
|
path: app/build/outputs/apk/armv7/debug/*.apk
|
||||||
- name: Upload prod
|
|
||||||
uses: actions/upload-artifact@v3.1.2
|
|
||||||
with:
|
|
||||||
name: app-prod-release
|
|
||||||
path: app/build/outputs/apk/prod/debug/*.apk
|
|
||||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,10 +1,9 @@
|
|||||||
*.iml
|
*.iml
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
local.properties
|
||||||
/.idea/
|
/.idea/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
.cxx
|
.cxx
|
||||||
local.properties
|
|
@ -1,22 +1,16 @@
|
|||||||
{
|
{
|
||||||
"category": {
|
"category": {
|
||||||
"general": "General",
|
"spying_privacy": "Spying & Privacy",
|
||||||
"spying": "Spying",
|
"media_manager": "Media Manager",
|
||||||
"media_download": "Media Downloader",
|
"ui_tweaks": "UI & Tweaks",
|
||||||
"privacy": "Privacy",
|
"experimental_debugging": "Experimental"
|
||||||
"ui": "UI",
|
|
||||||
"extras": "Extras",
|
|
||||||
"tweaks": "Tweaks",
|
|
||||||
"location_spoof": "Location Spoof",
|
|
||||||
"experimental": "Experimental",
|
|
||||||
"debugging": "Debugging"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"action": {
|
"action": {
|
||||||
"clean_cache": "Clean Cache",
|
"clean_cache": "Clean Cache",
|
||||||
"clear_message_logger": "Clear Message Logger",
|
"clear_message_logger": "Clear Message Logger",
|
||||||
"refresh_mappings": "Refresh Mappings",
|
"refresh_mappings": "Refresh Mappings",
|
||||||
"open_map": "Pick a location on the map"
|
"open_map": "Choose location on map"
|
||||||
},
|
},
|
||||||
|
|
||||||
"property": {
|
"property": {
|
||||||
@ -24,16 +18,14 @@
|
|||||||
"prevent_read_receipts": "Prevent Read Receipts",
|
"prevent_read_receipts": "Prevent Read Receipts",
|
||||||
"hide_bitmoji_presence": "Hide Bitmoji Presence",
|
"hide_bitmoji_presence": "Hide Bitmoji Presence",
|
||||||
"show_message_content_in_notifications": "Show Message Content In Notifications",
|
"show_message_content_in_notifications": "Show Message Content In Notifications",
|
||||||
|
"better_notifications": "Better Notifications",
|
||||||
"notification_blacklist": "Notification Blacklist",
|
"notification_blacklist": "Notification Blacklist",
|
||||||
"message_logger": "Message Logger",
|
"message_logger": "Message Logger",
|
||||||
"unlimited_snap_view_time": "Unlimited Snap View Time",
|
"unlimited_snap_view_time": "Unlimited Snap View Time",
|
||||||
"auto_download_snaps": "Auto Download Snaps",
|
"auto_download_options": "Auto Download Options",
|
||||||
"auto_download_stories": "Auto Download Stories",
|
|
||||||
"auto_download_public_stories": "Auto Download Public Stories",
|
|
||||||
"auto_download_spotlight": "Auto Download Spotlight",
|
|
||||||
"download_options": "Download Options",
|
"download_options": "Download Options",
|
||||||
"download_inchat_snaps": "Download Inchat Snaps",
|
"chat_download_context_menu": "Enable Chat Download Context Menu",
|
||||||
"anti_auto_download_button": "Anti Auto Download Button",
|
"auto_download_blacklist": "Auto Download Blacklist",
|
||||||
"disable_metrics": "Disable Metrics",
|
"disable_metrics": "Disable Metrics",
|
||||||
"prevent_screenshot_notifications": "Prevent Screenshot Notifications",
|
"prevent_screenshot_notifications": "Prevent Screenshot Notifications",
|
||||||
"prevent_status_notifications": "Prevent Status Notifications (Save to camera roll, missed calls)",
|
"prevent_status_notifications": "Prevent Status Notifications (Save to camera roll, missed calls)",
|
||||||
@ -42,7 +34,7 @@
|
|||||||
"menu_slot_id": "Friend Menu Slot ID",
|
"menu_slot_id": "Friend Menu Slot ID",
|
||||||
"message_preview_length": "Message Preview Length",
|
"message_preview_length": "Message Preview Length",
|
||||||
"gallery_media_send_override": "Gallery Media Send Override",
|
"gallery_media_send_override": "Gallery Media Send Override",
|
||||||
"auto_save": "Auto Save",
|
"auto_save_messages": "Auto Save Messages",
|
||||||
"anti_auto_save": "Anti Auto Save Button",
|
"anti_auto_save": "Anti Auto Save Button",
|
||||||
"snapchat_plus": "Snapchat Plus",
|
"snapchat_plus": "Snapchat Plus",
|
||||||
"disable_snap_splitting": "Disable Snap Splitting",
|
"disable_snap_splitting": "Disable Snap Splitting",
|
||||||
@ -62,11 +54,17 @@
|
|||||||
"meo_passcode_bypass": "My Eyes Only Passcode Bypass",
|
"meo_passcode_bypass": "My Eyes Only Passcode Bypass",
|
||||||
"location_spoof": "Snapmap Location Spoofer",
|
"location_spoof": "Snapmap Location Spoofer",
|
||||||
"latitude_value": "Latitude",
|
"latitude_value": "Latitude",
|
||||||
"longitude_value": "Longitude"
|
"longitude_value": "Longitude",
|
||||||
|
"hide_ui_elements": "Hide UI Elements"
|
||||||
},
|
},
|
||||||
|
|
||||||
"option": {
|
"option": {
|
||||||
"property": {
|
"property": {
|
||||||
|
"better_notifications": {
|
||||||
|
"chat": "Show chat messages",
|
||||||
|
"snap": "Show medias",
|
||||||
|
"reply_button": "Add reply button"
|
||||||
|
},
|
||||||
"download_options": {
|
"download_options": {
|
||||||
"format_user_folder": "Create folder for each user",
|
"format_user_folder": "Create folder for each user",
|
||||||
"format_hash": "Add a unique hash to the file path",
|
"format_hash": "Add a unique hash to the file path",
|
||||||
@ -74,10 +72,46 @@
|
|||||||
"format_date_time": "Add the date and time to the file path",
|
"format_date_time": "Add the date and time to the file path",
|
||||||
"merge_overlay": "Merge Snap Image Overlays"
|
"merge_overlay": "Merge Snap Image Overlays"
|
||||||
},
|
},
|
||||||
|
"auto_download_options": {
|
||||||
|
"friend_snaps": "Friend Snaps",
|
||||||
|
"friend_stories": "Friend Stories",
|
||||||
|
"public_stories": "Public Stories",
|
||||||
|
"spotlight": "Spotlight"
|
||||||
|
},
|
||||||
|
"auto_save_messages": {
|
||||||
|
"NOTE": "Audio Note",
|
||||||
|
"CHAT": "Chat",
|
||||||
|
"EXTERNAL_MEDIA": "External Media",
|
||||||
|
"SNAP": "Snap",
|
||||||
|
"STICKER": "Sticker"
|
||||||
|
},
|
||||||
"notification_blacklist": {
|
"notification_blacklist": {
|
||||||
"chat": "Chat",
|
"chat": "Chat",
|
||||||
"snap": "Snap",
|
"snap": "Snap",
|
||||||
"typing": "Typing"
|
"typing": "Typing"
|
||||||
|
},
|
||||||
|
"gallery_media_send_override": {
|
||||||
|
"OFF": "Off",
|
||||||
|
"NOTE": "Audio Note",
|
||||||
|
"SNAP": "Snap",
|
||||||
|
"LIVE_SNAP": "Snap with audio"
|
||||||
|
},
|
||||||
|
"media_quality_level": {
|
||||||
|
"LEVEL_NONE": "Level None",
|
||||||
|
"LEVEL_1": "Level 1",
|
||||||
|
"LEVEL_2": "Level 2",
|
||||||
|
"LEVEL_3": "Level 3",
|
||||||
|
"LEVEL_4": "Level 4",
|
||||||
|
"LEVEL_5": "Level 5",
|
||||||
|
"LEVEL_6": "Level 6",
|
||||||
|
"LEVEL_7": "Level 7",
|
||||||
|
"LEVEL_MAX": "Level Max"
|
||||||
|
},
|
||||||
|
"hide_ui_elements": {
|
||||||
|
"remove_call_buttons": "Remove Call Buttons",
|
||||||
|
"remove_cognac_button": "Remove Cognac Button",
|
||||||
|
"remove_stickers_button": "Remove Stickers Button",
|
||||||
|
"remove_voice_record_button": "Remove Voice Record Button"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -94,6 +128,12 @@
|
|||||||
"preview": "Preview"
|
"preview": "Preview"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"chat_action_menu": {
|
||||||
|
"preview_button": "Preview",
|
||||||
|
"download_button": "Download",
|
||||||
|
"delete_logged_message_button": "Delete Logged Message"
|
||||||
|
},
|
||||||
|
|
||||||
"opera_context_menu": {
|
"opera_context_menu": {
|
||||||
"download": "Download Media"
|
"download": "Download Media"
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,7 @@ class MessageLoggerRequest(
|
|||||||
override fun write(bundle: Bundle) {
|
override fun write(bundle: Bundle) {
|
||||||
bundle.putString("action", action!!.name)
|
bundle.putString("action", action!!.name)
|
||||||
bundle.putString("conversationId", conversationId)
|
bundle.putString("conversationId", conversationId)
|
||||||
bundle.putLong("messageId", messageId!!)
|
bundle.putLong("messageId", messageId ?: 0)
|
||||||
bundle.putByteArray("message", message)
|
bundle.putByteArray("message", message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,8 @@ package me.rhunk.snapenhance.config
|
|||||||
enum class ConfigCategory(
|
enum class ConfigCategory(
|
||||||
val key: String
|
val key: String
|
||||||
) {
|
) {
|
||||||
GENERAL("category.general"),
|
SPYING_PRIVACY("category.spying_privacy"),
|
||||||
SPYING("category.spying"),
|
MEDIA_MANAGEMENT("category.media_manager"),
|
||||||
MEDIA_DOWNLOADER("category.media_download"),
|
UI_TWEAKS("category.ui_tweaks"),
|
||||||
PRIVACY("category.privacy"),
|
EXPERIMENTAL_DEBUGGING("category.experimental_debugging");
|
||||||
UI("category.ui"),
|
|
||||||
EXTRAS("category.extras"),
|
|
||||||
TWEAKS("category.tweaks"),
|
|
||||||
LOCATION_SPOOF("category.location_spoof"),
|
|
||||||
EXPERIMENTAL("category.experimental");
|
|
||||||
}
|
}
|
||||||
|
@ -12,30 +12,45 @@ enum class ConfigProperty(
|
|||||||
val nameKey: String,
|
val nameKey: String,
|
||||||
val descriptionKey: String,
|
val descriptionKey: String,
|
||||||
val category: ConfigCategory,
|
val category: ConfigCategory,
|
||||||
val valueContainer: ConfigValue<*>
|
val valueContainer: ConfigValue<*>,
|
||||||
|
val shouldAppearInSettings: Boolean = true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
//SPYING AND PRIVACY
|
||||||
|
MESSAGE_LOGGER("property.message_logger",
|
||||||
|
"description.message_logger",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
PREVENT_READ_RECEIPTS(
|
PREVENT_READ_RECEIPTS(
|
||||||
"property.prevent_read_receipts",
|
"property.prevent_read_receipts",
|
||||||
"description.prevent_read_receipts",
|
"description.prevent_read_receipts",
|
||||||
ConfigCategory.SPYING,
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
HIDE_BITMOJI_PRESENCE(
|
HIDE_BITMOJI_PRESENCE(
|
||||||
"property.hide_bitmoji_presence",
|
"property.hide_bitmoji_presence",
|
||||||
"description.hide_bitmoji_presence",
|
"description.hide_bitmoji_presence",
|
||||||
ConfigCategory.SPYING,
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
SHOW_MESSAGE_CONTENT_IN_NOTIFICATIONS(
|
BETTER_NOTIFICATIONS(
|
||||||
"property.show_message_content_in_notifications",
|
"property.better_notifications",
|
||||||
"description.show_message_content_in_notifications",
|
"description.better_notifications",
|
||||||
ConfigCategory.SPYING,
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
ConfigStateValue(false)
|
ConfigStateListValue(
|
||||||
|
listOf("snap", "chat", "reply_button"),
|
||||||
|
mutableMapOf(
|
||||||
|
"snap" to false,
|
||||||
|
"chat" to false,
|
||||||
|
"reply_button" to false
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
NOTIFICATION_BLACKLIST(
|
NOTIFICATION_BLACKLIST(
|
||||||
"property.notification_blacklist",
|
"property.notification_blacklist",
|
||||||
"description.notification_blacklist",
|
"description.notification_blacklist",
|
||||||
ConfigCategory.SPYING,
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
ConfigStateListValue(
|
ConfigStateListValue(
|
||||||
listOf("snap", "chat", "typing"),
|
listOf("snap", "chat", "typing"),
|
||||||
mutableMapOf(
|
mutableMapOf(
|
||||||
@ -45,43 +60,68 @@ enum class ConfigProperty(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
DISABLE_METRICS("property.disable_metrics",
|
||||||
MESSAGE_LOGGER("property.message_logger", "description.message_logger", ConfigCategory.SPYING, ConfigStateValue(false)),
|
"description.disable_metrics",
|
||||||
UNLIMITED_SNAP_VIEW_TIME("property.unlimited_snap_view_time", "description.unlimited_snap_view_time", ConfigCategory.SPYING, ConfigStateValue(false)),
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
BLOCK_ADS("property.block_ads",
|
||||||
|
"description.block_ads",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
UNLIMITED_SNAP_VIEW_TIME("property.unlimited_snap_view_time",
|
||||||
|
"description.unlimited_snap_view_time",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
PREVENT_SCREENSHOT_NOTIFICATIONS(
|
||||||
|
"property.prevent_screenshot_notifications",
|
||||||
|
"description.prevent_screenshot_notifications",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
PREVENT_STATUS_NOTIFICATIONS(
|
||||||
|
"property.prevent_status_notifications",
|
||||||
|
"description.prevent_status_notifications",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
ANONYMOUS_STORY_VIEW(
|
||||||
|
"property.anonymous_story_view",
|
||||||
|
"description.anonymous_story_view",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
HIDE_TYPING_NOTIFICATION(
|
||||||
|
"property.hide_typing_notification",
|
||||||
|
"description.hide_typing_notification",
|
||||||
|
ConfigCategory.SPYING_PRIVACY,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
|
||||||
|
//MEDIA MANAGEMENT
|
||||||
SAVE_FOLDER(
|
SAVE_FOLDER(
|
||||||
"property.save_folder", "description.save_folder", ConfigCategory.MEDIA_DOWNLOADER,
|
"property.save_folder", "description.save_folder", ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStringValue(File(
|
ConfigStringValue(File(
|
||||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).absolutePath + "/Snapchat",
|
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).absolutePath + "/Snapchat",
|
||||||
"SnapEnhance"
|
"SnapEnhance"
|
||||||
).absolutePath)
|
).absolutePath)
|
||||||
),
|
),
|
||||||
AUTO_DOWNLOAD_SNAPS(
|
AUTO_DOWNLOAD_OPTIONS(
|
||||||
"property.auto_download_snaps",
|
"property.auto_download_options", "description.auto_download_options", ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
"description.auto_download_snaps",
|
ConfigStateListValue(
|
||||||
ConfigCategory.MEDIA_DOWNLOADER,
|
listOf("friend_snaps", "friend_stories", "public_stories", "spotlight"),
|
||||||
ConfigStateValue(false)
|
mutableMapOf(
|
||||||
),
|
"friend_snaps" to false,
|
||||||
AUTO_DOWNLOAD_STORIES(
|
"friend_stories" to false,
|
||||||
"property.auto_download_stories",
|
"public_stories" to false,
|
||||||
"description.auto_download_stories",
|
"spotlight" to false
|
||||||
ConfigCategory.MEDIA_DOWNLOADER,
|
)
|
||||||
ConfigStateValue(false)
|
)
|
||||||
),
|
|
||||||
AUTO_DOWNLOAD_PUBLIC_STORIES(
|
|
||||||
"property.auto_download_public_stories",
|
|
||||||
"description.auto_download_public_stories",
|
|
||||||
ConfigCategory.MEDIA_DOWNLOADER,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
AUTO_DOWNLOAD_SPOTLIGHT(
|
|
||||||
"property.auto_download_spotlight",
|
|
||||||
"description.auto_download_spotlight",
|
|
||||||
ConfigCategory.MEDIA_DOWNLOADER,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
),
|
||||||
DOWNLOAD_OPTIONS(
|
DOWNLOAD_OPTIONS(
|
||||||
"property.download_options", "description.download_options", ConfigCategory.MEDIA_DOWNLOADER,
|
"property.download_options", "description.download_options", ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateListValue(
|
ConfigStateListValue(
|
||||||
listOf("format_user_folder", "format_hash", "format_date_time", "format_username", "merge_overlay"),
|
listOf("format_user_folder", "format_hash", "format_date_time", "format_username", "merge_overlay"),
|
||||||
mutableMapOf(
|
mutableMapOf(
|
||||||
@ -93,167 +133,154 @@ enum class ConfigProperty(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
DOWNLOAD_INCHAT_SNAPS(
|
CHAT_DOWNLOAD_CONTEXT_MENU(
|
||||||
"property.download_inchat_snaps",
|
"property.chat_download_context_menu",
|
||||||
"description.download_inchat_snaps",
|
"description.chat_download_context_menu",
|
||||||
ConfigCategory.MEDIA_DOWNLOADER,
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
ANTI_DOWNLOAD_BUTTON(
|
DOWNLOAD_BLACKLIST(
|
||||||
"property.anti_auto_download_button",
|
"property.auto_download_blacklist",
|
||||||
"description.anti_auto_download_button",
|
"description.auto_download_blacklist",
|
||||||
ConfigCategory.MEDIA_DOWNLOADER,
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
|
|
||||||
DISABLE_METRICS("property.disable_metrics", "description.disable_metrics", ConfigCategory.PRIVACY, ConfigStateValue(false)),
|
|
||||||
PREVENT_SCREENSHOT_NOTIFICATIONS(
|
|
||||||
"property.prevent_screenshot_notifications",
|
|
||||||
"description.prevent_screenshot_notifications",
|
|
||||||
ConfigCategory.PRIVACY,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
PREVENT_STATUS_NOTIFICATIONS(
|
|
||||||
"property.prevent_status_notifications",
|
|
||||||
"description.prevent_status_notifications",
|
|
||||||
ConfigCategory.PRIVACY,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
ANONYMOUS_STORY_VIEW(
|
|
||||||
"property.anonymous_story_view",
|
|
||||||
"description.anonymous_story_view",
|
|
||||||
ConfigCategory.PRIVACY,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
HIDE_TYPING_NOTIFICATION(
|
|
||||||
"property.hide_typing_notification",
|
|
||||||
"description.hide_typing_notification",
|
|
||||||
ConfigCategory.PRIVACY,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
|
|
||||||
MENU_SLOT_ID("property.menu_slot_id", "description.menu_slot_id", ConfigCategory.UI, ConfigIntegerValue(1)),
|
|
||||||
MESSAGE_PREVIEW_LENGTH(
|
|
||||||
"property.message_preview_length",
|
|
||||||
"description.message_preview_length",
|
|
||||||
ConfigCategory.UI,
|
|
||||||
ConfigIntegerValue(20)
|
|
||||||
),
|
|
||||||
|
|
||||||
AUTO_SAVE("property.auto_save", "description.auto_save", ConfigCategory.EXTRAS, ConfigStateValue(false)),
|
|
||||||
ANTI_AUTO_SAVE("property.anti_auto_save", "description.anti_auto_save", ConfigCategory.EXTRAS, ConfigStateValue(false)),
|
|
||||||
SNAPCHAT_PLUS("property.snapchat_plus", "description.snapchat_plus", ConfigCategory.EXTRAS, ConfigStateValue(false)),
|
|
||||||
DISABLE_SNAP_SPLITTING(
|
|
||||||
"property.disable_snap_splitting",
|
|
||||||
"description.disable_snap_splitting",
|
|
||||||
ConfigCategory.EXTRAS,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
DISABLE_VIDEO_LENGTH_RESTRICTION(
|
|
||||||
"property.disable_video_length_restriction",
|
|
||||||
"description.disable_video_length_restriction",
|
|
||||||
ConfigCategory.EXTRAS,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
OVERRIDE_MEDIA_QUALITY(
|
|
||||||
"property.override_media_quality",
|
|
||||||
"description.override_media_quality",
|
|
||||||
ConfigCategory.EXTRAS,
|
|
||||||
ConfigStateValue(false)
|
|
||||||
),
|
|
||||||
MEDIA_QUALITY_LEVEL(
|
|
||||||
"property.media_quality_level",
|
|
||||||
"description.media_quality_level",
|
|
||||||
ConfigCategory.EXTRAS,
|
|
||||||
ConfigStateSelection(
|
|
||||||
listOf("LEVEL_NONE", "LEVEL_1", "LEVEL_2", "LEVEL_3", "LEVEL_4", "LEVEL_5", "LEVEL_6", "LEVEL_7", "LEVEL_MAX"),
|
|
||||||
"LEVEL_NONE"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
GALLERY_MEDIA_SEND_OVERRIDE(
|
GALLERY_MEDIA_SEND_OVERRIDE(
|
||||||
"property.gallery_media_send_override",
|
"property.gallery_media_send_override",
|
||||||
"description.gallery_media_send_override",
|
"description.gallery_media_send_override",
|
||||||
ConfigCategory.EXTRAS,
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateSelection(
|
ConfigStateSelection(
|
||||||
listOf("OFF", "NOTE", "SNAP", "LIVE_SNAP"),
|
listOf("OFF", "NOTE", "SNAP", "LIVE_SNAP"),
|
||||||
"OFF"
|
"OFF"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
AUTO_SAVE_MESSAGES("property.auto_save_messages",
|
||||||
REMOVE_VOICE_RECORD_BUTTON(
|
"description.auto_save_messages",
|
||||||
"property.remove_voice_record_button",
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
"description.remove_voice_record_button",
|
ConfigStateListValue(
|
||||||
ConfigCategory.TWEAKS,
|
listOf("CHAT", "SNAP", "NOTE", "EXTERNAL_MEDIA", "STICKER")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ANTI_AUTO_SAVE("property.anti_auto_save",
|
||||||
|
"description.anti_auto_save",
|
||||||
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
REMOVE_STICKERS_BUTTON(
|
|
||||||
"property.remove_stickers_button",
|
OVERRIDE_MEDIA_QUALITY(
|
||||||
"description.remove_stickers_button",
|
"property.override_media_quality",
|
||||||
ConfigCategory.TWEAKS,
|
"description.override_media_quality",
|
||||||
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
REMOVE_COGNAC_BUTTON(
|
MEDIA_QUALITY_LEVEL(
|
||||||
"property.remove_cognac_button",
|
"property.media_quality_level",
|
||||||
"description.remove_cognac_button",
|
"description.media_quality_level",
|
||||||
ConfigCategory.TWEAKS,
|
ConfigCategory.MEDIA_MANAGEMENT,
|
||||||
ConfigStateValue(false)
|
ConfigStateSelection(
|
||||||
|
listOf("LEVEL_NONE", "LEVEL_1", "LEVEL_2", "LEVEL_3", "LEVEL_4", "LEVEL_5", "LEVEL_6", "LEVEL_7", "LEVEL_MAX"),
|
||||||
|
"LEVEL_NONE"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
REMOVE_CALL_BUTTONS(
|
|
||||||
"property.remove_call_buttons",
|
//UI AND TWEAKS
|
||||||
"description.remove_call_buttons",
|
HIDE_UI_ELEMENTS(
|
||||||
ConfigCategory.TWEAKS,
|
"property.hide_ui_elements",
|
||||||
ConfigStateValue(false)
|
"description.hide_ui_elements",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigStateListValue(
|
||||||
|
listOf("remove_voice_record_button", "remove_stickers_button", "remove_cognac_button", "remove_call_buttons"),
|
||||||
|
mutableMapOf(
|
||||||
|
"remove_voice_record_button" to false,
|
||||||
|
"remove_stickers_button" to false,
|
||||||
|
"remove_cognac_button" to false,
|
||||||
|
"remove_call_buttons" to false,
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
BLOCK_ADS("property.block_ads", "description.block_ads", ConfigCategory.TWEAKS, ConfigStateValue(false)),
|
|
||||||
STREAK_EXPIRATION_INFO(
|
STREAK_EXPIRATION_INFO(
|
||||||
"property.streak_expiration_info",
|
"property.streak_expiration_info",
|
||||||
"description.streakexpirationinfo",
|
"description.streakexpirationinfo",
|
||||||
ConfigCategory.TWEAKS,
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
DISABLE_SNAP_SPLITTING(
|
||||||
|
"property.disable_snap_splitting",
|
||||||
|
"description.disable_snap_splitting",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
DISABLE_VIDEO_LENGTH_RESTRICTION(
|
||||||
|
"property.disable_video_length_restriction",
|
||||||
|
"description.disable_video_length_restriction",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
SNAPCHAT_PLUS("property.snapchat_plus",
|
||||||
|
"description.snapchat_plus",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigStateValue(false)
|
||||||
|
),
|
||||||
|
NEW_MAP_UI("property.new_map_ui",
|
||||||
|
"description.new_map_ui",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
NEW_MAP_UI("property.new_map_ui", "description.new_map_ui", ConfigCategory.TWEAKS, ConfigStateValue(false)),
|
|
||||||
|
|
||||||
LOCATION_SPOOF(
|
LOCATION_SPOOF(
|
||||||
"property.location_spoof",
|
"property.location_spoof",
|
||||||
"description.location_spoof",
|
"description.location_spoof",
|
||||||
ConfigCategory.LOCATION_SPOOF,
|
ConfigCategory.UI_TWEAKS,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
LATITUDE(
|
LATITUDE(
|
||||||
"property.latitude_value",
|
"property.latitude_value",
|
||||||
"description.latitude_value",
|
"description.latitude_value",
|
||||||
ConfigCategory.LOCATION_SPOOF,
|
ConfigCategory.UI_TWEAKS,
|
||||||
ConfigStringValue("0.0000")
|
ConfigStringValue("0.0000"),
|
||||||
|
shouldAppearInSettings = false
|
||||||
),
|
),
|
||||||
LONGITUDE(
|
LONGITUDE(
|
||||||
"property.longitude_value",
|
"property.longitude_value",
|
||||||
"description.longitude_value",
|
"description.longitude_value",
|
||||||
ConfigCategory.LOCATION_SPOOF,
|
ConfigCategory.UI_TWEAKS,
|
||||||
ConfigStringValue("0.0000")
|
ConfigStringValue("0.0000"),
|
||||||
|
shouldAppearInSettings = false
|
||||||
),
|
),
|
||||||
|
MENU_SLOT_ID("property.menu_slot_id",
|
||||||
|
"description.menu_slot_id",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigIntegerValue(1)
|
||||||
|
),
|
||||||
|
MESSAGE_PREVIEW_LENGTH(
|
||||||
|
"property.message_preview_length",
|
||||||
|
"description.message_preview_length",
|
||||||
|
ConfigCategory.UI_TWEAKS,
|
||||||
|
ConfigIntegerValue(20)
|
||||||
|
),
|
||||||
|
|
||||||
|
// EXPERIMENTAL DEBUGGING
|
||||||
USE_DOWNLOAD_MANAGER(
|
USE_DOWNLOAD_MANAGER(
|
||||||
"property.use_download_manager",
|
"property.use_download_manager",
|
||||||
"description.use_download_manager",
|
"description.use_download_manager",
|
||||||
ConfigCategory.EXPERIMENTAL,
|
ConfigCategory.EXPERIMENTAL_DEBUGGING,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
APP_PASSCODE(
|
APP_PASSCODE(
|
||||||
"property.app_passcode",
|
"property.app_passcode",
|
||||||
"description.app_passcode",
|
"description.app_passcode",
|
||||||
ConfigCategory.EXPERIMENTAL,
|
ConfigCategory.EXPERIMENTAL_DEBUGGING,
|
||||||
ConfigStringValue("")
|
ConfigStringValue("", isHidden = true)
|
||||||
),
|
),
|
||||||
APP_LOCK_ON_RESUME(
|
APP_LOCK_ON_RESUME(
|
||||||
"property.app_lock_on_resume",
|
"property.app_lock_on_resume",
|
||||||
"description.app_lock_on_resume",
|
"description.app_lock_on_resume",
|
||||||
ConfigCategory.EXPERIMENTAL,
|
ConfigCategory.EXPERIMENTAL_DEBUGGING,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
),
|
),
|
||||||
MEO_PASSCODE_BYPASS(
|
MEO_PASSCODE_BYPASS(
|
||||||
"property.meo_passcode_bypass",
|
"property.meo_passcode_bypass",
|
||||||
"description.meo_passcode_bypass",
|
"description.meo_passcode_bypass",
|
||||||
ConfigCategory.EXPERIMENTAL,
|
ConfigCategory.EXPERIMENTAL_DEBUGGING,
|
||||||
ConfigStateValue(false)
|
ConfigStateValue(false)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,7 +1,22 @@
|
|||||||
package me.rhunk.snapenhance.config
|
package me.rhunk.snapenhance.config
|
||||||
|
|
||||||
abstract class ConfigValue<T> {
|
abstract class ConfigValue<T> {
|
||||||
|
private val propertyChangeListeners = mutableListOf<(T) -> Unit>()
|
||||||
|
|
||||||
|
fun addPropertyChangeListener(listener: (T) -> Unit) = propertyChangeListeners.add(listener)
|
||||||
|
fun removePropertyChangeListener(listener: (T) -> Unit) = propertyChangeListeners.remove(listener)
|
||||||
|
|
||||||
abstract fun value(): T
|
abstract fun value(): T
|
||||||
abstract fun write(): String
|
abstract fun read(): String
|
||||||
abstract fun read(value: String)
|
protected abstract fun write(value: String)
|
||||||
|
|
||||||
|
protected fun onValueChanged() {
|
||||||
|
propertyChangeListeners.forEach { it(value()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun writeFrom(value: String) {
|
||||||
|
val oldValue = read()
|
||||||
|
write(value)
|
||||||
|
if (oldValue != value) onValueChanged()
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,15 +3,15 @@ package me.rhunk.snapenhance.config.impl
|
|||||||
import me.rhunk.snapenhance.config.ConfigValue
|
import me.rhunk.snapenhance.config.ConfigValue
|
||||||
|
|
||||||
class ConfigIntegerValue(
|
class ConfigIntegerValue(
|
||||||
var value: Int
|
private var value: Int
|
||||||
) : ConfigValue<Int>() {
|
) : ConfigValue<Int>() {
|
||||||
override fun value() = value
|
override fun value() = value
|
||||||
|
|
||||||
override fun write(): String {
|
override fun read(): String {
|
||||||
return value.toString()
|
return value.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(value: String) {
|
override fun write(value: String) {
|
||||||
this.value = value.toInt()
|
this.value = value.toInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,17 +4,22 @@ import me.rhunk.snapenhance.config.ConfigValue
|
|||||||
|
|
||||||
class ConfigStateListValue(
|
class ConfigStateListValue(
|
||||||
private val keys: List<String>,
|
private val keys: List<String>,
|
||||||
var states: MutableMap<String, Boolean> = mutableMapOf()
|
private var states: MutableMap<String, Boolean> = mutableMapOf()
|
||||||
) : ConfigValue<Map<String, Boolean>>() {
|
) : ConfigValue<Map<String, Boolean>>() {
|
||||||
override fun value() = states
|
override fun value() = states
|
||||||
|
|
||||||
fun value(key: String) = states[key] ?: false
|
fun setKey(key: String, state: Boolean) {
|
||||||
|
states[key] = state
|
||||||
|
onValueChanged()
|
||||||
|
}
|
||||||
|
|
||||||
override fun write(): String {
|
operator fun get(key: String) = states[key] ?: false
|
||||||
|
|
||||||
|
override fun read(): String {
|
||||||
return keys.joinToString("|") { "$it:${states[it]}" }
|
return keys.joinToString("|") { "$it:${states[it]}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(value: String) {
|
override fun write(value: String) {
|
||||||
value.split("|").forEach {
|
value.split("|").forEach {
|
||||||
val (key, state) = it.split(":")
|
val (key, state) = it.split(":")
|
||||||
states[key] = state.toBoolean()
|
states[key] = state.toBoolean()
|
||||||
|
@ -4,25 +4,19 @@ import me.rhunk.snapenhance.config.ConfigValue
|
|||||||
|
|
||||||
class ConfigStateSelection(
|
class ConfigStateSelection(
|
||||||
private val keys: List<String>,
|
private val keys: List<String>,
|
||||||
var state: String = ""
|
private var state: String = ""
|
||||||
) : ConfigValue<String>() {
|
) : ConfigValue<String>() {
|
||||||
|
|
||||||
fun keys(): List<String> {
|
fun keys(): List<String> {
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
override fun value(): String {
|
|
||||||
|
override fun value() = state
|
||||||
|
|
||||||
|
override fun read(): String {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
fun value(key: String) {
|
override fun write(value: String) {
|
||||||
state = key
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun write(): String {
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(value: String) {
|
|
||||||
state = value
|
state = value
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,15 +3,15 @@ package me.rhunk.snapenhance.config.impl
|
|||||||
import me.rhunk.snapenhance.config.ConfigValue
|
import me.rhunk.snapenhance.config.ConfigValue
|
||||||
|
|
||||||
class ConfigStateValue(
|
class ConfigStateValue(
|
||||||
var value: Boolean
|
private var value: Boolean
|
||||||
) : ConfigValue<Boolean>() {
|
) : ConfigValue<Boolean>() {
|
||||||
override fun value() = value
|
override fun value() = value
|
||||||
|
|
||||||
override fun write(): String {
|
override fun read(): String {
|
||||||
return value.toString()
|
return value.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(value: String) {
|
override fun write(value: String) {
|
||||||
this.value = value.toBoolean()
|
this.value = value.toBoolean()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,15 +3,18 @@ package me.rhunk.snapenhance.config.impl
|
|||||||
import me.rhunk.snapenhance.config.ConfigValue
|
import me.rhunk.snapenhance.config.ConfigValue
|
||||||
|
|
||||||
class ConfigStringValue(
|
class ConfigStringValue(
|
||||||
var value: String = ""
|
private var value: String = "",
|
||||||
|
val isHidden: Boolean = false
|
||||||
) : ConfigValue<String>() {
|
) : ConfigValue<String>() {
|
||||||
override fun value() = value
|
override fun value() = value
|
||||||
|
|
||||||
override fun write(): String {
|
fun hiddenValue() = if (isHidden) value.map { '*' }.joinToString("") else value
|
||||||
|
|
||||||
|
override fun read(): String {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun read(value: String) {
|
override fun write(value: String) {
|
||||||
this.value = value
|
this.value = value
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -60,7 +60,7 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun canMergeOverlay(): Boolean {
|
private fun canMergeOverlay(): Boolean {
|
||||||
if (context.config.options(ConfigProperty.DOWNLOAD_OPTIONS)["overlay_merge"] == false) return false
|
if (context.config.options(ConfigProperty.DOWNLOAD_OPTIONS)["merge_overlay"] == false) return false
|
||||||
return isFFmpegPresent
|
return isFFmpegPresent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,9 +228,7 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
|
|||||||
forceDownload: Boolean
|
forceDownload: Boolean
|
||||||
) {
|
) {
|
||||||
//messages
|
//messages
|
||||||
if (paramMap.containsKey("MESSAGE_ID") &&
|
paramMap["MESSAGE_ID"]?.toString()?.takeIf { forceDownload || canAutoDownload("friend_snaps") }?.let { id ->
|
||||||
(forceDownload || context.config.bool(ConfigProperty.AUTO_DOWNLOAD_SNAPS))) {
|
|
||||||
val id = paramMap["MESSAGE_ID"].toString()
|
|
||||||
val messageId = id.substring(id.lastIndexOf(":") + 1).toLong()
|
val messageId = id.substring(id.lastIndexOf(":") + 1).toLong()
|
||||||
val senderId: String = context.database.getConversationMessageFromId(messageId)!!.sender_id!!
|
val senderId: String = context.database.getConversationMessageFromId(messageId)!!.sender_id!!
|
||||||
|
|
||||||
@ -244,23 +242,25 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
|
|||||||
}
|
}
|
||||||
|
|
||||||
//private stories
|
//private stories
|
||||||
val playlistV2Group =
|
paramMap["PLAYLIST_V2_GROUP"]?.toString()?.takeIf {
|
||||||
if (paramMap.containsKey("PLAYLIST_V2_GROUP")) paramMap["PLAYLIST_V2_GROUP"].toString() else null
|
it.contains("storyUserId=") && (forceDownload || canAutoDownload("friend_stories"))
|
||||||
if (playlistV2Group != null &&
|
}?.let { playlistGroup ->
|
||||||
playlistV2Group.contains("storyUserId=") &&
|
val storyIdStartIndex = playlistGroup.indexOf("storyUserId=") + 12
|
||||||
(forceDownload || context.config.bool(ConfigProperty.AUTO_DOWNLOAD_STORIES))
|
val storyUserId = playlistGroup.substring(
|
||||||
) {
|
storyIdStartIndex,
|
||||||
val storyIdStartIndex = playlistV2Group.indexOf("storyUserId=") + 12
|
playlistGroup.indexOf(",", storyIdStartIndex)
|
||||||
val storyUserId = playlistV2Group.substring(storyIdStartIndex, playlistV2Group.indexOf(",", storyIdStartIndex))
|
)
|
||||||
val author = context.database.getFriendInfo(if (storyUserId == "null") context.database.getMyUserId()!! else storyUserId)
|
val author = context.database.getFriendInfo(if (storyUserId == "null") context.database.getMyUserId()!! else storyUserId)
|
||||||
|
|
||||||
downloadOperaMedia(mediaInfoMap, author!!.usernameForSorting!!)
|
downloadOperaMedia(mediaInfoMap, author!!.usernameForSorting!!)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val snapSource = paramMap["SNAP_SOURCE"].toString()
|
val snapSource = paramMap["SNAP_SOURCE"].toString()
|
||||||
|
|
||||||
//public stories
|
//public stories
|
||||||
if ((snapSource == "PUBLIC_USER" || snapSource == "SAVED_STORY") &&
|
if ((snapSource == "PUBLIC_USER" || snapSource == "SAVED_STORY") &&
|
||||||
(forceDownload || context.config.bool(ConfigProperty.AUTO_DOWNLOAD_PUBLIC_STORIES))) {
|
(forceDownload || canAutoDownload("public_stories"))) {
|
||||||
val userDisplayName = (if (paramMap.containsKey("USER_DISPLAY_NAME")) paramMap["USER_DISPLAY_NAME"].toString() else "").replace(
|
val userDisplayName = (if (paramMap.containsKey("USER_DISPLAY_NAME")) paramMap["USER_DISPLAY_NAME"].toString() else "").replace(
|
||||||
"[^\\x00-\\x7F]".toRegex(),
|
"[^\\x00-\\x7F]".toRegex(),
|
||||||
"")
|
"")
|
||||||
@ -269,7 +269,7 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
|
|||||||
}
|
}
|
||||||
|
|
||||||
//spotlight
|
//spotlight
|
||||||
if (snapSource == "SINGLE_SNAP_STORY" && (forceDownload || context.config.bool(ConfigProperty.AUTO_DOWNLOAD_SPOTLIGHT))) {
|
if (snapSource == "SINGLE_SNAP_STORY" && (forceDownload || canAutoDownload("spotlight"))) {
|
||||||
downloadOperaMedia(mediaInfoMap, "Spotlight")
|
downloadOperaMedia(mediaInfoMap, "Spotlight")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -323,11 +323,9 @@ class MediaDownloader : Feature("MediaDownloader", loadParams = FeatureLoadParam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canAutoDownload(): Boolean {
|
private fun canAutoDownload(keyFilter: String? = null): Boolean {
|
||||||
return context.config.bool(ConfigProperty.AUTO_DOWNLOAD_SNAPS) ||
|
val options = context.config.options(ConfigProperty.AUTO_DOWNLOAD_OPTIONS)
|
||||||
context.config.bool(ConfigProperty.AUTO_DOWNLOAD_STORIES) ||
|
return options.filter { it.value }.any { keyFilter == null || it.key.contains(keyFilter, true) }
|
||||||
context.config.bool(ConfigProperty.AUTO_DOWNLOAD_PUBLIC_STORIES) ||
|
|
||||||
context.config.bool(ConfigProperty.AUTO_DOWNLOAD_SPOTLIGHT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun asyncOnActivityCreate() {
|
override fun asyncOnActivityCreate() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.bridge.common.impl.file.BridgeFileType
|
import me.rhunk.snapenhance.bridge.common.impl.file.BridgeFileType
|
||||||
import me.rhunk.snapenhance.features.BridgeFileFeature
|
import me.rhunk.snapenhance.features.BridgeFileFeature
|
@ -1,8 +1,7 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.Logger
|
import me.rhunk.snapenhance.Logger
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
import me.rhunk.snapenhance.data.ContentType
|
|
||||||
import me.rhunk.snapenhance.data.MessageState
|
import me.rhunk.snapenhance.data.MessageState
|
||||||
import me.rhunk.snapenhance.data.wrapper.impl.Message
|
import me.rhunk.snapenhance.data.wrapper.impl.Message
|
||||||
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
|
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
|
||||||
@ -61,17 +60,14 @@ class AutoSave : Feature("Auto Save", loadParams = FeatureLoadParams.ACTIVITY_CR
|
|||||||
|
|
||||||
private fun canSaveMessage(message: Message): Boolean {
|
private fun canSaveMessage(message: Message): Boolean {
|
||||||
if (message.messageMetadata.savedBy.any { uuid -> uuid.toString() == myUserId }) return false
|
if (message.messageMetadata.savedBy.any { uuid -> uuid.toString() == myUserId }) return false
|
||||||
//only save chats
|
val contentType = message.messageContent.contentType.toString()
|
||||||
with(message.messageContent.contentType) {
|
|
||||||
if (this != ContentType.CHAT &&
|
return context.config.options(ConfigProperty.AUTO_SAVE_MESSAGES).filter { it.value }.any { it.key == contentType }
|
||||||
this != ContentType.NOTE &&
|
|
||||||
this != ContentType.STICKER &&
|
|
||||||
this != ContentType.EXTERNAL_MEDIA) return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canSave(): Boolean {
|
private fun canSave(): Boolean {
|
||||||
|
if (context.config.options(ConfigProperty.AUTO_SAVE_MESSAGES).none { it.value }) return false
|
||||||
|
|
||||||
with(context.feature(Messaging::class)) {
|
with(context.feature(Messaging::class)) {
|
||||||
if (lastOpenedConversationUUID == null) return@canSave false
|
if (lastOpenedConversationUUID == null) return@canSave false
|
||||||
val conversation = lastOpenedConversationUUID.toString()
|
val conversation = lastOpenedConversationUUID.toString()
|
||||||
@ -87,7 +83,7 @@ class AutoSave : Feature("Auto Save", loadParams = FeatureLoadParams.ACTIVITY_CR
|
|||||||
context.mappings.getMappedClass("callbacks", "FetchConversationWithMessagesCallback"),
|
context.mappings.getMappedClass("callbacks", "FetchConversationWithMessagesCallback"),
|
||||||
"onFetchConversationWithMessagesComplete",
|
"onFetchConversationWithMessagesComplete",
|
||||||
HookStage.BEFORE,
|
HookStage.BEFORE,
|
||||||
{ context.config.bool(ConfigProperty.AUTO_SAVE) && canSave()}
|
{ canSave() }
|
||||||
) { param ->
|
) { param ->
|
||||||
val conversationId = SnapUUID(param.arg<Any>(0).getObjectField("mConversationId")!!)
|
val conversationId = SnapUUID(param.arg<Any>(0).getObjectField("mConversationId")!!)
|
||||||
val messages = param.arg<List<Any>>(1).map { Message(it) }
|
val messages = param.arg<List<Any>>(1).map { Message(it) }
|
||||||
@ -104,7 +100,7 @@ class AutoSave : Feature("Auto Save", loadParams = FeatureLoadParams.ACTIVITY_CR
|
|||||||
context.mappings.getMappedClass("callbacks", "FetchMessageCallback"),
|
context.mappings.getMappedClass("callbacks", "FetchMessageCallback"),
|
||||||
"onFetchMessageComplete",
|
"onFetchMessageComplete",
|
||||||
HookStage.BEFORE,
|
HookStage.BEFORE,
|
||||||
{ context.config.bool(ConfigProperty.AUTO_SAVE) && canSave()}
|
{ canSave() }
|
||||||
) { param ->
|
) { param ->
|
||||||
val message = Message(param.arg(0))
|
val message = Message(param.arg(0))
|
||||||
if (!canSaveMessage(message)) return@hook
|
if (!canSaveMessage(message)) return@hook
|
||||||
@ -119,7 +115,7 @@ class AutoSave : Feature("Auto Save", loadParams = FeatureLoadParams.ACTIVITY_CR
|
|||||||
context.mappings.getMappedClass("callbacks", "SendMessageCallback"),
|
context.mappings.getMappedClass("callbacks", "SendMessageCallback"),
|
||||||
"onSuccess",
|
"onSuccess",
|
||||||
HookStage.BEFORE,
|
HookStage.BEFORE,
|
||||||
{ context.config.bool(ConfigProperty.AUTO_SAVE) && canSave()}
|
{ canSave() }
|
||||||
) {
|
) {
|
||||||
val callback = CallbackBuilder(fetchConversationWithMessagesCallbackClass).build()
|
val callback = CallbackBuilder(fetchConversationWithMessagesCallbackClass).build()
|
||||||
runCatching {
|
runCatching {
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
import me.rhunk.snapenhance.features.Feature
|
import me.rhunk.snapenhance.features.Feature
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
import me.rhunk.snapenhance.data.ContentType
|
import me.rhunk.snapenhance.data.ContentType
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
@ -17,8 +17,8 @@ class LocationSpoofer: Feature("LocationSpoof", loadParams = FeatureLoadParams.A
|
|||||||
val longitude = bundle.getFloat("longitude")
|
val longitude = bundle.getFloat("longitude")
|
||||||
|
|
||||||
with(context.config) {
|
with(context.config) {
|
||||||
get(ConfigProperty.LATITUDE).read(latitude.toString())
|
get(ConfigProperty.LATITUDE).writeFrom(latitude.toString())
|
||||||
get(ConfigProperty.LONGITUDE).read(longitude.toString())
|
get(ConfigProperty.LONGITUDE).writeFrom(longitude.toString())
|
||||||
writeConfig()
|
writeConfig()
|
||||||
}
|
}
|
||||||
context.longToast("Location set to $latitude, $longitude")
|
context.longToast("Location set to $latitude, $longitude")
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
import me.rhunk.snapenhance.features.Feature
|
import me.rhunk.snapenhance.features.Feature
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
@ -206,7 +206,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
else it
|
else it
|
||||||
}[MediaType.ORIGINAL] ?: throw Throwable("Failed to download media")
|
}[MediaType.ORIGINAL] ?: throw Throwable("Failed to download media")
|
||||||
|
|
||||||
val bitmapPreview = PreviewUtils.createPreview(downloadedMedia, mediaType == MediaReferenceType.VIDEO)!!
|
val bitmapPreview = PreviewUtils.createPreview(downloadedMedia, mediaType.name.contains("VIDEO"))!!
|
||||||
val notificationBuilder = XposedHelpers.newInstance(
|
val notificationBuilder = XposedHelpers.newInstance(
|
||||||
Notification.Builder::class.java,
|
Notification.Builder::class.java,
|
||||||
context.androidContext,
|
context.androidContext,
|
||||||
@ -227,7 +227,7 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contentType == ContentType.CHAT) {
|
if (contentType == ContentType.CHAT && context.config.options(ConfigProperty.BETTER_NOTIFICATIONS)["reply_button"] == true) {
|
||||||
setupNotificationActionButtons(conversationId, notificationData)
|
setupNotificationActionButtons(conversationId, notificationData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,9 +264,8 @@ class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.IN
|
|||||||
return@hook
|
return@hook
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.config.bool(ConfigProperty.SHOW_MESSAGE_CONTENT_IN_NOTIFICATIONS)) return@hook
|
if (context.config.options(ConfigProperty.BETTER_NOTIFICATIONS)
|
||||||
|
.filter { it.value }.none { notificationType.endsWith(it.key.uppercase())}) return@hook
|
||||||
if (!notificationType.endsWith("CHAT") && !notificationType.endsWith("SNAP")) return@hook
|
|
||||||
|
|
||||||
val conversationManager: Any = context.feature(Messaging::class).conversationManager
|
val conversationManager: Any = context.feature(Messaging::class).conversationManager
|
||||||
notificationDataQueue[messageId.toLong()] = notificationData
|
notificationDataQueue[messageId.toLong()] = notificationData
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
import me.rhunk.snapenhance.features.Feature
|
import me.rhunk.snapenhance.features.Feature
|
@ -1,4 +1,4 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.extras
|
package me.rhunk.snapenhance.features.impl.tweaks
|
||||||
|
|
||||||
import me.rhunk.snapenhance.config.ConfigProperty
|
import me.rhunk.snapenhance.config.ConfigProperty
|
||||||
import me.rhunk.snapenhance.data.ContentType
|
import me.rhunk.snapenhance.data.ContentType
|
@ -22,14 +22,15 @@ class UITweaks : Feature("UITweaks", loadParams = FeatureLoadParams.ACTIVITY_CRE
|
|||||||
val chatNoteRecordButton = resources.getIdentifier("chat_note_record_button", "id", Constants.SNAPCHAT_PACKAGE_NAME)
|
val chatNoteRecordButton = resources.getIdentifier("chat_note_record_button", "id", Constants.SNAPCHAT_PACKAGE_NAME)
|
||||||
val chatInputBarSticker = resources.getIdentifier("chat_input_bar_sticker", "id", Constants.SNAPCHAT_PACKAGE_NAME)
|
val chatInputBarSticker = resources.getIdentifier("chat_input_bar_sticker", "id", Constants.SNAPCHAT_PACKAGE_NAME)
|
||||||
val chatInputBarCognac = resources.getIdentifier("chat_input_bar_cognac", "id", Constants.SNAPCHAT_PACKAGE_NAME)
|
val chatInputBarCognac = resources.getIdentifier("chat_input_bar_cognac", "id", Constants.SNAPCHAT_PACKAGE_NAME)
|
||||||
|
val hiddenElements = context.config.options(ConfigProperty.HIDE_UI_ELEMENTS)
|
||||||
|
|
||||||
Hooker.hook(View::class.java, "setVisibility", HookStage.BEFORE) { methodParam ->
|
Hooker.hook(View::class.java, "setVisibility", HookStage.BEFORE) { methodParam ->
|
||||||
val viewId = (methodParam.thisObject() as View).id
|
val viewId = (methodParam.thisObject() as View).id
|
||||||
if (viewId == chatNoteRecordButton && context.config.bool(ConfigProperty.REMOVE_VOICE_RECORD_BUTTON)) {
|
if (viewId == chatNoteRecordButton && hiddenElements["remove_voice_record_button"] == true) {
|
||||||
methodParam.setArg(0, View.GONE)
|
methodParam.setArg(0, View.GONE)
|
||||||
}
|
}
|
||||||
if (viewId == callButton1 || viewId == callButton2) {
|
if (viewId == callButton1 || viewId == callButton2) {
|
||||||
if (!context.config.bool(ConfigProperty.REMOVE_CALL_BUTTONS)) return@hook
|
if (hiddenElements["remove_call_buttons"] == false) return@hook
|
||||||
methodParam.setArg(0, View.GONE)
|
methodParam.setArg(0, View.GONE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,23 +46,23 @@ class UITweaks : Feature("UITweaks", loadParams = FeatureLoadParams.ACTIVITY_CRE
|
|||||||
val view: View = param.arg(0)
|
val view: View = param.arg(0)
|
||||||
val viewId = view.id
|
val viewId = view.id
|
||||||
|
|
||||||
if (viewId == chatNoteRecordButton && context.config.bool(ConfigProperty.REMOVE_VOICE_RECORD_BUTTON)) {
|
if (viewId == chatNoteRecordButton && hiddenElements["remove_voice_record_button"] == true) {
|
||||||
view.isEnabled = false
|
view.isEnabled = false
|
||||||
view.setWillNotDraw(true)
|
view.setWillNotDraw(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chatInputBarCognac == viewId && context.config.bool(ConfigProperty.REMOVE_COGNAC_BUTTON)) {
|
if (chatInputBarCognac == viewId && hiddenElements["remove_cognac_button"] == true) {
|
||||||
view.visibility = View.GONE
|
view.visibility = View.GONE
|
||||||
}
|
}
|
||||||
if (chatInputBarSticker == viewId && context.config.bool(ConfigProperty.REMOVE_STICKERS_BUTTON)) {
|
if (chatInputBarSticker == viewId && hiddenElements["remove_stickers_button"] == true) {
|
||||||
view.visibility = View.GONE
|
view.visibility = View.GONE
|
||||||
}
|
}
|
||||||
if (viewId == callButton1 || viewId == callButton2) {
|
if (viewId == callButton1 || viewId == callButton2) {
|
||||||
if (!context.config.bool(ConfigProperty.REMOVE_CALL_BUTTONS)) return@hook
|
if (hiddenElements["remove_call_buttons"] == false) return@hook
|
||||||
if (view.visibility == View.GONE) return@hook
|
if (view.visibility == View.GONE) return@hook
|
||||||
}
|
}
|
||||||
if (viewId == callButtonsStub) {
|
if (viewId == callButtonsStub) {
|
||||||
if (!context.config.bool(ConfigProperty.REMOVE_CALL_BUTTONS)) return@hook
|
if (hiddenElements["remove_call_buttons"] == false) return@hook
|
||||||
param.setResult(null)
|
param.setResult(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package me.rhunk.snapenhance.features.impl.ui.menus
|
package me.rhunk.snapenhance.features.impl.ui.menus
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import android.widget.EditText
|
||||||
import me.rhunk.snapenhance.R
|
import me.rhunk.snapenhance.R
|
||||||
import org.osmdroid.config.Configuration
|
import org.osmdroid.config.Configuration
|
||||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
|
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
|
||||||
@ -20,12 +23,13 @@ class MapActivity : Activity() {
|
|||||||
|
|
||||||
private lateinit var mapView: MapView
|
private lateinit var mapView: MapView
|
||||||
|
|
||||||
|
@SuppressLint("MissingInflatedId", "ResourceType")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val contextBundle = intent.extras?.getBundle("location") ?: return
|
val contextBundle = intent.extras?.getBundle("location") ?: return
|
||||||
val latitude = contextBundle.getDouble("latitude")
|
val locationLatitude = contextBundle.getDouble("latitude")
|
||||||
val longitude = contextBundle.getDouble("longitude")
|
val locationLongitude = contextBundle.getDouble("longitude")
|
||||||
|
|
||||||
Configuration.getInstance().load(applicationContext, getSharedPreferences("osmdroid", Context.MODE_PRIVATE))
|
Configuration.getInstance().load(applicationContext, getSharedPreferences("osmdroid", Context.MODE_PRIVATE))
|
||||||
|
|
||||||
@ -35,7 +39,7 @@ class MapActivity : Activity() {
|
|||||||
mapView.setMultiTouchControls(true);
|
mapView.setMultiTouchControls(true);
|
||||||
mapView.setTileSource(TileSourceFactory.MAPNIK)
|
mapView.setTileSource(TileSourceFactory.MAPNIK)
|
||||||
|
|
||||||
val startPoint = GeoPoint(latitude, longitude)
|
val startPoint = GeoPoint(locationLatitude, locationLongitude)
|
||||||
mapView.controller.setZoom(10.0)
|
mapView.controller.setZoom(10.0)
|
||||||
mapView.controller.setCenter(startPoint)
|
mapView.controller.setCenter(startPoint)
|
||||||
|
|
||||||
@ -64,6 +68,28 @@ class MapActivity : Activity() {
|
|||||||
setResult(RESULT_OK, intent.putExtra("location", bundle))
|
setResult(RESULT_OK, intent.putExtra("location", bundle))
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val setPreciseLocationButton = findViewById<Button>(R.id.set_precise_location_button)
|
||||||
|
|
||||||
|
setPreciseLocationButton.setOnClickListener {
|
||||||
|
val locationDialog = layoutInflater.inflate(R.layout.precise_location_dialog, null)
|
||||||
|
val dialogLatitude = locationDialog.findViewById<EditText>(R.id.dialog_latitude).also { it.setText(marker.position.latitude.toString()) }
|
||||||
|
val dialogLongitude = locationDialog.findViewById<EditText>(R.id.dialog_longitude).also { it.setText(marker.position.longitude.toString()) }
|
||||||
|
|
||||||
|
AlertDialog.Builder(this)
|
||||||
|
.setView(locationDialog)
|
||||||
|
.setTitle("Set a precise location")
|
||||||
|
.setPositiveButton("Set") { _, _ ->
|
||||||
|
val latitude = dialogLatitude.text.toString().toDoubleOrNull()
|
||||||
|
val longitude = dialogLongitude.text.toString().toDoubleOrNull()
|
||||||
|
if (latitude != null && longitude != null) {
|
||||||
|
val preciseLocation = GeoPoint(latitude, longitude)
|
||||||
|
mapView.controller.setCenter(preciseLocation)
|
||||||
|
marker.position = preciseLocation
|
||||||
|
mapView.invalidate()
|
||||||
|
}
|
||||||
|
}.setNegativeButton("Cancel") { _, _ -> }.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
@ -64,34 +64,35 @@ class ChatActionMenu : AbstractMenu() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (context.config.bool(ConfigProperty.DOWNLOAD_INCHAT_SNAPS)) {
|
if (context.config.bool(ConfigProperty.CHAT_DOWNLOAD_CONTEXT_MENU)) {
|
||||||
val previewButton = Button(viewGroup.context)
|
parent.addView(Button(viewGroup.context).apply {
|
||||||
applyButtonTheme(parent, previewButton)
|
applyButtonTheme(parent, this)
|
||||||
previewButton.text = "Preview"
|
text = this@ChatActionMenu.context.translation.get("chat_action_menu.preview_button")
|
||||||
previewButton.setOnClickListener {
|
setOnClickListener {
|
||||||
closeActionMenu()
|
closeActionMenu()
|
||||||
context.executeAsync { context.feature(MediaDownloader::class).onMessageActionMenu(true) }
|
this@ChatActionMenu.context.executeAsync { this@ChatActionMenu.context.feature(MediaDownloader::class).onMessageActionMenu(true) }
|
||||||
}
|
}
|
||||||
parent.addView(previewButton)
|
})
|
||||||
}
|
|
||||||
|
|
||||||
//download snap in chat
|
parent.addView(Button(viewGroup.context).apply {
|
||||||
if (context.config.bool(ConfigProperty.DOWNLOAD_INCHAT_SNAPS)) {
|
applyButtonTheme(parent, this)
|
||||||
val downloadButton = Button(viewGroup.context)
|
text = this@ChatActionMenu.context.translation.get("chat_action_menu.download_button")
|
||||||
applyButtonTheme(parent, downloadButton)
|
setOnClickListener {
|
||||||
downloadButton.text = "Download"
|
closeActionMenu()
|
||||||
downloadButton.setOnClickListener {
|
this@ChatActionMenu.context.executeAsync {
|
||||||
closeActionMenu()
|
this@ChatActionMenu.context.feature(
|
||||||
context.executeAsync { context.feature(MediaDownloader::class).onMessageActionMenu(false) }
|
MediaDownloader::class
|
||||||
}
|
).onMessageActionMenu(false)
|
||||||
parent.addView(downloadButton)
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//delete logged message button
|
//delete logged message button
|
||||||
if (context.config.bool(ConfigProperty.MESSAGE_LOGGER)) {
|
if (context.config.bool(ConfigProperty.MESSAGE_LOGGER)) {
|
||||||
val downloadButton = Button(viewGroup.context)
|
val downloadButton = Button(viewGroup.context)
|
||||||
applyButtonTheme(parent, downloadButton)
|
applyButtonTheme(parent, downloadButton)
|
||||||
downloadButton.text = "Deleted logged message"
|
downloadButton.text = context.translation.get("chat_action_menu.delete_logged_message_button")
|
||||||
downloadButton.setOnClickListener {
|
downloadButton.setOnClickListener {
|
||||||
closeActionMenu()
|
closeActionMenu()
|
||||||
context.executeAsync {
|
context.executeAsync {
|
||||||
|
@ -21,7 +21,7 @@ import me.rhunk.snapenhance.database.objects.FriendInfo
|
|||||||
import me.rhunk.snapenhance.database.objects.UserConversationLink
|
import me.rhunk.snapenhance.database.objects.UserConversationLink
|
||||||
import me.rhunk.snapenhance.features.impl.Messaging
|
import me.rhunk.snapenhance.features.impl.Messaging
|
||||||
import me.rhunk.snapenhance.features.impl.downloader.AntiAutoDownload
|
import me.rhunk.snapenhance.features.impl.downloader.AntiAutoDownload
|
||||||
import me.rhunk.snapenhance.features.impl.extras.AntiAutoSave
|
import me.rhunk.snapenhance.features.impl.tweaks.AntiAutoSave
|
||||||
import me.rhunk.snapenhance.features.impl.spying.StealthMode
|
import me.rhunk.snapenhance.features.impl.spying.StealthMode
|
||||||
import me.rhunk.snapenhance.features.impl.ui.menus.AbstractMenu
|
import me.rhunk.snapenhance.features.impl.ui.menus.AbstractMenu
|
||||||
import me.rhunk.snapenhance.features.impl.ui.menus.ViewAppearanceHelper.applyTheme
|
import me.rhunk.snapenhance.features.impl.ui.menus.ViewAppearanceHelper.applyTheme
|
||||||
@ -215,7 +215,7 @@ class FriendFeedInfoMenu : AbstractMenu() {
|
|||||||
|
|
||||||
run {
|
run {
|
||||||
val userId = context.database.getFriendFeedInfoByConversationId(conversationId)?.friendUserId ?: return@run
|
val userId = context.database.getFriendFeedInfoByConversationId(conversationId)?.friendUserId ?: return@run
|
||||||
if (context.config.bool(ConfigProperty.ANTI_DOWNLOAD_BUTTON)) {
|
if (context.config.bool(ConfigProperty.DOWNLOAD_BLACKLIST)) {
|
||||||
createToggleFeature(viewModel,
|
createToggleFeature(viewModel,
|
||||||
viewConsumer,
|
viewConsumer,
|
||||||
"friend_menu_option.anti_auto_download",
|
"friend_menu_option.anti_auto_download",
|
||||||
|
@ -35,10 +35,11 @@ class SettingsMenu : AbstractMenu() {
|
|||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun createPropertyView(viewModel: View, property: ConfigProperty): View {
|
private fun createPropertyView(viewModel: View, property: ConfigProperty): View {
|
||||||
val updateButtonText: (TextView, String) -> Unit = { textView, text ->
|
val updateButtonText: (TextView, String) -> Unit = { textView, text ->
|
||||||
textView.text = "${context.translation.get(property.nameKey)} $text"
|
textView.text = "${context.translation.get(property.nameKey)}${if (text.isEmpty()) "" else ": $text"}"
|
||||||
}
|
}
|
||||||
val updateStateSelectionText: (TextView, String) -> Unit = { textView, text ->
|
|
||||||
updateButtonText(textView, text.let { if (it.isEmpty()) "(empty)" else ": $it" })
|
val updateLocalizedText: (TextView, String) -> Unit = { textView, value ->
|
||||||
|
updateButtonText(textView, value.let { if (it.isEmpty()) "(empty)" else context.translation.get("option." + property.nameKey + "." + it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
val textEditor: ((String) -> Unit) -> Unit = { updateValue ->
|
val textEditor: ((String) -> Unit) -> Unit = { updateValue ->
|
||||||
@ -61,23 +62,29 @@ class SettingsMenu : AbstractMenu() {
|
|||||||
val resultView: View = when (property.valueContainer) {
|
val resultView: View = when (property.valueContainer) {
|
||||||
is ConfigStringValue -> {
|
is ConfigStringValue -> {
|
||||||
val textView = TextView(viewModel.context)
|
val textView = TextView(viewModel.context)
|
||||||
updateButtonText(textView, property.valueContainer.value)
|
updateButtonText(textView, property.valueContainer.let {
|
||||||
|
if (it.isHidden) it.hiddenValue()
|
||||||
|
else it.value()
|
||||||
|
})
|
||||||
ViewAppearanceHelper.applyTheme(viewModel, textView)
|
ViewAppearanceHelper.applyTheme(viewModel, textView)
|
||||||
textView.setOnClickListener {
|
textView.setOnClickListener {
|
||||||
textEditor { value ->
|
textEditor { value ->
|
||||||
property.valueContainer.value = value
|
property.valueContainer.writeFrom(value)
|
||||||
updateButtonText(textView, value)
|
updateButtonText(textView, property.valueContainer.let {
|
||||||
|
if (it.isHidden) it.hiddenValue()
|
||||||
|
else it.value()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
textView
|
textView
|
||||||
}
|
}
|
||||||
is ConfigIntegerValue -> {
|
is ConfigIntegerValue -> {
|
||||||
val button = Button(viewModel.context)
|
val button = Button(viewModel.context)
|
||||||
updateButtonText(button, property.valueContainer.value.toString())
|
updateButtonText(button, property.valueContainer.value().toString())
|
||||||
button.setOnClickListener {
|
button.setOnClickListener {
|
||||||
textEditor { value ->
|
textEditor { value ->
|
||||||
runCatching {
|
runCatching {
|
||||||
property.valueContainer.value = value.toInt()
|
property.valueContainer.writeFrom(value)
|
||||||
updateButtonText(button, value)
|
updateButtonText(button, value)
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
context.shortToast("Invalid value")
|
context.shortToast("Invalid value")
|
||||||
@ -90,30 +97,30 @@ class SettingsMenu : AbstractMenu() {
|
|||||||
is ConfigStateValue -> {
|
is ConfigStateValue -> {
|
||||||
val switch = Switch(viewModel.context)
|
val switch = Switch(viewModel.context)
|
||||||
switch.text = context.translation.get(property.nameKey)
|
switch.text = context.translation.get(property.nameKey)
|
||||||
switch.isChecked = property.valueContainer.value
|
switch.isChecked = property.valueContainer.value()
|
||||||
switch.setOnCheckedChangeListener { _, isChecked ->
|
switch.setOnCheckedChangeListener { _, isChecked ->
|
||||||
property.valueContainer.value = isChecked
|
property.valueContainer.writeFrom(isChecked.toString())
|
||||||
}
|
}
|
||||||
ViewAppearanceHelper.applyTheme(viewModel, switch)
|
ViewAppearanceHelper.applyTheme(viewModel, switch)
|
||||||
switch
|
switch
|
||||||
}
|
}
|
||||||
is ConfigStateSelection -> {
|
is ConfigStateSelection -> {
|
||||||
val button = Button(viewModel.context)
|
val button = Button(viewModel.context)
|
||||||
updateStateSelectionText(button, property.valueContainer.value())
|
updateLocalizedText(button, property.valueContainer.value())
|
||||||
|
|
||||||
button.setOnClickListener {_ ->
|
button.setOnClickListener {_ ->
|
||||||
val builder = AlertDialog.Builder(viewModel.context)
|
val builder = AlertDialog.Builder(viewModel.context)
|
||||||
builder.setTitle(context.translation.get(property.nameKey))
|
builder.setTitle(context.translation.get(property.nameKey))
|
||||||
|
|
||||||
builder.setSingleChoiceItems(
|
builder.setSingleChoiceItems(
|
||||||
property.valueContainer.keys().toTypedArray(),
|
property.valueContainer.keys().toTypedArray().map { context.translation.get("option." + property.nameKey + "." + it) }.toTypedArray(),
|
||||||
property.valueContainer.keys().indexOf(property.valueContainer.value())
|
property.valueContainer.keys().indexOf(property.valueContainer.value())
|
||||||
) { _, which ->
|
) { _, which ->
|
||||||
property.valueContainer.value(property.valueContainer.keys()[which])
|
property.valueContainer.writeFrom(property.valueContainer.keys()[which])
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setPositiveButton("OK") { _, _ ->
|
builder.setPositiveButton("OK") { _, _ ->
|
||||||
updateStateSelectionText(button, property.valueContainer.value())
|
updateLocalizedText(button, property.valueContainer.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.show()
|
builder.show()
|
||||||
@ -123,25 +130,25 @@ class SettingsMenu : AbstractMenu() {
|
|||||||
}
|
}
|
||||||
is ConfigStateListValue -> {
|
is ConfigStateListValue -> {
|
||||||
val button = Button(viewModel.context)
|
val button = Button(viewModel.context)
|
||||||
updateStateSelectionText(button, property.valueContainer.toString())
|
updateButtonText(button, "(${property.valueContainer.value().count { it.value }})")
|
||||||
|
|
||||||
button.setOnClickListener {_ ->
|
button.setOnClickListener {_ ->
|
||||||
val builder = AlertDialog.Builder(viewModel.context)
|
val builder = AlertDialog.Builder(viewModel.context)
|
||||||
builder.setTitle(context.translation.get(property.nameKey))
|
builder.setTitle(context.translation.get(property.nameKey))
|
||||||
|
|
||||||
val sortedStates = property.valueContainer.states.toSortedMap()
|
val sortedStates = property.valueContainer.value().toSortedMap()
|
||||||
|
|
||||||
builder.setMultiChoiceItems(
|
builder.setMultiChoiceItems(
|
||||||
sortedStates.toSortedMap().map { context.translation.get("option." + property.nameKey + "." +it.key) }.toTypedArray(),
|
sortedStates.toSortedMap().map { context.translation.get("option." + property.nameKey + "." +it.key) }.toTypedArray(),
|
||||||
sortedStates.map { it.value }.toBooleanArray()
|
sortedStates.map { it.value }.toBooleanArray()
|
||||||
) { _, which, isChecked ->
|
) { _, which, isChecked ->
|
||||||
sortedStates.keys.toList()[which].let { key ->
|
sortedStates.keys.toList()[which].let { key ->
|
||||||
property.valueContainer.states[key] = isChecked
|
property.valueContainer.setKey(key, isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setPositiveButton("OK") { _, _ ->
|
builder.setPositiveButton("OK") { _, _ ->
|
||||||
updateStateSelectionText(button, property.valueContainer.toString())
|
updateButtonText(button, "(${property.valueContainer.value().count { it.value }})")
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.show()
|
builder.show()
|
||||||
@ -191,15 +198,15 @@ class SettingsMenu : AbstractMenu() {
|
|||||||
it.key.category
|
it.key.category
|
||||||
}.forEach { (category, value) ->
|
}.forEach { (category, value) ->
|
||||||
addView(createCategoryTitle(viewModel, category.key))
|
addView(createCategoryTitle(viewModel, category.key))
|
||||||
value.forEach {
|
value.filter { it.key.shouldAppearInSettings }.forEach { (property, _) ->
|
||||||
addView(createPropertyView(viewModel, it.key))
|
addView(createPropertyView(viewModel, property))
|
||||||
actions.find { pair -> pair.first.dependsOnProperty == it.key }?.let { pair ->
|
actions.find { pair -> pair.first.dependsOnProperty == property}?.let { pair ->
|
||||||
addView(pair.second())
|
addView(pair.second())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addView(createCategoryTitle(viewModel, "category.debugging"))
|
//addView(createCategoryTitle(viewModel, "category.debugging"))
|
||||||
actions.filter { it.first.dependsOnProperty == null }.forEach {
|
actions.filter { it.first.dependsOnProperty == null }.forEach {
|
||||||
addView(it.second())
|
addView(it.second())
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,14 @@ class ConfigManager(
|
|||||||
JsonObject::class.java
|
JsonObject::class.java
|
||||||
)
|
)
|
||||||
entries().forEach { (key, value) ->
|
entries().forEach { (key, value) ->
|
||||||
value.read(configObject.get(key.name)?.asString ?: value.write())
|
value.writeFrom(configObject.get(key.name)?.asString ?: value.read())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun writeConfig() {
|
fun writeConfig() {
|
||||||
val configObject = JsonObject()
|
val configObject = JsonObject()
|
||||||
entries().forEach { (key, value) ->
|
entries().forEach { (key, value) ->
|
||||||
configObject.addProperty(key.name, value.write())
|
configObject.addProperty(key.name, value.read())
|
||||||
}
|
}
|
||||||
context.bridgeClient.writeFile(
|
context.bridgeClient.writeFile(
|
||||||
BridgeFileType.CONFIG,
|
BridgeFileType.CONFIG,
|
||||||
|
@ -10,15 +10,15 @@ import me.rhunk.snapenhance.features.impl.downloader.AntiAutoDownload
|
|||||||
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
|
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
|
||||||
import me.rhunk.snapenhance.features.impl.experiments.AppPasscode
|
import me.rhunk.snapenhance.features.impl.experiments.AppPasscode
|
||||||
import me.rhunk.snapenhance.features.impl.experiments.MeoPasscodeBypass
|
import me.rhunk.snapenhance.features.impl.experiments.MeoPasscodeBypass
|
||||||
import me.rhunk.snapenhance.features.impl.extras.AntiAutoSave
|
import me.rhunk.snapenhance.features.impl.tweaks.AntiAutoSave
|
||||||
import me.rhunk.snapenhance.features.impl.extras.AutoSave
|
import me.rhunk.snapenhance.features.impl.tweaks.AutoSave
|
||||||
import me.rhunk.snapenhance.features.impl.extras.DisableVideoLengthRestriction
|
import me.rhunk.snapenhance.features.impl.tweaks.DisableVideoLengthRestriction
|
||||||
import me.rhunk.snapenhance.features.impl.extras.GalleryMediaSendOverride
|
import me.rhunk.snapenhance.features.impl.tweaks.GalleryMediaSendOverride
|
||||||
import me.rhunk.snapenhance.features.impl.extras.LocationSpoofer
|
import me.rhunk.snapenhance.features.impl.tweaks.LocationSpoofer
|
||||||
import me.rhunk.snapenhance.features.impl.extras.MediaQualityLevelOverride
|
import me.rhunk.snapenhance.features.impl.tweaks.MediaQualityLevelOverride
|
||||||
import me.rhunk.snapenhance.features.impl.extras.Notifications
|
import me.rhunk.snapenhance.features.impl.tweaks.Notifications
|
||||||
import me.rhunk.snapenhance.features.impl.extras.SnapchatPlus
|
import me.rhunk.snapenhance.features.impl.tweaks.SnapchatPlus
|
||||||
import me.rhunk.snapenhance.features.impl.extras.UnlimitedSnapViewTime
|
import me.rhunk.snapenhance.features.impl.tweaks.UnlimitedSnapViewTime
|
||||||
import me.rhunk.snapenhance.features.impl.privacy.DisableMetrics
|
import me.rhunk.snapenhance.features.impl.privacy.DisableMetrics
|
||||||
import me.rhunk.snapenhance.features.impl.privacy.PreventMessageSending
|
import me.rhunk.snapenhance.features.impl.privacy.PreventMessageSending
|
||||||
import me.rhunk.snapenhance.features.impl.spying.AnonymousStoryViewing
|
import me.rhunk.snapenhance.features.impl.spying.AnonymousStoryViewing
|
||||||
|
@ -11,15 +11,34 @@
|
|||||||
|
|
||||||
</org.osmdroid.views.MapView>
|
</org.osmdroid.views.MapView>
|
||||||
|
|
||||||
<Button
|
<FrameLayout
|
||||||
android:id="@+id/apply_location_button"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom|right"
|
<Button
|
||||||
android:layout_marginEnd="20dp"
|
android:id="@+id/set_precise_location_button"
|
||||||
android:layout_marginBottom="20dp"
|
android:layout_width="wrap_content"
|
||||||
android:textSize="20sp"
|
android:layout_height="match_parent"
|
||||||
android:background="@android:color/white"
|
android:layout_gravity="left"
|
||||||
android:text="Apply"
|
android:layout_marginStart="20dp"
|
||||||
tools:ignore="HardcodedText,RtlHardcoded" />
|
android:layout_marginTop="20dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="@android:color/white"
|
||||||
|
android:text="Set Precise Location"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:ignore="HardcodedText,RtlHardcoded" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/apply_location_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="right"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:background="@android:color/white"
|
||||||
|
android:text="Apply"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:ignore="HardcodedText,RtlHardcoded" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
28
app/src/main/res/layout/precise_location_dialog.xml
Normal file
28
app/src/main/res/layout/precise_location_dialog.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:ignore="HardcodedText">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/dialog_latitude"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="numberDecimal"
|
||||||
|
android:hint="Latitude"
|
||||||
|
android:autofillHints="" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/dialog_longitude"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="numberDecimal"
|
||||||
|
android:hint="Longitude"
|
||||||
|
android:autofillHints="" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user