mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 19:02:23 +08:00
feat(core): remove loop animations (#8242)
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { withUnit } from '../../utils/with-unit';
|
import { withUnit } from '../../utils/with-unit';
|
||||||
import { loading, speedVar } from './styles.css';
|
import { loading, rotateAnimation, speedVar } from './styles.css';
|
||||||
|
|
||||||
export interface LoadingProps {
|
export interface LoadingProps {
|
||||||
size?: number | string;
|
size?: number | string;
|
||||||
@@ -18,7 +19,7 @@ export const Loading = ({
|
|||||||
const sizeWithUnit = size ? withUnit(size, 'px') : '16px';
|
const sizeWithUnit = size ? withUnit(size, 'px') : '16px';
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
className={loading}
|
className={clsx(loading, speed !== 0 && rotateAnimation)}
|
||||||
width={sizeWithUnit}
|
width={sizeWithUnit}
|
||||||
height={sizeWithUnit}
|
height={sizeWithUnit}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ const rotate = keyframes({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
export const loading = style({
|
export const loading = style({
|
||||||
|
transform: 'rotate(-90deg)',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const rotateAnimation = style({
|
||||||
vars: {
|
vars: {
|
||||||
[speedVar]: '1.5s',
|
[speedVar]: '1.5s',
|
||||||
},
|
},
|
||||||
textRendering: 'optimizeLegibility',
|
|
||||||
transform: 'rotate(-90deg)',
|
|
||||||
animation: `${rotate} ${speedVar} infinite linear`,
|
animation: `${rotate} ${speedVar} infinite linear`,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,11 @@
|
|||||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||||
import {
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
GlobalStateService,
|
|
||||||
LiveData,
|
|
||||||
useLiveData,
|
|
||||||
useService,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { ToolContainer } from '../../workspace';
|
import { ToolContainer } from '../../workspace';
|
||||||
import { AIIcon } from './icons';
|
import { AIIcon } from './icons';
|
||||||
import {
|
import { aiIslandBtn, aiIslandWrapper, toolStyle } from './styles.css';
|
||||||
aiIslandAnimationBg,
|
|
||||||
aiIslandBtn,
|
|
||||||
aiIslandWrapper,
|
|
||||||
gradient,
|
|
||||||
toolStyle,
|
|
||||||
} from './styles.css';
|
|
||||||
|
|
||||||
const RIGHT_SIDEBAR_AI_HAS_EVER_OPENED_KEY =
|
|
||||||
'app:settings:rightsidebar:ai:has-ever-opened';
|
|
||||||
|
|
||||||
export const AIIsland = () => {
|
export const AIIsland = () => {
|
||||||
// to make sure ai island is hidden first and animate in
|
// to make sure ai island is hidden first and animate in
|
||||||
@@ -32,19 +18,6 @@ export const AIIsland = () => {
|
|||||||
);
|
);
|
||||||
const activeTab = useLiveData(activeView.activeSidebarTab$);
|
const activeTab = useLiveData(activeView.activeSidebarTab$);
|
||||||
const sidebarOpen = useLiveData(workbench.sidebarOpen$);
|
const sidebarOpen = useLiveData(workbench.sidebarOpen$);
|
||||||
const globalState = useService(GlobalStateService).globalState;
|
|
||||||
const aiChatHasEverOpened = useLiveData(
|
|
||||||
LiveData.from(
|
|
||||||
globalState.watch<boolean>(RIGHT_SIDEBAR_AI_HAS_EVER_OPENED_KEY),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (sidebarOpen && activeTab?.id === 'chat') {
|
|
||||||
globalState.set(RIGHT_SIDEBAR_AI_HAS_EVER_OPENED_KEY, true);
|
|
||||||
}
|
|
||||||
}, [activeTab, globalState, sidebarOpen]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setHide((sidebarOpen && activeTab?.id === 'chat') || !haveChatTab);
|
setHide((sidebarOpen && activeTab?.id === 'chat') || !haveChatTab);
|
||||||
@@ -52,18 +25,7 @@ export const AIIsland = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolContainer className={clsx(toolStyle, { hide })}>
|
<ToolContainer className={clsx(toolStyle, { hide })}>
|
||||||
<div
|
<div className={aiIslandWrapper} data-hide={hide}>
|
||||||
className={aiIslandWrapper}
|
|
||||||
data-hide={hide}
|
|
||||||
data-animation={!aiChatHasEverOpened}
|
|
||||||
>
|
|
||||||
{aiChatHasEverOpened ? null : (
|
|
||||||
<div className={aiIslandAnimationBg}>
|
|
||||||
<div className={gradient} />
|
|
||||||
<div className={gradient} />
|
|
||||||
<div className={gradient} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<button
|
<button
|
||||||
className={aiIslandBtn}
|
className={aiIslandBtn}
|
||||||
data-testid="ai-island"
|
data-testid="ai-island"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cssVar } from '@toeverything/theme';
|
import { cssVar } from '@toeverything/theme';
|
||||||
import { createVar, keyframes, style } from '@vanilla-extract/css';
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
export const toolStyle = style({
|
export const toolStyle = style({
|
||||||
selectors: {
|
selectors: {
|
||||||
@@ -49,84 +49,3 @@ export const aiIslandBtn = style({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// -------- animation --------
|
|
||||||
export const borderAngle1 = createVar('border-angle-1');
|
|
||||||
export const borderAngle2 = createVar('border-angle-2');
|
|
||||||
export const borderAngle3 = createVar('border-angle-3');
|
|
||||||
const brightBlue = createVar('bright-blue');
|
|
||||||
const brightGreen = createVar('bright-green');
|
|
||||||
const brightRed = createVar('bright-red');
|
|
||||||
const borderWidth = createVar('border-width');
|
|
||||||
|
|
||||||
const rotateBg = keyframes({
|
|
||||||
to: { transform: 'rotate(360deg)' },
|
|
||||||
});
|
|
||||||
|
|
||||||
export const aiIslandAnimationBg = style({
|
|
||||||
width: 'inherit',
|
|
||||||
height: 'inherit',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
borderRadius: '50%',
|
|
||||||
overflow: 'hidden',
|
|
||||||
|
|
||||||
vars: {
|
|
||||||
[borderAngle1]: '0deg',
|
|
||||||
[borderAngle2]: '90deg',
|
|
||||||
[borderAngle3]: '180deg',
|
|
||||||
[brightBlue]: 'rgb(0, 100, 255)',
|
|
||||||
[brightGreen]: '#1E96EB',
|
|
||||||
[brightRed]: 'rgb(0, 200, 255)',
|
|
||||||
[borderWidth]: '1.5px',
|
|
||||||
},
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
|
|
||||||
selectors: {
|
|
||||||
[`${aiIslandWrapper}[data-animation="true"] &`]: {
|
|
||||||
width: `calc(100% + 2 * ${borderWidth})`,
|
|
||||||
height: `calc(100% + 2 * ${borderWidth})`,
|
|
||||||
top: `calc(-1 * ${borderWidth})`,
|
|
||||||
left: `calc(-1 * ${borderWidth})`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const gradient = style({
|
|
||||||
position: 'absolute',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
borderRadius: 'inherit',
|
|
||||||
animationName: rotateBg,
|
|
||||||
animationIterationCount: 'infinite',
|
|
||||||
animationTimingFunction: 'linear',
|
|
||||||
pointerEvents: 'none',
|
|
||||||
willChange: 'transform',
|
|
||||||
selectors: {
|
|
||||||
[`&:nth-of-type(1)`]: {
|
|
||||||
animationDuration: '3s',
|
|
||||||
backgroundImage: `conic-gradient(from ${borderAngle1} at 50% 50%,
|
|
||||||
transparent, ${brightBlue} 10%,
|
|
||||||
transparent 30%,
|
|
||||||
transparent
|
|
||||||
)`,
|
|
||||||
},
|
|
||||||
[`&:nth-of-type(2)`]: {
|
|
||||||
animationDuration: '8s',
|
|
||||||
backgroundImage: `conic-gradient(from ${borderAngle2} at 50% 50%,
|
|
||||||
transparent, ${brightGreen} 10%,
|
|
||||||
transparent 60%,
|
|
||||||
transparent
|
|
||||||
)`,
|
|
||||||
},
|
|
||||||
[`&:nth-of-type(3)`]: {
|
|
||||||
animationDuration: '13s',
|
|
||||||
backgroundImage: `conic-gradient(from ${borderAngle3} at 50% 50%,
|
|
||||||
transparent, ${brightRed} 10%,
|
|
||||||
transparent 50%,
|
|
||||||
transparent
|
|
||||||
)`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const CloudWorkspaceStatus = () => {
|
|||||||
const SyncingWorkspaceStatus = ({ progress }: { progress?: number }) => {
|
const SyncingWorkspaceStatus = ({ progress }: { progress?: number }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Loading progress={progress} speed={progress ? 0 : undefined} />
|
<Loading progress={progress} speed={0} />
|
||||||
Syncing...
|
Syncing...
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ globalStyle(`.${workspaceActiveStatus} svg`, {
|
|||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
color: cssVar('iconSecondary'),
|
color: cssVar('iconSecondary'),
|
||||||
|
display: 'block',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const workspaceInfoTooltip = style({
|
export const workspaceInfoTooltip = style({
|
||||||
|
|||||||
Reference in New Issue
Block a user