Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuickCSS improvements #557

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
243ae14
remove blip from reloading
12944qwerty Aug 31, 2023
a1380df
redesign scrollbar
12944qwerty Aug 31, 2023
1437d03
popout
12944qwerty Sep 20, 2023
268c0c1
use icon files
12944qwerty Sep 20, 2023
609468b
sticky popout
12944qwerty Sep 20, 2023
a1a96b9
lint
12944qwerty Sep 20, 2023
389d6fd
fix css
12944qwerty Sep 22, 2023
512aea3
fix most changes
12944qwerty Sep 26, 2023
213d62c
lint
12944qwerty Sep 26, 2023
1abd0c4
i18n: update translations from weblate
weblate Sep 22, 2023
8568845
New i18n strings
asportnoy Sep 23, 2023
aba34cc
i18n: update translations from weblate
weblate Sep 23, 2023
1e0c9fe
i18n: update translations from weblate
weblate Sep 24, 2023
fff3b61
i18n: update translations from weblate
weblate Sep 24, 2023
9019fe4
i18n: update translations from weblate
weblate Sep 24, 2023
95e26f4
i18n: update translations from weblate
weblate Sep 25, 2023
9d68216
i18n: update translations from weblate
weblate Sep 25, 2023
933d085
i18n: update translations from weblate
weblate Sep 25, 2023
11c646e
Improve various logs (#561)
EastArctica Sep 25, 2023
12f9209
i18n: update translations from weblate
weblate Sep 26, 2023
7001f41
i18n: update translations from weblate
weblate Sep 26, 2023
7556fbf
i18n: update translations from weblate
weblate Sep 26, 2023
c88cf1a
Package updates (#549)
asportnoy Sep 26, 2023
8f90fff
Fix Discord crash (#562)
asportnoy Sep 27, 2023
0f52589
Security patch (Closes #556)
asportnoy Sep 27, 2023
e815318
4.6.4
asportnoy Sep 27, 2023
7eb26b6
Remove polyfill plugin
asportnoy Sep 27, 2023
0cb58ed
Remove package
asportnoy Sep 27, 2023
21b3f09
4.6.5
asportnoy Sep 27, 2023
cb06d92
Create SECURITY.md
asportnoy Sep 27, 2023
4212258
Update SECURITY.md (#563)
asportnoy Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
"REPLUGGED_PLUGIN": "Plugin",
"REPLUGGED_PLUGINS": "Plugins",
"REPLUGGED_QUICKCSS": "Quick CSS",
"REPLUGGED_QUICKCSS_CHANGES_APPLY": "Apply Changes",
"REPLUGGED_QUICKCSS_FOLDER_OPEN": "Open Quick CSS Folder",
"REPLUGGED_QUICKCSS_POPPED_OUT": "Quick CSS Editor has been popped out",
"REPLUGGED_SETTINGS_ADVANCED_DESC": "Don't touch stuff in here if you don't know what you're doing. Unexpected things can happen to your cat.",
"REPLUGGED_SETTINGS_BACKEND": "Backend URL",
"REPLUGGED_SETTINGS_BACKEND_DESC": "URL used to fetch some assets and to query Replugged's REST API.",
Expand Down Expand Up @@ -167,7 +170,6 @@
"REPLUGGED_LIST_RESULTS": "{count, plural, =1 {# match} other {# matches}}",
"REPLUGGED_NO_ADDON_RESULTS": "No {type} matched your search.",
"REPLUGGED_NO_ADDONS_INSTALLED": "No {type} installed.",
"REPLUGGED_QUICKCSS_CHANGES_APPLY": "Apply Changes",
"REPLUGGED_SEARCH_FOR_ADDON": "Search for a {type}",
"REPLUGGED_TOAST_ADDON_DISABLE_SUCCESS": "Disabled {name}",
"REPLUGGED_TOAST_ADDON_ENABLE_SUCCESS": "Enabled {name}",
Expand All @@ -189,7 +191,6 @@
"REPLUGGED_TOAST_INSTALLER_ADDON_INSTALL_SUCCESS": "{name} installed successfully.",
"REPLUGGED_TOAST_INSTALLER_ADDON_FETCH_INFO_FAILED": "Failed to get info for addon.",
"REPLUGGED_TOAST_INSTALLER_ADDON_CANCELED_INSTALL": "Install canceled.",
"REPLUGGED_QUICKCSS_FOLDER_OPEN": "Open Quick CSS Folder",
"REPLUGGED_ADDON_AUTHORS_ONE": "by {author1}",
"REPLUGGED_ADDON_AUTHORS_TWO": "by {author1} and {author2}",
"REPLUGGED_ADDON_AUTHORS_THREE": "by {author1}, {author2}, and {author3}",
Expand Down
11 changes: 11 additions & 0 deletions src/renderer/coremods/settings/icons/Pin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { MouseEventHandler } from "react";

export default (props: { onClick?: MouseEventHandler }): React.ReactElement => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a component (StayOnTopButton, id 631443) with the icon and all the functionality already done.

<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
onClick={props.onClick}>
<path fill="currentColor" d="M19 3H5V5H7V12H5V14H11V22H13V14H19V12H17V5H19V3Z" />
</svg>
);
11 changes: 11 additions & 0 deletions src/renderer/coremods/settings/icons/Popout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { MouseEventHandler } from "react";

export default (props: { onClick?: MouseEventHandler }): React.ReactElement => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use onClick on svg's. Instead use this icon wrapped in a Clickable component.

<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
onClick={props.onClick}>
<path d="M10 5V3H5.375C4.06519 3 3 4.06519 3 5.375V18.625C3 19.936 4.06519 21 5.375 21H18.625C19.936 21 21 19.936 21 18.625V14H19V19H5V5H10Z M21 2.99902H14V4.99902H17.586L9.29297 13.292L10.707 14.706L19 6.41302V9.99902H21V2.99902Z" />
</svg>
);
10 changes: 8 additions & 2 deletions src/renderer/coremods/settings/icons/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export default (): React.ReactElement => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
import { MouseEventHandler } from "react";

export default (props: { onClick?: MouseEventHandler }): React.ReactElement => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, use Clickable.

<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
fill="currentColor"
onClick={props.onClick}>
{/* Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. */}
<path d="M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336c44.2 0 80-35.8 80-80s-35.8-80-80-80s-80 35.8-80 80s35.8 80 80 80z" />
</svg>
Expand Down
24 changes: 24 additions & 0 deletions src/renderer/coremods/settings/icons/Unpin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { MouseEventHandler } from "react";

export default (props: { onClick?: MouseEventHandler }): React.ReactElement => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
onClick={props.onClick}>
<g fill="none" fillRule="evenodd">
<path
fill="#f04747"
d="M21.47,3.39,20.14,2.05,2.53,19.66,3.86,21l4.41-4.4,1.3-1.31,1.75-1.74,3.83-3.83Z"
/>
</g>
<g fill="none">
<polygon
points="17 11.14 16.55 11.59 14.14 14 19 14 19 12 17 12 17 11.14"
fill="currentColor"
/>
<polygon points="16.91 3 5 3 5 5 7 5 7 12 5 12 5 14 5.91 14 16.91 3" fill="currentColor" />
<polygon points="12.72 15.42 11 17.14 11 22 13 22 13 15.14 12.72 15.42" fill="currentColor" />
</g>
</svg>
);
6 changes: 6 additions & 0 deletions src/renderer/coremods/settings/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import Link from "./Link";
import Reload from "./Reload";
import Settings from "./Settings";
import Trash from "./Trash";
import Popout from "./Popout";
import Pin from "./Pin";
import Unpin from "./Unpin";

export default {
Discord,
Expand All @@ -12,4 +15,7 @@ export default {
Reload,
Settings,
Trash,
Popout,
Pin,
Unpin,
};
4 changes: 2 additions & 2 deletions src/renderer/coremods/settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Injector } from "@replugged";
import { filters, waitForModule } from "src/renderer/modules/webpack";
import type { Section as SectionType } from "src/types/coremods/settings";
import { Divider, Header, Section, insertSections, settingsTools } from "./lib";
import { General, Plugins, QuickCSS, Themes, Updater } from "./pages";
import { ConnectedQuickCSS, General, Plugins, Themes, Updater } from "./pages";

const injector = new Injector();

Expand Down Expand Up @@ -47,7 +47,7 @@ export function start(): void {
Section({
name: "rp-quickcss",
label: () => Messages.REPLUGGED_QUICKCSS,
elem: QuickCSS,
elem: ConnectedQuickCSS as unknown as (args: unknown) => React.ReactElement,
}),
Section({
name: "rp-plugins",
Expand Down
46 changes: 46 additions & 0 deletions src/renderer/coremods/settings/pages/QuickCSS.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
#replugged-quickcss-wrapper {
color: var(--text-normal);
}

#replugged-quickcss-wrapper[data-popout="true"] {
width: 100% !important;
}

#replugged-quickcss-wrapper .cm-editor {
border: 1px solid transparent;
border-radius: 4px;
Expand Down Expand Up @@ -25,4 +33,42 @@

#replugged-quickcss-wrapper .cm-scroller {
overflow: auto;
max-height: 75vh;
}

/* TODO: Fix the height not working in popout */
#replugged-quickcss-wrapper[data-popout="true"] .cm-scroller {
max-height: 95vh;
}

#replugged-quickcss-wrapper .cm-scroller::-webkit-scrollbar {
width: 10px;
height: 0px;
padding: 10px;
}

