From af93a92e934ffb6d990c2e13220b8f5512935118 Mon Sep 17 00:00:00 2001 From: 1708-huayu <57060237+1708-huayu@users.noreply.github.com> Date: Sun, 26 Jan 2025 16:10:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BF=AE=E6=94=B9todoTree=E6=90=9C?= =?UTF-8?q?=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useChildList.js | 43 ++++++++++++- src/pages/Home/index.js | 13 ++-- src/pages/ToDoTest/index.js | 119 ++++++++++++++++++++++++++++++++++++ src/pages/ToDoTree/index.js | 25 ++++++-- 4 files changed, 187 insertions(+), 13 deletions(-) create mode 100644 src/pages/ToDoTest/index.js diff --git a/src/hooks/useChildList.js b/src/hooks/useChildList.js index bea99c2..f23c60f 100644 --- a/src/hooks/useChildList.js +++ b/src/hooks/useChildList.js @@ -15,6 +15,11 @@ export function useChildList() { }); // Map key为pid和他的子项 const [childList, setChildList] = useState({}); + const [searchValue, setSearchValue] = useState(""); + // 当前选中的值,使用值过滤其子孙。 + const [selectValue, setSelectValue] = useState([]); + const [currentLab, setCurrentLab] = useState(0); + useEffect(() => { fetchOptionsForValue('0', 0) @@ -30,6 +35,27 @@ export function useChildList() { if (options === undefined) { return Cascader.optionSkeleton } + // 如果有搜索有值,需要过滤, + // 根据currentLab查看需要过滤第几层,当前层可能没有值就会停留在上一层 + if (searchValue && searchValue.length > 0) { + if (selectValue.length <= currentLab + 1) { + // 可能展示最新的,或没有停留在当前页面,正常是没有选择的时候搜索 + console.log({searchValue}, {currentLab}, {selectValue}) + if (currentLab === 0 && v === '0') { + return options.filter(option => option.label.includes(searchValue)).map(option => ({ + ...option, + children: generate(option.value), + })) + } else if (v === selectValue[currentLab - 1]) { + return options.filter(option => option.label.includes(searchValue)).map(option => ({ + ...option, + children: generate(option.value), + })) + } + } else { + // 用户切换回之前的标签,暂不处理 + } + } return options.map(option => ({ ...option, children: generate(option.value), @@ -37,7 +63,7 @@ export function useChildList() { } return generate('0') ?? [] - }, [childList]) + }, [childList,searchValue]) async function fetchOptionsForValue(v, level) { if (v in childList) return @@ -58,6 +84,18 @@ export function useChildList() { } + function changeSearchValue(value) { + setSearchValue(value) + } + + function changeCurrentLab(value) { + setCurrentLab(value) + } + + function changeSelectValue(value){ + setSelectValue(value) + } + function changeTaskId(taskId) { if (!(taskId && taskId.length > 0)) { return; @@ -79,6 +117,9 @@ export function useChildList() { return { changeTaskId, removeTaskId, + changeCurrentLab, + changeSearchValue, + changeSelectValue, options, task }; diff --git a/src/pages/Home/index.js b/src/pages/Home/index.js index 9eccde5..beb2a56 100644 --- a/src/pages/Home/index.js +++ b/src/pages/Home/index.js @@ -12,18 +12,19 @@ const Home = () => {
{ - location.pathname.endsWith("/calTask") ? ( + location.pathname.endsWith("/listTask") ? ( -
- -
-
- ) : (
+ ) : ( + +
+ +
+
) } diff --git a/src/pages/ToDoTest/index.js b/src/pages/ToDoTest/index.js new file mode 100644 index 0000000..fd72778 --- /dev/null +++ b/src/pages/ToDoTest/index.js @@ -0,0 +1,119 @@ +import React, { useState, useEffect, useRef } from 'react'; +import InfiniteScroll from 'react-infinite-scroll-component'; +import './index.css'; // 用于存放样式 + +const ToDoTest = () => { + const [messages, setMessages] = useState([]); // 聊天消息列表 + const [hasMore, setHasMore] = useState(true); // 是否还有更多消息 + const [messageText, setMessageText] = useState(''); // 当前输入的消息文本 + const messagesEndRef = useRef(null); // 用于自动滚动到底部 + + // 模拟获取初始聊天记录 + useEffect(() => { + fetchInitialMessages(); + }, []); + + const fetchInitialMessages = async () => { + const initialMessages = await new Promise(resolve => + setTimeout(() => resolve([ + { id: 1, text: "Hello", sender: "other" }, + { id: 2, text: "Hi there!", sender: "user" }, + { id: 3, text: "1Hi there!", sender: "user" }, + { id: 4, text: "2Hi there!", sender: "user" }, + { id: 5, text: "3Hi there!", sender: "user" }, + { id: 6, text: "4Hi there!", sender: "user" }, + { id: 7, text: "5Hi there!", sender: "user" }, + { id: 8, text: "6Hi there!", sender: "user" }, + { id: 9, text: "7Hi there!", sender: "user" }, + { id: 10, text: "8Hi there!", sender: "user" }, + { id: 11, text: "11Hello", sender: "other" }, + { id: 12, text: "12Hi there!", sender: "user" }, + { id: 13, text: "13Hi there!", sender: "user" }, + { id: 14, text: "14Hi there!", sender: "user" }, + { id: 15, text: "15Hi there!", sender: "user" }, + { id: 16, text: "16Hi there!", sender: "user" }, + { id: 17, text: "17Hi there!", sender: "user" }, + { id: 18, text: "18Hi there!", sender: "user" }, + { id: 19, text: "19Hi there!", sender: "user" }, + { id: 20, text: "20Hi there!", sender: "user" }, + { id: 31, text: "31Hello", sender: "other" }, + { id: 32, text: "32Hi there!", sender: "user" }, + { id: 33, text: "33Hi there!", sender: "user" }, + { id: 34, text: "34Hi there!", sender: "user" }, + { id: 35, text: "35Hi there!", sender: "user" }, + { id: 36, text: "36Hi there!", sender: "user" }, + { id: 37, text: "37Hi there!", sender: "user" }, + { id: 38, text: "38Hi there!", sender: "user" }, + { id: 39, text: "39Hi there!", sender: "user" }, + { id: 40, text: "40Hi there!", sender: "user" }, + ]), 1000)); + setMessages(initialMessages); + // scrollToBottom(); // 自动滚动到最新消息 + }; + + // 加载更多历史消息 + const fetchMoreData = async () => { + console.log("fetchMoreMessages") + if (!hasMore) return; + + const moreMessages = await new Promise(resolve => setTimeout(() => { + console.log("moreMessages",messages.length < 50) + if (messages.length < 500) { // 假设有50条消息作为限制 + const generatedMessages = []; + for (let i = messages[0]?.id - 1; i > messages[0]?.id - 10; i--) { + generatedMessages.push({ id: i, text: `Old Message ${i}`, sender: "other" }); + } + resolve(generatedMessages); + } else { + setHasMore(false); // 如果已经加载完所有消息,则设置 hasMore 为 false + resolve([]); + } + }, 1000)); + + setMessages([...moreMessages, ...messages]); // 新的历史消息添加到顶部 + }; + + const handleSendMessage = () => { + if (messageText.trim()) { + const updatedMessages = [...messages, { id: Date.now(), text: messageText, sender: "user" }]; + setMessages(updatedMessages); + setMessageText(''); + scrollToBottom(); + } + }; + + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + } + + return ( +
+ {/*Put the scroll bar always on the bottom*/} + Loading...} + scrollableTarget="scrollableDiv" + > + {messages.map((_, index) => ( +
+ div - #{index} +
+ ))} +
+
+ ); +}; + +export default ToDoTest; \ No newline at end of file diff --git a/src/pages/ToDoTree/index.js b/src/pages/ToDoTree/index.js index b6cec44..d384af1 100644 --- a/src/pages/ToDoTree/index.js +++ b/src/pages/ToDoTree/index.js @@ -1,13 +1,21 @@ -import {Fragment} from "react"; -import {Card, CascaderView, Dialog, Toast} from "antd-mobile"; +import React, {Fragment, useState} from "react"; +import {Card, CascaderView, Dialog, SearchBar, Toast} from "antd-mobile"; import {useChildList} from "../../hooks/useChildList"; import {useNavigate} from "react-router-dom"; -export default () => { - const {task, options, changeTaskId,} = useChildList(); +const ToDoTree = () => { + const {task, options, changeTaskId,changeSearchValue,changeCurrentLab,changeSelectValue} = useChildList(); const navigate = useNavigate(); + + return + { + changeSearchValue(value); + } + }/> { if (task&&task.id) { @@ -28,8 +36,13 @@ export default () => { // fetchOptionsForValue(value[value.length-1]) console.log({value}) changeTaskId(value) + changeSelectValue(value) + }} + onTabsChange={index => { + console.log("tabs", index) + changeCurrentLab(index) }} - /> -} \ No newline at end of file +} +export default ToDoTree \ No newline at end of file