GithubHelp home page GithubHelp logo

terhechte / ebou Goto Github PK

View Code? Open in Web Editor NEW
508.0 6.0 30.0 8.05 MB

A cross platform Mastodon Client written in Rust

Home Page: https://terhech.de/ebou/

License: GNU General Public License v3.0

Swift 0.13% Shell 0.60% JavaScript 0.28% Rust 90.23% HTML 2.16% SCSS 6.59%
app desktop-app dioxus linux macos mastodon mastodon-client rust windows

ebou's Introduction

Ebou

Ebou is a cross platform Mastodon (and Pleroma, untested) client written in Rust using the Dioxus UI library. It currently runs on macOS [stable], Windows [beta], and theoretically on Linux [untested].

Ebou is a different take on the Microblogging / Mastodon experience. It groups new Toots by author and displays them in a UI not unlike modern messengers like Telegram, iMessage or WhatsApp.

This makes it easy to see your friends' updates at once.

It also has a Conversation view which helps seeing replies in the originating context.

Ebou is currently an experiment and therefore missing some features which you might expect from a full Mastodon client. They will be implemented over time.

You can download the current release for macOS Testflight or in the GitHub releases

Note: I worked on Ebou in my spare time. Please judge the code not as a professional project but more like a small side project where the outcome (a working desktop client) had higher priority than beautiful, well architected, well abstracted code.

Screenshots

Full Screenshot with Conversation Tree:

List of Followers:

Classic Timeline:

Windows Beta:

Linux Beta:

State

Ebou is currently in a beta state. There're bugs, and there're missing features. Here's a list of currently supported Mastodon features:

  • Timelines
  • Super Minimal Notifications (only Mentions and Ebou doesn’t remember which ones you already saw)
  • Posting (including Video / Image attachments via Dragging and Dropping images onto window)
  • Conversations in a nice nested tree view
  • Boost, favorite, reply, bookmark
  • Lists
  • Your favourites / bookmarks
  • Profiles
  • Settings
  • Minimal Search
  • Followers / Follows
  • Some settings

Dioxus

Ebou uses Dioxus as the UI library. Dioxus makes it easy to build functional cross platform apps, but it is also currently unfinished and lacking features. Some of the limitations of Ebou are related to missing features in Dioxus.

One particular issue I have with Dioxus is that it uses a lot of abstractions and patterns from the React world. This leads to a lot of mixing of logic, model and ui domains.

Navicula

Therfore, I wrote an additional abstraction on top of Dioxus which implements a reducer model where each view is split up into the view, the state, the action / message and the reducer. It is a bit of a mix between the Elm architecture and the Swift Composable Architecture. It is called Navicula and a separate crate which can be found here.

Forks

Due to the way things work, many of the dependencies that Ebou uses had the one or other issue which made it difficult to use in Ebou. Therefore (if you look at the dependencies in Cargo.toml) there're several forks of different crates. I plan to get these changes merged over time.

Model Layer

