Fix deprecation warning text being covered by right dock (#30456)

Sergei Kartsev and Smit Barmase created

Closes [#30378](https://github.com/zed-industries/zed/issues/30378)

Release Notes:

- Fixed deprecation warning text being covered by right dock

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>

Change summary

Cargo.lock                    |   1 
crates/zed/Cargo.toml         |   1 
crates/zed/src/zed/migrate.rs | 144 +++++++++++++++++++++---------------
3 files changed, 86 insertions(+), 60 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -18593,6 +18593,7 @@ dependencies = [
  "languages",
  "libc",
  "log",
+ "markdown",
  "markdown_preview",
  "menu",
  "migrator",

crates/zed/Cargo.toml 🔗

@@ -78,6 +78,7 @@ languages = { workspace = true, features = ["load-grammars"] }
 libc.workspace = true
 log.workspace = true
 markdown_preview.workspace = true
+markdown.workspace = true
 menu.workspace = true
 migrator.workspace = true
 mimalloc = { version = "0.1", optional = true }

crates/zed/src/zed/migrate.rs 🔗

@@ -2,12 +2,14 @@ use anyhow::{Context as _, Result};
 use editor::Editor;
 use fs::Fs;
 use migrator::{migrate_keymap, migrate_settings};
-use settings::{KeymapFile, SettingsStore};
+use settings::{KeymapFile, Settings, SettingsStore};
 use util::ResultExt;
 
 use std::sync::Arc;
 
-use gpui::{Entity, EventEmitter, Global, Task};
+use gpui::{Entity, EventEmitter, Global, Task, TextStyle, TextStyleRefinement};
+use markdown::{Markdown, MarkdownElement, MarkdownStyle};
+use theme::ThemeSettings;
 use ui::prelude::*;
 use workspace::item::ItemHandle;
 use workspace::{ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace};
@@ -21,6 +23,7 @@ pub enum MigrationType {
 pub struct MigrationBanner {
     migration_type: Option<MigrationType>,
     should_migrate_task: Option<Task<()>>,
+    markdown: Option<Entity<Markdown>>,
 }
 
 pub enum MigrationEvent {
@@ -63,22 +66,7 @@ impl MigrationBanner {
         Self {
             migration_type: None,
             should_migrate_task: None,
-        }
-    }
-
-    fn backup_file_name(&self) -> String {
-        match self.migration_type {
-            Some(MigrationType::Keymap) => paths::keymap_backup_file()
-                .file_name()
-                .unwrap_or_default()
-                .to_string_lossy()
-                .into_owned(),
-            Some(MigrationType::Settings) => paths::settings_backup_file()
-                .file_name()
-                .unwrap_or_default()
-                .to_string_lossy()
-                .into_owned(),
-            None => String::new(),
+            markdown: None,
         }
     }
 
@@ -100,6 +88,48 @@ impl MigrationBanner {
             }
         }
     }
+
+    fn show(&mut self, cx: &mut Context<Self>) {
+        let (file_type, backup_file_name) = match self.migration_type {
+            Some(MigrationType::Keymap) => (
+                "keymap",
+                paths::keymap_backup_file()
+                    .file_name()
+                    .unwrap_or_default()
+                    .to_string_lossy()
+                    .into_owned(),
+            ),
+            Some(MigrationType::Settings) => (
+                "settings",
+                paths::settings_backup_file()
+                    .file_name()
+                    .unwrap_or_default()
+                    .to_string_lossy()
+                    .into_owned(),
+            ),
+            None => return,
+        };
+
+        let migration_text = format!(
+            "Your {} file uses deprecated settings which can be \
+            automatically updated. A backup will be saved to `{}`",
+            file_type, backup_file_name
+        );
+
+        self.markdown = Some(cx.new(|cx| Markdown::new(migration_text.into(), None, None, cx)));
+
+        cx.emit(ToolbarItemEvent::ChangeLocation(
+            ToolbarItemLocation::Secondary,
+        ));
+        cx.notify();
+    }
+
+    fn reset(&mut self, cx: &mut Context<Self>) {
+        self.should_migrate_task.take();
+        self.migration_type.take();
+        self.markdown.take();
+        cx.notify();
+    }
 }
 
 impl EventEmitter<ToolbarItemEvent> for MigrationBanner {}
@@ -111,8 +141,8 @@ impl ToolbarItemView for MigrationBanner {
         window: &mut Window,
         cx: &mut Context<Self>,
     ) -> ToolbarItemLocation {
-        cx.notify();
-        self.should_migrate_task.take();
+        self.reset(cx);
+
         let Some(target) = active_pane_item
             .and_then(|item| item.act_as::<Editor>(cx))
             .and_then(|editor| editor.update(cx, |editor, cx| editor.target_file_abs_path(cx)))
@@ -126,11 +156,8 @@ impl ToolbarItemView for MigrationBanner {
             let should_migrate = should_migrate_keymap(fs);
             self.should_migrate_task = Some(cx.spawn_in(window, async move |this, cx| {
                 if let Ok(true) = should_migrate.await {
-                    this.update(cx, |_, cx| {
-                        cx.emit(ToolbarItemEvent::ChangeLocation(
-                            ToolbarItemLocation::Secondary,
-                        ));
-                        cx.notify();
+                    this.update(cx, |this, cx| {
+                        this.show(cx);
                     })
                     .log_err();
                 }
@@ -141,11 +168,8 @@ impl ToolbarItemView for MigrationBanner {
             let should_migrate = should_migrate_settings(fs);
             self.should_migrate_task = Some(cx.spawn_in(window, async move |this, cx| {
                 if let Ok(true) = should_migrate.await {
-                    this.update(cx, |_, cx| {
-                        cx.emit(ToolbarItemEvent::ChangeLocation(
-                            ToolbarItemLocation::Secondary,
-                        ));
-                        cx.notify();
+                    this.update(cx, |this, cx| {
+                        this.show(cx);
                     })
                     .log_err();
                 }
@@ -159,54 +183,54 @@ impl ToolbarItemView for MigrationBanner {
 impl Render for MigrationBanner {
     fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
         let migration_type = self.migration_type;
-        let file_type = match migration_type {
-            Some(MigrationType::Keymap) => "keymap",
-            Some(MigrationType::Settings) => "settings",
-            None => "",
-        };
-        let backup_file_name = self.backup_file_name();
-
+        let settings = ThemeSettings::get_global(cx);
+        let ui_font_family = settings.ui_font.family.clone();
+        let line_height = settings.ui_font_size(cx) * 1.3;
         h_flex()
             .py_1()
             .pl_2()
             .pr_1()
-            .flex_wrap()
             .justify_between()
             .bg(cx.theme().status().info_background.opacity(0.6))
             .border_1()
             .border_color(cx.theme().colors().border_variant)
             .rounded_sm()
-            .overflow_hidden()
             .child(
                 h_flex()
                     .gap_2()
+                    .overflow_hidden()
                     .child(
                         Icon::new(IconName::Warning)
                             .size(IconSize::XSmall)
                             .color(Color::Warning),
                     )
                     .child(
-                        h_flex()
-                            .gap_0p5()
-                            .child(
-                                Label::new(format!(
-                                    "Your {} file uses deprecated settings which can be \
-                                    automatically updated. A backup will be saved to",
-                                    file_type
-                                ))
-                                .color(Color::Default),
-                            )
-                            .child(
-                                div()
-                                    .px_1()
-                                    .bg(cx.theme().colors().background)
-                                    .rounded_xs()
-                                    .child(
-                                        Label::new(backup_file_name)
-                                            .buffer_font(cx)
-                                            .size(LabelSize::Small),
-                                    ),
-                            ),
+                        div()
+                            .overflow_hidden()
+                            .text_size(TextSize::Default.rems(cx))
+                            .max_h(2 * line_height)
+                            .when_some(self.markdown.as_ref(), |this, markdown| {
+                                this.child(
+                                    MarkdownElement::new(
+                                        markdown.clone(),
+                                        MarkdownStyle {
+                                            base_text_style: TextStyle {
+                                                color: cx.theme().colors().text,
+                                                font_family: ui_font_family,
+                                                ..Default::default()
+                                            },
+                                            inline_code: TextStyleRefinement {
+                                                background_color: Some(
+                                                    cx.theme().colors().background,
+                                                ),
+                                                ..Default::default()
+                                            },
+                                            ..Default::default()
+                                        },
+                                    )
+                                    .into_any_element(),
+                                )
+                            }),
                     ),
             )
             .child(