diff --git a/App.tsx b/App.tsx
index 40949c4..022972f 100644
--- a/App.tsx
+++ b/App.tsx
@@ -1,22 +1,21 @@
import 'react-native-gesture-handler';
import * as React from 'react';
-import {StyleSheet, View, Platform, SafeAreaView} from 'react-native';
-import {BigbluebuttonMobile} from 'bigbluebutton-mobile-sdk';
-import { Bootstrap } from './react-native/bootstrap/start/component';
+import { StyleSheet, Platform, LogBox } from 'react-native';
import { Routes } from './react-native/app/routes/component';
+import { PortalContextContainer } from './react-native/app/contexts/portals/container';
export default function App() {
+ React.useEffect(()=>{
+ LogBox.ignoreLogs([
+ "[react-native-gesture-handler] Seems like you\'re using an old API with gesture components, check out new Gestures system!",
+ ]);
+ })
return (
<>
+
+
>
);
}
-
-const styles = StyleSheet.create({
- bbb: {
- marginTop: Platform.select({ios: 20, android: 0}),
- flex: 1,
- },
-});
diff --git a/react-native/app/components/button/component.tsx b/react-native/app/components/button/component.tsx
new file mode 100644
index 0000000..16bfbd2
--- /dev/null
+++ b/react-native/app/components/button/component.tsx
@@ -0,0 +1,19 @@
+import React from 'react'
+import { Text } from 'react-native'
+import { TouchableOpacity } from 'react-native-gesture-handler'
+import { ButtonAppStyle, TextButton } from './styles';
+
+type IButtonApp = {
+ children?: object
+ onPress?: Function
+}
+export const ButtonApp = ({children, onPress}:IButtonApp)=>{
+ return (
+ <>
+
+ {children}
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/react-native/app/components/button/styles.ts b/react-native/app/components/button/styles.ts
new file mode 100644
index 0000000..1da892c
--- /dev/null
+++ b/react-native/app/components/button/styles.ts
@@ -0,0 +1,19 @@
+import styled from 'styled-components/native';
+import { colors } from '../../styles/colors';
+
+
+export const ButtonAppStyle = styled.TouchableHighlight`
+ height: 50px;
+ font-size: 22px;
+ background-color: ${colors.primary_light};
+ border-radius: 5px;
+ align-items: center;
+ justify-content: center;
+`
+
+export const TextButton = styled.Text`
+ font-size: 22px;
+ font-weight: bold;
+ color: #fff;
+
+`
\ No newline at end of file
diff --git a/react-native/app/components/input/text/component.tsx b/react-native/app/components/input/text/component.tsx
new file mode 100644
index 0000000..90e81e8
--- /dev/null
+++ b/react-native/app/components/input/text/component.tsx
@@ -0,0 +1,21 @@
+import React from 'react'
+import { LabelInput, WrapperInputText } from './styles';
+
+type IInputText = {
+ children?: object;
+ placeholder: string;
+ label: string;
+ onChangeText?: any,
+ value?: any
+}
+export const InputText = (props: IInputText)=>{
+
+ const {children, placeholder, label, onChangeText, value} = props
+
+ return (
+ <>
+ {props.label}
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/react-native/app/components/input/text/styles.ts b/react-native/app/components/input/text/styles.ts
new file mode 100644
index 0000000..8b40d5e
--- /dev/null
+++ b/react-native/app/components/input/text/styles.ts
@@ -0,0 +1,16 @@
+import styled from 'styled-components/native';
+
+
+export const WrapperInputText = styled.TextInput`
+ background-color: #f2f2f2;
+ padding: 10px 20px 10px 20px;
+ border-radius: 5px
+
+`
+
+export const LabelInput = styled.Text`
+ color: #fff;
+ font-size: 20px;
+ font-weight: bold;
+
+`
\ No newline at end of file
diff --git a/react-native/app/pages/list_portals/component.tsx b/react-native/app/pages/list_portals/component.tsx
new file mode 100644
index 0000000..1eead86
--- /dev/null
+++ b/react-native/app/pages/list_portals/component.tsx
@@ -0,0 +1,116 @@
+import AsyncStorage from '@react-native-async-storage/async-storage'
+import React, { useRef } from 'react'
+import { ButtonDelete, ButtonOpen, DivButtonDelete, DivDelete, ItemList, TextButtonOpen, TextItem, TextWithoutPortal, WrapperItemListText, WrapperItemListView, WrapperList, WrapperListContainer, WrapperViewAdd } from './styles'
+import { usePortal } from '../../contexts/portals/hook';
+import { Modalize } from 'react-native-modalize';
+import { Alert } from 'react-native';
+import { StorePortals } from '../store_portals/component';
+import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
+import { colors } from '../../styles/colors';
+import { SwipeListView } from 'react-native-swipe-list-view';
+import { IHandles } from 'react-native-modalize/lib/options';
+import { IItem, IItemDelete, IListPortalsDTO } from './types'
+
+export const ListPortals = ({ navigation }: IListPortalsDTO)=>{
+ const icon = ;
+ const {portals, setPortals} = usePortal()
+ async function getPortals(){
+ try{
+ let items = await AsyncStorage.getAllKeys()
+ if(items.includes('portal')){
+
+ let portalsStorage = await AsyncStorage.getItem('portal')
+ portalsStorage = JSON.parse(portalsStorage as string)
+ setPortals(portalsStorage)
+ console.log('portals', portals)
+ } else {
+ console.log('Dont Have Portals Storage')
+ }
+ } catch(e){
+ console.log('error',e)
+ }
+ }
+
+ React.useEffect(()=>{getPortals()}, [])
+
+ const modalizeRef = useRef(null);
+
+ const onOpen = () => modalizeRef.current?.open();
+
+ const DeleteItem = async (item:IItemDelete)=>{
+ try{
+ let items = await AsyncStorage.getAllKeys()
+ if(items.includes('portal')){
+
+ let portalsStorage = await AsyncStorage.getItem('portal')
+ portalsStorage = JSON.parse(portalsStorage as string)
+ const newPortalStorage = portalsStorage?.filter((portalItem: IItemDelete)=>{
+ if(item.name == portalItem.name) return false
+ return portalItem
+ })
+
+ await AsyncStorage.setItem('portal', JSON.stringify(newPortalStorage))
+ setPortals(newPortalStorage)
+ } else {
+ Alert.alert('Portals', 'Dont have Portals in Storage')
+ }
+ } catch(e){
+ console.log('error',e)
+ }
+ }
+
+ const onPress = (namePortal:string) => navigation.navigate(namePortal);
+
+ const Item = ({namePortal, url}: IItem)=>(
+ onPress(namePortal)}>
+ {namePortal}
+ {url}
+
+ )
+
+ return (
+
+
+
+ New Portal {icon}
+
+
+
+
+
+
+
+
+ {
+ portals && portals.length != 0 ?
+ - }
+ renderHiddenItem={ (rowData, rowMap) => (
+
+
+ DeleteItem(rowData.item as IItemDelete)}>
+
+
+
+
+ )}
+ leftOpenValue={0}
+ rightOpenValue={-80}
+ disableRightSwipe={true}
+ closeOnRowPress={true}
+ closeOnRowOpen={true}
+ onRowOpen={(rowKey, rowMap) => {
+ setTimeout(() => {
+ if(rowMap[rowKey] != undefined){
+ rowMap[rowKey].closeRow()
+ }
+ }, 3000)
+ }}
+ />
+ : There aren't Portals
+ }
+
+ )
+}
\ No newline at end of file
diff --git a/react-native/app/pages/list_portals/styles.ts b/react-native/app/pages/list_portals/styles.ts
new file mode 100644
index 0000000..13239b2
--- /dev/null
+++ b/react-native/app/pages/list_portals/styles.ts
@@ -0,0 +1,125 @@
+import styled from 'styled-components/native'
+import { colors } from '../../styles/colors';
+import { TouchableOpacity } from 'react-native-gesture-handler';
+import { SwipeListView } from 'react-native-swipe-list-view';
+
+
+export const WrapperListContainer = styled.View`
+ background-color: ${colors.secundary};
+ flex: 1 ;
+ justify-content: center;
+ align-items: center;
+ padding: 20px;
+`;
+
+export const WrapperList = styled.FlatList`
+ background-color: ${colors.primary};
+ width: 95%;
+
+ border-radius: 10px;
+`
+
+export const WrapperItemListText = styled.TouchableOpacity`
+
+ width: 300px;
+ padding: 5px;
+ margin: 3% auto;
+ height: 80px;
+ background-color: ${colors.primary_light};
+ border-radius: 10px;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+`
+export const WrapperItemListView = styled.View`
+ display: flex;
+ flex: 1;
+ background-color: black;
+
+ padding: 10px;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ height: 100px;
+ width: 200px;
+
+`
+
+export const ItemList = styled.Text`
+ color: #fff;
+ padding: 2px;
+ font-size: 16px;
+
+ font-weight: ${(props)=>(props.bold ? 'bold': 'normal')};
+
+`
+
+
+export const TextItem = styled.Text`
+ font-size: 18px;
+`
+
+export const WrapperViewAdd = styled.View`
+ background-color: ${colors.primary};
+ margin: 70px 0px 0px 0px;
+
+`
+
+export const ButtonOpen = styled.TouchableOpacity`
+ padding: 10px;
+ background-color: ${colors.primary};
+ width: 90%;
+ margin: 10px;
+ border-radius: 10px;
+
+ align-items: center;
+ justify-content: center;
+
+
+`
+
+export const TextButtonOpen = styled.Text`
+ color: #fff;
+ font-size: 20px;
+ font-weight: bold;
+`
+
+
+export const TextWithoutPortal = styled.Text`
+ color: ${colors.primary};
+ font-size: 20px;
+
+`
+
+export const ButtonDelete = styled.TouchableOpacity`
+ background-color: ${colors.white};
+ border-radius: 10px;
+ margin: 3% auto;
+ width: 100%;
+ height: 80px;
+ //left: 20px;
+
+
+ justify-content: center;
+ align-items: center;
+
+ flex-direction: row;
+
+`
+
+export const DivButtonDelete = styled.View`
+ width: 100px;
+ align-items: center;
+ justify-content: center;
+ margin: 3% 0px;
+ align-content: center;
+ justify-items: center;
+
+
+`
+
+export const DivDelete = styled.View`
+ width: 300px;
+ justify-content: flex-end;
+ align-items: flex-end;
+`
\ No newline at end of file
diff --git a/react-native/app/pages/list_portals/types.ts b/react-native/app/pages/list_portals/types.ts
new file mode 100644
index 0000000..721fdf8
--- /dev/null
+++ b/react-native/app/pages/list_portals/types.ts
@@ -0,0 +1,14 @@
+import { DrawerScreenProps } from '@react-navigation/drawer';
+export type IItem = {
+ url: string;
+ namePortal: string;
+}
+
+export type IListPortalsDTO = {
+ navigation: DrawerScreenProps
+}
+
+export type IItemDelete = {
+ name: string;
+ url: string
+}
\ No newline at end of file
diff --git a/react-native/app/pages/store_portals/component.tsx b/react-native/app/pages/store_portals/component.tsx
new file mode 100644
index 0000000..c772ff6
--- /dev/null
+++ b/react-native/app/pages/store_portals/component.tsx
@@ -0,0 +1,71 @@
+import React from 'react'
+import { InputText } from '../../components/input/text/component';
+import { TextEmptyFileds, WrapperInput, WrapperStore, WrapperStoreContainer } from './styles';
+import { Text } from 'react-native';
+import { ButtonApp } from '../../components/button/component';
+import AsyncStorage from '@react-native-async-storage/async-storage';
+import { usePortal } from '../../contexts/portals/hook';
+import { IStore } from './types';
+
+export const StorePortals = ({navigation, modalizeRef}:IStore)=>{
+ const {portals, setPortals} = usePortal()
+ const [name, setName] = React.useState('');
+ const [url, setUrl] = React.useState('');
+ const [emptyFields, setEmptyFields] = React.useState(false);
+
+ async function newPortal(name:string, url:string){
+ let portalsStorage;
+ portalsStorage = await AsyncStorage.getItem('portal')
+ portalsStorage = portalsStorage ? JSON.parse(portalsStorage) : null
+ portalsStorage.push({name, url})
+ await AsyncStorage.setItem('portal', JSON.stringify(portalsStorage))
+ setPortals(portalsStorage)
+ setTimeout(()=>{
+ modalizeRef?.current?.close();
+ }, 500)
+
+ navigation.navigate(name)
+ }
+
+ async function onPress(){
+
+ if(!name || !url) return setEmptyFields(true)
+ try{
+ await newPortal(name, url )
+ } catch(e){
+ console.log('error', e)
+ await AsyncStorage.setItem('portal', JSON.stringify([]))
+ newPortal(name, url )
+ return null
+ }
+ }
+
+ const textEmptyFields = ()=>(
+ <>
+ {
+ emptyFields ?
+ Empty Fields
+ : null
+ }
+ >
+ )
+
+ return (
+ <>
+
+
+ {textEmptyFields()}
+
+ setName(e)} placeholder='Demo Server' label='Portal Name'/>
+
+
+ setUrl(e)} placeholder='https://bigbluebutton.org/' label='Server URL'/>
+
+
+ Add
+
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/react-native/app/pages/store_portals/styles.ts b/react-native/app/pages/store_portals/styles.ts
new file mode 100644
index 0000000..ed708d6
--- /dev/null
+++ b/react-native/app/pages/store_portals/styles.ts
@@ -0,0 +1,35 @@
+import styled from 'styled-components/native'
+import { colors } from '../../styles/colors';
+
+export const WrapperStoreContainer = styled.View`
+ background-color: ${colors.white};
+ flex: 1 ;
+ justify-content: center;
+ align-items: center;
+`;
+
+
+
+export const WrapperStore = styled.View`
+ background-color: ${colors.primary};
+ width: 80%;
+ height: 95%;
+ border-radius: 10px;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ padding: 5px;
+ padding-top: 20px;
+`
+
+
+export const WrapperInput = styled.View`
+ background-color: transparent;
+ width: 80%;
+ height: 100px;
+ margin: 20px;
+
+`
+export const TextEmptyFileds = styled.Text`
+ color: ${colors.danger}
+`
\ No newline at end of file
diff --git a/react-native/app/pages/store_portals/types.ts b/react-native/app/pages/store_portals/types.ts
new file mode 100644
index 0000000..a137346
--- /dev/null
+++ b/react-native/app/pages/store_portals/types.ts
@@ -0,0 +1,6 @@
+import { Modalize } from 'react-native-modalize';
+import { IHandles } from 'react-native-modalize/lib/options';
+export type IStore = {
+ navigation?: any;
+ modalizeRef?: IHandles
+}
\ No newline at end of file
diff --git a/react-native/app/routes/component.js b/react-native/app/routes/component.js
index de02eef..03f129c 100644
--- a/react-native/app/routes/component.js
+++ b/react-native/app/routes/component.js
@@ -1,37 +1,70 @@
import * as React from 'react';
-import { Button, View } from 'react-native';
-import { createDrawerNavigator } from '@react-navigation/drawer';
+import { Alert } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { ListPortals } from '../pages/list_portals/component';
+import { usePortal } from '../contexts/portals/hook';
+import AsyncStorage from '@react-native-async-storage/async-storage';
-function NotificationsScreen({ navigation }) {
- return (
-
-
- );
-}
-
-function Test(){
- return (
-
-
-
- )
-}
+import {
+ createDrawerNavigator,
+} from '@react-navigation/drawer';
+import SdkContainer from '../../bootstrap/sdk/container';
const Drawer = createDrawerNavigator();
export const Routes = ()=>{
- return (
-
-
-
-
- {['1','2'].map((item)=>{
- return
- })}
-
-
+
+ const {portals, setPortals} = usePortal()
+ async function getPortals(){
+ try{
+ let items = await AsyncStorage.getAllKeys()
+ if(items.includes('portal')){
+ let portalsStorage = await AsyncStorage.getItem('portal')
+ portalsStorage = JSON.parse(portalsStorage)
+ setPortals(portalsStorage)
+ } else {
+ Alert.alert('Portals', 'Dont have Portals in Storage')
+ }
+ } catch(e){
+ console.log('error', e)
+ return null
+ }
+ }
+
+ React.useEffect(()=>{
+ getPortals()
+ }, [])
+
+ return (
+
+
+
+
+
+ {
+ portals || portals != 0 ?
+ portals.map((item)=>{
+ return ()}/>
+ }) : null
+ }
+
+
+
);
+}
+
+
+export const RoutesContainer = ()=>{
+
+ return(
+
+ <>
+
+ >
+ )
}
\ No newline at end of file
diff --git a/react-native/app/routes/styles.ts b/react-native/app/routes/styles.ts
new file mode 100644
index 0000000..7e52db3
--- /dev/null
+++ b/react-native/app/routes/styles.ts
@@ -0,0 +1,3 @@
+import styled from "styled-components/native"
+import { colors } from '../styles/colors';
+
diff --git a/react-native/app/styles/colors.ts b/react-native/app/styles/colors.ts
new file mode 100644
index 0000000..3a211ed
--- /dev/null
+++ b/react-native/app/styles/colors.ts
@@ -0,0 +1,15 @@
+interface IColors {
+ primary: string
+ secundary: string
+ primary_light: string
+ white: string
+ danger: string
+}
+
+export const colors: IColors = {
+ primary: '#06172A',
+ secundary: '#F3F6F9',
+ primary_light: '#176DC8',
+ white: '#FFF',
+ danger: '#DF2621'
+}
\ No newline at end of file
diff --git a/react-native/bootstrap/sdk/container.tsx b/react-native/bootstrap/sdk/container.tsx
new file mode 100644
index 0000000..9d9e4c0
--- /dev/null
+++ b/react-native/bootstrap/sdk/container.tsx
@@ -0,0 +1,32 @@
+import { BigbluebuttonMobile } from 'bigbluebutton-mobile-sdk'
+import React from 'react'
+import {StyleSheet, View, Platform} from 'react-native';
+type ISdkContainer = {
+ url: string
+ props?: any
+}
+export default function SdkContainer({url, ...props}: ISdkContainer){
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ flexDirection: 'row',
+ },
+ bbb: {
+ marginTop: Platform.select({ios: 20, android: 0}),
+ flex: 1,
+ },
+ });
\ No newline at end of file
diff --git a/react-native/bootstrap/start/component.js b/react-native/bootstrap/start/component.js
index 03db78a..5e6b5d1 100644
--- a/react-native/bootstrap/start/component.js
+++ b/react-native/bootstrap/start/component.js
@@ -1,5 +1,4 @@
import React from 'react'
-import { Text, View } from 'react-native'
import { GestureHandlerRootView } from 'react-native-gesture-handler'
import { Routes } from '../../app/routes/component';
@@ -7,11 +6,10 @@ import { Routes } from '../../app/routes/component';
//This archive is used to envolve app in contexts, libs, etc..
export const Bootstrap = ()=>{
return (
- <>
-
- a
-
-
+ <>
+
+
+
>
)
}
\ No newline at end of file