diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json index f15c03d0..ca5e5a56 100644 --- a/common/src/main/assets/lang/en_US.json +++ b/common/src/main/assets/lang/en_US.json @@ -166,6 +166,10 @@ "name": "Download Profile Pictures", "description": "Allows you to download Profile Pictures from the profile page" }, + "opera_download_button": { + "name": "Opera Download Button", + "description": "Adds a download button on the top right corner when viewing a Snap" + }, "chat_download_context_menu": { "name": "Chat Download Context Menu", "description": "Allows you to download media from a conversation by long-pressing them" diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/DownloaderConfig.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/DownloaderConfig.kt index 6f9403f7..d0c73d51 100644 --- a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/DownloaderConfig.kt +++ b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/DownloaderConfig.kt @@ -42,6 +42,7 @@ class DownloaderConfig : ConfigContainer() { addFlags(ConfigFlag.NO_TRANSLATE) } val downloadProfilePictures = boolean("download_profile_pictures") { requireRestart() } + val operaDownloadButton = boolean("opera_download_button") { requireRestart() } val chatDownloadContextMenu = boolean("chat_download_context_menu") val ffmpegOptions = container("ffmpeg_options", FFMpegOptions()) { addNotices(FeatureNotice.UNSTABLE) } val logging = multiple("logging", "started", "success", "progress", "failure").apply { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/MenuViewInjector.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/MenuViewInjector.kt index ebe7fdf7..f8d68cd9 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/MenuViewInjector.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/MenuViewInjector.kt @@ -27,9 +27,10 @@ class MenuViewInjector : Feature("MenuViewInjector", loadParams = FeatureLoadPar @SuppressLint("ResourceType") override fun asyncOnActivityCreate() { + menuMap[OperaContextActionMenu::class] = OperaContextActionMenu() + menuMap[OperaDownloadIconMenu::class] = OperaDownloadIconMenu() menuMap[SettingsGearInjector::class] = SettingsGearInjector() menuMap[FriendFeedInfoMenu::class] = FriendFeedInfoMenu() - menuMap[OperaContextActionMenu::class] = OperaContextActionMenu() menuMap[ChatActionMenu::class] = ChatActionMenu() menuMap[SettingsMenu::class] = SettingsMenu() @@ -42,6 +43,7 @@ class MenuViewInjector : Feature("MenuViewInjector", loadParams = FeatureLoadPar val actionMenu = context.resources.getIdentifier("action_menu", "id") val componentsHolder = context.resources.getIdentifier("components_holder", "id") val feedNewChat = context.resources.getIdentifier("feed_new_chat", "id") + val contextMenuButtonIconView = context.resources.getIdentifier("context_menu_button_icon_view", "id") context.event.subscribe(AddViewEvent::class) { event -> val originalAddView: (View) -> Unit = { @@ -57,6 +59,10 @@ class MenuViewInjector : Feature("MenuViewInjector", loadParams = FeatureLoadPar val childView: View = event.view menuMap[OperaContextActionMenu::class]!!.inject(viewGroup, childView, originalAddView) + if (childView.id == contextMenuButtonIconView) { + menuMap[OperaDownloadIconMenu::class]!!.inject(viewGroup, childView, originalAddView) + } + if (event.parent.id == componentsHolder && childView.id == feedNewChat) { menuMap[SettingsGearInjector::class]!!.inject(viewGroup, childView, originalAddView) return@subscribe diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/OperaDownloadIconMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/OperaDownloadIconMenu.kt new file mode 100644 index 00000000..5dcb0e61 --- /dev/null +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/OperaDownloadIconMenu.kt @@ -0,0 +1,39 @@ +package me.rhunk.snapenhance.core.ui.menu.impl + +import android.graphics.Color +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import me.rhunk.snapenhance.core.features.impl.downloader.MediaDownloader +import me.rhunk.snapenhance.core.ui.menu.AbstractMenu +import me.rhunk.snapenhance.core.util.ktx.getDimens +import me.rhunk.snapenhance.core.util.ktx.getDrawable + +class OperaDownloadIconMenu : AbstractMenu() { + private val downloadSvgDrawable by lazy { context.resources.getDrawable("svg_download", context.androidContext.theme) } + private val actionMenuIconSize by lazy { context.resources.getDimens("action_menu_icon_size") } + private val actionMenuIconMargin by lazy { context.resources.getDimens("action_menu_icon_margin") } + private val actionMenuIconMarginTop by lazy { context.resources.getDimens("action_menu_icon_margin_top") } + + override fun inject(parent: ViewGroup, view: View, viewConsumer: (View) -> Unit) { + if (!context.config.downloader.operaDownloadButton.get()) return + + parent.addView(ImageView(view.context).apply { + setImageDrawable(downloadSvgDrawable) + setColorFilter(Color.WHITE) + layoutParams = FrameLayout.LayoutParams( + actionMenuIconSize, + actionMenuIconSize + ).apply { + setMargins(0, actionMenuIconMarginTop * 2 + actionMenuIconSize, 0, 0) + marginEnd = actionMenuIconMargin + gravity = Gravity.TOP or Gravity.END + } + setOnClickListener { + this@OperaDownloadIconMenu.context.feature(MediaDownloader::class).downloadLastOperaMediaAsync() + } + }, 0) + } +} \ No newline at end of file