Skip to content

Commit

Permalink
Merge pull request #658 from ephemeraHQ/lr/requests-ui-enhancements
Browse files Browse the repository at this point in the history
Improve Message Requests UI for iOS
  • Loading branch information
alexrisch authored Sep 5, 2024
2 parents 926499a + d1a339e commit a908afb
Show file tree
Hide file tree
Showing 5 changed files with 454 additions and 64 deletions.
80 changes: 31 additions & 49 deletions components/ConversationList/RequestsButton.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { NativeStackScreenProps } from "@react-navigation/native-stack";
import {
clickedItemBackgroundColor,
listItemSeparatorColor,
primaryColor,
textPrimaryColor,
actionSecondaryColor,
requestsTextColor,
textSecondaryColor,
} from "@styles/colors";
import {
Platform,
Pressable,
StyleSheet,
Text,
TouchableHighlight,
useColorScheme,
View,
} from "react-native";
Expand All @@ -22,77 +20,61 @@ type Props = { requestsCount: number } & NativeStackScreenProps<
"Chats" | "ShareFrame" | "Blocked"
>;
export default function RequestsButton({ navigation, requestsCount }: Props) {
const colorScheme = useColorScheme();
const styles = useStyles();

return (
<TouchableHighlight
underlayColor={clickedItemBackgroundColor(colorScheme)}
<Pressable
key="requests"
onPress={() => {
navigation.push("ChatsRequests");
}}
onPress={() => navigation.push("ChatsRequests")}
style={styles.requestsHeader}
>
<View style={styles.requestsHeader}>
<Text style={styles.requestsHeaderTitle}>Requests</Text>
<Text style={styles.requestsCount}>{requestsCount}</Text>
</View>
</TouchableHighlight>
{({ pressed }) => (
<View>
<Text
style={[
styles.requestsCount,
requestsCount === 0 && styles.zeroRequests,
pressed && styles.pressedText,
]}
>
{requestsCount === 0 ? "Requests" : `Requests (${requestsCount})`}
</Text>
</View>
)}
</Pressable>
);
}

const useStyles = () => {
const colorScheme = useColorScheme();
return StyleSheet.create({
requestsHeader: {
flexDirection: "row",
alignItems: "center",
...Platform.select({
default: {
paddingVertical: 8,
paddingRight: 8,
paddingLeft: 24,
height: 40,
borderBottomWidth: 0.25,
borderBottomColor: listItemSeparatorColor(colorScheme),
borderTopWidth: 0.25,
borderTopColor: listItemSeparatorColor(colorScheme),
},
android: {
paddingVertical: 12,
paddingLeft: 24,
paddingRight: 14,
},
}),
},
requestsHeaderTitle: {
color: textPrimaryColor(colorScheme),
...Platform.select({
default: {
fontSize: 17,
fontWeight: "600",
marginBottom: 3,
marginRight: 110,
},
android: {
fontSize: 16,
},
}),
},
requestsCount: {
marginLeft: "auto",

fontWeight: "500",
color: requestsTextColor(colorScheme),
...Platform.select({
default: {
marginRight: 16,
fontSize: 15,
color: textSecondaryColor(colorScheme),
fontSize: 14,
marginBottom: 3,
},
android: {
marginRight: 1,
fontSize: 11,
color: primaryColor(colorScheme),
},
}),
},
zeroRequests: {
color: textSecondaryColor(colorScheme),
},
pressedText: {
color: actionSecondaryColor(colorScheme),
},
});
};
98 changes: 98 additions & 0 deletions components/ConversationList/RequestsSegmentedController.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {
tertiaryBackgroundColor,
textPrimaryColor,
BACKGROUND_LIGHT,
TEXT_PRIMARY_COLOR_LIGHT,
} from "@styles/colors";
import React from "react";
import {
View,
Text,
TouchableOpacity,
StyleSheet,
useColorScheme,
} from "react-native";

interface SegmentedControllerProps {
options: string[];
selectedIndex: number;
onSelect: (index: number) => void;
}

