chat ui begin

alpha
Jan Umbach 2023-03-05 22:36:18 +01:00
parent 79365c55f1
commit 589545ae09
8 changed files with 210 additions and 121 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"cSpell.words": ["Pressable"]
}

View File

@ -44,6 +44,10 @@ import {
LoginStackNavigatorParamList, LoginStackNavigatorParamList,
RegisterScreenAnim, RegisterScreenAnim,
} from './components/NotLoggedIn'; } from './components/NotLoggedIn';
import ChatMainScreen, {
ChatMainStackNavigatorParamList,
} from './components/chat/screen/main';
import ChatScreenStack from './components/chat/screen/main';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -59,6 +63,7 @@ export const linking: LinkingOptions<{}> = {
export type RootStackNavigatorParamList = { export type RootStackNavigatorParamList = {
Home: NavigatorScreenParams<HomeStackNavigatorParamList>; Home: NavigatorScreenParams<HomeStackNavigatorParamList>;
Register: NavigatorScreenParams<LoginStackNavigatorParamList>; Register: NavigatorScreenParams<LoginStackNavigatorParamList>;
Chat: NavigatorScreenParams<ChatMainStackNavigatorParamList>;
}; };
export type RootScreenNavigationProp = export type RootScreenNavigationProp =
@ -69,6 +74,11 @@ export default function Navigation() {
<Stack.Navigator screenOptions={{headerShown: false}}> <Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Home" component={HomeStack} /> <Stack.Screen name="Home" component={HomeStack} />
<Stack.Screen name="Register" component={RegisterScreenAnim} /> <Stack.Screen name="Register" component={RegisterScreenAnim} />
<Stack.Screen
name="Chat"
component={ChatScreenStack}
options={{animation: 'fade'}}
/>
</Stack.Navigator> </Stack.Navigator>
); );
} }
@ -79,7 +89,7 @@ export type HomeStackNavigatorParamList = {
Account: NavigatorScreenParams<AccountStackNavigatorParamList>; Account: NavigatorScreenParams<AccountStackNavigatorParamList>;
Calendar: NavigatorScreenParams<CalendarStackNavigatorParamList>; Calendar: NavigatorScreenParams<CalendarStackNavigatorParamList>;
Maps: NavigatorScreenParams<MapsStackNavigatorParamList>; Maps: NavigatorScreenParams<MapsStackNavigatorParamList>;
Chat: NavigatorScreenParams<ChatStackNavigatorParamList>; ChatList: NavigatorScreenParams<ChatStackNavigatorParamList>;
}; };
function AccountTabAnim(props: any) { function AccountTabAnim(props: any) {
@ -106,9 +116,9 @@ function MapsTabAnim(props: any) {
} }
function ChatTabAnim(props: any) { function ChatTabAnim(props: any) {
return ( return (
<SlideFromRightView> <SlideFromLeftView>
<ChatTab {...props} /> <ChatTab {...props} />
</SlideFromRightView> </SlideFromLeftView>
); );
} }
@ -118,7 +128,7 @@ function HomeStack() {
<Tab.Screen name="Account" component={AccountTabAnim} /> <Tab.Screen name="Account" component={AccountTabAnim} />
<Tab.Screen name="Calendar" component={CalendarTabAnim} /> <Tab.Screen name="Calendar" component={CalendarTabAnim} />
<Tab.Screen name="Maps" component={MapsTabAnim} /> <Tab.Screen name="Maps" component={MapsTabAnim} />
<Tab.Screen name="Chat" component={ChatTabAnim} /> <Tab.Screen name="ChatList" component={ChatTabAnim} />
</Tab.Navigator> </Tab.Navigator>
); );
} }

View File

