chore: improve web support (#36)

Reviewed-on: https://git.reya.su/reya/coop/pulls/36
This commit was merged in pull request #36.
This commit is contained in:
2026-07-30 08:47:30 +00:00
parent b518c729f6
commit 6d9284b37a
86 changed files with 1537 additions and 5215 deletions
+35 -33
View File
@@ -1,11 +1,10 @@
use std::time::Duration;
use anyhow::{Error, anyhow};
use gpui::prelude::FluentBuilder;
use gpui::{
AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
Subscription, Task, Window, div,
};
use instant::Duration;
use nostr_connect::prelude::*;
use state::{CoopAuthUrlHandler, NostrRegistry, USER_KEYRING};
use theme::ActiveTheme;
@@ -36,7 +35,7 @@ pub struct ImportIdentity {
impl ImportIdentity {
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let key_input = cx.new(|cx| InputState::new(window, cx));
let key_input = cx.new(|cx| InputState::new(window, cx).placeholder("nsec or bunker://"));
let pass_input = cx.new(|cx| InputState::new(window, cx).masked(true));
let error = cx.new(|_| None);
@@ -135,7 +134,6 @@ impl ImportIdentity {
})?;
}
}
Ok(())
}));
}
@@ -146,7 +144,7 @@ impl ImportIdentity {
let password = uri.to_string();
let save = cx.write_credentials(USER_KEYRING, "bunker", password.as_bytes());
cx.spawn_in(window, async move |_this, cx| {
self.tasks.push(cx.spawn_in(window, async move |_this, cx| {
let keys = master_keys.await;
let timeout = Duration::from_secs(30);
@@ -162,9 +160,8 @@ impl ImportIdentity {
cx.notify();
});
Ok::<(), anyhow::Error>(())
})
.detach();
Ok(())
}));
}
fn set_loading(&mut self, status: bool, cx: &mut Context<Self>) {
@@ -209,40 +206,45 @@ impl Render for ImportIdentity {
v_flex()
.size_full()
.gap_2()
.gap_4()
.text_sm()
.child(
v_flex()
.gap_1()
.text_color(cx.theme().text_muted)
.child("Continue with existing key or bunker connection")
.child(Input::new(&self.key_input)),
.gap_2()
.child(
v_flex()
.gap_1()
.text_color(cx.theme().text_muted)
.child("Continue with existing key or bunker connection")
.child(Input::new(&self.key_input)),
)
.when(require_password, |this| {
this.child(
v_flex()
.gap_1()
.text_color(cx.theme().text_muted)
.child("Decrypt Password:")
.child(Input::new(&self.pass_input)),
)
})
.when(key_warning, |this| {
this.child(
div()
.text_xs()
.text_color(cx.theme().text_warning)
.child(div().font_semibold().child("Warning"))
.child(div().child(MSG)),
)
}),
)
.when(require_password, |this| {
this.child(
v_flex()
.gap_1()
.text_color(cx.theme().text_muted)
.child("Decrypt Password:")
.child(Input::new(&self.pass_input)),
)
})
.when(key_warning, |this| {
this.child(
div()
.v_flex()
.text_xs()
.text_color(cx.theme().text_warning)
.child(div().font_semibold().child("Warning"))
.child(div().child(MSG)),
)
})
.child(
Button::new("login")
.label("Continue")
.primary()
.font_semibold()
.loading(self.loading)
.disabled(self.loading)
.on_click(cx.listener(move |this, _, window, cx| {
.on_click(cx.listener(move |this, _ev, window, cx| {
this.login(window, cx);
})),
)
+1 -1
View File
@@ -1,4 +1,4 @@
use std::time::Duration;
use instant::Duration;
use anyhow::Error;
use device::DeviceRegistry;
+4 -3
View File
@@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::time::Duration;
use anyhow::Error;
use common::TimestampExt;
@@ -8,6 +7,7 @@ use gpui::{
App, AppContext, Context, Div, Entity, InteractiveElement, IntoElement, ParentElement, Render,
SharedString, Styled, Subscription, Task, Window, div, px, relative, uniform_list,
};
use instant::Duration;
use nostr_sdk::prelude::*;
use person::{Person, PersonRegistry, shorten_pubkey};
use smallvec::{SmallVec, smallvec};
@@ -55,7 +55,7 @@ impl Screening {
window.close_all_modals(cx);
}));
cx.defer_in(window, move |this, _window, cx| {
cx.defer_in(window, |this, _window, cx| {
this.check_contact(cx);
this.check_wot(cx);
this.check_last_activity(cx);
@@ -234,7 +234,8 @@ impl Screening {
}
.to_tag();
let event = EventBuilder::report(vec![tag], "")
let event = EventBuilder::new(Kind::Reporting, "")
.tag(tag)
.finalize_async(&signer)
.await?;
+1 -49
View File
@@ -3,7 +3,7 @@ use gpui::{
App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
Window, div, px,
};
use settings::{AppSettings, AuthMode};
use settings::AppSettings;
use theme::{ActiveTheme, Theme, ThemeMode};
use ui::button::{Button, ButtonVariants};
use ui::group_box::{GroupBox, GroupBoxVariants};
@@ -60,13 +60,11 @@ impl Render for Preferences {
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
const MODE: &str = "Use the selected light or dark theme, or to follow the OS.";
const NIP4E: &str = "Use a dedicated key to encrypt and decrypt messages.";
const AUTH: &str = "Choose the authentication behavior for relays.";
const RESET: &str = "Reset the theme to the default one.";
let screening = AppSettings::get_screening(cx);
let hide_avatar = AppSettings::get_hide_avatar(cx);
let nip4e = AppSettings::get_nip4e(cx);
let auth_mode = AppSettings::get_auth_mode(cx);
let theme_mode = AppSettings::get_theme_mode(cx);
v_flex()
@@ -93,52 +91,6 @@ impl Render for Preferences {
.on_click(move |_, _window, cx| {
AppSettings::update_hide_avatar(!hide_avatar, cx);
}),
)
.child(
h_flex()
.gap_3()
.justify_between()
.child(
v_flex()
.child(
div()
.text_sm()
.child(SharedString::from("Relay authentication")),
)
.child(
div()
.text_xs()
.text_color(cx.theme().text_muted)
.child(SharedString::from(AUTH)),
),
)
.child(
Button::new("auth")
.label(auth_mode.to_string())
.ghost_alt()
.small()
.dropdown_menu(|this, _window, _cx| {
this.min_w(px(256.))
.item(
PopupMenuItem::new("Auto authentication").on_click(
|_ev, _window, cx| {
AppSettings::update_auth_mode(
AuthMode::Auto,
cx,
);
},
),
)
.item(PopupMenuItem::new("Ask every time").on_click(
|_ev, _window, cx| {
AppSettings::update_auth_mode(
AuthMode::Manual,
cx,
);
},
))
}),
),
),
)
.child(