This project was started a long^looong time ago (originally named "Workspaces") and was my first-ever Node.js + Electron endeavour. Some code snippets you may stumble upon date back to the dark ages of my JS knowledge hence may insult, even hurt more experienced programmers. In addition, 2020 to 2022 I took on a role as a freelance DevOps engineer for a major retail bank, which meant putting everything else besides the bare necessities on hold(people who suffered through a multimillion $$$ project behind schedule in this industry may know and most probably still vividly recall the pain). That being said, if you have any questions or need assistance with the setup, please do not hesitate to contact me directly. I will be more than happy to help! For the time being, please follow the development branch.
Canvas is a cross-platform desktop overlay to help organize my work / workflows and data into separate "contexts".
Contexts are represented by a tree structure resembling a file-system hierarchy; every tree node represents a separate layer filtering down all unstructured information fighting for my attention on a standard(tm) desktop setup(emails, notifications, chat messages, growing number of random browser tabs and ad-hoc download-extract-test-forget endeavors).
A Canvas context tree is designed to be dynamic, supporting frequent changes to accommodate any structure needed to be productive:
universe://
/Home
/Music
/Podcasts
/Physics
/Medicine
/Library
/Physics
/Math
/Medicine
/Our new house
/Heating
/Electricity
/Kitchen
/Sinks
/Materials
/Shinnoki
/Egger
/..
/Project docs
/Archicad
/Sketchup
/Twinmotion
/Edu
/AIT
/Physics
/Work
/AirBnB
/Atlas Apartment
/Fountainhead Apartment
/Cu$tomer A
/Dev
/JIRA-1234
/JIRA-1237
/Reports
/Compliance
/2022
/2023
/SaaS Startup FOO
/DC Frankfurt
/network
/hv
/Billing
/acme llc
/2022
/2023
/acme inc
/2023
/08
Context URLuniverse://work/customer-a/reports
will (presumably) return all reports for Customer A,
universe://reports
will return all reports indexed("linked") by the bitmap index of the "reports" layer for your entire universe.
You want to prevent having multiple layers representing the same data. "Reports", "reports_new", "reports2", "customera-reports" should be represented by one layer - fe "reports", leaving the context(layer order) handle the filtering for you.
This setup enables having the same data accessible through different, ad-hoc "filesystem-like" context paths:universe://photos/2023/06
universe://home/inspirations/kitchens
universe://travel/Spain/2023
universe://tasks/data-cleanup/2023/09
For the above example, all contexts return (among other data) the same file IMG_1234.jpg
- a picture of a nice kitchen from an airbnb we stayed at. As a bonus - regardless of where it is stored(the storage part is abstracted away via storeD). Same goes for tabs, notes or any other documents - including the entropy-rich content of my ~/Downloads and ~/Desktop folders.
There are 5 layer types:
Workspace: Exportable, shareable collection of data sources and layers. By default, you start with an undifferentiated "universe". Workspaces in Canvas can have a primary color assigned. If they do, Canvas will automatically use gradients [of the primary workspace color] for individual data abstractions.
Canvas: A layer with multiple context, feature and/or filter bitmaps assigned that can optionally store Canvas UI layout and UI applet data. Canvases are the central piece of a lets say unorthodox approach to desktop environments, but more on that later.
Context: The default layer type that links a context url part to one and only one context bitmap.
Filter: Represents a single filter or feature bitmap*; example: universe://customer_a/:emails/:today
, where :emails represents the "data/abstraction/email" feature bitmap, :today represents the "filter/datetime/today" filter.
Label: A noop layer with no context or feature bitmap links
There are couple of motivating factors for this project:
Canvas server
Moved to a separate repo:
Manages your entire (not exclusively digital) universe. Server hosts your global context tree, stores all layers and indexes all your Apps, Roles, Utils, Dotfiles and data. It is also a proxy between your data backends and your client, exporting your contextualized OS environment configuration through various transports(REST API, socket.io, IPC, webdav).
Canvas client
Client repositories:
Client runtime [on a linux OS] ensures all configured apps(flatpak), local roles(docker/podman), utils(stored), dotfiles(git) and data(stored) are available on your host system for the context you are currently working in. You can pin a canvas client to a specific workspace(context), for example say your work notebook to universe://work
and your htpc to universe://home/living-room
, both with its own (sub-)set of apps, roles, utils, dotfiles and data visibility limited to the pinned context subtree.
Some of the technologies used in no particular order:
For portable use, download and extract nodejs and electron into the canvas/runtime folder
Default user home for portable use: canvas/user
Default user home: $HOME/.canvas
Environment variables:
I'm trying to motivate myself to do daily code updates by doing not-yet-but-soon-to-be live coding sessions(usually ~5AM - 6AM CEST). Wouldn't watch any of the existing videos yet, mostly OBS audio tests and a showcase of sleep deprivation, but you can subscribe for updates nevertheless.
YT Channel + Some (royalty-free) music used in my videos
Any suggestions welcome ("you should use <module> to do <stuff> instead of <whatever nightmare you have currently implemented>"), as a hobby-programmer this is really appreciated!
Thank you!