Compare commits
2
Commits
v1.0.0
..
2f834a0bcc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f834a0bcc | ||
|
|
49cd5cb9a0 |
Generated
+480
-648
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -4,7 +4,7 @@ members = ["crates/*", "desktop", "web"]
|
||||
default-members = ["desktop"]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.0.0-beta5"
|
||||
version = "1.0.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["crates/*", "desktop", "web"]
|
||||
default-members = ["desktop"]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.0.0-beta5"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[workspace.dependencies]
|
||||
# GPUI
|
||||
gpui = { git = "https://github.com/zed-industries/zed" }
|
||||
gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["font-kit", "x11", "wayland"] }
|
||||
gpui_linux = { git = "https://github.com/zed-industries/zed" }
|
||||
gpui_windows = { git = "https://github.com/zed-industries/zed" }
|
||||
gpui_macos = { git = "https://github.com/zed-industries/zed" }
|
||||
gpui_tokio = { git = "https://github.com/zed-industries/zed" }
|
||||
reqwest_client = { git = "https://github.com/zed-industries/zed" }
|
||||
|
||||
# Nostr
|
||||
nostr-lmdb = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr-memory = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr-blossom = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr-gossip-memory = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr-connect = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr-sdk = { git = "https://github.com/rust-nostr/nostr" }
|
||||
nostr = { git = "https://github.com/rust-nostr/nostr", features = [ "nip59", "nip49", "nip44" ] }
|
||||
|
||||
# Others
|
||||
anyhow = "1.0.44"
|
||||
chrono = { version = "0.4.38", features = ["wasmbind"] }
|
||||
futures = "0.3"
|
||||
itertools = "0.13.0"
|
||||
log = "0.4"
|
||||
oneshot = "0.1.10"
|
||||
flume = { version = "0.11.1", default-features = false, features = ["async", "select"] }
|
||||
rust-embed = { version = "8.5", features = ["include-exclude"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
schemars = "1"
|
||||
smallvec = "1.14.0"
|
||||
smol = "2"
|
||||
webbrowser = "1.0.4"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
|
||||
errno = { version = "0.3.14", default-features = false }
|
||||
instant = "0.1"
|
||||
|
||||
[patch.crates-io]
|
||||
# Use stacker's psm version which may have better WASM support
|
||||
psm = { git = "https://github.com/rust-lang/stacker", branch = "master" }
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
|
||||
[profile.profiling]
|
||||
inherits = "release"
|
||||
debug = true
|
||||
@@ -11,7 +11,7 @@ publish = false
|
||||
atomic-destructor = "0.2"
|
||||
event-listener = "5"
|
||||
nostr.workspace = true
|
||||
opaquerr = "0.1"
|
||||
opaquerr = { version = "0.1", features = ["alloc"] }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
smol.workspace = true
|
||||
|
||||
+19
-6
@@ -365,7 +365,8 @@ impl ChatRegistry {
|
||||
.query(filter)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.first_owned()
|
||||
.into_iter()
|
||||
.next()
|
||||
.is_some();
|
||||
|
||||
if !found {
|
||||
@@ -397,7 +398,8 @@ impl ChatRegistry {
|
||||
.database()
|
||||
.query(filter)
|
||||
.await?
|
||||
.first_owned()
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(anyhow::anyhow!("No inbox relays found"))?;
|
||||
|
||||
let relays: Vec<RelayUrl> = nip17::extract_relay_list(&event).collect();
|
||||
@@ -656,15 +658,26 @@ impl ChatRegistry {
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let public_key = signer.get_public_key_async().await?;
|
||||
let contacts = client
|
||||
|
||||
// Query the latest contact list (previously `NostrDatabaseExt::contacts_public_keys`)
|
||||
let filter = Filter::new()
|
||||
.author(public_key)
|
||||
.kind(Kind::ContactList)
|
||||
.limit(1);
|
||||
|
||||
let contacts: HashSet<PublicKey> = client
|
||||
.database()
|
||||
.contacts_public_keys(public_key)
|
||||
.query(filter)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|event| event.tags.public_keys().collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::K), "14");
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_K, "14");
|
||||
|
||||
let events = client.database().query(filter).await?;
|
||||
let mut grouped: HashMap<u64, Vec<UnsignedEvent>> = HashMap::new();
|
||||
@@ -827,7 +840,7 @@ async fn set_rumor(client: &Client, id: EventId, rumor: &UnsignedEvent) -> Resul
|
||||
async fn get_rumor(client: &Client, gift_wrap: EventId) -> Result<UnsignedEvent, Error> {
|
||||
let filter = Filter::new().identifier(gift_wrap).limit(1);
|
||||
|
||||
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
||||
if let Some(event) = client.database().query(filter).await?.into_iter().next() {
|
||||
UnsignedEvent::from_json(event.content).map_err(|e| anyhow!(e))
|
||||
} else {
|
||||
Err(anyhow!("Event is not cached yet."))
|
||||
|
||||
@@ -403,7 +403,7 @@ impl Room {
|
||||
cx.background_spawn(async move {
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.custom_tag(SingleLetterTag::lowercase(Alphabet::R), room_id);
|
||||
.custom_tag(SingleLetterTag::LOWERCASE_R, room_id);
|
||||
|
||||
let messages = client
|
||||
.database()
|
||||
@@ -461,13 +461,10 @@ impl Room {
|
||||
// Add all receiver tags (no intermediate allocation)
|
||||
for public_key in self.members.iter().filter(|pk| *pk != &sender) {
|
||||
let member = persons.read(cx).get(public_key, cx);
|
||||
tags.push(
|
||||
Nip01Tag::PublicKey {
|
||||
public_key: member.public_key(),
|
||||
relay_hint: member.messaging_relay_hint(),
|
||||
}
|
||||
.to_tag(),
|
||||
);
|
||||
tags.push(Tag::from(Nip01Tag::PublicKey {
|
||||
public_key: member.public_key(),
|
||||
relay_hint: member.messaging_relay_hint(),
|
||||
}));
|
||||
}
|
||||
|
||||
// Construct a direct message rumor event
|
||||
|
||||
@@ -4,13 +4,13 @@ use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::{Context as AnyhowContext, Error, anyhow};
|
||||
use gpui::{
|
||||
App, AppContext, Context, Entity, EventEmitter, Global, IntoElement, ParentElement,
|
||||
SharedString, Styled, Subscription, Task, Window, div, relative,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::PersonRegistry;
|
||||
use settings::AppSettings;
|
||||
@@ -414,7 +414,7 @@ impl DeviceRegistry {
|
||||
.pubkey(app_pubkey)
|
||||
.limit(1);
|
||||
|
||||
match client.database().query(filter).await?.first_owned() {
|
||||
match client.database().query(filter).await?.into_iter().next() {
|
||||
// Found an approval event
|
||||
Some(event) => Ok(Some(event)),
|
||||
// No approval event found, construct a request event
|
||||
|
||||
@@ -84,8 +84,20 @@ impl Screening {
|
||||
|
||||
let task: Task<Result<bool, Error>> = cx.background_spawn(async move {
|
||||
// Check if user is in contact list
|
||||
let contacts = client.database().contacts_public_keys(current_user).await;
|
||||
let followed = contacts.unwrap_or_default().contains(&public_key);
|
||||
let filter = Filter::new()
|
||||
.author(current_user)
|
||||
.kind(Kind::ContactList)
|
||||
.limit(1);
|
||||
|
||||
let followed = client
|
||||
.database()
|
||||
.query(filter)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|event| event.tags.public_keys().any(|k| k == public_key))
|
||||
.unwrap_or(false);
|
||||
|
||||
Ok(followed)
|
||||
});
|
||||
@@ -228,11 +240,10 @@ impl Screening {
|
||||
let public_key = self.public_key;
|
||||
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
let tag = Nip56Tag::PublicKey {
|
||||
let tag = Tag::from(Nip56Tag::PublicKey {
|
||||
public_key,
|
||||
report: Report::Impersonation,
|
||||
}
|
||||
.to_tag();
|
||||
});
|
||||
|
||||
let event = EventBuilder::new(Kind::Reporting, "")
|
||||
.tag(tag)
|
||||
|
||||
@@ -88,7 +88,20 @@ impl ContactListPanel {
|
||||
};
|
||||
|
||||
let task: Task<Result<HashSet<PublicKey>, Error>> = cx.background_spawn(async move {
|
||||
let contact_list = client.database().contacts_public_keys(public_key).await?;
|
||||
let filter = Filter::new()
|
||||
.author(public_key)
|
||||
.kind(Kind::ContactList)
|
||||
.limit(1);
|
||||
|
||||
let contact_list: HashSet<PublicKey> = client
|
||||
.database()
|
||||
.query(filter)
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|event| event.tags.public_keys().collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(contact_list)
|
||||
});
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ impl MessagingRelayPanel {
|
||||
.author(public_key)
|
||||
.limit(1);
|
||||
|
||||
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
||||
if let Some(event) = client.database().query(filter).await?.into_iter().next() {
|
||||
Ok(nip17::extract_relay_list(&event).collect())
|
||||
} else {
|
||||
Err(anyhow!("Not found."))
|
||||
@@ -177,7 +177,7 @@ impl MessagingRelayPanel {
|
||||
let tags: Vec<Tag> = self
|
||||
.relays
|
||||
.iter()
|
||||
.map(|relay| Nip17Tag::Relay(relay.to_owned()).to_tag())
|
||||
.map(|relay| Tag::from(Nip17Tag::Relay(relay.to_owned())))
|
||||
.collect();
|
||||
|
||||
// Set updating state
|
||||
|
||||
@@ -111,7 +111,7 @@ impl RelayListPanel {
|
||||
.author(public_key)
|
||||
.limit(1);
|
||||
|
||||
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
||||
if let Some(event) = client.database().query(filter).await?.into_iter().next() {
|
||||
Ok(nip65::extract_relay_list(&event).collect())
|
||||
} else {
|
||||
Err(anyhow!("Not found."))
|
||||
|
||||
@@ -158,7 +158,20 @@ impl Sidebar {
|
||||
};
|
||||
|
||||
let task: Task<Result<HashSet<PublicKey>, Error>> = cx.background_spawn(async move {
|
||||
let contacts = client.database().contacts_public_keys(public_key).await?;
|
||||
let filter = Filter::new()
|
||||
.author(public_key)
|
||||
.kind(Kind::ContactList)
|
||||
.limit(1);
|
||||
|
||||
let contacts: HashSet<PublicKey> = client
|
||||
.database()
|
||||
.query(filter)
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|event| event.tags.public_keys().collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(contacts)
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ product-name = "Coop"
|
||||
description = "Chat Freely, Stay Private on Nostr"
|
||||
identifier = "su.reya.coop"
|
||||
category = "SocialNetworking"
|
||||
version = "1.0.0-beta5"
|
||||
version = "1.0.0"
|
||||
out-dir = "../dist"
|
||||
before-packaging-command = "cargo build --release"
|
||||
resources = ["Cargo.toml", "src"]
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
[package]
|
||||
name = "coop"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[[bin]]
|
||||
name = "coop"
|
||||
path = "src/main.rs"
|
||||
|
||||
[package.metadata.packager]
|
||||
name = "Coop"
|
||||
product-name = "Coop"
|
||||
description = "Chat Freely, Stay Private on Nostr"
|
||||
identifier = "su.reya.coop"
|
||||
category = "SocialNetworking"
|
||||
version = "1.0.0-beta5"
|
||||
out-dir = "../dist"
|
||||
before-packaging-command = "cargo build --release"
|
||||
resources = ["Cargo.toml", "src"]
|
||||
icons = [
|
||||
"resources/32x32.png",
|
||||
"resources/128x128.png",
|
||||
"resources/128x128@2x.png",
|
||||
"resources/icon.icns",
|
||||
"resources/icon.ico",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
assets = { path = "../crates/assets" }
|
||||
workspace = { path = "../crates/workspace" }
|
||||
ui = { path = "../crates/ui" }
|
||||
theme = { path = "../crates/theme" }
|
||||
common = { path = "../crates/common" }
|
||||
state = { path = "../crates/state" }
|
||||
device = { path = "../crates/device" }
|
||||
chat = { path = "../crates/chat" }
|
||||
settings = { path = "../crates/settings" }
|
||||
auto_update = { path = "../crates/auto_update" }
|
||||
person = { path = "../crates/person" }
|
||||
|
||||
gpui.workspace = true
|
||||
gpui_platform.workspace = true
|
||||
gpui_linux.workspace = true
|
||||
gpui_windows.workspace = true
|
||||
gpui_macos.workspace = true
|
||||
reqwest_client.workspace = true
|
||||
|
||||
log.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
nostr-sdk.workspace = true
|
||||
+4
-4
@@ -55,8 +55,8 @@ flatpak run --command=flatpak-builder-lint org.flatpak.Builder repo repo
|
||||
|
||||
Ensure you have:
|
||||
- [ ] Committed all changes
|
||||
- [ ] Tagged the release: `git tag -a v1.0.0-beta2 -m "Release v1.0.0-beta2"`
|
||||
- [ ] Pushed the tag: `git push origin v1.0.0-beta2`
|
||||
- [ ] Tagged the release: `git tag -a v1.0.0 -m "Release v1.0.0"`
|
||||
- [ ] Pushed the tag: `git push origin v1.0.0`
|
||||
- [ ] Run `./script/prepare-flathub.sh` to regenerate files
|
||||
|
||||
### 2. Fork and Submit
|
||||
@@ -101,8 +101,8 @@ git push origin su.reya.coop
|
||||
To release a new version:
|
||||
|
||||
1. Update version in workspace `Cargo.toml`
|
||||
2. Tag the new release: `git tag -a v1.0.0-beta3 -m "Release v1.0.0-beta3"`
|
||||
3. Push the tag: `git push origin v1.0.0-beta3`
|
||||
2. Tag the new release: `git tag -a v1.0.0 -m "Release v1.0.0"`
|
||||
3. Push the tag: `git push origin v1.0.0`
|
||||
4. Run `./script/prepare-flathub.sh` to regenerate
|
||||
5. Clone the flathub repo: `git clone https://github.com/flathub/su.reya.coop.git`
|
||||
6. Update the manifest with new commit/tag and hashes
|
||||
|
||||
Reference in New Issue
Block a user