From 7979ec3008ad6ecce746757f97f72aad9aa5b472 Mon Sep 17 00:00:00 2001 From: yofukashino Date: Sat, 31 Aug 2024 13:36:43 +0530 Subject: [PATCH 1/6] works --- src/globals.d.ts | 1 + src/main/index.ts | 7 +++++- .../coremods/settings/pages/General.tsx | 19 ++++++++++++++ .../coremods/titlebar/plaintextPatches.ts | 25 +++++++++++++++++++ src/renderer/managers/coremods.ts | 2 ++ src/types/settings.ts | 2 ++ 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/renderer/coremods/titlebar/plaintextPatches.ts diff --git a/src/globals.d.ts b/src/globals.d.ts index f40d51cf5..59e6ca096 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -37,6 +37,7 @@ declare global { paste: () => void; read: () => string; }; + process: { platform: string }; }; export const _: typeof Lodash; diff --git a/src/main/index.ts b/src/main/index.ts index acbb2dc45..ce282bee3 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -8,7 +8,10 @@ import { getSetting } from "./ipc/settings"; const electronPath = require.resolve("electron"); const discordPath = join(dirname(require.main!.filename), "..", "app.orig.asar"); // require.main!.filename = discordMain; - +let customTitlebar: boolean; +void getSetting("dev.replugged.Settings", "titlebar", false).then( + (titlebar) => (customTitlebar = titlebar), +); Object.defineProperty(global, "appSettings", { set: (v /* : typeof global.appSettings*/) => { // cspell:ignore youre @@ -34,6 +37,8 @@ class BrowserWindow extends electron.BrowserWindow { }; }, ) { + if (opts.frame && process.platform.includes("linux") && customTitlebar) opts.frame = void 0; + const originalPreload = opts.webPreferences?.preload; if (opts.webContents) { diff --git a/src/renderer/coremods/settings/pages/General.tsx b/src/renderer/coremods/settings/pages/General.tsx index ca98f3579..3908f8b8a 100644 --- a/src/renderer/coremods/settings/pages/General.tsx +++ b/src/renderer/coremods/settings/pages/General.tsx @@ -57,6 +57,10 @@ export const General = (): React.ReactElement => { "reactDevTools", ); + const { value: titlebarValue, onChange: titlebarOnChange } = util.useSetting( + generalSettings, + "titlebar", + ); const [kKeys, setKKeys] = React.useState([]); const isEasterEgg = kKeys.toString().includes(konamiCode.join(",")); @@ -109,6 +113,21 @@ export const General = (): React.ReactElement => { {Messages.REPLUGGED_SETTINGS_QUICKCSS_AUTO_APPLY} + { + // TODO: i18n + DiscordNative.process.platform.includes("linux") && ( + { + titlebarOnChange(value); + restartModal(false); + }} + note={"Use custom window titlebars instead of the default OS titlebars"}> + Custom Titlebar + + ) + } + diff --git a/src/renderer/coremods/titlebar/plaintextPatches.ts b/src/renderer/coremods/titlebar/plaintextPatches.ts new file mode 100644 index 000000000..85a04fb82 --- /dev/null +++ b/src/renderer/coremods/titlebar/plaintextPatches.ts @@ -0,0 +1,25 @@ +import { init } from "src/renderer/apis/settings"; +import { type GeneralSettings, type PlaintextPatch, defaultSettings } from "src/types"; + +const generalSettings = await init( + "dev.replugged.Settings", + defaultSettings, +); + +export default (DiscordNative.process.platform.includes("linux") && generalSettings.get("titlebar") + ? [ + { + find: "macOSFrame:!0", + replacements: [ + { + match: /\[.&&(null!=.\?)/, + replace: (_, suffix: string) => `[${suffix}`, + }, + ], + }, + { + find: "renderWindow:window", + replacements: [{ match: /\(0,.\.getPlatform\)\(\)/, replace: () => `"WINDOWS"` }], + }, + ] + : []) as PlaintextPatch[]; diff --git a/src/renderer/managers/coremods.ts b/src/renderer/managers/coremods.ts index e975c24ab..6ba48ea8f 100644 --- a/src/renderer/managers/coremods.ts +++ b/src/renderer/managers/coremods.ts @@ -11,6 +11,7 @@ import { default as languagePlaintext } from "../coremods/language/plaintextPatc import { default as commandsPlaintext } from "../coremods/commands/plaintextPatches"; import { default as settingsPlaintext } from "../coremods/settings/plaintextPatches"; import { default as badgesPlaintext } from "../coremods/badges/plaintextPatches"; +import { default as titlebarPlaintext } from "../coremods/titlebar/plaintextPatches"; import { Logger } from "../modules/logger"; const logger = Logger.api("Coremods"); @@ -89,5 +90,6 @@ export function runPlaintextPatches(): void { commandsPlaintext, settingsPlaintext, badgesPlaintext, + titlebarPlaintext, ].forEach(patchPlaintext); } diff --git a/src/types/settings.ts b/src/types/settings.ts index 374d349fe..aa637d131 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -14,6 +14,7 @@ export type GeneralSettings = { showWelcomeNoticeOnOpen?: boolean; addonEmbeds?: boolean; reactDevTools?: boolean; + titlebar?: boolean; }; export const defaultSettings = { @@ -24,4 +25,5 @@ export const defaultSettings = { showWelcomeNoticeOnOpen: true, reactDevTools: false, addonEmbeds: true, + titlebar: false, } satisfies Partial; From f441acff93d88cc6faf49f3c94cae2f4e1b36b9c Mon Sep 17 00:00:00 2001 From: yofukashino Date: Sat, 31 Aug 2024 13:44:08 +0530 Subject: [PATCH 2/6] cspell --- cspell.json | 1 + src/renderer/apis/settings.ts | 4 ++-- src/renderer/coremods/commands/commands.ts | 8 ++++---- src/renderer/coremods/settings/pages/General.tsx | 2 +- src/renderer/coremods/settings/pages/Updater.tsx | 5 +++-- src/renderer/util.ts | 13 +++++++------ 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/cspell.json b/cspell.json index ec580088b..156d786de 100644 --- a/cspell.json +++ b/cspell.json @@ -59,6 +59,7 @@ "signingkey", "Skema", "skus", + "titlebar", "uninject", "uninjector", "uninjectors", diff --git a/src/renderer/apis/settings.ts b/src/renderer/apis/settings.ts index 93708dd52..2cdfd9a51 100644 --- a/src/renderer/apis/settings.ts +++ b/src/renderer/apis/settings.ts @@ -57,8 +57,8 @@ export class SettingsManager, D extends ke ): K extends D ? NonNullable : F extends null | undefined - ? T[K] | undefined - : NonNullable | F { + ? T[K] | undefined + : NonNullable | F { if (typeof this.#settings === "undefined") { throw new Error(`Settings not loaded for namespace ${this.namespace}`); } diff --git a/src/renderer/coremods/commands/commands.ts b/src/renderer/coremods/commands/commands.ts index 7665c1f12..7377fe0f0 100644 --- a/src/renderer/coremods/commands/commands.ts +++ b/src/renderer/coremods/commands/commands.ts @@ -351,8 +351,8 @@ export function loadCommands(): void { listType === "enabled" ? enabledString : listType === "disabled" - ? disabledString - : `${enabledString}\n\n${disabledString}`; + ? disabledString + : `${enabledString}\n\n${disabledString}`; return { send, @@ -383,8 +383,8 @@ export function loadCommands(): void { listType === "enabled" ? enabledString : listType === "disabled" - ? disabledString - : `${enabledString}\n\n${disabledString}`; + ? disabledString + : `${enabledString}\n\n${disabledString}`; return { send, diff --git a/src/renderer/coremods/settings/pages/General.tsx b/src/renderer/coremods/settings/pages/General.tsx index 3908f8b8a..824536835 100644 --- a/src/renderer/coremods/settings/pages/General.tsx +++ b/src/renderer/coremods/settings/pages/General.tsx @@ -122,7 +122,7 @@ export const General = (): React.ReactElement => { titlebarOnChange(value); restartModal(false); }} - note={"Use custom window titlebars instead of the default OS titlebars"}> + note={"Use custom window titlebar instead of the default OS titlebar"}> Custom Titlebar ) diff --git a/src/renderer/coremods/settings/pages/Updater.tsx b/src/renderer/coremods/settings/pages/Updater.tsx index 9473d39c7..f56d2b97d 100644 --- a/src/renderer/coremods/settings/pages/Updater.tsx +++ b/src/renderer/coremods/settings/pages/Updater.tsx @@ -22,8 +22,9 @@ const logger = Logger.coremod("Settings:Updater"); export const Updater = (): React.ReactElement => { const [checking, setChecking] = React.useState(false); - const [updatesAvailable, setUpdatesAvailable] = - React.useState>(getAvailableUpdates()); + const [updatesAvailable, setUpdatesAvailable] = React.useState< + Array + >(getAvailableUpdates()); const [updatePromises, setUpdatePromises] = React.useState>>({}); const [didInstallAll, setDidInstallAll] = React.useState(false); const [lastChecked, setLastChecked] = useSettingArray(updaterSettings, "lastChecked"); diff --git a/src/renderer/util.ts b/src/renderer/util.ts index b79a6ccc2..3ffed1f32 100644 --- a/src/renderer/util.ts +++ b/src/renderer/util.ts @@ -197,8 +197,8 @@ export function useSetting< value: K extends D ? NonNullable : F extends null | undefined - ? T[K] | undefined - : NonNullable | F; + ? T[K] | undefined + : NonNullable | F; onChange: (newValue: ValType) => void; } { const initial = settings.get(key, fallback); @@ -237,8 +237,8 @@ export function useSettingArray< K extends D ? NonNullable : F extends null | undefined - ? T[K] | undefined - : NonNullable | F, + ? T[K] | undefined + : NonNullable | F, (newValue: ValType) => void, ] { const { value, onChange } = useSetting(settings, key, fallback); @@ -256,8 +256,9 @@ type UnionToIntersection = (U extends never ? never : (k: U) => void) extends type ObjectType = Record; -type ExtractObjectType = - O extends Array ? UnionToIntersection : never; +type ExtractObjectType = O extends Array + ? UnionToIntersection + : never; export function virtualMerge(...objects: O): ExtractObjectType { const fallback = {}; From 62f84526355fa92b227c9c896bca4380a067637c Mon Sep 17 00:00:00 2001 From: yofukashino Date: Sat, 31 Aug 2024 14:06:23 +0530 Subject: [PATCH 3/6] prettier --- src/renderer/apis/settings.ts | 4 ++-- src/renderer/coremods/commands/commands.ts | 8 ++++---- src/renderer/coremods/settings/pages/Updater.tsx | 5 ++--- src/renderer/util.ts | 13 ++++++------- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/renderer/apis/settings.ts b/src/renderer/apis/settings.ts index 2cdfd9a51..93708dd52 100644 --- a/src/renderer/apis/settings.ts +++ b/src/renderer/apis/settings.ts @@ -57,8 +57,8 @@ export class SettingsManager, D extends ke ): K extends D ? NonNullable : F extends null | undefined - ? T[K] | undefined - : NonNullable | F { + ? T[K] | undefined + : NonNullable | F { if (typeof this.#settings === "undefined") { throw new Error(`Settings not loaded for namespace ${this.namespace}`); } diff --git a/src/renderer/coremods/commands/commands.ts b/src/renderer/coremods/commands/commands.ts index 7377fe0f0..7665c1f12 100644 --- a/src/renderer/coremods/commands/commands.ts +++ b/src/renderer/coremods/commands/commands.ts @@ -351,8 +351,8 @@ export function loadCommands(): void { listType === "enabled" ? enabledString : listType === "disabled" - ? disabledString - : `${enabledString}\n\n${disabledString}`; + ? disabledString + : `${enabledString}\n\n${disabledString}`; return { send, @@ -383,8 +383,8 @@ export function loadCommands(): void { listType === "enabled" ? enabledString : listType === "disabled" - ? disabledString - : `${enabledString}\n\n${disabledString}`; + ? disabledString + : `${enabledString}\n\n${disabledString}`; return { send, diff --git a/src/renderer/coremods/settings/pages/Updater.tsx b/src/renderer/coremods/settings/pages/Updater.tsx index f56d2b97d..9473d39c7 100644 --- a/src/renderer/coremods/settings/pages/Updater.tsx +++ b/src/renderer/coremods/settings/pages/Updater.tsx @@ -22,9 +22,8 @@ const logger = Logger.coremod("Settings:Updater"); export const Updater = (): React.ReactElement => { const [checking, setChecking] = React.useState(false); - const [updatesAvailable, setUpdatesAvailable] = React.useState< - Array - >(getAvailableUpdates()); + const [updatesAvailable, setUpdatesAvailable] = + React.useState>(getAvailableUpdates()); const [updatePromises, setUpdatePromises] = React.useState>>({}); const [didInstallAll, setDidInstallAll] = React.useState(false); const [lastChecked, setLastChecked] = useSettingArray(updaterSettings, "lastChecked"); diff --git a/src/renderer/util.ts b/src/renderer/util.ts index 3ffed1f32..b79a6ccc2 100644 --- a/src/renderer/util.ts +++ b/src/renderer/util.ts @@ -197,8 +197,8 @@ export function useSetting< value: K extends D ? NonNullable : F extends null | undefined - ? T[K] | undefined - : NonNullable | F; + ? T[K] | undefined + : NonNullable | F; onChange: (newValue: ValType) => void; } { const initial = settings.get(key, fallback); @@ -237,8 +237,8 @@ export function useSettingArray< K extends D ? NonNullable : F extends null | undefined - ? T[K] | undefined - : NonNullable | F, + ? T[K] | undefined + : NonNullable | F, (newValue: ValType) => void, ] { const { value, onChange } = useSetting(settings, key, fallback); @@ -256,9 +256,8 @@ type UnionToIntersection = (U extends never ? never : (k: U) => void) extends type ObjectType = Record; -type ExtractObjectType = O extends Array - ? UnionToIntersection - : never; +type ExtractObjectType = + O extends Array ? UnionToIntersection : never; export function virtualMerge(...objects: O): ExtractObjectType { const fallback = {}; From 235be121152ce0a8aed5dc3120f91b55de1b03d0 Mon Sep 17 00:00:00 2001 From: Federico <38290480+FedeIlLeone@users.noreply.github.com> Date: Sun, 24 Nov 2024 15:28:39 +0100 Subject: [PATCH 4/6] feat: add i18n for title bar --- i18n/en-US.messages.d.ts | 26 +++++++++++++++++++ i18n/en-US.messages.js | 3 +++ .../coremods/settings/pages/General.tsx | 25 ++++++++---------- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/i18n/en-US.messages.d.ts b/i18n/en-US.messages.d.ts index 30e3e1568..477e6444c 100644 --- a/i18n/en-US.messages.d.ts +++ b/i18n/en-US.messages.d.ts @@ -1487,6 +1487,32 @@ declare const messages: { * Missing translations: `ar`, `bg`, `da`, `el`, `he`, `hi`, `hr`, `hu`, `lt`, `no`, `pt-PT`, `ro`, `sv-SE` */ 'REPLUGGED_SETTINGS_BADGES_DESC': TypedIntlMessageGetter<{}>, + /** + * Key: `5D5ltL` + * + * ### Definition + * ```text + * Custom Title Bar + * ``` + * + * ### Problems + * + * Missing translations: `ar`, `bg`, `cs`, `da`, `de`, `el`, `en-GB`, `es-ES`, `fi`, `fr`, `he`, `hi`, `hr`, `hu`, `id`, `it`, `ja`, `ko`, `lt`, `nl`, `no`, `pl`, `pt-BR`, `pt-PT`, `ro`, `ru`, `sk`, `sv-SE`, `tr`, `uk`, `vi`, `zh-CN`, `zh-TW` + */ + 'REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR': TypedIntlMessageGetter<{}>, + /** + * Key: `x5PfoK` + * + * ### Definition + * ```text + * Use Discord's custom title bar instead of the system title bar. **Requires restart**. + * ``` + * + * ### Problems + * + * Missing translations: `ar`, `bg`, `cs`, `da`, `de`, `el`, `en-GB`, `es-ES`, `fi`, `fr`, `he`, `hi`, `hr`, `hu`, `id`, `it`, `ja`, `ko`, `lt`, `nl`, `no`, `pl`, `pt-BR`, `pt-PT`, `ro`, `ru`, `sk`, `sv-SE`, `tr`, `uk`, `vi`, `zh-CN`, `zh-TW` + */ + 'REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR_DESC': TypedIntlMessageGetter<{$b?: HookFunction}>, /** * Key: `RIDq4u` * diff --git a/i18n/en-US.messages.js b/i18n/en-US.messages.js index c9ebe4246..ba6bb42ae 100644 --- a/i18n/en-US.messages.js +++ b/i18n/en-US.messages.js @@ -288,4 +288,7 @@ export default defineMessages({ "****WARNING:**** **Hardware acceleration** may need to be turned **off**. In some cases, you may experience a black background, such as when the window is cut off at the top or bottom due to the monitor resolution, or when the development tools are open and docked.", REPLUGGED_SETTINGS_ERROR_PLUGIN_NAME: "Plugin: {name}", REPLUGGED_STORE: "Store", + REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR: "Custom Title Bar", + REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR_DESC: + "Use Discord's custom title bar instead of the system title bar. **Requires restart**.", }); diff --git a/src/renderer/coremods/settings/pages/General.tsx b/src/renderer/coremods/settings/pages/General.tsx index b64d77e60..87c780d0c 100644 --- a/src/renderer/coremods/settings/pages/General.tsx +++ b/src/renderer/coremods/settings/pages/General.tsx @@ -114,20 +114,17 @@ export const General = (): React.ReactElement => { {intl.string(t.REPLUGGED_SETTINGS_QUICKCSS_AUTO_APPLY)} - { - // TODO: i18n - DiscordNative.process.platform.includes("linux") && ( - { - titlebarOnChange(value); - restartModal(false); - }} - note={"Use custom window titlebar instead of the default OS titlebar"}> - Custom Titlebar - - ) - } + {DiscordNative.process.platform.includes("linux") && ( + { + titlebarOnChange(value); + restartModal(false); + }} + note={intl.format(t.REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR_DESC, {})}> + {intl.string(t.REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR)} + + )} Date: Sun, 24 Nov 2024 15:29:27 +0100 Subject: [PATCH 5/6] fix: title bar on overlay and precise find match --- src/renderer/coremods/titlebar/plaintextPatches.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/renderer/coremods/titlebar/plaintextPatches.ts b/src/renderer/coremods/titlebar/plaintextPatches.ts index 85a04fb82..83b4ef6f4 100644 --- a/src/renderer/coremods/titlebar/plaintextPatches.ts +++ b/src/renderer/coremods/titlebar/plaintextPatches.ts @@ -9,17 +9,13 @@ const generalSettings = await init `[${suffix}`, + match: /\(0,.\.getPlatform\)\(\)/, + replace: `"WINDOWS"`, }, ], }, - { - find: "renderWindow:window", - replacements: [{ match: /\(0,.\.getPlatform\)\(\)/, replace: () => `"WINDOWS"` }], - }, ] : []) as PlaintextPatch[]; From d782dde13043a6723504842aea9379efa82cb810 Mon Sep 17 00:00:00 2001 From: Federico <38290480+FedeIlLeone@users.noreply.github.com> Date: Sun, 24 Nov 2024 15:51:53 +0100 Subject: [PATCH 6/6] style: correct naming --- cspell.json | 1 - src/main/index.ts | 8 ++++---- src/renderer/coremods/settings/pages/General.tsx | 10 +++++----- .../{titlebar => titleBar}/plaintextPatches.ts | 2 +- src/renderer/managers/coremods.ts | 4 ++-- src/types/settings.ts | 4 ++-- 6 files changed, 14 insertions(+), 15 deletions(-) rename src/renderer/coremods/{titlebar => titleBar}/plaintextPatches.ts (94%) diff --git a/cspell.json b/cspell.json index 7786fefcc..bfdff9467 100644 --- a/cspell.json +++ b/cspell.json @@ -61,7 +61,6 @@ "signingkey", "Skema", "skus", - "titlebar", "uninject", "uninjector", "uninjectors", diff --git a/src/main/index.ts b/src/main/index.ts index a1445400a..1f6e0be89 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -10,9 +10,9 @@ const discordPath = join(dirname(require.main!.filename), "..", "app.orig.asar") const discordPackage = require(join(discordPath, "package.json")); require.main!.filename = join(discordPath, discordPackage.main); -let customTitlebar: boolean; -void getSetting("dev.replugged.Settings", "titlebar", false).then( - (titlebar) => (customTitlebar = titlebar), +let customTitleBar: boolean; +void getSetting("dev.replugged.Settings", "titleBar", false).then( + (titleBar) => (customTitleBar = titleBar), ); Object.defineProperty(global, "appSettings", { @@ -40,7 +40,7 @@ class BrowserWindow extends electron.BrowserWindow { }; }, ) { - if (opts.frame && process.platform.includes("linux") && customTitlebar) opts.frame = void 0; + if (opts.frame && process.platform.includes("linux") && customTitleBar) opts.frame = void 0; const originalPreload = opts.webPreferences?.preload; diff --git a/src/renderer/coremods/settings/pages/General.tsx b/src/renderer/coremods/settings/pages/General.tsx index 87c780d0c..ee2d4a122 100644 --- a/src/renderer/coremods/settings/pages/General.tsx +++ b/src/renderer/coremods/settings/pages/General.tsx @@ -58,9 +58,9 @@ export const General = (): React.ReactElement => { "reactDevTools", ); - const { value: titlebarValue, onChange: titlebarOnChange } = util.useSetting( + const { value: titleBarValue, onChange: titleBarOnChange } = util.useSetting( generalSettings, - "titlebar", + "titleBar", ); const [kKeys, setKKeys] = React.useState([]); @@ -116,10 +116,10 @@ export const General = (): React.ReactElement => { {DiscordNative.process.platform.includes("linux") && ( { - titlebarOnChange(value); - restartModal(false); + titleBarOnChange(value); + restartModal(true); }} note={intl.format(t.REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR_DESC, {})}> {intl.string(t.REPLUGGED_SETTINGS_CUSTOM_TITLE_BAR)} diff --git a/src/renderer/coremods/titlebar/plaintextPatches.ts b/src/renderer/coremods/titleBar/plaintextPatches.ts similarity index 94% rename from src/renderer/coremods/titlebar/plaintextPatches.ts rename to src/renderer/coremods/titleBar/plaintextPatches.ts index 83b4ef6f4..6485bef01 100644 --- a/src/renderer/coremods/titlebar/plaintextPatches.ts +++ b/src/renderer/coremods/titleBar/plaintextPatches.ts @@ -6,7 +6,7 @@ const generalSettings = await init;