const RequestsSegmentedController: React.FC<SegmentedControllerProps> = ({
options,
selectedIndex,
onSelect,
}) => {
const styles = useStyles();

return (
<View style={styles.container}>
{options.map((option, index) => (
<TouchableOpacity
key={index}
style={[
styles.option,
index === selectedIndex && styles.selectedOption,
index === 0 && styles.firstOption,
index === options.length - 1 && styles.lastOption,
]}
onPress={() => onSelect(index)}
>
<Text
style={[
styles.optionText,
index === selectedIndex && styles.selectedOptionText,
]}
>
{option}
</Text>
</TouchableOpacity>
))}
</View>
);
};

const useStyles = () => {
const colorScheme = useColorScheme();
return StyleSheet.create({
container: {
flexDirection: "row",
backgroundColor: tertiaryBackgroundColor(colorScheme),
borderRadius: 8,
padding: 2,
height: 32,
marginTop: 10,
marginBottom: 2,
marginHorizontal: 16,
},
option: {
flex: 1,
paddingVertical: 6,
alignItems: "center",
justifyContent: "center",
},
selectedOption: {
backgroundColor: BACKGROUND_LIGHT,
borderRadius: 6,
},
firstOption: {
borderTopLeftRadius: 6,
borderBottomLeftRadius: 6,
},
lastOption: {
borderTopRightRadius: 6,
borderBottomRightRadius: 6,
},
optionText: {
fontSize: 13,
color: textPrimaryColor(colorScheme),
},
selectedOptionText: {
fontWeight: "500",
color: TEXT_PRIMARY_COLOR_LIGHT,
},
});
};

export default RequestsSegmentedController;
63 changes: 52 additions & 11 deletions screens/ConversationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NativeStackScreenProps } from "@react-navigation/native-stack";
import {
backgroundColor,
itemSeparatorColor,
listItemSeparatorColor,
textPrimaryColor,
} from "@styles/colors";
import React, { useCallback, useEffect, useState } from "react";
Expand Down Expand Up @@ -162,27 +163,38 @@ function ConversationList({ navigation, route, searchBarRef }: Props) {
key="pinnedConversations"
/>,
];

const showSearchTitleHeader =
((Platform.OS === "ios" && searchBarFocused && !showNoResult) ||
(Platform.OS === "android" && searchBarFocused)) &&
!sharingMode;

if (showSearchTitleHeader) {
ListHeaderComponents.push(
<View key="search" style={styles.searchTitleContainer}>
<Text style={styles.searchTitle}>Chats</Text>
<Text style={styles.searchTitle}>Messages</Text>
</View>
);
} else if (
sortedConversationsWithPreview.conversationsRequests.length > 0 &&
!sharingMode
) {
ListHeaderComponents.push(
<RequestsButton
key="requests"
navigation={navigation}
route={route}
requestsCount={likelyNotSpam.length}
/>
<View key="search" style={styles.headerTitleContainer}>
<Text style={styles.headerTitle}>Messages</Text>
<RequestsButton
key="requests"
navigation={navigation}
route={route}
requestsCount={likelyNotSpam.length}
/>
</View>
);
} else if (!sharingMode) {
ListHeaderComponents.push(
<View key="search" style={styles.headerTitleContainer}>
<Text style={styles.headerTitle}>Messages</Text>
</View>
);
}

Expand Down Expand Up @@ -254,10 +266,39 @@ const useStyles = () => {
color: textPrimaryColor(colorScheme),
},
android: {
fontSize: 11,
textTransform: "uppercase",
fontWeight: "bold",
color: textPrimaryColor(colorScheme),
fontSize: 16,
},
}),
},
headerTitleContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingTop: 12,
paddingBottom: 8,
paddingHorizontal: 16,
...Platform.select({
default: {
backgroundColor: backgroundColor(colorScheme),
borderTopWidth: 0.25,
borderTopColor: listItemSeparatorColor(colorScheme),
},
android: {
borderBottomWidth: 0,
},
}),
},
headerTitle: {
color: textPrimaryColor(colorScheme),
...Platform.select({
default: {
fontSize: 16,
fontWeight: "600",
marginBottom: 3,
marginRight: 110,
},
android: {
fontSize: 16,
},
}),
},
Expand Down
Loading

0 comments on commit a908afb

Please sign in to comment.