Skip to content

Commit

Permalink
fix: aside resizing added
Browse files Browse the repository at this point in the history
  • Loading branch information
siandreev committed Mar 13, 2024
1 parent 7005191 commit 0957f1e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 48 deletions.
4 changes: 0 additions & 4 deletions apps/desktop/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,6 @@ const WideLayout = styled.div`
width: 100%;
height: 100%;
display: flex;
& > *:first-child {
width: 250px;
}
`;

const WideContent = styled.div`
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/Keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum AppKey {
MNEMONIC = 'mnemonic',

THEME = 'theme',
UI_PREFERENCES = 'ui_preferences',

PASSWORD = 'password',
LOCK = 'lock',
Expand Down
152 changes: 110 additions & 42 deletions packages/uikit/src/components/aside/AsideMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useCallback, useMemo, useState } from 'react';
import { FC, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import { useAppContext } from '../../hooks/appContext';
Expand All @@ -13,9 +13,28 @@ import { ImportNotification } from '../create/ImportNotification';
import { SubscriptionInfo } from './SubscriptionInfo';
import { WalletEmoji } from '../shared/emoji/WalletEmoji';
import { useIsScrolled } from '../../hooks/useIsScrolled';
import { useUserUIPreferences, useMutateUserUIPreferencesWidth } from '../../state/theme';

const AsideContainer = styled.div`
const AsideContainer = styled.div<{ width: number }>`
height: 100%;
display: flex;
position: relative;
width: ${p => p.width}px;
`;

const AsideResizeHandle = styled.div`
position: absolute;
height: 100%;
width: 10px;
cursor: col-resize;
right: -5px;
z-index: 50;
`;

