fix: left sidebar style fixes (#3950)

Co-authored-by: Alex Yang <himself65@outlook.com>
This commit is contained in:
Peng Xiao
2023-08-29 00:04:22 +08:00
committed by GitHub
parent e92d27549a
commit d62935935f
15 changed files with 235 additions and 99 deletions

View File

@@ -18,21 +18,23 @@ export const root = style({
'&:hover': {
background: 'var(--affine-white-60)',
},
'&[data-has-update="true"]:before': {
'&[data-disabled="true"]': {
pointerEvents: 'none',
},
'&:after': {
content: "''",
position: 'absolute',
top: '-3px',
right: '-3px',
top: '-2px',
right: '-2px',
width: '8px',
height: '8px',
backgroundColor: 'var(--affine-primary-color)',
borderRadius: '50%',
zIndex: 1,
opacity: 1,
transition: '0.3s ease',
transition: 'opacity 0.3s',
},
'&[data-disabled="true"]': {
pointerEvents: 'none',
'&:hover:after': {
opacity: 0,
},
},
vars: {
@@ -42,7 +44,7 @@ export const root = style({
export const icon = style({
marginRight: '18px',
color: 'var(--affine-primary-color)',
color: 'var(--affine-icon-color)',
fontSize: '24px',
});
@@ -90,7 +92,7 @@ export const installLabelNormal = style([
{
justifyContent: 'space-between',
selectors: {
[`${root}:hover &`]: {
[`${root}:hover &, ${root}[data-updating=true] &`]: {
display: 'none',
},
},
@@ -102,7 +104,7 @@ export const installLabelHover = style([
{
display: 'none',
selectors: {
[`${root}:hover &`]: {
[`${root}:hover &, ${root}[data-updating=true] &`]: {
display: 'flex',
},
},
@@ -175,7 +177,7 @@ export const particles = style({
pointerEvents: 'none',
display: 'none',
selectors: {
[`${root}:hover &`]: {
[`${root}:hover &, ${root}[data-updating=true] &`]: {
display: 'block',
},
'&:before': {
@@ -224,8 +226,10 @@ export const halo = style({
'radial-gradient(ellipse 30% 45% at bottom, rgba(30, 150, 235, 0.6), transparent)',
},
selectors: {
'&:hover:before, &:hover:after': {
transform: 'translateY(0) scale(1)',
},
[`${root}:hover &:before, ${root}:hover &:after,
${root}[data-updating=true] &:before, ${root}[data-updating=true] &:after`]:
{
transform: 'translateY(0) scale(1)',
},
},
});

View File

@@ -1,4 +1,5 @@
import { isBrowser } from '@affine/env/constant';
import type { UpdateMeta } from '@toeverything/infra';
import { atomWithObservable, atomWithStorage } from 'jotai/utils';
import { Observable } from 'rxjs';
@@ -8,7 +9,7 @@ function rpcToObservable<
H extends () => Promise<T>,
E extends (callback: (t: T) => void) => () => void,
>(
initialValue: T,
initialValue: T | null,
{
event,
handler,
@@ -18,8 +19,8 @@ function rpcToObservable<
handler?: H;
onSubscribe?: () => void;
}
) {
return new Observable<T>(subscriber => {
): Observable<T | null> {
return new Observable<T | null>(subscriber => {
subscriber.next(initialValue);
onSubscribe?.();
if (!isBrowser || !environment.isDesktop || !event) {
@@ -40,13 +41,13 @@ function rpcToObservable<
}
export const updateReadyAtom = atomWithObservable(() => {
return rpcToObservable(null as any | null, {
return rpcToObservable(null as UpdateMeta | null, {
event: window.events?.updater.onUpdateReady,
});
});
export const updateAvailableAtom = atomWithObservable(() => {
return rpcToObservable(null as any | null, {
return rpcToObservable(null as UpdateMeta | null, {
event: window.events?.updater.onUpdateAvailable,
onSubscribe: () => {
window.apis?.updater.checkForUpdatesAndNotify().catch(err => {
@@ -56,8 +57,8 @@ export const updateAvailableAtom = atomWithObservable(() => {
});
});
export const downloadProgressAtom = atomWithObservable<number>(() => {
return rpcToObservable(0, {
export const downloadProgressAtom = atomWithObservable(() => {
return rpcToObservable(null as number | null, {
event: window.events?.updater.onDownloadProgress,
});
});

View File

@@ -14,7 +14,17 @@ import {
updateReadyAtom,
} from './index.jotai';
interface AddPageButtonProps {
export interface AddPageButtonPureProps {
onClickUpdate: () => void;
onDismissCurrentChangelog: () => void;
currentChangelogUnread: boolean;
updateReady: boolean;
updateAvailable: {
version: string;
allowAutoUpdate: boolean;
} | null;
downloadProgress: number | null;
appQuitting: boolean;
className?: string;
style?: React.CSSProperties;
}
@@ -39,61 +49,19 @@ const currentChangelogUnreadAtom = atom(async get => {
return false;
});
// Although it is called an input, it is actually a button.
export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
export function AppUpdaterButtonPure({
updateReady,
onClickUpdate,
onDismissCurrentChangelog,
currentChangelogUnread,
updateAvailable,
downloadProgress,
appQuitting,
className,
style,
}: AddPageButtonPureProps) {
const t = useAFFiNEI18N();
const currentChangelogUnread = useAtomValue(currentChangelogUnreadAtom);
const updateReady = useAtomValue(updateReadyAtom);
const updateAvailable = useAtomValue(updateAvailableAtom);
const currentVersion = useAtomValue(currentVersionAtom);
const downloadProgress = useAtomValue(downloadProgressAtom);
const setChangelogCheckAtom = useSetAtom(changelogCheckedAtom);
const [appQuitting, setAppQuitting] = useState(false);
const onDismissCurrentChangelog = useCallback(() => {
if (!currentVersion) {
return;
}
startTransition(() =>
setChangelogCheckAtom(mapping => {
return {
...mapping,
[currentVersion]: true,
};
})
);
}, [currentVersion, setChangelogCheckAtom]);
const onClickUpdate = useCallback(() => {
if (updateReady) {
setAppQuitting(true);
window.apis?.updater.quitAndInstall().catch(err => {
// TODO: add error toast here
console.error(err);
});
} else if (updateAvailable) {
if (updateAvailable.allowAutoUpdate) {
// wait for download to finish
} else {
window.open(
`https://github.com/toeverything/AFFiNE/releases/tag/v${currentVersion}`,
'_blank'
);
}
} else if (currentChangelogUnread) {
window.open(runtimeConfig.changelogUrl, '_blank');
onDismissCurrentChangelog();
} else {
throw new Unreachable();
}
}, [
currentChangelogUnread,
currentVersion,
onDismissCurrentChangelog,
updateAvailable,
updateReady,
]);
if (!updateAvailable && !currentChangelogUnread) {
return null;
}
@@ -125,7 +93,8 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
<button
style={style}
className={clsx([styles.root, className])}
data-has-update={updateAvailable ? 'true' : 'false'}
data-has-update={!!updateAvailable}
data-updating={appQuitting}
data-disabled={
(updateAvailable?.allowAutoUpdate && !updateReady) || appQuitting
}
@@ -157,7 +126,9 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
<div className={clsx([styles.installLabelHover])}>
<ResetIcon className={styles.icon} />
<span className={styles.ellipsisTextOverflow}>
{t['com.affine.updater.restart-to-update']()}
{t[
appQuitting ? 'Loading' : 'com.affine.updater.restart-to-update'
]()}
</span>
</div>
) : (
@@ -215,3 +186,76 @@ export function AppUpdaterButton({ className, style }: AddPageButtonProps) {
);
}
}
// Although it is called an input, it is actually a button.
export function AppUpdaterButton({
className,
style,
}: {
className?: string;
style?: React.CSSProperties;
}) {
const currentChangelogUnread = useAtomValue(currentChangelogUnreadAtom);
const updateReady = useAtomValue(updateReadyAtom);
const updateAvailable = useAtomValue(updateAvailableAtom);
const currentVersion = useAtomValue(currentVersionAtom);
const downloadProgress = useAtomValue(downloadProgressAtom);
const setChangelogCheckAtom = useSetAtom(changelogCheckedAtom);
const [appQuitting, setAppQuitting] = useState(false);
const onDismissCurrentChangelog = useCallback(() => {
if (!currentVersion) {
return;
}
startTransition(() =>
setChangelogCheckAtom(mapping => {
return {
...mapping,
[currentVersion]: true,
};
})
);
}, [currentVersion, setChangelogCheckAtom]);
const onClickUpdate = useCallback(() => {
if (updateReady) {
setAppQuitting(true);
window.apis?.updater.quitAndInstall().catch(err => {
// TODO: add error toast here
console.error(err);
});
} else if (updateAvailable) {
if (updateAvailable.allowAutoUpdate) {
// wait for download to finish
} else {
window.open(
`https://github.com/toeverything/AFFiNE/releases/tag/v${currentVersion}`,
'_blank'
);
}
} else if (currentChangelogUnread) {
window.open(runtimeConfig.changelogUrl, '_blank');
onDismissCurrentChangelog();
} else {
throw new Unreachable();
}
}, [
currentChangelogUnread,
currentVersion,
onDismissCurrentChangelog,
updateAvailable,
updateReady,
]);
return (
<AppUpdaterButtonPure
appQuitting={appQuitting}
updateReady={!!updateReady}
onClickUpdate={onClickUpdate}
onDismissCurrentChangelog={onDismissCurrentChangelog}
currentChangelogUnread={currentChangelogUnread}
updateAvailable={updateAvailable}
downloadProgress={downloadProgress}
className={className}
style={style}
/>
);
}

View File

@@ -70,7 +70,7 @@ export const mainContainerStyle = style({
backgroundColor: 'var(--affine-background-primary-color)',
selectors: {
'&[data-show-padding="true"]': {
margin: '8px',
margin: '8px 8px 8px 0',
borderRadius: '5px',
overflow: 'hidden',
boxShadow: 'var(--affine-shadow-1)',