Skip to content

Commit 5919b84

Browse files
authored
Merge pull request #63 from funnyzak/feature/liketopic
2 parents f8fe330 + c439547 commit 5919b84

File tree

16 files changed

+289
-83
lines changed

16 files changed

+289
-83
lines changed

src/actions/CacheAction.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
APP_CACHE_ADD_NODE,
1111
APP_CACHE_MEMBER_FOLLOWING,
1212
APP_CACHE_MEMBER_INTEREST_NODES,
13+
APP_CACHE_MEMBER_LIKE_TOPICS,
1314
APP_CACHE_RESET,
1415
APP_CACHE_RESET_MEMBERS,
1516
APP_CACHE_RESET_NODES,
@@ -50,6 +51,11 @@ export const cacheMemberInterestNodes = (nodes: V2exObject.Node[] | undefined) =
5051
payload: nodes
5152
})
5253

54+
export const cacheMemberLikeTopicss = (topics: V2exObject.Topic[] | undefined) => ({
55+
type: APP_CACHE_MEMBER_LIKE_TOPICS,
56+
payload: topics
57+
})
58+
5359
export const resetCache = (type: 'all' | 'nodes' | 'members') => ({
5460
type: type === 'nodes' ? APP_CACHE_RESET_NODES : type === 'members' ? APP_CACHE_RESET_MEMBERS : APP_CACHE_RESET
5561
})

src/actions/MemberActions.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ import {
1919
MEMBER_SATE_SETTING,
2020
MEMBER_TOPICS,
2121
MEMBER_UNINTEREST_NODE,
22+
MEMBER_FOLLOW_PEOPLE,
23+
MEMBER_UNFOLLOW_PEOPLE,
24+
MEMBER_LIKE_TOPICS,
25+
MEMBER_UNLIKE_TOPICS,
2226
V2exObject
2327
} from '../types'
24-
import { cacheMemberInterestNodes } from './CacheAction'
28+
import { cacheMemberFollowing, cacheMemberInterestNodes, cacheMemberLikeTopicss } from './CacheAction'
2529

2630
export const myProfile = () => async (dispatch: Dispatch, getState: () => RootState) => {
2731
const _member = await v2exLib.member.myProfile()
@@ -35,7 +39,8 @@ export const myProfile = () => async (dispatch: Dispatch, getState: () => RootSt
3539
type: MEMBER_SATE_SETTING,
3640
payload: {
3741
interestNodes: getState().cache.membersInterestNodes[_member.id],
38-
followPeoples: getState().cache.membersFollowing[_member.id]
42+
followPeoples: getState().cache.membersFollowing[_member.id],
43+
likeTopics: getState().cache.membersLikeTopics[_member.id]
3944
}
4045
})
4146
}
@@ -68,6 +73,38 @@ export const unInterestNode = (node: V2exObject.Node) => async (dispatch: Dispat
6873
dispatch(cacheMemberInterestNodes(getState().member.interestNodes))
6974
}
7075

