-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JS function to setTags and getTags #17795
base: main
Are you sure you want to change the base?
Conversation
@david-allison Do you think we should deprecate addTagToNote? Also [set/replace]NoteTags triggers lint failure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we should deprecate addTagToNote
Yes - haven't done our deprecation strategy in a while, not sure exactly how. Is it documented anywhere? May not be, but we should be able to mark something as deprecated and have it emit a warning in console or similar
This comment was marked as spam.
This comment was marked as spam.
783f9fa
to
36e8da6
Compare
From some searching, the most I can find is the deprecated decorator on Kotlin side, I dunno how we would approach on js. Is there official documentation for JS api? if not we can just have a comment? |
Hey! Can you you elaborate further? |
@Mizokuiam please stop. You are wasting everyone's time. |
Spammer? :( |
@Haz3-jolt I assume so. Negative value contributions, banned at organization level by me now. |
@mikehardy How is this for a deprecation warning? Since people mainly interact on Js side Subject: [PATCH] JS function to setTags and getTags
---
Index: AnkiDroid/src/main/assets/scripts/js-api.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/assets/scripts/js-api.js b/AnkiDroid/src/main/assets/scripts/js-api.js
--- a/AnkiDroid/src/main/assets/scripts/js-api.js (revision 6d3d270e9067fbad4797f25b0f3060adc60e41cd)
+++ b/AnkiDroid/src/main/assets/scripts/js-api.js (date 1736620228061)
@@ -121,6 +121,7 @@
Object.keys(jsApiList).forEach(method => {
if (method === "ankiAddTagToNote") {
AnkiDroidJS.prototype[method] = async function (noteId, tag) {
+ console.warn("ankiAddTagToNote is deprecated. Use ankiSetNoteTags instead.");
const endpoint = jsApiList[method];
const data = JSON.stringify({ noteId, tag });
return await this.handleRequest(endpoint, data); |
@Haz3-jolt I believe that deprecation in javascript console is the correctly location for it |
Amend the current commit or separate commit? |
amend I think, the deprecation of the old is part of adding the new to me, it's all one piece |
Cool! |
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
We should be using the Otherwise we risk edge cases |
"setNoteTags" -> {
val jsonObject = JSONObject(apiParams)
val noteId = jsonObject.getLong("noteId")
val tags = jsonObject.getJSONArray("tags")
withCol {
val note = getNote(noteId).apply {
this.tags = this@withCol.tags.split(tags.stringIterable().joinToString(" "))
}
updateNote(note)
}
convertToByteArray(apiContract, true)
} Would this be better? It uses split from the tags class in libanki |
@david-allison I still can't see how this would prevent any edge cases, any pointers? |
(not at my PC, DM me if this is ambiguous) I believe we have another I don't like the manual splitting of tags, we want to use the same logic each time (via a class/method), or a bug can lead to data corruption |
So i can directly use the method from Utils.kt in api? |
Subject: [PATCH] rEDO
---
Index: api/src/main/java/com/ichi2/anki/api/Utils.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/api/src/main/java/com/ichi2/anki/api/Utils.kt b/api/src/main/java/com/ichi2/anki/api/Utils.kt
--- a/api/src/main/java/com/ichi2/anki/api/Utils.kt (revision 633f2a37a0e95b34207494740f63a3321632d4aa)
+++ b/api/src/main/java/com/ichi2/anki/api/Utils.kt (date 1737822495862)
@@ -24,7 +24,7 @@
/**
* Utilities class for the API
*/
-internal object Utils {
+public object Utils {
// Regex pattern used in removing tags from text before checksum
private val stylePattern = Pattern.compile("(?s)<style.*?>.*?</style>")
private val scriptPattern = Pattern.compile("(?s)<script.*?>.*?</script>")
@@ -34,15 +34,15 @@
private const val FIELD_SEPARATOR = '\u001f'.toString()
// TODO: Add contract for null -> null and non-null to non-null when kotlin contracts become stable/out of experimental phase
- fun joinFields(list: Array<String>?): String? = list?.joinToString(FIELD_SEPARATOR)
+ public fun joinFields(list: Array<String>?): String? = list?.joinToString(FIELD_SEPARATOR)
- fun splitFields(fields: String): Array<String> =
+ public fun splitFields(fields: String): Array<String> =
fields
.split(FIELD_SEPARATOR.toRegex())
.dropLastWhile { it.isEmpty() }
.toTypedArray()
- fun joinTags(tags: Set<String?>?): String {
+ public fun joinTags(tags: Set<String?>?): String {
if (tags.isNullOrEmpty()) {
return ""
}
@@ -52,9 +52,9 @@
return tags.joinToString(" ")
}
- fun splitTags(tags: String): Array<String> = tags.trim { it <= ' ' }.split("\\s+".toRegex()).toTypedArray()
+ public fun splitTags(tags: String): Array<String> = tags.trim { it <= ' ' }.split("\\s+".toRegex()).toTypedArray()
- fun fieldChecksum(data: String): Long {
+ public fun fieldChecksum(data: String): Long {
val strippedData = stripHTMLMedia(data)
return try {
val md = MessageDigest.getInstance("SHA1")
Index: AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt
--- a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt (revision 633f2a37a0e95b34207494740f63a3321632d4aa)
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt (date 1737822029568)
@@ -58,6 +58,7 @@
import org.json.JSONException
import org.json.JSONObject
import timber.log.Timber
+import com.ichi2.anki.api.Utils
typealias JvmBoolean = Boolean
typealias JvmInt = Int
@@ -383,7 +384,7 @@
withCol {
val note =
getNote(noteId).apply {
- setTagsFromStr(this@withCol, tags.stringIterable().joinToString(" "))
+ setTagsFromStr(this@withCol, Utils.joinTags(tags.stringIterable().toSet()))
}
updateNote(note)
} @david-allison Here is a patch of changes if it's all good, ill push changes. |
Something like this Index: AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt
--- a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt (revision 633f2a37a0e95b34207494740f63a3321632d4aa)
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidJsAPI.kt (date 1737833155918)
@@ -45,6 +45,7 @@
import com.ichi2.libanki.Card
import com.ichi2.libanki.Collection
import com.ichi2.libanki.Decks
+import com.ichi2.libanki.Note
import com.ichi2.libanki.SortOrder
import com.ichi2.utils.NetworkUtils
import com.ichi2.utils.stringIterable
@@ -377,13 +378,19 @@
}
"setNoteTags" -> {
+
val jsonObject = JSONObject(apiParams)
val noteId = jsonObject.getLong("noteId")
val tags = jsonObject.getJSONArray("tags")
withCol {
+ fun Note.setTagsFromList(tagList: List<String>) {
+ val tagsAsString = [email protected](tagList)
+ setTagsFromStr(this@withCol, tagsAsString)
+ }
+
val note =
getNote(noteId).apply {
- setTagsFromStr(this@withCol, tags.stringIterable().joinToString(" "))
+ setTagsFromList(tags.stringIterable().toList())
}
updateNote(note)
} |
Got it, thanks for the help! |
@david-allison did the final changes, and confirmed that all tests are passing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing for a tag with a space, or trailing whitespace would be useful
4b7ec2b
to
5b2f5bc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be the last one!
@david-allison Any other changes? Ive double checked that both functions are working. |
@david-allison although I don't think I can do it rn, any idea on how a integration test for the setTags can be done? Perhaps setting a note with the Js function in the note, and using espresso to find the button or something? |
@david-allison should I re base and force push to check if any conflicts are there? its been a while since this PR has been open |
Okay so looks like no conflicts |
The PR will display conflicts if there are any (and it'll have Has Conflicts ) If it's sat for a while, a rebase saves a little time on our end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cheers!
Purpose / Description
Adds two JS API functions [set/replace]NoteTags and getTagsFromNote which act similar to PUT and GET from a REST API
Fixes
Approach
Adds two methods to allow the caller to get Tags and update/set tags.
How Has This Been Tested?
Added two unit tests both verified and passing.
Checklist
Please, go through these checks before submitting the PR.