One tricky issue about apps servicing microblogging services such as Twitter or Mastodon is that the data model needs to support the use case of sharing and mutating each Status (or Toot, or Tweet, or Message, I'll use the word Status now).

You could have the same Status multiple times on the screen. As a Status, and then as a boost and then in another column as one of your liked items, and then maybe in the conversation view as well. If you star one of them, the following needs to happen:

  1. The state is temporarily changed
  2. The mastodon star api is called
  3. If successful the star should be made permanent
  4. Find all the places where this particular Status is currently displayed
  5. Update it in all these places
  6. Redraw the related UI in these places
  7. All this on different threads (because the api call will probably happen on tokio and should not block the UI)

This particular problem is a bit hard in Rust because shared mutable cross thread state can only be achived with a Arc<Mutex<...>> which is hard to use because everytime you'd want to read any property of it you'd need to watch out for a poisoned lock, etc.

Ebou currently doesn't have a really good solution to this problem. It has something called RefPublisher which keeps all the Status data in a variety of structures. Reducers can subscribe to this RefPublisher. Then, whenever something in the storage changes, the view will be notified that it needs to re-render. Mutation then happens with a specific with_mutation function which makes sure to update all subscribers. This is not a particularly good solution because of multiple reasons:

  1. It is not fine-grained enough. It should be possible to subscribe on a per Status level
  2. Statuses are currently not stored as references. Instead, multiple instances can exist in memory. Something aking to a ECS might be a useful idea here
  3. The with_mutation way is cumbersome to use.

Replacing this system with something better would go a long way towards improving the performance and reliability of Ebou.

Javascript

There're some places where Dioxus didn't support the required functionality yet, so Ebou uses ugly javascript injection hacks to achieve some sort of effect. I can't say that I'm particularly happy about this.

Building

cargo run
# or
cargo run --release

Signing & Releasing

macOS

In order to create a macOS release build, we first generate a universal binary in Rust and then let Xcode sign it. It is possible to use command line utilities to sign the binary, but this is quite the hassle. Instead, there is an included Xcode project in the Xcode-Container folder:

  1. Open up the Xcode Project
  2. Build an Archive
  3. Open the Archive in Finder to get the path to the archive on disk
  4. Call the make.sh script with a version number and the path, e.g. `./make.sh 700 "/Users/ben/Library/Developer/Xcode/Archives/2023-05-05/Ebou 23.05.23.xcarchive"
  5. This will build Ebou and replace the binary in the Xcode archive with the actual Ebou binary
  6. Go to Xcode, selected the archive in the Organizer and sign & submit it from there

Linux

Linux requires a couple of additional dependencies.

Debian

sudo apt-get install pkg-config libssl-dev libgtk-3-dev xdotool libwebkit2gtk-4.1-dev libgtk-3-0 libgtk-3-dev libxdo-dev

Arch

There's a AUR package for Arch Linux:

https://aur.archlinux.org/packages/ebou-git

Thanks to https://github.com/StandingPadAnimations

Fedora

# Untested
dnf install pkg-config openssl-devel gtk3 gtk3-devel webkit2gtk4.1-devel xdotool xdotool-devel

License

Ebou is licensed under the GPL License

ebou's People

Contributors

cantudo avatar cyborus04 avatar rachtsingh avatar shombando avatar terhechte avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ebou's Issues

Linux build dependencies

Just a comment on the build dependencies. I used a docker container to build the app on Ubuntu successfully but I noticed that gcc is missing from the listed dependencies to install. For a full install of Ubuntu/Debian this won't matter as it will be available by default but in a container it isn't.

Furthermore, current Fedora doesn't have a xdotool-devel package. I tried compiling without it but the build failed (not sure if for this reason, though). Side note: gcc is also needed as a dependency here, although the build ultimately failed.

Release builds fail

Currently release builds of Ebou fail due to a mistake in the build script.

#[cfg(not(debug_assertions))]
fn styles() -> String {
    grass::include!("../public/style.css").to_string()
}

is probably meant to be

#[cfg(not(debug_assertions))]
fn styles() -> String {
    grass::include!("public/style.scss").to_string()
}

Failed to connect to pleroma

Hey there, ebou looks like a beautiful project ! Unfortunately I can't get it to run on my pleroma instance, I get this error:

src/environment/native/model.rs:616 2023-06-24T13:05:59 [ERROR] - API Error: login RequestError(reqwest::Error { kind: Decode, source: Error("missing field `invites_enabled`", line: 1, column: 1982) })

Is this expected ?

Ebou Arch Linux version UI probleme

Hello,
It seems that several Ebou functions are not available on the Arch Linux version of Ebou, below I have highlighted in red all the buttons that do not work, then you can look is reply to messages but impossible to go to the settings, connect with another account, etc. ...
image

Failing compilation on Linux

I'm no Rustacean, so I can't help with the coding part but I know my way around the basics of cargo, so I've tried my hand at compiling Ebou on my Linux machine.

I just tried to cargo run it and after installing a few missing development dependencies1 on my OpenSUSE Tumbleweed, I received a lot of error[E0433]: failed to resolve: use of undeclared crate or module during compilation of Ebou itself. Not sure what's missing but here's the error log I collected from cargo run: error-log.txt

If you need any further information or would like me to test some things, I'd be happy to help.

Footnotes

  1. Namely gtk3-devel, libsoup-devel, webkit2gtk3-soup2-devel, webkit2gtk3-devel, webkit2gtk4-devel. I'm not sure which of the webkit2gtk3-* packages were really needed but webkit2gtk4-devel alone was certainly not enough, so I just installed them both for good measure.

Ctrl+R is blocked on MacOS while Ebou is open in the background

Ebou version: Version 0.2.0 (742)
MacOS version: 13.4.1 (c)

A few days ago, I noticed that Ctrl+R stopped working on my mac.
I was trying to redo an undone change in neovim, but nothing happened at all when I pressed Ctrl+R. I was also unable to use Ctrl+R in my shell, to search my previous commands. I tried a different terminal app, but that didn't help.

However, as soon as I closed Ebou, Ctrl+R started to work again. When I reopened Ebou to see if it was consistent, Ctrl+R went back to doing nothing.

This seems really strange. As far as I can tell, there are no keyboard shortcuts in Ebou that are bound to Ctrl+R, and nothing happens in Ebou when I press Ctrl+R. The closest is Cmd+R, but that works as expected (it refreshes the posts)

I did not notice any other combinations with Ctrl that were similarly affected. (The ones I remember using and working fine: Ctrl+Z, Ctrl+C, Ctrl+G, Ctrl+T)

A dockefile or compose setup ?

I attempted this on Linux, but the build failed. Since I'm not very familiar with Rust and I'm concerned about potentially disrupting my system dependencies, I would like to explore the possibility of setting up a Dockerfile. This would make the setup process easier on any system. I will conduct some research to see if I can find a suitable solution and submit a pull request to the repository if I discover one.

[Linux] failed compilation of dependency: javascriptcore-rs

OS: Arch Linux (6.4.1 kernel)
/usr/lib/libjavascriptcoregtk-4.0.so is present as a part of webkit2gtk (btw, list it as a dep maybe)
but it misses a pkg-config file so the compilation fails because it depends on it.

Tried:
cargo build --release

output:

warning: `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" "pkg-config" "--libs" "--cflags" "javascriptcoregtk-4.1" "javascriptcoregtk-4.1 >= 2.24"` did not exit successfully: exit status: 1

error: failed to run custom build command for `javascriptcore-rs-sys v0.5.1`

Caused by:
  process didn't exit successfully: `/home/user/Ebou/target/release/build/javascriptcore-rs-sys-e2aec79b2d46c4e2/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-env-changed=JAVASCRIPTCOREGTK_4.1_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:warning=`PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" "pkg-config" "--libs" "--cflags" "javascriptcoregtk-4.1" "javascriptcoregtk-4.1 >= 2.24"` did not exit successfully: exit status: 1
  error: could not find system library 'javascriptcoregtk-4.1' required by the 'javascriptcore-rs-sys' crate

  --- stderr
  Package javascriptcoregtk-4.1 was not found in the pkg-config search path.
  Perhaps you should add the directory containing `javascriptcoregtk-4.1.pc'
  to the PKG_CONFIG_PATH environment variable
  Package 'javascriptcoregtk-4.1', required by 'virtual:world', not found
  Package 'javascriptcoregtk-4.1', required by 'virtual:world', not found

Attaching media to posts

Ebou can send text for posts, but would be nice if we could attach media to posts as well with Ebou.

Ebou adds a trailing slash to the base API URL

When sending API requests, Ebou appends a trailing slash to the base API URL.
This might work fine with Mastodon (since Rails probably just ignores that slash when routing), but alternative implementations refuse to route these URLs.

This happens because of this line:

state.selected_instance_url = Some(success.as_str().to_string());

Proposal

Instead of re-encoding the parsed URL as a string, re-use the term variable as the value since it's guaranteed to be a valid URL.

Like so:

if url::Url::parse(&term).is_ok() {
  state.selected_instance_url = Some(term);
}

Ebou sends JSON encoded payload to OAuth endpoints

When trying to get the access token, Ebou sends a JSON-encoded payload to the /oauth/token endpoint.

While this is fine with Mastodon (since Rails just deserializes based on the Content-Type header), this causes issues with alternative implementations that actually follow the OAuth2 spec closely, which states that all the body contents have to be application/x-www-form-urlencoded.

Looking at the code, there seem to be two solutions to this:

  1. Submit everything to the API as application/x-www-form-urlencoded bodies. This should work fine.
  2. Make a special case for the OAuth endpoints to submit the data as application/x-www-form-urlencoded instead of application/json (this is more effort, not sure if it's worth it)

Ebou as a juicy client

Do you think Ebou might be flexible enough to fit the vision of a multi-modal client?

https://blog.erlend.sh/juicy-clients

Basically I’m wondering if you’d accept contributions towards this, starting with an additional view to support a Reddit-style interface. There’s a lot of interest in this within the Rust community so I’m confident we could rally support for this effort: https://www.reddit.com/r/rust/comments/146qxzn/building_a_better_rrust_together/

Although it’s several Dioxus versions ago now, there’s some prior art for a links-aggregator UI by @mrxiaozhuox here: https://github.com/mrxiaozhuox/dioxus-hackernews

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.