forked from 1b-agent/opencadstudio-upstream
Merge PR #1096: align history controls and fix browser history copy
This commit is contained in:
commit
b2ec9ef863
6 files changed
+63
-7
No files matched your search
@@ -2180,6 +2180,8 @@ pub enum Message {
|
||||
/// clipboard as plain text — issue #232, so output can be pasted for
|
||||
/// debugging instead of screenshotted.
|
||||
CommandHistoryCopy,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
CommandHistoryCopied(bool),
|
||||
/// Clear every line from the command-line history.
|
||||
CommandHistoryClear,
|
||||
/// Copy every line currently retained by the PERF panel.
|
||||
|
||||
+25
-3
@@ -1839,10 +1839,32 @@ impl OpenCADStudio {
|
||||
Message::CommandHistoryCopy => {
|
||||
let text = self.command_line.history_plain_text();
|
||||
if text.is_empty() {
|
||||
Task::none()
|
||||
} else {
|
||||
iced::clipboard::write(text).discard()
|
||||
return Task::none();
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
let promise = crate::sys::copy_history_text(
|
||||
&text,
|
||||
crate::t!("Clipboard access is unavailable. Press Ctrl+C or Command+C to copy the selected history.").as_ref(),
|
||||
crate::t!("Close").as_ref(),
|
||||
);
|
||||
Task::perform(async move {
|
||||
wasm_bindgen_futures::JsFuture::from(promise).await
|
||||
.ok().and_then(|value| value.as_bool()).unwrap_or(false)
|
||||
}, Message::CommandHistoryCopied)
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
iced::clipboard::write(text).discard()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Message::CommandHistoryCopied(copied) => {
|
||||
if copied {
|
||||
self.command_line.push_info(crate::t!("Copied").as_ref());
|
||||
} else {
|
||||
self.command_line.push_error(crate::t!("Clipboard access is unavailable. Press Ctrl+C or Command+C to copy the selected history.").as_ref());
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::CommandHistoryClear => {
|
||||
|
||||
+2
-2
@@ -2930,7 +2930,7 @@ pub(super) fn doc_tab_bar<'a>(
|
||||
let new_btn = button(text("+").size(14))
|
||||
.on_press(Message::TabNew)
|
||||
.height(iced::Length::Fixed(28.0))
|
||||
.padding([5, 10])
|
||||
.padding([4, 8])
|
||||
.style(|theme: &Theme, status| {
|
||||
let palette = theme.palette();
|
||||
let hovered = matches!(
|
||||
@@ -2960,7 +2960,7 @@ pub(super) fn doc_tab_bar<'a>(
|
||||
top: 0.0,
|
||||
right: 0.0,
|
||||
bottom: 0.0,
|
||||
left: 6.0,
|
||||
left: 2.0,
|
||||
})
|
||||
.into(),
|
||||
);
|
||||
|
||||
@@ -226,6 +226,13 @@ pub async fn read_clipboard_text() -> Option<String> {
|
||||
value.as_string()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[wasm_bindgen::prelude::wasm_bindgen(module = "/web/clipboard.js")]
|
||||
extern "C" {
|
||||
#[wasm_bindgen::prelude::wasm_bindgen(js_name = copyHistory)]
|
||||
pub fn copy_history_text(text: &str, fallback_label: &str, close_label: &str) -> js_sys::Promise;
|
||||
}
|
||||
|
||||
/// Web: write text to the system clipboard (fire-and-forget). Backs Ctrl+C in
|
||||
/// plain text_input fields, whose iced-internal copy is a no-op on the web
|
||||
/// (#346). The triggering keypress is a user gesture, so the write is allowed.
|
||||
|
||||
@@ -849,10 +849,10 @@ impl CommandLine {
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.padding([2, 6]);
|
||||
.padding([2, 8]);
|
||||
let panel = container(column![header, log])
|
||||
.width(Length::Fill)
|
||||
.padding([4, 8]);
|
||||
.padding(Padding { top: 2.0, right: 8.0, bottom: 4.0, left: 8.0 });
|
||||
let resize = iced::widget::mouse_area(
|
||||
container(crate::ui::icons::themed_primary(
|
||||
crate::ui::icons::RESIZE,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export async function copyHistory(text, fallbackLabel, closeLabel) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
return true;
|
||||
} catch {
|
||||
const dialog = document.createElement('dialog');
|
||||
const label = document.createElement('p');
|
||||
label.textContent = fallbackLabel;
|
||||
const field = document.createElement('textarea');
|
||||
field.value = text;
|
||||
field.readOnly = true;
|
||||
field.setAttribute('aria-label', fallbackLabel);
|
||||
field.style.cssText = 'width:70vw;height:50vh;display:block';
|
||||
const close = document.createElement('button');
|
||||
close.textContent = closeLabel;
|
||||
close.onclick = () => dialog.close();
|
||||
dialog.append(label, field, close);
|
||||
dialog.addEventListener('close', () => dialog.remove(), { once: true });
|
||||
document.body.append(dialog);
|
||||
dialog.showModal();
|
||||
field.focus();
|
||||
field.select();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user