cool changes (#682)

* BetterUserArea: fix some stuff

* bleh

* add better update notification

* wau

* HeaderBarApi: fix new style
This commit is contained in:
prism 2026-01-25 17:04:05 +01:00 • committed by GitHub
parent 795cfcb7fe
commit 2c2df3b0d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 26 deletions

View file

@ -36,6 +36,7 @@ import { createAndAppendStyle } from "@utils/css";
import { StartAt } from "@utils/types";
import { get as dsGet } from "./api/DataStore";
import { showNotice } from "./api/Notices";
import { NotificationData, showNotification } from "./api/Notifications";
import { initPluginManager, PMLogger, startAllPlugins } from "./api/PluginManager";
import { PlainSettings, Settings, SettingsStore } from "./api/Settings";
@ -145,20 +146,26 @@ async function runUpdateCheck() {
if (Settings.autoUpdate) {
await update();
if (Settings.autoUpdateNotification) {
notify({
title: "Equicord has been updated!",
body: "Click here to restart",
onClick: relaunch
});
if (notifiedForUpdatesThisSession) return;
notifiedForUpdatesThisSession = true;
showNotice(
"Equicord has been updated!",
"Restart",
relaunch
);
}
return;
}
notify({
title: "A Equicord update is available!",
body: "Click here to view the update",
onClick: () => openSettingsTabModal(UpdaterTab!)
});
if (notifiedForUpdatesThisSession) return;
notifiedForUpdatesThisSession = true;
showNotice(
"A new version of Equicord is available!",
"View Update",
() => openSettingsTabModal(UpdaterTab!)
);
} catch (err) {
UpdateLogger.error("Failed to check for updates", err);
}

View file

@ -6,13 +6,15 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { Logger } from "@utils/Logger";
import { findComponentByCodeLazy } from "@webpack";
import { useEffect, useState } from "@webpack/common";
import { classes } from "@utils/misc";
import { findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { Clickable, Tooltip, useEffect, useState } from "@webpack/common";
import type { ComponentType, JSX, MouseEventHandler, ReactNode } from "react";
const logger = new Logger("HeaderBarAPI");
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '"aria-haspopup":') as ComponentType<HeaderBarButtonProps>;
const HeaderBarClasses = findCssClassesLazy("clickable", "withHighlight");
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '"aria-haspopup":') as ComponentType<ChannelToolbarButtonProps>;
export interface HeaderBarButtonProps {
/** The icon component to render inside the button */
@ -25,6 +27,17 @@ export interface HeaderBarButtonProps {
onContextMenu?: MouseEventHandler<HTMLDivElement>;
/** Additional CSS class names */
className?: string;
/** Size of the icon in pixels */
iconSize?: number;
/** Tooltip position relative to the button */
position?: "top" | "bottom" | "left" | "right";
/** Whether the button appears in a selected/active state */
selected?: boolean;
/** Aria label for accessibility */
"aria-label"?: string;
}
export interface ChannelToolbarButtonProps extends HeaderBarButtonProps {
/** CSS class name for the icon element */
iconClassName?: string;
/** Tooltip position relative to the button */
@ -37,10 +50,6 @@ export interface HeaderBarButtonProps {
showBadge?: boolean;
/** Position of the notification badge */
badgePosition?: "top" | "bottom";
/** Size of the icon in pixels */
iconSize?: number;
/** Ref to the button element */
ref?: React.RefObject<any>;
}
export type HeaderBarButtonFactory = () => JSX.Element | null;
@ -71,7 +80,41 @@ interface ButtonEntry {
* onClick={() => console.log("clicked")}
* />
*/
export const HeaderBarButton = HeaderBarIcon;
export function HeaderBarButton(props: HeaderBarButtonProps & { ref?: React.RefObject<any>; }) {
const {
icon: Icon,
tooltip,
onClick,
onContextMenu,
className,
iconSize = 18,
position = "bottom",
selected,
ref,
"aria-label": ariaLabel,
} = props;
const label = ariaLabel ?? (typeof tooltip === "string" ? tooltip : undefined);
return (
<Tooltip text={tooltip ?? ""} position={position} shouldShow={tooltip != null}>
{() => (
<Clickable
{...{ innerRef: ref } as any}
className={classes(HeaderBarClasses.clickable, HeaderBarClasses.withHighlight, className)}
onClick={onClick}
onContextMenu={onContextMenu}
role="button"
tabIndex={0}
aria-label={label}
aria-expanded={selected}
>
<Icon size="custom" width={iconSize} height={iconSize} color="currentColor" />
</Clickable>
)}
</Tooltip>
);
}
/**
* Button component for the channel toolbar (below the search bar).
@ -85,7 +128,7 @@ export const HeaderBarButton = HeaderBarIcon;
* selected={isOpen}
* />
*/
export function ChannelToolbarButton(props: HeaderBarButtonProps) {
export function ChannelToolbarButton(props: ChannelToolbarButtonProps) {
return <HeaderBarIcon {...props} />;
}

View file

@ -65,12 +65,19 @@ export default definePlugin({
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
replacement: [
{
match: /(?<=#{intl::MUTE}\),)className:\i\.\i,/g,
match: /(?<=#{intl::MUTE}\),)className:\i\.\i,/,
replace: ""
},
{
// TODO: MAKE THIS BETTER
match: /,\(0,\i\.jsxs?\).{0,130}#{intl::18wnuD::raw}.{0,530}\}\)(?=\])/g,
match: /(?<=#{intl::DEAFEN}\),)className:\i\.\i,/,
replace: ""
},
{
match: /,\(0,\i\.jsxs?\)\(\i\.\i,\{.{0,600}#{intl::ACCOUNT_INPUT_OPTIONS}\)\}\)(?=\])/,
replace: ""
},
{
match: /,\(0,\i\.jsxs?\)\(\i\.\i,\{.{0,650}#{intl::ACCOUNT_OUTPUT_OPTIONS}\)\}\)(?=\])/,
replace: ""
}
],
@ -86,10 +93,20 @@ export default definePlugin({
},
{
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
replacement: {
match: /tooltipText:\i,/g,
replace: "tooltipText:void 0,"
},
replacement: [
{
match: /:\{tooltipText:\i\};/,
replace: ":{tooltipText:void 0};"
},
{
match: /(?<=role:"switch",)tooltipText:\i\}/,
replace: "tooltipText:void 0}"
},
{
match: /(?<=useRef\(null\);)(\i)=.{0,100}#{intl::USER_SETTINGS}\);/,
replace: "$1=void 0;"
}
],
predicate: () => settings.store.removeButtonTooltips
},
{