loading_label.rs

  1use crate::prelude::*;
  2use gpui::{Animation, AnimationExt, FontWeight};
  3use std::time::Duration;
  4
  5#[derive(IntoElement)]
  6pub struct LoadingLabel {
  7    base: Label,
  8    text: SharedString,
  9}
 10
 11impl LoadingLabel {
 12    pub fn new(text: impl Into<SharedString>) -> Self {
 13        let text = text.into();
 14        LoadingLabel {
 15            base: Label::new(text.clone()),
 16            text,
 17        }
 18    }
 19}
 20
 21impl LabelCommon for LoadingLabel {
 22    fn size(mut self, size: LabelSize) -> Self {
 23        self.base = self.base.size(size);
 24        self
 25    }
 26
 27    fn weight(mut self, weight: FontWeight) -> Self {
 28        self.base = self.base.weight(weight);
 29        self
 30    }
 31
 32    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
 33        self.base = self.base.line_height_style(line_height_style);
 34        self
 35    }
 36
 37    fn color(mut self, color: Color) -> Self {
 38        self.base = self.base.color(color);
 39        self
 40    }
 41
 42    fn strikethrough(mut self) -> Self {
 43        self.base = self.base.strikethrough();
 44        self
 45    }
 46
 47    fn italic(mut self) -> Self {
 48        self.base = self.base.italic();
 49        self
 50    }
 51
 52    fn alpha(mut self, alpha: f32) -> Self {
 53        self.base = self.base.alpha(alpha);
 54        self
 55    }
 56
 57    fn underline(mut self) -> Self {
 58        self.base = self.base.underline();
 59        self
 60    }
 61
 62    fn truncate(mut self) -> Self {
 63        self.base = self.base.truncate();
 64        self
 65    }
 66
 67    fn single_line(mut self) -> Self {
 68        self.base = self.base.single_line();
 69        self
 70    }
 71
 72    fn buffer_font(mut self, cx: &App) -> Self {
 73        self.base = self.base.buffer_font(cx);
 74        self
 75    }
 76
 77    fn inline_code(mut self, cx: &App) -> Self {
 78        self.base = self.base.inline_code(cx);
 79        self
 80    }
 81}
 82
 83impl RenderOnce for LoadingLabel {
 84    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
 85        let text = self.text.clone();
 86
 87        self.base.color(Color::Muted).with_animations(
 88            "loading_label",
 89            vec![
 90                Animation::new(Duration::from_secs(1)),
 91                Animation::new(Duration::from_secs(1)).repeat(),
 92            ],
 93            move |mut label, animation_ix, delta| {
 94                match animation_ix {
 95                    0 => {
 96                        let chars_to_show = (delta * text.len() as f32).ceil() as usize;
 97                        let text = SharedString::from(text[0..chars_to_show].to_string());
 98                        label.set_text(text);
 99                    }
100                    1 => match delta {
101                        d if d < 0.25 => label.set_text(text.clone()),
102                        d if d < 0.5 => label.set_text(format!("{}.", text)),
103                        d if d < 0.75 => label.set_text(format!("{}..", text)),
104                        _ => label.set_text(format!("{}...", text)),
105                    },
106                    _ => {}
107                }
108                label
109            },
110        )
111    }
112}