 Hello and welcome to the very first episode of Nicolò tries to do something useful for KDE in a totally new and different way by making an application for it. So that is actually something I never did. Like I did some contributions to other KDE applications, but usually not even that. Like my main field of work is KDE Plasma, which is the desktop and usually just the panel actually, because that's where most of my work goes and, you know, stuff that goes inside the panel. So we just that's what I usually do. But, you know, I had to do a different project for this time. I'm still working on the panel query. But at the same time, I've been preparing this other thing. So this is an application for KDE in theory, if everything goes well, that's a big if and it should be an app reader. Now you might ask, why does KDE need yet another application to read EPUBs? The answer is that surprisingly enough, currently no KDE application that I know of, maybe I missed some, but no KDE application that I know of can read EPUBs. Now, there is a plugin for Ocular. The problem is that it uses a very, very, very, very, very old library for reading EPUBs that mostly doesn't support anything. So what you get is not pretty. And of course, you lack everything that you are supposed to find in a EPUB reader like the ability to change the colors. Maybe you like dark mode, better or sepia and also the ability to change the text size. These kind of things are pretty important in a EPUB reader. Ocular doesn't have them. So I've actually been asked a lot to do videos on how explaining how to do KDE applets or how to do KDE applications. And usually I can't really act on that because that is such a wide range of topics to cover and it really depends on what you're trying to do. But I can talk and show you how I'm doing my thing. But keep in mind that again, this is not something that I usually do. Usually working, I'm working on something else entirely. But nonetheless, I do know some stuff. So it may be invite me. I hope it is a learning experience for you to to a certain extent. So this is my test app. Sorry, this is my test app. It's a great book. I suggest you that you already did if you're into it. This is a pub.js. A pub.js is a library for reading a pubs that is based on JavaScript. And it's kind of the standard nowadays, I think, like I've seen multiple appabreaders in the Linux world use it. I'm using as a reference for Lyate, I think it's called, which does that. Like it reads a pubs. This is introduction to topology, as an example. And this uses a pub.js. And you can see that you have options such as changing the colors, which is, again, not something you have in ocular. Then what else? There's also the elementary OS appabreader, whose name I currently forgot. They also use appab.js. I haven't used them much because I'm trying to read the source code of those projects to learn from it. But the elementary application source code is not for me. Like I don't understand anything. Foliati is slightly easier, so I can kind of get a screen on. This is because appab.js, in my very frank opinion, has terrible documentation. Like I cannot understand barely anything of how it's supposed to be used. So this is actually why I'm doing progress so slowly. But let me finally show you four minutes in what I have so far. This is just, you know, raw stuff that I'm working. So you can see that you do have the first page. You do have the ebook title. No, you don't, actually. But you do have the first page, which is great. And with these two arrows, you can switch pages. So right now you, like, I'm covering basic functionalities, but, you know, I'm trying. And the next step after being able to switch pages for me is being able to show the progress on this slider and, you know, being able to set the slider. But now it doesn't do anything. I'm just working on it. So how does this work code wise? Let's see very quickly the code. It's nothing particularly fancy. Again, it's me trying. So first, we have an HTML file because app.js is meant to be used in, like, a web page. So what we do is that we actually have a web page where we use app.js. And then we embed that web page inside the view of the Krugam application. Now, this is very different from doing something like Electron where the whole UI is a web page. I'm not doing that. Obviously, it's just what you see as the app, which is an embedded web view. So nothing particularly fancy. We have a div, which is an area which covers the entire screen where we actually render the app. We load this thing, which I kind of forgot about. Maybe it's not necessary. Like, I probably don't want to have this. I think it's for unzipping some compressed app. So I completely forgot about this, sorry. Then we load, you know, app.js. We create an app object reading the test app. We create a rendition object, which is the thing that actually manages the rendering of the app. And we tell it to render it to area, which is this thing. I could probably just say document body instead of area. I think I'm still learning. That's something to be investigated. Flow paginated, which means that you have like pages. I didn't show this, but if you resize this window, it will become multiple pages like this. That's pretty, I think. And this is what is meant with paginated. And I also tell it, please don't use more than two columns. Just that random value right now. I have nothing, I guess, like four pages if you have very big monitors. It's just right now. And then we got this displayed object, which was in the documentation. I have no clue right now how to use it, I think. So right now I'm not doing anything to it. Then we have a test function because I was trying how to, I was testing some of the objects to try to learn from them. This is just the web view. Now we get to the actual application, which is a Kuri-Gami application. And this is the most basic stuff. You have an application window, you set some sizes, and then you have page stack, which is like the pages of the application. If you add something to the page stack, it adds a page to the right for you it's here. So, you know, if you use Kuri-Gami applications, you know what I'm talking about. So we just set an initial page, which is probably the only page I'll ever need for this application. It's supposed to be simple and easy and everything. I'm hoping I'm not doing a mess. So we set the title, which in the future will actually be the title of the e-book, in theory. And then we take off all the padding because by default, we do have some padding on top, left, bottom, by default. We don't want that. We want the web view to touch the borders. So I just go with that. And then we add the two buttons that are on the top bar. We set the arrows. This is on the right. This is pointing on the right. This is pointing on the left. This is the action on the right. This is the action on the left, obviously. When this is trigger, we call view next, which I'll get to. When this is trigger, we'll call now it's a test, but it's view, sorry, prep, which these two functions will change the pages. We'll see now how. Here we have a column layout, which is completely useless actually. That was a mistake of mine. I don't actually need it, but what is important is this element, which is the web engine view. It's actually the webpage we just saw, but embedded in this component. And we're just saying, fill all the width, fill all the height. You gotta be as big as you want. Like try to be as big as you want. The URL of the HTML file is here. Now in theory, I guess, I shouldn't even rely on an external.html file. And I should just create the DOM instead, like the relevant elements inside of here. And then I can just run the JavaScript that you see here, but directly here. I guess that's another way to do it. Probably a better way. I will investigate. Again, I'm just trying to get things work. Then we'll see how to make them pretty. I also saw that for some reason, this object only gives me the errors that we get here. But if I have a console.logs, that gets ignored for some reason. So with this on JavaScript console message, console.logs message, this actually shows me every message that I console log inside of here, which is nice. And finally, we have the two functions that I talked about, which are our next and preview to change pages. And these just run some JavaScript inside of here, because of course, rendition and the book, all these important things are inside min.html. So if I want to do anything, I gotta run some JavaScript inside of here. And easy enough, I just called rendition.next and .rev, which changed the pages. Now, then I will have to do some more complex stuff. I'm not exactly sure how yet, especially because to be honest, the documentation just, I don't understand anything. I'm trying, I'm trying. And then finally, we have a footer, which is on the bottom with a slider. We had some padding around it, otherwise it's too cramped. And then we tell it to be as wide as possible. And in the future, I want like my next goal is to be able to read at like how many pages are there, what percentage are we currently of the book? But the point is that it's very difficult to talk about pages for an app, like an app itself. I think it doesn't actually have pages. It really depends on how you display it, like the size of the window and the size of font, these kinds of things. So pages should probably be dynamically calculated. And I think kpop.js does that. I just haven't understood how. But something I'm learning from is that there's this CFI, I think it's called, way to express precise locations inside of a app. And then I do see lots of methods called like percentage from CFI. I've understood how to calculate what CFI I'm currently displaying, which is great. I haven't understood how to get a percentage out of the CFI. And of course, I cannot get the general idea of a CFI, but it's weird. Can I show it? I think I can show it like here. I can console here, yes. So what I can do is take the element that manages the rendering, take the location of it. Now location has start and end, because I guess that the point, I think that start refers to the first line that you're rendering and the last line, these kind of things. I take the last point just, I think it's the same. And then I take the CFI and this actually works. And this test function now is called as a debugging way when I click on the left button. And if I get back here, you can see that if I press left, it tells me yes, app up CFI 6, 8, 4, 28, 2, 1, 18. Okay. Okay. I'm a trust you. Like I get the general idea, but I have no clue what those, all of those elements actually mean. Stuff like 1, 18, maybe this is a range. I don't know. I'm not an app expert. I'm just trying to do something. So are you an app expert? Trudy Kanavan, please don't sue me. I don't think it's illegal to show a couple of pages from the book, like just as an example on how the application works. But don't sue me, please. If you're an app expert and show about this stuff, maybe you've used app.js before. I don't know, you can write me a message. I'm sure I will be very happy to learn more, but nonetheless, I hope that provided some insightful commentary. Before you go though, and before I go, keep in mind that I'm doing all of this, this application, this videos, the contribution that I make to the panel, all thanks to your donation. Like literally the only thing that makes my work. So I'm close enough to get to the goal of November, but I won't reach it because November is too far close to the end. So nonetheless, I'm trying my best. So if you could like throw in the donations, if you haven't yet, if you are able to, that would be awesome. You know, I'm just trying my best. So thanks everybody for following and see you tomorrow with yet another video. Hopefully I will publish these videos with my progress sort of regularly, not every day, but every time I make some progress. Bye.