diff --git a/HTTPShortcuts/app/src/main/assets/docs/scripting.html b/HTTPShortcuts/app/src/main/assets/docs/scripting.html index 79b74ed2c..d9de53f53 100644 --- a/HTTPShortcuts/app/src/main/assets/docs/scripting.html +++ b/HTTPShortcuts/app/src/main/assets/docs/scripting.html @@ -81,7 +81,8 @@
With this function you can change the description of a shortcut. Simply pass the name or ID of a shortcut as the first parameter and the new description as the second one. You can also pass an empty string as the first parameter to target the current shortcut.
changeDescription('My Shortcut', 'New Description');
A shortcut's description is only visible in categories that use a list layout, not in those that use a grid layout.
With this function you can change the icon of a shortcut. Simply pass the name or ID of a shortcut as the first parameter and the name of the icon as the second one. You can also pass an empty string as the first parameter to target the current shortcut. Use the "Add Code Snippet" button in the app to select an icon. Alternatively, you can check the source code for all the available icons names (look for the prefix "R.drawable.", everything after it is a valid icon name).
changeIcon('My Shortcut', 'bitsies_lightbulb');
This function allows you to show or hide individual shortcuts inside the app. Simply pass the name or ID of a shortcut as the first parameter and true
or false
as the second parameter. You can also pass an empty string as the first parameter to target the current shortcut.
setShortcutHidden('My Shortcut', true);
-
You can make hidden shortcuts visible via an option on the Settings screen.
This section lists some of the options you have to control the execution flow of your script.
The wait
function allows you to delay execution by waiting (also called sleeping) for a specified number of milliseconds before continuing with the execution of the script.
wait(3000); // delay execution by 3 seconds
+
You can make hidden shortcuts visible via an option on the Settings screen.
This function allows you to show or hide categories. Simply pass the name or ID of a category as the first parameter and true
or false
as the second parameter.
setCategoryHidden('My Category', true);
+
There must always be at least one non-hidden category. If you try to hide the last visible category with this, nothing will happen.
This section lists some of the options you have to control the execution flow of your script.
The wait
function allows you to delay execution by waiting (also called sleeping) for a specified number of milliseconds before continuing with the execution of the script.
wait(3000); // delay execution by 3 seconds
Please note that this is a blocking action, meaning that you will not be able to interact with the app during the waiting time.
With the abort
function you can abort the execution of the shortcut.
abort();
If the shortcut was called from another shortcut via the executeShortcut function, only the current shortcut will be aborted. If you want to abort also the calling shortcut, you can use abortAll()
.
As part of the "Run on Success" code block, you can also use the abortAndTreatAsFailure()
function, which skips the rest of the "success" steps and instead treats the execution as a failure, meaning that the "Run on Failure" code will be run, as well as any other failure-related steps such as displaying an error message. You can use this in cases where the default behavior of only checking the HTTP status code is not enough to determine whether a request should be considered a success. As an optional parameter, you can pass a string which will be used as the error message.
// Basic example
abortAndTreatAsFailure();
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/categories/CategoriesViewModel.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/categories/CategoriesViewModel.kt
index d17a6f23a..4de2d1c73 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/categories/CategoriesViewModel.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/categories/CategoriesViewModel.kt
@@ -103,7 +103,7 @@ constructor(
val categoryId = activeCategoryId ?: skipAction()
updateDialogState(null)
withProgressTracking {
- categoryRepository.toggleCategoryHidden(categoryId, !visible)
+ categoryRepository.setCategoryHidden(categoryId, !visible)
hasChanged = true
showSnackbar(if (visible) R.string.message_category_visible else R.string.message_category_hidden)
}
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/editor/scripting/codesnippets/usecases/GenerateCodeSnippetItemsUseCase.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/editor/scripting/codesnippets/usecases/GenerateCodeSnippetItemsUseCase.kt
index 05d7a46a5..6eb5bb337 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/editor/scripting/codesnippets/usecases/GenerateCodeSnippetItemsUseCase.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/editor/scripting/codesnippets/usecases/GenerateCodeSnippetItemsUseCase.kt
@@ -322,6 +322,13 @@ constructor(
insertText("setShortcutHidden($shortcutPlaceholder, true", ");\n")
}
}
+ item(
+ R.string.action_type_change_category_hidden_title,
+ docRef = "set-category-hidden",
+ keywords = setOf("change", "update", "visible", "visibility", "hide", "hidden", "show"),
+ ) {
+ insertText("setCategoryHidden(\"category name", "\", true);\n")
+ }
}
section(R.string.dialog_code_snippet_control_flow, R.drawable.ic_control_flow) {
item(
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainContent.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainContent.kt
index 925789147..9481dd290 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainContent.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainContent.kt
@@ -56,7 +56,7 @@ fun MainContent(
if (categoryItems.size > 1) {
TabBar(
categoryItems = categoryItems,
- activeTabIndex = pagerState.currentPage,
+ activeTabIndex = pagerState.currentPage.coerceAtMost(categoryItems.size - 1),
onActiveCategoryIdChanged = onActiveCategoryIdChanged,
)
}
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainViewModel.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainViewModel.kt
index 18225abbd..7bf3a50a4 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainViewModel.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/activities/main/MainViewModel.kt
@@ -47,6 +47,8 @@ import ch.rmy.curlcommand.CurlCommand
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.drop
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -90,13 +92,26 @@ constructor(
private var activeShortcutId: ShortcutId? = null
override suspend fun initialize(data: InitData): MainViewState {
- this.categories = categoryRepository.getCategories()
+ val categoriesFlow = categoryRepository.getObservableCategories()
+ this.categories = categoriesFlow.first()
viewModelScope.launch(Dispatchers.Default) {
// Ensure that the VariablePlaceholderProvider is initialized
variablePlaceholderProvider.applyVariables(variableRepository.getVariables())
}
+ viewModelScope.launch {
+ categoriesFlow.drop(1).collect { categories ->
+ this@MainViewModel.categories = categories
+ updateViewState {
+ copy(
+ categoryItems = getCategoryTabItems(),
+ activeCategoryId = (categories.find { it.id == activeCategoryId && !it.hidden } ?: categories.first { !it.hidden }).id
+ )
+ }
+ }
+ }
+
val appLockObservable = appRepository.getObservableLock()
val appLock = appLockObservable.firstOrNull()
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/QueryExtensions.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/QueryExtensions.kt
index fb9c1cd33..a9a92943f 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/QueryExtensions.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/QueryExtensions.kt
@@ -30,6 +30,9 @@ fun RealmContext.getBase(): RealmQuery =
fun RealmContext.getCategoryById(categoryId: CategoryId): RealmQuery =
get("${Category.FIELD_ID} == $0", categoryId)
+fun RealmContext.getCategoryByNameOrId(categoryNameOrId: String): RealmQuery =
+ get("${Category.FIELD_ID} == $0 OR ${Category.FIELD_NAME} ==[c] $1", categoryNameOrId, categoryNameOrId)
+
fun RealmContext.getShortcutById(shortcutId: ShortcutId): RealmQuery =
get("${Shortcut.FIELD_ID} == $0", shortcutId)
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/categories/CategoryRepository.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/categories/CategoryRepository.kt
index a6fc7f621..a7d84da05 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/categories/CategoryRepository.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/domains/categories/CategoryRepository.kt
@@ -6,6 +6,7 @@ import ch.rmy.android.framework.extensions.swap
import ch.rmy.android.framework.utils.UUIDUtils.newUUID
import ch.rmy.android.http_shortcuts.data.domains.getBase
import ch.rmy.android.http_shortcuts.data.domains.getCategoryById
+import ch.rmy.android.http_shortcuts.data.domains.getCategoryByNameOrId
import ch.rmy.android.http_shortcuts.data.enums.CategoryBackgroundType
import ch.rmy.android.http_shortcuts.data.enums.CategoryLayoutType
import ch.rmy.android.http_shortcuts.data.enums.ShortcutClickBehavior
@@ -36,6 +37,11 @@ constructor(
getCategoryById(categoryId)
}
+ suspend fun getCategoryByNameOrId(categoryNameOrId: String): Category =
+ queryItem {
+ this.getCategoryByNameOrId(categoryNameOrId)
+ }
+
fun getObservableCategory(categoryId: CategoryId): Flow =
observeItem {
getCategoryById(categoryId)
@@ -96,8 +102,16 @@ constructor(
}
}
- suspend fun toggleCategoryHidden(categoryId: CategoryId, hidden: Boolean) {
+ suspend fun setCategoryHidden(categoryId: CategoryId, hidden: Boolean) {
commitTransaction {
+ if (hidden) {
+ val categories = getBase().findFirst()!!.categories
+ if (categories.all { it.hidden || it.id == categoryId }) {
+ // Disallow hiding the last non-hidden category
+ return@commitTransaction
+ }
+ }
+
getCategoryById(categoryId)
.findFirst()
?.hidden = hidden
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/models/Category.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/models/Category.kt
index 7defab03a..2eb305087 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/models/Category.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/data/models/Category.kt
@@ -83,6 +83,7 @@ class Category() : RealmObject {
companion object {
const val FIELD_ID = "id"
+ const val FIELD_NAME = "name"
const val NAME_MAX_LENGTH = 50
}
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/ActionFactory.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/ActionFactory.kt
index e4ff515a2..b8cfb4c4d 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/ActionFactory.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/ActionFactory.kt
@@ -36,6 +36,7 @@ import ch.rmy.android.http_shortcuts.scripting.actions.types.SendIntentActionTyp
import ch.rmy.android.http_shortcuts.scripting.actions.types.SendMQTTMessagesActionType
import ch.rmy.android.http_shortcuts.scripting.actions.types.SendTCPPacketActionType
import ch.rmy.android.http_shortcuts.scripting.actions.types.SendUDPPacketActionType
+import ch.rmy.android.http_shortcuts.scripting.actions.types.SetCategoryHiddenActionType
import ch.rmy.android.http_shortcuts.scripting.actions.types.SetResultActionType
import ch.rmy.android.http_shortcuts.scripting.actions.types.SetShortcutHiddenActionType
import ch.rmy.android.http_shortcuts.scripting.actions.types.SetVariableActionType
@@ -93,6 +94,7 @@ constructor(
sendMQTTMessagesActionType: SendMQTTMessagesActionType,
sendTCPPacketActionType: SendTCPPacketActionType,
sendUDPPacketActionType: SendUDPPacketActionType,
+ setCategoryHiddenActionType: SetCategoryHiddenActionType,
setShortcutHiddenActionType: SetShortcutHiddenActionType,
setResultActionType: SetResultActionType,
setVariableActionType: SetVariableActionType,
@@ -155,6 +157,7 @@ constructor(
sendMQTTMessagesActionType,
sendTCPPacketActionType,
sendUDPPacketActionType,
+ setCategoryHiddenActionType,
setShortcutHiddenActionType,
setResultActionType,
setVariableActionType,
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetCategoryHiddenAction.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetCategoryHiddenAction.kt
new file mode 100644
index 000000000..7ae199912
--- /dev/null
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetCategoryHiddenAction.kt
@@ -0,0 +1,33 @@
+package ch.rmy.android.http_shortcuts.scripting.actions.types
+
+import ch.rmy.android.http_shortcuts.R
+import ch.rmy.android.http_shortcuts.data.domains.categories.CategoryRepository
+import ch.rmy.android.http_shortcuts.exceptions.ActionException
+import ch.rmy.android.http_shortcuts.scripting.ExecutionContext
+import javax.inject.Inject
+
+class SetCategoryHiddenAction
+@Inject
+constructor(
+ private val categoryRepository: CategoryRepository,
+) : Action {
+ override suspend fun Params.execute(executionContext: ExecutionContext) {
+ setHidden(this.categoryNameOrId ?: "")
+ }
+
+ private suspend fun Params.setHidden(categoryNameOrId: String) {
+ val category = try {
+ categoryRepository.getCategoryByNameOrId(categoryNameOrId)
+ } catch (_: NoSuchElementException) {
+ throw ActionException {
+ getString(R.string.error_category_not_found_for_set_visible, categoryNameOrId)
+ }
+ }
+ categoryRepository.setCategoryHidden(category.id, hidden)
+ }
+
+ data class Params(
+ val categoryNameOrId: String?,
+ val hidden: Boolean,
+ )
+}
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetCategoryHiddenActionType.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetCategoryHiddenActionType.kt
new file mode 100644
index 000000000..7963de265
--- /dev/null
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetCategoryHiddenActionType.kt
@@ -0,0 +1,34 @@
+package ch.rmy.android.http_shortcuts.scripting.actions.types
+
+import ch.rmy.android.framework.extensions.takeUnlessEmpty
+import ch.rmy.android.http_shortcuts.scripting.ActionAlias
+import ch.rmy.android.http_shortcuts.scripting.actions.ActionData
+import ch.rmy.android.http_shortcuts.scripting.actions.ActionRunnable
+import javax.inject.Inject
+
+class SetCategoryHiddenActionType
+@Inject
+constructor(
+ private val setCategoryHiddenAction: SetCategoryHiddenAction,
+) : ActionType {
+ override val type = TYPE
+
+ override fun getActionRunnable(actionDTO: ActionData) =
+ ActionRunnable(
+ action = setCategoryHiddenAction,
+ params = SetCategoryHiddenAction.Params(
+ categoryNameOrId = actionDTO.getString(0)?.takeUnlessEmpty(),
+ hidden = actionDTO.getBoolean(1) != false,
+ ),
+ )
+
+ override fun getAlias() = ActionAlias(
+ functionName = FUNCTION_NAME,
+ parameters = 2,
+ )
+
+ companion object {
+ private const val TYPE = "set_category_hidden"
+ private const val FUNCTION_NAME = "setCategoryHidden"
+ }
+}
diff --git a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetShortcutHiddenActionType.kt b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetShortcutHiddenActionType.kt
index 92928006e..81ea24387 100644
--- a/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetShortcutHiddenActionType.kt
+++ b/HTTPShortcuts/app/src/main/kotlin/ch/rmy/android/http_shortcuts/scripting/actions/types/SetShortcutHiddenActionType.kt
@@ -18,7 +18,7 @@ constructor(
action = setShortcutHiddenAction,
params = SetShortcutHiddenAction.Params(
shortcutNameOrId = actionDTO.getString(0)?.takeUnlessEmpty(),
- hidden = actionDTO.getBoolean(1) ?: true,
+ hidden = actionDTO.getBoolean(1) != false,
),
)
diff --git a/HTTPShortcuts/app/src/main/res/values/strings.xml b/HTTPShortcuts/app/src/main/res/values/strings.xml
index c0661646c..005058781 100644
--- a/HTTPShortcuts/app/src/main/res/values/strings.xml
+++ b/HTTPShortcuts/app/src/main/res/values/strings.xml
@@ -774,6 +774,8 @@
Change Shortcut Description
Show/Hide Shortcut
+
+ Show/Hide Category
Enqueue Shortcut
@@ -1018,6 +1020,8 @@
Could not rename shortcut \“%1$s\” because it does not exist.
Could not change visibility of shortcut \“%1$s\” because it does not exist.
+
+ Could not change visibility of category \“%1$s\” because it does not exist.
Could not change icon of shortcut \“%1$s\” because it does not exist.