├── .gitignore ├── .metadata ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── androz2091 │ │ │ │ └── pronote_notifications │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── launcher_icon.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── launcher_icon.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── settings_aar.gradle ├── assets ├── icon.png ├── launcher-icon.png └── url-pronote.png ├── fonts └── ProductSans-Regular.ttf ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── Runner-Bridging-Header.h │ └── Runner.entitlements ├── lib ├── api.dart ├── firebase.dart ├── main.dart ├── pages │ ├── home.dart │ ├── login.dart │ ├── notifications.dart │ └── root.dart ├── url.dart └── widgets │ └── dialogs.dart ├── pubspec.lock ├── pubspec.yaml └── screenshots ├── badges ├── appstore.png └── playstore.png ├── ipad-4th-gen-129-inches ├── account.png ├── login.png └── notification.png ├── iphone-6s-plus-55-inches ├── account.png ├── login.png └── notification.png ├── iphone-xs-max-65-inches ├── account.png ├── login.png └── notification.png └── preview ├── account.png ├── login.png └── notification.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | 46 | # Firebase 47 | google-services.json 48 | GoogleService-Info.plist 49 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 216dee60c0cc9449f0b29bcf922974d612263e24 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": false, 3 | "[dart]": { 4 | "editor.formatOnSave": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Androz2091 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [🔔 Notifications pour Pronote](https://play.google.com/store/apps/details?id=com.androz2091.pronote_notifications&gl=FR) 2 | 3 | ## PROJET ABANDONNÉ 4 | 5 | Ce projet est désormais archivé. Il est tout à fait possible de le lancer de nouveau sur votre propre serveur mais il ne sera plus disponible en ligne et sur les stores à compter de juillet 2021, pour les raisons suivantes : 6 | * bans réguliers de la part de Pronote (ban de l'IP de l'API, et non pas des comptes, ce n'est donc pas risqué pour les utilisateurs, et tout à fait bypassable par des proxies - simplement cela demande du temps). 7 | * manque de temps des maintainers (Notif. pour Pronote est maintenue par Androz et certains membres de l'équipe de EduWireApps, qui ne sont plus disponibles). 8 | * quelques coups de pression de la part de Pronote pour supprimer l'appli (ils n'ont théoriquement aucune raison suffisante de faire l'effort de porter plainte, mais nous n'avons pas de temps à perdre avec ça si un tel évènement devait arriver). Cf message de Pronote (que nous avons gentiment ignoré pendant des mois pour vous permettre de continuer à bénéficier de l'appli :) 9 | 10 | 11 | 12 | Notifications pour Pronote est une application mobile qui étend les fonctionnalités de l'application [Pronote](https:/https://play.google.com/store/apps/details?id=com.IndexEducation.Pronote) en envoyant des notifications lors de l'ajout d'un devoir ou d'une note. 13 | 14 | ## Téléchargement 15 | 16 | 17 | 18 | 19 | ## Fonctionnalités 20 | 21 | * Envoi de notifications lorsqu'un devoir est ajouté sur Pronote 22 | * Envoi de notifications lorsqu'une note est ajoutée sur Pronote 23 | * Support de tous les collèges et lycées utilisant Pronote 24 | 25 | ### Prévues 26 | 27 | * Envoi de notifications lorsqu'un cours des deux prochaines semaines est annulé 28 | * Envoi de notifications lorsque la salle d'un cours des deux prochaines semaines est modifiée 29 | * Ajout d'un bouton `Supprimer mes données` 30 | 31 | ## Screenshots 32 | 33 |

34 | Login 35 | Account 36 | Notification 37 |

