Skip to content

[Feature] JavaScript Addons Support - Reviewer Addons#9232

Closed
krmanik wants to merge 12 commits intoankidroid:mainfrom
krmanik:jsaddons-1
Closed

[Feature] JavaScript Addons Support - Reviewer Addons#9232
krmanik wants to merge 12 commits intoankidroid:mainfrom
krmanik:jsaddons-1

Conversation

@krmanik
Copy link
Copy Markdown
Member

@krmanik krmanik commented Jul 9, 2021

Pull Request template

Purpose / Description

Using AnkiDroid JS API a deck can be extended to implement features like progress bar or custom card layouts. But it requires user to manually add the html/css/js to card templates. This is implementation for a way to inject js code to all card templates when for activated addons.

This addon will be implemented in three part

  1. package download/extract/copy from npmjs
  2. List packages from directory
  3. Add enabled addons content to reviewer

Fixes

Fixes #7959

Approach

This implemented using TaskDelegate and jackson.
Jackson used to fetch latest package json then it parse to AddoInfo. There is isValidAnkiDroidAddon boolean function will check the addons is valid or not.

'Addons' menu to side navigation drawer

Added Addon Browser activity, it will be open from side nav menu

'Install Addons' button will be added at bottom for valid addona

Onlick 'Install Addon', confirmation alert shown

Download, extract and copied to addons folder

Implemented .tgz file extract and its test

This implemented using android.googlesource.com/TarUtil.java. There are test added by adding .tgz files to assets folder in androidTest. Using the functions to extract to temp folder and check if extracted files exists and match to original files.

Implemented AddonModel for mapping package.json from npmjs and its test

This is implemented using jackson

This is sample package.json of an addon. The jackson ObjectMapper map this to AddonModel.
The isvalidAnkiDroidAddon in next commits in this PR check if name, ankidroidJsApi, keywords and addonType present or not. These fields distinguish from other npm packages.

{
    "name": "ankidroid-js-addon-progress-bar",
    "version": "1.0.0",
    "author": "https://github.com/infinyte7",
    "homepage": "https://github.com/infinyte7/Anki-Custom-Card-Layout",
    "ankidroidJsApi": "0.0.1",
    "addonType": "reviewer",
    "keywords": ["ankidroid-js-addon"]
}

There are two types of addon reviewer and note_editor.
In this PR, first part of reviewer addon is implemented.

NpmUtils for extracting package name from url and its test

These are sample url of addons. The getAddonNameFromUrl function in NpmUtils extract package name from url. It replace https://www.npmjs.prg/package then check if / or '?' then split and get first element in split array.
View NpmUtilsTest for more.

The extracted package name used by Install Addons in Custom tabs.

    // npm search url
    private val NPM_PACKAGE_SEARCH_URL = "https://www.npmjs.com/search?q=keywords:ankidroid-js-addon"

    // valid npm package url
    private val NPM_PACKAGE_URL = "https://www.npmjs.com/package/valid-ankidroid-js-addon-test"

    // valid npm package url with version
    private val NPM_PACKAGE_URL_WITH_VERSION = "https://www.npmjs.com/package/valid-ankidroid-js-addon-test/v/1.0.0"

    // valid npm package url with ?activeTab
    private val NPM_PACKAGE_URL_WITH_TAB = "https://www.npmjs.com/package/valid-ankidroid-js-addon-test?activeTab=versions"

    // different url
    private val ANKIDROID_DOC_URL = "https://docs.ankidroid.org/"

Implemented Download addon, extract and copy to addons folder and its test

In this commit, files downloaded using TaskDelegate in background then extracted using previous tar extract implementation then copied to AnkiDroid/addons folder

test for isvalidAnkiDroidAddon using to .tgz file (valid & invalid .tgz files)

This is used for testing if current addon extracted in addons directory is valid or not. It will be helpful when user manually put the extracted files to addons folder. So, this function check before listing in AddonBrowser screen.

