T11b loading: progress bars and rings that glide, loading overlay, lazy load, suspense and async view, refresh and typing indicators, upload list; draw-time notifies ask for a frame
This commit is contained in:
38 files changed
+1646
-91
No files matched your search
+8
-49
@@ -1,12 +1,12 @@
|
||||
use gpui::{
|
||||
Animation, AnimationExt, AnyElement, App, AppContext, Bounds, IntoElement, ParentElement,
|
||||
RenderOnce, SharedString, Styled, Window, WindowBounds, WindowHandle, WindowOptions, div,
|
||||
prelude::*, relative,
|
||||
Animation, AnimationExt, App, AppContext, Bounds, IntoElement, ParentElement, RenderOnce,
|
||||
SharedString, Styled, Window, WindowBounds, WindowHandle, WindowOptions, div, prelude::*,
|
||||
relative,
|
||||
};
|
||||
|
||||
use super::{Hosted, open_hosted};
|
||||
use crate::{
|
||||
motion,
|
||||
motion::{self, ProgressBar},
|
||||
primitives::{Icon, IconName},
|
||||
theme::{ActiveTheme, ControlSize, IconSize, Radius, TextSize},
|
||||
typography::{Caption, CopyableText, ExternalLink, Paragraph, Title},
|
||||
@@ -32,50 +32,6 @@ fn mark(name: &SharedString, icon: Option<IconName>, cx: &App) -> impl IntoEleme
|
||||
})
|
||||
}
|
||||
|
||||
/// A thin track: `Some` fills to the value, `None` sweeps.
|
||||
pub(super) fn progress_track(value: Option<f32>, cx: &App) -> AnyElement {
|
||||
let theme = cx.theme();
|
||||
let colors = &theme.colors;
|
||||
let fill = div()
|
||||
.absolute()
|
||||
.top_0()
|
||||
.h_full()
|
||||
.rounded_full()
|
||||
.bg(colors.fg);
|
||||
let track = div()
|
||||
.relative()
|
||||
.w_full()
|
||||
.h(theme.progress_thickness())
|
||||
.rounded_full()
|
||||
.overflow_hidden()
|
||||
.bg(colors.border);
|
||||
match value {
|
||||
Some(value) => {
|
||||
assert!(
|
||||
(0.0..=1.0).contains(&value),
|
||||
"progress {value} is not 0..=1"
|
||||
);
|
||||
track
|
||||
.child(fill.left_0().w(relative(value)))
|
||||
.into_any_element()
|
||||
}
|
||||
None if theme.reduced_motion => track
|
||||
.child(fill.left(relative(0.35)).w(relative(0.3)))
|
||||
.into_any_element(),
|
||||
None => track
|
||||
.child(
|
||||
fill.w(relative(0.3)).with_animation(
|
||||
"progress-sweep",
|
||||
Animation::new(motion::duration(motion::SLOW, cx) * 4)
|
||||
.repeat()
|
||||
.with_easing(motion::ease_in_out_cubic),
|
||||
|bar, t| bar.left(relative(-0.3 + 1.3 * t)),
|
||||
),
|
||||
)
|
||||
.into_any_element(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Name, version, credits: the About window's content.
|
||||
#[derive(IntoElement, Clone)]
|
||||
pub struct AboutDialog {
|
||||
@@ -243,7 +199,10 @@ impl RenderOnce for SplashScreen {
|
||||
let theme = cx.theme();
|
||||
let colors = &theme.colors;
|
||||
let enter = motion::duration(motion::SLOW, cx);
|
||||
let track = progress_track(self.progress, cx);
|
||||
let track = match self.progress {
|
||||
Some(value) => ProgressBar::new("splash-progress", value).into_any_element(),
|
||||
None => ProgressBar::indeterminate("splash-progress").into_any_element(),
|
||||
};
|
||||
div()
|
||||
.size_full()
|
||||
.flex()
|
||||
|
||||
+8
-7
@@ -5,10 +5,11 @@ use gpui::{
|
||||
Window, WindowHandle, div, prelude::*,
|
||||
};
|
||||
|
||||
use super::{Hosted, dialogs::progress_track, open_hosted};
|
||||
use super::{Hosted, open_hosted};
|
||||
use crate::{
|
||||
buttons::{Button, ButtonVariant, IconButton},
|
||||
layout::ScrollArea,
|
||||
motion::ProgressBar,
|
||||
primitives::{Icon, IconName},
|
||||
theme::{ActiveTheme, ControlSize, IconSize, Radius, TextSize},
|
||||
typography::{Caption, Label, Title},
|
||||
@@ -33,9 +34,11 @@ struct Actions {
|
||||
later: Option<Action>,
|
||||
}
|
||||
|
||||
fn progress_line(state: UpdateState, cx: &App) -> Option<AnyElement> {
|
||||
fn progress_line(state: UpdateState) -> Option<AnyElement> {
|
||||
match state {
|
||||
UpdateState::Downloading(value) => Some(progress_track(Some(value), cx)),
|
||||
UpdateState::Downloading(value) => {
|
||||
Some(ProgressBar::new("update-progress", value).into_any_element())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -159,7 +162,7 @@ impl RenderOnce for UpdateBanner {
|
||||
.on_click(move |_, window, cx| dismiss(window, cx)),
|
||||
)
|
||||
})
|
||||
.when_some(progress_line(self.state, cx), |banner, line| {
|
||||
.when_some(progress_line(self.state), |banner, line| {
|
||||
banner.child(div().absolute().left_0().right_0().bottom_0().child(line))
|
||||
})
|
||||
}
|
||||
@@ -258,9 +261,7 @@ impl RenderOnce for UpdateDialog {
|
||||
),
|
||||
),
|
||||
)
|
||||
.when_some(progress_line(self.state, cx), |dialog, line| {
|
||||
dialog.child(line)
|
||||
})
|
||||
.when_some(progress_line(self.state), |dialog, line| dialog.child(line))
|
||||
.child(div().flex().justify_end().gap_2().children(buttons(
|
||||
self.state,
|
||||
&self.actions,
|
||||
|
||||
Reference in new issue
Block a user