Compare commits

..

No commits in common. "master" and "5.0.0" have entirely different histories.

348 changed files with 10292 additions and 15058 deletions

9
.gitignore vendored
View File

@ -12,10 +12,10 @@ refilc/build/
refilc/android/key.properties
refilc/android/debug.keystore
# refilc_desktop_ui/.flutter-plugins
# refilc_desktop_ui/.flutter-plugins-dependencies
# refilc_desktop_ui/pubspec.lock
# refilc_desktop_ui/.dart_tool/
refilc_desktop_ui/.flutter-plugins
refilc_desktop_ui/.flutter-plugins-dependencies
refilc_desktop_ui/pubspec.lock
refilc_desktop_ui/.dart_tool/
refilc_kreta_api/.flutter-plugins
refilc_kreta_api/.flutter-plugins-dependencies
@ -37,7 +37,6 @@ refilc_mobile_ui/.dart_tool/
.idea
.gitmodules
.gradle
.kotlin
refilc/.DS_Store
.DS_Store

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "naplo-plus"]
path = refilc_plus
url = git@github.com:refilc/naplo-plus.git

1286
.idea/libraries/Dart_Packages.xml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,25 @@
<component name="libraryTable">
<library name="Dart SDK">
<CLASSES>
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/async" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/cli" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/concurrent" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/core" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/ffi" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/html" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/io" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/js" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/js_interop" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/js_interop_unsafe" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/js_util" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/math" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/svg" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/typed_data" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/web_audio" />
<root url="file://P:/flutter/bin/cache/dart-sdk/lib/web_gl" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/async" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/cli" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/core" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/ffi" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/html" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/io" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/js" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/js_util" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/math" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/svg" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/typed_data" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/web_audio" />
<root url="file:///opt/flutter/bin/cache/dart-sdk/lib/web_gl" />
</CLASSES>
<JAVADOC />
<SOURCES />

1
.idea/misc.xml generated
View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Android API 33, extension level 3 Platform" project-jdk-type="Android SDK" />
</project>

13
.idea/naplo.iml generated
View File

@ -60,21 +60,8 @@
<excludeFolder url="file://$MODULE_DIR$/filcnaplo/linux/flutter/ephemeral/.plugin_symlinks/flutter_acrylic/build" />
<excludeFolder url="file://$MODULE_DIR$/filcnaplo/linux/flutter/ephemeral/.plugin_symlinks/flutter_acrylic/.pub" />
<excludeFolder url="file://$MODULE_DIR$/filcnaplo/linux/flutter/ephemeral/.plugin_symlinks/flutter_acrylic/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/refilc/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/refilc/.pub" />
<excludeFolder url="file://$MODULE_DIR$/refilc/build" />
<excludeFolder url="file://$MODULE_DIR$/refilc_kreta_api/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/refilc_kreta_api/.pub" />
<excludeFolder url="file://$MODULE_DIR$/refilc_kreta_api/build" />
<excludeFolder url="file://$MODULE_DIR$/refilc_mobile_ui/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/refilc_mobile_ui/.pub" />
<excludeFolder url="file://$MODULE_DIR$/refilc_mobile_ui/build" />
<excludeFolder url="file://$MODULE_DIR$/refilc_plus/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/refilc_plus/.pub" />
<excludeFolder url="file://$MODULE_DIR$/refilc_plus/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
</component>
</module>

5
.idea/vcs.xml generated
View File

@ -2,6 +2,9 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/refilc_plus" vcs="Git" />
<mapping directory="$PROJECT_DIR$/filcnaplo_desktop_ui" vcs="Git" />
<mapping directory="$PROJECT_DIR$/filcnaplo_kreta_api" vcs="Git" />
<mapping directory="$PROJECT_DIR$/filcnaplo_mobile_ui" vcs="Git" />
<mapping directory="$PROJECT_DIR$/filcnaplo_premium" vcs="Git" />
</component>
</project>

View File

