starting.rs

 1use std::time::Duration;
 2
 3use anyhow::Result;
 4
 5use dap::client::SessionId;
 6use gpui::{
 7    Animation, AnimationExt, Entity, EventEmitter, FocusHandle, Focusable, Task, Transformation,
 8    percentage,
 9};
10use project::debugger::session::Session;
11use ui::{Color, Context, Icon, IconName, IntoElement, ParentElement, Render, Styled, v_flex};
12
13pub(crate) struct StartingState {
14    focus_handle: FocusHandle,
15    pub(super) session_id: SessionId,
16    _notify_parent: Task<()>,
17}
18
19pub(crate) enum StartingEvent {
20    Failed,
21    Finished(Entity<Session>),
22}
23
24impl EventEmitter<StartingEvent> for StartingState {}
25
26impl StartingState {
27    pub(crate) fn new(
28        session_id: SessionId,
29        task: Task<Result<Entity<Session>>>,
30        cx: &mut Context<Self>,
31    ) -> Self {
32        let _notify_parent = cx.spawn(async move |this, cx| {
33            let entity = task.await;
34
35            this.update(cx, |_, cx| {
36                if let Ok(entity) = entity {
37                    cx.emit(StartingEvent::Finished(entity))
38                } else {
39                    cx.emit(StartingEvent::Failed)
40                }
41            })
42            .ok();
43        });
44        Self {
45            session_id,
46            focus_handle: cx.focus_handle(),
47            _notify_parent,
48        }
49    }
50}
51
52impl Focusable for StartingState {
53    fn focus_handle(&self, _: &ui::App) -> FocusHandle {
54        self.focus_handle.clone()
55    }
56}
57
58impl Render for StartingState {
59    fn render(
60        &mut self,
61        _window: &mut ui::Window,
62        _cx: &mut ui::Context<'_, Self>,
63    ) -> impl ui::IntoElement {
64        v_flex()
65            .size_full()
66            .gap_1()
67            .items_center()
68            .child("Starting a debug adapter")
69            .child(
70                Icon::new(IconName::ArrowCircle)
71                    .color(Color::Info)
72                    .with_animation(
73                        "arrow-circle",
74                        Animation::new(Duration::from_secs(2)).repeat(),
75                        |icon, delta| icon.transform(Transformation::rotate(percentage(delta))),
76                    )
77                    .into_any_element(),
78            )
79    }
80}