mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat: implement latest version updater for macos (#2214)
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
@@ -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',
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user