|
1 | 1 | use crate::state::{FilteredSnapshot, ViewerAppStateRef, ViewerSystemCommand}; |
2 | 2 | use eframe::egui; |
3 | | -use eframe::egui::{Id, ScrollArea, TextEdit, Ui, Widget as _}; |
| 3 | +use eframe::egui::{Id, OpenUrl, ScrollArea, TextEdit, Ui}; |
| 4 | +use re_ui::UiExt as _; |
| 5 | +use re_ui::alert::Alert; |
4 | 6 | use re_ui::list_item::LabelContent; |
5 | | -use re_ui::{UiExt as _, icons}; |
6 | 7 | use std::task::Poll; |
7 | 8 |
|
| 9 | +fn is_github_permission_error(err: &anyhow::Error) -> bool { |
| 10 | + for cause in err.chain() { |
| 11 | + if let Some(github_err) = cause.downcast_ref::<octocrab::GitHubError>() { |
| 12 | + return matches!( |
| 13 | + github_err.status_code, |
| 14 | + reqwest::StatusCode::FORBIDDEN | reqwest::StatusCode::NOT_FOUND |
| 15 | + ); |
| 16 | + } |
| 17 | + } |
| 18 | + // octocrab can fail to parse a 404 error body, producing a serde error instead |
| 19 | + let msg = err.to_string().to_lowercase(); |
| 20 | + msg.contains("not found") || msg.contains("missing field") |
| 21 | +} |
| 22 | + |
8 | 23 | pub fn file_tree(ui: &mut Ui, state: &ViewerAppStateRef<'_>) { |
9 | 24 | ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Truncate); |
10 | 25 |
|
11 | 26 | state.loader.extra_ui(ui, state.app); |
12 | 27 |
|
| 28 | + if let Poll::Ready(Err(e)) = state.loader.state() { |
| 29 | + if is_github_permission_error(e) { |
| 30 | + Alert::warning().show(ui, |ui: &mut Ui| { |
| 31 | + ui.vertical(|ui| { |
| 32 | + ui.label("kitdiff does not have access to this repository."); |
| 33 | + if ui.link("Grant repository access").clicked() { |
| 34 | + ui.ctx().open_url(OpenUrl::new_tab( |
| 35 | + crate::github::auth::GitHubAuth::MANAGE_REPO_ACCESS_URL, |
| 36 | + )); |
| 37 | + } |
| 38 | + }); |
| 39 | + }); |
| 40 | + } else { |
| 41 | + Alert::error().show(ui, |ui: &mut Ui| { |
| 42 | + ui.label(e.to_string()); |
| 43 | + }); |
| 44 | + } |
| 45 | + } |
| 46 | + |
13 | 47 | ui.panel_title_bar_with_buttons(&state.loader.files_header(), None, |ui| { |
14 | 48 | match state.loader.state() { |
15 | 49 | Poll::Ready(Ok(())) => {} |
16 | | - Poll::Ready(Err(e)) => { |
17 | | - icons::ERROR |
18 | | - .as_image() |
19 | | - .tint(ui.tokens().alert_error.icon) |
20 | | - .ui(ui) |
21 | | - .on_hover_text(e.to_string()); |
22 | | - } |
| 50 | + Poll::Ready(Err(_)) => {} |
23 | 51 | Poll::Pending => { |
24 | 52 | ui.spinner(); |
25 | 53 | } |
|
0 commit comments