Skip to content

Commit

Permalink
feat(das-dui-tool): Add chat file preview support and small refactor (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian325 committed Apr 26, 2024
1 parent a4377e8 commit 3fd6e72
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 87 deletions.
72 changes: 66 additions & 6 deletions apps/das-dui-tool/app/(auth)/(app)/chats/[chatId].tsx
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -13,6 +14,7 @@ import {

import {
H2,
Image,
ListItem,
ListItemSubtitle,
SizableText,
Expand All @@ -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"
Expand Down Expand Up @@ -210,12 +214,60 @@ export default function ChatPage() {
subTitle={item.preview.description}
/>
)}
<RenderHTMLGeneric
content={
item.content_rendered ||
"<i>Deleted</i>"
}
/>
{item.file ? (
<>
{item.file.type?.startsWith(
"image"
) ? (
<FileLink
cloud_id={
item.file.cloud_id
}
file_type={
item.file.file_type
}
name={item.file.name}
path={item.file.path}
uuid={item.file.uuid}
>
<Image
source={{
uri:
item.file.meta
.thumbnail_uri ??
item.file.meta
.uri,
}}
style={styles.image}
/>
</FileLink>
) : (
<FileListItemLink
cloud_id={
item.file.cloud_id
}
extension={
item.file.extension
}
file_type={
item.file.file_type
}
meta={item.file.meta}
name={item.file.name}
path={item.file.path}
uuid={item.file.uuid}
/>
)}
</>
) : (
<RenderHTMLGeneric
content={
item.content_rendered ||
"<i>Deleted</i>"
}
/>
)}

<View alignSelf="flex-end">
<SizableText fontSize={"$3"}>
{new Date(
Expand Down Expand Up @@ -275,3 +327,11 @@ export default function ChatPage() {
</>
)
}

const styles = StyleSheet.create({
image: {
width: 200,
height: 150,
resizeMode: "contain",
},
})
95 changes: 14 additions & 81 deletions apps/das-dui-tool/app/(auth)/(app)/chats/cloud/file/[fileId].tsx
Original file line number Diff line number Diff line change
@@ -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<{
Expand Down Expand Up @@ -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 (
<Link
push
href={
item.file_type === "DIR"
? {
pathname:
"/(auth)/(app)/chats/cloud/file/[fileId]",
params: {
fileId: item.uuid,
cloudId: cloudId,
path: item.path,
},
}
: {
pathname:
"/(auth)/(app)/chats/cloud/open_file/[fileId]",
params: {
fileId: item.uuid,
cloudId: item.cloud_id,
name: nameParam,
},
}
}
asChild
>
<ListItem
title={item.name}
subTitle={item.meta.subtitle}
icon={
<GenericIcon
name={
item.file_type === "DIR"
? item.meta.files_count > 0
? "folder"
: "folder-open"
: iconNameBasedOnFileExtension(
item.extension
)
}
size={30}
color={theme.color10.val}
/>
}
iconAfter={
<TouchableOpacity
onPress={() =>
WebBrowser.openBrowserAsync(
item.meta.download_uri
)
}
>
<GenericIcon
name="download"
color={theme.color9.val}
/>
</TouchableOpacity>
}
bordered
pressTheme
hoverTheme
br={"$4"}
my="$2"
/>
</Link>
)
}}
renderItem={({ item }) => (
<FileListItemLink
cloud_id={item.cloud_id}
extension={item.extension}
file_type={item.file_type}
meta={item.meta}
name={item.name}
uuid={item.uuid}
path={item.path}
/>
)}
onEndReached={fetchNextPage}
estimatedItemSize={80}
contentContainerStyle={{ padding: 20 }}
Expand Down
61 changes: 61 additions & 0 deletions apps/das-dui-tool/components/cloud/FileLink.tsx
Original file line number Diff line number Diff line change
@@ -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<PropsWithChildren<FileLinkProps>> = ({
children,
cloud_id,
file_type,
name,
path,
uuid,
}) => {
const params = new URLSearchParams({
name: name,
})
const nameParam = params
.toString()
.split("&")[0]
.split("=")[1]
.replaceAll("+", " ")

return (
<Link
push
href={
file_type === "DIR"
? {
pathname: "/(auth)/(app)/chats/cloud/file/[fileId]",
params: {
fileId: uuid,
cloudId: cloud_id,
path: path,
},
}
: {
pathname:
"/(auth)/(app)/chats/cloud/open_file/[fileId]",
params: {
fileId: uuid,
cloudId: cloud_id,
name: nameParam,
},
}
}
asChild
>
{children}
</Link>
)
}

FileLink.displayName = "FileLink"

export default FileLink
63 changes: 63 additions & 0 deletions apps/das-dui-tool/components/cloud/FileListItem.tsx
Original file line number Diff line number Diff line change
@@ -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<FileListItemProps> = ({
name,
meta,
extension,
file_type,
}) => {
const theme = useTheme()

return (
<ListItem
title={name}
subTitle={meta.subtitle}
icon={
<GenericIcon
name={
file_type === "DIR"
? meta.files_count > 0
? "folder"
: "folder-open"
: iconNameBasedOnFileExtension(extension)
}
size={30}
color={theme.color10.val}
/>
}
iconAfter={
<TouchableOpacity
onPress={() =>
WebBrowser.openBrowserAsync(meta.download_uri)
}
>
<GenericIcon name="download" color={theme.color9.val} />
</TouchableOpacity>
}
bordered
pressTheme
hoverTheme
br={"$4"}
my="$2"
/>
)
}

FileListItem.displayName = "FileListItem"

export default FileListItem
Loading

0 comments on commit 3fd6e72

Please sign in to comment.