chat (wip)

This commit is contained in:
Linus109
2025-11-25 20:52:53 +01:00
parent 56ae3a1b2d
commit 154491bc3a
4 changed files with 371 additions and 3 deletions

350
app/Chat.tsx Normal file
View File

@@ -0,0 +1,350 @@
import { View, Text, FlatList, TextInput } from "react-native";
import currentTheme from "./Themes";
import { useState } from "react";
// TODO: better shadows for everything
type BubbleSide = "left" | "right";
type ChatMessageProps = {
side: BubbleSide;
width: number;
height: number;
};
type messageData = {
id: string;
side: BubbleSide;
width: number;
height: number;
};
// NOTE: only for testing
const getRandomInt = (min: number, max: number) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const randomWidth = () => getRandomInt(100, 400);
const randomHeight = () => getRandomInt(50, 100);
const messages: messageData[] = [
// {{{
{
id: "1",
side: "left",
width: randomWidth(),
height: randomHeight(),
},
{
id: "2",
side: "right",
width: randomWidth(),
height: randomHeight(),
},
{
id: "3",
side: "left",
width: randomWidth(),
height: randomHeight(),
},
{
id: "4",
side: "right",
width: randomWidth(),
height: randomHeight(),
},
{
id: "5",
side: "left",
width: randomWidth(),
height: randomHeight(),
},
{
id: "6",
side: "right",
width: randomWidth(),
height: randomHeight(),
},
{
id: "7",
side: "left",
width: randomWidth(),
height: randomHeight(),
},
{
id: "8",
side: "right",
width: randomWidth(),
height: randomHeight(),
},
{
id: "9",
side: "left",
width: randomWidth(),
height: randomHeight(),
},
{
id: "10",
side: "right",
width: randomWidth(),
height: randomHeight(),
},
// {
// id: "11",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "12",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "13",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "14",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "15",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "16",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "17",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "18",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "19",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "20",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "21",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "22",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "23",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "24",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "25",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "26",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "27",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "28",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "29",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "30",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "31",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "32",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "33",
// side: "left",
// width: randomWidth(),
// height: randomHeight(),
// },
// {
// id: "34",
// side: "right",
// width: randomWidth(),
// height: randomHeight(),
// },
//, width: randomWidth, height: getRandomInt(50, 500) }}}
];
const Chat = () => {
return (
<View
className="h-full"
style={{
backgroundColor: currentTheme.primeBg,
}}
>
<ChatHeader />
<View
className="h-2 bg-black"
style={{
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 5,
},
shadowOpacity: 0.34,
shadowRadius: 6.27,
elevation: 10,
}}
/>
<FlatList
inverted
data={messages}
renderItem={({ item }) => (
<ChatMessage
side={item.side}
width={item.width}
height={item.height}
/>
)}
keyExtractor={(item) => item.id}
// extraData={selectedId} might need this later for re-rendering
/>
<ChatInput />
</View>
);
};
const ChatHeader = () => {
return (
<View
className="flex flex-row items-center py-4"
style={{
backgroundColor: currentTheme.chatBot,
}}
>
<View
className="ml-3 w-12 h-12 rounded-3xl border border-solid"
style={{
backgroundColor: currentTheme.placeholderBg,
borderColor: currentTheme.primeFg,
}}
></View>
<Text className="text-lg pl-3">CalChat</Text>
</View>
);
};
const ChatInput = () => {
const [text, onChangeText] = useState("Nachricht");
return (
<View className="flex flex-row w-full h-8 my-2">
<TextInput
className="w-4/5 h-full border border-solid rounded-2xl mx-2 px-2"
style={{
backgroundColor: currentTheme.messageBorderBg,
}}
onChangeText={onChangeText}
value={text}
/>
<View
className="w-8 h-full rounded-2xl"
style={{
backgroundColor: currentTheme.placeholderBg,
}}
></View>
</View>
);
};
const ChatMessage = (props: ChatMessageProps) => {
const borderColor =
props.side === "left" ? currentTheme.chatBot : currentTheme.primeFg;
const selfSide =
props.side === "left"
? "self-start ml-2 rounded-bl-sm"
: "self-end mr-2 rounded-br-sm";
return (
<View
className={
`bg-white border-2 border-solid rounded-xl my-2 ` + `${selfSide}`
}
style={{
width: props.width,
height: props.height,
borderColor: borderColor,
elevation: 8,
}}
>
<Text className="p-1">Lorem Ipsum Dolor sit amet</Text>
</View>
);
};
export default Chat;

18
app/Themes.tsx Normal file
View File

@@ -0,0 +1,18 @@
type Theme = {
chatBot: string,
primeFg: string,
primeBg: string,
messageBorderBg: string,
placeholderBg: string,
}
const defaultLight: Theme = {
chatBot: "#DE6C20",
primeFg: "#3B3329",
primeBg: "#FFEEDE",
messageBorderBg: "#FFFFFF",
placeholderBg: "#D9D9D9"
}
let currentTheme: Theme = defaultLight;
export default currentTheme;

View File

@@ -2,5 +2,5 @@ import { Stack } from "expo-router";
import "../global.css";
export default function RootLayout() {
return <Stack />;
return <Stack screenOptions={{ headerShown: false }} />;
}

View File

@@ -1,8 +1,8 @@
import React from "react";
import ManyHelloes from "./Hello_World";
import Chat from "./Chat";
export default function Index() {
return (
<ManyHelloes/>
<Chat />
);
}