76+
export const likeTopic = (topic: V2exObject.Topic) => async (dispatch: Dispatch, getState: () => RootState) => {
77+
dispatch({
78+
type: MEMBER_LIKE_TOPICS,
79+
payload: topic
80+
})
81+
dispatch(cacheMemberLikeTopicss(getState().member.likeTopics))
82+
}
83+
84+
export const unLikeTopic = (topic: V2exObject.Topic) => async (dispatch: Dispatch, getState: () => RootState) => {
85+
dispatch({
86+
type: MEMBER_UNLIKE_TOPICS,
87+
payload: topic
88+
})
89+
dispatch(cacheMemberLikeTopicss(getState().member.likeTopics))
90+
}
91+
92+
export const followPeople = (member: V2exObject.Member) => async (dispatch: Dispatch, getState: () => RootState) => {
93+
dispatch({
94+
type: MEMBER_FOLLOW_PEOPLE,
95+
payload: member
96+
})
97+
dispatch(cacheMemberFollowing(getState().member.followPeoples))
98+
}
99+
100+
export const unFollowPeople = (member: V2exObject.Member) => async (dispatch: Dispatch, getState: () => RootState) => {
101+
dispatch({
102+
type: MEMBER_UNFOLLOW_PEOPLE,
103+
payload: member
104+
})
105+
dispatch(cacheMemberFollowing(getState().member.followPeoples))
106+
}
107+
71108
export const setCurrentToken = (token?: V2exObject.MToken) => ({
72109
type: APP_AUTH,
73110
payload: token

src/actions/types.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ export const APP_NOTIFICATION_LATEST = 'notification'
1717
export const APP_NOTIFICATION_REMOVE = 'notification_remove'
1818

1919
export const MEMBER_PROFILE = 'profile'
20-
export const MEMBER_FOLLOW_PEOPLE = 'follow_people'
21-
export const MEMBER_LIKE_TOPICS = 'like_topics'
20+
21+
export const MEMBER_FOLLOW_PEOPLE = 'member_follow_people'
22+
export const MEMBER_UNFOLLOW_PEOPLE = 'member_unfollow_people'
23+
24+
export const MEMBER_LIKE_TOPICS = 'member_like_topics'
25+
export const MEMBER_UNLIKE_TOPICS = 'member_unlike_topics'
26+
2227
export const MEMBER_READ_TOPIC = 'read_topic'
2328
export const MEMBER_TOPICS = 'member_topics'
29+
2430
export const MEMBER_INSEREST_NODE = 'member_interest_node'
2531
export const MEMBER_UNINTEREST_NODE = 'member_uninterest_node'
2632
export const MEMBER_SATE_SETTING = 'member_state_setting'
@@ -46,15 +52,19 @@ export const APP_NODE_LOAD_ERROR = 'v2ex_node_error'
4652

4753
export const APP_CACHE_ADD_MEMBER = 'v2ex_cache_add_member'
4854
export const APP_CACHE_ADD_NODE = 'v2ex_cache_add_node'
55+
4956
export const APP_CACHE_MEMBER_INTEREST_NODES = 'v2ex_cache_member_interest_nodes'
5057
export const APP_CACHE_MEMBER_FOLLOWING = 'v2ex_cache_member_following'
58+
export const APP_CACHE_MEMBER_LIKE_TOPICS = 'v2ex_cache_member_like_topics'
59+
5160
export const APP_CACHE_RESET_MEMBERS = 'v2ex_cache_reset_member'
5261
export const APP_CACHE_RESET_NODES = 'v2ex_cache_reset_node'
5362
export const APP_CACHE_RESET = 'v2ex_cache_reset'
5463

5564
export const ActionTypes = {
5665
MEMBER_INSEREST_NODE,
5766
APP_CACHE_MEMBER_INTEREST_NODES,
67+
APP_CACHE_MEMBER_LIKE_TOPICS,
5868
MEMBER_UNINTEREST_NODE,
5969
APP_CACHE_MEMBER_FOLLOWING,
6070
MEMBER_TOPICS,
@@ -84,7 +94,9 @@ export const ActionTypes = {
8494
APP_AUTH_LOADING,
8595
APP_AUTH_RESET,
8696
MEMBER_FOLLOW_PEOPLE,
97+
MEMBER_UNFOLLOW_PEOPLE,
8798
MEMBER_LIKE_TOPICS,
99+
MEMBER_UNLIKE_TOPICS,
88100
APP_AUTH,
89101
FEEDBACKING,
90102
TOPIC_GET,

src/components/common/Placeholder.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react'
22
import { View, ViewStyle, TextStyle, ImageSourcePropType, Image, StyleProp } from 'react-native'
33
import { useTheme, ITheme } from '@src/theme'
44
import { Text, Button } from '.'
5+
import { translate } from '@src/i18n'
56

67
const Placeholder = ({
78
containerStyle,
@@ -14,7 +15,7 @@ const Placeholder = ({
1415
containerStyle?: StyleProp<ViewStyle>
1516
displayType?: 'icon' | 'text' | 'none'
1617
icon?: ImageSourcePropType
17-
placeholderText: string
18+
placeholderText?: string
1819
buttonText?: string
1920
buttonPress?: () => void
2021
}) => {
@@ -36,7 +37,7 @@ const Placeholder = ({
3637
return (
3738
<View style={[styles.containerStyle(theme), containerStyle]}>
3839
{renderIcon()}
39-
<Text style={styles.textStyle(theme)}>{placeholderText}</Text>
40+
<Text style={styles.textStyle(theme)}>{placeholderText ?? translate('placeholder.empty')}</Text>
4041

4142
{buttonText && (
4243
<Button style={styles.buttonContainer(theme)} disabled={false} type="small" onPress={buttonPress}>

src/i18n/locales/zh.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
"token": "输入API令牌..",
151151
"search": "搜索关键字...",
152152
"message": "写点啥...",
153-
"empty": "无内容",
153+
"empty": "无内容.",
154154
"noResult": "无内容",
155155
"noFound": "未找到内容 ",
156156
"noTopics": "还没有任何主题.",

src/reducers/CacheReducer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
APP_CACHE_ADD_NODE,
55
APP_CACHE_MEMBER_FOLLOWING,
66
APP_CACHE_MEMBER_INTEREST_NODES,
7+
APP_CACHE_MEMBER_LIKE_TOPICS,
78
APP_CACHE_RESET,
89
APP_CACHE_RESET_MEMBERS,
910
APP_CACHE_RESET_NODES,
@@ -16,7 +17,8 @@ const INITIAL_STATE: IState.CacheState = {
1617
members: [],
1718
nodes: [],
1819
membersFollowing: { 0: undefined },
19-
membersInterestNodes: { 0: undefined }
20+
membersInterestNodes: { 0: undefined },
21+
membersLikeTopics: { 0: undefined }
2022
}
2123

2224
export default (state: IState.CacheState = INITIAL_STATE, action: Action): IState.CacheState => {
@@ -38,6 +40,9 @@ export default (state: IState.CacheState = INITIAL_STATE, action: Action): IStat
3840
case APP_CACHE_MEMBER_INTEREST_NODES:
3941
state.membersInterestNodes[state.currentSessionMember?.id ?? 0] = action.payload
4042
return { ...state }
43+
case APP_CACHE_MEMBER_LIKE_TOPICS:
44+
state.membersLikeTopics[state.currentSessionMember?.id ?? 0] = action.payload
45+
return { ...state }
4146
case APP_CACHE_MEMBER_FOLLOWING:
4247
state.membersFollowing[state.currentSessionMember?.id ?? 0] = action.payload
4348
return { ...state }

src/reducers/MemberReducer.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ import {
99
MEMBER_TOPICS,
1010
MEMBER_INSEREST_NODE,
1111
MEMBER_UNINTEREST_NODE,
12+
MEMBER_FOLLOW_PEOPLE,
13+
MEMBER_UNFOLLOW_PEOPLE,
14+
MEMBER_LIKE_TOPICS,
15+
MEMBER_UNLIKE_TOPICS,
1216
MEMBER_SATE_SETTING
1317
} from '../types'
1418
const INITIAL_STATE: IState.MemberState = {
1519
refreshing: false,
16-
interestNodes: []
20+
interestNodes: [],
21+
followPeoples: [],
22+
likeTopics: []
1723
}
1824

1925
export default (state: IState.MemberState = INITIAL_STATE, action: Action): IState.MemberState => {
@@ -32,6 +38,32 @@ export default (state: IState.MemberState = INITIAL_STATE, action: Action): ISta
3238
...state,
3339
interestNodes: state.interestNodes.filter((v) => v.id !== action.payload.id)
3440
}
41+
case MEMBER_FOLLOW_PEOPLE:
42+
return {
43+
...state,
44+
followPeoples: state.followPeoples.concat(
45+
state.followPeoples && state.followPeoples.findIndex((v) => v.id === action.payload.id) >= 0
46+
? []
47+
: action.payload
48+
)
49+
}
50+
case MEMBER_UNFOLLOW_PEOPLE:
51+
return {
52+
...state,
53+
followPeoples: state.followPeoples.filter((v) => v.id !== action.payload.id)
54+
}
55+
case MEMBER_LIKE_TOPICS:
56+
return {
57+
...state,
58+
likeTopics: state.likeTopics.concat(
59+
state.likeTopics && state.likeTopics.findIndex((v) => v.id === action.payload.id) >= 0 ? [] : action.payload
60+
)
61+
}
62+
case MEMBER_UNLIKE_TOPICS:
63+
return {
64+
...state,
65+
likeTopics: state.likeTopics.filter((v) => v.id !== action.payload.id)
66+
}
3567
case MEMBER_SATE_SETTING:
3668
return { ...state, ...action.payload }
3769
case MEMBER_TOPICS:
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Created by leon<[email protected]> on 22/05/27.
3+
*/
4+
import { followPeople, interestNode, unFollowPeople, unInterestNode } from '@src/actions'
5+
import { useAppDispatch, useAppSelector } from '@src/hooks'
6+
import { useSession } from '@src/hooks/useSession'
7+
import { translate } from '@src/i18n'
8+
import { NavigationService, ROUTES } from '@src/navigation'
9+
import { useTheme } from '@src/theme'
10+
import { V2exObject } from '@src/types'
11+
import React, { useMemo } from 'react'
12+
import { StyleProp, ViewStyle } from 'react-native'
13+
import { HeaderButton } from '../../common'
14+
15+
/**
16+
* Follow People Button
17+
* @param {
18+
* text,
19+
* buttonText,
20+
* buttonPress
21+
* }
22+
* @returns
23+
*/
24+
const FollowPeopleHeaderButton = ({
25+
containerStyle,
26+
member
27+
}: {
28+
containerStyle?: StyleProp<ViewStyle>
29+
member: V2exObject.Member
30+
}) => {
31+
const { theme } = useTheme()
32+
const { logined } = useSession()
33+
const { followPeoples } = useAppSelector((RootState) => RootState.member)
34+
const dispatch = useAppDispatch()
35+
const isInterest = useMemo(
36+
() => (logined ? followPeoples && followPeoples.findIndex((v) => v.id === member.id) >= 0 : false),
37+
[followPeoples]
38+
)
39+
40+
const buttonPress = () => {
41+
if (!logined) {
42+
NavigationService.navigate(ROUTES.SignIn)
43+
} else {
44+
if (isInterest) {
45+
dispatch(unFollowPeople(member) as any)
46+
} else {
47+
dispatch(followPeople(member) as any)
48+
}
49+
}
50+
}
51+
52+
return (
53+
<HeaderButton
54+
text={translate(`common.${isInterest ? 'cancel' : 'follow'}`)}
55+
textColor={isInterest ? theme.colors.captionText : theme.colors.secondary}
56+
onPress={buttonPress}
57+
containerStyle={containerStyle}
58+
/>
59+
)
60+
}
61+
62+
export default FollowPeopleHeaderButton
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Created by leon<[email protected]> on 22/05/27.
3+
*/
4+
import { likeTopic, unLikeTopic } from '@src/actions'
5+
import { useAppDispatch, useAppSelector } from '@src/hooks'
6+
import { useSession } from '@src/hooks/useSession'
7+
import { translate } from '@src/i18n'
8+
import { NavigationService, ROUTES } from '@src/navigation'
9+
import { useTheme } from '@src/theme'
10+
import { V2exObject } from '@src/types'
11+
import React, { useMemo } from 'react'
12+
import { StyleProp, ViewStyle } from 'react-native'
13+
import { HeaderButton } from '../../common'
14+
15+
/**
16+
* Like Topic Button
17+
* @param {
18+
* text,
19+
* buttonText,
20+
* buttonPress
21+
* }
22+
* @returns
23+
*/
24+
const LikeTopicHeaderButton = ({
25+
containerStyle,
26+
topic
27+
}: {
28+
containerStyle?: StyleProp<ViewStyle>
29+
topic: V2exObject.Topic
30+
}) => {
31+
const { theme } = useTheme()
32+
const { logined } = useSession()
33+
const { likeTopics } = useAppSelector((RootState) => RootState.member)
34+
35+
const dispatch = useAppDispatch()
36+
const isLike = useMemo(
37+
() => (logined ? likeTopics && likeTopics.findIndex((v) => v.id === topic.id) >= 0 : false),
38+
[likeTopics]
39+
)
40+
41+
const buttonPress = () => {
42+
if (!logined) {
43+
NavigationService.navigate(ROUTES.SignIn)
44+
} else {
45+
if (isLike) {
46+
dispatch(unLikeTopic(topic) as any)
47+
} else {
48+
dispatch(likeTopic(topic) as any)
49+
}
50+
}
51+
}
52+
53+
return (
54+
<HeaderButton
55+
text={translate(`common.${isLike ? 'cancel' : 'favorite'}`)}
56+
textColor={isLike ? theme.colors.captionText : theme.colors.secondary}
57+
onPress={buttonPress}
58+
containerStyle={containerStyle}
59+
/>
60+
)
61+
}
62+
63+
export default LikeTopicHeaderButton
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export { default as LikeNodeHeaderButton } from './LikeNode'
2+
export { default as LikeTopicHeaderButton } from './LikeTopic'
3+
export { default as FollowPeopleHeaderButton } from './FollowPeople'

0 commit comments

Comments
 (0)