@ -1,43 +1,34 @@
<p align=center>
<img src="https://raw.githubusercontent.com/Laky2k8/Refilc-2-Episode-1/refs/heads/master/refilc-2-real.png" width=150>
<img src="https://refilc.hu/image/brand/logo.png" width=150>
<h1 align=center><b>reFilc</b></h1>
</p>
#### Nem hivatalos e-napló alkalmazás az e-KRÉTA rendszerhez - tanulóktól, tanulóknak.
[![Downloads](https://img.shields.io/github/downloads-pre/refilc/naplo/total?&logo=github&label=Downloads)](https://github.com/refilc/naplo/releases) &nbsp; [![Discord](https://img.shields.io/discord/1111649116020285532?logo=discord&label=Discord)](https://discord.gg/refilc-1111649116020285532)
[![Downloads](https://img.shields.io/github/downloads-pre/refilc/naplo/total?&logo=github&label=Downloads)](https://github.com/refilc/naplo/releases) &nbsp; [![Discord](https://img.shields.io/discord/1111649116020285532?logo=discord&label=Discord)](https://dc.refilc.hu)
## Környezet felállítása
## Setup
### Source code letöltése
### Clone the project
*Az építhéshez szükséged lesz a refilc_plus repora is, amit itt találsz: [student-plus](https://git.qwit.cloud/refilc/student-plus)*
<em>A teljes source eléréséhez szükséged lesz a naplo-plus repo-ra is, mely biztonsági okokból privát. Írj Discord szerverünkön, hogy kaphass hozzáférést.</em>
```sh
git clone https://git.qwit.cloud/refilc/student-legacy.git --recursive
git clone --branch dev https://github.com/refilc/naplo --recursive
cd naplo
# ha ez nem töltött le refilc plus repoba értelmes dolgokat futtasd a többi parancsot is
rm -rf refilc_plus
git clone https://git.qwit.cloud/refilc/student-plus.git refilc_plus
```
### Csomagok telepítése
### Install packages
Menj be minden mappába és futtasd a következő parancsokat:
```sh
flutter clean
flutter pub get
```
Run `fix-pub.sh`
### Alkalmazás építése
### Run the app
```sh
cd refilc
flutter build apk --release
flutter run (--release)
```
*Ez egy apk fájlt fog építeni*
### Contribution
**Nézd meg a [Contribution guide](CONTRIBUTING.md)-ot!**
@ -46,22 +37,16 @@ Az összes (ugyan azon verzióhoz tartozó) contribution meg fog jelenni a relea
-------
# Csapatunk
# Team
**Management**
- Zypherift
- hayn
- Pearoo
- Zizi
- mnus
- xou
**kima:** head developer / project manager
**Designerek**
- dwe
- xou
**Reiner, pdf, Pearoo, Zizi:** community- and project manager / developer
**vrolandd, TMarccci:** head developer
**dwe., xou:** designer
**Péter:** video editor
***annon:** a régi Filc Napló fejlesztője (ez az app, ha bár sokban változott, alapjaiban a Filc-re épül)*
<em>**annon:** a régi Filc Napló fejlesztője (ez az app, ha bár sokban változott, alapjaiban a Filc-re épül)</em>

View File

@ -1,7 +0,0 @@
cd refilc && flutter pub outdated && cd ..
cd refilc_kreta_api && flutter pub outdated && cd ..
cd refilc_mobile_ui && flutter pub outdated && cd ..
# cd refilc_desktop_ui && flutter pub upgrade && cd ..
cd refilc_plus && flutter pub outdated && cd ..
echo Outdated version list above.

View File

@ -1,7 +0,0 @@
cd refilc && flutter pub upgrade --major-versions && cd ..
cd refilc_kreta_api && flutter pub upgrade --major-versions && cd ..
cd refilc_mobile_ui && flutter pub upgrade --major-versions && cd ..
# cd refilc_desktop_ui && flutter pub upgrade && cd ..
cd refilc_plus && flutter pub upgrade --major-versions && cd ..
echo "Upgraded pub (major)."

2
refilc/.gitignore vendored
View File

@ -5,11 +5,9 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related

View File

@ -1 +0,0 @@
*.jks

View File

@ -39,23 +39,8 @@ def debugKeystoreProperties = new Properties()
def debugKeystorePropertiesFile = rootProject.file("debugkey.properties")
debugKeystoreProperties.load(new FileInputStream(debugKeystorePropertiesFile))
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android {
if (!hasProperty('namespace') || namespace == null || namespace.isEmpty()) {
// Assign a default namespace based on the project name or group
namespace = project.group.toString() ?: "com.example.${project.name}"
}
}
}
}
}
android {
namespace = "hu.refilc.naplo"
ndkVersion "27.2.12479018"
ndkVersion "25.1.8937393"
// compileSdkVersion rootProject.ext.compileSdkVersion
compileSdkVersion 34
@ -73,7 +58,7 @@ android {
defaultConfig {
applicationId "hu.refilc.naplo"
minSdkVersion 24
minSdkVersion 21
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@ -85,16 +70,8 @@ android {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
// sourceCompatibility JavaVersion.VERSION_1_8
// targetCompatibility JavaVersion.VERSION_1_8
// sourceCompatibility JavaVersion.VERSION_21
// targetCompatibility JavaVersion.VERSION_21
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
signingConfigs {
@ -120,13 +97,7 @@ android {
release {
signingConfig signingConfigs.release
shrinkResources true
minifyEnabled true
debuggable false
jniDebuggable false
renderscriptDebuggable false
pseudoLocalesEnabled false
zipAlignEnabled true
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
@ -146,7 +117,7 @@ dependencies {
implementation 'joda-time:joda-time:2.9.4'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation 'androidx.window:window:1.0.0'
implementation 'androidx.window:window-java:1.0.0'
}

View File

@ -9,8 +9,3 @@
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProvider
-dontwarn org.joda.convert.FromString
-dontwarn org.joda.convert.ToString
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

View File

@ -2,6 +2,9 @@
xmlns:tools="http://schemas.android.com/tools" package="hu.refilc.naplo">
<application android:name="${applicationName}" android:label="reFilc" tools:replace="android:label" android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true" android:enableOnBackInvokedCallback="false">
<service
android:name="com.solusibejo.flutter_dynamic_icon_plus.FlutterDynamicIconPlusService"
android:stopWithTask="false"/>
<activity android:exported="true" android:name="hu.refilc.naplo.MainActivity"
android:launchMode="singleTop" android:theme="@style/LaunchTheme"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

After

Width:  |  Height:  |  Size: 69 B

View File

@ -20,7 +20,7 @@
android:gravity="center"
android:text="1."
android:textColor="@color/filc"
android:textColorLink="#ff052460"
android:textColorLink="#ff3D7BF4"
android:textSize="30sp"
android:textStyle="bold"
tools:ignore="HardcodedText" />

View File

@ -1,9 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground>
<inset
android:drawable="@drawable/ic_launcher_foreground"
android:inset="16%" />
</foreground>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -6,7 +6,7 @@
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#7CA021</item>
<item name="android:windowSplashScreenBackground">#03112D</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.

View File

@ -6,7 +6,7 @@
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#7CA021</item>
<item name="android:windowSplashScreenBackground">#03112D</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#7CA021</color>
<color name="ic_launcher_background">#03112D</color>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
@ -27,7 +27,7 @@
<color name="yellow_light">#ffFFCC00</color>
<color name="light_yellow_light">#40FFD60A</color>
<color name="green_light">#ff34C759</color>
<color name="filc_light">#ff052460</color>
<color name="filc_light">#ff3D7BF4</color>
<color name="teal_light">#ff5AC8FA</color>
<color name="blue_light">#ff007AFF</color>
<color name="indigo_light">#ff5856D6</color>
@ -49,8 +49,8 @@
<color name="yellow">#ffFFD60A</color>
<color name="light_yellow">#40FFD60A</color>
<color name="green">#ff32D74B</color>
<color name="filc">#ff052460</color>
<color name="filc_gradient">#ff06348f</color>
<color name="filc">#ff3D7BF4</color>
<color name="filc_gradient">#ff3D93F5</color>
<color name="teal">#ff64D2FF</color>
<color name="blue">#ff0A84FF</color>
<color name="indigo">#ff5E5CE6</color>

View File

@ -1,4 +1,8 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
org.gradle.jvmargs=-Xmx1536M \
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
android.useAndroidX=true
android.enableJetifier=true
# kotlin.jvm.target.validation.mode=IGNORE

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
distributionUrl=https://services.gradle.org/distributions/gradle-7.3.3-all.zip

View File

@ -24,8 +24,8 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.3" apply false
id "org.jetbrains.kotlin.android" version "2.0.21" apply false
id "com.android.application" version "7.1.1" apply false
id "org.jetbrains.kotlin.android" version "1.8.21" apply false
}
include ":app"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 KiB

After

Width:  |  Height:  |  Size: 581 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1009 KiB

After

Width:  |  Height:  |  Size: 982 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 KiB

After

Width:  |  Height:  |  Size: 330 KiB

View File

@ -1,43 +0,0 @@
<svg width="375" height="174" viewBox="0 0 375 174" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1575_5258)">
<g style="mix-blend-mode:color-burn">
<rect x="187.881" y="36.8047" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="238.186" y="36.8047" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="187.881" y="-13.5" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="238.186" y="-13.5" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="288.49" y="36.8047" width="49.3049" height="50.4482" stroke="#858585"/>
<rect x="337.652" y="36.8047" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="288.49" y="-13.5" width="49.3049" height="50.4482" stroke="#858585"/>
<rect x="337.652" y="-13.5" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="187.881" y="136.271" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="238.186" y="136.271" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="187.881" y="87.1099" width="50.4482" height="49.3049" stroke="#858585"/>
<rect x="238.186" y="87.1099" width="50.4482" height="49.3049" stroke="#858585"/>
<rect x="288.49" y="136.271" width="49.3049" height="50.4482" stroke="#858585"/>
<rect x="337.652" y="136.271" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="288.49" y="87.1099" width="49.3049" height="49.3049" stroke="#858585"/>
<rect x="337.652" y="87.1099" width="50.4482" height="49.3049" stroke="#858585"/>
<rect x="-12.1953" y="36.8047" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="-12.1953" y="-13.5" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="38.1094" y="36.8047" width="49.3049" height="50.4482" stroke="#858585"/>
<rect x="87.2705" y="36.8047" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="38.1094" y="-13.5" width="49.3049" height="50.4482" stroke="#858585"/>
<rect x="87.2705" y="-13.5" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="-12.1953" y="136.271" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="-12.1953" y="87.1099" width="50.4482" height="49.3049" stroke="#858585"/>
<rect x="38.1094" y="136.271" width="49.3049" height="50.4482" stroke="#858585"/>
<rect x="87.2705" y="136.271" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="38.1094" y="87.1099" width="49.3049" height="49.3049" stroke="#858585"/>
<rect x="87.2705" y="87.1099" width="50.4482" height="49.3049" stroke="#858585"/>
<rect x="137.576" y="36.8047" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="137.576" y="-13.5" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="137.576" y="136.271" width="50.4482" height="50.4482" stroke="#858585"/>
<rect x="137.576" y="87.1099" width="50.4482" height="49.3049" stroke="#858585"/>
</g>
</g>
<defs>
<clipPath id="clip0_1575_5258">
<rect width="375" height="173.78" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,27 +0,0 @@
<svg width="375" height="175" viewBox="0 0 375 175" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1575_5259)">
<g style="mix-blend-mode:color-burn">
<mask id="path-1-inside-1_1575_5259" fill="white">
<path d="M0 37H375V89H0V37Z"/>
</mask>
<path d="M0 38H375V36H0V38Z" fill="#858585" mask="url(#path-1-inside-1_1575_5259)"/>
<mask id="path-3-inside-2_1575_5259" fill="white">
<path d="M0 -13H375V38H0V-13Z"/>
</mask>
<path d="M0 -12H375V-14H0V-12Z" fill="#858585" mask="url(#path-3-inside-2_1575_5259)"/>
<mask id="path-5-inside-3_1575_5259" fill="white">
<path d="M0 137H375V188H0V137Z"/>
</mask>
<path d="M0 138H375V136H0V138Z" fill="#858585" mask="url(#path-5-inside-3_1575_5259)"/>
<mask id="path-7-inside-4_1575_5259" fill="white">
<path d="M0 87H375V138H0V87Z"/>
</mask>
<path d="M0 88H375V86H0V88Z" fill="#858585" mask="url(#path-7-inside-4_1575_5259)"/>
</g>
</g>
<defs>
<clipPath id="clip0_1575_5259">
<rect width="375" height="173.78" fill="white" transform="translate(0 0.780518)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,47 +0,0 @@
<svg width="375" height="175" viewBox="0 0 375 175" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1575_5260)">
<g style="mix-blend-mode:color-burn">
<circle cx="17" cy="19.561" r="1" fill="#858585"/>
<circle cx="59" cy="19.561" r="1" fill="#858585"/>
<circle cx="101" cy="19.561" r="1" fill="#858585"/>
<circle cx="143" cy="19.561" r="1" fill="#858585"/>
<circle cx="185" cy="19.561" r="1" fill="#858585"/>
<circle cx="227" cy="19.561" r="1" fill="#858585"/>
<circle cx="269" cy="19.561" r="1" fill="#858585"/>
<circle cx="311" cy="19.561" r="1" fill="#858585"/>
<circle cx="353" cy="19.561" r="1" fill="#858585"/>
<circle cx="17" cy="61.561" r="1" fill="#858585"/>
<circle cx="59" cy="61.561" r="1" fill="#858585"/>
<circle cx="101" cy="61.561" r="1" fill="#858585"/>
<circle cx="143" cy="61.561" r="1" fill="#858585"/>
<circle cx="185" cy="61.561" r="1" fill="#858585"/>
<circle cx="227" cy="61.561" r="1" fill="#858585"/>
<circle cx="269" cy="61.561" r="1" fill="#858585"/>
<circle cx="311" cy="61.561" r="1" fill="#858585"/>
<circle cx="353" cy="61.561" r="1" fill="#858585"/>
<circle cx="17" cy="103.561" r="1" fill="#858585"/>
<circle cx="59" cy="103.561" r="1" fill="#858585"/>
<circle cx="101" cy="103.561" r="1" fill="#858585"/>
<circle cx="143" cy="103.561" r="1" fill="#858585"/>
<circle cx="185" cy="103.561" r="1" fill="#858585"/>
<circle cx="227" cy="103.561" r="1" fill="#858585"/>
<circle cx="269" cy="103.561" r="1" fill="#858585"/>
<circle cx="311" cy="103.561" r="1" fill="#858585"/>
<circle cx="353" cy="103.561" r="1" fill="#858585"/>
<circle cx="17" cy="145.561" r="1" fill="#858585"/>
<circle cx="59" cy="145.561" r="1" fill="#858585"/>
<circle cx="101" cy="145.561" r="1" fill="#858585"/>
<circle cx="143" cy="145.561" r="1" fill="#858585"/>
<circle cx="185" cy="145.561" r="1" fill="#858585"/>
<circle cx="227" cy="145.561" r="1" fill="#858585"/>
<circle cx="269" cy="145.561" r="1" fill="#858585"/>
<circle cx="311" cy="145.561" r="1" fill="#858585"/>
<circle cx="353" cy="145.561" r="1" fill="#858585"/>
</g>
</g>
<defs>
<clipPath id="clip0_1575_5260">
<rect width="375" height="173.78" fill="white" transform="translate(0 0.561035)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,28 +0,0 @@
<svg width="375" height="175" viewBox="0 0 375 175" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1575_5261)">
<g style="mix-blend-mode:color-burn">
<path d="M0 63.0001H375" stroke="#858585"/>
<path d="M0 75.0001H375" stroke="#858585"/>
<path d="M0 87.0001H375" stroke="#858585"/>
<path d="M0 99.0001H375" stroke="#858585"/>
<path d="M0 111H375" stroke="#858585"/>
</g>
<g style="mix-blend-mode:color-burn">
<path d="M0 135H375" stroke="#858585"/>
<path d="M0 147H375" stroke="#858585"/>
<path d="M0 159H375" stroke="#858585"/>
<path d="M0 171H375" stroke="#858585"/>
</g>
<g style="mix-blend-mode:color-burn">
<path d="M0 3.00012H375" stroke="#858585"/>
<path d="M0 15.0001H375" stroke="#858585"/>
<path d="M0 27.0001H375" stroke="#858585"/>
<path d="M0 39.0001H375" stroke="#858585"/>
</g>
</g>
<defs>
<clipPath id="clip0_1575_5261">
<rect width="375" height="173.78" fill="white" transform="translate(0 0.341431)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 973 B

View File

@ -0,0 +1,43 @@
<svg width="375" height="174" viewBox="0 0 375 174" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_581_2504)">
<g style="mix-blend-mode:color-burn">
<rect x="138.881" y="36.8047" width="50.4482" height="50.4482" stroke="black"/>
<rect x="189.186" y="36.8047" width="50.4482" height="50.4482" stroke="black"/>
<rect x="138.881" y="-13.5" width="50.4482" height="50.4482" stroke="black"/>
<rect x="189.186" y="-13.5" width="50.4482" height="50.4482" stroke="black"/>
<rect x="239.49" y="36.8047" width="49.3049" height="50.4482" stroke="black"/>
<rect x="288.652" y="36.8047" width="50.4482" height="50.4482" stroke="black"/>
<rect x="239.49" y="-13.5" width="49.3049" height="50.4482" stroke="black"/>
<rect x="288.652" y="-13.5" width="50.4482" height="50.4482" stroke="black"/>
<rect x="138.881" y="136.271" width="50.4482" height="50.4482" stroke="black"/>
<rect x="189.186" y="136.271" width="50.4482" height="50.4482" stroke="black"/>
<rect x="138.881" y="87.1099" width="50.4482" height="49.3049" stroke="black"/>
<rect x="189.186" y="87.1099" width="50.4482" height="49.3049" stroke="black"/>
<rect x="239.49" y="136.271" width="49.3049" height="50.4482" stroke="black"/>
<rect x="288.652" y="136.271" width="50.4482" height="50.4482" stroke="black"/>
<rect x="239.49" y="87.1099" width="49.3049" height="49.3049" stroke="black"/>
<rect x="288.652" y="87.1099" width="50.4482" height="49.3049" stroke="black"/>
<rect x="338.957" y="36.8047" width="50.4482" height="50.4482" stroke="black"/>
<rect x="338.957" y="-13.5" width="50.4482" height="50.4482" stroke="black"/>
<rect x="338.957" y="136.271" width="50.4482" height="50.4482" stroke="black"/>
<rect x="338.957" y="87.1099" width="50.4482" height="49.3049" stroke="black"/>
<rect x="-10.8906" y="36.8047" width="49.3049" height="50.4482" stroke="black"/>
<rect x="38.2705" y="36.8047" width="50.4482" height="50.4482" stroke="black"/>
<rect x="-10.8906" y="-13.5" width="49.3049" height="50.4482" stroke="black"/>
<rect x="38.2705" y="-13.5" width="50.4482" height="50.4482" stroke="black"/>
<rect x="-10.8906" y="136.271" width="49.3049" height="50.4482" stroke="black"/>
<rect x="38.2705" y="136.271" width="50.4482" height="50.4482" stroke="black"/>
<rect x="-10.8906" y="87.1099" width="49.3049" height="49.3049" stroke="black"/>
<rect x="38.2705" y="87.1099" width="50.4482" height="49.3049" stroke="black"/>
<rect x="88.5762" y="36.8047" width="50.4482" height="50.4482" stroke="black"/>
<rect x="88.5762" y="-13.5" width="50.4482" height="50.4482" stroke="black"/>
<rect x="88.5762" y="136.271" width="50.4482" height="50.4482" stroke="black"/>
<rect x="88.5762" y="87.1099" width="50.4482" height="49.3049" stroke="black"/>
</g>
</g>
<defs>
<clipPath id="clip0_581_2504">
<rect width="375" height="173.78" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

2
refilc/build.sh Executable file → Normal file
View File

@ -1,3 +1,3 @@
#!/bin/sh
flutter build apk --release --tree-shake-icons --split-debug-info=debug-info --split-per-abi --target-platform android-arm,android-arm64 --obfuscate
flutter build apk --release --dart-define=APPVER=$(cat pubspec.yaml | grep version: | cut -d' ' -f2 | cut -d+ -f1) --no-tree-shake-icons

View File

@ -43,21 +43,4 @@ post_install do |installer|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
bitcode_strip_path = `xcrun --find bitcode_strip`.chop!
def strip_bitcode_from_framework(bitcode_strip_path, framework_relative_path)
framework_path = File.join(Dir.pwd, framework_relative_path)
command = "#{bitcode_strip_path} #{framework_path} -r -o #{framework_path}"
puts "Stripping bitcode: #{command}"
system(command)
end
framework_paths = [
"Pods/Shake/Sources/Shake.xcframework/ios-arm64/Shake.framework/Shake",
"Pods/Shake/Sources/Shake.xcframework/ios-arm64_x86_64-simulator/Shake.framework/Shake"
]
framework_paths.each do |framework_relative_path|
strip_bitcode_from_framework(bitcode_strip_path, framework_relative_path)
end
end

View File

@ -517,11 +517,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 283;
DEVELOPMENT_TEAM = 4J97JVC2FG;
CURRENT_PROJECT_VERSION = 255;
DEVELOPMENT_TEAM = 4DKAF249F3;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_NAME = 5.1.1;
FLUTTER_BUILD_NUMBER = 283;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = reFilc;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
@ -529,8 +527,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.1.1;
PRODUCT_BUNDLE_IDENTIFIER = hu.qwit.refilc;
MARKETING_VERSION = 5.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@ -551,8 +549,8 @@
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 283;
DEVELOPMENT_TEAM = 4J97JVC2FG;
CURRENT_PROJECT_VERSION = 255;
DEVELOPMENT_TEAM = 4DKAF249F3;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = livecard/Info.plist;
@ -565,10 +563,10 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.1.1;
MARKETING_VERSION = 5.0.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = hu.qwit.refilc.livecard;
PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo.livecardpro;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
@ -593,8 +591,8 @@
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 283;
DEVELOPMENT_TEAM = 4J97JVC2FG;
CURRENT_PROJECT_VERSION = 255;
DEVELOPMENT_TEAM = 4DKAF249F3;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = livecard/Info.plist;
@ -607,9 +605,9 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.1.1;
MARKETING_VERSION = 5.0.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = hu.qwit.refilc.livecard;
PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo.livecardpro;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
@ -633,8 +631,8 @@
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 283;
DEVELOPMENT_TEAM = 4J97JVC2FG;
CURRENT_PROJECT_VERSION = 255;
DEVELOPMENT_TEAM = 4DKAF249F3;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = livecard/Info.plist;
@ -647,9 +645,9 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.1.1;
MARKETING_VERSION = 5.0.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = hu.qwit.refilc.livecard;
PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo.livecardpro;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
@ -777,11 +775,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 283;
DEVELOPMENT_TEAM = 4J97JVC2FG;
CURRENT_PROJECT_VERSION = 255;
DEVELOPMENT_TEAM = 4DKAF249F3;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_NAME = 5.1.1;
FLUTTER_BUILD_NUMBER = 283;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = reFilc;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
@ -789,8 +785,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.1.1;
PRODUCT_BUNDLE_IDENTIFIER = hu.qwit.refilc;
MARKETING_VERSION = 5.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -807,11 +803,9 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 283;
DEVELOPMENT_TEAM = 4J97JVC2FG;
CURRENT_PROJECT_VERSION = 255;
DEVELOPMENT_TEAM = 4DKAF249F3;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_NAME = 5.1.1;
FLUTTER_BUILD_NUMBER = 283;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = reFilc;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
@ -819,8 +813,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 5.1.1;
PRODUCT_BUNDLE_IDENTIFIER = hu.qwit.refilc;
MARKETING_VERSION = 5.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.refilc2.naplo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;

View File

@ -12,7 +12,7 @@
<key>livecard.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>86</integer>
<integer>83</integer>
</dict>
</dict>
</dict>

View File

@ -3,7 +3,7 @@ import background_fetch
import ActivityKit
import Flutter
@main
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
private var methodChannel: FlutterMethodChannel?

View File

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "rf_1024.png",
"filename" : "reFilc_Logo.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

@ -38,7 +38,7 @@
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="2700" height="2700"/>
<image name="LaunchImage" width="1700" height="1700"/>
<image name="LaunchBackground" width="1" height="1"/>
</resources>
</document>

View File

@ -1,7 +1,7 @@
<?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>
<dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.transistorsoft.refilcnotification</string>
@ -134,5 +134,5 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</dict>
</plist>

View File

@ -1,4 +1,5 @@
import Foundation
import ActivityKit
public struct LessonData {
var color: String
@ -32,13 +33,8 @@ public struct LessonData {
if let endDateStr = dictionary["endDate"] as? String, let endDateInt = Int(endDateStr) {
self.endDate = Date(timeIntervalSince1970: TimeInterval(endDateInt) / 1000)
} else {
self.endDate = self.startDate
}
if self.startDate <= self.endDate {
self.date = self.startDate...self.endDate
} else {
self.date = self.endDate...self.endDate
self.endDate = Date()
}
date = self.startDate...self.endDate
}
}

View File

@ -11,17 +11,6 @@ struct Widgets: WidgetBundle {
}
}
// text contrast background
extension Text {
func getContrastText(backgroundColor: Color) -> some View {
var r, g, b, a: CGFloat
(r, g, b, a) = (0, 0, 0, 0)
UIColor(backgroundColor).getRed(&r, green: &g, blue: &b, alpha: &a)
let luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b
return luminance < 0.6 ? self.foregroundColor(.white) : self.foregroundColor(.black)
}
}
// Color Converter
extension Color {
init(hex: String, alpha: Double = 1.0) {
@ -63,22 +52,14 @@ struct LockScreenLiveActivityView: View {
VStack(alignment: .center) {
// Jelenlegi óra
VStack {
if(context.state.title.contains("Az első órádig")) {
Text(context.state.title)
.font(.system(size: 15))
.bold()
.multilineTextAlignment(.center)
} else if(context.state.title == "Szünet") {
Text(context.state.title)
.font(.body)
.bold()
.padding(.trailing, 90)
} else {
MultilineTextView(text: "\(context.state.index) \(context.state.title) - \(context.state.subtitle)", limit: 25)
Text(context.state.index + " " + context.state.title)
.font(.body)
.bold()
.multilineTextAlignment(.center)
}
Text("Terem: \(context.state.subtitle)")
.italic()
.font(.caption)
}
// Leírás
@ -88,23 +69,17 @@ struct LockScreenLiveActivityView: View {
}
// Következő óra
if(context.state.nextSubject != "" && context.state.nextRoom != "") {
HStack {
Image(systemName: "arrow.right")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: CGFloat(8), height: CGFloat(8))
.foregroundStyle(.secondary)
Text("\(context.state.nextSubject) - \(context.state.nextRoom)")
Text(context.state.nextSubject)
.font(.caption)
Text(context.state.nextRoom)
.font(.caption2)
}
.multilineTextAlignment(.center)
} else {
Spacer(minLength: 5)
Text("Ez az utolsó óra! Kitartást!")
.font(.system(size: 15))
}
}
.padding(15)
@ -116,17 +91,13 @@ struct LockScreenLiveActivityView: View {
.frame(width: 85)
.font(.title2)
.monospacedDigit()
.padding(.trailing)
.padding(.trailing, CGFloat(24))
}
// .activityBackgroundTint(
// context.state.color != "#676767"
// ? Color(hex: context.state.color)
// : Color.clear
// )
.activityBackgroundTint(
Color.clear
context.state.color != "#676767"
? Color(hex: context.state.color)
: Color.clear
)
.foregroundStyle(Color(hex: context.state.color))
}
}
@ -164,77 +135,31 @@ struct LiveCardWidget: Widget {
}
DynamicIslandExpandedRegion(.center) {
VStack(alignment: .center) {
// Első óra előtti expanded DynamicIsland
if(context.state.title.contains("Az első órádig")) {
Text("Az első órád:")
.font(.body)
.bold()
.padding(.trailing, -15)
MultilineTextView(text: "\(context.state.nextSubject)", limit: 25)
.font(.body)
.padding(.trailing, -25)
Text("Ebben a teremben:")
.font(.body)
.bold()
.padding(.leading, 15)
Text(context.state.nextRoom)
.font(.body)
.padding(.leading, 15)
} else if(context.state.title == "Szünet") {
// Amikor szünet van, expanded DynamicIsland
Text(context.state.title)
Text(context.state.index + context.state.title)
.lineLimit(1)
.font(.body)
.bold()
.padding(.leading, 15)
Spacer(minLength: 5)
Text("Következő óra és terem:")
.font(.system(size: 13))
.padding(.leading, 25)
Text(context.state.nextSubject)
Text(context.state.subtitle)
.lineLimit(1)
.font(.subheadline)
Spacer()
Text(context.state.description)
.lineLimit(2)
.font(.caption)
.padding(.leading, 15)
Text(context.state.nextRoom)
.font(.caption2)
.padding(.leading, 15)
} else {
// Amikor óra van, expanded DynamicIsland
MultilineTextView(text: "\(context.state.index) \(context.state.title) - \(context.state.subtitle)", limit: 25)
.lineLimit(1)
.font(.body)
.bold()
.padding(.trailing, -35)
Spacer(minLength: 2)
if(context.state.nextRoom != "" && context.state.nextSubject != "") {
Text("Következő óra és terem:")
.font(.system(size: 14))
.padding(.trailing, -45)
Spacer(minLength: 2)
Text("\(context.state.nextSubject) - \(context.state.nextRoom)")
.modifier(DynamicFontSizeModifier(text: "\(context.state.nextSubject) - \(context.state.nextRoom)"))
.padding(.trailing, 35)
} else {
Text("Ez az utolsó óra! Kitartást!")
.font(.system(size: 14))
.padding(.trailing, -30)
}
}
}.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0))
}
/// Compact
} compactLeading: {
Label {
Text(context.state.title)
} icon: {
Image(systemName: context.state.icon)
}
.font(.caption2)
}
compactTrailing: {
Text(timerInterval: context.state.date, countsDown: true)
.multilineTextAlignment(.center)
@ -270,118 +195,3 @@ struct LiveCardWidget: Widget {
}
}
}
struct MultilineTextView: View {
var text: String
var limit: Int = 20 // default is 20 character
var body: some View {
let words = text.split(separator: " ")
var currentLine = ""
var lines: [String] = []
for word in words {
if (currentLine.count + word.count + 1) > limit {
lines.append(currentLine)
currentLine = ""
}
if !currentLine.isEmpty {
currentLine += " "
}
currentLine += word
}
if !currentLine.isEmpty {
lines.append(currentLine)
}
return VStack(alignment: .center) {
ForEach(lines, id: \.self) { line in
Text(line)
}
Spacer(minLength: 1)
}
}
}
struct DynamicFontSizeModifier: ViewModifier {
var text: String
func body(content: Content) -> some View {
content
.font(.system(size: fontSize(for: text)))
}
private func fontSize(for text: String) -> CGFloat {
let length = text.count
if length < 10 {
return 12
} else if length < 20 {
return 12
} else {
return 11
}
}
}
struct LiveCardWidget_Previews: PreviewProvider {
static let attributes = LiveActivitiesAppAttributes()
static let duringLessonExmaple = LiveActivitiesAppAttributes.ContentState(
color: "#FF5733",
icon: "bell",
index: "1.",
title: "Math Class",
subtitle: "101",
description: "Algebra lesson",
startDate: Date(),
endDate: Date().addingTimeInterval(3000),
date: Date()...Date().addingTimeInterval(3000), // 50 minutes later
nextSubject: "Physics",
nextRoom: "102"
)
static let inBreak = LiveActivitiesAppAttributes.ContentState(
color: "#FF5733",
icon: "house",
index: "",
title: "Szünet",
subtitle: "Menj a(z) 122 terembe.",
description: "",
startDate: Date(),
endDate: Date().addingTimeInterval(3000),
date: Date()...Date().addingTimeInterval(3000), // 50 minutes later
nextSubject: "Physics",
nextRoom: "122"
)
static let lastLesson = LiveActivitiesAppAttributes.ContentState(
color: "#00ff00",
icon: "bell",
index: "6.",
title: "Math Class",
subtitle: "",
description: "Lorem Ipsum",
startDate: Date(),
endDate: Date().addingTimeInterval(3000),
date: Date()...Date().addingTimeInterval(3000), // 50 minutes later
nextSubject: "",
nextRoom: ""
)
static var previews: some View {
// Dynamic Island Compact
Group {
attributes
.previewContext(duringLessonExmaple, viewKind: .dynamicIsland(.compact))
.previewDisplayName("During Lesson")
attributes
.previewContext(inBreak, viewKind: .dynamicIsland(.compact))
.previewDisplayName("In Break")
attributes
.previewContext(lastLesson, viewKind: .dynamicIsland(.compact))
.previewDisplayName("During Last Lesson")
}
}
}

