Compare commits
3 Commits
a06c26130d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdeda666c1 | ||
|
|
505cc110aa | ||
|
|
269e8ef6ee |
163
Cargo.lock
generated
163
Cargo.lock
generated
@@ -1234,6 +1234,17 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ermine"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"slint",
|
||||||
|
"slint-build",
|
||||||
|
"ureq",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.14"
|
version = "0.3.14"
|
||||||
@@ -1645,6 +1656,17 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@@ -1858,6 +1880,22 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48ce8546b993eaf241d69ded33b1be6d205dd9857ec879d9d18bd05d3676e144"
|
checksum = "48ce8546b993eaf241d69ded33b1be6d205dd9857ec879d9d18bd05d3676e144"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i-slint-backend-linuxkms"
|
name = "i-slint-backend-linuxkms"
|
||||||
version = "1.15.1"
|
version = "1.15.1"
|
||||||
@@ -3803,6 +3841,20 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.17.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"getrandom 0.2.17",
|
||||||
|
"libc",
|
||||||
|
"untrusted",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rowan"
|
name = "rowan"
|
||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
@@ -3884,6 +3936,41 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.23.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pki-types"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
|
||||||
|
dependencies = [
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.103.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
@@ -4154,14 +4241,6 @@ dependencies = [
|
|||||||
"spin_on",
|
"spin_on",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "slint-rust-template"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"slint",
|
|
||||||
"slint-build",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slotmap"
|
name = "slotmap"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
@@ -4362,6 +4441,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "svgtypes"
|
name = "svgtypes"
|
||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
@@ -4782,12 +4867,47 @@ version = "0.2.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unty"
|
name = "unty"
|
||||||
version = "0.0.4"
|
version = "0.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
|
checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq"
|
||||||
|
version = "3.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fdc97a28575b85cfedf2a7e7d3cc64b3e11bd8ac766666318003abbacc7a21fc"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"flate2",
|
||||||
|
"log",
|
||||||
|
"percent-encoding",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"ureq-proto",
|
||||||
|
"utf-8",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ureq-proto"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.8"
|
version = "2.5.8"
|
||||||
@@ -4827,6 +4947,12 @@ dependencies = [
|
|||||||
"xmlwriter",
|
"xmlwriter",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf-8"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8_iter"
|
name = "utf8_iter"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -4894,6 +5020,12 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasip2"
|
name = "wasip2"
|
||||||
version = "1.0.2+wasi-0.2.9"
|
version = "1.0.2+wasi-0.2.9"
|
||||||
@@ -5160,6 +5292,15 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "weezl"
|
name = "weezl"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
@@ -6215,6 +6356,12 @@ dependencies = [
|
|||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zeroize"
|
||||||
|
version = "1.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerotrie"
|
name = "zerotrie"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "slint-rust-template"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
name = "ermine"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
serde = {version = "1.0.149", features = ["derive"]}
|
||||||
|
serde_json = "1.0.149"
|
||||||
slint = "1.14.1"
|
slint = "1.14.1"
|
||||||
|
ureq = "3.2.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
slint-build = "1.14.1"
|
slint-build = "1.14.1"
|
||||||
|
|||||||
70
NOTES.md
Normal file
70
NOTES.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# 2026-02-22
|
||||||
|
## 2200
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
- Need a better Revolt client that's cross-platform native
|
||||||
|
- Ideally macOS / iPadOS / iOS / Windows / Linux / Android / Web
|
||||||
|
- Need the UI / UX to be top-notch and feel good in the hands, otherwise people won't use it
|
||||||
|
- On top of this, it should also be _fun_ and _cute_
|
||||||
|
- Accessibility should be considered, but I do not have experience in this area, will need to do research
|
||||||
|
- Currently Revolt has a (now deprecated) web app and a native app that doesn't support custom endpoints
|
||||||
|
- We're forking from Revolt, so don't need to worry about breaking changes on their end
|
||||||
|
- Sticking with the name ermine cause I like it (stylized `ermine` all lowercase to be cool)
|
||||||
|
- Decided to try using Slint + Rust for a more bare-bones low-level approach
|
||||||
|
- Licensing
|
||||||
|
- Slint requires GPLv3 without a paid license - fine with this
|
||||||
|
- Revolt is also AGPLv3
|
||||||
|
- Code I write will be MIT as I don't want to hinder people re-using anything for any reason
|
||||||
|
- Have already spent a number of hours 100% vibe coding a prototype
|
||||||
|
- Used Flutter + Dart (was considered for this iteration)
|
||||||
|
- It worked okay, had a UX close to what I want as a starting point, so we know what we want is possible, we just need to build it
|
||||||
|
- There are just too many bugs and there's no way to trust the code written underneath
|
||||||
|
- Feel awful and ashamed of vibe coding, giving away my agency and creativity to an LLM and to big tech, rotting away my ability to create
|
||||||
|
- This is a project to push myself outside of my comfort zone towards something I've not done before, to grow beyond the limitations I've placed upon myself
|
||||||
|
- Having seen what other people've worked on, over months, and the kind of dedication they have towards software quality, I know this is something that will take time to craft instead of something I can bang out in a few hyperfixated days
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
- Slint
|
||||||
|
- https://docs.slint.dev/latest/docs/slint/
|
||||||
|
- Rust
|
||||||
|
- https://docs.rs/http/latest/http/
|
||||||
|
- https://docs.rs/sqlite/latest/sqlite/
|
||||||
|
- https://docs.rs/json/latest/json/
|
||||||
|
- https://docs.rs/websocket/latest/websocket/
|
||||||
|
- https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html
|
||||||
|
- Revolt
|
||||||
|
- https://developers.stoat.chat/developers/endpoints/
|
||||||
|
- https://developers.stoat.chat/api-reference
|
||||||
|
- https://stoat.chat/api
|
||||||
|
- https://revolt.handmadecities.com/api
|
||||||
|
- https://github.com/livekit/livekit
|
||||||
|
- HMC
|
||||||
|
- https://git.handmadecities.com/HMC/handmade-revolt
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Slint reminds me a lot of when I tried messing with SwiftUI
|
||||||
|
- Trying to make things look pretty early on is a fools errand
|
||||||
|
- Need to remember to make things work, then make them look nice
|
||||||
|
- Have not used Rust before so this should be interesting
|
||||||
|
- HMC Revolt seems to be on version 0.8.2 while Stoat is now on 0.11.5
|
||||||
|
- Have an OpenAPI spec for the latest stoat, but no historical ones
|
||||||
|
- Need to figure out what differences exist, if any, and how to support different server versions cleanly
|
||||||
|
- Seems like there's an `/api` endpoint with information about the server (if it's a revolt server)
|
||||||
|
- App version
|
||||||
|
- autumn endpoint (file server)
|
||||||
|
- january endpoint (media server)
|
||||||
|
- voso ?
|
||||||
|
- livekit ?
|
||||||
|
- livekit seems to be what's used for voice / video support
|
||||||
|
- Currently not supported by HMC Revolt instance
|
||||||
|
- main websocket
|
||||||
|
- Trying to use progenitor + openAPI spec to generate rust code, not going that well, and Gwen said it may be better to write these by hand
|
||||||
|
- progenitor didn't work due to it operating under the assumption that endpoints only return one type, which this spec violates (https://github.com/oxidecomputer/progenitor/issues/950)
|
||||||
|
- Read through documentation mostly, taking it slow and making sure I understand how things are working, being patient with myself
|
||||||
|
|
||||||
|
# 2026-03-20
|
||||||
|
## 0220
|
||||||
|
|
||||||
|
Figured the API endpoint (`/api`) would be a good place to start. Now have successful deserialization.
|
||||||
|
|
||||||
|
Sidebars are important, so I added two, one for channel list and another for server list. I'm still trying to figure out the best way to integrate different instances seamlessly.
|
||||||
32
src/api.rs
Normal file
32
src/api.rs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#[derive(serde::Deserialize, Debug)]
|
||||||
|
pub struct ServerInfo {
|
||||||
|
// version number
|
||||||
|
revolt: String,
|
||||||
|
// main websocket
|
||||||
|
ws: String,
|
||||||
|
// main app URL
|
||||||
|
app: String,
|
||||||
|
vapid: String,
|
||||||
|
features: ServerFeatures,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, Debug)]
|
||||||
|
struct ServerFeatures {
|
||||||
|
email: bool,
|
||||||
|
invite_only: bool,
|
||||||
|
// file server
|
||||||
|
autumn: Option<ServerFeatureEndpoint>,
|
||||||
|
// media server
|
||||||
|
january: Option<ServerFeatureEndpoint>,
|
||||||
|
//
|
||||||
|
voso: Option<ServerFeatureEndpoint>,
|
||||||
|
// voip server
|
||||||
|
livekit: Option<ServerFeatureEndpoint>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, Debug)]
|
||||||
|
struct ServerFeatureEndpoint {
|
||||||
|
enabled: bool,
|
||||||
|
url: Option<String>,
|
||||||
|
ws: Option<String>,
|
||||||
|
}
|
||||||
10
src/main.rs
10
src/main.rs
@@ -2,10 +2,20 @@
|
|||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
mod api;
|
||||||
|
|
||||||
slint::include_modules!();
|
slint::include_modules!();
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let response = ureq::get("https://revolt.handmadecities.com/api")
|
||||||
|
.call()?
|
||||||
|
.body_mut()
|
||||||
|
.read_to_string()?;
|
||||||
|
|
||||||
|
let server_info: api::ServerInfo = serde_json::from_str(&response).unwrap();
|
||||||
|
|
||||||
|
println!("{:#?}", server_info);
|
||||||
|
|
||||||
let ui = AppWindow::new()?;
|
let ui = AppWindow::new()?;
|
||||||
|
|
||||||
// ui.on_request_increase_value({
|
// ui.on_request_increase_value({
|
||||||
|
|||||||
@@ -1,7 +1,24 @@
|
|||||||
import { Button, VerticalBox, TextEdit } from "std-widgets.slint";
|
import { Button, VerticalBox, TextEdit } from "std-widgets.slint";
|
||||||
import { ChatView } from "chat-view.slint";
|
import { ChatView } from "chat-view.slint";
|
||||||
|
import { ChannelSidebar, ServerSidebar } from "sidebar.slint";
|
||||||
|
|
||||||
export component AppWindow inherits Window {
|
export component AppWindow inherits Window {
|
||||||
|
title: "ermine";
|
||||||
|
|
||||||
|
property <bool> sidebar-open: true;
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
ServerSidebar {
|
||||||
|
open: root.width > 600px;
|
||||||
|
server_list: [{ icon: "😳" }, { icon: "😍" }];
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelSidebar {
|
||||||
|
open: root.width > 600px ? sidebar-open : false;
|
||||||
|
channel_list: [{ title: "Foo" }, { title: "Bar" }];
|
||||||
|
background: blue;
|
||||||
|
}
|
||||||
|
|
||||||
VerticalLayout {
|
VerticalLayout {
|
||||||
|
|
||||||
@@ -30,3 +47,4 @@ export component AppWindow inherits Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
27
ui/sidebar.slint
Normal file
27
ui/sidebar.slint
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
export component ChannelSidebar inherits Rectangle {
|
||||||
|
in property <bool> open;
|
||||||
|
in property <[{title: string}]> channel_list;
|
||||||
|
|
||||||
|
width: open ? 200px : 0px;
|
||||||
|
clip: true;
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
width: 200px;
|
||||||
|
for channel in channel_list: Text {
|
||||||
|
text: channel.title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export component ServerSidebar inherits Rectangle {
|
||||||
|
in property <bool> open;
|
||||||
|
in property <[{icon: string}]> server_list;
|
||||||
|
|
||||||
|
width: open ? 48px : 0px;
|
||||||
|
VerticalLayout {
|
||||||
|
width: 48px;
|
||||||
|
for server in server_list: Text {
|
||||||
|
text: server.icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user