38 | 39 | ## Fonctionnement 40 | 41 | Pronote ne disposant pas d'API, le seul moyen de détecter des ajouts de devoirs/notes/... est de se connecter à un interval de temps régulier et de comparer le résultat avec le précédent, ce qui est effectué par [l'API de l'application](https://github.com/pronote-notifications/pronote-notifications-api). Pour cela, l'API doit disposer au préalable des identifiants des utilisateurs et les mots de passes sont donc stockés par l'API pour se connecter automatiquement. Un bouton pour supprimer les données est prévu mais n'est pas encore disponible. Si vous souhaitez que vos données soient supprimées, vous pouvez m'envoyer un mail (`androz2091@gmail.com`). 42 | 43 | Le code est entièrement open source : 44 | 45 | * [repository de l'application mobile](https://github.com/pronote-notifications/pronote-notifications-app) 46 | * [repository de l'API de l'application](https://github.com/pronote-notifications/pronote-notifications-api) 47 | 48 | ## Build 49 | 50 | * Installer le SDK flutter. 51 | * Construire l'application : `flutter build apk --split-per-abi --no-sound-null-safety`. 52 | * Tester l'application : `flutter run`. 53 | 54 | ### Made with 55 | 56 | **Flutter** (front-end) 57 | **Node.js** (back-end) 58 | **PostgreSQL** (base de données) 59 | **Firebase** (notifications) 60 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | def keystoreProperties = new Properties() 29 | def keystorePropertiesFile = rootProject.file('key.properties') 30 | if (keystorePropertiesFile.exists()) { 31 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 32 | } 33 | 34 | android { 35 | compileSdkVersion 29 36 | 37 | sourceSets { 38 | main.java.srcDirs += 'src/main/kotlin' 39 | } 40 | 41 | lintOptions { 42 | disable 'InvalidPackage' 43 | } 44 | 45 | defaultConfig { 46 | applicationId "com.androz2091.pronote_notifications" 47 | minSdkVersion 16 48 | targetSdkVersion 29 49 | versionCode flutterVersionCode.toInteger() 50 | versionName flutterVersionName 51 | } 52 | 53 | signingConfigs { 54 | release { 55 | keyAlias keystoreProperties['keyAlias'] 56 | keyPassword keystoreProperties['keyPassword'] 57 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null 58 | storePassword keystoreProperties['storePassword'] 59 | } 60 | } 61 | 62 | buildTypes { 63 | release { 64 | signingConfig signingConfigs.release 65 | } 66 | } 67 | } 68 | 69 | flutter { 70 | source '../..' 71 | } 72 | 73 | dependencies { 74 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 75 | } 76 | 77 | apply plugin: 'com.google.gms.google-services' 78 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 11 | 18 | 22 | 26 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/androz2091/pronote_notifications/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.androz2091.pronote_notifications 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-hdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-mdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.gms:google-services:4.3.4' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | } 26 | subprojects { 27 | project.evaluationDependsOn(':app') 28 | } 29 | 30 | task clean(type: Delete) { 31 | delete rootProject.buildDir 32 | } 33 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/assets/icon.png -------------------------------------------------------------------------------- /assets/launcher-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/assets/launcher-icon.png -------------------------------------------------------------------------------- /assets/url-pronote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/assets/url-pronote.png -------------------------------------------------------------------------------- /fonts/ProductSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/fonts/ProductSans-Regular.ttf -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig" 3 | #include "Generated.xcconfig" 4 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '10.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - connectivity (0.0.1): 3 | - Flutter 4 | - Reachability 5 | - external_app_launcher (0.0.1): 6 | - Flutter 7 | - Firebase/CoreOnly (7.3.0): 8 | - FirebaseCore (= 7.3.0) 9 | - Firebase/Messaging (7.3.0): 10 | - Firebase/CoreOnly 11 | - FirebaseMessaging (~> 7.3.0) 12 | - firebase_core (1.0.3): 13 | - Firebase/CoreOnly (= 7.3.0) 14 | - Flutter 15 | - firebase_messaging (9.1.1): 16 | - Firebase/Messaging (= 7.3.0) 17 | - firebase_core 18 | - Flutter 19 | - FirebaseCore (7.3.0): 20 | - FirebaseCoreDiagnostics (~> 7.0) 21 | - GoogleUtilities/Environment (~> 7.0) 22 | - GoogleUtilities/Logger (~> 7.0) 23 | - FirebaseCoreDiagnostics (7.8.0): 24 | - GoogleDataTransport (~> 8.0) 25 | - GoogleUtilities/Environment (~> 7.0) 26 | - GoogleUtilities/Logger (~> 7.0) 27 | - nanopb (~> 2.30907.0) 28 | - FirebaseInstallations (7.8.0): 29 | - FirebaseCore (~> 7.0) 30 | - GoogleUtilities/Environment (~> 7.0) 31 | - GoogleUtilities/UserDefaults (~> 7.0) 32 | - PromisesObjC (~> 1.2) 33 | - FirebaseInstanceID (7.8.0): 34 | - FirebaseCore (~> 7.0) 35 | - FirebaseInstallations (~> 7.0) 36 | - GoogleUtilities/Environment (~> 7.0) 37 | - GoogleUtilities/UserDefaults (~> 7.0) 38 | - FirebaseMessaging (7.3.0): 39 | - FirebaseCore (~> 7.0) 40 | - FirebaseInstanceID (~> 7.0) 41 | - GoogleUtilities/AppDelegateSwizzler (~> 7.0) 42 | - GoogleUtilities/Environment (~> 7.0) 43 | - GoogleUtilities/Reachability (~> 7.0) 44 | - GoogleUtilities/UserDefaults (~> 7.0) 45 | - Flutter (1.0.0) 46 | - flutter_local_notifications (0.0.1): 47 | - Flutter 48 | - geolocator (6.2.0): 49 | - Flutter 50 | - GoogleDataTransport (8.3.0): 51 | - GoogleUtilities/Environment (~> 7.2) 52 | - nanopb (~> 2.30907.0) 53 | - PromisesObjC (~> 1.2) 54 | - GoogleUtilities/AppDelegateSwizzler (7.3.1): 55 | - GoogleUtilities/Environment 56 | - GoogleUtilities/Logger 57 | - GoogleUtilities/Network 58 | - GoogleUtilities/Environment (7.3.1): 59 | - PromisesObjC (~> 1.2) 60 | - GoogleUtilities/Logger (7.3.1): 61 | - GoogleUtilities/Environment 62 | - GoogleUtilities/Network (7.3.1): 63 | - GoogleUtilities/Logger 64 | - "GoogleUtilities/NSData+zlib" 65 | - GoogleUtilities/Reachability 66 | - "GoogleUtilities/NSData+zlib (7.3.1)" 67 | - GoogleUtilities/Reachability (7.3.1): 68 | - GoogleUtilities/Logger 69 | - GoogleUtilities/UserDefaults (7.3.1): 70 | - GoogleUtilities/Logger 71 | - in_app_review (0.2.0): 72 | - Flutter 73 | - nanopb (2.30907.0): 74 | - nanopb/decode (= 2.30907.0) 75 | - nanopb/encode (= 2.30907.0) 76 | - nanopb/decode (2.30907.0) 77 | - nanopb/encode (2.30907.0) 78 | - package_info (0.0.1): 79 | - Flutter 80 | - PromisesObjC (1.2.12) 81 | - Reachability (3.2) 82 | - shared_preferences (0.0.1): 83 | - Flutter 84 | - url_launcher (0.0.1): 85 | - Flutter 86 | 87 | DEPENDENCIES: 88 | - connectivity (from `.symlinks/plugins/connectivity/ios`) 89 | - external_app_launcher (from `.symlinks/plugins/external_app_launcher/ios`) 90 | - firebase_core (from `.symlinks/plugins/firebase_core/ios`) 91 | - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) 92 | - Flutter (from `Flutter`) 93 | - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) 94 | - geolocator (from `.symlinks/plugins/geolocator/ios`) 95 | - in_app_review (from `.symlinks/plugins/in_app_review/ios`) 96 | - package_info (from `.symlinks/plugins/package_info/ios`) 97 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 98 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`) 99 | 100 | SPEC REPOS: 101 | trunk: 102 | - Firebase 103 | - FirebaseCore 104 | - FirebaseCoreDiagnostics 105 | - FirebaseInstallations 106 | - FirebaseInstanceID 107 | - FirebaseMessaging 108 | - GoogleDataTransport 109 | - GoogleUtilities 110 | - nanopb 111 | - PromisesObjC 112 | - Reachability 113 | 114 | EXTERNAL SOURCES: 115 | connectivity: 116 | :path: ".symlinks/plugins/connectivity/ios" 117 | external_app_launcher: 118 | :path: ".symlinks/plugins/external_app_launcher/ios" 119 | firebase_core: 120 | :path: ".symlinks/plugins/firebase_core/ios" 121 | firebase_messaging: 122 | :path: ".symlinks/plugins/firebase_messaging/ios" 123 | Flutter: 124 | :path: Flutter 125 | flutter_local_notifications: 126 | :path: ".symlinks/plugins/flutter_local_notifications/ios" 127 | geolocator: 128 | :path: ".symlinks/plugins/geolocator/ios" 129 | in_app_review: 130 | :path: ".symlinks/plugins/in_app_review/ios" 131 | package_info: 132 | :path: ".symlinks/plugins/package_info/ios" 133 | shared_preferences: 134 | :path: ".symlinks/plugins/shared_preferences/ios" 135 | url_launcher: 136 | :path: ".symlinks/plugins/url_launcher/ios" 137 | 138 | SPEC CHECKSUMS: 139 | connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 140 | external_app_launcher: ad55ac844aa21f2d2197d7cec58ff0d0dc40bbc0 141 | Firebase: 26223c695fe322633274198cb19dca8cb7e54416 142 | firebase_core: b5d81dfd4fb2d6f700e67de34d9a633ae325c4e9 143 | firebase_messaging: 7547c99f31466371f9cfcb733d5a1bf32a819872 144 | FirebaseCore: 4d3c72622ce0e2106aaa07bb4b2935ba2c370972 145 | FirebaseCoreDiagnostics: 066f996579cf097bdad3d7dc9a918d6b9e129c50 146 | FirebaseInstallations: 7f7ed0e7e27fb51f57291e1876e2ddb1524126c1 147 | FirebaseInstanceID: aaecc93b4528bbcafea12c477e26827719ca1183 148 | FirebaseMessaging: 68d1bcb14880189558a8ae57167abe0b7e417232 149 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c 150 | flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 151 | geolocator: f5e3de65e241caba7ce3e8a618803387bda73384 152 | GoogleDataTransport: b006084b73915a42c28a3466961a4edda3065da6 153 | GoogleUtilities: e1d9ed4e544fc32a93e00e721400cbc3f377200d 154 | in_app_review: 4a97249f7a2f539a0f294c2d9196b7fe35e49541 155 | nanopb: 59221d7f958fb711001e6a449489542d92ae113e 156 | package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 157 | PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 158 | Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 159 | shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d 160 | url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef 161 | 162 | PODFILE CHECKSUM: fe0e1ee7f3d1f7d00b11b474b62dd62134535aea 163 | 164 | COCOAPODS: 1.10.1 165 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | E8E3628C49229436E0D91DEB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DEDA0134818319F1A939D90 /* Pods_Runner.framework */; }; 17 | F4A256AE260A356200D453F2 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = F4A256AD260A356200D453F2 /* GoogleService-Info.plist */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 120717558FC326B8276A2065 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 37 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 42 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 43 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 9DEDA0134818319F1A939D90 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | B633E0909F9D4A7915EF7225 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 50 | F49698622634B8490049E0F5 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; 51 | F4A256AD260A356200D453F2 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 52 | F830D590A3BA1B1FC6C456E7 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | E8E3628C49229436E0D91DEB /* Pods_Runner.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 2BCE7ABA1CD0BFB72065BC14 /* Frameworks */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 9DEDA0134818319F1A939D90 /* Pods_Runner.framework */, 71 | ); 72 | name = Frameworks; 73 | sourceTree = ""; 74 | }; 75 | 584C427145F879CB2D0CBA58 /* Pods */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | B633E0909F9D4A7915EF7225 /* Pods-Runner.debug.xcconfig */, 79 | 120717558FC326B8276A2065 /* Pods-Runner.release.xcconfig */, 80 | F830D590A3BA1B1FC6C456E7 /* Pods-Runner.profile.xcconfig */, 81 | ); 82 | path = Pods; 83 | sourceTree = ""; 84 | }; 85 | 9740EEB11CF90186004384FC /* Flutter */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 89 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 90 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 91 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 92 | ); 93 | name = Flutter; 94 | sourceTree = ""; 95 | }; 96 | 97C146E51CF9000F007C117D = { 97 | isa = PBXGroup; 98 | children = ( 99 | 9740EEB11CF90186004384FC /* Flutter */, 100 | 97C146F01CF9000F007C117D /* Runner */, 101 | 97C146EF1CF9000F007C117D /* Products */, 102 | 584C427145F879CB2D0CBA58 /* Pods */, 103 | 2BCE7ABA1CD0BFB72065BC14 /* Frameworks */, 104 | ); 105 | sourceTree = ""; 106 | }; 107 | 97C146EF1CF9000F007C117D /* Products */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 97C146EE1CF9000F007C117D /* Runner.app */, 111 | ); 112 | name = Products; 113 | sourceTree = ""; 114 | }; 115 | 97C146F01CF9000F007C117D /* Runner */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | F49698622634B8490049E0F5 /* Runner.entitlements */, 119 | F4A256AD260A356200D453F2 /* GoogleService-Info.plist */, 120 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 121 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 122 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 123 | 97C147021CF9000F007C117D /* Info.plist */, 124 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 125 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 126 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 127 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 128 | ); 129 | path = Runner; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | 97C146ED1CF9000F007C117D /* Runner */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 138 | buildPhases = ( 139 | 1150A8C51EC8DFF13E9455FA /* [CP] Check Pods Manifest.lock */, 140 | 9740EEB61CF901F6004384FC /* Run Script */, 141 | 97C146EA1CF9000F007C117D /* Sources */, 142 | 97C146EB1CF9000F007C117D /* Frameworks */, 143 | 97C146EC1CF9000F007C117D /* Resources */, 144 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 145 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 146 | E8992D219F7C43BAE8308C3A /* [CP] Embed Pods Frameworks */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = Runner; 153 | productName = Runner; 154 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 155 | productType = "com.apple.product-type.application"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | 97C146E61CF9000F007C117D /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | LastUpgradeCheck = 1020; 164 | ORGANIZATIONNAME = ""; 165 | TargetAttributes = { 166 | 97C146ED1CF9000F007C117D = { 167 | CreatedOnToolsVersion = 7.3.1; 168 | LastSwiftMigration = 1100; 169 | }; 170 | }; 171 | }; 172 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 173 | compatibilityVersion = "Xcode 9.3"; 174 | developmentRegion = en; 175 | hasScannedForEncodings = 0; 176 | knownRegions = ( 177 | en, 178 | Base, 179 | ); 180 | mainGroup = 97C146E51CF9000F007C117D; 181 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 182 | projectDirPath = ""; 183 | projectRoot = ""; 184 | targets = ( 185 | 97C146ED1CF9000F007C117D /* Runner */, 186 | ); 187 | }; 188 | /* End PBXProject section */ 189 | 190 | /* Begin PBXResourcesBuildPhase section */ 191 | 97C146EC1CF9000F007C117D /* Resources */ = { 192 | isa = PBXResourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 196 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 197 | F4A256AE260A356200D453F2 /* GoogleService-Info.plist in Resources */, 198 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 199 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | /* End PBXResourcesBuildPhase section */ 204 | 205 | /* Begin PBXShellScriptBuildPhase section */ 206 | 1150A8C51EC8DFF13E9455FA /* [CP] Check Pods Manifest.lock */ = { 207 | isa = PBXShellScriptBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | ); 211 | inputFileListPaths = ( 212 | ); 213 | inputPaths = ( 214 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 215 | "${PODS_ROOT}/Manifest.lock", 216 | ); 217 | name = "[CP] Check Pods Manifest.lock"; 218 | outputFileListPaths = ( 219 | ); 220 | outputPaths = ( 221 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | shellPath = /bin/sh; 225 | 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"; 226 | showEnvVarsInLog = 0; 227 | }; 228 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 229 | isa = PBXShellScriptBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | ); 233 | inputPaths = ( 234 | ); 235 | name = "Thin Binary"; 236 | outputPaths = ( 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | shellPath = /bin/sh; 240 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 241 | }; 242 | 9740EEB61CF901F6004384FC /* Run Script */ = { 243 | isa = PBXShellScriptBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputPaths = ( 248 | ); 249 | name = "Run Script"; 250 | outputPaths = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 255 | }; 256 | E8992D219F7C43BAE8308C3A /* [CP] Embed Pods Frameworks */ = { 257 | isa = PBXShellScriptBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | inputFileListPaths = ( 262 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 263 | ); 264 | name = "[CP] Embed Pods Frameworks"; 265 | outputFileListPaths = ( 266 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | shellPath = /bin/sh; 270 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 271 | showEnvVarsInLog = 0; 272 | }; 273 | /* End PBXShellScriptBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | 97C146EA1CF9000F007C117D /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 281 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | /* End PBXSourcesBuildPhase section */ 286 | 287 | /* Begin PBXVariantGroup section */ 288 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 289 | isa = PBXVariantGroup; 290 | children = ( 291 | 97C146FB1CF9000F007C117D /* Base */, 292 | ); 293 | name = Main.storyboard; 294 | sourceTree = ""; 295 | }; 296 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 297 | isa = PBXVariantGroup; 298 | children = ( 299 | 97C147001CF9000F007C117D /* Base */, 300 | ); 301 | name = LaunchScreen.storyboard; 302 | sourceTree = ""; 303 | }; 304 | /* End PBXVariantGroup section */ 305 | 306 | /* Begin XCBuildConfiguration section */ 307 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ALWAYS_SEARCH_USER_PATHS = NO; 311 | CLANG_ANALYZER_NONNULL = YES; 312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 313 | CLANG_CXX_LIBRARY = "libc++"; 314 | CLANG_ENABLE_MODULES = YES; 315 | CLANG_ENABLE_OBJC_ARC = YES; 316 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 317 | CLANG_WARN_BOOL_CONVERSION = YES; 318 | CLANG_WARN_COMMA = YES; 319 | CLANG_WARN_CONSTANT_CONVERSION = YES; 320 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 321 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 322 | CLANG_WARN_EMPTY_BODY = YES; 323 | CLANG_WARN_ENUM_CONVERSION = YES; 324 | CLANG_WARN_INFINITE_RECURSION = YES; 325 | CLANG_WARN_INT_CONVERSION = YES; 326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 331 | CLANG_WARN_STRICT_PROTOTYPES = YES; 332 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu99; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNDECLARED_SELECTOR = YES; 345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 346 | GCC_WARN_UNUSED_FUNCTION = YES; 347 | GCC_WARN_UNUSED_VARIABLE = YES; 348 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 349 | MTL_ENABLE_DEBUG_INFO = NO; 350 | SDKROOT = iphoneos; 351 | SUPPORTED_PLATFORMS = iphoneos; 352 | TARGETED_DEVICE_FAMILY = "1,2"; 353 | VALIDATE_PRODUCT = YES; 354 | }; 355 | name = Profile; 356 | }; 357 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 358 | isa = XCBuildConfiguration; 359 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 360 | buildSettings = { 361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 362 | CLANG_ENABLE_MODULES = YES; 363 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 364 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 365 | DEVELOPMENT_TEAM = CQ53Y973KM; 366 | ENABLE_BITCODE = NO; 367 | FRAMEWORK_SEARCH_PATHS = ( 368 | "$(inherited)", 369 | "$(PROJECT_DIR)/Flutter", 370 | ); 371 | INFOPLIST_FILE = Runner/Info.plist; 372 | LD_RUNPATH_SEARCH_PATHS = ( 373 | "$(inherited)", 374 | "@executable_path/Frameworks", 375 | ); 376 | LIBRARY_SEARCH_PATHS = ( 377 | "$(inherited)", 378 | "$(PROJECT_DIR)/Flutter", 379 | ); 380 | PRODUCT_BUNDLE_IDENTIFIER = com.eduwire.pronotenotifications; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 383 | SWIFT_VERSION = 5.0; 384 | VERSIONING_SYSTEM = "apple-generic"; 385 | }; 386 | name = Profile; 387 | }; 388 | 97C147031CF9000F007C117D /* Debug */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | ALWAYS_SEARCH_USER_PATHS = NO; 392 | CLANG_ANALYZER_NONNULL = YES; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 398 | CLANG_WARN_BOOL_CONVERSION = YES; 399 | CLANG_WARN_COMMA = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 403 | CLANG_WARN_EMPTY_BODY = YES; 404 | CLANG_WARN_ENUM_CONVERSION = YES; 405 | CLANG_WARN_INFINITE_RECURSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 409 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 412 | CLANG_WARN_STRICT_PROTOTYPES = YES; 413 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 414 | CLANG_WARN_UNREACHABLE_CODE = YES; 415 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 416 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 417 | COPY_PHASE_STRIP = NO; 418 | DEBUG_INFORMATION_FORMAT = dwarf; 419 | ENABLE_STRICT_OBJC_MSGSEND = YES; 420 | ENABLE_TESTABILITY = YES; 421 | GCC_C_LANGUAGE_STANDARD = gnu99; 422 | GCC_DYNAMIC_NO_PIC = NO; 423 | GCC_NO_COMMON_BLOCKS = YES; 424 | GCC_OPTIMIZATION_LEVEL = 0; 425 | GCC_PREPROCESSOR_DEFINITIONS = ( 426 | "DEBUG=1", 427 | "$(inherited)", 428 | ); 429 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 430 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 431 | GCC_WARN_UNDECLARED_SELECTOR = YES; 432 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 433 | GCC_WARN_UNUSED_FUNCTION = YES; 434 | GCC_WARN_UNUSED_VARIABLE = YES; 435 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 436 | MTL_ENABLE_DEBUG_INFO = YES; 437 | ONLY_ACTIVE_ARCH = YES; 438 | SDKROOT = iphoneos; 439 | TARGETED_DEVICE_FAMILY = "1,2"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147041CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_ANALYZER_NONNULL = YES; 448 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 449 | CLANG_CXX_LIBRARY = "libc++"; 450 | CLANG_ENABLE_MODULES = YES; 451 | CLANG_ENABLE_OBJC_ARC = YES; 452 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 453 | CLANG_WARN_BOOL_CONVERSION = YES; 454 | CLANG_WARN_COMMA = YES; 455 | CLANG_WARN_CONSTANT_CONVERSION = YES; 456 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 458 | CLANG_WARN_EMPTY_BODY = YES; 459 | CLANG_WARN_ENUM_CONVERSION = YES; 460 | CLANG_WARN_INFINITE_RECURSION = YES; 461 | CLANG_WARN_INT_CONVERSION = YES; 462 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 463 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 464 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 466 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 467 | CLANG_WARN_STRICT_PROTOTYPES = YES; 468 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 469 | CLANG_WARN_UNREACHABLE_CODE = YES; 470 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 471 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 472 | COPY_PHASE_STRIP = NO; 473 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 474 | ENABLE_NS_ASSERTIONS = NO; 475 | ENABLE_STRICT_OBJC_MSGSEND = YES; 476 | GCC_C_LANGUAGE_STANDARD = gnu99; 477 | GCC_NO_COMMON_BLOCKS = YES; 478 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 479 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 480 | GCC_WARN_UNDECLARED_SELECTOR = YES; 481 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 482 | GCC_WARN_UNUSED_FUNCTION = YES; 483 | GCC_WARN_UNUSED_VARIABLE = YES; 484 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 485 | MTL_ENABLE_DEBUG_INFO = NO; 486 | SDKROOT = iphoneos; 487 | SUPPORTED_PLATFORMS = iphoneos; 488 | SWIFT_COMPILATION_MODE = wholemodule; 489 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 490 | TARGETED_DEVICE_FAMILY = "1,2"; 491 | VALIDATE_PRODUCT = YES; 492 | }; 493 | name = Release; 494 | }; 495 | 97C147061CF9000F007C117D /* Debug */ = { 496 | isa = XCBuildConfiguration; 497 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 498 | buildSettings = { 499 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 500 | CLANG_ENABLE_MODULES = YES; 501 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 502 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 503 | DEVELOPMENT_TEAM = CQ53Y973KM; 504 | ENABLE_BITCODE = NO; 505 | FRAMEWORK_SEARCH_PATHS = ( 506 | "$(inherited)", 507 | "$(PROJECT_DIR)/Flutter", 508 | ); 509 | INFOPLIST_FILE = Runner/Info.plist; 510 | LD_RUNPATH_SEARCH_PATHS = ( 511 | "$(inherited)", 512 | "@executable_path/Frameworks", 513 | ); 514 | LIBRARY_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "$(PROJECT_DIR)/Flutter", 517 | ); 518 | PRODUCT_BUNDLE_IDENTIFIER = com.eduwire.pronotenotifications; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 521 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 522 | SWIFT_VERSION = 5.0; 523 | VERSIONING_SYSTEM = "apple-generic"; 524 | }; 525 | name = Debug; 526 | }; 527 | 97C147071CF9000F007C117D /* Release */ = { 528 | isa = XCBuildConfiguration; 529 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 530 | buildSettings = { 531 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 532 | CLANG_ENABLE_MODULES = YES; 533 | CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 534 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 535 | DEVELOPMENT_TEAM = CQ53Y973KM; 536 | ENABLE_BITCODE = NO; 537 | FRAMEWORK_SEARCH_PATHS = ( 538 | "$(inherited)", 539 | "$(PROJECT_DIR)/Flutter", 540 | ); 541 | INFOPLIST_FILE = Runner/Info.plist; 542 | LD_RUNPATH_SEARCH_PATHS = ( 543 | "$(inherited)", 544 | "@executable_path/Frameworks", 545 | ); 546 | LIBRARY_SEARCH_PATHS = ( 547 | "$(inherited)", 548 | "$(PROJECT_DIR)/Flutter", 549 | ); 550 | PRODUCT_BUNDLE_IDENTIFIER = com.eduwire.pronotenotifications; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 553 | SWIFT_VERSION = 5.0; 554 | VERSIONING_SYSTEM = "apple-generic"; 555 | }; 556 | name = Release; 557 | }; 558 | /* End XCBuildConfiguration section */ 559 | 560 | /* Begin XCConfigurationList section */ 561 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 97C147031CF9000F007C117D /* Debug */, 565 | 97C147041CF9000F007C117D /* Release */, 566 | 249021D3217E4FDB00AE95B9 /* Profile */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | 97C147061CF9000F007C117D /* Debug */, 575 | 97C147071CF9000F007C117D /* Release */, 576 | 249021D4217E4FDB00AE95B9 /* Profile */, 577 | ); 578 | defaultConfigurationIsVisible = 0; 579 | defaultConfigurationName = Release; 580 | }; 581 | /* End XCConfigurationList section */ 582 | }; 583 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 584 | } 585 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | if #available(iOS 10.0, *) { 12 | UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate 13 | } 14 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Notifications pour Pronote 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | pronote_notifications 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | ITSAppUsesNonExemptEncryption 26 | 27 | LSApplicationQueriesSchemes 28 | 29 | pronote 30 | 31 | LSRequiresIPhoneOS 32 | 33 | NSAppTransportSecurity 34 | 35 | NSAllowsLocalNetworking 36 | 37 | 38 | NSLocationAlwaysUsageDescription 39 | Localisation requise pour chercher les établissements à proximité 40 | NSLocationWhenInUseUsageDescription 41 | Localisation requise pour chercher les établissements à proximité 42 | PermissionGroupNotification 43 | Afficher les notifications de notes, devoirs, etc. 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UISupportedInterfaceOrientations~ipad 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | UIViewControllerBasedStatusBarAppearance 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'package:http/http.dart' as http; 4 | import 'package:shared_preferences/shared_preferences.dart'; 5 | import 'package:pronote_notifications/firebase.dart'; 6 | import 'package:package_info/package_info.dart'; 7 | import 'dart:io' show Platform; 8 | 9 | class UserData { 10 | // informations 11 | String fullName; 12 | String studentClass; 13 | String avatarBase64; 14 | String establishment; 15 | 16 | // settings 17 | bool notificationsHomeworks; 18 | bool notificationsMarks; 19 | 20 | UserData(this.fullName, this.establishment, this.studentClass, 21 | this.avatarBase64, this.notificationsHomeworks, this.notificationsMarks); 22 | } 23 | 24 | class NotificationData { 25 | String type; 26 | String title; 27 | bool hasSmallBody; 28 | String smallBody; 29 | String body; 30 | 31 | NotificationData( 32 | this.type, this.title, this.hasSmallBody, this.smallBody, this.body); 33 | } 34 | 35 | class EstablishmentData { 36 | String name; 37 | String url; 38 | 39 | EstablishmentData(this.name, this.url); 40 | } 41 | 42 | // Get the application information, including the platform and the version 43 | PackageInfo packageInfo; 44 | Future getApplicationVersion() async { 45 | if (packageInfo == null) { 46 | packageInfo = await PackageInfo.fromPlatform(); 47 | } 48 | return (Platform.isAndroid ? 'android-' : 'ios-') + packageInfo.version; 49 | } 50 | 51 | const API_URL = 'pnotifications.atlanta-bot.fr'; 52 | 53 | // Implements all the API requests 54 | class API { 55 | static Future isLogged() async { 56 | final sharedPreferences = await SharedPreferences.getInstance(); 57 | final logged = sharedPreferences.getBool('logged') ?? false; 58 | return logged; 59 | } 60 | 61 | static Future register( 62 | String username, String password, String pronoteURL) async { 63 | final fcmToken = await getDeviceToken(); 64 | final response = await http.post( 65 | Uri.https(API_URL, "register"), 66 | headers: { 67 | 'Content-Type': 'application/json; charset=UTF-8', 68 | 'App-Version': await getApplicationVersion() 69 | }, 70 | body: jsonEncode({ 71 | 'pronote_username': username, 72 | 'pronote_password': password, 73 | 'pronote_url': pronoteURL, 74 | 'fcm_token': fcmToken 75 | }), 76 | ); 77 | final jsonData = json.decode(response.body); 78 | if (!jsonData['success']) { 79 | throw (jsonData['message']); 80 | } else { 81 | final sharedPreferences = await SharedPreferences.getInstance(); 82 | sharedPreferences.setBool('logged', true); 83 | sharedPreferences.setString('jwt', jsonData['jwt']); 84 | sharedPreferences.setString('form_pronote_username', username); 85 | sharedPreferences.setString('form_pronote_url', pronoteURL); 86 | sharedPreferences.setString('jwt', jsonData['jwt']); 87 | return new UserData( 88 | jsonData['full_name'], 89 | jsonData['establishment'], 90 | jsonData['student_class'], 91 | jsonData['avatar_base64'], 92 | jsonData['notifications_homeworks'], 93 | jsonData['notifications_marks']); 94 | } 95 | } 96 | 97 | static Future login() async { 98 | final sharedPreferences = await SharedPreferences.getInstance(); 99 | final token = sharedPreferences.getString('jwt'); 100 | final response = 101 | await http.get(Uri.https(API_URL, "login"), headers: { 102 | 'Content-Type': 'application/json; charset=UTF-8', 103 | 'Authorization': token, 104 | 'App-Version': await getApplicationVersion() 105 | }); 106 | final jsonData = json.decode(response.body); 107 | if (!jsonData['success']) { 108 | throw (jsonData['message']); 109 | } else { 110 | return new UserData( 111 | jsonData['full_name'], 112 | jsonData['establishment'], 113 | jsonData['student_class'], 114 | jsonData['avatar_base64'], 115 | jsonData['notifications_homeworks'], 116 | jsonData['notifications_marks']); 117 | } 118 | } 119 | 120 | static Future updateSettings( 121 | bool notificationsHomeworks, bool notificationsMarks) async { 122 | final sharedPreferences = await SharedPreferences.getInstance(); 123 | final token = sharedPreferences.getString('jwt'); 124 | await http.post( 125 | Uri.https(API_URL, "settings"), 126 | headers: { 127 | 'Content-Type': 'application/json; charset=UTF-8', 128 | 'Authorization': token, 129 | 'App-Version': await getApplicationVersion() 130 | }, 131 | body: jsonEncode({ 132 | 'notifications_homeworks': notificationsHomeworks.toString(), 133 | 'notifications_marks': notificationsMarks.toString() 134 | }), 135 | ); 136 | return; 137 | } 138 | 139 | static Future logout() async { 140 | final sharedPreferences = await SharedPreferences.getInstance(); 141 | final token = sharedPreferences.getString('jwt'); 142 | await http.post(Uri.https(API_URL, "logout"), headers: { 143 | 'Content-Type': 'application/json; charset=UTF-8', 144 | 'Authorization': token, 145 | 'App-Version': await getApplicationVersion() 146 | }); 147 | sharedPreferences.setBool('logged', false); 148 | sharedPreferences.remove('jwt'); 149 | } 150 | 151 | static Future> getUserNotifications() async { 152 | final sharedPreferences = await SharedPreferences.getInstance(); 153 | final token = sharedPreferences.getString('jwt'); 154 | final response = await http 155 | .get(Uri.https(API_URL, "notifications"), headers: { 156 | 'Content-Type': 'application/json; charset=UTF-8', 157 | 'Authorization': token, 158 | 'App-Version': await getApplicationVersion() 159 | }); 160 | final jsonData = json.decode(response.body); 161 | if (!jsonData['success']) { 162 | throw (jsonData['message']); 163 | } else { 164 | return jsonData['notifications'] 165 | .map((notificationData) => NotificationData( 166 | notificationData['type'], 167 | notificationData['title'], 168 | notificationData['body'].length > 30, 169 | notificationData['body'].length > 30 170 | ? notificationData['body'].substring(0, 30) + "..." 171 | : null, 172 | notificationData['body'])) 173 | .toList(); 174 | } 175 | } 176 | 177 | static Future> getEstablishments(latitude, longitude) async { 178 | var jsonData; 179 | try { 180 | final response = await http.get( 181 | Uri.https('pnotifications.atlanta-bot.fr', 'establishments', { 182 | 'latitude': latitude.toString(), 183 | 'longitude': longitude.toString() 184 | }), 185 | headers: {'App-Version': await getApplicationVersion()}); 186 | jsonData = json.decode(response.body); 187 | } catch (e) { 188 | throw 'Impossible de se connecter au serveur'; 189 | } 190 | if (!jsonData['success']) { 191 | throw (jsonData['message']); 192 | } else { 193 | if (jsonData['establishments'].length == 0) { 194 | throw 'Aucun établissement trouvé...'; 195 | } else { 196 | return jsonData['establishments'] 197 | .map((establishmentData) => EstablishmentData( 198 | establishmentData['nomEtab'], establishmentData['url'])) 199 | .toList(); 200 | } 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /lib/firebase.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:firebase_messaging/firebase_messaging.dart'; 3 | import 'package:flutter_local_notifications/flutter_local_notifications.dart'; 4 | import 'package:firebase_core/firebase_core.dart'; 5 | import 'package:pronote_notifications/pages/notifications.dart'; 6 | import 'package:external_app_launcher/external_app_launcher.dart'; 7 | 8 | final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance; 9 | final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = 10 | new FlutterLocalNotificationsPlugin(); 11 | final initializationSettingsAndroid = 12 | AndroidInitializationSettings('@mipmap/launcher_icon'); 13 | final initializationSettingsIOS = IOSInitializationSettings(); 14 | final initializationSettings = InitializationSettings( 15 | android: initializationSettingsAndroid, iOS: initializationSettingsIOS); 16 | 17 | bool _initialized = false; 18 | 19 | void initFirebase(GlobalKey navigatorKey) { 20 | if (_initialized) { 21 | return; 22 | } 23 | 24 | Firebase.initializeApp(); 25 | 26 | void handleSelectNotification () async { 27 | if (await LaunchApp.isAppInstalled(androidPackageName: 'com.IndexEducation.Pronote', iosUrlScheme: 'pronote://') != 0) { 28 | print('Launching Pronote...'); 29 | LaunchApp.openApp(androidPackageName: 'com.IndexEducation.Pronote', iosUrlScheme: 'pronote://'); 30 | } else { 31 | print('Pronote is not installed...'); 32 | navigatorKey.currentState 33 | .push(MaterialPageRoute(builder: (context) => NotificationsPage())); 34 | } 35 | } 36 | 37 | Future onSelectNotification (String payload) { 38 | handleSelectNotification(); 39 | return null; 40 | } 41 | 42 | _flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: onSelectNotification); 43 | _initialized = true; 44 | 45 | FirebaseMessaging.onMessage.listen((RemoteMessage message) { 46 | print("message received from Firebase Messaging"); 47 | if (message.data['type'] != null) showNotification(message.notification.title, message.notification.body); 48 | }); 49 | FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { 50 | print("notification clicked by the user"); 51 | if (message.data['type'] != null) handleSelectNotification(); 52 | }); 53 | } 54 | 55 | showNotification(String title, String body) async { 56 | final android = new AndroidNotificationDetails(title, title, title, 57 | styleInformation: BigTextStyleInformation('')); 58 | final iOS = new IOSNotificationDetails(); 59 | final platform = new NotificationDetails(android: android, iOS: iOS); 60 | await _flutterLocalNotificationsPlugin.show(0, title, body, platform); 61 | } 62 | 63 | Future getDeviceToken() async { 64 | try { 65 | return await _firebaseMessaging.getToken(); 66 | } catch (e) { 67 | print('Error while getting device token'); 68 | print(e); 69 | return "nope"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:pronote_notifications/pages/root.dart'; 4 | 5 | void main() { 6 | WidgetsFlutterBinding.ensureInitialized(); 7 | runApp(new MainApp()); 8 | } 9 | 10 | Map color = { 11 | 50: Color.fromRGBO(41, 130, 108, .1), 12 | 100: Color.fromRGBO(41, 130, 108, .2), 13 | 200: Color.fromRGBO(41, 130, 108, .3), 14 | 300: Color.fromRGBO(41, 130, 108, .4), 15 | 400: Color.fromRGBO(41, 130, 108, .5), 16 | 500: Color.fromRGBO(41, 130, 108, .6), 17 | 600: Color.fromRGBO(41, 130, 108, .7), 18 | 700: Color.fromRGBO(41, 130, 108, .8), 19 | 800: Color.fromRGBO(41, 130, 108, .9), 20 | 900: Color.fromRGBO(41, 130, 108, 1), 21 | }; 22 | 23 | MaterialColor colorCustom = MaterialColor(0xFF29826c, color); 24 | 25 | class MainApp extends StatefulWidget { 26 | @override 27 | _MainAppState createState() => _MainAppState(); 28 | } 29 | 30 | class _MainAppState extends State { 31 | final GlobalKey navigatorKey = 32 | GlobalKey(debugLabel: "MainNavigator"); 33 | 34 | @override 35 | void initState() { 36 | super.initState(); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | SystemChrome.setPreferredOrientations( 42 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); 43 | 44 | return new MaterialApp( 45 | navigatorKey: navigatorKey, 46 | title: 'Notifications pour Pronote', 47 | debugShowCheckedModeBanner: false, 48 | theme: new ThemeData( 49 | primarySwatch: colorCustom, 50 | ), 51 | home: new RootPage(navigatorKey: navigatorKey)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/pages/home.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io' show Platform; 2 | import 'dart:async'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:pronote_notifications/api.dart'; 5 | import 'package:settings_ui/settings_ui.dart'; 6 | import 'package:pronote_notifications/pages/notifications.dart'; 7 | import 'package:pronote_notifications/widgets/dialogs.dart'; 8 | import 'package:in_app_review/in_app_review.dart'; 9 | 10 | final InAppReview inAppReview = InAppReview.instance; 11 | 12 | class HomePage extends StatefulWidget { 13 | HomePage({Key key, this.userData, this.logoutCallback}) : super(key: key); 14 | 15 | final VoidCallback logoutCallback; 16 | final UserData userData; 17 | 18 | @override 19 | State createState() => new _HomePageState(); 20 | } 21 | 22 | class _HomePageState extends State { 23 | bool notificationsHomeworks; 24 | bool notificationsMarks; 25 | 26 | bool _loggingOut = false; 27 | 28 | @override 29 | void initState() { 30 | super.initState(); 31 | notificationsHomeworks = widget.userData.notificationsHomeworks; 32 | notificationsMarks = widget.userData.notificationsMarks; 33 | } 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return Scaffold( 38 | appBar: new AppBar( 39 | title: new Text('Notifications pour Pronote'), 40 | actions: [ 41 | PopupMenuButton( 42 | onSelected: (String value) async { 43 | if (value == 'À propos') { 44 | showAboutAppDialog(context); 45 | } else { 46 | inAppReview.openStoreListing(appStoreId: '1564109971'); 47 | } 48 | }, 49 | itemBuilder: (BuildContext context) { 50 | return ['Laisser un avis', 'À propos'].map((String choice) { 51 | return PopupMenuItem( 52 | value: choice, 53 | child: Text(choice), 54 | ); 55 | }).toList(); 56 | }, 57 | ) 58 | ], 59 | ), 60 | body: SettingsList( 61 | contentPadding: Platform.isIOS ? null : EdgeInsets.symmetric(vertical: 20), 62 | sections: [ 63 | SettingsSection( 64 | title: 'Vos informations', 65 | tiles: [ 66 | SettingsTile( 67 | iosChevronEnabled: false, 68 | title: widget.userData.fullName, 69 | leading: Icon(Icons.account_circle)), 70 | SettingsTile( 71 | iosChevronEnabled: false, 72 | title: 73 | "${widget.userData.establishment} (${widget.userData.studentClass})", 74 | leading: Icon(Icons.school)), 75 | ], 76 | ), 77 | SettingsSection( 78 | title: 'Gestion des notifications', 79 | tiles: [ 80 | SettingsTile.switchTile( 81 | title: 'Nouveaux devoirs', 82 | leading: Icon(Icons.today), 83 | switchValue: notificationsHomeworks, 84 | onToggle: (bool value) async { 85 | setState(() { 86 | notificationsHomeworks = value; 87 | }); 88 | await API.updateSettings( 89 | notificationsHomeworks, notificationsMarks); 90 | }, 91 | ), 92 | SettingsTile.switchTile( 93 | title: 'Nouvelles notes', 94 | leading: Icon(Icons.assessment), 95 | switchValue: notificationsMarks, 96 | onToggle: (bool value) async { 97 | setState(() { 98 | notificationsMarks = value; 99 | }); 100 | await API.updateSettings( 101 | notificationsHomeworks, notificationsMarks); 102 | }, 103 | enabled: true), 104 | SettingsTile( 105 | title: 'Historique des notifications', 106 | leading: Icon(Icons.history), 107 | iosChevron: Icon(Icons.chevron_right), 108 | enabled: true, 109 | onPressed: (context) { 110 | Navigator.push( 111 | context, 112 | MaterialPageRoute( 113 | builder: (context) => NotificationsPage()), 114 | ); 115 | }, 116 | ), 117 | ], 118 | ), 119 | SettingsSection( 120 | title: 'Compte', 121 | tiles: [ 122 | SettingsTile( 123 | iosChevronEnabled: false, 124 | title: 'Déconnexion', 125 | leading: _loggingOut 126 | ? Container( 127 | height: 15, 128 | width: 15, 129 | margin: EdgeInsets.all(5), 130 | child: CircularProgressIndicator(strokeWidth: 2.0), 131 | ) 132 | : Icon(Icons.exit_to_app), 133 | onPressed: (context) { 134 | setState(() { 135 | _loggingOut = true; 136 | }); 137 | logout(); 138 | }, 139 | ) 140 | ], 141 | ) 142 | ], 143 | )); 144 | } 145 | 146 | logout() async { 147 | try { 148 | await API.logout(); 149 | widget.logoutCallback(); 150 | _loggingOut = false; 151 | } catch (e) { 152 | print(e); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /lib/pages/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:pronote_notifications/api.dart'; 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | import 'package:pronote_notifications/widgets/dialogs.dart'; 5 | import 'package:geolocator/geolocator.dart'; 6 | import 'package:pronote_notifications/url.dart'; 7 | 8 | class LoginPage extends StatefulWidget { 9 | LoginPage({this.loginCallback}); 10 | 11 | final Function loginCallback; 12 | 13 | @override 14 | State createState() => new _LoginPageState(); 15 | } 16 | 17 | class _LoginPageState extends State { 18 | final _formKey = new GlobalKey(); 19 | 20 | // used to store credentials before sending them to the server 21 | String _username; 22 | String _password; 23 | String _pronoteURL; 24 | 25 | String _pronoteURLInfoText = 'Sélectionnez votre établissement'; 26 | 27 | String _geolocationErrorMessage; 28 | bool _useGeolocation = true; 29 | String _selectedEstablishment; 30 | bool _establishmentsLoaded = false; 31 | List _establishments; 32 | 33 | bool _isLoading; 34 | final _pronoteGeoController = TextEditingController(); 35 | final _pronoteURLController = TextEditingController(); 36 | final _usernameController = TextEditingController(); 37 | 38 | @override 39 | void initState() { 40 | super.initState(); 41 | 42 | setState(() { 43 | _isLoading = false; 44 | }); 45 | 46 | SharedPreferences.getInstance().then((instance) { 47 | final username = instance.getString('form_pronote_username'); 48 | final pronoteURL = instance.getString('form_pronote_url'); 49 | if (username != null && pronoteURL != null) { 50 | setState(() { 51 | _usernameController.text = username; 52 | _pronoteURLController.text = pronoteURL; 53 | }); 54 | } 55 | }); 56 | } 57 | 58 | // Check if form is valid before perform login or signup 59 | bool validateAndSave() { 60 | final form = _formKey.currentState; 61 | if (form.validate()) { 62 | form.save(); 63 | return true; 64 | } 65 | return false; 66 | } 67 | 68 | // Perform login or signup 69 | void validateAndSubmit() async { 70 | setState(() { 71 | _isLoading = true; 72 | }); 73 | if (validateAndSave()) { 74 | try { 75 | final userData = await API.register(_username, _password, _pronoteURL); 76 | print('Signed in: ${userData.fullName}'); 77 | setState(() { 78 | _isLoading = false; 79 | }); 80 | widget.loginCallback(userData); 81 | } catch (e) { 82 | print('Error: $e'); 83 | if (e is String) { 84 | setState(() { 85 | _isLoading = false; 86 | showInfoDialog(context, 87 | title: 'Une erreur est survenue', content: e); 88 | }); 89 | } else { 90 | if (e.message == null) 91 | showInfoDialog(context, 92 | title: 'Une erreur est survenue', 93 | content: 94 | 'Quelque chose s\'est mal passé durant la connexion...'); 95 | setState(() { 96 | _isLoading = false; 97 | if (e.message.contains('Unexpected character')) { 98 | showInfoDialog(context, 99 | title: 'Une erreur est survenue', 100 | content: 101 | 'Le serveur de Notifications pour Pronote est actuellement injoignable. Merci de patienter puis réessayez !'); 102 | } else { 103 | showInfoDialog(context, 104 | title: 'Une erreur est survenue', content: e.message); 105 | } 106 | }); 107 | } 108 | } 109 | } else { 110 | setState(() { 111 | _isLoading = false; 112 | }); 113 | } 114 | } 115 | 116 | void resetForm() { 117 | _formKey.currentState.reset(); 118 | } 119 | 120 | @override 121 | Widget build(BuildContext context) { 122 | return new Scaffold( 123 | appBar: new AppBar( 124 | title: new Text('Notifications pour Pronote'), 125 | actions: [ 126 | PopupMenuButton( 127 | onSelected: (String value) { 128 | if (value == 'Problèmes de connexion') { 129 | showInfoDialog(context, 130 | title: "Aide à la connexion", 131 | content: 132 | "Si vous ne parvenez pas à vous connecter, n'hésitez surtout pas à nous envoyer un mail à androz2091@gmail.com. Nous répondons en quelques heures.", 133 | actions: [ 134 | new ElevatedButton( 135 | style: ButtonStyle( 136 | backgroundColor: 137 | MaterialStateProperty.all( 138 | Colors.blueAccent)), 139 | child: new Text("Envoyer un mail"), 140 | onPressed: () async { 141 | final Uri emailParams = Uri( 142 | scheme: 'mailto', 143 | path: 'androz2091@gmail.com', 144 | query: 'subject=Problème de connexion à Notifications pour Pronote&body=Bonjour, je rencontre des difficultés pour me connecter à l\'application.\n\nMéthode d\'authentification:\n' + 145 | (_useGeolocation 146 | ? 'Géolocalisation (' + 147 | (_establishmentsLoaded 148 | ? _establishments.length 149 | .toString() + 150 | ' établissements chargés)' 151 | : 'aucun établissement chargé)') 152 | : 'URL personnalisée (' + 153 | (_pronoteURL ?? 'aucune URL') + 154 | ')') + 155 | '\n\nSerait-il possible de m\'aider ?\n\nCordialement,\nYour Name Here' 156 | ); 157 | final url = emailParams.toString(); 158 | final launched = await launchURL(url); 159 | if (!launched) showInfoDialog(context, title: 'Erreur', content: 'Impossible d\'ouvrir l\'application mail automatiquement...'); 160 | }) 161 | ]); 162 | } else { 163 | showAboutAppDialog(context); 164 | } 165 | }, 166 | itemBuilder: (BuildContext context) { 167 | return ['Problèmes de connexion', 'À propos'] 168 | .map((String choice) { 169 | return PopupMenuItem( 170 | value: choice, 171 | child: Text(choice), 172 | ); 173 | }).toList(); 174 | }, 175 | ) 176 | ], 177 | ), 178 | body: Stack( 179 | children: [_showForm()], 180 | )); 181 | } 182 | 183 | Widget _showForm() { 184 | return new Container( 185 | padding: EdgeInsets.all(16.0), 186 | child: new Form( 187 | key: _formKey, 188 | child: new ListView( 189 | shrinkWrap: true, 190 | children: [ 191 | showLogo(), 192 | showDescription(), 193 | showUsernameInput(), 194 | showPasswordInput(), 195 | if (_useGeolocation) showPronoteEstablishmentsDropdown(), 196 | if (!_useGeolocation) showPronoteURL(), 197 | if (!_useGeolocation) 198 | Container( 199 | child: Text( 200 | '(exemple: https://0314700h.index-education.net)', 201 | style: TextStyle(color: Color.fromRGBO(0, 0, 0, .6))), 202 | margin: const EdgeInsets.only(top: 10)), 203 | showSwitchMethod(), 204 | showLoginButton(), 205 | ], 206 | ), 207 | )); 208 | } 209 | 210 | Widget showLogo() { 211 | return new Hero( 212 | tag: 'pronote-logo', 213 | child: Padding( 214 | padding: EdgeInsets.fromLTRB(0.0, 60.0, 0.0, 0.0), 215 | child: CircleAvatar( 216 | backgroundColor: Colors.transparent, 217 | radius: 48.0, 218 | child: Image.asset('assets/icon.png'), 219 | ), 220 | ), 221 | ); 222 | } 223 | 224 | Widget showDescription() { 225 | return Padding( 226 | padding: const EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 0.0), 227 | child: new DefaultTextStyle( 228 | style: TextStyle(fontSize: 36, color: Colors.blue), 229 | child: Center( 230 | child: Column( 231 | mainAxisAlignment: MainAxisAlignment.center, 232 | children: [ 233 | const Text( 234 | 'Bienvenue, merci de renseigner vos identifiants pour commencer à recevoir les notifications ! 🔔', 235 | style: TextStyle(fontSize: 15, color: Colors.black), 236 | textAlign: TextAlign.center), 237 | if (_geolocationErrorMessage != null) 238 | Container( 239 | margin: const EdgeInsets.only(top: 10), 240 | child: Text(_geolocationErrorMessage, 241 | textAlign: TextAlign.center, 242 | style: TextStyle(color: Colors.red, fontSize: 14))) 243 | ], 244 | ), 245 | ), 246 | ), 247 | ); 248 | } 249 | 250 | Widget showUsernameInput() { 251 | return Padding( 252 | padding: const EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 0.0), 253 | child: new TextFormField( 254 | readOnly: _isLoading, 255 | maxLines: 1, 256 | keyboardType: TextInputType.text, 257 | autofocus: false, 258 | controller: _usernameController, 259 | initialValue: null, 260 | decoration: new InputDecoration( 261 | hintText: 'Nom d\'utilisateur', 262 | icon: new Icon( 263 | Icons.account_circle, 264 | color: Colors.grey, 265 | )), 266 | validator: (value) => value.isEmpty 267 | ? 'Le nom d\'utilisateur ne peut pas être vide' 268 | : null, 269 | onSaved: (value) => _username = value.trim(), 270 | ), 271 | ); 272 | } 273 | 274 | Widget showPasswordInput() { 275 | return Padding( 276 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0), 277 | child: new TextFormField( 278 | readOnly: _isLoading, 279 | maxLines: 1, 280 | obscureText: true, 281 | autofocus: false, 282 | initialValue: _password ?? null, 283 | decoration: new InputDecoration( 284 | hintText: 'Mot de passe', 285 | icon: new Icon( 286 | Icons.lock, 287 | color: Colors.grey, 288 | )), 289 | validator: (value) => 290 | value.isEmpty ? 'Le mot de passe ne peut pas être vide' : null, 291 | onSaved: (value) => _password = value.trim(), 292 | ), 293 | ); 294 | } 295 | 296 | Future _determinePosition() async { 297 | bool serviceEnabled; 298 | LocationPermission permission; 299 | serviceEnabled = await Geolocator.isLocationServiceEnabled(); 300 | if (!serviceEnabled) { 301 | return Future.error('Location services are disabled.'); 302 | } 303 | permission = await Geolocator.checkPermission(); 304 | if (permission == LocationPermission.denied) { 305 | permission = await Geolocator.requestPermission(); 306 | if (permission == LocationPermission.deniedForever) { 307 | return Future.error( 308 | 'Location permissions are permanently denied, we cannot request permissions.'); 309 | } 310 | 311 | if (permission == LocationPermission.denied) { 312 | return Future.error('Location permissions are denied'); 313 | } 314 | } 315 | return await Geolocator.getCurrentPosition(); 316 | } 317 | 318 | Widget showSwitchMethod() { 319 | return InkWell( 320 | splashColor: Colors.transparent, 321 | highlightColor: Colors.transparent, 322 | onTap: () { 323 | setState(() { 324 | _useGeolocation = !_useGeolocation; 325 | if (!_useGeolocation) { 326 | _pronoteGeoController.text = null; 327 | } 328 | }); 329 | }, 330 | child: Container( 331 | margin: const EdgeInsets.only(top: 10, bottom: 10), 332 | child: Text( 333 | _useGeolocation 334 | ? 'ou entrez une URL Pronote manuellement' 335 | : 'ou chercher automatiquement les établissements à proximité', 336 | style: TextStyle( 337 | color: Color.fromRGBO(41, 130, 108, .8), 338 | decoration: TextDecoration.underline)))); 339 | } 340 | 341 | Widget showPronoteURL() { 342 | return Padding( 343 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0), 344 | child: new TextFormField( 345 | readOnly: _isLoading, 346 | maxLines: 1, 347 | keyboardType: TextInputType.url, 348 | autofocus: false, 349 | controller: _pronoteURLController, 350 | decoration: new InputDecoration( 351 | hintText: 'URL Pronote', 352 | icon: new Icon( 353 | Icons.http, 354 | color: Colors.grey, 355 | )), 356 | validator: (value) { 357 | String message; 358 | if (value.isEmpty) message = 'L\'URL Pronote ne peut pas être vide'; 359 | return message; 360 | }, 361 | onSaved: (value) => _pronoteURL = value.trim(), 362 | )); 363 | } 364 | 365 | Widget showPronoteEstablishmentsDropdown() { 366 | return Padding( 367 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0), 368 | child: _establishmentsLoaded 369 | ? Row(children: [ 370 | Container( 371 | child: new Icon( 372 | Icons.school, 373 | color: Colors.grey, 374 | ), 375 | ), 376 | Container( 377 | margin: const EdgeInsets.only(left: 20.0, right: 20.0), 378 | child: DropdownButton( 379 | value: _selectedEstablishment ?? _establishments[0].name, 380 | onChanged: !_isLoading 381 | ? (String newValue) { 382 | setState(() { 383 | _selectedEstablishment = newValue; 384 | _pronoteURL = _establishments 385 | .firstWhere((es) => es.name == newValue) 386 | .url; 387 | }); 388 | } 389 | : null, 390 | items: (_establishments 391 | .map((e) => e.name.toString()) 392 | .toList()) 393 | .map>((String value) { 394 | return DropdownMenuItem( 395 | value: value, 396 | child: Text(value), 397 | ); 398 | }).toList(), 399 | )) 400 | ]) 401 | : new TextFormField( 402 | readOnly: true, 403 | maxLines: 1, 404 | autofocus: false, 405 | controller: _pronoteGeoController, 406 | decoration: new InputDecoration( 407 | hintText: _pronoteURLInfoText, 408 | icon: new Icon( 409 | Icons.school, 410 | color: Colors.grey, 411 | )), 412 | validator: (value) => 'Veuillez sélectionner un établissement', 413 | onTap: () { 414 | setState(() { 415 | _geolocationErrorMessage = null; 416 | _pronoteURLInfoText = 'Chargement des étab. à proximité...'; 417 | }); 418 | _determinePosition().then((value) async { 419 | API 420 | .getEstablishments(value.latitude, value.longitude) 421 | .then((establishments) { 422 | setState(() { 423 | _establishments = establishments; 424 | _establishmentsLoaded = true; 425 | }); 426 | }).catchError((e) { 427 | setState(() { 428 | _pronoteURLInfoText = e.toString(); 429 | }); 430 | }); 431 | }, onError: (e) { 432 | print(e); 433 | setState(() { 434 | _pronoteURLInfoText = 'Sélectionnez votre établissement'; 435 | _geolocationErrorMessage = 436 | 'Pour faciliter la connexion, l\'application peut trouver pour vous tous les établissements à proximité (géolocalisation requise). Sinon, vous pouvez entrer manuellement votre URL Pronote.'; 437 | }); 438 | }); 439 | }, 440 | )); 441 | } 442 | 443 | Widget showLoginButton() { 444 | return new Padding( 445 | padding: EdgeInsets.fromLTRB(0.0, 45.0, 0.0, 30.0), 446 | child: SizedBox( 447 | height: 40.0, 448 | child: new ElevatedButton( 449 | style: ElevatedButton.styleFrom( 450 | primary: Color(0xff29826c), 451 | elevation: 5.0, 452 | shape: new RoundedRectangleBorder( 453 | borderRadius: new BorderRadius.circular(30.0))), 454 | child: _isLoading 455 | ? new LinearProgressIndicator( 456 | valueColor: new AlwaysStoppedAnimation( 457 | Color.fromRGBO(41, 170, 108, 1))) 458 | : new Text( 459 | 'Connexion', 460 | style: new TextStyle(fontSize: 20.0, color: Colors.white), 461 | ), 462 | onPressed: _isLoading ? () => {} : validateAndSubmit, 463 | ), 464 | )); 465 | } 466 | } 467 | -------------------------------------------------------------------------------- /lib/pages/notifications.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:pronote_notifications/api.dart'; 3 | import 'package:pronote_notifications/widgets/dialogs.dart'; 4 | 5 | class NotificationsPage extends StatefulWidget { 6 | NotificationsPage(); 7 | 8 | @override 9 | State createState() { 10 | return _NotificationsPageState(); 11 | } 12 | } 13 | 14 | class _NotificationsPageState extends State { 15 | List _notifications = []; 16 | bool _fetched = false; 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | refreshNotifications(); 22 | } 23 | 24 | void refreshNotifications() async { 25 | API.getUserNotifications().then((result) { 26 | setState(() { 27 | _fetched = true; 28 | _notifications = result; 29 | }); 30 | }); 31 | } 32 | 33 | Widget _buildList() { 34 | return _fetched 35 | ? (_notifications.length != 0 36 | ? RefreshIndicator( 37 | child: ListView.builder( 38 | padding: EdgeInsets.all(8), 39 | itemCount: _notifications.length, 40 | itemBuilder: (BuildContext context, int index) { 41 | return Card( 42 | child: Column( 43 | children: [ 44 | ListTile( 45 | leading: Container( 46 | child: 47 | _notifications[index].type == 'homework' 48 | ? Icon(Icons.today) 49 | : Icon(Icons.assessment)), 50 | title: Text(_notifications[index].title, 51 | style: new TextStyle( 52 | fontSize: 14, 53 | fontWeight: FontWeight.bold)), 54 | subtitle: Text( 55 | _notifications[index].type == 'homework' 56 | ? (_notifications[index].hasSmallBody 57 | ? _notifications[index].smallBody 58 | : _notifications[index].body) 59 | : _notifications[index].body), 60 | onTap: () { 61 | showInfoDialog(context, 62 | title: _notifications[index].title, 63 | content: _notifications[index].body); 64 | }) 65 | ], 66 | ), 67 | ); 68 | }), 69 | onRefresh: _getData, 70 | ) 71 | : RefreshIndicator( 72 | child: SingleChildScrollView( 73 | physics: AlwaysScrollableScrollPhysics(), 74 | child: Container( 75 | child: Column( 76 | mainAxisAlignment: MainAxisAlignment.center, 77 | crossAxisAlignment: CrossAxisAlignment.center, 78 | children: [ 79 | Center( 80 | child: Image( 81 | image: AssetImage('bell.png'), 82 | height: 100, 83 | width: 100)), 84 | SizedBox(height: 30), 85 | Center( 86 | child: Text( 87 | 'Aucune notification pour le moment !', 88 | style: new TextStyle( 89 | fontWeight: FontWeight.bold), 90 | textAlign: TextAlign.center)) 91 | ]), 92 | height: MediaQuery.of(context).size.height - 100)), 93 | onRefresh: _getData, 94 | )) 95 | : Center(child: CircularProgressIndicator()); 96 | } 97 | 98 | Future _getData() async { 99 | setState(() { 100 | refreshNotifications(); 101 | }); 102 | } 103 | 104 | @override 105 | Widget build(BuildContext context) { 106 | return Scaffold( 107 | appBar: AppBar( 108 | title: Text('Notifications'), 109 | ), 110 | body: Container(child: _buildList()), 111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/pages/root.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:pronote_notifications/pages/login.dart'; 3 | import 'package:pronote_notifications/api.dart'; 4 | import 'package:pronote_notifications/pages/home.dart'; 5 | import 'package:pronote_notifications/firebase.dart'; 6 | import 'package:pronote_notifications/widgets/dialogs.dart'; 7 | 8 | enum AuthStatus { 9 | NOT_DETERMINED, 10 | NOT_LOGGED_IN, 11 | LOGGED_IN, 12 | } 13 | 14 | class RootPage extends StatefulWidget { 15 | RootPage({this.navigatorKey}); 16 | 17 | final GlobalKey navigatorKey; 18 | 19 | @override 20 | State createState() => new _RootPageState(); 21 | } 22 | 23 | class _RootPageState extends State { 24 | AuthStatus authStatus = AuthStatus.NOT_DETERMINED; 25 | UserData _userData; 26 | 27 | @override 28 | void initState() { 29 | super.initState(); 30 | initFirebase(widget.navigatorKey); 31 | 32 | API.isLogged().then((isLogged) { 33 | if (!isLogged) { 34 | setState(() { 35 | authStatus = AuthStatus.NOT_LOGGED_IN; 36 | }); 37 | } else { 38 | try { 39 | API.login().then((userData) { 40 | setState(() { 41 | _userData = userData; 42 | authStatus = AuthStatus.LOGGED_IN; 43 | }); 44 | }); 45 | } catch (e) { 46 | print('Error: $e'); 47 | if (e is String) { 48 | setState(() { 49 | showInfoDialog(context, 50 | title: 'Une erreur est survenue', content: e); 51 | }); 52 | } else { 53 | if (e.message == null) 54 | showInfoDialog(context, 55 | title: 'Une erreur est survenue', 56 | content: 57 | 'Quelque chose s\'est mal passé durant la connexion...'); 58 | setState(() { 59 | if (e.message.contains('Unexpected character')) { 60 | showInfoDialog(context, 61 | title: 'Une erreur est survenue', 62 | content: 63 | 'Le serveur de Notifications pour Pronote est actuellement injoignable. Merci de patienter puis réessayez !'); 64 | } else { 65 | setState(() { 66 | authStatus = AuthStatus.NOT_LOGGED_IN; 67 | }); 68 | } 69 | }); 70 | } 71 | } 72 | } 73 | }); 74 | } 75 | 76 | void loginCallback(UserData userData) { 77 | setState(() { 78 | _userData = userData; 79 | authStatus = AuthStatus.LOGGED_IN; 80 | }); 81 | } 82 | 83 | void logoutCallback() { 84 | setState(() { 85 | authStatus = AuthStatus.NOT_LOGGED_IN; 86 | _userData = null; 87 | }); 88 | } 89 | 90 | Widget buildWaitingScreen() { 91 | return Scaffold( 92 | body: Container( 93 | alignment: Alignment.center, 94 | child: CircularProgressIndicator(), 95 | ), 96 | ); 97 | } 98 | 99 | @override 100 | Widget build(BuildContext context) { 101 | switch (authStatus) { 102 | case AuthStatus.NOT_DETERMINED: 103 | return buildWaitingScreen(); 104 | break; 105 | case AuthStatus.NOT_LOGGED_IN: 106 | return new LoginPage( 107 | loginCallback: loginCallback, 108 | ); 109 | break; 110 | case AuthStatus.LOGGED_IN: 111 | if (_userData != null) { 112 | return new HomePage( 113 | userData: _userData, 114 | logoutCallback: logoutCallback, 115 | ); 116 | } else 117 | return buildWaitingScreen(); 118 | break; 119 | default: 120 | return buildWaitingScreen(); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/url.dart: -------------------------------------------------------------------------------- 1 | import 'package:url_launcher/url_launcher.dart'; 2 | 3 | Future launchURL(_url) async { 4 | final canLaunchURL = await canLaunch(_url); 5 | if (canLaunchURL) launch(_url); 6 | return canLaunchURL; 7 | } 8 | -------------------------------------------------------------------------------- /lib/widgets/dialogs.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:pronote_notifications/url.dart'; 3 | import 'package:flutter_linkify/flutter_linkify.dart'; 4 | 5 | void showInfoDialog(BuildContext context, 6 | {String title, String content, List actions}) { 7 | showDialog( 8 | context: context, 9 | builder: (BuildContext context) { 10 | return AlertDialog( 11 | title: new Text(title), 12 | content: Linkify( 13 | onOpen: (link) => launchURL(link.url), 14 | style: TextStyle(color: Colors.black), 15 | linkStyle: TextStyle(color: Colors.blue), 16 | text: (content)), 17 | actions: [ 18 | ...(actions ?? []), 19 | new ElevatedButton( 20 | child: new Text("Fermer"), 21 | onPressed: () { 22 | Navigator.of(context).pop(); 23 | }, 24 | ) 25 | ]); 26 | }, 27 | ); 28 | } 29 | 30 | void showAboutAppDialog(BuildContext context) { 31 | showInfoDialog(context, 32 | title: 'À propos', 33 | content: 34 | 'Notifications pour Pronote est une application gratuite, open source et sans publicité développée par des étudiants !', 35 | actions: [ 36 | new ElevatedButton( 37 | style: ButtonStyle( 38 | backgroundColor: 39 | MaterialStateProperty.all(Colors.deepOrangeAccent)), 40 | child: new Text("Faire un don"), 41 | onPressed: () async { 42 | final launched = await launchURL('https://paypal.me/andr0z'); 43 | if (!launched) { 44 | showInfoDialog(context, title: 'Erreur', content: 'Impossible d\'ouvrir le lien automatiquement. Utilisez https://paypal.me/andr0z pour nous soutenir !'); 45 | } 46 | }, 47 | ) 48 | ]); 49 | } 50 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "3.1.2" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.0.0" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.5.0" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "2.1.0" 32 | characters: 33 | dependency: transitive 34 | description: 35 | name: characters 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.0" 39 | charcode: 40 | dependency: transitive 41 | description: 42 | name: charcode 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.2.0" 46 | clock: 47 | dependency: transitive 48 | description: 49 | name: clock 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.1.0" 53 | collection: 54 | dependency: transitive 55 | description: 56 | name: collection 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.15.0" 60 | connectivity: 61 | dependency: "direct main" 62 | description: 63 | name: connectivity 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "3.0.3" 67 | connectivity_for_web: 68 | dependency: transitive 69 | description: 70 | name: connectivity_for_web 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "0.4.0" 74 | connectivity_macos: 75 | dependency: transitive 76 | description: 77 | name: connectivity_macos 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "0.2.0" 81 | connectivity_platform_interface: 82 | dependency: transitive 83 | description: 84 | name: connectivity_platform_interface 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "2.0.1" 88 | crypto: 89 | dependency: transitive 90 | description: 91 | name: crypto 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "3.0.0" 95 | english_words: 96 | dependency: "direct main" 97 | description: 98 | name: english_words 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "4.0.0" 102 | external_app_launcher: 103 | dependency: "direct main" 104 | description: 105 | name: external_app_launcher 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "0.0.1" 109 | fake_async: 110 | dependency: transitive 111 | description: 112 | name: fake_async 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "1.2.0" 116 | ffi: 117 | dependency: transitive 118 | description: 119 | name: ffi 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "1.0.0" 123 | file: 124 | dependency: transitive 125 | description: 126 | name: file 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "6.1.0" 130 | firebase_core: 131 | dependency: "direct main" 132 | description: 133 | name: firebase_core 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "1.0.3" 137 | firebase_core_platform_interface: 138 | dependency: transitive 139 | description: 140 | name: firebase_core_platform_interface 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "4.0.0" 144 | firebase_core_web: 145 | dependency: transitive 146 | description: 147 | name: firebase_core_web 148 | url: "https://pub.dartlang.org" 149 | source: hosted 150 | version: "1.0.2" 151 | firebase_messaging: 152 | dependency: "direct main" 153 | description: 154 | name: firebase_messaging 155 | url: "https://pub.dartlang.org" 156 | source: hosted 157 | version: "9.1.1" 158 | firebase_messaging_platform_interface: 159 | dependency: transitive 160 | description: 161 | name: firebase_messaging_platform_interface 162 | url: "https://pub.dartlang.org" 163 | source: hosted 164 | version: "2.1.1" 165 | firebase_messaging_web: 166 | dependency: transitive 167 | description: 168 | name: firebase_messaging_web 169 | url: "https://pub.dartlang.org" 170 | source: hosted 171 | version: "1.0.4" 172 | flutter: 173 | dependency: "direct main" 174 | description: flutter 175 | source: sdk 176 | version: "0.0.0" 177 | flutter_launcher_icons: 178 | dependency: "direct main" 179 | description: 180 | name: flutter_launcher_icons 181 | url: "https://pub.dartlang.org" 182 | source: hosted 183 | version: "0.9.0" 184 | flutter_linkify: 185 | dependency: "direct main" 186 | description: 187 | name: flutter_linkify 188 | url: "https://pub.dartlang.org" 189 | source: hosted 190 | version: "5.0.2" 191 | flutter_local_notifications: 192 | dependency: "direct main" 193 | description: 194 | name: flutter_local_notifications 195 | url: "https://pub.dartlang.org" 196 | source: hosted 197 | version: "5.0.0+1" 198 | flutter_local_notifications_platform_interface: 199 | dependency: transitive 200 | description: 201 | name: flutter_local_notifications_platform_interface 202 | url: "https://pub.dartlang.org" 203 | source: hosted 204 | version: "3.0.0" 205 | flutter_test: 206 | dependency: "direct dev" 207 | description: flutter 208 | source: sdk 209 | version: "0.0.0" 210 | flutter_web_plugins: 211 | dependency: transitive 212 | description: flutter 213 | source: sdk 214 | version: "0.0.0" 215 | geolocator: 216 | dependency: "direct main" 217 | description: 218 | name: geolocator 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "7.0.1" 222 | geolocator_platform_interface: 223 | dependency: transitive 224 | description: 225 | name: geolocator_platform_interface 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "2.0.0" 229 | geolocator_web: 230 | dependency: transitive 231 | description: 232 | name: geolocator_web 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "2.0.1" 236 | http: 237 | dependency: "direct main" 238 | description: 239 | name: http 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "0.13.1" 243 | http_parser: 244 | dependency: transitive 245 | description: 246 | name: http_parser 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "4.0.0" 250 | image: 251 | dependency: transitive 252 | description: 253 | name: image 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "3.0.1" 257 | in_app_review: 258 | dependency: "direct main" 259 | description: 260 | name: in_app_review 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "2.0.1" 264 | in_app_review_platform_interface: 265 | dependency: transitive 266 | description: 267 | name: in_app_review_platform_interface 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "2.0.2" 271 | js: 272 | dependency: transitive 273 | description: 274 | name: js 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "0.6.3" 278 | linkify: 279 | dependency: transitive 280 | description: 281 | name: linkify 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "4.0.0" 285 | matcher: 286 | dependency: transitive 287 | description: 288 | name: matcher 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "0.12.10" 292 | meta: 293 | dependency: transitive 294 | description: 295 | name: meta 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "1.3.0" 299 | package_info: 300 | dependency: "direct main" 301 | description: 302 | name: package_info 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "2.0.0" 306 | path: 307 | dependency: transitive 308 | description: 309 | name: path 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "1.8.0" 313 | path_provider_linux: 314 | dependency: transitive 315 | description: 316 | name: path_provider_linux 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "2.0.0" 320 | path_provider_platform_interface: 321 | dependency: transitive 322 | description: 323 | name: path_provider_platform_interface 324 | url: "https://pub.dartlang.org" 325 | source: hosted 326 | version: "2.0.1" 327 | path_provider_windows: 328 | dependency: transitive 329 | description: 330 | name: path_provider_windows 331 | url: "https://pub.dartlang.org" 332 | source: hosted 333 | version: "2.0.0" 334 | pedantic: 335 | dependency: transitive 336 | description: 337 | name: pedantic 338 | url: "https://pub.dartlang.org" 339 | source: hosted 340 | version: "1.11.0" 341 | petitparser: 342 | dependency: transitive 343 | description: 344 | name: petitparser 345 | url: "https://pub.dartlang.org" 346 | source: hosted 347 | version: "4.0.2" 348 | platform: 349 | dependency: transitive 350 | description: 351 | name: platform 352 | url: "https://pub.dartlang.org" 353 | source: hosted 354 | version: "3.0.0" 355 | plugin_platform_interface: 356 | dependency: transitive 357 | description: 358 | name: plugin_platform_interface 359 | url: "https://pub.dartlang.org" 360 | source: hosted 361 | version: "2.0.0" 362 | process: 363 | dependency: transitive 364 | description: 365 | name: process 366 | url: "https://pub.dartlang.org" 367 | source: hosted 368 | version: "4.1.0" 369 | settings_ui: 370 | dependency: "direct main" 371 | description: 372 | path: "." 373 | ref: f9d0639 374 | resolved-ref: f9d0639494f591cad9fc77783b052b56d29e9dcf 375 | url: "https://github.com/EduWireApps/flutter-settings-ui.git" 376 | source: git 377 | version: "1.0.0-nullsafety.2" 378 | shared_preferences: 379 | dependency: "direct main" 380 | description: 381 | name: shared_preferences 382 | url: "https://pub.dartlang.org" 383 | source: hosted 384 | version: "2.0.5" 385 | shared_preferences_linux: 386 | dependency: transitive 387 | description: 388 | name: shared_preferences_linux 389 | url: "https://pub.dartlang.org" 390 | source: hosted 391 | version: "2.0.0" 392 | shared_preferences_macos: 393 | dependency: transitive 394 | description: 395 | name: shared_preferences_macos 396 | url: "https://pub.dartlang.org" 397 | source: hosted 398 | version: "2.0.0" 399 | shared_preferences_platform_interface: 400 | dependency: transitive 401 | description: 402 | name: shared_preferences_platform_interface 403 | url: "https://pub.dartlang.org" 404 | source: hosted 405 | version: "2.0.0" 406 | shared_preferences_web: 407 | dependency: transitive 408 | description: 409 | name: shared_preferences_web 410 | url: "https://pub.dartlang.org" 411 | source: hosted 412 | version: "2.0.0" 413 | shared_preferences_windows: 414 | dependency: transitive 415 | description: 416 | name: shared_preferences_windows 417 | url: "https://pub.dartlang.org" 418 | source: hosted 419 | version: "2.0.0" 420 | sky_engine: 421 | dependency: transitive 422 | description: flutter 423 | source: sdk 424 | version: "0.0.99" 425 | source_span: 426 | dependency: transitive 427 | description: 428 | name: source_span 429 | url: "https://pub.dartlang.org" 430 | source: hosted 431 | version: "1.8.0" 432 | stack_trace: 433 | dependency: transitive 434 | description: 435 | name: stack_trace 436 | url: "https://pub.dartlang.org" 437 | source: hosted 438 | version: "1.10.0" 439 | stream_channel: 440 | dependency: transitive 441 | description: 442 | name: stream_channel 443 | url: "https://pub.dartlang.org" 444 | source: hosted 445 | version: "2.1.0" 446 | string_scanner: 447 | dependency: transitive 448 | description: 449 | name: string_scanner 450 | url: "https://pub.dartlang.org" 451 | source: hosted 452 | version: "1.1.0" 453 | term_glyph: 454 | dependency: transitive 455 | description: 456 | name: term_glyph 457 | url: "https://pub.dartlang.org" 458 | source: hosted 459 | version: "1.2.0" 460 | test_api: 461 | dependency: transitive 462 | description: 463 | name: test_api 464 | url: "https://pub.dartlang.org" 465 | source: hosted 466 | version: "0.2.19" 467 | timezone: 468 | dependency: transitive 469 | description: 470 | name: timezone 471 | url: "https://pub.dartlang.org" 472 | source: hosted 473 | version: "0.7.0" 474 | typed_data: 475 | dependency: transitive 476 | description: 477 | name: typed_data 478 | url: "https://pub.dartlang.org" 479 | source: hosted 480 | version: "1.3.0" 481 | url_launcher: 482 | dependency: "direct main" 483 | description: 484 | name: url_launcher 485 | url: "https://pub.dartlang.org" 486 | source: hosted 487 | version: "6.0.3" 488 | url_launcher_linux: 489 | dependency: transitive 490 | description: 491 | name: url_launcher_linux 492 | url: "https://pub.dartlang.org" 493 | source: hosted 494 | version: "2.0.0" 495 | url_launcher_macos: 496 | dependency: transitive 497 | description: 498 | name: url_launcher_macos 499 | url: "https://pub.dartlang.org" 500 | source: hosted 501 | version: "2.0.0" 502 | url_launcher_platform_interface: 503 | dependency: transitive 504 | description: 505 | name: url_launcher_platform_interface 506 | url: "https://pub.dartlang.org" 507 | source: hosted 508 | version: "2.0.2" 509 | url_launcher_web: 510 | dependency: transitive 511 | description: 512 | name: url_launcher_web 513 | url: "https://pub.dartlang.org" 514 | source: hosted 515 | version: "2.0.0" 516 | url_launcher_windows: 517 | dependency: transitive 518 | description: 519 | name: url_launcher_windows 520 | url: "https://pub.dartlang.org" 521 | source: hosted 522 | version: "2.0.0" 523 | vector_math: 524 | dependency: transitive 525 | description: 526 | name: vector_math 527 | url: "https://pub.dartlang.org" 528 | source: hosted 529 | version: "2.1.0" 530 | win32: 531 | dependency: transitive 532 | description: 533 | name: win32 534 | url: "https://pub.dartlang.org" 535 | source: hosted 536 | version: "2.0.4" 537 | xdg_directories: 538 | dependency: transitive 539 | description: 540 | name: xdg_directories 541 | url: "https://pub.dartlang.org" 542 | source: hosted 543 | version: "0.2.0" 544 | xml: 545 | dependency: transitive 546 | description: 547 | name: xml 548 | url: "https://pub.dartlang.org" 549 | source: hosted 550 | version: "5.0.2" 551 | yaml: 552 | dependency: transitive 553 | description: 554 | name: yaml 555 | url: "https://pub.dartlang.org" 556 | source: hosted 557 | version: "3.1.0" 558 | sdks: 559 | dart: ">=2.12.0 <3.0.0" 560 | flutter: ">=2.0.0" 561 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: pronote_notifications 2 | description: Notifications pour Pronote 3 | 4 | publish_to: 'none' 5 | 6 | version: 1.1.4+5 7 | 8 | environment: 9 | sdk: ">=2.7.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | firebase_core: ^1.0.3 15 | firebase_messaging: ^9.1.1 16 | flutter_local_notifications: ^5.0.0+1 17 | english_words: ^4.0.0 18 | http: ^0.13.1 19 | shared_preferences: ^2.0.5 20 | connectivity: ^3.0.3 21 | settings_ui: 22 | git: 23 | url: https://github.com/EduWireApps/flutter-settings-ui.git 24 | ref: f9d0639 25 | flutter_launcher_icons: ^0.9.0 26 | geolocator: ^7.0.1 27 | url_launcher: ^6.0.3 28 | in_app_review: ^2.0.1 29 | package_info: ^2.0.0 30 | external_app_launcher: ^0.0.1 31 | flutter_linkify: ^5.0.2 32 | 33 | flutter_icons: 34 | android: "launcher_icon" 35 | ios: true 36 | image_path: "assets/launcher-icon.png" 37 | 38 | cupertino_icons: ^1.0.2 39 | 40 | dev_dependencies: 41 | flutter_test: 42 | sdk: flutter 43 | 44 | flutter: 45 | 46 | uses-material-design: true 47 | 48 | fonts: 49 | - family: Product Sans 50 | fonts: 51 | - asset: fonts/ProductSans-Regular.ttf 52 | 53 | assets: 54 | - url-pronote.png 55 | - launcher-icon.png 56 | - icon.png 57 | -------------------------------------------------------------------------------- /screenshots/badges/appstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/badges/appstore.png -------------------------------------------------------------------------------- /screenshots/badges/playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/badges/playstore.png -------------------------------------------------------------------------------- /screenshots/ipad-4th-gen-129-inches/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/ipad-4th-gen-129-inches/account.png -------------------------------------------------------------------------------- /screenshots/ipad-4th-gen-129-inches/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/ipad-4th-gen-129-inches/login.png -------------------------------------------------------------------------------- /screenshots/ipad-4th-gen-129-inches/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/ipad-4th-gen-129-inches/notification.png -------------------------------------------------------------------------------- /screenshots/iphone-6s-plus-55-inches/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/iphone-6s-plus-55-inches/account.png -------------------------------------------------------------------------------- /screenshots/iphone-6s-plus-55-inches/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/iphone-6s-plus-55-inches/login.png -------------------------------------------------------------------------------- /screenshots/iphone-6s-plus-55-inches/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/iphone-6s-plus-55-inches/notification.png -------------------------------------------------------------------------------- /screenshots/iphone-xs-max-65-inches/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/iphone-xs-max-65-inches/account.png -------------------------------------------------------------------------------- /screenshots/iphone-xs-max-65-inches/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/iphone-xs-max-65-inches/login.png -------------------------------------------------------------------------------- /screenshots/iphone-xs-max-65-inches/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/iphone-xs-max-65-inches/notification.png -------------------------------------------------------------------------------- /screenshots/preview/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/preview/account.png -------------------------------------------------------------------------------- /screenshots/preview/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/preview/login.png -------------------------------------------------------------------------------- /screenshots/preview/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EduWireApps/pronote-notifications-app/43e16300d2461c1f0070774e619d22f5dd467488/screenshots/preview/notification.png --------------------------------------------------------------------------------