xref: /expo/home/components/BranchListItem.tsx (revision 76cce7af)
1import { BranchIcon, UpdateIcon, iconSize, ChevronDownIcon } from '@expo/styleguide-native';
2import { useNavigation } from '@react-navigation/native';
3import { StackNavigationProp } from '@react-navigation/stack';
4import format from 'date-fns/format';
5import { Row, Spacer, Text, useExpoTheme, View } from 'expo-dev-client-components';
6import { HomeStackRoutes } from 'navigation/Navigation.types';
7import React from 'react';
8import { TouchableOpacity } from 'react-native-gesture-handler';
9
10import { DateFormats } from '../constants/DateFormats';
11import { WebContainerProjectPage_Query } from '../graphql/types';
12
13type Update =
14  WebContainerProjectPage_Query['app']['byId']['updateBranches'][number]['updates'][number];
15
16type Props = {
17  name: string;
18  latestUpdate: Update;
19  appId: string;
20  first: boolean;
21  last: boolean;
22};
23
24/**
25 * This component is used to render a list item for the branches section on the project screen and on
26 * the branches list page for an app.
27 */
28
29export function BranchListItem({
30  name,
31  appId,
32  latestUpdate: { message, createdAt },
33  first,
34  last,
35}: Props) {
36  const theme = useExpoTheme();
37
38  const navigation = useNavigation<StackNavigationProp<HomeStackRoutes>>();
39
40  const handlePressBranch = () => {
41    navigation.navigate('BranchDetails', { appId, branchName: name });
42  };
43
44  return (
45    <View
46      border="default"
47      roundedTop={first ? 'large' : undefined}
48      roundedBottom={last ? 'large' : undefined}
49      style={{
50        borderBottomWidth: last ? 1 : 0,
51        borderTopWidth: first ? 1 : 0,
52      }}>
53      <TouchableOpacity onPress={handlePressBranch}>
54        <View
55          padding="medium"
56          bg="default"
57          roundedTop={first ? 'large' : undefined}
58          roundedBottom={last ? 'large' : undefined}>
59          <Row align="center" justify="between">
60            <View align="start" flex="1">
61              <Row align="center">
62                <BranchIcon color={theme.icon.default} size={iconSize.small} />
63                <Spacer.Horizontal size="tiny" />
64                <Text ellipsizeMode="tail" numberOfLines={1} type="InterMedium">
65                  Branch: {name}
66                </Text>
67              </Row>
68              {message && (
69                <>
70                  <View flex="0" height="2" />
71                  <Row flex="1">
72                    <Spacer.Horizontal size="medium" />
73                    <UpdateIcon color={theme.icon.secondary} size={iconSize.small} />
74                    <Spacer.Horizontal size="tiny" />
75                    <View flex="1">
76                      <Text
77                        type="InterRegular"
78                        color="secondary"
79                        size="small"
80                        ellipsizeMode="middle"
81                        numberOfLines={1}>
82                        "{message}"
83                      </Text>
84                      <Spacer.Vertical size="tiny" />
85                      <Text
86                        type="InterRegular"
87                        color="secondary"
88                        size="small"
89                        ellipsizeMode="tail"
90                        numberOfLines={1}>
91                        Published {format(new Date(createdAt), DateFormats.timestamp)}
92                      </Text>
93                    </View>
94                  </Row>
95                </>
96              )}
97            </View>
98            <Spacer.Horizontal size="tiny" />
99            <ChevronDownIcon
100              style={{ transform: [{ rotate: '-90deg' }] }}
101              color={theme.icon.secondary}
102            />
103          </Row>
104        </View>
105      </TouchableOpacity>
106    </View>
107  );
108}
109