@ -50,8 +50,6 @@ export function ProfilePicture(props: {size: number; UserId: UserId}) {
hash = Math.abs(hash >> 16); hash = Math.abs(hash >> 16);
console.log(hash);
return ( return (
<Box <Box
bg={'hsl(' + hash + ', 70%, 60%)'} bg={'hsl(' + hash + ', 70%, 60%)'}

View File

@ -1,11 +1,14 @@
import {appNonSaveVarActions} from '@caj/configs/appNonSaveVarReducer';
import { import {
darkThemeStyle, darkThemeStyle,
getBackgroundColor, getBackgroundColor,
themeSelector, themeSelector,
} from '@caj/configs/colors'; } from '@caj/configs/colors';
import {RootState} from '@caj/redux/store'; import {RootScreenNavigationProp} from '@caj/Navigation';
import {RootState, store} from '@caj/redux/store';
import UserManager from '@caj/user/UserManager'; import UserManager from '@caj/user/UserManager';
import {Box, HStack, Text, VStack} from 'native-base'; import {useNavigation} from '@react-navigation/native';
import {Box, HStack, Pressable, Text, VStack} from 'native-base';
import {useSelector} from 'react-redux'; import {useSelector} from 'react-redux';
import {start} from 'repl'; import {start} from 'repl';
import {ProfilePicture} from '../ProfilePicture'; import {ProfilePicture} from '../ProfilePicture';
@ -18,6 +21,11 @@ export function ListChats() {
const chatActivity = useSelector( const chatActivity = useSelector(
(state: RootState) => state.nonSaveVariables.chatActivity, (state: RootState) => state.nonSaveVariables.chatActivity,
); );
const selectedChat = useSelector(
(state: RootState) => state.nonSaveVariables.selectedChat,
);
console.log('selectedChat', selectedChat);
const space = 4; const space = 4;
const ppSize = 64; const ppSize = 64;
@ -25,6 +33,8 @@ export function ListChats() {
const lang = useSelector((state: RootState) => state.appVariables.lang); const lang = useSelector((state: RootState) => state.appVariables.lang);
const navigation = useNavigation<RootScreenNavigationProp>();
return ( return (
<VStack <VStack
mt={space * 2 + 'px'} mt={space * 2 + 'px'}
@ -37,118 +47,131 @@ export function ListChats() {
const user = UserManager.getUserSelector(chatId); const user = UserManager.getUserSelector(chatId);
return ( return (
<Box <Pressable
key={'chatList_i' + i + chatId} key={'chatList_i' + i + chatId}
bg={'blackBG.400'} onPress={() => {
{...darkThemeStyle(theme, 'black.400')} store.dispatch(appNonSaveVarActions.setSelectedChat(chatId));
borderRadius={ppSize / 2 + 'px'} navigation.navigate('Chat', {screen: 'Overview'});
borderTopRightRadius={ //navigation.navigate('Register', {screen: 'RegStepOne'});
chat.unreadMessages !== 0 }}>
? tagSize / 2 + 'px' {({isHovered, isFocused, isPressed}) => {
: ppSize / 2 + 'px' return (
} <Box
borderBottomLeftRadius={ bg={isHovered ? 'black.200' : 'blackBG.400'}
chat.tags.length > 0 ? tagSize / 2 + 'px' : ppSize / 2 + 'px' {...darkThemeStyle(theme, 'black.400')}
} borderRadius={ppSize / 2 + 'px'}
marginX={space + 'px'} borderTopRightRadius={
padding={space + 'px'}> chat.unreadMessages !== 0
<HStack ? tagSize / 2 + 'px'
position={'absolute'} : ppSize / 2 + 'px'
space={space * 2 + 'px'} }
right={space + 'px'} borderBottomLeftRadius={
top={-tagSize * 0.3 + 'px'}> chat.tags.length > 0
<Box ? tagSize / 2 + 'px'
height={tagSize + 'px'} : ppSize / 2 + 'px'
paddingX={tagSize / 3 + 'px'} }
borderRadius={tagSize / 2} marginX={space + 'px'}
bg={'#666'}> padding={space + 'px'}>
<TextSkeleton <HStack
color={'#eee'} position={'absolute'}
SkeletonProps={{ space={space * 2 + 'px'}
lines: 1, right={space + 'px'}
width: '75px', top={-tagSize * 0.3 + 'px'}>
}} <Box
lineHeight={tagSize + 'px'} height={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}> paddingX={tagSize / 3 + 'px'}
{user.AccountName.data} borderRadius={tagSize / 2}
</TextSkeleton> bg={'#666'}>
</Box> <TextSkeleton
<Box color={'#eee'}
alignItems={'center'} SkeletonProps={{
height={tagSize + 'px'} lines: 1,
paddingX={tagSize / 2.75 + 'px'} width: '75px',
mt={tagSize * 0.3 + space + 'px'} }}
borderRadius={tagSize / 2} lineHeight={tagSize + 'px'}
bg={'primary.600'} fontSize={tagSize / 1.75 + 'px'}>
opacity={chat.unreadMessages === 0 ? 0 : 1}> {user.AccountName.data}
<TextSkeleton </TextSkeleton>
color={'#fff'} </Box>
SkeletonProps={{ <Box
lines: 1, alignItems={'center'}
width: '75px', height={tagSize + 'px'}
}} paddingX={tagSize / 2.75 + 'px'}
lineHeight={tagSize + 'px'} mt={tagSize * 0.3 + space + 'px'}
fontSize={tagSize / 1.75 + 'px'}> borderRadius={tagSize / 2}
{chat.unreadMessages} bg={'primary.600'}
</TextSkeleton> opacity={chat.unreadMessages === 0 ? 0 : 1}>
</Box> <TextSkeleton
</HStack> color={'#fff'}
<VStack> SkeletonProps={{
<HStack space={space + 'px'}> lines: 1,
<ProfilePicture width: '75px',
UserId={chatId} }}
size={ppSize}></ProfilePicture> lineHeight={tagSize + 'px'}
<VStack mt={ppSize / 6 + 'px'}> fontSize={tagSize / 1.75 + 'px'}>
<TextSkeleton {chat.unreadMessages}
lineHeight={ppSize / 3 + 'px'} </TextSkeleton>
numberOfLines={1} </Box>
SkeletonProps={{ </HStack>
lines: 1, <VStack>
width: '160px', <HStack space={space + 'px'}>
}} <ProfilePicture
color="primary.400"> UserId={chatId}
{user.Username.data} size={ppSize}></ProfilePicture>
</TextSkeleton> <VStack mt={ppSize / 6 + 'px'}>
<TextSkeleton <TextSkeleton
lineHeight={ppSize / 3 + 'px'} lineHeight={ppSize / 3 + 'px'}
numberOfLines={1} numberOfLines={1}
SkeletonProps={{ SkeletonProps={{
lines: 1, lines: 1,
width: '160px', width: '160px',
}} }}
color="white.700"> color="primary.400">
{'I love Chicken McNuggets von Burgerking'} {user.Username.data}
</TextSkeleton> </TextSkeleton>
</VStack> <TextSkeleton
</HStack> lineHeight={ppSize / 3 + 'px'}
{chat.tags.length > 0 ? ( numberOfLines={1}
<HStack flexWrap={'wrap'}> SkeletonProps={{
{chat.tags.map((tag, i) => { lines: 1,
const tagObj = getTagUI(tag, lang); width: '160px',
}}
color="white.700">
{'I love Chicken McNuggets von Burgerking'}
</TextSkeleton>
</VStack>
</HStack>
{chat.tags.length > 0 ? (
<HStack flexWrap={'wrap'}>
{chat.tags.map((tag, i) => {
const tagObj = getTagUI(tag, lang);
let tagName = tagObj.name; let tagName = tagObj.name;
return ( return (
<Box <Box
key={'tag' + i + tag + chat.id} key={'tag' + i + tag + chat.id}
height={tagSize + 'px'} height={tagSize + 'px'}
mr={space + 'px'} mr={space + 'px'}
mt={space + 'px'} mt={space + 'px'}
paddingX={tagSize / 3 + 'px'} paddingX={tagSize / 3 + 'px'}
borderRadius={tagSize / 2} borderRadius={tagSize / 2}
bg={tagObj.background}> bg={tagObj.background}>
<Text <Text
color={tagObj.textColor} color={tagObj.textColor}
lineHeight={tagSize + 'px'} lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}> fontSize={tagSize / 1.75 + 'px'}>
{tagName} {tagName}
</Text> </Text>
</Box> </Box>
); );
})} })}
</HStack> </HStack>
) : null} ) : null}
</VStack> </VStack>
</Box> </Box>
);
}}
</Pressable>
); );
} }
})} })}

