mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add legal link to TUI /plugin details (#15692)
- Adds language and "[learn more](https://help.openai.com/en/articles/11487775-apps-in-chatgpt)" link to plugin details pages. - Message is hidden when plugin is installed <img width="1970" height="498" alt="image" src="https://github.com/user-attachments/assets/f14330f7-661e-4860-8538-6dc9e8bbd90a" />
This commit is contained in:
@@ -8,6 +8,7 @@ use crate::bottom_pane::ColumnWidthMode;
|
||||
use crate::bottom_pane::SelectionItem;
|
||||
use crate::bottom_pane::SelectionViewParams;
|
||||
use crate::history_cell;
|
||||
use crate::onboarding::mark_url_hyperlink;
|
||||
use crate::render::renderable::ColumnRenderable;
|
||||
use crate::render::renderable::Renderable;
|
||||
use crate::shimmer::shimmer_spans;
|
||||
@@ -24,10 +25,12 @@ use codex_features::Feature;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Rect;
|
||||
use ratatui::prelude::Widget;
|
||||
use ratatui::style::Stylize;
|
||||
use ratatui::text::Line;
|
||||
use ratatui::widgets::Paragraph;
|
||||
use ratatui::widgets::WidgetRef;
|
||||
use ratatui::widgets::Wrap;
|
||||
|
||||
const PLUGINS_SELECTION_VIEW_ID: &str = "plugins-selection";
|
||||
const LOADING_ANIMATION_DELAY: Duration = Duration::from_secs(1);
|
||||
@@ -93,6 +96,29 @@ impl Renderable for DelayedLoadingHeader {
|
||||
}
|
||||
}
|
||||
|
||||
const APPS_HELP_ARTICLE_URL: &str = "https://help.openai.com/en/articles/11487775-apps-in-chatgpt";
|
||||
|
||||
struct PluginDisclosureLine {
|
||||
line: Line<'static>,
|
||||
}
|
||||
|
||||
impl Renderable for PluginDisclosureLine {
|
||||
fn render(&self, area: Rect, buf: &mut Buffer) {
|
||||
Paragraph::new(self.line.clone())
|
||||
.wrap(Wrap { trim: false })
|
||||
.render(area, buf);
|
||||
mark_url_hyperlink(buf, area, APPS_HELP_ARTICLE_URL);
|
||||
}
|
||||
|
||||
fn desired_height(&self, width: u16) -> u16 {
|
||||
Paragraph::new(self.line.clone())
|
||||
.wrap(Wrap { trim: false })
|
||||
.line_count(width)
|
||||
.try_into()
|
||||
.unwrap_or(u16::MAX)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub(super) enum PluginsCacheState {
|
||||
#[default]
|
||||
@@ -812,13 +838,37 @@ impl ChatWidget {
|
||||
) -> SelectionViewParams {
|
||||
let marketplace_label = plugin.marketplace_name.clone();
|
||||
let display_name = plugin_display_name(&plugin.summary);
|
||||
let status_label = plugin_status_label(&plugin.summary);
|
||||
let detail_status_label = if plugin.summary.installed {
|
||||
if plugin.summary.enabled {
|
||||
"Installed"
|
||||
} else {
|
||||
"Installed · Disabled"
|
||||
}
|
||||
} else {
|
||||
match plugin.summary.install_policy {
|
||||
PluginInstallPolicy::NotAvailable => "Not installable",
|
||||
PluginInstallPolicy::Available => "Can be installed",
|
||||
PluginInstallPolicy::InstalledByDefault => "Available by default",
|
||||
}
|
||||
};
|
||||
let mut header = ColumnRenderable::new();
|
||||
header.push(Line::from("Plugins".bold()));
|
||||
header.push(Line::from(
|
||||
format!("{display_name} · {marketplace_label}").bold(),
|
||||
format!("{display_name} · {detail_status_label} · {marketplace_label}").bold(),
|
||||
));
|
||||
header.push(Line::from(status_label.dim()));
|
||||
if !plugin.summary.installed {
|
||||
header.push(PluginDisclosureLine {
|
||||
line: Line::from(vec![
|
||||
"Data shared with this app is subject to the app's ".into(),
|
||||
"terms of service".bold(),
|
||||
" and ".into(),
|
||||
"privacy policy".bold(),
|
||||
". ".into(),
|
||||
"Learn more".cyan().underlined(),
|
||||
".".into(),
|
||||
]),
|
||||
});
|
||||
}
|
||||
if let Some(description) = plugin_detail_description(plugin) {
|
||||
header.push(Line::from(description.dim()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user