feat: create repository #3

Merged
reya merged 2 commits from feat/create-repo into master 2026-08-26 13:51:48 +00:00
5 changed files with 180 additions and 61 deletions
Showing only changes of commit df8b8a9598 - Show all commits
Generated
+30 -29
View File
@@ -1259,7 +1259,7 @@ dependencies = [
[[package]] [[package]]
name = "collections" name = "collections"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"gpui_util", "gpui_util",
"indexmap", "indexmap",
@@ -1725,7 +1725,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#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3480,7 +3480,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui" name = "gpui"
version = "0.2.2" version = "0.2.2"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"anyhow", "anyhow",
@@ -3551,7 +3551,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui-base" name = "gpui-base"
version = "0.5.2" version = "0.5.2"
source = "git+https://github.com/longbridge/gpui-component#d5821f270317754f2a311a0bb148ec32cbb0ced4" source = "git+https://github.com/longbridge/gpui-component#ff3eb1128ac1058f1bb88e777744ce1237aa3b79"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"anyhow", "anyhow",
@@ -3583,7 +3583,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui-component" name = "gpui-component"
version = "0.5.2" version = "0.5.2"
source = "git+https://github.com/longbridge/gpui-component#d5821f270317754f2a311a0bb148ec32cbb0ced4" source = "git+https://github.com/longbridge/gpui-component#ff3eb1128ac1058f1bb88e777744ce1237aa3b79"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -3663,7 +3663,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui-component-assets" name = "gpui-component-assets"
version = "0.5.1" version = "0.5.1"
source = "git+https://github.com/longbridge/gpui-component#d5821f270317754f2a311a0bb148ec32cbb0ced4" source = "git+https://github.com/longbridge/gpui-component#ff3eb1128ac1058f1bb88e777744ce1237aa3b79"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"gpui", "gpui",
@@ -3677,7 +3677,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui-component-macros" name = "gpui-component-macros"
version = "0.5.1" version = "0.5.1"
source = "git+https://github.com/longbridge/gpui-component#d5821f270317754f2a311a0bb148ec32cbb0ced4" source = "git+https://github.com/longbridge/gpui-component#ff3eb1128ac1058f1bb88e777744ce1237aa3b79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3687,7 +3687,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_apple" name = "gpui_apple"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"block", "block",
@@ -3710,7 +3710,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_linux" name = "gpui_linux"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_unix", "accesskit_unix",
@@ -3756,7 +3756,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_macos" name = "gpui_macos"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_macos", "accesskit_macos",
@@ -3802,7 +3802,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#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
@@ -3813,7 +3813,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_platform" name = "gpui_platform"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"gpui", "gpui",
@@ -3826,7 +3826,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_shared_string" name = "gpui_shared_string"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"schemars", "schemars",
"serde", "serde",
@@ -3836,7 +3836,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_util" name = "gpui_util"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"log", "log",
@@ -3846,7 +3846,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_web" name = "gpui_web"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"console_error_panic_hook", "console_error_panic_hook",
@@ -3870,7 +3870,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_wgpu" name = "gpui_wgpu"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytemuck", "bytemuck",
@@ -3896,7 +3896,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_windows" name = "gpui_windows"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_windows", "accesskit_windows",
@@ -4209,7 +4209,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#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-compression", "async-compression",
@@ -4229,7 +4229,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#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"rustls", "rustls",
"rustls-platform-verifier 0.5.3", "rustls-platform-verifier 0.5.3",
@@ -5205,7 +5205,7 @@ dependencies = [
[[package]] [[package]]
name = "media" name = "media"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bindgen", "bindgen",
@@ -6243,7 +6243,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]] [[package]]
name = "perf" name = "perf"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"collections", "collections",
"serde", "serde",
@@ -7031,7 +7031,7 @@ dependencies = [
[[package]] [[package]]
name = "refineable" name = "refineable"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"derive_refineable", "derive_refineable",
] ]
@@ -7114,7 +7114,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#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -7526,7 +7526,7 @@ dependencies = [
[[package]] [[package]]
name = "scheduler" name = "scheduler"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"async-task", "async-task",
"backtrace", "backtrace",
@@ -8219,7 +8219,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#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"heapless 0.9.3", "heapless 0.9.3",
"log", "log",
@@ -9592,7 +9592,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]] [[package]]
name = "util_macros" name = "util_macros"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"perf", "perf",
"quote", "quote",
@@ -10877,6 +10877,7 @@ dependencies = [
"gpui-component", "gpui-component",
"log", "log",
"nostr", "nostr",
"paths",
"signed_core", "signed_core",
"signed_git", "signed_git",
"signed_state", "signed_state",
@@ -11390,7 +11391,7 @@ checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12"
[[package]] [[package]]
name = "zlog" name = "zlog"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -11407,7 +11408,7 @@ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
[[package]] [[package]]
name = "ztracing" name = "ztracing"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
dependencies = [ dependencies = [
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@@ -11418,7 +11419,7 @@ dependencies = [
[[package]] [[package]]
name = "ztracing_macro" name = "ztracing_macro"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#55007f518bc1d49e6b3291c5eaa1aabf649b36fd" source = "git+https://github.com/zed-industries/zed#fecc3273ed32643c2ea1b04a74c8780e2c9ffaf8"
[[package]] [[package]]
name = "zune-core" name = "zune-core"
+6
View File
@@ -35,6 +35,12 @@ pub fn home_dir() -> PathBuf {
dirs::home_dir().expect("failed to determine home directory") dirs::home_dir().expect("failed to determine home directory")
} }
/// Returns the current user's Desktop folder, falling back to the home
/// directory (or an empty path) when it can't be determined.
pub fn desktop_dir() -> PathBuf {
dirs::desktop_dir().unwrap_or_else(|| dirs::home_dir().unwrap_or_default())
}
/// Sets a custom directory for all user data, overriding the default data /// Sets a custom directory for all user data, overriding the default data
/// directory. Must be called before any other path operation. The directory /// directory. Must be called before any other path operation. The directory
/// is created if it doesn't exist and canonicalized to an absolute path. /// is created if it doesn't exist and canonicalized to an absolute path.
+1
View File
@@ -7,6 +7,7 @@ publish.workspace = true
[dependencies] [dependencies]
assets = { path = "../assets" } assets = { path = "../assets" }
dock = { workspace = true } dock = { workspace = true }
paths = { path = "../paths" }
signed_core = { path = "../signed_core" } signed_core = { path = "../signed_core" }
signed_git = { path = "../signed_git" } signed_git = { path = "../signed_git" }
signed_state = { path = "../signed_state" } signed_state = { path = "../signed_state" }
@@ -1,12 +1,11 @@
use dock::{DockArea, DockPlacement, panel_handle}; use dock::{DockArea, DockPlacement, panel_handle};
use gpui::prelude::*; use gpui::prelude::*;
use gpui::{App, Entity, SharedString, WeakEntity, Window, div, px}; use gpui::{App, Entity, PathPromptOptions, SharedString, WeakEntity, Window, div, px};
use gpui_base::input::TextareaState; use gpui_base::input::TextareaState;
use gpui_component::button::{Button, ButtonVariants}; use gpui_component::button::{Button, ButtonVariants, Toggle, ToggleVariants};
use gpui_component::dialog::{DialogDescription, DialogFooter, DialogHeader, DialogTitle}; use gpui_component::dialog::{DialogDescription, DialogFooter, DialogHeader, DialogTitle};
use gpui_component::form::{field, v_form}; use gpui_component::form::{field, v_form};
use gpui_component::input::{Input, InputState, Textarea}; use gpui_component::input::{Input, InputState, Textarea};
use gpui_component::tag::Tag;
use gpui_component::{ActiveTheme, Disableable, IconName, Sizable, WindowExt, h_flex, v_flex}; use gpui_component::{ActiveTheme, Disableable, IconName, Sizable, WindowExt, h_flex, v_flex};
use nostr::prelude::*; use nostr::prelude::*;
use signed_core::{Announcement, filters}; use signed_core::{Announcement, filters};
@@ -29,6 +28,8 @@ pub struct CreateRepoState {
pub loading_servers: bool, pub loading_servers: bool,
pub error: Option<SharedString>, pub error: Option<SharedString>,
pub grasp_servers: Vec<RelayUrl>, pub grasp_servers: Vec<RelayUrl>,
/// Whether the grasp server section is shown; defaults to shown.
pub servers_enabled: bool,
} }
impl CreateRepoState { impl CreateRepoState {
@@ -36,6 +37,7 @@ impl CreateRepoState {
fn new_default() -> Self { fn new_default() -> Self {
Self { Self {
loading_servers: true, loading_servers: true,
servers_enabled: false,
grasp_servers: DEFAULT_GRASP_SERVERS grasp_servers: DEFAULT_GRASP_SERVERS
.iter() .iter()
.filter_map(|url| RelayUrl::parse(url).ok()) .filter_map(|url| RelayUrl::parse(url).ok())
@@ -57,6 +59,10 @@ pub fn open(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App)
.auto_grow(3, 5) .auto_grow(3, 5)
.placeholder("Short description") .placeholder("Short description")
}); });
let folder_input = cx.new(|cx| {
InputState::new(window, cx)
.default_value(paths::desktop_dir().to_string_lossy().to_string())
});
let relay_input = cx.new(|cx| { let relay_input = cx.new(|cx| {
InputState::new(window, cx).placeholder("wss://relay.example.com or relay.example.com") InputState::new(window, cx).placeholder("wss://relay.example.com or relay.example.com")
}); });
@@ -65,8 +71,14 @@ pub fn open(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App)
load_user_grasp_servers(state.clone(), window, cx); load_user_grasp_servers(state.clone(), window, cx);
window.open_dialog(cx, move |dialog, _window, _cx| { window.open_dialog(cx, move |dialog, _window, _cx| {
const DESC: &str = "Publish a new repository to your grasp servers.";
const FOLDER_NOTE: &str = "Where the repository is stored, defaults to your Desktop";
const SERVER_NOTE: &str =
"Where the repository is hosted, the initial push goes to each server";
let name_input = name_input.clone(); let name_input = name_input.clone();
let desc_input = desc_input.clone(); let desc_input = desc_input.clone();
let folder_input = folder_input.clone();
let relay_input = relay_input.clone(); let relay_input = relay_input.clone();
let state = state.clone(); let state = state.clone();
let dock_area = dock_area.clone(); let dock_area = dock_area.clone();
@@ -79,15 +91,13 @@ pub fn open(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App)
let error = state.read(cx).error.clone(); let error = state.read(cx).error.clone();
let servers = state.read(cx).grasp_servers.clone(); let servers = state.read(cx).grasp_servers.clone();
let loading_servers = state.read(cx).loading_servers; let loading_servers = state.read(cx).loading_servers;
let servers_enabled = state.read(cx).servers_enabled;
content content
.child( .child(
DialogHeader::new() DialogHeader::new()
.child(DialogTitle::new().child("Create repository")) .child(DialogTitle::new().child("Create repository"))
.child( .child(DialogDescription::new().child(DESC)),
DialogDescription::new()
.child("Publish a new repository to your grasp servers."),
),
) )
.child( .child(
v_form() v_form()
@@ -101,34 +111,86 @@ pub fn open(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App)
.child( .child(
field() field()
.label("Description") .label("Description")
.description("Optional")
.child(Textarea::new(&desc_input)), .child(Textarea::new(&desc_input)),
) )
.child( .child(
field() field().label("Folder").description(FOLDER_NOTE).child(
.label("Grasp servers") h_flex()
.description( .gap_1()
"Where the repository is hosted; the initial push goes to each server", .items_center()
.child(
div()
.flex_1()
.child(Input::new(&folder_input).disabled(true)),
) )
.child( .child(
v_flex() Button::new("choose-folder")
.icon(IconName::FolderOpen)
.ghost()
.tooltip("Choose folder")
.on_click({
let folder_input = folder_input.clone();
move |_ev, window, cx| {
choose_folder(&folder_input, window, cx);
}
}),
),
),
)
.child(
field()
.label_fn({
let state = state.clone();
move |_window, cx| {
let enabled = state.read(cx).servers_enabled;
h_flex()
.w_full()
.justify_between()
.items_center()
.gap_1() .gap_1()
.children( .child(
servers Toggle::new("grasp-servers-toggle")
.iter() .xsmall()
.enumerate() .ghost()
.map(|(ix, relay)| { .icon({
render_server_row(ix, relay, state.clone()) if enabled {
IconName::ChevronDown
} else {
IconName::ChevronUp
}
})
.checked(enabled)
.on_click({
let state = state.clone();
move |checked, _window, cx| {
state.update(cx, |state, cx| {
state.servers_enabled =
*checked;
cx.notify();
});
}
}), }),
) )
.child(div().child("Grasp servers"))
}
})
.when(servers_enabled, |this| this.description(SERVER_NOTE))
.child(v_flex().gap_1().when(servers_enabled, |this| {
this.children(servers.iter().enumerate().map(
|(ix, relay)| {
render_server_row(ix, relay, state.clone(), cx)
},
))
.child(
h_flex()
.gap_1()
.items_center()
.child( .child(
h_flex().gap_1().items_center().child(
div().flex_1().child(Input::new(&relay_input)), div().flex_1().child(Input::new(&relay_input)),
) )
.child( .child(
Button::new("add-relay") Button::new("add-relay")
.icon(IconName::Plus) .icon(IconName::Plus)
.small()
.ghost() .ghost()
.tooltip("Add grasp server") .tooltip("Add grasp server")
.on_click({ .on_click({
@@ -145,15 +207,18 @@ pub fn open(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App)
}), }),
), ),
) )
.when(loading_servers, |this| { .when(
loading_servers,
|this| {
this.child( this.child(
div() div()
.text_xs() .text_xs()
.text_color(cx.theme().muted_foreground) .text_color(cx.theme().muted_foreground)
.child("Loading your grasp servers…"), .child("Loading your grasp servers…"),
) )
}), },
), )
})),
), ),
) )
.children(error.map(|message| { .children(error.map(|message| {
@@ -164,6 +229,7 @@ pub fn open(dock_area: WeakEntity<DockArea>, window: &mut Window, cx: &mut App)
Button::new("create") Button::new("create")
.primary() .primary()
.label("Create repository") .label("Create repository")
.icon(IconName::ArrowRight)
.tooltip("Create repository") .tooltip("Create repository")
.loading(busy) .loading(busy)
.disabled(busy) .disabled(busy)
@@ -195,16 +261,26 @@ fn render_server_row(
ix: usize, ix: usize,
relay: &RelayUrl, relay: &RelayUrl,
state: Entity<CreateRepoState>, state: Entity<CreateRepoState>,
cx: &App,
) -> impl IntoElement { ) -> impl IntoElement {
h_flex() h_flex()
.w_full() .w_full()
.gap_1() .gap_1()
.items_center() .items_center()
.child(Tag::new().flex_1().child(display_server(relay))) .child(
h_flex()
.h_8()
.w_full()
.px_2()
.bg(cx.theme().muted)
.text_color(cx.theme().muted_foreground)
.text_sm()
.rounded(cx.theme().radius)
.child(display_server(relay)),
)
.child( .child(
Button::new(format!("remove-relay:{ix}")) Button::new(format!("remove-relay:{ix}"))
.icon(IconName::Close) .icon(IconName::Close)
.small()
.ghost() .ghost()
.flex_shrink_0() .flex_shrink_0()
.tooltip("Remove") .tooltip("Remove")
@@ -227,6 +303,34 @@ fn display_server(relay: &RelayUrl) -> SharedString {
.unwrap_or_else(|| SharedString::from(relay.to_string())) .unwrap_or_else(|| SharedString::from(relay.to_string()))
} }
/// Prompt the user to pick the folder the repository will be stored in, using
/// the platform's native folder picker, and show the result in the disabled
/// folder input.
fn choose_folder(folder_input: &Entity<InputState>, window: &mut Window, cx: &mut App) {
let handle = window.window_handle();
let folder_input = folder_input.clone();
let prompt = cx.prompt_for_paths(PathPromptOptions {
files: false,
directories: true,
multiple: false,
prompt: Some("Choose folder".into()),
});
cx.spawn(async move |cx| {
if let Ok(Ok(Some(mut paths))) = prompt.await
&& let Some(path) = paths.pop()
{
let path = path.to_string_lossy().to_string();
cx.update_window(handle, |_, window, cx| {
folder_input.update(cx, |input, cx| input.set_value(path, window, cx));
})
.ok();
}
})
.detach();
}
/// Parse the relay input (accepting a bare host) and append it to the list. /// Parse the relay input (accepting a bare host) and append it to the list.
fn add_relay( fn add_relay(
state: &Entity<CreateRepoState>, state: &Entity<CreateRepoState>,
+7
View File
@@ -0,0 +1,7 @@
# TODO
## Create repository dialog
- [ ] Persist the user's preferred local repository folder (the one picked in
the create-repository dialog, defaulting to Desktop) and use it as the
default next time the dialog opens.