Skip to content

Commit

Permalink
feat: add corrections (#218)
Browse files Browse the repository at this point in the history
* refactor: fix lint, downgrade react native svg

* refactor: apply automatic truncation
  • Loading branch information
pyphilia authored Jun 5, 2024
1 parent ae5a323 commit ea2d09c
Show file tree
Hide file tree
Showing 27 changed files with 210 additions and 157 deletions.
1 change: 1 addition & 0 deletions e2e/constants/testIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const ITEM_LIST_OPTIONS_OPEN_CHAT = 'item-list-options-open-chat';
export const ITEM_LIST_OPTIONS_OPEN_MAP = 'item-list-options-open-map';
export const ITEM_LIST_OPTIONS_DELETE = 'item-list-options-delete';
export const ITEM_LIST_OPTIONS_SHARE = 'item-list-options-share';
export const ITEM_LIST_OPTIONS_SHOW_QR_CODE = 'item-list-options-show-qr-code';
export const CONFIRM_EDIT_ITEM = 'confirm-edit-item';
export const CANCEL_EDIT_ITEM = 'cancel-edit-item';
export const EDIT_ITEM_NAME_INPUT = 'edit-item-name-input';
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,12 @@
"react-native-root-siblings": "^4.1.1",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"react-native-svg": "^14.1.0",
"react-native-svg": "14.1.0",
"react-native-toast-message": "^2.1.7",
"react-native-url-polyfill": "^2.0.0",
"react-native-web": "~0.19.9",
"react-native-webview": "13.6.4",
"react-qr-code": "^2.0.13",
"uuid": "^9.0.1"
},
"devDependencies": {
Expand Down
5 changes: 5 additions & 0 deletions src/components/FileImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ const FileImage: FC<FileImageProps> = ({
useEffect(() => {
if (!isPlayerView) {
navigation.setOptions({
headerTitleAlign: 'left',
// move to headerBackTitle: ' ' when we have only 2 buttons
// corresponds to the max space available for title on the left and 3 buttons on the right
headerTitleContainerStyle: { maxWidth: '50%' },
headerBackTitleVisible: false,
headerRight: () => (
<View style={styles.headerButtons}>
<ChatButton item={item} />
Expand Down
5 changes: 5 additions & 0 deletions src/components/FileVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ const FileVideo: FC<FileVideoProps> = ({
useEffect(() => {
if (!isPlayerView) {
navigation.setOptions({
headerTitleAlign: 'left',
// corresponds to the max space available for title on the left and 3 buttons on the right
// to remove when right content has at most 2 buttons
headerTitleContainerStyle: { maxWidth: '50%' },
headerBackTitleVisible: false,
headerRight: () => (
<View style={styles.headerButtons}>
<ChatButton item={item} />
Expand Down
2 changes: 1 addition & 1 deletion src/components/FolderItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const styles = StyleSheet.create({
backgroundColor: '#fff',
},
headerButtons: {
paddingRight: 20,
paddingRight: 10,
flexDirection: 'row',
alignItems: 'center',
},
Expand Down
77 changes: 42 additions & 35 deletions src/components/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { FC } from 'react';
import { Pressable, View } from 'react-native';
import { ListItem } from 'react-native-elements';

Expand All @@ -23,7 +22,12 @@ interface ItemProps {
refresh: ItemOptionsButtonProps['refresh'];
}

const Item: FC<ItemProps> = ({ item, showOptions = false, index, refresh }) => {
const Item = ({
item,
showOptions = false,
index,
refresh,
}: ItemProps): JSX.Element => {
const { id, name, type, extra } = item;
const { navigate } =
useNavigation<ItemScreenProps<'ItemStackItem'>['navigation']>();
Expand All @@ -34,41 +38,44 @@ const Item: FC<ItemProps> = ({ item, showOptions = false, index, refresh }) => {
});
}

function renderListItem() {
return (
<ListItem testID={`${ITEM_LIST}-${index + 1}`}>
<ItemIcon type={type} extra={extra} />
<ListItem.Content style={{ flexDirection: 'row' }}>
<ListItem.Title style={{ flex: 2 }}>{name}</ListItem.Title>
</ListItem.Content>
</ListItem>
);
}

return (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Pressable onPress={() => handleItemPress()} style={{ flex: 2 }}>
{renderListItem()}
</Pressable>
{showOptions && (
<>
{type === ItemType.FOLDER && (
<PlayerButton
name={name}
type={type}
itemId={id}
origin={{ rootId: id, context: Context.Builder }}
/>
<ListItem testID={`${ITEM_LIST}-${index + 1}`}>
<ListItem.Content style={{ width: '100%' }}>
<View
style={{
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Pressable
onPress={() => handleItemPress()}
style={{ flex: 2, flexDirection: 'row', gap: 10 }}
>
<ItemIcon type={type} extra={extra} />
<ListItem.Title style={{ flex: 2 }}>{name}</ListItem.Title>
</Pressable>
{showOptions && (
<>
{type === ItemType.FOLDER && (
<PlayerButton
name={name}
type={type}
itemId={id}
origin={{ rootId: id, context: Context.Builder }}
/>
)}
<ItemOptionsButton
refresh={refresh}
item={item}
color={ITEMS_TABLE_ROW_ICON_COLOR}
testId={`${ITEM_LIST_OPTIONS}-${index + 1}`}
/>
</>
)}
<ItemOptionsButton
refresh={refresh}
item={item}
color={ITEMS_TABLE_ROW_ICON_COLOR}
testId={`${ITEM_LIST_OPTIONS}-${index + 1}`}
/>
</>
)}
</View>
</View>
</ListItem.Content>
</ListItem>
);
};

Expand Down
67 changes: 32 additions & 35 deletions src/components/ItemListOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { FC, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Share, StyleSheet } from 'react-native';
import { Button, Divider, ListItem, Overlay } from 'react-native-elements';
import { Divider, ListItem, Overlay, Text } from 'react-native-elements';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import QRCode from 'react-qr-code';

import { MaterialIcons } from '@expo/vector-icons';

Expand All @@ -18,12 +19,10 @@ import {
ITEM_LIST_OPTIONS_MAP,
ITEM_LIST_OPTIONS_OPEN_CHAT,
ITEM_LIST_OPTIONS_SHARE,
SHARE_ITEM_BUILDER,
SHARE_ITEM_PLAYER,
ITEM_LIST_OPTIONS_SHOW_QR_CODE,
} from '../../e2e/constants/testIds';
import {
ANALYTICS_EVENTS,
PRIMARY_COLOR,
SHARE_HOST,
SHARE_OPTIONS,
VIEWS,
Expand Down Expand Up @@ -76,7 +75,8 @@ const ItemListOptions: FC<ItemListOptionsProps> = ({
isLoading: isLoadingCurrentMember,
isError: isErrorCurrentMember,
} = hooks.useCurrentMember();
const [shareModalVisible, setShareModalVisible] = useState<boolean>(false);
const [showQrCodeModalVisible, setShowQrCodeModalVisible] =
useState<boolean>(false);
const [editItemModalVisible, setEditItemModalVisible] =
useState<boolean>(false);
const [deleteItemModalVisible, setDeleteItemModalVisible] =
Expand Down Expand Up @@ -116,7 +116,11 @@ const ItemListOptions: FC<ItemListOptionsProps> = ({
};

const handleSharePress = () => {
setShareModalVisible(true);
onShare(item.id, SHARE_OPTIONS.BUILDER);
};

const handleShowQrCodePress = () => {
setShowQrCodeModalVisible(true);
};

const handleOpenChat = async () => {
Expand All @@ -133,24 +137,24 @@ const ItemListOptions: FC<ItemListOptionsProps> = ({
throw new Error('No itemId');
}
const result = await Share.share({
message: `Check out this on Graasp: ${
message: `Check out ${item.name} on Graasp: ${
linkType === SHARE_OPTIONS.BUILDER
? `${SHARE_HOST.BUILDER}/${itemId}`
: `${SHARE_HOST.PLAYER}/${itemId}`
}`,
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
setShareModalVisible(false);
setShowQrCodeModalVisible(false);
} else {
setShareModalVisible(false);
setShowQrCodeModalVisible(false);
}
await customAnalyticsEvent(ANALYTICS_EVENTS.SHARE_GRAASP_LINK, {
method:
linkType === SHARE_OPTIONS.BUILDER ? VIEWS.BUILDER : VIEWS.PLAYER,
});
} else if (result.action === Share.dismissedAction) {
//setModalVisible({ toggle: false, itemId: null });
// do nothing
}
} catch (error: any) {
alert(error.message);
Expand All @@ -166,29 +170,12 @@ const ItemListOptions: FC<ItemListOptionsProps> = ({
<>
<Overlay
overlayStyle={styles.modalView}
isVisible={shareModalVisible}
onBackdropPress={() => setShareModalVisible(false)}
isVisible={showQrCodeModalVisible}
onBackdropPress={() => setShowQrCodeModalVisible(false)}
>
<Button
title="Player"
raised={true}
buttonStyle={{ backgroundColor: PRIMARY_COLOR }}
containerStyle={{ marginBottom: 20 }}
onPress={async () => {
await onShare(item.id, SHARE_OPTIONS.PLAYER);
}}
testID={SHARE_ITEM_PLAYER}
/>
<Divider />
<Button
title="Builder"
raised={true}
buttonStyle={{ backgroundColor: PRIMARY_COLOR }}
onPress={async () => {
await onShare(item.id, SHARE_OPTIONS.BUILDER);
}}
testID={SHARE_ITEM_BUILDER}
/>
<QRCode value={`${SHARE_HOST.BUILDER}/${item.id}`} />
<Text style={{ fontSize: 20, marginTop: 5 }}>{item.name}</Text>
<Text>{item.creator?.name}</Text>
</Overlay>
<Overlay
overlayStyle={styles.modalEditItemView}
Expand Down Expand Up @@ -234,9 +221,7 @@ const ItemListOptions: FC<ItemListOptionsProps> = ({
}}
/>

<BottomSheetScrollView
contentContainerStyle={{ backgroundColor: 'white' }}
>
<BottomSheetScrollView>
<ListItem
onPress={() => handleDetailsPress()}
style={{ paddingLeft: insets.left }}
Expand Down Expand Up @@ -289,6 +274,18 @@ const ItemListOptions: FC<ItemListOptionsProps> = ({
<ListItem.Title style={{ flex: 2 }}>{t('Share')}</ListItem.Title>
</ListItem.Content>
</ListItem>
<ListItem
onPress={() => handleShowQrCodePress()}
style={{ paddingLeft: insets.left }}
testID={ITEM_LIST_OPTIONS_SHOW_QR_CODE}
>
<MaterialIcons name="qr-code" size={24} color="grey" />
<ListItem.Content style={{ flexDirection: 'row' }}>
<ListItem.Title style={{ flex: 2 }}>
{t('Show QR code')}
</ListItem.Title>
</ListItem.Content>
</ListItem>
<BookmarkListItem item={item} onClick={closeSheet} />
{displayEditOrDeleteItem && (
<ListItem
Expand Down
8 changes: 4 additions & 4 deletions src/components/ItemsList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FC } from 'react';
import { FlatList } from 'react-native';
import { FlatList, View } from 'react-native';
import { Divider } from 'react-native-elements';

import { DiscriminatedItem, UUID } from '@graasp/sdk';
Expand Down Expand Up @@ -47,9 +47,9 @@ const ItemsList: FC<ItemsListProps> = ({
contentContainerStyle={{ flexGrow: 1 }}
ListEmptyComponent={<EmptyList />}
ItemSeparatorComponent={() => (
<Divider
style={{ width: '90%', marginHorizontal: 10, marginBottom: 10 }}
/>
<View style={{ alignItems: 'center' }}>
<Divider style={{ width: '90%' }} />
</View>
)}
/>
{displayAddItem && <AddItem parentId={parentId} refresh={refresh} />}
Expand Down
8 changes: 5 additions & 3 deletions src/components/PlayerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { divideContentAndFolderItems } from '../utils/functions/item';
import ActivityIndicator from './ActivityIndicator';
import PlayerFolderMenu from './PlayerFolderMenu';
import PlayerItem from './PlayerItem';
import ContainsOnlyFolderContent from './common/ContainsOnlyFolderContent';
import EmptyList from './common/EmptyList';

interface PlayerViewProps {
Expand Down Expand Up @@ -38,8 +39,9 @@ const PlayerView: FC<PlayerViewProps> = ({ origin, children }) => {
// do not add a view here because it might contain a link - webview
<>
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
{contentItems.length === 0 ? (
<EmptyList />
{children.length === 0 && <EmptyList />}
{contentItems.length === 0 && folderItems.length !== 0 ? (
<ContainsOnlyFolderContent />
) : (
contentItems.map((item) => (
<>
Expand Down Expand Up @@ -68,7 +70,7 @@ const styles = StyleSheet.create({
height: '100%',
},
bottomSpace: {
height: 100,
height: 20,
},
});

Expand Down
33 changes: 33 additions & 0 deletions src/components/common/ContainsOnlyFolderContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, View } from 'react-native';

import { MaterialIcons } from '@expo/vector-icons';

const ContainsOnlyFolderContent = () => {
const { t } = useTranslation();

return (
<View style={styles.container}>
<View style={styles.emptyIcon}>
<MaterialIcons name="folder-copy" size={50} />
</View>
<Text style={styles.text}>{t('FOLDER_CONTAINS_ONLY_FOLDERS')}</Text>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
textAlign: 'center',
},
emptyIcon: {
paddingBottom: 20,
},
});

export default ContainsOnlyFolderContent;
Loading

0 comments on commit ea2d09c

Please sign in to comment.