Compare commits

..

128 commits

Author SHA1 Message Date
4228a5555d Added update notes 2020-05-10 13:41:12 +02:00
41abbfb03f Added vote image 2020-05-10 12:42:00 +02:00
cbc1e88a37 Fixed webview crash on android 9+ 2020-05-02 22:46:44 +02:00
0c9b70998d Fixed planex theme change and removed unused planex controls 2020-05-01 21:41:08 +02:00
d8f7dc72d4 Removed console.log 2020-05-01 17:38:57 +02:00
ddfac76f4e Updated libraries 2020-05-01 17:36:04 +02:00
097ea5379a use react native community async storage 2020-05-01 16:57:37 +02:00
e96f55d142 Removed unused icons and changed android activity background 2020-05-01 16:43:20 +02:00
2dab27de22 Further performance improvements 2020-05-01 16:38:57 +02:00
3d0e03cb9d Removed expo from used technologies 2020-05-01 16:36:11 +02:00
854e03e893 Show settings and about buttons by default 2020-05-01 16:35:23 +02:00
885bf239d8 Changed icons color 2020-05-01 16:32:23 +02:00
9e4e340302 Fixed modal displaying negative remaining times 2020-05-01 16:18:55 +02:00
ea16a1f50f Improved planex group search performance 2020-05-01 16:13:46 +02:00
0b7191887d Improved settings screen elements 2020-05-01 15:59:47 +02:00
517e75f4b9 Fixed accordion auto closing on setting selection 2020-05-01 11:10:26 +02:00
cb522466c7 Fixed tab bar icon not updating on theme change 2020-05-01 11:06:37 +02:00
eda9edd21c Updated icons 2020-05-01 11:03:46 +02:00
b83b142942 Fixed crash 2020-04-30 23:05:59 +02:00
65eb4dd77b Added notification translation 2020-04-30 22:49:25 +02:00
aa2fad344a Improved notification activation on corner cases 2020-04-30 22:38:33 +02:00
1835fcadf9 Added tests for proxiwash util functions 2020-04-30 22:16:35 +02:00
7fb4de3c5b Augmented app delegate to use ios notifications 2020-04-30 18:13:39 +02:00
9882873861 added ios notifications dependency 2020-04-30 18:08:36 +02:00
e5299ed9c3 Moved util functions in own file 2020-04-30 14:58:12 +02:00
087331258a Added local notifications on android 2020-04-30 14:04:31 +02:00
f8ded811f4 Fixed ios build crash 2020-04-29 21:09:30 +02:00
7e4c385083 Removed unimodules from ios 2020-04-29 17:52:25 +02:00
f89aa2d2ff Load only used icon font 2020-04-29 17:43:18 +02:00
a4bbd84136 Completely removed expo from android project 2020-04-29 13:04:59 +02:00
8daa2641dc Use react native camera instead of expo one 2020-04-29 11:34:52 +02:00
4f49b48fc5 Disabled some expo unimodules 2020-04-29 10:10:36 +02:00
ca6f66c661 Use react native vector icons instead of expo implementation 2020-04-29 08:49:09 +02:00
660bbd856a Fixed default proximo sort order 2020-04-28 22:16:14 +02:00
aeb7c438b1 Changed feedback buttons style 2020-04-28 20:30:58 +02:00
252272cd55 Changed default transitions 2020-04-28 20:22:55 +02:00
070d6beb83 Improved accordion performance 2020-04-28 20:18:52 +02:00
1e0cc867b8 Forced android to allow http traffic 2020-04-28 19:06:22 +02:00
35141eaa21 Workaround android 9+ crash on planex group selection screen navigation 2020-04-28 15:33:37 +02:00
dfa7d2220f Fixed debug not dynamically activating 2020-04-28 10:59:55 +02:00
50a5f087b6 Fixed banner content offset 2020-04-28 10:57:36 +02:00
e1014a173e Merge branch 'bare' of https://git.etud.insa-toulouse.fr/vergnet/application-amicale into bare 2020-04-28 08:32:19 +02:00
2c8356f9d3 Improved splash screen 2020-04-28 08:31:11 +02:00
470ec8bcdb Updated console.log usage 2020-04-28 08:24:55 +02:00
987bbf9113 Updated permissions 2020-04-28 08:22:31 +02:00
9980e78918 use react native keystore instead of expo secure store 2020-04-27 22:55:24 +02:00
2b620fdc2d Updated script 2020-04-27 22:07:42 +02:00
bb5d453a2b Replaced expo permissions by react native one 2020-04-27 22:05:36 +02:00
b784a5d164 Replaced expo localization by react native one 2020-04-27 21:47:49 +02:00
6ca2ca67a5 Replaced expo linear gradient by react native one 2020-04-27 21:40:30 +02:00
7181579481 Use react native Linking instead of expo 2020-04-27 21:30:12 +02:00
a56d2978e1 Merge branch 'bare' of https://git.etud.insa-toulouse.fr/vergnet/application-amicale into bare 2020-04-27 08:48:01 +02:00
15733c2019 edited xcode project 2020-04-27 08:47:44 +02:00
cb5fac940b Added android splash screen 2020-04-26 23:05:27 +02:00
19d5663210 Added ios linking code 2020-04-26 22:35:34 +02:00
6607d9206b Fixed qr code crash 2020-04-26 22:33:43 +02:00
8a1f0d110b Added ios icons 2020-04-26 20:11:14 +02:00
2d9eed6d95 fixed build crash 2020-04-26 12:45:35 +02:00
31d68de2f8 loaded xcode project 2020-04-26 00:11:46 +02:00
aee51d5dfb Removed expo updates specific ios code 2020-04-25 22:59:53 +02:00
f1ed672824 Fixed intro statusbar color on android 2020-04-25 18:10:20 +02:00
5048f979a7 Fixed intro image 2020-04-25 17:54:14 +02:00
51ffb15365 Removed unnecessary permissions in release build 2020-04-25 17:29:02 +02:00
82f208b366 Fixed crash on club screen 2020-04-25 16:49:13 +02:00
13b9e8dad0 Fixed crash on about screen 2020-04-25 16:39:07 +02:00
9e904bc2d5 Updated android icon 2020-04-25 16:23:55 +02:00
04ad4901c1 Ejected to bare 2020-04-25 15:09:08 +02:00
a779a3049e Changed contact mail 2020-04-23 15:29:58 +02:00
cca091beef Updated Changelog.md to 2.0.0 (oupsi forgot) 2020-04-23 15:27:24 +02:00
8c9e068faa Added bug report button on home screen 2020-04-23 15:19:34 +02:00
9e251ad150 Replaced bug report modal by a screen 2020-04-23 15:06:19 +02:00
eb71316995 Moved services related files into services folder 2020-04-23 14:07:42 +02:00
03d57e91d9 Updated about screen 2020-04-23 14:05:39 +02:00
24106e9791 Fixed recursive import warning 2020-04-23 13:49:58 +02:00
7162978503 Fixed ios header back button title 2020-04-23 11:25:02 +02:00
b7e1d56ff6 Fixed ios warnings 2020-04-23 11:23:38 +02:00
f617dba1e6 Fixed ios style 2020-04-23 11:19:35 +02:00
0267ff70ce Improved error messages 2020-04-23 11:05:35 +02:00
2fc2db39c7 Fixed planning url link and added loading dialog on link scanned 2020-04-23 10:38:43 +02:00
f8363353c3 Changed home button click effect and added tetris on long press 2020-04-23 10:10:52 +02:00
0410499593 Removed paging as it caused problems on some screen sizes 2020-04-23 08:51:22 +02:00
43a3d64deb Made collapsible header opaque 2020-04-23 08:46:22 +02:00
c4337b13cb Added contact link 2020-04-23 08:39:07 +02:00
b7d6c98025 Updated default screen transition 2020-04-23 08:06:13 +02:00
033bb388fd Moved collapsible stack creating in own file 2020-04-23 08:02:34 +02:00
56effeaaf9 Moved amicale contact to services header button 2020-04-22 23:14:04 +02:00
b83e748d29 Fixed club information page 2020-04-22 21:40:04 +02:00
65ba27ea26 Fixed navigation white background 2020-04-22 21:37:40 +02:00
3a3cf200f5 Moved services screen outside of tab navigation for improved usability 2020-04-22 21:33:05 +02:00
3bac6d6662 Enabled horizontal paging 2020-04-22 20:44:05 +02:00
4c4f968e25 Updated settings default screen 2020-04-22 20:08:46 +02:00
0f0b63bdd7 Fixed broken reset button 2020-04-22 19:44:30 +02:00
ac9709d666 Updated translations 2020-04-22 18:54:34 +02:00
f7e66b1251 Reduced splash size 2020-04-22 18:46:54 +02:00
38a5761f23 Removed drawer related files and renamed navigator for more coherence 2020-04-22 18:36:57 +02:00
faa174b8f1 Moved proximo and proxiwash images on the web 2020-04-22 18:34:23 +02:00
030cf7b795 Fixed text alignement 2020-04-22 15:20:10 +02:00
e8fc8b79dc Updated translations 2020-04-22 15:19:00 +02:00
62db99cac7 Reduced image size 2020-04-22 14:58:08 +02:00
87f0c01024 Redirect to service screen index 2020-04-22 12:29:36 +02:00
b5d2f686dd Fixed image alignement 2020-04-22 12:28:35 +02:00
9207d02c2a Improved dashboard amicale item 2020-04-22 12:20:55 +02:00
b31269586b Use card items when viewing the section 2020-04-22 12:08:23 +02:00
fc7754588f Improved login flow 2020-04-22 11:49:22 +02:00
92fce1d425 Fixed login redirection error 2020-04-22 11:35:01 +02:00
0c71a78b22 Enabled collapsing header in login screen 2020-04-22 11:18:43 +02:00
c9b8a6e2ca Added login/logout icon on home 2020-04-22 11:12:24 +02:00
3f945fca7a Added services section title to match current section 2020-04-22 10:49:54 +02:00
49fa8a82e3 Improved readability 2020-04-22 10:47:18 +02:00
524dd5362a Changed sections icons 2020-04-22 10:45:31 +02:00
443f179f1d Changed cards to basic view 2020-04-22 10:42:02 +02:00
8eaa46b900 Added amicale section 2020-04-22 10:14:37 +02:00
926515213d Improved code readability 2020-04-22 09:54:40 +02:00
bbe343da3b Render services in sections 2020-04-22 09:37:31 +02:00
8fca2eac12 Moved tab order 2020-04-22 08:50:47 +02:00
20cff1aeb1 Fixed ref warning 2020-04-21 20:05:21 +02:00
96ed75ac72 Added collapsible header to profile 2020-04-21 20:02:17 +02:00
b151a8ff6f Updated translations and fixed filenames 2020-04-21 19:54:53 +02:00
1f0ada3b24 Improved project structure 2020-04-21 19:48:44 +02:00
78634b0c5d Added more websites 2020-04-21 19:46:33 +02:00
e6835b0d6f Improved dashboard interaction 2020-04-21 19:40:40 +02:00
03c4a43e58 Moved all services in same tab and planning in its own 2020-04-21 19:30:13 +02:00
0b17a35856 Improved selection screens 2020-04-21 15:17:00 +02:00
77cc5d8746 Changed tab order and stacks 2020-04-21 12:59:36 +02:00
3b977bdf64 Added badge animation 2020-04-21 10:38:38 +02:00
dca27e091c Always show home content even if an error occurred 2020-04-21 10:35:04 +02:00
dc57cbd7bd Improved dashboard items placement 2020-04-21 10:22:32 +02:00
c37e052aa2 Removed drawer and put all links in home screen 2020-04-21 09:50:13 +02:00
145 changed files with 4746 additions and 2179 deletions

