Updater: show update dialog instead of forcing updates (#1184)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
import "./screenSharePicker.css";
|
||||
|
||||
import { classNameFactory } from "@vencord/types/api/Styles";
|
||||
import { FormSwitch } from "@vencord/types/components";
|
||||
import { closeModal, Logger, Modals, ModalSize, openModal, useAwaiter } from "@vencord/types/utils";
|
||||
import { onceReady } from "@vencord/types/webpack";
|
||||
@@ -15,7 +16,7 @@ import type { Dispatch, SetStateAction } from "react";
|
||||
import { MediaEngineStore } from "renderer/common";
|
||||
import { addPatch } from "renderer/patches/shared";
|
||||
import { State, useSettings, useVesktopState } from "renderer/settings";
|
||||
import { classNameFactory, isLinux, isWindows } from "renderer/utils";
|
||||
import { isLinux, isWindows } from "renderer/utils";
|
||||
|
||||
const StreamResolutions = ["480", "720", "1080", "1440", "2160"] as const;
|
||||
const StreamFps = ["15", "30", "60"] as const;
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
import { Button, Forms, Text, Toasts } from "@vencord/types/webpack/common";
|
||||
import { Settings } from "shared/settings";
|
||||
|
||||
import { SettingsComponent } from "./Settings";
|
||||
import { cl, SettingsComponent } from "./Settings";
|
||||
|
||||
export const DeveloperOptionsButton: SettingsComponent = ({ settings }) => {
|
||||
return <Button onClick={() => openDeveloperOptionsModal(settings)}>Open Developer Settings</Button>;
|
||||
@@ -41,7 +41,7 @@ function openDeveloperOptionsModal(settings: Settings) {
|
||||
<Forms.FormTitle tag="h5" className={Margins.top16}>
|
||||
Debugging
|
||||
</Forms.FormTitle>
|
||||
<div className="vcd-settings-button-grid">
|
||||
<div className={cl("button-grid")}>
|
||||
<Button onClick={() => VesktopNative.debug.launchGpu()}>Open chrome://gpu</Button>
|
||||
<Button onClick={() => VesktopNative.debug.launchWebrtcInternals()}>
|
||||
Open chrome://webrtc-internals
|
||||
@@ -75,7 +75,7 @@ const VencordLocationPicker: SettingsComponent = ({ settings }) => {
|
||||
"the default location"
|
||||
)}
|
||||
</Forms.FormText>
|
||||
<div className="vcd-settings-button-grid">
|
||||
<div className={cl("button-grid")}>
|
||||
<Button
|
||||
size={Button.Sizes.SMALL}
|
||||
onClick={async () => {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import "./settings.css";
|
||||
|
||||
import { classNameFactory } from "@vencord/types/api/Styles";
|
||||
import { ErrorBoundary } from "@vencord/types/components";
|
||||
import { Forms, Text } from "@vencord/types/webpack/common";
|
||||
import { ComponentType } from "react";
|
||||
@@ -16,6 +17,7 @@ import { AutoStartToggle } from "./AutoStartToggle";
|
||||
import { DeveloperOptionsButton } from "./DeveloperOptions";
|
||||
import { DiscordBranchPicker } from "./DiscordBranchPicker";
|
||||
import { NotificationBadgeToggle } from "./NotificationBadgeToggle";
|
||||
import { Updater } from "./Updater";
|
||||
import { UserAssetsButton } from "./UserAssets";
|
||||
import { VesktopSettingsSwitch } from "./VesktopSettingsSwitch";
|
||||
import { WindowsTransparencyControls } from "./WindowsTransparencyControls";
|
||||
@@ -29,6 +31,8 @@ interface BooleanSetting {
|
||||
invisible?(): boolean;
|
||||
}
|
||||
|
||||
export const cl = classNameFactory("vcd-settings-");
|
||||
|
||||
export type SettingsComponent = ComponentType<{ settings: typeof Settings.store }>;
|
||||
|
||||
const SettingsOptions: Record<string, Array<BooleanSetting | SettingsComponent>> = {
|
||||
@@ -144,12 +148,12 @@ function SettingsSections() {
|
||||
const Settings = useSettings();
|
||||
|
||||
const sections = Object.entries(SettingsOptions).map(([title, settings], i, arr) => (
|
||||
<div key={title} className="vcd-settings-category">
|
||||
<Text variant="heading-lg/semibold" color="header-primary" className="vcd-settings-category-title">
|
||||
<div key={title} className={cl("category")}>
|
||||
<Text variant="heading-lg/semibold" color="header-primary" className={cl("category-title")}>
|
||||
{title}
|
||||
</Text>
|
||||
|
||||
<div className="vcd-settings-category-content">
|
||||
<div className={cl("category-content")}>
|
||||
{settings.map(Setting => {
|
||||
if (typeof Setting === "function") return <Setting settings={Settings} />;
|
||||
|
||||
@@ -169,7 +173,7 @@ function SettingsSections() {
|
||||
})}
|
||||
</div>
|
||||
|
||||
{i < arr.length - 1 && <Forms.FormDivider className="vcd-settings-category-divider" />}
|
||||
{i < arr.length - 1 && <Forms.FormDivider className={cl("category-divider")} />}
|
||||
</div>
|
||||
));
|
||||
|
||||
@@ -180,9 +184,10 @@ export default ErrorBoundary.wrap(
|
||||
function SettingsUI() {
|
||||
return (
|
||||
<section>
|
||||
<Text variant="heading-xl/semibold" color="header-primary" className="vcd-settings-title">
|
||||
<Text variant="heading-xl/semibold" color="header-primary" className={cl("title")}>
|
||||
Vesktop Settings
|
||||
</Text>
|
||||
<Updater />
|
||||
<SettingsSections />
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
|
||||
* Copyright (c) 2025 Vendicated and Vesktop contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { useAwaiter } from "@vencord/types/utils";
|
||||
import { Button, Text } from "@vencord/types/webpack/common";
|
||||
|
||||
import { cl } from "./Settings";
|
||||
|
||||
export function Updater() {
|
||||
const [isOutdated] = useAwaiter(VesktopNative.app.isOutdated);
|
||||
|
||||
if (!isOutdated) return null;
|
||||
|
||||
return (
|
||||
<div className={cl("updater-card")}>
|
||||
<Text variant="text-md/semibold">Your Vesktop is outdated!</Text>
|
||||
<Text variant="text-sm/normal">Staying up to date is important for security and stability.</Text>
|
||||
|
||||
<Button
|
||||
onClick={() => VesktopNative.app.openUpdater()}
|
||||
size={Button.Sizes.SMALL}
|
||||
color={Button.Colors.TRANSPARENT}
|
||||
>
|
||||
Open Updater
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
import { FormSwitch } from "@vencord/types/components";
|
||||
import { ComponentProps } from "react";
|
||||
|
||||
import { cl } from "./Settings";
|
||||
|
||||
export function VesktopSettingsSwitch(props: ComponentProps<typeof FormSwitch>) {
|
||||
return <FormSwitch {...props} hideBorder className="vcd-settings-switch" />;
|
||||
return <FormSwitch {...props} hideBorder className={cl("switch")} />;
|
||||
}
|
||||
|
||||
@@ -31,4 +31,17 @@
|
||||
|
||||
.vcd-settings-switch {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.vcd-settings-updater-card {
|
||||
padding: 1em;
|
||||
margin-bottom: 1em;
|
||||
display: grid;
|
||||
gap: 0.5em;
|
||||
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg-secondary);
|
||||
background: var(--background-feedback-warning);
|
||||
border: 1px solid var(--info-warning-foreground);
|
||||
color: var(--text-feedback-warning);
|
||||
}
|
||||
@@ -19,26 +19,3 @@ const { platform } = navigator;
|
||||
export const isWindows = platform.startsWith("Win");
|
||||
export const isMac = platform.startsWith("Mac");
|
||||
export const isLinux = platform.startsWith("Linux");
|
||||
|
||||
type ClassNameFactoryArg = string | string[] | Record<string, unknown> | false | null | undefined | 0 | "";
|
||||
/**
|
||||
* @param prefix The prefix to add to each class, defaults to `""`
|
||||
* @returns A classname generator function
|
||||
* @example
|
||||
* const cl = classNameFactory("plugin-");
|
||||
*
|
||||
* cl("base", ["item", "editable"], { selected: null, disabled: true })
|
||||
* // => "plugin-base plugin-item plugin-editable plugin-disabled"
|
||||
*/
|
||||
export const classNameFactory =
|
||||
(prefix: string = "") =>
|
||||
(...args: ClassNameFactoryArg[]) => {
|
||||
const classNames = new Set<string>();
|
||||
for (const arg of args) {
|
||||
if (arg && typeof arg === "string") classNames.add(arg);
|
||||
else if (Array.isArray(arg)) arg.forEach(name => classNames.add(name));
|
||||
else if (arg && typeof arg === "object")
|
||||
Object.entries(arg).forEach(([name, value]) => value && classNames.add(name));
|
||||
}
|
||||
return Array.from(classNames, name => prefix + name).join(" ");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user