Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f38ff3b862 | ||
|
|
89e67c369e | ||
|
|
6dd68c8f5d | ||
|
|
97b01e9f14 | ||
|
|
556ba9d289 | ||
|
|
64868e85f3 | ||
|
|
30ac155b4b | ||
|
|
36bd679644 | ||
|
|
75b03b95bc | ||
|
|
ac18cf62c3 | ||
|
|
3619a7a4a7 | ||
|
|
a71b365e4a | ||
|
|
20fa9a8aef | ||
|
|
da12ac8646 | ||
|
|
4b40692fe1 | ||
|
|
26f65a4144 | ||
|
|
f8cfa04d04 | ||
|
|
82671f5ec9 | ||
|
|
5d37de897f | ||
|
|
fcb1d8d6d9 | ||
|
|
446fad4c5f | ||
|
|
0f799375a1 | ||
|
|
29aa356cd0 | ||
|
|
3abaf2f96a | ||
|
|
5b48847cf2 | ||
|
|
b82a56ca65 | ||
|
|
94c57abdea | ||
|
|
e3c26987ec | ||
|
|
eac710a5b4 | ||
|
|
b8299c4daf | ||
|
|
7a671b6aa6 | ||
|
|
f51de83c88 | ||
|
|
d77cc081a9 | ||
|
|
18fa9a6de7 | ||
|
|
4467267e61 | ||
|
|
f39b9ffeb6 | ||
|
|
0df9de97d4 | ||
|
|
69a3090f16 | ||
|
|
818060bbcb | ||
|
|
38eb8c440b | ||
|
|
47a18c1ec2 | ||
|
|
cc33550331 | ||
|
|
4af3e51300 | ||
|
|
ea33d00f54 | ||
|
|
75eba2c83f | ||
|
|
4a81722747 | ||
|
|
ed67551164 | ||
|
|
c53502f16a | ||
|
|
d13de96ae9 | ||
|
|
53e9aca376 | ||
|
|
8a39086ca6 | ||
|
|
fd7793a20d | ||
|
|
7a793a3af0 | ||
|
|
cac21a4849 | ||
|
|
4c558157e8 | ||
|
|
043b669737 | ||
|
|
7b9ec6de2e | ||
|
|
b14821901c | ||
|
|
cc05524bea | ||
|
|
b3d791a4c3 | ||
|
|
9525d7d1df | ||
|
|
bc040185d0 | ||
|
|
65e98bf8a8 | ||
|
|
1a0558485e |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
|||||||
patreon: filcnaplo
|
github: filc
|
||||||
|
|||||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "pub" # See documentation for possible values
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
|||||||
# See https://www.dartlang.org/guides/libraries/private-files
|
# See https://www.dartlang.org/guides/libraries/private-files
|
||||||
|
|
||||||
termek.txt
|
termek.txt
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
# Files and directories created by pub
|
# Files and directories created by pub
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
|
|||||||
18
changelog.md
18
changelog.md
@@ -1,2 +1,16 @@
|
|||||||
- Design javítások
|
What's new:
|
||||||
- Hibajavítások
|
|
||||||
|
- A jelenlegi hét kiválasztása esetén, egyből az aktuális napot választja ki ⏰
|
||||||
|
- A szellemjegyeknél bármilyen értéket megadhatsz 🎲
|
||||||
|
- A házifeladatok mostmár tökéletesen működnek 📚
|
||||||
|
- Mobilnetes firssítésnél figyelmeztetés ⚠️
|
||||||
|
- Hibajavítások 🐛
|
||||||
|
- **Megérkezett a Filc Premium!** ✨
|
||||||
|
|
||||||
|
Prémium funkciók:
|
||||||
|
|
||||||
|
- Egyedi név 👤
|
||||||
|
- Részletes jegy statisztikák 📈
|
||||||
|
- Testre szabhatóbb színek 🎨
|
||||||
|
- Választható tantárgy ikonok 📚
|
||||||
|
- Heti órarend nézet 📅
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
# This file tracks properties of this Flutter project.
|
# This file tracks properties of this Flutter project.
|
||||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
#
|
#
|
||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: 06e2fd63574bad2edafbe4653104ed76871ee0b1
|
revision: 3c0bee85b8e43b860877922bdc411a7333db4d32
|
||||||
channel: beta
|
channel: beta
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: 3c0bee85b8e43b860877922bdc411a7333db4d32
|
||||||
|
base_revision: 3c0bee85b8e43b860877922bdc411a7333db4d32
|
||||||
|
- platform: macos
|
||||||
|
create_revision: 3c0bee85b8e43b860877922bdc411a7333db4d32
|
||||||
|
base_revision: 3c0bee85b8e43b860877922bdc411a7333db4d32
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||||
|
|||||||
@@ -26,13 +26,8 @@ apply plugin: 'kotlin-android'
|
|||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
def keystorePropertiesFile = rootProject.file("$System.env.ANDROID_SIGNING")
|
def keystorePropertiesFile = rootProject.file("$System.env.HOME/keys/filc3.properties")
|
||||||
if (keystorePropertiesFile.exists()) {
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
|
||||||
} else {
|
|
||||||
keystoreProperties.load(new FileInputStream(rootProject.file("signing/signing.properties")))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
|
|||||||
@@ -3,17 +3,60 @@
|
|||||||
<activity android:exported="true" android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
|
<activity android:exported="true" android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
|
||||||
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
|
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter android:autoVerify="true">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<!-- Accepts URIs that begin with https://api.filcnaplo.hu -->
|
||||||
|
<data
|
||||||
|
android:scheme="https"
|
||||||
|
android:host="api.filcnaplo.hu"
|
||||||
|
android:pathPrefix="/callback" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<meta-data android:name="flutterEmbedding" android:value="2" />
|
<meta-data android:name="flutterEmbedding" android:value="2" />
|
||||||
|
|
||||||
|
<!-- <receiver android:name=".WidgetTimetable.widget_timetable"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
<action android:name="list_widget.ACTION_WIDGET_CLICK_NAV_LEFT" />
|
||||||
|
<action android:name="list_widget.ACTION_WIDGET_CLICK_NAV_RIGHT" />
|
||||||
|
<action android:name="list_widget.ACTION_WIDGET_CLICK_NAV_TODAY" />
|
||||||
|
<action android:name="list_widget.ACTION_WIDGET_CLICK_NAV_REFRESH" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/home_widget_test_info" />
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<service android:name=".WidgetTimetable.widget_timetable_service"
|
||||||
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
|
|
||||||
|
<receiver android:name="es.antonborri.home_widget.HomeWidgetBackgroundReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="es.antonborri.home_widget.action.BACKGROUND" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<service android:name="es.antonborri.home_widget.HomeWidgetBackgroundService"
|
||||||
|
android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
|
||||||
|
-->
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<!-- Permissions -->
|
<!-- Permissions -->
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -2,8 +2,8 @@ buildscript {
|
|||||||
ext.kotlin_version = '1.6.10'
|
ext.kotlin_version = '1.6.10'
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
compileSdkVersion = 31
|
compileSdkVersion = 33
|
||||||
targetSdkVersion = 31
|
targetSdkVersion = 33
|
||||||
appCompatVersion = "1.1.0"
|
appCompatVersion = "1.1.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ subprojects {
|
|||||||
afterEvaluate {project ->
|
afterEvaluate {project ->
|
||||||
if (project.plugins.hasPlugin('android') || project.plugins.hasPlugin('android-library')) {
|
if (project.plugins.hasPlugin('android') || project.plugins.hasPlugin('android-library')) {
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
compileSdkVersion 33
|
||||||
buildToolsVersion '31.0.0'
|
buildToolsVersion '31.0.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
|||||||
keyAlias=test
|
|
||||||
keyPassword=test123
|
|
||||||
storeFile=../signing/signing.keystore
|
|
||||||
storePassword=test123
|
|
||||||
BIN
filcnaplo/assets/animations/backpack-2.riv
Normal file
BIN
filcnaplo/assets/animations/backpack-2.riv
Normal file
Binary file not shown.
1
filcnaplo/assets/animations/bell-alert.json
Normal file
1
filcnaplo/assets/animations/bell-alert.json
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
12
filcnaplo/build.sh
Normal file → Executable file
12
filcnaplo/build.sh
Normal file → Executable file
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/fish
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
# With build number
|
# With build number
|
||||||
function get_version_bn
|
function get_version_bn
|
||||||
@@ -9,11 +9,5 @@ function get_version
|
|||||||
cat pubspec.yaml | grep version: | cut -d' ' -f2 | cut -d+ -f1
|
cat pubspec.yaml | grep version: | cut -d' ' -f2 | cut -d+ -f1
|
||||||
end
|
end
|
||||||
|
|
||||||
if test -e /mnt/enc/keys/filc3.properties
|
flutter build apk --release --dart-define=APPVER=(get_version) --no-tree-shake-icons && \
|
||||||
set -x ANDROID_SIGNING /mnt/enc/keys/filc3.properties
|
cp -v "build/app/outputs/flutter-apk/app-release.apk" ~/"Desktop/hu.filc.naplo_"(get_version_bn).apk
|
||||||
end
|
|
||||||
|
|
||||||
flutter build apk --release --dart-define=APPVER=(get_version) --no-tree-shake-icons
|
|
||||||
cp -v "build/app/outputs/flutter-apk/app-release.apk" ~/"Desktop/hu.filc.naplo_"(get_version_bn).apk
|
|
||||||
|
|
||||||
notify-send "Flutter" "Apk build done."
|
|
||||||
|
|||||||
@@ -21,6 +21,6 @@
|
|||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>9.0</string>
|
<string>11.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
# platform :ios, '9.0'
|
# platform :ios, '11.0'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
@@ -33,7 +33,7 @@ target 'Runner' do
|
|||||||
|
|
||||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||||
|
|
||||||
pod 'DKImagePickerController/PhotoGallery', :git => 'https://github.com/miguelpruivo/DKImagePickerController.git'
|
pod 'DKImagePickerController/PhotoGallery', :git => 'https://github.com/zhangao0086/DKImagePickerController.git'
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
|
|||||||
146
filcnaplo/ios/Podfile.lock
Normal file
146
filcnaplo/ios/Podfile.lock
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
PODS:
|
||||||
|
- connectivity_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- ReachabilitySwift
|
||||||
|
- DKImagePickerController/Core (4.3.4):
|
||||||
|
- DKImagePickerController/ImageDataManager
|
||||||
|
- DKImagePickerController/Resource
|
||||||
|
- DKImagePickerController/ImageDataManager (4.3.4)
|
||||||
|
- DKImagePickerController/PhotoGallery (4.3.4):
|
||||||
|
- DKImagePickerController/Core
|
||||||
|
- DKPhotoGallery
|
||||||
|
- DKImagePickerController/Resource (4.3.4)
|
||||||
|
- DKPhotoGallery (0.0.17):
|
||||||
|
- DKPhotoGallery/Core (= 0.0.17)
|
||||||
|
- DKPhotoGallery/Model (= 0.0.17)
|
||||||
|
- DKPhotoGallery/Preview (= 0.0.17)
|
||||||
|
- DKPhotoGallery/Resource (= 0.0.17)
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Core (0.0.17):
|
||||||
|
- DKPhotoGallery/Model
|
||||||
|
- DKPhotoGallery/Preview
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Model (0.0.17):
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Preview (0.0.17):
|
||||||
|
- DKPhotoGallery/Model
|
||||||
|
- DKPhotoGallery/Resource
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- DKPhotoGallery/Resource (0.0.17):
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
- file_picker (0.0.1):
|
||||||
|
- DKImagePickerController/PhotoGallery
|
||||||
|
- Flutter
|
||||||
|
- Flutter (1.0.0)
|
||||||
|
- flutter_custom_tabs (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FMDB (2.7.5):
|
||||||
|
- FMDB/standard (= 2.7.5)
|
||||||
|
- FMDB/standard (2.7.5)
|
||||||
|
- live_activities (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- open_file (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- path_provider_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- permission_handler_apple (9.0.4):
|
||||||
|
- Flutter
|
||||||
|
- quick_actions_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- ReachabilitySwift (5.0.0)
|
||||||
|
- SDWebImage (5.13.2):
|
||||||
|
- SDWebImage/Core (= 5.13.2)
|
||||||
|
- SDWebImage/Core (5.13.2)
|
||||||
|
- share_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- sqflite (0.0.2):
|
||||||
|
- Flutter
|
||||||
|
- FMDB (>= 2.7.5)
|
||||||
|
- SwiftyGif (5.4.3)
|
||||||
|
- url_launcher_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||||
|
- DKImagePickerController/PhotoGallery (from `https://github.com/zhangao0086/DKImagePickerController.git`)
|
||||||
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
|
- Flutter (from `Flutter`)
|
||||||
|
- flutter_custom_tabs (from `.symlinks/plugins/flutter_custom_tabs/ios`)
|
||||||
|
- live_activities (from `.symlinks/plugins/live_activities/ios`)
|
||||||
|
- open_file (from `.symlinks/plugins/open_file/ios`)
|
||||||
|
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||||
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
|
- quick_actions_ios (from `.symlinks/plugins/quick_actions_ios/ios`)
|
||||||
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- DKPhotoGallery
|
||||||
|
- FMDB
|
||||||
|
- ReachabilitySwift
|
||||||
|
- SDWebImage
|
||||||
|
- SwiftyGif
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
connectivity_plus:
|
||||||
|
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||||
|
DKImagePickerController:
|
||||||
|
:git: https://github.com/zhangao0086/DKImagePickerController.git
|
||||||
|
file_picker:
|
||||||
|
:path: ".symlinks/plugins/file_picker/ios"
|
||||||
|
Flutter:
|
||||||
|
:path: Flutter
|
||||||
|
flutter_custom_tabs:
|
||||||
|
:path: ".symlinks/plugins/flutter_custom_tabs/ios"
|
||||||
|
live_activities:
|
||||||
|
:path: ".symlinks/plugins/live_activities/ios"
|
||||||
|
open_file:
|
||||||
|
:path: ".symlinks/plugins/open_file/ios"
|
||||||
|
path_provider_ios:
|
||||||
|
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||||
|
permission_handler_apple:
|
||||||
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
|
quick_actions_ios:
|
||||||
|
:path: ".symlinks/plugins/quick_actions_ios/ios"
|
||||||
|
share_plus:
|
||||||
|
:path: ".symlinks/plugins/share_plus/ios"
|
||||||
|
sqflite:
|
||||||
|
:path: ".symlinks/plugins/sqflite/ios"
|
||||||
|
url_launcher_ios:
|
||||||
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
|
CHECKOUT OPTIONS:
|
||||||
|
DKImagePickerController:
|
||||||
|
:commit: a727e44718a67e300089174e5591166045815ba4
|
||||||
|
:git: https://github.com/zhangao0086/DKImagePickerController.git
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
|
||||||
|
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||||
|
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||||
|
file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95
|
||||||
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
|
flutter_custom_tabs: 7a10a08686955cb748e5d26e0ae586d30689bf89
|
||||||
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
live_activities: 9ff56a06a2d43ecd68f56deeed13b18a8304789c
|
||||||
|
open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d
|
||||||
|
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||||
|
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
||||||
|
quick_actions_ios: 56c03753992beabaa6c598e470e12d430d6e5e2f
|
||||||
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
|
SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866
|
||||||
|
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||||
|
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||||
|
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
||||||
|
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 862f939bb7e5390bdb8b2534eb81a9457ea9fbdc
|
||||||
|
|
||||||
|
COCOAPODS: 1.11.3
|
||||||
@@ -3,11 +3,18 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 46;
|
objectVersion = 51;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
|
3127F78D28EAEDE200C2EFB3 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3127F75528EAECC800C2EFB3 /* WidgetKit.framework */; };
|
||||||
|
3127F78E28EAEDE200C2EFB3 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3127F75728EAECC800C2EFB3 /* SwiftUI.framework */; };
|
||||||
|
3127F79828EAEDE300C2EFB3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3127F79728EAEDE300C2EFB3 /* Assets.xcassets */; };
|
||||||
|
3127F79E28EAEDE300C2EFB3 /* livecard.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 3127F78C28EAEDE200C2EFB3 /* livecard.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
3127F7A428EAEE3D00C2EFB3 /* livecard.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A328EAEE3D00C2EFB3 /* livecard.intentdefinition */; };
|
||||||
|
3127F7A628EAEE5900C2EFB3 /* livecard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A528EAEE5900C2EFB3 /* livecard.swift */; };
|
||||||
|
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */; };
|
||||||
373A6ECB5FC71FE9D8AF2EDB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F0ADD56276103500A3016C8 /* Pods_Runner.framework */; };
|
373A6ECB5FC71FE9D8AF2EDB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F0ADD56276103500A3016C8 /* Pods_Runner.framework */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
@@ -16,7 +23,28 @@
|
|||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
3127F79C28EAEDE300C2EFB3 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 3127F78B28EAEDE200C2EFB3;
|
||||||
|
remoteInfo = livecardExtension;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
3127F74F28EAEC8A00C2EFB3 /* Embed Foundation Extensions */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 13;
|
||||||
|
files = (
|
||||||
|
3127F79E28EAEDE300C2EFB3 /* livecard.appex in Embed Foundation Extensions */,
|
||||||
|
);
|
||||||
|
name = "Embed Foundation Extensions";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -33,6 +61,16 @@
|
|||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
3127F73928EAEC3200C2EFB3 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
|
3127F73F28EAEC8A00C2EFB3 /* IntentsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IntentsUI.framework; path = System/Library/Frameworks/IntentsUI.framework; sourceTree = SDKROOT; };
|
||||||
|
3127F75528EAECC800C2EFB3 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||||
|
3127F75728EAECC800C2EFB3 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||||
|
3127F78C28EAEDE200C2EFB3 /* livecard.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = livecard.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
3127F79728EAEDE300C2EFB3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
3127F79928EAEDE300C2EFB3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
3127F7A328EAEE3D00C2EFB3 /* livecard.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; path = livecard.intentdefinition; sourceTree = "<group>"; };
|
||||||
|
3127F7A528EAEE5900C2EFB3 /* livecard.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = livecard.swift; sourceTree = "<group>"; tabWidth = 2; };
|
||||||
|
3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = lesson_model.swift; sourceTree = "<group>"; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
707F8089D970F81C480F73C4 /* 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 = "<group>"; };
|
707F8089D970F81C480F73C4 /* 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 = "<group>"; };
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
@@ -50,6 +88,15 @@
|
|||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
3127F78928EAEDE200C2EFB3 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
3127F78E28EAEDE200C2EFB3 /* SwiftUI.framework in Frameworks */,
|
||||||
|
3127F78D28EAEDE200C2EFB3 /* WidgetKit.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -61,10 +108,25 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
3127F78F28EAEDE200C2EFB3 /* livecard */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3127F7A728EAEE8500C2EFB3 /* lesson_model.swift */,
|
||||||
|
3127F7A328EAEE3D00C2EFB3 /* livecard.intentdefinition */,
|
||||||
|
3127F79728EAEDE300C2EFB3 /* Assets.xcassets */,
|
||||||
|
3127F79928EAEDE300C2EFB3 /* Info.plist */,
|
||||||
|
3127F7A528EAEE5900C2EFB3 /* livecard.swift */,
|
||||||
|
);
|
||||||
|
path = livecard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
6640A963014A9D4F31026053 /* Frameworks */ = {
|
6640A963014A9D4F31026053 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */,
|
1F0ADD56276103500A3016C8 /* Pods_Runner.framework */,
|
||||||
|
3127F73F28EAEC8A00C2EFB3 /* IntentsUI.framework */,
|
||||||
|
3127F75528EAECC800C2EFB3 /* WidgetKit.framework */,
|
||||||
|
3127F75728EAECC800C2EFB3 /* SwiftUI.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -76,7 +138,6 @@
|
|||||||
98578F0EBCC6D3FF8391AAEB /* Pods-Runner.release.xcconfig */,
|
98578F0EBCC6D3FF8391AAEB /* Pods-Runner.release.xcconfig */,
|
||||||
707F8089D970F81C480F73C4 /* Pods-Runner.profile.xcconfig */,
|
707F8089D970F81C480F73C4 /* Pods-Runner.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
name = Pods;
|
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@@ -96,6 +157,7 @@
|
|||||||
children = (
|
children = (
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
|
3127F78F28EAEDE200C2EFB3 /* livecard */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
91FEB6212755D596FFFFEC73 /* Pods */,
|
91FEB6212755D596FFFFEC73 /* Pods */,
|
||||||
6640A963014A9D4F31026053 /* Frameworks */,
|
6640A963014A9D4F31026053 /* Frameworks */,
|
||||||
@@ -106,6 +168,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||||
|
3127F78C28EAEDE200C2EFB3 /* livecard.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -113,6 +176,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
3127F73928EAEC3200C2EFB3 /* Runner.entitlements */,
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||||
@@ -128,6 +192,23 @@
|
|||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
3127F78B28EAEDE200C2EFB3 /* livecard */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 3127F79F28EAEDE300C2EFB3 /* Build configuration list for PBXNativeTarget "livecard" */;
|
||||||
|
buildPhases = (
|
||||||
|
3127F78828EAEDE200C2EFB3 /* Sources */,
|
||||||
|
3127F78928EAEDE200C2EFB3 /* Frameworks */,
|
||||||
|
3127F78A28EAEDE200C2EFB3 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = livecard;
|
||||||
|
productName = livecardExtension;
|
||||||
|
productReference = 3127F78C28EAEDE200C2EFB3 /* livecard.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
@@ -140,10 +221,12 @@
|
|||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
71459C0EB905E05018E3D78F /* [CP] Embed Pods Frameworks */,
|
71459C0EB905E05018E3D78F /* [CP] Embed Pods Frameworks */,
|
||||||
|
3127F74F28EAEC8A00C2EFB3 /* Embed Foundation Extensions */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
3127F79D28EAEDE300C2EFB3 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Runner;
|
name = Runner;
|
||||||
productName = Runner;
|
productName = Runner;
|
||||||
@@ -156,9 +239,13 @@
|
|||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1020;
|
LastSwiftUpdateCheck = 1410;
|
||||||
|
LastUpgradeCheck = 1300;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
|
3127F78B28EAEDE200C2EFB3 = {
|
||||||
|
CreatedOnToolsVersion = 14.1;
|
||||||
|
};
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
CreatedOnToolsVersion = 7.3.1;
|
CreatedOnToolsVersion = 7.3.1;
|
||||||
LastSwiftMigration = 1100;
|
LastSwiftMigration = 1100;
|
||||||
@@ -179,11 +266,20 @@
|
|||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
97C146ED1CF9000F007C117D /* Runner */,
|
97C146ED1CF9000F007C117D /* Runner */,
|
||||||
|
3127F78B28EAEDE200C2EFB3 /* livecard */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
3127F78A28EAEDE200C2EFB3 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
3127F79828EAEDE300C2EFB3 /* Assets.xcassets in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -268,6 +364,16 @@
|
|||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
3127F78828EAEDE200C2EFB3 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
3127F7A828EAEE8500C2EFB3 /* lesson_model.swift in Sources */,
|
||||||
|
3127F7A428EAEE3D00C2EFB3 /* livecard.intentdefinition in Sources */,
|
||||||
|
3127F7A628EAEE5900C2EFB3 /* livecard.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -279,6 +385,14 @@
|
|||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
3127F79D28EAEDE300C2EFB3 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 3127F78B28EAEDE200C2EFB3 /* livecard */;
|
||||||
|
targetProxy = 3127F79C28EAEDE300C2EFB3 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
@@ -322,6 +436,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
@@ -340,7 +455,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
@@ -353,12 +468,18 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo;
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -367,6 +488,125 @@
|
|||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
};
|
};
|
||||||
|
3127F7A028EAEDE300C2EFB3 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = livecard/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo.livecardpro;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
3127F7A128EAEDE300C2EFB3 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = livecard/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo.livecardpro;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
3127F7A228EAEDE300C2EFB3 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = livecard/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = livecard;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
INFOPLIST_KEY_NSSupportsLiveActivities = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo.livecardpro;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
97C147031CF9000F007C117D /* Debug */ = {
|
97C147031CF9000F007C117D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
@@ -390,6 +630,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
@@ -414,7 +655,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -445,6 +686,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
@@ -463,10 +705,11 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
@@ -477,12 +720,18 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo;
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -496,12 +745,18 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo;
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.naplo;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@@ -513,6 +768,16 @@
|
|||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
3127F79F28EAEDE300C2EFB3 /* Build configuration list for PBXNativeTarget "livecard" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
3127F7A028EAEDE300C2EFB3 /* Debug */,
|
||||||
|
3127F7A128EAEDE300C2EFB3 /* Release */,
|
||||||
|
3127F7A228EAEDE300C2EFB3 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1300"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -27,8 +27,6 @@
|
|||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
@@ -38,8 +36,8 @@
|
|||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<Testables>
|
||||||
</AdditionalOptions>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -61,8 +59,6 @@
|
|||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Profile"
|
buildConfiguration = "Profile"
|
||||||
|
|||||||
@@ -8,6 +8,18 @@ import Flutter
|
|||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
|
|
||||||
|
// here, Without this code the task will not work.
|
||||||
|
//SwiftFlutterForegroundTaskPlugin.setPluginRegistrantCallback(registerPlugins)
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
|
||||||
|
}
|
||||||
|
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// here
|
||||||
|
func registerPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
GeneratedPluginRegistrant.register(with: registry)
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSSupportsLiveActivities</key>
|
||||||
|
<true/>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
@@ -52,5 +54,7 @@
|
|||||||
<string>The app requires the photo library to set a custom profile picture.</string>
|
<string>The app requires the photo library to set a custom profile picture.</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
</dict>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>production</string>
|
<string>development</string>
|
||||||
</dict>
|
<key>com.apple.developer.associated-domains</key>
|
||||||
|
<array>
|
||||||
|
<string>applinks:api.filcnaplo.hu</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
6
filcnaplo/ios/livecard/Assets.xcassets/Contents.json
Normal file
6
filcnaplo/ios/livecard/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
11
filcnaplo/ios/livecard/Info.plist
Normal file
11
filcnaplo/ios/livecard/Info.plist
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
<string>com.apple.widgetkit-extension</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
27
filcnaplo/ios/livecard/lesson_model.swift
Normal file
27
filcnaplo/ios/livecard/lesson_model.swift
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
class LessonData {
|
||||||
|
var icon: String
|
||||||
|
var index: String
|
||||||
|
var title: String
|
||||||
|
var subtitle: String
|
||||||
|
var description: String
|
||||||
|
var startDate: Date
|
||||||
|
var endDate: Date
|
||||||
|
var date: ClosedRange<Date>
|
||||||
|
var nextSubject: String
|
||||||
|
var nextRoom: String
|
||||||
|
|
||||||
|
init?(JSONData data:[String: String]) {
|
||||||
|
self.icon = data["icon"]!
|
||||||
|
self.index = data["index"]!
|
||||||
|
self.title = data["title"]!
|
||||||
|
self.subtitle = data["subtitle"]!
|
||||||
|
self.description = data["description"]!
|
||||||
|
self.startDate = Date(timeIntervalSince1970: Double(data["startDate"]!)! / 1000)
|
||||||
|
self.endDate = Date(timeIntervalSince1970: Double(data["endDate"]!)! / 1000)
|
||||||
|
date = self.startDate...self.endDate
|
||||||
|
self.nextSubject = data["nextSubject"]!
|
||||||
|
self.nextRoom = data["nextRoom"]!
|
||||||
|
}
|
||||||
|
}
|
||||||
59
filcnaplo/ios/livecard/livecard.intentdefinition
Normal file
59
filcnaplo/ios/livecard/livecard.intentdefinition
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>INEnums</key>
|
||||||
|
<array/>
|
||||||
|
<key>INIntentDefinitionModelVersion</key>
|
||||||
|
<string>1.2</string>
|
||||||
|
<key>INIntentDefinitionNamespace</key>
|
||||||
|
<string>88xZPY</string>
|
||||||
|
<key>INIntentDefinitionSystemVersion</key>
|
||||||
|
<string>20A294</string>
|
||||||
|
<key>INIntentDefinitionToolsBuildVersion</key>
|
||||||
|
<string>12A6144</string>
|
||||||
|
<key>INIntentDefinitionToolsVersion</key>
|
||||||
|
<string>12.0</string>
|
||||||
|
<key>INIntents</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>INIntentCategory</key>
|
||||||
|
<string>information</string>
|
||||||
|
<key>INIntentDescriptionID</key>
|
||||||
|
<string>tVvJ9c</string>
|
||||||
|
<key>INIntentEligibleForWidgets</key>
|
||||||
|
<true/>
|
||||||
|
<key>INIntentIneligibleForSuggestions</key>
|
||||||
|
<true/>
|
||||||
|
<key>INIntentName</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>INIntentResponse</key>
|
||||||
|
<dict>
|
||||||
|
<key>INIntentResponseCodes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>INIntentResponseCodeName</key>
|
||||||
|
<string>success</string>
|
||||||
|
<key>INIntentResponseCodeSuccess</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>INIntentResponseCodeName</key>
|
||||||
|
<string>failure</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<key>INIntentTitle</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>INIntentTitleID</key>
|
||||||
|
<string>gpCwrM</string>
|
||||||
|
<key>INIntentType</key>
|
||||||
|
<string>Custom</string>
|
||||||
|
<key>INIntentVerb</key>
|
||||||
|
<string>View</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>INTypes</key>
|
||||||
|
<array/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
137
filcnaplo/ios/livecard/livecard.swift
Normal file
137
filcnaplo/ios/livecard/livecard.swift
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
import ActivityKit
|
||||||
|
import WidgetKit
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct Widgets: WidgetBundle {
|
||||||
|
var body: some Widget {
|
||||||
|
if #available(iOS 16.1, *) {
|
||||||
|
LiveCardWidget()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to redefined live activities pipe
|
||||||
|
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
|
||||||
|
public typealias LiveDeliveryData = ContentState
|
||||||
|
|
||||||
|
public struct ContentState: Codable, Hashable {
|
||||||
|
var data: Dictionary<String, String>
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = UUID()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOSApplicationExtension 16.1, *)
|
||||||
|
struct LiveCardWidget: Widget {
|
||||||
|
var body: some WidgetConfiguration {
|
||||||
|
/// Live Activity Notification
|
||||||
|
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
|
||||||
|
let lesson = LessonData(JSONData: context.state.data)
|
||||||
|
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
Image(systemName: lesson!.icon)
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: CGFloat(30), height: CGFloat(30))
|
||||||
|
.padding(.leading, CGFloat(8))
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text(lesson!.index + lesson!.title)
|
||||||
|
.font(.title3)
|
||||||
|
.bold()
|
||||||
|
|
||||||
|
Text(lesson!.description)
|
||||||
|
.font(.subheadline)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "arrow.right")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: CGFloat(12), height: CGFloat(12))
|
||||||
|
Text(lesson!.nextSubject)
|
||||||
|
.font(.caption)
|
||||||
|
Text(lesson!.nextRoom)
|
||||||
|
.font(.caption2)
|
||||||
|
}
|
||||||
|
}.padding(15)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text(lesson!.subtitle)
|
||||||
|
.font(.subheadline)
|
||||||
|
.padding(.trailing, 12)
|
||||||
|
}.padding(12)
|
||||||
|
/// Dynamic Island
|
||||||
|
} dynamicIsland: { context in
|
||||||
|
let lesson = LessonData(JSONData: context.state.data)
|
||||||
|
|
||||||
|
/// Expanded
|
||||||
|
return DynamicIsland {
|
||||||
|
DynamicIslandExpandedRegion(.leading) {
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: lesson!.icon)
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: CGFloat(30), height: CGFloat(30))
|
||||||
|
.padding(.leading, CGFloat(6))
|
||||||
|
.padding(.bottom, CGFloat(6))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DynamicIslandExpandedRegion(.center) {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text(lesson!.index + lesson!.title)
|
||||||
|
.lineLimit(1)
|
||||||
|
.font(.title3)
|
||||||
|
.bold()
|
||||||
|
|
||||||
|
Text(lesson!.description)
|
||||||
|
.lineLimit(2)
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DynamicIslandExpandedRegion(.trailing) {
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
Text(lesson!.subtitle)
|
||||||
|
.lineLimit(1)
|
||||||
|
.font(.subheadline)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compact
|
||||||
|
} compactLeading: {
|
||||||
|
Label {
|
||||||
|
Text(lesson!.title)
|
||||||
|
} icon: {
|
||||||
|
Image(systemName: lesson!.icon)
|
||||||
|
}
|
||||||
|
.font(.caption2)
|
||||||
|
} compactTrailing: {
|
||||||
|
Text(timerInterval: lesson!.date, countsDown: true)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.frame(width: 40)
|
||||||
|
.font(.caption2)
|
||||||
|
|
||||||
|
/// Collapsed
|
||||||
|
} minimal: {
|
||||||
|
VStack(alignment: .center) {
|
||||||
|
Image(systemName: lesson!.icon)
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: CGFloat(12), height: CGFloat(12))
|
||||||
|
|
||||||
|
Text(timerInterval: lesson!.date, countsDown: true)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.monospacedDigit()
|
||||||
|
.font(.system(size: CGFloat(10)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.keylineTint(.accentColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,8 @@ class FilcAPI {
|
|||||||
// Private API
|
// Private API
|
||||||
static const config = "https://api.filcnaplo.hu/config";
|
static const config = "https://api.filcnaplo.hu/config";
|
||||||
static const reportApi = "https://api.filcnaplo.hu/report";
|
static const reportApi = "https://api.filcnaplo.hu/report";
|
||||||
|
static const premiumApi = "https://api.filcnaplo.hu/premium/activate";
|
||||||
|
static const premiumScopesApi = "https://api.filcnaplo.hu/premium/scopes";
|
||||||
|
|
||||||
// Updates
|
// Updates
|
||||||
static const repo = "filc/naplo";
|
static const repo = "filc/naplo";
|
||||||
@@ -121,19 +123,16 @@ class FilcAPI {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<http.StreamedResponse?> downloadRelease(Release release) {
|
static Future<http.StreamedResponse?> downloadRelease(ReleaseDownload release) {
|
||||||
if (release.downloads.isNotEmpty) {
|
|
||||||
try {
|
try {
|
||||||
var client = http.Client();
|
var client = http.Client();
|
||||||
var request = http.Request('GET', Uri.parse(release.downloads.first));
|
var request = http.Request('GET', Uri.parse(release.url));
|
||||||
return client.send(request);
|
return client.send(request);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
print("ERROR: FilcAPI.downloadRelease: $error");
|
print("ERROR: FilcAPI.downloadRelease: $error");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Future.value(null);
|
return Future.value(null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> sendReport(ErrorReport report) async {
|
static Future<void> sendReport(ErrorReport report) async {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// ignore_for_file: avoid_print
|
// ignore_for_file: avoid_print, use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:filcnaplo/utils/jwt.dart';
|
import 'package:filcnaplo/utils/jwt.dart';
|
||||||
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
||||||
@@ -23,9 +23,9 @@ import 'package:filcnaplo/api/nonce.dart';
|
|||||||
|
|
||||||
enum LoginState { missingFields, invalidGrant, failed, normal, inProgress, success }
|
enum LoginState { missingFields, invalidGrant, failed, normal, inProgress, success }
|
||||||
|
|
||||||
Nonce getNonce(BuildContext context, String nonce, String username, String instituteCode) {
|
Nonce getNonce(String nonce, String username, String instituteCode) {
|
||||||
Nonce nonceEncoder = Nonce(key: [53, 75, 109, 112, 109, 103, 100, 53, 102, 74], nonce: nonce);
|
Nonce nonceEncoder = Nonce(key: [98, 97, 83, 115, 120, 79, 119, 108, 85, 49, 106, 77], nonce: nonce);
|
||||||
nonceEncoder.encode(username.toLowerCase() + instituteCode.toLowerCase() + nonce);
|
nonceEncoder.encode(instituteCode.toUpperCase() + nonce + username.toUpperCase());
|
||||||
|
|
||||||
return nonceEncoder;
|
return nonceEncoder;
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ Future loginApi({
|
|||||||
|
|
||||||
String nonceStr = await Provider.of<KretaClient>(context, listen: false).getAPI(KretaAPI.nonce, json: false);
|
String nonceStr = await Provider.of<KretaClient>(context, listen: false).getAPI(KretaAPI.nonce, json: false);
|
||||||
|
|
||||||
Nonce nonce = getNonce(context, nonceStr, username, instituteCode);
|
Nonce nonce = getNonce(nonceStr, username, instituteCode);
|
||||||
headers.addAll(nonce.header());
|
headers.addAll(nonce.header());
|
||||||
|
|
||||||
Map? res = await Provider.of<KretaClient>(context, listen: false).postAPI(KretaAPI.login,
|
Map? res = await Provider.of<KretaClient>(context, listen: false).postAPI(KretaAPI.login,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Nonce {
|
|||||||
return {
|
return {
|
||||||
"X-Authorizationpolicy-Nonce": nonce,
|
"X-Authorizationpolicy-Nonce": nonce,
|
||||||
"X-Authorizationpolicy-Key": encoded ?? "",
|
"X-Authorizationpolicy-Key": encoded ?? "",
|
||||||
"X-Authorizationpolicy-Version": "v1",
|
"X-Authorizationpolicy-Version": "v2",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:io';
|
|||||||
import 'package:filcnaplo/database/query.dart';
|
import 'package:filcnaplo/database/query.dart';
|
||||||
import 'package:filcnaplo/database/store.dart';
|
import 'package:filcnaplo/database/store.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||||
|
|
||||||
class DatabaseProvider {
|
class DatabaseProvider {
|
||||||
|
|||||||
199
filcnaplo/lib/api/providers/live_card_provider.dart
Normal file
199
filcnaplo/lib/api/providers/live_card_provider.dart
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:filcnaplo/helpers/subject.dart';
|
||||||
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/lesson.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/week.dart';
|
||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:live_activities/live_activities.dart';
|
||||||
|
|
||||||
|
enum LiveCardState { empty, duringLesson, duringBreak, morning, afternoon, night }
|
||||||
|
|
||||||
|
class LiveCardProvider extends ChangeNotifier {
|
||||||
|
Lesson? currentLesson;
|
||||||
|
Lesson? nextLesson;
|
||||||
|
Lesson? prevLesson;
|
||||||
|
List<Lesson>? nextLessons;
|
||||||
|
|
||||||
|
LiveCardState currentState = LiveCardState.empty;
|
||||||
|
late Timer _timer;
|
||||||
|
late final TimetableProvider _timetable;
|
||||||
|
late final SettingsProvider _settings;
|
||||||
|
|
||||||
|
late Duration _delay;
|
||||||
|
|
||||||
|
final _liveActivitiesPlugin = LiveActivities();
|
||||||
|
String? _latestActivityId;
|
||||||
|
Map<String, String> _lastActivity = {};
|
||||||
|
|
||||||
|
LiveCardProvider({
|
||||||
|
required TimetableProvider timetable,
|
||||||
|
required SettingsProvider settings,
|
||||||
|
}) : _timetable = timetable,
|
||||||
|
_settings = settings {
|
||||||
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) => update());
|
||||||
|
timetable.restore().then((_) => update());
|
||||||
|
_delay = settings.bellDelayEnabled ? Duration(seconds: settings.bellDelay) : Duration.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_timer.cancel();
|
||||||
|
if (_latestActivityId != null && Platform.isIOS) _liveActivitiesPlugin.endActivity(_latestActivityId!);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
static DateTime _now() {
|
||||||
|
return DateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFloorDifference() {
|
||||||
|
final prevFloor = prevLesson!.getFloor();
|
||||||
|
final nextFloor = nextLesson!.getFloor();
|
||||||
|
if (prevFloor == null || nextFloor == null || prevFloor == nextFloor) {
|
||||||
|
return "to room";
|
||||||
|
}
|
||||||
|
if (nextFloor == 0) {
|
||||||
|
return "ground floor";
|
||||||
|
}
|
||||||
|
if (nextFloor > prevFloor) {
|
||||||
|
return "up floor";
|
||||||
|
} else {
|
||||||
|
return "down floor";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> toMap() {
|
||||||
|
switch (currentState) {
|
||||||
|
case LiveCardState.duringLesson:
|
||||||
|
return {
|
||||||
|
"icon": currentLesson != null ? SubjectIcon.resolveName(subject: currentLesson?.subject) : "book",
|
||||||
|
"index": currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
||||||
|
"title": currentLesson != null ? ShortSubject.resolve(subject: currentLesson?.subject).capital() : "",
|
||||||
|
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
|
"description": currentLesson?.description ?? "",
|
||||||
|
"startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
|
||||||
|
"endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
|
||||||
|
"nextSubject": nextLesson != null ? ShortSubject.resolve(subject: nextLesson?.subject).capital() : "",
|
||||||
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
|
};
|
||||||
|
case LiveCardState.duringBreak:
|
||||||
|
final iconFloorMap = {
|
||||||
|
"to room": "chevron.right.2",
|
||||||
|
"up floor": "arrow.up.right",
|
||||||
|
"down floor": "arrow.down.left",
|
||||||
|
"ground floor": "arrow.down.left",
|
||||||
|
};
|
||||||
|
|
||||||
|
final diff = getFloorDifference();
|
||||||
|
|
||||||
|
return {
|
||||||
|
"icon": iconFloorMap[diff] ?? "cup.and.saucer",
|
||||||
|
"title": "Szünet",
|
||||||
|
"description": "Maradj ebben a teremben.",
|
||||||
|
"startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
|
||||||
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) - _delay.inMilliseconds).toString(),
|
||||||
|
"nextSubject": nextLesson != null ? ShortSubject.resolve(subject: nextLesson?.subject) : "",
|
||||||
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
|
"index": "",
|
||||||
|
"subtitle": "",
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
final cmap = toMap();
|
||||||
|
if (cmap != _lastActivity) {
|
||||||
|
_lastActivity = cmap;
|
||||||
|
|
||||||
|
if (_lastActivity != {}) {
|
||||||
|
if (_latestActivityId == null) {
|
||||||
|
_liveActivitiesPlugin.createActivity(_lastActivity).then((value) => _latestActivityId = value);
|
||||||
|
} else {
|
||||||
|
_liveActivitiesPlugin.updateActivity(_latestActivityId!, _lastActivity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_latestActivityId != null) _liveActivitiesPlugin.endActivity(_latestActivityId!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Lesson> today = _today(_timetable);
|
||||||
|
|
||||||
|
if (today.isEmpty) {
|
||||||
|
await _timetable.fetch(week: Week.current());
|
||||||
|
today = _today(_timetable);
|
||||||
|
}
|
||||||
|
|
||||||
|
_delay = _settings.bellDelayEnabled ? Duration(seconds: _settings.bellDelay) : Duration.zero;
|
||||||
|
|
||||||
|
final now = _now().add(_delay);
|
||||||
|
|
||||||
|
// Filter cancelled lessons #20
|
||||||
|
// Filter label lessons #128
|
||||||
|
today = today.where((lesson) => lesson.status?.name != "Elmaradt" && lesson.subject.id != '' && !lesson.isEmpty).toList();
|
||||||
|
|
||||||
|
if (today.isNotEmpty) {
|
||||||
|
// sort
|
||||||
|
today.sort((a, b) => a.start.compareTo(b.start));
|
||||||
|
|
||||||
|
final _lesson = today.firstWhere((l) => l.start.isBefore(now) && l.end.isAfter(now), orElse: () => Lesson.fromJson({}));
|
||||||
|
|
||||||
|
if (_lesson.start.year != 0) {
|
||||||
|
currentLesson = _lesson;
|
||||||
|
} else {
|
||||||
|
currentLesson = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final _next = today.firstWhere((l) => l.start.isAfter(now), orElse: () => Lesson.fromJson({}));
|
||||||
|
nextLessons = today.where((l) => l.start.isAfter(now)).toList();
|
||||||
|
|
||||||
|
if (_next.start.year != 0) {
|
||||||
|
nextLesson = _next;
|
||||||
|
} else {
|
||||||
|
nextLesson = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final _prev = today.lastWhere((l) => l.end.isBefore(now), orElse: () => Lesson.fromJson({}));
|
||||||
|
|
||||||
|
if (_prev.start.year != 0) {
|
||||||
|
prevLesson = _prev;
|
||||||
|
} else {
|
||||||
|
prevLesson = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLesson != null) {
|
||||||
|
currentState = LiveCardState.duringLesson;
|
||||||
|
} else if (nextLesson != null && prevLesson != null) {
|
||||||
|
currentState = LiveCardState.duringBreak;
|
||||||
|
} else if (now.hour >= 12 && now.hour < 20) {
|
||||||
|
currentState = LiveCardState.afternoon;
|
||||||
|
} else if (now.hour >= 20) {
|
||||||
|
currentState = LiveCardState.night;
|
||||||
|
} else if (now.hour >= 5 && now.hour <= 10) {
|
||||||
|
currentState = LiveCardState.morning;
|
||||||
|
} else {
|
||||||
|
currentState = LiveCardState.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get show => currentState != LiveCardState.empty;
|
||||||
|
|
||||||
|
Duration get delay => _delay;
|
||||||
|
|
||||||
|
bool _sameDate(DateTime a, DateTime b) => (a.year == b.year && a.month == b.month && a.day == b.day);
|
||||||
|
|
||||||
|
List<Lesson> _today(TimetableProvider p) => p.lessons.where((l) => _sameDate(l.date, _now())).toList();
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:filcnaplo/api/client.dart';
|
import 'package:filcnaplo/api/client.dart';
|
||||||
@@ -39,7 +41,7 @@ class NewsProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_state = state_;
|
_state = state_;
|
||||||
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
|
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> fetch() async {
|
Future<void> fetch() async {
|
||||||
@@ -51,7 +53,7 @@ class NewsProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
if (_fresh < 0) {
|
if (_fresh < 0) {
|
||||||
_state = news_.length;
|
_state = news_.length;
|
||||||
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
|
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fresh = max(_fresh, 0);
|
_fresh = max(_fresh, 0);
|
||||||
@@ -70,7 +72,7 @@ class NewsProvider extends ChangeNotifier {
|
|||||||
_fresh--;
|
_fresh--;
|
||||||
_state++;
|
_state++;
|
||||||
|
|
||||||
Provider.of<SettingsProvider>(_context, listen: false).update(_context, newsState: _state);
|
Provider.of<SettingsProvider>(_context, listen: false).update(newsState: _state);
|
||||||
|
|
||||||
if (_fresh > 0) {
|
if (_fresh > 0) {
|
||||||
show = true;
|
show = true;
|
||||||
|
|||||||
@@ -7,9 +7,12 @@ enum Status { network, maintenance, syncing }
|
|||||||
class StatusProvider extends ChangeNotifier {
|
class StatusProvider extends ChangeNotifier {
|
||||||
final List<Status> _stack = [];
|
final List<Status> _stack = [];
|
||||||
double _progress = 0.0;
|
double _progress = 0.0;
|
||||||
|
ConnectivityResult _networkType = ConnectivityResult.none;
|
||||||
|
ConnectivityResult get networkType => _networkType;
|
||||||
|
|
||||||
StatusProvider() {
|
StatusProvider() {
|
||||||
_handleNetworkChanges();
|
_handleNetworkChanges();
|
||||||
|
Connectivity().checkConnectivity().then((value) => _networkType = value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status? getStatus() => _stack.isNotEmpty ? _stack[0] : null;
|
Status? getStatus() => _stack.isNotEmpty ? _stack[0] : null;
|
||||||
@@ -18,6 +21,7 @@ class StatusProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
void _handleNetworkChanges() {
|
void _handleNetworkChanges() {
|
||||||
Connectivity().onConnectivityChanged.listen((event) {
|
Connectivity().onConnectivityChanged.listen((event) {
|
||||||
|
_networkType = event;
|
||||||
if (event == ConnectivityResult.none) {
|
if (event == ConnectivityResult.none) {
|
||||||
if (!_stack.contains(Status.network)) {
|
if (!_stack.contains(Status.network)) {
|
||||||
_stack.insert(0, Status.network);
|
_stack.insert(0, Status.network);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:filcnaplo/api/providers/database_provider.dart';
|
import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/api/providers/status_provider.dart';
|
import 'package:filcnaplo/api/providers/status_provider.dart';
|
||||||
import 'package:filcnaplo/api/providers/user_provider.dart';
|
import 'package:filcnaplo/api/providers/user_provider.dart';
|
||||||
@@ -33,24 +35,24 @@ Future<void> syncAll(BuildContext context) {
|
|||||||
List<Future<void>> tasks = [];
|
List<Future<void>> tasks = [];
|
||||||
int taski = 0;
|
int taski = 0;
|
||||||
|
|
||||||
Future<void> _syncStatus(Future<void> future) async {
|
Future<void> syncStatus(Future<void> future) async {
|
||||||
await future.onError((error, stackTrace) => null);
|
await future.onError((error, stackTrace) => null);
|
||||||
taski++;
|
taski++;
|
||||||
statusProvider.triggerSync(current: taski, max: tasks.length);
|
statusProvider.triggerSync(current: taski, max: tasks.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks = [
|
tasks = [
|
||||||
_syncStatus(Provider.of<GradeProvider>(context, listen: false).fetch()),
|
syncStatus(Provider.of<GradeProvider>(context, listen: false).fetch()),
|
||||||
_syncStatus(Provider.of<TimetableProvider>(context, listen: false).fetch(week: Week.current())),
|
syncStatus(Provider.of<TimetableProvider>(context, listen: false).fetch(week: Week.current())),
|
||||||
_syncStatus(Provider.of<ExamProvider>(context, listen: false).fetch()),
|
syncStatus(Provider.of<ExamProvider>(context, listen: false).fetch()),
|
||||||
_syncStatus(Provider.of<HomeworkProvider>(context, listen: false).fetch(from: DateTime.now().subtract(const Duration(days: 30)))),
|
syncStatus(Provider.of<HomeworkProvider>(context, listen: false).fetch(from: DateTime.now().subtract(const Duration(days: 30)))),
|
||||||
_syncStatus(Provider.of<MessageProvider>(context, listen: false).fetchAll()),
|
syncStatus(Provider.of<MessageProvider>(context, listen: false).fetchAll()),
|
||||||
_syncStatus(Provider.of<NoteProvider>(context, listen: false).fetch()),
|
syncStatus(Provider.of<NoteProvider>(context, listen: false).fetch()),
|
||||||
_syncStatus(Provider.of<EventProvider>(context, listen: false).fetch()),
|
syncStatus(Provider.of<EventProvider>(context, listen: false).fetch()),
|
||||||
_syncStatus(Provider.of<AbsenceProvider>(context, listen: false).fetch()),
|
syncStatus(Provider.of<AbsenceProvider>(context, listen: false).fetch()),
|
||||||
|
|
||||||
// Sync student
|
// Sync student
|
||||||
_syncStatus(() async {
|
syncStatus(() async {
|
||||||
if (user.user == null) return;
|
if (user.user == null) return;
|
||||||
Map? studentJson = await Provider.of<KretaClient>(context, listen: false).getAPI(KretaAPI.student(user.instituteCode!));
|
Map? studentJson = await Provider.of<KretaClient>(context, listen: false).getAPI(KretaAPI.student(user.instituteCode!));
|
||||||
if (studentJson == null) return;
|
if (studentJson == null) return;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ class UserProvider with ChangeNotifier {
|
|||||||
String? get password => user?.password;
|
String? get password => user?.password;
|
||||||
Role? get role => user?.role;
|
Role? get role => user?.role;
|
||||||
Student? get student => user?.student;
|
Student? get student => user?.student;
|
||||||
|
String? get nickname => user?.nickname;
|
||||||
|
String? get displayName => user?.displayName;
|
||||||
|
|
||||||
void setUser(String userId) {
|
void setUser(String userId) {
|
||||||
_selectedUserId = userId;
|
_selectedUserId = userId;
|
||||||
|
|||||||
@@ -3,18 +3,14 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:dynamic_color/dynamic_color.dart';
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
import 'package:filcnaplo/api/client.dart';
|
import 'package:filcnaplo/api/client.dart';
|
||||||
|
import 'package:filcnaplo/api/providers/live_card_provider.dart';
|
||||||
import 'package:filcnaplo/api/providers/news_provider.dart';
|
import 'package:filcnaplo/api/providers/news_provider.dart';
|
||||||
import 'package:filcnaplo/api/providers/database_provider.dart';
|
import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/api/providers/status_provider.dart';
|
import 'package:filcnaplo/api/providers/status_provider.dart';
|
||||||
import 'package:filcnaplo/models/config.dart';
|
import 'package:filcnaplo/models/config.dart';
|
||||||
import 'package:filcnaplo/theme.dart';
|
import 'package:filcnaplo/theme/observer.dart';
|
||||||
|
import 'package:filcnaplo/theme/theme.dart';
|
||||||
import 'package:filcnaplo_kreta_api/client/client.dart';
|
import 'package:filcnaplo_kreta_api/client/client.dart';
|
||||||
import 'package:filcnaplo_mobile_ui/common/system_chrome.dart';
|
|
||||||
import 'package:filcnaplo_mobile_ui/screens/login/login_route.dart';
|
|
||||||
import 'package:filcnaplo_mobile_ui/screens/login/login_screen.dart';
|
|
||||||
import 'package:filcnaplo_mobile_ui/screens/navigation/navigation_screen.dart';
|
|
||||||
import 'package:filcnaplo_mobile_ui/screens/settings/settings_route.dart';
|
|
||||||
import 'package:filcnaplo_mobile_ui/screens/settings/settings_screen.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
@@ -22,6 +18,19 @@ import 'package:i18n_extension/i18n_widget.dart';
|
|||||||
import 'package:material_color_utilities/palettes/core_palette.dart';
|
import 'package:material_color_utilities/palettes/core_palette.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
// Mobile UI
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/system_chrome.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_mobile_ui/screens/login/login_route.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_mobile_ui/screens/login/login_screen.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_mobile_ui/screens/navigation/navigation_screen.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_mobile_ui/screens/settings/settings_route.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_mobile_ui/screens/settings/settings_screen.dart' as mobile;
|
||||||
|
|
||||||
|
// Desktop UI
|
||||||
|
import 'package:filcnaplo_desktop_ui/screens/navigation/navigation_screen.dart' as desktop;
|
||||||
|
import 'package:filcnaplo_desktop_ui/screens/login/login_screen.dart' as desktop;
|
||||||
|
import 'package:filcnaplo_desktop_ui/screens/login/login_route.dart' as desktop;
|
||||||
|
|
||||||
// Providers
|
// Providers
|
||||||
import 'package:filcnaplo/models/settings.dart';
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
||||||
@@ -36,6 +45,7 @@ import 'package:filcnaplo/api/providers/user_provider.dart';
|
|||||||
import 'package:filcnaplo/api/providers/update_provider.dart';
|
import 'package:filcnaplo/api/providers/update_provider.dart';
|
||||||
import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
|
import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
|
||||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||||
|
import 'package:filcnaplo_premium/providers/premium_provider.dart';
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
final SettingsProvider settings;
|
final SettingsProvider settings;
|
||||||
@@ -48,35 +58,40 @@ class App extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
setSystemChrome(context);
|
mobile.setSystemChrome(context);
|
||||||
|
|
||||||
// Set high refresh mode #28
|
// Set high refresh mode #28
|
||||||
if (Platform.isAndroid) FlutterDisplayMode.setHighRefreshRate();
|
if (Platform.isAndroid) FlutterDisplayMode.setHighRefreshRate();
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
FilcAPI.getConfig(settings).then((Config? config) {
|
|
||||||
if (config != null) settings.update(context, database: database, config: config);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
CorePalette? corePalette;
|
CorePalette? corePalette;
|
||||||
|
|
||||||
return I18n(
|
final status = StatusProvider();
|
||||||
initialLocale: Locale(settings.language, settings.language.toUpperCase()),
|
final kreta = KretaClient(user: user, settings: settings, status: status);
|
||||||
child: MultiProvider(
|
final timetable = TimetableProvider(user: user, database: database, kreta: kreta);
|
||||||
|
final premium = PremiumProvider(settings: settings);
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
FilcAPI.getConfig(settings).then((Config? config) {
|
||||||
|
if (config != null) settings.update(config: config);
|
||||||
|
});
|
||||||
|
premium.activate();
|
||||||
|
});
|
||||||
|
|
||||||
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
ChangeNotifierProvider<PremiumProvider>(create: (_) => premium),
|
||||||
ChangeNotifierProvider<SettingsProvider>(create: (_) => settings),
|
ChangeNotifierProvider<SettingsProvider>(create: (_) => settings),
|
||||||
ChangeNotifierProvider<UserProvider>(create: (_) => user),
|
ChangeNotifierProvider<UserProvider>(create: (_) => user),
|
||||||
ChangeNotifierProvider<StatusProvider>(create: (context) => StatusProvider()),
|
ChangeNotifierProvider<StatusProvider>(create: (_) => status),
|
||||||
Provider<KretaClient>(create: (context) => KretaClient(context: context, userAgent: settings.config.userAgent)),
|
Provider<KretaClient>(create: (_) => kreta),
|
||||||
Provider<DatabaseProvider>(create: (context) => database),
|
Provider<DatabaseProvider>(create: (context) => database),
|
||||||
ChangeNotifierProvider<ThemeModeObserver>(create: (context) => ThemeModeObserver(initialTheme: settings.theme)),
|
ChangeNotifierProvider<ThemeModeObserver>(create: (context) => ThemeModeObserver(initialTheme: settings.theme)),
|
||||||
ChangeNotifierProvider<NewsProvider>(create: (context) => NewsProvider(context: context)),
|
ChangeNotifierProvider<NewsProvider>(create: (context) => NewsProvider(context: context)),
|
||||||
ChangeNotifierProvider<UpdateProvider>(create: (context) => UpdateProvider(context: context)),
|
ChangeNotifierProvider<UpdateProvider>(create: (context) => UpdateProvider(context: context)),
|
||||||
|
|
||||||
// User data providers
|
// User data providers
|
||||||
ChangeNotifierProvider<GradeProvider>(create: (context) => GradeProvider(context: context)),
|
ChangeNotifierProvider<GradeProvider>(create: (_) => GradeProvider(settings: settings, user: user, database: database, kreta: kreta)),
|
||||||
ChangeNotifierProvider<TimetableProvider>(create: (context) => TimetableProvider(context: context)),
|
ChangeNotifierProvider<TimetableProvider>(create: (_) => timetable),
|
||||||
ChangeNotifierProvider<ExamProvider>(create: (context) => ExamProvider(context: context)),
|
ChangeNotifierProvider<ExamProvider>(create: (context) => ExamProvider(context: context)),
|
||||||
ChangeNotifierProvider<HomeworkProvider>(create: (context) => HomeworkProvider(context: context)),
|
ChangeNotifierProvider<HomeworkProvider>(create: (context) => HomeworkProvider(context: context)),
|
||||||
ChangeNotifierProvider<MessageProvider>(create: (context) => MessageProvider(context: context)),
|
ChangeNotifierProvider<MessageProvider>(create: (context) => MessageProvider(context: context)),
|
||||||
@@ -84,7 +99,9 @@ class App extends StatelessWidget {
|
|||||||
ChangeNotifierProvider<EventProvider>(create: (context) => EventProvider(context: context)),
|
ChangeNotifierProvider<EventProvider>(create: (context) => EventProvider(context: context)),
|
||||||
ChangeNotifierProvider<AbsenceProvider>(create: (context) => AbsenceProvider(context: context)),
|
ChangeNotifierProvider<AbsenceProvider>(create: (context) => AbsenceProvider(context: context)),
|
||||||
|
|
||||||
ChangeNotifierProvider<GradeCalculatorProvider>(create: (context) => GradeCalculatorProvider(context)),
|
ChangeNotifierProvider<GradeCalculatorProvider>(
|
||||||
|
create: (_) => GradeCalculatorProvider(settings: settings, user: user, database: database, kreta: kreta)),
|
||||||
|
ChangeNotifierProvider<LiveCardProvider>(create: (context) => LiveCardProvider(timetable: timetable, settings: settings))
|
||||||
],
|
],
|
||||||
child: Consumer<ThemeModeObserver>(
|
child: Consumer<ThemeModeObserver>(
|
||||||
builder: (context, themeMode, child) {
|
builder: (context, themeMode, child) {
|
||||||
@@ -97,9 +114,12 @@ class App extends StatelessWidget {
|
|||||||
// Limit font size scaling to 1.0
|
// Limit font size scaling to 1.0
|
||||||
double textScaleFactor = min(MediaQuery.of(context).textScaleFactor, 1.0);
|
double textScaleFactor = min(MediaQuery.of(context).textScaleFactor, 1.0);
|
||||||
|
|
||||||
return MediaQuery(
|
return I18n(
|
||||||
|
initialLocale: Locale(settings.language, settings.language.toUpperCase()),
|
||||||
|
child: MediaQuery(
|
||||||
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor),
|
data: MediaQuery.of(context).copyWith(textScaleFactor: textScaleFactor),
|
||||||
child: child ?? Container(),
|
child: child ?? Container(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
title: "Filc Napló",
|
title: "Filc Napló",
|
||||||
@@ -136,26 +156,37 @@ class App extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Route? rootNavigator(RouteSettings route) {
|
Route? rootNavigator(RouteSettings route) {
|
||||||
// if platform == android || platform == ios
|
// if platform == android || platform == ios
|
||||||
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
switch (route.name) {
|
switch (route.name) {
|
||||||
case "login_back":
|
case "login_back":
|
||||||
return CupertinoPageRoute(builder: (context) => const LoginScreen(back: true));
|
return CupertinoPageRoute(builder: (context) => const mobile.LoginScreen(back: true));
|
||||||
case "login":
|
case "login":
|
||||||
return _rootRoute(const LoginScreen());
|
return _rootRoute(const mobile.LoginScreen());
|
||||||
case "navigation":
|
case "navigation":
|
||||||
return _rootRoute(const NavigationScreen());
|
return _rootRoute(const mobile.NavigationScreen());
|
||||||
case "login_to_navigation":
|
case "login_to_navigation":
|
||||||
return loginRoute(const NavigationScreen());
|
return mobile.loginRoute(const mobile.NavigationScreen());
|
||||||
case "settings":
|
case "settings":
|
||||||
return settingsRoute(const SettingsScreen());
|
return mobile.settingsRoute(const mobile.SettingsScreen());
|
||||||
|
}
|
||||||
|
} else if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) {
|
||||||
|
switch (route.name) {
|
||||||
|
case "login_back":
|
||||||
|
return CupertinoPageRoute(builder: (context) => const desktop.LoginScreen(back: true));
|
||||||
|
case "login":
|
||||||
|
return _rootRoute(const desktop.LoginScreen());
|
||||||
|
case "navigation":
|
||||||
|
return _rootRoute(const desktop.NavigationScreen());
|
||||||
|
case "login_to_navigation":
|
||||||
|
return desktop.loginRoute(const desktop.NavigationScreen());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
// else if platform == windows || ...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Route _rootRoute(Widget widget) {
|
Route _rootRoute(Widget widget) {
|
||||||
|
|||||||
@@ -2,30 +2,36 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/database/struct.dart';
|
import 'package:filcnaplo/database/struct.dart';
|
||||||
import 'package:filcnaplo/models/settings.dart';
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||||
|
|
||||||
const settingsDB = DatabaseStruct("settings", {
|
const settingsDB = DatabaseStruct("settings", {
|
||||||
"language": String, "start_page": int, "rounding": int, "theme": int, "accent_color": int, "news": int, "news_state": int, "developer_mode": int,
|
"language": String, "start_page": int, "rounding": int, "theme": int, "accent_color": int, "news": int, "news_state": int, "developer_mode": int,
|
||||||
"update_channel": int, "config": String, // general
|
"update_channel": int, "config": String, "custom_accent_color": int, "custom_background_color": int, "custom_highlight_color": int, // general
|
||||||
"grade_color1": int, "grade_color2": int, "grade_color3": int, "grade_color4": int, "grade_color5": int, // grade colors
|
"grade_color1": int, "grade_color2": int, "grade_color3": int, "grade_color4": int, "grade_color5": int, // grade colors
|
||||||
"vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int,
|
"vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int,
|
||||||
"notifications": int, "notifications_bitfield": int, "notification_poll_interval": int, // notifications
|
"notifications": int, "notifications_bitfield": int, "notification_poll_interval": int, // notifications
|
||||||
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int, "bell_delay": int, "bell_delay_enabled": int,
|
"x_filc_id": String, "graph_class_avg": int, "presentation_mode": int, "bell_delay": int, "bell_delay_enabled": int,
|
||||||
|
"grade_opening_fun": int, "icon_pack": String, "premium_scopes": String, "premium_token": String,
|
||||||
|
});
|
||||||
|
const usersDB = DatabaseStruct("users", {
|
||||||
|
"id": String, "name": String, "username": String, "password": String, "institute_code": String, "student": String, "role": int,
|
||||||
|
"nickname": String // premium only
|
||||||
});
|
});
|
||||||
const usersDB = DatabaseStruct(
|
|
||||||
"users", {"id": String, "name": String, "username": String, "password": String, "institute_code": String, "student": String, "role": int});
|
|
||||||
const userDataDB = DatabaseStruct("user_data", {
|
const userDataDB = DatabaseStruct("user_data", {
|
||||||
"id": String, "grades": String, "timetable": String, "exams": String, "homework": String, "messages": String, "notes": String,
|
"id": String, "grades": String, "timetable": String, "exams": String, "homework": String, "messages": String, "notes": String,
|
||||||
"events": String, "absences": String, "group_averages": String,
|
"events": String, "absences": String, "group_averages": String,
|
||||||
// "subject_lesson_count": String, // non kreta data
|
// "subject_lesson_count": String, // non kreta data
|
||||||
|
"last_seen_grade": int,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> createTable(Database db, DatabaseStruct struct) => db.execute("CREATE TABLE IF NOT EXISTS ${struct.table} ($struct)");
|
Future<void> createTable(Database db, DatabaseStruct struct) => db.execute("CREATE TABLE IF NOT EXISTS ${struct.table} ($struct)");
|
||||||
|
|
||||||
Future<Database> initDB() async {
|
Future<Database> initDB(DatabaseProvider database) async {
|
||||||
Database db;
|
Database db;
|
||||||
|
|
||||||
if (Platform.isLinux || Platform.isWindows) {
|
if (Platform.isLinux || Platform.isWindows) {
|
||||||
@@ -41,7 +47,7 @@ Future<Database> initDB() async {
|
|||||||
|
|
||||||
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first == 0) {
|
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first == 0) {
|
||||||
// Set default values for table Settings
|
// Set default values for table Settings
|
||||||
await db.insert("settings", SettingsProvider.defaultSettings().toMap());
|
await db.insert("settings", SettingsProvider.defaultSettings(database: database).toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate Databases
|
// Migrate Databases
|
||||||
@@ -49,7 +55,7 @@ Future<Database> initDB() async {
|
|||||||
await migrateDB(
|
await migrateDB(
|
||||||
db,
|
db,
|
||||||
struct: settingsDB,
|
struct: settingsDB,
|
||||||
defaultValues: SettingsProvider.defaultSettings().toMap(),
|
defaultValues: SettingsProvider.defaultSettings(database: database).toMap(),
|
||||||
);
|
);
|
||||||
await migrateDB(
|
await migrateDB(
|
||||||
db,
|
db,
|
||||||
@@ -60,6 +66,7 @@ Future<Database> initDB() async {
|
|||||||
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]", "messages": "[]", "notes": "[]", "events": "[]", "absences": "[]",
|
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]", "messages": "[]", "notes": "[]", "events": "[]", "absences": "[]",
|
||||||
"group_averages": "[]",
|
"group_averages": "[]",
|
||||||
// "subject_lesson_count": "{}", // non kreta data
|
// "subject_lesson_count": "{}", // non kreta data
|
||||||
|
"last_seen_grade": 0,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
print("ERROR: migrateDB: $error");
|
print("ERROR: migrateDB: $error");
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/models/subject_lesson_count.dart';
|
import 'package:filcnaplo/models/subject_lesson_count.dart';
|
||||||
import 'package:filcnaplo/models/user.dart';
|
import 'package:filcnaplo/models/user.dart';
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:sqflite_common/sqlite_api.dart';
|
import 'package:sqflite_common/sqlite_api.dart';
|
||||||
|
|
||||||
// Models
|
// Models
|
||||||
@@ -21,9 +23,9 @@ class DatabaseQuery {
|
|||||||
|
|
||||||
final Database db;
|
final Database db;
|
||||||
|
|
||||||
Future<SettingsProvider> getSettings() async {
|
Future<SettingsProvider> getSettings(DatabaseProvider database) async {
|
||||||
Map settingsMap = (await db.query("settings")).elementAt(0);
|
Map settingsMap = (await db.query("settings")).elementAt(0);
|
||||||
SettingsProvider settings = SettingsProvider.fromMap(settingsMap);
|
SettingsProvider settings = SettingsProvider.fromMap(settingsMap, database: database);
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,4 +133,13 @@ class UserDatabaseQuery {
|
|||||||
SubjectLessonCount lessonCount = SubjectLessonCount.fromMap(jsonDecode(lessonCountJson) as Map);
|
SubjectLessonCount lessonCount = SubjectLessonCount.fromMap(jsonDecode(lessonCountJson) as Map);
|
||||||
return lessonCount;
|
return lessonCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<DateTime> lastSeenGrade({required String userId}) async {
|
||||||
|
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||||
|
if (userData.isEmpty) return DateTime(0);
|
||||||
|
int? lastSeenDate = userData.elementAt(0)["last_seen_grade"] as int?;
|
||||||
|
if (lastSeenDate == null) return DateTime(0);
|
||||||
|
DateTime lastSeen = DateTime.fromMillisecondsSinceEpoch(lastSeenDate);
|
||||||
|
return lastSeen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:filcnaplo/models/subject_lesson_count.dart';
|
import 'package:filcnaplo/models/subject_lesson_count.dart';
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:sqflite_common/sqlite_api.dart';
|
import 'package:sqflite_common/sqlite_api.dart';
|
||||||
|
|
||||||
// Models
|
// Models
|
||||||
@@ -90,9 +91,13 @@ class UserDatabaseStore {
|
|||||||
await db.update("user_data", {"group_averages": groupAveragesJson}, where: "id = ?", whereArgs: [userId]);
|
await db.update("user_data", {"group_averages": groupAveragesJson}, where: "id = ?", whereArgs: [userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<void> storeSubjectLessonCount(SubjectLessonCount lessonCount, {required String userId}) async {
|
Future<void> storeSubjectLessonCount(SubjectLessonCount lessonCount, {required String userId}) async {
|
||||||
String lessonCountJson = jsonEncode(lessonCount.toMap());
|
String lessonCountJson = jsonEncode(lessonCount.toMap());
|
||||||
await db.update("user_data", {"subject_lesson_count": lessonCountJson}, where: "id = ?", whereArgs: [userId]);
|
await db.update("user_data", {"subject_lesson_count": lessonCountJson}, where: "id = ?", whereArgs: [userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> storeLastSeenGrade(DateTime date, {required String userId}) async {
|
||||||
|
int lastSeenDate = date.millisecondsSinceEpoch;
|
||||||
|
await db.update("user_data", {"last_seen_grade": lastSeenDate}, where: "id = ?", whereArgs: [userId]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
|
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||||
|
|
||||||
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||||
|
|
||||||
class AverageHelper {
|
class AverageHelper {
|
||||||
static double averageEvals(List<Grade> grades, {bool finalAvg = false}) {
|
static double averageEvals(List<Grade> grades, {bool finalAvg = false}) {
|
||||||
double average = 0.0;
|
|
||||||
|
|
||||||
List<String> ignoreInFinal = ["5,SzorgalomErtek", "4,MagatartasErtek"];
|
List<String> ignoreInFinal = ["5,SzorgalomErtek", "4,MagatartasErtek"];
|
||||||
|
if (finalAvg) grades.removeWhere((e) => (e.value.value == 0) || (ignoreInFinal.contains(e.gradeType?.id)));
|
||||||
|
|
||||||
if (finalAvg) {
|
double average =
|
||||||
grades.removeWhere((e) =>
|
grades.map((e) => e.value.value * e.value.weight / 100.0).fold(0.0, (double a, double b) => a + b) / weightSum(grades, finalAvg: finalAvg);
|
||||||
(e.value.value == 0) ||
|
|
||||||
(ignoreInFinal.contains(e.gradeType?.id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var e in grades) {
|
|
||||||
average += e.value.value * ((finalAvg ? 100 : e.value.weight) / 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
average = average /
|
|
||||||
grades
|
|
||||||
.map((e) => (finalAvg ? 100 : e.value.weight) / 100)
|
|
||||||
.fold(0.0, (a, b) => a + b);
|
|
||||||
|
|
||||||
return average.isNaN ? 0.0 : average;
|
return average.isNaN ? 0.0 : average;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double weightSum(List<Grade> grades, {bool finalAvg = false}) =>
|
||||||
|
grades.map((e) => finalAvg ? 1 : e.value.weight / 100).fold(0, (a, b) => a + b);
|
||||||
|
|
||||||
|
static int howManyNeeded(int grade, List<Grade> base, double goal, {bool filcgrade = true, double avg = 0, double wsum = 0}) {
|
||||||
|
double _avg = filcgrade ? averageEvals(base) : avg;
|
||||||
|
double _wsum = filcgrade ? weightSum(base) : wsum;
|
||||||
|
if (_avg >= goal) return 0;
|
||||||
|
return (_wsum * (_avg - goal) / (goal - grade)).ceil();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import 'package:share_plus/share_plus.dart';
|
|||||||
|
|
||||||
class ShareHelper {
|
class ShareHelper {
|
||||||
static Future<void> shareText(String text, {String? subject}) => Share.share(text, subject: subject);
|
static Future<void> shareText(String text, {String? subject}) => Share.share(text, subject: subject);
|
||||||
|
// ignore: deprecated_member_use
|
||||||
static Future<void> shareFile(String path, {String? text, String? subject}) => Share.shareFiles([path], text: text, subject: subject);
|
static Future<void> shareFile(String path, {String? text, String? subject}) => Share.shareFiles([path], text: text, subject: subject);
|
||||||
|
|
||||||
static Future<void> shareAttachment(Attachment attachment, {required BuildContext context}) async {
|
static Future<void> shareAttachment(Attachment attachment, {required BuildContext context}) async {
|
||||||
|
|||||||
144
filcnaplo/lib/helpers/subject.dart
Normal file
144
filcnaplo/lib/helpers/subject.dart
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import 'package:filcnaplo/icons/filc_icons.dart';
|
||||||
|
import 'package:filcnaplo/models/icon_pack.dart';
|
||||||
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/subject.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
typedef SubjectIconVariants = Map<IconPack, IconData>;
|
||||||
|
|
||||||
|
class SubjectIconData {
|
||||||
|
final SubjectIconVariants data;
|
||||||
|
final String name; // for iOS live activities compatibilty
|
||||||
|
|
||||||
|
SubjectIconData({
|
||||||
|
this.data = const {
|
||||||
|
IconPack.material: Icons.widgets_outlined,
|
||||||
|
IconPack.cupertino: CupertinoIcons.rectangle_grid_2x2,
|
||||||
|
},
|
||||||
|
this.name = "square.grid.2x2",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SubjectIconVariants createIcon({required IconData material, required IconData cupertino}) {
|
||||||
|
return {
|
||||||
|
IconPack.material: material,
|
||||||
|
IconPack.cupertino: cupertino,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class SubjectIcon {
|
||||||
|
static String resolveName({Subject? subject, String? subjectName}) => _resolve(subject: subject, subjectName: subjectName).name;
|
||||||
|
static IconData resolveVariant({Subject? subject, String? subjectName, required BuildContext context}) =>
|
||||||
|
_resolve(subject: subject, subjectName: subjectName).data[Provider.of<SettingsProvider>(context, listen: false).iconPack]!;
|
||||||
|
|
||||||
|
static SubjectIconData _resolve({Subject? subject, String? subjectName}) {
|
||||||
|
assert(!(subject == null && subjectName == null));
|
||||||
|
|
||||||
|
String name = (subject?.name ?? subjectName ?? "").toLowerCase().specialChars().trim();
|
||||||
|
String category = subject?.category.description.toLowerCase().specialChars() ?? "";
|
||||||
|
|
||||||
|
// todo: check for categories
|
||||||
|
if (RegExp("mate(k|matika)").hasMatch(name) || category == "matematika") {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.function, material: Icons.calculate_outlined), name: "function");
|
||||||
|
} else if (RegExp("magyar nyelv|nyelvtan").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.textformat_alt, material: Icons.spellcheck_outlined), name: "textformat.alt");
|
||||||
|
} else if (RegExp("irodalom").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.book, material: Icons.menu_book_outlined), name: "book");
|
||||||
|
} else if (RegExp("tor(i|tenelem)").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.compass, material: Icons.hourglass_empty_outlined), name: "safari");
|
||||||
|
} else if (RegExp("foldrajz").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.map, material: Icons.public_outlined), name: "map");
|
||||||
|
} else if (RegExp("rajz|muvtori|muveszet|vizualis").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.paintbrush, material: Icons.palette_outlined), name: "paintbrush");
|
||||||
|
} else if (RegExp("fizika").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.lightbulb, material: Icons.emoji_objects_outlined), name: "lightbulb");
|
||||||
|
} else if (RegExp("^enek|zene|szolfezs|zongora|korus").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.music_note, material: Icons.music_note_outlined), name: "music.note");
|
||||||
|
} else if (RegExp("^tes(i|tneveles)|sport").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.sportscourt, material: Icons.sports_soccer_outlined), name: "sportscourt");
|
||||||
|
} else if (RegExp("kemia").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.lab_flask, material: Icons.science_outlined), name: "testtube.2");
|
||||||
|
} else if (RegExp("biologia").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.paw, material: Icons.pets_outlined), name: "pawprint");
|
||||||
|
} else if (RegExp("kornyezet|termeszet ?(tudomany|ismeret)|hon( es nep)?ismeret").hasMatch(name)) {
|
||||||
|
return SubjectIconData(
|
||||||
|
data: createIcon(cupertino: CupertinoIcons.arrow_3_trianglepath, material: Icons.eco_outlined), name: "arrow.3.trianglepath");
|
||||||
|
} else if (RegExp("(hit|erkolcs)tan|vallas|etika").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.heart, material: Icons.favorite_border_outlined), name: "heart");
|
||||||
|
} else if (RegExp("penzugy").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.money_dollar, material: Icons.savings_outlined), name: "dollarsign");
|
||||||
|
} else if (RegExp("informatika|szoftver|iroda|digitalis").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.device_laptop, material: Icons.computer_outlined), name: "laptopcomputer");
|
||||||
|
} else if (RegExp("prog").hasMatch(name)) {
|
||||||
|
return SubjectIconData(
|
||||||
|
data: createIcon(cupertino: CupertinoIcons.chevron_left_slash_chevron_right, material: Icons.code_outlined),
|
||||||
|
name: "chevron.left.forwardslash.chevron.right");
|
||||||
|
} else if (RegExp("halozat").hasMatch(name)) {
|
||||||
|
return SubjectIconData(
|
||||||
|
data: createIcon(cupertino: CupertinoIcons.antenna_radiowaves_left_right, material: Icons.wifi_tethering_outlined),
|
||||||
|
name: "antenna.radiowaves.left.and.right");
|
||||||
|
} else if (RegExp("szinhaz").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.hifispeaker, material: Icons.theater_comedy_outlined), name: "hifispeaker");
|
||||||
|
} else if (RegExp("film|media").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.film, material: Icons.theaters_outlined), name: "film");
|
||||||
|
} else if (RegExp("elektro(tech)?nika").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.bolt, material: Icons.electrical_services_outlined), name: "bolt");
|
||||||
|
} else if (RegExp("gepesz|mernok|ipar").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.wrench, material: Icons.precision_manufacturing_outlined), name: "wrench");
|
||||||
|
} else if (RegExp("technika").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.hammer, material: Icons.build_outlined), name: "hammer");
|
||||||
|
} else if (RegExp("tanc").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.music_mic, material: Icons.speaker_outlined), name: "music.mic");
|
||||||
|
} else if (RegExp("filozofia").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.bubble_left, material: Icons.psychology_outlined), name: "bubble.left");
|
||||||
|
} else if (RegExp("osztaly(fonoki|kozosseg)").hasMatch(name) || name == "ofo") {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.group, material: Icons.groups_outlined), name: "person.3");
|
||||||
|
} else if (RegExp("gazdasag").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.chart_pie, material: Icons.account_balance_outlined), name: "chart.pie");
|
||||||
|
} else if (RegExp("szorgalom").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.checkmark_seal, material: Icons.verified_outlined), name: "checkmark.seal");
|
||||||
|
} else if (RegExp("magatartas").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.smiley, material: Icons.emoji_people_outlined), name: "face.smiling");
|
||||||
|
} else if (RegExp("angol|nemet|francia|olasz|orosz|spanyol|latin|kinai|nyelv").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(cupertino: CupertinoIcons.globe, material: Icons.translate_outlined), name: "globe");
|
||||||
|
} else if (RegExp("linux").hasMatch(name)) {
|
||||||
|
return SubjectIconData(data: createIcon(material: FilcIcons.linux, cupertino: FilcIcons.linux));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SubjectIconData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShortSubject {
|
||||||
|
static String resolve({Subject? subject, String? subjectName}) {
|
||||||
|
assert(!(subject == null && subjectName == null));
|
||||||
|
|
||||||
|
String name = (subject?.name ?? subjectName ?? "").toLowerCase().specialChars().trim();
|
||||||
|
// String category = subject?.category.description.toLowerCase().specialChars() ?? "";
|
||||||
|
|
||||||
|
if (RegExp("magyar irodalom").hasMatch(name)) {
|
||||||
|
return "Irodalom";
|
||||||
|
} else if (RegExp("magyar nyelv").hasMatch(name)) {
|
||||||
|
return "Nyelvtan";
|
||||||
|
} else if (RegExp("matematika").hasMatch(name)) {
|
||||||
|
return "Matek";
|
||||||
|
} else if (RegExp("digitalis kultura").hasMatch(name)) {
|
||||||
|
return "Dig. kult.";
|
||||||
|
} else if (RegExp("testneveles").hasMatch(name)) {
|
||||||
|
return "Tesi";
|
||||||
|
} else if (RegExp("tortenelem").hasMatch(name)) {
|
||||||
|
return "Töri";
|
||||||
|
} else if (RegExp("(angol|nemet|francia|olasz|orosz|spanyol|latin|kinai) nyelv").hasMatch(name)) {
|
||||||
|
return (subject?.name ?? subjectName ?? "?").replaceAll(" nyelv", "");
|
||||||
|
} else if (RegExp("informatika").hasMatch(name)) {
|
||||||
|
return "Infó";
|
||||||
|
} else if (RegExp("osztalyfonoki").hasMatch(name)) {
|
||||||
|
return "Ofő";
|
||||||
|
}
|
||||||
|
|
||||||
|
return subject?.name.capital() ?? subjectName?.capital() ?? "?";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import 'package:filcnaplo/icons/filc_icons.dart';
|
|
||||||
import 'package:filcnaplo/utils/format.dart';
|
|
||||||
import 'package:filcnaplo_kreta_api/models/subject.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class SubjectIcon {
|
|
||||||
static IconData? lookup({Subject? subject, String? subjectName}) {
|
|
||||||
assert(!(subject == null && subjectName == null));
|
|
||||||
|
|
||||||
String name = (subject?.name ?? subjectName ?? "").toLowerCase().specialChars().trim();
|
|
||||||
String category = subject?.category.description.toLowerCase().specialChars() ?? "";
|
|
||||||
|
|
||||||
// todo: check for categories
|
|
||||||
if (RegExp("mate(k|matika)").hasMatch(name) || category == "matematika") return Icons.calculate_outlined;
|
|
||||||
if (RegExp("magyar nyelv|nyelvtan").hasMatch(name)) return Icons.spellcheck_outlined;
|
|
||||||
if (RegExp("irodalom").hasMatch(name)) return Icons.menu_book_outlined;
|
|
||||||
if (RegExp("tor(i|tenelem)").hasMatch(name)) return Icons.hourglass_empty_outlined;
|
|
||||||
if (RegExp("foldrajz").hasMatch(name)) return Icons.public_outlined;
|
|
||||||
if (RegExp("rajz|muvtori|muveszet|vizualis").hasMatch(name)) return Icons.palette_outlined;
|
|
||||||
if (RegExp("fizika").hasMatch(name)) return Icons.emoji_objects_outlined;
|
|
||||||
if (RegExp("^enek|zene|szolfezs|zongora|korus").hasMatch(name)) return Icons.music_note_outlined;
|
|
||||||
if (RegExp("^tes(i|tneveles)|sport").hasMatch(name)) return Icons.sports_soccer_outlined;
|
|
||||||
if (RegExp("kemia").hasMatch(name)) return Icons.science_outlined;
|
|
||||||
if (RegExp("biologia").hasMatch(name)) return Icons.pets_outlined;
|
|
||||||
if (RegExp("kornyezet|termeszet(tudomany|ismeret)|hon( es nep)?ismeret").hasMatch(name)) return Icons.eco_outlined;
|
|
||||||
if (RegExp("(hit|erkolcs)tan|vallas|etika").hasMatch(name)) return Icons.favorite_border_outlined;
|
|
||||||
if (RegExp("penzugy").hasMatch(name)) return Icons.savings_outlined;
|
|
||||||
if (RegExp("informatika|szoftver|iroda|digitalis").hasMatch(name)) return Icons.computer_outlined;
|
|
||||||
if (RegExp("prog").hasMatch(name)) return Icons.code_outlined;
|
|
||||||
if (RegExp("halozat").hasMatch(name)) return Icons.wifi_tethering_outlined;
|
|
||||||
if (RegExp("szinhaz").hasMatch(name)) return Icons.theater_comedy_outlined;
|
|
||||||
if (RegExp("film|media").hasMatch(name)) return Icons.theaters_outlined;
|
|
||||||
if (RegExp("elektro(tech)?nika").hasMatch(name)) return Icons.electrical_services_outlined;
|
|
||||||
if (RegExp("gepesz|mernok|ipar").hasMatch(name)) return Icons.precision_manufacturing_outlined;
|
|
||||||
if (RegExp("technika").hasMatch(name)) return Icons.build_outlined;
|
|
||||||
if (RegExp("tanc").hasMatch(name)) return Icons.speaker_outlined;
|
|
||||||
if (RegExp("filozofia").hasMatch(name)) return Icons.psychology_outlined;
|
|
||||||
if (RegExp("osztaly(fonoki|kozosseg)").hasMatch(name) || name == "ofo") return Icons.groups_outlined;
|
|
||||||
if (RegExp("gazdasag").hasMatch(name)) return Icons.account_balance_outlined;
|
|
||||||
if (RegExp("szorgalom").hasMatch(name)) return Icons.verified_outlined;
|
|
||||||
if (RegExp("magatartas").hasMatch(name)) return Icons.emoji_people_outlined;
|
|
||||||
if (RegExp("angol|nemet|francia|olasz|orosz|spanyol|latin|kinai|nyelv").hasMatch(name)) return Icons.translate_outlined;
|
|
||||||
if (RegExp("linux").hasMatch(name)) return FilcIcons.linux;
|
|
||||||
return Icons.widgets_outlined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,7 @@ extension UpdateHelper on Release {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List> download({UpdateCallback? updateCallback}) async {
|
Future<Uint8List> download({UpdateCallback? updateCallback}) async {
|
||||||
var response = await FilcAPI.downloadRelease(this);
|
var response = await FilcAPI.downloadRelease(downloads.first);
|
||||||
|
|
||||||
List<List<int>> chunks = [];
|
List<List<int>> chunks = [];
|
||||||
int downloaded = 0;
|
int downloaded = 0;
|
||||||
|
|||||||
@@ -16,4 +16,7 @@ class FilcIcons {
|
|||||||
|
|
||||||
/// downstairs
|
/// downstairs
|
||||||
static const IconData downstairs = IconData(0x03, fontFamily: iconFontFamily);
|
static const IconData downstairs = IconData(0x03, fontFamily: iconFontFamily);
|
||||||
|
|
||||||
|
/// premium
|
||||||
|
static const IconData premium = IconData(0x04, fontFamily: iconFontFamily);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ class Startup {
|
|||||||
late DatabaseProvider database;
|
late DatabaseProvider database;
|
||||||
|
|
||||||
Future<void> start() async {
|
Future<void> start() async {
|
||||||
var db = await initDB();
|
|
||||||
await db.close();
|
|
||||||
database = DatabaseProvider();
|
database = DatabaseProvider();
|
||||||
|
var db = await initDB(database);
|
||||||
|
await db.close();
|
||||||
await database.init();
|
await database.init();
|
||||||
settings = await database.query.getSettings();
|
settings = await database.query.getSettings(database);
|
||||||
user = await database.query.getUsers();
|
user = await database.query.getUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
filcnaplo/lib/models/icon_pack.dart
Normal file
1
filcnaplo/lib/models/icon_pack.dart
Normal file
@@ -0,0 +1 @@
|
|||||||
|
enum IconPack { material, cupertino }
|
||||||
@@ -1,9 +1,26 @@
|
|||||||
|
class ReleaseDownload {
|
||||||
|
String url;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
ReleaseDownload({
|
||||||
|
required this.url,
|
||||||
|
required this.size,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ReleaseDownload.fromJson(Map json) {
|
||||||
|
return ReleaseDownload(
|
||||||
|
url: json["browser_download_url"] ?? "",
|
||||||
|
size: json["size"] ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Release {
|
class Release {
|
||||||
String tag;
|
String tag;
|
||||||
Version version;
|
Version version;
|
||||||
String author;
|
String author;
|
||||||
String body;
|
String body;
|
||||||
List<String> downloads;
|
List<ReleaseDownload> downloads;
|
||||||
bool prerelease;
|
bool prerelease;
|
||||||
|
|
||||||
Release({
|
Release({
|
||||||
@@ -20,7 +37,7 @@ class Release {
|
|||||||
tag: json["tag_name"] ?? Version.zero.toString(),
|
tag: json["tag_name"] ?? Version.zero.toString(),
|
||||||
author: json["author"] != null ? json["author"]["login"] ?? "" : "",
|
author: json["author"] != null ? json["author"]["login"] ?? "" : "",
|
||||||
body: json["body"] ?? "",
|
body: json["body"] ?? "",
|
||||||
downloads: json["assets"] != null ? json["assets"].map((a) => a["browser_download_url"] ?? "").toList().cast<String>() : [],
|
downloads: json["assets"] != null ? json["assets"].map((a) => ReleaseDownload.fromJson(a)).toList().cast<ReleaseDownload>() : [],
|
||||||
prerelease: json["prerelease"] ?? false,
|
prerelease: json["prerelease"] ?? false,
|
||||||
version: Version.fromString(json["tag_name"] ?? ""),
|
version: Version.fromString(json["tag_name"] ?? ""),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import 'dart:developer';
|
|||||||
|
|
||||||
import 'package:filcnaplo/api/providers/database_provider.dart';
|
import 'package:filcnaplo/api/providers/database_provider.dart';
|
||||||
import 'package:filcnaplo/models/config.dart';
|
import 'package:filcnaplo/models/config.dart';
|
||||||
import 'package:filcnaplo/theme.dart';
|
import 'package:filcnaplo/models/icon_pack.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/accent.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/dark_mobile.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
enum Pages { home, grades, timetable, messages, absences }
|
enum Pages { home, grades, timetable, messages, absences }
|
||||||
@@ -15,6 +16,8 @@ enum UpdateChannel { stable, beta, dev }
|
|||||||
enum VibrationStrength { off, light, medium, strong }
|
enum VibrationStrength { off, light, medium, strong }
|
||||||
|
|
||||||
class SettingsProvider extends ChangeNotifier {
|
class SettingsProvider extends ChangeNotifier {
|
||||||
|
final DatabaseProvider? _database;
|
||||||
|
|
||||||
// en_en, hu_hu, de_de
|
// en_en, hu_hu, de_de
|
||||||
String _language;
|
String _language;
|
||||||
Pages _startPage;
|
Pages _startPage;
|
||||||
@@ -54,8 +57,16 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
bool _presentationMode;
|
bool _presentationMode;
|
||||||
bool _bellDelayEnabled;
|
bool _bellDelayEnabled;
|
||||||
int _bellDelay;
|
int _bellDelay;
|
||||||
|
bool _gradeOpeningFun;
|
||||||
|
IconPack _iconPack;
|
||||||
|
Color _customAccentColor;
|
||||||
|
Color _customBackgroundColor;
|
||||||
|
Color _customHighlightColor;
|
||||||
|
List<String> _premiumScopes;
|
||||||
|
String _premiumAccessToken;
|
||||||
|
|
||||||
SettingsProvider({
|
SettingsProvider({
|
||||||
|
DatabaseProvider? database,
|
||||||
required String language,
|
required String language,
|
||||||
required Pages startPage,
|
required Pages startPage,
|
||||||
required int rounding,
|
required int rounding,
|
||||||
@@ -79,7 +90,15 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
required bool presentationMode,
|
required bool presentationMode,
|
||||||
required bool bellDelayEnabled,
|
required bool bellDelayEnabled,
|
||||||
required int bellDelay,
|
required int bellDelay,
|
||||||
}) : _language = language,
|
required bool gradeOpeningFun,
|
||||||
|
required IconPack iconPack,
|
||||||
|
required Color customAccentColor,
|
||||||
|
required Color customBackgroundColor,
|
||||||
|
required Color customHighlightColor,
|
||||||
|
required List<String> premiumScopes,
|
||||||
|
required String premiumAccessToken,
|
||||||
|
}) : _database = database,
|
||||||
|
_language = language,
|
||||||
_startPage = startPage,
|
_startPage = startPage,
|
||||||
_rounding = rounding,
|
_rounding = rounding,
|
||||||
_theme = theme,
|
_theme = theme,
|
||||||
@@ -101,9 +120,16 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
_goodStudent = goodStudent,
|
_goodStudent = goodStudent,
|
||||||
_presentationMode = presentationMode,
|
_presentationMode = presentationMode,
|
||||||
_bellDelayEnabled = bellDelayEnabled,
|
_bellDelayEnabled = bellDelayEnabled,
|
||||||
_bellDelay = bellDelay;
|
_bellDelay = bellDelay,
|
||||||
|
_gradeOpeningFun = gradeOpeningFun,
|
||||||
|
_iconPack = iconPack,
|
||||||
|
_customAccentColor = customAccentColor,
|
||||||
|
_customBackgroundColor = customBackgroundColor,
|
||||||
|
_customHighlightColor = customHighlightColor,
|
||||||
|
_premiumScopes = premiumScopes,
|
||||||
|
_premiumAccessToken = premiumAccessToken;
|
||||||
|
|
||||||
factory SettingsProvider.fromMap(Map map) {
|
factory SettingsProvider.fromMap(Map map, {required DatabaseProvider database}) {
|
||||||
Map<String, Object?>? configMap;
|
Map<String, Object?>? configMap;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -113,6 +139,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return SettingsProvider(
|
return SettingsProvider(
|
||||||
|
database: database,
|
||||||
language: map["language"],
|
language: map["language"],
|
||||||
startPage: Pages.values[map["start_page"]],
|
startPage: Pages.values[map["start_page"]],
|
||||||
rounding: map["rounding"],
|
rounding: map["rounding"],
|
||||||
@@ -142,6 +169,13 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
presentationMode: map["presentation_mode"] == 1,
|
presentationMode: map["presentation_mode"] == 1,
|
||||||
bellDelayEnabled: map["bell_delay_enabled"] == 1,
|
bellDelayEnabled: map["bell_delay_enabled"] == 1,
|
||||||
bellDelay: map["bell_delay"],
|
bellDelay: map["bell_delay"],
|
||||||
|
gradeOpeningFun: map["grade_opening_fun"] == 1,
|
||||||
|
iconPack: Map.fromEntries(IconPack.values.map((e) => MapEntry(e.name, e)))[map["icon_pack"]]!,
|
||||||
|
customAccentColor: Color(map["custom_accent_color"]),
|
||||||
|
customBackgroundColor: Color(map["custom_background_color"]),
|
||||||
|
customHighlightColor: Color(map["custom_highlight_color"]),
|
||||||
|
premiumScopes: jsonDecode(map["premium_scopes"]).cast<String>(),
|
||||||
|
premiumAccessToken: map["premium_token"],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,22 +207,30 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
"presentation_mode": _presentationMode ? 1 : 0,
|
"presentation_mode": _presentationMode ? 1 : 0,
|
||||||
"bell_delay_enabled": _bellDelayEnabled ? 1 : 0,
|
"bell_delay_enabled": _bellDelayEnabled ? 1 : 0,
|
||||||
"bell_delay": _bellDelay,
|
"bell_delay": _bellDelay,
|
||||||
|
"grade_opening_fun": _gradeOpeningFun ? 1 : 0,
|
||||||
|
"icon_pack": _iconPack.name,
|
||||||
|
"custom_accent_color": _customAccentColor.value,
|
||||||
|
"custom_background_color": _customBackgroundColor.value,
|
||||||
|
"custom_highlight_color": _customHighlightColor.value,
|
||||||
|
"premium_scopes": jsonEncode(_premiumScopes),
|
||||||
|
"premium_token": _premiumAccessToken,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
factory SettingsProvider.defaultSettings() {
|
factory SettingsProvider.defaultSettings({DatabaseProvider? database}) {
|
||||||
return SettingsProvider(
|
return SettingsProvider(
|
||||||
|
database: database,
|
||||||
language: "hu",
|
language: "hu",
|
||||||
startPage: Pages.home,
|
startPage: Pages.home,
|
||||||
rounding: 5,
|
rounding: 5,
|
||||||
theme: ThemeMode.system,
|
theme: ThemeMode.system,
|
||||||
accentColor: AccentColor.filc,
|
accentColor: AccentColor.filc,
|
||||||
gradeColors: [
|
gradeColors: [
|
||||||
DarkAppColors().red,
|
DarkMobileAppColors().red,
|
||||||
DarkAppColors().orange,
|
DarkMobileAppColors().orange,
|
||||||
DarkAppColors().yellow,
|
DarkMobileAppColors().yellow,
|
||||||
DarkAppColors().green,
|
DarkMobileAppColors().green,
|
||||||
DarkAppColors().filc,
|
DarkMobileAppColors().filc,
|
||||||
],
|
],
|
||||||
newsEnabled: true,
|
newsEnabled: true,
|
||||||
newsState: -1,
|
newsState: -1,
|
||||||
@@ -207,6 +249,13 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
presentationMode: false,
|
presentationMode: false,
|
||||||
bellDelayEnabled: false,
|
bellDelayEnabled: false,
|
||||||
bellDelay: 0,
|
bellDelay: 0,
|
||||||
|
gradeOpeningFun: true,
|
||||||
|
iconPack: IconPack.cupertino,
|
||||||
|
customAccentColor: const Color(0xff20AC9B),
|
||||||
|
customBackgroundColor: const Color(0xff000000),
|
||||||
|
customHighlightColor: const Color(0xff222222),
|
||||||
|
premiumScopes: [],
|
||||||
|
premiumAccessToken: "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,10 +283,15 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
bool get presentationMode => _presentationMode;
|
bool get presentationMode => _presentationMode;
|
||||||
bool get bellDelayEnabled => _bellDelayEnabled;
|
bool get bellDelayEnabled => _bellDelayEnabled;
|
||||||
int get bellDelay => _bellDelay;
|
int get bellDelay => _bellDelay;
|
||||||
|
bool get gradeOpeningFun => _gradeOpeningFun;
|
||||||
|
IconPack get iconPack => _iconPack;
|
||||||
|
Color? get customAccentColor => _customAccentColor == accentColorMap[AccentColor.custom] ? null : _customAccentColor;
|
||||||
|
Color? get customBackgroundColor => _customBackgroundColor;
|
||||||
|
Color? get customHighlightColor => _customHighlightColor;
|
||||||
|
List<String> get premiumScopes => _premiumScopes;
|
||||||
|
String get premiumAccessToken => _premiumAccessToken;
|
||||||
|
|
||||||
Future<void> update(
|
Future<void> update({
|
||||||
BuildContext context, {
|
|
||||||
DatabaseProvider? database,
|
|
||||||
bool store = true,
|
bool store = true,
|
||||||
String? language,
|
String? language,
|
||||||
Pages? startPage,
|
Pages? startPage,
|
||||||
@@ -262,6 +316,13 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
bool? presentationMode,
|
bool? presentationMode,
|
||||||
bool? bellDelayEnabled,
|
bool? bellDelayEnabled,
|
||||||
int? bellDelay,
|
int? bellDelay,
|
||||||
|
bool? gradeOpeningFun,
|
||||||
|
IconPack? iconPack,
|
||||||
|
Color? customAccentColor,
|
||||||
|
Color? customBackgroundColor,
|
||||||
|
Color? customHighlightColor,
|
||||||
|
List<String>? premiumScopes,
|
||||||
|
String? premiumAccessToken,
|
||||||
}) async {
|
}) async {
|
||||||
if (language != null && language != _language) _language = language;
|
if (language != null && language != _language) _language = language;
|
||||||
if (startPage != null && startPage != _startPage) _startPage = startPage;
|
if (startPage != null && startPage != _startPage) _startPage = startPage;
|
||||||
@@ -288,9 +349,15 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
if (presentationMode != null && presentationMode != _presentationMode) _presentationMode = presentationMode;
|
if (presentationMode != null && presentationMode != _presentationMode) _presentationMode = presentationMode;
|
||||||
if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay;
|
if (bellDelay != null && bellDelay != _bellDelay) _bellDelay = bellDelay;
|
||||||
if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled) _bellDelayEnabled = bellDelayEnabled;
|
if (bellDelayEnabled != null && bellDelayEnabled != _bellDelayEnabled) _bellDelayEnabled = bellDelayEnabled;
|
||||||
|
if (gradeOpeningFun != null && gradeOpeningFun != _gradeOpeningFun) _gradeOpeningFun = gradeOpeningFun;
|
||||||
|
if (iconPack != null && iconPack != _iconPack) _iconPack = iconPack;
|
||||||
|
if (customAccentColor != null && customAccentColor != _customAccentColor) _customAccentColor = customAccentColor;
|
||||||
|
if (customBackgroundColor != null && customBackgroundColor != _customBackgroundColor) _customBackgroundColor = customBackgroundColor;
|
||||||
|
if (customHighlightColor != null && customHighlightColor != _customHighlightColor) _customHighlightColor = customHighlightColor;
|
||||||
|
if (premiumScopes != null && premiumScopes != _premiumScopes) _premiumScopes = premiumScopes;
|
||||||
|
if (premiumAccessToken != null && premiumAccessToken != _premiumAccessToken) _premiumAccessToken = premiumAccessToken;
|
||||||
|
|
||||||
database ??= Provider.of<DatabaseProvider>(context, listen: false);
|
if (store) await _database?.store.storeSettings(this);
|
||||||
if (store) await database.store.storeSettings(this);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ class User {
|
|||||||
String name;
|
String name;
|
||||||
Student student;
|
Student student;
|
||||||
Role role;
|
Role role;
|
||||||
|
String nickname;
|
||||||
|
|
||||||
|
String get displayName => nickname != '' ? nickname : name;
|
||||||
|
|
||||||
User({
|
User({
|
||||||
String? id,
|
String? id,
|
||||||
@@ -22,6 +25,7 @@ class User {
|
|||||||
required this.instituteCode,
|
required this.instituteCode,
|
||||||
required this.student,
|
required this.student,
|
||||||
required this.role,
|
required this.role,
|
||||||
|
this.nickname = "",
|
||||||
}) {
|
}) {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -39,6 +43,7 @@ class User {
|
|||||||
name: map["name"].trim(),
|
name: map["name"].trim(),
|
||||||
student: Student.fromJson(jsonDecode(map["student"])),
|
student: Student.fromJson(jsonDecode(map["student"])),
|
||||||
role: Role.values[map["role"] ?? 0],
|
role: Role.values[map["role"] ?? 0],
|
||||||
|
nickname: map["nickname"] ?? "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +56,7 @@ class User {
|
|||||||
"name": name,
|
"name": name,
|
||||||
"student": jsonEncode(student.json),
|
"student": jsonEncode(student.json),
|
||||||
"role": role.index,
|
"role": role.index,
|
||||||
|
"nickname": nickname,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,4 +76,17 @@ class User {
|
|||||||
"client_id": KretaAPI.clientId,
|
"client_id": KretaAPI.clientId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Map<String, Object?> refreshBody({
|
||||||
|
required String refreshToken,
|
||||||
|
required String instituteCode,
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
"refresh_token": refreshToken,
|
||||||
|
"institute_code": instituteCode,
|
||||||
|
"client_id": KretaAPI.clientId,
|
||||||
|
"grant_type": "refresh_token",
|
||||||
|
"refresh_user_data": "false",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,235 +0,0 @@
|
|||||||
import 'package:filcnaplo/models/settings.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:material_color_utilities/material_color_utilities.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class AppTheme {
|
|
||||||
// Dev note: All of these could be constant variables, but this is better for
|
|
||||||
// development (you don't have to hot-restart)
|
|
||||||
|
|
||||||
static const String _fontFamily = "Montserrat";
|
|
||||||
|
|
||||||
static Color? _paletteAccentLight(CorePalette? palette) => palette != null ? Color(palette.primary.get(70)) : null;
|
|
||||||
static Color? _paletteHighlightLight(CorePalette? palette) => palette != null ? Color(palette.neutral.get(100)) : null;
|
|
||||||
static Color? _paletteBackgroundLight(CorePalette? palette) => palette != null ? Color(palette.neutral.get(95)) : null;
|
|
||||||
|
|
||||||
static Color? _paletteAccentDark(CorePalette? palette) => palette != null ? Color(palette.primary.get(80)) : null;
|
|
||||||
static Color? _paletteBackgroundDark(CorePalette? palette) => palette != null ? Color(palette.neutralVariant.get(10)) : null;
|
|
||||||
static Color? _paletteHighlightDark(CorePalette? palette) => palette != null ? Color(palette.neutralVariant.get(20)) : null;
|
|
||||||
|
|
||||||
// Light Theme
|
|
||||||
static ThemeData lightTheme(BuildContext context, {CorePalette? palette}) {
|
|
||||||
var lightColors = LightAppColors();
|
|
||||||
AccentColor accentColor = Provider.of<SettingsProvider>(context, listen: false).accentColor;
|
|
||||||
Color accent = accentColorMap[accentColor] ?? const Color(0x00000000);
|
|
||||||
|
|
||||||
if (accentColor == AccentColor.adaptive) {
|
|
||||||
if (palette != null) accent = _paletteAccentLight(palette)!;
|
|
||||||
} else {
|
|
||||||
palette = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ThemeData(
|
|
||||||
brightness: Brightness.light,
|
|
||||||
fontFamily: _fontFamily,
|
|
||||||
scaffoldBackgroundColor: _paletteBackgroundLight(palette) ?? lightColors.background,
|
|
||||||
backgroundColor: _paletteHighlightLight(palette) ?? lightColors.highlight,
|
|
||||||
primaryColor: lightColors.filc,
|
|
||||||
dividerColor: const Color(0x00000000),
|
|
||||||
colorScheme: ColorScheme.fromSwatch(
|
|
||||||
accentColor: accent,
|
|
||||||
backgroundColor: _paletteBackgroundLight(palette) ?? lightColors.background,
|
|
||||||
brightness: Brightness.light,
|
|
||||||
cardColor: _paletteHighlightLight(palette) ?? lightColors.highlight,
|
|
||||||
errorColor: lightColors.red,
|
|
||||||
primaryColorDark: lightColors.filc,
|
|
||||||
primarySwatch: Colors.teal,
|
|
||||||
),
|
|
||||||
shadowColor: lightColors.shadow,
|
|
||||||
appBarTheme: AppBarTheme(backgroundColor: _paletteBackgroundLight(palette) ?? lightColors.background),
|
|
||||||
indicatorColor: accent,
|
|
||||||
iconTheme: IconThemeData(color: lightColors.text.withOpacity(.75)),
|
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
|
||||||
indicatorColor: accent.withOpacity(accentColor == AccentColor.adaptive ? 0.4 : 0.8),
|
|
||||||
iconTheme: MaterialStateProperty.all(IconThemeData(color: lightColors.text)),
|
|
||||||
backgroundColor: _paletteHighlightLight(palette) ?? lightColors.highlight,
|
|
||||||
labelTextStyle: MaterialStateProperty.all(TextStyle(
|
|
||||||
fontSize: 13.0,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: lightColors.text.withOpacity(0.8),
|
|
||||||
)),
|
|
||||||
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
|
|
||||||
height: 76.0,
|
|
||||||
),
|
|
||||||
sliderTheme: SliderThemeData(
|
|
||||||
inactiveTrackColor: accent.withOpacity(.3),
|
|
||||||
),
|
|
||||||
progressIndicatorTheme: ProgressIndicatorThemeData(color: accent),
|
|
||||||
expansionTileTheme: ExpansionTileThemeData(iconColor: accent),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dark Theme
|
|
||||||
static ThemeData darkTheme(BuildContext context, {CorePalette? palette}) {
|
|
||||||
var darkColors = DarkAppColors();
|
|
||||||
AccentColor accentColor = Provider.of<SettingsProvider>(context, listen: false).accentColor;
|
|
||||||
Color accent = accentColorMap[accentColor] ?? const Color(0x00000000);
|
|
||||||
|
|
||||||
if (accentColor == AccentColor.adaptive) {
|
|
||||||
if (palette != null) accent = _paletteAccentDark(palette)!;
|
|
||||||
} else {
|
|
||||||
palette = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ThemeData(
|
|
||||||
brightness: Brightness.dark,
|
|
||||||
fontFamily: _fontFamily,
|
|
||||||
scaffoldBackgroundColor: _paletteBackgroundDark(palette) ?? darkColors.background,
|
|
||||||
backgroundColor: _paletteHighlightDark(palette) ?? darkColors.highlight,
|
|
||||||
primaryColor: darkColors.filc,
|
|
||||||
dividerColor: const Color(0x00000000),
|
|
||||||
colorScheme: ColorScheme.fromSwatch(
|
|
||||||
accentColor: accent,
|
|
||||||
backgroundColor: _paletteBackgroundDark(palette) ?? darkColors.background,
|
|
||||||
brightness: Brightness.dark,
|
|
||||||
cardColor: _paletteHighlightDark(palette) ?? darkColors.highlight,
|
|
||||||
errorColor: darkColors.red,
|
|
||||||
primaryColorDark: darkColors.filc,
|
|
||||||
primarySwatch: Colors.teal,
|
|
||||||
),
|
|
||||||
shadowColor: darkColors.shadow,
|
|
||||||
appBarTheme: AppBarTheme(backgroundColor: _paletteBackgroundDark(palette) ?? darkColors.background),
|
|
||||||
indicatorColor: accent,
|
|
||||||
iconTheme: IconThemeData(color: darkColors.text.withOpacity(.75)),
|
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
|
||||||
indicatorColor: accent.withOpacity(accentColor == AccentColor.adaptive ? 0.4 : 0.8),
|
|
||||||
iconTheme: MaterialStateProperty.all(IconThemeData(color: darkColors.text)),
|
|
||||||
backgroundColor: _paletteHighlightDark(palette) ?? darkColors.highlight,
|
|
||||||
labelTextStyle: MaterialStateProperty.all(TextStyle(
|
|
||||||
fontSize: 13.0,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: darkColors.text.withOpacity(0.8),
|
|
||||||
)),
|
|
||||||
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
|
|
||||||
height: 76.0,
|
|
||||||
),
|
|
||||||
sliderTheme: SliderThemeData(
|
|
||||||
inactiveTrackColor: accent.withOpacity(.3),
|
|
||||||
),
|
|
||||||
progressIndicatorTheme: ProgressIndicatorThemeData(color: accent),
|
|
||||||
expansionTileTheme: ExpansionTileThemeData(iconColor: accent),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AppColors {
|
|
||||||
static ThemeAppColors of(BuildContext context) {
|
|
||||||
return Theme.of(context).brightness == Brightness.light ? LightAppColors() : DarkAppColors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum AccentColor { filc, blue, green, lime, yellow, orange, red, pink, purple, adaptive }
|
|
||||||
|
|
||||||
Map<AccentColor, Color> accentColorMap = {
|
|
||||||
AccentColor.filc: const Color(0xff20AC9B),
|
|
||||||
AccentColor.blue: Colors.blue.shade300,
|
|
||||||
AccentColor.green: Colors.green.shade400,
|
|
||||||
AccentColor.lime: Colors.lightGreen.shade400,
|
|
||||||
AccentColor.yellow: Colors.orange.shade300,
|
|
||||||
AccentColor.orange: Colors.deepOrange.shade300,
|
|
||||||
AccentColor.red: Colors.red.shade300,
|
|
||||||
AccentColor.pink: Colors.pink.shade300,
|
|
||||||
AccentColor.purple: Colors.purple.shade300,
|
|
||||||
AccentColor.adaptive: const Color(0xff20AC9B),
|
|
||||||
};
|
|
||||||
|
|
||||||
abstract class ThemeAppColors {
|
|
||||||
final Color shadow = const Color(0x00000000);
|
|
||||||
final Color text = const Color(0x00000000);
|
|
||||||
final Color background = const Color(0x00000000);
|
|
||||||
final Color highlight = const Color(0x00000000);
|
|
||||||
final Color red = const Color(0x00000000);
|
|
||||||
final Color orange = const Color(0x00000000);
|
|
||||||
final Color yellow = const Color(0x00000000);
|
|
||||||
final Color green = const Color(0x00000000);
|
|
||||||
final Color filc = const Color(0x00000000);
|
|
||||||
final Color teal = const Color(0x00000000);
|
|
||||||
final Color blue = const Color(0x00000000);
|
|
||||||
final Color indigo = const Color(0x00000000);
|
|
||||||
final Color purple = const Color(0x00000000);
|
|
||||||
final Color pink = const Color(0x00000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
class LightAppColors implements ThemeAppColors {
|
|
||||||
@override
|
|
||||||
final shadow = const Color(0xffE8E8E8);
|
|
||||||
@override
|
|
||||||
final text = Colors.black;
|
|
||||||
@override
|
|
||||||
final background = const Color(0xffF4F9FF);
|
|
||||||
@override
|
|
||||||
final highlight = const Color(0xffFFFFFF);
|
|
||||||
@override
|
|
||||||
final red = const Color(0xffFF3B30);
|
|
||||||
@override
|
|
||||||
final orange = const Color(0xffFF9500);
|
|
||||||
@override
|
|
||||||
final yellow = const Color(0xffFFCC00);
|
|
||||||
@override
|
|
||||||
final green = const Color(0xff34C759);
|
|
||||||
@override
|
|
||||||
final filc = const Color(0xff247665);
|
|
||||||
@override
|
|
||||||
final teal = const Color(0xff5AC8FA);
|
|
||||||
@override
|
|
||||||
final blue = const Color(0xff007AFF);
|
|
||||||
@override
|
|
||||||
final indigo = const Color(0xff5856D6);
|
|
||||||
@override
|
|
||||||
final purple = const Color(0xffAF52DE);
|
|
||||||
@override
|
|
||||||
final pink = const Color(0xffFF2D55);
|
|
||||||
}
|
|
||||||
|
|
||||||
class DarkAppColors implements ThemeAppColors {
|
|
||||||
@override
|
|
||||||
final shadow = const Color(0x00000000);
|
|
||||||
@override
|
|
||||||
final text = Colors.white;
|
|
||||||
@override
|
|
||||||
final background = const Color(0xff000000);
|
|
||||||
@override
|
|
||||||
final highlight = const Color(0xff141516);
|
|
||||||
@override
|
|
||||||
final red = const Color(0xffFF453A);
|
|
||||||
@override
|
|
||||||
final orange = const Color(0xffFF9F0A);
|
|
||||||
@override
|
|
||||||
final yellow = const Color(0xffFFD60A);
|
|
||||||
@override
|
|
||||||
final green = const Color(0xff32D74B);
|
|
||||||
@override
|
|
||||||
final filc = const Color(0xff29826F);
|
|
||||||
@override
|
|
||||||
final teal = const Color(0xff64D2FF);
|
|
||||||
@override
|
|
||||||
final blue = const Color(0xff0A84FF);
|
|
||||||
@override
|
|
||||||
final indigo = const Color(0xff5E5CE6);
|
|
||||||
@override
|
|
||||||
final purple = const Color(0xffBF5AF2);
|
|
||||||
@override
|
|
||||||
final pink = const Color(0xffFF375F);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ThemeModeObserver extends ChangeNotifier {
|
|
||||||
ThemeMode _themeMode;
|
|
||||||
ThemeMode get themeMode => _themeMode;
|
|
||||||
|
|
||||||
ThemeModeObserver({ThemeMode initialTheme = ThemeMode.system}) : _themeMode = initialTheme;
|
|
||||||
|
|
||||||
void changeTheme(ThemeMode mode) {
|
|
||||||
_themeMode = mode;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
17
filcnaplo/lib/theme/colors/accent.dart
Normal file
17
filcnaplo/lib/theme/colors/accent.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
enum AccentColor { filc, blue, green, lime, yellow, orange, red, pink, purple, adaptive, custom }
|
||||||
|
|
||||||
|
Map<AccentColor, Color> accentColorMap = {
|
||||||
|
AccentColor.filc: const Color(0xff20AC9B),
|
||||||
|
AccentColor.blue: Colors.blue.shade300,
|
||||||
|
AccentColor.green: Colors.green.shade400,
|
||||||
|
AccentColor.lime: Colors.lightGreen.shade400,
|
||||||
|
AccentColor.yellow: Colors.orange.shade300,
|
||||||
|
AccentColor.orange: Colors.deepOrange.shade300,
|
||||||
|
AccentColor.red: Colors.red.shade300,
|
||||||
|
AccentColor.pink: Colors.pink.shade300,
|
||||||
|
AccentColor.purple: Colors.purple.shade300,
|
||||||
|
AccentColor.adaptive: const Color(0xff20AC9B),
|
||||||
|
AccentColor.custom: const Color(0xff20AC9B),
|
||||||
|
};
|
||||||
46
filcnaplo/lib/theme/colors/colors.dart
Normal file
46
filcnaplo/lib/theme/colors/colors.dart
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:filcnaplo/theme/colors/dark_desktop.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/dark_mobile.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/light_desktop.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/light_mobile.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AppColors {
|
||||||
|
static ThemeAppColors of(BuildContext context) => fromBrightness(Theme.of(context).brightness);
|
||||||
|
|
||||||
|
static fromBrightness(Brightness brightness) {
|
||||||
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
|
switch (brightness) {
|
||||||
|
case Brightness.light:
|
||||||
|
return LightMobileAppColors();
|
||||||
|
case Brightness.dark:
|
||||||
|
return DarkMobileAppColors();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (brightness) {
|
||||||
|
case Brightness.light:
|
||||||
|
return LightDesktopAppColors();
|
||||||
|
case Brightness.dark:
|
||||||
|
return DarkDesktopAppColors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ThemeAppColors {
|
||||||
|
final Color shadow = const Color(0x00000000);
|
||||||
|
final Color text = const Color(0x00000000);
|
||||||
|
final Color background = const Color(0x00000000);
|
||||||
|
final Color highlight = const Color(0x00000000);
|
||||||
|
final Color red = const Color(0x00000000);
|
||||||
|
final Color orange = const Color(0x00000000);
|
||||||
|
final Color yellow = const Color(0x00000000);
|
||||||
|
final Color green = const Color(0x00000000);
|
||||||
|
final Color filc = const Color(0x00000000);
|
||||||
|
final Color teal = const Color(0x00000000);
|
||||||
|
final Color blue = const Color(0x00000000);
|
||||||
|
final Color indigo = const Color(0x00000000);
|
||||||
|
final Color purple = const Color(0x00000000);
|
||||||
|
final Color pink = const Color(0x00000000);
|
||||||
|
}
|
||||||
33
filcnaplo/lib/theme/colors/dark_desktop.dart
Normal file
33
filcnaplo/lib/theme/colors/dark_desktop.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DarkDesktopAppColors implements ThemeAppColors {
|
||||||
|
@override
|
||||||
|
final shadow = const Color(0x00000000);
|
||||||
|
@override
|
||||||
|
final text = Colors.white;
|
||||||
|
@override
|
||||||
|
final background = const Color.fromARGB(255, 42, 42, 42);
|
||||||
|
@override
|
||||||
|
final highlight = const Color.fromARGB(255, 46, 48, 50);
|
||||||
|
@override
|
||||||
|
final red = const Color(0xffFF453A);
|
||||||
|
@override
|
||||||
|
final orange = const Color(0xffFF9F0A);
|
||||||
|
@override
|
||||||
|
final yellow = const Color(0xffFFD60A);
|
||||||
|
@override
|
||||||
|
final green = const Color(0xff32D74B);
|
||||||
|
@override
|
||||||
|
final filc = const Color(0xff29826F);
|
||||||
|
@override
|
||||||
|
final teal = const Color(0xff64D2FF);
|
||||||
|
@override
|
||||||
|
final blue = const Color(0xff0A84FF);
|
||||||
|
@override
|
||||||
|
final indigo = const Color(0xff5E5CE6);
|
||||||
|
@override
|
||||||
|
final purple = const Color(0xffBF5AF2);
|
||||||
|
@override
|
||||||
|
final pink = const Color(0xffFF375F);
|
||||||
|
}
|
||||||
33
filcnaplo/lib/theme/colors/dark_mobile.dart
Normal file
33
filcnaplo/lib/theme/colors/dark_mobile.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DarkMobileAppColors implements ThemeAppColors {
|
||||||
|
@override
|
||||||
|
final shadow = const Color(0x00000000);
|
||||||
|
@override
|
||||||
|
final text = Colors.white;
|
||||||
|
@override
|
||||||
|
final background = const Color(0xff000000);
|
||||||
|
@override
|
||||||
|
final highlight = const Color(0xff141516);
|
||||||
|
@override
|
||||||
|
final red = const Color(0xffFF453A);
|
||||||
|
@override
|
||||||
|
final orange = const Color(0xffFF9F0A);
|
||||||
|
@override
|
||||||
|
final yellow = const Color(0xffFFD60A);
|
||||||
|
@override
|
||||||
|
final green = const Color(0xff32D74B);
|
||||||
|
@override
|
||||||
|
final filc = const Color(0xff29826F);
|
||||||
|
@override
|
||||||
|
final teal = const Color(0xff64D2FF);
|
||||||
|
@override
|
||||||
|
final blue = const Color(0xff0A84FF);
|
||||||
|
@override
|
||||||
|
final indigo = const Color(0xff5E5CE6);
|
||||||
|
@override
|
||||||
|
final purple = const Color(0xffBF5AF2);
|
||||||
|
@override
|
||||||
|
final pink = const Color(0xffFF375F);
|
||||||
|
}
|
||||||
33
filcnaplo/lib/theme/colors/light_desktop.dart
Normal file
33
filcnaplo/lib/theme/colors/light_desktop.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LightDesktopAppColors implements ThemeAppColors {
|
||||||
|
@override
|
||||||
|
final shadow = const Color(0xffE8E8E8);
|
||||||
|
@override
|
||||||
|
final text = Colors.black;
|
||||||
|
@override
|
||||||
|
final background = const Color(0xffF4F9FF);
|
||||||
|
@override
|
||||||
|
final highlight = const Color(0xffFFFFFF);
|
||||||
|
@override
|
||||||
|
final red = const Color(0xffFF3B30);
|
||||||
|
@override
|
||||||
|
final orange = const Color(0xffFF9500);
|
||||||
|
@override
|
||||||
|
final yellow = const Color(0xffFFCC00);
|
||||||
|
@override
|
||||||
|
final green = const Color(0xff34C759);
|
||||||
|
@override
|
||||||
|
final filc = const Color(0xff247665);
|
||||||
|
@override
|
||||||
|
final teal = const Color(0xff5AC8FA);
|
||||||
|
@override
|
||||||
|
final blue = const Color(0xff007AFF);
|
||||||
|
@override
|
||||||
|
final indigo = const Color(0xff5856D6);
|
||||||
|
@override
|
||||||
|
final purple = const Color(0xffAF52DE);
|
||||||
|
@override
|
||||||
|
final pink = const Color(0xffFF2D55);
|
||||||
|
}
|
||||||
33
filcnaplo/lib/theme/colors/light_mobile.dart
Normal file
33
filcnaplo/lib/theme/colors/light_mobile.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LightMobileAppColors implements ThemeAppColors {
|
||||||
|
@override
|
||||||
|
final shadow = const Color(0xffE8E8E8);
|
||||||
|
@override
|
||||||
|
final text = Colors.black;
|
||||||
|
@override
|
||||||
|
final background = const Color(0xffF4F9FF);
|
||||||
|
@override
|
||||||
|
final highlight = const Color(0xffFFFFFF);
|
||||||
|
@override
|
||||||
|
final red = const Color(0xffFF3B30);
|
||||||
|
@override
|
||||||
|
final orange = const Color(0xffFF9500);
|
||||||
|
@override
|
||||||
|
final yellow = const Color(0xffFFCC00);
|
||||||
|
@override
|
||||||
|
final green = const Color(0xff34C759);
|
||||||
|
@override
|
||||||
|
final filc = const Color(0xff247665);
|
||||||
|
@override
|
||||||
|
final teal = const Color(0xff5AC8FA);
|
||||||
|
@override
|
||||||
|
final blue = const Color(0xff007AFF);
|
||||||
|
@override
|
||||||
|
final indigo = const Color(0xff5856D6);
|
||||||
|
@override
|
||||||
|
final purple = const Color(0xffAF52DE);
|
||||||
|
@override
|
||||||
|
final pink = const Color(0xffFF2D55);
|
||||||
|
}
|
||||||
13
filcnaplo/lib/theme/observer.dart
Normal file
13
filcnaplo/lib/theme/observer.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ThemeModeObserver extends ChangeNotifier {
|
||||||
|
ThemeMode _themeMode;
|
||||||
|
ThemeMode get themeMode => _themeMode;
|
||||||
|
|
||||||
|
ThemeModeObserver({ThemeMode initialTheme = ThemeMode.system}) : _themeMode = initialTheme;
|
||||||
|
|
||||||
|
void changeTheme(ThemeMode mode) {
|
||||||
|
_themeMode = mode;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
138
filcnaplo/lib/theme/theme.dart
Normal file
138
filcnaplo/lib/theme/theme.dart
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/accent.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:material_color_utilities/material_color_utilities.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AppTheme {
|
||||||
|
// Dev note: All of these could be constant variables, but this is better for
|
||||||
|
// development (you don't have to hot-restart)
|
||||||
|
|
||||||
|
static const String _fontFamily = "Montserrat";
|
||||||
|
|
||||||
|
static Color? _paletteAccentLight(CorePalette? palette) => palette != null ? Color(palette.primary.get(70)) : null;
|
||||||
|
static Color? _paletteHighlightLight(CorePalette? palette) => palette != null ? Color(palette.neutral.get(100)) : null;
|
||||||
|
static Color? _paletteBackgroundLight(CorePalette? palette) => palette != null ? Color(palette.neutral.get(95)) : null;
|
||||||
|
|
||||||
|
static Color? _paletteAccentDark(CorePalette? palette) => palette != null ? Color(palette.primary.get(80)) : null;
|
||||||
|
static Color? _paletteBackgroundDark(CorePalette? palette) => palette != null ? Color(palette.neutralVariant.get(10)) : null;
|
||||||
|
static Color? _paletteHighlightDark(CorePalette? palette) => palette != null ? Color(palette.neutralVariant.get(20)) : null;
|
||||||
|
|
||||||
|
// Light Theme
|
||||||
|
static ThemeData lightTheme(BuildContext context, {CorePalette? palette}) {
|
||||||
|
var lightColors = AppColors.fromBrightness(Brightness.light);
|
||||||
|
final settings = Provider.of<SettingsProvider>(context, listen: false);
|
||||||
|
AccentColor accentColor = settings.accentColor;
|
||||||
|
final customAccentColor = accentColor == AccentColor.custom ? settings.customAccentColor : null;
|
||||||
|
Color accent = customAccentColor ?? accentColorMap[accentColor] ?? const Color(0x00000000);
|
||||||
|
|
||||||
|
if (accentColor == AccentColor.adaptive) {
|
||||||
|
if (palette != null) accent = _paletteAccentLight(palette)!;
|
||||||
|
} else {
|
||||||
|
palette = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color backgroundColor =
|
||||||
|
accentColor == AccentColor.custom ? settings.customBackgroundColor : _paletteBackgroundLight(palette) ?? lightColors.background;
|
||||||
|
Color highlighColor =
|
||||||
|
accentColor == AccentColor.custom ? settings.customHighlightColor : _paletteHighlightLight(palette) ?? lightColors.highlight;
|
||||||
|
|
||||||
|
return ThemeData(
|
||||||
|
brightness: Brightness.light,
|
||||||
|
useMaterial3: false,
|
||||||
|
fontFamily: _fontFamily,
|
||||||
|
scaffoldBackgroundColor: backgroundColor,
|
||||||
|
backgroundColor: highlighColor,
|
||||||
|
primaryColor: lightColors.filc,
|
||||||
|
dividerColor: const Color(0x00000000),
|
||||||
|
colorScheme: ColorScheme.fromSwatch(
|
||||||
|
accentColor: accent,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
brightness: Brightness.light,
|
||||||
|
cardColor: highlighColor,
|
||||||
|
errorColor: lightColors.red,
|
||||||
|
primaryColorDark: lightColors.filc,
|
||||||
|
),
|
||||||
|
shadowColor: highlighColor.withOpacity(.5), //lightColors.shadow,
|
||||||
|
appBarTheme: AppBarTheme(backgroundColor: backgroundColor),
|
||||||
|
indicatorColor: accent,
|
||||||
|
iconTheme: IconThemeData(color: lightColors.text.withOpacity(.75)),
|
||||||
|
navigationBarTheme: NavigationBarThemeData(
|
||||||
|
indicatorColor: accent.withOpacity(accentColor == AccentColor.adaptive ? 0.4 : 0.8),
|
||||||
|
iconTheme: MaterialStateProperty.all(IconThemeData(color: lightColors.text)),
|
||||||
|
backgroundColor: highlighColor,
|
||||||
|
labelTextStyle: MaterialStateProperty.all(TextStyle(
|
||||||
|
fontSize: 13.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: lightColors.text.withOpacity(0.8),
|
||||||
|
)),
|
||||||
|
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
|
||||||
|
height: 76.0,
|
||||||
|
),
|
||||||
|
sliderTheme: SliderThemeData(
|
||||||
|
inactiveTrackColor: accent.withOpacity(.3),
|
||||||
|
),
|
||||||
|
progressIndicatorTheme: ProgressIndicatorThemeData(color: accent),
|
||||||
|
expansionTileTheme: ExpansionTileThemeData(iconColor: accent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark Theme
|
||||||
|
static ThemeData darkTheme(BuildContext context, {CorePalette? palette}) {
|
||||||
|
var darkColors = AppColors.fromBrightness(Brightness.dark);
|
||||||
|
final settings = Provider.of<SettingsProvider>(context, listen: false);
|
||||||
|
AccentColor accentColor = settings.accentColor;
|
||||||
|
final customAccentColor = accentColor == AccentColor.custom ? settings.customAccentColor : null;
|
||||||
|
Color accent = customAccentColor ?? accentColorMap[accentColor] ?? const Color(0x00000000);
|
||||||
|
|
||||||
|
if (accentColor == AccentColor.adaptive) {
|
||||||
|
if (palette != null) accent = _paletteAccentDark(palette)!;
|
||||||
|
} else {
|
||||||
|
palette = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color backgroundColor =
|
||||||
|
accentColor == AccentColor.custom ? settings.customBackgroundColor : _paletteBackgroundDark(palette) ?? darkColors.background;
|
||||||
|
Color highlightColor = accentColor == AccentColor.custom ? settings.customHighlightColor : _paletteHighlightDark(palette) ?? darkColors.highlight;
|
||||||
|
|
||||||
|
return ThemeData(
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
useMaterial3: false,
|
||||||
|
fontFamily: _fontFamily,
|
||||||
|
scaffoldBackgroundColor: backgroundColor,
|
||||||
|
backgroundColor: highlightColor,
|
||||||
|
primaryColor: darkColors.filc,
|
||||||
|
dividerColor: const Color(0x00000000),
|
||||||
|
colorScheme: ColorScheme.fromSwatch(
|
||||||
|
accentColor: accent,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
cardColor: highlightColor,
|
||||||
|
errorColor: darkColors.red,
|
||||||
|
primaryColorDark: darkColors.filc,
|
||||||
|
),
|
||||||
|
shadowColor: highlightColor.withOpacity(.5), //darkColors.shadow,
|
||||||
|
appBarTheme: AppBarTheme(backgroundColor: backgroundColor),
|
||||||
|
indicatorColor: accent,
|
||||||
|
iconTheme: IconThemeData(color: darkColors.text.withOpacity(.75)),
|
||||||
|
navigationBarTheme: NavigationBarThemeData(
|
||||||
|
indicatorColor: accent.withOpacity(accentColor == AccentColor.adaptive ? 0.4 : 0.8),
|
||||||
|
iconTheme: MaterialStateProperty.all(IconThemeData(color: darkColors.text)),
|
||||||
|
backgroundColor: highlightColor,
|
||||||
|
labelTextStyle: MaterialStateProperty.all(TextStyle(
|
||||||
|
fontSize: 13.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: darkColors.text.withOpacity(0.8),
|
||||||
|
)),
|
||||||
|
labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
|
||||||
|
height: 76.0,
|
||||||
|
),
|
||||||
|
sliderTheme: SliderThemeData(
|
||||||
|
inactiveTrackColor: accent.withOpacity(.3),
|
||||||
|
),
|
||||||
|
progressIndicatorTheme: ProgressIndicatorThemeData(color: accent),
|
||||||
|
expansionTileTheme: ExpansionTileThemeData(iconColor: accent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
filcnaplo/lib/ui/date_widget.dart
Normal file
8
filcnaplo/lib/ui/date_widget.dart
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class DateWidget {
|
||||||
|
final DateTime date;
|
||||||
|
final Widget widget;
|
||||||
|
final String? key;
|
||||||
|
const DateWidget({required this.date, required this.widget, this.key});
|
||||||
|
}
|
||||||
159
filcnaplo/lib/ui/filter/sort.dart
Normal file
159
filcnaplo/lib/ui/filter/sort.dart
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets.dart';
|
||||||
|
import 'package:filcnaplo/ui/widgets/message/message_tile.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/message.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/absence/absence_viewable.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/absence_group/absence_group_tile.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:implicitly_animated_reorderable_list/implicitly_animated_reorderable_list.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/lesson/changed_lesson_tile.dart';
|
||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
|
||||||
|
// difference.inDays is not reliable
|
||||||
|
bool _sameDate(DateTime a, DateTime b) => (a.year == b.year && a.month == b.month && a.day == b.day);
|
||||||
|
|
||||||
|
List<Widget> sortDateWidgets(
|
||||||
|
BuildContext context, {
|
||||||
|
required List<DateWidget> dateWidgets,
|
||||||
|
bool showTitle = true,
|
||||||
|
bool showDivider = false,
|
||||||
|
bool hasShadow = false,
|
||||||
|
EdgeInsetsGeometry? padding,
|
||||||
|
}) {
|
||||||
|
dateWidgets.sort((a, b) => -a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
List<Conversation> conversations = [];
|
||||||
|
List<DateWidget> convMessages = [];
|
||||||
|
|
||||||
|
// Group messages into conversations
|
||||||
|
for (var w in dateWidgets) {
|
||||||
|
if (w.widget.runtimeType == MessageTile) {
|
||||||
|
Message message = (w.widget as MessageTile).message;
|
||||||
|
|
||||||
|
if (message.conversationId != null) {
|
||||||
|
convMessages.add(w);
|
||||||
|
|
||||||
|
Conversation conv = conversations.firstWhere((e) => e.id == message.conversationId, orElse: () => Conversation(id: message.conversationId!));
|
||||||
|
conv.add(message);
|
||||||
|
if (conv.messages.length == 1) conversations.add(conv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conversations.any((c) => c.id == message.messageId)) {
|
||||||
|
Conversation conv = conversations.firstWhere((e) => e.id == message.messageId);
|
||||||
|
convMessages.add(w);
|
||||||
|
conv.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove individual messages
|
||||||
|
for (var e in convMessages) {
|
||||||
|
dateWidgets.remove(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add conversations
|
||||||
|
for (var conv in conversations) {
|
||||||
|
conv.sort();
|
||||||
|
|
||||||
|
dateWidgets.add(DateWidget(
|
||||||
|
key: "${conv.newest.date.millisecondsSinceEpoch}-msg",
|
||||||
|
date: conv.newest.date,
|
||||||
|
widget: MessageTile(
|
||||||
|
conv.newest,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
dateWidgets.sort((a, b) => -a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
List<List<DateWidget>> groupedDateWidgets = [[]];
|
||||||
|
for (var element in dateWidgets) {
|
||||||
|
if (groupedDateWidgets.last.isNotEmpty) {
|
||||||
|
if (!_sameDate(element.date, groupedDateWidgets.last.last.date)) {
|
||||||
|
groupedDateWidgets.add([element]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupedDateWidgets.last.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
|
||||||
|
if (groupedDateWidgets.first.isNotEmpty) {
|
||||||
|
for (var elements in groupedDateWidgets) {
|
||||||
|
bool cst = showTitle;
|
||||||
|
|
||||||
|
// Group Absence Tiles
|
||||||
|
List<DateWidget> absenceTileWidgets = elements.where((element) {
|
||||||
|
return element.widget is AbsenceViewable && (element.widget as AbsenceViewable).absence.delay == 0;
|
||||||
|
}).toList();
|
||||||
|
List<AbsenceViewable> absenceTiles = absenceTileWidgets.map((e) => e.widget as AbsenceViewable).toList();
|
||||||
|
if (absenceTiles.length > 1) {
|
||||||
|
elements.removeWhere((element) => element.widget.runtimeType == AbsenceViewable && (element.widget as AbsenceViewable).absence.delay == 0);
|
||||||
|
if (elements.isEmpty) {
|
||||||
|
cst = false;
|
||||||
|
}
|
||||||
|
elements.add(DateWidget(
|
||||||
|
widget: AbsenceGroupTile(absenceTiles, showDate: !cst),
|
||||||
|
date: absenceTileWidgets.first.date,
|
||||||
|
key: "${absenceTileWidgets.first.date.millisecondsSinceEpoch}-absence-group"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bring Lesson Tiles to front & sort by index asc
|
||||||
|
List<DateWidget> lessonTiles = elements.where((element) {
|
||||||
|
return element.widget.runtimeType == ChangedLessonTile;
|
||||||
|
}).toList();
|
||||||
|
lessonTiles.sort((a, b) => (a.widget as ChangedLessonTile).lesson.lessonIndex.compareTo((b.widget as ChangedLessonTile).lesson.lessonIndex));
|
||||||
|
elements.removeWhere((element) => element.widget.runtimeType == ChangedLessonTile);
|
||||||
|
elements.insertAll(0, lessonTiles);
|
||||||
|
|
||||||
|
final date = (elements + absenceTileWidgets).first.date;
|
||||||
|
items.add(DateWidget(
|
||||||
|
date: date,
|
||||||
|
widget: Panel(
|
||||||
|
key: ValueKey(date),
|
||||||
|
padding: padding ?? const EdgeInsets.symmetric(vertical: 6.0),
|
||||||
|
title: cst ? Text(date.format(context, forceToday: true)) : null,
|
||||||
|
hasShadow: hasShadow,
|
||||||
|
child: ImplicitlyAnimatedList<DateWidget>(
|
||||||
|
areItemsTheSame: (a, b) => a.key == b.key,
|
||||||
|
spawnIsolate: false,
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, animation, item, index) => filterItemBuilder(context, animation, item.widget, index),
|
||||||
|
items: elements,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final nh = DateTime.now();
|
||||||
|
final now = DateTime(nh.year, nh.month, nh.day).subtract(const Duration(seconds: 1));
|
||||||
|
|
||||||
|
if (showDivider && items.any((i) => i.date.isBefore(now)) && items.any((i) => i.date.isAfter(now))) {
|
||||||
|
items.add(
|
||||||
|
DateWidget(
|
||||||
|
date: now,
|
||||||
|
widget: Center(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 12.0),
|
||||||
|
height: 3.0,
|
||||||
|
width: 150.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
color: AppColors.of(context).text.withOpacity(.25),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort future dates asc, past dates desc
|
||||||
|
items.sort((a, b) => (a.date.isAfter(now) && b.date.isAfter(now) ? 1 : -1) * a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
return items.map((e) => e.widget).toList();
|
||||||
|
}
|
||||||
179
filcnaplo/lib/ui/filter/widgets.dart
Normal file
179
filcnaplo/lib/ui/filter/widgets.dart
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
import 'package:filcnaplo/api/providers/update_provider.dart';
|
||||||
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/grades.dart' as grade_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/certifications.dart' as certification_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/messages.dart' as message_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/absences.dart' as absence_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/homework.dart' as homework_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/exams.dart' as exam_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/notes.dart' as note_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/events.dart' as event_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/lessons.dart' as lesson_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/update.dart' as update_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/missed_exams.dart' as missed_exam_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/premium.dart' as premium_filter;
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/exam_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/homework_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/message_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/note_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
|
||||||
|
import 'package:filcnaplo_premium/providers/premium_provider.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:implicitly_animated_reorderable_list/transitions.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
const List<FilterType> homeFilters = [FilterType.all, FilterType.grades, FilterType.messages, FilterType.absences];
|
||||||
|
|
||||||
|
enum FilterType { all, grades, newGrades, messages, absences, homework, exams, notes, events, lessons, updates, certifications, missedExams, premium }
|
||||||
|
|
||||||
|
Future<List<DateWidget>> getFilterWidgets(FilterType activeData, {bool absencesNoExcused = false, required BuildContext context}) async {
|
||||||
|
final gradeProvider = Provider.of<GradeProvider>(context);
|
||||||
|
final timetableProvider = Provider.of<TimetableProvider>(context);
|
||||||
|
final messageProvider = Provider.of<MessageProvider>(context);
|
||||||
|
final absenceProvider = Provider.of<AbsenceProvider>(context);
|
||||||
|
final homeworkProvider = Provider.of<HomeworkProvider>(context);
|
||||||
|
final examProvider = Provider.of<ExamProvider>(context);
|
||||||
|
final noteProvider = Provider.of<NoteProvider>(context);
|
||||||
|
final eventProvider = Provider.of<EventProvider>(context);
|
||||||
|
final updateProvider = Provider.of<UpdateProvider>(context);
|
||||||
|
final settingsProvider = Provider.of<SettingsProvider>(context);
|
||||||
|
final premiumProvider = Provider.of<PremiumProvider>(context);
|
||||||
|
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
|
||||||
|
switch (activeData) {
|
||||||
|
// All
|
||||||
|
case FilterType.all:
|
||||||
|
final all = await Future.wait<List<DateWidget>>([
|
||||||
|
getFilterWidgets(FilterType.grades, context: context),
|
||||||
|
getFilterWidgets(FilterType.lessons, context: context),
|
||||||
|
getFilterWidgets(FilterType.messages, context: context),
|
||||||
|
getFilterWidgets(FilterType.absences, context: context, absencesNoExcused: true),
|
||||||
|
getFilterWidgets(FilterType.homework, context: context),
|
||||||
|
getFilterWidgets(FilterType.exams, context: context),
|
||||||
|
getFilterWidgets(FilterType.updates, context: context),
|
||||||
|
getFilterWidgets(FilterType.certifications, context: context),
|
||||||
|
getFilterWidgets(FilterType.missedExams, context: context),
|
||||||
|
getFilterWidgets(FilterType.premium, context: context),
|
||||||
|
]);
|
||||||
|
items = all.expand((x) => x).toList();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Grades
|
||||||
|
case FilterType.grades:
|
||||||
|
items = grade_filter.getWidgets(gradeProvider.grades, gradeProvider.lastSeenDate);
|
||||||
|
if (settingsProvider.gradeOpeningFun) {
|
||||||
|
items.addAll(await getFilterWidgets(FilterType.newGrades, context: context));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Grades
|
||||||
|
case FilterType.newGrades:
|
||||||
|
items = grade_filter.getNewWidgets(gradeProvider.grades, gradeProvider.lastSeenDate);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Certifications
|
||||||
|
case FilterType.certifications:
|
||||||
|
items = certification_filter.getWidgets(gradeProvider.grades);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Messages
|
||||||
|
case FilterType.messages:
|
||||||
|
items = message_filter.getWidgets(
|
||||||
|
messageProvider.messages,
|
||||||
|
noteProvider.notes,
|
||||||
|
eventProvider.events,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Absences
|
||||||
|
case FilterType.absences:
|
||||||
|
items = absence_filter.getWidgets(absenceProvider.absences, noExcused: absencesNoExcused);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Homework
|
||||||
|
case FilterType.homework:
|
||||||
|
items = homework_filter.getWidgets(homeworkProvider.homework);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Exams
|
||||||
|
case FilterType.exams:
|
||||||
|
items = exam_filter.getWidgets(examProvider.exams);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Notes
|
||||||
|
case FilterType.notes:
|
||||||
|
items = note_filter.getWidgets(noteProvider.notes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Events
|
||||||
|
case FilterType.events:
|
||||||
|
items = event_filter.getWidgets(eventProvider.events);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Changed Lessons
|
||||||
|
case FilterType.lessons:
|
||||||
|
items = lesson_filter.getWidgets(timetableProvider.lessons);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Updates
|
||||||
|
case FilterType.updates:
|
||||||
|
if (updateProvider.available) items = [update_filter.getWidget(updateProvider.releases.first)];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Missed Exams
|
||||||
|
case FilterType.missedExams:
|
||||||
|
items = missed_exam_filter.getWidgets(timetableProvider.lessons);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterType.premium:
|
||||||
|
final now = DateTime.now();
|
||||||
|
final isWeekend = now.weekday == DateTime.saturday || now.weekday == DateTime.sunday;
|
||||||
|
items = [if (!premiumProvider.hasPremium && isWeekend) premium_filter.getWidget()];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget filterItemBuilder(BuildContext context, Animation<double> animation, Widget item, int index) {
|
||||||
|
final wrappedItem = SizeFadeTransition(
|
||||||
|
curve: Curves.easeInOutCubic,
|
||||||
|
animation: animation,
|
||||||
|
child: item,
|
||||||
|
);
|
||||||
|
return item is Panel
|
||||||
|
// Re-add & animate shadow
|
||||||
|
? AnimatedBuilder(
|
||||||
|
animation: animation,
|
||||||
|
child: wrappedItem,
|
||||||
|
builder: (context, child) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 12.0),
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
offset: const Offset(0, 21),
|
||||||
|
blurRadius: 23.0,
|
||||||
|
color: Theme.of(context).shadowColor.withOpacity(
|
||||||
|
Theme.of(context).shadowColor.opacity *
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: CurvedAnimation(parent: animation, curve: Curves.easeInOutCubic),
|
||||||
|
curve: const Interval(2 / 3, 1.0),
|
||||||
|
).value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: wrappedItem;
|
||||||
|
}
|
||||||
15
filcnaplo/lib/ui/filter/widgets/absences.dart
Normal file
15
filcnaplo/lib/ui/filter/widgets/absences.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/absence.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/absence/absence_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Absence> providerAbsences, {bool noExcused = false}) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
providerAbsences.where((a) => !noExcused || a.state != Justification.excused).forEach((absence) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: absence.id,
|
||||||
|
date: absence.date,
|
||||||
|
widget: mobile.AbsenceViewable(absence),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
return items;
|
||||||
|
}
|
||||||
24
filcnaplo/lib/ui/filter/widgets/certifications.dart
Normal file
24
filcnaplo/lib/ui/filter/widgets/certifications.dart
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/cretification/certification_card.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Grade> providerGrades) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var gradeType in GradeType.values) {
|
||||||
|
if ([GradeType.midYear, GradeType.unknown, GradeType.levelExam].contains(gradeType)) continue;
|
||||||
|
|
||||||
|
List<Grade> grades = providerGrades.where((grade) => grade.type == gradeType).toList();
|
||||||
|
if (grades.isNotEmpty) {
|
||||||
|
grades.sort((a, b) => -a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
items.add(DateWidget(
|
||||||
|
date: grades.first.date,
|
||||||
|
widget: mobile.CertificationCard(
|
||||||
|
grades,
|
||||||
|
gradeType: gradeType,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
15
filcnaplo/lib/ui/filter/widgets/events.dart
Normal file
15
filcnaplo/lib/ui/filter/widgets/events.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/event.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/event/event_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Event> providerEvents) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var event in providerEvents) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: event.id,
|
||||||
|
date: event.start,
|
||||||
|
widget: mobile.EventViewable(event),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
15
filcnaplo/lib/ui/filter/widgets/exams.dart
Normal file
15
filcnaplo/lib/ui/filter/widgets/exams.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/exam.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/exam/exam_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Exam> providerExams) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var exam in providerExams) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: exam.id,
|
||||||
|
date: exam.writeDate.year != 0 ? exam.writeDate : exam.date,
|
||||||
|
widget: mobile.ExamViewable(exam),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
41
filcnaplo/lib/ui/filter/widgets/grades.dart
Normal file
41
filcnaplo/lib/ui/filter/widgets/grades.dart
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo/utils/platform.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/grade/grade_viewable.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/grade/new_grades.dart' as mobile;
|
||||||
|
import 'package:filcnaplo_desktop_ui/common/widgets/grade/grade_viewable.dart' as desktop;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Grade> providerGrades, DateTime? lastSeenDate) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var grade in providerGrades) {
|
||||||
|
final surprise = (!(lastSeenDate != null && grade.date.isAfter(lastSeenDate)) || grade.value.value == 0);
|
||||||
|
if (grade.type == GradeType.midYear && surprise) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: grade.id,
|
||||||
|
date: grade.date,
|
||||||
|
widget: PlatformUtils.isMobile ? mobile.GradeViewable(grade) : desktop.GradeViewable(grade),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DateWidget> getNewWidgets(List<Grade> providerGrades, DateTime? lastSeenDate) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
List<Grade> newGrades = [];
|
||||||
|
for (var grade in providerGrades) {
|
||||||
|
final surprise = !(lastSeenDate != null && !grade.date.isAfter(lastSeenDate)) && grade.value.value != 0;
|
||||||
|
if (grade.type == GradeType.midYear && surprise) {
|
||||||
|
newGrades.add(grade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newGrades.sort((a, b) => a.date.compareTo(b.date));
|
||||||
|
if (newGrades.isNotEmpty) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: newGrades.last.id,
|
||||||
|
date: newGrades.last.date,
|
||||||
|
widget: mobile.NewGradesSurprise(newGrades),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
15
filcnaplo/lib/ui/filter/widgets/homework.dart
Normal file
15
filcnaplo/lib/ui/filter/widgets/homework.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/homework.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/homework/homework_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Homework> providerHomework) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var homework in providerHomework) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: homework.id,
|
||||||
|
date: homework.deadline.year != 0 ? homework.deadline : homework.date,
|
||||||
|
widget: mobile.HomeworkViewable(homework),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
15
filcnaplo/lib/ui/filter/widgets/lessons.dart
Normal file
15
filcnaplo/lib/ui/filter/widgets/lessons.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/lesson.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/lesson/changed_lesson_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Lesson> providerLessons) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
providerLessons.where((l) => l.isChanged && l.start.isAfter(DateTime.now())).forEach((lesson) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: lesson.id,
|
||||||
|
date: DateTime(lesson.date.year, lesson.date.month, lesson.date.day, lesson.start.hour, lesson.start.minute),
|
||||||
|
widget: mobile.ChangedLessonViewable(lesson),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
return items;
|
||||||
|
}
|
||||||
23
filcnaplo/lib/ui/filter/widgets/messages.dart
Normal file
23
filcnaplo/lib/ui/filter/widgets/messages.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/notes.dart' as note_filter;
|
||||||
|
import 'package:filcnaplo/ui/filter/widgets/events.dart' as event_filter;
|
||||||
|
import 'package:filcnaplo_kreta_api/models/event.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/message.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/note.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/message/message_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Message> providerMessages, List<Note> providerNotes, List<Event> providerEvents) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var message in providerMessages) {
|
||||||
|
if (message.type == MessageType.inbox) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: "${message.id}",
|
||||||
|
date: message.date,
|
||||||
|
widget: mobile.MessageViewable(message),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items.addAll(note_filter.getWidgets(providerNotes));
|
||||||
|
items.addAll(event_filter.getWidgets(providerEvents));
|
||||||
|
return items;
|
||||||
|
}
|
||||||
35
filcnaplo/lib/ui/filter/widgets/missed_exams.dart
Normal file
35
filcnaplo/lib/ui/filter/widgets/missed_exams.dart
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/lesson.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/missed_exam/missed_exam_viewable.dart';
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Lesson> providerLessons) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
List<Lesson> missedExams = [];
|
||||||
|
|
||||||
|
for (var lesson in providerLessons) {
|
||||||
|
final desc = lesson.description.toLowerCase().specialChars();
|
||||||
|
// Check if lesson description includes hints for an exam written during the lesson
|
||||||
|
if (!lesson.studentPresence &&
|
||||||
|
(lesson.exam != "" ||
|
||||||
|
desc.contains("dolgozat") ||
|
||||||
|
desc.contains("feleles") ||
|
||||||
|
desc.contains("temazaro") ||
|
||||||
|
desc.contains("szamonkeres") ||
|
||||||
|
desc == "tz") &&
|
||||||
|
!(desc.contains("felkeszules") || desc.contains("gyakorlas"))) {
|
||||||
|
missedExams.add(lesson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missedExams.isNotEmpty) {
|
||||||
|
missedExams.sort((a, b) => -a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
items.add(DateWidget(
|
||||||
|
date: missedExams.first.date,
|
||||||
|
widget: MissedExamViewable(missedExams),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
15
filcnaplo/lib/ui/filter/widgets/notes.dart
Normal file
15
filcnaplo/lib/ui/filter/widgets/notes.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/note.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/note/note_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
List<DateWidget> getWidgets(List<Note> providerNotes) {
|
||||||
|
List<DateWidget> items = [];
|
||||||
|
for (var note in providerNotes) {
|
||||||
|
items.add(DateWidget(
|
||||||
|
key: note.id,
|
||||||
|
date: note.date,
|
||||||
|
widget: mobile.NoteViewable(note),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
16
filcnaplo/lib/ui/filter/widgets/premium.dart
Normal file
16
filcnaplo/lib/ui/filter/widgets/premium.dart
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_premium/ui/mobile/premium/premium_banner_button.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
DateWidget getWidget() {
|
||||||
|
return DateWidget(
|
||||||
|
date: DateTime.now().add(const Duration(minutes: 1)),
|
||||||
|
widget: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(14.0),
|
||||||
|
child: const PremiumBannerButton(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
10
filcnaplo/lib/ui/filter/widgets/update.dart
Normal file
10
filcnaplo/lib/ui/filter/widgets/update.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:filcnaplo/models/release.dart';
|
||||||
|
import 'package:filcnaplo/ui/date_widget.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/update/update_viewable.dart' as mobile;
|
||||||
|
|
||||||
|
DateWidget getWidget(Release providerRelease) {
|
||||||
|
return DateWidget(
|
||||||
|
date: DateTime.now(),
|
||||||
|
widget: mobile.UpdateViewable(providerRelease),
|
||||||
|
);
|
||||||
|
}
|
||||||
255
filcnaplo/lib/ui/widgets/grade/grade_tile.dart
Normal file
255
filcnaplo/lib/ui/widgets/grade/grade_tile.dart
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||||
|
import 'package:filcnaplo/helpers/subject.dart';
|
||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/pages/grades/calculator/grade_calculator_provider.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/pages/grades/subject_grades_container.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class GradeTile extends StatelessWidget {
|
||||||
|
const GradeTile(this.grade, {Key? key, this.onTap, this.padding}) : super(key: key);
|
||||||
|
|
||||||
|
final Grade grade;
|
||||||
|
final void Function()? onTap;
|
||||||
|
final EdgeInsetsGeometry? padding;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String title;
|
||||||
|
String subtitle;
|
||||||
|
EdgeInsets leadingPadding = EdgeInsets.zero;
|
||||||
|
bool isSubjectView = SubjectGradesContainer.of(context) != null;
|
||||||
|
String subjectName = grade.subject.name.capital();
|
||||||
|
String modeDescription = grade.mode.description.capital();
|
||||||
|
String description = grade.description.capital();
|
||||||
|
|
||||||
|
GradeCalculatorProvider calculatorProvider = Provider.of<GradeCalculatorProvider>(context, listen: false);
|
||||||
|
|
||||||
|
// Test order:
|
||||||
|
// description
|
||||||
|
// mode
|
||||||
|
// value name
|
||||||
|
if (grade.type == GradeType.midYear || grade.type == GradeType.ghost) {
|
||||||
|
if (grade.description != "") {
|
||||||
|
title = description;
|
||||||
|
} else {
|
||||||
|
title = modeDescription != "" ? modeDescription : grade.value.valueName.split("(")[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
title = subjectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test order:
|
||||||
|
// subject name
|
||||||
|
// mode + weight != 100
|
||||||
|
if (grade.type == GradeType.midYear) {
|
||||||
|
subtitle = isSubjectView
|
||||||
|
? description != ""
|
||||||
|
? modeDescription
|
||||||
|
: ""
|
||||||
|
: subjectName;
|
||||||
|
} else {
|
||||||
|
subtitle = grade.value.valueName.split("(")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subtitle != "") leadingPadding = const EdgeInsets.only(top: 2.0);
|
||||||
|
|
||||||
|
return Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: Padding(
|
||||||
|
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: ListTile(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
contentPadding: isSubjectView
|
||||||
|
? grade.type != GradeType.ghost
|
||||||
|
? const EdgeInsets.symmetric(horizontal: 12.0)
|
||||||
|
: const EdgeInsets.only(left: 12.0, right: 4.0)
|
||||||
|
: const EdgeInsets.only(left: 8.0, right: 12.0),
|
||||||
|
onTap: onTap,
|
||||||
|
// onLongPress: kDebugMode ? () => log(jsonEncode(grade.json)) : null,
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||||
|
leading: isSubjectView
|
||||||
|
? GradeValueWidget(grade.value)
|
||||||
|
: SizedBox(
|
||||||
|
width: 44,
|
||||||
|
height: 44,
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: leadingPadding,
|
||||||
|
child: Icon(
|
||||||
|
SubjectIcon.resolveVariant(subject: grade.subject, context: context),
|
||||||
|
size: 28.0,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.75),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
title,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
subtitle: subtitle != ""
|
||||||
|
? Text(
|
||||||
|
subtitle,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
trailing: isSubjectView
|
||||||
|
? grade.type != GradeType.ghost
|
||||||
|
? Text(grade.date.format(context), style: const TextStyle(fontWeight: FontWeight.w500))
|
||||||
|
: IconButton(
|
||||||
|
splashRadius: 24.0,
|
||||||
|
icon: Icon(FeatherIcons.trash2, color: AppColors.of(context).red),
|
||||||
|
onPressed: () {
|
||||||
|
calculatorProvider.removeGrade(grade);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: GradeValueWidget(grade.value),
|
||||||
|
minLeadingWidth: isSubjectView ? 32.0 : 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GradeValueWidget extends StatelessWidget {
|
||||||
|
const GradeValueWidget(
|
||||||
|
this.value, {
|
||||||
|
Key? key,
|
||||||
|
this.size = 38.0,
|
||||||
|
this.fill = false,
|
||||||
|
this.contrast = false,
|
||||||
|
this.shadow = false,
|
||||||
|
this.outline = false,
|
||||||
|
this.complemented = false,
|
||||||
|
this.nocolor = false,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final GradeValue value;
|
||||||
|
final double size;
|
||||||
|
final bool fill;
|
||||||
|
final bool contrast;
|
||||||
|
final bool shadow;
|
||||||
|
final bool outline;
|
||||||
|
final bool complemented;
|
||||||
|
final bool nocolor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
GradeValue value = Provider.of<SettingsProvider>(context).goodStudent ? GradeValue(5, "Példás", "Példás", this.value.weight) : this.value;
|
||||||
|
bool isSubjectView = SubjectGradesContainer.of(context) != null;
|
||||||
|
|
||||||
|
Color color = gradeColor(context: context, value: value.value, nocolor: nocolor);
|
||||||
|
Widget valueText;
|
||||||
|
final percentage = value.percentage;
|
||||||
|
|
||||||
|
if (percentage) {
|
||||||
|
double multiplier = 1.0;
|
||||||
|
|
||||||
|
if (isSubjectView) multiplier = 0.75;
|
||||||
|
|
||||||
|
valueText = Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
text: value.value.toString(),
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: "\n%",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.w700, fontSize: size / 2.5 * multiplier, height: 0.7),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
style: TextStyle(fontWeight: FontWeight.w700, fontSize: size / 1 * multiplier, height: 1),
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
);
|
||||||
|
} else if (value.valueName.toLowerCase().specialChars() == 'nem irt') {
|
||||||
|
valueText = const Icon(FeatherIcons.slash);
|
||||||
|
} else {
|
||||||
|
valueText = Stack(alignment: Alignment.topRight, children: [
|
||||||
|
Transform.translate(
|
||||||
|
offset: (value.weight >= 200) ? const Offset(2, 1.5) : Offset.zero,
|
||||||
|
child: Text(
|
||||||
|
value.value.toString(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: value.weight == 50 ? FontWeight.w600 : FontWeight.bold,
|
||||||
|
fontSize: size,
|
||||||
|
color: contrast ? Colors.white : color,
|
||||||
|
shadows: [
|
||||||
|
if (value.weight >= 200)
|
||||||
|
Shadow(
|
||||||
|
color: (contrast ? Colors.white : color).withOpacity(.4),
|
||||||
|
offset: const Offset(-4, -3),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (complemented)
|
||||||
|
Transform.translate(
|
||||||
|
offset: const Offset(9, 1),
|
||||||
|
child: Text(
|
||||||
|
"*",
|
||||||
|
style: TextStyle(fontSize: size / 1.6, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fill
|
||||||
|
? Container(
|
||||||
|
width: size * 1.4,
|
||||||
|
height: size * 1.4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color.withOpacity(contrast ? 1.0 : .25),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
boxShadow: [
|
||||||
|
if (shadow)
|
||||||
|
BoxShadow(
|
||||||
|
color: color,
|
||||||
|
blurRadius: 62.0,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Center(child: valueText),
|
||||||
|
)
|
||||||
|
: valueText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color gradeColor({required BuildContext context, required num value, bool nocolor = false}) {
|
||||||
|
int valueInt = 0;
|
||||||
|
|
||||||
|
var settings = Provider.of<SettingsProvider>(context, listen: false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (value > value.floor() + settings.rounding / 10) {
|
||||||
|
valueInt = value.ceil();
|
||||||
|
} else {
|
||||||
|
valueInt = value.floor();
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
if (nocolor) return AppColors.of(context).text;
|
||||||
|
|
||||||
|
switch (valueInt) {
|
||||||
|
case 5:
|
||||||
|
return settings.gradeColors[4];
|
||||||
|
case 4:
|
||||||
|
return settings.gradeColors[3];
|
||||||
|
case 3:
|
||||||
|
return settings.gradeColors[2];
|
||||||
|
case 2:
|
||||||
|
return settings.gradeColors[1];
|
||||||
|
case 1:
|
||||||
|
return settings.gradeColors[0];
|
||||||
|
default:
|
||||||
|
return AppColors.of(context).text;
|
||||||
|
}
|
||||||
|
}
|
||||||
308
filcnaplo/lib/ui/widgets/lesson/lesson_tile.dart
Normal file
308
filcnaplo/lib/ui/widgets/lesson/lesson_tile.dart
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
import 'package:filcnaplo_kreta_api/providers/exam_provider.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/providers/homework_provider.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/exam.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/homework.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/lesson.dart';
|
||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/exam/exam_view.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/widgets/homework/homework_view.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'lesson_tile.i18n.dart';
|
||||||
|
|
||||||
|
class LessonTile extends StatelessWidget {
|
||||||
|
const LessonTile(this.lesson, {Key? key, this.onTap, this.swapDesc = false}) : super(key: key);
|
||||||
|
|
||||||
|
final Lesson lesson;
|
||||||
|
final bool swapDesc;
|
||||||
|
final void Function()? onTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<Widget> subtiles = [];
|
||||||
|
|
||||||
|
Color accent = Theme.of(context).colorScheme.secondary;
|
||||||
|
bool fill = false;
|
||||||
|
bool fillLeading = false;
|
||||||
|
String lessonIndexTrailing = "";
|
||||||
|
|
||||||
|
// Only put a trailing . if its a digit
|
||||||
|
if (RegExp(r'\d').hasMatch(lesson.lessonIndex)) lessonIndexTrailing = ".";
|
||||||
|
|
||||||
|
var now = DateTime.now();
|
||||||
|
if (lesson.start.isBefore(now) && lesson.end.isAfter(now) && lesson.status?.name != "Elmaradt") {
|
||||||
|
fillLeading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lesson.substituteTeacher != "") {
|
||||||
|
fill = true;
|
||||||
|
accent = AppColors.of(context).yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lesson.status?.name == "Elmaradt") {
|
||||||
|
fill = true;
|
||||||
|
accent = AppColors.of(context).red;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lesson.isEmpty) {
|
||||||
|
accent = AppColors.of(context).text.withOpacity(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lesson.studentPresence) {
|
||||||
|
subtiles.add(LessonSubtile(
|
||||||
|
type: LessonSubtileType.absence,
|
||||||
|
title: "absence".i18n,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lesson.homeworkId != "") {
|
||||||
|
Homework homework = Provider.of<HomeworkProvider>(context, listen: false)
|
||||||
|
.homework
|
||||||
|
.firstWhere((h) => h.id == lesson.homeworkId, orElse: () => Homework.fromJson({}));
|
||||||
|
|
||||||
|
if (homework.id != "") {
|
||||||
|
subtiles.add(LessonSubtile(
|
||||||
|
type: LessonSubtileType.homework,
|
||||||
|
title: homework.content,
|
||||||
|
onPressed: () => HomeworkView.show(homework, context: context),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lesson.exam != "") {
|
||||||
|
Exam exam = Provider.of<ExamProvider>(context, listen: false).exams.firstWhere((t) => t.id == lesson.exam, orElse: () => Exam.fromJson({}));
|
||||||
|
if (exam.id != "") {
|
||||||
|
subtiles.add(LessonSubtile(
|
||||||
|
type: LessonSubtileType.exam,
|
||||||
|
title: exam.description != "" ? exam.description : exam.mode?.description ?? "exam".i18n,
|
||||||
|
onPressed: () => ExamView.show(exam, context: context),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String description = '';
|
||||||
|
String room = '';
|
||||||
|
|
||||||
|
final cleanDesc = lesson.description.specialChars().toLowerCase().replaceAll(lesson.subject.name.specialChars().toLowerCase(), '');
|
||||||
|
|
||||||
|
if (!swapDesc) {
|
||||||
|
if (cleanDesc != "") {
|
||||||
|
description = lesson.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changed lesson Description
|
||||||
|
if (lesson.isChanged) {
|
||||||
|
if (lesson.status?.name == "Elmaradt") {
|
||||||
|
description = 'cancelled'.i18n;
|
||||||
|
} else if (lesson.substituteTeacher != "") {
|
||||||
|
description = 'substitution'.i18n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
room = lesson.room.replaceAll("_", " ");
|
||||||
|
} else {
|
||||||
|
description = lesson.room.replaceAll("_", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 2.0),
|
||||||
|
child: Material(
|
||||||
|
color: fill ? accent.withOpacity(.25) : Colors.transparent,
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
child: Visibility(
|
||||||
|
visible: lesson.subject.id != '' || lesson.isEmpty,
|
||||||
|
replacement: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 6.0),
|
||||||
|
child: PanelTitle(title: Text(lesson.name)),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: subtiles.isEmpty ? 0.0 : 12.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
minVerticalPadding: 12.0,
|
||||||
|
dense: true,
|
||||||
|
onTap: onTap,
|
||||||
|
// onLongPress: kDebugMode ? () => log(jsonEncode(lesson.json)) : null,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
||||||
|
title: Text(
|
||||||
|
!lesson.isEmpty ? lesson.subject.name.capital() : "empty".i18n,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 15.5,
|
||||||
|
color: AppColors.of(context).text.withOpacity(!lesson.isEmpty ? 1.0 : 0.5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: description != ""
|
||||||
|
? Text(
|
||||||
|
description,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 14.0,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
softWrap: false,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
minLeadingWidth: 34.0,
|
||||||
|
leading: AspectRatio(
|
||||||
|
aspectRatio: 1,
|
||||||
|
child: Center(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
lesson.lessonIndex + lessonIndexTrailing,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 30.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: accent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Current lesson indicator
|
||||||
|
Transform.translate(
|
||||||
|
offset: const Offset(-12.0, -2.0),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: fillLeading ? Theme.of(context).colorScheme.secondary.withOpacity(.3) : const Color(0x00000000),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
boxShadow: [
|
||||||
|
if (fillLeading)
|
||||||
|
BoxShadow(
|
||||||
|
color: Theme.of(context).colorScheme.secondary.withOpacity(.25),
|
||||||
|
blurRadius: 6.0,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
|
width: 4.0,
|
||||||
|
height: double.infinity,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: !lesson.isEmpty
|
||||||
|
? Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (!swapDesc)
|
||||||
|
SizedBox(
|
||||||
|
width: 52.0,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 6.0),
|
||||||
|
child: Text(
|
||||||
|
room,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 2,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.75),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
// Fix alignment hack
|
||||||
|
const Opacity(opacity: 0, child: Text("EE:EE")),
|
||||||
|
Text(
|
||||||
|
"${DateFormat("H:mm").format(lesson.start)}\n${DateFormat("H:mm").format(lesson.end)}",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.9),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Homework & Exams
|
||||||
|
...subtiles,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LessonSubtileType { homework, exam, absence }
|
||||||
|
|
||||||
|
class LessonSubtile extends StatelessWidget {
|
||||||
|
const LessonSubtile({Key? key, this.onPressed, required this.title, required this.type}) : super(key: key);
|
||||||
|
|
||||||
|
final Function()? onPressed;
|
||||||
|
final String title;
|
||||||
|
final LessonSubtileType type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
IconData icon;
|
||||||
|
Color iconColor = AppColors.of(context).text;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case LessonSubtileType.absence:
|
||||||
|
icon = FeatherIcons.slash;
|
||||||
|
iconColor = AppColors.of(context).red;
|
||||||
|
break;
|
||||||
|
case LessonSubtileType.exam:
|
||||||
|
icon = FeatherIcons.file;
|
||||||
|
break;
|
||||||
|
case LessonSubtileType.homework:
|
||||||
|
icon = FeatherIcons.home;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onPressed,
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 30.0,
|
||||||
|
child: Icon(icon, color: iconColor.withOpacity(.75), size: 20.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 20.0),
|
||||||
|
child: Text(
|
||||||
|
title.escapeHtml(),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(fontWeight: FontWeight.w500, color: AppColors.of(context).text.withOpacity(.65)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
filcnaplo/lib/ui/widgets/lesson/lesson_tile.i18n.dart
Normal file
33
filcnaplo/lib/ui/widgets/lesson/lesson_tile.i18n.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:i18n_extension/i18n_extension.dart';
|
||||||
|
|
||||||
|
extension Localization on String {
|
||||||
|
static final _t = Translations.byLocale("hu_hu") +
|
||||||
|
{
|
||||||
|
"en_en": {
|
||||||
|
"empty": "Free period",
|
||||||
|
"cancelled": "Cancelled",
|
||||||
|
"substitution": "Substituted",
|
||||||
|
"absence": "You were absent on this lesson",
|
||||||
|
"exam": "Exam"
|
||||||
|
},
|
||||||
|
"hu_hu": {
|
||||||
|
"empty": "Lyukasóra",
|
||||||
|
"cancelled": "Elmarad",
|
||||||
|
"substitution": "Helyettesítés",
|
||||||
|
"absence": "Hiányoztál ezen az órán",
|
||||||
|
"exam": "Dolgozat"
|
||||||
|
},
|
||||||
|
"de_de": {
|
||||||
|
"empty": "Springstunde",
|
||||||
|
"cancelled": "Abgesagte",
|
||||||
|
"substitution": "Vertretene",
|
||||||
|
"absence": "Sie waren in dieser Lektion nicht anwesend",
|
||||||
|
"exam": "Prüfung"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
String get i18n => localize(this, _t);
|
||||||
|
String fill(List<Object> params) => localizeFill(this, params);
|
||||||
|
String plural(int value) => localizePlural(value, this, _t);
|
||||||
|
String version(Object modifier) => localizeVersion(modifier, this, _t);
|
||||||
|
}
|
||||||
78
filcnaplo/lib/ui/widgets/message/message_tile.dart
Normal file
78
filcnaplo/lib/ui/widgets/message/message_tile.dart
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import 'package:filcnaplo/models/settings.dart';
|
||||||
|
import 'package:filcnaplo/theme/colors/colors.dart';
|
||||||
|
import 'package:filcnaplo/utils/color.dart';
|
||||||
|
import 'package:filcnaplo/utils/format.dart';
|
||||||
|
import 'package:filcnaplo_kreta_api/models/message.dart';
|
||||||
|
import 'package:filcnaplo_mobile_ui/common/profile_image/profile_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class MessageTile extends StatelessWidget {
|
||||||
|
const MessageTile(
|
||||||
|
this.message, {
|
||||||
|
Key? key,
|
||||||
|
this.messages,
|
||||||
|
this.padding,
|
||||||
|
this.onTap,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Message message;
|
||||||
|
final List<Message>? messages;
|
||||||
|
final EdgeInsetsGeometry? padding;
|
||||||
|
final Function()? onTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: Padding(
|
||||||
|
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
child: ListTile(
|
||||||
|
onTap: onTap,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
contentPadding: const EdgeInsets.only(left: 8.0, right: 4.0),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14.0)),
|
||||||
|
leading: !Provider.of<SettingsProvider>(context, listen: false).presentationMode
|
||||||
|
? ProfileImage(
|
||||||
|
name: message.author,
|
||||||
|
radius: 22.0,
|
||||||
|
backgroundColor: ColorUtils.stringToColor(message.author),
|
||||||
|
)
|
||||||
|
: ProfileImage(
|
||||||
|
name: "Béla",
|
||||||
|
radius: 22.0,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
title: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
!Provider.of<SettingsProvider>(context, listen: false).presentationMode ? message.author : "Béla",
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 15.5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (message.attachments.isNotEmpty) const Icon(FeatherIcons.paperclip, size: 16.0)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
message.subject,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 14.0),
|
||||||
|
),
|
||||||
|
trailing: Text(
|
||||||
|
message.date.format(context),
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 14.0,
|
||||||
|
color: AppColors.of(context).text.withOpacity(.75),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:filcnaplo_kreta_api/models/week.dart';
|
import 'package:filcnaplo_kreta_api/models/week.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@@ -29,6 +31,11 @@ extension StringFormatUtils on String {
|
|||||||
var document = parse(htmlString);
|
var document = parse(htmlString);
|
||||||
return document.body?.text.trim() ?? "";
|
return document.body?.text.trim() ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String limit(int max) {
|
||||||
|
if (length <= max) return this;
|
||||||
|
return '${substring(0, min(length, 14))}…';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DateFormatUtils on DateTime {
|
extension DateFormatUtils on DateTime {
|
||||||
|
|||||||
6
filcnaplo/lib/utils/platform.dart
Normal file
6
filcnaplo/lib/utils/platform.dart
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
class PlatformUtils {
|
||||||
|
static bool get isDesktop => Platform.isWindows || Platform.isMacOS || Platform.isLinux;
|
||||||
|
static bool get isMobile => !isDesktop;
|
||||||
|
}
|
||||||
@@ -6,9 +6,17 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <dynamic_color/dynamic_color_plugin.h>
|
||||||
|
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
|
||||||
|
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) flutter_acrylic_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterAcrylicPlugin");
|
||||||
|
flutter_acrylic_plugin_register_with_registrar(flutter_acrylic_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
dynamic_color
|
||||||
|
flutter_acrylic
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
7
filcnaplo/macos/.gitignore
vendored
Normal file
7
filcnaplo/macos/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Flutter-related
|
||||||
|
**/Flutter/ephemeral/
|
||||||
|
**/Pods/
|
||||||
|
|
||||||
|
# Xcode-related
|
||||||
|
**/dgph
|
||||||
|
**/xcuserdata/
|
||||||
2
filcnaplo/macos/Flutter/Flutter-Debug.xcconfig
Normal file
2
filcnaplo/macos/Flutter/Flutter-Debug.xcconfig
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||||
2
filcnaplo/macos/Flutter/Flutter-Release.xcconfig
Normal file
2
filcnaplo/macos/Flutter/Flutter-Release.xcconfig
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
|
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||||
24
filcnaplo/macos/Flutter/GeneratedPluginRegistrant.swift
Normal file
24
filcnaplo/macos/Flutter/GeneratedPluginRegistrant.swift
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
import FlutterMacOS
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
import connectivity_plus
|
||||||
|
import dynamic_color
|
||||||
|
import flutter_acrylic
|
||||||
|
import path_provider_macos
|
||||||
|
import share_plus_macos
|
||||||
|
import sqflite
|
||||||
|
import url_launcher_macos
|
||||||
|
|
||||||
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||||
|
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||||
|
FlutterAcrylicPlugin.register(with: registry.registrar(forPlugin: "FlutterAcrylicPlugin"))
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||||
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
}
|
||||||
40
filcnaplo/macos/Podfile
Normal file
40
filcnaplo/macos/Podfile
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
platform :osx, '10.11'
|
||||||
|
|
||||||
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|
||||||
|
project 'Runner', {
|
||||||
|
'Debug' => :debug,
|
||||||
|
'Profile' => :release,
|
||||||
|
'Release' => :release,
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutter_root
|
||||||
|
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||||
|
unless File.exist?(generated_xcode_build_settings_path)
|
||||||
|
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||||
|
end
|
||||||
|
|
||||||
|
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||||
|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||||
|
return matches[1].strip if matches
|
||||||
|
end
|
||||||
|
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||||
|
end
|
||||||
|
|
||||||
|
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||||
|
|
||||||
|
flutter_macos_podfile_setup
|
||||||
|
|
||||||
|
target 'Runner' do
|
||||||
|
use_frameworks!
|
||||||
|
use_modular_headers!
|
||||||
|
|
||||||
|
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||||
|
end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
flutter_additional_macos_build_settings(target)
|
||||||
|
end
|
||||||
|
end
|
||||||
83
filcnaplo/macos/Podfile.lock
Normal file
83
filcnaplo/macos/Podfile.lock
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
PODS:
|
||||||
|
- connectivity_plus_macos (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- ReachabilitySwift
|
||||||
|
- dynamic_color (0.0.2):
|
||||||
|
- FlutterMacOS
|
||||||
|
- flutter_acrylic (0.1.0):
|
||||||
|
- FlutterMacOS
|
||||||
|
- flutter_local_notifications (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- FlutterMacOS (1.0.0)
|
||||||
|
- FMDB (2.7.5):
|
||||||
|
- FMDB/standard (= 2.7.5)
|
||||||
|
- FMDB/standard (2.7.5)
|
||||||
|
- path_provider_macos (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- ReachabilitySwift (5.0.0)
|
||||||
|
- share_plus_macos (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- shared_preferences_macos (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
- sqflite (0.0.2):
|
||||||
|
- FlutterMacOS
|
||||||
|
- FMDB (>= 2.7.5)
|
||||||
|
- url_launcher_macos (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- connectivity_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos`)
|
||||||
|
- dynamic_color (from `Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos`)
|
||||||
|
- flutter_acrylic (from `Flutter/ephemeral/.symlinks/plugins/flutter_acrylic/macos`)
|
||||||
|
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
|
||||||
|
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||||
|
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
|
||||||
|
- share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`)
|
||||||
|
- shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`)
|
||||||
|
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
|
||||||
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- FMDB
|
||||||
|
- ReachabilitySwift
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
connectivity_plus_macos:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos
|
||||||
|
dynamic_color:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/dynamic_color/macos
|
||||||
|
flutter_acrylic:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/flutter_acrylic/macos
|
||||||
|
flutter_local_notifications:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos
|
||||||
|
FlutterMacOS:
|
||||||
|
:path: Flutter/ephemeral
|
||||||
|
path_provider_macos:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
|
||||||
|
share_plus_macos:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos
|
||||||
|
shared_preferences_macos:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos
|
||||||
|
sqflite:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
|
||||||
|
url_launcher_macos:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308
|
||||||
|
dynamic_color: 394d6a888650f8534e029b27d2f8bc5c64e44008
|
||||||
|
flutter_acrylic: c3df24ae52ab6597197837ce59ef2a8542640c17
|
||||||
|
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
|
||||||
|
FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
|
||||||
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19
|
||||||
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
|
share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4
|
||||||
|
shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727
|
||||||
|
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
|
||||||
|
url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
|
||||||
|
|
||||||
|
COCOAPODS: 1.11.3
|
||||||
669
filcnaplo/macos/Runner.xcodeproj/project.pbxproj
Normal file
669
filcnaplo/macos/Runner.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,669 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 51;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXAggregateTarget section */
|
||||||
|
33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
|
||||||
|
isa = PBXAggregateTarget;
|
||||||
|
buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
|
||||||
|
buildPhases = (
|
||||||
|
33CC111E2044C6BF0003C045 /* ShellScript */,
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "Flutter Assemble";
|
||||||
|
productName = FLX;
|
||||||
|
};
|
||||||
|
/* End PBXAggregateTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
|
||||||
|
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
|
||||||
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||||
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||||
|
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||||
|
43DE217EE63035454211B258 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BB026B00EBE728C695C538A /* Pods_Runner.framework */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 33CC111A2044C6BA0003C045;
|
||||||
|
remoteInfo = FLX;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
33CC110E2044A8840003C045 /* Bundle Framework */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
name = "Bundle Framework";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
||||||
|
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
||||||
|
33CC10ED2044A3C60003C045 /* Felt Diary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Felt Diary.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||||
|
33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = "<group>"; };
|
||||||
|
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = "<group>"; };
|
||||||
|
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
|
||||||
|
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
||||||
|
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||||
|
72E0977D2D8959666A33F54C /* 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 = "<group>"; };
|
||||||
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||||
|
8BB026B00EBE728C695C538A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
|
9C848561CA407DAFCC1F5699 /* 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 = "<group>"; };
|
||||||
|
C200D9112D0A790C324733AA /* 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 = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
33CC10EA2044A3C60003C045 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
43DE217EE63035454211B258 /* Pods_Runner.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
33BA886A226E78AF003329D5 /* Configs */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33E5194F232828860026EE4D /* AppInfo.xcconfig */,
|
||||||
|
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||||
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||||
|
333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Configs;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CC10E42044A3C60003C045 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33FAB671232836740065AC1E /* Runner */,
|
||||||
|
33CEB47122A05771004F2AC0 /* Flutter */,
|
||||||
|
33CC10EE2044A3C60003C045 /* Products */,
|
||||||
|
51085A7CB06D107E9E0B55D2 /* Pods */,
|
||||||
|
D1EA9707C367C55447080BD3 /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CC10EE2044A3C60003C045 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33CC10ED2044A3C60003C045 /* Felt Diary.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CC11242044D66E0003C045 /* Resources */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33CC10F22044A3C60003C045 /* Assets.xcassets */,
|
||||||
|
33CC10F42044A3C60003C045 /* MainMenu.xib */,
|
||||||
|
33CC10F72044A3C60003C045 /* Info.plist */,
|
||||||
|
);
|
||||||
|
name = Resources;
|
||||||
|
path = ..;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33CEB47122A05771004F2AC0 /* Flutter */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
|
||||||
|
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
|
||||||
|
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
|
||||||
|
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Flutter;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
33FAB671232836740065AC1E /* Runner */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
33CC10F02044A3C60003C045 /* AppDelegate.swift */,
|
||||||
|
33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
|
||||||
|
33E51913231747F40026EE4D /* DebugProfile.entitlements */,
|
||||||
|
33E51914231749380026EE4D /* Release.entitlements */,
|
||||||
|
33CC11242044D66E0003C045 /* Resources */,
|
||||||
|
33BA886A226E78AF003329D5 /* Configs */,
|
||||||
|
);
|
||||||
|
path = Runner;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
51085A7CB06D107E9E0B55D2 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
72E0977D2D8959666A33F54C /* Pods-Runner.debug.xcconfig */,
|
||||||
|
C200D9112D0A790C324733AA /* Pods-Runner.release.xcconfig */,
|
||||||
|
9C848561CA407DAFCC1F5699 /* Pods-Runner.profile.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D1EA9707C367C55447080BD3 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8BB026B00EBE728C695C538A /* Pods_Runner.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
33CC10EC2044A3C60003C045 /* Runner */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
|
buildPhases = (
|
||||||
|
FD4539A7C90013601C734851 /* [CP] Check Pods Manifest.lock */,
|
||||||
|
33CC10E92044A3C60003C045 /* Sources */,
|
||||||
|
33CC10EA2044A3C60003C045 /* Frameworks */,
|
||||||
|
33CC10EB2044A3C60003C045 /* Resources */,
|
||||||
|
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||||
|
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||||
|
558B4163B66FBD35BF611538 /* [CP] Embed Pods Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
33CC11202044C79F0003C045 /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = Runner;
|
||||||
|
productName = Runner;
|
||||||
|
productReference = 33CC10ED2044A3C60003C045 /* Felt Diary.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
33CC10E52044A3C60003C045 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastSwiftUpdateCheck = 0920;
|
||||||
|
LastUpgradeCheck = 1400;
|
||||||
|
ORGANIZATIONNAME = "";
|
||||||
|
TargetAttributes = {
|
||||||
|
33CC10EC2044A3C60003C045 = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
LastSwiftMigration = 1100;
|
||||||
|
SystemCapabilities = {
|
||||||
|
com.apple.Sandbox = {
|
||||||
|
enabled = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
33CC111A2044C6BA0003C045 = {
|
||||||
|
CreatedOnToolsVersion = 9.2;
|
||||||
|
ProvisioningStyle = Manual;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
|
||||||
|
compatibilityVersion = "Xcode 9.3";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 33CC10E42044A3C60003C045;
|
||||||
|
productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
33CC10EC2044A3C60003C045 /* Runner */,
|
||||||
|
33CC111A2044C6BA0003C045 /* Flutter Assemble */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
33CC10EB2044A3C60003C045 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
|
||||||
|
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
|
||||||
|
};
|
||||||
|
33CC111E2044C6BF0003C045 /* ShellScript */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
Flutter/ephemeral/FlutterInputs.xcfilelist,
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
Flutter/ephemeral/tripwire,
|
||||||
|
);
|
||||||
|
outputFileListPaths = (
|
||||||
|
Flutter/ephemeral/FlutterOutputs.xcfilelist,
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||||
|
};
|
||||||
|
558B4163B66FBD35BF611538 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
FD4539A7C90013601C734851 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
33CC10E92044A3C60003C045 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
|
||||||
|
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
|
||||||
|
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
|
||||||
|
targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
33CC10F52044A3C60003C045 /* Base */,
|
||||||
|
);
|
||||||
|
name = MainMenu.xib;
|
||||||
|
path = Runner;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
338D0CE9231458BD00FA5F75 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
338D0CEA231458BD00FA5F75 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Filc Napló";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
NEW_SETTING = "";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.filcnaplo;
|
||||||
|
PRODUCT_NAME = "Felt Diary";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
338D0CEB231458BD00FA5F75 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
33CC10F92044A3C60003C045 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
33CC10FA2044A3C60003C045 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
33CC10FC2044A3C60003C045 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Filc Napló";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
NEW_SETTING = "";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.filcnaplo;
|
||||||
|
PRODUCT_NAME = "Felt Diary";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
33CC10FD2044A3C60003C045 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
DEVELOPMENT_TEAM = MYUTW2GF6J;
|
||||||
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Filc Napló";
|
||||||
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
NEW_SETTING = "";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = hu.filc.filcnaplo;
|
||||||
|
PRODUCT_NAME = "Felt Diary";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
33CC111C2044C6BA0003C045 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
33CC111D2044C6BA0003C045 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
33CC10F92044A3C60003C045 /* Debug */,
|
||||||
|
33CC10FA2044A3C60003C045 /* Release */,
|
||||||
|
338D0CE9231458BD00FA5F75 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
33CC10FC2044A3C60003C045 /* Debug */,
|
||||||
|
33CC10FD2044A3C60003C045 /* Release */,
|
||||||
|
338D0CEA231458BD00FA5F75 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
33CC111C2044C6BA0003C045 /* Debug */,
|
||||||
|
33CC111D2044C6BA0003C045 /* Release */,
|
||||||
|
338D0CEB231458BD00FA5F75 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 33CC10E52044A3C60003C045 /* Project object */;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1400"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Felt Diary.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Felt Diary.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Felt Diary.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Profile"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
|
||||||
|
BuildableName = "Felt Diary.app"
|
||||||
|
BlueprintName = "Runner"
|
||||||
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
10
filcnaplo/macos/Runner.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
filcnaplo/macos/Runner.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "group:Runner.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
9
filcnaplo/macos/Runner/AppDelegate.swift
Normal file
9
filcnaplo/macos/Runner/AppDelegate.swift
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import Cocoa
|
||||||
|
import FlutterMacOS
|
||||||
|
|
||||||
|
@NSApplicationMain
|
||||||
|
class AppDelegate: FlutterAppDelegate {
|
||||||
|
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"size" : "16x16",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_16.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "16x16",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_32.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "32x32",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_32.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "32x32",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_64.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "128x128",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_128.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "128x128",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_256.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "256x256",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_256.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "256x256",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_512.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "512x512",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_512.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "512x512",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "app_icon_1024.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user