diff --git a/xtablo-expo/app/(home)/(tabs)/index.tsx b/xtablo-expo/app/(home)/(tabs)/index.tsx index a4d7589..1db4bc6 100644 --- a/xtablo-expo/app/(home)/(tabs)/index.tsx +++ b/xtablo-expo/app/(home)/(tabs)/index.tsx @@ -17,96 +17,6 @@ import { ColorMap } from "@/constants/colors"; import { UserTablo } from "@/types/tablos.types"; // Custom Avatar Component for Channel List -const CustomChannelAvatar = ({ - channel, - tablos, -}: { - channel: Channel; - tablos: UserTablo[]; -}) => { - const tabloId = channel?.id || ""; - const tablo = tablos?.find((t) => t.id === tabloId); - const tabloColor = tablo?.color || "bg-blue-500"; - const tabloName = tablo?.name || channel?.data?.name || "Tablo"; - - // Get members info - const members = channel?.state?.members || {}; - const memberCount = Object.keys(members).length; - - // Generate initials from tablo name - const getInitials = (name: string) => { - return name - .split(" ") - .map((word) => word.charAt(0)) - .join("") - .toUpperCase() - .slice(0, 2); - }; - - // // Create gradient colors based on tablo color - const getTabloGradientColors = (colorKey: string): [string, string] => { - const baseColor = ColorMap[colorKey] || ColorMap["bg-blue-500"]; - - // Create a lighter version for gradient effect - const lightenColor = (hex: string, percent: number): string => { - const num = parseInt(hex.replace("#", ""), 16); - const amt = Math.round(2.55 * percent); - const R = Math.min(255, Math.max(0, (num >> 16) + amt)); - const G = Math.min(255, Math.max(0, ((num >> 8) & 0x00ff) + amt)); - const B = Math.min(255, Math.max(0, (num & 0x0000ff) + amt)); - return "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1); - }; - - // Create a darker version for gradient effect - const darkenColor = (hex: string, percent: number): string => { - const num = parseInt(hex.replace("#", ""), 16); - const amt = Math.round(2.55 * percent); - const R = Math.min(255, Math.max(0, (num >> 16) - amt)); - const G = Math.min(255, Math.max(0, ((num >> 8) & 0x00ff) - amt)); - const B = Math.min(255, Math.max(0, (num & 0x0000ff) - amt)); - return "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1); - }; - - const lightColor = lightenColor(baseColor, 15); - const darkColor = darkenColor(baseColor, 10); - - return [lightColor, darkColor]; - }; - - const initials = getInitials(tabloName); - const gradientColors = getTabloGradientColors(tabloColor); - - return ( - - - {initials} - - {/* Member count indicator for group channels */} - {memberCount > 2 && ( - - {memberCount} - - )} - - - {/* Decorative ring */} - - - {/* Status indicator (online/active) */} - - - ); -}; // Custom Title Component for bigger channel names const CustomChannelTitle = ({ channel }: { channel: Channel }) => { @@ -121,7 +31,7 @@ const CustomChannelTitle = ({ channel }: { channel: Channel }) => { export default function HomeScreen() { const user = useUser(); - const { data: tablos } = useTablosList(); + const { data: tablos, isLoading } = useTablosList(); // Search animation state // const [isSearchVisible, setIsSearchVisible] = useState(false); @@ -164,10 +74,100 @@ export default function HomeScreen() { limit: 20, }; - // Create a wrapper component for the avatar that has access to tablos data - const AvatarWithTablos = ({ channel }: { channel: Channel }) => ( - - ); + const CustomChannelAvatar = ({ + channel, + tablos, + }: { + channel: Channel; + tablos: UserTablo[]; + }) => { + const tabloId = channel?.id || ""; + const tablo = tablos?.find((t) => t.id === tabloId); + const tabloColor = tablo?.color || "bg-blue-500"; + const tabloName = tablo?.name || channel?.data?.name || "Tablo"; + + // Get members info + const members = channel?.state?.members || {}; + const memberCount = Object.keys(members).length; + + // Generate initials from tablo name + const getInitials = (name: string) => { + return name + .split(" ") + .map((word) => word.charAt(0)) + .join("") + .toUpperCase() + .slice(0, 2); + }; + + // // Create gradient colors based on tablo color + const getTabloGradientColors = (colorKey: string): [string, string] => { + const baseColor = ColorMap[colorKey] || ColorMap["bg-blue-500"]; + + // Create a lighter version for gradient effect + const lightenColor = (hex: string, percent: number): string => { + const num = parseInt(hex.replace("#", ""), 16); + const amt = Math.round(2.55 * percent); + const R = Math.min(255, Math.max(0, (num >> 16) + amt)); + const G = Math.min(255, Math.max(0, ((num >> 8) & 0x00ff) + amt)); + const B = Math.min(255, Math.max(0, (num & 0x0000ff) + amt)); + return ( + "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1) + ); + }; + + // Create a darker version for gradient effect + const darkenColor = (hex: string, percent: number): string => { + const num = parseInt(hex.replace("#", ""), 16); + const amt = Math.round(2.55 * percent); + const R = Math.min(255, Math.max(0, (num >> 16) - amt)); + const G = Math.min(255, Math.max(0, ((num >> 8) & 0x00ff) - amt)); + const B = Math.min(255, Math.max(0, (num & 0x0000ff) - amt)); + return ( + "#" + ((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1) + ); + }; + + const lightColor = lightenColor(baseColor, 15); + const darkColor = darkenColor(baseColor, 10); + + return [lightColor, darkColor]; + }; + + const initials = getInitials(tabloName); + const gradientColors = getTabloGradientColors(tabloColor); + + return ( + + + {initials} + + {/* Member count indicator for group channels */} + {memberCount > 2 && ( + + {memberCount} + + )} + + + {/* Decorative ring */} + + + {/* Status indicator (online/active) */} + + + ); + }; // Toggle search animation // const toggleSearch = () => { @@ -272,6 +272,51 @@ export default function HomeScreen() { // // ); + if (isLoading) { + return ( + + + + {/* Loading Header */} + + + + + Discussions + + Chargement de vos conversations... + + + + + + {/* Decorative Elements */} + + + + + {/* Loading Content */} + + {/* Loading Skeleton Items */} + {[1, 2, 3, 4, 5].map((item) => ( + + + + + + + + ))} + + + ); + } + return ( @@ -327,7 +372,12 @@ export default function HomeScreen() { }} sort={sort} options={options} - PreviewAvatar={AvatarWithTablos} + PreviewAvatar={(props) => ( + + )} PreviewTitle={CustomChannelTitle} // ListHeaderComponent={SearchHeader} // Show loading state during search @@ -655,4 +705,44 @@ const styles = StyleSheet.create({ textAlign: "center", paddingHorizontal: 20, }, + + // Loading Skeleton Styles + loadingContentContainer: { + flex: 1, + backgroundColor: "#f8fafc", + marginTop: -10, + borderTopLeftRadius: 10, + borderTopRightRadius: 10, + paddingTop: 20, + paddingHorizontal: 20, + }, + loadingItem: { + flexDirection: "row", + alignItems: "center", + paddingVertical: 12, + marginBottom: 8, + }, + loadingAvatar: { + width: 56, + height: 56, + borderRadius: 16, + backgroundColor: "#e5e7eb", + marginRight: 12, + }, + loadingTextContainer: { + flex: 1, + }, + loadingTitle: { + height: 20, + backgroundColor: "#e5e7eb", + borderRadius: 4, + marginBottom: 8, + width: "70%", + }, + loadingSubtitle: { + height: 16, + backgroundColor: "#f3f4f6", + borderRadius: 4, + width: "50%", + }, });