const AsideContentContainer = styled.div`
flex: 1;
height: 100%;
width: 100%;
box-sizing: border-box;
background: ${p => p.theme.backgroundContent};
Expand Down Expand Up @@ -158,50 +177,99 @@ export const AsideMenu: FC<{ className?: string }> = ({ className }) => {
[location.pathname]
);

const [asideWidth, setAsideWidth] = useState(250);
const asideWidthRef = useRef(asideWidth);
const isResizing = useRef(false);
const { data: uiPreferences } = useUserUIPreferences();
const { mutate: mutateWidth } = useMutateUserUIPreferencesWidth();

useLayoutEffect(() => {
if (uiPreferences?.asideWidth) {
setAsideWidth(uiPreferences?.asideWidth);
asideWidthRef.current = uiPreferences?.asideWidth;
}
}, [uiPreferences?.asideWidth]);

useEffect(() => {
const minWidth = 200;
const maxWidth = 500;
const onMouseUp = () => {
document.body.style.cursor = 'unset';
document.documentElement.classList.remove('no-user-select');
isResizing.current = false;
mutateWidth({ asideWidth: asideWidthRef.current });
};

const onMouseMove = (e: MouseEvent) => {
if (isResizing.current) {
const newWidth =
e.pageX < minWidth ? minWidth : e.pageX > maxWidth ? maxWidth : e.pageX;
setAsideWidth(newWidth);
asideWidthRef.current = newWidth;
}
};

document.addEventListener('mouseup', onMouseUp);
document.addEventListener('mousemove', onMouseMove);
return () => {
document.removeEventListener('mouseup', onMouseUp);
document.removeEventListener('mousemove', onMouseMove);
};
}, [mutateWidth]);

return (
<AsideContainer className={className}>
<ScrollContainer ref={ref}>
{proFeatures && (
<AsideContainer width={asideWidth}>
<AsideContentContainer className={className}>
<ScrollContainer ref={ref}>
{proFeatures && (
<AsideMenuCard
isSelected={activeRoute === AppProRoute.dashboard}
onClick={() => handleNavigateClick(AppProRoute.dashboard)}
>
<StatsIcon />
<Body2>{t('aside_dashboard')}</Body2>
</AsideMenuCard>
)}
{account.publicKeys.map(publicKey => (
<AsideMenuAccount
key={publicKey}
publicKey={publicKey}
isSelected={
!activeRoute &&
!!account.activePublicKey &&
account.activePublicKey === publicKey
}
/>
))}
</ScrollContainer>
<AsideMenuBottom>
<DividerStyled isHidden={!closeBottom} />
<AsideMenuCard isSelected={false} onClick={() => setIsOpenImport(true)}>
<IconWrapper>
<PlusIcon />
</IconWrapper>
<Body2>{t('aside_add_wallet')}</Body2>
</AsideMenuCard>
<AsideMenuCard
isSelected={activeRoute === AppProRoute.dashboard}
onClick={() => handleNavigateClick(AppProRoute.dashboard)}
onClick={() => handleNavigateClick(AppRoute.settings)}
isSelected={activeRoute === AppRoute.settings}
>
<StatsIcon />
<Body2>{t('aside_dashboard')}</Body2>
<IconWrapper>
<SlidersIcon />
</IconWrapper>
<Body2>{t('aside_settings')}</Body2>
</AsideMenuCard>
)}
{account.publicKeys.map(publicKey => (
<AsideMenuAccount
key={publicKey}
publicKey={publicKey}
isSelected={
!activeRoute &&
!!account.activePublicKey &&
account.activePublicKey === publicKey
}
/>
))}
</ScrollContainer>
<AsideMenuBottom>
<DividerStyled isHidden={!closeBottom} />
<AsideMenuCard isSelected={false} onClick={() => setIsOpenImport(true)}>
<IconWrapper>
<PlusIcon />
</IconWrapper>
<Body2>{t('aside_add_wallet')}</Body2>
</AsideMenuCard>
<AsideMenuCard
onClick={() => handleNavigateClick(AppRoute.settings)}
isSelected={activeRoute === AppRoute.settings}
>
<IconWrapper>
<SlidersIcon />
</IconWrapper>
<Body2>{t('aside_settings')}</Body2>
</AsideMenuCard>
<SubscriptionInfo />
</AsideMenuBottom>
<ImportNotification isOpen={isOpenImport} setOpen={setIsOpenImport} />
<SubscriptionInfo />
</AsideMenuBottom>
<ImportNotification isOpen={isOpenImport} setOpen={setIsOpenImport} />
</AsideContentContainer>
<AsideResizeHandle
onMouseDown={() => {
isResizing.current = true;
document.body.style.cursor = 'col-resize';
document.documentElement.classList.add('no-user-select');
}}
/>
</AsideContainer>
);
};
5 changes: 3 additions & 2 deletions packages/uikit/src/providers/UserThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { userDefaultTheme } from '@tonkeeper/core/dist/entries/theme';
import { FC, PropsWithChildren, useMemo } from 'react';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { useUserTheme } from '../state/theme';
import { useUserUIPreferences, useUserTheme } from '../state/theme';
import { defaultTheme } from '../styles/defaultTheme';
import { lightTheme } from '../styles/lightTheme';
import { proTheme } from '../styles/proTheme';
Expand All @@ -22,6 +22,7 @@ export const UserThemeProvider: FC<
PropsWithChildren<{ isDark?: boolean; displayType?: 'compact' | 'full-width'; isPro?: boolean }>
> = ({ children, isDark = true, displayType, isPro }) => {
const { data, isFetched } = useUserTheme();
const { isFetched: isUIPreferencesLoaded } = useUserUIPreferences();

const currentTheme = useMemo(() => {
let theme = isPro ? proTheme : isDark ? defaultTheme : lightTheme;
Expand Down Expand Up @@ -51,7 +52,7 @@ export const UserThemeProvider: FC<
}
}, [data, isDark, displayType, isPro]);

if (!isFetched) {
if (!isFetched || !isUIPreferencesLoaded) {
return <div></div>;
}

Expand Down
20 changes: 20 additions & 0 deletions packages/uikit/src/state/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,23 @@ export const useMutateTheme = () => {
await client.invalidateQueries([AppKey.THEME]);
});
};

export interface UIPreferences {
asideWidth: number;
}

export const useUserUIPreferences = () => {
const sdk = useAppSdk();
return useQuery([AppKey.UI_PREFERENCES], () => {
return sdk.storage.get<UIPreferences>(AppKey.UI_PREFERENCES);
});
};

export const useMutateUserUIPreferencesWidth = () => {
const sdk = useAppSdk();
const client = useQueryClient();
return useMutation<void, Error, UIPreferences>(async preferences => {
await sdk.storage.set(AppKey.UI_PREFERENCES, preferences);
await client.invalidateQueries([AppKey.UI_PREFERENCES]);
});
};
9 changes: 9 additions & 0 deletions packages/uikit/src/styles/globalStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ export const GlobalStyleCss = css`
-webkit-overflow-scrolling: touch;
}
html.no-user-select {
* {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
}
.disable-hover {
pointer-events: none;
}
Expand Down

0 comments on commit 0957f1e

Please sign in to comment.