[{"content":"Personal management knowledge and productivity tools has been important for me, especially for my chaotic behavior (pardon me). I started taking notes in Zettelkasten method since the first time I entered uni, so it\u0026rsquo;s been three years ago. And since I\u0026rsquo;m a huge fan of terminal apps, I\u0026rsquo;ve been doing this on my terminal; Neovim is my preferred tool for taking notes.\nZettelkasten on Neovim I mainly use Neovim, I\u0026rsquo;ve used zk and zk-nvim. The zk CLI experience was decent because its use is intended for writing notes in Zettelkasten method. I love the way it already provides some basic commands to create notes, to filter my notes, LSP, etc. To support my workflow, I also installed marksman LSP, so it was all great. But, since it only works on desktop, I looked for another solution; both in desktop and my Android phone.\nI\u0026rsquo;ve never liked Obsidian app on both desktop and Android, to be honest. Why? Simply because I prefer simplicity and cleanness on the UI (but Ray, you never liked GUI apps at all! You\u0026rsquo;re a fucking terminal nerd). In my opinion, Obsidian doesn\u0026rsquo;t met my requirement on what a clean UI is. I never enjoyed writing notes in Obsidian especially on phone. Fine, the plugins are cool but still, I don\u0026rsquo;t like its UI; too much clutter. From all of this time, GUI apps on desktop often confuses me; too many buttons, opened tabs here and there and will likely distracts me.\nSo, my workflow all these time was: I write notes in Neovim with the help of zk and obsidian.nvim, and mobile is for read-only. It\u0026rsquo;s really rare of me to take notes on phone. If I really need to write stuff, I prefer to do it inside Keep and add it later to my Obsidian vault from desktop.\nFrom writing notes alone, I already used many software and after years of doing this, I was thinking \u0026ldquo;this is too much\u0026rdquo;.\nFound Logseq After three years of doing that, I decided to look for another solution. I found Logseq. I always looked away from Logseq while I\u0026rsquo;m searching for alternatives because at the first impression, I didn\u0026rsquo;t really understand how to use this software; it uses bullet points to take notes, which I thought it\u0026rsquo;s kinda weird and I haven\u0026rsquo;t tried much whether it could render markdown. Since I was too exhausted on using my old workflow because from time to time, it makes me lazy to write notes because inconvenience, I tried Logseq once again.\nAfter learning the usage for a while, I was amazed and regretted that I always looked away from this app. I wish I started with Logseq earlier rather than the Obsidian workflow.\nLogseq is actually usable for my zettelkasten workflow out of the box rather than using Obsidian that needs some setups. It doesn\u0026rsquo;t force me to give my notes titles because Logseq approach is more to journaling, so, when you open the app, it\u0026rsquo;s already on today\u0026rsquo;s note. Sure, Obsidian can also do this by using plugin or setting up some stuff on the settings page but compared to Logseq, Obsidian still needs too much work to set it up.\nI never thought that I really love the idea of writing on the journal page directly that it has less work only for writing notes.\nI\u0026rsquo;m naturally not a writer nor have the ability to write long paragraphs. The bullet point approach on Logseq helped me to write my notes better than just writing on a plain markdown where I think I need to write beautiful sentences. I love that I can directly write core ideas within each bullet points. What if a particular core idea has a child or a branching idea? Just press enter and indent the bullet point, no need to write conjunction words.\nLogseq fans have been waiting on the new Logseq DB version which I myself also can\u0026rsquo;t wait to try it out. Since it\u0026rsquo;s still on beta version, I consider myself to stay on the original Logseq app for now but I wish the DB version is will be better and improved alot. Thanks Logseq devs!\nConclusion So that was my journey on personal knowledge management tool. I don\u0026rsquo;t know if my future self will move to another software but for now I found Logseq is great and suitable for me.\n","permalink":"https://rayfadh.codeberg.page/posts/changes-on-my-personal-knowledge-management-workflow/","summary":"\u003cp\u003ePersonal management knowledge and productivity tools has been important for me, especially for my chaotic behavior (pardon me). I started taking notes in Zettelkasten method since the first time I entered uni, so it\u0026rsquo;s been three years ago. And since I\u0026rsquo;m a huge fan of terminal apps, I\u0026rsquo;ve been doing this on my terminal; Neovim is my preferred tool for taking notes.\u003c/p\u003e\n\u003ch2 id=\"zettelkasten-on-neovim\"\u003eZettelkasten on Neovim\u003c/h2\u003e\n\u003cp\u003eI mainly use Neovim, I\u0026rsquo;ve used \u003ca href=\"https://github.com/zk-org/zk\"\u003ezk\u003c/a\u003e and \u003ca href=\"https://github.com/zk-org/zk-nvim\"\u003ezk-nvim\u003c/a\u003e. The \u003ccode\u003ezk\u003c/code\u003e CLI experience was decent because its use is intended for writing notes in Zettelkasten method. I love the way it already provides some basic commands to create notes, to filter my notes, LSP, etc. To support my workflow, I also installed \u003ca href=\"https://github.com/artempyanykh/marksman\"\u003emarksman\u003c/a\u003e LSP, so it was all great. But, since it only works on desktop, I looked for another solution; both in desktop and my Android phone.\u003c/p\u003e","tags":["Self Development"],"title":"Changes on My Personal Knowledge Management Workflow"},{"content":"This is a guide about how I use Ormin as my project dependency.\nInitialize the Project Initialize your new project with Nimble:\n$ nimble init \u0026lt;myproject\u0026gt; Or, you can also make the directory first and run:\n$ mkdir \u0026lt;myproject\u0026gt; $ nimble init After that, nimble init will interactively ask you about the metadata of your project, such as package type (library, binary, or hybrid), initial version, description, etc.\nInitialize Ormin Clone Ormin\u0026rsquo;s repository from GitHub:\n$ git clone git@github:Araq/ormin.git Or using HTTPS:\n$ git clone https://github.com/Araq/ormin.git (Optional, because we will override this later). Add Ormin as your project dependency on the \u0026lt;myproject\u0026gt;.nimble file:\n$ nimble add ormin While using Ormin, db_connector is still needed, so:\n$ nimble add db_connector Run nimble setup and Nimble will automatically create config.nims and nimble.paths for you.\nEdit the nimble.paths and change the ormin path to this:\n--noNimblePath --path:\u0026#34;/home/yourusername/.nimble/pkgs2/db_connector-0.1.0-xxx\u0026#34; --path:\u0026#34;ormin\u0026#34; # this one Pro-Tip: Simplifying Paths You can safely delete --noNimblePath and the hardcoded db_connector path. By removing them, the Nim compiler will automatically find the correct versions of your dependencies in $HOME/.nimble/, keeping your configuration clean and portable.\nThe last step is to compile the ormin_importer.nim and copy the binary to either $HOME/.local/bin/ or /usr/local/bin/. I chose my $HOME local binary directory.\n# inside your project root $ cd ormin/tools $ nim c ormin_importer.nim $ cp ormin_importer $HOME/.local/bin/ $ cd ../.. # return to project root Create the Database Create your SQL file inside the src/ directory. For example, this is my schema:\n-- src/user_model.sql create table if not exists users ( id integer primary key, name varchar(20) not null ); And then, run:\n$ ormin_importer src/user_model.sql This will create the .nim file equivalent of your SQL file.\nThis is how the project directory would look like:\nmyproject/ ├── ormin/ \u0026lt;-- Cloned repo ├── src/ │ ├── myproject.nim \u0026lt;-- Main code │ ├── user_model.sql \u0026lt;-- Schema │ └── user_model.nim \u0026lt;-- Generated by ormin_importer ├── nimble.paths \u0026lt;-- Path config └── myproject.nimble \u0026lt;-- Metadata Now, open your project\u0026rsquo;s main entry; it would be inside src/\u0026lt;myproject\u0026gt;.nim and edit the file.\nimport ormin import ormin/db_utils from db_connector/db_sqlite import exec importModel(DbBackend.sqlite, \u0026#34;user_model\u0026#34;) # this loads the generated .nim file let db {.global.} = open(\u0026#34;test.db\u0026#34;, \u0026#34;\u0026#34;, \u0026#34;\u0026#34;, \u0026#34;\u0026#34;) srcDir = currentSourcePath.parentDir() sqlFile = Path(srcDir / \u0026#34;user_model.sql\u0026#34;) insertUser = sql\u0026#34;insert into users(id, name) values (?, ?)\u0026#34; db.droptable(sqlFile, \u0026#34;users\u0026#34;) db.createTable(sqlFile, \u0026#34;users\u0026#34;) db.exec(insertUser, 1, \u0026#34;rayfadh\u0026#34;) # inserts id, and name let users = query: select users(name) echo users # @[\u0026#34;rayfadh\u0026#34;] Now, run this inside your project root:\n$ nimble run Going Further For more information, the test specs of Ormin are easy to read and understand, so if you need more examples, just take a look at the test specs.\nSo that\u0026rsquo;s how I use Ormin on my Nim project. Hope this helps!\n","permalink":"https://rayfadh.codeberg.page/posts/using-ormin-as-a-dependency/","summary":"\u003cp\u003eThis is a guide about how I use \u003ca href=\"https://github.com/Araq/ormin\"\u003eOrmin\u003c/a\u003e as my project dependency.\u003c/p\u003e\n\u003ch2 id=\"initialize-the-project\"\u003eInitialize the Project\u003c/h2\u003e\n\u003cp\u003eInitialize your new project with Nimble:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ nimble init \u0026lt;myproject\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eOr, you can also make the directory first and run:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ mkdir \u0026lt;myproject\u0026gt;\n$ nimble init\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eAfter that, \u003ccode\u003enimble init\u003c/code\u003e will interactively ask you about the metadata of your project, such as package type (library, binary, or hybrid), initial version, description, etc.\u003c/p\u003e\n\u003ch2 id=\"initialize-ormin\"\u003eInitialize Ormin\u003c/h2\u003e\n\u003cp\u003eClone Ormin\u0026rsquo;s repository from GitHub:\u003c/p\u003e","tags":["Tutorial","Nim"],"title":"Using Ormin as a Dependency"},{"content":"Since I\u0026rsquo;m currently exploring Nim and wanted to build a simple project for my own personal use and also to learn the language deeper, I decided to build a simple CLI application for storing bookmarks, and in this project I\u0026rsquo;m planning to use ORM because this project will depend on a database like SQLite so I don\u0026rsquo;t have to write raw SQL statements (I\u0026rsquo;m lazy).\nLooking for an ORM in Nim Ecosystem So two days ago, I headed to nimble.directory, a place where Nim libraries and tools are listed. I typed ORM there, and the results are showing. The first entry was Norm and I see that it has many stars, so I was giving it a shot.\nAfter I initialized my project with nimble init, I read Norm\u0026rsquo;s README on GitHub and also the library\u0026rsquo;s dedicated documentation. After reading it, I decided to try it by running nimble add norm. The interesting part is Norm has a scaffolding and migration manager called Norman so it seems like both Norm and Norman are expected to behave similarly to SQLAlchemy and Alembic pair.\nFirst Attempt on Norm and Norman I was a little bit skeptical because Norman itself hasn\u0026rsquo;t been updated since four years ago, but I didn\u0026rsquo;t really mind it, so I just went straight to coding and added that too\u0026mdash;nimble add norman. After adding Norman, I was following Norm\u0026rsquo;s tutorial on how to create tables with iNim, a community-maintained Nim REPL (sigh, I wish there were an official Nim REPL already). The guide is pretty great; I was able to follow it through on the interactive shell.\nAfter that, I opened my favorite text editor, Neovim, implementing what I already did on the REPL session to a real .nim file. It worked great too; there were not any errors.\nThen, I wanted to try the migration tool, Norman; I read the documentation first on its README since it doesn\u0026rsquo;t have dedicated documentation like Norm does; there\u0026rsquo;s a URL on the project description, but when I clicked it, my browser couldn\u0026rsquo;t find that site. So, I was heavily dependent on the README only. It\u0026rsquo;s still great because it has a usage section that is meant for developers to follow along. But I experienced something weird here on Norman.\nAfter Norman generated the directories and the files for it to be able to get to work, the usage tells us to create the model by running norman model -n \u0026lt;model name\u0026gt;. The documentation shows that it\u0026rsquo;ll create the model and the model\u0026rsquo;s migration file, but on my side it didn\u0026rsquo;t. Since the next steps are dependent on the migration file\u0026mdash;applying the migration and editing the migration file\u0026mdash;I gave up easily on this.\nI already assumed that maybe the README is just not updated, and I still can see the actual source code for me to read, but since I\u0026rsquo;m really new to Nim syntax and the file structure is modular, I think I\u0026rsquo;m giving up on this one because I don\u0026rsquo;t want to have a headache on learning a language that is really new to me.\nSo, I decided to seek another solution. I tried to search for another ORM on the Nimble directory, and I found out that the Nim language creator, Araq, has actually already developed an ORM called Ormin so I\u0026rsquo;m checking that one.\nSecond Attempt on Ormin I also was a little bit skeptical about this one because the release tag is only one, and it\u0026rsquo;s version 0.1.0 from 2017. But I see that there\u0026rsquo;s a new commit there, so it gives me hope.\nAfter a walk-through reading the documentation, I\u0026rsquo;m a little bit excited because Ormin uses DSL to create queries. This gives me Ruby vibes.\nI replaced norm and norman from my project dependency with ormin. This one doesn\u0026rsquo;t use nimble add ormin but I have to clone the whole ormin repository to my project root directory. I also feel that the documentation for Ormin is not really well-covered because the installation guide is not there; it\u0026rsquo;s directly about how to use Ormin in your code and use the ormin_importer to parse SQL schema files into Nim type information.\nLearning by Reading Tests instead of Docs I was having a headache too with Ormin since the documentation is not really clear for me, BUT Ormin has test specs so I can see the code there about how to use the functions it provides. Norm has test specs too, but its migration tool, Norman, doesn\u0026rsquo;t.\nI was forcing myself on this one. Because I believe that if a tool is created by the core developers, it will be maintained and won\u0026rsquo;t stall, I always have a bias in favor of official tools over community-maintained ones.\nTherefore, I was able to successfully implement Ormin by reading and comprehending the test syntax and function logics. I\u0026rsquo;m happy, lol.\nReflections My overall experience in Nim is sadly not satisfying because most libraries are not well documented, in my opinion. This forces me to read the actual source code rather than the one that already rendered beautifully on markdowns (I know I\u0026rsquo;m acting spoiled).\nWhat I\u0026rsquo;ll Do Next Since I already know how to work with Ormin, I\u0026rsquo;ll post the tutorial on my next post on this blog to make it easy for other beginners that are interested in Nim and looking for an ORM for their projects.\nI\u0026rsquo;m still feeling challenged to do database stuff with Norm, so I\u0026rsquo;ll get my hands on it once my hobby project in Nim is done. Also, probably I\u0026rsquo;ll contribute to the documentation for both Ormin and Norm once I\u0026rsquo;m decent in Nim. Norm and Norman are promising, actually, so I likely will prioritize it.\n","permalink":"https://rayfadh.codeberg.page/posts/working-with-orm-in-nim/","summary":"\u003cp\u003eSince I\u0026rsquo;m currently exploring Nim and wanted to build a simple project for my own personal use and also to learn the language deeper, I decided to build a simple CLI application for storing bookmarks, and in this project I\u0026rsquo;m planning to use ORM because this project will depend on a database like SQLite so I don\u0026rsquo;t have to write raw SQL statements (I\u0026rsquo;m lazy).\u003c/p\u003e\n\u003ch2 id=\"looking-for-an-orm-in-nim-ecosystem\"\u003eLooking for an ORM in Nim Ecosystem\u003c/h2\u003e\n\u003cp\u003eSo two days ago, I headed to \u003ca href=\"https://nimble.directory\"\u003enimble.directory\u003c/a\u003e, a place where Nim libraries and tools are listed. I typed ORM there, and the results are showing. The first entry was \u003ca href=\"https://github.com/moigagoo/norm\"\u003eNorm\u003c/a\u003e and I see that it has many stars, so I was giving it a shot.\u003c/p\u003e","tags":["Programming","Nim"],"title":"Working with ORM in Nim"},{"content":"Lately, I\u0026rsquo;ve been losing enjoyment in programming at all; this can be caused by the current global events like AI coding agents, etc. It makes me a little bit lazy to write code. I am always trying to find some niche languages to learn because when you use unpopular languages, AI can\u0026rsquo;t really help you\u0026mdash;maybe only for scaffolding and prototyping, but when it comes to using the language\u0026rsquo;s external libraries, the help from AI is gone because there are not so many datasets to train LLMs. I\u0026rsquo;ve been trying to learn Rust again; it turns out I can\u0026rsquo;t handle its verbosity and complexity (skill issue), so I\u0026rsquo;m looking for another language.\nRecently, I was checking out Nim because I watched a video on YouTube that Nim is popular among hackers\u0026mdash;they use it for creating payloads. Since I\u0026rsquo;m also interested in low-level exploitation and reverse engineering, I\u0026rsquo;m giving it a shot.\nAt first impression, Nim really looks like Python because it heavily depends on indentations for control blocks. I don\u0026rsquo;t really like using Python because it depends on indentations. Even though the ecosystem is huge, Python libraries are hard to use for me because different libraries it means different ways to use. Some libraries are using functional paradigm; some use OOPs\u0026mdash;thus it\u0026rsquo;s so inconsistent. I hate the way I have to look at each library\u0026rsquo;s documentation and learn how to use it, and I have to re-read the docs over and over because of those different paradigm approaches. Ruby, on the other hand, is consistent; everything is an object, thus I only have to read the classes and the methods; I don\u0026rsquo;t have to remember how to use each method, unlike Python.\nEven though Nim is similar to Python, it\u0026rsquo;s really consistent in terms of flexibility. The first time I used it and read some of its documentation, especially on the method call syntax, I was doing research about it, and I found out about UFCS then I instantly fell in love with this language!\nI was just playing around with it, writing silly code. I still can\u0026rsquo;t believe my eyes this is a valid code:\nimport options import times type URL = object url: string name: Option[string] tags: Option[seq[string]] notes: Option[string] proc addUrl(data: URL): void = data.url.echo if data.tags.isSome(): echo data.tags.get() else: echo \u0026#34;no tags\u0026#34; when isMainModule: addUrl(URL(url: \u0026#34;url\u0026#34;)) var tags = some(@[\u0026#34;foo\u0026#34;, \u0026#34;bar\u0026#34;]) addurl URL(url: \u0026#34;test\u0026#34;, tags: tags) if issome tags: echo tags.get()[0] This language basically doesn\u0026rsquo;t have a strict rule on how to write code. Other people can write libraries in functional paradigm, and I can use them in OOP paradigm; there would be no problems! Since I found Nim, I\u0026rsquo;m having enjoyment in programming again. But there are still some things that I wish improved in Nim.\nI really enjoy using Ruby\u0026rsquo;s REPL. In my opinion, it\u0026rsquo;s the best REPL other than any languages. Nim still doesn\u0026rsquo;t have a mature REPL. Its capabilities due to UFCS are kind of wasted if it doesn\u0026rsquo;t have a nice REPL like Ruby does.\nThe other thing is the LSP. I don\u0026rsquo;t know whether it\u0026rsquo;s my own fault, but nimlangserver is kind of suck on my Neovim setup. Every time I open .nim files, my Neovim always shows notifications like LSP[nim_langserver][Info] Nimsuggest initialized for \u0026lt;myfile\u0026gt;.nim and sometimes the LSP is stuck after I copy-paste something to the file.\nThis puts Nim as my most loved language after Ruby. Even without improvised toolings, I STILL FUCKING LOVE NIM!\n","permalink":"https://rayfadh.codeberg.page/posts/nim-is-amazing/","summary":"\u003cp\u003eLately, I\u0026rsquo;ve been losing enjoyment in programming at all; this can be caused by the current global events like AI coding agents, etc. It makes me a little bit lazy to write code. I am always trying to find some niche languages to learn because when you use unpopular languages, AI can\u0026rsquo;t really help you\u0026mdash;maybe only for scaffolding and prototyping, but when it comes to using the language\u0026rsquo;s external libraries, the help from AI is gone because there are not so many datasets to train LLMs. I\u0026rsquo;ve been trying to learn Rust again; it turns out I can\u0026rsquo;t handle its verbosity and complexity (skill issue), so I\u0026rsquo;m looking for another language.\u003c/p\u003e","tags":["Programming","Nim"],"title":"Nim is Amazing"},{"content":"I was wondering how to make an infinite scroll feature that already present on Inertia.js v2.0 and Laravel support already work out of the box. But how is the support on AdonisJS? The official AdonisJS\u0026rsquo;s Inertia adapter hasn\u0026rsquo;t supported this feature yet but according to Virk (Core member of AdonisJS team) the scroll() method will be out in the next version of the adapter. So how to implement it in the current version of AdonisJS? Let\u0026rsquo;s get started.\nInitialize Project Initialize the repo\n$ npm init adonisjs@latest infinite-scroll-inertia -- --kit=inertia --db=sqlite I just want to start easy on this example, you can modify the database and the authentication mechanism.\nChoose the authentication guard. I chose skip in this step.\nChoose the frontend library. I chose Vue 3.\nSSR? I chose false. Set it to true if you want by pressing y.\nWait the setup.\nBackend Part Let\u0026rsquo;s start by creating the User model.\n$ node ace make:model user -mfc # migration, factory and controller So now we have the User model and its factory. Let\u0026rsquo;s attach some props to User.\n// models/user.ts import { DateTime } from \u0026#39;luxon\u0026#39; import { BaseModel, column } from \u0026#39;@adonisjs/lucid/orm\u0026#39; export default class User extends BaseModel { @column({ isPrimary: true }) declare id: number @column() declare name: string @column() declare email: string @column.dateTime({ autoCreate: true }) declare createdAt: DateTime @column.dateTime({ autoCreate: true, autoUpdate: true }) declare updatedAt: DateTime } Modify the migration file:\n// \u0026lt;timestamp\u0026gt;_create_users_table.ts import { BaseSchema } from \u0026#39;@adonisjs/lucid/schema\u0026#39; export default class extends BaseSchema { protected tableName = \u0026#39;users\u0026#39; async up() { this.schema.createTable(this.tableName, (table) =\u0026gt; { table.increments(\u0026#39;id\u0026#39;) table.string(\u0026#39;name\u0026#39;) table.string(\u0026#39;email\u0026#39;) table.timestamp(\u0026#39;created_at\u0026#39;) table.timestamp(\u0026#39;updated_at\u0026#39;) }) } async down() { this.schema.dropTable(this.tableName) } } Modify the factory:\n// factories/user_factory.ts import factory from \u0026#39;@adonisjs/lucid/factories\u0026#39; import User from \u0026#39;#models/user\u0026#39; export const UserFactory = factory .define(User, async ({ faker }) =\u0026gt; { return { name: faker.person.firstName(), email: faker.internet.email() } }) .build() Create the seeder:\n$ node ace make:seeder main Use the factory on seeder:\n// seeders/main_seeder.ts import { BaseSeeder } from \u0026#39;@adonisjs/lucid/seeders\u0026#39; import { UserFactory } from \u0026#39;#database/factories/user_factory\u0026#39; export default class extends BaseSeeder { async run() { await UserFactory.createMany(50); } } Edit the UserController:\n// controllers/user_controller.ts import type { HttpContext } from \u0026#39;@adonisjs/core/http\u0026#39; import User from \u0026#34;#models/user\u0026#34;; export default class UsersController { async index({ inertia, request }: HttpContext) { const page = request.input(\u0026#39;page\u0026#39;, 1) const perPage = request.input(\u0026#39;perPage\u0026#39;, 10) console.log(\u0026#39;page\u0026#39;, page) const users = await User.query().paginate(page, perPage); return inertia.render(\u0026#39;users/index\u0026#39;, { users: inertia.merge(() =\u0026gt; users.toJSON().data), usersMeta: users.getMeta() }) } } Add the route on routes.ts:\n// start/routes.ts /* |-------------------------------------------------------------------------- | Routes file |-------------------------------------------------------------------------- | | The routes file is used for defining the HTTP routes. | */ import router from \u0026#39;@adonisjs/core/services/router\u0026#39; const UsersController = () =\u0026gt; import(\u0026#39;#controllers/users_controller\u0026#39;) router.on(\u0026#39;/\u0026#39;).renderInertia(\u0026#39;home\u0026#39;) router.get(\u0026#39;users\u0026#39;, [UsersController, \u0026#39;index\u0026#39;]) Do the migration:\n$ node ace migration:fresh --seed Now let\u0026rsquo;s head to the frontend.\nFrontend Part Let\u0026rsquo;s add the loading icon:\n$ npm i lucide-vue-next And add a simple helper called SimplePaginatorDtoMetaContract from @adocasts.com/dto/types:\n$ npm i @adocasts.com/dto Create users/index.vue on inertia/pages/ dir.\n// pages/users/index.vue \u0026lt;script setup lang=\u0026#34;ts\u0026#34;\u0026gt; import { WhenVisible } from \u0026#39;@inertiajs/vue3\u0026#39; import { ref, computed, watchEffect } from \u0026#39;vue\u0026#39; import { SimplePaginatorDtoMetaContract } from \u0026#39;@adocasts.com/dto/types\u0026#39; import { Loader2 } from \u0026#39;lucide-vue-next\u0026#39; import type User from \u0026#39;#models/user\u0026#39; const props = defineProps\u0026lt;{ users: User[] usersMeta: SimplePaginatorDtoMetaContract }\u0026gt;() const users = ref(props.users) const hasMorePages = computed(() =\u0026gt; { const { currentPage, lastPage } = props.usersMeta return currentPage \u0026lt; lastPage }) watchEffect(() =\u0026gt; (users.value = props.users)) const whenVisibleParams = computed(() =\u0026gt; ({ only: [\u0026#39;users\u0026#39;, \u0026#39;usersMeta\u0026#39;], preserveUrl: true, data: { page: props.usersMeta.currentPage + 1, }, })) \u0026lt;/script\u0026gt; \u0026lt;template\u0026gt; \u0026lt;div class=\u0026#34;w-full max-w-screen-md mx-auto border rounded-xl p-4\u0026#34;\u0026gt; \u0026lt;h1 class=\u0026#34;text-2xl font-bold mb-4\u0026#34;\u0026gt;Users\u0026lt;/h1\u0026gt; \u0026lt;table class=\u0026#34;w-full border-collapse\u0026#34;\u0026gt; \u0026lt;thead\u0026gt; \u0026lt;tr class=\u0026#34;border-b\u0026#34;\u0026gt; \u0026lt;th class=\u0026#34;text-left p-2\u0026#34;\u0026gt;ID\u0026lt;/th\u0026gt; \u0026lt;th class=\u0026#34;text-left p-2\u0026#34;\u0026gt;Name\u0026lt;/th\u0026gt; \u0026lt;th class=\u0026#34;text-left p-2\u0026#34;\u0026gt;Email\u0026lt;/th\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/thead\u0026gt; \u0026lt;tbody v-if=\u0026#34;users?.length\u0026#34;\u0026gt; \u0026lt;tr v-for=\u0026#34;user in users\u0026#34; :key=\u0026#34;user.id\u0026#34; class=\u0026#34;border-b hover:bg-gray-50\u0026#34;\u0026gt; \u0026lt;td class=\u0026#34;p-2\u0026#34;\u0026gt;{{ user.id }}\u0026lt;/td\u0026gt; \u0026lt;td class=\u0026#34;p-2\u0026#34;\u0026gt;{{ user.name }}\u0026lt;/td\u0026gt; \u0026lt;td class=\u0026#34;p-2\u0026#34;\u0026gt;{{ user.email }}\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;WhenVisible :params=\u0026#34;whenVisibleParams\u0026#34; :always=\u0026#34;hasMorePages\u0026#34;\u0026gt; \u0026lt;template #fallback\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;td colspan=\u0026#34;3\u0026#34; class=\u0026#34;text-center p-4 flex justify-center items-center gap-2\u0026#34;\u0026gt; \u0026lt;Loader2 class=\u0026#34;w-4 h-4 animate-spin text-muted-foreground\u0026#34; /\u0026gt; \u0026lt;span\u0026gt;Loading more...\u0026lt;/span\u0026gt; \u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;/WhenVisible\u0026gt; \u0026lt;/tbody\u0026gt; \u0026lt;tbody v-else\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;td colspan=\u0026#34;3\u0026#34; class=\u0026#34;text-center p-4\u0026#34;\u0026gt;No users found.\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/tbody\u0026gt; \u0026lt;/table\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; Since I\u0026rsquo;m not an expert with Vue, this implementation needs a slight improvement. The infinite scroll depends on the zoom level on the browser. Feel free to contact me to fix it or just rewrite this blog.\nSo that\u0026rsquo;s how we implement the InertiaJS infinite scroll with AdonisJS. Hope this tut helped you.\n","permalink":"https://rayfadh.codeberg.page/posts/adonisjs-infinite-scroll/","summary":"\u003cp\u003eI was wondering how to make an infinite scroll feature that already present on Inertia.js v2.0 and Laravel support already work out of the box. But how is the support on AdonisJS? The official \u003ca href=\"https://github.com/adonisjs/inertia\"\u003eAdonisJS\u0026rsquo;s Inertia adapter\u003c/a\u003e hasn\u0026rsquo;t supported this feature yet but according to Virk (Core member of AdonisJS team) the \u003ccode\u003escroll()\u003c/code\u003e method will be out in the next version of the adapter. So how to implement it in the current version of AdonisJS? Let\u0026rsquo;s get started.\u003c/p\u003e","tags":["Tutorial","Programming","TypeScript","AdonisJS","Vue"],"title":"AdonisJS Infinite Scroll"},{"content":"This is my first post on my personal blog! I was put in a dilemma about whether I should stay on infosec.press or rant.li (both are WriteFreely instances). I think it\u0026rsquo;s better to make my own using Hugo and host it on Codeberg Pages or GitHub Pages.\nSince I love Codeberg, I decided to use Codeberg Pages to host this blog. I thought it would be hard to host my own personal blog, turns out it\u0026rsquo;s so easy.\nOn this blog, I\u0026rsquo;ll post about my thoughts and my dev logs.\n","permalink":"https://rayfadh.codeberg.page/posts/i-made-a-new-blog/","summary":"\u003cp\u003eThis is my first post on my personal blog! I was put in a dilemma about whether I should stay on \u003ca href=\"https://infosec.press\"\u003einfosec.press\u003c/a\u003e or \u003ca href=\"https://rant.li\"\u003erant.li\u003c/a\u003e (both are \u003ca href=\"https://writefreely.org/\"\u003eWriteFreely\u003c/a\u003e instances). I think it\u0026rsquo;s better to make my own using Hugo and host it on Codeberg Pages or GitHub Pages.\u003c/p\u003e\n\u003cp\u003eSince I love Codeberg, I decided to use Codeberg Pages to host this blog. I thought it would be hard to host my own personal blog, turns out it\u0026rsquo;s so easy.\u003c/p\u003e","tags":null,"title":"I Made a New Blog"}]