Skip to content

Commit

Permalink
feat: add meteor component
Browse files Browse the repository at this point in the history
  • Loading branch information
oeyoews committed Nov 1, 2024
1 parent 1ea4c91 commit f58dd1a
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 77 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"publisher": "oeyoews",
"name": "usewiki2",
"displayName": "usewiki2",
"version": "2.7.2",
"version": "2.8.0",
"private": true,
"packageManager": "[email protected]",
"description": "",
Expand Down
26 changes: 23 additions & 3 deletions packages/react/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { WebviewMessenger } from './utils/WebViewMessenger';
import { getLinks } from './links';
import { useTranslation } from 'react-i18next';
import { ILanguage } from './i18n';
import Meteors from './components/ui/meteors';

const vscode =
// @ts-expect-error
Expand All @@ -39,6 +40,7 @@ function App() {
const [inputValue, setInputValue] = useState('');
const inputRef = useRef<HTMLTextAreaElement>(null);
const [placeholder, setPlaceholder] = useState(t('placeholder'));
const [dark, setDark] = useState(false);

function changeLanguage(lang: ILanguage) {
i18n.changeLanguage(lang);
Expand Down Expand Up @@ -84,6 +86,19 @@ function App() {
}
}, []);

// theme
useEffect(() => {
// 监听theme变化
messenger.on('changeTheme', (data) => {
console.log(data, 'changeTheme');
if (data.text === 'dark') {
setDark(true);
} else {
setDark(false);
}
});
}, []);