View File

@ -0,0 +1,50 @@
import {defaultHeaderStyle} from '@caj/configs/colors';
import {SlideFromRightView} from '@caj/helper/animations';
import {RootState} from '@caj/redux/store';
import {
createNativeStackNavigator,
NativeStackNavigationProp,
} from '@react-navigation/native-stack';
import {Text} from 'native-base';
import {useSelector} from 'react-redux';
export type ChatMainStackNavigatorParamList = {
Overview: undefined;
};
const ChatStack = createNativeStackNavigator<ChatMainStackNavigatorParamList>();
export type ChatScreenNavigationProp =
NativeStackNavigationProp<ChatMainStackNavigatorParamList>;
function ChatScreenStack() {
const lang = useSelector((state: RootState) => state.appVariables.lang);
const theme = useSelector(
(state: RootState) => state.appVariables.preferences.theme,
);
return (
<ChatStack.Navigator>
<ChatStack.Screen
name="Overview"
options={{
title: '',
animation: 'fade',
headerShown: true,
...defaultHeaderStyle(theme),
}}
component={ChatMainScreen}
/>
</ChatStack.Navigator>
);
}
function ChatMainScreen() {
const chatId = useSelector(
(state: RootState) => state.nonSaveVariables.selectedChat,
);
return <Text>{chatId}</Text>;
}
export default ChatScreenStack;