#replugged-quickcss-wrapper .cm-scroller::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thin-thumb);
border-radius: 10px;
}

.replugged-quickcss-header {
height: 30px;
color: var(--text-normal);
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding: 7px 15px;
background-color: var(--background-secondary);
}
/* Why do these have to be different in different windows.. */
#replugged-quickcss-wrapper[data-popout="true"] .replugged-quickcss-header {
height: 16px;
}

.replugged-quickcss-header span,
.replugged-quickcss-header svg {
width: 100%;
height: 100%;
}
159 changes: 141 additions & 18 deletions src/renderer/coremods/settings/pages/QuickCSS.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { React, toast } from "@common";
import { React, flux, toast } from "@common";
import { Messages } from "@common/i18n";
import { EditorView, basicSetup } from "codemirror";
import { EditorState } from "@codemirror/state";
import { css } from "@codemirror/lang-css";
import { githubDark, githubLight } from "./codemirror-github";
import { webpack } from "@replugged";
import { Button, Divider, Flex, Text } from "@components";
import { Button, ButtonItem, Divider, Flex, Text, Tooltip } from "@components";
import "./QuickCSS.css";
import { generalSettings } from "./General";
import { ReactComponent } from "src/types";
import { Store } from "@common/flux";
import Settings from "../icons/Settings";
import Popout from "../icons/Popout";
import Unpin from "../icons/Unpin";
import Pin from "../icons/Pin";

