feat: add seen-on-relays viewer per message (#149)
* chore: bump version * add seen on * seen on menu
This commit is contained in:
76
Cargo.lock
generated
76
Cargo.lock
generated
@@ -190,7 +190,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assets"
|
name = "assets"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"gpui",
|
"gpui",
|
||||||
@@ -428,7 +428,7 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "auto_update"
|
name = "auto_update"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo-packager-updater",
|
"cargo-packager-updater",
|
||||||
@@ -1029,7 +1029,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "client_keys"
|
name = "client_keys"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"global",
|
"global",
|
||||||
@@ -1131,7 +1131,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collections"
|
name = "collections"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"rustc-hash 2.1.1",
|
"rustc-hash 2.1.1",
|
||||||
@@ -1166,7 +1166,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "common"
|
name = "common"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -1239,7 +1239,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coop"
|
name = "coop"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"assets",
|
"assets",
|
||||||
@@ -1572,7 +1572,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_refineable"
|
name = "derive_refineable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2405,7 +2405,7 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "global"
|
name = "global"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"dirs 5.0.1",
|
"dirs 5.0.1",
|
||||||
@@ -2498,7 +2498,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gpui"
|
name = "gpui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"as-raw-xcb-connection",
|
"as-raw-xcb-connection",
|
||||||
@@ -2592,7 +2592,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gpui_macros"
|
name = "gpui_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -2604,7 +2604,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gpui_tokio"
|
name = "gpui_tokio"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"gpui",
|
"gpui",
|
||||||
@@ -2818,7 +2818,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "http_client"
|
name = "http_client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -2838,7 +2838,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "http_client_tls"
|
name = "http_client_tls"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-platform-verifier",
|
"rustls-platform-verifier",
|
||||||
@@ -2941,7 +2941,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "i18n"
|
name = "i18n"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rust-i18n",
|
"rust-i18n",
|
||||||
]
|
]
|
||||||
@@ -3629,7 +3629,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "media"
|
name = "media"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bindgen 0.71.1",
|
"bindgen 0.71.1",
|
||||||
@@ -5069,7 +5069,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "refineable"
|
name = "refineable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derive_refineable",
|
"derive_refineable",
|
||||||
"workspace-hack",
|
"workspace-hack",
|
||||||
@@ -5106,7 +5106,7 @@ checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "registry"
|
name = "registry"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"common",
|
"common",
|
||||||
@@ -5223,7 +5223,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest_client"
|
name = "reqwest_client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -5758,7 +5758,7 @@ checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "semantic_version"
|
name = "semantic_version"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -5773,18 +5773,28 @@ checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.219"
|
version = "1.0.221"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
checksum = "341877e04a22458705eb4e131a1508483c877dca2792b3781d4e5d8a6019ec43"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.221"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c459bc0a14c840cb403fc14b148620de1e0778c96ecd6e0c8c3cacb6d8d00fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.219"
|
version = "1.0.221"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
checksum = "d6185cf75117e20e62b1ff867b9518577271e58abe0037c40bb4794969355ab0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -5813,15 +5823,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.143"
|
version = "1.0.144"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
|
checksum = "56177480b00303e689183f110b4e727bb4211d692c62d4fcd16d02be93077d40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5893,7 +5903,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "settings"
|
name = "settings"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"global",
|
"global",
|
||||||
@@ -5960,7 +5970,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signer_proxy"
|
name = "signer_proxy"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"atomic-destructor",
|
"atomic-destructor",
|
||||||
@@ -6199,7 +6209,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "sum_tree"
|
name = "sum_tree"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"log",
|
"log",
|
||||||
@@ -6502,7 +6512,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "theme"
|
name = "theme"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"gpui",
|
"gpui",
|
||||||
@@ -6664,7 +6674,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "title_bar"
|
name = "title_bar"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"common",
|
"common",
|
||||||
@@ -7035,7 +7045,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ui"
|
name = "ui"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"common",
|
"common",
|
||||||
@@ -7229,7 +7239,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "util"
|
name = "util"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/zed-industries/zed#ded646760467d653fd57ee3ef4fc1edcfafba6ae"
|
source = "git+https://github.com/zed-industries/zed#c50b561e1c826e707e0d89bd7d82373c27f2fe32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-fs",
|
"async-fs",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ members = ["crates/*"]
|
|||||||
default-members = ["crates/coop"]
|
default-members = ["crates/coop"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
|||||||
4
assets/icons/server.svg
Normal file
4
assets/icons/server.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
|
||||||
|
<path stroke="currentColor" stroke-linecap="square" stroke-linejoin="round" stroke-width="1.5" d="M21.25 12V6.75a2 2 0 0 0-2-2H4.75a2 2 0 0 0-2 2V12m18.5 0H2.75m18.5 0v5.25a2 2 0 0 1-2 2H4.75a2 2 0 0 1-2-2V12"/>
|
||||||
|
<path fill="currentColor" stroke="currentColor" stroke-width=".5" d="M6.5 14.875a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5Zm0-7.25a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 486 B |
@@ -14,7 +14,7 @@ product-name = "Coop"
|
|||||||
description = "Chat Freely, Stay Private on Nostr"
|
description = "Chat Freely, Stay Private on Nostr"
|
||||||
identifier = "su.reya.coop"
|
identifier = "su.reya.coop"
|
||||||
category = "SocialNetworking"
|
category = "SocialNetworking"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
out-dir = "../../dist"
|
out-dir = "../../dist"
|
||||||
before-packaging-command = "cargo build --release"
|
before-packaging-command = "cargo build --release"
|
||||||
resources = ["Cargo.toml", "src"]
|
resources = ["Cargo.toml", "src"]
|
||||||
|
|||||||
@@ -382,6 +382,14 @@ impl ChatSpace {
|
|||||||
|
|
||||||
match message {
|
match message {
|
||||||
RelayMessage::Event { event, .. } => {
|
RelayMessage::Event { event, .. } => {
|
||||||
|
// Keep track of which relays have seen this event
|
||||||
|
css.seen_on_relays
|
||||||
|
.write()
|
||||||
|
.await
|
||||||
|
.entry(event.id)
|
||||||
|
.or_insert_with(HashSet::new)
|
||||||
|
.insert(relay_url);
|
||||||
|
|
||||||
// Skip events that have already been processed
|
// Skip events that have already been processed
|
||||||
if !processed_events.insert(event.id) {
|
if !processed_events.insert(event.id) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use ui::dock_area::panel::{Panel, PanelEvent};
|
|||||||
use ui::emoji_picker::EmojiPicker;
|
use ui::emoji_picker::EmojiPicker;
|
||||||
use ui::input::{InputEvent, InputState, TextInput};
|
use ui::input::{InputEvent, InputState, TextInput};
|
||||||
use ui::modal::ModalButtonProps;
|
use ui::modal::ModalButtonProps;
|
||||||
use ui::popup_menu::PopupMenu;
|
use ui::popup_menu::{PopupMenu, PopupMenuExt};
|
||||||
use ui::text::RenderedText;
|
use ui::text::RenderedText;
|
||||||
use ui::{
|
use ui::{
|
||||||
h_flex, v_flex, ContextModal, Disableable, Icon, IconName, InteractiveElementExt, Sizable,
|
h_flex, v_flex, ContextModal, Disableable, Icon, IconName, InteractiveElementExt, Sizable,
|
||||||
@@ -40,7 +40,7 @@ mod subject;
|
|||||||
|
|
||||||
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
||||||
#[action(namespace = chat, no_json)]
|
#[action(namespace = chat, no_json)]
|
||||||
pub struct ChangeSubject(pub String);
|
pub struct SeenOn(pub EventId);
|
||||||
|
|
||||||
pub fn init(room: Entity<Room>, window: &mut Window, cx: &mut App) -> Entity<Chat> {
|
pub fn init(room: Entity<Room>, window: &mut Window, cx: &mut App) -> Entity<Chat> {
|
||||||
cx.new(|cx| Chat::new(room, window, cx))
|
cx.new(|cx| Chat::new(room, window, cx))
|
||||||
@@ -920,30 +920,44 @@ impl Chat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_actions(&self, id: &EventId, cx: &Context<Self>) -> impl IntoElement {
|
fn render_actions(&self, id: &EventId, cx: &Context<Self>) -> impl IntoElement {
|
||||||
let groups = vec![
|
let reply = Button::new("reply")
|
||||||
Button::new("reply")
|
.icon(IconName::Reply)
|
||||||
.icon(IconName::Reply)
|
.tooltip(t!("chat.reply_button"))
|
||||||
.tooltip(t!("chat.reply_button"))
|
.small()
|
||||||
.small()
|
.ghost()
|
||||||
.ghost()
|
.on_click({
|
||||||
.on_click({
|
let id = id.to_owned();
|
||||||
let id = id.to_owned();
|
cx.listener(move |this, _event, _window, cx| {
|
||||||
cx.listener(move |this, _event, _window, cx| {
|
this.reply_to(&id, cx);
|
||||||
this.reply_to(&id, cx);
|
})
|
||||||
})
|
})
|
||||||
}),
|
.into_any_element();
|
||||||
Button::new("copy")
|
|
||||||
.icon(IconName::Copy)
|
let copy = Button::new("copy")
|
||||||
.tooltip(t!("chat.copy_message_button"))
|
.icon(IconName::Copy)
|
||||||
.small()
|
.tooltip(t!("chat.copy_message_button"))
|
||||||
.ghost()
|
.small()
|
||||||
.on_click({
|
.ghost()
|
||||||
let id = id.to_owned();
|
.on_click({
|
||||||
cx.listener(move |this, _event, _window, cx| {
|
let id = id.to_owned();
|
||||||
this.copy_message(&id, cx);
|
cx.listener(move |this, _event, _window, cx| {
|
||||||
})
|
this.copy_message(&id, cx);
|
||||||
}),
|
})
|
||||||
];
|
})
|
||||||
|
.into_any_element();
|
||||||
|
|
||||||
|
let more = Button::new("seen-on")
|
||||||
|
.icon(IconName::Ellipsis)
|
||||||
|
.small()
|
||||||
|
.ghost()
|
||||||
|
.popup_menu({
|
||||||
|
let id = id.to_owned();
|
||||||
|
move |this, _window, _cx| {
|
||||||
|
// TODO: add more actions
|
||||||
|
this.menu(t!("common.seen_on"), Box::new(SeenOn(id)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into_any_element();
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.p_0p5()
|
.p_0p5()
|
||||||
@@ -957,7 +971,7 @@ impl Chat {
|
|||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.bg(cx.theme().background)
|
.bg(cx.theme().background)
|
||||||
.children(groups)
|
.children(vec![reply, copy, more])
|
||||||
.group_hover("", |this| this.visible())
|
.group_hover("", |this| this.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1133,6 +1147,62 @@ impl Chat {
|
|||||||
.ok();
|
.ok();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_open_seen_on(&mut self, ev: &SeenOn, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
let id = ev.0;
|
||||||
|
|
||||||
|
let task: Task<Result<Vec<RelayUrl>, Error>> = cx.background_spawn(async move {
|
||||||
|
let client = nostr_client();
|
||||||
|
let css = css();
|
||||||
|
let mut relays: Vec<RelayUrl> = vec![];
|
||||||
|
|
||||||
|
let filter = Filter::new()
|
||||||
|
.kind(Kind::ApplicationSpecificData)
|
||||||
|
.event(id)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
||||||
|
if let Some(Ok(id)) = event.tags.identifier().map(EventId::parse) {
|
||||||
|
if let Some(urls) = css.seen_on_relays.read().await.get(&id).cloned() {
|
||||||
|
relays.extend(urls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(relays)
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.spawn_in(window, async move |_, cx| {
|
||||||
|
if let Ok(urls) = task.await {
|
||||||
|
cx.update(|window, cx| {
|
||||||
|
window.open_modal(cx, move |this, _window, cx| {
|
||||||
|
this.title(shared_t!("common.seen_on")).child(
|
||||||
|
v_flex().pb_4().gap_2().children({
|
||||||
|
let mut items = Vec::with_capacity(urls.len());
|
||||||
|
|
||||||
|
for url in urls.clone().into_iter() {
|
||||||
|
items.push(
|
||||||
|
h_flex()
|
||||||
|
.h_8()
|
||||||
|
.px_2()
|
||||||
|
.bg(cx.theme().elevated_surface_background)
|
||||||
|
.rounded(cx.theme().radius)
|
||||||
|
.font_semibold()
|
||||||
|
.text_xs()
|
||||||
|
.child(url.to_string()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Panel for Chat {
|
impl Panel for Chat {
|
||||||
@@ -1179,6 +1249,7 @@ impl Focusable for Chat {
|
|||||||
impl Render for Chat {
|
impl Render for Chat {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
v_flex()
|
v_flex()
|
||||||
|
.on_action(cx.listener(Self::on_open_seen_on))
|
||||||
.image_cache(self.image_cache.clone())
|
.image_cache(self.image_cache.clone())
|
||||||
.size_full()
|
.size_full()
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
@@ -115,13 +115,15 @@ impl Ingester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A simple storage to store all runtime states that using across the application.
|
/// A simple storage to store all states that using across the application.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CoopSimpleStorage {
|
pub struct CoopSimpleStorage {
|
||||||
pub init_at: Timestamp,
|
pub init_at: Timestamp,
|
||||||
|
pub last_used_at: Option<Timestamp>,
|
||||||
pub gift_wrap_sub_id: SubscriptionId,
|
pub gift_wrap_sub_id: SubscriptionId,
|
||||||
pub gift_wrap_processing: AtomicBool,
|
pub gift_wrap_processing: AtomicBool,
|
||||||
pub auto_close_opts: Option<SubscribeAutoCloseOptions>,
|
pub auto_close_opts: Option<SubscribeAutoCloseOptions>,
|
||||||
|
pub seen_on_relays: RwLock<HashMap<EventId, HashSet<RelayUrl>>>,
|
||||||
pub sent_ids: RwLock<HashSet<EventId>>,
|
pub sent_ids: RwLock<HashSet<EventId>>,
|
||||||
pub resent_ids: RwLock<Vec<Output<EventId>>>,
|
pub resent_ids: RwLock<Vec<Output<EventId>>>,
|
||||||
pub resend_queue: RwLock<HashMap<EventId, RelayUrl>>,
|
pub resend_queue: RwLock<HashMap<EventId, RelayUrl>>,
|
||||||
@@ -137,11 +139,13 @@ impl CoopSimpleStorage {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
init_at: Timestamp::now(),
|
init_at: Timestamp::now(),
|
||||||
|
last_used_at: None,
|
||||||
gift_wrap_sub_id: SubscriptionId::new("inbox"),
|
gift_wrap_sub_id: SubscriptionId::new("inbox"),
|
||||||
gift_wrap_processing: AtomicBool::new(false),
|
gift_wrap_processing: AtomicBool::new(false),
|
||||||
auto_close_opts: Some(
|
auto_close_opts: Some(
|
||||||
SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE),
|
SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE),
|
||||||
),
|
),
|
||||||
|
seen_on_relays: RwLock::new(HashMap::new()),
|
||||||
sent_ids: RwLock::new(HashSet::new()),
|
sent_ids: RwLock::new(HashSet::new()),
|
||||||
resent_ids: RwLock::new(Vec::new()),
|
resent_ids: RwLock::new(Vec::new()),
|
||||||
resend_queue: RwLock::new(HashMap::new()),
|
resend_queue: RwLock::new(HashMap::new()),
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ pub enum IconName {
|
|||||||
Signal,
|
Signal,
|
||||||
Search,
|
Search,
|
||||||
Settings,
|
Settings,
|
||||||
|
Server,
|
||||||
SortAscending,
|
SortAscending,
|
||||||
SortDescending,
|
SortDescending,
|
||||||
Sun,
|
Sun,
|
||||||
@@ -112,6 +113,7 @@ impl IconName {
|
|||||||
Self::Signal => "icons/signal.svg",
|
Self::Signal => "icons/signal.svg",
|
||||||
Self::Search => "icons/search.svg",
|
Self::Search => "icons/search.svg",
|
||||||
Self::Settings => "icons/settings.svg",
|
Self::Settings => "icons/settings.svg",
|
||||||
|
Self::Server => "icons/server.svg",
|
||||||
Self::SortAscending => "icons/sort-ascending.svg",
|
Self::SortAscending => "icons/sort-ascending.svg",
|
||||||
Self::SortDescending => "icons/sort-descending.svg",
|
Self::SortDescending => "icons/sort-descending.svg",
|
||||||
Self::Sun => "icons/sun.svg",
|
Self::Sun => "icons/sun.svg",
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ common:
|
|||||||
en: "Recommended:"
|
en: "Recommended:"
|
||||||
resend:
|
resend:
|
||||||
en: "Resend"
|
en: "Resend"
|
||||||
|
seen_on:
|
||||||
|
en: "Seen on"
|
||||||
|
|
||||||
auto_update:
|
auto_update:
|
||||||
updating:
|
updating:
|
||||||
|
|||||||
Reference in New Issue
Block a user