View File

@ -18,51 +18,45 @@ import 'package:connectivity_plus/connectivity_plus.dart';
class FilcAPI {
// API base
static const baseUrl = "https://api.refilcapp.hu";
static const baseUrl = "https://api.refilc.hu";
// Public API
static const schoolList = "https://api.refilcapp.hu/v3/public/school-list";
static const news = "https://staticrf-api.pages.dev/news/index.json";
static const supporters = "0.0.0.0";
static const schoolList = "$baseUrl/v3/public/school-list";
static const news = "$baseUrl/v3/public/news";
static const supporters = "$baseUrl/v3/public/supporters";
// Private API
static const ads = "0.0.0.0";
static const ads = "$baseUrl/v3/private/ads";
static const config = "$baseUrl/v3/private/config";
static const reportApi = "$baseUrl/v3/private/crash-report";
static const rfPlus = "0.0.0.0";
static const plusAuthLogin = "0.0.0.0";
static const plusAuthCallback = "0.0.0.0";
static const plusActivation = "0.0.0.0";
static const plusScopes = "0.0.0.0/";
static const rfPlus = "$baseUrl/v3/rf-plus";
static const plusAuthLogin = "$rfPlus/auth/login";
static const plusAuthCallback = "$rfPlus/auth/callback";
static const plusActivation = "$rfPlus/activate";
static const plusScopes = "$rfPlus/scopes";
// Updates
static const repo = "refilc/naplo";
static const releases = "https://api.github.com/repos/$repo/releases";
// Share API
static const themeShare = "https://api.refilcapp.hu/v3/shared/theme/add";
static const themeGet = "https://api.refilcapp.hu/v3/shared/theme/get";
static const themeShare = "$baseUrl/v3/shared/theme/add";
static const themeGet = "$baseUrl/v3/shared/theme/get";
static const allThemes = "$themeGet/all";
static const themeByID = "$themeGet/";
static const gradeColorsShare = "https://api.refilcapp.hu/v3/shared/grade-colors/add";
static const gradeColorsGet = "https://api.refilcapp.hu/v3/shared/grade-colors/get";
static const gradeColorsShare = "$baseUrl/v3/shared/grade-colors/add";
static const gradeColorsGet = "$baseUrl/v3/shared/grade-colors/get";
static const allGradeColors = "$gradeColorsGet/all";
static const gradeColorsByID = "$gradeColorsGet/";
// Payment API
static const payment = "0.0.0.0";
static const stripeSheet = "0.0.0.0";
// Cloud Sync
// cloud sync? for what reason
static const cloudSyncApi = "0.0.0.0";
static const payment = "$baseUrl/v3/payment";
static const stripeSheet = "$payment/stripe-sheet";
static Future<bool> checkConnectivity() async =>
(await Connectivity().checkConnectivity())[0] != ConnectivityResult.none;
(await Connectivity().checkConnectivity()) != ConnectivityResult.none;
// nem tudom nem vazar-e senkit se, de mar ertelmetlen ez
static Future<List<School>?> getSchools() async {
try {
http.Response res = await http.get(Uri.parse(schoolList));
@ -72,6 +66,16 @@ class FilcAPI {
.cast<Map>()
.map((json) => School.fromJson(json))
.toList();
schools.add(School(
city: "Stockholm",
instituteCode: "refilc-test-sweden",
name: "reFilc Test SE - Leo Ekström High School",
));
schools.add(School(
city: "Madrid",
instituteCode: "refilc-test-spain",
name: "reFilc Test ES - Emilio Obrero University",
));
return schools;
} else {
throw "HTTP ${res.statusCode}: ${res.body}";
@ -89,12 +93,10 @@ class FilcAPI {
"x-filc-id": settings.xFilcId,
"user-agent": userAgent,
// platform things
"rf-platform":
settings.analyticsEnabled ? Platform.operatingSystem : "unknown",
"rf-platform-version": settings.analyticsEnabled
? Platform.operatingSystemVersion
: "unknown",
"rf-app-version": const String.fromEnvironment("APPVER", defaultValue: "?"),
"rf-platform": Platform.operatingSystem,
"rf-platform-version": Platform.operatingSystemVersion,
"rf-app-version":
const String.fromEnvironment("APPVER", defaultValue: "?"),
"rf-uinid": settings.xFilcId,
};
@ -125,8 +127,7 @@ class FilcAPI {
http.Response res = await http.get(Uri.parse(news));
if (res.statusCode == 200) {
String utf8Body = utf8.decode(res.bodyBytes);
return (jsonDecode(utf8Body) as List)
return (jsonDecode(res.body) as List)
.cast<Map>()
.map((e) => News.fromJson(e))
.toList();
@ -230,7 +231,7 @@ class FilcAPI {
}
// sharing
static Future<int> addSharedTheme(SharedTheme theme) async {
static Future<void> addSharedTheme(SharedTheme theme) async {
try {
theme.json.remove('json');
theme.json['is_public'] = theme.isPublic.toString();
@ -262,19 +263,13 @@ class FilcAPI {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
);
// if (res.statusCode != 201) {
// throw "HTTP ${res.statusCode}: ${res.body}";
// }
if (res.statusCode == 201) {
log('Shared theme successfully with ID: ${theme.id}');
if (res.statusCode != 201) {
throw "HTTP ${res.statusCode}: ${res.body}";
}
return res.statusCode;
log('Shared theme successfully with ID: ${theme.id}');
} on Exception catch (error, stacktrace) {
log("ERROR: FilcAPI.addSharedTheme: $error $stacktrace");
return 696;
}
}
@ -308,7 +303,8 @@ class FilcAPI {
return null;
}
static Future<int> addSharedGradeColors(SharedGradeColors gradeColors) async {
static Future<void> addSharedGradeColors(
SharedGradeColors gradeColors) async {
try {
gradeColors.json.remove('json');
gradeColors.json['is_public'] = gradeColors.isPublic.toString();
@ -324,19 +320,13 @@ class FilcAPI {
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
);
// if (res.statusCode != 201) {
// throw "HTTP ${res.statusCode}: ${res.body}";
// }
if (res.statusCode == 201) {
log('Shared grade colors successfully with ID: ${gradeColors.id}');
if (res.statusCode != 201) {
throw "HTTP ${res.statusCode}: ${res.body}";
}
return res.statusCode;
log('Shared grade colors successfully with ID: ${gradeColors.id}');
} on Exception catch (error, stacktrace) {
log("ERROR: FilcAPI.addSharedGradeColors: $error $stacktrace");
return 696;
}
}
@ -346,8 +336,6 @@ class FilcAPI {
if (res.statusCode == 200) {
return (jsonDecode(res.body) as Map);
} else if (res.statusCode == 404) {
return {"public_id": ""};
} else {
throw "HTTP ${res.statusCode}: ${res.body}";
}
@ -385,11 +373,6 @@ class FilcAPI {
return null;
}
// cloud sync
static Future<Map?> cloudSync(Map<String, String> data, String token) async {
return null;
}
}
class ErrorReport {

View File

@ -1,6 +1,5 @@
// ignore_for_file: avoid_print, use_build_context_synchronously
import 'package:flutter/foundation.dart';
import 'package:refilc/utils/jwt.dart';
import 'package:refilc_kreta_api/models/school.dart';
import 'package:refilc_kreta_api/providers/absence_provider.dart';
@ -65,12 +64,8 @@ Future loginAPI({
parents: ['Teszt András', 'Teszt Linda'],
json: {"a": "b"},
address: '1117 Budapest, Gábor Dénes utca 4.',
gradeDelay: 0,
),
role: Role.parent,
accessToken: '',
accessTokenExpire: DateTime.now(),
refreshToken: '',
);
if (onLogin != null) onLogin(user);
@ -112,9 +107,7 @@ Future loginAPI({
default:
// normal login from here
Provider.of<KretaClient>(context, listen: false).userAgent =
Provider.of<SettingsProvider>(context, listen: false)
.config
.userAgent;
Provider.of<SettingsProvider>(context, listen: false).config.userAgent;
Map<String, String> headers = {
"content-type": "application/x-www-form-urlencoded",
@ -134,7 +127,6 @@ Future loginAPI({
password: password,
instituteCode: instituteCode,
));
if (res != null) {
if (res.containsKey("error")) {
if (res["error"] == "invalid_grant") {
@ -156,134 +148,6 @@ Future loginAPI({
name: student.name,
student: student,
role: JwtUtils.getRoleFromJWT(res["access_token"])!,
accessToken: res["access_token"],
accessTokenExpire: DateTime.now(),
refreshToken: '',
);
if (onLogin != null) onLogin(user);
// Store User in the database
await Provider.of<DatabaseProvider>(context, listen: false)
.store
.storeUser(user);
Provider.of<UserProvider>(context, listen: false).addUser(user);
Provider.of<UserProvider>(context, listen: false)
.setUser(user.id);
// Get user data
try {
await Future.wait([
Provider.of<GradeProvider>(context, listen: false).fetch(),
Provider.of<TimetableProvider>(context, listen: false)
.fetch(week: Week.current()),
Provider.of<ExamProvider>(context, listen: false).fetch(),
Provider.of<HomeworkProvider>(context, listen: false).fetch(),
Provider.of<MessageProvider>(context, listen: false)
.fetchAll(),
Provider.of<MessageProvider>(context, listen: false)
.fetchAllRecipients(),
Provider.of<NoteProvider>(context, listen: false).fetch(),
Provider.of<EventProvider>(context, listen: false).fetch(),
Provider.of<AbsenceProvider>(context, listen: false).fetch(),
]);
} catch (error) {
print("WARNING: failed to fetch user data: $error");
}
if (onSuccess != null) onSuccess();
return LoginState.success;
} catch (error) {
print("ERROR: loginAPI: $error");
// maybe check debug mode
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("ERROR: $error")));
return LoginState.failed;
}
}
}
}
break;
}
return LoginState.failed;
}
// new login api
Future newLoginAPI({
required String code,
required BuildContext context,
void Function(User)? onLogin,
void Function()? onSuccess,
}) async {
// actual login (token grant) logic
Provider.of<KretaClient>(context, listen: false).userAgent =
Provider.of<SettingsProvider>(context, listen: false).config.userAgent;
Map<String, String> headers = {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"accept": "*/*",
"user-agent": "eKretaStudent/264745 CFNetwork/1494.0.7 Darwin/23.4.0",
};
Map? res = await Provider.of<KretaClient>(context, listen: false)
.postAPI(KretaAPI.login, headers: headers, body: {
"code": code,
"code_verifier": "DSpuqj_HhDX4wzQIbtn8lr8NLE5wEi1iVLMtMK0jY6c",
"redirect_uri":
"https://mobil.e-kreta.hu/ellenorzo-student/prod/oauthredirect",
"client_id": KretaAPI.clientId,
"grant_type": "authorization_code",
});
if (res != null) {
if (kDebugMode) {
print(res);
// const splitSize = 1000;
// RegExp exp = RegExp(r"\w{" "$splitSize" "}");
// // String str = "0102031522";
// Iterable<Match> matches = exp.allMatches(res.toString());
// var list = matches.map((m) => m.group(0));
// list.forEach((e) {
// print(e);
// });
}
if (res.containsKey("error")) {
if (res["error"] == "invalid_grant") {
print("ERROR: invalid_grant");
return;
}
} else {
if (res.containsKey("access_token")) {
try {
Provider.of<KretaClient>(context, listen: false).accessToken =
res["access_token"];
Provider.of<KretaClient>(context, listen: false).refreshToken =
res["refresh_token"];
String instituteCode =
JwtUtils.getInstituteFromJWT(res["access_token"])!;
String username = JwtUtils.getUsernameFromJWT(res["access_token"])!;
Role role = JwtUtils.getRoleFromJWT(res["access_token"])!;
Map? studentJson =
await Provider.of<KretaClient>(context, listen: false)
.getAPI(KretaAPI.student(instituteCode));
Student student = Student.fromJson(studentJson!);
var user = User(
username: username,
password: '',
instituteCode: instituteCode,
name: student.name,
student: student,
role: role,
accessToken: res["access_token"],
accessTokenExpire:
DateTime.now().add(Duration(seconds: (res["expires_in"] - 30))),
refreshToken: res["refresh_token"],
);
if (onLogin != null) onLogin(user);
@ -326,6 +190,8 @@ Future newLoginAPI({
}
}
}
break;
}
return LoginState.failed;
}

View File

@ -18,7 +18,7 @@ class AdProvider extends ChangeNotifier {
}
Future<void> fetch() async {
_ads = [];
_ads = await FilcAPI.getAds() ?? [];
_ads.sort((a, b) => -a.date.compareTo(b.date));
// check for new ads

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:refilc/database/query.dart';
import 'package:refilc/database/store.dart';
// ignore: depend_on_referenced_packages
@ -13,7 +15,11 @@ class DatabaseProvider {
Future<void> init() async {
Database db;
if (Platform.isLinux || Platform.isWindows) {
db = await databaseFactoryFfi.openDatabase("app.db");
} else {
db = await openDatabase("app.db");
}
query = DatabaseQuery(db: db);
store = DatabaseStore(db: db);

View File

@ -5,7 +5,6 @@ import 'dart:async';
import 'package:refilc/api/providers/liveactivity/platform_channel.dart';
import 'package:refilc/helpers/subject.dart';
import 'package:refilc/models/settings.dart';
import 'package:refilc/ui/flutter_colorpicker/utils.dart';
import 'package:refilc_kreta_api/models/lesson.dart';
import 'package:refilc_kreta_api/models/week.dart';
import 'package:refilc/utils/format.dart';
@ -85,18 +84,15 @@ class LiveCardProvider extends ChangeNotifier {
}
Map<String, String> toMap() {
// print("LIVE ACTIVITY COLOR BELOW:");
// print(_settings.liveActivityColor.toHexString().substring(2));
String color = '#${_settings.liveActivityColor.toHexString().substring(2)}';
switch (currentState) {
case LiveCardState.morning:
return {
"color": color,
"color":
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
"icon": nextLesson != null
? SubjectIcon.resolveName(subject: nextLesson?.subject)
: "book",
"title": "Jó reggelt! Az első órádig:",
"title": "Első órádig:",
"subtitle": "",
"description": "",
"startDate": storeFirstRunDate != null
@ -116,11 +112,12 @@ class LiveCardProvider extends ChangeNotifier {
case LiveCardState.afternoon:
return {
"color": color,
"color":
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
"icon": nextLesson != null
? SubjectIcon.resolveName(subject: nextLesson?.subject)
: "book",
"title": "Jó napot! Az első órádig:",
"title": "Első órádig:",
"subtitle": "",
"description": "",
"startDate": storeFirstRunDate != null
@ -140,11 +137,12 @@ class LiveCardProvider extends ChangeNotifier {
case LiveCardState.night:
return {
"color": color,
"color":
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
"icon": nextLesson != null
? SubjectIcon.resolveName(subject: nextLesson?.subject)
: "book",
"title": "Jó estét! Az első órádig:",
"title": "Első órádig:",
"subtitle": "",
"description": "",
"startDate": storeFirstRunDate != null
@ -164,7 +162,8 @@ class LiveCardProvider extends ChangeNotifier {
case LiveCardState.duringLesson:
return {
"color": color,
"color":
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
"icon": currentLesson != null
? SubjectIcon.resolveName(subject: currentLesson?.subject)
: "book",
@ -175,8 +174,7 @@ class LiveCardProvider extends ChangeNotifier {
ShortSubject.resolve(subject: currentLesson?.subject)
.capital()
: "",
"subtitle":
"Terem: ${currentLesson?.room.replaceAll("_", " ") ?? ""}",
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
"description": currentLesson?.description ?? "",
"startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) -
_delay.inMilliseconds)
@ -201,7 +199,8 @@ class LiveCardProvider extends ChangeNotifier {
final diff = getFloorDifference();
return {
"color": color,
"color":
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
"icon": iconFloorMap[diff] ?? "cup.and.saucer",
"title": "Szünet",
"description": "go $diff".i18n.fill([
@ -363,16 +362,7 @@ class LiveCardProvider extends ChangeNotifier {
}
//END
if ((currentState == LiveCardState.afternoon ||
currentState == LiveCardState.morning ||
currentState == LiveCardState.night) &&
hasActivityStarted &&
nextLesson != null &&
nextLesson!.start.difference(now).inMinutes > 60) {
debugPrint("Több, mint 1 óra van az első óráig. Befejezés...");
PlatformChannel.endLiveActivity();
hasActivityStarted = false;
} else if (hasActivityStarted &&
if (hasActivityStarted &&
!hasDayEnd &&
nextLesson == null &&
now.isAfter(prevLesson!.end)) {

View File

@ -7,23 +7,17 @@ import 'package:provider/provider.dart';
class SelfNoteProvider with ChangeNotifier {
late List<SelfNote> _notes;
late List<TodoItem> _todoItems;
late BuildContext _context;
List<SelfNote> get notes => _notes;
List<TodoItem> get todos => _todoItems;
SelfNoteProvider({
List<SelfNote> initialNotes = const [],
List<TodoItem> initialTodoItems = const [],
required BuildContext context,
}) {
_notes = List.castFrom(initialNotes);
_todoItems = List.castFrom(initialTodoItems);
_context = context;
if (_notes.isEmpty) restore();
if (_todoItems.isEmpty) restoreTodo();
}
// restore self notes from db
@ -44,24 +38,6 @@ class SelfNoteProvider with ChangeNotifier {
}
}
// restore todo items from db
Future<void> restoreTodo() async {
String? userId = Provider.of<UserProvider>(_context, listen: false).id;
// await Provider.of<DatabaseProvider>(_context, listen: false)
// .userStore
// .storeSelfNotes([], userId: userId!);
// load self notes from db
if (userId != null) {
var dbTodo = await Provider.of<DatabaseProvider>(_context, listen: false)
.userQuery
.getTodoItems(userId: userId);
_todoItems = dbTodo;
notifyListeners();
}
}
// fetches fresh data from api (not needed, cuz no api for that)
// Future<void> fetch() async {
// }
@ -78,17 +54,4 @@ class SelfNoteProvider with ChangeNotifier {
_notes = notes;
notifyListeners();
}
// store todo items in db
Future<void> storeTodo(List<TodoItem> todos) async {
User? user = Provider.of<UserProvider>(_context, listen: false).user;
if (user == null) throw "Cannot store Self Notes for User null";
String userId = user.id;
await Provider.of<DatabaseProvider>(_context, listen: false)
.userStore
.storeSelfTodoItems(todos, userId: userId);
_todoItems = todos;
notifyListeners();
}
}

View File

@ -15,7 +15,7 @@ class StatusProvider extends ChangeNotifier {
StatusProvider() {
_handleNetworkChanges();
_handleDNSFailure();
Connectivity().checkConnectivity().then((value) => _networkType = value[0]);
Connectivity().checkConnectivity().then((value) => _networkType = value);
}
Status? getStatus() => _stack.isNotEmpty ? _stack[0] : null;
@ -24,8 +24,8 @@ class StatusProvider extends ChangeNotifier {
void _handleNetworkChanges() {
Connectivity().onConnectivityChanged.listen((event) {
_networkType = event[0];
if (event[0] == ConnectivityResult.none) {
_networkType = event;
if (event == ConnectivityResult.none) {
if (!_stack.contains(Status.network)) {
_stack.remove(Status.apiError);
_stack.insert(0, Status.network);

View File

@ -2,7 +2,6 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:refilc/api/providers/database_provider.dart';
import 'package:refilc/api/providers/status_provider.dart';
import 'package:refilc/api/providers/user_provider.dart';
@ -29,7 +28,7 @@ import 'liveactivity/platform_channel.dart';
// Mutex
bool lock = false;
Future<void> syncAll(BuildContext context) async {
Future<void> syncAll(BuildContext context) {
if (lock) return Future.value();
// Lock
lock = true;
@ -41,12 +40,6 @@ Future<void> syncAll(BuildContext context) async {
StatusProvider statusProvider =
Provider.of<StatusProvider>(context, listen: false);
// check if access token isn't expired
// if (user.user?.accessToken == null) {
// lock = false;
// return Future.value();
// }
List<Future<void>> tasks = [];
int taski = 0;
@ -57,49 +50,6 @@ Future<void> syncAll(BuildContext context) async {
}
tasks = [
// refresh login
syncStatus(() async {
// print(user.user?.accessTokenExpire);
// print('${user.user?.accessToken ?? "no token"} - ACCESS TOKEN');
// user.user!.accessToken = "";
if (user.user == null) {
Navigator.of(context).pushNamedAndRemoveUntil("login", (_) => false);
lock = false;
return Future.value();
}
if (user.user!.accessToken.replaceAll(" ", "") == "") {
String uid = user.user!.id;
user.removeUser(uid);
await Provider.of<DatabaseProvider>(context, listen: false)
.store
.removeUser(uid);
Navigator.of(context).pushNamedAndRemoveUntil("login", (_) => false);
lock = false;
return;
}
if (user.user!.accessTokenExpire.isBefore(DateTime.now())) {
String authRes = await Provider.of<KretaClient>(context, listen: false)
.refreshLogin() ??
'';
if (authRes != 'success') {
if (kDebugMode) print('ERROR: failed to refresh login');
lock = false;
return Future.value();
} else {
if (kDebugMode) print('INFO: access token refreshed');
}
} else {
if (kDebugMode) print('INFO: access token is not expired');
}
}()),
syncStatus(Provider.of<GradeProvider>(context, listen: false).fetch()),
syncStatus(Provider.of<TimetableProvider>(context, listen: false)
.fetch(week: Week.current())),
@ -121,8 +71,6 @@ Future<void> syncAll(BuildContext context) async {
if (studentJson == null) return;
Student student = Student.fromJson(studentJson);
// print(studentJson);
user.user?.name = student.name;
// Store user
@ -141,11 +89,13 @@ Future<void> syncAll(BuildContext context) async {
return false;
}
return Future.wait(tasks).then((value) {
// Unlock
lock = false;
if (Platform.isIOS && LiveCardProvider.hasActivityStarted == true) {
if(Platform.isIOS && LiveCardProvider.hasActivityStarted == true){
PlatformChannel.endLiveActivity();
LiveCardProvider.hasActivityStarted = false;
}

View File

@ -23,7 +23,6 @@ class UserProvider with ChangeNotifier {
String? get nickname => user?.nickname;
String get picture => user?.picture ?? "";
String? get displayName => user?.displayName;
int? get gradeStreak => user?.gradeStreak;
final SettingsProvider _settings;

View File

@ -31,7 +31,6 @@ import 'package:provider/provider.dart';
import 'package:refilc_mobile_ui/common/system_chrome.dart' as mobile;
import 'package:refilc_mobile_ui/screens/login/login_route.dart' as mobile;
import 'package:refilc_mobile_ui/screens/login/login_screen.dart' as mobile;
// import 'package:refilc_mobile_ui/screens/login/kreten_login.dart' as mobileTest;
import 'package:refilc_mobile_ui/screens/navigation/navigation_screen.dart'
as mobile;
import 'package:refilc_mobile_ui/screens/settings/settings_route.dart'
@ -39,11 +38,11 @@ import 'package:refilc_mobile_ui/screens/settings/settings_route.dart'
import 'package:refilc_mobile_ui/screens/settings/settings_screen.dart'
as mobile;
// Desktop UI (no more desktop ui)
// import 'package:refilc_desktop_ui/screens/navigation/navigation_screen.dart'
// as desktop;
// import 'package:refilc_desktop_ui/screens/login/login_screen.dart' as desktop;
// import 'package:refilc_desktop_ui/screens/login/login_route.dart' as desktop;
// Desktop UI
import 'package:refilc_desktop_ui/screens/navigation/navigation_screen.dart'
as desktop;
import 'package:refilc_desktop_ui/screens/login/login_screen.dart' as desktop;
import 'package:refilc_desktop_ui/screens/login/login_route.dart' as desktop;
// Providers
import 'package:refilc/models/settings.dart';
@ -81,8 +80,7 @@ class App extends StatelessWidget {
CorePalette? corePalette;
final status = StatusProvider();
final kreta = KretaClient(
user: user, settings: settings, database: database, status: status);
final kreta = KretaClient(user: user, settings: settings, status: status);
final timetable =
TimetableProvider(user: user, database: database, kreta: kreta);
final premium = PlusProvider(settings: settings);
@ -237,7 +235,7 @@ class App extends StatelessWidget {
},
onGenerateRoute: (settings) => rootNavigator(settings),
initialRoute:
(user.getUsers().isNotEmpty) ? "navigation" : "login",
user.getUsers().isNotEmpty ? "navigation" : "login",
);
},
);
@ -248,18 +246,17 @@ class App extends StatelessWidget {
Route? rootNavigator(RouteSettings route) {
if (kIsWeb) {
return null;
// 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());
// }
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());
}
} else if (Platform.isAndroid || Platform.isIOS) {
switch (route.name) {
case "login_back":
@ -275,18 +272,17 @@ class App extends StatelessWidget {
return mobile.settingsRoute(const mobile.SettingsScreen());
}
} else if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) {
return null;
// 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());
// }
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;
}

View File

@ -8,7 +8,7 @@ import 'package:refilc/models/settings.dart';
import 'package:flutter/foundation.dart';
// ignore: depend_on_referenced_packages
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
// import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
const settingsDB = DatabaseStruct("settings", {
"language": String, "start_page": int, "rounding": int, "theme": int,
@ -27,8 +27,7 @@ const settingsDB = DatabaseStruct("settings", {
"notifications_absences": int,
"notifications_messages": int,
"notifications_lessons": int, // notifications
"x_filc_id": String, "graph_class_avg": int,
"analytics_enabled": int, "presentation_mode": 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, "premium_login": String,
@ -46,7 +45,6 @@ const settingsDB = DatabaseStruct("settings", {
// more
"show_breaks": int,
"font_family": String,
"title_only_font": int,
"plus_session_id": String,
"cal_sync_room_location": String, "cal_sync_show_exams": int,
"cal_sync_show_teacher": int, "cal_sync_renamed": int,
@ -54,11 +52,6 @@ const settingsDB = DatabaseStruct("settings", {
"nav_shadow": int,
"new_colors": int,
"uwu_mode": int,
"new_popups": int,
"unseen_new_features": String,
"cloud_sync_enabled": int,
"cloud_sync_token": String,
"local_updated_at": String,
// quick settings
"q_timetable_lesson_num": int, "q_timetable_sub_tiles": int,
"q_subjects_sub_tiles": int,
@ -68,10 +61,7 @@ const settingsDB = DatabaseStruct("settings", {
const usersDB = DatabaseStruct("users", {
"id": String, "name": String, "username": String, "password": String,
"institute_code": String, "student": String, "role": int,
"nickname": String, "picture": String, // premium only (it's now plus btw)
"grade_streak": int,
"access_token": String, "access_token_expire": String,
"refresh_token": String,
"nickname": String, "picture": String // premium only
});
const userDataDB = DatabaseStruct("user_data", {
"id": String, "grades": String, "timetable": String, "exams": String,
@ -94,13 +84,12 @@ const userDataDB = DatabaseStruct("user_data", {
"goal_befores": String,
"goal_pin_dates": String,
// todo and notes
"todo_items": String, "self_notes": String, "self_todo": String,
"todo_items": String, "self_notes": String,
// v5 shit
"roundings": String,
"grade_rarities": String,
"linked_accounts": String,
"custom_lesson_desc": String,
"watch_data": String,
});
Future<void> createTable(Database db, DatabaseStruct struct) =>
@ -110,8 +99,7 @@ Future<Database> initDB(DatabaseProvider database) async {
Database db;
if (kIsWeb) {
// db = await databaseFactoryFfiWeb.openDatabase("app.db");
throw "web is not supported";
db = await databaseFactoryFfiWeb.openDatabase("app.db");
} else if (Platform.isLinux || Platform.isWindows) {
sqfliteFfiInit();
db = await databaseFactoryFfi.openDatabase("app.db");
@ -141,15 +129,7 @@ Future<Database> initDB(DatabaseProvider database) async {
await migrateDB(
db,
struct: usersDB,
defaultValues: {
"role": 0,
"nickname": "",
"picture": "",
"grade_streak": 0,
"access_token": "",
"access_token_expire": "",
"refresh_token": "",
},
defaultValues: {"role": 0, "nickname": "", "picture": ""},
);
await migrateDB(db, struct: userDataDB, defaultValues: {
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]",
@ -172,13 +152,12 @@ Future<Database> initDB(DatabaseProvider database) async {
"goal_befores": "{}",
"goal_pin_dates": "{}",
// todo and notes
"todo_items": "{}", "self_notes": "[]", "self_todo": "[]",
"todo_items": "{}", "self_notes": "[]",
// v5 shit
"roundings": "{}",
"grade_rarities": "{}",
"linked_accounts": "[]",
"custom_lesson_desc": "{}",
"watch_data": "{}",
});
} catch (error) {
print("ERROR: migrateDB: $error");

View File

@ -317,18 +317,6 @@ class UserDatabaseQuery {
return selfNotes;
}
Future<List<TodoItem>> getTodoItems({required String userId}) async {
List<Map> userData =
await db.query("user_data", where: "id = ?", whereArgs: [userId]);
if (userData.isEmpty) return [];
String? todoItemsJson = userData.elementAt(0)["self_todo"] as String?;
if (todoItemsJson == null) return [];
List<TodoItem> todoItems = (jsonDecode(todoItemsJson) as List)
.map((e) => TodoItem.fromJson(e))
.toList();
return todoItems;
}
// v5
Future<Map<String, String>> getRoundings({required String userId}) async {
List<Map> userData =

View File

@ -196,13 +196,6 @@ class UserDatabaseStore {
where: "id = ?", whereArgs: [userId]);
}
Future<void> storeSelfTodoItems(List<TodoItem> todoItems,
{required String userId}) async {
String todoItemsJson = jsonEncode(todoItems.map((e) => e.json).toList());
await db.update("user_data", {"self_todo": todoItemsJson},
where: "id = ?", whereArgs: [userId]);
}
// v5
Future<void> storeRoundings(Map<String, String> roundings,
{required String userId}) async {

View File

@ -8,10 +8,10 @@ class DatabaseStruct {
String typeName = "";
switch (type.runtimeType) {
case const (int):
case int:
typeName = "integer";
break;
case const (String):
case String:
typeName = "text";
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,10 @@ import 'package:share_plus/share_plus.dart';
class ShareHelper {
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.shareXFiles([XFile(path)], text: text, subject: subject);
// ignore: deprecated_member_use
Share.shareFiles([path], text: text, subject: subject);
static Future<void> shareAttachment(Attachment attachment,
{required BuildContext context}) async {

View File

@ -292,105 +292,3 @@ class ShortSubject {
return subject?.name.capital() ?? subjectName?.capital() ?? "?";
}
}
// new v5 thingie
class SubjectBooklet {
// static String resolveName({GradeSubject? subject, String? subjectName}) =>
// _resolve(subject: subject, subjectName: subjectName).name;
static String resolveVariant(
{GradeSubject? subject,
String? subjectName,
required BuildContext context}) =>
_resolve(subject: subject, subjectName: subjectName);
static String _resolve({GradeSubject? subject, String? subjectName}) {
assert(!(subject == null && subjectName == null));
String name = (subject?.name ?? subjectName ?? "")
.toLowerCase()
.specialChars()
.trim();
String category =
subject?.category.description.toLowerCase().specialChars() ?? "";
String basePath = "assets/svg/cover_arts";
// todo: check for categories
if (RegExp("mate(k|matika)").hasMatch(name) || category == "matematika") {
return "$basePath/grid.svg";
} else if (RegExp("magyar nyelv|nyelvtan").hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("irodalom").hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("tor(i|tenelem)").hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("foldrajz").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("rajz|muvtori|muveszet|vizualis").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("fizika").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("^enek|zene|szolfezs|zongora|korus").hasMatch(name)) {
return "$basePath/vocal.svg";
} else if (RegExp("^tes(i|tneveles)|sport|edzeselmelet").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("kemia").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("biologia").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp(
"kornyezet|termeszet ?(tudomany|ismeret)|hon( es nep)?ismeret")
.hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("(hit|erkolcs)tan|vallas|etika|bibliaismeret")
.hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("penzugy").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("informatika|szoftver|iroda|digitalis").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("prog").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("halozat").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("szinhaz").hasMatch(name)) {
return "$basePath/vocal.svg";
} else if (RegExp("film|media").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("elektro(tech)?nika").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("gepesz|mernok|ipar").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("technika").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("tanc").hasMatch(name)) {
return "$basePath/vocal.svg";
} else if (RegExp("filozofia").hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("osztaly(fonoki|kozosseg)|kozossegi|neveles")
.hasMatch(name) ||
name == "ofo") {
return "$basePath/plain.svg";
} else if (RegExp("gazdasag").hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("szorgalom").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("magatartas").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp(
"angol|nemet|francia|olasz|orosz|spanyol|latin|kinai|nyelv")
.hasMatch(name)) {
return "$basePath/line.svg";
} else if (RegExp("linux").hasMatch(name)) {
return "$basePath/plain.svg";
} else if (RegExp("adatbazis").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("asztali alkalmazasok").hasMatch(name)) {
return "$basePath/grid.svg";
} else if (RegExp("projekt").hasMatch(name)) {
return "$basePath/plain.svg";
}
return "$basePath/plain.svg";
}
}

View File

@ -1,130 +0,0 @@
import 'dart:math';
class Uwuifier {
final Map<String, double> _spacesModifier;
final double _wordsModifier;
final List<String> faces = [
"OwO",
"UwU",
">w<",
"^w^",
"^-^",
":3",
];
final List<List<String>> uwuMap = [
['(?:r|l)', 'w'],
['(?:R|L)', 'W'],
['na', 'nya'],
['ne', 'nye'],
['NA', 'NYA'],
['NE', 'NYE'],
['Na', 'Nya'],
['Ne', 'Nye'],
['no', 'nyo'],
['NO', 'NYO'],
['No', 'Nyo'],
['nO', 'NYo'],
['ove', 'uv'],
['no', 'nwo'],
];
final Map<String, String> _uwuCache = {};
Uwuifier({
Map<String, double>? spaces,
double? words,
}) : _spacesModifier = spaces ?? {
'faces': 0.05,
'actions': 0.0,
'stutters': 0.1,
},
_wordsModifier = words ?? 1.0;
String uwuifyWords(String sentence) {
final words = sentence.split(' ');
final uwuifiedSentence = words.map((word) {
if (isAt(word) || isUri(word)) return word;
var seed = Random().nextDouble();
for (final uwuMapEntry in uwuMap) {
final oldWord = RegExp(uwuMapEntry[0], caseSensitive: false);
final newWord = uwuMapEntry[1];
if (seed > _wordsModifier) continue;
word = word.replaceAll(oldWord, newWord);
}
return word;
}).join(' ');
return uwuifiedSentence;
}
String uwuifySpaces(String sentence) {
final words = sentence.split(' ');
final faceThreshold = _spacesModifier['faces']!;
final actionThreshold = _spacesModifier['actions']! + faceThreshold;
final stutterThreshold = _spacesModifier['stutters']! + actionThreshold;
final uwuifiedSentence = words.map((word) {
final seed = Random().nextDouble();
final firstCharacter = word[0];
if (seed <= faceThreshold && faces.isNotEmpty) {
word += ' ${faces[Random().nextInt(faces.length)]}';
} else if (seed <= actionThreshold) {
// Skip actions
} else if (seed <= stutterThreshold && !isUri(word)) {
if (Random().nextInt(10) == 0) {
final stutter = Random().nextInt(3);
return '${firstCharacter * (stutter + 1)}-$word';
}
}
return word;
}).join(' ');
return uwuifiedSentence;
}
String uwuifySentence(String sentence) {
if (_uwuCache.containsKey(sentence)) {
return _uwuCache[sentence]!;
}
var uwuifiedSentence = uwuifyWords(sentence);
uwuifiedSentence = uwuifySpaces(uwuifiedSentence);
_uwuCache[sentence] = uwuifiedSentence;
return uwuifiedSentence;
}
bool isAt(String value) {
return value.startsWith('@');
}
bool isUri(String? value) {
if (value == null) return false;
final split = RegExp(
r'''(?:([^:/?#]+):)?(?:\/\/([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?''')
.firstMatch(value);
if (split == null) return false;
final scheme = split.group(1);
final authority = split.group(2);
final path = split.group(3);
if (!(scheme?.isNotEmpty == true && path?.isNotEmpty == true)) return false;
if (authority != null && authority.isNotEmpty) {
if (!(path?.isEmpty == true || path!.startsWith('/'))) return false;
} else if (path?.startsWith('//') == true) {
return false;
}
if (!RegExp(r'''^[a-z][a-z0-9+\-\.]*$''', caseSensitive: false)
.hasMatch(scheme!.toLowerCase())) {
return false;
}
return true;
}
}

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