20
.github/workflows/build.yml
vendored
Normal file
20
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
jobs:
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: SonarCloud Scan
|
||||
uses: SonarSource/sonarcloud-github-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
}
|
||||
41
App.tsx
41
App.tsx
@@ -1,27 +1,24 @@
|
||||
import 'react-native-gesture-handler';
|
||||
import * as React from 'react';
|
||||
|
||||
import {StyleSheet, View, Platform} from 'react-native';
|
||||
import {BigbluebuttonMobile} from 'bigbluebutton-mobile-sdk';
|
||||
import { Routes } from './react-native/app/routes/component';
|
||||
import { PortalContextContainer } from './react-native/app/contexts/portals/container';
|
||||
import { LogBox } from 'react-native';
|
||||
import { Bootstrap } from './react-native/bootstrap/start/component';
|
||||
|
||||
|
||||
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<BigbluebuttonMobile
|
||||
broadcastAppBundleId="org.bigbluebutton.mobile.BigBlueButton-Broadcast"
|
||||
url="https://bigbluebutton.org"
|
||||
style={styles.bbb}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
React.useEffect(()=>{
|
||||
LogBox.ignoreAllLogs();
|
||||
}, [])
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
bbb: {
|
||||
marginTop: Platform.select({ios: 20, android: 0}),
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
return (
|
||||
<>
|
||||
|
||||
<Bootstrap/>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
||||
import com.android.build.OutputFile
|
||||
|
||||
/**
|
||||
@@ -78,9 +78,10 @@ import com.android.build.OutputFile
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
enableHermes: true, // clean and rebuild if changing
|
||||
]
|
||||
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
|
||||
/**
|
||||
@@ -189,6 +190,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-vector-icons')
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
|
||||
@@ -4,12 +4,20 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
import com.reactnativecommunity.asyncstorage.AsyncStoragePackage;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
|
||||
import com.facebook.react.bridge.JSIModulePackage; // <- add
|
||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
@@ -24,8 +32,8 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
//Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
packages.add(new MyReactNativePackage(), new VectorIconsPackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@@ -33,6 +41,11 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new ReanimatedJSIModulePackage(); // <- add
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
rootProject.name = 'BigBlueButton'
|
||||
include ':react-native-vector-icons'
|
||||
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
|
||||
include ':@react-native-async-storage_async-storage'
|
||||
project(':@react-native-async-storage_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-async-storage/async-storage/android')
|
||||
include ':react-native-gesture-handler'
|
||||
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':app'
|
||||
include ':app'
|
||||
@@ -1,3 +1,4 @@
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: ['react-native-reanimated/plugin']
|
||||
};
|
||||
|
||||
2
index.js
2
index.js
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @format
|
||||
*/
|
||||
|
||||
import 'react-native-gesture-handler';
|
||||
import {AppRegistry} from 'react-native';
|
||||
import App from './App';
|
||||
import {name as appName} from './app.json';
|
||||
|
||||
@@ -18,6 +18,22 @@
|
||||
F1F618E927BCA28B0085BEDE /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F618E827BCA28B0085BEDE /* ReplayKit.framework */; };
|
||||
F1F618EC27BCA28B0085BEDE /* SampleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1F618EB27BCA28B0085BEDE /* SampleHandler.swift */; };
|
||||
F1F618F027BCA28B0085BEDE /* BigBlueButton Broadcast.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = F1F618E727BCA28B0085BEDE /* BigBlueButton Broadcast.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
0606905B02944948BB17104F /* AntDesign.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F8C64715D8804F81B20225FA /* AntDesign.ttf */; };
|
||||
AB0C61DD6BF546C0AAFC9E4C /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7D1758C1493F48EA828278EF /* Entypo.ttf */; };
|
||||
31550F2772BF404481C8789A /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CA446FEA80BA4D3E8F05F808 /* EvilIcons.ttf */; };
|
||||
529DC832EC8C4237BE3A08FC /* Feather.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C476EA1931454EB399147EA8 /* Feather.ttf */; };
|
||||
A723DEC078834C6F8BEBD955 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D15C46CFBEDD4C6A8A724A7D /* FontAwesome.ttf */; };
|
||||
0433F9CE5A2A432A898C2AFF /* FontAwesome5_Brands.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8AA7B799D187471DBFC6D766 /* FontAwesome5_Brands.ttf */; };
|
||||
4A06D1FBDE5B49428E883010 /* FontAwesome5_Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = EFC11513C1C04CC6A061ADFC /* FontAwesome5_Regular.ttf */; };
|
||||
86C1979548D543E7AA444647 /* FontAwesome5_Solid.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3AD3ABECB8FE487080FEB2C7 /* FontAwesome5_Solid.ttf */; };
|
||||
8F9DAD740A8341F2A477C7CC /* Fontisto.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B5A6C6B34B2D453B868416B2 /* Fontisto.ttf */; };
|
||||
EECF50FCB6AA45BA9A872B70 /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 126F1909D1CE4C2EB0CFE8C3 /* Foundation.ttf */; };
|
||||
74C4F550BACA4F3991D85855 /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BC33F460718241E28F848AAC /* Ionicons.ttf */; };
|
||||
8B432F0B0C0C43FDB47806FA /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 879799A718E1458B986C16E4 /* MaterialCommunityIcons.ttf */; };
|
||||
9A86AC6C44524D28957B3C2C /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FEDEE48CF90146588BFB1F7E /* MaterialIcons.ttf */; };
|
||||
1B77DAAF12B24E7BB140B9FD /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 264CAB36471C4A52B613546B /* Octicons.ttf */; };
|
||||
A4277D7E8515496091672296 /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 28D9D2F4459D4C6CB600189C /* SimpleLineIcons.ttf */; };
|
||||
9F154B5AB41F45C9938B2E68 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A78E75D2CEC348FF82EEC375 /* Zocial.ttf */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -76,6 +92,22 @@
|
||||
F1F618E827BCA28B0085BEDE /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
|
||||
F1F618EB27BCA28B0085BEDE /* SampleHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleHandler.swift; sourceTree = "<group>"; };
|
||||
F1F618ED27BCA28B0085BEDE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
F8C64715D8804F81B20225FA /* AntDesign.ttf */ = {isa = PBXFileReference; name = "AntDesign.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
7D1758C1493F48EA828278EF /* Entypo.ttf */ = {isa = PBXFileReference; name = "Entypo.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
CA446FEA80BA4D3E8F05F808 /* EvilIcons.ttf */ = {isa = PBXFileReference; name = "EvilIcons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
C476EA1931454EB399147EA8 /* Feather.ttf */ = {isa = PBXFileReference; name = "Feather.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Feather.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
D15C46CFBEDD4C6A8A724A7D /* FontAwesome.ttf */ = {isa = PBXFileReference; name = "FontAwesome.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
8AA7B799D187471DBFC6D766 /* FontAwesome5_Brands.ttf */ = {isa = PBXFileReference; name = "FontAwesome5_Brands.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
EFC11513C1C04CC6A061ADFC /* FontAwesome5_Regular.ttf */ = {isa = PBXFileReference; name = "FontAwesome5_Regular.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
3AD3ABECB8FE487080FEB2C7 /* FontAwesome5_Solid.ttf */ = {isa = PBXFileReference; name = "FontAwesome5_Solid.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
B5A6C6B34B2D453B868416B2 /* Fontisto.ttf */ = {isa = PBXFileReference; name = "Fontisto.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
126F1909D1CE4C2EB0CFE8C3 /* Foundation.ttf */ = {isa = PBXFileReference; name = "Foundation.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
BC33F460718241E28F848AAC /* Ionicons.ttf */ = {isa = PBXFileReference; name = "Ionicons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
879799A718E1458B986C16E4 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; name = "MaterialCommunityIcons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
FEDEE48CF90146588BFB1F7E /* MaterialIcons.ttf */ = {isa = PBXFileReference; name = "MaterialIcons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
264CAB36471C4A52B613546B /* Octicons.ttf */ = {isa = PBXFileReference; name = "Octicons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
28D9D2F4459D4C6CB600189C /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; name = "SimpleLineIcons.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
A78E75D2CEC348FF82EEC375 /* Zocial.ttf */ = {isa = PBXFileReference; name = "Zocial.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -166,6 +198,7 @@
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
E233CBF5F47BEE60B243DCF8 /* Pods */,
|
||||
0B7E80F3E3D64BD78EE80539 /* Resources */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@@ -204,6 +237,30 @@
|
||||
path = "BigBlueButton Broadcast";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0B7E80F3E3D64BD78EE80539 /* Resources */ = {
|
||||
isa = "PBXGroup";
|
||||
children = (
|
||||
F8C64715D8804F81B20225FA /* AntDesign.ttf */,
|
||||
7D1758C1493F48EA828278EF /* Entypo.ttf */,
|
||||
CA446FEA80BA4D3E8F05F808 /* EvilIcons.ttf */,
|
||||
C476EA1931454EB399147EA8 /* Feather.ttf */,
|
||||
D15C46CFBEDD4C6A8A724A7D /* FontAwesome.ttf */,
|
||||
8AA7B799D187471DBFC6D766 /* FontAwesome5_Brands.ttf */,
|
||||
EFC11513C1C04CC6A061ADFC /* FontAwesome5_Regular.ttf */,
|
||||
3AD3ABECB8FE487080FEB2C7 /* FontAwesome5_Solid.ttf */,
|
||||
B5A6C6B34B2D453B868416B2 /* Fontisto.ttf */,
|
||||
126F1909D1CE4C2EB0CFE8C3 /* Foundation.ttf */,
|
||||
BC33F460718241E28F848AAC /* Ionicons.ttf */,
|
||||
879799A718E1458B986C16E4 /* MaterialCommunityIcons.ttf */,
|
||||
FEDEE48CF90146588BFB1F7E /* MaterialIcons.ttf */,
|
||||
264CAB36471C4A52B613546B /* Octicons.ttf */,
|
||||
28D9D2F4459D4C6CB600189C /* SimpleLineIcons.ttf */,
|
||||
A78E75D2CEC348FF82EEC375 /* Zocial.ttf */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
path = "";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -325,6 +382,22 @@
|
||||
files = (
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
0606905B02944948BB17104F /* AntDesign.ttf in Resources */,
|
||||
AB0C61DD6BF546C0AAFC9E4C /* Entypo.ttf in Resources */,
|
||||
31550F2772BF404481C8789A /* EvilIcons.ttf in Resources */,
|
||||
529DC832EC8C4237BE3A08FC /* Feather.ttf in Resources */,
|
||||
A723DEC078834C6F8BEBD955 /* FontAwesome.ttf in Resources */,
|
||||
0433F9CE5A2A432A898C2AFF /* FontAwesome5_Brands.ttf in Resources */,
|
||||
4A06D1FBDE5B49428E883010 /* FontAwesome5_Regular.ttf in Resources */,
|
||||
86C1979548D543E7AA444647 /* FontAwesome5_Solid.ttf in Resources */,
|
||||
8F9DAD740A8341F2A477C7CC /* Fontisto.ttf in Resources */,
|
||||
EECF50FCB6AA45BA9A872B70 /* Foundation.ttf in Resources */,
|
||||
74C4F550BACA4F3991D85855 /* Ionicons.ttf in Resources */,
|
||||
8B432F0B0C0C43FDB47806FA /* MaterialCommunityIcons.ttf in Resources */,
|
||||
9A86AC6C44524D28957B3C2C /* MaterialIcons.ttf in Resources */,
|
||||
1B77DAAF12B24E7BB140B9FD /* Octicons.ttf in Resources */,
|
||||
A4277D7E8515496091672296 /* SimpleLineIcons.ttf in Resources */,
|
||||
9F154B5AB41F45C9938B2E68 /* Zocial.ttf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<string/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
@@ -48,5 +48,24 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>AntDesign.ttf</string>
|
||||
<string>Entypo.ttf</string>
|
||||
<string>EvilIcons.ttf</string>
|
||||
<string>Feather.ttf</string>
|
||||
<string>FontAwesome.ttf</string>
|
||||
<string>FontAwesome5_Brands.ttf</string>
|
||||
<string>FontAwesome5_Regular.ttf</string>
|
||||
<string>FontAwesome5_Solid.ttf</string>
|
||||
<string>Fontisto.ttf</string>
|
||||
<string>Foundation.ttf</string>
|
||||
<string>Ionicons.ttf</string>
|
||||
<string>MaterialCommunityIcons.ttf</string>
|
||||
<string>MaterialIcons.ttf</string>
|
||||
<string>Octicons.ttf</string>
|
||||
<string>SimpleLineIcons.ttf</string>
|
||||
<string>Zocial.ttf</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -16,6 +16,12 @@ target 'BigBlueButton' do
|
||||
:hermes_enabled => false
|
||||
)
|
||||
|
||||
pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'
|
||||
|
||||
pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-async-storage/async-storage'
|
||||
|
||||
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||
|
||||
target 'BigBlueButtonTests' do
|
||||
inherit! :complete
|
||||
# Pods for testing
|
||||
|
||||
26374
package-lock.json
generated
Normal file
26374
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@@ -10,10 +10,27 @@
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native-async-storage/async-storage": "^1.16.1",
|
||||
"@react-native-community/masked-view": "^0.1.11",
|
||||
"@react-navigation/drawer": "^6.3.1",
|
||||
"@react-navigation/native-stack": "^6.5.0",
|
||||
"@types/styled-components-react-native": "^5.1.3",
|
||||
"bigbluebutton-mobile-sdk": "^0.1.6",
|
||||
"i18next": "^21.6.12",
|
||||
"i18next-browser-languagedetector": "^6.1.3",
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.67.2",
|
||||
"react-native-webview": "^11.17.2"
|
||||
"react-native-gesture-handler": "^2.2.0",
|
||||
"react-native-languages": "^3.0.2",
|
||||
"react-native-localization": "^2.3.1",
|
||||
"react-native-modalize": "^2.0.13",
|
||||
"react-native-reanimated": "^2.4.1",
|
||||
"react-native-safe-area-context": "^3.4.0",
|
||||
"react-native-screens": "^3.11.1",
|
||||
"react-native-swipe-list-view": "^3.2.9",
|
||||
"react-native-vector-icons": "^9.1.0",
|
||||
"react-native-webview": "^11.17.2",
|
||||
"styled-components": "^5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9",
|
||||
@@ -21,7 +38,9 @@
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"@types/jest": "^26.0.23",
|
||||
"@types/react-native": "^0.66.15",
|
||||
"@types/react-native-vector-icons": "^6.4.10",
|
||||
"@types/react-test-renderer": "^17.0.1",
|
||||
"@types/styled-components": "^5.1.22",
|
||||
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
||||
"@typescript-eslint/parser": "^5.7.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
|
||||
19
react-native/app/components/button/component.tsx
Normal file
19
react-native/app/components/button/component.tsx
Normal file
@@ -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 (
|
||||
<>
|
||||
<ButtonAppStyle onPress={onPress}>
|
||||
<TextButton>{children}</TextButton>
|
||||
</ButtonAppStyle>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
19
react-native/app/components/button/styles.ts
Normal file
19
react-native/app/components/button/styles.ts
Normal file
@@ -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;
|
||||
|
||||
`
|
||||
21
react-native/app/components/input/text/component.tsx
Normal file
21
react-native/app/components/input/text/component.tsx
Normal file
@@ -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 (
|
||||
<>
|
||||
<LabelInput>{props.label}</LabelInput>
|
||||
<WrapperInputText value={props.value} onChangeText={props.onChangeText} placeholder={props.placeholder}></WrapperInputText>
|
||||
</>
|
||||
)
|
||||
}
|
||||
16
react-native/app/components/input/text/styles.ts
Normal file
16
react-native/app/components/input/text/styles.ts
Normal file
@@ -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;
|
||||
|
||||
`
|
||||
19
react-native/app/contexts/portals/container.tsx
Normal file
19
react-native/app/contexts/portals/container.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react'
|
||||
import { PortalContext } from './context'
|
||||
type IPortalContext = {
|
||||
portals?: any
|
||||
setPortals?: any
|
||||
}
|
||||
|
||||
export const PortalContextContainer = ({children}: any)=>{
|
||||
const [portals, setPortals] = React.useState(0)
|
||||
const portalHook: IPortalContext = {portals, setPortals}
|
||||
return (
|
||||
<>
|
||||
<PortalContext.Provider value={portalHook}>
|
||||
{children}
|
||||
</PortalContext.Provider>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
2
react-native/app/contexts/portals/context.ts
Normal file
2
react-native/app/contexts/portals/context.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import React, { createContext } from 'react'
|
||||
export const PortalContext = createContext(false);
|
||||
11
react-native/app/contexts/portals/hook.ts
Normal file
11
react-native/app/contexts/portals/hook.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import React, { useContext } from 'react'
|
||||
import { PortalContext } from './context';
|
||||
type IPortalContext = {
|
||||
portals?: any
|
||||
setPortals?: any
|
||||
}
|
||||
|
||||
export const usePortal = (): IPortalContext=>{
|
||||
const contextOfPortals = useContext(PortalContext);
|
||||
return contextOfPortals as IPortalContext;
|
||||
}
|
||||
120
react-native/app/pages/list_portals/component.tsx
Normal file
120
react-native/app/pages/list_portals/component.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
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 { 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'
|
||||
import i18next from 'i18next'
|
||||
import { initTranslation } from '../../translations/index';
|
||||
|
||||
export const ListPortals = ({ navigation }: IListPortalsDTO)=>{
|
||||
|
||||
initTranslation()
|
||||
const icon = <FontAwesome5 color={colors.white} solid size={18} name={'plus'} />;
|
||||
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)
|
||||
|
||||
} else {
|
||||
console.log('Error: Dont Have Portals Storage')
|
||||
}
|
||||
} catch(e){
|
||||
console.log('error',e)
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(()=>{getPortals()}, [])
|
||||
|
||||
const modalizeRef = useRef<Modalize>(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 {
|
||||
console.log('Error: Dont have Portals in Storage')
|
||||
}
|
||||
} catch(e){
|
||||
console.log('error',e)
|
||||
}
|
||||
}
|
||||
|
||||
const onPress = (namePortal:string) => navigation.navigate(namePortal);
|
||||
|
||||
const Item = ({namePortal, url}: IItem)=>(
|
||||
<WrapperItemListText onPress={()=>onPress(namePortal)}>
|
||||
<ItemList bold>{namePortal}</ItemList>
|
||||
<ItemList>{url}</ItemList>
|
||||
</WrapperItemListText>
|
||||
)
|
||||
|
||||
return (
|
||||
<WrapperListContainer>
|
||||
|
||||
<ButtonOpen onPress={onOpen}>
|
||||
<TextButtonOpen>{i18next.t("mobileApp.portals.list.add.button.label")} {icon}</TextButtonOpen>
|
||||
</ButtonOpen>
|
||||
|
||||
<Modalize ref={modalizeRef} adjustToContentHeight={true}>
|
||||
<WrapperViewAdd>
|
||||
<StorePortals modalizeRef={modalizeRef as unknown as IHandles} navigation={navigation}/>
|
||||
</WrapperViewAdd>
|
||||
</Modalize>
|
||||
|
||||
{
|
||||
portals && portals.length != 0 ?
|
||||
<SwipeListView
|
||||
useFlatList={true}
|
||||
data={portals}
|
||||
renderItem={(rowData, rowMap) => <Item onPress={onPress} key={rowData.index} namePortal={rowData.item.name} url={rowData.item.url}/>}
|
||||
renderHiddenItem={ (rowData, rowMap) => (
|
||||
<DivDelete>
|
||||
<DivButtonDelete>
|
||||
<ButtonDelete onPress={()=>DeleteItem(rowData.item as IItemDelete)}>
|
||||
<FontAwesome5 size={20} color={colors.primary} name={'trash'}/>
|
||||
</ButtonDelete>
|
||||
</DivButtonDelete>
|
||||
</DivDelete>
|
||||
)}
|
||||
leftOpenValue={0}
|
||||
rightOpenValue={-80}
|
||||
disableRightSwipe={true}
|
||||
closeOnRowPress={true}
|
||||
closeOnRowOpen={true}
|
||||
onRowOpen={(rowKey, rowMap) => {
|
||||
//This timeout is recommended https://github.com/jemise111/react-native-swipe-list-view/blob/master/docs/migrating-to-flatlist.md
|
||||
setTimeout(() => {
|
||||
if(rowMap[rowKey] != undefined){
|
||||
rowMap[rowKey].closeRow()
|
||||
}
|
||||
}, 3000)
|
||||
}}
|
||||
/>
|
||||
: <TextWithoutPortal>{i18next.t("mobileApp.portals.list.empty.label")}</TextWithoutPortal>
|
||||
}
|
||||
</WrapperListContainer>
|
||||
)
|
||||
}
|
||||
123
react-native/app/pages/list_portals/styles.ts
Normal file
123
react-native/app/pages/list_portals/styles.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
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;
|
||||
|
||||
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;
|
||||
`
|
||||
14
react-native/app/pages/list_portals/types.ts
Normal file
14
react-native/app/pages/list_portals/types.ts
Normal file
@@ -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
|
||||
}
|
||||
86
react-native/app/pages/store_portals/component.tsx
Normal file
86
react-native/app/pages/store_portals/component.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
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';
|
||||
import { initTranslation } from '../../translations/index';
|
||||
import i18next from 'i18next';
|
||||
|
||||
export const StorePortals = ({navigation, modalizeRef}:IStore)=>{
|
||||
initTranslation()
|
||||
const {portals, setPortals} = usePortal()
|
||||
const [name, setName] = React.useState('');
|
||||
const [url, setUrl] = React.useState('');
|
||||
const [emptyFields, setEmptyFields] = React.useState(false);
|
||||
const [nameAlreadyUsed, setNameAlreadyUsed] = 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})
|
||||
AsyncStorage.setItem('portal', JSON.stringify(portalsStorage))
|
||||
setPortals(portalsStorage)
|
||||
modalizeRef?.current?.close();
|
||||
navigation.navigate(name)
|
||||
}
|
||||
|
||||
async function onPress(){
|
||||
//return false;
|
||||
if(!name || !url) return setEmptyFields(true)
|
||||
try{
|
||||
let portalsFilter = portals.filter((portal: {name: string, url: string})=>{
|
||||
if(portal.name != name ) return false
|
||||
return portal
|
||||
})
|
||||
if(portalsFilter.length >= 1){
|
||||
setNameAlreadyUsed(true)
|
||||
return false;
|
||||
}
|
||||
await newPortal(name, url )
|
||||
|
||||
} catch(e){
|
||||
console.log('error', e)
|
||||
await AsyncStorage.setItem('portal', JSON.stringify([]))
|
||||
newPortal(name, url )
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const textEmptyFields = ()=>(
|
||||
<>
|
||||
{
|
||||
emptyFields ?
|
||||
<TextEmptyFileds>{i18next.t("mobileApp.portals.addPortalPopup.validation.emptyFilds")}</TextEmptyFileds>
|
||||
: null
|
||||
}
|
||||
{
|
||||
nameAlreadyUsed ?
|
||||
<TextEmptyFileds>{i18next.t("mobileApp.portals.addPortalPopup.validation.portalNameAlreadyExists")}</TextEmptyFileds>
|
||||
: null
|
||||
}
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<WrapperStoreContainer>
|
||||
<WrapperStore>
|
||||
{textEmptyFields()}
|
||||
<WrapperInput>
|
||||
<InputText value={name} onChangeText={(e:any)=>setName(e)} placeholder={i18next.t("mobileApp.portals.fields.name.placeholder")} label={i18next.t("mobileApp.portals.fields.name.label")}/>
|
||||
</WrapperInput>
|
||||
<WrapperInput>
|
||||
<InputText value={url} onChangeText={(e:any)=>setUrl(e)} placeholder={i18next.t("mobileApp.portals.fields.url.placeholder")} label={i18next.t("mobileApp.portals.fields.url.label")}/>
|
||||
</WrapperInput>
|
||||
<WrapperInput>
|
||||
<ButtonApp onPress={onPress}><Text>{i18next.t("mobileApp.portals.addPortalPopup.confirm.button.label")}</Text></ButtonApp>
|
||||
</WrapperInput>
|
||||
</WrapperStore>
|
||||
</WrapperStoreContainer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
35
react-native/app/pages/store_portals/styles.ts
Normal file
35
react-native/app/pages/store_portals/styles.ts
Normal file
@@ -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}
|
||||
`
|
||||
6
react-native/app/pages/store_portals/types.ts
Normal file
6
react-native/app/pages/store_portals/types.ts
Normal file
@@ -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
|
||||
}
|
||||
58
react-native/app/routes/component.js
vendored
Normal file
58
react-native/app/routes/component.js
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
import * as React from 'react';
|
||||
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';
|
||||
import i18next from 'i18next';
|
||||
|
||||
import {
|
||||
createDrawerNavigator,
|
||||
} from '@react-navigation/drawer';
|
||||
import SdkContainer from '../../bootstrap/sdk/container';
|
||||
import { initTranslation } from '../translations/index';
|
||||
|
||||
const Drawer = createDrawerNavigator();
|
||||
export const Routes = ()=>{
|
||||
initTranslation()
|
||||
|
||||
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)
|
||||
}
|
||||
} catch(e){
|
||||
console.log('error', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(()=>{
|
||||
getPortals()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
<NavigationContainer>
|
||||
<Drawer.Navigator
|
||||
initialRouteName="Portals"
|
||||
screenOptions={{
|
||||
headerShown: false
|
||||
}}
|
||||
>
|
||||
|
||||
<Drawer.Screen name={i18next.t("mobileApp.portals.drawerNavigation.button.label")} component={ListPortals} />
|
||||
{
|
||||
portals || portals != 0 ?
|
||||
portals.map((item)=>{
|
||||
return <Drawer.Screen key={item.name} name={item.name} children={()=> (<SdkContainer url={item.url}/>)}/>
|
||||
}) : null
|
||||
}
|
||||
|
||||
</Drawer.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
3
react-native/app/routes/styles.ts
Normal file
3
react-native/app/routes/styles.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import styled from "styled-components/native"
|
||||
import { colors } from '../styles/colors';
|
||||
|
||||
15
react-native/app/styles/colors.ts
Normal file
15
react-native/app/styles/colors.ts
Normal file
@@ -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'
|
||||
}
|
||||
11
react-native/app/translations/index.ts
Normal file
11
react-native/app/translations/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import i18next from 'i18next'
|
||||
import RNLanguages from 'react-native-languages';
|
||||
import resources from './resources';
|
||||
|
||||
export const initTranslation = ()=>{
|
||||
i18next.init({
|
||||
compatibilityJSON: 'v3',
|
||||
lng: RNLanguages.language,
|
||||
resources: resources
|
||||
})
|
||||
}
|
||||
12
react-native/app/translations/resources/en-US.ts
Normal file
12
react-native/app/translations/resources/en-US.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
"mobileApp.portals.list.empty.label": "There aren't portals.",
|
||||
"mobileApp.portals.list.add.button.label": "New Portal",
|
||||
"mobileApp.portals.fields.name.label": "Portal Name",
|
||||
"mobileApp.portals.fields.name.placeholder": "BigBlueButton demo",
|
||||
"mobileApp.portals.fields.url.label": "Server URL",
|
||||
"mobileApp.portals.fields.url.placeholder": "https://demo.bigbluebutton.org",
|
||||
"mobileApp.portals.addPortalPopup.confirm.button.label": "Add Portal",
|
||||
"mobileApp.portals.drawerNavigation.button.label": "Portals",
|
||||
"mobileApp.portals.addPortalPopup.validation.emptyFilds": "Empty Fields",
|
||||
"mobileApp.portals.addPortalPopup.validation.portalNameAlreadyExists": "Name Already Exists"
|
||||
}
|
||||
11
react-native/app/translations/resources/index.ts
Normal file
11
react-native/app/translations/resources/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import enUS from "./en-US";
|
||||
import ptBR from "./pt-BR";
|
||||
|
||||
export default {
|
||||
'en-US': {
|
||||
translation: enUS
|
||||
},
|
||||
'pt-BR': {
|
||||
translation: ptBR
|
||||
}
|
||||
}
|
||||
12
react-native/app/translations/resources/pt-BR.ts
Normal file
12
react-native/app/translations/resources/pt-BR.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
"mobileApp.portals.list.empty.label": "Não há portais.",
|
||||
"mobileApp.portals.list.add.button.label": "Novo Portal",
|
||||
"mobileApp.portals.fields.name.label": "Nome do Portal",
|
||||
"mobileApp.portals.fields.name.placeholder": "BigBlueButton demo",
|
||||
"mobileApp.portals.fields.url.label": "URL do Servidor",
|
||||
"mobileApp.portals.fields.url.placeholder": "https://demo.bigbluebutton.org",
|
||||
"mobileApp.portals.addPortalPopup.confirm.button.label": "Adicionar Portal",
|
||||
"mobileApp.portals.drawerNavigation.button.label": "Portais",
|
||||
"mobileApp.portals.addPortalPopup.validation.emptyFilds": "Campos Vazios",
|
||||
"mobileApp.portals.addPortalPopup.validation.portalNameAlreadyExists": "Nome Já Existe"
|
||||
}
|
||||
32
react-native/bootstrap/sdk/container.tsx
Normal file
32
react-native/bootstrap/sdk/container.tsx
Normal file
@@ -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 (
|
||||
<>
|
||||
<View style={styles.container}>
|
||||
<BigbluebuttonMobile
|
||||
broadcastAppBundleId="org.bigbluebutton.mobile.BigBlueButton-Broadcast"
|
||||
url={url}
|
||||
style={styles.bbb}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
bbb: {
|
||||
marginTop: Platform.select({ios: 20, android: 0}),
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
13
react-native/bootstrap/start/component.js
vendored
Normal file
13
react-native/bootstrap/start/component.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import { Routes } from '../../app/routes/component';
|
||||
import { PortalContextContainer } from '../../app/contexts/portals/container';
|
||||
|
||||
|
||||
//This file is used to envolve app in contexts, libs, etc..
|
||||
export const Bootstrap = ()=>{
|
||||
return (
|
||||
<PortalContextContainer>
|
||||
<Routes/>
|
||||
</PortalContextContainer>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user