- Fennel 88.4%
- CSS 8.5%
- JavaScript 3.1%
|
|
||
|---|---|---|
| assets | just saving | |
| libs | Upgrade RetroV | |
| lua-color @ac886a1192 | Initial commit | |
| .gitignore | Move icons to a different file since it's kinda messy | |
| .gitmodules | Initial commit | |
| banner.png | Add a banner | |
| build-helpers.fnl | Ignore hidden files created by Emacs | |
| build.fnl | Separate files | |
| html.fnl | Add donation button | |
| i18n.fnl | Detect preferred language | |
| icon.png | Use an icon that's more representative of the app | |
| icons.fnl | Add donation button | |
| index.fnl | Separate files | |
| index.js | We can now delete saved colors | |
| itch.png | Add itch.io badge | |
| LICENSE | Add license | |
| main.fnl | Detect preferred language | |
| manifest.toml | icon and manifest | |
| README.md | No AI | |
| style.css | Add donation button | |
| webxdc.js | Initial implementation of saving | |
🪻 So Many Colors!
So Many Colors! is an app that picks a random base color and derives color schemes from it. It helps you find color combinations that you can use for your designs and artwork. It's a Webxdc app that's meant to run on Delta Chat, monocles chat, and Cheogram.
You can get it on itch.io, webxdc.org, or in the release page!
License
This is anti-capitalist software, released for free use by individuals and organizations that do not operate by capitalist principles.
Contains bits and pieces of the following projects:
Please support them if you can!
- Fennel: Programming language that runs on the Lua runtime (MIT License) (version 1.5.3)
- Fengari: Lua VM written in JS (MIT License) (version v0.1.4)
- Shelf: Remarkably small, remarkably useful CRDT (MIT License) (commit efacd67)
- Pico CSS: A minimalist and lightweight starter kit (MIT License) (version v2.1.1)
- Solar icon set (CC BY 4.0 License)
- RetroV: Virtual DOM rendering library (MIT License) (commit 3fed42e)
- lua-color: Library for manipulating colors (MIT License) (version v1.2-4)
- Wikipedia (CC BY-SA 4.0 License)
Introduction for devs
This app is written in Fennel which is compiled into Lua which then runs on Fengari which is a Lua VM written in JavaScript. Now why are we standing on the computer language equivalent of the Tower of Babel? Because it's fun to write in Fennel and I wanted it to run on the browser!
How to build
Prerequisites
Ok this is kind of an annoying part, but bear with me. We need to get you some of the tools that we need to build this project.
- Lua is used to run the Fennel compiler. Since Fengari is compatible with Lua 5.3, we should install 5.3 on our system.
- Fennel is used to compile our code into Lua.
- LuaFileSystem is used to check for any file changes.
- luaposix is used to pause the program while waiting for changes.
- Zip compresses our app and creates the
.xdcfile.
Installing these tools vary between different operating systems (there's so many of them!), but I've tried it on the following systems. Here's how you can install Lua and its dependencies:
Debian-based (Linux Mint, Ubuntu, etc.)
Debian
Install Lua, the Lua libraries, and zip.
$ sudo apt install lua5.3 lua-filesystem zip lua-posix
After that, install the Fennel executable.
OpenBSD
OpenBSD
Thankfully, everything we need are a part of the package manager!
$ doas pkg_add fennel-lua53 lua53fs lua53posix zip
Building
So after installing those tools, what we need to do to build is to cd into the directory and run:
$ fennel build.fnl
This compiles our Fennel program into Lua and bundles everything else into an index.html file. There's nothing else to do after that, really! You'll find that there's a dist/moments.xdc file that's also ready to go. Drag and drop that file into Delta Chat, and you're done! You can also view the app by opening index.html in your browser.
Technical deets
This is a deep dive into the inner workings of the app. This is mostly for me because I'm likely to forget how this app works in the future, but if something is not clear let me know!
Useful hacking tools
Before I was using Sublime Text with sublime-text-fennel, but I find that it's much nicer to use Emacs with fennel-mode and rainbow-delimiters when working with Fennel. It takes some getting used to, but it feels worth it.
It's also good to have the fennel executable in your path so that you can use M-x fennel-repl within Emacs as well.
Build process
Let's start with the fennel build.fnl file. This runs on the Lua runtime on your machine and it generates a single index.html file that includes:
- Fennel files compiled to Lua in a
<script>tag. - JS added into a
<script>tags. - CSS added into
<style>tags.
The HTML is represented as a Lua table in index.fnl which build.fnl reads and writes an HTML string into index.html. Inside the Lua table you'll find a function call to build.load-assets that's defined in build-helpers.fnl. This takes a sequential table (array in other languages) which has the files that we want to include, the filetype, and whether we want to inline it or not.
(fn load-assets[assets](table.unpack(icollect [_[assetfiletypeinline](ipairs assets)](if inline(casefiletype:js[:script{}(read-fileasset)]:css[:style{}(read-fileasset)]:lua[:script{:type"application/lua"}(read-fileasset)])(casefiletype:js[:script{:srcasset:type"text/javascript"}]:css[:link{:rel"stylesheet":hrefasset:type"text/css"}]:lua[:script{:srcasset:type"application/lua":asynctrue}])))))I prefer to inline everything to have a nice single index.html output, but there's no technical reason for that I just like it that way. You'll notice though that webxdc.js is not inlined, however. This is because Delta Chat (and other Webxdc compatible clients) provide this file themselves so we don't actually want to bundle the webxdc.js file that's inside our repository.
It also reads and compiles our Fennel files into Lua which is written inside index.html and also main.lua. The files that we want to build are in the files table. Finally, it creates a zip file called dist/colors.xdc which we can then share with other people.
;; Create our webxdc app(let [commands["mkdir -p dist""rm -rf dist/colors.xdc""zip -9 --recurse-paths dist/colors.xdc index.html icon.jpg manifest.toml"]](each [_cmd(ipairs commands)](print "Command"cmd)(os.execute cmd)))Additionally, build.fnl also watches for file changes and re-runs the whole build process automatically! To quit, simply press Ctrl+C.
How the app works
index.js
The story of our program begins at index.js. This initializes our local "database" which is stored in window.crdt and basically manages sending our data through webxdc.sendUpdate and receiving our data through webxdc.setUpdateListener and keeps the database (which is a CRDT) synced as it sends and receives.
main.fnl
Most of the logic of the app resides in the Fennel files and it all happens in main.fnl. This file is responsible for displaying the UI, generating random colors, converting colors to different formats, and saving them.
html.fnl
This file converts a Lua table that represents our HTML and converts it into virtual DOM that's handled by RetroV. Calling render checks for any changes in our data is then the difference is displayed by this library.
icons.fnl
All our SVG icons reside in this file.
i18n.fnl
Translation strings are stored in this file. The current locale is stored in localStorage, and it uses the locale key to use the right strings. If a key-value is missing, it falls back to en locale.
No AI
No AI was involved in making this. Fuck that.