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

View File

@ -68,7 +68,7 @@ export default function NotLoggedIn() {
);
const lang = useSelector((state: RootState) => state.appVariables.lang);
const theme = useSelector(
const theme = useSelector(
(state: RootState) => state.appVariables.preferences.theme,
);

View File

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

View File

@ -1,11 +1,14 @@
import {appNonSaveVarActions} from '@caj/configs/appNonSaveVarReducer';
import {
darkThemeStyle,
getBackgroundColor,
themeSelector,
} 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 {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 {start} from 'repl';
import {ProfilePicture} from '../ProfilePicture';
@ -18,6 +21,11 @@ export function ListChats() {
const chatActivity = useSelector(
(state: RootState) => state.nonSaveVariables.chatActivity,
);
const selectedChat = useSelector(
(state: RootState) => state.nonSaveVariables.selectedChat,
);
console.log('selectedChat', selectedChat);
const space = 4;
const ppSize = 64;
@ -25,6 +33,8 @@ export function ListChats() {
const lang = useSelector((state: RootState) => state.appVariables.lang);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<VStack
mt={space * 2 + 'px'}
@ -37,118 +47,131 @@ export function ListChats() {
const user = UserManager.getUserSelector(chatId);
return (
<Box
<Pressable
key={'chatList_i' + i + chatId}
bg={'blackBG.400'}
{...darkThemeStyle(theme, 'black.400')}
borderRadius={ppSize / 2 + 'px'}
borderTopRightRadius={
chat.unreadMessages !== 0
? tagSize / 2 + 'px'
: ppSize / 2 + 'px'
}
borderBottomLeftRadius={
chat.tags.length > 0 ? tagSize / 2 + 'px' : ppSize / 2 + 'px'
}
marginX={space + 'px'}
padding={space + 'px'}>
<HStack
position={'absolute'}
space={space * 2 + 'px'}
right={space + 'px'}
top={-tagSize * 0.3 + 'px'}>
<Box
height={tagSize + 'px'}
paddingX={tagSize / 3 + 'px'}
borderRadius={tagSize / 2}
bg={'#666'}>
<TextSkeleton
color={'#eee'}
SkeletonProps={{
lines: 1,
width: '75px',
}}
lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}>
{user.AccountName.data}
</TextSkeleton>
</Box>
<Box
alignItems={'center'}
height={tagSize + 'px'}
paddingX={tagSize / 2.75 + 'px'}
mt={tagSize * 0.3 + space + 'px'}
borderRadius={tagSize / 2}
bg={'primary.600'}
opacity={chat.unreadMessages === 0 ? 0 : 1}>
<TextSkeleton
color={'#fff'}
SkeletonProps={{
lines: 1,
width: '75px',
}}
lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}>
{chat.unreadMessages}
</TextSkeleton>
</Box>
</HStack>
<VStack>
<HStack space={space + 'px'}>
<ProfilePicture
UserId={chatId}
size={ppSize}></ProfilePicture>
<VStack mt={ppSize / 6 + 'px'}>
<TextSkeleton
lineHeight={ppSize / 3 + 'px'}
numberOfLines={1}
SkeletonProps={{
lines: 1,
width: '160px',
}}
color="primary.400">
{user.Username.data}
</TextSkeleton>
<TextSkeleton
lineHeight={ppSize / 3 + 'px'}
numberOfLines={1}
SkeletonProps={{
lines: 1,
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);
onPress={() => {
store.dispatch(appNonSaveVarActions.setSelectedChat(chatId));
navigation.navigate('Chat', {screen: 'Overview'});
//navigation.navigate('Register', {screen: 'RegStepOne'});
}}>
{({isHovered, isFocused, isPressed}) => {
return (
<Box
bg={isHovered ? 'black.200' : 'blackBG.400'}
{...darkThemeStyle(theme, 'black.400')}
borderRadius={ppSize / 2 + 'px'}
borderTopRightRadius={
chat.unreadMessages !== 0
? tagSize / 2 + 'px'
: ppSize / 2 + 'px'
}
borderBottomLeftRadius={
chat.tags.length > 0
? tagSize / 2 + 'px'
: ppSize / 2 + 'px'
}
marginX={space + 'px'}
padding={space + 'px'}>
<HStack
position={'absolute'}
space={space * 2 + 'px'}
right={space + 'px'}
top={-tagSize * 0.3 + 'px'}>
<Box
height={tagSize + 'px'}
paddingX={tagSize / 3 + 'px'}
borderRadius={tagSize / 2}
bg={'#666'}>
<TextSkeleton
color={'#eee'}
SkeletonProps={{
lines: 1,
width: '75px',
}}
lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}>
{user.AccountName.data}
</TextSkeleton>
</Box>
<Box
alignItems={'center'}
height={tagSize + 'px'}
paddingX={tagSize / 2.75 + 'px'}
mt={tagSize * 0.3 + space + 'px'}
borderRadius={tagSize / 2}
bg={'primary.600'}
opacity={chat.unreadMessages === 0 ? 0 : 1}>
<TextSkeleton
color={'#fff'}
SkeletonProps={{
lines: 1,
width: '75px',
}}
lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}>
{chat.unreadMessages}
</TextSkeleton>
</Box>
</HStack>
<VStack>
<HStack space={space + 'px'}>
<ProfilePicture
UserId={chatId}
size={ppSize}></ProfilePicture>
<VStack mt={ppSize / 6 + 'px'}>
<TextSkeleton
lineHeight={ppSize / 3 + 'px'}
numberOfLines={1}
SkeletonProps={{
lines: 1,
width: '160px',
}}
color="primary.400">
{user.Username.data}
</TextSkeleton>
<TextSkeleton
lineHeight={ppSize / 3 + 'px'}
numberOfLines={1}
SkeletonProps={{
lines: 1,
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;
return (
<Box
key={'tag' + i + tag + chat.id}
height={tagSize + 'px'}
mr={space + 'px'}
mt={space + 'px'}
paddingX={tagSize / 3 + 'px'}
borderRadius={tagSize / 2}
bg={tagObj.background}>
<Text
color={tagObj.textColor}
lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}>
{tagName}
</Text>
</Box>
);
})}
</HStack>
) : null}
</VStack>
</Box>
let tagName = tagObj.name;
return (
<Box
key={'tag' + i + tag + chat.id}
height={tagSize + 'px'}
mr={space + 'px'}
mt={space + 'px'}
paddingX={tagSize / 3 + 'px'}
borderRadius={tagSize / 2}
bg={tagObj.background}>
<Text
color={tagObj.textColor}
lineHeight={tagSize + 'px'}
fontSize={tagSize / 1.75 + 'px'}>
{tagName}
</Text>
</Box>
);
})}
</HStack>
) : null}
</VStack>
</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
import { chatEntity, chatId } from '@caj/components/chat/types';
import {chatEntity, chatId} from '@caj/components/chat/types';
import {getVersionByNum, VersionType} from '@caj/helper/version';
import {User} from '@caj/user/types';
import {UserId} from './types';
@ -26,8 +26,9 @@ export interface NON_SAVE_VARS {
appStatus: appStatus;
connectionStatus: connectionStatus;
cachedUsers: {[key: UserId]: User};
chats: {[key: chatId]: chatEntity}
chats: {[key: chatId]: chatEntity};
chatActivity: chatId[];
selectedChat: chatId | 'none';
}
export const non_save_vars: NON_SAVE_VARS = {
@ -37,4 +38,5 @@ export const non_save_vars: NON_SAVE_VARS = {
cachedUsers: {},
chats: {},
chatActivity: [],
selectedChat: 'none',
};

View File

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