From 2dcfbfbc126b2ee6006cee52d1bf2c6ded5e21d7 Mon Sep 17 00:00:00 2001 From: arvinxx Date: Wed, 1 Nov 2023 22:18:17 +0800 Subject: [PATCH] :tada: chore: int project --- .eslintrc.cjs | 1 + .gitignore | 24 ++++ .npmrc | 10 ++ .prettierrc.cjs | 1 + README.md | 125 ++++++++++++++++++ index.html | 12 ++ package.json | 33 +++++ public/manifest-dev.json | 20 +++ public/manifest.json | 20 +++ src/app.tsx | 29 ++++ src/components/clock/circle/Circle.tsx | 26 ++++ src/components/clock/index.tsx | 25 ++++ src/components/clock/needles/Needles.style.ts | 52 ++++++++ src/components/clock/needles/Needles.tsx | 37 ++++++ src/components/clock/sticks/Sticks.style.ts | 46 +++++++ src/components/clock/sticks/Sticks.tsx | 27 ++++ src/components/time/index.tsx | 21 +++ src/components/time/style.ts | 24 ++++ src/global.css | 39 ++++++ src/main.tsx | 16 +++ src/store/index.ts | 53 ++++++++ src/vite-env.d.ts | 1 + tsconfig.json | 25 ++++ tsconfig.node.json | 10 ++ vite.config.ts | 7 + 25 files changed, 684 insertions(+) create mode 100644 .eslintrc.cjs create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .prettierrc.cjs create mode 100644 README.md create mode 100644 index.html create mode 100644 package.json create mode 100644 public/manifest-dev.json create mode 100644 public/manifest.json create mode 100644 src/app.tsx create mode 100644 src/components/clock/circle/Circle.tsx create mode 100644 src/components/clock/index.tsx create mode 100644 src/components/clock/needles/Needles.style.ts create mode 100644 src/components/clock/needles/Needles.tsx create mode 100644 src/components/clock/sticks/Sticks.style.ts create mode 100644 src/components/clock/sticks/Sticks.tsx create mode 100644 src/components/time/index.tsx create mode 100644 src/components/time/style.ts create mode 100644 src/global.css create mode 100644 src/main.tsx create mode 100644 src/store/index.ts create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..bc75953 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').eslint; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5fb53b3 --- /dev/null +++ b/.npmrc @@ -0,0 +1,10 @@ +lockfile=false +public-hoist-pattern[]=*@umijs/lint* +public-hoist-pattern[]=*changelog* +public-hoist-pattern[]=*commitlint* +public-hoist-pattern[]=*eslint* +public-hoist-pattern[]=*postcss* +public-hoist-pattern[]=*prettier* +public-hoist-pattern[]=*remark* +public-hoist-pattern[]=*semantic-release* +public-hoist-pattern[]=*stylelint* diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..f0355a9 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1 @@ +module.exports = require('@lobehub/lint').prettier; diff --git a/README.md b/README.md new file mode 100644 index 0000000..3443da8 --- /dev/null +++ b/README.md @@ -0,0 +1,125 @@ + + +
+ + + + + +

Clock Time
LobeChat Plugin

