Skip to content
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

Integrate AnkiHub Sign-in #3232

Merged
merged 34 commits into from
Aug 17, 2024
Merged

Integrate AnkiHub Sign-in #3232

merged 34 commits into from
Aug 17, 2024

Conversation

abdnh
Copy link
Collaborator

@abdnh abdnh commented Jun 13, 2024

This PR integrates AnkiHub sign-in natively into Anki.

Summary

  • Added a section for AnkiHub sign-in to the preferences screen.
    image
    (The AnkiWeb section was updated to give a short intro about AnkiWeb too.)
  • Added a login dialog.
    image
  • Implemented login/logout API requests in the backend.
  • Install the AnkiHub add-on automatically after log-in.

@andrewsanchez @RisingOrange

@abdnh abdnh marked this pull request as draft June 13, 2024 13:33
This is used by the add-on.

#[derive(Serialize, Deserialize, Debug)]
pub struct LoginRequest {
// FIXME: we need to pass either `username` or `email`
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The add-on uses a regex to determine whether the user entered an email or a username, but maybe it makes more sense to move the logic to the AnkiHub backend so clients don't have to worry about that.

Copy link
Member

Choose a reason for hiding this comment

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

Any complexity we can push into the Rust layer means we don't have to duplicate work on each client.

@abdnh abdnh marked this pull request as ready for review June 13, 2024 17:25
@htester-kim
Copy link

htester-kim commented Jun 15, 2024

Sorry for asking, but shouldn't this feature be a part of the AnkiHub add-on instead of vanilla Anki, since these two aren't exactly maintained by the same people, and may lead to new users confusing them.

Secondly, from an outsider's view (who doesn't understand the difference between these similarly named products), this might seem like Anki is officially promoting microtransactions, since Ankihub is essentially a paid service.

I'm very thankful for what the Anking team has done for the community, and especially you for making so many add-ons, code contributions and much more. However, I believe significant considerations are still warranted before integrating a third party service into the vanilla ecosystem.

@brishtibheja
Copy link
Contributor

  1. If this is added, I think it should be made a bit more clear that it is a third-party service that Anki is unaffiliated with. Just another sentence making it clear. (I mean ankiweb explicitly states that ankidroid is created by a different group of people so why not here)

  2. I think I have never seen "don't have an account? sign up now" for third party services. This almost feels like promoting it instead of providing a way for users of this service an easy way to log-in.

Of course, none of what I say matter if dae is actually endorsing AnkiHub (but the point about droid app still stands imo)

@BrayanDSO
Copy link
Contributor

So, are you suggesting to add integration of a closed source, paid, third-party software to the main app?

Really, why?

@brishtibheja
Copy link
Contributor

What are you talking about, Brayan? I don't understand when did I suggest integrating a paid third party software. I'm saying 1. Anki should more prominently mention that this is a not officially endorsed software (if this is in fact the case). 2. Don't prompt Anki users to create an account there in any way. I think the "sign up now" link should be removed.

I'm not saying the rest should stay but if dae wants it who am I to go against it. I'm just providing feedback based on the assumption that everyone would like AnkiHub to be differentiated from AnkiWeb because as you said, paid, closed-source, third-party software.

@BrayanDSO
Copy link
Contributor

BrayanDSO commented Jun 15, 2024

What are you talking about, Brayan?

I'm asking the PR author (@abdnh) the motivation of this PR. Not talking about anyone else's commentaries. Sorry if I wasn't clear enough.

@BrayanDSO
Copy link
Contributor

BrayanDSO commented Jun 16, 2024

Some more questions to make this clearer:

  • why not an addon?
  • do you intend this to be an ecosystem feature? i.e. do you think that it should be implemented in AnkiMobile and AnkiDroid?
  • Why not an open API that any collaboration platform could use, like AnkiCollab (free and open source), AnkiHub or any other new one?

@chrislongros
Copy link

I like AnkiHub but I think native support will not offer more than the addon

@dae
Copy link
Member

dae commented Jun 22, 2024

For some background, the AnkiHub crew and I have spoken about this a bit already. AnkiHub would like to integrate their syncing code into the Rust layer, so that the mobile clients can be used directly with AnkiHub, instead of requiring access to a computer. This PR is an initial step towards that.

