-
-
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 Addons] list addons from addons directory #10985
base: main
Are you sure you want to change the base?
Conversation
00ebeac
to
8cf509f
Compare
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
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.
A bunch of unrelated comments :-), I don't see anything really wrong here - a minor structural question, some Kotlin null-typing stuff and some grammar bikeshedding ... Curious for thoughts on all of them
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowser.kt
Outdated
Show resolved
Hide resolved
AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/AddonsBrowserAdapter.kt
Outdated
Show resolved
Hide resolved
private fun deleteSelectedAddonPackageDir(addonModel: AddonModel) { | ||
// remove the js addon folder | ||
val currentAnkiDroidDirectory = CollectionHelper.getCurrentAnkiDroidDirectory(context) | ||
val addonsHomeDir = File(currentAnkiDroidDirectory, "addons") | ||
val dir = File(addonsHomeDir, addonModel.name) | ||
|
||
val deleted = BackupManager.removeDir(dir) | ||
|
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.
I don't want to over-engineer it, but I feel like having the filesystem code mixed in with the UI code will make it harder to test etc - you have AddonModel, Is there an AddonStorage perhaps, where the "get me the add on directory / get me the list of addons in directory / delete the addon" code could go? Then it would be really easy to have a test just for that stuff
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.
I have created AddonStorage
class. It is more cleaner and better implementation. Thanks
* | ||
* @param addonModel | ||
*/ | ||
private fun deleteSelectedAddonPackageDir(addonModel: AddonModel) { |
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.
I think delete can go in the new extracted AddOnStorage object now
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.
I think it's really close now - can put more into the storage class and use it by reference, and should probably do a second refactor as a follow-on to have code from previous PRs use the storage class as well and centralize all the directory / file handling (from the download/install/unpack PRs)
I think this is good idea to handle the addons related file/folder related from a centralized class. I will do refactor in next PR. (Added to TODO) |
I'm going to move this to draft just as a strategy to manage the PR review queue, and because I know you are focused on exams right now (as you should be!). Cheers |
I will update the PR later. |
Hello 👋, this PR has been opened for more than 2 months with no activity on it. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 7 days until this gets closed automatically |
Hello 👋, this PR has been opened for more than 2 months with no activity on it. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 7 days until this gets closed automatically |
Not stale - dormant because of too much work on my end and prioritizing scoped storage but this will all happen. JS addons are the future and this is the infrastructure... |
Hello 👋, this PR has been opened for more than 2 months with no activity on it. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 7 days until this gets closed automatically |
Hello 👋, this PR has had no activity for more than 2 weeks and needs a reply from the author. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 7 days until this gets closed automatically |
The JS AddOn series needs to stay open. It is perfect for 2.17 once storage is finally done |
I will start implementing this after scope storage. |
@krmanik If you want I can look into fixing and updating the code in this PR to get it merged. Maybe the other related PR as well. |
Pains me greatly that these aren't merged yet and I feel a lot of responsibility there - not sure how @krmanik feels about it but I would owe you or anyone a debt of gratitude if the work here was finally shepherded in. It's good stuff IMHO and would be a big step forward I think |
@BrayanDSO I believe you had the last conversation regarding addons in the forums. Pinging for your understanding & thoughts |
Reviewer add-ons won't happen in the desktop version if they aren't 99,99% secure, and Damien apparently doesn't want it even as a per-notetype opt-in setting with a big warning or just stopped replying because he's busy with something else. To avoid duplicating the bulletproofing job in the mobile versions, the reviewer should ideally be moved to Svelte first. I do think that there should be a JS API and addons infrastructure as soon as possible so we can take advantage of the work of other developers. If we wait until all of those desktop issues to be solved (probably at least 3 years from now if I'm optimistic with the current development pace), we will lose a lot of work that could be done in the addons ecosystem in that meantime. There are a lot of developers, including myself, that may have some time and motivation right now, but not in the future. I could have implemented the whole infrastructure when I created the forums post, but I lost two weeks just in discussion, and stopped getting replied. Now I don't have time for it, nor I want to do it anymore in the future. So I strongly suggest to continue the JS addons work here in AnkiDroid. To avoid issues in the future, like when Anki implemented a different TTS syntax, I suggest consulting Damien and making him compromise with the API, with whatever is saved in the collection, and with the way that addons are distributed. |
Ok, I'll be implementing the code in this PR for now. |
6fcb827
to
b4aebcc
Compare
Thanks @lukstbit for continuing this PR. This is good features we can support for AnkiDroid. I still busy at the moment but willing to review if I get chance. |
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.
I think we all want this to move forward. Let's do it
Given the nature of this feature, I'd like to see a little documentation of folder structures on the disk, and how profiles will interact with this feature when they're added.
In Anki Desktop, addons are global across profiles. This change doesn't allow for this.
I'd like to think about deep links to addons, and how/whether we'd want to accomplish this
@@ -463,6 +463,10 @@ | |||
android:theme="@style/Theme.AppCompat.NoActionBar" | |||
android:configChanges="keyboardHidden|screenSize" /> | |||
|
|||
<activity android:name=".jsaddons.AddonsBrowserActivity" |
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.
Don't use jsaddons
, we can't change the package name later, and this ties us to a technology
@@ -463,6 +463,10 @@ | |||
android:theme="@style/Theme.AppCompat.NoActionBar" | |||
android:configChanges="keyboardHidden|screenSize" /> | |||
|
|||
<activity android:name=".jsaddons.AddonsBrowserActivity" | |||
android:parentActivityName=".DeckPicker" |
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.
Is this correct? I suspect we're starting this from Preferences
in the initial release
// package.json in tgz file does not contains dist but it is available when the file loaded | ||
// from network, the dist contains .tgz url which will be used to download the file |
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.
Move to KDoc for the class, or move to a constructor which can handle fromNetwork
/fromFile
|
||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { | ||
val addonModel = | ||
BundleCompat.getParcelable(requireArguments(), KEY_ADDON_MODEL, AddonModel::class.java) |
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.
can this be extracted to a val
companion object { | ||
private const val KEY_ADDON_MODEL = "key_addon_model" | ||
|
||
fun newInstance(addonModel: AddonModel): AddonDetailsDialog = AddonDetailsDialog().apply { |
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.
@CheckResult
* @return some-addon dir e.g. AnkiDroid/addons/some-addon/ | ||
*/ | ||
fun getSelectedAddonDir(addonName: String): File { | ||
return File(addonsHomeDir, addonName) |
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.
*/ | ||
fun deleteSelectedAddonPackageDir(addonName: String): Boolean { | ||
val dir = getSelectedAddonDir(addonName) | ||
return BackupManager.removeDir(dir) |
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.
use a better named API
*/ | ||
// TODO ===== EXTRACT RELATED STRINGS FOR TRANSLATION BEFORE RELEASE ===== | ||
class AddonsBrowserActivity : AnkiActivity() { | ||
private val addonsAdapter by lazy { |
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.
Can we move to a ViewModel here?
return oldItem.modelRef.name == newItem.modelRef.name && | ||
oldItem.modelRef.addonType == newItem.modelRef.addonType && | ||
oldItem.modelRef.addonTitle == newItem.modelRef.addonTitle && | ||
oldItem.modelRef.author["name"] == oldItem.modelRef.author["name"] && | ||
oldItem.modelRef.author["url"] == oldItem.modelRef.author["url"] && | ||
oldItem.modelRef.version == newItem.modelRef.version && | ||
oldItem.modelRef.ankidroidJsApi == newItem.modelRef.ankidroidJsApi && | ||
oldItem.modelRef.description == newItem.modelRef.description && | ||
oldItem.modelRef.homepage == newItem.modelRef.homepage && | ||
oldItem.modelRef.license == newItem.modelRef.license && | ||
oldItem.modelRef.dist.tarball == newItem.modelRef.dist.tarball |
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.
move to the class
android:src="@drawable/ic_extension" | ||
app:tint="@color/material_blue_grey_100" /> | ||
|
||
<TextView |
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.
FIxedTextVIew
Interesting. With per-profile add-ons you can have the same add-on for everyone but you can also have "AnkiGamify" and "Ank-2-button" (I'm making those up) just for your toddler's profile as they're learning phonics without it affecting yours. That is, per-profile is the most powerful style IMHO. If it was one or the other, I'd say per-profile. Deep links? Perhaps we should just get it in first 😆 |
@david-allison @mikehardy |
Contains the initial code to fetch and parse addons and also the basic UI to display the addons.
b4aebcc
to
61feaa0
Compare
Android Studio interface is changed, rebased the code, now add changes to the code. |
This comment was marked as resolved.
This comment was marked as resolved.
@david-allison Thanks for the changes, I have added it to local codebase. I have started implementing the suggested changes, will take some days to implement the features. |
Pull Request template
Purpose / Description
This is UI for addons listing in recycler view from addons directory. The list in view will contains
details
,remove
andtoggle switch
button.Also addons menu added to side bar but it will be hidden till all the PR merged.
The implementation will be used in next PR when addons listed from network for download and install.
Fixes
Fixes #7959
Approach
dist
package.json made empty when package.json loaded from local directory.details button
- show popup with addons info like name, author, version etc.remove button
- remove the addons from directorytoggle switch
- used to enable/disable addons, for enabled addons, the content will be added to reviewer or note editorHow Has This Been Tested?
Tested on emulator and devices. (Test will be added in next PR)
demo.mp4
Learning (optional, can help others)
Checklist
Please, go through these checks before submitting the PR.
if
statements)