diff --git a/FAQ.md b/FAQ.md index e85bd60a1..250753385 100644 --- a/FAQ.md +++ b/FAQ.md @@ -16,7 +16,9 @@ Download and install the file at the link: sudo apt install libopengl0 +~~~bash +sudo apt install libopengl0 +~~~ ## How do I setup my GameCube Controller Adapter? @@ -45,17 +47,23 @@ Make sure to check the "overclock" option when installing your driver. This will Run the following command block -> sudo rm -f /etc/udev/rules.d/51-gcadapter.rules && sudo touch /etc/udev/rules.d/51-gcadapter.rules && echo 'SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666"' | sudo tee /etc/udev/rules.d/51-gcadapter.rules > /dev/null && sudo udevadm control --reload-rules +~~~bash +sudo rm -f /etc/udev/rules.d/51-gcadapter.rules && sudo touch /etc/udev/rules.d/51-gcadapter.rules && echo 'SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="0337", MODE="0666"' | sudo tee /etc/udev/rules.d/51-gcadapter.rules > /dev/null && sudo udevadm control --reload-rules +~~~ There is no output, so once it is finished restart Dolphin and test your adapter. If your adapter still doesn't work then try running the command below if you use systemd or restarting your computer. -> sudo systemctl restart udev.service +~~~bash +sudo systemctl restart udev.service +~~~ On some distributions you need to run this command instead to restart the service: -> sudo systemctl restart systemd-udevd.service +~~~bash +sudo systemctl restart systemd-udevd.service +~~~ ## What are delay frames and how do I change them? diff --git a/src/main/preload.ts b/src/main/preload.ts index 8072f37c1..758a6de8e 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -3,7 +3,7 @@ import consoleApi from "@console/api"; import dolphinApi from "@dolphin/api"; import replaysApi from "@replays/api"; import settingsApi from "@settings/api"; -import { clipboard, contextBridge, ipcRenderer, shell } from "electron"; +import { contextBridge, ipcRenderer, shell } from "electron"; import path from "path"; import { isSubdirectory } from "utils/is_subdirectory"; @@ -24,10 +24,6 @@ const api = { path: { join: path.join, }, - clipboard: { - writeText: clipboard.writeText, - readText: clipboard.readText, - }, shell: { openPath: shell.openPath, openExternal: shell.openExternal, diff --git a/src/renderer/components/markdown_content/code_block.tsx b/src/renderer/components/markdown_content/code_block.tsx new file mode 100644 index 000000000..f5ecd5bc2 --- /dev/null +++ b/src/renderer/components/markdown_content/code_block.tsx @@ -0,0 +1,57 @@ +import ContentCopyIcon from "@mui/icons-material/ContentCopy"; +import IconButton from "@mui/material/IconButton"; +import Tooltip from "@mui/material/Tooltip"; +import stylex from "@stylexjs/stylex"; +import React from "react"; + +const styles = stylex.create({ + container: { + fontSize: 15, + padding: "20px 30px", + backgroundColor: "rgba(0, 0, 0, 0.5)", + borderRadius: 5, + position: "relative", + }, + code: { + color: "#999", + lineHeight: "1.5em", + }, + buttonContainer: { + position: "absolute", + top: 10, + right: 10, + opacity: 0, + transition: "opacity 0.1s ease-in-out", + }, + visible: { + opacity: 1, + }, +}); + +export const CodeBlock = React.memo(function CodeBlock({ content }: { content: string }) { + const [copied, setCopied] = React.useState(false); + const [isHovering, setIsHovering] = React.useState(false); + const onMouseEnter = () => setIsHovering(true); + const onMouseLeave = () => setIsHovering(false); + const onCopy = () => { + navigator.clipboard + .writeText(content) + .then(() => { + setCopied(true); + window.setTimeout(() => setCopied(false), 2000); + }) + .catch(console.error); + }; + return ( +
+
+ + + + + +
+ {content} +
+ ); +}); diff --git a/src/renderer/components/markdown_content.tsx b/src/renderer/components/markdown_content/markdown_content.tsx similarity index 88% rename from src/renderer/components/markdown_content.tsx rename to src/renderer/components/markdown_content/markdown_content.tsx index 1fb91f944..ae20a65a8 100644 --- a/src/renderer/components/markdown_content.tsx +++ b/src/renderer/components/markdown_content/markdown_content.tsx @@ -4,12 +4,15 @@ import ReactMarkdown from "react-markdown"; import { ExternalLink as A } from "@/components/external_link"; import { withFont } from "@/styles/with_font"; +import { CodeBlock } from "./code_block"; + export const MarkdownContent = ({ content, className }: { className?: string; content: string }) => { return ( , link: ({ href, children }) => ( {children} diff --git a/src/renderer/pages/home/news_feed/news_article/news_article.tsx b/src/renderer/pages/home/news_feed/news_article/news_article.tsx index 7ece0d4da..322273185 100644 --- a/src/renderer/pages/home/news_feed/news_article/news_article.tsx +++ b/src/renderer/pages/home/news_feed/news_article/news_article.tsx @@ -12,7 +12,7 @@ import React from "react"; import TimeAgo from "react-timeago"; import { ExternalLink } from "@/components/external_link"; -import { MarkdownContent } from "@/components/markdown_content"; +import { MarkdownContent } from "@/components/markdown_content/markdown_content"; const styles = stylex.create({ container: { diff --git a/src/renderer/pages/settings/dolphin_settings/gecko_codes/manage_codes/manage_codes.container.tsx b/src/renderer/pages/settings/dolphin_settings/gecko_codes/manage_codes/manage_codes.container.tsx index 62fb6b894..93776f647 100644 --- a/src/renderer/pages/settings/dolphin_settings/gecko_codes/manage_codes/manage_codes.container.tsx +++ b/src/renderer/pages/settings/dolphin_settings/gecko_codes/manage_codes/manage_codes.container.tsx @@ -19,8 +19,12 @@ export const ManageCodesContainer = ({ }; const handleCopy = (geckoCode: GeckoCode) => { - window.electron.clipboard.writeText(geckoCodeToString(geckoCode).trim()); - showSuccess("Code copied to clipboard!"); + navigator.clipboard + .writeText(geckoCodeToString(geckoCode).trim()) + .then(() => { + showSuccess("Code copied to clipboard!"); + }) + .catch(console.error); }; const handleToggle = (code: GeckoCode) => { diff --git a/src/renderer/pages/settings/help_page/help_page.tsx b/src/renderer/pages/settings/help_page/help_page.tsx index 1627f6c4d..d66a61a02 100644 --- a/src/renderer/pages/settings/help_page/help_page.tsx +++ b/src/renderer/pages/settings/help_page/help_page.tsx @@ -5,7 +5,7 @@ import { alpha } from "@mui/material/styles"; import faqMarkdown from "raw-loader!@/../../FAQ.md"; import React from "react"; -import { MarkdownContent } from "@/components/markdown_content"; +import { MarkdownContent } from "@/components/markdown_content/markdown_content"; import { SupportBox } from "./support_box"; diff --git a/src/renderer/pages/settings/help_page/network_diagnostics/cgnat_command_section.tsx b/src/renderer/pages/settings/help_page/network_diagnostics/cgnat_command_section.tsx index cf3557698..b50edb5ba 100644 --- a/src/renderer/pages/settings/help_page/network_diagnostics/cgnat_command_section.tsx +++ b/src/renderer/pages/settings/help_page/network_diagnostics/cgnat_command_section.tsx @@ -40,9 +40,13 @@ export const CgnatCommandSection = ({ address }: CgnatCommandSectionProps) => { const displayedCgnatCommand = `${tracerouteCommand} ${cgnatCommandHidden ? hiddenIpAddress : address}`; const [cgnatCommandCopied, setCgnatCommandCopied] = React.useState(false); const onCgnatCommandCopy = React.useCallback(() => { - window.electron.clipboard.writeText(cgnatCommand); - setCgnatCommandCopied(true); - window.setTimeout(() => setCgnatCommandCopied(false), 2000); + navigator.clipboard + .writeText(cgnatCommand) + .then(() => { + setCgnatCommandCopied(true); + window.setTimeout(() => setCgnatCommandCopied(false), 2000); + }) + .catch(console.error); }, [cgnatCommand]); return ( diff --git a/src/renderer/pages/settings/help_page/network_diagnostics/nat_type_section.tsx b/src/renderer/pages/settings/help_page/network_diagnostics/nat_type_section.tsx index 33c39ec85..6120b0f3a 100644 --- a/src/renderer/pages/settings/help_page/network_diagnostics/nat_type_section.tsx +++ b/src/renderer/pages/settings/help_page/network_diagnostics/nat_type_section.tsx @@ -41,9 +41,13 @@ export const NatTypeSection = ({ address, description, natType, title }: NatType const ipAddressTitle = getIpAddressTitle(natType); const [ipAddressCopied, setIpAddressCopied] = React.useState(false); const onIpAddressCopy = React.useCallback(() => { - window.electron.clipboard.writeText(address); - setIpAddressCopied(true); - window.setTimeout(() => setIpAddressCopied(false), 2000); + navigator.clipboard + .writeText(address) + .then(() => { + setIpAddressCopied(true); + window.setTimeout(() => setIpAddressCopied(false), 2000); + }) + .catch(console.error); }, [address]); const [ipAddressHidden, setIpAddressHidden] = React.useState(true); const onIpAddressShowHide = () => { diff --git a/src/renderer/pages/settings/help_page/network_diagnostics/network_diagnostics_result.tsx b/src/renderer/pages/settings/help_page/network_diagnostics/network_diagnostics_result.tsx index 06723b194..29831e3de 100644 --- a/src/renderer/pages/settings/help_page/network_diagnostics/network_diagnostics_result.tsx +++ b/src/renderer/pages/settings/help_page/network_diagnostics/network_diagnostics_result.tsx @@ -109,9 +109,13 @@ export const NetworkDiagnosticsResult = React.memo( const [diagnosticResultsCopied, setDiagnosticResultsCopied] = React.useState(false); const onDiagnosticResultsCopy = React.useCallback(() => { const diagnosticResults = `${natTypeTitle}\n${natTypeDescription}\n\n${portMappingTitle}\n${portMappingDescription}\n\n${cgnatTitle}\n${cgnatDescription}`; - window.electron.clipboard.writeText(diagnosticResults); - setDiagnosticResultsCopied(true); - window.setTimeout(() => setDiagnosticResultsCopied(false), 2000); + navigator.clipboard + .writeText(diagnosticResults) + .then(() => { + setDiagnosticResultsCopied(true); + window.setTimeout(() => setDiagnosticResultsCopied(false), 2000); + }) + .catch(console.error); }, [cgnatDescription, cgnatTitle, natTypeDescription, natTypeTitle, portMappingDescription, portMappingTitle]); return ( diff --git a/src/renderer/pages/spectate/share_gameplay_block/start_broadcast_dialog.tsx b/src/renderer/pages/spectate/share_gameplay_block/start_broadcast_dialog.tsx index 5528eb565..cd77d4989 100644 --- a/src/renderer/pages/spectate/share_gameplay_block/start_broadcast_dialog.tsx +++ b/src/renderer/pages/spectate/share_gameplay_block/start_broadcast_dialog.tsx @@ -126,10 +126,14 @@ export const StartBroadcastDialog = ({ open, onClose, onSubmit }: StartBroadcast { - const text = window.electron.clipboard.readText(); - if (text) { - handleChange(text); - } + navigator.clipboard + .readText() + .then((text) => { + if (text) { + handleChange(text); + } + }) + .catch(console.error); }} > diff --git a/src/renderer/pages/spectate/spectator_id_block.tsx b/src/renderer/pages/spectate/spectator_id_block.tsx index 4b32115fa..cbb13529b 100644 --- a/src/renderer/pages/spectate/spectator_id_block.tsx +++ b/src/renderer/pages/spectate/spectator_id_block.tsx @@ -15,11 +15,14 @@ export const SpectatorIdBlock = ({ userId, className }: SpectatorIdBlockProps) = const onCopy = React.useCallback(() => { // Set the clipboard text - window.electron.clipboard.writeText(userId); - - // Set copied indication - setCopied(true); - window.setTimeout(() => setCopied(false), 2000); + navigator.clipboard + .writeText(userId) + .then(() => { + // Set copied indication + setCopied(true); + window.setTimeout(() => setCopied(false), 2000); + }) + .catch(console.error); }, [userId]); return (