useEffect(() => {
messenger.on('playSound', () => {
playSound();
Expand Down Expand Up @@ -124,7 +139,7 @@ function App() {
// }

return (
<div className="relative h-screen p-3 antialiased">
<div className="relative h-screen p-3 antialiased overflow-hidden">
<h1 className="text-xl font-bold">
{t('app_name')}
<img
Expand All @@ -142,7 +157,13 @@ function App() {
<ContextMenuItem>Coming</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>

{/* meeteors */}
{/* TODO: 添加开关配置 */}
{dark && (
<div className="flex w-full flex-col items-center justify-center overflow-hidden pointer-events-none">
<Meteors number={20} />
</div>
)}
{/* https://talks.antfu.me/2024/vue-fes-japan/15?clicks=6 */}
<Accordion
type="single"
Expand Down Expand Up @@ -175,7 +196,6 @@ function App() {
</AccordionContent>
</AccordionItem>
</Accordion>

<div className="absolute inset-x-3 bottom-3 flex flex-col gap-2 p-0">
<Textarea
ref={inputRef}
Expand Down
44 changes: 44 additions & 0 deletions packages/react/src/components/ui/meteors.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client";

import { useEffect, useState } from "react";

import { cn } from "@/lib/utils";

interface MeteorsProps {
number?: number;
}
export const Meteors = ({ number = 20 }: MeteorsProps) => {
const [meteorStyles, setMeteorStyles] = useState<Array<React.CSSProperties>>(
[],
);

useEffect(() => {
const styles = [...new Array(number)].map(() => ({
top: -5,
left: Math.floor(Math.random() * window.innerWidth) + "px",
animationDelay: Math.random() * 1 + 0.2 + "s",
animationDuration: Math.floor(Math.random() * 8 + 2) + "s",
}));
setMeteorStyles(styles);
}, [number]);

return (
<>
{[...meteorStyles].map((style, idx) => (
// Meteor Head
<span
key={idx}
className={cn(
"pointer-events-none absolute left-1/2 top-1/2 size-0.5 rotate-[215deg] animate-meteor rounded-full bg-slate-500 shadow-[0_0_0_1px_#ffffff10]",
)}
style={style}
>
{/* Meteor Tail */}
<div className="pointer-events-none absolute top-1/2 -z-10 h-px w-[50px] -translate-y-1/2 bg-gradient-to-r from-slate-500 to-transparent" />
</span>
))}
</>
);
};

export default Meteors;
156 changes: 85 additions & 71 deletions packages/react/tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,77 +11,91 @@ export default {
// preflight: true,
// },
theme: {
extend: {
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)',
},
colors: {
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))',
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))',
},
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))',
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))',
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))',
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))',
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))',
},
border: 'transparent',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
chart: {
1: 'hsl(var(--chart-1))',
2: 'hsl(var(--chart-2))',
3: 'hsl(var(--chart-3))',
4: 'hsl(var(--chart-4))',
5: 'hsl(var(--chart-5))',
},
},
keyframes: {
'accordion-down': {
from: {
height: '0',
},
to: {
height: 'var(--radix-accordion-content-height)',
},
},
'accordion-up': {
from: {
height: 'var(--radix-accordion-content-height)',
},
to: {
height: '0',
},
},
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
},
},
extend: {
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
},
colors: {
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))'
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))'
},
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))'
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))'
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))'
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))'
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))'
},
border: 'transparent',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
chart: {
'1': 'hsl(var(--chart-1))',
'2': 'hsl(var(--chart-2))',
'3': 'hsl(var(--chart-3))',
'4': 'hsl(var(--chart-4))',
'5': 'hsl(var(--chart-5))'
}
},
keyframes: {
'accordion-down': {
from: {
height: '0'
},
to: {
height: 'var(--radix-accordion-content-height)'
}
},
'accordion-up': {
from: {
height: 'var(--radix-accordion-content-height)'
},
to: {
height: '0'
}
},
meteor: {
'0%': {
transform: 'rotate(215deg) translateX(0)',
opacity: '1'
},
'70%': {
opacity: '1'
},
'100%': {
transform: 'rotate(215deg) translateX(-500px)',
opacity: '0'
}
}
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
meteor: 'meteor 5s linear infinite'
}
}
},
plugins: [
require('tailwindcss-animate'),
Expand Down
2 changes: 1 addition & 1 deletion src/generated/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// Meta info
export const publisher = "oeyoews"
export const name = "usewiki2"
export const version = "2.7.2"
export const version = "2.8.0"
export const displayName = "usewiki2"
export const description = undefined
export const extensionId = `${publisher}.${name}`
Expand Down
7 changes: 6 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { usewikiViewProvider } from './webviews';
import * as openWiki from './commands/openWikiCmd';
import * as wikiInfo from './commands/wikiInfo';
import * as opensetting from './commands/openSettings';
import { type ExtensionContext, window, commands } from 'vscode';
import {
type ExtensionContext,
window,
commands,
ColorThemeKind,
} from 'vscode';

// import * as usewikiCmd from './commands/usewikiCmd';
// import * as refreshWiki from './commands/refreshWiki';
Expand Down
28 changes: 28 additions & 0 deletions src/webviews/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@ import {
Uri,
workspace,
env,
window,
ColorTheme,
type Webview,
type WebviewView,
type WebviewViewResolveContext,
type CancellationToken,
type ExtensionContext,
type WebviewViewProvider,
ColorThemeKind,
} from 'vscode';

export class usewikiViewProvider implements WebviewViewProvider {
private _view?: WebviewView;
private _messenger?: WebviewMessenger;
constructor(
private context: ExtensionContext,
private _extensionUri = context.extensionUri
Expand Down Expand Up @@ -45,6 +49,18 @@ export class usewikiViewProvider implements WebviewViewProvider {
});

const messenger = new WebviewMessenger({ context: this._view });
this._messenger = messenger;
this.checkTheme();
window.onDidChangeActiveColorTheme((theme) => {
const themeKind = theme.kind;
if (themeKind === ColorThemeKind.Dark) {
messenger.send('changeTheme', { text: 'dark' });
} else if (themeKind === ColorThemeKind.Light) {
messenger.send('changeTheme', { text: 'light' });
} else {
messenger.send('changeTheme', { text: 'high-contrast' });
}
});

messenger.send('changeLanguage', { text: getLang() });
messenger.on('showVsCodeLanguageInputBox', async () => {
Expand All @@ -67,6 +83,18 @@ export class usewikiViewProvider implements WebviewViewProvider {
});
});
}
// 初始化时检查当前主题模式
private checkTheme() {
const themeKind = window.activeColorTheme.kind;
if (themeKind === ColorThemeKind.Dark) {
this._messenger?.send('changeTheme', { text: 'dark' });
} else if (themeKind === ColorThemeKind.Light) {
this._messenger?.send('changeTheme', { text: 'light' });
} else {
this._messenger?.send('changeTheme', { text: 'high-contrast' });
}
}

private getWebviewContent(webview: Webview) {
const scriptUri = webview.asWebviewUri(
Uri.joinPath(this._extensionUri, 'react-dist', 'main.js')
Expand Down

0 comments on commit f58dd1a

Please sign in to comment.