mirror of
https://github.com/KDE/kdeconnect-android
synced 2025-09-02 07:05:09 +00:00
Modernize ComposeSendActivity
* UI update for the old compose send screen. * Introduces Jetpack Compose. * Migrates activity to Kotlin. * Fixes "send" button being next to "clear".
This commit is contained in:
committed by
Albert Vaca Cintora
parent
921d0ee884
commit
e9bc90d91a
@@ -275,9 +275,10 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.ComposeSendActivity"
|
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.ComposeSendActivity"
|
||||||
android:label="Compose send"
|
android:label="@string/compose_send_title"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:parentActivityName="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity">
|
android:parentActivityName="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity" />
|
android:value="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity" />
|
||||||
|
12
build.gradle
12
build.gradle
@@ -29,7 +29,13 @@ android {
|
|||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding true
|
viewBinding true
|
||||||
|
compose true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
composeOptions {
|
||||||
|
kotlinCompilerExtensionVersion = "1.4.2"
|
||||||
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
@@ -139,6 +145,12 @@ ext {
|
|||||||
dependencies {
|
dependencies {
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||||
|
|
||||||
|
implementation 'androidx.compose.material3:material3:1.0.1'
|
||||||
|
implementation 'androidx.compose.ui:ui-tooling-preview:1.4.2'
|
||||||
|
implementation 'androidx.activity:activity-compose:1.7.1'
|
||||||
|
implementation 'com.google.accompanist:accompanist-themeadapter-material3:0.31.0-alpha'
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout-compose:1.0.1'
|
||||||
|
|
||||||
implementation 'androidx.media:media:1.6.0'
|
implementation 'androidx.media:media:1.6.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'androidx.core:core-ktx:1.10.0'
|
implementation 'androidx.core:core-ktx:1.10.0'
|
||||||
|
@@ -16,7 +16,8 @@
|
|||||||
android:id="@+id/coordinatorLayout"
|
android:id="@+id/coordinatorLayout"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.MainActivity">
|
tools:context="org.kde.kdeconnect.UserInterface.MainActivity"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||||
|
|
||||||
|
@@ -5,7 +5,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.About.AboutKDEActivity">
|
tools:context="org.kde.kdeconnect.UserInterface.About.AboutKDEActivity"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||||
|
|
||||||
|
@@ -1,50 +0,0 @@
|
|||||||
<?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"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
|
||||||
android:id="@+id/appBarLayout2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="?attr/actionBarSize" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/compose"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:ems="10"
|
|
||||||
android:hint="@string/click_here_to_type"
|
|
||||||
android:imeActionLabel="@string/send_compose"
|
|
||||||
android:imeOptions="actionSend|actionDone"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:inputType="textLongMessage|textMultiLine"
|
|
||||||
android:isScrollContainer="true"
|
|
||||||
android:saveEnabled="true"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/appBarLayout2"
|
|
||||||
app:layout_constraintVertical_bias="1.0"
|
|
||||||
tools:ignore="SpeakableTextPresentCheck,TextContrastCheck" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@@ -6,7 +6,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.CustomDevicesActivity">
|
tools:context="org.kde.kdeconnect.UserInterface.CustomDevicesActivity"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.About.LicensesActivity">
|
tools:context="org.kde.kdeconnect.UserInterface.About.LicensesActivity">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||||
|
@@ -7,14 +7,14 @@
|
|||||||
<androidx.drawerlayout.widget.DrawerLayout
|
<androidx.drawerlayout.widget.DrawerLayout
|
||||||
android:id="@+id/drawer_layout"
|
android:id="@+id/drawer_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:fitsSystemWindows="true"> <!-- fitSystemWindows to make the drawer slide below the Lollipop transparent status bar -->
|
|
||||||
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
android:id="@+id/coordinatorLayout"
|
android:id="@+id/coordinatorLayout"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.MainActivity">
|
tools:context="org.kde.kdeconnect.UserInterface.MainActivity"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout"/>
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout"/>
|
||||||
|
|
||||||
|
@@ -9,9 +9,7 @@
|
|||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:elevation="8dp"
|
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
@@ -21,10 +19,7 @@
|
|||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/mpris_tabs"
|
android:id="@+id/mpris_tabs"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:background="@color/toolbar_color"
|
|
||||||
app:tabIndicatorColor="?android:textColorPrimary"
|
|
||||||
app:tabSelectedTextColor="?android:textColorPrimary" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
@@ -6,7 +6,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="org.kde.kdeconnect.UserInterface.PluginSettingsActivity">
|
tools:context="org.kde.kdeconnect.UserInterface.PluginSettingsActivity"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
<include layout="@layout/toolbar" android:id="@+id/toolbar_layout" />
|
||||||
|
|
||||||
|
@@ -5,12 +5,11 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:elevation="8dp"
|
|
||||||
app:title="@string/kde_connect"/>
|
app:title="@string/kde_connect"/>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_send_compose"
|
|
||||||
android:icon="@android:drawable/ic_menu_send"
|
|
||||||
android:title="@string/send_compose"
|
|
||||||
kdeconnect:showAsAction="ifRoom" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_clear_compose"
|
|
||||||
android:title="@string/clear_compose"
|
|
||||||
kdeconnect:showAsAction="always" />
|
|
||||||
|
|
||||||
</menu>
|
|
@@ -6,13 +6,13 @@
|
|||||||
android:id="@+id/menu_rise_up"
|
android:id="@+id/menu_rise_up"
|
||||||
android:icon="@drawable/ic_arrow_upward_black_24dp"
|
android:icon="@drawable/ic_arrow_upward_black_24dp"
|
||||||
android:title="@string/rise_up"
|
android:title="@string/rise_up"
|
||||||
android:iconTint="@color/text_color"
|
kdeconnect:iconTint="?colorOnSurfaceVariant"
|
||||||
kdeconnect:showAsAction="ifRoom" />
|
kdeconnect:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_rise_down"
|
android:id="@+id/menu_rise_down"
|
||||||
android:icon="@drawable/ic_arrow_downward_black_24dp"
|
android:icon="@drawable/ic_arrow_downward_black_24dp"
|
||||||
android:title="@string/rise_down"
|
android:title="@string/rise_down"
|
||||||
android:iconTint="@color/text_color"
|
kdeconnect:iconTint="?colorOnSurfaceVariant"
|
||||||
kdeconnect:showAsAction="ifRoom" />
|
kdeconnect:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
<color name="toolbar_color">@android:color/system_neutral1_900</color>
|
<color name="toolbar_color">@android:color/system_neutral1_900</color>
|
||||||
<color name="card_stroke_color">@android:color/system_neutral2_800</color>
|
<color name="card_stroke_color">@android:color/system_neutral2_800</color>
|
||||||
<color name="activity_background">@android:color/system_neutral1_900</color>
|
<color name="activity_background">@android:color/system_neutral1_900</color>
|
||||||
<item name="lightMode" type="bool">false</item>
|
|
||||||
|
|
||||||
<!-- This is for dark theme. In dark theme both selected and unselected text in the
|
<!-- This is for dark theme. In dark theme both selected and unselected text in the
|
||||||
navigation bar should be white. This is different from the light theme as both states have
|
navigation bar should be white. This is different from the light theme as both states have
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
<color name="toolbar_color">@android:color/black</color>
|
<color name="toolbar_color">@android:color/black</color>
|
||||||
<color name="card_stroke_color">#8C8C8C</color>
|
<color name="card_stroke_color">#8C8C8C</color>
|
||||||
<color name="activity_background">@android:color/black</color>
|
<color name="activity_background">@android:color/black</color>
|
||||||
<item name="lightMode" type="bool">false</item>
|
|
||||||
|
|
||||||
<!-- This is for dark theme. In dark theme both selected and unselected text in the
|
<!-- This is for dark theme. In dark theme both selected and unselected text in the
|
||||||
navigation bar should be white. This is different from the light theme as both states have
|
navigation bar should be white. This is different from the light theme as both states have
|
||||||
|
@@ -11,6 +11,5 @@
|
|||||||
<color name="toolbar_color">@android:color/system_neutral1_50</color>
|
<color name="toolbar_color">@android:color/system_neutral1_50</color>
|
||||||
<color name="card_stroke_color">@android:color/system_neutral2_100</color>
|
<color name="card_stroke_color">@android:color/system_neutral2_100</color>
|
||||||
<color name="activity_background">@android:color/system_neutral1_50</color>
|
<color name="activity_background">@android:color/system_neutral1_50</color>
|
||||||
<item name="lightMode" type="bool">true</item>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar">
|
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar">
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
<item name="android:windowLightStatusBar">@bool/lightMode</item>
|
<item name="android:windowLightStatusBar">?attr/isLightTheme</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<style name="KdeConnectThemeBase.V27" parent="KdeConnectThemeBase">
|
<style name="KdeConnectThemeBase.V27" parent="KdeConnectThemeBase">
|
||||||
<item name="android:navigationBarColor">@color/activity_background</item>
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||||
<item name="android:windowLightNavigationBar">?attr/isLightTheme</item>
|
<item name="android:windowLightNavigationBar">?attr/isLightTheme</item>
|
||||||
</style>
|
</style>
|
||||||
|
@@ -11,5 +11,4 @@
|
|||||||
<color name="toolbar_color">@android:color/white</color>
|
<color name="toolbar_color">@android:color/white</color>
|
||||||
<color name="card_stroke_color">#C8C8C8</color>
|
<color name="card_stroke_color">#C8C8C8</color>
|
||||||
<color name="activity_background">@android:color/white</color>
|
<color name="activity_background">@android:color/white</color>
|
||||||
<item name="lightMode" type="bool">true</item>
|
|
||||||
</resources>
|
</resources>
|
@@ -488,6 +488,7 @@
|
|||||||
<string name="click_here_to_type">Tap here to type</string>
|
<string name="click_here_to_type">Tap here to type</string>
|
||||||
<string name="clear_compose">Clear</string>
|
<string name="clear_compose">Clear</string>
|
||||||
<string name="send_compose">Send</string>
|
<string name="send_compose">Send</string>
|
||||||
|
<string name="compose_send_title">Compose send</string>
|
||||||
<string name="open_compose_send">Compose text</string>
|
<string name="open_compose_send">Compose text</string>
|
||||||
|
|
||||||
<string name="about_kde_about"><![CDATA[
|
<string name="about_kde_about"><![CDATA[
|
||||||
|
@@ -2,25 +2,24 @@
|
|||||||
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
|
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
|
||||||
<style name="KdeConnectThemeBase" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="KdeConnectThemeBase" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
<!-- The main color attributes -->
|
<!-- The main color attributes -->
|
||||||
<!-- The three colors used by system widgets, according to https://chris.banes.me/2014/10/17/appcompat-v21/ -->
|
|
||||||
<item name="colorPrimary">@color/primary</item>
|
<item name="colorPrimary">@color/primary</item>
|
||||||
<item name="colorPrimaryDark">@color/primaryDark</item>
|
<item name="colorPrimaryDark">@color/primaryDark</item>
|
||||||
<item name="colorSecondary">@color/primary</item>
|
<item name="colorSecondary">@color/primary</item>
|
||||||
<item name="colorOnSecondary">@color/on_secondary</item>
|
<item name="colorOnSecondary">@color/on_secondary</item>
|
||||||
<item name="colorAccent">@color/accent</item>
|
|
||||||
<item name="colorHighContrast">@color/on_high_contrast</item>
|
<item name="colorHighContrast">@color/on_high_contrast</item>
|
||||||
<item name="android:windowBackground">@color/activity_background</item>
|
|
||||||
<item name="android:colorBackground">@color/activity_background</item>
|
|
||||||
<!-- TODO: The 2 items below change too much (eg snackbar text is now black, should be white) -->
|
<!-- TODO: The 2 items below change too much (eg snackbar text is now black, should be white) -->
|
||||||
<item name="android:textColorPrimary">@color/text_color_primary</item>
|
<item name="android:textColorPrimary">@color/text_color_primary</item>
|
||||||
<item name="android:textColor">@color/text_color</item>
|
<item name="android:textColor">@color/text_color</item>
|
||||||
|
|
||||||
|
<!--For android below 23 api-->
|
||||||
|
<item name="android:statusBarColor">@android:color/black</item>
|
||||||
|
|
||||||
<!-- Drawable definitions and overrides -->
|
<!-- Drawable definitions and overrides -->
|
||||||
<item name="divider">?colorHighContrast</item>
|
<item name="divider">?colorHighContrast</item>
|
||||||
|
|
||||||
<!-- Style overrides -->
|
<!-- Style overrides -->
|
||||||
<item name="actionModeStyle">@style/ActionModeStyle</item>
|
<item name="actionModeStyle">@style/Widget.Material3.ActionMode</item>
|
||||||
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar</item>
|
<item name="toolbarStyle">@style/Widget.Material3.Toolbar</item>
|
||||||
|
|
||||||
<!-- Theme overrides -->
|
<!-- Theme overrides -->
|
||||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||||
|
@@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2021 Forrest Hilton <forrestmhilton@gmail.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package org.kde.kdeconnect.Plugins.MousePadPlugin;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.inputmethod.EditorInfo;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import org.kde.kdeconnect.BackgroundService;
|
|
||||||
import org.kde.kdeconnect.NetworkPacket;
|
|
||||||
import org.kde.kdeconnect.UserInterface.ThemeUtil;
|
|
||||||
import org.kde.kdeconnect_tp.R;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
|
|
||||||
public class ComposeSendActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
private String deviceId;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_compose_send);
|
|
||||||
|
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
|
||||||
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
|
|
||||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
|
|
||||||
deviceId = intent.getStringExtra("org.kde.kdeconnect.Plugins.MousePadPlugin.deviceId");
|
|
||||||
|
|
||||||
EditText editText = findViewById(R.id.compose);
|
|
||||||
|
|
||||||
editText.requestFocus();
|
|
||||||
// this is almost never used
|
|
||||||
editText.setOnEditorActionListener((v, actionId, event) -> {
|
|
||||||
if (actionId == EditorInfo.IME_ACTION_SEND) {
|
|
||||||
sendComposed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
|
||||||
clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendChars(CharSequence chars) {
|
|
||||||
final NetworkPacket np = new NetworkPacket(MousePadPlugin.PACKET_TYPE_MOUSEPAD_REQUEST);
|
|
||||||
np.set("key", chars.toString());
|
|
||||||
sendKeyPressPacket(np);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendKeyPressPacket(final NetworkPacket np) {
|
|
||||||
try {
|
|
||||||
Log.d("packed", np.serialize());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("KDE/ComposeSend", "Exception", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
BackgroundService.RunWithPlugin(this, deviceId, MousePadPlugin.class, plugin -> plugin.sendKeyboardPacket(np));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendComposed() {
|
|
||||||
EditText editText = findViewById(R.id.compose);
|
|
||||||
|
|
||||||
String editTextStr = editText.getText().toString();
|
|
||||||
sendChars(editTextStr);
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
EditText editText = findViewById(R.id.compose);
|
|
||||||
editText.setText("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.menu_compose_send, menu);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
if (id == R.id.menu_clear_compose) {
|
|
||||||
clear();
|
|
||||||
return true;
|
|
||||||
} else if (id == R.id.menu_send_compose) {
|
|
||||||
sendComposed();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Dmitry Yudin <dgyudin@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.kde.kdeconnect.Plugins.MousePadPlugin
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.Send
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.google.accompanist.themeadapter.material3.Mdc3Theme
|
||||||
|
import org.kde.kdeconnect.BackgroundService
|
||||||
|
import org.kde.kdeconnect.NetworkPacket
|
||||||
|
import org.kde.kdeconnect.UserInterface.compose.KdeTextButton
|
||||||
|
import org.kde.kdeconnect.UserInterface.compose.KdeTextField
|
||||||
|
import org.kde.kdeconnect.UserInterface.compose.KdeTopAppBar
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
|
||||||
|
private const val INPUT_CACHE_KEY = "compose_send_input_cache"
|
||||||
|
|
||||||
|
class ComposeSendActivity : AppCompatActivity() {
|
||||||
|
private var deviceId: String? = null
|
||||||
|
private val userInput = mutableStateOf(String())
|
||||||
|
private val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
prefs.getString(INPUT_CACHE_KEY, null)?.let { userInput.value = it }
|
||||||
|
|
||||||
|
setContent { ComposeSendScreen() }
|
||||||
|
|
||||||
|
deviceId = intent.getStringExtra("org.kde.kdeconnect.Plugins.MousePadPlugin.deviceId")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
with(prefs.edit()) {
|
||||||
|
if (userInput.value.isNotBlank()) putString(INPUT_CACHE_KEY, userInput.value) else remove(INPUT_CACHE_KEY)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendChars(chars: String) {
|
||||||
|
val np = NetworkPacket(MousePadPlugin.PACKET_TYPE_MOUSEPAD_REQUEST)
|
||||||
|
np["key"] = chars
|
||||||
|
sendKeyPressPacket(np)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendKeyPressPacket(np: NetworkPacket) {
|
||||||
|
try {
|
||||||
|
Log.d("packed", np.serialize())
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("KDE/ComposeSend", "Exception", e)
|
||||||
|
}
|
||||||
|
BackgroundService.RunWithPlugin(
|
||||||
|
this, deviceId, MousePadPlugin::class.java
|
||||||
|
) { plugin: MousePadPlugin -> plugin.sendKeyboardPacket(np) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendComposed() {
|
||||||
|
sendChars(userInput.value)
|
||||||
|
clearComposeInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearComposeInput() {
|
||||||
|
userInput.value = String()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
private fun ComposeSendScreen() {
|
||||||
|
Mdc3Theme {
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
KdeTopAppBar(
|
||||||
|
title = stringResource(R.string.compose_send_title),
|
||||||
|
navIcon = Icons.Default.ArrowBack,
|
||||||
|
navIconOnClick = { onBackPressedDispatcher.onBackPressed() },
|
||||||
|
actions = {
|
||||||
|
KdeTextButton(
|
||||||
|
modifier = Modifier.padding(horizontal = 8.dp),
|
||||||
|
onClick = { clearComposeInput() },
|
||||||
|
text = stringResource(R.string.clear_compose),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
) { scaffoldPadding ->
|
||||||
|
Box(modifier = Modifier.padding(scaffoldPadding).fillMaxSize()) {
|
||||||
|
KdeTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.padding(bottom = 80.dp)
|
||||||
|
.align(Alignment.BottomStart)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
input = userInput,
|
||||||
|
label = stringResource(R.string.click_here_to_type),
|
||||||
|
)
|
||||||
|
KdeTextButton(
|
||||||
|
onClick = { sendComposed() },
|
||||||
|
modifier = Modifier.padding(all = 16.dp).align(Alignment.BottomEnd),
|
||||||
|
enabled = userInput.value.isNotEmpty(),
|
||||||
|
text = stringResource(R.string.send_compose),
|
||||||
|
iconLeft = Icons.Default.Send,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -8,6 +8,10 @@ package org.kde.kdeconnect.Plugins.MousePadPlugin;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.hardware.Sensor;
|
||||||
|
import android.hardware.SensorEvent;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
@@ -15,17 +19,11 @@ import android.view.Menu;
|
|||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.hardware.SensorManager;
|
|
||||||
import android.hardware.SensorEventListener;
|
|
||||||
import android.hardware.SensorEvent;
|
|
||||||
import android.hardware.Sensor;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
import org.kde.kdeconnect.BackgroundService;
|
import org.kde.kdeconnect.BackgroundService;
|
||||||
import org.kde.kdeconnect.UserInterface.PluginSettingsActivity;
|
import org.kde.kdeconnect.UserInterface.PluginSettingsActivity;
|
||||||
@@ -455,7 +453,6 @@ public class MousePadActivity
|
|||||||
BackgroundService.RunWithPlugin(this, deviceId, MousePadPlugin.class, plugin -> plugin.sendScroll(0, y));
|
BackgroundService.RunWithPlugin(this, deviceId, MousePadPlugin.class, plugin -> plugin.sendScroll(0, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Does not work on KitKat with or without requestFocus()
|
|
||||||
private void showKeyboard() {
|
private void showKeyboard() {
|
||||||
InputMethodManager imm = ContextCompat.getSystemService(this, InputMethodManager.class);
|
InputMethodManager imm = ContextCompat.getSystemService(this, InputMethodManager.class);
|
||||||
keyListenerView.requestFocus();
|
keyListenerView.requestFocus();
|
||||||
|
42
src/org/kde/kdeconnect/UserInterface/compose/Buttons.kt
Normal file
42
src/org/kde/kdeconnect/UserInterface/compose/Buttons.kt
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Dmitry Yudin <dgyudin@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.kde.kdeconnect.UserInterface.compose
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun KdeTextButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier,
|
||||||
|
text: String,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
contentPadding: PaddingValues = PaddingValues(16.dp),
|
||||||
|
iconLeft: ImageVector? = null,
|
||||||
|
) {
|
||||||
|
TextButton(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier,
|
||||||
|
enabled = enabled,
|
||||||
|
contentPadding = contentPadding,
|
||||||
|
content = {
|
||||||
|
iconLeft?.let {
|
||||||
|
Icon(imageVector = it, contentDescription = null)
|
||||||
|
Spacer(Modifier.width(16.dp))
|
||||||
|
}
|
||||||
|
Text(text = text)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
41
src/org/kde/kdeconnect/UserInterface/compose/TextFields.kt
Normal file
41
src/org/kde/kdeconnect/UserInterface/compose/TextFields.kt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Dmitry Yudin <dgyudin@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.kde.kdeconnect.UserInterface.compose
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import org.kde.kdeconnect_tp.R
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun KdeTextField(modifier: Modifier = Modifier, input: MutableState<String>, label: String) {
|
||||||
|
var value by rememberSaveable { input }
|
||||||
|
OutlinedTextField(
|
||||||
|
modifier = modifier,
|
||||||
|
value = value,
|
||||||
|
onValueChange = { userInput -> value = userInput },
|
||||||
|
label = { Text(label) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("UnrememberedMutableState")
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun Preview() {
|
||||||
|
KdeTextField(
|
||||||
|
input = mutableStateOf("John Doe"),
|
||||||
|
label = stringResource(R.string.click_here_to_type),
|
||||||
|
)
|
||||||
|
}
|
33
src/org/kde/kdeconnect/UserInterface/compose/TopAppBars.kt
Normal file
33
src/org/kde/kdeconnect/UserInterface/compose/TopAppBars.kt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Dmitry Yudin <dgyudin@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.kde.kdeconnect.UserInterface.compose
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun KdeTopAppBar(
|
||||||
|
title: String,
|
||||||
|
navIcon: ImageVector,
|
||||||
|
navIconOnClick: () -> Unit,
|
||||||
|
actions: @Composable (RowScope.() -> Unit) = {},
|
||||||
|
) {
|
||||||
|
TopAppBar(
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(onClick = navIconOnClick, content = { Icon(navIcon, null) })
|
||||||
|
},
|
||||||
|
title = { Text(title) },
|
||||||
|
actions = actions
|
||||||
|
)
|
||||||
|
}
|
Reference in New Issue
Block a user