Skip to content

Commit

Permalink
Add entry info prop copy
Browse files Browse the repository at this point in the history
  • Loading branch information
perry-mitchell committed Mar 27, 2024
1 parent 36808b4 commit e55d3fc
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
41 changes: 35 additions & 6 deletions source/popup/components/entries/EntryInfoDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React, { useMemo } from "react";
import { Button, Classes, Dialog, DialogBody } from "@blueprintjs/core";
import React, { useCallback, useMemo } from "react";
import { Button, Classes, Dialog, DialogBody, InputGroup, Intent } from "@blueprintjs/core";
import { SearchResult } from "buttercup";
import cn from "classnames";
import styled from "styled-components";
import { t } from "../../../shared/i18n/trans.js";
import { copyTextToClipboard } from "../../services/clipboard.js";
import { getToaster } from "../../../shared/services/notifications.js";
import { localisedErrorMessage } from "../../../shared/library/error.js";

interface EntryInfoDialogProps {
entry: SearchResult | null;
Expand Down Expand Up @@ -30,13 +34,26 @@ const InfoTable = styled.table`
table-layout: fixed;
width: 100%;
`;
const ValueInput = styled.input`
width: 100%;
`;

export function EntryInfoDialog(props: EntryInfoDialogProps) {
const { entry, onClose } = props;
const properties = useMemo(() => entry ? orderProperties(entry.properties) : [], [entry]);
const handleCopyClick = useCallback(async (property: string, value: string) => {
try {
await copyTextToClipboard(value);
getToaster().show({
intent: Intent.SUCCESS,
message: t("popup.entries.info.copy-success", { property }),
timeout: 4000
});
} catch (err) {
getToaster().show({
intent: Intent.DANGER,
message: t("popup.entries.info.copy-error", { message: localisedErrorMessage(err) }),
timeout: 10000
});
}
}, []);
return (
<InfoDialog
icon="info-sign"
Expand All @@ -52,7 +69,19 @@ export function EntryInfoDialog(props: EntryInfoDialogProps) {
<tr key={property.key}>
<td style={{ width: "100%" }}>
{property.title}<br />
<ValueInput className={Classes.INPUT} type={property.sensitive ? "password" : "text"} value={property.value} readOnly />
<InputGroup
type={property.sensitive ? "password" : "text"}
value={property.value}
readOnly
rightElement={
<Button
icon="clipboard"
minimal
onClick={() => handleCopyClick(property.title, property.value)}
title={t("popup.entries.info.copy-tooltip")}
/>
}
/>
</td>
</tr>
))}
Expand Down
24 changes: 24 additions & 0 deletions source/popup/services/clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Layerr } from "layerr";

export async function copyTextToClipboard(text: string): Promise<void> {
// Navigator clipboard api needs a secure context (https)
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
} else {
// Use the 'out of viewport hidden text area' trick
const textArea = document.createElement("textarea");
textArea.value = text;
// Move textarea out of the viewport so it's not visible
textArea.style.position = "absolute";
textArea.style.left = "-999999px";
document.body.prepend(textArea);
textArea.select();
try {
document.execCommand("copy");
} catch (error) {
throw new Layerr(error, "Failed copying text");
} finally {
textArea.remove();
}
}
}
3 changes: 3 additions & 0 deletions source/shared/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@
"recent-set-error": "Failed recording recent entry: {{message}}"
},
"info": {
"copy-error": "Failed copying value: {{message}}",
"copy-success": "Copied value to clipboard: {{property}}",
"copy-tooltip": "Copy to clipoard",
"tooltip": "Show entry properties"
},
"otp": {
Expand Down
1 change: 1 addition & 0 deletions source/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface BackgroundMessage {
notification?: string;
searchTerm?: string;
sourceID?: VaultSourceID;
text?: string;
type: BackgroundMessageType;
url?: string;
}
Expand Down

0 comments on commit e55d3fc

Please sign in to comment.