[MM-42565] Toast - Follow/Unfollow thread with undo functionality (#7267)
This commit is contained in:
parent
2658d62c9c
commit
265c4fe8a6
7 changed files with 32 additions and 6 deletions
|
|
@ -12,6 +12,7 @@ import {getPostById} from '@queries/servers/post';
|
|||
import {getConfigValue, getCurrentChannelId, getCurrentTeamId} from '@queries/servers/system';
|
||||
import {getIsCRTEnabled, getThreadById, getTeamThreadsSyncData} from '@queries/servers/thread';
|
||||
import {getCurrentUser} from '@queries/servers/user';
|
||||
import {showThreadFollowingSnackbar} from '@utils/snack_bar';
|
||||
import {getThreadsListEdges} from '@utils/thread';
|
||||
|
||||
import {forceLogoutIfNecessary} from './session';
|
||||
|
|
@ -202,7 +203,7 @@ export const markThreadAsUnread = async (serverUrl: string, teamId: string, thre
|
|||
}
|
||||
};
|
||||
|
||||
export const updateThreadFollowing = async (serverUrl: string, teamId: string, threadId: string, state: boolean) => {
|
||||
export const updateThreadFollowing = async (serverUrl: string, teamId: string, threadId: string, state: boolean, showSnackBar: boolean) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
|
||||
if (!database) {
|
||||
|
|
@ -228,6 +229,11 @@ export const updateThreadFollowing = async (serverUrl: string, teamId: string, t
|
|||
// Update locally
|
||||
await updateThread(serverUrl, threadId, {is_following: state});
|
||||
|
||||
if (showSnackBar) {
|
||||
const onUndo = () => updateThreadFollowing(serverUrl, teamId, threadId, !state, false);
|
||||
showThreadFollowingSnackbar(state, onUndo);
|
||||
}
|
||||
|
||||
return {data};
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const FollowThreadOption = ({bottomSheetId, thread, teamId}: FollowThreadOptionP
|
|||
return;
|
||||
}
|
||||
await dismissBottomSheet(bottomSheetId);
|
||||
updateThreadFollowing(serverUrl, teamId, thread.id, !thread.isFollowing);
|
||||
updateThreadFollowing(serverUrl, teamId, thread.id, !thread.isFollowing, true);
|
||||
}, [bottomSheetId, teamId, thread]);
|
||||
|
||||
const followThreadOptionTestId = thread.isFollowing ? 'post_options.following_thread.option' : 'post_options.follow_thread.option';
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ const Footer = ({channelId, location, participants, teamId, thread}: Props) => {
|
|||
if (teamId == null) {
|
||||
return;
|
||||
}
|
||||
updateThreadFollowing(serverUrl, teamId, thread.id, !thread.isFollowing);
|
||||
updateThreadFollowing(serverUrl, teamId, thread.id, !thread.isFollowing, true);
|
||||
}), [thread.isFollowing]);
|
||||
|
||||
let repliesComponent;
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: TOAST_HEIGHT,
|
||||
paddingLeft: 20,
|
||||
paddingRight: 10,
|
||||
paddingHorizontal: 16,
|
||||
shadowColor: changeOpacity('#000', 0.12),
|
||||
shadowOffset: {width: 0, height: 4},
|
||||
shadowRadius: 6,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ import keyMirror from '@utils/key_mirror';
|
|||
export const SNACK_BAR_TYPE = keyMirror({
|
||||
ADD_CHANNEL_MEMBERS: null,
|
||||
FAVORITE_CHANNEL: null,
|
||||
FOLLOW_THREAD: null,
|
||||
LINK_COPIED: null,
|
||||
MESSAGE_COPIED: null,
|
||||
MUTE_CHANNEL: null,
|
||||
REMOVE_CHANNEL_USER: null,
|
||||
UNFAVORITE_CHANNEL: null,
|
||||
UNMUTE_CHANNEL: null,
|
||||
UNFOLLOW_THREAD: null,
|
||||
});
|
||||
|
||||
type SnackBarConfig = {
|
||||
|
|
@ -35,6 +37,12 @@ export const SNACK_BAR_CONFIG: Record<string, SnackBarConfig> = {
|
|||
iconName: 'star',
|
||||
canUndo: true,
|
||||
},
|
||||
FOLLOW_THREAD: {
|
||||
id: t('snack.bar.following.thread'),
|
||||
defaultMessage: 'Thread followed',
|
||||
iconName: 'check',
|
||||
canUndo: true,
|
||||
},
|
||||
LINK_COPIED: {
|
||||
id: t('snack.bar.link.copied'),
|
||||
defaultMessage: 'Link copied to clipboard',
|
||||
|
|
@ -71,6 +79,12 @@ export const SNACK_BAR_CONFIG: Record<string, SnackBarConfig> = {
|
|||
iconName: 'bell-outline',
|
||||
canUndo: true,
|
||||
},
|
||||
UNFOLLOW_THREAD: {
|
||||
id: t('snack.bar.unfollow.thread'),
|
||||
defaultMessage: 'Thread unfollowed',
|
||||
iconName: 'check',
|
||||
canUndo: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ function ThreadFollow({isFollowing, teamId, threadId}: Props) {
|
|||
const serverUrl = useServerUrl();
|
||||
|
||||
const onPress = preventDoubleTap(() => {
|
||||
updateThreadFollowing(serverUrl, teamId, threadId, !isFollowing);
|
||||
updateThreadFollowing(serverUrl, teamId, threadId, !isFollowing, false);
|
||||
});
|
||||
|
||||
const containerStyle: StyleProp<ViewStyle> = [styles.container];
|
||||
|
|
|
|||
|
|
@ -47,3 +47,10 @@ export const showRemoveChannelUserSnackbar = () => {
|
|||
sourceScreen: Screens.MANAGE_CHANNEL_MEMBERS,
|
||||
});
|
||||
};
|
||||
|
||||
export const showThreadFollowingSnackbar = (following: boolean, onAction: () => void) => {
|
||||
return showSnackBar({
|
||||
onAction,
|
||||
barType: following ? SNACK_BAR_TYPE.FOLLOW_THREAD : SNACK_BAR_TYPE.UNFOLLOW_THREAD,
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue