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

Feature: Bring your own font #3020

Draft
wants to merge 22 commits into
base: develop
Choose a base branch
from
Draft

Conversation

Fesaa
Copy link
Contributor

@Fesaa Fesaa commented Jun 26, 2024

Added

  • Added: user may provide their own fonts to be used in the epub reader

THIS IS A DRAFT

I'm not done with this yet, quite a bit to do. But feel like it is time to ask for feedback on a few things. Opening a draft pull request, just so it's here as well. Will cross post in the discord after.

Loading the fonts.

They're currently being loaded in the book-reader, this should ensure they're only being loaded when needed. I've also not noticed any higher loading times, but I've only had max 4 fonts loaded. We may want to try with a bunch more, at the very least the default ones, to see if it has any noticeable impact.

Design choices

Need some feedback / greenlight for design choices as to call what what, and place what where.

  • Fonts are called EpubFonts
  • Fonts are stored in ${pwd}/config/fonts

If these are fine, how do we want to differentiate between the default fonts, and user fonts? Can we store them in the same folder, should we not?

If these are not fine, suggestions as to changes to do.

Link with AppUserPreferences

Currently, the font preference for a user is saved, as the fonts name. It's still doing this currently, and should work fine. However, we could change this to the ID of the font. Having it be the fonts name, does make it easier to load and reset them. As simple as changing it to default.

Default font
The dropdown menu in the UI, currently, isn't displaying the default font, as it's not an EpubFont. Where should I best inject this option? In the UI, or the controller; instinctively I would do it in the controller, such that the UI doesn't have too much extra logic it has no business of owning. But wanted to ask for opinions anyway, maybe there is a better place?

Notes

  • The controller currently has the wrong authorize annotations, still has to be changed.
  • The seed class doesn't have all default fonts in it yet. I only copied over one
  • I'll probably squash commits before merging and give them a better name

TODO's

Apart from "smaller" TODO's in the code. I think these are the big ones still to do

  • Add update task in Admin UI
  • Auto scan fonts
  • Scan update communication with UI

I may have missed some

will add comments in draft pull request
Copy link
Member

@majora2007 majora2007 left a comment

Choose a reason for hiding this comment

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

Overall a great start. I didn't pull it down and test it, but from the code, I got the jist of it. I think this will be a great enhancement, but I do strongly think moving to a more UI centered loading system would be really smart. This will reduce friction by having to have admin's add their own fonts via their filesystem and instead rely completely on the UI.

I would also argue that we could expand this functionality to non-admins (we would need a role for this). And if we really wanted to go to the next step, we could intake not only a file, but a Google Fonts url and download directly into the fonts directory.

Let me know your thoughts as that expands the scope (but would be really fun to code).

API/Controllers/FontController.cs Outdated Show resolved Hide resolved
API/Controllers/FontController.cs Outdated Show resolved Hide resolved
API/Controllers/FontController.cs Outdated Show resolved Hide resolved
API/Controllers/FontController.cs Outdated Show resolved Hide resolved
API/Controllers/FontController.cs Outdated Show resolved Hide resolved
this.bookService.getEpubFonts().subscribe(fonts => {
fonts.forEach(font => {
const fontFace = new FontFace(font.name, `url(${this.bookService.baseUrl}Font/download-font?fontId=${font.id})`);
fontFace.load().then(loadedFace => {
Copy link
Member

Choose a reason for hiding this comment

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

One thing I'm worried about is timing. There is no way to know if all the fonts are loaded or not. I also don't see setting the loaded fonts somewhere for the user to select from.

Copy link
Member

Choose a reason for hiding this comment

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

Second pass, I think instead what we should do is move this load fonts to the book service. To make this most efficient, we can cache the loaded fonts and return the fonts from that.

bookService.getEpubFonts() {
 getFonts().pipe(tap(f => {
            const fontFace = new FontFace(font.name, `url(${this.bookService.baseUrl}Font/download-font?fontId=${font.id})`);
            fontFace.load().then(loadedFace => { // cache then put on the document }
            // ...
}

We just need to bust this when we get a fontScan complete (or if we go the theme manager route, book theme modified event).

Thoughts?

UI/Web/src/app/book-reader/_services/book.service.ts Outdated Show resolved Hide resolved
UI/Web/src/app/book-reader/_services/book.service.ts Outdated Show resolved Hide resolved
@majora2007
Copy link
Member

As mentioned in Discord, I will be taking a look and working on this to help with the implementation and polishing.

@majora2007
Copy link
Member

Okay here's my plan of attack on this:

  1. System Provided fonts (like I did with themes). This will allow the UI to mimic the theme manager.
  2. For the google font idea, we can do it by url. They need to give us the url https://fonts.google.com/specimen/Inter and we then call https://fonts.google.com/download/list?family=Inter. This will give us the download information. This will all happen on the backend. Likely we need a Role for this.
  3. Currently you only allow Woff, but not all fonts are in that format. We can expand this further to provide a better experience.

There were quite a bit of bugs I found that prevented me from actually testing this. I will be working on your code today and pushing to a branch feature/font-manager. We can collaborate after the fact.

@majora2007
Copy link
Member

First pass of work is implemented, you can review and see my approach and the bugs fixed in feature/font-manager.

I fixed up how loading takes place for System provided fonts (and fixed seeding as you were checking for fonts in the theme table) and updated the manager to match the UX of Theme manager. Lots of small improvements overall from your code.

I put a few todos as well in there. I can return to this work later, but this should be enough if you want to start tackling and furthering what I did.

@Fesaa
Copy link
Contributor Author

Fesaa commented Jul 13, 2024

Hi! I'll have a look tomorrow and try to do some TODO's 🎉

Fesaa added 11 commits July 14, 2024 00:25
Not moving fox string as the idea behind it is that every letter is in the sentence.
This adds a list entry at the top to return to the upload new font page, this was not possible before without refreshing the page or leaving and returning to the font tab.
Simple design, happy to make changes to it
If we want to add other types, we will also have to update it in the Parser
This deletes a font, regardless of it being used by users or not
Adds a toggle to hide system fonts in the fonts list
Styles the add button better, and aligns it with the style of other add
buttons in the user preferences menu
This way we don't have to request all fonts again, and have one function
for the animation, which I can't figure out for now
# Conflicts:
#	API/Data/Migrations/DataContextModelSnapshot.cs
#	API/Services/DirectoryService.cs
#	UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts
#	UI/Web/src/app/book-reader/_components/reader-settings/reader-settings.component.ts
#	UI/Web/src/app/user-settings/manga-user-preferences/manage-user-preferences.component.ts
#	UI/Web/src/app/user-settings/theme-manager/theme-manager.component.html
#	UI/Web/src/app/user-settings/theme-manager/theme-manager.component.ts
#	UI/Web/src/app/user-settings/user-preferences/user-preferences.component.html
#	UI/Web/src/assets/langs/en.json
#	openapi.json
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.

2 participants