refactor: 调整目录结构
This commit is contained in:
parent
28d86317c6
commit
8e2682e7c2
@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable no-console -- debug */
|
/* eslint-disable no-console -- debug */
|
||||||
"use client";
|
"use client";
|
||||||
import { useRef, useState, useEffect } from "react";
|
import { useRef, useState, useEffect } from "react";
|
||||||
import { query } from "@/app/lib/actions/lyrics";
|
import { query } from "@/lib/actions/lyrics";
|
||||||
|
|
||||||
const useLyricsRunner = (runner: (lyric: string) => void, interval: number) => {
|
const useLyricsRunner = (runner: (lyric: string) => void, interval: number) => {
|
||||||
const [lyrics, setLyrics] = useState<string[]>([]);
|
const [lyrics, setLyrics] = useState<string[]>([]);
|
||||||
|
@ -3,6 +3,7 @@ import { Inter } from "next/font/google";
|
|||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import SignoutButton from "./components/signout-button";
|
import SignoutButton from "./components/signout-button";
|
||||||
import Logo from "./components/logo";
|
import Logo from "./components/logo";
|
||||||
|
import BackButton from "./components/back-button";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
@ -42,7 +43,10 @@ export default function RootLayout({
|
|||||||
关于
|
关于
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
<SignoutButton className="inline-flex items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-base mt-4 md:mt-0" />
|
<div className="join">
|
||||||
|
<BackButton className="btn join-item" />
|
||||||
|
<SignoutButton className="btn join-item" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
@ -56,9 +60,7 @@ export default function RootLayout({
|
|||||||
<Logo />
|
<Logo />
|
||||||
<span className="ml-3 text-xl">音乐弹幕</span>
|
<span className="ml-3 text-xl">音乐弹幕</span>
|
||||||
</a>
|
</a>
|
||||||
<p className="mt-2 text-sm text-gray-500">
|
<p className="mt-2 text-sm text-gray-500">歌曲歌词到直播间</p>
|
||||||
歌曲歌词到直播间
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-grow flex flex-wrap md:pl-20 -mb-10 md:mt-0 mt-10 md:text-left text-center">
|
<div className="flex-grow flex flex-wrap md:pl-20 -mb-10 md:mt-0 mt-10 md:text-left text-center">
|
||||||
<div className="lg:w-1/4 md:w-1/2 w-full px-4">
|
<div className="lg:w-1/4 md:w-1/2 w-full px-4">
|
||||||
|
@ -1,96 +1,100 @@
|
|||||||
'use client';
|
"use client";
|
||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
import useWebSocket, { ReadyState } from 'react-use-websocket';
|
import useWebSocket, { ReadyState } from "react-use-websocket";
|
||||||
|
|
||||||
const MOMO_IM_URL = 'wss://live-ws.immomo.com/ws/im'
|
const MOMO_IM_URL = "wss://live-ws.immomo.com/ws/im";
|
||||||
|
|
||||||
export const Danmu: React.FC = () => {
|
export const Danmu: React.FC = () => {
|
||||||
//Public API that will echo messages sent to it back to the client
|
//Public API that will echo messages sent to it back to the client
|
||||||
const [socketUrl, setSocketUrl] = useState(MOMO_IM_URL);
|
const [socketUrl, setSocketUrl] = useState(MOMO_IM_URL);
|
||||||
const [messageHistory, setMessageHistory] = useState<MessageEvent<any>[]>([]);
|
const [messageHistory, setMessageHistory] = useState<MessageEvent<any>[]>([]);
|
||||||
|
|
||||||
// { "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" } }
|
// { "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, {
|
const { sendMessage, lastMessage, readyState } = useWebSocket(socketUrl, {
|
||||||
heartbeat:
|
heartbeat: {
|
||||||
{
|
message: () => {
|
||||||
message: () => {
|
const pingMessage = {
|
||||||
const pingMessage = { "msg_id": 2, "client_time": Date.now(), "type": "Ping", "data": {} }
|
msg_id: 2,
|
||||||
return JSON.stringify(pingMessage);
|
client_time: Date.now(),
|
||||||
},
|
type: "Ping",
|
||||||
interval: 5000,
|
data: {},
|
||||||
}
|
};
|
||||||
});
|
return JSON.stringify(pingMessage);
|
||||||
|
},
|
||||||
|
interval: 5000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const momoId = "404821828"
|
const momoId = "404821828";
|
||||||
const roomId = "14515460054"
|
const roomId = "14515460054";
|
||||||
const momoToken = "97e721d0bd3bf2e63a9797f9daf50919"
|
const momoToken = "97e721d0bd3bf2e63a9797f9daf50919";
|
||||||
|
|
||||||
const clientTime = Date.now()
|
const clientTime = Date.now();
|
||||||
const data = {
|
const data = {
|
||||||
"msg_id": 1,
|
msg_id: 1,
|
||||||
"client_time": clientTime,
|
client_time: clientTime,
|
||||||
"type": "Sauth",
|
type: "Sauth",
|
||||||
"data": {
|
data: {
|
||||||
"momoid": momoId, "roomid": roomId,
|
momoid: momoId,
|
||||||
"role": 6, "isVisitor": false,
|
roomid: roomId,
|
||||||
"token": momoToken
|
role: 6,
|
||||||
},
|
isVisitor: false,
|
||||||
|
token: momoToken,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ReadyState.OPEN === readyState) {
|
||||||
|
sendMessage(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
}, [readyState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ReadyState.OPEN === readyState) {
|
if (lastMessage !== null) {
|
||||||
sendMessage(JSON.stringify(data));
|
if (lastMessage.data) {
|
||||||
|
const message = JSON.parse(lastMessage.data);
|
||||||
|
if (message.type === "pong") {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, [readyState])
|
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 (
|
||||||
useEffect(() => {
|
<div>
|
||||||
if (lastMessage !== null) {
|
{messageHistory.map((message, idx) => (
|
||||||
if (lastMessage.data) {
|
<MessageDispatcher key={idx} message={message} />
|
||||||
const message = JSON.parse(lastMessage.data);
|
))}
|
||||||
if (message.type === 'pong') {
|
<div className="chat chat-end">
|
||||||
return;
|
<div className="chat-bubble">You underestimate my power!</div>
|
||||||
}
|
</div>
|
||||||
setMessageHistory((prev) => prev.concat(message));
|
</div>
|
||||||
}
|
);
|
||||||
}
|
|
||||||
}, [lastMessage]);
|
|
||||||
|
|
||||||
|
|
||||||
const connectionStatus = {
|
|
||||||
[ReadyState.CONNECTING]: 'Connecting',
|
|
||||||
[ReadyState.OPEN]: 'Open',
|
|
||||||
[ReadyState.CLOSING]: 'Closing',
|
|
||||||
[ReadyState.CLOSED]: 'Closed',
|
|
||||||
[ReadyState.UNINSTANTIATED]: 'Uninstantiated',
|
|
||||||
}[readyState];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{messageHistory.map((message, idx) => (
|
|
||||||
<MessageDispatcher key={idx} message={message} />
|
|
||||||
))}
|
|
||||||
<div className="chat chat-end">
|
|
||||||
<div className="chat-bubble">You underestimate my power!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO
|
const MessageDispatcher: React.FC<{ message: any }> = ({ message }) => {
|
||||||
const MessageDispatcher: React.FC = ({ message }) => {
|
const messageType = message?.groups?.[0]?.units?.[0]?.type;
|
||||||
|
let nick = "wait";
|
||||||
const messageType = message?.groups?.[0]?.units?.[0]?.type
|
let content = "wait";
|
||||||
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 (<div className="chat chat-start">
|
|
||||||
<div className="chat-bubble">{nick}: {content}</div>
|
|
||||||
</div>)
|
|
||||||
|
|
||||||
|
if (messageType === "Message") {
|
||||||
|
nick = message?.groups?.[0]?.nick;
|
||||||
|
content = message?.groups?.[0]?.units?.[0]?.["Msg.Message.data"]?.text;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="chat chat-start">
|
||||||
|
<div className="chat-bubble">
|
||||||
|
{nick}: {content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
@ -1,7 +1,5 @@
|
|||||||
import { Danmu } from "./danmu";
|
import { Danmu } from "./danmu";
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <main>hello world
|
return <Danmu />;
|
||||||
<Danmu />
|
|
||||||
</main>
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { signin } from "@/app/lib/actions/auth";
|
import { signin } from "@/lib/actions/auth";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useFormState, useFormStatus } from "react-dom";
|
import { useFormState, useFormStatus } from "react-dom";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { signup } from "@/app/lib/actions/auth";
|
import { signup } from "@/lib/actions/auth";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useFormState, useFormStatus } from "react-dom";
|
import { useFormState, useFormStatus } from "react-dom";
|
||||||
import signupSvg from "@/app/signup/signup.svg";
|
import signupSvg from "@/app/signup/signup.svg";
|
||||||
|
21
components/back-button.tsx
Normal file
21
components/back-button.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
export default function BackButton({
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
className?: string | undefined;
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={className}
|
||||||
|
onClick={() => {
|
||||||
|
router.back();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
回退
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { signout } from "@/app/lib/actions/auth";
|
import { signout } from "@/lib/actions/auth";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
|
||||||
export default function SignoutButton({
|
export default function SignoutButton({
|
Loading…
Reference in New Issue
Block a user