I was concerned that including this feature would appear to be promoting AnkiHub, and the existing descriptions were at my suggestion, as I want it to be clear to people that it's optional, and costs money. Suggestions on how to make it clearer are welcome.

Ideally, the collaboration features would be offered directly by AnkiWeb. But it's likely going to be quite a while until that happens. In the mean time, this is a step towards providing users with AnkiHub syncing across all platforms - at least for those who can afford the monthly fee.


#[derive(Serialize, Deserialize, Debug)]
pub struct LoginRequest {
// FIXME: we need to pass either `username` or `email`
Copy link
Member

Choose a reason for hiding this comment

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

Any complexity we can push into the Rust layer means we don't have to duplicate work on each client.

ftl/core/sync.ftl Outdated Show resolved Hide resolved
@@ -54,6 +54,12 @@ sync-upload-too-large =
Your collection file is too large to send to AnkiWeb. You can reduce its
size by removing any unwanted decks (optionally exporting them first), and
then using Check Database to shrink the file size down. ({ $details })
sync-ankihub-dialog-heading = Enable AnkiHub?
sync-ankihub-username-label = Username or Email:
sync-ankihub-signup-label = Don't have an AnkiHub account? <a href="{ $signup_link }">Sign up now</a><br><a href="{ $password_reset_link }">Forgot password?</a>
Copy link
Member

Choose a reason for hiding this comment

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

Please use separate strings instead of one big HTML one, as the mobile clients will likely use native widgets for now, not HTML.

@iamllama
Copy link
Contributor

I was concerned that including this feature would appear to be promoting AnkiHub, and the existing descriptions were at my suggestion, as I want it to be clear to people that it's optional, and costs money. Suggestions on how to make it clearer are welcome.

Perhaps the AnkiHub login section on desktop could be added in via their addon instead of being baked in, as a concession. It'd be understandable if the mobile clients did so, as they don't support addons yet

so that the mobile clients can be used directly with AnkiHub

Would this include AnkiDroid? @BrayanDSO is one of its active contributors and some of the concerns he raised above have still not been answered. This might indicate that more discussions are to be had among devs from the entire ecosystem

@BrayanDSO
Copy link
Contributor

BrayanDSO commented Jun 23, 2024

Why not an open API that any collaboration platform could use, like AnkiCollab (free and open source), AnkiHub or any other new one?

My question keeps unanswered.

Would this include AnkiDroid?

If it is an open standard that any platform can use, like AnkiCollab or AnkiHub, I support it 100%. If it is an endorsement of a closed, third-party, and paid platform like AnkiHub, I'm strongly against it, despite of how incredible it may be.

Since AnkiDroid doesn't have a BDFL governance like Anki, the decision depends on the other maintaners' opinions as well.

@mikehardy
Copy link
Contributor

Damien, with your gate-keeping control and knowledge of overall architecture, you could require this PR puts in place a nicely thought out interface / provider system such that all similar providers (including open ones) benefit. The arguments for / against are relatively obvious so I won't waste the bits but the difference in future state (short and long-term) are worth considering IMHO, they're pretty different

@brob3rto
Copy link

Please please make this open and make it benefit everyone. Ankihub would benefit a lot from millions of mobile users, so that seems only fair to ask.

But please also think if it is good to do this at all. I use Anki because it is open-source and I can get good decks for free. I know this is the same for a lot of people in my country and everywhere. If more decks go to Ankihub what then? So far Ankiweb still has great language decks, but what if that stops? Even if they make Ankihub free one day, it is bad that a closed website by someone else controls all the good decks, no?

Also a lot of friends are already confused about what is the real Anki and what is fake. This makes it even more confusing, no? If I know nothing about Anki and look at this, do I understand it? It is strange to have a website to download paid decks next to settings to sync my cards.

@dae
Copy link
Member

dae commented Jun 24, 2024

I've replied on the forum thread that was created:

https://forums.ankiweb.net/t/integrate-an-open-interface-for-collaboration-plaftorms/46372/9

you could require this PR puts in place a nicely thought out interface / provider system such that all similar providers (including open ones) benefit.

My understanding is that the initial implementation will effectively call ankihubSync() at the end of ankiwebSync(), so there isn't really anything that can be refactored into a reusable component at this stage. The implementation would serve as a reference for future implementors however, and in the future if it needs a UI, we'll need a way for such features to expose a config page.

@brishtibheja
Copy link
Contributor

  1. I couldn't find 'AI capabilities' mentioned in the main website.

  2. Why are you naming the technology instead of the feature?

  3. For the amount of information 'AI' provides, it draws too much attention from the user. It's capitalised. Also, it's vague enough to make you curious, but trustable enough because it comes with Anki.

@abdnh
Copy link
Collaborator Author

abdnh commented Jul 24, 2024

I couldn't find 'AI capabilities' mentioned in the main website.

It's not mentioned yet but many AI features are getting released this year: https://community.ankihub.net/t/march-may-2024-updates/231199

But since many people raised objections about this being a buzzword, we reworded the description to be like this:
image

@andrewsanchez
Copy link
Contributor

  • I couldn't find 'AI capabilities' mentioned in the main website.
  • Why are you naming the technology instead of the feature?
  • For the amount of information 'AI' provides, it draws too much attention from the user. It's capitalised. Also, it's vague enough to make you curious, but trustable enough because it comes with Anki.

@brishtibheja, I responded to this here.

@dae
Copy link
Member

dae commented Jul 26, 2024

Promoting third-party services

The recent changes are certainly an improvement.

I can understand why some people would (still) see this as promoting AnkiHub, as it may make people aware of the service who were not otherwise. We're not going to fully solve that without making it a hidden option, which I think would be over the top. I think the current service description is not unreasonable, but until we have a free alternative like AnkiCollab in the list as well, I can see how it could be seen as promotional by some.

I like the idea of a a 'learn more' link. It keeps promotional text out of the translations and shifts translation responsibility onto the third-party service. It also keeps those strings outside of the codebase, which some of our more puritanical users may appreciate.

That said, until AnkiCollab or some other option is in there too, perhaps the approach least likely to upset anyone is to remove the promotional text, and avoid adding a link for now, so only "AnkiHub" is shown. It still unlocks functionality for mobile clients (when this is all implemented), and offers a modicum of discoverablility for now. What do you think?

Clarifying future plans

This PR is trickier than normal to review. It's an MVP/first step towards something bigger, and thus there's not a lot of code to review at the moment, but it's also acting as a proxy for the larger question of "is the bigger goal of this and future PRs something that is likely to be merged?"

On the one hand, I understand why it has been done this way: AnkiHub doesn't want to invest a lot of time in building something that is unlikely to be accepted, and dividing large changes up into smaller steps can minimize wasted effort.

On the other hand, it means I need to a) consider that the current changes are a stepping-stone, and not the final point we want to end up at, and b) need to make a decision based on my understanding about future plans, instead of the code in front of me.

The following is how I understand you plan to move forward. Is it correct?

  • A follow-up PR in the next few months will add the ability to sync with AnkiHub automatically as part of the regular sync process - the user will sync normally, and the AnkiHub sync will happen as part of that regular sync. This should require minimal changes to the different clients, as most of the code should be in the Rust layer.
  • AnkiHub might want to store its auth token outside of the collection like AnkiWeb does, which will mean Rust won't have access to it. So the sync method might need to be extended to allow passing in third-party credentials, which each of the clients would need to be updated to support. Alternatively, if you're happy to have the auth token stored in collection config and shared between devices, that would allow the Rust layer to read it directly, and the client frontends would not need to be updated. The latter is appealing in that it minimizes work for the clients, but would mean you can't log out one device without logging them all out.
  • If in-app configuration is required in the future, it would be implemented as a Svelte page/fragment that the preferences screen can display, and Rust methods to load/store that data.

Brayan raised some concerns about the login screen being implemented in Qt, which will mean the mobile clients need to implement their own versions. What are your future plans here? Are you expecting a Svelte prefererences screen to be implemented before we integrate this into the mobile clients? Or are you expecting us to reimplement the login screen for the mobile clients for now?

Private approval

p.s. I would appreciate if any other proposals like this one would be done publicly and transparently, instead of receiving a thumbs-up in private and making people discover it only when there is a PR already opened.

To be fair, these were preliminary discussions done over a year ago, with no guarantee of approval. AnkiHub have still had to submit a public PR, which I haven't exactly rushed through, so the community at large has had a chance to participate too.

