# Gempub adventures, the final chapter? Alright, enough is enough. I ran into some problems with my microcontroler-based project. Since that was on pause, I still wanted to be able to read a gpub without my laptop... I don't use a smartphone (I have a feature phone with an eink screen), but I had an old LG Nexus 5x (actually, two of them) lying around. I thought: okay, so building my own has stalled... can I code something up for Android and just keep an old phone with no connection to any networks in the car for reading while I wait in the parking lot for my child to get out of school? I decided to find out. I knew I had only a few routes: 1. Java/Kotlin, Flutter, React Native, that sort of thing. 2. A progressive web app (PWA). The Android development environment is heavy and I use an old system. I didn't think I wanted to do that. Plus, I didn't think I really wanted to start from scratch again. I knew the tech involved in a PWA, more or less. I don't like writing JavaScript, but I did it for a living until frameworks and chasing the shiny thing became so prevalent. So I knew that was a route that I could manage. I spent three days reading documentation and adapting code (as well as writing new code). I had already written a browser-based gpub reader. It had some bugs and did not work like I wanted the application to work, but it handled page turning and had basic css and layout already taken care of. It also had all of the code for unzipping a gpub and building a table of contents and that sort of thing. So I figured I had that in my pocket, and could start on other aspects. I wrote a library page first, something to hold books. I knew I wanted the PWA to not just open a book, but be able to manage them a bit as well. I borrowed the unzipping code and had a form that code "import" a book into the application/library. I use the word "import" since the browser cannot, due to security necessities, access the hard drive willy nilly. So the books get stored in the browser. I had two real options for doing this: 1. IndexedDb 2. localSorage IndexedDb was the more powerful option. Probably also more performant. It would give me access to a ton of storage... but it was an async api. I really dislike working with and reasoning about async code in JS. localStorage on the other hand was an old friend. I knew how it worked and only needed two very simple function calls and a synchronous workflow. The down- side was that there were more severe restrictions on space. Most modern browsers let a site have between 5mb and 10mb of localStorage. I looked at the books I had in gpub format. The largest was around 350kb. I also used localStorage for storing user settings and book position/metadata. So after all of that I figured that I would still store around 10 books, especially given that that 350k book was a pretty long book. 10 books in storage seemed fine. So I went with that. Next I added a settings page with stubs for theme (dark or light), font size, and whether or not to prevent the screen from sleeping while reading. I also added a read only display of how much storage was currently being used (as a percent of total). Lastly, I got the reader working. It stored extra stuff since my other reader, the one I took the code from, did not keep track of where you were in books. It just expected you to keep a book open until you were done with it. This new reader keeps track, since having a library implies you can move freely between books. Okay. All of that done I wrote up a manifest file. This allows your phone to "install" the website to your home screen. The manifest provides icons, color theming for surrounding native window ui, and lets the OS know that the "application" should be run in full screen. The last bit was the service worker. This registers the application with the browser and uses the `fetch` api to cache pages and then return the cached pages when a request for them is made. This allows the program to run fully offline. It just gets the cache version every time, which is great for my purpose. If I want, I can update the service worker with a new version number and change various details about caching or the like and a user that already uses the application will get a silent update in the bg. I have been reading a book I had started on my laptop in my terminal reader. It has been really nice to spend three days and achieve the goal of being able to read gpubs on the go. I remain very convinced that they are a nice, simple format and should have a real place in the ebook landscape. I really like them. They are small, fast, and easy to work with (both as a reader and as a writer). If you are interested in trying it out, the reader is called "Peregrin" (a fool of a Took)... which continues my LoTR naming scheme (I have programs called Bombadillo, Elrond, and Goldberry already). It can be accessed here: https://peregrin.colorfield.space The source code, as well as some instructions and other information is here: https://tildegit.org/sloum/peregrin You can find books here: gemini://zaibatsu.circumlunar.space/~sloum/collections/ or here: https://zaibatsu.circumlunar.space/~sloum/ More information about gpubs in general can be found here: gemini://zaibatsu.circumlunar.space/~sloum/formats/gpub.gmi or here: https://gpub.colorfield.space If you have been reading these phlog posts, thanks for following along. I think I am done with the gpub tinkering now. I just get to read good stuff with the fruits of my labor. Maybe I'll find something else to write soon. Until then, be well!