diff --git a/app/globals.css b/app/globals.css
index cad0201..bd6213e 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,33 +1,3 @@
@tailwind base;
@tailwind components;
-@tailwind utilities;
-
-/* :root {
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
- }
-}
-
-body {
- color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
-}
-
-@layer utilities {
- .text-balance {
- text-wrap: balance;
- }
-} */
\ No newline at end of file
+@tailwind utilities;
\ No newline at end of file
diff --git a/app/layout.tsx b/app/layout.tsx
index 3314e47..0bcecca 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -15,7 +15,7 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
+
{children}
);
diff --git a/app/music/danmu.tsx b/app/music/danmu.tsx
new file mode 100644
index 0000000..860e2f2
--- /dev/null
+++ b/app/music/danmu.tsx
@@ -0,0 +1,96 @@
+'use client';
+import { useState, useEffect, useCallback } from "react";
+import useWebSocket, { ReadyState } from 'react-use-websocket';
+
+const MOMO_IM_URL = 'wss://live-ws.immomo.com/ws/im'
+
+export const Danmu: React.FC = () => {
+ //Public API that will echo messages sent to it back to the client
+ const [socketUrl, setSocketUrl] = useState(MOMO_IM_URL);
+ const [messageHistory, setMessageHistory] = useState[]>([]);
+
+ // { "msg_id": 1, "client_time": 1712305590234, "type": "Sauth", "data": { "momoid": "404821828", "roomid": "14515460054", "role": 6, "isVisitor": false, "token": "97e721d0bd3bf2e63a9797f9daf50919", "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" } }
+ const { sendMessage, lastMessage, readyState } = useWebSocket(socketUrl, {
+ heartbeat:
+ {
+ message: () => {
+ const pingMessage = { "msg_id": 2, "client_time": Date.now(), "type": "Ping", "data": {} }
+ return JSON.stringify(pingMessage);
+ },
+ interval: 5000,
+ }
+ });
+
+ const momoId = "404821828"
+ const roomId = "14515460054"
+ const momoToken = "97e721d0bd3bf2e63a9797f9daf50919"
+
+ const clientTime = Date.now()
+ const data = {
+ "msg_id": 1,
+ "client_time": clientTime,
+ "type": "Sauth",
+ "data": {
+ "momoid": momoId, "roomid": roomId,
+ "role": 6, "isVisitor": false,
+ "token": momoToken
+ },
+ }
+
+ useEffect(() => {
+ if (ReadyState.OPEN === readyState) {
+ sendMessage(JSON.stringify(data));
+ }
+ }, [readyState])
+
+
+
+ useEffect(() => {
+ if (lastMessage !== null) {
+ if (lastMessage.data) {
+ const message = JSON.parse(lastMessage.data);
+ if (message.type === 'pong') {
+ return;
+ }
+ setMessageHistory((prev) => prev.concat(message));
+ }
+ }
+ }, [lastMessage]);
+
+
+ const connectionStatus = {
+ [ReadyState.CONNECTING]: 'Connecting',
+ [ReadyState.OPEN]: 'Open',
+ [ReadyState.CLOSING]: 'Closing',
+ [ReadyState.CLOSED]: 'Closed',
+ [ReadyState.UNINSTANTIATED]: 'Uninstantiated',
+ }[readyState];
+
+ return (
+
+ {messageHistory.map((message, idx) => (
+
+ ))}
+
+
You underestimate my power!
+
+
+ );
+};
+
+// TODO
+const MessageDispatcher: React.FC = ({ message }) => {
+
+ const messageType = message?.groups?.[0]?.units?.[0]?.type
+ let nick = 'wait';
+ let content = 'wait';
+
+ if (messageType === 'Message') {
+ nick = message?.groups?.[0]?.nick;
+ content = message?.groups?.[0]?.units?.[0]?.['Msg.Message.data']?.text
+ }
+ return ()
+
+};
\ No newline at end of file
diff --git a/app/music/page.tsx b/app/music/page.tsx
index 57e519a..e5eafd3 100644
--- a/app/music/page.tsx
+++ b/app/music/page.tsx
@@ -1,3 +1,7 @@
+import { Danmu } from "./danmu";
+
export default function Page() {
- return hello world
+ return hello world
+
+
}
\ No newline at end of file
diff --git a/app/page.tsx b/app/page.tsx
index dcc2b40..2c359a2 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -3,115 +3,122 @@ import SignoutButton from "@/app/components/signout-button";
import Link from "next/link";
export default function Home() {
- return (
-
-
- 弹幕测试
-
-
- Get started by editing
- app/page.tsx
-
-
-
-
-
-
-
-
-
-
- );
+ return
+
+ 弹幕测试
+
}
+
+// export default function Home() {
+// return (
+//
+//
+// 弹幕测试
+//
+//
+// Get started by editing
+// app/page.tsx
+//
+//
+//
+
+//
+//
+//
+
+//
+//
+// );
+// }
diff --git a/package.json b/package.json
index f7aca14..244b6a5 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
"axios": "^1.6.8",
"next": "14.1.4",
"react": "^18",
- "react-dom": "^18"
+ "react-dom": "^18",
+ "react-use-websocket": "^4.8.1"
},
"devDependencies": {
"@types/node": "^20",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a62d75d..1e9fbd3 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,6 +17,9 @@ dependencies:
react-dom:
specifier: ^18
version: 18.2.0(react@18.2.0)
+ react-use-websocket:
+ specifier: ^4.8.1
+ version: 4.8.1(react-dom@18.2.0)(react@18.2.0)
devDependencies:
'@types/node':
@@ -2393,6 +2396,16 @@ packages:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: true
+ /react-use-websocket@4.8.1(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-FTXuG5O+LFozmu1BRfrzl7UIQngECvGJmL7BHsK4TYXuVt+mCizVA8lT0hGSIF0Z0TedF7bOo1nRzOUdginhDw==}
+ peerDependencies:
+ react: '>= 18.0.0'
+ react-dom: '>= 18.0.0'
+ dependencies:
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 8d0d047..2d8e539 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -17,5 +17,15 @@ const config: Config = {
},
},
plugins: [daisyui],
+ daisyui: {
+ themes: false, // false: only light + dark | true: all themes | array: specific themes like this ["light", "dark", "cupcake"]
+ darkTheme: "dark", // name of one of the included themes for dark mode
+ base: true, // applies background color and foreground color for root element by default
+ styled: true, // include daisyUI colors and design decisions for all components
+ utils: true, // adds responsive and modifier utility classes
+ prefix: "", // prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors)
+ logs: true, // Shows info about daisyUI version and used config in the console when building your CSS
+ themeRoot: ":root", // The element that receives theme color CSS variables
+ },
};
export default config;