From 4107a4d5146dc3e79080c1e2ff13f01a0efbf25f Mon Sep 17 00:00:00 2001 From: Ygor Mutti Date: Mon, 7 Apr 2025 09:01:14 -0300 Subject: [PATCH 1/4] DROID-4000 Add icon --- .../res/drawable/ic_quick_create_tile.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 app/src/main/res/drawable/ic_quick_create_tile.xml diff --git a/app/src/main/res/drawable/ic_quick_create_tile.xml b/app/src/main/res/drawable/ic_quick_create_tile.xml new file mode 100644 index 0000000000..a06765b9e1 --- /dev/null +++ b/app/src/main/res/drawable/ic_quick_create_tile.xml @@ -0,0 +1,20 @@ + + + + + + + From c02cbfcd0ee11dad04f3abbfdd791269d756d2ea Mon Sep 17 00:00:00 2001 From: Ygor Mutti Date: Mon, 7 Apr 2025 09:06:42 -0300 Subject: [PATCH 2/4] DROID-4000 Adds tile service --- app/src/main/AndroidManifest.xml | 12 ++++ .../anytype/app/QuickCreateTileService.kt | 63 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 app/src/main/java/com/anytypeio/anytype/app/QuickCreateTileService.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 07cbba72cb..c7fbb9fc79 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -160,6 +160,18 @@ + + + + + + + diff --git a/app/src/main/java/com/anytypeio/anytype/app/QuickCreateTileService.kt b/app/src/main/java/com/anytypeio/anytype/app/QuickCreateTileService.kt new file mode 100644 index 0000000000..966b77c9c4 --- /dev/null +++ b/app/src/main/java/com/anytypeio/anytype/app/QuickCreateTileService.kt @@ -0,0 +1,63 @@ +package com.anytypeio.anytype.app + +import android.annotation.SuppressLint +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.service.quicksettings.Tile +import android.service.quicksettings.TileService +import com.anytypeio.anytype.ui.main.MainActivity + +/** + * Quick Settings tile service that allows creating new objects from the quick settings panel. + * + * The tile's behavior is configured through shared preferences: + * - typeKey: The type of object to create when clicked + * - label: The display label for the tile + * + * The tile will be unavailable if no type is configured, and greyed out (but clickable) when it's set. + * When clicked, it launches MainActivity with an intent to create a new object of the configured type. + */ +class QuickCreateTileService : TileService() { + private var typeKey: String? = null + + @SuppressLint("StartActivityAndCollapseDeprecated") + override fun onClick() { + super.onClick() + unlockAndRun { + val intent = Intent(Intent.ACTION_VIEW, null).apply { + setClass(applicationContext, MainActivity::class.java) + putExtra(DefaultAppActionManager.ACTION_CREATE_NEW_TYPE_KEY, typeKey) + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + val pendingIntent = PendingIntent.getActivity( + applicationContext, + 0, // request code + intent, + PendingIntent.FLAG_IMMUTABLE + ) + startActivityAndCollapse(pendingIntent) + } else { + startActivityAndCollapse(intent) + } + } + } + + override fun onStartListening() { + super.onStartListening() + updateTile() + } + + private fun updateTile() { + val prefs = getSharedPreferences(DefaultAppActionManager.QUICK_CREATE_TILE_PREFS, Context.MODE_PRIVATE) + typeKey = prefs.getString("typeKey", null) + + val tile = qsTile + tile.state = if (typeKey != null) Tile.STATE_INACTIVE else Tile.STATE_UNAVAILABLE + tile.label = prefs.getString("label", "New Object") + tile.updateTile() + } +} From d489e9b8c44d88bb03b044202fdbafe3190713d8 Mon Sep 17 00:00:00 2001 From: Ygor Mutti Date: Mon, 7 Apr 2025 09:13:03 -0300 Subject: [PATCH 3/4] DROID-4000 Set up quick tile on DefaultAppActionManager --- .../anytype/app/DefaultAppActionManager.kt | 20 +++++++++++++++++++ .../anytype/domain/misc/AppActionManager.kt | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/anytypeio/anytype/app/DefaultAppActionManager.kt b/app/src/main/java/com/anytypeio/anytype/app/DefaultAppActionManager.kt index d1e2d46d14..a9444a3c10 100644 --- a/app/src/main/java/com/anytypeio/anytype/app/DefaultAppActionManager.kt +++ b/app/src/main/java/com/anytypeio/anytype/app/DefaultAppActionManager.kt @@ -1,13 +1,16 @@ package com.anytypeio.anytype.app import android.content.Context +import android.content.ComponentName import android.content.Intent +import android.service.quicksettings.TileService import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat import com.anytypeio.anytype.R import com.anytypeio.anytype.domain.misc.AppActionManager import com.anytypeio.anytype.ui.main.MainActivity +import com.anytypeio.anytype.app.QuickCreateTileService import timber.log.Timber /** @@ -44,6 +47,7 @@ class DefaultAppActionManager(val context: Context) : AppActionManager { val shortcuts = ShortcutManagerCompat.getDynamicShortcuts(context).map { it.id } ShortcutManagerCompat.removeLongLivedShortcuts(context, shortcuts) ShortcutManagerCompat.removeAllDynamicShortcuts(context) + setupQuickCreateTile(null, null) } private fun setupCreateNewObjectAction( @@ -66,10 +70,26 @@ class DefaultAppActionManager(val context: Context) : AppActionManager { ) .build() ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) + + if (action.isDefault) { + setupQuickCreateTile(action.type.key, label) + } + } + + private fun setupQuickCreateTile(typeKey: String?, label: String?) { + val prefs = context.getSharedPreferences(QUICK_CREATE_TILE_PREFS, Context.MODE_PRIVATE) + val editor = prefs.edit() + editor.putString("typeKey", typeKey) + editor.putString("label", label) + editor.apply() + + val componentName = ComponentName(context.applicationContext, QuickCreateTileService::class.java) + TileService.requestListeningState(context, componentName) } companion object { const val ACTION_CREATE_NEW_ID = "anytype.app-action.create-new.id" const val ACTION_CREATE_NEW_TYPE_KEY = "anytype.app-action.create-new.key" + const val QUICK_CREATE_TILE_PREFS = "anytype.quick-create-tile" } } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/misc/AppActionManager.kt b/domain/src/main/java/com/anytypeio/anytype/domain/misc/AppActionManager.kt index b4a9030019..0a7f359044 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/misc/AppActionManager.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/misc/AppActionManager.kt @@ -9,7 +9,7 @@ interface AppActionManager { fun setup(actions: List) sealed class Action { - data class CreateNew(val type: TypeKey, val name: String) : Action() + data class CreateNew(val type: TypeKey, val name: String, val isDefault: Boolean = false) : Action() object ClearAll: Action() } } \ No newline at end of file From 7331c5c69a6d6f04b8a12615234a921436707ae1 Mon Sep 17 00:00:00 2001 From: Ygor Mutti Date: Mon, 7 Apr 2025 09:14:42 -0300 Subject: [PATCH 4/4] DROID-4000 Flag default type in CreateNew actions --- .../anytype/presentation/home/HomeScreenViewModel.kt | 3 ++- .../presentation/settings/PersonalizationSettingsViewModel.kt | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt index 8a416bb987..40683e7d48 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt @@ -1715,7 +1715,8 @@ class HomeScreenViewModel( if (type.map.containsKey(Relations.UNIQUE_KEY)) { AppActionManager.Action.CreateNew( type = TypeKey(type.uniqueKey), - name = type.name.orEmpty() + name = type.name.orEmpty(), + isDefault = defaultObjectType?.key == type.uniqueKey ) } else { null diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/settings/PersonalizationSettingsViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/settings/PersonalizationSettingsViewModel.kt index 68a594bbbb..7c44cabd3e 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/settings/PersonalizationSettingsViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/settings/PersonalizationSettingsViewModel.kt @@ -139,6 +139,7 @@ class PersonalizationSettingsViewModel( ) ).process( success = { wrappers -> + val defaultObjectType = getDefaultObjectType.async(SpaceId(spaceManager.get())).getOrNull()?.type val types = wrappers .map { ObjectWrapper.Type(it.map) } .sortedBy { keys.indexOf(it.uniqueKey) } @@ -146,7 +147,8 @@ class PersonalizationSettingsViewModel( val actions = types.map { type -> AppActionManager.Action.CreateNew( type = TypeKey(type.uniqueKey), - name = type.name.orEmpty() + name = type.name.orEmpty(), + isDefault = type.uniqueKey == defaultObjectType?.key ) } appActionManager.setup(actions = actions)