But I take your point - I regret that we didn't do a great job of providing the full context or future plans from the start, which has probably caused some undue alarm.

@abdnh
Copy link
Collaborator Author

abdnh commented Jul 26, 2024

Brayan raised some concerns about the login screen being implemented in Qt, which will mean the mobile clients need to implement their own versions. What are your future plans here? Are you expecting a Svelte prefererences screen to be implemented before we integrate this into the mobile clients? Or are you expecting us to reimplement the login screen for the mobile clients for now?

Just speaking about my impression here, I was thinking of the current login screen as a placeholder until we do the larger work of syncing integration, with no expectation for it to be implemented for mobile clients at this stage.

@andrewsanchez
Copy link
Contributor

I can understand why some people would (still) see this as promoting AnkiHub, as it may make people aware of the service who were not otherwise. We're not going to fully solve that without making it a hidden option, which I think would be over the top.

Let's be honest. This isn't not going to benefit AnkiHub. The question is, is that really a problem? I think the important thing is the motivation. The motivation is not promotion. The motivation is to solve serious user experience issues that lead to med students deciding not to use Anki. As we solve problems for our users, our goal is to do the same for all Anki users. This is a step in that direction.

That said, until AnkiCollab or some other option is in there too, perhaps the approach least likely to upset anyone is to remove the promotional text, and avoid adding a link for now, so only "AnkiHub" is shown.

The primary goal is to help people who are starting their journey on AnkiHub. So, while removing the description and link isn't ideal, it's not a major problem. That said, I think having a description and a link makes sense. But I also think it makes sense to move forward with an option that doesn't upset others.

A follow-up PR in the next few months will add the ability to sync with AnkiHub automatically as part of the regular sync process - the user will sync normally, and the AnkiHub sync will happen as part of that regular sync. This should require minimal changes to the different clients, as most of the code should be in the Rust layer.

👍🏻

if you're happy to have the auth token stored in collection config and shared between devices, that would allow the Rust layer to read it directly, and the client frontends would not need to be updated. The latter is appealing in that it minimizes work for the clients, but would mean you can't log out one device without logging them all out.

That's fine as long as users can log in again when the token expires. Tokens expire every 4 weeks or if the user logs in on a third device. Of course, this is all configurable on our backend.

If in-app configuration is required in the future, it would be implemented as a Svelte page/fragment that the preferences screen can display, and Rust methods to load/store that data.
👍🏻

Brayan raised some concerns about the login screen being implemented in Qt, which will mean the mobile clients need to implement their own versions. What are your future plans here? Are you expecting a Svelte prefererences screen to be implemented before we integrate this into the mobile clients? Or are you expecting us to reimplement the login screen for the mobile clients for now?

During the next step, we can consider how to build something that will support potential future integrations. For example, we could make a log-in screen that shows options for whatever integrations the user has enabled.

I am all for building something that others (even free alternatives/competitors) can benefit from. This applies to the "open interface" idea as well.

But I take your point - I regret that we didn't do a great job of providing the full context or future plans from the start, which has probably caused some undue alarm.

I agree and am all for more transparency and open discussion with the community, especially since we would like to start considering how we can contribute in a way that benefits all Anki users, not just AnkiHub users.

@BrayanDSO
Copy link
Contributor

BrayanDSO commented Jul 27, 2024

When designing the architecture, I strongly suggest trying to make it an extension of the app instead of integrating it, by adding an interface that you can use.

That way, it reduces the maintenence burden of Anki and AnkiDroid, and a development burden in AnkiMobile, where you supposedly can't help because it is closed source.

It would also help your product, since it makes possible to update your extension without having to create a PR here and pass through all the reviewing process. This PR was created almost two months ago and it hasn't moved much, so I think that it serves at least a little as an example.

Additionally, it would reduce the odds of breaking the extension when doing something else (e.g. 24.06 and 24.06.1 launches, which had simple and obvious issues that got launched due to a lack of testing).

Moreover, you would be able to release updates independently of Anki's release cycle, which commonly takes months to happen. That's probably only possible with Javascript/Typescript, but I don't see any problem with that, as it can call any defined Rust methods.

If you don't care about updating it because you expect it to be still and stable, I still reinforce the point about reducing the maintenance burden, since Anki's backlog is relatively big at the time being, and the rhythm here isn't that fast.

