feat(Comment): enhance like functionality for comments and replies
- Updated CommentItem component to accept the comment object in the onLike callback, allowing for more detailed like handling. - Added a like button for replies, improving user interaction with nested comments. - Refactored handleLikeComment function in PostDetailScreen for optimized state management and error handling during like operations. - Enhanced SettingsScreen to provide debug information for theme preferences, improving user experience in theme selection. - Updated themeStore to dynamically manage system theme changes and improve overall theme handling.
This commit is contained in:
@@ -895,61 +895,48 @@ export const PostDetailScreen: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 点赞评论(包括回复)
|
||||
// 点赞评论(包括回复)- 优化版
|
||||
const handleLikeComment = async (comment: Comment) => {
|
||||
// 先保存旧状态用于回滚
|
||||
const oldIsLiked = comment.is_liked;
|
||||
const oldLikesCount = comment.likes_count;
|
||||
const { id, is_liked, likes_count } = comment;
|
||||
|
||||
// 乐观更新本地状态 - 辅助函数用于更新评论或回复
|
||||
const updateCommentLike = (c: Comment): Comment => {
|
||||
// 如果是目标评论/回复
|
||||
if (c.id === comment.id) {
|
||||
return {
|
||||
...c,
|
||||
is_liked: !c.is_liked,
|
||||
likes_count: c.is_liked ? c.likes_count - 1 : c.likes_count + 1
|
||||
};
|
||||
// 乐观更新:切换点赞状态
|
||||
const newIsLiked = !is_liked;
|
||||
const newLikesCount = newIsLiked ? likes_count + 1 : Math.max(0, likes_count - 1);
|
||||
|
||||
// 递归更新评论树中的点赞状态
|
||||
const updateLikeInTree = (c: Comment): Comment => {
|
||||
if (c.id === id) {
|
||||
return { ...c, is_liked: newIsLiked, likes_count: newLikesCount };
|
||||
}
|
||||
// 如果有回复,递归查找
|
||||
if (c.replies && c.replies.length > 0) {
|
||||
return {
|
||||
...c,
|
||||
replies: c.replies.map(r => updateCommentLike(r))
|
||||
};
|
||||
if (c.replies?.length) {
|
||||
return { ...c, replies: c.replies.map(r => updateLikeInTree(r)) };
|
||||
}
|
||||
return c;
|
||||
};
|
||||
|
||||
// 更新本地状态
|
||||
setComments(prev => prev.map(c => updateCommentLike(c)));
|
||||
setComments(prev => prev.map(c => updateLikeInTree(c)));
|
||||
|
||||
try {
|
||||
if (oldIsLiked) {
|
||||
await commentService.unlikeComment(comment.id);
|
||||
} else {
|
||||
await commentService.likeComment(comment.id);
|
||||
const success = newIsLiked
|
||||
? await commentService.likeComment(id)
|
||||
: await commentService.unlikeComment(id);
|
||||
|
||||
if (!success) {
|
||||
throw new Error('点赞操作失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('评论点赞操作失败:', error);
|
||||
// 失败时回滚状态
|
||||
const rollbackCommentLike = (c: Comment): Comment => {
|
||||
if (c.id === comment.id) {
|
||||
return {
|
||||
...c,
|
||||
is_liked: oldIsLiked,
|
||||
likes_count: oldLikesCount
|
||||
};
|
||||
// 回滚状态
|
||||
const rollbackLikeInTree = (c: Comment): Comment => {
|
||||
if (c.id === id) {
|
||||
return { ...c, is_liked, likes_count };
|
||||
}
|
||||
if (c.replies && c.replies.length > 0) {
|
||||
return {
|
||||
...c,
|
||||
replies: c.replies.map(r => rollbackCommentLike(r))
|
||||
};
|
||||
if (c.replies?.length) {
|
||||
return { ...c, replies: c.replies.map(r => rollbackLikeInTree(r)) };
|
||||
}
|
||||
return c;
|
||||
};
|
||||
setComments(prev => prev.map(c => rollbackCommentLike(c)));
|
||||
setComments(prev => prev.map(c => rollbackLikeInTree(c)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1373,7 +1360,7 @@ export const PostDetailScreen: React.FC = () => {
|
||||
return (
|
||||
<CommentItem
|
||||
comment={item}
|
||||
onLike={() => handleLikeComment(item)}
|
||||
onLike={handleLikeComment}
|
||||
onReply={() => handleReply(item)}
|
||||
onUserPress={() => authorId && handleUserPress(authorId)}
|
||||
floorNumber={index + 1}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
borderRadius,
|
||||
useThemePreference,
|
||||
useSetThemePreference,
|
||||
useThemeStore,
|
||||
type AppColors,
|
||||
} from '../../theme';
|
||||
import { useAuthStore } from '../../stores';
|
||||
@@ -204,29 +205,41 @@ export const SettingsScreen: React.FC = () => {
|
||||
|
||||
const handleItemPress = (key: string) => {
|
||||
switch (key) {
|
||||
case 'theme':
|
||||
Alert.alert('主题模式', '选择应用界面明暗', [
|
||||
{ text: '取消', style: 'cancel' },
|
||||
{
|
||||
text: '跟随系统',
|
||||
onPress: () => {
|
||||
void setThemePreference('system');
|
||||
case 'theme': {
|
||||
// 获取调试信息
|
||||
const { Appearance } = require('react-native');
|
||||
const systemScheme = Appearance?.getColorScheme?.() || 'undefined';
|
||||
const resolvedScheme = useThemeStore.getState().resolvedScheme;
|
||||
const storedPref = useThemeStore.getState().preference;
|
||||
const storedSystem = useThemeStore.getState().systemScheme;
|
||||
|
||||
Alert.alert(
|
||||
'主题模式',
|
||||
`选择应用界面明暗\n\n[调试信息]\n系统主题: ${systemScheme}\n存储偏好: ${storedPref}\n存储系统: ${storedSystem}\n实际应用: ${resolvedScheme}`,
|
||||
[
|
||||
{ text: '取消', style: 'cancel' },
|
||||
{
|
||||
text: '跟随系统',
|
||||
onPress: () => {
|
||||
void setThemePreference('system');
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '浅色',
|
||||
onPress: () => {
|
||||
void setThemePreference('light');
|
||||
{
|
||||
text: '浅色',
|
||||
onPress: () => {
|
||||
void setThemePreference('light');
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '深色',
|
||||
onPress: () => {
|
||||
void setThemePreference('dark');
|
||||
{
|
||||
text: '深色',
|
||||
onPress: () => {
|
||||
void setThemePreference('dark');
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
]
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'edit_profile':
|
||||
router.push(hrefs.hrefProfileEdit());
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user