You are reading content from Scuttlebutt
@andrestaltz %f5LvRb79CgCvz7+5f3h4tuZBalXilWxzZkuyt1+/s0U=.sha256

Manyverse Desktop Dev Diary

I think it'll be good to share little by little how Manyverse Desktop is shaping up, since it'll be a long journey.

@Powersource (phone) and I agreed to share the responsibility of building it, for a couple of reasons: (1) the workload is large and both me and him have limited time budget, so it makes sense to merge our time budgets, (2) Jacob can work on this earliest in July and we need to speed up mv-desktop development in May and June somehow, (3) some obstacles are Cycle.js-specific and since I created that framework, I should tackles those obstacles, (4) people need hope for an actively-maintained desktop app.

mv-desktop challenges eerily remind me of my first dev diary in 2017, where I was trying to cram scuttlebot into React Native, except this time the challenge is in the opposite direction, where I try to cram React Native stuff into conventional web and Electron development. In 2017, the challenge was mostly with the backend, i.e. running the ssb-server (database and networking parts) on mobile. This time, the challenge is mostly with the frontend, adapting React Native and Cycle.js to an Electron environment. The basic hurdles are solved by using react-native-web, but the devil is in the details, and there are lots of details (see mv-desktop roadmap).

That said, I'll leave most of the nitty-gritty details to GitLab issue discussions. In this thread I'll share the fun stuff: the achievements, the frankenstein gradually coming alive, some diagrams, etc.


Here's the big-plan diagram:

mvdesktopdiagram.jpg

The right side of that tech stack is what we're trying to build. I started by handling the lowest layer, with electron-ssb-client, and then Jacob handled all of the other low-level right-side stack (react-native-web etc), and now the biggest missing piece is "Cycle Native Navigation Web", which will handle "page navigation". There are specific challenges related to that which I'll try to share in another update.

So far what we got working is: the backend is fully functional and correctly communicates with the frontend, and all the Electron/webpack/react-native-web machinery is working. Jacob once demoed the Thread screen working.

This time, I got the Welcome screen fully functional. Sounds easy, but there were lots of CSS and React to struggle with until everything looked pretty. Below is a demo:

mv-desktop-welcome.gif

The next big task will be switching to other pages. I.e. Cycle Native Navigation Web will need to be built.

@SoapDog (Macbook Air M1) %n1BHmWUinT/8i+zaB5ZuA/4cQx40lDygvYllW4U6RdI=.sha256

fantastic work!

@andrestaltz %0OU7HWe4Muj4kgBN6yNXB1h4QJRGenh+QHdOdjonVwU=.sha256
Content warning: Animated GIF of something super exciting

The next big task will be switching to other pages. I.e. Cycle Native Navigation Web will need to be built.

Actually, before tackling that, I thought what other screens could I try. And then I obviously had to try the Central screen. Turns out, most of it is already very functional! Just gotta polish the UI, but it's mostly good:

mvdesktop-central.gif

I am excited

@andrestaltz %re28iQSBxX1bj9SE73sTGFXaUvD5QSM/pZGYiEEPxmk=.sha256

Before working on page navigation in Electron, I wanted to have a clear picture of the current state of screen navigation in Manyverse. So I dabbled with a script to inspect the source code for all screen transitions, made a graphml file, loaded it into yEd and tweaked it a bit to produce this:

navigation.png

(open in browser and zoom in to read it properly)

@Hendrik Peter %YplfDjdA+cWueEqYzeYATDOiFGagdbrTBHSEK5QNbP4=.sha256

Hey @andrestaltz, One of my colleagues is going completely insane over some new kind of front-end framework called "Tauri" which runs on Rust. it seems that Tauri is much less resource hungry than Electron is and the base application size sits at around 500kb if you build a fairly clean hello world instance (in stark contrast with Electron which will eat about half a hundred of megs).

Website with info:
https://tauri.studio/en/

We actually talk about this in one of our podcasts
https://patraden.knightec.se/podcast/2021/04/25/apropa-git.html (that's in Swedish though)

@andrestaltz %se8yIrUJ6C9ObVIedC2p0RGbkO3QT1wNWIpg5E23cXk=.sha256
Content warning: Animated GIF

This probably won't make sense to people unfamiliar with cycle.js and/or react-native-navigation, but I'm very excited about it.

I started working on cycle-native-navigation-web which I thought would be a huge undertaking as a driver or "runner" compatible with cycle-native-navigation, but I realized that "navigation is just app logic", and that meant I could do it as Cycle components, not as drivers or runners. Which simplifies my work a bit.

