Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 10, 2022 10:23 am GMT

useMindMap

Overview of My Submission

useMindMap is a mind mapping application backed by Appwrite. It leverages Users/Teams, Database, Realtime, and Functions to provide a basic mind mapping service for yourself or a team.

Live: https://usemindmap.app

View of the useMindmap dashboard

View of a useMindmap flow

  • Sign up/sign in, forgot password, and team invites
  • Personal and Team workspaces for your mind maps
  • Collaborative mind mapping powered by Appwrite Realtime
  • Mind mapping functionality built on top of React Flow

Building useMindmap

The first step was to deploy Appwrite. I've used Digital Ocean for some time and I love their single-click app marketplace. This got me a cheap droplet running Appwrite in about 5min. Using an existing domain for testing purposes I set up a subdomain for the Appwrite instance, played around with the admin console and thought "Hell yeah, this is awesome!"

I created a Web project, configured environment variables, and did all the housekeeping necessary to prepare for full-scale development. After two days getting acquainted with Appwrite I was ready to build.

FRONTEND

I started the frontend with a simple React project template (webpack, babel, eslint, typescript) and blocked out the page routes I would need:

  • Home (/)
  • Auth ( /sign-in, /sign-up, etc)
  • Dashboard (/~, /~/profile, /~/teams, etc)
  • Mindmap (/~/maps)

Using inspiration from Chakra UI Pro and Tailwind UI I then created the sign-up/sign-in pages and integrated with the Appwrite SDK to create a user and a logged in session.

The Dashboard followed with the sidebar and content:

  • Logged in user details
  • Main "activity" view
  • Profile and Teams view
  • "Workspaces" list and view

View of the user's personal workspace

From some tinkering around with Appwrite's Database and SDK, I settled on making each workspace a Collection and each Mindmap a Document with attributes:

  • name: string
  • description: string
  • nodes: string[]
  • edges: string[]
  • tags: string[]

After a couple weeks fleshing out the UI and getting intimate with the Docs and SDK, I was finally tackling the MIIINDMAAAP (*spooky music*)

When a user creates a mindmap for a given workspace, a document is created in the associated collection and the user is launched into the /~/maps/:id path. Once inside the Mindmap view, the React Flow instance is used to create nodes, moved them around, save a label, attach edges, and delete them.

React Flow represents its nodes and edges as objects with attributes like id, position, width, height, source, target, there are many many more properties but these ones are the important bits so they can be saved/restored and propagated to other connected clients.

Each one of these events triggers a Function execution with a payload of the new value (a node move event sends the updated position, a label update sends a new data object, etc).

From this point, it's up to Appwrite Functions to resolve the mutation on the mindmap document. Onward, to the Backend!

BACKEND

I wanted the concept of a group of mindmaps to be something the user or team doesn't even need to manage. To support this, using Appwrite Functions, every user.create or teams.create system event creates a new collection only that user/team has access to. In effect, this produces a "scoped workspace" of sorts for the user/team to call their own and is entirely automatic.

(As a side note, I also use a Function to generate a gravatar URL for each user upon registration)

When a user opens a mindmap, the client fetches the initial state of the document while also subscribing to document changes with the Realtime endpoint. Realtime changes received by the client are then merged to the React Query cache to keep them in sync (honestly, React Query isn't even needed to push Realtime data from the callback response to React Flow, but it's just so damn easy to use for handling server state that I can't not use it)... moving on.

With clients listening to documents for changes, what's left is for Appwrite Functions to resolve updates to nodes and edges. To do this, I created two Functions to handle nodes and edges, whose responsibilities are:

  1. Accept the incoming payload from a HTTP event
  2. Pull the most up-to-date document from Database
  3. Insert/merge/remove the changed attribute into/from the original attribute
  4. Save the new document attributes back to Database
  5. Exit gracefully stage right, grab a coffee

This all seems like an oversimplification, and while it's rather straightforward, I did get inside my own head for a few days considering all sorts of funky solutions like CRDTs and custom WebSocket servers with Yjs. I'd like to thank the invaluable support offered by the Appwrite Team in the Office Hours channel on Discord.

Submission Category:

Web2 Wizards

Link to Code

Proudly open source on GitHub: https://github.com/benweier/use-mind-map

Additional Resources / Info

Tech Stack

  • Appwrite (duh)
  • React
  • Digital Ocean (1x droplet + 1x static site app)

Key Dependencies:

Future Plans

Obviously this is a pretty quick'n'dirty mind mapper, but I loved the experience of combining Appwrite with React Flow that I plan to take this further and develop it into a fully-fledged app.

The mindmap experience right now is basic and rough, and there's not a lot of expressive features to make a mindmap your own. Having options like colours and shapes for the nodes at least, as well as making editing seamless - like opening the node edit panel above the selected node, shortcut keys to add a pre-linked node, an automatic layout engine with elkjs - would all go a long way.


Original Link: https://dev.to/benweier/usemindmap-1j3f

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To