diff --git a/app/views/HomeView/data.tsx b/app/views/HomeView/data.tsx new file mode 100644 index 000000000..8b1df07fc --- /dev/null +++ b/app/views/HomeView/data.tsx @@ -0,0 +1,71 @@ +import {SizeTypes} from './interfaces' + +export const largeTiles = [ + { + title: 'Peer Supporter Library', + screen: 'ProfileLibraryNavigator', + size: SizeTypes.LARGE, + color: 'mossGreen', + icon: require('../../static/images/peer-supporter-solid.png'), + disabled: false + }, + { + title: '24/7 Chat Room', + screen: '24Chat', + size: SizeTypes.LARGE, + color: 'magenta', + icon: require('../../static/images/24-7-solid.png'), + disabled: false + } +]; + +export const smallTiles = [ + { + title: 'Discussion Boards', + screen: 'DiscussionStackNavigator', + size: SizeTypes.SMALL, + color: 'dreamBlue', + icon: require('../../static/images/discussion-solid.png'), + disabled: false + }, + { + title: 'Virtual Happy Hour', + screen: 'VirtualHappyHour', + size: SizeTypes.SMALL, + color: 'creamsicleYellow', + icon: require('../../static/images/happy-hour-solid.png'), + disabled: true + }, + { + title: 'Calendar', + screen: 'Calendar', + size: SizeTypes.SMALL, + color: 'pink', + icon: require('../../static/images/calendar-solid.png'), + disabled: true + }, + { + title: 'Direct Messaging', + screen: 'ChatsStackNavigator', + size: SizeTypes.SMALL, + color: 'pink', + icon: require('../../static/images/messaging-solid.png'), + disabled: false + }, + { + title: 'Tech Support', + screen: 'TechSupport', + size: SizeTypes.SMALL, + color: 'magenta', + icon: require('../../static/images/support-solid.png'), + disabled: true + }, + { + title: 'Settings', + screen: 'SettingsStackNavigator', + size: SizeTypes.SMALL, + color: 'creamsicleYellow', + icon: require('../../static/images/settings-solid.png'), + disabled: false + } +]; diff --git a/app/views/HomeView/helpers.tsx b/app/views/HomeView/helpers.tsx new file mode 100644 index 000000000..b120e9545 --- /dev/null +++ b/app/views/HomeView/helpers.tsx @@ -0,0 +1,61 @@ +import { Q } from '@nozbe/watermelondb'; +import { Subscription } from 'rxjs'; + +import database from '../../lib/database'; +import { TSubscriptionModel } from '../../definitions'; +import { goRoom } from '../../lib/methods/helpers/goRoom'; + +const CHAT247ROOMID = '24-7-chatroom'; + +let querySubscription: Subscription; + +const unsubscribeQuery = () => { + if (querySubscription && querySubscription.unsubscribe) { + querySubscription.unsubscribe(); + } +}; + +export const get247Chat = async (): Promise => { + let chatRoom: TSubscriptionModel | undefined; + + unsubscribeQuery(); + + const db = database.active; + + const defaultWhereClause = [Q.where('archived', false), Q.where('open', true)] as (Q.WhereDescription | Q.SortBy)[]; + defaultWhereClause.push(Q.experimentalSortBy('room_updated_at', Q.desc)); + + const observable = await db + .get('subscriptions') + .query(...defaultWhereClause) + .observeWithColumns(['on_hold']); + + const subscriptionPromise = new Promise((resolve, reject) => { + querySubscription = observable.subscribe( + data => { + chatRoom = data.find(chat => chat.name === CHAT247ROOMID); + resolve(); + }, + error => { + reject(error); + } + ); + }); + + await subscriptionPromise; + return chatRoom; +}; + +export const navigateTo247Chat = async (Navigation: any, isMasterDetail: boolean) => { + if (Navigation) { + try { + const chatRoom = await get247Chat(); + await Navigation.navigate('ChatsStackNavigator', { + screen: 'RoomListView' + }); + goRoom({ item: chatRoom, isMasterDetail }); + } catch (error) { + console.error('error', error); + } + } +}; diff --git a/app/views/HomeView/index.tsx b/app/views/HomeView/index.tsx new file mode 100644 index 000000000..6d872bab5 --- /dev/null +++ b/app/views/HomeView/index.tsx @@ -0,0 +1,109 @@ +import React, { useEffect } from 'react'; +import { ScrollView, Text, View, Image } from 'react-native'; +import { useSelector } from 'react-redux'; +import Touchable from 'react-native-platform-touchable'; +import { useNavigation } from '@react-navigation/native'; +import { StackNavigationProp } from '@react-navigation/stack'; + +import { getUserSelector } from '../../selectors/login'; +import { LISTENER } from '../../containers/Toast'; +import StatusBar from '../../containers/StatusBar'; +import * as HeaderButton from '../../containers/HeaderButton'; +import EventEmitter from '../../lib/methods/helpers/events'; +import { themes } from '../../lib/constants'; +import { + // useTheme, + withTheme +} from '../../theme'; +import { IApplicationState } from '../../definitions'; +import * as tileData from './data'; +import * as allStyles from './styles'; +import { Tileprops } from './interfaces'; +import { navigateTo247Chat } from './helpers'; +import Avatar from '../../containers/Avatar/Avatar'; +import Navigation from '../../lib/navigation/appNavigation'; + +const HomeView: React.FC = () => { + const navigation = useNavigation>(); + const user = useSelector((state: IApplicationState) => getUserSelector(state)); + const isMasterDetail = useSelector((state: IApplicationState) => state.app.isMasterDetail); + const server = useSelector((state: IApplicationState) => state.server.server); + const userName = user?.name || ''; + // const { theme } = useTheme(); + const theme = 'light'; + + const { largeTiles, smallTiles } = tileData; + const { styles, createTileStyles } = allStyles; + + useEffect(() => { + navigation.setOptions({ title: '', headerStyle: { shadowColor: 'transparent' } }); + if (!isMasterDetail) { + navigation.setOptions({ + headerLeft: () => , + headerRight: () => ( + + { + EventEmitter.emit(LISTENER, { message: `Open search` }); + }} + /> + navigation.navigate('ProfileStackNavigator')}> + {userName ? ( + + ) : ( + <> + )} + + + ) + }); + } + }); + + const homeViewTile = ({ icon, title, size, screen, color, disabled = false }: Tileprops, index: number) => { + const tileStyles = createTileStyles({ + size, + color: themes[theme][color] + }); + const imageStyle = size === 'large' ? tileStyles.largeImage : tileStyles.smallImage; + + return ( + { + if (screen) { + if (screen === '24Chat') { + navigateTo247Chat(Navigation, isMasterDetail); + return; + } + navigation.navigate(screen); + } + }} + style={{ opacity: disabled ? 0.4 : 1, ...tileStyles.tile }} + key={index} + disabled={disabled} + activeOpacity={0.6} + > + + + + + {title} + + + ); + }; + + return ( + + + + {`Welcome ${userName},`} + {largeTiles.map((item, index) => homeViewTile(item, index))} + {smallTiles.map((item, index) => homeViewTile(item, index))} + + + ); +}; + +export default withTheme(HomeView); diff --git a/app/views/HomeView/interfaces.tsx b/app/views/HomeView/interfaces.tsx new file mode 100644 index 000000000..1d8d605a0 --- /dev/null +++ b/app/views/HomeView/interfaces.tsx @@ -0,0 +1,15 @@ +import { TColors } from '../../theme'; + +export enum SizeTypes { + SMALL = 'small', + LARGE = 'large' +} + +export interface Tileprops { + icon: any; + title: string; + size: SizeTypes; + screen: string; + color: TColors; + disabled?: boolean; +} diff --git a/app/views/HomeView/styles.ts b/app/views/HomeView/styles.ts new file mode 100644 index 000000000..5f7b3f333 --- /dev/null +++ b/app/views/HomeView/styles.ts @@ -0,0 +1,65 @@ +import { StyleSheet } from 'react-native'; + +import { colors } from '../../lib/constants'; + +export const styles = StyleSheet.create({ + mainContainer: { + backgroundColor: colors.light.backgroundColor, + flex: 1, + padding: 20 + }, + title: { + fontSize: 24, + lineHeight: 29, + fontWeight: '600' + }, + tileContainer: { + flexDirection: 'row', + justifyContent: 'space-around', + flexWrap: 'wrap' + }, + profileImageContainer: { + marginRight: 20 + }, + profileImage: { + // width: 24, + // height: 24, + borderRadius: 12, + // backgroundColor: 'red' + } +}); + +export const createTileStyles = ({ size, color }: { size?: 'small' | 'large'; color: string }) => + StyleSheet.create({ + tile: { + width: size === 'small' ? 96 : 130, + marginVertical: 16, + alignItems: 'center' + }, + tileContent: { + alignItems: 'center' + }, + imageContainer: { + justifyContent: 'center', + alignItems: 'center', + width: size === 'small' ? 80 : 130, + height: size === 'small' ? 80 : 130, + borderRadius: size === 'small' ? 10 : 65, + backgroundColor: color + }, + text: { + fontSize: 16, + lineHeight: 19, + textAlign: 'center', + fontWeight: '500', + marginTop: size === 'small' ? 14 : 16 + }, + smallImage: { + width: 45, + height: 45 + }, + largeImage: { + width: 75, + height: 75 + } + });