How Has This Been Tested?

Tested on emulator and devices

Demo

In this demo following tested

  • Click 'Addons' in NavigationDrawer
  • Open AddonBrowser screen (here addons will listed from addons directory - TODO next PR)
  • 'Install Addonbuttons added for only valid addon <br>Note: This option only added for URL starts withhttps://www.npmjs.com`
  • Then click Install Addon on npm package search URL i.e. https://www.npmjs.com/search?q=keywords:ankidroid-js-addon. It toasts with invalid addon message because no package can be extracted from search page.

    Now DownloadAddon class implemented using TaskDelegate download and do the following:-
    • Fetch package.json using jackson ObjectMapper to AddonModel
    • Check if name, ankidroidJsApi, keywords and addonType present or not
    • If package is valid, then get 'tarballurl fromdist:{}` field
    • Using HttpFetcher.downloadFileToSdCardMethod and tarball url download .tgz files
    • Using NpmPackageTgzExtract.extractTarGzipToAddonFolder extract to AnkiDroid/addons folder
  • Then go to invalid addon page and click 'Install Addon, it show toast with message invalid addons` and return
  • Listing of addons in AnkiDroid directory

Learning (optional, can help others)

https://junit.org/junit5/
https://github.com/FasterXML/jackson
https://github.com/FasterXML/jackson-docs
https://github.com/ankidroid/Anki-Android/wiki/Asynchronous-computation

Checklist

Please, go through these checks before submitting the PR.

  • [ x ] You have not changed whitespace unnecessarily (it makes diffs hard to read)
  • [ x ] You have a descriptive commit message with a short title (first line, max 50 chars).
  • [ x ] Your code follows the style of the project (e.g. never omit braces in if statements)
  • [ x ] You have commented your code, particularly in hard-to-understand areas
  • [ x ] You have performed a self-review of your own code
  • [ x ] UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • UI Changes: You have tested your change using the Google Accessibility Scanner

Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First quick look over - tests are failing

To discuss with the others @mikehardy @Arthur-Milchior: I don't think we should be implementing a second type of concurrency primitive in this PR. As much as I dislike AsyncTask, until we actively pick the new direction, we shouldn't fragment how we implement concurrency

