feat: implement latest version updater for macos (#2214)

Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
Horus
2023-05-09 02:21:15 +08:00
committed by GitHub
parent d1457075b3
commit 41d4af1dc1
21 changed files with 263 additions and 12 deletions

View File

@@ -105,3 +105,66 @@ export const sidebarFloatMaskStyle = style({
},
},
});
export const haloStyle = style({
overflow: 'hidden',
width: '100%',
height: '100%',
position: 'absolute',
top: 0,
left: 0,
':before': {
content: '""',
display: 'block',
width: '60%',
height: '40%',
position: 'absolute',
top: '80%',
left: '50%',
background:
'linear-gradient(180deg, rgba(50, 26, 206, 0.1) 10%, rgba(50, 26, 206, 0.35) 30%, rgba(84, 56, 255, 1) 50%)',
filter: 'blur(10px) saturate(1.2)',
transform: 'translateX(-50%) translateY(calc(0 * 1%)) scale(0)',
transition: '0.3s ease',
willChange: 'filter',
},
selectors: {
'&:hover:before': {
transform: 'translateX(-50%) translateY(calc(-70 * 1%)) scale(1)',
},
},
});
export const updaterButtonStyle = style({});
export const particlesStyle = style({
background: `var(--svg-animation), var(--svg-animation)`,
backgroundRepeat: 'no-repeat, repeat',
backgroundPosition: 'center, center top 100%',
backgroundSize: '100%, 130%',
WebkitMaskImage:
'linear-gradient(to top, transparent, black, black, transparent)',
width: '100%',
height: '100%',
position: 'absolute',
});
export const particlesBefore = style({
content: '""',
display: 'block',
position: 'absolute',
width: '100%',
height: '100%',
background: `var(--svg-animation), var(--svg-animation), var(--svg-animation)`,
backgroundRepeat: 'no-repeat, repeat, repeat',
backgroundPosition: 'center, center top 100%, center center',
backgroundSize: '100% 120%, 150%, 120%',
filter: 'blur(1px)',
willChange: 'filter',
});
export const installLabelStyle = style({
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
paddingLeft: '8px',
});

View File

@@ -1,4 +1,6 @@
import { atomWithObservable } from 'jotai/utils';
import { atomWithStorage } from 'jotai/utils';
import { Observable } from 'rxjs';
export const APP_SIDEBAR_OPEN = 'app-sidebar-open';
export const appSidebarOpenAtom = atomWithStorage(
@@ -9,3 +11,20 @@ export const appSidebarWidthAtom = atomWithStorage(
'app-sidebar-width',
256 /* px */
);
export const updateAvailableAtom = atomWithObservable<boolean>(() => {
return new Observable<boolean>(subscriber => {
if (typeof window !== 'undefined') {
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
if (isMacosDesktop) {
const dispose = window.apis?.onClientUpdateAvailable(() => {
subscriber.next(true);
});
return () => {
dispose?.();
};
}
}
subscriber.next(false);
});
});

View File

@@ -1,7 +1,10 @@
import { Button } from '@affine/component';
import { getEnvironment } from '@affine/env';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import {
ArrowLeftSmallIcon,
ArrowRightSmallIcon,
ResetIcon,
SidebarIcon,
} from '@blocksuite/icons';
import { assignInlineVars } from '@vanilla-extract/dynamic';
@@ -13,18 +16,23 @@ import { forwardRef, useCallback, useEffect } from 'react';
import { IconButton } from '../../ui/button/IconButton';
import {
floatingMaxWidth,
haloStyle,
installLabelStyle,
navBodyStyle,
navFooterStyle,
navHeaderStyle,
navStyle,
navWidthVar,
particlesStyle,
sidebarButtonStyle,
sidebarFloatMaskStyle,
updaterButtonStyle,
} from './index.css';
import {
APP_SIDEBAR_OPEN,
appSidebarOpenAtom,
appSidebarWidthAtom,
updateAvailableAtom,
} from './index.jotai';
export { appSidebarOpenAtom };
@@ -36,7 +44,8 @@ export type AppSidebarProps = PropsWithChildren<{
export const AppSidebar = forwardRef<HTMLElement, AppSidebarProps>(
function AppSidebar(props, forwardedRef): ReactElement {
const [open, setOpen] = useAtom(appSidebarOpenAtom);
const clientUpdateAvailable = useAtomValue(updateAvailableAtom);
const t = useAFFiNEI18N();
const appSidebarWidth = useAtomValue(appSidebarWidthAtom);
const initialRender = open === undefined;
@@ -112,6 +121,23 @@ export const AppSidebar = forwardRef<HTMLElement, AppSidebarProps>(
</IconButton>
</div>
<div className={navBodyStyle}>{props.children}</div>
{clientUpdateAvailable && (
<Button
onClick={() => {
window.apis?.onClientUpdateInstall();
}}
noBorder
className={updaterButtonStyle}
type={'light'}
>
<div className={particlesStyle} aria-hidden="true"></div>
<span className={haloStyle} aria-hidden="true"></span>
<div className={installLabelStyle}>
<ResetIcon />
<span>{t['Restart Install Client Update']()}</span>
</div>
</Button>
)}
<div className={navFooterStyle}>{props.footer}</div>
</nav>
<div