fix BetterSessions (#4249)

This commit is contained in:
thororen 2026-05-27 22:44:45 -04:00 • committed by GitHub
parent 596bfff94e
commit a50ab50caf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 80 additions and 48 deletions

View file

@ -6,6 +6,7 @@
import { Button } from "@components/Button";
import { SessionInfo } from "@plugins/betterSessions/types";
import { cl } from "@plugins/betterSessions/utils";
import { openModal } from "@webpack/common";
import { RenameModal } from "./RenameModal";
@ -15,7 +16,7 @@ export function RenameButton({ session, state }: { session: SessionInfo["session
<Button
variant="secondary"
size="xs"
className="vc-betterSessions-rename-btn"
className={cl("rename-btn")}
onClick={() =>
openModal(props => (
<RenameModal
@ -36,7 +37,7 @@ export function NewButton() {
<Button
variant="dangerPrimary"
size="min"
className="vc-betterSessions-new-btn"
className={cl("new-btn")}
>
NEW
</Button>

View file

@ -21,6 +21,7 @@ import "./styles.css";
import { showNotification } from "@api/Notifications";
import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Paragraph } from "@components/Paragraph";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy, findCssClassesLazy, findStoreLazy } from "@webpack";
@ -28,13 +29,10 @@ import { Constants, React, RestAPI, SettingsRouter, Tooltip } from "@webpack/com
import { NewButton, RenameButton } from "./components/RenameButton";
import { Session, SessionInfo } from "./types";
import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
import { cl, fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
const AuthSessionsStore = findStoreLazy("AuthSessionsStore");
const TimestampClasses = findCssClassesLazy("timestamp", "blockquoteContainer");
const SessionIconClasses = findCssClassesLazy("sessionIcon");
const BlobMask = findComponentByCodeLazy("!1,lowerBadgeSize:");
const settings = definePluginSettings({
@ -61,24 +59,26 @@ export default definePlugin({
patches: [
{
find: "#{intl::AUTH_SESSIONS_SESSION_LOG_OUT}",
find: "#{intl::AUTH_SESSIONS_OS_UNKNOWN}",
replacement: [
// Replace children with a single label with state
{
match: /({variant:"eyebrow",className:\i\.\i,children:).{70,110}{children:"\\xb7"}\),\(0,\i\.\i\)\("span",{children:\i\[\d+\]}\)\]}\)\]/,
replace: "$1$self.renderName(arguments[0])"
match: /(#{intl::AUTH_SESSIONS_ACTIVE_RECENTLY}.{0,230}role:"listitem",children:\[.{0,15},\{Icon:)\i/,
replace: "$1()=>$self.renderIcon(arguments[0])"
},
{
match: /({variant:"text-sm\/medium",className:\i\.\i,children:.{70,110}{children:"\\xb7"}\),\(0,\i\.\i\)\("span",{children:)(\i\[\d+\])}/,
replace: "$1$self.renderTimestamp({...arguments[0],timeLabel:$2})}"
match: /("horizontal",gap:"xs",children:)\[.{0,250}"text-subtle",children:\i\}\)\]\}\),/,
replace: "$1$self.renderName(arguments[0])}),"
},
// Replace the icon
{
match: /(?<=Icon:(\i).{0,250}className:\i\.\i,children:\[)/,
replace: "$self.renderIcon({...arguments[0],DeviceIcon:$1}),false&&"
}
match: /("text-muted",children:)\i(?=\}\)\]\}\),.{0,120}\.client_info\?\.location)/,
replace: "$1$self.renderDescription(arguments[0])"
},
{
match: /:\i\(\i\.approx_last_used_time\).{0,40}\(0,\i\.jsxs?\)\(\i,\{/,
replace: "$&session:arguments[0]?.session,"
},
]
}
},
],
renderName: ErrorBoundary.wrap(({ session }: SessionInfo) => {
@ -86,32 +86,43 @@ export default definePlugin({
const state = React.useState(savedSession?.name ? `${savedSession.name}*` : getDefaultName(session.client_info));
const [title, setTitle] = state;
// Show a "NEW" badge if the session is seen for the first time
return (
<>
<span>{title}</span>
{(savedSession == null || savedSession.isNew) && (
<NewButton />
)}
<RenameButton session={session} state={state} />
<Paragraph size="md" weight="semibold" color="text-strong">{title}</Paragraph>
<div className={cl("footer-buttons")}>
{(savedSession == null || savedSession.isNew) && (
<NewButton />
)}
<RenameButton session={session} state={state} />
</div>
</>
);
}, { noop: true }),
renderTimestamp: ErrorBoundary.wrap(({ session, timeLabel }: { session: Session, timeLabel: string; }) => {
renderDescription: ErrorBoundary.wrap(({ session, description }: { session: Session, description: string; }) => {
const [label, timeLabel] = description.split(" \xb7 ");
return (
<Tooltip text={session.approx_last_used_time.toLocaleString()}>
{props => (
<span {...props} className={TimestampClasses.timestamp}>
{timeLabel}
</span>
<div className={cl("description")}>
<Paragraph size="sm" weight="normal" color="text-muted">{label}</Paragraph>
{timeLabel && (
<>
{" \xb7 "}
<Tooltip text={session.approx_last_used_time.toLocaleString()}>
{props => (
<span {...props} className={TimestampClasses.timestamp}>
{timeLabel}
</span>
)}
</Tooltip>
</>
)}
</Tooltip>
</div>
);
}, { noop: true }),
renderIcon: ErrorBoundary.wrap(({ session, DeviceIcon }: { session: Session, DeviceIcon: React.ComponentType<any>; }) => {
renderIcon: ErrorBoundary.wrap(({ session, icon: DeviceIcon }: { session: Session; icon: React.ComponentType<any>; }) => {
const PlatformIcon = GetPlatformIcon(session.client_info.platform);
return (
@ -120,22 +131,8 @@ export default definePlugin({
style={{ cursor: "unset" }}
selected={false}
lowerBadge={
<div
style={{
width: "20px",
height: "20px",
display: "flex",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
borderRadius: "50%",
backgroundColor: "var(--interactive-icon-default)",
color: "var(--background-base-lower)",
}}
>
<PlatformIcon width={14} height={14} />
<div className={cl("lowerBadge")}>
<PlatformIcon width={14} height={14} className={cl("lowerBadge-icon")} />
</div>
}
lowerBadgeSize={{
@ -144,7 +141,7 @@ export default definePlugin({
}}
>
<div
className={SessionIconClasses.sessionIcon}
className={cl("icon")}
style={{ backgroundColor: GetOsColor(session.client_info.os) }}
>
<DeviceIcon size="md" color="currentColor" />

View file

@ -2,6 +2,8 @@
display: flex;
gap: 0.5em;
align-items: center;
justify-content: center;
margin-top: 2px;
}
.vc-betterSessions-rename-btn {
@ -14,4 +16,34 @@
translate: 0 -2px;
pointer-events: none;
padding: 1px 4px;
}
.vc-betterSessions-lowerBadge {
width: 20px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 50%;
background-color: var(--interactive-icon-default);
color: var(--background-base-lower);
}
.vc-betterSessions-lowerBadge-icon {
display: block;
}
.vc-betterSessions-icon {
align-items: center;
border-radius: var(--radius-sm);
display: flex;
height: 48px;
justify-content: center;
width: 48px
}
.vc-betterSessions-description {
display: flex;
gap: 4px;
}

View file

@ -17,6 +17,7 @@
*/
import * as DataStore from "@api/DataStore";
import { classNameFactory } from "@utils/css";
import { UserStore } from "@webpack/common";
import { ChromeIcon, DiscordIcon, EdgeIcon, FirefoxIcon, IEIcon, MobileIcon, OperaIcon, SafariIcon, UnknownIcon } from "./components/icons";
@ -24,6 +25,7 @@ import { SessionInfo } from "./types";
const getDataKey = () => `BetterSessions_savedSessions_${UserStore.getCurrentUser().id}`;
export const cl = classNameFactory("vc-betterSessions-");
export const savedSessionsCache: Map<string, { name: string, isNew: boolean; }> = new Map();
export function getDefaultName(clientInfo: SessionInfo["session"]["client_info"]) {