"What should we build in <project>?" in T3's lighter 30px type, with the project as a picker listing No project, the projects and Add project. A thread without a project asks "What should we work on?" with the picker below it; "or start without a project" shows its shortcut. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Showing 1 changed file with 44 additions and 32 deletions.
| @@ -1154,8 +1154,18 @@ impl ChatView { | ||
| 1154 | 1154 | }) |
| 1155 | 1155 | .unwrap_or_default(); |
| 1156 | 1156 | let chat = cx.entity().downgrade(); |
| 1157 | + // T3 Code's project menu: No project, the projects, Add project. | |
| 1157 | 1158 | let project_menu = move |mut menu: gpui_kit::component::menu::PopupMenu, _: &mut Window, _: &mut Context<gpui_kit::component::menu::PopupMenu>| { |
| 1158 | - menu = menu.min_w(px(240.)).label("Project"); | |
| 1159 | + menu = menu.min_w(px(240.)).max_h(px(320.)); | |
| 1160 | + let no_project = chat.clone(); | |
| 1161 | + menu = menu.item( | |
| 1162 | + PopupMenuItem::new("No project") | |
| 1163 | + .icon(Icon::new(Lucide::MessageSquareDashed)) | |
| 1164 | + .checked(scratch) | |
| 1165 | + .on_click(move |_, _, cx| { | |
| 1166 | + let _ = no_project.update(cx, |_, cx| cx.emit(ChatEvent::StartWithoutProject)); | |
| 1167 | + }), | |
| 1168 | + ); | |
| 1159 | 1169 | for (name, path, project_env) in projects.clone() { |
| 1160 | 1170 | let chat = chat.clone(); |
| 1161 | 1171 | let checked = path == cwd && project_env == env; |
| @@ -1165,9 +1175,21 @@ impl ChatView { | ||
| 1165 | 1175 | })); |
| 1166 | 1176 | } |
| 1167 | 1177 | let chat = chat.clone(); |
| 1168 | - menu.separator().item(PopupMenuItem::new("Add project folder…").on_click(move |_, _, cx| { | |
| 1169 | - let _ = chat.update(cx, |_, cx| cx.emit(ChatEvent::AddProject)); | |
| 1170 | - })) | |
| 1178 | + menu.separator().item(PopupMenuItem::new("Add project").icon(Icon::new(Lucide::FolderPlus)).on_click( | |
| 1179 | + move |_, _, cx| { | |
| 1180 | + let _ = chat.update(cx, |_, cx| cx.emit(ChatEvent::AddProject)); | |
| 1181 | + }, | |
| 1182 | + )) | |
| 1183 | + }; | |
| 1184 | + let picker = |id: &'static str, label: SharedString| { | |
| 1185 | + MetalButton::new(id) | |
| 1186 | + .ghost() | |
| 1187 | + .label(label) | |
| 1188 | + .px(px(2.)) | |
| 1189 | + .rounded(px(0.)) | |
| 1190 | + .border_b(px(1.)) | |
| 1191 | + .border_dashed() | |
| 1192 | + .border_color(p.ink3.opacity(0.6)) | |
| 1171 | 1193 | }; |
| 1172 | 1194 | |
| 1173 | 1195 | v_flex() |
| @@ -1181,44 +1203,33 @@ impl ChatView { | ||
| 1181 | 1203 | .flex_wrap() |
| 1182 | 1204 | .justify_center() |
| 1183 | 1205 | .items_center() |
| 1184 | - .text_size(px(34.)) | |
| 1185 | - .line_height(px(44.)) | |
| 1186 | - .font_weight(FontWeight::SEMIBOLD) | |
| 1206 | + .text_size(px(30.)) | |
| 1207 | + .line_height(px(36.)) | |
| 1187 | 1208 | .text_color(p.ink) |
| 1188 | 1209 | .map(|this| { |
| 1189 | 1210 | if scratch { |
| 1190 | - this.child("What should we build?") | |
| 1211 | + this.child("What should we work on?") | |
| 1191 | 1212 | } else { |
| 1192 | 1213 | this.child("What should we build in\u{a0}") |
| 1193 | 1214 | .child( |
| 1194 | - MetalButton::new("start-project") | |
| 1195 | - .ghost() | |
| 1196 | - .label(project) | |
| 1197 | - .h(px(44.)) | |
| 1198 | - .px(px(2.)) | |
| 1199 | - .rounded(px(0.)) | |
| 1200 | - .text_size(px(34.)) | |
| 1201 | - .font_weight(FontWeight::SEMIBOLD) | |
| 1215 | + picker("start-project", project) | |
| 1216 | + .h(px(36.)) | |
| 1217 | + .max_w(px(256.)) | |
| 1218 | + .text_size(px(30.)) | |
| 1219 | + .font_weight(FontWeight::NORMAL) | |
| 1202 | 1220 | .text_color(p.ink) |
| 1203 | - .border_b(px(2.)) | |
| 1204 | - .border_dashed() | |
| 1205 | - .border_color(p.ink3.opacity(0.6)) | |
| 1206 | 1221 | .dropdown_menu(project_menu.clone()), |
| 1207 | 1222 | ) |
| 1208 | 1223 | .child("?") |
| 1209 | 1224 | } |
| 1210 | 1225 | }), |
| 1211 | 1226 | ) |
| 1212 | - .map(|this| { | |
| 1227 | + .child(div().mt(px(8.)).h(px(24.)).flex().items_center().text_size(px(14.)).map(|this| { | |
| 1213 | 1228 | if scratch { |
| 1214 | 1229 | this.child( |
| 1215 | - MetalButton::new("pick-project") | |
| 1216 | - .ghost() | |
| 1217 | - .compact() | |
| 1218 | - .label("or pick a project") | |
| 1219 | - .caret() | |
| 1220 | - .mt(px(6.)) | |
| 1221 | - .text_size(px(15.)) | |
| 1230 | + picker("pick-project", "No project".into()) | |
| 1231 | + .h(px(24.)) | |
| 1232 | + .text_size(px(14.)) | |
| 1222 | 1233 | .text_color(p.ink3) |
| 1223 | 1234 | .dropdown_menu(project_menu), |
| 1224 | 1235 | ) |
| @@ -1226,17 +1237,18 @@ impl ChatView { | ||
| 1226 | 1237 | this.child( |
| 1227 | 1238 | div() |
| 1228 | 1239 | .id("start-without-project") |
| 1229 | - .mt(px(6.)) | |
| 1230 | - .text_size(px(15.)) | |
| 1231 | 1240 | .text_color(p.ink3) |
| 1232 | 1241 | .cursor_pointer() |
| 1233 | - .hover(|style| style.text_color(p.ink)) | |
| 1242 | + .hover(|style| style.text_color(p.ink).underline()) | |
| 1243 | + .tooltip(|window, cx| { | |
| 1244 | + gpui_kit::component::tooltip::Tooltip::new("Ctrl+Alt+N").build(window, cx) | |
| 1245 | + }) | |
| 1234 | 1246 | .on_click(cx.listener(|_, _, _, cx| cx.emit(ChatEvent::StartWithoutProject))) |
| 1235 | 1247 | .child("or start without a project"), |
| 1236 | 1248 | ) |
| 1237 | 1249 | } |
| 1238 | - }) | |
| 1239 | - .child(div().h(px(30.))) | |
| 1250 | + })) | |
| 1251 | + .child(div().h(px(24.))) | |
| 1240 | 1252 | .child(self.render_composer(true, window, cx)) |
| 1241 | 1253 | } |
| 1242 | 1254 | |