Then, it also helped me to realize that I don't need to support the "web" (actual browser) use case, I can focus only on Electron. Which means that I don't need to handle page navigation as literally different HTML files in Electron, it can be a pure single-page application. Another supporting realization is that there are no "anchor links" in Manyverse, except Markdown links but clicks on those are always intercepted, so there are no "natural web links" in Manyverse. This will help a lot.

So I started dabbling with navigation logic last night. I did this in a playground repo, not on the manyverse repo, because it would be easier to test out.

Some requirements I had in mind:

  • There has to be a "frame" surrounding the current page. The frame will contain search bar, back button, left side menu etc
  • Navigating back has to preserve the scroll position on the previous page
  • Page A has to be able to send props to page B
  • Support the same "navigation commands" currently used in manyverse according to react-native-navigation

Here's a fun GIF showing the basics working already!

  • Pink is the "frame"
  • Blue is one page
  • Yellow is another page

nav.gif

@andrestaltz %4kb7zeTGG4Ka5tIQYfoyesa2UfGYqqWkrT3NswNrWI8=.sha256
Content warning: Animated GIF

After updating Cycle.js's state management library I was able to build and publish cycle-native-navigation-web (alpha version). So far it only supports a tiny subset of react-native-navigation, just enough to let me get started with mv desktop. But updating it will be simple from now onwards, it's just a matter of supporting different screen transitions, methods, etc. The core logic is built.

So I put cycle-native-navigation-web in Manyverse, and after a few hurdles, it works! Here's an example of a screen transition, from the Welcome screen to the Central screen.

multiscreen.gif

@andrestaltz %DPbBStBq575kuKJl/IiGvYOlwp1gQmbOL2jOhafK4fQ=.sha256
Content warning: Animated GIF :)

desktop202106.gif

User has not chosen to be hosted publicly
@andrestaltz %wJaZLb1rBO7zzrk/x55KfharxEJuhjZmmf1Vi5HjaGg=.sha256

Jacob and I got back to collaborating on mv desktop and it's been steady progress. This time we focused on getting the Compose screen working, and it works surprisingly well, not a lot of bugs in the basic use case of writing, previewing, and publishing.

One of the bigger challenges was setting up a system for dialogs and popups. Basically iOS and Android come with their own dialogs (and design guidelines for that), but when it comes to Electron (and the web), there isn't. I mean, there is window.alert and window.confirm but those are hideous. Most websites with pretty-looking dialogs have to role out their own solution.

The tricky thing with dialogs is that the cover the whole screen, and in the Cycle.js architecture in Manyverse, we took an ad-hoc solution where we're just providing dialogs as a driver, basically "shimming" the operating system's lack of dialogs (and/or their use in Electron). This is the smallest departure we can do from the existing app architecture. The other option was a complete overhaul of how dialogs work in the app, and that seemed like too much refactoring.

So I set up a funky "shim" of dialogs in Electron as a React app that runs in parallel to the Cycle-React app controlling all the screens in Manyverse. And @Powersource (phone) did the job of finding and integrating a sweet Material design component library that matches almost perfectly the dialogs in Android, and we got to this point (the dialog that appears when you press "..." on a message):

photo_2021-07-21_23-35-14.jpg

@SoapDog (Macbook Air M1) %yaDGOa4ZYp52GiYBbURMjweCuru7C4iODqOfuDR2gbk=.sha256

great work @andrestaltz and @Powersource (phone) :D

It is impressive how much we need to reinvent when using Electron. This is not me dissing it, I like it to some extent. It is just that in case of operating systems such as macOS, there is so much available for native developers that can't be easily tapped by Electron-based apps. :-(

makes me appreciate even more all the work you folks been putting into Manyverse Desktop. :D

@andrestaltz %C6FxtXeNzb4s4KsDSmsQP/t5OWhrf8lVsylh6x4334c=.sha256

@SoapDog (Macbook Air) Yeah I noticed that Manyverse M1 uses macOS's own pretty-looking dialogs. It would be awesome if Electron gave us a way of using those. I really wish I knew how to do that.

@SoapDog (Macbook Air M1) %BqfeKysri9A2s5UloHG3gGJqJNpcoa9Ox9Prvqz+uoo=.sha256

@andrestaltz does the Electron native dialog API helps? Don't know if you have tried that before.

User has not chosen to be hosted publicly
@andrestaltz %GyMxuY2fPSrx/6RE4Qoxx5s+M4+yf1MfDttmkdiZSnM=.sha256

