feat(widget): Add home screen widget with quick access actions
This commit is contained in:
@@ -119,6 +119,19 @@
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="dataSync|microphone"/>
|
||||
|
||||
<!-- Home Screen Widget -->
|
||||
<receiver
|
||||
android:name=".ConduitWidgetProvider"
|
||||
android:exported="true"
|
||||
android:label="@string/widget_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/conduit_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package app.cogwheel.conduit
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.widget.RemoteViews
|
||||
import es.antonborri.home_widget.HomeWidgetLaunchIntent
|
||||
|
||||
/**
|
||||
* Home screen widget provider for Conduit.
|
||||
*
|
||||
* Provides quick actions:
|
||||
* - New Chat: Start a fresh conversation
|
||||
* - Mic: Start voice input
|
||||
* - Camera: Take a photo and attach to chat
|
||||
* - Photos: Pick from gallery and attach to chat
|
||||
* - Clipboard: Paste clipboard content as prompt
|
||||
*/
|
||||
class ConduitWidgetProvider : AppWidgetProvider() {
|
||||
|
||||
override fun onUpdate(
|
||||
context: Context,
|
||||
appWidgetManager: AppWidgetManager,
|
||||
appWidgetIds: IntArray
|
||||
) {
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
// Called when the first widget is created
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
// Called when the last widget is removed
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ACTION_NEW_CHAT = "new_chat"
|
||||
private const val ACTION_MIC = "mic"
|
||||
private const val ACTION_CAMERA = "camera"
|
||||
private const val ACTION_PHOTOS = "photos"
|
||||
private const val ACTION_CLIPBOARD = "clipboard"
|
||||
|
||||
private fun updateAppWidget(
|
||||
context: Context,
|
||||
appWidgetManager: AppWidgetManager,
|
||||
appWidgetId: Int
|
||||
) {
|
||||
val views = RemoteViews(context.packageName, R.layout.conduit_widget)
|
||||
|
||||
// Set up click handlers using home_widget's launch intent
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.widget_container,
|
||||
HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java,
|
||||
Uri.parse("homewidget://$ACTION_NEW_CHAT")
|
||||
)
|
||||
)
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.btn_new_chat,
|
||||
HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java,
|
||||
Uri.parse("homewidget://$ACTION_NEW_CHAT")
|
||||
)
|
||||
)
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.btn_mic,
|
||||
HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java,
|
||||
Uri.parse("homewidget://$ACTION_MIC")
|
||||
)
|
||||
)
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.btn_camera,
|
||||
HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java,
|
||||
Uri.parse("homewidget://$ACTION_CAMERA")
|
||||
)
|
||||
)
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.btn_photos,
|
||||
HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java,
|
||||
Uri.parse("homewidget://$ACTION_PHOTOS")
|
||||
)
|
||||
)
|
||||
views.setOnClickPendingIntent(
|
||||
R.id.btn_clipboard,
|
||||
HomeWidgetLaunchIntent.getActivity(
|
||||
context,
|
||||
MainActivity::class.java,
|
||||
Uri.parse("homewidget://$ACTION_CLIPBOARD")
|
||||
)
|
||||
)
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
}
|
||||
}
|
||||
15
android/app/src/main/res/drawable-v31/ic_widget_camera.xml
Normal file
15
android/app/src/main/res/drawable-v31/ic_widget_camera.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,2L7.17,4H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2H9zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z" />
|
||||
</vector>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container">
|
||||
<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,2H5c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V4c0,-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,-1zM14,18H7v-2h7v2zM17,14H7v-2h10v2zM17,10H7V8h10v2z" />
|
||||
</vector>
|
||||
|
||||
13
android/app/src/main/res/drawable-v31/ic_widget_mic.xml
Normal file
13
android/app/src/main/res/drawable-v31/ic_widget_mic.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Material Design Mic Icon - Material You -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11H5c0,3.41 2.72,6.23 6,6.72V21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" />
|
||||
</vector>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Mic icon with accent color tint - Material You -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_mic_icon">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11H5c0,3.41 2.72,6.23 6,6.72V21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" />
|
||||
</vector>
|
||||
|
||||
12
android/app/src/main/res/drawable-v31/ic_widget_photos.xml
Normal file
12
android/app/src/main/res/drawable-v31/ic_widget_photos.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
|
||||
</vector>
|
||||
|
||||
12
android/app/src/main/res/drawable-v31/ic_widget_waveform.xml
Normal file
12
android/app/src/main/res/drawable-v31/ic_widget_waveform.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Graphic equalizer icon for voice - Material You -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,18h2V6H7v12zM11,22h2V2h-2v20zM3,14h2v-4H3v4zM15,18h2V6h-2v12zM19,10v4h2v-4h-2z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Widget background - Material You dynamic surface color -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/widget_surface" />
|
||||
<corners android:radius="@dimen/widget_corner_radius" />
|
||||
</shape>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Rounded button - Material You -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#20FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container" />
|
||||
<corners android:radius="16dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
11
android/app/src/main/res/drawable-v31/widget_button_mic.xml
Normal file
11
android/app/src/main/res/drawable-v31/widget_button_mic.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Mic button inside pill - Material You lighter accent -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#20FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="@color/widget_mic_background" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
12
android/app/src/main/res/drawable-v31/widget_button_pill.xml
Normal file
12
android/app/src/main/res/drawable-v31/widget_button_pill.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Pill-shaped primary button - Material You dynamic color (darker accent) -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#40FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_primary_dark" />
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Primary button - Material You dynamic primary color -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#40FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_primary" />
|
||||
<corners android:radius="@dimen/widget_button_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Secondary button - Material You dynamic secondary container color -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#20000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container" />
|
||||
<corners android:radius="@dimen/widget_secondary_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
13
android/app/src/main/res/drawable/ic_hub.xml
Normal file
13
android/app/src/main/res/drawable/ic_hub.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Material Design Hub Icon (Filled) -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="#FFFFFF">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M240,920q-50,0 -85,-35t-35,-85q0,-50 35,-85t85,-35q14,0 26,3t23,8l57,-71q-28,-31 -39,-70t-5,-78l-81,-27q-17,25 -43,40t-58,15q-50,0 -85,-35T0,380q0,-50 35,-85t85,-35q50,0 85,35t35,85v8l81,28q20,-36 53.5,-61t75.5,-32v-87q-39,-11 -64.5,-42.5T360,120q0,-50 35,-85t85,-35q50,0 85,35t35,85q0,42 -26,73.5T510,236v87q42,7 75.5,32t53.5,61l81,-28v-8q0,-50 35,-85t85,-35q50,0 85,35t35,85q0,50 -35,85t-85,35q-32,0 -58.5,-15T739,445l-81,27q6,39 -5,77.5T614,620l57,70q11,-5 23,-7.5t26,-2.5q50,0 85,35t35,85q0,50 -35,85t-85,35q-50,0 -85,-35t-35,-85q0,-20 6.5,-38.5T624,728l-57,-71q-41,23 -87.5,23T392,657l-56,71q11,15 17.5,33.5T360,800q0,50 -35,85t-85,35Z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2l1.5,5.5L19,9l-5.5,1.5L12,16l-1.5,-5.5L5,9l5.5,-1.5L12,2z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19,15l0.94,2.06L22,18l-2.06,0.94L19,21l-0.94,-2.06L16,18l2.06,-0.94L19,15z"/>
|
||||
</vector>
|
||||
15
android/app/src/main/res/drawable/ic_widget_camera.xml
Normal file
15
android/app/src/main/res/drawable/ic_widget_camera.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container_fallback">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,2L7.17,4H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2H9zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z" />
|
||||
</vector>
|
||||
|
||||
12
android/app/src/main/res/drawable/ic_widget_clipboard.xml
Normal file
12
android/app/src/main/res/drawable/ic_widget_clipboard.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container_fallback">
|
||||
<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,2H5c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V4c0,-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,-1zM14,18H7v-2h7v2zM17,14H7v-2h10v2zM17,10H7V8h10v2z" />
|
||||
</vector>
|
||||
|
||||
13
android/app/src/main/res/drawable/ic_widget_mic.xml
Normal file
13
android/app/src/main/res/drawable/ic_widget_mic.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Material Design Mic Icon -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container_fallback">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11H5c0,3.41 2.72,6.23 6,6.72V21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" />
|
||||
</vector>
|
||||
|
||||
13
android/app/src/main/res/drawable/ic_widget_mic_accent.xml
Normal file
13
android/app/src/main/res/drawable/ic_widget_mic_accent.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Mic icon with accent color tint -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_mic_icon_fallback">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11H5c0,3.41 2.72,6.23 6,6.72V21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" />
|
||||
</vector>
|
||||
|
||||
12
android/app/src/main/res/drawable/ic_widget_photos.xml
Normal file
12
android/app/src/main/res/drawable/ic_widget_photos.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container_fallback">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
|
||||
</vector>
|
||||
|
||||
12
android/app/src/main/res/drawable/ic_widget_waveform.xml
Normal file
12
android/app/src/main/res/drawable/ic_widget_waveform.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Graphic equalizer icon for voice -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/widget_on_secondary_container_fallback">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,18h2V6H7v12zM11,22h2V2h-2v20zM3,14h2v-4H3v4zM15,18h2V6h-2v12zM19,10v4h2v-4h-2z" />
|
||||
</vector>
|
||||
8
android/app/src/main/res/drawable/widget_background.xml
Normal file
8
android/app/src/main/res/drawable/widget_background.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Widget background - Material 3 surface with large corner radius -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/widget_surface_fallback" />
|
||||
<corners android:radius="@dimen/widget_corner_radius" />
|
||||
</shape>
|
||||
|
||||
11
android/app/src/main/res/drawable/widget_button_circle.xml
Normal file
11
android/app/src/main/res/drawable/widget_button_circle.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Rounded button - ChatGPT style -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#20FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container_fallback" />
|
||||
<corners android:radius="16dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
11
android/app/src/main/res/drawable/widget_button_mic.xml
Normal file
11
android/app/src/main/res/drawable/widget_button_mic.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Mic button inside pill - lighter accent background -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#20FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="@color/widget_mic_background_fallback" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
12
android/app/src/main/res/drawable/widget_button_pill.xml
Normal file
12
android/app/src/main/res/drawable/widget_button_pill.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Pill-shaped primary button - Material 3 style with darker accent -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#40FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_primary_dark_fallback" />
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
12
android/app/src/main/res/drawable/widget_button_primary.xml
Normal file
12
android/app/src/main/res/drawable/widget_button_primary.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Primary button - Material 3 filled button style -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#40FFFFFF">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_primary_fallback" />
|
||||
<corners android:radius="@dimen/widget_button_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Secondary button - Material 3 tonal button style -->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#20000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container_fallback" />
|
||||
<corners android:radius="@dimen/widget_secondary_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
54
android/app/src/main/res/drawable/widget_preview.xml
Normal file
54
android/app/src/main/res/drawable/widget_preview.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Widget preview shown in the widget picker - Material 3 style -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Background -->
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_surface_fallback" />
|
||||
<corners android:radius="@dimen/widget_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- Primary button preview -->
|
||||
<item
|
||||
android:left="16dp"
|
||||
android:top="16dp"
|
||||
android:right="16dp"
|
||||
android:bottom="72dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_primary_fallback" />
|
||||
<corners android:radius="@dimen/widget_button_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
<!-- Secondary buttons preview -->
|
||||
<item
|
||||
android:left="16dp"
|
||||
android:top="80dp"
|
||||
android:right="176dp"
|
||||
android:bottom="16dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container_fallback" />
|
||||
<corners android:radius="@dimen/widget_secondary_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:left="96dp"
|
||||
android:top="80dp"
|
||||
android:right="96dp"
|
||||
android:bottom="16dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container_fallback" />
|
||||
<corners android:radius="@dimen/widget_secondary_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:left="176dp"
|
||||
android:top="80dp"
|
||||
android:right="16dp"
|
||||
android:bottom="16dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/widget_secondary_container_fallback" />
|
||||
<corners android:radius="@dimen/widget_secondary_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
||||
130
android/app/src/main/res/layout/conduit_widget.xml
Normal file
130
android/app/src/main/res/layout/conduit_widget.xml
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- ChatGPT-style widget design -->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/widget_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="@drawable/widget_background"
|
||||
android:clipToOutline="true">
|
||||
|
||||
<!-- Main "Ask Conduit" Pill -->
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_new_chat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="@drawable/widget_button_pill"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:layout_marginBottom="12dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:src="@drawable/ic_hub"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_marginEnd="12dp"
|
||||
tools:ignore="UseAppTint" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/widget_ask_conduit"
|
||||
android:textColor="@color/widget_on_primary"
|
||||
android:textSize="18sp"
|
||||
android:fontFamily="sans-serif-medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 4 Circular Icon Buttons Row -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<!-- Camera Button -->
|
||||
<FrameLayout
|
||||
android:id="@+id/btn_camera"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:background="@drawable/widget_button_circle">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_widget_camera"
|
||||
android:importantForAccessibility="no"
|
||||
tools:ignore="UseAppTint" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Photos Button -->
|
||||
<FrameLayout
|
||||
android:id="@+id/btn_photos"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginHorizontal="6dp"
|
||||
android:background="@drawable/widget_button_circle">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_widget_photos"
|
||||
android:importantForAccessibility="no"
|
||||
tools:ignore="UseAppTint" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Voice/Mic Button -->
|
||||
<FrameLayout
|
||||
android:id="@+id/btn_mic"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginHorizontal="6dp"
|
||||
android:background="@drawable/widget_button_circle">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_widget_waveform"
|
||||
android:importantForAccessibility="no"
|
||||
tools:ignore="UseAppTint" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Clipboard Button -->
|
||||
<FrameLayout
|
||||
android:id="@+id/btn_clipboard"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="6dp"
|
||||
android:background="@drawable/widget_button_circle">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_widget_clipboard"
|
||||
android:importantForAccessibility="no"
|
||||
tools:ignore="UseAppTint" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
31
android/app/src/main/res/values-night/colors.xml
Normal file
31
android/app/src/main/res/values-night/colors.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Material 3 Widget Colors (Dark Mode) -->
|
||||
|
||||
<!-- Primary colors for main button -->
|
||||
<color name="widget_primary">@android:color/system_accent1_200</color>
|
||||
<color name="widget_primary_dark">@android:color/system_accent1_400</color>
|
||||
<color name="widget_on_primary">@android:color/system_accent1_800</color>
|
||||
|
||||
<!-- Mic button colors (lighter accent inside pill) -->
|
||||
<color name="widget_mic_background">@android:color/system_accent1_200</color>
|
||||
<color name="widget_mic_icon">@android:color/system_accent1_800</color>
|
||||
|
||||
<!-- Secondary container colors for action buttons -->
|
||||
<color name="widget_secondary_container">@android:color/system_accent2_700</color>
|
||||
<color name="widget_on_secondary_container">@android:color/system_accent2_100</color>
|
||||
|
||||
<!-- Surface colors for widget background -->
|
||||
<color name="widget_surface">@android:color/system_neutral1_900</color>
|
||||
<color name="widget_surface_variant">@android:color/system_neutral2_700</color>
|
||||
|
||||
<!-- Fallback colors for pre-Android 12 -->
|
||||
<color name="widget_primary_fallback">#D0BCFF</color>
|
||||
<color name="widget_primary_dark_fallback">#9A82DB</color>
|
||||
<color name="widget_mic_background_fallback">#D0BCFF</color>
|
||||
<color name="widget_mic_icon_fallback">#4A3880</color>
|
||||
<color name="widget_secondary_container_fallback">#4A4458</color>
|
||||
<color name="widget_on_secondary_container_fallback">#E8DEF8</color>
|
||||
<color name="widget_surface_fallback">#1C1B1F</color>
|
||||
</resources>
|
||||
|
||||
10
android/app/src/main/res/values-night/dimens.xml
Normal file
10
android/app/src/main/res/values-night/dimens.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Widget dimensions (same for both modes) -->
|
||||
<dimen name="widget_padding">12dp</dimen>
|
||||
<dimen name="widget_button_spacing">6dp</dimen>
|
||||
<dimen name="widget_corner_radius">24dp</dimen>
|
||||
<dimen name="widget_button_corner_radius">16dp</dimen>
|
||||
<dimen name="widget_secondary_corner_radius">12dp</dimen>
|
||||
</resources>
|
||||
|
||||
31
android/app/src/main/res/values/colors.xml
Normal file
31
android/app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Material 3 Widget Colors (Light Mode) -->
|
||||
|
||||
<!-- Primary colors for main button -->
|
||||
<color name="widget_primary">@android:color/system_accent1_600</color>
|
||||
<color name="widget_primary_dark">@android:color/system_accent1_800</color>
|
||||
<color name="widget_on_primary">@android:color/white</color>
|
||||
|
||||
<!-- Mic button colors (lighter accent inside pill) -->
|
||||
<color name="widget_mic_background">@android:color/system_accent1_100</color>
|
||||
<color name="widget_mic_icon">@android:color/system_accent1_700</color>
|
||||
|
||||
<!-- Secondary container colors for action buttons -->
|
||||
<color name="widget_secondary_container">@android:color/system_accent2_100</color>
|
||||
<color name="widget_on_secondary_container">@android:color/system_accent1_700</color>
|
||||
|
||||
<!-- Surface colors for widget background -->
|
||||
<color name="widget_surface">@android:color/system_neutral1_10</color>
|
||||
<color name="widget_surface_variant">@android:color/system_neutral2_100</color>
|
||||
|
||||
<!-- Fallback colors for pre-Android 12 -->
|
||||
<color name="widget_primary_fallback">#6750A4</color>
|
||||
<color name="widget_primary_dark_fallback">#4A3880</color>
|
||||
<color name="widget_mic_background_fallback">#E8DEF8</color>
|
||||
<color name="widget_mic_icon_fallback">#6750A4</color>
|
||||
<color name="widget_secondary_container_fallback">#E8DEF8</color>
|
||||
<color name="widget_on_secondary_container_fallback">#1D192B</color>
|
||||
<color name="widget_surface_fallback">#FFFBFE</color>
|
||||
</resources>
|
||||
|
||||
10
android/app/src/main/res/values/dimens.xml
Normal file
10
android/app/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Widget dimensions following Material 3 guidelines -->
|
||||
<dimen name="widget_padding">12dp</dimen>
|
||||
<dimen name="widget_button_spacing">6dp</dimen>
|
||||
<dimen name="widget_corner_radius">24dp</dimen>
|
||||
<dimen name="widget_button_corner_radius">16dp</dimen>
|
||||
<dimen name="widget_secondary_corner_radius">12dp</dimen>
|
||||
</resources>
|
||||
|
||||
14
android/app/src/main/res/values/strings.xml
Normal file
14
android/app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Conduit</string>
|
||||
|
||||
<!-- Widget strings -->
|
||||
<string name="widget_name">Conduit</string>
|
||||
<string name="widget_description">Quick access to Conduit chat with camera, photos, and clipboard shortcuts</string>
|
||||
<string name="widget_ask_conduit">Ask Conduit</string>
|
||||
<string name="widget_camera">Camera</string>
|
||||
<string name="widget_photos">Photos</string>
|
||||
<string name="widget_clipboard">Clipboard</string>
|
||||
<string name="widget_mic">Voice</string>
|
||||
</resources>
|
||||
|
||||
18
android/app/src/main/res/xml/conduit_widget_info.xml
Normal file
18
android/app/src/main/res/xml/conduit_widget_info.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="250dp"
|
||||
android:minHeight="110dp"
|
||||
android:targetCellWidth="3"
|
||||
android:targetCellHeight="2"
|
||||
android:minResizeWidth="180dp"
|
||||
android:minResizeHeight="110dp"
|
||||
android:maxResizeWidth="400dp"
|
||||
android:maxResizeHeight="200dp"
|
||||
android:updatePeriodMillis="0"
|
||||
android:initialLayout="@layout/conduit_widget"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:widgetCategory="home_screen"
|
||||
android:previewImage="@drawable/widget_preview"
|
||||
android:description="@string/widget_description"
|
||||
android:widgetFeatures="reconfigurable" />
|
||||
|
||||
Reference in New Issue
Block a user