Skip to content

Commit

Permalink
Include install source in synced app-data (gplay, fdroid, samsung, am…
Browse files Browse the repository at this point in the history
…azon)
  • Loading branch information
d4rken committed Sep 14, 2024
1 parent f30fb13 commit 9b8806e
Show file tree
Hide file tree
Showing 24 changed files with 421 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package eu.darken.octi.main.ui.dashboard

import android.content.Intent
import eu.darken.octi.common.permissions.Permission

sealed class DashboardEvent {
sealed interface DashboardEvent {

data class ShowPermissionPopup(
val permission: Permission,
val onDismiss: (Permission) -> Unit,
val onGrant: (Permission) -> Unit,
) : DashboardEvent()
) : DashboardEvent

data class ShowPermissionDismissHint(val permission: Permission) : DashboardEvent()
data class RequestPermissionEvent(val permission: Permission) : DashboardEvent()
data class ShowPermissionDismissHint(val permission: Permission) : DashboardEvent
data class RequestPermissionEvent(val permission: Permission) : DashboardEvent

data class OpenAppOrStore(
val intent: Intent,
val fallback: Intent,
) : DashboardEvent

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import eu.darken.octi.R
import eu.darken.octi.common.BuildConfigWrap
import eu.darken.octi.common.colorString
import eu.darken.octi.common.debug.logging.log
import eu.darken.octi.common.error.asErrorDialogBuilder
import eu.darken.octi.common.getQuantityString2
import eu.darken.octi.common.lists.differ.update
import eu.darken.octi.common.lists.setupDefaults
Expand Down Expand Up @@ -147,6 +148,17 @@ class DashboardFragment : Fragment3(R.layout.dashboard_fragment) {
)
dialog.show()
}
is DashboardEvent.OpenAppOrStore -> {
try {
startActivity(event.intent)
} catch (e: Exception) {
try {
startActivity(event.fallback)
} catch (e: Exception) {
e.asErrorDialogBuilder(requireActivity()).show()
}
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import androidx.lifecycle.LiveData
import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.lifecycle.HiltViewModel
import eu.darken.octi.common.BuildConfigWrap
import eu.darken.octi.common.WebpageTool
import eu.darken.octi.common.coroutine.AppScope
import eu.darken.octi.common.coroutine.DispatcherProvider
Expand All @@ -30,6 +29,7 @@ import eu.darken.octi.main.ui.dashboard.items.perdevice.DeviceVH
import eu.darken.octi.module.core.ModuleData
import eu.darken.octi.module.core.ModuleManager
import eu.darken.octi.modules.apps.core.AppsInfo
import eu.darken.octi.modules.apps.core.getInstallerIntent
import eu.darken.octi.modules.apps.ui.dashboard.DeviceAppsVH
import eu.darken.octi.modules.clipboard.ClipboardHandler
import eu.darken.octi.modules.clipboard.ClipboardInfo
Expand Down Expand Up @@ -301,9 +301,10 @@ class DashboardVM @Inject constructor(
DashboardFragmentDirections.actionDashFragmentToAppsListFragment(deviceId).navigate()
},
onInstallClicked = {
val pkg =
data.installedPackages.maxByOrNull { it.installedAt }?.packageName ?: BuildConfigWrap.APPLICATION_ID
webpageTool.open("https://play.google.com/store/apps/details?id=$pkg")
this.data.installedPackages.maxByOrNull { it.installedAt }?.let {
val (main, fallback) = it.getInstallerIntent()
dashboardEvents.postValue(DashboardEvent.OpenAppOrStore(main, fallback))
}
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class GeneralModuleSettings @Inject constructor(
powerSettings.isEnabled,
wifiSettings.isEnabled,
appsSettings.isEnabled,
appsSettings.includeInstaller,
clipboardSettings.isEnabled,
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package eu.darken.octi.module.ui.settings

import android.os.Bundle
import android.view.View
import androidx.annotation.Keep
import androidx.fragment.app.viewModels
import androidx.lifecycle.asLiveData
import androidx.preference.CheckBoxPreference
import dagger.hilt.android.AndroidEntryPoint
import eu.darken.octi.R
import eu.darken.octi.common.observe2
import eu.darken.octi.common.uix.PreferenceFragment3
import eu.darken.octi.module.core.GeneralModuleSettings
import eu.darken.octi.modules.apps.core.AppsSettings
import javax.inject.Inject

@Keep
Expand All @@ -15,7 +21,20 @@ class ModuleSettingsFragment : PreferenceFragment3() {
override val vm: ModuleSettingsVM by viewModels()

@Inject lateinit var _settings: GeneralModuleSettings
@Inject lateinit var appsSettings: AppsSettings
override val settings: GeneralModuleSettings by lazy { _settings }
override val preferenceFile: Int = R.xml.preferences_module

private val moduleApps: CheckBoxPreference
get() = findPreference("module.apps.enabled")!!

private val moduleAppsIncludeInstaller: CheckBoxPreference
get() = findPreference("module.apps.include.installer")!!

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
appsSettings.isEnabled.flow.asLiveData().observe2(this) {
moduleAppsIncludeInstaller.isEnabled = moduleApps.isChecked
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class AppsListFragment : Fragment3(R.layout.module_apps_list_fragment) {
e.asErrorDialogBuilder(requireActivity()).show()
}
}

}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package eu.darken.octi.modules.apps.ui.appslist

import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -14,6 +12,7 @@ import eu.darken.octi.common.livedata.SingleLiveEvent
import eu.darken.octi.common.navigation.navArgs
import eu.darken.octi.common.uix.ViewModel3
import eu.darken.octi.modules.apps.core.AppsRepo
import eu.darken.octi.modules.apps.core.getInstallerIntent
import eu.darken.octi.modules.meta.core.MetaRepo
import kotlinx.coroutines.flow.combine
import javax.inject.Inject
Expand Down Expand Up @@ -54,16 +53,8 @@ class AppsListVM @Inject constructor(
DefaultPkgVH.Item(
pkg = pkg,
onClick = {
val intent = Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse("market://details?id=${pkg.packageName}")
setPackage("com.android.vending")
}
val fallback = Intent().apply {
action = Intent.ACTION_VIEW
data = Uri.parse("https://play.google.com/store/apps/details?id=${pkg.packageName}")
}
events.postValue(AppListAction.OpenAppOrStore(intent, fallback))
val (main, fallback) = pkg.getInstallerIntent()
events.postValue(AppListAction.OpenAppOrStore(main, fallback))
}
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package eu.darken.octi.modules.apps.ui.appslist

import android.view.ViewGroup
import androidx.core.view.isGone
import eu.darken.octi.R
import eu.darken.octi.common.coil.loadAppIcon
import eu.darken.octi.common.lists.binding
import eu.darken.octi.databinding.ModuleAppsListDefaultItemBinding
import eu.darken.octi.modules.apps.core.AppsInfo
import eu.darken.octi.modules.apps.core.installerIconRes


class DefaultPkgVH(parent: ViewGroup) :
Expand All @@ -23,6 +25,10 @@ class DefaultPkgVH(parent: ViewGroup) :
val pkg = item.pkg

icon.loadAppIcon(pkg)
installerIcon.apply {
isGone = pkg.installerPkg == null
setImageResource(pkg.installerIconRes)
}

primary.text = pkg.label ?: pkg.packageName
secondary.text = "${pkg.versionName} (${pkg.versionCode}) - ${pkg.packageName}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import eu.darken.octi.databinding.DashboardDeviceAppsItemBinding
import eu.darken.octi.main.ui.dashboard.items.perdevice.PerDeviceModuleAdapter
import eu.darken.octi.module.core.ModuleData
import eu.darken.octi.modules.apps.core.AppsInfo
import eu.darken.octi.modules.apps.core.installerIconRes


class DeviceAppsVH(parent: ViewGroup) :
Expand All @@ -25,15 +26,16 @@ class DeviceAppsVH(parent: ViewGroup) :
appsPrimary.apply {
text = getString(R.string.module_apps_x_installed, apps.installedPackages.size)
}

appsSecondary.apply {
val last = apps.installedPackages.maxByOrNull { it.installedAt }
text = last?.let { getString(R.string.module_apps_last_installed_x, "${it.label} (${it.versionName})") }
}
val last = apps.installedPackages.maxByOrNull { it.installedAt }
appsSecondary.text =
last?.let { getString(R.string.module_apps_last_installed_x, "${it.label} (${it.versionName})") }

itemView.setOnClickListener { item.onAppsInfoClicked() }

installAction.setOnClickListener { item.onInstallClicked() }
installAction.apply {
setIconResource(last.installerIconRes)
setOnClickListener { item.onInstallClicked() }
}
}

data class Item(
Expand Down
22 changes: 16 additions & 6 deletions app/src/main/res/layout/module_apps_list_default_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:background="?selectableItemBackground"
android:layout_marginVertical="8dp">
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp"
android:background="?selectableItemBackground">

<ImageView
android:id="@+id/installer_icon"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_human_dolly_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_baseline_apps_24"
app:layout_constraintBottom_toBottomOf="@id/secondary"
app:layout_constraintStart_toStartOf="parent"
Expand All @@ -24,9 +32,11 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:singleLine="true"
app:layout_constraintBottom_toTopOf="@id/secondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@id/installer_icon"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="128 apps" />
Expand All @@ -38,7 +48,7 @@
android:layout_height="wrap_content"
android:singleLine="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/primary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/primary"
app:layout_constraintTop_toBottomOf="@id/primary"
tools:text="Last installed: SD Maid" />
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@

<string name="modules_settings_label">Modules</string>
<string name="modules_settings_desc">Toggle different modules and tweak their settings.</string>

<string name="modules_category_connectivity_label">Connectivity</string>
<string name="modules_category_energy_label">Battery</string>
<string name="modules_category_apps_label">Apps</string>
<string name="modules_category_misc_label">Misc</string>
<string name="module_apps_category_label">Apps</string>
<string name="device_x_label">Device: %s</string>

<string name="pro_device_limit_reached_title">Device limit reached</string>
Expand Down
58 changes: 33 additions & 25 deletions app/src/main/res/xml/preferences_module.xml
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<CheckBoxPreference
android:icon="@drawable/ic_baseline_battery_full_24"
android:key="module.power.enabled"
android:summary="@string/module_power_desc"
android:title="@string/module_power_label" />

<CheckBoxPreference
android:icon="@drawable/ic_baseline_network_wifi_5_bar_24"
android:key="module.wifi.enabled"
android:summary="@string/module_wifi_desc"
android:title="@string/module_wifi_label" />

<CheckBoxPreference
android:icon="@drawable/ic_baseline_apps_24"
android:key="module.apps.enabled"
android:summary="@string/module_apps_desc"
android:title="@string/module_apps_label" />

<CheckBoxPreference
android:icon="@drawable/ic_baseline_content_paste_24"
android:key="module.clipboard.enabled"
android:summary="@string/module_clipboard_desc"
android:title="@string/module_clipboard_label" />

<PreferenceCategory android:title="@string/modules_category_energy_label">
<CheckBoxPreference
android:icon="@drawable/ic_baseline_battery_full_24"
android:key="module.power.enabled"
android:summary="@string/module_power_desc"
android:title="@string/module_power_label" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/modules_category_connectivity_label">
<CheckBoxPreference
android:icon="@drawable/ic_baseline_network_wifi_5_bar_24"
android:key="module.wifi.enabled"
android:summary="@string/module_wifi_desc"
android:title="@string/module_wifi_label" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/module_apps_category_label">
<CheckBoxPreference
android:icon="@drawable/ic_baseline_apps_24"
android:key="module.apps.enabled"
android:summary="@string/module_apps_desc"
android:title="@string/module_apps_label" />
<CheckBoxPreference
android:icon="@drawable/ic_store_24"
android:key="module.apps.include.installer"
android:summary="@string/module_apps_installer_desc"
android:title="@string/module_apps_installer_label" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/modules_category_misc_label">
<CheckBoxPreference
android:icon="@drawable/ic_baseline_content_paste_24"
android:key="module.clipboard.enabled"
android:summary="@string/module_clipboard_desc"
android:title="@string/module_clipboard_label" />
</PreferenceCategory>
</PreferenceScreen>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ data class AppsInfo(
@Json(name = "versionCode") val versionCode: Long,
@Json(name = "versionName") val versionName: String?,
@Json(name = "installedAt") val installedAt: Instant,
@Json(name = "installerPkg") val installerPkg: String?,
)

override fun toString(): String = "AppsInfo(size=${installedPackages.size})"
Expand Down
Loading

0 comments on commit 9b8806e

Please sign in to comment.