diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml new file mode 100644 index 0000000..7dc1249 --- /dev/null +++ b/.idea/git_toolbox_blame.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/lib/generator/templates/package.json b/lib/generator/templates/package.json index 430291f..9c41dfe 100644 --- a/lib/generator/templates/package.json +++ b/lib/generator/templates/package.json @@ -14,23 +14,27 @@ }, "dependencies": { "@aelf-design/nextjs-registry": "^1.1.1", - "@aelf-web-login/wallet-adapter-base": "^0.0.2-alpha.9", - "@aelf-web-login/wallet-adapter-bridge": "^0.0.2-alpha.9", - "@aelf-web-login/wallet-adapter-night-elf": "^0.0.2-alpha.9", - "@aelf-web-login/wallet-adapter-portkey-aa": "^0.0.2-alpha.9", - "@aelf-web-login/wallet-adapter-portkey-discover": "^0.0.2-alpha.9", - "@aelf-web-login/wallet-adapter-react": "^0.0.2-alpha.9", + "@aelf-web-login/wallet-adapter-base": "^0.0.2-alpha.35", + "@aelf-web-login/wallet-adapter-bridge": "^0.0.2-alpha.35", + "@aelf-web-login/wallet-adapter-night-elf": "^0.0.2-alpha.35", + "@aelf-web-login/wallet-adapter-portkey-aa": "^0.0.2-alpha.35", + "@aelf-web-login/wallet-adapter-portkey-discover": "^0.0.2-alpha.35", + "@aelf-web-login/wallet-adapter-react": "^0.0.2-alpha.35", "@ant-design/nextjs-registry": "^1.0.0", + "@chaingpt/generalchat": "^0.0.8", "@next/third-parties": "^14.2.3", "@reduxjs/toolkit": "^2.2.5", "@sentry/nextjs": "^8.4.0", "aelf-design": "^1.1.0", "aelf-sdk": "^3.4.12", "antd": "^5.18.0", + "antd-mobile": "^5.36.1", "next": "^14.2.3", "react": "^18", "react-dom": "^18", - "react-redux": "^9.1.2" + "react-redux": "^9.1.2", + "react-use": "^17.5.0", + "socket.io-client": "^4.7.5" }, "devDependencies": { "@commitlint/cli": "^19.3.0", diff --git a/lib/generator/templates/src/app/api/demos/chaingpt/route.ts b/lib/generator/templates/src/app/api/demos/chaingpt/route.ts new file mode 100644 index 0000000..509b0e0 --- /dev/null +++ b/lib/generator/templates/src/app/api/demos/chaingpt/route.ts @@ -0,0 +1,53 @@ +import type {NextRequest} from "next/server"; +import {NextResponse} from "next/server"; +import {Errors, GeneralChat} from '@chaingpt/generalchat'; +import { setTimeout } from 'node:timers/promises' + +console.log('CHAINGPT_API_KEY: ', process.env.CHAINGPT_API_KEY); +const generalchat = new GeneralChat({ + apiKey: process.env.CHAINGPT_API_KEY as string, +}); + +interface Context { + params: undefined; +} + +async function chainGPTChat(question: string) { + return new Promise(async (resolve, reject) => { + try { + console.log('generalchat', question, process.env.CHAINGPT_API_KEY); + const stream = await generalchat.createChatStream({ + question: question, // 'Explain quantum computing in simple terms', + chatHistory: "off" + }); + let data = ''; + stream.on('data', (chunk: any) => { + console.log(chunk.toString()); + data += chunk.toString(); + }); + stream.on('end', () => { + console.log("Stream ended"); + resolve(data); + }); + } catch (error) { + console.log('error:', error); + if (error instanceof Errors.GeneralChatError) { + reject(error.message); + } + } + }); +} + +export async function POST(request: NextRequest, context: Context) { + const body: { question: string } = await request.json(); + const { question = '' } = body; + console.log('process.env.CHAINGPT_API_KEY', process.env.CHAINGPT_API_KEY); + try { + // const data = await chainGPTChat(question); + await setTimeout(1000); + const data = 'hello world'; + return NextResponse.json({ code: 0, data }); + } catch (error) { + return NextResponse.json({ code: -1, error: error }); + } +} diff --git a/lib/generator/templates/src/app/demos/aelf-design/page.tsx b/lib/generator/templates/src/app/demos/aelf-design/page.tsx index 151ec03..d139692 100644 --- a/lib/generator/templates/src/app/demos/aelf-design/page.tsx +++ b/lib/generator/templates/src/app/demos/aelf-design/page.tsx @@ -1,4 +1,8 @@ -import { HashAddress } from 'aelf-design'; +"use client" +// import { HashAddress } from 'aelf-design'; +// import { Button } from 'antd'; +// import { Button } from 'aelf-design'; +import { Button } from 'antd-mobile'; /** * * If you are using the App Router in Next.js and using antd as your component library, @@ -15,8 +19,10 @@ export default function Page() {

Get more components from https://ant.design/

}/>

Get more components from https://aelf-design.vercel.app

- - - + {/**/} + {/**/} + {/**/} + + {/**/} } diff --git a/lib/generator/templates/src/app/demos/chaingpt/components/AnswerBox.tsx b/lib/generator/templates/src/app/demos/chaingpt/components/AnswerBox.tsx new file mode 100644 index 0000000..7bd15fd --- /dev/null +++ b/lib/generator/templates/src/app/demos/chaingpt/components/AnswerBox.tsx @@ -0,0 +1,13 @@ +export function AnswerBox({ + children, + className + }: { + children: React.ReactNode, + className?: string +}) { + return
+
+ {children} +
+
+} diff --git a/lib/generator/templates/src/app/demos/chaingpt/components/QuestionBox.tsx b/lib/generator/templates/src/app/demos/chaingpt/components/QuestionBox.tsx new file mode 100644 index 0000000..f2b43c1 --- /dev/null +++ b/lib/generator/templates/src/app/demos/chaingpt/components/QuestionBox.tsx @@ -0,0 +1,11 @@ +export function QuestionBox({ + children, // will be a page or nested layout + }: { + children: React.ReactNode +}) { + return
+
+ {children} +
+
+} diff --git a/lib/generator/templates/src/app/demos/chaingpt/page.tsx b/lib/generator/templates/src/app/demos/chaingpt/page.tsx new file mode 100644 index 0000000..48006a5 --- /dev/null +++ b/lib/generator/templates/src/app/demos/chaingpt/page.tsx @@ -0,0 +1,118 @@ +"use client" +/** + * + * If you are using the App Router in Next.js and using antd as your component library, + * to make the antd component library work better in your Next.js application and provide a better user experience, + * you can try using the following method to extract + * and inject antd's first-screen styles into HTML to avoid page flicker. + * https://ant.design/docs/react/use-with-next + **/ +import { Input, Spin } from 'antd'; +const { Search } = Input; +import { QuestionBox } from '@/app/demos/chaingpt/components/QuestionBox'; +import { AnswerBox } from '@/app/demos/chaingpt/components/AnswerBox'; +import {useEffect, useRef, useState} from 'react'; + +interface IChatItem { + text: string; + type: 'question' | 'answer'; +} + +const defaultList: IChatItem[] = [{"text":"the current price of ELF","type":"question"},{"text":"The current price of ELF (aelf) is $0.3994312670003399. Please note that cryptocurrency prices are highly volatile and can change rapidly. It's always a good idea to check the latest prices on a reliable cryptocurrency exchange or market data platform. Let me know if there's anything else I can help you with!","type":"answer"}]; + +// TODO: Virtual list to hold the messages +// import VirtualList from 'rc-virtual-list'; +export default function Page() { + const [chatList, setChainList] = useState(defaultList); + const [searchDisable, setSearchDisable] = useState(false); + const [searchInput, setSearchInput] = useState(''); + + const onSearch = async (value: string) => { + console.log('value: ', value); + if (value.trim().length <= 0) { + return; + } + const question: IChatItem = { + text: value, + type: 'question' + }; + const _list = [...chatList, question]; + setChainList(_list); + setSearchDisable(true); + + const askChainGPT = async (question: string) => { + const url = '/api/demos/chaingpt'; + let data; + + const response = await fetch(url, { + method: "POST", + body: JSON.stringify({ question }), + }); + if (!response.ok) { + throw new Error(`Response status: ${response.status}`); + } + + const json = await response.json(); + console.log(json); + data = json.data; + return data; + }; + let answerMessage; + try { + answerMessage = await askChainGPT(value); + setSearchInput(''); + } catch (error) { + answerMessage = error instanceof Error ? error.message : 'Please try again'; + } + const answer: IChatItem = { + text: answerMessage, + type: 'answer' + }; + setChainList([..._list, answer]); + setSearchDisable(false); + }; + + console.log('chatList', chatList, JSON.stringify(chatList)); + const bottomRef = useRef(null); + useEffect(() => { + if (bottomRef.current) { + bottomRef.current.scrollIntoView({ behavior: "smooth" }); + } + }, [chatList]); + + return <> +
+
+
+
+ {/*Hello World*/} + {/*Hello World hzz! aelf addresses interoperability with other blockchain networks through its multi-chain architecture and cross-chain communication protocols.*/} + {/* The aelf blockchain is designed to support seamless communication and data exchange between different blockchains. It achieves this by implementing a main chain and multiple side chains. The main chain handles general functions and acts as a bridge between the side chains. Each side chain is dedicated to specific applications or business scenarios, allowing for better scalability and performance.*/} + {/*Hello World 2331111*/} + {/*Hello World*/} + {/*Hello World hzz! aelf addresses interoperability with other blockchain networks through its multi-chain architecture and cross-chain communication protocols.*/} + {/* The aelf blockchain is designed to support seamless communication and data exchange between different blockchains. It achieves this by implementing a main chain and multiple side chains. The main chain handles general functions and acts as a bridge between the side chains. Each side chain is dedicated to specific applications or business scenarios, allowing for better scalability and performance.*/} + {/*Hello World 2331111*/} + {chatList.map((item, index) => ( +
+ {item.type === 'question' ? {item.text} : {item.text}} +
+ ))} + +
+
+
+
+
+ setSearchInput(e.target.value)} + onSearch={onSearch} + placeholder="Please input your question" /> +
+
+ +} diff --git a/lib/generator/templates/src/app/demos/layout.tsx b/lib/generator/templates/src/app/demos/layout.tsx index 7bd1460..329faf6 100644 --- a/lib/generator/templates/src/app/demos/layout.tsx +++ b/lib/generator/templates/src/app/demos/layout.tsx @@ -1,17 +1,7 @@ -import Link from 'next/link'; -import NavLinks from '@/app/ui/demos/nav-links/page'; -import {NickNameItem} from '@/app/demos/redux/nickName/NickNameItem'; -import {WalletConnectItem} from '@/app/demos/redux/walletConnect/WalletConnectItem'; +import Footer from '@/components/Footer'; -function SideBarItem ({ - children, // will be a page or nested layout -}: { - children: React.ReactNode -}) { - return
- {children} -
-} +import { menuList} from '@/config/demo/configMenu'; +import { MenuCustom } from '@/components/demo/Menu'; export default function HelloLayout({ children, // will be a page or nested layout @@ -19,30 +9,16 @@ export default function HelloLayout({ children: React.ReactNode }) { return ( -
- {/* Include shared UI here e.g. a header or sidebar */} - {/**/} -
- demo home - demo home with search params - tailwind - image desktop and mobile - fonts - sentry - aelf-web3 sdk - aelf-design - Redux Toolkit - file-upload - web login - jest -
-

Show link path here

- +
+
+
+
+ +
+
{children}
- -
-
{children}
+
) } diff --git a/lib/generator/templates/src/app/demos/socket/page.tsx b/lib/generator/templates/src/app/demos/socket/page.tsx new file mode 100644 index 0000000..22134b7 --- /dev/null +++ b/lib/generator/templates/src/app/demos/socket/page.tsx @@ -0,0 +1,49 @@ +'use client'; +import { io } from 'socket.io-client'; +import { Button } from 'antd' +import {useEffect, useState} from 'react'; +import {response} from 'express'; + +export default function SocketPage() { + const [socket, setSocket] = useState(); + const [answer, setAnswer] = useState(''); + + useEffect(() => { + if (!socket) { + return; + } + socket.on('answer-chain-gpt', (socketId: string, message: string) => { + console.log('answer-chain-gpt: ', socketId, message); + setAnswer(message); + }); + }, [socket]); + + return <> +

Socket io demo.

+ + + +
answer:
+
{answer}
+ +} diff --git a/lib/generator/templates/src/app/demos/web-login/page.tsx b/lib/generator/templates/src/app/demos/web-login/page.tsx index 38649e8..cc1f38e 100644 --- a/lib/generator/templates/src/app/demos/web-login/page.tsx +++ b/lib/generator/templates/src/app/demos/web-login/page.tsx @@ -1,10 +1,10 @@ 'use client' -// import dynamic from 'next/dynamic' -import WalletConnect from './WalletConnect'; +import dynamic from 'next/dynamic' +// import WalletConnect from './WalletConnect'; -// const WalletConnect = dynamic(() => import('./WalletConnect'), { -// ssr: false, -// }) +const WalletConnect = dynamic(() => import('./WalletConnect'), { + ssr: false, +}) export default function Page() { return ; diff --git a/lib/generator/templates/src/app/layout.tsx b/lib/generator/templates/src/app/layout.tsx index d66b346..3e80f9b 100644 --- a/lib/generator/templates/src/app/layout.tsx +++ b/lib/generator/templates/src/app/layout.tsx @@ -5,6 +5,8 @@ import { GoogleAnalytics } from '@next/third-parties/google'; import "./ui/globals.css"; import { inter } from '@/app/ui/fonts'; import {StoreProvider} from './StoreProvider'; +import Header from '@/components/Header'; +// import Footer from '@/components/Footer'; export const metadata: Metadata = { title: "Create Next App", @@ -22,7 +24,9 @@ export default function RootLayout({ +
{children} + {/*