Plugin
CopyFileContents
Adds a button to text file attachments to copy their contents
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import "./style.css";8
9
import ErrorBoundary from "@components/ErrorBoundary";10
import { CopyIcon, NoEntrySignIcon } from "@components/Icons";11
import { Devs } from "@utils/constants";12
import { copyWithToast } from "@utils/discord";13
import definePlugin from "@utils/types";14
import { Tooltip, useState } from "@webpack/common";15
16
const CheckMarkIcon = () => {17
return <svg width="18" height="18" viewBox="0 0 24 24">18
<path fill="currentColor" d="M21.7 5.3a1 1 0 0 1 0 1.4l-12 12a1 1 0 0 1-1.4 0l-6-6a1 1 0 1 1 1.4-1.4L9 16.58l11.3-11.3a1 1 0 0 1 1.4 0Z"></path>19
</svg>;20
};21
22
export default definePlugin({23
name: "CopyFileContents",24
description: "Adds a button to text file attachments to copy their contents",25
tags: ["Utility"],26
authors: [Devs.Obsidian, Devs.Nuckyz],27
patches: [28
{29
find: "#{intl::PREVIEW_BYTES_LEFT}",30
replacement: [31
// Inline preview32
{33
match: /fileContents:(\i),bytesLeft:(\i)\}\):null,/,34
replace: "$&$self.addCopyButton({fileContents:$1,bytesLeft:$2}),"35
},36
// Modal37
{38
match: /align:"\i"\}\),(?=\(0,\i\.jsx\)\(\i,\{wordWrap:\i,setWordWrap:\i)/,39
replace: "$&$self.addCopyButton(arguments[0]),"40
}41
]42
}43
],44
45
addCopyButton: ErrorBoundary.wrap(({ fileContents, bytesLeft }: { fileContents: string, bytesLeft: number; }) => {46
const [recentlyCopied, setRecentlyCopied] = useState(false);47
48
return (49
<Tooltip text={recentlyCopied ? "Copied!" : bytesLeft > 0 ? "File too large to copy" : "Copy File Contents"}>50
{tooltipProps => (51
<div52
{...tooltipProps}53
className="vc-cfc-button"54
role="button"55
onClick={() => {56
if (!recentlyCopied && bytesLeft <= 0) {57
copyWithToast(fileContents);58
setRecentlyCopied(true);59
setTimeout(() => setRecentlyCopied(false), 2000);60
}61
}}62
>63
{recentlyCopied64
? <CheckMarkIcon />65
: bytesLeft > 066
? <NoEntrySignIcon width={18} height={18} color="var(--channel-icon)" />67
: <CopyIcon width={18} height={18} />68
}69
</div>70
)}71
</Tooltip>72
);73
}, { noop: true }),74
});75