initial commit

This commit is contained in:
2024-11-19 08:23:43 +07:00
commit 4d8a1d44cc
8 changed files with 177 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@@ -0,0 +1,21 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
# RustRover
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

37
Cargo.toml Normal file
View File

@@ -0,0 +1,37 @@
[workspace]
members = ["crates/*"]
default-members = ["crates/ui"]
resolver = "2"
[workspace.dependencies]
coop = { path = "crates/*" }
# Account
keyring-search = "1.2.0"
keyring = { version = "3", features = [
"apple-native",
"windows-native",
"linux-native",
] }
# UI
gpui = { git = "https://github.com/zed-industries/zed" }
components = { package = "ui", git = "https://github.com/longbridgeapp/gpui-component", version = "0.1.0" }
# Nostr
nostr-relay-builder = { git = "https://github.com/rust-nostr/nostr" }
nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = [
"lmdb",
"all-nips",
] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dirs = "5.0"
itertools = "0.13.0"
futures = "0.3.30"
chrono = "0.4.38"
tracing = "0.1.40"
anyhow = "1.0.44"
smallvec = "1.13.2"

12
README.md Normal file
View File

@@ -0,0 +1,12 @@
# coop
Created with Create GPUI App.
- [`gpui`](https://www.gpui.rs/)
- [GPUI documentation](https://github.com/zed-industries/zed/tree/main/crates/gpui/docs)
- [GPUI examples](https://github.com/zed-industries/zed/tree/main/crates/gpui/examples)
## Usage
- Ensure Rust is installed - [Rustup](https://rustup.rs/)
- Run your app with `cargo run`

9
crates/nostr/Cargo.toml Normal file
View File

@@ -0,0 +1,9 @@
[package]
name = "nostr"
version = "0.1.0"
edition = "2021"
[dependencies]
nostr-sdk.workspace = true
dirs.workspace = true
tokio.workspace = true

1
crates/nostr/src/lib.rs Normal file
View File

@@ -0,0 +1 @@
pub mod state;

37
crates/nostr/src/state.rs Normal file
View File

@@ -0,0 +1,37 @@
use dirs::config_dir;
use nostr_sdk::prelude::*;
use std::fs;
use tokio::sync::OnceCell;
pub static CLIENT: OnceCell<Client> = OnceCell::const_new();
pub async fn get_client() -> &'static Client {
CLIENT
.get_or_init(|| async {
// Setup app data folder
let config_dir = config_dir().unwrap();
let _ = fs::create_dir_all(config_dir.join("Coop/"));
// Setup database
let lmdb = NostrLMDB::open(config_dir.join("Coop/nostr"))
.expect("Database is NOT initialized");
// Setup Nostr Client
let client = ClientBuilder::default().database(lmdb).build();
// Add some bootstrap relays
let _ = client.add_relay("wss://relay.damus.io").await;
let _ = client.add_relay("wss://relay.primal.net").await;
let _ = client.add_relay("wss://nostr.fmt.wiz.biz").await;
let _ = client.add_relay("wss://directory.yabu.me").await;
let _ = client.add_relay("wss://purplepag.es").await;
let _ = client.add_relay("wss://user.kindpag.es/").await;
// Connect to all relays
client.connect().await;
// Return client
client
})
.await
}

14
crates/ui/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "coop"
version = "0.1.0"
edition = "2021"
publish = false
[[bin]]
name = "coop"
path = "src/main.rs"
[dependencies]
gpui.workspace = true
tokio.workspace = true
nostr = { version = "0.1.0", path = "../nostr" }

46
crates/ui/src/main.rs Normal file
View File

@@ -0,0 +1,46 @@
use gpui::*;
use nostr::state::get_client;
struct HelloWorld {
text: SharedString,
}
impl Render for HelloWorld {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
div()
.bg(rgb(0xffffff))
.flex()
.size_full()
.justify_center()
.items_center()
.child(format!("Hello, {}!", &self.text))
}
}
#[tokio::main]
async fn main() {
let _client = get_client().await;
App::new().run(|cx: &mut AppContext| {
let bounds = Bounds::centered(None, size(px(860.0), px(650.0)), cx);
cx.open_window(
WindowOptions {
window_bounds: Some(WindowBounds::Windowed(bounds)),
window_decorations: Some(WindowDecorations::Client),
titlebar: Some(TitlebarOptions {
title: Some(SharedString::new_static("coop")),
appears_transparent: true,
..Default::default()
}),
..Default::default()
},
|cx| {
cx.new_view(|_cx| HelloWorld {
text: "coop".into(),
})
},
)
.unwrap();
});
}