68
.gitignore vendored
View file

@ -10,8 +10,74 @@ web-build/
web-report/
/.expo-shared/
/package-lock.json
/passwords.json
!/.idea/
/.idea/*
!/.idea/runConfigurations
# The following contents were automatically generated by expo-cli during eject
# ----------------------------------------------------------------------------
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# BUCK
buck-out/
\.buckd/
*.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots
# Bundle artifacts
*.jsbundle
# CocoaPods
/ios/Pods/
# Expo
.expo/*
/android/gradle.properties

35
App.js
View file

@ -1,26 +1,25 @@
// @flow
import * as React from 'react';
import {Platform, StatusBar, YellowBox} from 'react-native';
import {Platform, StatusBar, View, YellowBox} from 'react-native';
import LocaleManager from './src/managers/LocaleManager';
import AsyncStorageManager from "./src/managers/AsyncStorageManager";
import CustomIntroSlider from "./src/components/Overrides/CustomIntroSlider";
import {AppLoading} from 'expo';
import type {CustomTheme} from "./src/managers/ThemeManager";
import ThemeManager from './src/managers/ThemeManager';
import {NavigationContainer} from '@react-navigation/native';
import DrawerNavigator from './src/navigation/DrawerNavigator';
import {initExpoToken} from "./src/utils/Notifications";
import MainNavigator from './src/navigation/MainNavigator';
import {Provider as PaperProvider} from 'react-native-paper';
import AprilFoolsManager from "./src/managers/AprilFoolsManager";
import Update from "./src/constants/Update";
import ConnectionManager from "./src/managers/ConnectionManager";
import URLHandler from "./src/utils/URLHandler";
import {setSafeBounceHeight} from "react-navigation-collapsible";
import {enableScreens} from 'react-native-screens';
import SplashScreen from 'react-native-splash-screen'
// Native optimizations https://reactnavigation.org/docs/react-native-screens
enableScreens();
// Crashes app when navigating away from webview on android 9+
// enableScreens(true);
YellowBox.ignoreWarnings([ // collapsible headers cause this warning, just ignore as it is not an issue
@ -60,7 +59,6 @@ export default class App extends React.Component<Props, State> {
constructor() {
super();
LocaleManager.initTranslations();
// SplashScreen.preventAutoHide();
this.navigatorRef = React.createRef();
this.defaultHomeRoute = null;
this.defaultHomeData = {};
@ -120,7 +118,8 @@ export default class App extends React.Component<Props, State> {
} else {
StatusBar.setBarStyle('dark-content', true);
}
StatusBar.setBackgroundColor(ThemeManager.getCurrentTheme().colors.surface, true);
if (Platform.OS === "android")
StatusBar.setBackgroundColor(ThemeManager.getCurrentTheme().colors.surface, true);
}
/**
@ -144,7 +143,6 @@ export default class App extends React.Component<Props, State> {
*/
loadAssetsAsync = async () => {
await this.storageManager.loadPreferences();
await initExpoToken();
try {
await ConnectionManager.getInstance().recoverLogin();
} catch (e) {
@ -156,7 +154,7 @@ export default class App extends React.Component<Props, State> {
*/
onLoadFinished() {
// Only show intro if this is the first time starting the app
this.createDrawerNavigator = () => <DrawerNavigator
this.createDrawerNavigator = () => <MainNavigator
defaultHomeRoute={this.defaultHomeRoute}
defaultHomeData={this.defaultHomeData}
/>;
@ -173,6 +171,7 @@ export default class App extends React.Component<Props, State> {
showUpdate: this.storageManager.preferences.updateNumber.current !== Update.number.toString(),
showAprilFools: AprilFoolsManager.getInstance().isAprilFoolsEnabled() && this.storageManager.preferences.showAprilFoolsStart.current === '1',
});
SplashScreen.hide();
}
/**
@ -180,7 +179,7 @@ export default class App extends React.Component<Props, State> {
*/
render() {
if (this.state.isLoading) {
return <AppLoading/>;
return null;
} else if (this.state.showIntro || this.state.showUpdate || this.state.showAprilFools) {
return <CustomIntroSlider
onDone={this.onIntroDone}
@ -190,12 +189,14 @@ export default class App extends React.Component<Props, State> {
} else {
return (
<PaperProvider theme={this.state.currentTheme}>
<NavigationContainer theme={this.state.currentTheme} ref={this.navigatorRef}>
<DrawerNavigator
defaultHomeRoute={this.defaultHomeRoute}
defaultHomeData={this.defaultHomeData}
/>
</NavigationContainer>
<View style={{backgroundColor: ThemeManager.getCurrentTheme().colors.background, flex: 1}}>
<NavigationContainer theme={this.state.currentTheme} ref={this.navigatorRef}>
<MainNavigator
defaultHomeRoute={this.defaultHomeRoute}
defaultHomeData={this.defaultHomeData}
/>
</NavigationContainer>
</View>
</PaperProvider>
);
}

View file

@ -2,6 +2,20 @@
Pensez à garder l'appli à jour pour profiter des dernières fonctionnalités !
- **v2.0.0** - _12/03/2020_
- Nouvelle interface !
- Amélioration des performances
- Amélioration de la vitesse de démarrage
- _Notes de développement :_
- Utilisation de react-native-paper à la place de native base
- **v1.5.2** - _25/02/2020_
- Correction d'un problème d'affichage des détail du Proximo
- **v1.5.1** - _24/02/2020_
- Amélioration des performances
- Utilisation d'un tri des catégories du Proximo plus cohérent
- **v1.5.0** - _05/02/2020_
- Amélioration des performances de l'application
- Amélioration du menu gauche

View file

@ -0,0 +1,7 @@
const keychainMock = {
SECURITY_LEVEL_ANY: "MOCK_SECURITY_LEVEL_ANY",
SECURITY_LEVEL_SECURE_SOFTWARE: "MOCK_SECURITY_LEVEL_SECURE_SOFTWARE",
SECURITY_LEVEL_SECURE_HARDWARE: "MOCK_SECURITY_LEVEL_SECURE_HARDWARE",
}
export default keychainMock;

View file

@ -1,7 +1,8 @@
jest.mock('react-native-keychain');
import React from 'react';
import ConnectionManager from "../../src/managers/ConnectionManager";
import {ERROR_TYPE} from "../../src/utils/WebData";
import * as SecureStore from 'expo-secure-store';
let fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native
@ -25,45 +26,6 @@ test('isLoggedIn no', () => {
return expect(c.isLoggedIn()).toBe(false);
});
test('recoverLogin error crypto', () => {
jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
return Promise.reject();
});
return expect(c.recoverLogin()).rejects.toBe(false);
});
test('recoverLogin success crypto', () => {
jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
return Promise.resolve('token1');
});
return expect(c.recoverLogin()).resolves.toBe('token1');
});
test('saveLogin success', () => {
jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
return Promise.resolve();
});
return expect(c.saveLogin('email', 'token2')).resolves.toBeTruthy();
});
test('saveLogin error', () => {
jest.spyOn(SecureStore, 'setItemAsync').mockImplementationOnce(() => {
return Promise.reject();
});
return expect(c.saveLogin('email', 'token3')).rejects.toBeFalsy();
});
test('recoverLogin error crypto with saved token', () => {
jest.spyOn(SecureStore, 'getItemAsync').mockImplementationOnce(() => {
return Promise.reject();
});
return expect(c.recoverLogin()).resolves.toBe('token2');
});
test('recoverLogin success saved', () => {
return expect(c.recoverLogin()).resolves.toBe('token2');
});
test("isConnectionResponseValid", () => {
let json = {
error: 0,

View file

@ -0,0 +1,142 @@
import React from 'react';
import {getCleanedMachineWatched, getMachineEndDate, getMachineOfId, isMachineWatched} from "../../src/utils/Proxiwash";
test('getMachineEndDate', () => {
jest.spyOn(Date, 'now')
.mockImplementation(() =>
new Date('2020-01-14T15:00:00.000Z').getTime()
);
let expectDate = new Date('2020-01-14T15:00:00.000Z');
expectDate.setHours(23);
expectDate.setMinutes(10);
expect(getMachineEndDate({endTime: "23:10"}).getTime()).toBe(expectDate.getTime());
expectDate.setHours(16);
expectDate.setMinutes(30);
expect(getMachineEndDate({endTime: "16:30"}).getTime()).toBe(expectDate.getTime());
expect(getMachineEndDate({endTime: "15:30"})).toBeNull();
expect(getMachineEndDate({endTime: "13:10"})).toBeNull();
jest.spyOn(Date, 'now')
.mockImplementation(() =>
new Date('2020-01-14T23:00:00.000Z').getTime()
);
expectDate = new Date('2020-01-14T23:00:00.000Z');
expectDate.setHours(0);
expectDate.setMinutes(30);
expect(getMachineEndDate({endTime: "00:30"}).getTime()).toBe(expectDate.getTime());
});
test('isMachineWatched', () => {
let machineList = [
{
number: "0",
endTime: "23:30",
},
{
number: "1",
endTime: "20:30",
},
];
expect(isMachineWatched({number: "0", endTime: "23:30"}, machineList)).toBeTrue();
expect(isMachineWatched({number: "1", endTime: "20:30"}, machineList)).toBeTrue();
expect(isMachineWatched({number: "3", endTime: "20:30"}, machineList)).toBeFalse();
expect(isMachineWatched({number: "1", endTime: "23:30"}, machineList)).toBeFalse();
});
test('getMachineOfId', () => {
let machineList = [
{
number: "0",
},
{
number: "1",
},
];
expect(getMachineOfId("0", machineList)).toStrictEqual({number: "0"});
expect(getMachineOfId("1", machineList)).toStrictEqual({number: "1"});
expect(getMachineOfId("3", machineList)).toBeNull();
});
test('getCleanedMachineWatched', () => {
let machineList = [
{
number: "0",
endTime: "23:30",
},
{
number: "1",
endTime: "20:30",
},
{
number: "2",
endTime: "",
},
];
let watchList = [
{
number: "0",
endTime: "23:30",
},
{
number: "1",
endTime: "20:30",
},
{
number: "2",
endTime: "",
},
];
let cleanedList = watchList;
expect(getCleanedMachineWatched(watchList, machineList)).toStrictEqual(cleanedList);
watchList = [
{
number: "0",
endTime: "23:30",
},
{
number: "1",
endTime: "20:30",
},
{
number: "2",
endTime: "15:30",
},
];
cleanedList = [
{
number: "0",
endTime: "23:30",
},
{
number: "1",
endTime: "20:30",
},
];
expect(getCleanedMachineWatched(watchList, machineList)).toStrictEqual(cleanedList);
watchList = [
{
number: "0",
endTime: "23:30",
},
{
number: "1",
endTime: "20:31",
},
{
number: "3",
endTime: "15:30",
},
];
cleanedList = [
{
number: "0",
endTime: "23:30",
},
];
expect(getCleanedMachineWatched(watchList, machineList)).toStrictEqual(cleanedList);
});

55
android/app/BUCK Normal file
View file

@ -0,0 +1,55 @@
# To learn about Buck see [Docs](https://buckbuild.com/).
# To run your application with Buck:
# - install Buck
# - `npm start` - to start the packager
# - `cd android`
# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
# - `buck install -r android/app` - compile, install and run application
#
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
lib_deps = []
create_aar_targets(glob(["libs/*.aar"]))
create_jar_targets(glob(["libs/*.jar"]))
android_library(
name = "all-libs",
exported_deps = lib_deps,
)
android_library(
name = "app-code",
srcs = glob([
"src/main/java/**/*.java",
]),
deps = [
":all-libs",
":build_config",
":res",
],
)
android_build_config(
name = "build_config",
package = "fr.amicaleinsat.application",
)
android_resource(
name = "res",
package = "fr.amicaleinsat.application",
res = "src/main/res",
)
android_binary(
name = "app",
keystore = "//android/keystores:debug",
manifest = "src/main/AndroidManifest.xml",
package_type = "debug",
deps = [
":app-code",
],
)

215
android/app/build.gradle Normal file
View file

@ -0,0 +1,215 @@
apply plugin: "com.android.application"
import com.android.build.OutputFile
/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation
* entryFile: "index.android.js",
*
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/
project.ext.react = [
entryFile: "index.js",
enableHermes: true,
]
apply from: "../../node_modules/react-native/react.gradle"
project.ext.vectoricons = [
iconFontNames: [ 'MaterialCommunityIcons.ttf'] // Name of the font files you want to copy
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
/**
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
/**
* The preferred build flavor of JavaScriptCore.
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
/**
* Whether to enable the Hermes VM.
*
* This should be set on project.ext.react and mirrored here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);
android {
compileSdkVersion rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId 'fr.amicaleinsat.application'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 16
versionName "2.0.0"
missingDimensionStrategy 'react-native-camera', 'general'
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://facebook.github.io/react-native/docs/signed-apk-android.
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

View file

@ -0,0 +1,19 @@
"""Helper definitions to glob .aar and .jar targets"""
def create_aar_targets(aarfiles):
for aarfile in aarfiles:
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
lib_deps.append(":" + name)
android_prebuilt_aar(
name = name,
aar = aarfile,
)
def create_jar_targets(jarfiles):
for jarfile in jarfiles:
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
lib_deps.append(":" + name)
prebuilt_jar(
name = name,
binary_jar = jarfile,
)

13
android/app/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,13 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
-keep class com.facebook.hermes.unicode.** { *; }
-keep class com.facebook.jni.** { *; }

View file

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
</manifest>

View file

@ -0,0 +1,66 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.amicaleinsat.application">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
>
<!-- NOTIFICATIONS -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="reminders"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="reminders"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@color/colorPrimary"/> <!-- or @android:color/{name} to use a standard color -->
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- END NOTIFICATIONS-->
<meta-data android:name="com.facebook.sdk.AutoInitEnabled" android:value="false"/>
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/>
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="false"/>
<activity android:name=".MainActivity" android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask" android:windowSoftInputMode="adjustResize"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="campus-insat"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
</application>
</manifest>

View file

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1,48 @@
package fr.amicaleinsat.application;
import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
import android.content.Intent;
import android.content.res.Configuration;
import org.devio.rn.splashscreen.SplashScreen;
public class MainActivity extends ReactActivity {
// Added automatically by Expo Config
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = new Intent("onConfigurationChanged");
intent.putExtra("newConfig", newConfig);
sendBroadcast(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this);
super.onCreate(savedInstanceState);
}
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "main";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}

View file

@ -0,0 +1,75 @@
package fr.amicaleinsat.application;
import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this); // Remove this line if you don't want Flipper enabled
}
/**
* Loads Flipper in React Native templates.
*
* @param context
*/
private static void initializeFlipper(Context context) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:scaleType="fitCenter"
android:src="@drawable/launch_screen" />
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resources>
<color name="activityBackground">#be1522</color>
<color name="navigationBarColor">#121212</color>
<color name="colorPrimaryDark">#be1522</color>
<color name="colorPrimary">#be1522</color>
<color name="primary_dark">#be1522</color>
</resources>

View file

@ -0,0 +1,3 @@
<resources>
<string name="app_name">Campus</string>
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:textColor">#000000</item>
<item name="android:windowBackground">@color/activityBackground</item>
<item name="android:navigationBarColor">@color/navigationBarColor</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorPrimary">@color/colorPrimary</item>
</style>
</resources>

View file

@ -0,0 +1,27 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission tools:node="remove" android:name="android.permission.MANAGE_DOCUMENTS"/>
<uses-permission tools:node="remove" android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission tools:node="remove" android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission tools:node="remove" android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission tools:node="remove" android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission tools:node="remove" android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission tools:node="remove" android:name="android.permission.READ_CONTACTS"/>
<uses-permission tools:node="remove" android:name="android.permission.READ_CALENDAR"/>
<uses-permission tools:node="remove" android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission tools:node="remove" android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission tools:node="remove" android:name="android.permission.RECORD_AUDIO"/>
<uses-permission tools:node="remove" android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission tools:node="remove" android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission tools:node="remove" android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>

41
android/build.gradle Normal file
View file

@ -0,0 +1,41 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 21
compileSdkVersion = 28
targetSdkVersion = 28
}
repositories {
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.5.3")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
maven {
// expo-camera bundles a custom com.google.android:cameraview
url "$rootDir/../node_modules/expo-camera/android/maven"
}
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}

Binary file not shown.

View file

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

188
android/gradlew vendored Executable file
View file

@ -0,0 +1,188 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

100
android/gradlew.bat vendored Normal file
View file

@ -0,0 +1,100 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

6
android/settings.gradle Normal file
View file

@ -0,0 +1,6 @@
rootProject.name = 'Campus'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesSettingsGradle(settings)
include ':app'

View file

@ -1,70 +1,4 @@
{
"expo": {
"name": "Campus",
"description": "Application mobile compatible Android et iOS pour l'Amicale INSA Toulouse. Grâce à cette application, vous avez facilement accès aux news du campus, aux emplois du temps, à l'état de la laverie, et bien d'autres services ! Ceci est une version Beta, Toutes les fonctionnalités ne sont pas encore implémentées, et il est possible de rencontrer quelques bugs.",
"slug": "application-amicale",
"backgroundColor": "#ffffff",
"privacy": "public",
"version": "2.0.0",
"platforms": [
"ios",
"android"
],
"orientation": "portrait",
"primaryColor": "#be1522",
"icon": "./assets/android.icon.png",
"scheme": "campus-insat",
"facebookAutoInitEnabled": false,
"facebookAutoLogAppEventsEnabled": false,
"facebookAdvertiserIDCollectionEnabled": false,
"androidStatusBar": {
"barStyle": "light-content",
"hidden": false,
"translucent": false,
"backgroundColor": "#be1522"
},
"androidNavigationBar": {
"barStyle": "light-content",
"backgroundColor": "#121212"
},
"splash": {
"backgroundColor": "#be1522",
"resizeMode": "contain",
"image": "./assets/splash.png"
},
"notification": {
"icon": "./assets/icon-notification.png",
"color": "#be1522",
"androidMode": "default"
},
"updates": {
"enabled": false
},
"ios": {
"bundleIdentifier": "fr.amicaleinsat.application",
"icon": "./assets/ios.icon.png",
"appStoreUrl": "https://apps.apple.com/us/app/campus-amicale-insat/id1477722148?ls=1",
"usesIcloudStorage": false,
"usesAppleSignIn": false,
"accessesContactNotes": false
},
"android": {
"package": "fr.amicaleinsat.application",
"versionCode": 16,
"icon": "./assets/android.icon.png",
"adaptiveIcon": {
"foregroundImage": "./assets/android.adaptive-icon.png",
"backgroundColor": "#be1522"
},
"playStoreUrl": "https://play.google.com/store/apps/details?id=fr.amicaleinsat.application",
"permissions": [
"VIBRATE",
"CAMERA"
]
},
"userInterfaceStyle": "automatic",
"assetBundlePatterns": [
"**/*"
]
}
}
"name": "Campus",
"displayName": "Campus"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 147 KiB

View file

@ -1,11 +1,3 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo', '@babel/preset-flow'],
env: {
production: {
plugins: ['react-native-paper/babel'],
},
},
};
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};

View file

@ -16,5 +16,3 @@ echo "Installing dependencies..."
npm install
echo -e "Done\n"
echo "Starting expo with clear cache..."
expo r -c

37
eject.txt Normal file
View file

@ -0,0 +1,37 @@
Your git working tree is clean
To revert the changes after this command completes, you can run the following:
git clean --force && git reset --hard
✔ App configuration (app.json) updated.
✔ Created native project directories (./ios and ./android) and updated .gitignore.
✔ Updated package.json and added index.js entry point for iOS and Android.
✔ Installed JavaScript dependencies.
⚠️ iOS configuration applied with warnings that should be fixed:
- icon: This is the image that your app uses on your home screen, you will need to configure it manually.
- splash: This is the image that your app uses on the loading screen, we recommend installing and using expo-splash-screen. Details. (https://github.com/expo/expo/blob/master/packages/expo-splash-screen/README.md)
⚠️ Android configuration applied with warnings that should be fixed:
- splash: This is the image that your app uses on the loading screen, we recommend installing and using expo-splash-screen. Details. (https://github.com/expo/expo/blob/master/packages/expo-splash-screen/README.md)
- icon: This is the image that your app uses on your home screen, you will need to configure it manually.
- android.adaptiveIcon: This is the image that your app uses on your home screen, you will need to configure it manually.
✔ Skipped installing CocoaPods because operating system is not on macOS.
⚠️ Your app includes 3 packages that require additional setup in order to run:
- expo-camera: https://github.com/expo/expo/tree/master/packages/expo-camera
- react-native-appearance: https://github.com/expo/react-native-appearance
- react-native-webview: https://github.com/react-native-community/react-native-webview
➡️ Next steps
- 👆 Review the logs above and look for any warnings (⚠️ ) that might need follow-up.
- 💡 You may want to run npx @react-native-community/cli doctor to help install any tools that your app may need to run your native projects.
- 🍫 When CocoaPods is installed, initialize the project workspace: cd ios && pod install
- 🔑 Download your Android keystore (if you're not sure if you need to, just run the command and see): expo fetch:android:keystore
- 🚀 expo-updates (https://github.com/expo/expo/blob/master/packages/expo-updates/README.md) has been configured in your project. Before you do a release build, make sure you run expo publish. Learn more. (https://expo.fyi/release-builds-with-expo-updates)
☑️ When you are ready to run your project
To compile and run your project in development, execute one of the following commands:
- npm run ios
- npm run android
- npm run web

4
index.js Normal file
View file

@ -0,0 +1,4 @@
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('main', () => App);

View file

@ -0,0 +1,498 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
074F4BDC2432833400BDB9FE /* app.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 07C2E6E4243282B30028AF0A /* app.bundle */; };
074F4BDD2432833400BDB9FE /* app.manifest in Resources */ = {isa = PBXBuildFile; fileRef = 07C2E6E3243282B30028AF0A /* app.manifest */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
3DE4DAD41476765101945408 /* libPods-Campus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D43FF9D506E70904424FA7E9 /* libPods-Campus.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
07C2E6E3243282B30028AF0A /* app.manifest */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = app.manifest; path = Campus/Supporting/app.manifest; sourceTree = "<group>"; };
07C2E6E4243282B30028AF0A /* app.bundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = app.bundle; path = Campus/Supporting/app.bundle; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* application.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = application.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Campus/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Campus/AppDelegate.m; sourceTree = "<group>"; };
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Campus/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Campus/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Campus/main.m; sourceTree = "<group>"; };
2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
3B47C5AFCB8BDE514B7D1AC6 /* Pods-Campus.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Campus.debug.xcconfig"; path = "Target Support Files/Pods-Campus/Pods-Campus.debug.xcconfig"; sourceTree = "<group>"; };
8AC623DBF3A3E2CB072F81F2 /* Pods-Campus.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Campus.release.xcconfig"; path = "Target Support Files/Pods-Campus/Pods-Campus.release.xcconfig"; sourceTree = "<group>"; };
D43FF9D506E70904424FA7E9 /* libPods-Campus.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Campus.a"; sourceTree = BUILT_PRODUCTS_DIR; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3DE4DAD41476765101945408 /* libPods-Campus.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
13B07FAE1A68108700A75B9A /* Campus */ = {
isa = PBXGroup;
children = (
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
07C2E6E4243282B30028AF0A /* app.bundle */,
07C2E6E3243282B30028AF0A /* app.manifest */,
);
name = Campus;
sourceTree = "<group>";
};
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
2D16E6891FA4F8E400B85C8A /* libReact.a */,
D43FF9D506E70904424FA7E9 /* libPods-Campus.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
72E5486571395D51695C2A02 /* Pods */ = {
isa = PBXGroup;
children = (
3B47C5AFCB8BDE514B7D1AC6 /* Pods-Campus.debug.xcconfig */,
8AC623DBF3A3E2CB072F81F2 /* Pods-Campus.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
);
name = Libraries;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
13B07FAE1A68108700A75B9A /* Campus */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
72E5486571395D51695C2A02 /* Pods */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 0;
};
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
children = (
13B07F961A680F5B00A75B9A /* application.app */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
13B07F861A680F5B00A75B9A /* Campus */ = {
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Campus" */;
buildPhases = (
F8BC737F2AD7A05944D9E2A1 /* [CP] Check Pods Manifest.lock */,
FD4C38642228810C00325AF5 /* Start Packager */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle Expo Assets */,
58CDB7AB66969EE82AA3E3B0 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = Campus;
productName = "Hello World";
productReference = 13B07F961A680F5B00A75B9A /* application.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 940;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = 6JA7CLNUV6;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Campus" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
mainGroup = 83CBB9F61A601CBA00E9B192;
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
13B07F861A680F5B00A75B9A /* Campus */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
13B07F8E1A680F5B00A75B9A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
074F4BDC2432833400BDB9FE /* app.bundle in Resources */,
074F4BDD2432833400BDB9FE /* app.manifest in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
00DD1BFF1BD5951E006B06BC /* Bundle Expo Assets */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Bundle Expo Assets";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
58CDB7AB66969EE82AA3E3B0 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Campus/Pods-Campus-resources.sh",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Feather.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Brands.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Foundation.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Feather.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Brands.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Regular.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FontAwesome5_Solid.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Fontisto.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Foundation.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Ionicons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialCommunityIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MaterialIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Campus/Pods-Campus-resources.sh\"\n";
showEnvVarsInLog = 0;
};
F8BC737F2AD7A05944D9E2A1 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Campus-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
FD4C38642228810C00325AF5 /* Start Packager */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Start Packager";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ \"$CONFIGURATION\" == \"Release\" ]; then\n exit 0;\nfi\nexport RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
13B07F871A680F5B00A75B9A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
13B07FB21A68108700A75B9A /* Base */,
);
name = LaunchScreen.xib;
path = Campus;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B47C5AFCB8BDE514B7D1AC6 /* Pods-Campus.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Campus/application.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = 6JA7CLNUV6;
INFOPLIST_FILE = Campus/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.0.1;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application;
PRODUCT_NAME = application;
PROVISIONING_PROFILE_SPECIFIER = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8AC623DBF3A3E2CB072F81F2 /* Pods-Campus.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Campus/application.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = 6JA7CLNUV6;
INFOPLIST_FILE = Campus/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.0.1;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application;
PRODUCT_NAME = application;
PROVISIONING_PROFILE_SPECIFIER = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
83CBBA201A601CBA00E9B192 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = Campus/application.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application;
PRODUCT_NAME = application;
SDKROOT = iphoneos;
};
name = Debug;
};
83CBBA211A601CBA00E9B192 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_ENTITLEMENTS = Campus/application.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application;
PRODUCT_NAME = application;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Campus" */ = {
isa = XCConfigurationList;
buildConfigurations = (
13B07F941A680F5B00A75B9A /* Debug */,
13B07F951A680F5B00A75B9A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Campus" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83CBBA201A601CBA00E9B192 /* Debug */,
83CBBA211A601CBA00E9B192 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
}

View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
BuildableName = "libReact.a"
BlueprintName = "React"
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "application.app"
BlueprintName = "Campus"
ReferencedContainer = "container:Campus.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "CampusTests.xctest"
BlueprintName = "CampusTests"
ReferencedContainer = "container:Campus.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "application.app"
BlueprintName = "Campus"
ReferencedContainer = "container:Campus.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "CampusTests.xctest"
BlueprintName = "CampusTests"
ReferencedContainer = "container:Campus.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "application.app"
BlueprintName = "Campus"
ReferencedContainer = "container:Campus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "application.app"
BlueprintName = "Campus"
ReferencedContainer = "container:Campus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

16
ios/Campus/AppDelegate.h Normal file
View file

@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTBridgeDelegate.h>
#import <UserNotifications/UNUserNotificationCenter.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
@property (nonatomic, strong) UIWindow *window;
@end

89
ios/Campus/AppDelegate.m Normal file
View file

@ -0,0 +1,89 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#import "RNSplashScreen.h"
#import <RNCPushNotificationIOS.h>
#import <UserNotifications/UserNotifications.h>
@implementation AppDelegate
@synthesize window = _window;
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
// Define UNUserNotificationCenter
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[RNSplashScreen show];
return YES;
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#ifdef DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina3_5" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LaunchScreen" translatesAutoresizingMaskIntoConstraints="NO" id="MEu-9j-Yk9">
<rect key="frame" x="0.0" y="0.0" width="320" height="440"/>
</imageView>
</subviews>
<color key="backgroundColor" red="0.74509803921568629" green="0.082352941176470587" blue="0.13333333333333333" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="MEu-9j-Yk9" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="topMargin" id="JBv-Ns-A6x"/>
<constraint firstItem="MEu-9j-Yk9" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="JNO-FD-uRI"/>
<constraint firstItem="MEu-9j-Yk9" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="KdP-HF-t4U"/>
<constraint firstItem="MEu-9j-Yk9" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="LNb-Oe-Px1"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<modalPageSheetSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="546.37681159420299" y="453.26086956521743"/>
</view>
</objects>
<resources>
<image name="LaunchScreen" width="682.66668701171875" height="200"/>
</resources>
</document>

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -0,0 +1,62 @@
{
"images" : [
{
"filename" : "40.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "80.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "120-1.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View file

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "splash.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

79
ios/Campus/Info.plist Normal file
View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>Campus</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>campus-insat</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>FacebookAdvertiserIDCollectionEnabled</key>
<false/>
<key>FacebookAutoInitEnabled</key>
<false/>
<key>FacebookAutoLogAppEventsEnabled</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>Allow Campus to use the camera</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Automatic</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIAppFonts</key>
<array>
<string>MaterialCommunityIcons.ttf</string>
</array>
</dict>
</plist>

View file

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

16
ios/Campus/main.m Normal file
View file

@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

49
ios/Podfile Normal file
View file

@ -0,0 +1,49 @@
platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
target 'Campus' do
rnPrefix = "../node_modules/react-native"
# React Native and its dependencies
pod 'FBLazyVector', :path => "#{rnPrefix}/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "#{rnPrefix}/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "#{rnPrefix}/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "#{rnPrefix}/Libraries/TypeSafety"
pod 'React', :path => "#{rnPrefix}/"
pod 'React-Core', :path => "#{rnPrefix}/"
pod 'React-CoreModules', :path => "#{rnPrefix}/React/CoreModules"
pod 'React-RCTActionSheet', :path => "#{rnPrefix}/Libraries/ActionSheetIOS"
pod 'React-RCTAnimation', :path => "#{rnPrefix}/Libraries/NativeAnimation"
pod 'React-RCTBlob', :path => "#{rnPrefix}/Libraries/Blob"
pod 'React-RCTImage', :path => "#{rnPrefix}/Libraries/Image"
pod 'React-RCTLinking', :path => "#{rnPrefix}/Libraries/LinkingIOS"
pod 'React-RCTNetwork', :path => "#{rnPrefix}/Libraries/Network"
pod 'React-RCTSettings', :path => "#{rnPrefix}/Libraries/Settings"
pod 'React-RCTText', :path => "#{rnPrefix}/Libraries/Text"
pod 'React-RCTVibration', :path => "#{rnPrefix}/Libraries/Vibration"
pod 'React-Core/RCTWebSocket', :path => "#{rnPrefix}/"
pod 'React-Core/DevSupport', :path => "#{rnPrefix}/"
pod 'React-cxxreact', :path => "#{rnPrefix}/ReactCommon/cxxreact"
pod 'React-jsi', :path => "#{rnPrefix}/ReactCommon/jsi"
pod 'React-jsiexecutor', :path => "#{rnPrefix}/ReactCommon/jsiexecutor"
pod 'React-jsinspector', :path => "#{rnPrefix}/ReactCommon/jsinspector"
pod 'ReactCommon/jscallinvoker', :path => "#{rnPrefix}/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "#{rnPrefix}/ReactCommon"
pod 'Yoga', :path => "#{rnPrefix}/ReactCommon/yoga"
pod 'DoubleConversion', :podspec => "#{rnPrefix}/third-party-podspecs/DoubleConversion.podspec"
pod 'glog', :podspec => "#{rnPrefix}/third-party-podspecs/glog.podspec"
pod 'Folly', :podspec => "#{rnPrefix}/third-party-podspecs/Folly.podspec"
# Other native modules
# react-native-cli autolinking
use_native_modules!
# Permissions
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications.podspec"
pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec"
end

17
metro.config.js Normal file
View file

@ -0,0 +1,17 @@
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* @format
*/
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
};

View file

@ -1,14 +1,13 @@
{
"main": "node_modules/expo/AppEntry.js",
"name": "campus",
"version": "2.0.0",
"private": true,
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject",
"start": "react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios",
"test": "jest",
"testw": "jest --watch",
"testc": "jest --coverage"
"lint": "eslint ."
},
"jest": {
"preset": "react-native",
@ -20,50 +19,54 @@
]
},
"dependencies": {
"@expo/vector-icons": "^10.0.0",
"@react-native-community/masked-view": "0.1.6",
"@react-navigation/bottom-tabs": "^5.1.1",
"@react-navigation/drawer": "^5.1.1",
"@react-navigation/native": "^5.0.9",
"@react-navigation/stack": "^5.1.1",
"expo": "^37.0.0",
"expo-barcode-scanner": "~8.1.0",
"expo-camera": "latest",
"expo-linear-gradient": "~8.1.0",
"expo-localization": "~8.1.0",
"expo-permissions": "~8.1.0",
"expo-secure-store": "~8.1.0",
"@nartc/react-native-barcode-mask": "^1.1.9",
"@react-native-community/async-storage": "^1.9.0",
"@react-native-community/masked-view": "^0.1.10",
"@react-native-community/push-notification-ios": "^1.1.1",
"@react-native-community/slider": "^2.0.9",
"@react-navigation/bottom-tabs": "^5.3.2",
"@react-navigation/native": "^5.2.2",
"@react-navigation/stack": "^5.2.17",
"i18n-js": "^3.3.0",
"react": "16.9.0",
"react": "~16.9.0",
"react-dom": "16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.0.tar.gz",
"react-native": "~0.61.5",
"react-native-animatable": "^1.3.3",
"react-native-app-intro-slider": "^4.0.0",
"react-native-appearance": "~0.3.3",
"react-native-autolink": "^3.0.0",
"react-native-calendars": "^1.260.0",
"react-native-camera": "^3.23.1",
"react-native-collapsible": "^1.5.2",
"react-native-gesture-handler": "~1.6.0",
"react-native-image-modal": "^1.0.6",
"react-native-keychain": "^6.0.0",
"react-native-linear-gradient": "^2.5.6",
"react-native-localize": "^1.4.0",
"react-native-modalize": "^1.3.6",
"react-native-paper": "^3.8.0",
"react-native-paper": "^3.9.0",
"react-native-permissions": "^2.1.4",
"react-native-push-notification": "^3.3.1",
"react-native-reanimated": "^1.8.0",
"react-native-render-html": "^4.1.2",
"react-native-safe-area-context": "0.7.3",
"react-native-webview": "8.1.1",
"react-native-screens": "^2.7.0",
"react-native-splash-screen": "^3.2.0",
"react-native-vector-icons": "^6.6.0",
"react-native-webview": "^9.4.0",
"react-navigation-collapsible": "^5.5.0",
"react-navigation-header-buttons": "^3.0.5",
"react-native-screens": "~2.2.0",
"react-native-reanimated": "~1.7.0"
"react-navigation-header-buttons": "^3.0.5"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-flow": "^7.9.0",
"babel-preset-expo": "^8.1.0",
"flow-bin": "^0.122.0",
"jest": "^25.1.0",
"@babel/core": "^7.9.6",
"@babel/runtime": "^7.9.6",
"@react-native-community/eslint-config": "^1.1.0",
"babel-jest": "^25.5.1",
"eslint": "^6.5.1",
"flow-bin": "^0.123.0",
"jest": "^25.5.3",
"jest-extended": "^0.11.5",
"react-test-renderer": "^16.13.1"
},
"private": true
"metro-react-native-babel-preset": "^0.59.0",
"react-test-renderer": "16.9.0"
}
}

View file

@ -15,6 +15,12 @@ type Props = {
mandatory: boolean
}>,
renderFunction: (Array<{ [key: string]: any } | null>) => React.Node,
errorViewOverride?: Array<{
errorCode: number,
message: string,
icon: string,
showRetryButton: boolean
}>,
}
type State = {
@ -158,13 +164,38 @@ class AuthenticatedScreen extends React.Component<Props, State> {
* @return {*}
*/
getErrorRender() {
return (
<ErrorView
{...this.props}
errorCode={this.getError()}
onRefresh={this.fetchData}
/>
);
const errorCode = this.getError();
let shouldOverride = false;
let override = null;
const overrideList = this.props.errorViewOverride;
if (overrideList != null) {
for (let i = 0; i < overrideList.length; i++) {
if (overrideList[i].errorCode === errorCode) {
shouldOverride = true;
override = overrideList[i];
break;
}
}
}
if (shouldOverride && override != null) {
return (
<ErrorView
{...this.props}
icon={override.icon}
message={override.message}
showRetryButton={override.showRetryButton}
/>
);
} else {
return (
<ErrorView
{...this.props}
errorCode={errorCode}
onRefresh={this.fetchData}
/>
);
}
}
/**

View file

@ -12,48 +12,62 @@ type Props = {
title: string,
subtitle?: string,
left?: (props: { [keys: string]: any }) => React.Node,
startOpen: boolean,
keepOpen: boolean,
opened?: boolean,
unmountWhenCollapsed: boolean,
children?: React.Node,
}
type State = {
expanded: boolean
expanded: boolean,
}
const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon);
class AnimatedAccordion extends React.PureComponent<Props, State> {
class AnimatedAccordion extends React.Component<Props, State> {
static defaultProps = {
startOpen: false,
keepOpen: false,
unmountWhenCollapsed: false,
}
chevronRef: { current: null | AnimatedListIcon };
chevronIcon: string;
animStart: string;
animEnd: string;
state = {
expanded: false,
expanded: this.props.opened != null ? this.props.opened : false,
}
constructor(props) {
super(props);
this.chevronRef = React.createRef();
this.setupChevron();
}
componentDidMount() {
if (this.props.startOpen)
this.toggleAccordion();
setupChevron() {
if (this.state.expanded) {
this.chevronIcon = "chevron-up";
this.animStart = "180deg";
this.animEnd = "0deg";
} else {
this.chevronIcon = "chevron-down";
this.animStart = "0deg";
this.animEnd = "180deg";
}
}
toggleAccordion = () => {
if (!this.props.keepOpen) {
if (this.chevronRef.current != null)
this.chevronRef.current.transitionTo({rotate: this.state.expanded ? '0deg' : '180deg'});
if (this.chevronRef.current != null) {
this.chevronRef.current.transitionTo({rotate: this.state.expanded ? this.animStart : this.animEnd});
this.setState({expanded: !this.state.expanded})
}
};
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
if (nextProps.opened != null && nextProps.opened !== this.props.opened)
this.state.expanded = nextProps.opened;
return true;
}
render() {
const colors = this.props.theme.colors;
return (
@ -67,13 +81,13 @@ class AnimatedAccordion extends React.PureComponent<Props, State> {
right={(props) => <AnimatedListIcon
ref={this.chevronRef}
{...props}
icon={"chevron-down"}
icon={this.chevronIcon}
color={this.state.expanded ? colors.primary : undefined}
useNativeDriver
/>}
left={this.props.left}
/>
<Collapsible collapsed={!this.props.keepOpen && !this.state.expanded}>
<Collapsible collapsed={!this.state.expanded}>
{!this.props.unmountWhenCollapsed || (this.props.unmountWhenCollapsed && this.state.expanded)
? this.props.children
: null}

View file

@ -11,6 +11,7 @@ type Props = {
title: string,
titleLoading: string,
message: string,
startLoading: boolean,
}
type State = {
@ -19,8 +20,16 @@ type State = {
class LoadingConfirmDialog extends React.PureComponent<Props, State> {
static defaultProps = {
title: '',
message: '',
onDismiss: () => {},
onAccept: () => {return Promise.resolve()},
startLoading: false,
}
state = {
loading: false,
loading: this.props.startLoading,
};
/**

View file

@ -1,63 +1,66 @@
// @flow
import * as React from 'react';
import {Button, Card, withTheme} from 'react-native-paper';
import {Platform, StyleSheet} from "react-native";
import i18n from 'i18n-js';
import {DrawerNavigationProp} from "@react-navigation/drawer";
import {Avatar, Card, List, withTheme} from 'react-native-paper';
import {StyleSheet, View} from "react-native";
import type {CustomTheme} from "../../managers/ThemeManager";
import i18n from 'i18n-js';
import {StackNavigationProp} from "@react-navigation/stack";
const ICON_AMICALE = require("../../../assets/amicale.png");
type Props = {
navigation: DrawerNavigationProp,
navigation: StackNavigationProp,
theme: CustomTheme,
isLoggedIn: boolean,
}
class ActionsDashBoardItem extends React.Component<Props> {
shouldComponentUpdate(nextProps: Props): boolean {
return (nextProps.theme.dark !== this.props.theme.dark)
|| (nextProps.isLoggedIn !== this.props.isLoggedIn);
}
openDrawer = () => this.props.navigation.openDrawer();
gotToSettings = () => this.props.navigation.navigate("settings");
render() {
const isLoggedIn = this.props.isLoggedIn;
return (
<Card style={{
...styles.card,
borderColor: this.props.theme.colors.primary,
}}>
<Card.Content style={styles.content}>
<Button
icon="information"
mode="contained"
onPress={this.openDrawer}
style={styles.servicesButton}
>
{i18n.t("homeScreen.servicesButton")}
</Button>
{
// Leave space to fix ios icon position
Platform.OS === 'ios'
? <Button
icon="settings"
mode="contained"
onPress={this.gotToSettings}
style={styles.settingsButton}
compact
> </Button>
: <Button
icon="settings"
mode="contained"
onPress={this.gotToSettings}
style={styles.settingsButton}
compact
/>
}
<View>
<Card style={{
...styles.card,
borderColor: this.props.theme.colors.primary,
}}>
<List.Item
title={i18n.t("homeScreen.dashboard.amicaleTitle")}
description={isLoggedIn
? i18n.t("homeScreen.dashboard.amicaleConnected")
: i18n.t("homeScreen.dashboard.amicaleConnect")}
left={props => <Avatar.Image
{...props}
size={40}
source={ICON_AMICALE}
style={styles.avatar}/>}
right={props => <List.Icon {...props} icon={isLoggedIn
? "chevron-right"
: "login"}/>}
onPress={isLoggedIn
? () => this.props.navigation.navigate("services", {
screen: 'index'
})
: () => this.props.navigation.navigate("login")}
style={styles.list}
/>
</Card>
<List.Item
title={i18n.t("feedbackScreen.homeButtonTitle")}
description={i18n.t("feedbackScreen.homeButtonSubtitle")}
left={props => <List.Icon {...props} icon={"bug"}/>}
right={props => <List.Icon {...props} icon={"chevron-right"}/>}
onPress={() => this.props.navigation.navigate("feedback")}
style={{...styles.list, marginLeft: 10, marginRight: 10}}
/>
</View>
</Card.Content>
</Card>
);
}
}
@ -65,27 +68,18 @@ class ActionsDashBoardItem extends React.Component<Props> {
const styles = StyleSheet.create({
card: {
width: 'auto',
marginLeft: 10,
marginRight: 10,
marginTop: 10,
overflow: 'hidden',
elevation: 4,
margin: 10,
borderWidth: 1,
},
avatar: {
backgroundColor: 'transparent'
backgroundColor: 'transparent',
marginTop: 'auto',
marginBottom: 'auto',
},
content: {
flex: 1,
flexDirection: 'row',
},
servicesButton: {
marginLeft: 'auto',
marginRight: 5,
},
settingsButton: {
marginLeft: 5,
marginRight: 'auto',
list: {
// height: 50,
paddingTop: 0,
paddingBottom: 0,
}
});

View file

@ -4,7 +4,7 @@ import * as React from 'react';
import {Badge, IconButton, withTheme} from 'react-native-paper';
import {View} from "react-native";
import type {CustomTheme} from "../../managers/ThemeManager";
import * as Animatable from "react-native-animatable";
type Props = {
color: string,
@ -15,6 +15,8 @@ type Props = {
theme: CustomTheme,
};
const AnimatableBadge = Animatable.createAnimatableComponent(Badge);
/**
* Component used to render a small dashboard item
*/
@ -43,14 +45,17 @@ class SmallDashboardItem extends React.Component<Props> {
/>
{
props.badgeNumber > 0 ?
<Badge
<AnimatableBadge
animation={"zoomIn"}
duration={300}
useNativeDriver
style={{
position: 'absolute',
top: 5,
right: 5
}}>
{props.badgeNumber}
</Badge> : null
</AnimatableBadge> : null
}
</View>
);

View file

@ -0,0 +1,63 @@
// @flow
import * as React from 'react';
import {Animated} from "react-native";
import ImageListItem from "./ImageListItem";
import CardListItem from "./CardListItem";
type Props = {
dataset: Array<cardItem>,
isHorizontal: boolean,
}
export type cardItem = {
title: string,
subtitle: string,
image: string | number,
onPress: () => void,
};
export type cardList = Array<cardItem>;
export default class CardList extends React.Component<Props> {
static defaultProps = {
isHorizontal: false,
}
renderItem = ({item}: { item: cardItem }) => {
if (this.props.isHorizontal)
return <ImageListItem item={item} key={item.title}/>;
else
return <CardListItem item={item} key={item.title}/>;
};
keyExtractor = (item: cardItem) => item.title;
render() {
let containerStyle;
if (this.props.isHorizontal) {
containerStyle = {
...this.props.contentContainerStyle,
height: 150,
justifyContent: 'space-around',
};
} else {
containerStyle = {
...this.props.contentContainerStyle,
}
}
return (
<Animated.FlatList
{...this.props}
data={this.props.dataset}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
numColumns={this.props.isHorizontal ? undefined : 2}
horizontal={this.props.isHorizontal}
contentContainerStyle={containerStyle}
/>
);
}
}

View file

@ -0,0 +1,44 @@
// @flow
import * as React from 'react';
import {Caption, Card, Paragraph} from 'react-native-paper';
import type {cardItem} from "./CardList";
type Props = {
item: cardItem,
}
export default class CardListItem extends React.Component<Props> {
shouldComponentUpdate() {
return false;
}
render() {
const props = this.props;
const item = props.item;
const source = typeof item.image === "number"
? item.image
: {uri: item.image};
return (
<Card
style={{
width: '40%',
margin: 5,
marginLeft: 'auto',
marginRight: 'auto',
}}
onPress={item.onPress}
>
<Card.Cover
style={{height: 80}}
source={source}
/>
<Card.Content>
<Paragraph>{item.title}</Paragraph>
<Caption>{item.subtitle}</Caption>
</Card.Content>
</Card>
);
}
}

View file

@ -0,0 +1,53 @@
// @flow
import * as React from 'react';
import {Text, TouchableRipple} from 'react-native-paper';
import {Image, View} from 'react-native';
import type {cardItem} from "./CardList";
type Props = {
item: cardItem,
}
export default class ImageListItem extends React.Component<Props> {
shouldComponentUpdate() {
return false;
}
render() {
const props = this.props;
const item = props.item;
const source = typeof item.image === "number"
? item.image
: {uri: item.image};
return (
<TouchableRipple
style={{
width: 100,
height: 150,
margin: 5,
}}
onPress={item.onPress}
>
<View>
<Image
style={{
width: 80,
height: 80,
marginLeft: 'auto',
marginRight: 'auto',
}}
source={source}
/>
<Text style={{
marginTop: 5,
marginLeft: 'auto',
marginRight: 'auto',
textAlign: 'center'
}}>{item.title}</Text>
</View>
</TouchableRipple>
);
}
}

View file

@ -1,22 +1,43 @@
// @flow
import * as React from 'react';
import {Card, List, Text} from 'react-native-paper';
import {Card, Chip, List, Text} from 'react-native-paper';
import {StyleSheet, View} from "react-native";
import i18n from 'i18n-js';
import AnimatedAccordion from "../../Animations/AnimatedAccordion";
import {isItemInCategoryFilter} from "../../../utils/Search";
import type {category} from "../../../screens/Amicale/Clubs/ClubListScreen";
type Props = {
categoryRender: Function,
categories: Array<Object>,
categories: Array<category>,
onChipSelect: (id: number) => void,
selectedCategories: Array<number>,
}
class ClubListHeader extends React.Component<Props> {
shouldComponentUpdate(nextProps: Props) {
return nextProps.selectedCategories.length !== this.props.selectedCategories.length;
}
getChipRender = (category: category, key: string) => {
const onPress = () => this.props.onChipSelect(category.id);
return <Chip
selected={isItemInCategoryFilter(this.props.selectedCategories, [category.id])}
mode={'outlined'}
onPress={onPress}
style={{marginRight: 5, marginBottom: 5}}
key={key}
>
{category.name}
</Chip>;
};
getCategoriesRender() {
let final = [];
for (let i = 0; i < this.props.categories.length; i++) {
final.push(this.props.categoryRender(this.props.categories[i], this.props.categories[i].id));
final.push(this.getChipRender(this.props.categories[i], this.props.categories[i].id.toString()));
}
return final;
}
@ -27,7 +48,7 @@ class ClubListHeader extends React.Component<Props> {
<AnimatedAccordion
title={i18n.t("clubs.categories")}
left={props => <List.Icon {...props} icon="star"/>}
startOpen={true}
opened={true}
>
<Text style={styles.text}>{i18n.t("clubs.categoriesFilterMessage")}</Text>
<View style={styles.chipContainer}>

View file

@ -19,50 +19,43 @@ type Props = {
theme: CustomTheme,
}
type State = {
expanded: boolean,
}
const LIST_ITEM_HEIGHT = 64;
class GroupListAccordion extends React.Component<Props, State> {
constructor(props) {
super(props);
this.state = {
expanded: props.item.id === "0",
}
}
shouldComponentUpdate(nextProps: Props, nextSate: State) {
if (nextProps.currentSearchString !== this.props.currentSearchString)
this.state.expanded = nextProps.currentSearchString.length > 0;
class GroupListAccordion extends React.Component<Props> {
shouldComponentUpdate(nextProps: Props) {
return (nextProps.currentSearchString !== this.props.currentSearchString)
|| (nextSate.expanded !== this.state.expanded)
|| (nextProps.favoriteNumber !== this.props.favoriteNumber)
|| (nextProps.item.content.length !== this.props.item.content.length);
}
keyExtractor = (item: group) => item.id.toString();
renderItem = ({item}: {item: group}) => {
if (stringMatchQuery(item.name, this.props.currentSearchString)) {
const onPress = () => this.props.onGroupPress(item);
const onStarPress = () => this.props.onFavoritePress(item);
return (
<GroupListItem
height={LIST_ITEM_HEIGHT}
item={item}
onPress={onPress}
onStarPress={onStarPress}/>
);
} else
return null;
renderItem = ({item}: { item: group }) => {
const onPress = () => this.props.onGroupPress(item);
const onStarPress = () => this.props.onFavoritePress(item);
return (
<GroupListItem
height={LIST_ITEM_HEIGHT}
item={item}
onPress={onPress}
onStarPress={onStarPress}/>
);
}
getData() {
const originalData = this.props.item.content;
let displayData = [];
for (let i = 0; i < originalData.length; i++) {
if (stringMatchQuery(originalData[i].name, this.props.currentSearchString))
displayData.push(originalData[i]);
}
return displayData;
}
itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
render() {
const item = this.props.item;
return (
@ -82,16 +75,17 @@ class GroupListAccordion extends React.Component<Props, State> {
/>
: null}
unmountWhenCollapsed={true}// Only render list if expanded for increased performance
opened={this.props.item.id === 0 || this.props.currentSearchString.length > 0}
>
{/*$FlowFixMe*/}
<FlatList
data={item.content}
data={this.getData()}
extraData={this.props.currentSearchString}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
listKey={item.id.toString()}
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
getItemLayout={this.itemLayout} // Broken with search
getItemLayout={this.itemLayout}
removeClippedSubviews={true}
/>
</AnimatedAccordion>

View file

@ -1,7 +1,7 @@
import * as React from 'react';
import {Text, withTheme} from 'react-native-paper';
import HTML from "react-native-render-html";
import {Linking} from "expo";
import {Linking} from "react-native";
type Props = {
theme: Object,
@ -18,7 +18,6 @@ class CustomHTML extends React.Component<Props> {
};
getBasicText = (htmlAttribs, children, convertedCSSStyles, passProps) => {
// console.log(convertedCSSStyles);
return <Text {...passProps}>{children}</Text>;
};

View file

@ -1,20 +1,18 @@
// @flow
import * as React from 'react';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
import {HeaderButton, HeaderButtons} from 'react-navigation-header-buttons';
import {withTheme} from "react-native-paper";
import * as Touchable from "react-native/Libraries/Components/Touchable/TouchableNativeFeedback.android";
const MaterialHeaderButton = (props: Object) => (
<HeaderButton
const MaterialHeaderButton = (props: Object) => <HeaderButton
IconComponent={MaterialCommunityIcons}
iconSize={26}
color={props.theme.colors.text}
color={props.color != null ? props.color : props.theme.colors.text}
background={Touchable.Ripple(props.theme.colors.ripple, true)}
{...props}
/>
);
/>;
const MaterialHeaderButtons = (props: Object) => {
return (

View file

@ -1,13 +1,14 @@
// @flow
import * as React from 'react';
import {LinearGradient} from "expo-linear-gradient";
import {Image, StyleSheet, View} from "react-native";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import {Image, Platform, StatusBar, StyleSheet, View} from "react-native";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
import {Text} from "react-native-paper";
import i18n from 'i18n-js';
import AppIntroSlider from "react-native-app-intro-slider";
import Update from "../../constants/Update";
import ThemeManager from "../../managers/ThemeManager";
import LinearGradient from 'react-native-linear-gradient';
type Props = {
onDone: Function,
@ -20,75 +21,83 @@ type Props = {
*/
export default class CustomIntroSlider extends React.Component<Props> {
sliderRef: {current: null | AppIntroSlider};
introSlides: Array<Object>;
updateSlides: Array<Object>;
aprilFoolsSlides: Array<Object>;
currentSlides: Array<Object>;
/**
* Generates intro slides
*/
constructor() {
super();
this.sliderRef = React.createRef();
this.introSlides = [
{
key: '1',
title: i18n.t('intro.slide1.title'),
text: i18n.t('intro.slide1.text'),
image: require('../../../assets/splash.png'),
colors: ['#e01928', '#be1522'],
colors: ['#dc2634', '#be1522'],
},
{
key: '2',
title: i18n.t('intro.slide2.title'),
text: i18n.t('intro.slide2.text'),
icon: 'calendar-range',
colors: ['#d99e09', '#c28d08'],
colors: ['#d99e09', '#9e7205'],
},
{
key: '3',
title: i18n.t('intro.slide3.title'),
text: i18n.t('intro.slide3.text'),
icon: 'washing-machine',
colors: ['#1fa5ee', '#1c97da'],
colors: ['#1fa5ee', '#0976b1'],
},
{
key: '4',
title: i18n.t('intro.slide4.title'),
text: i18n.t('intro.slide4.text'),
icon: 'shopping',
colors: ['#ec5904', '#da5204'],
colors: ['#ec5904', '#b64300'],
},
{
key: '5',
title: i18n.t('intro.slide5.title'),
text: i18n.t('intro.slide5.text'),
icon: 'timetable',
colors: ['#7c33ec', '#732fda'],
colors: ['#7c33ec', '#5e11d1'],
},
{
key: '6',
title: i18n.t('intro.slide6.title'),
text: i18n.t('intro.slide6.text'),
icon: 'silverware-fork-knife',
colors: ['#ec1213', '#ff372f'],
colors: ['#ec1213', '#970902'],
},
{
key: '7',
title: i18n.t('intro.slide7.title'),
text: i18n.t('intro.slide7.text'),
icon: 'cogs',
colors: ['#37c13e', '#26852b'],
},
];
this.updateSlides = [
{
key: '1',
title: Update.getInstance().title,
text: Update.getInstance().description,
icon: Update.icon,
colors: ['#e01928', '#be1522'],
colors: ['#37c13e', '#1a5a1d'],
},
];
this.updateSlides = [];
for (let i = 0; i < Update.slidesNumber; i++) {
this.updateSlides.push(
{
key: i.toString(),
title: Update.getInstance().titleList[i],
text: Update.getInstance().descriptionList[i],
icon: Update.iconList[i],
colors: Update.colorsList[i],
},
);
}
this.aprilFoolsSlides = [
{
key: '1',
@ -108,7 +117,6 @@ export default class CustomIntroSlider extends React.Component<Props> {
* @param dimensions Dimensions of the item
*/
static getIntroRenderItem({item, dimensions}: Object) {
return (
<LinearGradient
style={[
@ -120,7 +128,13 @@ export default class CustomIntroSlider extends React.Component<Props> {
end={{x: 0.1, y: 1}}
>
{item.image !== undefined ?
<Image source={item.image} style={styles.image}/>
<View style={styles.image}>
<Image
source={item.image}
resizeMode={"contain"}
style={{width: '100%', height: '100%'}}
/>
</View>
: <MaterialCommunityIcons
name={item.icon}
color={'#fff'}
@ -133,19 +147,43 @@ export default class CustomIntroSlider extends React.Component<Props> {
);
}
setStatusBarColor(color: string) {
if (Platform.OS === 'android')
StatusBar.setBackgroundColor(color, true);
}
onSlideChange = (index: number, lastIndex: number) => {
this.setStatusBarColor(this.currentSlides[index].colors[0]);
};
onSkip = () => {
this.setStatusBarColor(this.currentSlides[this.currentSlides.length-1].colors[0]);
if (this.sliderRef.current != null)
this.sliderRef.current.goToSlide(this.currentSlides.length-1);
}
onDone = () => {
this.setStatusBarColor(ThemeManager.getCurrentTheme().colors.surface);
this.props.onDone();
}
render() {
let slides = this.introSlides;
this.currentSlides = this.introSlides;
if (this.props.isUpdate)
slides = this.updateSlides;
this.currentSlides = this.updateSlides;
else if (this.props.isAprilFools)
slides = this.aprilFoolsSlides;
this.currentSlides = this.aprilFoolsSlides;
this.setStatusBarColor(this.currentSlides[0].colors[0]);
return (
<AppIntroSlider
ref={this.sliderRef}
renderItem={CustomIntroSlider.getIntroRenderItem}
data={slides}
onDone={this.props.onDone}
data={this.currentSlides}
onDone={this.onDone}
bottomButton
showSkipButton
onSlideChange={this.onSlideChange}
onSkip={this.onSkip}
skipLabel={i18n.t('intro.buttons.skip')}
doneLabel={i18n.t('intro.buttons.done')}
nextLabel={i18n.t('intro.buttons.next')}

View file

@ -0,0 +1,58 @@
// @flow
import * as React from 'react';
import {Text, withTheme} from 'react-native-paper';
import {View} from "react-native-animatable";
import type {CustomTheme} from "../../managers/ThemeManager";
import Slider, {SliderProps} from "@react-native-community/slider";
type Props = {
theme: CustomTheme,
valueSuffix: string,
...SliderProps
}
type State = {
currentValue: number,
}
/**
* Abstraction layer for Modalize component, using custom configuration
*
* @param props Props to pass to the element. Must specify an onRef prop to get an Modalize ref.
* @return {*}
*/
class CustomSlider extends React.Component<Props, State> {
static defaultProps = {
valueSuffix: "",
}
state = {
currentValue: this.props.value,
}
onValueChange = (value: number) => {
this.setState({currentValue: value});
if (this.props.onValueChange != null)
this.props.onValueChange(value);
}
render() {
return (
<View style={{flex: 1, flexDirection: 'row'}}>
<Text style={{marginHorizontal: 10, marginTop: 'auto', marginBottom: 'auto'}}>
{this.state.currentValue}min
</Text>
<Slider
{...this.props}
onValueChange={this.onValueChange}
/>
</View>
);
}
}
export default withTheme(CustomSlider);

View file

@ -3,7 +3,7 @@
import * as React from 'react';
import {Button, Subheading, withTheme} from 'react-native-paper';
import {StyleSheet, View} from "react-native";
import {MaterialCommunityIcons} from "@expo/vector-icons";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
import i18n from 'i18n-js';
import {ERROR_TYPE} from "../../utils/WebData";
import * as Animatable from 'react-native-animatable';

View file

@ -22,6 +22,7 @@ type Props = {
onScroll: (event: SyntheticEvent<EventTarget>) => void,
collapsibleStack: Collapsible,
showError: boolean,
itemHeight?: number,
updateData?: number,
renderSectionHeader?: (data: { [key: string]: any }) => React.Node,
@ -49,6 +50,7 @@ class WebSectionList extends React.PureComponent<Props, State> {
static defaultProps = {
stickyHeader: false,
updateData: 0,
showError: true,
};
scrollRef: { current: null | Animated.SectionList };
@ -202,8 +204,12 @@ class WebSectionList extends React.PureComponent<Props, State> {
render() {
let dataset = [];
if (this.state.fetchedData != null)
dataset = this.props.createDataset(this.state.fetchedData);
if (this.state.fetchedData != null || (this.state.fetchedData == null && !this.props.showError)) {
if (this.state.fetchedData == null)
dataset = this.props.createDataset({});
else
dataset = this.props.createDataset(this.state.fetchedData);
}
const {containerPaddingTop, scrollIndicatorInsetTop, onScrollWithListener} = this.props.collapsibleStack;
return (
<View>

View file

@ -7,9 +7,8 @@ import ErrorView from "./ErrorView";
import {ERROR_TYPE} from "../../utils/WebData";
import MaterialHeaderButtons, {Item} from '../Overrides/CustomHeaderButton';
import {HiddenItem} from "react-navigation-header-buttons";
import {Linking} from "expo";
import i18n from 'i18n-js';
import {Animated, BackHandler} from "react-native";
import {Animated, BackHandler, Linking} from "react-native";
import {withCollapsible} from "../../utils/withCollapsible";
type Props = {
@ -19,6 +18,7 @@ type Props = {
collapsibleStack: Object,
onMessage: Function,
onScroll: Function,
showAdvancedControls: boolean,
}
const AnimatedWebView = Animated.createAnimatedComponent(WebView);
@ -30,6 +30,7 @@ class WebViewScreen extends React.PureComponent<Props> {
static defaultProps = {
customJS: '',
showAdvancedControls: true,
};
webviewRef: Object;
@ -46,9 +47,10 @@ class WebViewScreen extends React.PureComponent<Props> {
* Creates refresh button after mounting
*/
componentDidMount() {
const rightButton = this.getRefreshButton.bind(this);
this.props.navigation.setOptions({
headerRight: rightButton,
headerRight: this.props.showAdvancedControls
? this.getAdvancedButtons
: this.getBasicButton,
});
this.props.navigation.addListener(
'focus',
@ -81,7 +83,22 @@ class WebViewScreen extends React.PureComponent<Props> {
*
* @return {*}
*/
getRefreshButton() {
getBasicButton = () => {
return (
<MaterialHeaderButtons>
<Item
title="refresh"
iconName="refresh"
onPress={this.onRefreshClicked}/>
<Item
title={i18n.t("general.openInBrowser")}
iconName="open-in-new"
onPress={this.onOpenClicked}/>
</MaterialHeaderButtons>
);
};
getAdvancedButtons = () => {
return (
<MaterialHeaderButtons>
<Item
@ -102,7 +119,7 @@ class WebViewScreen extends React.PureComponent<Props> {
onPress={this.onOpenClicked}/>
</MaterialHeaderButtons>
);
};
}
/**
* Callback to use when refresh button is clicked. Reloads the webview.

View file

@ -1,148 +0,0 @@
// @flow
import * as React from 'react';
import {FlatList} from "react-native";
import {Drawer, withTheme} from 'react-native-paper';
import {Linking} from "expo";
import AnimatedAccordion from "../Animations/AnimatedAccordion";
import {StackActions} from '@react-navigation/native';
type Props = {
navigation: Object,
startOpen: boolean,
isLoggedIn: boolean,
sectionName: string,
activeRoute: string,
listKey: string,
listData: Array<Object>,
}
const LIST_ITEM_HEIGHT = 48;
class SideBarSection extends React.PureComponent<Props> {
colors: Object;
accordionRef: {current: null | AnimatedAccordion};
constructor(props) {
super(props);
this.colors = props.theme.colors;
this.accordionRef = React.createRef();
}
/**
* Searches if the current route is contained in the given list data.
* If this is the case and the list is collapsed, we should expand this list.
*
* @return boolean
*/
shouldExpandList() {
for (let i = 0; i < this.props.listData.length; i++) {
if (this.props.listData[i].route === this.props.activeRoute) {
return true;
}
}
return false;
}
/**
* Callback when a drawer item is pressed.
* It will either navigate to the associated screen, or open the browser to the associated link
*
* @param item The item pressed
*/
onListItemPress(item: Object) {
if (item.link !== undefined)
Linking.openURL(item.link);
else if (item.action !== undefined)
item.action();
else if (this.props.activeRoute === "main")
this.props.navigation.navigate(item.route);
else {
this.props.navigation.dispatch(
StackActions.replace(item.route)
);
this.props.navigation.closeDrawer();
}
}
/**
* Key extractor for list items
*
* @param item The item to extract the key from
* @return {string} The extracted key
*/
listKeyExtractor = (item: Object) => item.route;
shouldHideItem(item: Object) {
const onlyWhenLoggedOut = item.onlyWhenLoggedOut !== undefined && item.onlyWhenLoggedOut === true;
const onlyWhenLoggedIn = item.onlyWhenLoggedIn !== undefined && item.onlyWhenLoggedIn === true;
return (onlyWhenLoggedIn && !this.props.isLoggedIn || onlyWhenLoggedOut && this.props.isLoggedIn);
}
/**
* Gets the render item for the given list item
*
* @param item The item to render
* @return {*}
*/
getRenderItem = ({item}: Object) => {
const onListItemPress = this.onListItemPress.bind(this, item);
if (this.shouldHideItem(item))
return null;
return (
<Drawer.Item
label={item.name}
active={this.props.activeRoute === item.route}
icon={item.icon}
onPress={onListItemPress}
style={{
height: LIST_ITEM_HEIGHT,
justifyContent: 'center',
}}
/>
);
};
shouldRenderAccordion() {
let itemsToRender = 0;
for (let i = 0; i < this.props.listData.length; i++) {
if (!this.shouldHideItem(this.props.listData[i]))
itemsToRender += 1;
}
return itemsToRender > 1;
}
itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
getFlatList() {
return (
// $FlowFixMe
<FlatList
data={this.props.listData}
extraData={this.props.isLoggedIn.toString() + this.props.activeRoute}
renderItem={this.getRenderItem}
keyExtractor={this.listKeyExtractor}
listKey={this.props.listKey}
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
getItemLayout={this.itemLayout}
/>
);
}
render() {
if (this.shouldRenderAccordion()) {
return (
<AnimatedAccordion
title={this.props.sectionName}
keepOpen={this.shouldExpandList()}
>
{this.getFlatList()}
</AnimatedAccordion>
);
} else
return this.getFlatList();
}
}
export default withTheme(SideBarSection);

View file

@ -1,267 +0,0 @@
// @flow
import * as React from 'react';
import {Dimensions, FlatList, Image, StyleSheet, View,} from 'react-native';
import i18n from "i18n-js";
import {TouchableRipple} from "react-native-paper";
import ConnectionManager from "../../managers/ConnectionManager";
import LogoutDialog from "../Amicale/LogoutDialog";
import SideBarSection from "./SideBarSection";
import {DrawerNavigationProp} from "@react-navigation/drawer";
const deviceWidth = Dimensions.get("window").width;
type Props = {
navigation: DrawerNavigationProp,
state: {[key: string] : any},
theme?: Object,
};
type State = {
isLoggedIn: boolean,
dialogVisible: boolean,
};
/**
* Component used to render the drawer menu content
*/
class SideBar extends React.Component<Props, State> {
dataSet: Array<Object>;
activeRoute: string;
/**
* Generate the dataset
*
* @param props
*/
constructor(props: Props) {
super(props);
this.activeRoute = 'main';
// Dataset used to render the drawer
const mainData = [
{
name: i18n.t('screens.home'),
route: "main",
icon: "home",
},
];
const amicaleData = [
{
name: i18n.t('screens.login'),
route: "login",
icon: "login",
onlyWhenLoggedOut: true,
shouldEmphasis: true,
},
{
name: i18n.t('screens.amicaleAbout'),
route: "amicale-contact",
icon: "information",
},
{
name: i18n.t('screens.profile'),
route: "profile",
icon: "account",
onlyWhenLoggedIn: true,
},
{
name: i18n.t('clubs.clubList'),
route: "club-list",
icon: "account-group",
onlyWhenLoggedIn: true,
},
{
name: i18n.t('screens.vote'),
route: "vote",
icon: "vote",
onlyWhenLoggedIn: true,
},
{
name: i18n.t('screens.logout'),
route: 'disconnect',
action: this.showDisconnectDialog,
icon: "logout",
onlyWhenLoggedIn: true,
},
];
const servicesData = [
{
name: i18n.t('screens.menuSelf'),
route: "self-menu",
icon: "silverware-fork-knife",
},
{
name: i18n.t('screens.availableRooms'),
route: "available-rooms",
icon: "calendar-check",
},
{
name: i18n.t('screens.bib'),
route: "bib",
icon: "book",
},
{
name: i18n.t('screens.bluemind'),
route: "bluemind",
link: "https://etud-mel.insa-toulouse.fr/webmail/",
icon: "email",
},
{
name: i18n.t('screens.ent'),
route: "ent",
link: "https://ent.insa-toulouse.fr/",
icon: "notebook",
},
];
const websitesData = [
{
name: "Amicale",
route: "amicale-website",
icon: "alpha-a-box",
},
{
name: "Élus Étudiants",
route: "elus-etudiants",
icon: "alpha-e-box",
},
{
name: "Wiketud",
route: "wiketud",
icon: "wikipedia",
},
{
name: "Tutor'INSA",
route: "tutorinsa",
icon: "school",
},
];
const othersData = [
{
name: i18n.t('screens.settings'),
route: "settings",
icon: "settings",
},
{
name: i18n.t('screens.about'),
route: "about",
icon: "information",
},
];
this.dataSet = [
{
key: '1',
name: i18n.t('screens.home'),
startOpen: true, // App always starts on Main
data: mainData
},
{
key: '2',
name: i18n.t('sidenav.divider4'),
startOpen: false, // TODO set by user preferences
data: amicaleData
},
{
key: '3',
name: i18n.t('sidenav.divider2'),
startOpen: false,
data: servicesData
},
{
key: '4',
name: i18n.t('sidenav.divider1'),
startOpen: false,
data: websitesData
},
{
key: '5',
name: i18n.t('sidenav.divider3'),
startOpen: false,
data: othersData
},
];
ConnectionManager.getInstance().addLoginStateListener(this.onLoginStateChange);
this.state = {
isLoggedIn: ConnectionManager.getInstance().isLoggedIn(),
dialogVisible: false,
};
}
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
const nextNavigationState = nextProps.state.routes[0].state;
const nextRoute = nextNavigationState.routes[nextNavigationState.index].name;
let currentRoute = "main";
const currentNavigationState = this.props.state.routes[0].state;
if (currentNavigationState != null) {
currentRoute = currentNavigationState.routes[currentNavigationState.index].name;
}
this.activeRoute = nextRoute;
return (nextState !== this.state)
|| (nextRoute !== currentRoute);
}
showDisconnectDialog = () => this.setState({dialogVisible: true});
hideDisconnectDialog = () => this.setState({dialogVisible: false});
onLoginStateChange = (isLoggedIn: boolean) => this.setState({isLoggedIn: isLoggedIn});
/**
* Gets the render item for the given list item
*
* @param item The item to render
* @return {*}
*/
getRenderItem = ({item}: Object) => {
return <SideBarSection
{...this.props}
listKey={item.key}
activeRoute={this.activeRoute}
isLoggedIn={this.state.isLoggedIn}
sectionName={item.name}
startOpen={item.startOpen}
listData={item.data}
/>
};
render() {
return (
<View style={{height: '100%'}}>
<TouchableRipple
onPress={() => this.props.navigation.navigate("tetris")}
>
<Image
source={require("../../../assets/drawer-cover.png")}
style={styles.drawerCover}
/>
</TouchableRipple>
{/*$FlowFixMe*/}
<FlatList
data={this.dataSet}
extraData={this.state.isLoggedIn.toString() + this.activeRoute}
renderItem={this.getRenderItem}
/>
<LogoutDialog
{...this.props}
visible={this.state.dialogVisible}
onDismiss={this.hideDisconnectDialog}
/>
</View>
);
}
}
const styles = StyleSheet.create({
drawerCover: {
height: deviceWidth / 3,
width: 2 * deviceWidth / 3,
position: "relative",
marginBottom: 10,
marginTop: 20
},
});
export default SideBar;

View file

@ -18,9 +18,9 @@ type State = {
}
const TAB_ICONS = {
planning: 'calendar-range',
proxiwash: 'tshirt-crew',
proximo: 'cart',
services: 'account-circle',
planning: 'calendar-range',
planex: 'clock',
};
@ -31,26 +31,16 @@ class CustomTabBar extends React.Component<Props, State> {
static TAB_BAR_HEIGHT = 48;
activeColor: string;
inactiveColor: string;
state = {
translateY: new Animated.Value(0),
barSynced: false,// Is the bar synced with the header for animations?
}
// shouldComponentUpdate(nextProps: Props): boolean {
// return (nextProps.theme.dark !== this.props.theme.dark)
// || (nextProps.state.index !== this.props.state.index);
// }
tabRef: Object;
constructor(props) {
super(props);
this.tabRef = React.createRef();
this.activeColor = props.theme.colors.primary;
this.inactiveColor = props.theme.colors.tabIcon;
}
onItemPress(route: Object, currentIndex: number, destIndex: number) {
@ -65,6 +55,17 @@ class CustomTabBar extends React.Component<Props, State> {
}
}
onItemLongPress(route: Object) {
const event = this.props.navigation.emit({
type: 'tabLongPress',
target: route.key,
canPreventDefault: true,
});
if (route.name === "home" && !event.defaultPrevented) {
this.props.navigation.navigate('tetris');
}
}
tabBarIcon = (route, focused) => {
let icon = TAB_ICONS[route.name];
icon = focused ? icon : icon + ('-outline');
@ -93,12 +94,8 @@ class CustomTabBar extends React.Component<Props, State> {
const onPress = () => this.onItemPress(route, state.index, index);
const onLongPress = () => {
this.props.navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
const onLongPress = () => this.onItemLongPress(route);
if (isFocused) {
const stackState = route.state;
const stackRoute = route.state ? stackState.routes[stackState.index] : undefined;
@ -112,7 +109,7 @@ class CustomTabBar extends React.Component<Props, State> {
}
}
const color = isFocused ? this.activeColor : this.inactiveColor;
const color = isFocused ? this.props.theme.colors.primary : this.props.theme.colors.tabIcon;
if (route.name !== "home") {
return <TabIcon
onPress={onPress}
@ -130,6 +127,7 @@ class CustomTabBar extends React.Component<Props, State> {
onLongPress={onLongPress}
focused={isFocused}
key={route.key}
tabBarHeight={CustomTabBar.TAB_BAR_HEIGHT}
/>
};

View file

@ -1,8 +1,8 @@
// @flow
import * as React from 'react';
import {Image, View} from "react-native";
import {FAB, withTheme} from 'react-native-paper';
import {Image, Platform, View} from "react-native";
import {FAB, TouchableRipple, withTheme} from 'react-native-paper';
import * as Animatable from "react-native-animatable";
type Props = {
@ -10,6 +10,7 @@ type Props = {
onPress: Function,
onLongPress: Function,
theme: Object,
tabBarHeight: number,
}
const AnimatedFAB = Animatable.createAnimatableComponent(FAB);
@ -65,23 +66,38 @@ class TabHomeIcon extends React.Component<Props> {
render(): React$Node {
const props = this.props;
return (
<View style={{
flex: 1,
justifyContent: 'center',
}}>
<AnimatedFAB
duration={200}
easing={"ease-out"}
animation={props.focused ? "fabFocusIn" : "fabFocusOut"}
useNativeDriver
<View
style={{
flex: 1,
justifyContent: 'center',
}}>
<TouchableRipple
onPress={props.onPress}
onLongPress={props.onLongPress}
icon={this.iconRender}
borderless={true}
rippleColor={Platform.OS === 'android' ? this.props.theme.colors.primary : 'transparent'}
style={{
marginLeft: 'auto',
marginRight: 'auto'
}}/>
position: 'absolute',
bottom: 0,
left: 0,
width: '100%',
height: this.props.tabBarHeight + 30,
marginBottom: -15,
}}
>
<AnimatedFAB
duration={200}
easing={"ease-out"}
animation={props.focused ? "fabFocusIn" : "fabFocusOut"}
icon={this.iconRender}
style={{
marginTop: 15,
marginLeft: 'auto',
marginRight: 'auto'
}}/>
</TouchableRipple>
</View>
);
}

View file

@ -3,7 +3,7 @@
import * as React from 'react';
import {View} from "react-native";
import {TouchableRipple, withTheme} from 'react-native-paper';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
import * as Animatable from "react-native-animatable";
type Props = {
@ -69,10 +69,11 @@ class TabIcon extends React.Component<Props> {
<TouchableRipple
onPress={props.onPress}
onLongPress={props.onLongPress}
borderless={true}
rippleColor={this.props.theme.colors.primary}
style={{
flex: 1,
justifyContent: 'center',
alignItem: 'center',
}}
>
<View>

View file

@ -14,21 +14,38 @@ import i18n from "i18n-js";
export default class Update {
// Increment the number to show the update slide
static number = 5;
// Change the icon to be displayed on the update slide
static icon = 'surround-sound-2-0';
static number = 6;
// Change the number of slides to display
static slidesNumber = 4;
// Change the icons to be displayed on the update slide
static iconList = [
'star',
'clock',
'qrcode-scan',
'account',
];
static colorsList = [
['#e01928', '#be1522'],
['#7c33ec', '#5e11d1'],
['#337aec', '#114ed1'],
['#e01928', '#be1522'],
]
static instance: Update | null = null;
title: string;
description: string;
titleList: Array<string>;
descriptionList: Array<string>;
/**
* Init translations
*/
constructor() {
this.title = i18n.t('intro.updateSlide.title');
this.description = i18n.t('intro.updateSlide.text');
this.titleList = [];
this.descriptionList = [];
for (let i = 0; i < Update.slidesNumber; i++) {
this.titleList.push(i18n.t('intro.updateSlide'+ i + '.title'))
this.descriptionList.push(i18n.t('intro.updateSlide'+ i + '.text'))
}
}
/**

View file

@ -1,6 +1,6 @@
// @flow
import {AsyncStorage} from "react-native";
import AsyncStorage from '@react-native-community/async-storage';
/**
* Singleton used to manage preferences.
@ -69,6 +69,11 @@ export default class AsyncStorageManager {
default: '1',
current: '',
},
proxiwashWatchedMachines: {
key: 'proxiwashWatchedMachines',
default: '[]',
current: '',
},
planexShowBanner: {
key: 'planexShowBanner',
default: '1',

Some files were not shown because too many files have changed in this diff Show more