diff --git a/e2e/settings.spec.ts b/e2e/settings.spec.ts index b61d10ea7b..a6291a3382 100644 --- a/e2e/settings.spec.ts +++ b/e2e/settings.spec.ts @@ -33,7 +33,10 @@ electronTest('Settings', async (app, page) => { }) await test.step('shows the Advanced settings', async () => { - await page.getByTestId('settings').click() + await page + .locator('.Sidebar') + .locator('.Sidebar__item', { hasText: 'Settings' }) + .click() page.getByText('Global Settings') await page.getByText('Advanced').click() }) diff --git a/src/backend/main.ts b/src/backend/main.ts index 8cbc1fecfc..0c1b10f2d5 100644 --- a/src/backend/main.ts +++ b/src/backend/main.ts @@ -1668,7 +1668,7 @@ ipcMain.on('processShortcut', async (e, combination: string) => { break // hotkey to open the settings on frontend case 'ctrl+k': - sendFrontendMessage('openScreen', '/settings/app/default/general') + sendFrontendMessage('openScreen', '/settings/general') break // hotkey to open the downloads screen on frontend case 'ctrl+j': diff --git a/src/frontend/App.tsx b/src/frontend/App.tsx index 91c4e38ef8..aec937b571 100644 --- a/src/frontend/App.tsx +++ b/src/frontend/App.tsx @@ -118,7 +118,7 @@ const router = createHashRouter([ lazy: makeLazyFunc(import('./screens/WebView')) }, { - path: 'settings/:runner/:appName/:type', + path: 'settings/:type', lazy: makeLazyFunc(import('./screens/Settings')) }, { diff --git a/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.css b/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.css new file mode 100644 index 0000000000..ba2d772af7 --- /dev/null +++ b/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.css @@ -0,0 +1,52 @@ +.Sidebar { + .currentDownload { + font-size: var(--text-sm); + padding: var(--space-md) 0; + transition: 300ms; + margin-top: var(--space-sm); + align-self: end; + + & > .gameTitle { + font-size: var(--text-md); + transition: 600ms; + font-weight: var(--bold); + } + + &:hover > .gameTitle { + color: var(--accent-overlay); + transition: 600ms; + } + + .downloadStatus { + color: var(--success); + font-family: var(--secondary-font-family); + font-style: italic; + font-weight: normal; + font-size: var(--text-sm); + line-height: var(--text-sm); + } + + .MuiLinearProgress-bar1Determinate { + background-color: var(--success); + } + + .statusIcon { + display: none; + margin-inline-end: 10px; + svg { + width: 27px; + height: auto; + color: var(--success); + } + } + } + + &.collapsed { + .statusIcon { + display: block; + } + .full-size { + display: none; + } + } +} diff --git a/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.scss b/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.scss deleted file mode 100644 index 14375cd181..0000000000 --- a/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.scss +++ /dev/null @@ -1,40 +0,0 @@ -.currentDownload { - font-size: var(--text-sm); - padding: var(--space-md) 0; - transition: 300ms; - margin-top: var(--space-sm); - - & > .gameTitle { - font-size: var(--text-md); - transition: 600ms; - font-weight: var(--bold); - } - - &:hover > .gameTitle { - color: var(--accent-overlay); - transition: 600ms; - } - - .downloadStatus { - color: var(--success); - font-family: var(--secondary-font-family); - font-style: italic; - font-weight: normal; - font-size: var(--text-sm); - line-height: var(--text-sm); - } - - .MuiLinearProgress-bar1Determinate { - background-color: var(--success); - } - - .statusIcon { - display: none; - margin-inline-end: 10px; - svg { - width: 27px; - height: auto; - color: var(--success); - } - } -} diff --git a/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.tsx b/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.tsx index 77ea259484..c56a0fcae9 100644 --- a/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.tsx +++ b/src/frontend/components/UI/Sidebar/components/CurrentDownload/index.tsx @@ -8,7 +8,7 @@ import Box from '@mui/material/Box' import { getGameInfo } from 'frontend/helpers' import { hasProgress } from 'frontend/hooks/hasProgress' import { Runner } from 'common/types' -import './index.scss' +import './index.css' import { useTranslation } from 'react-i18next' import ContextProvider from 'frontend/state/ContextProvider' import Badge from '@mui/material/Badge' @@ -52,37 +52,35 @@ export default React.memo(function CurrentDownload({ appName, runner }: Props) { } return ( - <> - - - - - - + + + + + + -
- {gameTitle ?? 'GameName'} -
- {getStatus()} -
- - - - - - {`${Math.round( - progress.percent || 0 - )}%`} - +
+ {gameTitle ?? 'GameName'} +
+ {getStatus()} +
+ + + -
- - + + {`${Math.round( + progress.percent || 0 + )}%`} + +
+
+ ) }) diff --git a/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.css b/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.css new file mode 100644 index 0000000000..e3a3626036 --- /dev/null +++ b/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.css @@ -0,0 +1,47 @@ +.Sidebar { + .heroicVersion { + display: flex; + gap: 5px; + font-size: var(--text-sm); + cursor: pointer; + transition: 300ms; + color: var(--brand-text-01); + + &:hover { + color: var(--accent); + } + } + + .heroicNewReleases { + display: flex; + flex-direction: column; + justify-content: space-around; + font-size: var(--text-sm); + + & > a { + color: var(--accent); + transition: 300ms; + -webkit-app-region: no-drag; + cursor: pointer; + + &:hover { + color: var(--accent-overlay); + } + } + } + + &.collapsed { + .heroicVersion { + font-size: var(--text-xs); + text-align: center; + } + + .heroicVersion__title { + display: none; + } + + .heroicNewReleases { + display: none; + } + } +} diff --git a/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.tsx b/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.tsx index d594b4fb94..7001f3e6e5 100644 --- a/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.tsx +++ b/src/frontend/components/UI/Sidebar/components/HeroicVersion/index.tsx @@ -2,6 +2,7 @@ import React, { useContext, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import ContextProvider from 'frontend/state/ContextProvider' import { ChangelogModal } from '../../../ChangelogModal' +import './index.css' type Release = { html_url: string diff --git a/src/frontend/components/UI/Sidebar/components/SidebarItem/index.css b/src/frontend/components/UI/Sidebar/components/SidebarItem/index.css new file mode 100644 index 0000000000..c11a3e1988 --- /dev/null +++ b/src/frontend/components/UI/Sidebar/components/SidebarItem/index.css @@ -0,0 +1,111 @@ +.Sidebar { + .Sidebar__item { + --sidebar-item-inactive-text-color: var( + --navbar-inactive, + var(--navbar-accent) + ); + --sidebar-hover-text-color: var(--text-hover); + --sidebar-item-active-text-color: var( + --navbar-active, + var(--accent-overlay, var(--accent)) + ); + --sidebar-active-item-background: var(--navbar-active-background); + + display: flex; + gap: 10px; + width: 100%; + padding: var(--space-xs) var(--sidebar-horizontal-padding); + border: none; + background: none; + cursor: pointer; + font-size: var(--text-md); + color: var(--sidebar-item-inactive-text-color); + transition: color 250ms; + text-align: start; + font-family: var(--primary-font-family); + + .Sidebar__itemIcon { + width: 24px; + display: inline-flex; + justify-content: center; + } + + &:focus-visible { + outline: 2px solid var(--sidebar-hover-text-color); + outline-offset: -2px; + } + + &.active { + color: var(--sidebar-item-active-text-color); + + .Sidebar__itemIcon { + color: currentColor; + } + + &.SidebarLinks__subItem { + font-weight: var(--bold); + } + } + &.active:not(.SidebarLinks__subItem) { + background-color: var(--sidebar-active-item-background); + } + + &.SidebarLinks__subItem { + &, + &:hover { + padding-block: var(--space-3xs); + padding-inline: var(--space-xl) var(--sidebar-horizontal-padding); + font-size: var(--text-sm); + line-height: 20px; + white-space: break-spaces; + } + &::before { + content: '• '; + } + & + .Sidebar__item:not(.SidebarLinks__subItem) { + margin-top: 4px; + } + } + + &:hover { + background-color: var(--navbar-active-background); + transition: 0.1s; + padding-inline-start: 12px; + } + + @media screen and (max-width: 730px) { + &, + &:hover { + padding: var(--space-3xs) var(--sidebar-horizontal-padding) + var(--space-3xs) var(--space-lg); + } + } + } + + &.collapsed { + .Sidebar__item { + padding: var(--space-xs) 0; + + & > span { + display: none; + } + + &.SidebarLinks__subItem { + padding: var(--space-xs) var(--sidebar-horizontal-padding); + &::before { + display: none; + } + } + + &.active svg, + & svg { + transform: scale(1.2); + padding: var(--space-2xs) 0; + } + + .Sidebar__itemIcon { + margin: 0 auto; + } + } + } +} diff --git a/src/frontend/components/UI/Sidebar/components/SidebarItem/index.tsx b/src/frontend/components/UI/Sidebar/components/SidebarItem/index.tsx new file mode 100644 index 0000000000..2bf3e21955 --- /dev/null +++ b/src/frontend/components/UI/Sidebar/components/SidebarItem/index.tsx @@ -0,0 +1,60 @@ +import React, { MouseEventHandler } from 'react' +import classNames from 'classnames' +import { NavLink } from 'react-router-dom' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { IconProp } from '@fortawesome/fontawesome-svg-core' +import './index.css' + +interface SidebarItemProps { + label: string + url?: string + icon?: IconProp + isActiveFallback?: boolean + onClick?: MouseEventHandler + className?: string + elementType?: 'a' | 'button' +} + +export default function SidebarItem({ + icon, + label, + url = '', + isActiveFallback = false, + onClick, + className, + elementType +}: SidebarItemProps) { + const itemContent = ( + <> + {icon && ( +
+ +
+ )} + {label} + + ) + + switch (elementType) { + case 'button': + return ( + + ) + default: + return ( + + classNames('Sidebar__item', className, { + active: isActive || isActiveFallback + }) + } + to={url} + onClick={onClick} + > + {itemContent} + + ) + } +} diff --git a/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.css b/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.css deleted file mode 100644 index f34fd1c38b..0000000000 --- a/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.css +++ /dev/null @@ -1,35 +0,0 @@ -.SidebarLinks { - grid-area: links; - font-size: var(--text-lg); -} - -.Sidebar__item.SidebarLinks__subItem, -.Sidebar__item.SidebarLinks__subItem:hover { - padding-block: var(--space-3xs); - padding-inline: var(--space-xl) var(--sidebar-horizontal-padding); - font-size: var(--text-sm); - line-height: 20px; - white-space: break-spaces; -} - -.Sidebar__item:hover { - background-color: var(--navbar-active-background); - transition: 0.1s; - padding-inline-start: 12px; -} - -.Sidebar__item.SidebarLinks__subItem::before { - content: '• '; -} - -.SidebarLinks__subItem + .Sidebar__item:not(.SidebarLinks__subItem) { - margin-top: 4px; -} - -@media screen and (max-width: 730px) { - .Sidebar__item.SidebarLinks__subItem, - .Sidebar__item.SidebarLinks__subItem:hover { - padding: var(--space-3xs) var(--sidebar-horizontal-padding) var(--space-3xs) - var(--space-lg); - } -} diff --git a/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.tsx b/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.tsx index d89e47e78c..b199a46b88 100644 --- a/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.tsx +++ b/src/frontend/components/UI/Sidebar/components/SidebarLinks/index.tsx @@ -10,34 +10,23 @@ import { faWineGlass, faBarsProgress } from '@fortawesome/free-solid-svg-icons' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { NavLink, useLocation } from 'react-router-dom' -import classNames from 'classnames' +import { useLocation } from 'react-router-dom' import React, { useContext } from 'react' import { useTranslation } from 'react-i18next' import { faDiscord, faPatreon } from '@fortawesome/free-brands-svg-icons' import { openDiscordLink } from 'frontend/helpers' import ContextProvider from 'frontend/state/ContextProvider' -import { Runner } from 'common/types' -import './index.css' import QuitButton from '../QuitButton' -import { LocationState } from 'frontend/types' import { SHOW_EXTERNAL_LINK_DIALOG_STORAGE_KEY } from 'frontend/components/UI/ExternalLinkDialog' +import SidebarItem from '../SidebarItem' -type PathSplit = [ - a: undefined, - b: undefined, - runner: Runner | 'app', - appName: string, - type: string -] +type PathSplit = [a: undefined, b: undefined, type: string] export default function SidebarLinks() { const { t } = useTranslation() - const { state } = useLocation() as { state: LocationState } const location = useLocation() as { pathname: string } - const [, , runner, appName, type] = location.pathname.split('/') as PathSplit + const [, , type] = location.pathname.split('/') as PathSplit const { amazon, @@ -54,8 +43,6 @@ export default function SidebarLinks() { const isSettings = location.pathname.includes('settings') const isWin = platform === 'win32' - const settingsPath = '/settings/app/default/general' - const loggedIn = epic.username || gog.username || amazon.user_id async function handleRefresh() { @@ -101,288 +88,159 @@ export default function SidebarLinks() { return (
{!loggedIn && ( - - classNames('Sidebar__item', { active: isActive }) - } - to={'/login'} - > - <> -
- -
- {t('button.login', 'Login')} - -
+ )} - - classNames('Sidebar__item', { - active: isActive || location.pathname.includes('gamepage') - }) - } - to={'/'} + handleRefresh()} - > - <> -
- -
- {t('Library')} - -
+ /> +
- - classNames('Sidebar__item', { - active: isActive || location.pathname.includes('store') - }) - } - to={`/store/${defaultStore}`} - > - <> -
- -
- {t('stores', 'Stores')} - -
+ {inWebviewScreen && (
- - classNames('Sidebar__item', 'SidebarLinks__subItem', { - active: isActive - }) - } - to="/store/epic" - > - {t('store', 'Epic Store')} - - - classNames('Sidebar__item', 'SidebarLinks__subItem', { - active: isActive - }) - } - to="/store/gog" - > - {t('gog-store', 'GOG Store')} - - - classNames('Sidebar__item', 'SidebarLinks__subItem', { - active: isActive - }) - } - to="/store/amazon" - > - {t('prime-gaming', 'Prime Gaming')} - + + +
)}
- - classNames('Sidebar__item', { - active: isActive || location.pathname.includes('settings') - }) - } - to={{ pathname: settingsPath }} - state={{ - fromGameCard: false - }} - > - <> -
- -
- {t('Settings', 'Settings')} - -
+ {isSettings && (
- - {t('settings.navbar.general')} - + + {!isWin && ( - - - {t( - 'settings.navbar.games_settings_defaults', - 'Game Defaults' - )} - - + )} - - {t('settings.navbar.advanced', 'Advanced')} - - - - {t('settings.navbar.systemInformation', 'System Information')} - - - - {t('settings.navbar.log', 'Log')} - + + + + + +
)}
- - classNames('Sidebar__item', { active: isActive }) - } - to={{ pathname: '/download-manager' }} - > - <> -
- -
- {t('download-manager.link', 'Downloads')} - -
+ + {!isWin && ( - - classNames('Sidebar__item', { active: isActive }) - } - to={{ pathname: '/wine-manager' }} - > - <> -
- -
- {t('wine.manager.link', 'Wine Manager')} - -
+ )} + {loggedIn && ( - -
- -
- {t('userselector.manageaccounts', 'Manage Accounts')} -
+ )} - - classNames('Sidebar__item', { active: isActive }) - } - to={{ pathname: '/accessibility' }} - > - <> -
- -
- {t('accessibility.title', 'Accessibility')} - -
+ + +
- - classNames('Sidebar__item', { active: isActive }) - } - to={{ pathname: '/wiki' }} - > - <> -
- -
- {t('docs', 'Documentation')} - -
- - - + icon={faCoffee} + label="Ko-fi" + /> +
) diff --git a/src/frontend/components/UI/Sidebar/index.css b/src/frontend/components/UI/Sidebar/index.css new file mode 100644 index 0000000000..f08e0dea5d --- /dev/null +++ b/src/frontend/components/UI/Sidebar/index.css @@ -0,0 +1,140 @@ +.Sidebar { + --sidebar-horizontal-padding: var(--space-md); + --sidebar-vertical-padding: var(--space-lg); + --sidebar-width: 350px; + --sidebar-background: var(--navbar-background); + --sidebar-divider-color: var(--divider); + + width: var(--sidebar-width); + position: relative; + z-index: 10; + display: grid; + grid-template-rows: min-content 2fr min-content min-content; + grid-template-areas: 'icon' 'links' 'utils' 'updates' 'version'; + grid-area: sidebar; + padding: 0; + font-family: var(--secondary-font-family); + text-align: start; + background: var(--sidebar-background); + overflow: auto; + overflow-x: hidden; + -webkit-app-region: drag; + + .heroicIcon { + grid-area: icon; + width: 50px; + height: 68px; + margin-top: var(--space-xs); + justify-self: center; + } + + .SidebarLinks { + grid-area: links; + } + + .heroicVersion { + grid-area: version; + margin-block: 0 var(--sidebar-vertical-padding); + margin-inline: var(--sidebar-horizontal-padding) var(--space-3xs); + -webkit-app-region: no-drag; + } + + .heroicNewReleases { + grid-area: updates; + margin-block: 0 var(--space-sm); + margin-inline: var(--sidebar-horizontal-padding) var(--space-3xs); + } + + .Sidebar__section { + -webkit-app-region: no-drag; + } + + .currentDownloads { + grid-area: utils; + margin-block: 0 var(--sidebar-vertical-padding); + margin-inline: var(--sidebar-horizontal-padding) var(--space-3xs); + } + + .divider { + height: 1px; + margin: var(--space-3xs) var(--space-xs); + background-color: var(--sidebar-divider-color); + } + + .resizer { + position: absolute; + top: 0; + right: 0; + width: 10px; + height: 100%; + z-index: 1; + cursor: col-resize; + } + + &.collapsed { + --sidebar-vertical-padding: var(--space-xs); + --sidebar-horizontal-padding: var(--space-lg); + overflow-x: hidden; + overflow-y: auto; + + .currentDownloads { + margin-inline: auto; + } + + .heroicVersion { + margin: var(--space-sm); + } + + .divider { + margin: var(--space-3xs) 0; + } + + .SidebarItemWithSubmenu { + &:has(.SidebarSubmenu) { + position: relative; + z-index: 2; + } + + .SidebarSubmenu { + display: none; + } + + &:hover, + &:focus-within { + .SidebarSubmenu { + display: block; + position: fixed; + left: var(--sidebar-width); + top: 66px; + background-color: var(--sidebar-background); + padding: var(--space-2xs) 0; + + & span { + display: block; + } + + &.settings { + top: 114px; + } + } + } + } + } +} + +.isRTL .Sidebar { + &.collapsed .SidebarItemWithSubmenu { + &:hover, + &:focus-within { + .SidebarSubmenu { + right: var(--sidebar-width); + left: auto; + } + } + } + + & .resizer { + left: 0; + right: auto; + } +} diff --git a/src/frontend/components/UI/Sidebar/index.scss b/src/frontend/components/UI/Sidebar/index.scss deleted file mode 100644 index 50c1ac6bea..0000000000 --- a/src/frontend/components/UI/Sidebar/index.scss +++ /dev/null @@ -1,251 +0,0 @@ -.Sidebar { - --sidebar-horizontal-padding: var(--space-md); - --sidebar-vertical-padding: var(--space-lg); - position: relative; - z-index: 10; - display: grid; - grid-template-rows: min-content 2fr min-content min-content; - grid-template-areas: 'icon' 'links' 'utils' 'updates' 'version'; - grid-area: sidebar; - height: 100%; - padding: 0; - font-family: var(--secondary-font-family); - text-align: start; - background: var(--navbar-background); - overflow: auto; - overflow-x: hidden; - --sidebar-width: 350px; - width: var(--sidebar-width); - -webkit-app-region: drag; - - .heroicIcon { - grid-area: icon; - width: 50px; - height: 68px; - display: flex; - margin-top: var(--space-xs); - justify-self: center; - } -} - -.Sidebar.collapsed { - --sidebar-vertical-padding: var(--space-xs); - --sidebar-horizontal-padding: var(--space-lg); - overflow-x: hidden; - overflow-y: auto; -} - -.Sidebar__section { - display: flex; - width: 100%; - height: fit-content; - font-family: var(--secondary-font-family); - flex-direction: column; - -webkit-app-region: no-drag; -} - -.Sidebar__item { - display: flex; - width: 100%; - padding: var(--space-xs) var(--sidebar-horizontal-padding); - border: none; - background: none; - cursor: pointer; - font-size: var(--text-md); - color: var(--navbar-accent); - color: var(--navbar-inactive, var(--navbar-accent)); - transition: color 250ms; - text-align: start; - font-family: var(--primary-font-family); - border-radius: 0; -} - -.collapsed .Sidebar__item { - padding: var(--space-xs) 0; -} - -.collapsed .Sidebar__itemIcon { - margin: 0 auto; -} -.Sidebar__item:focus-visible { - outline: 2px solid var(--text-hover); - outline-offset: -2px; -} - -.Sidebar__item.active { - color: var(--accent); - color: var(--navbar-active, var(--accent-overlay)); - - .Sidebar__itemIcon { - color: var(--accent); - color: var(--navbar-active, var(--accent-overlay)); - } -} - -.Sidebar__item.active:not(.SidebarLinks__subItem) { - background-color: var(--navbar-active-background); -} - -.Sidebar__item.active.SidebarLinks__subItem { - font-weight: var(--bold); -} - -.Sidebar__itemIcon { - box-sizing: border-box; - width: 24px; - margin-inline-end: 10px; - display: inline-flex; - justify-content: center; - color: var(--accent); - color: var(--navbar-inactive, var(--accent)); -} - -.currentDownloads { - grid-area: utils; - align-self: end; - margin-block: 0 var(--sidebar-vertical-padding); - margin-inline: var(--sidebar-horizontal-padding) var(--space-3xs); -} - -.divider { - height: 1px; - opacity: 0.5; - margin: var(--space-3xs) var(--space-xs); - background-color: var(--divider); -} - -.heroicVersion { - display: flex; - gap: 5px; - grid-area: version; - margin-block: 0 var(--sidebar-vertical-padding); - margin-inline: var(--sidebar-horizontal-padding) var(--space-3xs); - font-size: var(--text-sm); - cursor: pointer; - transition: 300ms; - color: var(--brand-text-01); - -webkit-app-region: no-drag; -} - -.heroicVersion:hover { - color: var(--accent); -} - -.heroicNewReleases { - grid-area: updates; - display: flex; - flex-direction: column; - justify-content: space-around; - margin-block: 0 var(--space-sm); - margin-inline: var(--space-3xs) var(--sidebar-horizontal-padding); - font-size: var(--text-sm); -} - -.heroicNewReleases > a { - color: var(--accent); - transition: 300ms; - -webkit-app-region: no-drag; -} - -.heroicNewReleases > a:hover { - color: var(--accent-overlay); -} - -.Sidebar.collapsed { - .heroicVersion { - margin: var(--space-sm); - font-size: var(--text-xs); - text-align: center; - &__title { - display: none; - } - } - - .heroicNewReleases { - display: none; - } - - .currentDownloads { - margin-inline: auto; - .statusIcon { - display: block; - } - .full-size { - display: none; - } - } -} - -.Sidebar.collapsed .divider { - margin: var(--space-3xs) 0; -} - -.Sidebar.collapsed .Sidebar__item.active span, -.Sidebar.collapsed .Sidebar__item > span { - display: none; -} - -.Sidebar.collapsed .SidebarItemWithSubmenu:has(.SidebarSubmenu) { - position: relative; - z-index: 2; -} - -.Sidebar.collapsed .SidebarItemWithSubmenu .SidebarSubmenu { - display: none; -} - -.Sidebar.collapsed .SidebarItemWithSubmenu:hover .SidebarSubmenu span, -.Sidebar.collapsed .SidebarItemWithSubmenu:focus-within .SidebarSubmenu span { - display: block; -} - -.Sidebar.collapsed .SidebarItemWithSubmenu:hover .SidebarSubmenu, -.Sidebar.collapsed .SidebarItemWithSubmenu:focus-within .SidebarSubmenu { - display: block; - position: fixed; - left: var(--sidebar-width); - top: 66px; - background-color: var(--navbar-background); - padding: var(--space-2xs) 0; -} - -.isRTL .Sidebar.collapsed .SidebarItemWithSubmenu:hover .SidebarSubmenu, -.isRTL .Sidebar.collapsed .SidebarItemWithSubmenu:focus-within .SidebarSubmenu { - right: var(--sidebar-width); - left: auto; -} - -.Sidebar.collapsed .SidebarItemWithSubmenu:hover .SidebarSubmenu.settings, -.Sidebar.collapsed - .SidebarItemWithSubmenu:focus-within - .SidebarSubmenu.settings { - top: 114px; -} - -.Sidebar.collapsed .Sidebar__item.SidebarLinks__subItem::before { - display: none; -} - -.Sidebar.collapsed .Sidebar__item.SidebarLinks__subItem { - padding: var(--space-xs) var(--sidebar-horizontal-padding); -} -.Sidebar.collapsed .Sidebar__item.active svg, -.Sidebar.collapsed .Sidebar__item svg { - transform: scale(1.2); - padding: var(--space-2xs) 0; -} - -.resizer { - position: absolute; - top: 0; - right: 0; - width: 10px; - height: 100%; - z-index: 1; - cursor: col-resize; -} - -.isRTL .resizer { - left: 0; - right: auto; -} diff --git a/src/frontend/components/UI/Sidebar/index.tsx b/src/frontend/components/UI/Sidebar/index.tsx index 8477ba77fe..4617b04306 100644 --- a/src/frontend/components/UI/Sidebar/index.tsx +++ b/src/frontend/components/UI/Sidebar/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react' import CurrentDownload from './components/CurrentDownload' import SidebarLinks from './components/SidebarLinks' -import './index.scss' +import './index.css' import HeroicVersion from './components/HeroicVersion' import { DMQueueElement } from 'common/types' diff --git a/src/frontend/components/UI/Winetricks/index.tsx b/src/frontend/components/UI/Winetricks/index.tsx index 2047fdcae7..6631278730 100644 --- a/src/frontend/components/UI/Winetricks/index.tsx +++ b/src/frontend/components/UI/Winetricks/index.tsx @@ -4,13 +4,15 @@ import { ProgressDialog } from '../ProgressDialog' import WinetricksSearchBar from './WinetricksSearch' import { useTranslation } from 'react-i18next' import SettingsContext from 'frontend/screens/Settings/SettingsContext' +import { Runner } from 'common/types' interface Props { onClose: () => void + runner: Runner } -export default function Winetricks({ onClose }: Props) { - const { appName, runner } = useContext(SettingsContext) +export default function Winetricks({ onClose, runner }: Props) { + const { appName } = useContext(SettingsContext) const { t } = useTranslation() const [loading, setLoading] = useState(true) diff --git a/src/frontend/hooks/useSettingsContext.ts b/src/frontend/hooks/useSettingsContext.ts index cd0b704471..43f8489063 100644 --- a/src/frontend/hooks/useSettingsContext.ts +++ b/src/frontend/hooks/useSettingsContext.ts @@ -6,8 +6,8 @@ import ContextProvider from 'frontend/state/ContextProvider' type Props = { appName: string - gameInfo: GameInfo - runner: Runner + gameInfo?: GameInfo + runner?: Runner } const useSettingsContext = ({ appName, gameInfo, runner }: Props) => { diff --git a/src/frontend/screens/Settings/SettingsContext.tsx b/src/frontend/screens/Settings/SettingsContext.tsx index 0a28dff343..cff8965bd4 100644 --- a/src/frontend/screens/Settings/SettingsContext.tsx +++ b/src/frontend/screens/Settings/SettingsContext.tsx @@ -9,7 +9,7 @@ const initialContext: SettingsContextType = { isDefault: true, appName: 'default', runner: 'legendary', - gameInfo: null, + gameInfo: undefined, isMacNative: false, isLinuxNative: false } diff --git a/src/frontend/screens/Settings/components/OfflineMode.tsx b/src/frontend/screens/Settings/components/OfflineMode.tsx index a3af91e6b7..c6f31a6fae 100644 --- a/src/frontend/screens/Settings/components/OfflineMode.tsx +++ b/src/frontend/screens/Settings/components/OfflineMode.tsx @@ -14,6 +14,9 @@ const OfflineMode = () => { useEffect(() => { const getInfo = async () => { + if (!runner) { + return + } const info = await getGameInfo(appName, runner) if (info) { const { canRunOffline: can_run_offline } = info @@ -21,9 +24,7 @@ const OfflineMode = () => { } } - if (!isDefault) { - getInfo() - } + getInfo() }, []) const [offlineMode, setOfflineMode] = useSetting('offlineMode', false) diff --git a/src/frontend/screens/Settings/components/Tools/index.tsx b/src/frontend/screens/Settings/components/Tools/index.tsx index 8ea01942af..9caab7f93e 100644 --- a/src/frontend/screens/Settings/components/Tools/index.tsx +++ b/src/frontend/screens/Settings/components/Tools/index.tsx @@ -19,11 +19,11 @@ export default function Tools() { const { platform } = useContext(ContextProvider) const isWindows = platform === 'win32' - if (isDefault || isWindows) { + if (isDefault || isWindows || !runner) { return <> } - async function callTools(tool: 'winecfg' | 'runExe', exe?: string) { + const callTools = async (tool: 'winecfg' | 'runExe', exe?: string) => { const toolStates = { winecfg: setWinecfgRunning, runExe: setRunExeRunning @@ -64,7 +64,7 @@ export default function Tools() { } } - async function dropHandler(ev: React.DragEvent) { + const dropHandler = async (ev: React.DragEvent) => { // Prevent default behavior (Prevent file from being opened) ev.preventDefault() @@ -97,7 +97,9 @@ export default function Tools() { return ( <>
- {winetricksRunning && } + {winetricksRunning && ( + + )}