From 3fd6e728d38caae23830498d99681ed7631daa11 Mon Sep 17 00:00:00 2001 From: Florian <101280123+Florian325@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:15:47 +0200 Subject: [PATCH] feat(das-dui-tool): Add chat file preview support and small refactor (#34) --- .../app/(auth)/(app)/chats/[chatId].tsx | 72 ++++++++++++-- .../(app)/chats/cloud/file/[fileId].tsx | 95 +++---------------- .../components/cloud/FileLink.tsx | 61 ++++++++++++ .../components/cloud/FileListItem.tsx | 63 ++++++++++++ .../components/cloud/FileListItemLink.tsx | 71 ++++++++++++++ 5 files changed, 275 insertions(+), 87 deletions(-) create mode 100644 apps/das-dui-tool/components/cloud/FileLink.tsx create mode 100644 apps/das-dui-tool/components/cloud/FileListItem.tsx create mode 100644 apps/das-dui-tool/components/cloud/FileListItemLink.tsx diff --git a/apps/das-dui-tool/app/(auth)/(app)/chats/[chatId].tsx b/apps/das-dui-tool/app/(auth)/(app)/chats/[chatId].tsx index b02440b..db68055 100644 --- a/apps/das-dui-tool/app/(auth)/(app)/chats/[chatId].tsx +++ b/apps/das-dui-tool/app/(auth)/(app)/chats/[chatId].tsx @@ -1,5 +1,6 @@ /* eslint-disable react/display-name */ import { Fragment, LegacyRef, ReactNode, forwardRef } from "react" +import { StyleSheet } from "react-native" import * as Linking from "expo-linking" import { Link, Stack, useLocalSearchParams } from "expo-router" @@ -13,6 +14,7 @@ import { import { H2, + Image, ListItem, ListItemSubtitle, SizableText, @@ -26,6 +28,8 @@ import { FlashList } from "@shopify/flash-list" import { NewsResponse } from "@das-dui/api-client" +import FileLink from "@/components/cloud/FileLink" +import FileListItemLink from "@/components/cloud/FileListItemLink" import NewsListItem from "@/components/news/NewsListItem" import GenericIcon from "@/components/ui/GenericIcon" import MessageInput from "@/components/ui/MessageInput" @@ -210,12 +214,60 @@ export default function ChatPage() { subTitle={item.preview.description} /> )} - Deleted" - } - /> + {item.file ? ( + <> + {item.file.type?.startsWith( + "image" + ) ? ( + + + + ) : ( + + )} + + ) : ( + Deleted" + } + /> + )} + {new Date( @@ -275,3 +327,11 @@ export default function ChatPage() { ) } + +const styles = StyleSheet.create({ + image: { + width: 200, + height: 150, + resizeMode: "contain", + }, +}) diff --git a/apps/das-dui-tool/app/(auth)/(app)/chats/cloud/file/[fileId].tsx b/apps/das-dui-tool/app/(auth)/(app)/chats/cloud/file/[fileId].tsx index b399f47..399bbc1 100644 --- a/apps/das-dui-tool/app/(auth)/(app)/chats/cloud/file/[fileId].tsx +++ b/apps/das-dui-tool/app/(auth)/(app)/chats/cloud/file/[fileId].tsx @@ -1,19 +1,18 @@ import { useState } from "react" import { TouchableOpacity } from "react-native" -import { Link, Stack, useLocalSearchParams } from "expo-router" -import * as WebBrowser from "expo-web-browser" +import { Stack, useLocalSearchParams } from "expo-router" import { useInfiniteQuery } from "@tanstack/react-query" -import { H6, ListItem, Spinner, View, useTheme } from "tamagui" +import { H6, Spinner, View, useTheme } from "tamagui" import { FlashList } from "@shopify/flash-list" +import FileListItemLink from "@/components/cloud/FileListItemLink" import GenericIcon from "@/components/ui/GenericIcon" import InputBar from "@/components/ui/InputBar" import useApiClient from "@/hooks/useApiClient" -import { iconNameBasedOnFileExtension } from "@/utils/iconNameBasedOnFileExtension" export default function CloudPage() { const { fileId, cloudId, path } = useLocalSearchParams<{ @@ -101,83 +100,17 @@ export default function CloudPage() { onSubmit={() => setSearchQuery("")} /> } - renderItem={({ item }) => { - const params = new URLSearchParams({ - name: item.name, - }) - const nameParam = params - .toString() - .split("&")[0] - .split("=")[1] - .replaceAll("+", " ") - - return ( - - 0 - ? "folder" - : "folder-open" - : iconNameBasedOnFileExtension( - item.extension - ) - } - size={30} - color={theme.color10.val} - /> - } - iconAfter={ - - WebBrowser.openBrowserAsync( - item.meta.download_uri - ) - } - > - - - } - bordered - pressTheme - hoverTheme - br={"$4"} - my="$2" - /> - - ) - }} + renderItem={({ item }) => ( + + )} onEndReached={fetchNextPage} estimatedItemSize={80} contentContainerStyle={{ padding: 20 }} diff --git a/apps/das-dui-tool/components/cloud/FileLink.tsx b/apps/das-dui-tool/components/cloud/FileLink.tsx new file mode 100644 index 0000000..7907b28 --- /dev/null +++ b/apps/das-dui-tool/components/cloud/FileLink.tsx @@ -0,0 +1,61 @@ +import { FC, PropsWithChildren } from "react" + +import { Link } from "expo-router" + +import { CloudResponse } from "@das-dui/api-client" + +type FileLinkProps = Pick< + CloudResponse.CloudFile, + "uuid" | "cloud_id" | "path" | "name" | "file_type" +> + +const FileLink: FC> = ({ + children, + cloud_id, + file_type, + name, + path, + uuid, +}) => { + const params = new URLSearchParams({ + name: name, + }) + const nameParam = params + .toString() + .split("&")[0] + .split("=")[1] + .replaceAll("+", " ") + + return ( + + {children} + + ) +} + +FileLink.displayName = "FileLink" + +export default FileLink diff --git a/apps/das-dui-tool/components/cloud/FileListItem.tsx b/apps/das-dui-tool/components/cloud/FileListItem.tsx new file mode 100644 index 0000000..c61ca9e --- /dev/null +++ b/apps/das-dui-tool/components/cloud/FileListItem.tsx @@ -0,0 +1,63 @@ +import { FC } from "react" +import { TouchableOpacity } from "react-native" + +import * as WebBrowser from "expo-web-browser" + +import { ListItem, useTheme } from "tamagui" + +import { ChatMessagesResponse, CloudResponse } from "@das-dui/api-client" + +import GenericIcon from "@/components/ui/GenericIcon" +import { iconNameBasedOnFileExtension } from "@/utils/iconNameBasedOnFileExtension" + +type FileListItemProps = Pick< + CloudResponse.CloudFile | ChatMessagesResponse.File, + "name" | "meta" | "file_type" | "extension" +> + +const FileListItem: FC = ({ + name, + meta, + extension, + file_type, +}) => { + const theme = useTheme() + + return ( + 0 + ? "folder" + : "folder-open" + : iconNameBasedOnFileExtension(extension) + } + size={30} + color={theme.color10.val} + /> + } + iconAfter={ + + WebBrowser.openBrowserAsync(meta.download_uri) + } + > + + + } + bordered + pressTheme + hoverTheme + br={"$4"} + my="$2" + /> + ) +} + +FileListItem.displayName = "FileListItem" + +export default FileListItem diff --git a/apps/das-dui-tool/components/cloud/FileListItemLink.tsx b/apps/das-dui-tool/components/cloud/FileListItemLink.tsx new file mode 100644 index 0000000..16ed487 --- /dev/null +++ b/apps/das-dui-tool/components/cloud/FileListItemLink.tsx @@ -0,0 +1,71 @@ +import { FC } from "react" +import { TouchableOpacity } from "react-native" + +import * as WebBrowser from "expo-web-browser" + +import { ListItem, useTheme } from "tamagui" + +import { ChatMessagesResponse, CloudResponse } from "@das-dui/api-client" + +import FileLink from "@/components/cloud/FileLink" +import GenericIcon from "@/components/ui/GenericIcon" +import { iconNameBasedOnFileExtension } from "@/utils/iconNameBasedOnFileExtension" + +type FileListItemLinkProps = Pick< + CloudResponse.CloudFile | ChatMessagesResponse.File, + "uuid" | "cloud_id" | "path" | "name" | "file_type" | "meta" | "extension" +> +const FileListItemLink: FC = ({ + cloud_id, + file_type, + name, + path, + uuid, + meta, + extension, +}) => { + const theme = useTheme() + return ( + + 0 + ? "folder" + : "folder-open" + : iconNameBasedOnFileExtension(extension) + } + size={30} + color={theme.color10.val} + /> + } + iconAfter={ + + WebBrowser.openBrowserAsync(meta.download_uri) + } + > + + + } + bordered + pressTheme + hoverTheme + br={"$4"} + my="$2" + /> + + ) +} + +export default FileListItemLink