interface UseCodeMirrorOptions {
value?: string;
Expand All @@ -22,6 +28,38 @@ type ThemeModule = {
removeChangeListener: (listener: () => unknown) => unknown;
};

const PopoutModule = await webpack.waitForModule(
webpack.filters.bySource('type:"POPOUT_WINDOW_OPEN"'),
);
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these comments to disable the rules are useless. Instead use the ! assertion, or even better check later if it's undefined or not.

const openPopout = webpack.getFunctionBySource(PopoutModule, "POPOUT_WINDOW_OPEN") as (
Copy link
Member

@FedeIlLeone FedeIlLeone Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type generics are a thing with these webpack functions. Use them.

key: string,
render: ReactComponent<unknown>,
Copy link
Member

@FedeIlLeone FedeIlLeone Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely deleted the ReactComponent type quite some time ago for obvious reasons. You could pass any prop without type checking. Instead, create a new type for the component with the correct and typed props.

features: Record<string, string>,
) => void;
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
const closePopout = webpack.getFunctionBySource(PopoutModule, "POPOUT_WINDOW_CLOSE") as (
key: string,
) => void;

// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
const setAlwaysOnTop = webpack.getFunctionBySource(
PopoutModule,
"POPOUT_WINDOW_SET_ALWAYS_ON_TOP",
) as (key: string, alwaysOnTop: boolean) => void;

// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
const PopoutWindowStore = webpack.getByStoreName("PopoutWindowStore") as Store & {
getWindow: (key: string) => Window;
getWindowOpen: (key: string) => boolean;
getIsAlwaysOnTop: (key: string) => boolean;
};

// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
const DnDProvider = webpack.getBySource(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be precise, do not confuse the two components, which are different (DragAndDropProvider vs PopoutWindow)

Suggested change
const DnDProvider = webpack.getBySource(
const PopoutWindow = webpack.getBySource(

".EMBEDDED_ACTIVITIES_ARE_YOU_SURE_WANT_TO_LEAVE",
) as ReactComponent<unknown>;

function useTheme(): "light" | "dark" {
const [theme, setTheme] = React.useState<"light" | "dark">("dark");

Expand Down Expand Up @@ -110,7 +148,7 @@ function useCodeMirror({ value: initialValueParam, onChange, container }: UseCod
return { value, setValue: customSetValue };
}

export const QuickCSS = (): React.ReactElement => {
const QuickCSS = (props: { popout: boolean } & Record<string, boolean>): React.ReactElement => {
const ref = React.useRef<HTMLDivElement>(null);
const { value, setValue } = useCodeMirror({
container: ref.current,
Expand Down Expand Up @@ -170,24 +208,109 @@ export const QuickCSS = (): React.ReactElement => {
if (autoApply) setReloadTimer(setTimeout(reload, 500));
}, [value]);

if (props.popout) {
React.useEffect(() => {
const window = PopoutWindowStore?.getWindow("DISCORD_REPLUGGED_QUICKCSS");

let el = window.document.createElement("link");
el.rel = "stylesheet";
el.href = `replugged://renderer.css?t=${Date.now()}`;
window.document.head.appendChild(el);
}, []);
}

const [alwaysOnTop, setAlwaysOnTop_] = React.useState(props.popoutOnTop);

return (
<>
<Flex justify={Flex.Justify.BETWEEN} align={Flex.Align.START}>
<Text.H2>{Messages.REPLUGGED_QUICKCSS}</Text.H2>
<div style={{ display: "flex" }}>
{autoApply ? null : (
<Button onClick={reloadAndToast}>{Messages.REPLUGGED_QUICKCSS_CHANGES_APPLY}</Button>
)}
<Button
onClick={() => window.RepluggedNative.quickCSS.openFolder()}
color={Button.Colors.PRIMARY}
look={Button.Looks.LINK}>
{Messages.REPLUGGED_QUICKCSS_FOLDER_OPEN}
</Button>
{!props.popout ? (
<>
<Flex justify={Flex.Justify.BETWEEN} align={Flex.Align.START}>
<Text.H2>{Messages.REPLUGGED_QUICKCSS}</Text.H2>
<div style={{ display: "flex" }}>
{autoApply ? null : (
<Button onClick={reloadAndToast}>
{Messages.REPLUGGED_QUICKCSS_CHANGES_APPLY}
</Button>
)}
<Button
onClick={() => window.RepluggedNative.quickCSS.openFolder()}
color={Button.Colors.PRIMARY}
look={Button.Looks.LINK}>
{Messages.REPLUGGED_QUICKCSS_FOLDER_OPEN}
</Button>
</div>
</Flex>
<Divider style={{ margin: "20px 0px" }} />
</>
) : null}

{!props.popout && props.isPopoutOpen ? (
<ButtonItem
button="Close Popout"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i18n. You can use POPOUT_RETURN.

onClick={() => {
closePopout("DISCORD_REPLUGGED_QUICKCSS");
}}>
{Messages.REPLUGGED_QUICKCSS_POPPED_OUT}
</ButtonItem>
) : (
<div id="replugged-quickcss-wrapper" data-popout={props.popout}>
<div className="replugged-quickcss-header">
<Tooltip text={Messages.SETTINGS}>
<Settings />
</Tooltip>

{props.popout ? (
<Tooltip
text={alwaysOnTop ? Messages.POPOUT_REMOVE_FROM_TOP : Messages.POPOUT_STAY_ON_TOP}>
{alwaysOnTop ? (
<Unpin
onClick={() => {
setAlwaysOnTop("DISCORD_REPLUGGED_QUICKCSS", false);
setAlwaysOnTop_(false);
}}
/>
) : (
<Pin
onClick={() => {
setAlwaysOnTop("DISCORD_REPLUGGED_QUICKCSS", true);
setAlwaysOnTop_(true);
}}
/>
)}
</Tooltip>
) : (
<Tooltip text={Messages.POPOUT_PLAYER}>
<Popout
onClick={() => {
openPopout(
"DISCORD_REPLUGGED_QUICKCSS",
() => (
<DnDProvider windowKey="DISCORD_REPLUGGED_QUICKCSS">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass a title prop to set the window title, or else it will be undefined.

<QuickCSS popout={true}></QuickCSS>
</DnDProvider>
),
{},
);
}}
/>
</Tooltip>
)}
</div>
<div ref={ref}></div>
</div>
</Flex>
<Divider style={{ margin: "20px 0px" }} />
<div ref={ref} id="replugged-quickcss-wrapper" />
)}
</>
);
};

export const ConnectedQuickCSS = flux.connectStores<
{ popout: boolean },
{ popout: boolean; isPopoutOpen: boolean }
>([PopoutWindowStore], (props) => {
return {
isPopoutOpen: PopoutWindowStore.getWindowOpen("DISCORD_REPLUGGED_QUICKCSS"),
popoutOnTop: PopoutWindowStore.getIsAlwaysOnTop("DISCORD_REPLUGGED_QUICKCSS"),
...props,
};
})(QuickCSS);
3 changes: 1 addition & 2 deletions src/renderer/managers/quick-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ export function unload(): void {
}

export function reload(): void {
unload();
load();
if (el) el.href = `replugged://quickcss/main.css?t=${Date.now()}`;
}