return CompletableFuture.supplyAsync(() -> {
mTaskListener.addonShowProgressBar();
try {
ObjectMapper mapper = new ObjectMapper()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this fail if the NPM schema adds additional fields (which should be backwards compatible)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will fail if any fields in json change by NPM org.
The only field that depend this PR is getting tarball url to download .tgz file.
That file only can be downloaded from https://registry.npmjs.org/

Other fields like ankidroidJsApi and addonType distinguish from other npm packages.

So, for backward compatible JSONObject will be used to parse only required fields when above fails.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get your discussion.
Since you set the configuration not to fail on unknown property, it should work even if the properties change in the future

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would work. Because in JSONObject implementation that can not be solved. If these fields in top of package.json then it will work.
The PR is implemented according to this https://docs.npmjs.com/cli/v7/configuring-npm/package-json .

Copy link
Copy Markdown
Member

@david-allison david-allison Aug 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels that the issue is that NPM are already at v7, they'll happily go to v8, and when they do, it forces all AnkiDroid clients to update, or they'll be broken.

init();
shadowOf(getMainLooper()).idle();

CompletableFuture<String> result1 = mNpmPackageDownloader.getTarball(validAddonName);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Arthur-Milchior @mikehardy

What's our opinion on having tests depend on internet resources? I'm against this as-is (as it exposes us to failures from systems that we can't control).

I'd be OK if these were informational, rather than failing the build (maybe a separate test category + warning on GitHub, rather than a straight test failure).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget to remove this. Because CompletableFuture is removed from the class but not from test. I will remove it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that we already depended a lot on web, as we download things. I assume that the website we download from can afford it, even if its not efficient. Is github putting any limitation?
I'd clearly love to be as realistic as possible, so I find it cool to be tested actually.

I'm okay with informational failure, but I fear that it will be missed in the quantity of information, the ignored test, the long text printed.

Copy link
Copy Markdown
Member Author

@krmanik krmanik Jul 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The website will handle it, because this PR are not scrapping the website. In this PR user visit the npm package page as they visit in browser, then click 'Install Addon', here package.json downloaded for the package and tarball link extracted. The tarball taken from registry page of npm. http://registry.npmjs.org/
The same thing happen in nodejs cli in PC.

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 11, 2021

This PR is finally implemented using TaskDelegate with test.

@krmanik krmanik requested a review from david-allison July 11, 2021 22:25
@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 12, 2021

Added Install addon to custom tabs menu.

It will works as follows

  1. When Get more addons clicked in Addon Browser in AnkiDroid, it open url with search keywords ankidroid-js-addon

https://www.npmjs.com/search?q=keywords:ankidroid-js-addon

  1. Get url data from intent for selected addon page
  2. Check if the url is starts with https://www.npmjs.com/package/
  3. Then get addon's name from url
  4. Check if the addon is valid for AnkiDroid
  5. Download the addons

Copy link
Copy Markdown
Member

@Arthur-Milchior Arthur-Milchior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You wrote

to all deck templates
I don't understand it. Do you mean "card type's template"?

In your video, how is the user supposed to know what to enter and in which folder to go?
In particular, it's confusing to call it the name of the add-on while it's a command line.

Ideally, if there is a simpler way to deal with it, I'd prefer you take a real name. If it can't be done, then call it something else than "name".

Can you edit the first message, so that I know the current state of the code without having to check the latest comment.

I'd be great if you can rework the commit history. It seems that it's useless to read the sequence of commit one by one right now, and the whole change is so big it's hard to review. I probably forgot many comments,

init();
shadowOf(getMainLooper()).idle();

CompletableFuture<String> result1 = mNpmPackageDownloader.getTarball(validAddonName);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that we already depended a lot on web, as we download things. I assume that the website we download from can afford it, even if its not efficient. Is github putting any limitation?
I'd clearly love to be as realistic as possible, so I find it cool to be tested actually.

I'm okay with informational failure, but I fear that it will be missed in the quantity of information, the ignored test, the long text printed.

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 13, 2021

You wrote

to all deck templates
I don't understand it. Do you mean "card type's template"?

In your video, how is the user supposed to know what to enter and in which folder to go?
In particular, it's confusing to call it the name of the add-on while it's a command line.

The contents of addon in this code javascript code added to reviewer to any decks. i.e. any card templates.

Ideally, if there is a simpler way to deal with it, I'd prefer you take a real name. If it can't be done, then call it something else than "name".

name is npm package name. This is in package.json of npm package.

Can you edit the first message, so that I know the current state of the code without having to check the latest comment.

I will edit the first commit. I have implemented this PR with CompletableFuture then implemented using TaskDelegate and removed CompletableFuture

I'd be great if you can rework the commit history. It seems that it's useless to read the sequence of commit one by one right now, and the whole change is so big it's hard to review. I probably forgot many comments,

I will rewrite the commit history. The PR is started from Re-implemented using TaskDelegate and added test commit, all the previous commit can be ignored because that used CompletableFuture

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 13, 2021

It seems hard to remove the older commit without removing reviewed message.
Finally It has be done. This is clean PR with new commits. It only contains TaskDelegate and TaskListener.
All the previous implementation like (CompletableFuture, thread and other implementation removed from the commit history).

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 13, 2021

I thought that we already depended a lot on web, as we download things. I assume that the website we download from can afford it, even if its not efficient. Is github putting any limitation?

Use of npm Open Source
Subject to these Terms, npm grants you permission to use npm Open Source. That permission is not exclusive to you,
and you cannot transfer it to anyone else.

Your permission to use npm Open Source entitles you to do the following:

You may search for, download, publish, and manage packages of computer code (Packages) in the Public Registry,
and otherwise interact with the Public Registry, via the command-line tool published by npm at 
https://www.github.com/npm/npm (the CLI).

You may search for, download, publish, and manage Packages using software other than CLI via application 
programming interfaces that npm publicly documents or makes available for public use (Public APIs).

You may search for and manage Packages in the Public Registry, and otherwise interact with the Public Registry, 
via the Website.

You may update and manage your Account via the Website.

You may visit, create an account for, and participate in, discussions on npm.community.

@Arthur-Milchior
Copy link
Copy Markdown
Member

You wrote

to all deck templates
I don't understand it. Do you mean "card type's template"?

In your video, how is the user supposed to know what to enter and in which folder to go?
In particular, it's confusing to call it the name of the add-on while it's a command line.

The contents of addon in this code javascript code added to reviewer to any decks. i.e. any card templates.

I beg your pardon, you quote two questions I asked and give a single answer. It seems to ignore my second question, can you please answer it?

Also, what is the relation between deck and card template? Usually, there are none

Ideally, if there is a simpler way to deal with it, I'd prefer you take a real name. If it can't be done, then call it something else than "name".

name is npm package name. This is in package.json of npm package.

In this case, why does the name in your screen capture example start by "name -i"?

Can you edit the first message, so that I know the current state of the code without having to check the latest comment.

I will edit the first commit. I have implemented this PR with CompletableFuture then implemented using TaskDelegate and removed CompletableFuture

Sorry, in this case, I was not speaking of commit message. I understand the ambiguity. I was mentionning the first PR message. That is, what we see at the top of #9232 that starts by "Pull Request template"

By the way, it's not a problem if we loose some code comment in github. Either they are adressed and it's great. Or they are not, and we can redo them when we see the problem still exists.

I'd be great if you can rework the commit history. It seems that it's useless to read the sequence of commit one by one right now, and the whole change is so big it's hard to review. I probably forgot many comments,

I will rewrite the commit history. The PR is started from Re-implemented using TaskDelegate and added test commit, all the previous commit can be ignored because that used CompletableFuture

THanks

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 17, 2021

You wrote

to all deck templates
I don't understand it. Do you mean "card type's template"?

In your video, how is the user supposed to know what to enter and in which folder to go?
In particular, it's confusing to call it the name of the add-on while it's a command line.

The contents of addon in this code javascript code added to reviewer to any decks. i.e. any card templates.

I beg your pardon, you quote two questions I asked and give a single answer. It seems to ignore my second question, can you please answer it?

The same command copy from npmjs.org pasted inside edit text. But in later implementation, I added a menu to Custom tabs so, user do not need to copy it. They just have to visit the npmjs package then click 'Install Addon` from options menu.

Also, what is the relation between deck and card template? Usually, there are none

Ideally, if there is a simpler way to deal with it, I'd prefer you take a real name. If it can't be done, then call it something else than "name".

name is npm package name. This is in package.json of npm package.

In this case, why does the name in your screen capture example start by "name -i"?

I have written so that user may find what should be entered from npmjs package. But it will be removed and replaced with Custom tabs menu. It is more simpler than copying command from npmjs.

Can you edit the first message, so that I know the current state of the code without having to check the latest comment.

I will edit the first commit. I have implemented this PR with CompletableFuture then implemented using TaskDelegate and removed CompletableFuture

Sorry, in this case, I was not speaking of commit message. I understand the ambiguity. I was mentionning the first PR message. That is, what we see at the top of #9232 that starts by "Pull Request template"

By the way, it's not a problem if we loose some code comment in github. Either they are adressed and it's great. Or they are not, and we can redo them when we see the problem still exists.

I'd be great if you can rework the commit history. It seems that it's useless to read the sequence of commit one by one right now, and the whole change is so big it's hard to review. I probably forgot many comments,

I will rewrite the commit history. The PR is started from Re-implemented using TaskDelegate and added test commit, all the previous commit can be ignored because that used CompletableFuture

THanks

I have explained the commit message, also added test cases for almost all functions.

Copy link
Copy Markdown
Member

@Arthur-Milchior Arthur-Milchior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just reviewed the firs commit, I may go onto other commits later, but it's already big and hard to review.

I would really really love smaller commits, which introduce a single feature, such as extracting tgz or getting the name of add-on. This way, if we merge those features quickly, it mean the remaining of the PR is quick to review, as I'll only review the parts that we could not merge quickly first

@Arthur-Milchior
Copy link
Copy Markdown
Member

Oops, sorry, as I review commit by commit, I missed that you added test. I would appreciate if you could add tests in the same commit than the code they test.

If you want, we can take an hour at some point in time and pair code, so that at the very least I can discuss what I'd expect of commits. Because while they are split, they are not split in the way we usually do

@Arthur-Milchior
Copy link
Copy Markdown
Member

Also, I'd really love you to update the screen captured in the top of this page. Because I'd like to see the current version of the implementation. My questions were really related to the fact that your screen capture in the PR description contains "npm i"

@mikehardy
Copy link
Copy Markdown
Member

mikehardy commented Jul 17, 2021

This is an important feature that I really want, but no feature with 99 comments and +1500 lines of code in a single commit is okay. That is just not okay. I actively fear even looking at this. I avoid it.

This must be separated into even smaller things to be digestible - from my/our perspective there are more than 70 open PRs right now that all need attention, and 2 students working on Google Summer of Code that need lots of attention, along with regular release cycles and bugs and user feedback etc.

Reviewing a +1500 line commit that gets pushed multiple times per day is just not possible, I can't do it. I wish I could but I cannot.

When I see this text:

This implemented using TaskDelegate and jackson.
Jackson used to fetch latest package json then it parse to AddoInfo. There is isValidAnkiDroidAddon boolean function will check the addons is valid or not.

    Download addons from https://www.npmjs.com/search?q=keywords:ankidroid-js-addon inside the app
    In app there are implementation to check for valid addons for AnkiDroid
    It will check following string in latest package.json

{
    "name": "ankidroid-js-addon-progress-bar",
    "version": "1.0.0",
    "author": "https://github.com/infinyte7",
    "homepage": "https://github.com/infinyte7/Anki-Custom-Card-Layout",
    "ankidroidJsApi": "0.0.1",
    "addonType": "reviewer",
    "keywords": ["ankidroid-js-addon"]
}

Note: ankidroid_js_api and addon_type changed to ankidroidJsApi and addonType

I have also documented it here https://github.com/infinyte7/ankidroid-js-addon

There are two types of addon reviewer and note_editor.
In this PR, first part of reviewer addon is implemented.

I think of commits (maybe completely separate PRs) in chunks like:

  • Add method to parse package.json to AddonInfo with tests
  • Implement isValidAnkiDroidAddon boolean function will check the addons is valid or not with tests
  • Implement remote package fetch from npmjs.org with tests
  • Implement local package unpack with test (handle corrupt zip / pathological zip attack case)
  • Implement display of locally unpacked reviewer add-on packages with enabled/disable/delete status / actions
  • Implement npmjs.org remote query and result display with test (make sure network unavailable case is handled)
  • Orchestrate remote query+display / remote select+download+unpack+validate / reviewer add on list display / integrate

Each of those is a reasonably separate feature, at the very least easy to reason about as a separate commit

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 17, 2021

Yes, This PR is big. It needs split further. Currently I am doing that. I will mark it as draft for now. When PR split is done. I will mark it for Review. Thanks

@krmanik krmanik marked this pull request as draft July 17, 2021 16:59
@krmanik krmanik marked this pull request as ready for review July 18, 2021 14:58
@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jul 18, 2021

I have added contents to Pull Request Template explaining all commits in the PR.
I have considered all the reviewed message in this PR and implemented and split the PR.

Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, the UX on the download could do with improving. It's very hard to find the "install addon" button.

Once we find the "install" button, most of the listed addons on NPM don't install,

Is there a way to filter NPM to only addons which are available, then by star rating (/etc..) to avoid addons which don't work?

We might need to use the same technique that the "Shared Decks Download" uses here.

@krmanik krmanik changed the title [Feature] JavaScript Addons Support - npmjs addon package download (Part 1) [Feature] JavaScript Addons Support - Reviewer Addons Feb 7, 2022
@TarekkMA
Copy link
Copy Markdown
Contributor

TarekkMA commented Mar 3, 2022

Hi @krmanik,

I noticed you are constructing ObjectMapper multiple times. When I was researching about Jackson I found that it's a heavy object. So I've created AnkiSerialization in the past to provide a single instance. Maybe it will be useful here.

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Mar 3, 2022

Hi @TarekkMA
I will update the implementation to AnkiSerialization.

Also the PR needs review, so you can point out more suggestions.

Thanks

@TarekkMA
Copy link
Copy Markdown
Contributor

TarekkMA commented Mar 4, 2022

I will try to have a look tonight or tomorrow.

Copy link
Copy Markdown
Contributor

@TarekkMA TarekkMA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the things that I noticed right away, will try to give it another look sometime.

Thank you for the great work ❤️

val mapper = ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

val addonModel = mapper.readValue(File(file, "package/package.json"), AddonModel::class.java)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using jackson kotlin module, you can omit the last parameter.

Suggested change
val addonModel = mapper.readValue(File(file, "package/package.json"), AddonModel::class.java)
val addonModel: AddonModel = mapper.readValue(File(file, "package/package.json"))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It showing error.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to use jackson-module-kotlin library,

https://github.com/FasterXML/jackson-module-kotlin

Copy link
Copy Markdown
Contributor

@TarekkMA TarekkMA Mar 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to register it in AnkiSerilization class

val mapper = ObjectMapper().registerModule(KotlinModule())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood it but now I think I should split this PR into multiple PR for faster review. Please review the other PR I will create.

fun getJson(url: URL): MutableList<AddonModel>? {
try {
val mapper = AnkiSerialization.objectMapper
return mapper?.readValue(url, object : TypeReference<MutableList<AddonModel>>() {})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here you can use kotlin module to be more elegant looking.

Suggested change
return mapper?.readValue(url, object : TypeReference<MutableList<AddonModel>>() {})
return mapper?.readValue(url)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Mar 7, 2022

I will mark this PR as draft. Because it becomes harder to manage the code.
I will create 4-5 PR by splitting this PR. It will help in reviewing and managing the code.
I have already created first PR by splitting this PR.

@krmanik krmanik marked this pull request as draft March 7, 2022 09:32
@github-actions
Copy link
Copy Markdown
Contributor

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

@github-actions github-actions bot added the Stale label Jun 25, 2022
@mikehardy
Copy link
Copy Markdown
Member

I know you are watching the stale bot and keeping things that are "alive" live @krmanik - your patience is always appreciated
GSoC causes a huge PR load which I know you feel as well, we'll get all these through though...

@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jun 25, 2022

This PR is split and implemented in parts. So this PR should be closed. But the PR will be used as reference for suggestions and review other smaller PR.

I know you are watching the stale bot and keeping things that are "alive" live @krmanik - your patience is always appreciated GSoC causes a huge PR load which I know you feel as well, we'll get all these through though...

Yes, The priority should be GSoC, backend code then scope migration. Because I have more better idea for using backend code in add-on support.

@krmanik krmanik closed this Jun 25, 2022
@krmanik
Copy link
Copy Markdown
Member Author

krmanik commented Jun 25, 2022

There are some merged (split) PR and more will be merged soon.

https://github.com/ankidroid/Anki-Android/commits/main/AnkiDroid/src/main/java/com/ichi2/anki/jsaddons

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] JavaScript Addons support for AnkiDroid

5 participants