mirror of
https://github.com/Vendicated/Vencord.git
synced 2024-09-20 06:30:35 +00:00
Update name, remove css building, remove cache size setting
This commit is contained in:
parent
fce53b9535
commit
6c2222e295
4 changed files with 48 additions and 106 deletions
|
@ -407,36 +407,6 @@ export function PencilIcon(props: IconProps) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PreviewVisible(props: IconProps) {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
{...props}
|
|
||||||
className={classes(props.className, "vc-preview-visible")}
|
|
||||||
viewBox="0 0 226 226"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M113,37.66667c-75.33333,0 -103.58333,75.33333 -103.58333,75.33333c0,0 28.25,75.33333 103.58333,75.33333c75.33333,0 103.58333,-75.33333 103.58333,-75.33333c0,0 -28.25,-75.33333 -103.58333,-75.33333zM113,65.91667c25.99942,0 47.08333,21.08392 47.08333,47.08333c0,25.99942 -21.08392,47.08333 -47.08333,47.08333c-25.99942,0 -47.08333,-21.08392 -47.08333,-47.08333c0,-25.99942 21.08392,-47.08333 47.08333,-47.08333zM113,84.75c-15.60204,0 -28.25,12.64796 -28.25,28.25c0,15.60204 12.64796,28.25 28.25,28.25c15.60204,0 28.25,-12.64796 28.25,-28.25c0,-15.60204 -12.64796,-28.25 -28.25,-28.25z"
|
|
||||||
/>
|
|
||||||
</Icon>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PreviewInvisible(props: IconProps) {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
{...props}
|
|
||||||
className={classes(props.className, "vc-preview-invisible")}
|
|
||||||
viewBox="0 0 226 226"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M37.57471,28.15804c-3.83186,0.00101 -7.28105,2.32361 -8.72295,5.87384c-1.4419,3.55022 -0.58897,7.62011 2.15703,10.29267l16.79183,16.79183c-18.19175,14.60996 -29.9888,32.52303 -35.82747,43.03711c-3.12633,5.63117 -3.02363,12.41043 0.03678,18.07927c10.87625,20.13283 42.14532,66.10058 100.99007,66.10058c19.54493,0 35.83986,-5.13463 49.36394,-12.65365l19.31152,19.31152c2.36186,2.46002 5.8691,3.45098 9.16909,2.5907c3.3,-0.86028 5.87708,-3.43736 6.73736,-6.73736c0.86028,-3.3 -0.13068,-6.80724 -2.5907,-9.16909l-150.66666,-150.66667c-1.77289,-1.82243 -4.20732,-2.8506 -6.74984,-2.85075zM113,37.66667c-11.413,0 -21.60375,1.88068 -30.91683,4.81869l24.11182,24.11182c2.23175,-0.32958 4.47909,-0.6805 6.80501,-0.6805c25.99942,0 47.08333,21.08392 47.08333,47.08333c0,2.32592 -0.35092,4.57326 -0.6805,6.80501l32.29623,32.29623c10.1135,-11.22467 17.51573,-22.61015 21.94157,-30.18115c3.3335,-5.68767 3.32011,-12.67425 0.16553,-18.4655c-11.00808,-20.27408 -42.2439,-65.78792 -100.80615,-65.78792zM73.77002,87.08577l13.77555,13.77556c-1.77707,3.67147 -2.79557,7.77466 -2.79557,12.13867c0,15.60342 12.64658,28.25 28.25,28.25c4.364,0 8.46719,-1.01851 12.13867,-2.79557l13.79395,13.79395c-9.356,6.20362 -21.03043,9.17606 -33.4733,7.24642c-19.75617,-3.06983 -35.88427,-19.19794 -38.9541,-38.9541c-1.92879,-12.43739 1.0665,-24.10096 7.26481,-33.45491z"
|
|
||||||
/>
|
|
||||||
</Icon>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const WebsiteIconDark = "/assets/e1e96d89e192de1997f73730db26e94f.svg";
|
const WebsiteIconDark = "/assets/e1e96d89e192de1997f73730db26e94f.svg";
|
||||||
const WebsiteIconLight = "/assets/730f58bcfd5a57a5e22460c445a0c6cf.svg";
|
const WebsiteIconLight = "/assets/730f58bcfd5a57a5e22460c445a0c6cf.svg";
|
||||||
const GithubIconLight = "/assets/3ff98ad75ac94fa883af5ed62d17c459.svg";
|
const GithubIconLight = "/assets/3ff98ad75ac94fa883af5ed62d17c459.svg";
|
||||||
|
|
|
@ -4,15 +4,13 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Logger } from "@utils/Logger";
|
|
||||||
|
|
||||||
export class LRUCache {
|
export class LRUCache {
|
||||||
private cache: Map<string, string>;
|
private cache: Map<string, string>;
|
||||||
private maxSize: number;
|
private maxSize: number;
|
||||||
|
|
||||||
constructor() {
|
constructor(maxSize: number) {
|
||||||
this.cache = new Map();
|
this.cache = new Map();
|
||||||
this.maxSize = 50;
|
this.maxSize = maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(key: string): string | undefined {
|
get(key: string): string | undefined {
|
||||||
|
@ -47,16 +45,4 @@ export class LRUCache {
|
||||||
}
|
}
|
||||||
this.cache.clear();
|
this.cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
setMaxSize(maxSize: number) {
|
|
||||||
if (maxSize < 1) {
|
|
||||||
new Logger("FileViewer").error("Cache size must be at least 1");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.maxSize = maxSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxSize() {
|
|
||||||
return this.maxSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -4,22 +4,20 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "./fileViewer.css";
|
import "./pdfViewer.css";
|
||||||
|
|
||||||
import { get, set } from "@api/DataStore";
|
import { get, set } from "@api/DataStore";
|
||||||
import { addAccessory, removeAccessory } from "@api/MessageAccessories";
|
import { addAccessory, removeAccessory } from "@api/MessageAccessories";
|
||||||
import { updateMessage } from "@api/MessageUpdater";
|
import { updateMessage } from "@api/MessageUpdater";
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { PreviewInvisible, PreviewVisible } from "@components/Icons";
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
|
||||||
import definePlugin, { OptionType, PluginNative } from "@utils/types";
|
import definePlugin, { OptionType, PluginNative } from "@utils/types";
|
||||||
import { Tooltip, useEffect, useState } from "@webpack/common";
|
import { Icons, Spinner, Tooltip, useEffect, useState } from "@webpack/common";
|
||||||
|
|
||||||
import { LRUCache } from "./cache";
|
import { LRUCache } from "./cache";
|
||||||
|
|
||||||
const Native = VencordNative.pluginHelpers.FileViewer as PluginNative<typeof import("./native")>;
|
const Native = VencordNative.pluginHelpers.PdfViewer as PluginNative<typeof import("./native")>;
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
autoEmptyCache: {
|
autoEmptyCache: {
|
||||||
|
@ -32,20 +30,10 @@ const settings = definePluginSettings({
|
||||||
description: "Persist the state of opened/closed File Previews across channel switches and reloads.",
|
description: "Persist the state of opened/closed File Previews across channel switches and reloads.",
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
cacheSize: {
|
|
||||||
type: OptionType.SLIDER,
|
|
||||||
description: "Maximum number of PDF files to cache (after that, the least recently used file will be removed). Lower this value if you're running out of memory.",
|
|
||||||
default: 50,
|
|
||||||
restartNeeded: true,
|
|
||||||
markers: [10, 20, 30, 40, 50, 75, 100],
|
|
||||||
stickToMarkers: true,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const objectUrlsCache = new LRUCache();
|
const objectUrlsCache = new LRUCache(20);
|
||||||
const STORE_KEY = "FileViewer_PersistVisible";
|
const STORE_KEY = "PdfViewer_PersistVisible";
|
||||||
|
|
||||||
let style: HTMLStyleElement;
|
|
||||||
|
|
||||||
interface Attachment {
|
interface Attachment {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -58,25 +46,19 @@ interface Attachment {
|
||||||
title: string;
|
title: string;
|
||||||
spoiler: boolean;
|
spoiler: boolean;
|
||||||
previewBlobUrl?: string;
|
previewBlobUrl?: string;
|
||||||
|
previewVisible?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stripLink = (url: string) => url.replace("https://cdn.discordapp.com/attachments/", "").split("/").slice(0, 2).join("-");
|
|
||||||
function FilePreview({ attachment }: { attachment: Attachment; }) {
|
function FilePreview({ attachment }: { attachment: Attachment; }) {
|
||||||
const { previewBlobUrl } = attachment;
|
const { previewBlobUrl, previewVisible } = attachment;
|
||||||
|
|
||||||
if (!previewBlobUrl) return null;
|
if (!previewVisible) return null;
|
||||||
|
|
||||||
return <div className={"file-viewer container"} id={`file-viewer-${stripLink(attachment.url)}`}><embed src={previewBlobUrl} className="file-viewer preview" title={attachment.filename} /></div>;
|
return (
|
||||||
}
|
<div className={"vc-pdf-viewer-container"}>
|
||||||
|
{previewBlobUrl ? <embed src={previewBlobUrl} className="vc-pdf-viewer-preview" title={attachment.filename} /> : <Spinner />}
|
||||||
async function buildCss() {
|
</div>
|
||||||
const visiblePreviews: Set<string> | undefined = await get(STORE_KEY);
|
);
|
||||||
const elements = [...(visiblePreviews || [])].map(url => `#file-viewer-${stripLink(url)}`).join(",");
|
|
||||||
style.textContent = `
|
|
||||||
:is(${elements}) {
|
|
||||||
display: flex !important;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function PreviewButton({ attachment, channelId, messageId }: { attachment: Attachment; channelId: string; messageId: string; }) {
|
function PreviewButton({ attachment, channelId, messageId }: { attachment: Attachment; channelId: string; messageId: string; }) {
|
||||||
|
@ -92,6 +74,7 @@ function PreviewButton({ attachment, channelId, messageId }: { attachment: Attac
|
||||||
try {
|
try {
|
||||||
const buffer = await Native.getBufferResponse(attachment.url);
|
const buffer = await Native.getBufferResponse(attachment.url);
|
||||||
const file = new File([buffer], attachment.filename, { type: attachment.content_type });
|
const file = new File([buffer], attachment.filename, { type: attachment.content_type });
|
||||||
|
|
||||||
const blobUrl = URL.createObjectURL(file);
|
const blobUrl = URL.createObjectURL(file);
|
||||||
objectUrlsCache.set(attachment.url, blobUrl);
|
objectUrlsCache.set(attachment.url, blobUrl);
|
||||||
setUrl(blobUrl);
|
setUrl(blobUrl);
|
||||||
|
@ -100,24 +83,31 @@ function PreviewButton({ attachment, channelId, messageId }: { attachment: Attac
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateVisibility = async () => {
|
||||||
|
const data: Set<string> = await get(STORE_KEY) ?? new Set();
|
||||||
|
|
||||||
|
if (visible === null) {
|
||||||
|
setVisible(settings.store.persistPreviewState ? data.has(attachment.url) : false);
|
||||||
|
} else {
|
||||||
|
if (visible) data.add(attachment.url);
|
||||||
|
else data.delete(attachment.url);
|
||||||
|
|
||||||
|
await set(STORE_KEY, data);
|
||||||
|
|
||||||
|
attachment.previewVisible = visible;
|
||||||
|
updateMessage(channelId, messageId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
get(STORE_KEY).then(async data => {
|
updateVisibility();
|
||||||
if (visible === null) {
|
|
||||||
setVisible(settings.store.persistPreviewState ? (data ?? new Set()).has(attachment.url) : false);
|
|
||||||
} else {
|
|
||||||
const persistSet = (data ?? new Set());
|
|
||||||
if (visible) persistSet.add(attachment.url);
|
|
||||||
else persistSet.delete(attachment.url);
|
|
||||||
await set(STORE_KEY, persistSet);
|
|
||||||
buildCss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (visible && !url) initPdfData();
|
if (visible && !url) initPdfData();
|
||||||
}, [visible]);
|
}, [visible]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
attachment.previewBlobUrl = url;
|
attachment.previewBlobUrl = url;
|
||||||
updateMessage(channelId, messageId,);
|
updateMessage(channelId, messageId);
|
||||||
return () => {
|
return () => {
|
||||||
if (url && settings.store.autoEmptyCache) {
|
if (url && settings.store.autoEmptyCache) {
|
||||||
objectUrlsCache.delete(attachment.url);
|
objectUrlsCache.delete(attachment.url);
|
||||||
|
@ -129,20 +119,20 @@ function PreviewButton({ attachment, channelId, messageId }: { attachment: Attac
|
||||||
{tooltipProps => (
|
{tooltipProps => (
|
||||||
<div
|
<div
|
||||||
{...tooltipProps}
|
{...tooltipProps}
|
||||||
className="file-viewer toggle"
|
className="vc-pdf-viewer-toggle"
|
||||||
role="button"
|
role="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setVisible(v => !v);
|
setVisible(v => !v);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{visible ? <PreviewInvisible /> : <PreviewVisible />}
|
{visible ? <Icons.EyeSlashIcon /> : <Icons.EyeIcon />}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Tooltip>;
|
</Tooltip>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "FileViewer",
|
name: "PdfViewer",
|
||||||
description: "Preview PDF Files without having to download them",
|
description: "Preview PDF Files without having to download them",
|
||||||
authors: [Devs.AGreenPig],
|
authors: [Devs.AGreenPig],
|
||||||
dependencies: ["MessageAccessoriesAPI", "MessageUpdaterAPI",],
|
dependencies: ["MessageAccessoriesAPI", "MessageUpdaterAPI",],
|
||||||
|
@ -157,8 +147,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
start() {
|
start() {
|
||||||
objectUrlsCache.setMaxSize(Math.round(settings.store.cacheSize));
|
addAccessory("pdfViewer", props => {
|
||||||
addAccessory("fileViewer", props => {
|
|
||||||
const pdfAttachments = props.message.attachments.filter(a => a.content_type === "application/pdf");
|
const pdfAttachments = props.message.attachments.filter(a => a.content_type === "application/pdf");
|
||||||
if (!pdfAttachments.length) return null;
|
if (!pdfAttachments.length) return null;
|
||||||
|
|
||||||
|
@ -170,18 +159,13 @@ export default definePlugin({
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
}, -1);
|
}, -1);
|
||||||
|
|
||||||
style = document.createElement("style");
|
|
||||||
style.id = "VencordFileViewer";
|
|
||||||
document.head.appendChild(style);
|
|
||||||
},
|
},
|
||||||
renderPreviewButton: ErrorBoundary.wrap(e => {
|
renderPreviewButton: ErrorBoundary.wrap(e => {
|
||||||
if (e.item.originalItem.content_type !== "application/pdf") return null;
|
if (e.item.originalItem.content_type !== "application/pdf") return null;
|
||||||
return <PreviewButton attachment={e.item.originalItem} channelId={e.message.channel_id} messageId={e.message.id} />;
|
return <PreviewButton attachment={e.item.originalItem} channelId={e.message.channel_id} messageId={e.message.id} />;
|
||||||
},
|
}),
|
||||||
stop() {
|
stop() {
|
||||||
objectUrlsCache.clear();
|
objectUrlsCache.clear();
|
||||||
removeAccessory("fileViewer");
|
removeAccessory("pdfViewer");
|
||||||
style.remove();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
.file-viewer.container {
|
.vc-pdf-viewer-container {
|
||||||
resize: both;
|
resize: both;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@ -6,16 +6,18 @@
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
min-height: 500px;
|
min-height: 500px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: none; /* Will be set with buildCss */
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-viewer.preview {
|
.vc-pdf-viewer-preview {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-viewer.toggle {
|
.vc-pdf-viewer-toggle {
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -24,6 +26,6 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-viewer.toggle:hover {
|
.vc-pdf-viewer-toggle:hover {
|
||||||
color: var(--interactive-hover);
|
color: var(--interactive-hover);
|
||||||
}
|
}
|
Loading…
Reference in a new issue