aboutsummaryrefslogtreecommitdiff
path: root/src/components/PluginSettings
diff options
context:
space:
mode:
authorNickyux <30734036+nmsturcke@users.noreply.github.com>2022-12-23 03:17:19 +0100
committerGitHub <noreply@github.com>2022-12-23 03:17:19 +0100
commitaff1b68d6b480ecf25d03ee11ee7ca2fb04d945c (patch)
tree43ae0b57acdd88a6ec64f5441e3bf3061d947c5c /src/components/PluginSettings
parent074542f0b36cd61e3d2a1aefc7c716d394e1f751 (diff)
downloadVencord-aff1b68d6b480ecf25d03ee11ee7ca2fb04d945c.tar.gz
Vencord-aff1b68d6b480ecf25d03ee11ee7ca2fb04d945c.tar.bz2
Vencord-aff1b68d6b480ecf25d03ee11ee7ca2fb04d945c.zip
Add a "NEW" Badge for New Plugins (V2)! (#234)
Co-authored-by: Ven <vendicated@riseup.net> Co-authored-by: Justice Almanzar <superdash993@gmail.com> Co-authored-by: ArjixWasTaken <53124886+ArjixWasTaken@users.noreply.github.com>
Diffstat (limited to 'src/components/PluginSettings')
-rw-r--r--src/components/PluginSettings/components/BadgeComponent.tsx30
-rw-r--r--src/components/PluginSettings/components/index.ts1
-rw-r--r--src/components/PluginSettings/index.tsx43
-rw-r--r--src/components/PluginSettings/styles.ts13
4 files changed, 78 insertions, 9 deletions
diff --git a/src/components/PluginSettings/components/BadgeComponent.tsx b/src/components/PluginSettings/components/BadgeComponent.tsx
new file mode 100644
index 0000000..059376f
--- /dev/null
+++ b/src/components/PluginSettings/components/BadgeComponent.tsx
@@ -0,0 +1,30 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+import { BadgeStyle } from "@components/PluginSettings/styles";
+
+export function Badge({ text, color }): JSX.Element {
+ return (
+ <div style={{
+ backgroundColor: color,
+ justifySelf: "flex-end",
+ marginLeft: "auto",
+ ...BadgeStyle
+ }}>{text}</div>
+ );
+}
diff --git a/src/components/PluginSettings/components/index.ts b/src/components/PluginSettings/components/index.ts
index 9e75068..d44fb38 100644
--- a/src/components/PluginSettings/components/index.ts
+++ b/src/components/PluginSettings/components/index.ts
@@ -29,6 +29,7 @@ export interface ISettingElementProps<T extends PluginOptionBase> {
onError(hasError: boolean): void;
}
+export * from "./BadgeComponent";
export * from "./SettingBooleanComponent";
export * from "./SettingCustomComponent";
export * from "./SettingNumericComponent";
diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx
index 5ee9cc9..93bb489 100644
--- a/src/components/PluginSettings/index.tsx
+++ b/src/components/PluginSettings/index.tsx
@@ -16,26 +16,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import * as DataStore from "@api/DataStore";
import { showNotice } from "@api/Notices";
import { Settings, useSettings } from "@api/settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { ErrorCard } from "@components/ErrorCard";
import { Flex } from "@components/Flex";
import { handleComponentFailed } from "@components/handleComponentFailed";
+import { Badge } from "@components/PluginSettings/components";
+import PluginModal from "@components/PluginSettings/PluginModal";
+import * as styles from "@components/PluginSettings/styles";
import { ChangeList } from "@utils/ChangeList";
import Logger from "@utils/Logger";
-import { classes, LazyComponent } from "@utils/misc";
+import { classes, LazyComponent, useAwaiter } from "@utils/misc";
import { openModalLazy } from "@utils/modal";
import { Plugin } from "@utils/types";
import { findByCode, findByPropsLazy } from "@webpack";
import { Alerts, Button, Forms, Margins, Parser, React, Select, Switch, Text, TextInput, Toasts, Tooltip } from "@webpack/common";
+import { startDependenciesRecursive, startPlugin, stopPlugin } from "plugins";
import Plugins from "~plugins";
-import { startDependenciesRecursive, startPlugin, stopPlugin } from "../../plugins";
-import PluginModal from "./PluginModal";
-import * as styles from "./styles";
-
const logger = new Logger("PluginSettings", "#a6d189");
const InputStyles = findByPropsLazy("inputDefault", "inputWrapper");
@@ -78,9 +79,10 @@ interface PluginCardProps extends React.HTMLProps<HTMLDivElement> {
plugin: Plugin;
disabled: boolean;
onRestartNeeded(name: string): void;
+ isNew?: boolean;
}
-function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave }: PluginCardProps) {
+function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLeave, isNew }: PluginCardProps) {
const settings = useSettings();
const pluginSettings = settings.plugins[plugin.name];
@@ -162,8 +164,15 @@ function PluginCard({ plugin, disabled, onRestartNeeded, onMouseEnter, onMouseLe
</Text>}
hideBorder={true}
>
- <Flex style={{ marginTop: "auto", width: "100%", height: "100%", alignItems: "center" }}>
- <Text variant="text-md/bold" style={{ flexGrow: "1" }}>{plugin.name}</Text>
+ <Flex style={{ marginTop: "auto", width: "100%", height: "100%", alignItems: "center", gap: "8px" }}>
+ <Text
+ variant="text-md/bold"
+ style={{
+ display: "flex", width: "100%", alignItems: "center", flexGrow: "1", gap: "8px"
+ }}
+ >
+ {plugin.name}{(isNew) && <Badge text="NEW" color="#ED4245" />}
+ </Text>
<button role="switch" onClick={() => openModal()} style={styles.SettingsIcon} className="button-12Fmur">
{plugin.options
? <CogWheel
@@ -243,6 +252,23 @@ export default ErrorBoundary.wrap(function Settings() {
);
};
+ const [newPlugins] = useAwaiter(() => DataStore.get("Vencord_existingPlugins").then((cachedPlugins: Record<string, number> | undefined) => {
+ const now = Date.now() / 1000;
+ const existingTimestamps: Record<string, number> = {};
+ const sortedPluginNames = Object.values(sortedPlugins).map(plugin => plugin.name);
+
+ const newPlugins: string[] = [];
+ for (const { name: p } of sortedPlugins) {
+ const time = existingTimestamps[p] = cachedPlugins?.[p] ?? now;
+ if ((time + 60 * 60 * 24 * 2) > now) {
+ newPlugins.push(p);
+ }
+ }
+ DataStore.set("Vencord_existingPlugins", existingTimestamps);
+
+ return window._.isEqual(newPlugins, sortedPluginNames) ? [] : newPlugins;
+ }));
+
return (
<Forms.FormSection>
<Forms.FormTitle tag="h5" className={classes(Margins.marginTop20, Margins.marginBottom8)}>
@@ -281,6 +307,7 @@ export default ErrorBoundary.wrap(function Settings() {
onRestartNeeded={name => changes.add(name)}
disabled={plugin.required || !!dependency}
plugin={plugin}
+ isNew={newPlugins?.includes(plugin.name)}
key={plugin.name}
/>;
})
diff --git a/src/components/PluginSettings/styles.ts b/src/components/PluginSettings/styles.ts
index 703c579..5621b76 100644
--- a/src/components/PluginSettings/styles.ts
+++ b/src/components/PluginSettings/styles.ts
@@ -29,7 +29,7 @@ export const PluginsGridItem: React.CSSProperties = {
borderRadius: 3,
cursor: "pointer",
display: "block",
- height: "min-content",
+ height: "100%",
padding: 10,
width: "100%",
};
@@ -48,3 +48,14 @@ export const SettingsIcon: React.CSSProperties = {
background: "transparent",
marginRight: 8
};
+
+export const BadgeStyle: React.CSSProperties = {
+ padding: "0 6px",
+ fontFamily: "var(--font-display)",
+ fontWeight: "500",
+ borderRadius: "8px",
+ height: "16px",
+ fontSize: "12px",
+ lineHeight: "16px",
+ color: "var(--white-500)",
+};