Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
d4rken committed Nov 8, 2022
2 parents 267a76a + 24fc035 commit 603c136
Show file tree
Hide file tree
Showing 27 changed files with 633 additions and 2 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ dependencies {
implementation(project(":modules-power"))
implementation(project(":modules-wifi"))
implementation(project(":modules-apps"))
implementation(project(":modules-clipboard"))

addDI()
addCoroutines()
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/java/eu/darken/octi/main/ui/dashboard/DashboardVM.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ 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.ui.dashboard.DeviceAppsVH
import eu.darken.octi.modules.clipboard.ClipboardHandler
import eu.darken.octi.modules.clipboard.ClipboardInfo
import eu.darken.octi.modules.clipboard.ClipboardVH
import eu.darken.octi.modules.meta.core.MetaInfo
import eu.darken.octi.modules.power.core.PowerInfo
import eu.darken.octi.modules.power.ui.dashboard.DevicePowerVH
Expand Down Expand Up @@ -60,6 +63,7 @@ class DashboardVM @Inject constructor(
private val syncSettings: SyncSettings,
private val upgradeRepo: UpgradeRepo,
private val webpageTool: WebpageTool,
private val clipboardHandler: ClipboardHandler,
) : ViewModel3(dispatcherProvider = dispatcherProvider) {

val dashboardEvents = SingleLiveEvent<DashboardEvent>()
Expand Down Expand Up @@ -205,6 +209,7 @@ class DashboardVM @Inject constructor(
is PowerInfo -> (moduleData as ModuleData<PowerInfo>).createVHItem()
is WifiInfo -> (moduleData as ModuleData<WifiInfo>).createVHItem(missingPermissions)
is AppsInfo -> (moduleData as ModuleData<AppsInfo>).createVHItem()
is ClipboardInfo -> (moduleData as ModuleData<ClipboardInfo>).createVHItem()
else -> {
log(TAG, WARN) { "Unsupported module data: ${moduleData.data}" }
null
Expand Down Expand Up @@ -265,10 +270,20 @@ class DashboardVM @Inject constructor(
}
)

private fun ModuleData<ClipboardInfo>.createVHItem() = ClipboardVH.Item(
data = this,
isOurDevice = deviceId == syncSettings.deviceId,
onClearClicked = { launch { clipboardHandler.setSharedClipboard(ClipboardInfo()) } },
onPasteClicked = { launch { clipboardHandler.shareCurrentOSClipboard() } }
.takeIf { deviceId == syncSettings.deviceId },
onCopyClicked = { launch { clipboardHandler.setOSClipboard(data) } }
)

companion object {
private val INFO_ORDER = listOf(
PowerInfo::class,
WifiInfo::class,
ClipboardInfo::class,
AppsInfo::class,
)
private const val DEVICE_LIMIT = 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import eu.darken.octi.common.lists.modular.ModularAdapter
import eu.darken.octi.common.lists.modular.mods.DataBinderMod
import eu.darken.octi.common.lists.modular.mods.TypedVHCreatorMod
import eu.darken.octi.modules.apps.ui.dashboard.DeviceAppsVH
import eu.darken.octi.modules.clipboard.ClipboardVH
import eu.darken.octi.modules.power.ui.dashboard.DevicePowerVH
import eu.darken.octi.modules.wifi.ui.dashboard.DeviceWifiVH
import javax.inject.Inject
Expand All @@ -30,6 +31,7 @@ class PerDeviceModuleAdapter @Inject constructor() :
modules.add(TypedVHCreatorMod({ data[it] is DevicePowerVH.Item }) { DevicePowerVH(it) })
modules.add(TypedVHCreatorMod({ data[it] is DeviceWifiVH.Item }) { DeviceWifiVH(it) })
modules.add(TypedVHCreatorMod({ data[it] is DeviceAppsVH.Item }) { DeviceAppsVH(it) })
modules.add(TypedVHCreatorMod({ data[it] is ClipboardVH.Item }) { ClipboardVH(it) })
}

abstract class BaseVH<D : Item, B : ViewBinding>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import eu.darken.octi.common.datastore.PreferenceScreenData
import eu.darken.octi.common.datastore.PreferenceStoreMapper
import eu.darken.octi.common.debug.logging.logTag
import eu.darken.octi.modules.apps.core.AppsSettings
import eu.darken.octi.modules.clipboard.ClipboardSettings
import eu.darken.octi.modules.power.core.PowerSettings
import eu.darken.octi.modules.wifi.core.WifiSettings
import javax.inject.Inject
Expand All @@ -20,6 +21,7 @@ class GeneralModuleSettings @Inject constructor(
private val powerSettings: PowerSettings,
private val wifiSettings: WifiSettings,
private val appsSettings: AppsSettings,
private val clipboardSettings: ClipboardSettings,
) : PreferenceScreenData {
private val Context.dataStore by preferencesDataStore(name = "module_settings")

Expand All @@ -30,6 +32,7 @@ class GeneralModuleSettings @Inject constructor(
powerSettings.isEnabled,
wifiSettings.isEnabled,
appsSettings.isEnabled,
clipboardSettings.isEnabled,
)

companion object {
Expand Down
61 changes: 61 additions & 0 deletions app/src/main/java/eu/darken/octi/modules/clipboard/ClipboardVH.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package eu.darken.octi.modules.clipboard

import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isGone
import eu.darken.octi.R
import eu.darken.octi.databinding.DashboardDeviceClipboardItemBinding
import eu.darken.octi.main.ui.dashboard.items.perdevice.PerDeviceModuleAdapter
import eu.darken.octi.module.core.ModuleData


class ClipboardVH(parent: ViewGroup) :
PerDeviceModuleAdapter.BaseVH<ClipboardVH.Item, DashboardDeviceClipboardItemBinding>(
R.layout.dashboard_device_clipboard_item,
parent
) {

override val viewBinding = lazy { DashboardDeviceClipboardItemBinding.bind(itemView) }

override val onBindData: DashboardDeviceClipboardItemBinding.(
item: Item,
payloads: List<Any>
) -> Unit = { item, _ ->
val clip = item.data.data

secondary.text = when (clip.type) {
ClipboardInfo.Type.EMPTY -> getString(R.string.general_empty_label)
ClipboardInfo.Type.SIMPLE_TEXT -> clip.data.utf8()
else -> clip.data.toString()
}.let { "\"$it\"" }

pasteAction.apply {
setOnClickListener {
item.onPasteClicked?.invoke()
Toast.makeText(context, R.string.module_clipboard_copied_os_to_octi, Toast.LENGTH_SHORT).show()
}
setOnLongClickListener {
item.onClearClicked()
true
}
isGone = item.onPasteClicked == null
}

copyAction.setOnClickListener {
it.requestFocus()
item.onCopyClicked(clip)
Toast.makeText(context, R.string.module_clipboard_copied_octi_to_os, Toast.LENGTH_SHORT).show()
}
}

data class Item(
val data: ModuleData<ClipboardInfo>,
val isOurDevice: Boolean,
val onClearClicked: (() -> Unit),
val onPasteClicked: (() -> Unit)?,
val onCopyClicked: ((ClipboardInfo) -> Unit),
) : PerDeviceModuleAdapter.Item {
override val stableId: Long = data.moduleId.hashCode().toLong()
}

}
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_baseline_content_copy_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z" />
</vector>
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_baseline_content_paste_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,2h-4.18C14.4,0.84 13.3,0 12,0c-1.3,0 -2.4,0.84 -2.82,2L5,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,4c0,-1.1 -0.9,-2 -2,-2zM12,2c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM19,20L5,20L5,4h2v3h10L17,4h2v16z" />
</vector>
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_baseline_content_paste_go_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M5,5h2v3h10V5h2v6h2V5c0,-1.1 -0.9,-2 -2,-2h-4.18C14.4,1.84 13.3,1 12,1S9.6,1.84 9.18,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h5v-2H5V5zM12,3c0.55,0 1,0.45 1,1s-0.45,1 -1,1s-1,-0.45 -1,-1S11.45,3 12,3z" />
<path
android:fillColor="@android:color/white"
android:pathData="M18.01,13l-1.42,1.41l1.58,1.58l-6.17,0l0,2l6.17,0l-1.58,1.59l1.42,1.41l3.99,-4z" />
</vector>
74 changes: 74 additions & 0 deletions app/src/main/res/layout/dashboard_device_clipboard_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/DashboardDeviceInfoRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground">

<ImageView
android:id="@+id/icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_baseline_content_paste_24"
app:layout_constraintBottom_toBottomOf="@id/secondary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/primary"
tools:ignore="ContentDescription" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/primary"
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:singleLine="true"
android:text="@string/module_clipboard_label"
app:layout_constraintBottom_toTopOf="@id/secondary"
app:layout_constraintEnd_toStartOf="@id/paste_action"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="Clipboard" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/secondary"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="@string/general_empty_label"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/paste_action"
app:layout_constraintStart_toStartOf="@id/primary"
app:layout_constraintTop_toBottomOf="@id/primary" />

<com.google.android.material.button.MaterialButton
android:id="@+id/paste_action"
style="@style/Widget.Material3.Button"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:icon="@drawable/ic_baseline_content_paste_go_24"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/copy_action"
app:layout_constraintStart_toEndOf="@id/secondary"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.button.MaterialButton
android:id="@+id/copy_action"
style="@style/Widget.Material3.Button"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:icon="@drawable/ic_baseline_content_copy_24"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/paste_action"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
7 changes: 7 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<string name="general_create_account_action">Create account</string>
<string name="general_link_existing_action">Link to existing account</string>
<string name="general_na_label">N/A</string>
<string name="general_empty_label">Empty</string>
<string name="general_dismiss_action">Dismiss</string>
<string name="general_maybe_later_action">Maybe later</string>
<string name="general_manage_action">Manage</string>
Expand Down Expand Up @@ -194,6 +195,12 @@
<string name="pro_device_limit_reached_title">Device limit reached</string>
<string name="pro_device_limit_reached_description">You currently have %1$d synced devices. To view more than %2$d devices, upgrade to Octi Pro or remove devices.</string>
<string name="module_power_widget_description">Display the battery status of your synced devices.</string>

<string name="module_apps_label">Apps module</string>
<string name="module_apps_desc">Information about installed apps.</string>

<string name="module_clipboard_label">Clipboard module</string>
<string name="module_clipboard_desc">Copy and paste text between devices.</string>
<string name="module_clipboard_copied_octi_to_os">Copied Octi to system clipboard</string>
<string name="module_clipboard_copied_os_to_octi">Copied system to Octi clipboard</string>
</resources>
6 changes: 6 additions & 0 deletions app/src/main/res/xml/preferences_module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,10 @@
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" />

</PreferenceScreen>
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,13 @@ abstract class BaseModuleCache<T : Any> constructor(
null
}

uncachedData?.toModuleData().also {
log(tag, VERBOSE) { "get(id=$deviceId): $it" }
try {
uncachedData?.toModuleData().also {
log(tag, VERBOSE) { "get(id=$deviceId): $it" }
}
} catch (e: Exception) {
log(tag, ERROR) { "Failed to deserialize: ${e.asLog()}\nraw=$uncachedData" }
null
}
}

Expand Down
1 change: 1 addition & 0 deletions modules-clipboard/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
50 changes: 50 additions & 0 deletions modules-clipboard/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
id("kotlin-android")
id("kotlin-kapt")
id("kotlin-parcelize")
}

apply(plugin = "dagger.hilt.android.plugin")

android {
namespace = "eu.darken.octi.modules.clipboard"
compileSdk = ProjectConfig.compileSdk

defaultConfig {
minSdk = ProjectConfig.minSdk
targetSdk = ProjectConfig.targetSdk
}

setupModuleBuildTypes()

setupCompileOptions()

setupKotlinOptions()

testOptions {
unitTests {
isIncludeAndroidResources = true
}
tasks.withType<Test> {
useJUnitPlatform()
}
}
}

dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:${Versions.Desugar.core}")

implementation(project(":app-common"))
testImplementation(project(":app-common-test"))
implementation(project(":module-core"))
implementation(project(":sync-core"))

addAndroidCore()
addDI()
addCoroutines()
addSerialization()
addIO()
addTesting()
}
21 changes: 21 additions & 0 deletions modules-clipboard/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Loading

0 comments on commit 603c136

Please sign in to comment.