123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- import React, { PropsWithChildren, useRef } from 'react';
- import { Animated, StyleSheet, Text, View } from 'react-native';
- import { RectButton, Swipeable } from 'react-native-gesture-handler';
- import { Colors } from 'src/theme';
- import { getFontSize } from 'src/utils';
- import { SheetManager } from 'react-native-actions-sheet';
- import PinIcon from 'assets/icons/messages/pin.svg';
- import ArchiveIcon from 'assets/icons/messages/archive.svg';
- import DotsIcon from 'assets/icons/messages/dots.svg';
- import UnpinIcon from 'assets/icons/messages/unpin.svg';
- import { ChatProps } from '../types';
- import { usePostSetArchiveMutation, usePostSetPinMutation } from '@api/chat';
- interface AppleStyleSwipeableRowProps extends PropsWithChildren<unknown> {
- chat: ChatProps;
- token: string;
- onRowOpen: (ref: any) => void;
- refetch: () => void;
- }
- const SwipeableRow: React.FC<AppleStyleSwipeableRowProps> = ({
- children,
- chat,
- token,
- onRowOpen,
- refetch
- }) => {
- const swipeableRow = useRef<Swipeable>(null);
- const { mutateAsync: pinChat } = usePostSetPinMutation();
- const { mutateAsync: archiveChat } = usePostSetArchiveMutation();
- const close = () => {
- swipeableRow.current?.close();
- };
- const renderRightAction = (
- text: string,
- color: string,
- x: number,
- progress: Animated.AnimatedInterpolation<number>
- ) => {
- const trans = progress.interpolate({
- inputRange: [0, 1],
- outputRange: [x, 0]
- });
- const pressHandler = async () => {
- close();
- if (text === 'More') {
- SheetManager.show('more-modal', {
- payload: {
- id: chat.id,
- name: chat.name,
- avatar: chat.avatar
- } as any
- });
- } else {
- await archiveChat({
- token,
- value: chat.archive === 1 ? 0 : 1,
- conversation_with_user: chat.id
- });
- refetch();
- }
- };
- return (
- <Animated.View style={{ flex: 1, transform: [{ translateX: trans }] }}>
- <RectButton style={[styles.rightAction, { backgroundColor: color }]} onPress={pressHandler}>
- {text === 'More' ? (
- <DotsIcon height={18} width={18} />
- ) : (
- <ArchiveIcon height={18} width={18} />
- )}
- <Text style={styles.actionText}>{text}</Text>
- </RectButton>
- </Animated.View>
- );
- };
- const renderLeftAction = (
- text: string,
- color: string,
- x: number,
- progress: Animated.AnimatedInterpolation<number>
- ) => {
- const trans = progress.interpolate({
- inputRange: [0, 1],
- outputRange: [-x, 0]
- });
- const pressHandler = async () => {
- close();
- await pinChat({
- token,
- value: chat.pin === 1 ? 0 : 1,
- conversation_with_user: chat.id
- });
- refetch();
- };
- return (
- <Animated.View style={{ flex: 1, transform: [{ translateX: trans }] }}>
- <RectButton style={[styles.rightAction, { backgroundColor: color }]} onPress={pressHandler}>
- {chat.pin === 1 ? <UnpinIcon width={18} /> : <PinIcon width={18} />}
- <Text style={styles.actionText}>{text}</Text>
- </RectButton>
- </Animated.View>
- );
- };
- const renderRightActions = (progress: Animated.AnimatedInterpolation<number>) => (
- <View
- style={{
- width: 168,
- flexDirection: 'row'
- }}
- >
- {renderRightAction(
- chat.archive === 0 ? 'Archive' : 'Unarchive',
- Colors.BORDER_LIGHT,
- 168,
- progress
- )}
- {renderRightAction('More', Colors.FILL_LIGHT, 112, progress)}
- </View>
- );
- const renderLeftActions = (progress: Animated.AnimatedInterpolation<number>) => (
- <View
- style={{
- width: 84,
- flexDirection: 'row'
- }}
- >
- {renderLeftAction(chat.pin === 1 ? 'Unpin' : 'Pin', Colors.FILL_LIGHT, 84, progress)}
- </View>
- );
- return (
- <Swipeable
- ref={swipeableRow}
- friction={2}
- enableTrackpadTwoFingerGesture
- rightThreshold={40}
- renderRightActions={renderRightActions}
- renderLeftActions={renderLeftActions}
- onSwipeableOpenStartDrag={() => {
- onRowOpen(swipeableRow.current);
- }}
- >
- {children}
- </Swipeable>
- );
- };
- const styles = StyleSheet.create({
- actionText: {
- color: Colors.DARK_BLUE,
- fontSize: getFontSize(12),
- fontWeight: '600',
- backgroundColor: 'transparent'
- },
- rightAction: {
- alignItems: 'center',
- flex: 1,
- justifyContent: 'center',
- gap: 12
- }
- });
- export default SwipeableRow;
|