@@ -708,3 +708,15 @@ def set_network_timeout(self, timeout_secs: int) -> None:

def network_timeout(self) -> int:
return self.profile.get("networkTimeout") or 60

def set_ankihub_token(self, val: str | None) -> None:
self.profile["ankiHubToken"] = val
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest adding a prefix to the third-party keys. The name spaces will be a mess when other services are added

@abdnh
Copy link
Collaborator Author

abdnh commented Aug 6, 2024

We're not currently planning more changes on this @dae, unless if you think we need to implement this now:

I like the idea of a a 'learn more' link. It keeps promotional text out of the translations and shifts translation responsibility onto the third-party service. It also keeps those strings outside of the codebase, which some of our more puritanical users may appreciate.

As more third-party code is added, the link idea will no longer be practical of course. A separate Fluent repo for third party translations should be easy to add. Do you think services should also handle infrastructure (e.g. Pontoon) or you're OK with including them in https://i18n.ankiweb.net/?

@dae
Copy link
Member

dae commented Aug 7, 2024

Sorry guys, this is still on my radar, but got pushed back due to lack of time and lower-hanging fruit. Hopefully should have another review/reply by tomorrow.

Copy link
Member

@dae dae left a comment

Choose a reason for hiding this comment

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

I think with a few tweaks this should be good to go.

I'm a bit on the fence about the signup link - I fear some users may argue that it's driving traffic to AnkiHub. It doesn't bother me personally, as we have a signup link for AnkiWeb as well, and future services would get the same treatment. But it might be worth cutting out for now as a sign of good faith to that portion of our userbase that cares about this?

Some minor thoughts on the dialog appearance:

  • The service description is a bit redundant, as it's already shown in the listing in the preferences screen, but no strong feelings here.
  • There's a bit too much whitespace above the signup link, and below the forgot link

preferences-ankihub-not-logged-in = Not currently logged in to AnkiHub.
preferences-ankiweb-intro = AnkiWeb is a free service that lets you keep your flashcard data in sync across your devices, and provides a way to recover the data if your device breaks or is lost.
preferences-ankihub-intro = AnkiHub provides collaborative deck editing and additional study tools. A paid subscription is required to access certain features.
preferences-third-party-description = Third-party services are unaffiliated and not endorsed by Anki. Use of these services may require payment.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
preferences-third-party-description = Third-party services are unaffiliated and not endorsed by Anki. Use of these services may require payment.
preferences-third-party-description = Third-party services are unaffiliated with and not endorsed by Anki. Use of these services may require payment.

@@ -77,9 +76,16 @@ preferences-network-timeout = Network timeout
preferences-reset-window-sizes = Reset Window Sizes
preferences-reset-window-sizes-complete = Window sizes and locations have been reset.
preferences-shortcut-placeholder = Enter an unused shortcut key, or leave empty to disable.
preferences-third-party-services = Third-party services
preferences-ankihub = AnkiHub
Copy link
Member

Choose a reason for hiding this comment

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

We probably don't need to translate the service name?

Copy link
Member

Choose a reason for hiding this comment

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

Some blank space above the service name would also be good:

Screenshot 2024-08-08 at 7 54 51 PM

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Some blank space above the service name would also be good:

It looks fine on Windows. Adding some margin doesn't make a difference for me.

sync-sign-in = Sign in
sync-sign-up = Sign up
sync-forgot-password = Forgot password?
sync-ankihub-dialog-heading = Log into AnkiHub?
Copy link
Member

Choose a reason for hiding this comment

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

This would better match other dialogs in Anki:

Suggested change
sync-ankihub-dialog-heading = Log into AnkiHub?
sync-ankihub-dialog-heading = AnkiHub Login

@andrewsanchez
Copy link
Contributor

andrewsanchez commented Aug 8, 2024

I'm a bit on the fence about the signup link - I fear some users may argue that it's driving traffic to AnkiHub. It doesn't bother me personally, as we have a signup link for AnkiWeb as well, and future services would get the same treatment. But it might be worth cutting out for now as a sign of good faith to that portion of our userbase that cares about this?

I think removing the link for now as a sign of good faith that the intention is not to hijack Anki as a marketing tactic makes sense. Most users will come to this screen from AnkiHub so it's not a big deal.

When designing the architecture, I strongly suggest trying to make it an extension of the app instead of integrating it, by adding an interface that you can use.

@BrayanDSO, we made this PR to address some immediate concerns quickly and therefore excluded (temporarily) the important architectural concerns you and others have raised from this PR so that we could treat those considerations more thoroughly after taking this initial step. I know that's not ideal and I apologize for not doing a better job of communicating. For more context, we are rushing to improve the onboarding UX for new students who are starting medical school in the coming weeks.

That said, I think it would be great to discuss the next steps, including architecture, and how we can iterate on this in a way that benefits the whole ecosystem, doesn't create unnecessary maintenance burdens, etc, in-depth and openly on the forum. I'll be sure to ping you directly on those topics!

@BrayanDSO
Copy link
Contributor

we made this PR to address some immediate concerns quickly and therefore excluded (temporarily) the important architectural concerns

I don't expect things to get perfect immediately, and I believe that terative improvements is commonly the best way to do things, so please don't be feel rushed.

I also don't expect Anki to be able to handle cross-platform extensions for years, given ankitects' current priorities and the repo's pace of development. If you have in mind to avoid as much churn as possible, that's fine to me.

From a maintanence point, if you make something that only needs updates in Anki's repository, and not in the other ones, i.e. AnkiMobile and AnkiDroid (besides the initial implementation on them), it's already good enough to me. Doing everything in Rust and Svelte + avoiding changes in the API (like Image Occlusion recently did) makes that possible and isn't complex in terms of architecture.

Comment on lines 255 to 267
def ankihub_sync_login(self) -> None:
def on_success():
if self.mw.pm.ankihub_token():
self.update_login_status()

ankihub_login(self.mw, on_success, from_prefs_screen=True)

def ankihub_sync_logout(self) -> None:
def on_success():
self.mw.pm.set_ankihub_token(None)
self.update_login_status()

ankihub_logout(self.mw, on_success, self.mw.pm.ankihub_token())

Choose a reason for hiding this comment

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

⛏️ ankihub_sync_login doesn't set the credentials (they are set in ankihub_login instead) and ankihub_logout does set the credentials. By setting credentials I mean calling mw.pm.set_ankihub_token and mw.pm.set_ankihub_username. It would be better to make this consistent.

vbox.addWidget(bb)

diag.setLayout(vbox)
diag.show()
Copy link

@RisingOrange RisingOrange Aug 12, 2024

Choose a reason for hiding this comment

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

🔧 When I opened the AnkiHub login dialog, the text was cut off:

Suggested change
diag.show()
diag.adjustSize()
diag.show()

AnkiWeb's login dialog has the same problem:
https://github.com/abdnh/anki/blob/1ef83f07f61b178334eb5ce8710648d6bd1c34a3/qt/aqt/sync.py#L339



After adding `diag.adjustSize()`:

@dae
Copy link
Member

dae commented Aug 17, 2024

Thank you for your patience here!

@dae dae merged commit 520564d into ankitects:main Aug 17, 2024
1 check passed
@abdnh abdnh deleted the ankihub-login branch August 17, 2024 05:57
jeankhawand pushed a commit to jeankhawand/anki that referenced this pull request Aug 17, 2024
* Add AnkiHub section to preferences screen

* Add short intro for AnkiWeb and AnkiHub to syncing section

* Add AnkiHub login screen

* Implement login methods in backend

* Set minimum dialog width

* Add missing colon

* Respect the ANKIHUB_APP_URL env var

This is used by the add-on.

* Simplify login error reporting

* Fix from_prefs_screen not passed to subcall

* Add missing ankihub_pb2 import

* Install AnkiHub add-on after sign-in

* Avoid .exec()

* Update ftl/core/sync.ftl

Co-authored-by: Damien Elmes <dae@users.noreply.github.com>

* Split translation string

* Support login by username/email

* Fix entered username/email not being passed back to on_done

* Remove unused import

* Move to 'Third-party services' section

* Tweak login dialog's heading

* Remove 'third-party' from intro text

* Tweak copy

* Prefix profile keys

* Tweak strings

* Remove description from login dialog

* Remove signup links

* Clear credentials in ankihub_logout()

* Call .adjustSize()

* Title Case

* Add padding to third-party services, and fix tab order from other PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.