From 5a6575a393bf4423dc95ba334347a05061e69aa5 Mon Sep 17 00:00:00 2001 From: Red J Adaya Date: Sat, 6 Apr 2024 03:06:04 +0800 Subject: [PATCH] Copy button (#550) * cop button * cleanup * fix wrong type * updates to try to set the cmdinput position (as well as text). fix button alignment, change checkmark to green (and extend), and remove the transition from parent component and move to copy (sawka) --- src/app/common/elements/button.tsx | 10 ++-- src/app/common/elements/copybutton.less | 7 +++ src/app/common/elements/copybutton.tsx | 51 ++++++++++++++++++++ src/app/common/elements/index.tsx | 1 + src/app/history/history.less | 4 ++ src/app/history/history.tsx | 34 +++---------- src/app/workspace/cmdinput/textareainput.tsx | 14 ++++-- 7 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 src/app/common/elements/copybutton.less create mode 100644 src/app/common/elements/copybutton.tsx diff --git a/src/app/common/elements/button.tsx b/src/app/common/elements/button.tsx index d411f47b..32531743 100644 --- a/src/app/common/elements/button.tsx +++ b/src/app/common/elements/button.tsx @@ -6,7 +6,7 @@ import "./button.less"; interface ButtonProps { children: React.ReactNode; - onClick?: () => void; + onClick?: (e: React.MouseEvent) => void; disabled?: boolean; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode; @@ -14,6 +14,7 @@ interface ButtonProps { autoFocus?: boolean; className?: string; termInline?: boolean; + title?: string; } class Button extends React.Component { @@ -23,14 +24,14 @@ class Button extends React.Component { }; @boundMethod - handleClick() { + handleClick(e) { if (this.props.onClick && !this.props.disabled) { - this.props.onClick(); + this.props.onClick(e); } } render() { - const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className } = this.props; + const { leftIcon, rightIcon, children, disabled, style, autoFocus, termInline, className, title } = this.props; return ( + ); + } +} + +export { CopyButton }; diff --git a/src/app/common/elements/index.tsx b/src/app/common/elements/index.tsx index 75f99280..cf87b853 100644 --- a/src/app/common/elements/index.tsx +++ b/src/app/common/elements/index.tsx @@ -18,3 +18,4 @@ export { Toggle } from "./toggle"; export { Tooltip } from "./tooltip"; export { TabIcon } from "./tabicon"; export { DatePicker } from "./datepicker"; +export { CopyButton } from "./copybutton"; diff --git a/src/app/history/history.less b/src/app/history/history.less index a386e753..e323e0dd 100644 --- a/src/app/history/history.less +++ b/src/app/history/history.less @@ -357,6 +357,10 @@ cursor: pointer; } + .wave-button { + padding: 5px 5px; + } + visibility: hidden; } diff --git a/src/app/history/history.tsx b/src/app/history/history.tsx index 1d1481d1..7aecebd0 100644 --- a/src/app/history/history.tsx +++ b/src/app/history/history.tsx @@ -14,7 +14,7 @@ import localizedFormat from "dayjs/plugin/localizedFormat"; import customParseFormat from "dayjs/plugin/customParseFormat"; import { Line } from "@/app/line/linecomps"; import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil"; -import { TextField, Dropdown, Button, DatePicker } from "@/elements"; +import { TextField, Dropdown, Button, CopyButton } from "@/elements"; import { ReactComponent as ChevronLeftIcon } from "@/assets/icons/history/chevron-left.svg"; import { ReactComponent as ChevronRightIcon } from "@/assets/icons/history/chevron-right.svg"; @@ -22,8 +22,6 @@ import { ReactComponent as RightIcon } from "@/assets/icons/history/right.svg"; import { ReactComponent as SearchIcon } from "@/assets/icons/history/search.svg"; import { ReactComponent as TrashIcon } from "@/assets/icons/trash.svg"; import { ReactComponent as CheckedCheckbox } from "@/assets/icons/checked-checkbox.svg"; -import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg"; -import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg"; import "./history.less"; import { MainView } from "../common/elements/mainview"; @@ -115,7 +113,6 @@ class HistoryCmdStr extends React.Component< cmdstr: string; onUse: () => void; onCopy: () => void; - isCopied: boolean; fontSize: "normal" | "large"; limitHeight: boolean; }, @@ -138,24 +135,17 @@ class HistoryCmdStr extends React.Component< } render() { - const { isCopied, cmdstr, fontSize, limitHeight } = this.props; + const { cmdstr, fontSize, limitHeight } = this.props; return (
- -
-
copied
-
-
{cmdstr}
-
- -
-
- -
+ +
); @@ -190,7 +180,6 @@ class HistoryView extends React.Component<{}, {}> { tableRszObs: ResizeObserver; sessionDropdownActive: OV = mobx.observable.box(false, { name: "sessionDropdownActive" }); remoteDropdownActive: OV = mobx.observable.box(false, { name: "remoteDropdownActive" }); - copiedItemId: OV = mobx.observable.box(null, { name: "copiedItemId" }); @boundMethod handleNext() { @@ -377,14 +366,6 @@ class HistoryView extends React.Component<{}, {}> { return; } navigator.clipboard.writeText(item.cmdstr); - mobx.action(() => { - this.copiedItemId.set(item.historyid); - })(); - setTimeout(() => { - mobx.action(() => { - this.copiedItemId.set(null); - })(); - }, 600); } @boundMethod @@ -394,7 +375,7 @@ class HistoryView extends React.Component<{}, {}> { } mobx.action(() => { GlobalModel.showSessionView(); - GlobalModel.inputModel.setCurLine(item.cmdstr); + GlobalModel.inputModel.updateCmdLine({ str: item.cmdstr, pos: item.cmdstr.length }); setTimeout(() => GlobalModel.inputModel.giveFocus(), 50); })(); } @@ -569,7 +550,6 @@ class HistoryView extends React.Component<{}, {}> { cmdstr={item.cmdstr} onUse={() => this.handleUse(item)} onCopy={() => this.handleCopy(item)} - isCopied={this.copiedItemId.get() == item.historyid} fontSize="normal" limitHeight={true} /> diff --git a/src/app/workspace/cmdinput/textareainput.tsx b/src/app/workspace/cmdinput/textareainput.tsx index db1575d6..abac0f0a 100644 --- a/src/app/workspace/cmdinput/textareainput.tsx +++ b/src/app/workspace/cmdinput/textareainput.tsx @@ -253,9 +253,9 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: () controlRef: React.RefObject = React.createRef(); lastHeight: number = 0; lastSP: StrWithPos = { str: "", pos: appconst.NoStrPos }; - version: OV = mobx.observable.box(0); // forces render updates - mainInputFocused: OV = mobx.observable.box(true); - historyFocused: OV = mobx.observable.box(false); + version: OV = mobx.observable.box(0, { name: "textAreaInput-version" }); // forces render updates + mainInputFocused: OV = mobx.observable.box(true, { name: "textAreaInput-mainInputFocused" }); + historyFocused: OV = mobx.observable.box(false, { name: "textAreaInput-historyFocused" }); incVersion(): void { const v = this.version.get(); @@ -288,9 +288,13 @@ class TextAreaInput extends React.Component<{ screen: Screen; onHeightChange: () setFocus(): void { const inputModel = GlobalModel.inputModel; if (inputModel.historyFocus.get()) { - this.historyInputRef.current.focus(); + if (this.historyInputRef.current != null && document.activeElement != this.historyInputRef.current) { + this.historyInputRef.current.focus(); + } } else { - this.mainInputRef.current.focus(); + if (this.mainInputRef.current != null && document.activeElement != this.mainInputRef.current) { + this.mainInputRef.current.focus(); + } } }