|
@@ -1,4 +1,4 @@
|
|
|
-import { Text, View } from "@tarojs/components";
|
|
|
|
|
|
|
+import { Text, View, ScrollView } from "@tarojs/components";
|
|
|
import { Heart, HeartFill, Plus } from "@nutui/icons-react-taro";
|
|
import { Heart, HeartFill, Plus } from "@nutui/icons-react-taro";
|
|
|
import { Message } from "@nutui/icons-react-taro";
|
|
import { Message } from "@nutui/icons-react-taro";
|
|
|
import {
|
|
import {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
ImagePreview,
|
|
ImagePreview,
|
|
|
Toast,
|
|
Toast,
|
|
|
} from "@nutui/nutui-react-taro";
|
|
} from "@nutui/nutui-react-taro";
|
|
|
|
|
+import { createPortal } from "react-dom";
|
|
|
import MoreButton from "../fllower-button";
|
|
import MoreButton from "../fllower-button";
|
|
|
import { circlePostListApi } from "../../api/post";
|
|
import { circlePostListApi } from "../../api/post";
|
|
|
import {
|
|
import {
|
|
@@ -23,8 +24,7 @@ import { Dialog } from "@nutui/nutui-react-taro";
|
|
|
import { navigateTo } from "@tarojs/taro";
|
|
import { navigateTo } from "@tarojs/taro";
|
|
|
|
|
|
|
|
interface PostListProps {
|
|
interface PostListProps {
|
|
|
- onLoadMore?: () => void;
|
|
|
|
|
- onRefresh?: () => void;
|
|
|
|
|
|
|
+ style?: any;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export interface PostListRef {
|
|
export interface PostListRef {
|
|
@@ -34,7 +34,7 @@ export interface PostListRef {
|
|
|
loading: boolean;
|
|
loading: boolean;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
|
|
|
|
+const PostList = forwardRef<PostListRef, PostListProps>(({ style }, ref) => {
|
|
|
const [postList, setPostList] = useState<any[]>([]);
|
|
const [postList, setPostList] = useState<any[]>([]);
|
|
|
const [showPreview, setShowPreview] = useState(false);
|
|
const [showPreview, setShowPreview] = useState(false);
|
|
|
const [init, setInit] = useState(0);
|
|
const [init, setInit] = useState(0);
|
|
@@ -43,11 +43,16 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
const [hasMore, setHasMore] = useState(true);
|
|
const [hasMore, setHasMore] = useState(true);
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
+ const [refreshing, setRefreshing] = useState(false);
|
|
|
const pageSize = 10;
|
|
const pageSize = 10;
|
|
|
|
|
|
|
|
const getPostList = useCallback(
|
|
const getPostList = useCallback(
|
|
|
async (page = 1, isRefresh = false) => {
|
|
async (page = 1, isRefresh = false) => {
|
|
|
- setLoading(true);
|
|
|
|
|
|
|
+ if (isRefresh) {
|
|
|
|
|
+ setRefreshing(true);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ }
|
|
|
try {
|
|
try {
|
|
|
const res: any = await circlePostListApi({
|
|
const res: any = await circlePostListApi({
|
|
|
circleId: 1,
|
|
circleId: 1,
|
|
@@ -57,12 +62,6 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
|
|
|
|
|
if (res.code === 200) {
|
|
if (res.code === 200) {
|
|
|
const newList = res.data.list || [];
|
|
const newList = res.data.list || [];
|
|
|
- console.log("API Response:", {
|
|
|
|
|
- page,
|
|
|
|
|
- newListLength: newList.length,
|
|
|
|
|
- hasMore: res.data.has_more,
|
|
|
|
|
- isRefresh,
|
|
|
|
|
- });
|
|
|
|
|
|
|
|
|
|
if (isRefresh || page === 1) {
|
|
if (isRefresh || page === 1) {
|
|
|
setPostList(newList);
|
|
setPostList(newList);
|
|
@@ -75,13 +74,13 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
setCurrentPage(page);
|
|
setCurrentPage(page);
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- console.error("获取帖子列表失败:", error);
|
|
|
|
|
Toast.show("load_error", {
|
|
Toast.show("load_error", {
|
|
|
content: "加载失败,请重试",
|
|
content: "加载失败,请重试",
|
|
|
duration: 2,
|
|
duration: 2,
|
|
|
});
|
|
});
|
|
|
} finally {
|
|
} finally {
|
|
|
setLoading(false);
|
|
setLoading(false);
|
|
|
|
|
+ setRefreshing(false);
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
[pageSize]
|
|
[pageSize]
|
|
@@ -94,12 +93,20 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
|
|
|
|
|
// 上拉加载更多
|
|
// 上拉加载更多
|
|
|
const handleLoadMore = useCallback(async () => {
|
|
const handleLoadMore = useCallback(async () => {
|
|
|
- console.log("handleLoadMore called", { hasMore, currentPage, loading });
|
|
|
|
|
- if (hasMore && !loading) {
|
|
|
|
|
- console.log("Loading next page:", currentPage + 1);
|
|
|
|
|
|
|
+ if (hasMore && !loading && !refreshing) {
|
|
|
await getPostList(currentPage + 1, false);
|
|
await getPostList(currentPage + 1, false);
|
|
|
}
|
|
}
|
|
|
- }, [hasMore, currentPage, getPostList, loading]);
|
|
|
|
|
|
|
+ }, [hasMore, currentPage, getPostList, loading, refreshing]);
|
|
|
|
|
+
|
|
|
|
|
+ // ScrollView 滚动到底部事件
|
|
|
|
|
+ const handleScrollToLower = useCallback(() => {
|
|
|
|
|
+ handleLoadMore();
|
|
|
|
|
+ }, [handleLoadMore]);
|
|
|
|
|
+
|
|
|
|
|
+ // ScrollView 下拉刷新事件
|
|
|
|
|
+ const handleRefresherRefresh = useCallback(async () => {
|
|
|
|
|
+ await handleRefresh();
|
|
|
|
|
+ }, [handleRefresh]);
|
|
|
|
|
|
|
|
const handleMoreClick = (postIndex: number) => {
|
|
const handleMoreClick = (postIndex: number) => {
|
|
|
const data = [...postList];
|
|
const data = [...postList];
|
|
@@ -130,30 +137,18 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
// 关注/不关注
|
|
// 关注/不关注
|
|
|
const handleFollowClick = (followeeId: number, is_followed) => {
|
|
const handleFollowClick = (followeeId: number, is_followed) => {
|
|
|
if (is_followed) {
|
|
if (is_followed) {
|
|
|
- Dialog.open("followed_dialog", {
|
|
|
|
|
- title: "提示",
|
|
|
|
|
- content: "确定取消关注吗?",
|
|
|
|
|
- onConfirm: () => {
|
|
|
|
|
- unfollowApi({ followee_id: followeeId }).then(() => {
|
|
|
|
|
- Toast.show("follow_success", {
|
|
|
|
|
- content: "取消关注成功",
|
|
|
|
|
- duration: 2,
|
|
|
|
|
- lockScroll: true,
|
|
|
|
|
- });
|
|
|
|
|
- const data = [...postList];
|
|
|
|
|
- data.forEach((item: any) => {
|
|
|
|
|
- item.is_followed = false;
|
|
|
|
|
- });
|
|
|
|
|
- setPostList(data);
|
|
|
|
|
- Dialog.close("followed_dialog");
|
|
|
|
|
- });
|
|
|
|
|
- },
|
|
|
|
|
- onCancel: () => {
|
|
|
|
|
- Dialog.close("followed_dialog");
|
|
|
|
|
- },
|
|
|
|
|
- onClose: () => {
|
|
|
|
|
- Dialog.close("followed_dialog");
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ unfollowApi({ followee_id: followeeId }).then(() => {
|
|
|
|
|
+ Toast.show("follow_success", {
|
|
|
|
|
+ content: "取消关注成功",
|
|
|
|
|
+ duration: 2,
|
|
|
|
|
+ lockScroll: true,
|
|
|
|
|
+ });
|
|
|
|
|
+ const data = [...postList];
|
|
|
|
|
+ data.forEach((item: any) => {
|
|
|
|
|
+ item.is_followed = false;
|
|
|
|
|
+ });
|
|
|
|
|
+ setPostList(data);
|
|
|
|
|
+ Dialog.close("followed_dialog");
|
|
|
});
|
|
});
|
|
|
} else {
|
|
} else {
|
|
|
followApi({ followee_id: followeeId }).then(() => {
|
|
followApi({ followee_id: followeeId }).then(() => {
|
|
@@ -166,7 +161,6 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
data.forEach((item: any) => {
|
|
data.forEach((item: any) => {
|
|
|
item.is_followed = true;
|
|
item.is_followed = true;
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
setPostList(data);
|
|
setPostList(data);
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
@@ -181,11 +175,20 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
getPostList(1, true);
|
|
getPostList(1, true);
|
|
|
- }, []);
|
|
|
|
|
|
|
+ }, [getPostList]);
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
- <View className="post-list bg-[#f8f8f8]">
|
|
|
|
|
|
|
+ <ScrollView
|
|
|
|
|
+ className="post-list bg-[#f8f8f8]"
|
|
|
|
|
+ scrollY
|
|
|
|
|
+ refresherEnabled
|
|
|
|
|
+ refresherTriggered={refreshing}
|
|
|
|
|
+ onRefresherRefresh={handleRefresherRefresh}
|
|
|
|
|
+ onScrollToLower={handleScrollToLower}
|
|
|
|
|
+ lowerThreshold={50}
|
|
|
|
|
+ style={style}
|
|
|
|
|
+ >
|
|
|
{postList.map((item: any, index: number) => {
|
|
{postList.map((item: any, index: number) => {
|
|
|
return (
|
|
return (
|
|
|
<View
|
|
<View
|
|
@@ -213,7 +216,7 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
<View className="text-[14px] font-[800] text-[#9c9dee]">
|
|
<View className="text-[14px] font-[800] text-[#9c9dee]">
|
|
|
{item.user.nickname || item.user.username || "微信用户"}
|
|
{item.user.nickname || item.user.username || "微信用户"}
|
|
|
</View>
|
|
</View>
|
|
|
- {item.user.is_official ? (
|
|
|
|
|
|
|
+ {item.user.is_officia ? (
|
|
|
<View className="text-[12px] text-[#949494]">
|
|
<View className="text-[12px] text-[#949494]">
|
|
|
《心动女友》官方账号
|
|
《心动女友》官方账号
|
|
|
</View>
|
|
</View>
|
|
@@ -230,12 +233,10 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
handleFollowClick(item.user_id, item.is_followed);
|
|
handleFollowClick(item.user_id, item.is_followed);
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
|
- {item.is_followed ? <></> : <Plus color="#1874d0" />}
|
|
|
|
|
|
|
+ {!item.is_followed && <Plus color="#1874d0" />}
|
|
|
<Text>{item.is_followed ? "已关注" : "关注"}</Text>
|
|
<Text>{item.is_followed ? "已关注" : "关注"}</Text>
|
|
|
</View>
|
|
</View>
|
|
|
- {item.user.is_official ? (
|
|
|
|
|
- <></>
|
|
|
|
|
- ) : (
|
|
|
|
|
|
|
+ {!item.user.is_official && (
|
|
|
<MoreButton
|
|
<MoreButton
|
|
|
postIndex={index}
|
|
postIndex={index}
|
|
|
followeeId={item.user_id}
|
|
followeeId={item.user_id}
|
|
@@ -252,14 +253,30 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
}
|
|
}
|
|
|
>
|
|
>
|
|
|
<View className="text-[14px] text-[#333] pt-[20px]">
|
|
<View className="text-[14px] text-[#333] pt-[20px]">
|
|
|
- {strSlice(item.content, 100)}
|
|
|
|
|
- {item.content.length > 100 && (
|
|
|
|
|
- <Text className="text-[#1874d0]">全文</Text>
|
|
|
|
|
|
|
+ {item.type === "1" ? (
|
|
|
|
|
+ <>
|
|
|
|
|
+ {strSlice(item.content, 100)}
|
|
|
|
|
+ {item.content.length > 100 && (
|
|
|
|
|
+ <Text className="text-[#1874d0]">全文</Text>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <View
|
|
|
|
|
+ className="text-[14px] text-[#333]"
|
|
|
|
|
+ dangerouslySetInnerHTML={{
|
|
|
|
|
+ __html: strSlice(item.content, 100),
|
|
|
|
|
+ }}
|
|
|
|
|
+ ></View>
|
|
|
|
|
+ {item.content.length > 100 && (
|
|
|
|
|
+ <Text className="text-[#1874d0]">全文</Text>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </>
|
|
|
)}
|
|
)}
|
|
|
</View>
|
|
</View>
|
|
|
<View className="mt-[10px]">
|
|
<View className="mt-[10px]">
|
|
|
<Grid
|
|
<Grid
|
|
|
- columns={item.media_url.length < 3 ? 2 : 3} // 这里,如果图片小于3张,则columns为2,如果图片大于等于3张,则columns为3
|
|
|
|
|
|
|
+ columns={item.media_url.length < 3 ? 2 : 3}
|
|
|
gap={7}
|
|
gap={7}
|
|
|
style={
|
|
style={
|
|
|
{
|
|
{
|
|
@@ -274,17 +291,12 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
<GridItem>
|
|
<GridItem>
|
|
|
<Image
|
|
<Image
|
|
|
src={ite.src}
|
|
src={ite.src}
|
|
|
- mode={
|
|
|
|
|
- item.media_url.length === 1
|
|
|
|
|
- ? "scaleToFill"
|
|
|
|
|
- : "scaleToFill"
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ mode="scaleToFill"
|
|
|
onClick={(e) => {
|
|
onClick={(e) => {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
|
setMediaUrl(item.media_url);
|
|
setMediaUrl(item.media_url);
|
|
|
setInit(index + 1);
|
|
setInit(index + 1);
|
|
|
-
|
|
|
|
|
setShowPreview(true);
|
|
setShowPreview(true);
|
|
|
}}
|
|
}}
|
|
|
/>
|
|
/>
|
|
@@ -306,13 +318,11 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
|
handleInteraction(
|
|
handleInteraction(
|
|
|
item.id,
|
|
item.id,
|
|
|
- item.interaction_type === "praise"
|
|
|
|
|
- ? "dispraise"
|
|
|
|
|
- : "praise"
|
|
|
|
|
|
|
+ item.is_praised ? "dispraise" : "praise"
|
|
|
);
|
|
);
|
|
|
}}
|
|
}}
|
|
|
>
|
|
>
|
|
|
- {item.interaction_type === "praise" ? (
|
|
|
|
|
|
|
+ {item.is_praised ? (
|
|
|
<HeartFill size={16} color="#ec4342" />
|
|
<HeartFill size={16} color="#ec4342" />
|
|
|
) : (
|
|
) : (
|
|
|
<Heart size={16} color="#949494" />
|
|
<Heart size={16} color="#949494" />
|
|
@@ -348,18 +358,21 @@ const PostList = forwardRef<PostListRef, PostListProps>((props, ref) => {
|
|
|
<Text className="text-[14px] text-[#999]">没有更多了</Text>
|
|
<Text className="text-[14px] text-[#999]">没有更多了</Text>
|
|
|
</View>
|
|
</View>
|
|
|
)}
|
|
)}
|
|
|
-
|
|
|
|
|
- <ImagePreview
|
|
|
|
|
- images={mediaUrl}
|
|
|
|
|
- visible={showPreview}
|
|
|
|
|
- defaultValue={init}
|
|
|
|
|
- onClose={() => setShowPreview(false)}
|
|
|
|
|
- indicator
|
|
|
|
|
- />
|
|
|
|
|
- <Toast id="follow_success" />
|
|
|
|
|
- <Toast id="load_error" />
|
|
|
|
|
- <Dialog id="followed_dialog" />
|
|
|
|
|
- </View>
|
|
|
|
|
|
|
+ </ScrollView>
|
|
|
|
|
+ <Toast id="follow_success" />
|
|
|
|
|
+ <Toast id="load_error" />
|
|
|
|
|
+ <Dialog id="followed_dialog" />
|
|
|
|
|
+ {showPreview &&
|
|
|
|
|
+ createPortal(
|
|
|
|
|
+ <ImagePreview
|
|
|
|
|
+ images={mediaUrl}
|
|
|
|
|
+ visible={showPreview}
|
|
|
|
|
+ defaultValue={init}
|
|
|
|
|
+ onClose={() => setShowPreview(false)}
|
|
|
|
|
+ indicator
|
|
|
|
|
+ />,
|
|
|
|
|
+ document.body
|
|
|
|
|
+ )}
|
|
|
</>
|
|
</>
|
|
|
);
|
|
);
|
|
|
});
|
|
});
|