Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Vauxl Client

A Discord-style Matrix client. Tauri v2 shell, React (web) UI, and a Rust core.
Today it runs entirely on an in-memory `MockBackend`, so the whole interface can
be built and felt before any Matrix code exists. Swapping in a matrix-rust-sdk
backend later changes only one constructor.
Today it runs entirely on an in-memory `MockBackend`. Replies, edits, own-message
redaction, and reactions are functional mock behavior only. They are not
homeserver operations or real Matrix interoperability.

## Layout

```
client/
core/ vauxl-core: the contract types, the ChatBackend trait, MockBackend (no Tauri, no Matrix)
src-tauri/ the Tauri shell: command/event wrappers over ChatBackend, tauri-specta bindings export
core/ vauxl-core: contract types and MockBackend (no Tauri, no Matrix)
src-tauri/ the Tauri shell: command and event wrappers, tauri-specta bindings export
src/ the React UI (web). src/bindings.ts is GENERATED from Rust, do not edit it by hand
docs/ DATA_INTERFACE.md explains the contract and the security boundary
```
Expand Down Expand Up @@ -48,10 +48,9 @@ bun run build # typechecks and builds the frontend into dist/
bun run tauri build # produces a packaged desktop bundle
```

## Swapping the mock for real Matrix
## Replacing the mock with Matrix

1. Add a `MatrixBackend` to `core` (a new module) that implements `ChatBackend`
using `matrix-rust-sdk`. Crypto stays in `vodozemac` via the SDK; you write no
crypto yourself.
2. In `src-tauri/src/lib.rs`, change the constructor in `run` from
`MockBackend::new()` to your `MatrixBackend`. Nothing in the UI changes.
Implement the current command set used by the UI with `matrix-rust-sdk`, then
update `AppState` and the constructor in `src-tauri/src/lib.rs`. Add a shared
backend trait only when a second backend exists. Crypto stays in `vodozemac`
through the SDK.
1 change: 0 additions & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ description = "Protocol-agnostic chat contract and mock backend for the Vauxl cl
serde = { version = "1", features = ["derive"] }
specta = { version = "2.0.0-rc.25", features = ["derive"] }
thiserror = "2"
async-trait = "0.1"
tokio = { version = "1", features = ["sync", "time"] }

[dev-dependencies]
Expand Down
64 changes: 0 additions & 64 deletions core/src/backend.rs

This file was deleted.

43 changes: 8 additions & 35 deletions core/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ use specta::Type;
use crate::ids::*;
use crate::model::*;

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(tag = "type")]
pub enum SyncState {
Offline,
Connecting,
Syncing,
Live,
Error { message: String },
}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(tag = "op")]
pub enum TimelineChange {
Expand All @@ -22,34 +12,17 @@ pub enum TimelineChange {
Removed { id: MessageId },
}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct SasEmoji {
pub symbol: String,
pub name: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(tag = "type")]
pub enum VerificationUpdate {
Requested { from: UserId, flow: String },
ShowSas { flow: String, emoji: Vec<SasEmoji> },
Done { flow: String },
Cancelled { flow: String, reason: String },
}

/// Reactive updates pushed from the core to the UI. The Tauri layer forwards
/// each of these to the webview as an event.
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(tag = "type")]
pub enum CoreEvent {
Session { state: SessionState },
Sync { state: SyncState },
RoomUpserted { room: Room },
RoomRemoved { room: RoomId },
SpaceUpserted { space: Space },
Timeline { room: RoomId, change: TimelineChange },
Typing { room: RoomId, users: Vec<UserId> },
Receipt { room: RoomId, user: UserId, up_to: MessageId },
Presence { user: User },
Verification { update: VerificationUpdate },
Timeline {
room: RoomId,
change: TimelineChange,
},
Typing {
room: RoomId,
users: Vec<UserId>,
},
}
12 changes: 4 additions & 8 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
//! vauxl-core: the protocol-agnostic chat contract plus a MockBackend.
//! vauxl-core: protocol-agnostic chat types plus a MockBackend.
//!
//! This crate deliberately has no Tauri and no Matrix dependency. The same
//! `ChatBackend` trait is implemented by `MockBackend` (here, for the prototype)
//! and later by a matrix-rust-sdk backend. The UI depends only on these types,
//! so the shell and the protocol stay swappable.
//! This crate deliberately has no Tauri or Matrix dependency. `MockBackend`
//! drives the prototype while the UI consumes generated bindings.

pub mod backend;
pub mod error;
pub mod event;
pub mod ids;
pub mod mock;
pub mod model;

pub use backend::ChatBackend;
pub use error::CoreError;
pub use event::{CoreEvent, SasEmoji, SyncState, TimelineChange, VerificationUpdate};
pub use event::{CoreEvent, TimelineChange};
pub use ids::{DeviceId, MessageId, RoomId, SpaceId, UserId};
pub use mock::MockBackend;
pub use model::*;
Loading