Jacob finished porting all the dialogs in the app, and here's a sweet example. The following dialog component comes from Material-UI. And when you press "Yes", it actually logs you in and opens the room's site in the browser.

Screenshot from 2021-08-03 15-08-36.png

@andrestaltz %4+0cHJKHcf3KnZT2FC3VOP3OMtFdTQwPlnGq+z7pwUw=.sha256
Content warning: Fun fun animated GIF

Did some progress today on developing something called "the Frame", which is surrounding UI components that fulfill the purpose that the left-side menu has on mobile. It's looking pretty. There's still a bunch of things to fix, such as (seen in this screenshot): incorrect position of the green circular button, scroll bar bottom-right corner in the Thread screen.

Peek 2021-08-05 17-46.gif

@andrestaltz %/W9/VtKP9E5ow0jn7doaaFpd1cE44llpKi8czCLljHs=.sha256
Content warning: Animated GIF

It's looking pretty!

Peek 2021-08-06 17-52.gif

User has not chosen to be hosted publicly
@andrestaltz %zPVYzdZpVs2on2TsL0dSfmPh8jTXcnhCORrw+C8U67Y=.sha256

Today was productive, I did a bunch of small improvements:

  • Updated Electron to 15.x
  • Enabled the Backup (24 words) screen
  • Enabled some settings screens: About, Libraries, Thanks
  • Custom (for MV Desktop) progress bar for indexing status
  • Enabled the Edit Profile screen (although changing profile pic is missing)
  • Enabled Manage Aliases screen
User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
@andrestaltz %YRnio7ecVRwZim5QapFyrMdwu1elJv3dSJ6ZEpPmytU=.sha256

@Tod Robbins (he/him) not yet, but soon! Special testing help will be needed from Windows and macOS users since my main computer is Linux and I won't be testing super often on Windows and mac.

@moid Smells to me like you're using some very bleeding edge version of Node.js. Can you check that node -v says 12 or 14?

User has not chosen to be hosted publicly
@andrestaltz %NPYKn/3FYNw4AwBcNZMrjOOoZG75zzIR5iqO2AFzfx4=.sha256

v10 should work but try v12 just in case. It could be that the latest Electron is not compatible with an old Node.js version

User has not chosen to be hosted publicly
@andrestaltz %t4WJxAe7yMmZjW2mSSRXhXlhRJAwMXScEpo5Uc75eq8=.sha256
  • Supports attaching pictures to posts and changing profile pic
  • Supports toasts to notify you e.g. when an invite code works
@andrestaltz %xJsagJunyRbfxvYrR/Nr5OSIil71S+G5SFqt4W6ZgWM=.sha256

User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
@andrestaltz %IZpaFjRDl66NAwgBDBx3dcQdDxHDt9mASAUAYWZYHqk=.sha256

@moid Good questions and good that you're already alpha testing this to give some feedback. I could still change it back if that ends up making sense.

Overall what we're aiming for is to have a dedicated feed and database for each app, and then in the future with Fusion Identities (@arj and @Mix are keen to work on that) bind all these feeds together. The reason why we're forced to do this now is that Manyverse has ssb-db2 while all other apps have flume, and these write to different logs.

There are a couple different scenarios:

  • I don't have any other SSB app using ~/.ssb and I want to start using Manyverse
    • Manyverse will create the feed in its dedicated folder
  • I have another SSB app using ~/.ssb and I want to use that feed with Manyverse
    • "Migrate button" and delete the ~/.ssb
  • I have another SSB app using ~/.ssb and I want to try out Manyverse
    • Use Manyverse in read-only mode
  • I have another SSB app using ~/.ssb and I want to keep it like that while creating a new feed for Manyverse
    • Create the ~/.config/manyverse/ssb folder and open Manyverse
    • OR
    • Rename ~/.ssb to ~/.ssb-backup, open Manyverse and create a feed, close Manyverse, rename ~/.ssb-backup to ~/.ssb
  • I want to use the same feed on Manyverse and other SSB apps
    • No
  • I really want to use the same feed on Manyverse and other SSB apps
    • Symlink ~/.config/manyverse/ssb to ~/.ssb
    • Accept the risk of forking your feed if you're not careful about both logs having all of your messages in the same order

The "read-only mode and then migrate" was an idea that emerged from a session at #svendsolar by @cblgh if I remember correctly, and it's a decent one.

Question: would it have better to just present the user with a dialog asking them to choose between the 3 options below? (Typically it's just the 2 first options)

  • Create a new feed
  • Restore from 24-words
  • Migrate from ~/.ssb permanently
User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
Join Scuttlebutt now