View File

@ -1,6 +1,6 @@
//these variables should not changed by the user and will not be saved in storage //these variables should not changed by the user and will not be saved in storage
import { chatEntity, chatId } from '@caj/components/chat/types'; import {chatEntity, chatId} from '@caj/components/chat/types';
import {getVersionByNum, VersionType} from '@caj/helper/version'; import {getVersionByNum, VersionType} from '@caj/helper/version';
import {User} from '@caj/user/types'; import {User} from '@caj/user/types';
import {UserId} from './types'; import {UserId} from './types';
@ -26,8 +26,9 @@ export interface NON_SAVE_VARS {
appStatus: appStatus; appStatus: appStatus;
connectionStatus: connectionStatus; connectionStatus: connectionStatus;
cachedUsers: {[key: UserId]: User}; cachedUsers: {[key: UserId]: User};
chats: {[key: chatId]: chatEntity} chats: {[key: chatId]: chatEntity};
chatActivity: chatId[]; chatActivity: chatId[];
selectedChat: chatId | 'none';
} }
export const non_save_vars: NON_SAVE_VARS = { export const non_save_vars: NON_SAVE_VARS = {
@ -37,4 +38,5 @@ export const non_save_vars: NON_SAVE_VARS = {
cachedUsers: {}, cachedUsers: {},
chats: {}, chats: {},
chatActivity: [], chatActivity: [],
selectedChat: 'none',
}; };

View File

@ -19,6 +19,9 @@ export const appNonSaveVariablesSlice = createSlice({
removeCachedUser: (state, action: PayloadAction<UserId>) => { removeCachedUser: (state, action: PayloadAction<UserId>) => {
delete state.cachedUsers[action.payload]; delete state.cachedUsers[action.payload];
}, },
setSelectedChat: (state, action: PayloadAction<chatId>) => {
state.selectedChat = action.payload;
},
setChatEntity: (state, action: PayloadAction<chatEntity>) => { setChatEntity: (state, action: PayloadAction<chatEntity>) => {
const chatId = action.payload.id; const chatId = action.payload.id;