fix: chat input crashing when moving the cursor (#33)

Reviewed-on: #33
This commit was merged in pull request #33.
This commit is contained in:
2026-06-03 13:18:03 +00:00
parent 5d4c8634ef
commit c78e0a5163
42 changed files with 7175 additions and 1593 deletions

View File

@@ -11,7 +11,7 @@ use smallvec::{SmallVec, smallvec};
use state::{CoopAuthUrlHandler, NostrRegistry, StateEvent};
use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants};
use ui::input::{InputEvent, InputState, TextInput};
use ui::input::{Input, InputEvent, InputState};
use ui::{Disableable, v_flex};
#[derive(Debug)]
@@ -250,7 +250,7 @@ impl Render for ImportKey {
.text_sm()
.text_color(cx.theme().text_muted)
.child("nsec or bunker://")
.child(TextInput::new(&self.key_input)),
.child(Input::new(&self.key_input)),
)
.when(
self.key_input.read(cx).value().starts_with("ncryptsec1"),
@@ -261,7 +261,7 @@ impl Render for ImportKey {
.text_sm()
.text_color(cx.theme().text_muted)
.child("Password:")
.child(TextInput::new(&self.pass_input)),
.child(Input::new(&self.pass_input)),
)
},
)

View File

@@ -10,7 +10,7 @@ use gpui::{
use nostr_connect::prelude::*;
use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants};
use ui::input::{InputEvent, InputState, TextInput};
use ui::input::{Input, InputEvent, InputState};
use ui::{WindowExtension, v_flex};
#[derive(Debug)]
@@ -107,7 +107,7 @@ impl Render for RestoreEncryption {
.text_sm()
.text_color(cx.theme().text_muted)
.child("Secret Key")
.child(TextInput::new(&self.key_input)),
.child(Input::new(&self.key_input)),
)
.child(
Button::new("restore")

View File

@@ -7,7 +7,7 @@ use settings::{AppSettings, AuthMode};
use theme::{ActiveTheme, Theme, ThemeMode};
use ui::button::{Button, ButtonVariants};
use ui::group_box::{GroupBox, GroupBoxVariants};
use ui::input::{InputState, TextInput};
use ui::input::{Input, InputState};
use ui::menu::{DropdownMenu, PopupMenuItem};
use ui::notification::Notification;
use ui::switch::Switch;
@@ -218,7 +218,7 @@ impl Render for Preferences {
.child(
h_flex()
.gap_1()
.child(TextInput::new(&self.file_input).text_xs().small())
.child(Input::new(&self.file_input).text_xs().small())
.child(
Button::new("update-file-server")
.icon(IconName::Check)

View File

@@ -10,7 +10,7 @@ use state::KEYRING;
use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::input::{InputState, TextInput};
use ui::input::{Input, InputState};
use ui::{IconName, Sizable, StyledExt, divider, v_flex};
const MSG: &str = "Store your account keys in a safe location. \
@@ -40,8 +40,8 @@ pub struct BackupPanel {
impl BackupPanel {
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
let npub_input = cx.new(|cx| InputState::new(window, cx).disabled(true));
let nsec_input = cx.new(|cx| InputState::new(window, cx).disabled(true).masked(true));
let npub_input = cx.new(|cx| InputState::new(window, cx));
let nsec_input = cx.new(|cx| InputState::new(window, cx).masked(true));
// Run at the end of current cycle
cx.defer_in(window, |this, window, cx| {
@@ -156,7 +156,7 @@ impl Render for BackupPanel {
.child(SharedString::from("Public Key:")),
)
.child(
TextInput::new(&self.npub_input)
Input::new(&self.npub_input)
.small()
.bordered(false)
.disabled(true),
@@ -174,7 +174,7 @@ impl Render for BackupPanel {
.child(SharedString::from("Secret Key:")),
)
.child(
TextInput::new(&self.nsec_input)
Input::new(&self.nsec_input)
.small()
.bordered(false)
.disabled(true),

View File

@@ -16,7 +16,7 @@ use theme::ActiveTheme;
use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::input::{InputEvent, InputState, TextInput};
use ui::input::{Input, InputEvent, InputState};
use ui::{Disableable, IconName, Sizable, StyledExt, WindowExtension, h_flex, v_flex};
pub fn init(window: &mut Window, cx: &mut App) -> Entity<ContactListPanel> {
@@ -301,10 +301,10 @@ impl Render for ContactListPanel {
.gap_1()
.w_full()
.child(
TextInput::new(&self.input)
Input::new(&self.input)
.small()
.bordered(false)
.cleanable(),
.cleanable(true),
)
.child(
Button::new("add")

View File

@@ -14,7 +14,7 @@ use state::NostrRegistry;
use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::input::{InputEvent, InputState, TextInput};
use ui::input::{Input, InputEvent, InputState};
use ui::{Disableable, IconName, Sizable, StyledExt, WindowExtension, divider, h_flex, v_flex};
const MSG: &str = "Messaging Relays are relays that hosted all your messages. \
@@ -317,10 +317,10 @@ impl Render for MessagingRelayPanel {
.gap_1()
.w_full()
.child(
TextInput::new(&self.input)
Input::new(&self.input)
.small()
.bordered(false)
.cleanable(),
.cleanable(true),
)
.child(
Button::new("add")

View File

@@ -15,7 +15,7 @@ use theme::ActiveTheme;
use ui::avatar::Avatar;
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::input::{InputState, TextInput};
use ui::input::{Input, InputState};
use ui::notification::Notification;
use ui::{Disableable, IconName, Sizable, StyledExt, WindowExtension, h_flex, v_flex};
@@ -65,7 +65,7 @@ impl ProfilePanel {
// Use multi-line input for bio
let bio_input = cx.new(|cx| {
InputState::new(window, cx)
.multi_line()
.multi_line(true)
.auto_grow(3, 8)
.placeholder("A short introduce about you.")
});
@@ -352,7 +352,7 @@ impl Render for ProfilePanel {
.text_color(cx.theme().text_muted)
.child(SharedString::from("What should people call you?")),
)
.child(TextInput::new(&self.name_input).bordered(false).small()),
.child(Input::new(&self.name_input).bordered(false).small()),
)
.child(
v_flex()
@@ -363,7 +363,7 @@ impl Render for ProfilePanel {
.text_color(cx.theme().text_muted)
.child(SharedString::from("A short introduction about you:")),
)
.child(TextInput::new(&self.bio_input).bordered(false).small()),
.child(Input::new(&self.bio_input).bordered(false).small()),
)
.child(
v_flex()
@@ -374,7 +374,7 @@ impl Render for ProfilePanel {
.text_color(cx.theme().text_muted)
.child(SharedString::from("Website:")),
)
.child(TextInput::new(&self.website_input).bordered(false).small()),
.child(Input::new(&self.website_input).bordered(false).small()),
)
.child(
v_flex()

View File

@@ -15,7 +15,7 @@ use state::NostrRegistry;
use theme::ActiveTheme;
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::input::{InputEvent, InputState, TextInput};
use ui::input::{Input, InputEvent, InputState};
use ui::menu::DropdownMenu;
use ui::{Disableable, IconName, Sizable, StyledExt, WindowExtension, divider, h_flex, v_flex};
@@ -369,10 +369,10 @@ impl Render for RelayListPanel {
.gap_1()
.w_full()
.child(
TextInput::new(&self.input)
Input::new(&self.input)
.small()
.bordered(false)
.cleanable(),
.cleanable(true),
)
.child(
Button::new("metadata")

View File

@@ -20,7 +20,7 @@ use theme::{ActiveTheme, SIDEBAR_WIDTH, TABBAR_HEIGHT};
use ui::button::{Button, ButtonVariants};
use ui::dock::{Panel, PanelEvent};
use ui::indicator::Indicator;
use ui::input::{InputEvent, InputState, TextInput};
use ui::input::{Input, InputEvent, InputState};
use ui::notification::Notification;
use ui::scroll::Scrollbar;
use ui::{Icon, IconName, Selectable, Sizable, StyledExt, WindowExtension, h_flex, v_flex};
@@ -252,7 +252,6 @@ impl Sidebar {
fn set_finding(&mut self, status: bool, _window: &mut Window, cx: &mut Context<Self>) {
// Disable the input to prevent duplicate requests
self.find_input.update(cx, |this, cx| {
this.set_disabled(status, cx);
this.set_loading(status, cx);
});
// Set the search status
@@ -513,7 +512,7 @@ impl Render for Sidebar {
.border_color(cx.theme().border)
.bg(cx.theme().tab_background)
.child(
TextInput::new(&self.find_input)
Input::new(&self.find_input)
.appearance(false)
.bordered(false)
.small()