+ +This plugin show a clock of current time. + +[Changelog](./CHANGELOG.md) Β· [Report Bug][issues-url] Β· [Request Feature][issues-url] + + + +[![plugin][plugin-shield]][plugin-url] +[![releaseDate][release-date-shield]][release-date-url] +[![ciTest][ci-test-shield]][ci-test-url] +[![ciRelease][ci-release-shield]][ci-release-url]
+[![contributors][contributors-shield]][contributors-url] +[![forks][forks-shield]][forks-url] +[![stargazers][stargazers-shield]][stargazers-url] +[![issues][issues-shield]][issues-url] + +![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png) + +
+ +
+Table of contents + +#### TOC + +- [🀯 Usage](#-usage) +- [⌨️ Local Development](#️-local-development) +- [🀝 Contributing](#-contributing) + +#### + +
+ +## 🀯 Usage + +This is a function calling plugin for [Lobe Chat](https://github.com/lobehub/lobe-chat), you can install it in plugin setting page. + +
+ +[![][back-to-top]](#readme-top) + +
+ +## ⌨️ Local Development + +You can use Gitpod for online development: + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][gitpod-url] + +Or clone it for local development: + +```bash +$ git clone https://github.com/lobehub/chat-plugin-clock-time.git +$ cd lobe-ui +$ pnpm install +$ pnpm start +``` + +
+ +[![][back-to-top]](#readme-top) + +
+ +## 🀝 Contributing + + + +> πŸ“Š Total: **3** + + + + + + + + + + + + + +
+ +[![][back-to-top]](#readme-top) + +
+ +--- + +#### πŸ“ License + +Copyright Β© 2023 [LobeHub][profile-url].
+This project is [MIT](./LICENSE) licensed. + + + +[back-to-top]: https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square +[ci-release-shield]: https://github.com/lobehub/chat-plugin-clock-time/actions/workflows/release.yml/badge.svg +[ci-release-url]: https://github.com/lobehub/chat-plugin-clock-time/actions/workflows/release.yml +[ci-test-shield]: https://github.com/lobehub/chat-plugin-clock-time/actions/workflows/test.yml/badge.svg +[ci-test-url]: https://github.com/lobehub/chat-plugin-clock-time/actions/workflows/test.yml +[contributors-shield]: https://img.shields.io/github/contributors/lobehub/chat-plugin-clock-time.svg?style=flat +[contributors-url]: https://github.com/lobehub/chat-plugin-clock-time/graphs/contributors +[forks-shield]: https://img.shields.io/github/forks/lobehub/chat-plugin-clock-time.svg?style=flat +[forks-url]: https://github.com/lobehub/chat-plugin-clock-time/network/members +[gitpod-url]: https://gitpod.io/#https://github.com/lobehub/chat-plugin-clock-time +[issues-shield]: https://img.shields.io/github/issues/lobehub/chat-plugin-clock-time.svg?style=flat +[issues-url]: https://github.com/lobehub/chat-plugin-clock-time/issues/new/choose +[plugin-shield]: https://img.shields.io/badge/%F0%9F%A4%AF_LobeChat-plugin-cyan +[plugin-url]: https://github.com/lobehub/lobe-chat-plugins +[profile-url]: https://github.com/lobehub +[release-date-shield]: https://img.shields.io/github/release-date/lobehub/chat-plugin-clock-time?style=flat +[release-date-url]: https://github.com/lobehub/chat-plugin-clock-time/releases +[stargazers-shield]: https://img.shields.io/github/stars/lobehub/chat-plugin-clock-time.svg?style=flat +[stargazers-url]: https://github.com/lobehub/chat-plugin-clock-time/stargazers diff --git a/index.html b/index.html new file mode 100644 index 0000000..973dda1 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + LobeChat Plugin Time + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..2e54ca8 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "@lobehub/chat-plugin-clock-time", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "tsc && vite build", + "dev": "vite", + "lint": "eslint \"{src,api,docs}/**/*.{js,jsx,ts,tsx}\" --fix", + "preview": "vite preview" + }, + "dependencies": { + "@lobehub/ui": "^1.108.2", + "antd-style": "^3.5.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-layout-kit": "^1", + "zustand": "^4", + "zustand-utils": "^1" + }, + "devDependencies": { + "@lobehub/lint": "latest", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@vitejs/plugin-react-swc": "^3.3.2", + "eslint": "^8.45.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "prettier": "^3.0.3", + "typescript": "^5.0.2", + "vite": "^4.4.5" + } +} diff --git a/public/manifest-dev.json b/public/manifest-dev.json new file mode 100644 index 0000000..297f85a --- /dev/null +++ b/public/manifest-dev.json @@ -0,0 +1,20 @@ +{ + "api": [ + { + "name": "getCurrentTime", + "description": "θŽ·ε–ε½“ε‰ζ—Άι—΄", + "parameters": { + "type": "object", + "properties": {} + } + } + ], + "type": "standalone", + "identifier": "date-time-dev", + "ui": { + "url": "http://localhost:5173/", + "height": 350, + "width": 400 + }, + "version": "1" +} diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..63a452d --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,20 @@ +{ + "api": [ + { + "name": "getCurrentTime", + "description": "θŽ·ε–ε½“ε‰ζ—Άι—΄", + "parameters": { + "type": "object", + "properties": {} + } + } + ], + "type": "standalone", + "identifier": "clock-time", + "ui": { + "url": "http://localhost:5173/", + "height": 350, + "width": 400 + }, + "version": "1" +} diff --git a/src/app.tsx b/src/app.tsx new file mode 100644 index 0000000..279f704 --- /dev/null +++ b/src/app.tsx @@ -0,0 +1,29 @@ +import { FC, useEffect } from 'react'; +import { Center } from 'react-layout-kit'; + +import Clock from './components/clock'; +import Time from './components/time'; +import { useStore } from './store'; + +export const App: FC = () => { + const { updateTimeAction } = useStore(); + + useEffect(() => { + const id = setInterval(() => { + updateTimeAction(); + }, 1000); + + return () => { + clearInterval(id); + }; + }, []); + + return ( +
+
+ +
+
+ ); +}; diff --git a/src/components/clock/circle/Circle.tsx b/src/components/clock/circle/Circle.tsx new file mode 100644 index 0000000..cbe8796 --- /dev/null +++ b/src/components/clock/circle/Circle.tsx @@ -0,0 +1,26 @@ +import { createStyles } from 'antd-style'; +import { FC, PropsWithChildren } from 'react'; +import { Center } from 'react-layout-kit'; + +const useStyles = createStyles(({ token, isDarkMode }) => { + const shadowColor = `hsla(210, 30%, 86%, 1)`; + + return { + root: { + background: token.colorBgElevated, + border: isDarkMode ? `1px solid ${token.colorBorder}` : undefined, + borderRadius: '50%', + boxShadow: isDarkMode + ? `box-shadow: rgba(17, 17, 26, 0.1) 0px 8px 24px, rgba(17, 17, 26, 0.1) 0px 16px 56px, rgba(17, 17, 26, 0.1) 0px 24px 80px` + : `-6px -6px 16px ${token.colorBgContainer}, 6px 6px 16px ${shadowColor}, inset 6px 6px 16px ${shadowColor}, inset -6px -6px 16px ${token.colorBgContainer}`, + height: '200px', + position: 'relative', + width: '200px', + }, + }; +}); + +export const Circle: FC = (props) => { + const { styles } = useStyles(); + return
{props.children}
; +}; diff --git a/src/components/clock/index.tsx b/src/components/clock/index.tsx new file mode 100644 index 0000000..6af5dcb --- /dev/null +++ b/src/components/clock/index.tsx @@ -0,0 +1,25 @@ +import { memo } from 'react'; + +import { useStore } from '../../store'; +import { Circle } from './circle/Circle'; +import { NeedleHours, NeedleMinutes, NeedleSeconds } from './needles/Needles'; +import { Axis, StickNine, StickSix, StickThree, StickTwelve } from './sticks/Sticks'; + +const Clock = memo(() => { + const { hours, minutes, seconds } = useStore(); + + return ( + + + + + + + + + + + ); +}); + +export default Clock; diff --git a/src/components/clock/needles/Needles.style.ts b/src/components/clock/needles/Needles.style.ts new file mode 100644 index 0000000..cc1a2bb --- /dev/null +++ b/src/components/clock/needles/Needles.style.ts @@ -0,0 +1,52 @@ +import { createStyles } from "antd-style"; + +export const useTimeStyles = createStyles(({ token }) => ({ + hours: { + "&:before": { + backgroundColor: token.colorText, + borderRadius: ".75rem", + content: '""', + height: "3rem", + position: "absolute", + width: ".25rem", + zIndex: "var(--z-normal)", + }, + display: "flex", + height: "105px", + justifyContent: "center", + position: "absolute", + width: "105px", + }, + minutes: { + "&:before": { + backgroundColor: token.colorText, + borderRadius: ".75rem", + content: '""', + height: "4rem", + position: "absolute", + width: ".25rem", + zIndex: "var(--z-normal)", + }, + display: "flex", + height: "136px", + justifyContent: "center", + position: "absolute", + width: "136px", + }, + seconds: { + "&:before": { + backgroundColor: token.blue, + borderRadius: ".75rem", + content: '""', + height: "5rem", + position: "absolute", + width: ".125rem", + zIndex: "var(--z-normal)", + }, + display: "flex", + height: "130px", + justifyContent: "center", + position: "absolute", + width: "130px", + }, +})); diff --git a/src/components/clock/needles/Needles.tsx b/src/components/clock/needles/Needles.tsx new file mode 100644 index 0000000..d32a40d --- /dev/null +++ b/src/components/clock/needles/Needles.tsx @@ -0,0 +1,37 @@ +import { useTimeStyles } from "./Needles.style"; +import { FC } from "react"; + +interface Props { + value: number; +} + +export const NeedleHours: FC = (props) => { + const { styles } = useTimeStyles(); + + return ( + + ); +}; + +export const NeedleMinutes: FC = (props) => { + const { styles } = useTimeStyles(); + return ( + + ); +}; + +export const NeedleSeconds: FC = (props) => { + const { styles } = useTimeStyles(); + return ( + + ); +}; diff --git a/src/components/clock/sticks/Sticks.style.ts b/src/components/clock/sticks/Sticks.style.ts new file mode 100644 index 0000000..38a7320 --- /dev/null +++ b/src/components/clock/sticks/Sticks.style.ts @@ -0,0 +1,46 @@ +import { createStyles } from "antd-style"; + +export const useSticksStyles = createStyles(({ token }) => ({ + axis: { + backgroundColor: token.blue, + border: `2px solid ${token.blue7}`, + borderRadius: "50%", + height: ".75rem", + width: ".75rem", + zIndex: "var(--z-tooltip)", + }, + nine: { + backgroundColor: token.colorText, + height: "1px", + left: ".75rem", + position: "absolute", + top: "50%", + width: "1rem", + }, + six: { + backgroundColor: token.colorText, + bottom: "1.25rem", + height: "1px", + left: "50%", + position: "absolute", + transform: "translateX(-50%) rotate(90deg)", + width: "1rem", + }, + three: { + backgroundColor: token.colorText, + height: "1px", + position: "absolute", + right: ".75rem", + top: "50%", + width: "1rem", + }, + twelve: { + backgroundColor: token.colorText, + height: "1px", + left: "50%", + position: "absolute", + top: "1.5rem", + transform: "translateX(-50%) rotate(90deg)", + width: "1rem", + }, +})); diff --git a/src/components/clock/sticks/Sticks.tsx b/src/components/clock/sticks/Sticks.tsx new file mode 100644 index 0000000..5733d91 --- /dev/null +++ b/src/components/clock/sticks/Sticks.tsx @@ -0,0 +1,27 @@ +import * as React from "react"; +import { useSticksStyles } from "./Sticks.style"; + +export const StickTwelve: React.FC = () => { + const { styles } = useSticksStyles(); + return ; +}; + +export const StickThree: React.FC = () => { + const { styles } = useSticksStyles(); + return ; +}; + +export const StickSix: React.FC = () => { + const { styles } = useSticksStyles(); + return ; +}; + +export const StickNine: React.FC = () => { + const { styles } = useSticksStyles(); + return ; +}; + +export const Axis: React.FC = () => { + const { styles } = useSticksStyles(); + return ; +}; diff --git a/src/components/time/index.tsx b/src/components/time/index.tsx new file mode 100644 index 0000000..1ecd8d3 --- /dev/null +++ b/src/components/time/index.tsx @@ -0,0 +1,21 @@ +import { memo } from 'react'; + +import { useStore } from '../../store'; +import { useTimeStyles } from './style'; + +const Time = memo(() => { + const { styles } = useTimeStyles(); + const props = useStore(); + + const formatterHours = props.textHours < 10 ? '0' + props.textHours + ':' : props.textHours + ':'; + const formatterMinutes = props.textMinutes < 10 ? '0' + props.textMinutes : props.textMinutes; + return ( +
+
{formatterHours}
+
{formatterMinutes}
+
{props.ampm}
+
+ ); +}); + +export default Time; diff --git a/src/components/time/style.ts b/src/components/time/style.ts new file mode 100644 index 0000000..88120ac --- /dev/null +++ b/src/components/time/style.ts @@ -0,0 +1,24 @@ +import { createStyles } from "antd-style"; + +export const useTimeStyles = createStyles(({ token }) => ({ + ampm: { + color: token.colorTextQuaternary, + fontSize: "var(--tiny-font-size)", + fontWeight: "var(--font-medium)", + marginLeft: "var(--mn-0-25)", + }, + container: { + display: "flex", + justifyContent: "center", + }, + hours: { + color: token.colorText, + fontSize: "var(--biggest-font-size)", + fontWeight: "var(--font-medium)", + }, + minutes: { + color: token.colorText, + fontSize: "var(--biggest-font-size)", + fontWeight: "var(--font-medium)", + }, +})); diff --git a/src/global.css b/src/global.css new file mode 100644 index 0000000..8bd37cc --- /dev/null +++ b/src/global.css @@ -0,0 +1,39 @@ +:root { + /*========== Colors ==========*/ + --hue-color: 240; + + /*========== Font and typography ==========*/ + --body-font: 'Poppins', sans-serif; + --biggest-font-size: 3rem; + --small-font-size: 0.813rem; + --smaller-font-size: 0.75rem; + --tiny-font-size: 0.625rem; + + /*========== Font weight ==========*/ + --font-medium: 500; + + /*========== Margenes Bottom ==========*/ + --mb-0-25: 0.25rem; + --mb-1: 1rem; + --mb-1-5: 1.5rem; + --mb-2-5: 2.5rem; + + /*========== z index ==========*/ + --z-normal: 1; + --z-tooltip: 10; +} + +@media screen and (min-width: 968px) { + :root { + --biggest-font-size: 3.5rem; + --small-font-size: 0.875rem; + --smaller-font-size: 0.813rem; + --tiny-font-size: 0.75rem; + } +} + +html, +body { + background: transparent !important; + color-scheme: light !important; +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..830b67d --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,16 @@ +import { ThemeProvider } from '@lobehub/ui'; +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; + +import { App } from './app.tsx'; +import './global.css'; + +const root = createRoot(document.querySelector('#root')!); + +root.render( + + + + + , +); diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..bf18d13 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,53 @@ +import { create } from 'zustand'; + +export interface IClockState { + ampm: string; + hours: number; + minutes: number; + seconds: number; + textHours: number; + textMinutes: number; +} + +const initialState: IClockState = { + ampm: '', + hours: 0, + minutes: 0, + seconds: 0, + textHours: 0, + textMinutes: 0, +}; + +export interface Store extends IClockState { + updateTimeAction: () => void; +} +export const useStore = create((set) => ({ + ...initialState, + + updateTimeAction: () => { + const date = new Date(); + let hh = date.getHours() * 30; + let mm = date.getMinutes() * 6; + let ss = date.getSeconds() * 6; + let hours = date.getHours(); + let minutes = date.getMinutes(); + let ampm; + if (hours >= 12) { + hours -= 12; + ampm = 'PM'; + } else { + ampm = 'AM'; + } + if (hours === 0) { + hours = 12; + } + set({ + ampm: ampm, + hours: hh + mm / 12, + minutes: mm, + seconds: ss, + textHours: hours, + textMinutes: minutes, + }); + }, +})); diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a7fc6fb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..861b04b --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +})