Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93eaa5a74b | ||
|
|
5503b41be3 | ||
|
|
bd716e1717 | ||
|
|
7f8b716712 | ||
|
|
1a7b59f2fc | ||
|
|
9f62e44b52 | ||
|
|
7c34552aa5 | ||
|
|
57d784443a | ||
|
|
e73ee5a1f2 | ||
|
|
4277f0662a | ||
|
|
604e9dcaad | ||
|
|
c0dd84c665 | ||
|
|
7dc33d3b87 | ||
|
|
9bee0daeb5 | ||
|
|
dd8a4430a9 | ||
|
|
47934620ea | ||
|
|
9e815aff2f | ||
|
|
d8393b24e1 | ||
|
|
1abe990847 | ||
|
|
3a92716019 | ||
|
|
9b947256c8 | ||
|
|
0586da3742 | ||
|
|
9d863e1ec0 | ||
|
|
e080800aa8 | ||
|
|
e6f7728e42 | ||
|
|
ac11da1744 | ||
|
|
cad7bd19dc | ||
|
|
e1870b08e5 | ||
|
|
7842aa447f | ||
|
|
a23b2d63e5 | ||
|
|
58faeb4fa2 | ||
|
|
48e64d7761 | ||
|
|
aef8f78d16 | ||
|
|
2b36528327 | ||
|
|
918252ae4b | ||
|
|
63c650b68d | ||
|
|
090b0ccc85 | ||
|
|
0768dc9404 | ||
|
|
d36351d76b | ||
|
|
45a8e0dd71 | ||
|
|
94da2a9756 | ||
|
|
37aa1858a8 | ||
|
|
82f8a489dd | ||
|
|
96b69b89ae | ||
|
|
d9da7625ed | ||
|
|
c016258fb9 | ||
|
|
855e48aea8 | ||
|
|
b7e83d10dc | ||
|
|
45ffdff324 | ||
|
|
cd0729fa5e | ||
|
|
30cfdfe784 | ||
|
|
16f2593d22 | ||
|
|
14ab0c4ce3 | ||
|
|
9eb1317143 | ||
|
|
910a38650d | ||
|
|
a1f166980d | ||
|
|
0598b94ab9 | ||
|
|
1310ad4f2e | ||
|
|
4d32500d90 | ||
|
|
67558b76a3 | ||
|
|
7ab8914076 | ||
|
|
b0eb819afa | ||
|
|
416f42f42d | ||
|
|
a319b26d82 | ||
|
|
84537fdcef | ||
|
|
30f24d5d33 | ||
|
|
8c118eedc1 | ||
|
|
4dbe3d07a3 | ||
|
|
f1b1b23234 | ||
|
|
540e4d2812 | ||
|
|
93dd275969 | ||
|
|
c79c45705d | ||
|
|
ce31182a5c | ||
|
|
174046f954 | ||
|
|
3fc14ffbb8 | ||
|
|
f579270886 | ||
|
|
365bd7957e | ||
|
|
d24c4ec187 | ||
|
|
75ba5405bb | ||
|
|
e0bf8ac5e5 | ||
|
|
1a3d78a5bc | ||
|
|
c205bc592c | ||
|
|
308c8f966f | ||
|
|
139ac28be6 | ||
|
|
bbe53b8c01 | ||
|
|
56a0c2c02e | ||
|
|
122a5ea210 | ||
|
|
aaa3d79b30 | ||
|
|
cacf566794 | ||
|
|
9b29ede6eb | ||
|
|
9e9e46d0f8 | ||
|
|
9901251cfc | ||
|
|
e7ec93132d | ||
|
|
7cec2ff525 | ||
|
|
2ca8f4b8fe | ||
|
|
ae66a462e7 | ||
|
|
c85f15eb49 | ||
|
|
e04cc5ea2b | ||
|
|
3ed456c01f | ||
|
|
f64b1360d9 | ||
|
|
c9db496e59 | ||
|
|
d915200faa | ||
|
|
32abfe7037 |
56
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
environment {
|
||||||
|
ANDROID_SDK = '/home/jenkins/flutter_things/android-sdk'
|
||||||
|
ANDROID_PATH="$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools"
|
||||||
|
FLUTTER = '/home/jenkins/flutter_things/flutter/bin'
|
||||||
|
PATH = "$PATH:$ANDROID_PATH:$FLUTTER"
|
||||||
|
//TODO: need to fix flutter
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Copy Key Properties') {
|
||||||
|
steps {
|
||||||
|
// Copy the key.properties file
|
||||||
|
sh 'cp /home/jenkins/key.properties refilc/android/key.properties'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Flutter Doctor') {
|
||||||
|
steps {
|
||||||
|
// Ensure Flutter is set up correctly
|
||||||
|
sh 'flutter doctor'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Dependencies') {
|
||||||
|
steps {
|
||||||
|
// Get Flutter dependencies
|
||||||
|
sh 'cd refilc && flutter pub get'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
// Build the Flutter project
|
||||||
|
sh 'cd refilc && flutter build apk --release'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Archive') {
|
||||||
|
steps {
|
||||||
|
// Archive the APK
|
||||||
|
archiveArtifacts artifacts: 'build/app/outputs/flutter-apk/app-release.apk', fingerprint: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
// Clean up workspace after build
|
||||||
|
cleanWs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="1."
|
android:text="1."
|
||||||
android:textColor="@color/filc"
|
android:textColor="@color/filc"
|
||||||
android:textColorLink="#ff3D7BF4"
|
android:textColorLink="#ff052460"
|
||||||
android:textSize="30sp"
|
android:textSize="30sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
@@ -110,4 +110,4 @@
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
<color name="yellow_light">#ffFFCC00</color>
|
<color name="yellow_light">#ffFFCC00</color>
|
||||||
<color name="light_yellow_light">#40FFD60A</color>
|
<color name="light_yellow_light">#40FFD60A</color>
|
||||||
<color name="green_light">#ff34C759</color>
|
<color name="green_light">#ff34C759</color>
|
||||||
<color name="filc_light">#ff3D7BF4</color>
|
<color name="filc_light">#ff052460</color>
|
||||||
<color name="teal_light">#ff5AC8FA</color>
|
<color name="teal_light">#ff5AC8FA</color>
|
||||||
<color name="blue_light">#ff007AFF</color>
|
<color name="blue_light">#ff007AFF</color>
|
||||||
<color name="indigo_light">#ff5856D6</color>
|
<color name="indigo_light">#ff5856D6</color>
|
||||||
@@ -49,8 +49,8 @@
|
|||||||
<color name="yellow">#ffFFD60A</color>
|
<color name="yellow">#ffFFD60A</color>
|
||||||
<color name="light_yellow">#40FFD60A</color>
|
<color name="light_yellow">#40FFD60A</color>
|
||||||
<color name="green">#ff32D74B</color>
|
<color name="green">#ff32D74B</color>
|
||||||
<color name="filc">#ff3D7BF4</color>
|
<color name="filc">#ff052460</color>
|
||||||
<color name="filc_gradient">#ff3D93F5</color>
|
<color name="filc_gradient">#ff06348f</color>
|
||||||
<color name="teal">#ff64D2FF</color>
|
<color name="teal">#ff64D2FF</color>
|
||||||
<color name="blue">#ff0A84FF</color>
|
<color name="blue">#ff0A84FF</color>
|
||||||
<color name="indigo">#ff5E5CE6</color>
|
<color name="indigo">#ff5E5CE6</color>
|
||||||
@@ -66,4 +66,4 @@
|
|||||||
<color name="pink_shade300">#FFF06292</color>
|
<color name="pink_shade300">#FFF06292</color>
|
||||||
<color name="purple_shade300">#FFBA68C8</color>
|
<color name="purple_shade300">#FFBA68C8</color>
|
||||||
<color name="teal_shade300">#FF22AC9B</color>
|
<color name="teal_shade300">#FF22AC9B</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
43
refilc/assets/svg/cover_arts/grid.svg
Normal 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_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>
|
||||||
|
After Width: | Height: | Size: 2.8 KiB |
27
refilc/assets/svg/cover_arts/line.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
47
refilc/assets/svg/cover_arts/plain.svg
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
28
refilc/assets/svg/cover_arts/vocal.svg
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 973 B |
@@ -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_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>
|
|
||||||
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -517,7 +517,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 255;
|
CURRENT_PROJECT_VERSION = 257;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -549,7 +549,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 255;
|
CURRENT_PROJECT_VERSION = 257;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -591,7 +591,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 255;
|
CURRENT_PROJECT_VERSION = 257;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -631,7 +631,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
CODE_SIGN_ENTITLEMENTS = livecard/livecard.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 255;
|
CURRENT_PROJECT_VERSION = 257;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -775,7 +775,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 255;
|
CURRENT_PROJECT_VERSION = 257;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -803,7 +803,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 255;
|
CURRENT_PROJECT_VERSION = 257;
|
||||||
DEVELOPMENT_TEAM = 4DKAF249F3;
|
DEVELOPMENT_TEAM = 4DKAF249F3;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "reFilc_Logo.png",
|
"filename" : "rf_1024.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 577 KiB |
BIN
refilc/ios/Runner/Assets.xcassets/AppIcon.appiconset/rf_1024.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
@@ -52,14 +52,31 @@ struct LockScreenLiveActivityView: View {
|
|||||||
VStack(alignment: .center) {
|
VStack(alignment: .center) {
|
||||||
// Jelenlegi óra
|
// Jelenlegi óra
|
||||||
VStack {
|
VStack {
|
||||||
Text(context.state.index + " " + context.state.title)
|
if(context.state.title.contains("Az első órádig")) {
|
||||||
.font(.body)
|
Text(context.state.title)
|
||||||
.bold()
|
.font(.system(size: 15))
|
||||||
.multilineTextAlignment(.center)
|
.bold()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
} else if(context.state.title == "Szünet") {
|
||||||
|
Text(context.state.title)
|
||||||
|
.font(.body)
|
||||||
|
.bold()
|
||||||
|
.padding(.trailing, 90)
|
||||||
|
|
||||||
Text("Terem: \(context.state.subtitle)")
|
} else {
|
||||||
.italic()
|
MultilineTextView(text: "\(context.state.index) \(context.state.title)", limit: 25)
|
||||||
.font(.caption)
|
.font(.body)
|
||||||
|
.bold()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Terem
|
||||||
|
if (!context.state.subtitle.isEmpty) {
|
||||||
|
Text(context.state.subtitle)
|
||||||
|
.italic()
|
||||||
|
.bold()
|
||||||
|
.font(.system(size: 13))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leírás
|
// Leírás
|
||||||
@@ -69,6 +86,7 @@ struct LockScreenLiveActivityView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Következő óra
|
// Következő óra
|
||||||
|
if(context.state.nextSubject != "" && context.state.nextRoom != "") {
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "arrow.right")
|
Image(systemName: "arrow.right")
|
||||||
.resizable()
|
.resizable()
|
||||||
@@ -80,18 +98,24 @@ struct LockScreenLiveActivityView: View {
|
|||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
}
|
}
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
|
} else {
|
||||||
|
Spacer(minLength: 5)
|
||||||
|
Text("Ez az utolsó óra! Kitartást!")
|
||||||
|
.font(.system(size: 15))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.padding(15)
|
.padding(15)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
// Visszaszámláló
|
// Visszaszámláló
|
||||||
Text(timerInterval: context.state.date, countsDown: true)
|
Text(timerInterval: context.state.date, countsDown: true)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.frame(width: 85)
|
.frame(width: 85)
|
||||||
.font(.title2)
|
.font(.title2)
|
||||||
.monospacedDigit()
|
.monospacedDigit()
|
||||||
.padding(.trailing, CGFloat(24))
|
.padding(.trailing)
|
||||||
}
|
}
|
||||||
.activityBackgroundTint(
|
.activityBackgroundTint(
|
||||||
context.state.color != "#676767"
|
context.state.color != "#676767"
|
||||||
@@ -109,7 +133,7 @@ struct LiveCardWidget: Widget {
|
|||||||
LockScreenLiveActivityView(context: context)
|
LockScreenLiveActivityView(context: context)
|
||||||
/// Dynamic Island
|
/// Dynamic Island
|
||||||
} dynamicIsland: { context in
|
} dynamicIsland: { context in
|
||||||
|
|
||||||
/// Expanded
|
/// Expanded
|
||||||
return DynamicIsland {
|
return DynamicIsland {
|
||||||
DynamicIslandExpandedRegion(.leading) {
|
DynamicIslandExpandedRegion(.leading) {
|
||||||
@@ -133,39 +157,95 @@ struct LiveCardWidget: Widget {
|
|||||||
).progressViewStyle(.circular)
|
).progressViewStyle(.circular)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicIslandExpandedRegion(.center) {
|
DynamicIslandExpandedRegion(.center) {
|
||||||
VStack(alignment: .center) {
|
VStack(alignment: .center) {
|
||||||
Text(context.state.index + context.state.title)
|
// Első óra előtti expanded DynamicIsland
|
||||||
.lineLimit(1)
|
if(context.state.title.contains("Az első órádig")) {
|
||||||
.font(.body)
|
Text("Az első órád:")
|
||||||
.bold()
|
.font(.body)
|
||||||
|
.bold()
|
||||||
Text(context.state.subtitle)
|
.padding(.trailing, -15)
|
||||||
.lineLimit(1)
|
MultilineTextView(text: "\(context.state.nextSubject)", limit: 25)
|
||||||
.font(.subheadline)
|
.font(.body)
|
||||||
Spacer()
|
.padding(.trailing, -25)
|
||||||
|
|
||||||
Text(context.state.description)
|
Text("Ebben a teremben:")
|
||||||
.lineLimit(2)
|
.font(.body)
|
||||||
.font(.caption)
|
.bold()
|
||||||
}.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0))
|
.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)
|
||||||
|
.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)
|
||||||
|
.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)", limit: 25)
|
||||||
|
.lineLimit(1)
|
||||||
|
.font(.body)
|
||||||
|
.bold()
|
||||||
|
.padding(.trailing, -35)
|
||||||
|
|
||||||
|
Text(context.state.subtitle)
|
||||||
|
.lineLimit(1)
|
||||||
|
.italic()
|
||||||
|
.bold()
|
||||||
|
.font(.system(size: 13))
|
||||||
|
.padding(.trailing, -50)
|
||||||
|
|
||||||
|
Spacer(minLength: 5)
|
||||||
|
|
||||||
|
if(context.state.nextRoom != "" && context.state.nextSubject != "") {
|
||||||
|
Text("Következő óra és terem:")
|
||||||
|
.font(.system(size: 14))
|
||||||
|
.padding(.trailing, -35)
|
||||||
|
Spacer(minLength: 2)
|
||||||
|
Text(context.state.nextSubject)
|
||||||
|
.modifier(DynamicFontSizeModifier(text: context.state.nextSubject))
|
||||||
|
.padding(.trailing, -35)
|
||||||
|
Text(context.state.nextRoom)
|
||||||
|
// ignore: based on nextSubject characters, I check that the font size of the room is the same as the next subject.
|
||||||
|
.modifier(DynamicFontSizeModifier(text: context.state.nextSubject))
|
||||||
|
.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
|
/// Compact
|
||||||
} compactLeading: {
|
} compactLeading: {
|
||||||
Label {
|
Image(systemName: context.state.icon)
|
||||||
Text(context.state.title)
|
|
||||||
} icon: {
|
|
||||||
Image(systemName: context.state.icon)
|
|
||||||
}
|
|
||||||
.font(.caption2)
|
|
||||||
}
|
}
|
||||||
compactTrailing: {
|
compactTrailing: {
|
||||||
Text(timerInterval: context.state.date, countsDown: true)
|
Text(timerInterval: context.state.date, countsDown: true)
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
.frame(width: 40)
|
.frame(width: 40)
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
|
|
||||||
/// Collapsed
|
/// Collapsed
|
||||||
} minimal: {
|
} minimal: {
|
||||||
VStack(alignment: .center, content: {
|
VStack(alignment: .center, content: {
|
||||||
@@ -191,7 +271,59 @@ struct LiveCardWidget: Widget {
|
|||||||
context.state.color != "#676767"
|
context.state.color != "#676767"
|
||||||
? Color(hex: context.state.color)
|
? Color(hex: context.state.color)
|
||||||
: Color.clear
|
: Color.clear
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,6 +336,8 @@ class FilcAPI {
|
|||||||
|
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
return (jsonDecode(res.body) as Map);
|
return (jsonDecode(res.body) as Map);
|
||||||
|
} else if (res.statusCode == 404) {
|
||||||
|
return {"public_id": ""};
|
||||||
} else {
|
} else {
|
||||||
throw "HTTP ${res.statusCode}: ${res.body}";
|
throw "HTTP ${res.statusCode}: ${res.body}";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,24 +88,24 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
case LiveCardState.morning:
|
case LiveCardState.morning:
|
||||||
return {
|
return {
|
||||||
"color":
|
"color":
|
||||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||||
"icon": nextLesson != null
|
"icon": nextLesson != null
|
||||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||||
: "book",
|
: "book",
|
||||||
"title": "Első órádig:",
|
"title": "Jó reggelt! Az első órádig:",
|
||||||
"subtitle": "",
|
"subtitle": "",
|
||||||
"description": "",
|
"description": "",
|
||||||
"startDate": storeFirstRunDate != null
|
"startDate": storeFirstRunDate != null
|
||||||
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
||||||
(_delay.inMilliseconds))
|
(_delay.inMilliseconds))
|
||||||
.toString()
|
.toString()
|
||||||
: "",
|
: "",
|
||||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": nextLesson != null
|
"nextSubject": nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ??
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
: "",
|
: "",
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
};
|
};
|
||||||
@@ -113,24 +113,24 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
case LiveCardState.afternoon:
|
case LiveCardState.afternoon:
|
||||||
return {
|
return {
|
||||||
"color":
|
"color":
|
||||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||||
"icon": nextLesson != null
|
"icon": nextLesson != null
|
||||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||||
: "book",
|
: "book",
|
||||||
"title": "Első órádig:",
|
"title": "Jó napot! Az első órádig:",
|
||||||
"subtitle": "",
|
"subtitle": "",
|
||||||
"description": "",
|
"description": "",
|
||||||
"startDate": storeFirstRunDate != null
|
"startDate": storeFirstRunDate != null
|
||||||
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
||||||
(_delay.inMilliseconds))
|
(_delay.inMilliseconds))
|
||||||
.toString()
|
.toString()
|
||||||
: "",
|
: "",
|
||||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": nextLesson != null
|
"nextSubject": nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ??
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
: "",
|
: "",
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
};
|
};
|
||||||
@@ -138,24 +138,24 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
case LiveCardState.night:
|
case LiveCardState.night:
|
||||||
return {
|
return {
|
||||||
"color":
|
"color":
|
||||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||||
"icon": nextLesson != null
|
"icon": nextLesson != null
|
||||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||||
: "book",
|
: "book",
|
||||||
"title": "Első órádig:",
|
"title": "Jó estét! Az első órádig:",
|
||||||
"subtitle": "",
|
"subtitle": "",
|
||||||
"description": "",
|
"description": "",
|
||||||
"startDate": storeFirstRunDate != null
|
"startDate": storeFirstRunDate != null
|
||||||
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
||||||
(_delay.inMilliseconds))
|
(_delay.inMilliseconds))
|
||||||
.toString()
|
.toString()
|
||||||
: "",
|
: "",
|
||||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": nextLesson != null
|
"nextSubject": nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ??
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
: "",
|
: "",
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
};
|
};
|
||||||
@@ -163,28 +163,28 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
case LiveCardState.duringLesson:
|
case LiveCardState.duringLesson:
|
||||||
return {
|
return {
|
||||||
"color":
|
"color":
|
||||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||||
"icon": currentLesson != null
|
"icon": currentLesson != null
|
||||||
? SubjectIcon.resolveName(subject: currentLesson?.subject)
|
? SubjectIcon.resolveName(subject: currentLesson?.subject)
|
||||||
: "book",
|
: "book",
|
||||||
"index":
|
"index":
|
||||||
currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
||||||
"title": currentLesson != null
|
"title": currentLesson != null
|
||||||
? currentLesson?.subject.renamedTo ??
|
? currentLesson?.subject.renamedTo ??
|
||||||
ShortSubject.resolve(subject: currentLesson?.subject)
|
ShortSubject.resolve(subject: currentLesson?.subject)
|
||||||
.capital()
|
.capital()
|
||||||
: "",
|
: "",
|
||||||
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
|
"subtitle": "Terem: ${currentLesson?.room.replaceAll("_", " ") ?? ""}",
|
||||||
"description": currentLesson?.description ?? "",
|
"description": currentLesson?.description ?? "",
|
||||||
"startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) -
|
"startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) -
|
"endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": nextLesson != null
|
"nextSubject": nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ??
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||||
: "",
|
: "",
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
};
|
};
|
||||||
@@ -200,23 +200,23 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"color":
|
"color":
|
||||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||||
"icon": iconFloorMap[diff] ?? "cup.and.saucer",
|
"icon": iconFloorMap[diff] ?? "cup.and.saucer",
|
||||||
"title": "Szünet",
|
"title": "Szünet",
|
||||||
"description": "go $diff".i18n.fill([
|
"description": "go $diff".i18n.fill([
|
||||||
diff != "to room" ? (nextLesson!.getFloor() ?? 0) : nextLesson!.room
|
diff != "to room" ? (nextLesson!.getFloor() ?? 0) : nextLesson!.room
|
||||||
]),
|
]),
|
||||||
"startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) -
|
"startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||||
_delay.inMilliseconds)
|
_delay.inMilliseconds)
|
||||||
.toString(),
|
.toString(),
|
||||||
"nextSubject": (nextLesson != null
|
"nextSubject": (nextLesson != null
|
||||||
? nextLesson?.subject.renamedTo ??
|
? nextLesson?.subject.renamedTo ??
|
||||||
ShortSubject.resolve(subject: nextLesson?.subject)
|
ShortSubject.resolve(subject: nextLesson?.subject)
|
||||||
.capital()
|
.capital()
|
||||||
: "")
|
: "")
|
||||||
.capital(),
|
.capital(),
|
||||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||||
"index": "",
|
"index": "",
|
||||||
@@ -243,8 +243,8 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
DateTime now = _now().add(_delay);
|
DateTime now = _now().add(_delay);
|
||||||
|
|
||||||
if ((currentState == LiveCardState.morning ||
|
if ((currentState == LiveCardState.morning ||
|
||||||
currentState == LiveCardState.afternoon ||
|
currentState == LiveCardState.afternoon ||
|
||||||
currentState == LiveCardState.night) &&
|
currentState == LiveCardState.night) &&
|
||||||
storeFirstRunDate == null) {
|
storeFirstRunDate == null) {
|
||||||
storeFirstRunDate = now;
|
storeFirstRunDate = now;
|
||||||
}
|
}
|
||||||
@@ -253,9 +253,9 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
// Filter label lessons #128
|
// Filter label lessons #128
|
||||||
today = today
|
today = today
|
||||||
.where((lesson) =>
|
.where((lesson) =>
|
||||||
lesson.status?.name != "Elmaradt" &&
|
lesson.status?.name != "Elmaradt" &&
|
||||||
lesson.subject.id != '' &&
|
lesson.subject.id != '' &&
|
||||||
!lesson.isEmpty)
|
!lesson.isEmpty)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (today.isNotEmpty) {
|
if (today.isNotEmpty) {
|
||||||
@@ -263,7 +263,7 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
today.sort((a, b) => a.start.compareTo(b.start));
|
today.sort((a, b) => a.start.compareTo(b.start));
|
||||||
|
|
||||||
final _lesson = today.firstWhere(
|
final _lesson = today.firstWhere(
|
||||||
(l) => l.start.isBefore(now) && l.end.isAfter(now),
|
(l) => l.start.isBefore(now) && l.end.isAfter(now),
|
||||||
orElse: () => Lesson.fromJson({}));
|
orElse: () => Lesson.fromJson({}));
|
||||||
|
|
||||||
if (_lesson.start.year != 0) {
|
if (_lesson.start.year != 0) {
|
||||||
@@ -328,7 +328,7 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
hasActivityStarted = true;
|
hasActivityStarted = true;
|
||||||
} else if (!hasActivityStarted &&
|
} else if (!hasActivityStarted &&
|
||||||
((currentState == LiveCardState.duringLesson &&
|
((currentState == LiveCardState.duringLesson &&
|
||||||
currentLesson != null) ||
|
currentLesson != null) ||
|
||||||
currentState == LiveCardState.duringBreak)) {
|
currentState == LiveCardState.duringBreak)) {
|
||||||
debugPrint("Óra van, vagy szünet, de nincs LiveActivity. létrehozás...");
|
debugPrint("Óra van, vagy szünet, de nincs LiveActivity. létrehozás...");
|
||||||
PlatformChannel.createLiveActivity(toMap());
|
PlatformChannel.createLiveActivity(toMap());
|
||||||
@@ -362,7 +362,12 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//END
|
//END
|
||||||
if (hasActivityStarted &&
|
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 &&
|
||||||
!hasDayEnd &&
|
!hasDayEnd &&
|
||||||
nextLesson == null &&
|
nextLesson == null &&
|
||||||
now.isAfter(prevLesson!.end)) {
|
now.isAfter(prevLesson!.end)) {
|
||||||
@@ -384,4 +389,4 @@ class LiveCardProvider extends ChangeNotifier {
|
|||||||
List<Lesson> _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? [])
|
List<Lesson> _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? [])
|
||||||
.where((l) => _sameDate(l.date, _now()))
|
.where((l) => _sameDate(l.date, _now()))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
@@ -7,17 +7,23 @@ import 'package:provider/provider.dart';
|
|||||||
|
|
||||||
class SelfNoteProvider with ChangeNotifier {
|
class SelfNoteProvider with ChangeNotifier {
|
||||||
late List<SelfNote> _notes;
|
late List<SelfNote> _notes;
|
||||||
|
late List<TodoItem> _todoItems;
|
||||||
late BuildContext _context;
|
late BuildContext _context;
|
||||||
|
|
||||||
List<SelfNote> get notes => _notes;
|
List<SelfNote> get notes => _notes;
|
||||||
|
List<TodoItem> get todos => _todoItems;
|
||||||
|
|
||||||
SelfNoteProvider({
|
SelfNoteProvider({
|
||||||
List<SelfNote> initialNotes = const [],
|
List<SelfNote> initialNotes = const [],
|
||||||
|
List<TodoItem> initialTodoItems = const [],
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
}) {
|
}) {
|
||||||
_notes = List.castFrom(initialNotes);
|
_notes = List.castFrom(initialNotes);
|
||||||
|
_todoItems = List.castFrom(initialTodoItems);
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
||||||
if (_notes.isEmpty) restore();
|
if (_notes.isEmpty) restore();
|
||||||
|
if (_todoItems.isEmpty) restoreTodo();
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore self notes from db
|
// restore self notes from db
|
||||||
@@ -38,6 +44,24 @@ 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)
|
// fetches fresh data from api (not needed, cuz no api for that)
|
||||||
// Future<void> fetch() async {
|
// Future<void> fetch() async {
|
||||||
// }
|
// }
|
||||||
@@ -54,4 +78,17 @@ class SelfNoteProvider with ChangeNotifier {
|
|||||||
_notes = notes;
|
_notes = notes;
|
||||||
notifyListeners();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class UserProvider with ChangeNotifier {
|
|||||||
String? get nickname => user?.nickname;
|
String? get nickname => user?.nickname;
|
||||||
String get picture => user?.picture ?? "";
|
String get picture => user?.picture ?? "";
|
||||||
String? get displayName => user?.displayName;
|
String? get displayName => user?.displayName;
|
||||||
|
int? get gradeStreak => user?.gradeStreak;
|
||||||
|
|
||||||
final SettingsProvider _settings;
|
final SettingsProvider _settings;
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const settingsDB = DatabaseStruct("settings", {
|
|||||||
// more
|
// more
|
||||||
"show_breaks": int,
|
"show_breaks": int,
|
||||||
"font_family": String,
|
"font_family": String,
|
||||||
|
"title_only_font": int,
|
||||||
"plus_session_id": String,
|
"plus_session_id": String,
|
||||||
"cal_sync_room_location": String, "cal_sync_show_exams": int,
|
"cal_sync_room_location": String, "cal_sync_show_exams": int,
|
||||||
"cal_sync_show_teacher": int, "cal_sync_renamed": int,
|
"cal_sync_show_teacher": int, "cal_sync_renamed": int,
|
||||||
@@ -52,6 +53,7 @@ const settingsDB = DatabaseStruct("settings", {
|
|||||||
"nav_shadow": int,
|
"nav_shadow": int,
|
||||||
"new_colors": int,
|
"new_colors": int,
|
||||||
"uwu_mode": int,
|
"uwu_mode": int,
|
||||||
|
"new_popups": int,
|
||||||
// quick settings
|
// quick settings
|
||||||
"q_timetable_lesson_num": int, "q_timetable_sub_tiles": int,
|
"q_timetable_lesson_num": int, "q_timetable_sub_tiles": int,
|
||||||
"q_subjects_sub_tiles": int,
|
"q_subjects_sub_tiles": int,
|
||||||
@@ -61,7 +63,8 @@ const settingsDB = DatabaseStruct("settings", {
|
|||||||
const usersDB = DatabaseStruct("users", {
|
const usersDB = DatabaseStruct("users", {
|
||||||
"id": String, "name": String, "username": String, "password": String,
|
"id": String, "name": String, "username": String, "password": String,
|
||||||
"institute_code": String, "student": String, "role": int,
|
"institute_code": String, "student": String, "role": int,
|
||||||
"nickname": String, "picture": String // premium only
|
"nickname": String, "picture": String, // premium only (it's now plus btw)
|
||||||
|
"grade_streak": int,
|
||||||
});
|
});
|
||||||
const userDataDB = DatabaseStruct("user_data", {
|
const userDataDB = DatabaseStruct("user_data", {
|
||||||
"id": String, "grades": String, "timetable": String, "exams": String,
|
"id": String, "grades": String, "timetable": String, "exams": String,
|
||||||
@@ -84,12 +87,13 @@ const userDataDB = DatabaseStruct("user_data", {
|
|||||||
"goal_befores": String,
|
"goal_befores": String,
|
||||||
"goal_pin_dates": String,
|
"goal_pin_dates": String,
|
||||||
// todo and notes
|
// todo and notes
|
||||||
"todo_items": String, "self_notes": String,
|
"todo_items": String, "self_notes": String, "self_todo": String,
|
||||||
// v5 shit
|
// v5 shit
|
||||||
"roundings": String,
|
"roundings": String,
|
||||||
"grade_rarities": String,
|
"grade_rarities": String,
|
||||||
"linked_accounts": String,
|
"linked_accounts": String,
|
||||||
"custom_lesson_desc": String,
|
"custom_lesson_desc": String,
|
||||||
|
"watch_data": String,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> createTable(Database db, DatabaseStruct struct) =>
|
Future<void> createTable(Database db, DatabaseStruct struct) =>
|
||||||
@@ -129,7 +133,12 @@ Future<Database> initDB(DatabaseProvider database) async {
|
|||||||
await migrateDB(
|
await migrateDB(
|
||||||
db,
|
db,
|
||||||
struct: usersDB,
|
struct: usersDB,
|
||||||
defaultValues: {"role": 0, "nickname": "", "picture": ""},
|
defaultValues: {
|
||||||
|
"role": 0,
|
||||||
|
"nickname": "",
|
||||||
|
"picture": "",
|
||||||
|
"grade_streak": 0
|
||||||
|
},
|
||||||
);
|
);
|
||||||
await migrateDB(db, struct: userDataDB, defaultValues: {
|
await migrateDB(db, struct: userDataDB, defaultValues: {
|
||||||
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]",
|
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]",
|
||||||
@@ -152,12 +161,13 @@ Future<Database> initDB(DatabaseProvider database) async {
|
|||||||
"goal_befores": "{}",
|
"goal_befores": "{}",
|
||||||
"goal_pin_dates": "{}",
|
"goal_pin_dates": "{}",
|
||||||
// todo and notes
|
// todo and notes
|
||||||
"todo_items": "{}", "self_notes": "[]",
|
"todo_items": "{}", "self_notes": "[]", "self_todo": "[]",
|
||||||
// v5 shit
|
// v5 shit
|
||||||
"roundings": "{}",
|
"roundings": "{}",
|
||||||
"grade_rarities": "{}",
|
"grade_rarities": "{}",
|
||||||
"linked_accounts": "[]",
|
"linked_accounts": "[]",
|
||||||
"custom_lesson_desc": "{}",
|
"custom_lesson_desc": "{}",
|
||||||
|
"watch_data": "{}",
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
print("ERROR: migrateDB: $error");
|
print("ERROR: migrateDB: $error");
|
||||||
|
|||||||
@@ -317,6 +317,18 @@ class UserDatabaseQuery {
|
|||||||
return selfNotes;
|
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
|
// v5
|
||||||
Future<Map<String, String>> getRoundings({required String userId}) async {
|
Future<Map<String, String>> getRoundings({required String userId}) async {
|
||||||
List<Map> userData =
|
List<Map> userData =
|
||||||
|
|||||||
@@ -196,6 +196,13 @@ class UserDatabaseStore {
|
|||||||
where: "id = ?", whereArgs: [userId]);
|
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
|
// v5
|
||||||
Future<void> storeRoundings(Map<String, String> roundings,
|
Future<void> storeRoundings(Map<String, String> roundings,
|
||||||
{required String userId}) async {
|
{required String userId}) async {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:refilc_kreta_api/models/message.dart';
|
import 'package:refilc_kreta_api/models/message.dart';
|
||||||
|
|
||||||
// if you want to add a new category, also add it to the DB or else the app will probably crash
|
// if you want to add a new category, also add it to the DB or else the app will probably crash
|
||||||
enum LastSeenCategory {
|
enum LastSeenCategory {
|
||||||
grade,
|
grade,
|
||||||
surprisegrade,
|
surprisegrade,
|
||||||
absence,
|
absence,
|
||||||
@@ -212,7 +212,7 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
|||||||
),
|
),
|
||||||
notificationDetails,
|
notificationDetails,
|
||||||
payload: "grades");
|
payload: "grades");
|
||||||
} else if (settingsProvider.gradeOpeningFun) {
|
} else if (settingsProvider.gradeOpeningFun) {
|
||||||
// if surprise grades are enabled, show a notification without the grade
|
// if surprise grades are enabled, show a notification without the grade
|
||||||
await flutterLocalNotificationsPlugin.show(
|
await flutterLocalNotificationsPlugin.show(
|
||||||
grade.id.hashCode,
|
grade.id.hashCode,
|
||||||
@@ -485,9 +485,10 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
|||||||
lesson.lessonIndex,
|
lesson.lessonIndex,
|
||||||
lesson.name,
|
lesson.name,
|
||||||
dayTitle(lesson.date),
|
dayTitle(lesson.date),
|
||||||
lesson.substituteTeacher!.isRenamed
|
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||||
? lesson.substituteTeacher!.renamedTo!
|
? lesson.substituteTeacher?.renamedTo!
|
||||||
: lesson.substituteTeacher!.name
|
: lesson.substituteTeacher?.name) ??
|
||||||
|
'',
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
notificationDetails,
|
notificationDetails,
|
||||||
@@ -505,9 +506,10 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
|||||||
dayTitle(lesson.date),
|
dayTitle(lesson.date),
|
||||||
lesson.lessonIndex,
|
lesson.lessonIndex,
|
||||||
lesson.name,
|
lesson.name,
|
||||||
lesson.substituteTeacher!.isRenamed
|
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||||
? lesson.substituteTeacher!.renamedTo!
|
? lesson.substituteTeacher?.renamedTo!
|
||||||
: lesson.substituteTeacher!.name
|
: lesson.substituteTeacher?.name) ??
|
||||||
|
'',
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
notificationDetails,
|
notificationDetails,
|
||||||
@@ -525,9 +527,10 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
|||||||
lesson.lessonIndex,
|
lesson.lessonIndex,
|
||||||
lesson.name,
|
lesson.name,
|
||||||
dayTitle(lesson.date),
|
dayTitle(lesson.date),
|
||||||
lesson.substituteTeacher!.isRenamed
|
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||||
? lesson.substituteTeacher!.renamedTo!
|
? lesson.substituteTeacher?.renamedTo!
|
||||||
: lesson.substituteTeacher!.name
|
: lesson.substituteTeacher?.name) ??
|
||||||
|
'',
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
notificationDetails,
|
notificationDetails,
|
||||||
@@ -608,9 +611,10 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
|||||||
lesson.lessonIndex,
|
lesson.lessonIndex,
|
||||||
lesson.name,
|
lesson.name,
|
||||||
dayTitle(lesson.date),
|
dayTitle(lesson.date),
|
||||||
lesson.substituteTeacher!.isRenamed
|
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||||
? lesson.substituteTeacher!.renamedTo!
|
? lesson.substituteTeacher?.renamedTo!
|
||||||
: lesson.substituteTeacher!.name
|
: lesson.substituteTeacher?.name) ??
|
||||||
|
'',
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
notificationDetails,
|
notificationDetails,
|
||||||
@@ -629,9 +633,10 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
|||||||
dayTitle(lesson.date),
|
dayTitle(lesson.date),
|
||||||
lesson.lessonIndex,
|
lesson.lessonIndex,
|
||||||
lesson.name,
|
lesson.name,
|
||||||
lesson.substituteTeacher!.isRenamed
|
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||||
? lesson.substituteTeacher!.renamedTo!
|
? lesson.substituteTeacher?.renamedTo!
|
||||||
: lesson.substituteTeacher!.name
|
: lesson.substituteTeacher?.name) ??
|
||||||
|
'',
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
notificationDetails,
|
notificationDetails,
|
||||||
|
|||||||
@@ -292,3 +292,105 @@ class ShortSubject {
|
|||||||
return subject?.name.capital() ?? subjectName?.capital() ?? "?";
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
130
refilc/lib/helpers/uwu_helper.dart
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,3 +33,37 @@ class SelfNote {
|
|||||||
'note_type': noteType == NoteType.image ? 'image' : 'text',
|
'note_type': noteType == NoteType.image ? 'image' : 'text',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TodoItem {
|
||||||
|
String id;
|
||||||
|
String title;
|
||||||
|
String content;
|
||||||
|
bool done;
|
||||||
|
|
||||||
|
Map? json;
|
||||||
|
|
||||||
|
TodoItem({
|
||||||
|
required this.id,
|
||||||
|
required this.title,
|
||||||
|
required this.content,
|
||||||
|
required this.done,
|
||||||
|
this.json,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TodoItem.fromJson(Map json) {
|
||||||
|
return TodoItem(
|
||||||
|
id: json['id'],
|
||||||
|
title: json['title'],
|
||||||
|
content: json['content'],
|
||||||
|
done: json['done'],
|
||||||
|
json: json,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get toJson => {
|
||||||
|
'id': id,
|
||||||
|
'title': title,
|
||||||
|
'content': content,
|
||||||
|
'done': done,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
// more
|
// more
|
||||||
bool _showBreaks;
|
bool _showBreaks;
|
||||||
String _fontFamily;
|
String _fontFamily;
|
||||||
|
bool _titleOnlyFont;
|
||||||
String _plusSessionId;
|
String _plusSessionId;
|
||||||
String _calSyncRoomLocation;
|
String _calSyncRoomLocation;
|
||||||
bool _calSyncShowExams;
|
bool _calSyncShowExams;
|
||||||
@@ -105,6 +106,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
bool _navShadow;
|
bool _navShadow;
|
||||||
bool _newColors;
|
bool _newColors;
|
||||||
bool _uwuMode;
|
bool _uwuMode;
|
||||||
|
bool _newPopups;
|
||||||
// quick settings
|
// quick settings
|
||||||
bool _qTimetableLessonNum;
|
bool _qTimetableLessonNum;
|
||||||
bool _qTimetableSubTiles;
|
bool _qTimetableSubTiles;
|
||||||
@@ -167,6 +169,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
required String pinSetNotify,
|
required String pinSetNotify,
|
||||||
required String pinSetExtras,
|
required String pinSetExtras,
|
||||||
required String fontFamily,
|
required String fontFamily,
|
||||||
|
required bool titleOnlyFont,
|
||||||
required String plusSessionId,
|
required String plusSessionId,
|
||||||
required String calSyncRoomLocation,
|
required String calSyncRoomLocation,
|
||||||
required bool calSyncShowExams,
|
required bool calSyncShowExams,
|
||||||
@@ -176,6 +179,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
required bool navShadow,
|
required bool navShadow,
|
||||||
required bool newColors,
|
required bool newColors,
|
||||||
required bool uwuMode,
|
required bool uwuMode,
|
||||||
|
required bool newPopups,
|
||||||
required bool qTimetableLessonNum,
|
required bool qTimetableLessonNum,
|
||||||
required bool qTimetableSubTiles,
|
required bool qTimetableSubTiles,
|
||||||
required bool qSubjectsSubTiles,
|
required bool qSubjectsSubTiles,
|
||||||
@@ -235,6 +239,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
_pinSetNotify = pinSetNotify,
|
_pinSetNotify = pinSetNotify,
|
||||||
_pinSetExtras = pinSetExtras,
|
_pinSetExtras = pinSetExtras,
|
||||||
_fontFamily = fontFamily,
|
_fontFamily = fontFamily,
|
||||||
|
_titleOnlyFont = titleOnlyFont,
|
||||||
_plusSessionId = plusSessionId,
|
_plusSessionId = plusSessionId,
|
||||||
_calSyncRoomLocation = calSyncRoomLocation,
|
_calSyncRoomLocation = calSyncRoomLocation,
|
||||||
_calSyncShowExams = calSyncShowExams,
|
_calSyncShowExams = calSyncShowExams,
|
||||||
@@ -244,6 +249,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
_navShadow = navShadow,
|
_navShadow = navShadow,
|
||||||
_newColors = newColors,
|
_newColors = newColors,
|
||||||
_uwuMode = uwuMode,
|
_uwuMode = uwuMode,
|
||||||
|
_newPopups = newPopups,
|
||||||
_qTimetableLessonNum = qTimetableLessonNum,
|
_qTimetableLessonNum = qTimetableLessonNum,
|
||||||
_qTimetableSubTiles = qTimetableSubTiles,
|
_qTimetableSubTiles = qTimetableSubTiles,
|
||||||
_qSubjectsSubTiles = qSubjectsSubTiles;
|
_qSubjectsSubTiles = qSubjectsSubTiles;
|
||||||
@@ -322,6 +328,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
pinSetNotify: map['notify_s_pin'],
|
pinSetNotify: map['notify_s_pin'],
|
||||||
pinSetExtras: map['extras_s_pin'],
|
pinSetExtras: map['extras_s_pin'],
|
||||||
fontFamily: map['font_family'],
|
fontFamily: map['font_family'],
|
||||||
|
titleOnlyFont: map['title_only_font'] == 1,
|
||||||
plusSessionId: map['plus_session_id'],
|
plusSessionId: map['plus_session_id'],
|
||||||
calSyncRoomLocation: map['cal_sync_room_location'],
|
calSyncRoomLocation: map['cal_sync_room_location'],
|
||||||
calSyncShowExams: map['cal_sync_show_exams'] == 1,
|
calSyncShowExams: map['cal_sync_show_exams'] == 1,
|
||||||
@@ -331,6 +338,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
navShadow: map['nav_shadow'] == 1,
|
navShadow: map['nav_shadow'] == 1,
|
||||||
newColors: map['new_colors'] == 1,
|
newColors: map['new_colors'] == 1,
|
||||||
uwuMode: map['uwu_mode'] == 1,
|
uwuMode: map['uwu_mode'] == 1,
|
||||||
|
newPopups: map['new_popups'] == 1,
|
||||||
qTimetableLessonNum: map['q_timetable_lesson_num'] == 1,
|
qTimetableLessonNum: map['q_timetable_lesson_num'] == 1,
|
||||||
qTimetableSubTiles: map['q_timetable_sub_tiles'] == 1,
|
qTimetableSubTiles: map['q_timetable_sub_tiles'] == 1,
|
||||||
qSubjectsSubTiles: map['q_subjects_sub_tiles'] == 1,
|
qSubjectsSubTiles: map['q_subjects_sub_tiles'] == 1,
|
||||||
@@ -397,6 +405,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
"notify_s_pin": _pinSetNotify,
|
"notify_s_pin": _pinSetNotify,
|
||||||
"extras_s_pin": _pinSetExtras,
|
"extras_s_pin": _pinSetExtras,
|
||||||
"font_family": _fontFamily,
|
"font_family": _fontFamily,
|
||||||
|
"title_only_font": _titleOnlyFont ? 1 : 0,
|
||||||
"plus_session_id": _plusSessionId,
|
"plus_session_id": _plusSessionId,
|
||||||
"cal_sync_room_location": _calSyncRoomLocation,
|
"cal_sync_room_location": _calSyncRoomLocation,
|
||||||
"cal_sync_show_exams": _calSyncShowExams ? 1 : 0,
|
"cal_sync_show_exams": _calSyncShowExams ? 1 : 0,
|
||||||
@@ -406,6 +415,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
"nav_shadow": _navShadow ? 1 : 0,
|
"nav_shadow": _navShadow ? 1 : 0,
|
||||||
"new_colors": _newColors ? 1 : 0,
|
"new_colors": _newColors ? 1 : 0,
|
||||||
"uwu_mode": _uwuMode ? 1 : 0,
|
"uwu_mode": _uwuMode ? 1 : 0,
|
||||||
|
"new_popups": _newPopups ? 1 : 0,
|
||||||
"q_timetable_lesson_num": _qTimetableLessonNum ? 1 : 0,
|
"q_timetable_lesson_num": _qTimetableLessonNum ? 1 : 0,
|
||||||
"q_timetable_sub_tiles": _qTimetableSubTiles ? 1 : 0,
|
"q_timetable_sub_tiles": _qTimetableSubTiles ? 1 : 0,
|
||||||
"q_subjects_sub_tiles": _qSubjectsSubTiles ? 1 : 0,
|
"q_subjects_sub_tiles": _qSubjectsSubTiles ? 1 : 0,
|
||||||
@@ -476,6 +486,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
pinSetNotify: '',
|
pinSetNotify: '',
|
||||||
pinSetExtras: '',
|
pinSetExtras: '',
|
||||||
fontFamily: '',
|
fontFamily: '',
|
||||||
|
titleOnlyFont: false,
|
||||||
plusSessionId: '',
|
plusSessionId: '',
|
||||||
calSyncRoomLocation: 'location',
|
calSyncRoomLocation: 'location',
|
||||||
calSyncShowExams: true,
|
calSyncShowExams: true,
|
||||||
@@ -485,6 +496,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
navShadow: true,
|
navShadow: true,
|
||||||
newColors: true,
|
newColors: true,
|
||||||
uwuMode: false,
|
uwuMode: false,
|
||||||
|
newPopups: true,
|
||||||
qTimetableLessonNum: true,
|
qTimetableLessonNum: true,
|
||||||
qTimetableSubTiles: true,
|
qTimetableSubTiles: true,
|
||||||
qSubjectsSubTiles: true,
|
qSubjectsSubTiles: true,
|
||||||
@@ -546,6 +558,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
String get currentThemeCreator => _currentThemeCreator;
|
String get currentThemeCreator => _currentThemeCreator;
|
||||||
bool get showBreaks => _showBreaks;
|
bool get showBreaks => _showBreaks;
|
||||||
String get fontFamily => _fontFamily;
|
String get fontFamily => _fontFamily;
|
||||||
|
bool get titleOnlyFont => _titleOnlyFont;
|
||||||
String get plusSessionId => _plusSessionId;
|
String get plusSessionId => _plusSessionId;
|
||||||
String get calSyncRoomLocation => _calSyncRoomLocation;
|
String get calSyncRoomLocation => _calSyncRoomLocation;
|
||||||
bool get calSyncShowExams => _calSyncShowExams;
|
bool get calSyncShowExams => _calSyncShowExams;
|
||||||
@@ -555,6 +568,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
bool get navShadow => _navShadow;
|
bool get navShadow => _navShadow;
|
||||||
bool get newColors => _newColors;
|
bool get newColors => _newColors;
|
||||||
bool get uwuMode => _uwuMode;
|
bool get uwuMode => _uwuMode;
|
||||||
|
bool get newPopups => _newPopups;
|
||||||
bool get qTimetableLessonNum => _qTimetableLessonNum;
|
bool get qTimetableLessonNum => _qTimetableLessonNum;
|
||||||
bool get qTimetableSubTiles => _qTimetableSubTiles;
|
bool get qTimetableSubTiles => _qTimetableSubTiles;
|
||||||
bool get qSubjectsSubTiles => _qSubjectsSubTiles;
|
bool get qSubjectsSubTiles => _qSubjectsSubTiles;
|
||||||
@@ -612,6 +626,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
String? currentThemeCreator,
|
String? currentThemeCreator,
|
||||||
bool? showBreaks,
|
bool? showBreaks,
|
||||||
String? fontFamily,
|
String? fontFamily,
|
||||||
|
bool? titleOnlyFont,
|
||||||
String? plusSessionId,
|
String? plusSessionId,
|
||||||
String? calSyncRoomLocation,
|
String? calSyncRoomLocation,
|
||||||
bool? calSyncShowExams,
|
bool? calSyncShowExams,
|
||||||
@@ -621,6 +636,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
bool? navShadow,
|
bool? navShadow,
|
||||||
bool? newColors,
|
bool? newColors,
|
||||||
bool? uwuMode,
|
bool? uwuMode,
|
||||||
|
bool? newPopups,
|
||||||
bool? qTimetableLessonNum,
|
bool? qTimetableLessonNum,
|
||||||
bool? qTimetableSubTiles,
|
bool? qTimetableSubTiles,
|
||||||
bool? qSubjectsSubTiles,
|
bool? qSubjectsSubTiles,
|
||||||
@@ -777,6 +793,9 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
if (fontFamily != null && fontFamily != _fontFamily) {
|
if (fontFamily != null && fontFamily != _fontFamily) {
|
||||||
_fontFamily = fontFamily;
|
_fontFamily = fontFamily;
|
||||||
}
|
}
|
||||||
|
if (titleOnlyFont != null && titleOnlyFont != _titleOnlyFont) {
|
||||||
|
_titleOnlyFont = titleOnlyFont;
|
||||||
|
}
|
||||||
if (plusSessionId != null && plusSessionId != _plusSessionId) {
|
if (plusSessionId != null && plusSessionId != _plusSessionId) {
|
||||||
_plusSessionId = plusSessionId;
|
_plusSessionId = plusSessionId;
|
||||||
}
|
}
|
||||||
@@ -806,6 +825,9 @@ class SettingsProvider extends ChangeNotifier {
|
|||||||
if (uwuMode != null && uwuMode != _uwuMode) {
|
if (uwuMode != null && uwuMode != _uwuMode) {
|
||||||
_uwuMode = uwuMode;
|
_uwuMode = uwuMode;
|
||||||
}
|
}
|
||||||
|
if (newPopups != null && newPopups != _newPopups) {
|
||||||
|
_newPopups = newPopups;
|
||||||
|
}
|
||||||
if (qTimetableLessonNum != null &&
|
if (qTimetableLessonNum != null &&
|
||||||
qTimetableLessonNum != _qTimetableLessonNum) {
|
qTimetableLessonNum != _qTimetableLessonNum) {
|
||||||
_qTimetableLessonNum = qTimetableLessonNum;
|
_qTimetableLessonNum = qTimetableLessonNum;
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ class User {
|
|||||||
Role role;
|
Role role;
|
||||||
String nickname;
|
String nickname;
|
||||||
String picture;
|
String picture;
|
||||||
|
int gradeStreak;
|
||||||
|
|
||||||
String get displayName => nickname != '' ? nickname : name;
|
String get displayName => nickname != '' ? nickname : name;
|
||||||
|
bool get hasStreak => gradeStreak > 0;
|
||||||
|
|
||||||
User({
|
User({
|
||||||
String? id,
|
String? id,
|
||||||
@@ -29,6 +31,7 @@ class User {
|
|||||||
required this.role,
|
required this.role,
|
||||||
this.nickname = "",
|
this.nickname = "",
|
||||||
this.picture = "",
|
this.picture = "",
|
||||||
|
this.gradeStreak = 0,
|
||||||
}) {
|
}) {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -57,6 +60,7 @@ class User {
|
|||||||
role: Role.values[map["role"] ?? 0],
|
role: Role.values[map["role"] ?? 0],
|
||||||
nickname: map["nickname"] ?? "",
|
nickname: map["nickname"] ?? "",
|
||||||
picture: map["picture"] ?? "",
|
picture: map["picture"] ?? "",
|
||||||
|
gradeStreak: map["grade_streak"] ?? 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,9 +104,10 @@ class AppTheme {
|
|||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
fontFamily: _defaultFontFamily,
|
fontFamily: _defaultFontFamily,
|
||||||
textTheme:
|
textTheme: !settings.titleOnlyFont
|
||||||
googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor) ??
|
? (googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor) ??
|
||||||
const TextTheme().apply(bodyColor: textColor),
|
const TextTheme().apply(bodyColor: textColor))
|
||||||
|
: null,
|
||||||
scaffoldBackgroundColor: backgroundColor,
|
scaffoldBackgroundColor: backgroundColor,
|
||||||
primaryColor: lightColors.filc,
|
primaryColor: lightColors.filc,
|
||||||
dividerColor: const Color(0x00000000),
|
dividerColor: const Color(0x00000000),
|
||||||
@@ -229,8 +230,9 @@ class AppTheme {
|
|||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
fontFamily: _defaultFontFamily,
|
fontFamily: _defaultFontFamily,
|
||||||
textTheme:
|
textTheme: !settings.titleOnlyFont
|
||||||
googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor),
|
? (googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor))
|
||||||
|
: null,
|
||||||
scaffoldBackgroundColor: backgroundColor,
|
scaffoldBackgroundColor: backgroundColor,
|
||||||
primaryColor: darkColors.filc,
|
primaryColor: darkColors.filc,
|
||||||
dividerColor: const Color(0x00000000),
|
dividerColor: const Color(0x00000000),
|
||||||
|
|||||||
@@ -192,6 +192,8 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
bool advOverride = widget.colorMode == CustomColorMode.grade ? true : false;
|
||||||
|
|
||||||
if (MediaQuery.of(context).orientation == Orientation.portrait ||
|
if (MediaQuery.of(context).orientation == Orientation.portrait ||
|
||||||
widget.portraitOnly) {
|
widget.portraitOnly) {
|
||||||
return Column(
|
return Column(
|
||||||
@@ -218,7 +220,7 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
|||||||
child: colorPickerSlider(TrackType.saturation),
|
child: colorPickerSlider(TrackType.saturation),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (isAdvancedView)
|
if (isAdvancedView || advOverride)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 12.0, right: 12.0),
|
padding: const EdgeInsets.only(left: 12.0, right: 12.0),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@@ -230,7 +232,7 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (isAdvancedView &&
|
if ((isAdvancedView || advOverride) &&
|
||||||
widget.colorMode != CustomColorMode.theme &&
|
widget.colorMode != CustomColorMode.theme &&
|
||||||
widget.colorMode != CustomColorMode.enterId)
|
widget.colorMode != CustomColorMode.enterId)
|
||||||
Padding(
|
Padding(
|
||||||
@@ -295,7 +297,8 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.colorMode != CustomColorMode.enterId)
|
if (widget.colorMode != CustomColorMode.enterId &&
|
||||||
|
widget.colorMode != CustomColorMode.grade)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 70 * (widget.colorMode == CustomColorMode.theme ? 2 : 1),
|
height: 70 * (widget.colorMode == CustomColorMode.theme ? 2 : 1),
|
||||||
child: BlockPicker(
|
child: BlockPicker(
|
||||||
@@ -347,7 +350,8 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.colorMode != CustomColorMode.theme &&
|
if (widget.colorMode != CustomColorMode.theme &&
|
||||||
widget.colorMode != CustomColorMode.enterId)
|
widget.colorMode != CustomColorMode.enterId &&
|
||||||
|
!advOverride)
|
||||||
Material(
|
Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:i18n_extension/i18n_extension.dart';
|
||||||
import 'package:refilc/models/settings.dart';
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc_kreta_api/providers/exam_provider.dart';
|
import 'package:refilc_kreta_api/providers/exam_provider.dart';
|
||||||
import 'package:refilc_kreta_api/providers/homework_provider.dart';
|
import 'package:refilc_kreta_api/providers/homework_provider.dart';
|
||||||
@@ -8,7 +9,8 @@ import 'package:refilc_kreta_api/models/lesson.dart';
|
|||||||
import 'package:refilc/utils/format.dart';
|
import 'package:refilc/utils/format.dart';
|
||||||
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||||
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/exam/exam_view.dart';
|
// import 'package:refilc_mobile_ui/common/widgets/exam/exam_view.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/widgets/exam/exam_viewable.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/homework/homework_view.dart';
|
import 'package:refilc_mobile_ui/common/widgets/homework/homework_view.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
@@ -109,7 +111,8 @@ class LessonTile extends StatelessWidget {
|
|||||||
title: exam.description != ""
|
title: exam.description != ""
|
||||||
? exam.description
|
? exam.description
|
||||||
: exam.mode?.description ?? "exam".i18n,
|
: exam.mode?.description ?? "exam".i18n,
|
||||||
onPressed: () => ExamView.show(exam, context: context),
|
// onPressed: () => ExamView.show(exam, context: context),
|
||||||
|
onPressed: () => ExamPopup.show(context: context, exam: exam),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +193,7 @@ class LessonTile extends StatelessWidget {
|
|||||||
: Transform.translate(
|
: Transform.translate(
|
||||||
offset: const Offset(0, -2.0),
|
offset: const Offset(0, -2.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"${DateFormat("H:mm").format(lesson.start)}-${DateFormat("H:mm").format(lesson.end)}",
|
"${DateFormat("E, H:mm", I18n.of(context).locale.toString()).format(lesson.start)}-${DateFormat("H:mm").format(lesson.end)}",
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak."
|
|||||||
homepage: https://refilc.hu
|
homepage: https://refilc.hu
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
|
|
||||||
version: 5.0.0+257
|
version: 5.0.2+266
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <=3.3.2"
|
sdk: ">=2.17.0 <=3.3.2"
|
||||||
@@ -104,6 +104,7 @@ flutter:
|
|||||||
- assets/svg/menu_icons/
|
- assets/svg/menu_icons/
|
||||||
- assets/other/dirtywords.xml
|
- assets/other/dirtywords.xml
|
||||||
- assets/svg/
|
- assets/svg/
|
||||||
|
- assets/svg/cover_arts/
|
||||||
|
|
||||||
fonts:
|
fonts:
|
||||||
- family: FilcIcons
|
- family: FilcIcons
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
title: Padding(
|
title: Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Grades".i18n,
|
"page_title_grades".i18n,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.of(context).text,
|
color: AppColors.of(context).text,
|
||||||
fontSize: 32.0,
|
fontSize: 32.0,
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ class KretaClient {
|
|||||||
_status.triggerRequest(res);
|
_status.triggerRequest(res);
|
||||||
|
|
||||||
if (res.statusCode == 401) {
|
if (res.statusCode == 401) {
|
||||||
await refreshLogin();
|
|
||||||
headerMap.remove("authorization");
|
headerMap.remove("authorization");
|
||||||
|
await refreshLogin();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -212,8 +212,8 @@ class KretaClient {
|
|||||||
res = await request.send();
|
res = await request.send();
|
||||||
|
|
||||||
if (res.statusCode == 401) {
|
if (res.statusCode == 401) {
|
||||||
|
headerMap.remove("authorization");
|
||||||
await refreshLogin();
|
await refreshLogin();
|
||||||
headerMap.remove("authorization");
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||||
|
|
||||||
import 'package:refilc/utils/format.dart';
|
import 'package:refilc/utils/format.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
import 'category.dart';
|
import 'category.dart';
|
||||||
import 'subject.dart';
|
import 'subject.dart';
|
||||||
import 'teacher.dart';
|
import 'teacher.dart';
|
||||||
@@ -75,6 +76,40 @@ class Grade {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
factory Grade.fromExportJson(Map json) {
|
||||||
|
return Grade(
|
||||||
|
id: const Uuid().v4(),
|
||||||
|
date: json["date"] != null ? DateTime.parse(json["date"]) : DateTime(0),
|
||||||
|
value: GradeValue(
|
||||||
|
json["value"] ?? 0,
|
||||||
|
json["value_name"] ?? "",
|
||||||
|
json["value_name"] ?? "",
|
||||||
|
json["weight"] ?? 0,
|
||||||
|
percentage: false,
|
||||||
|
),
|
||||||
|
teacher: Teacher.fromString((json["teacher"] ?? "").trim()),
|
||||||
|
description: json["description"] ?? "",
|
||||||
|
type: json["type"] != null
|
||||||
|
? Category.getGradeType(json["type"]
|
||||||
|
.replaceAll("midYear", "evkozi_jegy_ertekeles")
|
||||||
|
.replaceAll("halfYear", "felevi_jegy_ertekeles")
|
||||||
|
.replaceAll("endYear", "evvegi_jegy_ertekeles"))
|
||||||
|
: GradeType.unknown,
|
||||||
|
groupId: const Uuid().v4(),
|
||||||
|
subject: GradeSubject(
|
||||||
|
id: const Uuid().v4(),
|
||||||
|
category: Category.fromJson({}),
|
||||||
|
name: json["subject"] ?? ""),
|
||||||
|
mode: Category.fromJson({}),
|
||||||
|
writeDate:
|
||||||
|
json["date"] != null ? DateTime.parse(json["date"]) : DateTime(0),
|
||||||
|
seenDate:
|
||||||
|
json["date"] != null ? DateTime.parse(json["date"]) : DateTime(0),
|
||||||
|
form: "",
|
||||||
|
json: json,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bool compareTo(dynamic other) {
|
bool compareTo(dynamic other) {
|
||||||
if (runtimeType != other.runtimeType) return false;
|
if (runtimeType != other.runtimeType) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class Student {
|
|||||||
String? address;
|
String? address;
|
||||||
String? groupId;
|
String? groupId;
|
||||||
List<String> parents;
|
List<String> parents;
|
||||||
|
// List<String> parentsPhone;
|
||||||
String? className;
|
String? className;
|
||||||
|
|
||||||
Student({
|
Student({
|
||||||
@@ -21,6 +22,7 @@ class Student {
|
|||||||
required this.yearId,
|
required this.yearId,
|
||||||
this.address,
|
this.address,
|
||||||
required this.parents,
|
required this.parents,
|
||||||
|
// required this.parentsPhone,
|
||||||
this.json,
|
this.json,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ class GradeProvider with ChangeNotifier {
|
|||||||
String? userId = _user.id;
|
String? userId = _user.id;
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
final userStore = _database.userStore;
|
final userStore = _database.userStore;
|
||||||
userStore.storeLastSeen(DateTime.now(), userId: userId, category: LastSeenCategory.surprisegrade);
|
userStore.storeLastSeen(DateTime.now(),
|
||||||
|
userId: userId, category: LastSeenCategory.surprisegrade);
|
||||||
_lastSeen = DateTime.now();
|
_lastSeen = DateTime.now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +60,8 @@ class GradeProvider with ChangeNotifier {
|
|||||||
String? userId = _user.id;
|
String? userId = _user.id;
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
final userStore = _database.userStore;
|
final userStore = _database.userStore;
|
||||||
userStore.storeLastSeen(DateTime(1969), userId: userId, category: LastSeenCategory.surprisegrade);
|
userStore.storeLastSeen(DateTime(1969),
|
||||||
|
userId: userId, category: LastSeenCategory.surprisegrade);
|
||||||
_lastSeen = DateTime(1969);
|
_lastSeen = DateTime(1969);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,9 +75,11 @@ class GradeProvider with ChangeNotifier {
|
|||||||
|
|
||||||
_grades = await userQuery.getGrades(userId: userId);
|
_grades = await userQuery.getGrades(userId: userId);
|
||||||
await convertBySettings();
|
await convertBySettings();
|
||||||
|
await getGradeStreak();
|
||||||
_groupAvg = await userQuery.getGroupAverages(userId: userId);
|
_groupAvg = await userQuery.getGroupAverages(userId: userId);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
DateTime lastSeenDB = await userQuery.lastSeen(userId: userId, category: LastSeenCategory.surprisegrade);
|
DateTime lastSeenDB = await userQuery.lastSeen(
|
||||||
|
userId: userId, category: LastSeenCategory.surprisegrade);
|
||||||
if (lastSeenDB.millisecondsSinceEpoch == 0 ||
|
if (lastSeenDB.millisecondsSinceEpoch == 0 ||
|
||||||
lastSeenDB.year == 0 ||
|
lastSeenDB.year == 0 ||
|
||||||
!_settings.gradeOpeningFun) {
|
!_settings.gradeOpeningFun) {
|
||||||
@@ -133,6 +137,28 @@ class GradeProvider with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get current grade streak and set it to the user
|
||||||
|
Future<void> getGradeStreak() async {
|
||||||
|
User? user = _user.user;
|
||||||
|
if (user == null) throw "Cannot get Grade Streak for User null";
|
||||||
|
|
||||||
|
// streak magic
|
||||||
|
int gradeStreak = 0;
|
||||||
|
List<Grade> grs = _grades;
|
||||||
|
grs.sort((a, b) => -a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
for (Grade grade in grs) {
|
||||||
|
if (grade.value.value == 5) {
|
||||||
|
gradeStreak++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user.gradeStreak = gradeStreak;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
// Fetches Grades from the Kreta API then stores them in the database
|
// Fetches Grades from the Kreta API then stores them in the database
|
||||||
Future<void> fetch() async {
|
Future<void> fetch() async {
|
||||||
// test cucc
|
// test cucc
|
||||||
@@ -173,6 +199,7 @@ class GradeProvider with ChangeNotifier {
|
|||||||
await _database.userStore.storeGrades(grades, userId: userId);
|
await _database.userStore.storeGrades(grades, userId: userId);
|
||||||
_grades = grades;
|
_grades = grades;
|
||||||
await convertBySettings();
|
await convertBySettings();
|
||||||
|
await getGradeStreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> storeGroupAvg(List<GroupAverage> groupAvgs) async {
|
Future<void> storeGroupAvg(List<GroupAverage> groupAvgs) async {
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ class ShareProvider extends ChangeNotifier {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// themes
|
// themes
|
||||||
Future<SharedTheme> shareCurrentTheme(BuildContext context,
|
Future<SharedTheme> shareCurrentTheme(
|
||||||
{bool isPublic = false,
|
BuildContext context, {
|
||||||
bool shareNick = true,
|
bool isPublic = false,
|
||||||
required SharedGradeColors gradeColors,
|
bool shareNick = true,
|
||||||
String displayName = ''}) async {
|
required SharedGradeColors gradeColors,
|
||||||
|
String displayName = '',
|
||||||
|
}) async {
|
||||||
final SettingsProvider settings =
|
final SettingsProvider settings =
|
||||||
Provider.of<SettingsProvider>(context, listen: false);
|
Provider.of<SettingsProvider>(context, listen: false);
|
||||||
|
|
||||||
@@ -69,7 +71,25 @@ class ShareProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
if (gradeColorsJson != null) {
|
if (gradeColorsJson != null) {
|
||||||
SharedTheme theme = SharedTheme.fromJson(
|
SharedTheme theme = SharedTheme.fromJson(
|
||||||
themeJson, SharedGradeColors.fromJson(gradeColorsJson));
|
themeJson,
|
||||||
|
SharedGradeColors.fromJson(gradeColorsJson["public_id"] != ''
|
||||||
|
? gradeColorsJson
|
||||||
|
: {
|
||||||
|
"public_id": "0",
|
||||||
|
"is_public": false,
|
||||||
|
"nickname": "Anonymous",
|
||||||
|
"five_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[4].value,
|
||||||
|
"four_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[3].value,
|
||||||
|
"three_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[2].value,
|
||||||
|
"two_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[1].value,
|
||||||
|
"one_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[0].value,
|
||||||
|
}),
|
||||||
|
);
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +113,25 @@ class ShareProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
if (gradeColorsJson != null) {
|
if (gradeColorsJson != null) {
|
||||||
SharedTheme theme = SharedTheme.fromJson(
|
SharedTheme theme = SharedTheme.fromJson(
|
||||||
t, SharedGradeColors.fromJson(gradeColorsJson));
|
t,
|
||||||
|
SharedGradeColors.fromJson(gradeColorsJson["public_id"] != ''
|
||||||
|
? gradeColorsJson
|
||||||
|
: {
|
||||||
|
"public_id": "0",
|
||||||
|
"is_public": false,
|
||||||
|
"nickname": "Anonymous",
|
||||||
|
"five_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[4].value,
|
||||||
|
"four_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[3].value,
|
||||||
|
"three_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[2].value,
|
||||||
|
"two_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[1].value,
|
||||||
|
"one_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[0].value,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
themes.add(theme);
|
themes.add(theme);
|
||||||
}
|
}
|
||||||
@@ -134,8 +172,25 @@ class ShareProvider extends ChangeNotifier {
|
|||||||
Map? gradeColorsJson = await FilcAPI.getSharedGradeColors(id);
|
Map? gradeColorsJson = await FilcAPI.getSharedGradeColors(id);
|
||||||
|
|
||||||
if (gradeColorsJson != null) {
|
if (gradeColorsJson != null) {
|
||||||
SharedGradeColors gradeColors =
|
SharedGradeColors gradeColors = SharedGradeColors.fromJson(
|
||||||
SharedGradeColors.fromJson(gradeColorsJson);
|
gradeColorsJson["public_id"] != ''
|
||||||
|
? gradeColorsJson
|
||||||
|
: {
|
||||||
|
"public_id": "0",
|
||||||
|
"is_public": false,
|
||||||
|
"nickname": "Anonymous",
|
||||||
|
"five_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[4].value,
|
||||||
|
"four_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[3].value,
|
||||||
|
"three_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[2].value,
|
||||||
|
"two_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[1].value,
|
||||||
|
"one_color":
|
||||||
|
SettingsProvider.defaultSettings().gradeColors[0].value,
|
||||||
|
},
|
||||||
|
);
|
||||||
return gradeColors;
|
return gradeColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
|
import 'package:dotted_border/dotted_border.dart';
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:i18n_extension/i18n_extension.dart';
|
import 'package:i18n_extension/i18n_extension.dart';
|
||||||
|
|
||||||
class AverageDisplay extends StatelessWidget {
|
class AverageDisplay extends StatelessWidget {
|
||||||
const AverageDisplay({super.key, this.average = 0.0, this.border = false});
|
const AverageDisplay({
|
||||||
|
super.key,
|
||||||
|
this.average = 0.0,
|
||||||
|
this.border = false,
|
||||||
|
this.dashed = false,
|
||||||
|
this.scale = 1.0,
|
||||||
|
});
|
||||||
|
|
||||||
final double average;
|
final double average;
|
||||||
final bool border;
|
final bool border;
|
||||||
|
final bool dashed;
|
||||||
|
final double scale;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -20,25 +29,44 @@ class AverageDisplay extends StatelessWidget {
|
|||||||
averageText = averageText.replaceAll(".", ",");
|
averageText = averageText.replaceAll(".", ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget txtWidget = Text(
|
||||||
|
average == 0.0 ? "-" : averageText,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: color, fontWeight: FontWeight.w600, fontSize: scale * 15.0),
|
||||||
|
maxLines: 1,
|
||||||
|
);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: border ? 57.0 : 54.0,
|
width: (border ? 57.0 : 54.0) * scale,
|
||||||
padding: EdgeInsets.symmetric(
|
padding: (border && dashed)
|
||||||
horizontal: 6.0 - (border ? 2 : 0), vertical: 5.0 - (border ? 2 : 0)),
|
? null
|
||||||
|
: EdgeInsets.symmetric(
|
||||||
|
horizontal: (6.0 - (border ? 2 : 0)) * scale,
|
||||||
|
vertical: (5.0 - (border ? 2 : 0))) *
|
||||||
|
scale,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(45.0),
|
borderRadius:
|
||||||
border: border
|
(border && dashed) ? null : BorderRadius.circular(45.0 * scale),
|
||||||
|
border: border && !dashed
|
||||||
? Border.fromBorderSide(
|
? Border.fromBorderSide(
|
||||||
BorderSide(color: color.withOpacity(.5), width: 1.0))
|
BorderSide(color: color.withOpacity(.5), width: 1.0 * scale))
|
||||||
: null,
|
: null,
|
||||||
color: !border ? color.withOpacity(average == 0.0 ? .15 : .25) : null,
|
color: !border ? color.withOpacity(average == 0.0 ? .15 : .25) : null,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: (border && dashed)
|
||||||
average == 0.0 ? "-" : averageText,
|
? DottedBorder(
|
||||||
textAlign: TextAlign.center,
|
strokeWidth: 1.0 * scale,
|
||||||
style: TextStyle(
|
padding: EdgeInsets.all(4.0 * scale),
|
||||||
color: color, fontWeight: FontWeight.w600, fontSize: 15.0),
|
color: color.withOpacity(.5),
|
||||||
maxLines: 1,
|
dashPattern: const [6, 6],
|
||||||
),
|
radius: Radius.circular(45.0 * scale),
|
||||||
|
borderType: BorderType.RRect,
|
||||||
|
child: Center(
|
||||||
|
child: txtWidget,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: txtWidget,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:refilc/helpers/subject.dart';
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:refilc/theme/colors/utils.dart';
|
import 'package:refilc/theme/colors/utils.dart';
|
||||||
@@ -113,7 +114,9 @@ class HeroScrollViewState extends State<HeroScrollView> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 26.0),
|
padding: const EdgeInsets.only(top: 26.0),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
"assets/svg/mesh_bg.svg",
|
// "assets/svg/mesh_bg.svg",
|
||||||
|
SubjectBooklet.resolveVariant(
|
||||||
|
context: context, subjectName: widget.title),
|
||||||
// ignore: deprecated_member_use
|
// ignore: deprecated_member_use
|
||||||
color: ColorsUtils()
|
color: ColorsUtils()
|
||||||
.darken(
|
.darken(
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ extension Localization on String {
|
|||||||
"d_npc":
|
"d_npc":
|
||||||
"You're such a non-player character, we couldn't give you a personality.",
|
"You're such a non-player character, we couldn't give you a personality.",
|
||||||
"s_npc": "In-game playtime (hours)",
|
"s_npc": "In-game playtime (hours)",
|
||||||
|
// other
|
||||||
|
"year_index": "Lesson Number",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
// main
|
// main
|
||||||
@@ -96,6 +98,8 @@ extension Localization on String {
|
|||||||
"d_npc":
|
"d_npc":
|
||||||
"Egy akkora nagy non-player character vagy, hogy neked semmilyen személyiség nem jutott ezen kívül.",
|
"Egy akkora nagy non-player character vagy, hogy neked semmilyen személyiség nem jutott ezen kívül.",
|
||||||
"s_npc": "In-game playtime (óra)",
|
"s_npc": "In-game playtime (óra)",
|
||||||
|
// other
|
||||||
|
"year_index": "Éves óraszám",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
// main
|
// main
|
||||||
@@ -144,6 +148,8 @@ extension Localization on String {
|
|||||||
"d_npc":
|
"d_npc":
|
||||||
"Du bist einfach so sehr wie ein Computer, dass wir dir nicht einmal eine Persönlichkeit geben konnten.",
|
"Du bist einfach so sehr wie ein Computer, dass wir dir nicht einmal eine Persönlichkeit geben konnten.",
|
||||||
"s_npc": "Spielzeit (Stunden)",
|
"s_npc": "Spielzeit (Stunden)",
|
||||||
|
// other
|
||||||
|
"year_index": "Ordinalzahl",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class ProfileButton extends StatelessWidget {
|
|||||||
radius: child.radius,
|
radius: child.radius,
|
||||||
badge: child.badge,
|
badge: child.badge,
|
||||||
role: child.role,
|
role: child.role,
|
||||||
|
gradeStreak: child.gradeStreak,
|
||||||
profilePictureString: child.profilePictureString,
|
profilePictureString: child.profilePictureString,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showSlidingBottomSheet(
|
showSlidingBottomSheet(
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class ProfileImage extends StatefulWidget {
|
|||||||
this.censored = false,
|
this.censored = false,
|
||||||
this.profilePictureString = "",
|
this.profilePictureString = "",
|
||||||
this.isNotePfp = false,
|
this.isNotePfp = false,
|
||||||
|
this.gradeStreak = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
final void Function()? onTap;
|
final void Function()? onTap;
|
||||||
@@ -35,6 +36,7 @@ class ProfileImage extends StatefulWidget {
|
|||||||
final bool censored;
|
final bool censored;
|
||||||
final String profilePictureString;
|
final String profilePictureString;
|
||||||
final bool isNotePfp;
|
final bool isNotePfp;
|
||||||
|
final bool gradeStreak;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ProfileImage> createState() => _ProfileImageState();
|
State<ProfileImage> createState() => _ProfileImageState();
|
||||||
@@ -145,6 +147,20 @@ class _ProfileImageState extends State<ProfileImage> {
|
|||||||
color: roleColor, size: widget.radius / 1.3),
|
color: roleColor, size: widget.radius / 1.3),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// streak indicator
|
||||||
|
// if (widget.gradeStreak)
|
||||||
|
// SizedBox(
|
||||||
|
// height: widget.radius * 2,
|
||||||
|
// width: widget.radius * 2,
|
||||||
|
// child: Container(
|
||||||
|
// alignment: Alignment.topLeft,
|
||||||
|
// child: Text(
|
||||||
|
// '🔥',
|
||||||
|
// style: TextStyle(fontSize: widget.radius * 0.9),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -238,6 +254,29 @@ class _ProfileImageState extends State<ProfileImage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// streak indicator
|
||||||
|
if (widget.gradeStreak)
|
||||||
|
Hero(
|
||||||
|
tag: "${widget.heroTag!}streak_indicator",
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.fitHeight,
|
||||||
|
child: SizedBox(
|
||||||
|
height: widget.radius * 2,
|
||||||
|
width: widget.radius * 2,
|
||||||
|
child: Transform.translate(
|
||||||
|
offset: Offset(-widget.radius / 4, -widget.radius / 4),
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: Text(
|
||||||
|
'🔥',
|
||||||
|
style: TextStyle(fontSize: widget.radius * 0.8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
Material(
|
Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ extension Localization on String {
|
|||||||
"unexcused": "unexcused %s",
|
"unexcused": "unexcused %s",
|
||||||
"absence": "absence",
|
"absence": "absence",
|
||||||
"delay": "delay",
|
"delay": "delay",
|
||||||
"minute": " minutes of ".one(" minute of "),
|
"minute": " minute(s) of ",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"excused": "igazolt %s",
|
"excused": "igazolt %s",
|
||||||
@@ -25,7 +25,7 @@ extension Localization on String {
|
|||||||
"unexcused": "unanerkannt %s",
|
"unexcused": "unanerkannt %s",
|
||||||
"absence": "Abwesenheit",
|
"absence": "Abwesenheit",
|
||||||
"delay": "Verspätung",
|
"delay": "Verspätung",
|
||||||
"minute": " Minuten ".one(" Minute "),
|
"minute": " Minute(n) ",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ extension Localization on String {
|
|||||||
"Mode": "Mode",
|
"Mode": "Mode",
|
||||||
"Submit date": "Submit Date",
|
"Submit date": "Submit Date",
|
||||||
"show in timetable": "Show in timetable",
|
"show in timetable": "Show in timetable",
|
||||||
"minutes": "minutes".one("minute"),
|
"minutes": "minute(s)",
|
||||||
"delay": "Delay",
|
"delay": "Delay",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
@@ -27,7 +27,7 @@ extension Localization on String {
|
|||||||
"Mode": "Typ",
|
"Mode": "Typ",
|
||||||
"Submit date": "Datum einreichen",
|
"Submit date": "Datum einreichen",
|
||||||
"show in timetable": "im Stundenplan anzeigen",
|
"show in timetable": "im Stundenplan anzeigen",
|
||||||
"minutes": "Minuten".one("Minute"),
|
"minutes": "Minute(n)",
|
||||||
"delay": "Verspätung",
|
"delay": "Verspätung",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:i18n_extension/i18n_extension.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:refilc/helpers/subject.dart';
|
import 'package:refilc/helpers/subject.dart';
|
||||||
@@ -13,8 +14,11 @@ import 'package:refilc_kreta_api/models/exam.dart';
|
|||||||
import 'package:refilc_kreta_api/models/lesson.dart';
|
import 'package:refilc_kreta_api/models/lesson.dart';
|
||||||
import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart';
|
import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart';
|
||||||
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/viewable.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/widgets/card_handle.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/exam/exam_tile.dart';
|
import 'package:refilc_mobile_ui/common/widgets/exam/exam_tile.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/widgets/exam/exam_view.dart';
|
||||||
|
|
||||||
class ExamViewable extends StatelessWidget {
|
class ExamViewable extends StatelessWidget {
|
||||||
const ExamViewable(this.exam,
|
const ExamViewable(this.exam,
|
||||||
@@ -26,22 +30,25 @@ class ExamViewable extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
if (Provider.of<SettingsProvider>(context).newPopups) {
|
||||||
onTap: () => ExamPopup.show(context: context, exam: exam),
|
return GestureDetector(
|
||||||
child: ExamTile(
|
onTap: () => ExamPopup.show(context: context, exam: exam),
|
||||||
|
child: ExamTile(
|
||||||
|
exam,
|
||||||
|
showSubject: showSubject,
|
||||||
|
padding: tilePadding,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Viewable(
|
||||||
|
tile: ExamTile(
|
||||||
exam,
|
exam,
|
||||||
showSubject: showSubject,
|
showSubject: showSubject,
|
||||||
padding: tilePadding,
|
padding: tilePadding,
|
||||||
),
|
),
|
||||||
|
view: CardHandle(child: ExamView(exam)),
|
||||||
);
|
);
|
||||||
// return Viewable(
|
|
||||||
// tile: ExamTile(
|
|
||||||
// exam,
|
|
||||||
// showSubject: showSubject,
|
|
||||||
// padding: tilePadding,
|
|
||||||
// ),
|
|
||||||
// view: CardHandle(child: ExamView(exam)),
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +105,9 @@ class ExamPopup extends StatelessWidget {
|
|||||||
Stack(
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
"assets/svg/mesh_bg.svg",
|
// "assets/svg/mesh_bg.svg",
|
||||||
|
SubjectBooklet.resolveVariant(
|
||||||
|
context: context, subject: exam.subject),
|
||||||
// ignore: deprecated_member_use
|
// ignore: deprecated_member_use
|
||||||
color: ColorsUtils()
|
color: ColorsUtils()
|
||||||
.fade(context, Theme.of(context).colorScheme.secondary,
|
.fade(context, Theme.of(context).colorScheme.secondary,
|
||||||
@@ -210,13 +219,19 @@ class ExamPopup extends StatelessWidget {
|
|||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
SizedBox(
|
||||||
exam.description.capital(),
|
width: MediaQuery.of(context).size.width * 0.7,
|
||||||
style: TextStyle(
|
child: Text(
|
||||||
color:
|
exam.description.capital(),
|
||||||
AppColors.of(context).text.withOpacity(0.9),
|
style: TextStyle(
|
||||||
fontSize: 16.0,
|
color: AppColors.of(context)
|
||||||
fontWeight: FontWeight.w600,
|
.text
|
||||||
|
.withOpacity(0.9),
|
||||||
|
fontSize: 16.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
maxLines: 3,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
@@ -288,7 +303,7 @@ class ExamPopup extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'${DateFormat('H:mm').format(lesson!.start)} - ${DateFormat('H:mm').format(lesson!.end)}',
|
'${DateFormat('MMM d, H:mm', I18n.locale.countryCode).format(lesson!.start).capital()} - ${DateFormat('H:mm').format(lesson!.end)}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color:
|
color:
|
||||||
AppColors.of(context).text.withOpacity(0.85),
|
AppColors.of(context).text.withOpacity(0.85),
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ extension Localization on String {
|
|||||||
"l_desc": "Description...",
|
"l_desc": "Description...",
|
||||||
"done": "Done",
|
"done": "Done",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
|
"year_index": "Lesson Number",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"Room": "Terem",
|
"Room": "Terem",
|
||||||
@@ -22,6 +23,7 @@ extension Localization on String {
|
|||||||
"l_desc": "Leírás...",
|
"l_desc": "Leírás...",
|
||||||
"done": "Kész",
|
"done": "Kész",
|
||||||
"cancel": "Mégse",
|
"cancel": "Mégse",
|
||||||
|
"year_index": "Éves óraszám",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"Room": "Raum",
|
"Room": "Raum",
|
||||||
@@ -32,6 +34,7 @@ extension Localization on String {
|
|||||||
"l_desc": "Beschreibung...",
|
"l_desc": "Beschreibung...",
|
||||||
"done": "Erledigt",
|
"done": "Erledigt",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
|
"year_index": "Ordinalzahl",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -8,11 +9,21 @@ import 'package:refilc/models/settings.dart';
|
|||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:refilc/theme/colors/utils.dart';
|
import 'package:refilc/theme/colors/utils.dart';
|
||||||
import 'package:refilc/utils/format.dart';
|
import 'package:refilc/utils/format.dart';
|
||||||
|
import 'package:refilc_kreta_api/models/exam.dart';
|
||||||
import 'package:refilc_kreta_api/models/lesson.dart';
|
import 'package:refilc_kreta_api/models/lesson.dart';
|
||||||
|
import 'package:refilc_kreta_api/providers/exam_provider.dart';
|
||||||
import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart';
|
import 'package:refilc_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||||
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
import 'package:refilc_mobile_ui/common/round_border_icon.dart';
|
||||||
import 'package:refilc/ui/widgets/lesson/lesson_tile.dart';
|
import 'package:refilc/ui/widgets/lesson/lesson_tile.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/viewable.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/widgets/card_handle.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_view.dart';
|
||||||
|
import 'package:refilc_plus/models/premium_scopes.dart';
|
||||||
|
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
|
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||||
|
import 'lesson_view.i18n.dart';
|
||||||
|
|
||||||
class LessonViewable extends StatefulWidget {
|
class LessonViewable extends StatefulWidget {
|
||||||
const LessonViewable(
|
const LessonViewable(
|
||||||
@@ -59,174 +70,169 @@ class LessonViewableState extends State<LessonViewable> {
|
|||||||
|
|
||||||
if (lsn.subject.id == '' || tile.lesson.isEmpty) return tile;
|
if (lsn.subject.id == '' || tile.lesson.isEmpty) return tile;
|
||||||
|
|
||||||
return GestureDetector(
|
// check if new popup needed
|
||||||
onTap: () => TimetableLessonPopup.show(
|
if (Provider.of<SettingsProvider>(context).newPopups) {
|
||||||
context: context,
|
return GestureDetector(
|
||||||
lesson: lsn,
|
onTap: () => TimetableLessonPopup.show(
|
||||||
),
|
context: context,
|
||||||
child: LessonTile(
|
lesson: lsn,
|
||||||
lsn,
|
),
|
||||||
swapDesc: widget.swapDesc,
|
child: tile,
|
||||||
showSubTiles: widget.showSubTiles,
|
);
|
||||||
// onTap: () => TimetableLessonPopup.show(
|
}
|
||||||
// context: context,
|
|
||||||
// lesson: lsn,
|
return Viewable(
|
||||||
// ),
|
tile: tile,
|
||||||
),
|
view: CardHandle(child: LessonView(lsn)),
|
||||||
|
actions: [
|
||||||
|
PanelButton(
|
||||||
|
background: true,
|
||||||
|
title: Text(
|
||||||
|
"edit_lesson".i18n,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
|
||||||
|
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||||
|
.hasScope(PremiumScopes.timetableNotes)) {
|
||||||
|
PlusLockedFeaturePopup.show(
|
||||||
|
context: context, feature: PremiumFeature.timetableNotes);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => StatefulBuilder(builder: (context, setS) {
|
||||||
|
return AlertDialog(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
||||||
|
title: Text("edit_lesson".i18n),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// description
|
||||||
|
TextField(
|
||||||
|
controller: _descTxt,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
contentPadding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
hintText: 'l_desc'.i18n,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
FeatherIcons.x,
|
||||||
|
color: Colors.grey,
|
||||||
|
size: 18.0,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_descTxt.text = '';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// const SizedBox(
|
||||||
|
// height: 14.0,
|
||||||
|
// ),
|
||||||
|
// // class
|
||||||
|
// TextField(
|
||||||
|
// controller: _descTxt,
|
||||||
|
// onEditingComplete: () async {
|
||||||
|
// // SharedTheme? theme = await shareProvider.getThemeById(
|
||||||
|
// // context,
|
||||||
|
// // id: _paintId.text.replaceAll(' ', ''),
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// // if (theme != null) {
|
||||||
|
// // // set theme variable
|
||||||
|
// // newThemeByID = theme;
|
||||||
|
|
||||||
|
// // _paintId.clear();
|
||||||
|
// // } else {
|
||||||
|
// // ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
// // CustomSnackBar(
|
||||||
|
// // content: Text("theme_not_found".i18n,
|
||||||
|
// // style: const TextStyle(color: Colors.white)),
|
||||||
|
// // backgroundColor: AppColors.of(context).red,
|
||||||
|
// // context: context,
|
||||||
|
// // ),
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
// },
|
||||||
|
// decoration: InputDecoration(
|
||||||
|
// border: OutlineInputBorder(
|
||||||
|
// borderSide: const BorderSide(
|
||||||
|
// color: Colors.grey, width: 1.5),
|
||||||
|
// borderRadius: BorderRadius.circular(12.0),
|
||||||
|
// ),
|
||||||
|
// focusedBorder: OutlineInputBorder(
|
||||||
|
// borderSide: const BorderSide(
|
||||||
|
// color: Colors.grey, width: 1.5),
|
||||||
|
// borderRadius: BorderRadius.circular(12.0),
|
||||||
|
// ),
|
||||||
|
// contentPadding:
|
||||||
|
// const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
// hintText: 'l_desc'.i18n,
|
||||||
|
// suffixIcon: IconButton(
|
||||||
|
// icon: const Icon(
|
||||||
|
// FeatherIcons.x,
|
||||||
|
// color: Colors.grey,
|
||||||
|
// size: 18.0,
|
||||||
|
// ),
|
||||||
|
// onPressed: () {
|
||||||
|
// setState(() {
|
||||||
|
// _descTxt.text = '';
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"cancel".i18n,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).maybePop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"done".i18n,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
saveLesson();
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
// return Viewable(
|
|
||||||
// tile: tile,
|
|
||||||
// view: CardHandle(child: LessonView(lsn)),
|
|
||||||
// actions: [
|
|
||||||
// PanelButton(
|
|
||||||
// background: true,
|
|
||||||
// title: Text(
|
|
||||||
// "edit_lesson".i18n,
|
|
||||||
// textAlign: TextAlign.center,
|
|
||||||
// maxLines: 2,
|
|
||||||
// overflow: TextOverflow.ellipsis,
|
|
||||||
// ),
|
|
||||||
// onPressed: () {
|
|
||||||
// Navigator.of(context, rootNavigator: true).pop();
|
|
||||||
|
|
||||||
// if (!Provider.of<PlusProvider>(context, listen: false)
|
|
||||||
// .hasScope(PremiumScopes.timetableNotes)) {
|
|
||||||
// PlusLockedFeaturePopup.show(
|
|
||||||
// context: context, feature: PremiumFeature.timetableNotes);
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// showDialog(
|
|
||||||
// context: context,
|
|
||||||
// builder: (context) => StatefulBuilder(builder: (context, setS) {
|
|
||||||
// return AlertDialog(
|
|
||||||
// shape: const RoundedRectangleBorder(
|
|
||||||
// borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
|
||||||
// title: Text("edit_lesson".i18n),
|
|
||||||
// content: Column(
|
|
||||||
// mainAxisSize: MainAxisSize.min,
|
|
||||||
// children: [
|
|
||||||
// // description
|
|
||||||
// TextField(
|
|
||||||
// controller: _descTxt,
|
|
||||||
// decoration: InputDecoration(
|
|
||||||
// border: OutlineInputBorder(
|
|
||||||
// borderSide: const BorderSide(
|
|
||||||
// color: Colors.grey, width: 1.5),
|
|
||||||
// borderRadius: BorderRadius.circular(12.0),
|
|
||||||
// ),
|
|
||||||
// focusedBorder: OutlineInputBorder(
|
|
||||||
// borderSide: const BorderSide(
|
|
||||||
// color: Colors.grey, width: 1.5),
|
|
||||||
// borderRadius: BorderRadius.circular(12.0),
|
|
||||||
// ),
|
|
||||||
// contentPadding:
|
|
||||||
// const EdgeInsets.symmetric(horizontal: 12.0),
|
|
||||||
// hintText: 'l_desc'.i18n,
|
|
||||||
// suffixIcon: IconButton(
|
|
||||||
// icon: const Icon(
|
|
||||||
// FeatherIcons.x,
|
|
||||||
// color: Colors.grey,
|
|
||||||
// size: 18.0,
|
|
||||||
// ),
|
|
||||||
// onPressed: () {
|
|
||||||
// setState(() {
|
|
||||||
// _descTxt.text = '';
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// // const SizedBox(
|
|
||||||
// // height: 14.0,
|
|
||||||
// // ),
|
|
||||||
// // // class
|
|
||||||
// // TextField(
|
|
||||||
// // controller: _descTxt,
|
|
||||||
// // onEditingComplete: () async {
|
|
||||||
// // // SharedTheme? theme = await shareProvider.getThemeById(
|
|
||||||
// // // context,
|
|
||||||
// // // id: _paintId.text.replaceAll(' ', ''),
|
|
||||||
// // // );
|
|
||||||
|
|
||||||
// // // if (theme != null) {
|
|
||||||
// // // // set theme variable
|
|
||||||
// // // newThemeByID = theme;
|
|
||||||
|
|
||||||
// // // _paintId.clear();
|
|
||||||
// // // } else {
|
|
||||||
// // // ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
// // // CustomSnackBar(
|
|
||||||
// // // content: Text("theme_not_found".i18n,
|
|
||||||
// // // style: const TextStyle(color: Colors.white)),
|
|
||||||
// // // backgroundColor: AppColors.of(context).red,
|
|
||||||
// // // context: context,
|
|
||||||
// // // ),
|
|
||||||
// // // );
|
|
||||||
// // // }
|
|
||||||
// // },
|
|
||||||
// // decoration: InputDecoration(
|
|
||||||
// // border: OutlineInputBorder(
|
|
||||||
// // borderSide: const BorderSide(
|
|
||||||
// // color: Colors.grey, width: 1.5),
|
|
||||||
// // borderRadius: BorderRadius.circular(12.0),
|
|
||||||
// // ),
|
|
||||||
// // focusedBorder: OutlineInputBorder(
|
|
||||||
// // borderSide: const BorderSide(
|
|
||||||
// // color: Colors.grey, width: 1.5),
|
|
||||||
// // borderRadius: BorderRadius.circular(12.0),
|
|
||||||
// // ),
|
|
||||||
// // contentPadding:
|
|
||||||
// // const EdgeInsets.symmetric(horizontal: 12.0),
|
|
||||||
// // hintText: 'l_desc'.i18n,
|
|
||||||
// // suffixIcon: IconButton(
|
|
||||||
// // icon: const Icon(
|
|
||||||
// // FeatherIcons.x,
|
|
||||||
// // color: Colors.grey,
|
|
||||||
// // size: 18.0,
|
|
||||||
// // ),
|
|
||||||
// // onPressed: () {
|
|
||||||
// // setState(() {
|
|
||||||
// // _descTxt.text = '';
|
|
||||||
// // });
|
|
||||||
// // },
|
|
||||||
// // ),
|
|
||||||
// // ),
|
|
||||||
// // ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// actions: [
|
|
||||||
// TextButton(
|
|
||||||
// child: Text(
|
|
||||||
// "cancel".i18n,
|
|
||||||
// style: const TextStyle(fontWeight: FontWeight.w500),
|
|
||||||
// ),
|
|
||||||
// onPressed: () {
|
|
||||||
// Navigator.of(context).maybePop();
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// TextButton(
|
|
||||||
// child: Text(
|
|
||||||
// "done".i18n,
|
|
||||||
// style: const TextStyle(fontWeight: FontWeight.w500),
|
|
||||||
// ),
|
|
||||||
// onPressed: () async {
|
|
||||||
// saveLesson();
|
|
||||||
|
|
||||||
// Navigator.of(context).pop();
|
|
||||||
// setState(() {});
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
// }),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveLesson() async {
|
void saveLesson() async {
|
||||||
@@ -283,6 +289,18 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Exam? lessonExam;
|
||||||
|
|
||||||
|
if (lesson.exam != "") {
|
||||||
|
Exam exam = Provider.of<ExamProvider>(context, listen: false)
|
||||||
|
.exams
|
||||||
|
.firstWhere((t) => t.id == lesson.exam,
|
||||||
|
orElse: () => Exam.fromJson({}));
|
||||||
|
if (exam.id != "") {
|
||||||
|
lessonExam = exam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
@@ -295,7 +313,9 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
Stack(
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
"assets/svg/mesh_bg.svg",
|
// "assets/svg/mesh_bg.svg",
|
||||||
|
SubjectBooklet.resolveVariant(
|
||||||
|
context: context, subject: lesson.subject),
|
||||||
// ignore: deprecated_member_use
|
// ignore: deprecated_member_use
|
||||||
color: ColorsUtils()
|
color: ColorsUtils()
|
||||||
.fade(context, Theme.of(context).colorScheme.secondary,
|
.fade(context, Theme.of(context).colorScheme.secondary,
|
||||||
@@ -319,13 +339,13 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
.withOpacity(0.1),
|
.withOpacity(0.1),
|
||||||
Theme.of(context).scaffoldBackgroundColor,
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
],
|
],
|
||||||
stops: const [0.1, 0.5, 0.7, 1.0],
|
stops: const [0.0, 0.3, 0.6, 0.95],
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: 175.0,
|
height: 200.0,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -340,16 +360,27 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
width: 40,
|
width: 40,
|
||||||
height: 4,
|
height: 4,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsUtils()
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
.fade(
|
|
||||||
context, Theme.of(context).colorScheme.secondary,
|
|
||||||
darkenAmount: 0.1, lightenAmount: 0.1)
|
|
||||||
.withOpacity(0.33),
|
|
||||||
borderRadius: BorderRadius.circular(
|
borderRadius: BorderRadius.circular(
|
||||||
2.0,
|
2.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
child: Container(
|
||||||
|
width: 40,
|
||||||
|
height: 4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsUtils()
|
||||||
|
.fade(context,
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
darkenAmount: 0.1, lightenAmount: 0.1)
|
||||||
|
.withOpacity(0.33),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
2.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 38.0,
|
height: 38.0,
|
||||||
),
|
),
|
||||||
@@ -387,11 +418,9 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
borderRadius: BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: const Radius.circular(12.0),
|
top: Radius.circular(12.0),
|
||||||
bottom: (lesson.description.replaceAll(' ', '') != '')
|
bottom: Radius.circular(6.0),
|
||||||
? const Radius.circular(6.0)
|
|
||||||
: const Radius.circular(12.0),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(14.0),
|
padding: const EdgeInsets.all(14.0),
|
||||||
@@ -466,7 +495,15 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
height: 8.0,
|
height: 8.0,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
lesson.teacher.name,
|
((lesson.substituteTeacher == null ||
|
||||||
|
lesson.substituteTeacher!.name == "")
|
||||||
|
? (lesson.teacher.isRenamed
|
||||||
|
? lesson.teacher.renamedTo
|
||||||
|
: lesson.teacher.name)
|
||||||
|
: (lesson.substituteTeacher!.isRenamed
|
||||||
|
? lesson.substituteTeacher!.renamedTo
|
||||||
|
: lesson.substituteTeacher!.name)) ??
|
||||||
|
'',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.of(context).text.withOpacity(0.9),
|
color: AppColors.of(context).text.withOpacity(0.9),
|
||||||
fontSize: 14.0,
|
fontSize: 14.0,
|
||||||
@@ -487,7 +524,7 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(6.0),
|
top: Radius.circular(6.0),
|
||||||
bottom: Radius.circular(12.0),
|
bottom: Radius.circular(6.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(14.0),
|
padding: const EdgeInsets.all(14.0),
|
||||||
@@ -506,6 +543,94 @@ class TimetableLessonPopup extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 6.0,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
borderRadius: BorderRadius.vertical(
|
||||||
|
top: const Radius.circular(6.0),
|
||||||
|
bottom: lesson.exam != ''
|
||||||
|
? const Radius.circular(6.0)
|
||||||
|
: const Radius.circular(12.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(14.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${'year_index'.i18n}: ${lesson.lessonYearIndex ?? '?'}',
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.9),
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (lesson.exam != '')
|
||||||
|
const SizedBox(
|
||||||
|
height: 6.0,
|
||||||
|
),
|
||||||
|
if (lesson.exam != '' && lessonExam != null)
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
top: Radius.circular(6.0),
|
||||||
|
bottom: Radius.circular(12.0)),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(14.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
FeatherIcons.file,
|
||||||
|
size: 20.0,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10.0,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.5,
|
||||||
|
child: Text(
|
||||||
|
lessonExam.description.capital(),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context)
|
||||||
|
.text
|
||||||
|
.withOpacity(0.9),
|
||||||
|
fontSize: 16.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
lessonExam.mode?.description ?? 'Dolgozat',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context)
|
||||||
|
.text
|
||||||
|
.withOpacity(0.85),
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
// const SizedBox(
|
// const SizedBox(
|
||||||
// height: 24.0,
|
// height: 24.0,
|
||||||
// ),
|
// ),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ extension Localization on String {
|
|||||||
"Messages": "Messages",
|
"Messages": "Messages",
|
||||||
"Absences": "Absences",
|
"Absences": "Absences",
|
||||||
"update_available": "Update Available",
|
"update_available": "Update Available",
|
||||||
"missed_exams": "You missed %s exams this week.".one("You missed an exam this week."),
|
"missed_exams": "You missed %s exam(s) this week.",
|
||||||
"missed_exam_contact": "Contact %s, to resolve it!",
|
"missed_exam_contact": "Contact %s, to resolve it!",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
@@ -34,7 +34,7 @@ extension Localization on String {
|
|||||||
"Messages": "Üzenetek",
|
"Messages": "Üzenetek",
|
||||||
"Absences": "Hiányok",
|
"Absences": "Hiányok",
|
||||||
"update_available": "Frissítés elérhető",
|
"update_available": "Frissítés elérhető",
|
||||||
"missed_exams": "Ezen a héten hiányoztál %s dolgozatról.".one("Ezen a héten hiányoztál egy dolgozatról."),
|
"missed_exams": "Ezen a héten hiányoztál %s dolgozatról.",
|
||||||
"missed_exam_contact": "Keresd %s-t, ha pótolni szeretnéd!",
|
"missed_exam_contact": "Keresd %s-t, ha pótolni szeretnéd!",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
@@ -51,7 +51,7 @@ extension Localization on String {
|
|||||||
"Messages": "Nachrichten",
|
"Messages": "Nachrichten",
|
||||||
"Absences": "Fehlen",
|
"Absences": "Fehlen",
|
||||||
"update_available": "Update verfügbar",
|
"update_available": "Update verfügbar",
|
||||||
"missed_exams": "Diese Woche haben Sie %s Prüfungen verpasst.".one("Diese Woche haben Sie eine Prüfung verpasst."),
|
"missed_exams": "Diese Woche haben Sie %s Prüfungen verpasst.",
|
||||||
"missed_exam_contact": "Wenden Sie sich an %s, um sie zu erneuern!",
|
"missed_exam_contact": "Wenden Sie sich an %s, um sie zu erneuern!",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:refilc/api/providers/update_provider.dart';
|
import 'package:refilc/api/providers/update_provider.dart';
|
||||||
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/theme/colors/utils.dart';
|
import 'package:refilc/theme/colors/utils.dart';
|
||||||
import 'package:refilc/ui/date_widget.dart';
|
import 'package:refilc/ui/date_widget.dart';
|
||||||
import 'package:refilc_kreta_api/models/absence.dart';
|
import 'package:refilc_kreta_api/models/absence.dart';
|
||||||
@@ -169,6 +171,7 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -179,10 +182,22 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Absences".i18n,
|
"Absences".i18n,
|
||||||
style: TextStyle(
|
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
||||||
color: AppColors.of(context).text,
|
'' &&
|
||||||
fontSize: 32.0,
|
Provider.of<SettingsProvider>(context).titleOnlyFont
|
||||||
fontWeight: FontWeight.bold),
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(context).fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
bottom: FilterBar(
|
bottom: FilterBar(
|
||||||
@@ -504,7 +519,9 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18.0,
|
fontSize: 18.0,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: AppColors.of(context).green,
|
color: value1 > 0
|
||||||
|
? AppColors.of(context).green
|
||||||
|
: AppColors.of(context).text,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
@@ -513,12 +530,14 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
fontSize: 16.0,
|
fontSize: 16.0,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
height: 1.1,
|
height: 1.1,
|
||||||
color: ColorsUtils().fade(
|
color: value1 > 0
|
||||||
context,
|
? ColorsUtils().fade(
|
||||||
AppColors.of(context).green,
|
context,
|
||||||
darkenAmount: 0.5,
|
AppColors.of(context).green,
|
||||||
lightenAmount: 0.4,
|
darkenAmount: 0.5,
|
||||||
),
|
lightenAmount: 0.4,
|
||||||
|
)
|
||||||
|
: AppColors.of(context).text,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -535,7 +554,9 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18.0,
|
fontSize: 18.0,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: AppColors.of(context).red,
|
color: value2 > 0
|
||||||
|
? AppColors.of(context).red
|
||||||
|
: AppColors.of(context).text,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
@@ -544,12 +565,14 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
fontSize: 16.0,
|
fontSize: 16.0,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
height: 1.1,
|
height: 1.1,
|
||||||
color: ColorsUtils().fade(
|
color: value2 > 0
|
||||||
context,
|
? ColorsUtils().fade(
|
||||||
AppColors.of(context).red,
|
context,
|
||||||
darkenAmount: 0.4,
|
AppColors.of(context).red,
|
||||||
lightenAmount: 0.2,
|
darkenAmount: 0.4,
|
||||||
),
|
lightenAmount: 0.2,
|
||||||
|
)
|
||||||
|
: AppColors.of(context).text,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -597,8 +620,9 @@ class AbsencesPageState extends State<AbsencesPage>
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.av_timer_rounded,
|
Icons.av_timer_rounded,
|
||||||
|
color: value3 > 0 ? Colors.orange : null,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10.0,
|
width: 10.0,
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import 'package:refilc_mobile_ui/pages/grades/calculator/grade_calculator_provid
|
|||||||
import 'package:refilc_mobile_ui/pages/grades/grades_count.dart';
|
import 'package:refilc_mobile_ui/pages/grades/grades_count.dart';
|
||||||
import 'package:refilc_mobile_ui/pages/grades/graph.dart';
|
import 'package:refilc_mobile_ui/pages/grades/graph.dart';
|
||||||
import 'package:refilc_mobile_ui/pages/grades/subject_grades_container.dart';
|
import 'package:refilc_mobile_ui/pages/grades/subject_grades_container.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/goal_planner/goal_planner_screen.dart';
|
|
||||||
// import 'package:refilc_plus/models/premium_scopes.dart';
|
// import 'package:refilc_plus/models/premium_scopes.dart';
|
||||||
// import 'package:refilc_plus/providers/plus_provider.dart';
|
// import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/goal_planner/goal_state_screen.dart';
|
import 'package:refilc_plus/ui/mobile/goal_planner/goal_state_screen.dart';
|
||||||
@@ -44,6 +43,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:refilc_plus/ui/mobile/goal_planner/goal_track_popup.dart';
|
||||||
import 'grades_page.i18n.dart';
|
import 'grades_page.i18n.dart';
|
||||||
// import 'package:refilc_plus/ui/mobile/goal_planner/new_goal.dart';
|
// import 'package:refilc_plus/ui/mobile/goal_planner/new_goal.dart';
|
||||||
|
|
||||||
@@ -425,9 +425,10 @@ class _GradeSubjectViewState extends State<GradeSubjectView>
|
|||||||
// ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
// const SnackBar(content: Text("Hamarosan...")));
|
// const SnackBar(content: Text("Hamarosan...")));
|
||||||
|
|
||||||
Navigator.of(context).push(CupertinoPageRoute(
|
// Navigator.of(context).push(CupertinoPageRoute(
|
||||||
builder: (context) =>
|
// builder: (context) =>
|
||||||
GoalPlannerScreen(subject: widget.subject)));
|
// GoalPlannerScreen(subject: widget.subject)));
|
||||||
|
GoalTrackPopup.show(context, subject: widget.subject);
|
||||||
},
|
},
|
||||||
child: const Icon(FeatherIcons.flag, size: 20.0),
|
child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:auto_size_text/auto_size_text.dart';
|
import 'package:auto_size_text/auto_size_text.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:refilc/api/providers/update_provider.dart';
|
import 'package:refilc/api/providers/update_provider.dart';
|
||||||
import 'package:refilc/models/settings.dart';
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
||||||
@@ -88,19 +92,18 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
int avgDropValue = 0;
|
int avgDropValue = 0;
|
||||||
|
|
||||||
bool gradeCalcMode = false;
|
bool gradeCalcMode = false;
|
||||||
|
bool importedViewMode = false;
|
||||||
|
|
||||||
|
List<Grade> jsonGrades = [];
|
||||||
|
|
||||||
List<Grade> getSubjectGrades(GradeSubject subject,
|
List<Grade> getSubjectGrades(GradeSubject subject,
|
||||||
{int days = 0}) =>
|
{int days = 0}) =>
|
||||||
!gradeCalcMode
|
!gradeCalcMode
|
||||||
? gradeProvider
|
? (importedViewMode ? jsonGrades : gradeProvider.grades)
|
||||||
.grades
|
|
||||||
.where((e) =>
|
.where((e) =>
|
||||||
e
|
e.subject == subject &&
|
||||||
.subject ==
|
|
||||||
subject &&
|
|
||||||
e.type == GradeType.midYear &&
|
e.type == GradeType.midYear &&
|
||||||
(days ==
|
(days == 0 ||
|
||||||
0 ||
|
|
||||||
e.date.isBefore(
|
e.date.isBefore(
|
||||||
DateTime.now().subtract(Duration(days: days)))))
|
DateTime.now().subtract(Duration(days: days)))))
|
||||||
.toList()
|
.toList()
|
||||||
@@ -109,18 +112,19 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
void generateTiles() {
|
void generateTiles() {
|
||||||
List<GradeSubject> subjects = gradeProvider.grades
|
List<GradeSubject> subjects =
|
||||||
.map((e) => GradeSubject(
|
(importedViewMode ? jsonGrades : gradeProvider.grades)
|
||||||
category: e.subject.category,
|
.map((e) => GradeSubject(
|
||||||
id: e.subject.id,
|
category: e.subject.category,
|
||||||
name: e.subject.name,
|
id: e.subject.id,
|
||||||
renamedTo: e.subject.renamedTo,
|
name: e.subject.name,
|
||||||
customRounding: e.subject.customRounding,
|
renamedTo: e.subject.renamedTo,
|
||||||
teacher: e.teacher,
|
customRounding: e.subject.customRounding,
|
||||||
))
|
teacher: e.teacher,
|
||||||
.toSet()
|
))
|
||||||
.toList()
|
.toSet()
|
||||||
..sort((a, b) => a.name.compareTo(b.name));
|
.toList()
|
||||||
|
..sort((a, b) => a.name.compareTo(b.name));
|
||||||
List<Widget> tiles = [];
|
List<Widget> tiles = [];
|
||||||
|
|
||||||
Map<GradeSubject, double> subjectAvgs = {};
|
Map<GradeSubject, double> subjectAvgs = {};
|
||||||
@@ -164,7 +168,8 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
e.subject.id == subject.id && e.writeDate.isAfter(DateTime.now()));
|
e.subject.id == subject.id && e.writeDate.isAfter(DateTime.now()));
|
||||||
|
|
||||||
bool hasUnder = (hasHomework || nearestExam != null) &&
|
bool hasUnder = (hasHomework || nearestExam != null) &&
|
||||||
Provider.of<SettingsProvider>(context).qSubjectsSubTiles;
|
Provider.of<SettingsProvider>(context, listen: false)
|
||||||
|
.qSubjectsSubTiles;
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: i > 1 ? const EdgeInsets.only(top: 9.0) : EdgeInsets.zero,
|
padding: i > 1 ? const EdgeInsets.only(top: 9.0) : EdgeInsets.zero,
|
||||||
@@ -219,7 +224,8 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
height: 6.0,
|
height: 6.0,
|
||||||
),
|
),
|
||||||
if (hasHomework &&
|
if (hasHomework &&
|
||||||
Provider.of<SettingsProvider>(context).qSubjectsSubTiles)
|
Provider.of<SettingsProvider>(context, listen: false)
|
||||||
|
.qSubjectsSubTiles)
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
@@ -267,6 +273,12 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (hasHomework &&
|
||||||
|
nearestExam != null &&
|
||||||
|
Provider.of<SettingsProvider>(context).qSubjectsSubTiles)
|
||||||
|
const SizedBox(
|
||||||
|
height: 6.0,
|
||||||
|
),
|
||||||
if (nearestExam != null &&
|
if (nearestExam != null &&
|
||||||
Provider.of<SettingsProvider>(context).qSubjectsSubTiles)
|
Provider.of<SettingsProvider>(context).qSubjectsSubTiles)
|
||||||
Container(
|
Container(
|
||||||
@@ -441,25 +453,28 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
.fold(0.0, (double a, double b) => a + b) /
|
.fold(0.0, (double a, double b) => a + b) /
|
||||||
gradeProvider.groupAverages.length;
|
gradeProvider.groupAverages.length;
|
||||||
|
|
||||||
final now = gradeProvider.grades.isNotEmpty
|
final now =
|
||||||
? gradeProvider.grades
|
(importedViewMode ? jsonGrades : gradeProvider.grades).isNotEmpty
|
||||||
.reduce((v, e) => e.date.isAfter(v.date) ? e : v)
|
? (importedViewMode ? jsonGrades : gradeProvider.grades)
|
||||||
.date
|
.reduce((v, e) => e.date.isAfter(v.date) ? e : v)
|
||||||
: DateTime.now();
|
.date
|
||||||
|
: DateTime.now();
|
||||||
|
|
||||||
final currentStudentAvg = AverageHelper.averageEvals(!gradeCalcMode
|
final currentStudentAvg = AverageHelper.averageEvals(!gradeCalcMode
|
||||||
? gradeProvider.grades
|
? (importedViewMode ? jsonGrades : gradeProvider.grades)
|
||||||
.where((e) => e.type == GradeType.midYear)
|
.where((e) => e.type == GradeType.midYear)
|
||||||
.toList()
|
.toList()
|
||||||
: calculatorProvider.grades);
|
: calculatorProvider.grades);
|
||||||
|
|
||||||
final prevStudentAvg = AverageHelper.averageEvals(gradeProvider.grades
|
final prevStudentAvg = AverageHelper.averageEvals((importedViewMode
|
||||||
|
? jsonGrades
|
||||||
|
: gradeProvider.grades)
|
||||||
.where((e) => e.type == GradeType.midYear)
|
.where((e) => e.type == GradeType.midYear)
|
||||||
.where((e) => e.date.isBefore(now.subtract(const Duration(days: 30))))
|
.where((e) => e.date.isBefore(now.subtract(const Duration(days: 30))))
|
||||||
.toList());
|
.toList());
|
||||||
|
|
||||||
List<Grade> graphGrades = !gradeCalcMode
|
List<Grade> graphGrades = !gradeCalcMode
|
||||||
? gradeProvider.grades
|
? (importedViewMode ? jsonGrades : gradeProvider.grades)
|
||||||
.where((e) =>
|
.where((e) =>
|
||||||
e.type == GradeType.midYear &&
|
e.type == GradeType.midYear &&
|
||||||
(avgDropValue == 0 ||
|
(avgDropValue == 0 ||
|
||||||
@@ -493,7 +508,7 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
// const SizedBox(width: 4.0),
|
// const SizedBox(width: 4.0),
|
||||||
TrendDisplay(
|
TrendDisplay(
|
||||||
previous: prevStudentAvg, current: currentStudentAvg),
|
previous: prevStudentAvg, current: currentStudentAvg),
|
||||||
if (gradeProvider.grades
|
if ((importedViewMode ? jsonGrades : gradeProvider.grades)
|
||||||
.where((e) => e.type == GradeType.midYear)
|
.where((e) => e.type == GradeType.midYear)
|
||||||
.isNotEmpty)
|
.isNotEmpty)
|
||||||
AverageDisplay(average: currentStudentAvg),
|
AverageDisplay(average: currentStudentAvg),
|
||||||
@@ -560,6 +575,7 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -568,11 +584,21 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
title: Padding(
|
title: Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Grades".i18n,
|
"page_title_grades".i18n,
|
||||||
style: TextStyle(
|
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
||||||
color: AppColors.of(context).text,
|
'' &&
|
||||||
fontSize: 32.0,
|
Provider.of<SettingsProvider>(context).titleOnlyFont
|
||||||
fontWeight: FontWeight.bold),
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(context).fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
shadowColor: Theme.of(context).shadowColor,
|
shadowColor: Theme.of(context).shadowColor,
|
||||||
@@ -614,7 +640,8 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
|
|
||||||
void gradeCalcTotal(BuildContext context) {
|
void gradeCalcTotal(BuildContext context) {
|
||||||
calculatorProvider.clear();
|
calculatorProvider.clear();
|
||||||
calculatorProvider.addAllGrades(gradeProvider.grades);
|
calculatorProvider
|
||||||
|
.addAllGrades((importedViewMode ? jsonGrades : gradeProvider.grades));
|
||||||
|
|
||||||
_sheetController = _scaffoldKey.currentState?.showBottomSheet(
|
_sheetController = _scaffoldKey.currentState?.showBottomSheet(
|
||||||
(context) => const RoundedBottomSheet(
|
(context) => const RoundedBottomSheet(
|
||||||
@@ -667,6 +694,66 @@ class GradesPageState extends State<GradesPage> {
|
|||||||
|
|
||||||
// SoonAlert.show(context: context);
|
// SoonAlert.show(context: context);
|
||||||
gradeCalcTotal(context);
|
gradeCalcTotal(context);
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10.0,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
color: Theme.of(context).colorScheme.background),
|
||||||
|
child: ListTile(
|
||||||
|
title: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.toll_rounded),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10.0,
|
||||||
|
),
|
||||||
|
Text('import_grades'.i18n),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
trailing: importedViewMode ? const Icon(FeatherIcons.x) : null,
|
||||||
|
onTap: () {
|
||||||
|
if (importedViewMode) {
|
||||||
|
importedViewMode = false;
|
||||||
|
|
||||||
|
generateTiles();
|
||||||
|
setState(() {});
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||||
|
.hasScope(PremiumScopes.gradeExporting)) {
|
||||||
|
PlusLockedFeaturePopup.show(
|
||||||
|
context: context, feature: PremiumFeature.gradeExporting);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// show file picker
|
||||||
|
FilePicker.platform.pickFiles(
|
||||||
|
type: FileType.custom,
|
||||||
|
allowedExtensions: ['json'],
|
||||||
|
).then((value) {
|
||||||
|
if (value != null) {
|
||||||
|
final File file = File(value.files.single.path!);
|
||||||
|
final String content = file.readAsStringSync();
|
||||||
|
final List<dynamic> json = jsonDecode(content);
|
||||||
|
|
||||||
|
jsonGrades = json.map((e) => Grade.fromJson(e)).toList();
|
||||||
|
importedViewMode = true;
|
||||||
|
|
||||||
|
generateTiles();
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ extension Localization on String {
|
|||||||
static final _t = Translations.byLocale("hu_hu") +
|
static final _t = Translations.byLocale("hu_hu") +
|
||||||
{
|
{
|
||||||
"en_en": {
|
"en_en": {
|
||||||
"Grades": "Subjects",
|
"Grades": "Grades",
|
||||||
"Ghost Grades": "Grades",
|
"page_title_grades": "Subjects",
|
||||||
|
"Ghost Grades": "Ghost Grades",
|
||||||
"Subjects": "Your Subjects",
|
"Subjects": "Your Subjects",
|
||||||
"Subjects_changes": "Subject Differences",
|
"Subjects_changes": "Subject Differences",
|
||||||
"empty": "You don't have any subjects.",
|
"empty": "You don't have any subjects.",
|
||||||
@@ -17,8 +18,7 @@ extension Localization on String {
|
|||||||
"subjectavg": "Subject Average",
|
"subjectavg": "Subject Average",
|
||||||
"classavg": "Class Average",
|
"classavg": "Class Average",
|
||||||
"fail_warning": "Failure warning",
|
"fail_warning": "Failure warning",
|
||||||
"fail_warning_description":
|
"fail_warning_description": "You are failing %d subject(s)!",
|
||||||
"You are failing %d subjects!".one("You are failing a subject!"),
|
|
||||||
"data": "Data",
|
"data": "Data",
|
||||||
"you_have_hw": "You have %s homework(s) to do",
|
"you_have_hw": "You have %s homework(s) to do",
|
||||||
"grades_cnt": "Grade count: %s",
|
"grades_cnt": "Grade count: %s",
|
||||||
@@ -29,9 +29,11 @@ extension Localization on String {
|
|||||||
"grades": "Grades",
|
"grades": "Grades",
|
||||||
"show_exams_homework": "Exams and Homework",
|
"show_exams_homework": "Exams and Homework",
|
||||||
"grade_calc": "Grade Calculator",
|
"grade_calc": "Grade Calculator",
|
||||||
|
"import_grades": "Import Grades (JSON)",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"Grades": "Tantárgyak",
|
"Grades": "Jegyek",
|
||||||
|
"page_title_grades": "Tantárgyak",
|
||||||
"Ghost Grades": "Szellem jegyek",
|
"Ghost Grades": "Szellem jegyek",
|
||||||
"Subjects": "Tantárgyaid",
|
"Subjects": "Tantárgyaid",
|
||||||
"Subjects_changes": "Tantárgyi változások",
|
"Subjects_changes": "Tantárgyi változások",
|
||||||
@@ -55,9 +57,11 @@ extension Localization on String {
|
|||||||
"grades": "Jegyek",
|
"grades": "Jegyek",
|
||||||
"show_exams_homework": "Dolgozatok és házik",
|
"show_exams_homework": "Dolgozatok és házik",
|
||||||
"grade_calc": "Jegy kalkulátor",
|
"grade_calc": "Jegy kalkulátor",
|
||||||
|
"import_grades": "Jegyek importálása (JSON)",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"Grades": "Fächer",
|
"Grades": "Klassen",
|
||||||
|
"page_title_grades": "Themen",
|
||||||
"Ghost Grades": "Geist Noten",
|
"Ghost Grades": "Geist Noten",
|
||||||
"Subjects": "Ihre Themen",
|
"Subjects": "Ihre Themen",
|
||||||
"Subjects_changes": "Betreff Änderungen",
|
"Subjects_changes": "Betreff Änderungen",
|
||||||
@@ -81,6 +85,7 @@ extension Localization on String {
|
|||||||
"grades": "Noten",
|
"grades": "Noten",
|
||||||
"show_exams_homework": "Referate und Hausaufgaben",
|
"show_exams_homework": "Referate und Hausaufgaben",
|
||||||
"grade_calc": "Noten-Rechner",
|
"grade_calc": "Noten-Rechner",
|
||||||
|
"import_grades": "Noten importieren (JSON)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -248,11 +248,12 @@ class GradeGraphState extends State<GradeGraph> {
|
|||||||
),
|
),
|
||||||
if (ghostData.isNotEmpty && ghostSpots.isNotEmpty)
|
if (ghostData.isNotEmpty && ghostSpots.isNotEmpty)
|
||||||
LineChartBarData(
|
LineChartBarData(
|
||||||
preventCurveOverShooting: true,
|
preventCurveOverShooting: false,
|
||||||
spots: ghostSpots,
|
spots: ghostSpots,
|
||||||
isCurved: true,
|
isCurved: true,
|
||||||
colors: [AppColors.of(context).text],
|
colors: [AppColors.of(context).text],
|
||||||
barWidth: 8,
|
barWidth: 6,
|
||||||
|
curveSmoothness: 0.2,
|
||||||
isStrokeCapRound: true,
|
isStrokeCapRound: true,
|
||||||
dotData: FlDotData(show: false),
|
dotData: FlDotData(show: false),
|
||||||
belowBarData: BarAreaData(
|
belowBarData: BarAreaData(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:refilc/api/providers/live_card_provider.dart';
|
import 'package:refilc/api/providers/live_card_provider.dart';
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:refilc/ui/date_widget.dart';
|
import 'package:refilc/ui/date_widget.dart';
|
||||||
@@ -244,14 +245,34 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
greeting,
|
greeting,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
style: TextStyle(
|
style:
|
||||||
fontWeight: FontWeight.bold,
|
Provider.of<SettingsProvider>(context)
|
||||||
fontSize: 18.0,
|
.fontFamily !=
|
||||||
color: Theme.of(context)
|
'' &&
|
||||||
.textTheme
|
Provider.of<SettingsProvider>(
|
||||||
.bodyMedium
|
context)
|
||||||
?.color,
|
.titleOnlyFont
|
||||||
),
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(
|
||||||
|
context)
|
||||||
|
.fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18.0,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.color,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18.0,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium
|
||||||
|
?.color,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
DateFormat('EEEE, MMM d',
|
DateFormat('EEEE, MMM d',
|
||||||
@@ -317,6 +338,7 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -355,7 +377,7 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
|||||||
LiveCardState.duringLesson ||
|
LiveCardState.duringLesson ||
|
||||||
_liveCard.currentState ==
|
_liveCard.currentState ==
|
||||||
LiveCardState.duringBreak)
|
LiveCardState.duringBreak)
|
||||||
? 55.0
|
? 62.0
|
||||||
: 52.0),
|
: 52.0),
|
||||||
),
|
),
|
||||||
child: Transform.scale(
|
child: Transform.scale(
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ extension Localization on String {
|
|||||||
"Messages": "Messages",
|
"Messages": "Messages",
|
||||||
"Absences": "Absences",
|
"Absences": "Absences",
|
||||||
"update_available": "Update Available",
|
"update_available": "Update Available",
|
||||||
"missed_exams": "You missed %s exams this week."
|
"missed_exams": "You missed %s exam(s) this week.",
|
||||||
.one("You missed an exam this week."),
|
|
||||||
"missed_exam_contact": "Contact %s to resolve it!",
|
"missed_exam_contact": "Contact %s to resolve it!",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
@@ -39,8 +38,7 @@ extension Localization on String {
|
|||||||
"Messages": "Üzenetek",
|
"Messages": "Üzenetek",
|
||||||
"Absences": "Hiányzások",
|
"Absences": "Hiányzások",
|
||||||
"update_available": "Frissítés elérhető",
|
"update_available": "Frissítés elérhető",
|
||||||
"missed_exams": "Ezen a héten hiányoztál %s dolgozatról."
|
"missed_exams": "Ezen a héten hiányoztál %s dolgozatról.",
|
||||||
.one("Ezen a héten hiányoztál egy dolgozatról."),
|
|
||||||
"missed_exam_contact": "Keresd %s tanár urat/hölgyet, hogy pótold!",
|
"missed_exam_contact": "Keresd %s tanár urat/hölgyet, hogy pótold!",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
@@ -59,8 +57,7 @@ extension Localization on String {
|
|||||||
"Messages": "Nachrichten",
|
"Messages": "Nachrichten",
|
||||||
"Absences": "Fehlen",
|
"Absences": "Fehlen",
|
||||||
"update_available": "Update verfügbar",
|
"update_available": "Update verfügbar",
|
||||||
"missed_exams": "Diese Woche haben Sie %s Prüfungen verpasst."
|
"missed_exams": "Diese Woche haben Sie %s Prüfungen verpasst.",
|
||||||
.one("Diese Woche haben Sie eine Prüfung verpasst."),
|
|
||||||
"missed_exam_contact": "Wenden Sie sich an %s, um sie zu erneuern!",
|
"missed_exam_contact": "Wenden Sie sich an %s, um sie zu erneuern!",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ class LiveCardStateA extends State<LiveCard> {
|
|||||||
swapRoom: true,
|
swapRoom: true,
|
||||||
currentLessonIndicator: false,
|
currentLessonIndicator: false,
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(top: 6.0, bottom: 4.0),
|
const EdgeInsets.only(top: 2.0, bottom: 4.0),
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
showSubTiles: false,
|
showSubTiles: false,
|
||||||
),
|
),
|
||||||
@@ -911,6 +911,37 @@ class LiveCardStateA extends State<LiveCard> {
|
|||||||
Row(
|
Row(
|
||||||
children: liveCard.nextLesson != null
|
children: liveCard.nextLesson != null
|
||||||
? [
|
? [
|
||||||
|
Container(
|
||||||
|
width: (liveCard.nextLesson?.room
|
||||||
|
.length ??
|
||||||
|
0) >
|
||||||
|
20
|
||||||
|
? 111
|
||||||
|
: null,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 5.5, vertical: 3.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.tertiary
|
||||||
|
.withOpacity(.15),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
liveCard.nextLesson!.room,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
height: 1.1,
|
||||||
|
fontSize: 12.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.9),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ extension Localization on String {
|
|||||||
{
|
{
|
||||||
"en_en": {
|
"en_en": {
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"remaining min": "%d mins".one("%d min"),
|
"remaining min": "%d min(s)",
|
||||||
"remaining sec": "%d secs".one("%d sec"),
|
"remaining sec": "%d sec(s)",
|
||||||
"break": "Break",
|
"break": "Break",
|
||||||
"go to room": "Go to room %s.",
|
"go to room": "Go to room %s.",
|
||||||
"go ground floor": "Go to the ground floor.",
|
"go ground floor": "Go to the ground floor.",
|
||||||
@@ -27,8 +27,8 @@ extension Localization on String {
|
|||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"next": "Következő",
|
"next": "Következő",
|
||||||
"remaining min": "%d perc".one("%d perc"),
|
"remaining min": "%d perc",
|
||||||
"remaining sec": "%d másodperc".one("%d másodperc"),
|
"remaining sec": "%d másodperc",
|
||||||
"break": "Szünet",
|
"break": "Szünet",
|
||||||
"go to room": "Menj a(z) %s terembe.",
|
"go to room": "Menj a(z) %s terembe.",
|
||||||
"go ground floor": "Menj a földszintre.",
|
"go ground floor": "Menj a földszintre.",
|
||||||
@@ -49,8 +49,8 @@ extension Localization on String {
|
|||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"next": "Nächste",
|
"next": "Nächste",
|
||||||
"remaining min": "%d Minuten".one("%d Minute"),
|
"remaining min": "%d Minute(n)",
|
||||||
"remaining sec": "%d Sekunden".one("%d Sekunden"),
|
"remaining sec": "%d Sekunde(n)",
|
||||||
"break": "Pause",
|
"break": "Pause",
|
||||||
"go to room": "Geh in den Raum %s.",
|
"go to room": "Geh in den Raum %s.",
|
||||||
"go ground floor": "Geh dir Treppe hinunter.",
|
"go ground floor": "Geh dir Treppe hinunter.",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:refilc/api/providers/update_provider.dart';
|
import 'package:refilc/api/providers/update_provider.dart';
|
||||||
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/ui/date_widget.dart';
|
import 'package:refilc/ui/date_widget.dart';
|
||||||
import 'package:refilc_kreta_api/providers/message_provider.dart';
|
import 'package:refilc_kreta_api/providers/message_provider.dart';
|
||||||
import 'package:refilc/api/providers/user_provider.dart';
|
import 'package:refilc/api/providers/user_provider.dart';
|
||||||
@@ -109,6 +111,7 @@ class MessagesPageState extends State<MessagesPage>
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -128,10 +131,22 @@ class MessagesPageState extends State<MessagesPage>
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"Messages".i18n,
|
"Messages".i18n,
|
||||||
style: TextStyle(
|
style: Provider.of<SettingsProvider>(context)
|
||||||
color: AppColors.of(context).text,
|
.fontFamily !=
|
||||||
fontSize: 32.0,
|
'' &&
|
||||||
fontWeight: FontWeight.bold),
|
Provider.of<SettingsProvider>(context)
|
||||||
|
.titleOnlyFont
|
||||||
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(context).fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:refilc/api/providers/database_provider.dart';
|
import 'package:refilc/api/providers/database_provider.dart';
|
||||||
import 'package:refilc/api/providers/self_note_provider.dart';
|
import 'package:refilc/api/providers/self_note_provider.dart';
|
||||||
import 'package:refilc/api/providers/update_provider.dart';
|
import 'package:refilc/api/providers/update_provider.dart';
|
||||||
@@ -35,6 +36,7 @@ import 'package:refilc_plus/models/premium_scopes.dart';
|
|||||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/plus/premium_inline.dart';
|
import 'package:refilc_plus/ui/mobile/plus/premium_inline.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
import 'notes_page.i18n.dart';
|
import 'notes_page.i18n.dart';
|
||||||
|
|
||||||
enum AbsenceFilter { absences, delays, misses }
|
enum AbsenceFilter { absences, delays, misses }
|
||||||
@@ -65,9 +67,14 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
Map<String, bool> doneItems = {};
|
Map<String, bool> doneItems = {};
|
||||||
List<Widget> noteTiles = [];
|
List<Widget> noteTiles = [];
|
||||||
|
List<TodoItem> todoItems = [];
|
||||||
|
|
||||||
|
final TextEditingController _taskName = TextEditingController();
|
||||||
|
final TextEditingController _taskContent = TextEditingController();
|
||||||
|
|
||||||
void generateTiles() async {
|
void generateTiles() async {
|
||||||
doneItems = await databaseProvider.userQuery.toDoItems(userId: user.id!);
|
doneItems = await databaseProvider.userQuery.toDoItems(userId: user.id!);
|
||||||
|
todoItems = await databaseProvider.userQuery.getTodoItems(userId: user.id!);
|
||||||
|
|
||||||
List<Widget> tiles = [];
|
List<Widget> tiles = [];
|
||||||
|
|
||||||
@@ -82,7 +89,7 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
List<Widget> toDoTiles = [];
|
List<Widget> toDoTiles = [];
|
||||||
|
|
||||||
if (hw.isNotEmpty &&
|
if (hw.isNotEmpty &&
|
||||||
!Provider.of<PlusProvider>(context, listen: false)
|
Provider.of<PlusProvider>(context, listen: false)
|
||||||
.hasScope(PremiumScopes.unlimitedSelfNotes)) {
|
.hasScope(PremiumScopes.unlimitedSelfNotes)) {
|
||||||
toDoTiles.addAll(hw.map((e) => TickTile(
|
toDoTiles.addAll(hw.map((e) => TickTile(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
@@ -102,6 +109,21 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selfNoteProvider.todos.isNotEmpty) {
|
||||||
|
toDoTiles.addAll(selfNoteProvider.todos.map((e) => TickTile(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
title: e.title,
|
||||||
|
description: e.content,
|
||||||
|
isTicked: e.done,
|
||||||
|
onTap: (p0) async {
|
||||||
|
todoItems.firstWhere((element) => element.id == e.id).done = p0;
|
||||||
|
|
||||||
|
await databaseProvider.userStore
|
||||||
|
.storeSelfTodoItems(todoItems, userId: user.id!);
|
||||||
|
},
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
if (toDoTiles.isNotEmpty) {
|
if (toDoTiles.isNotEmpty) {
|
||||||
tiles.add(const SizedBox(
|
tiles.add(const SizedBox(
|
||||||
height: 10.0,
|
height: 10.0,
|
||||||
@@ -128,26 +150,31 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
builder: (context) => NoteViewScreen(note: e))),
|
builder: (context) => NoteViewScreen(note: e))),
|
||||||
)
|
)
|
||||||
: Container(
|
: GestureDetector(
|
||||||
height: MediaQuery.of(context).size.width / 2.42,
|
onTap: () => Navigator.of(context, rootNavigator: true).push(
|
||||||
width: MediaQuery.of(context).size.width / 2.42,
|
CupertinoPageRoute(
|
||||||
decoration: BoxDecoration(
|
builder: (context) => NoteViewScreen(note: e))),
|
||||||
boxShadow: [
|
child: Container(
|
||||||
if (Provider.of<SettingsProvider>(context, listen: false)
|
height: MediaQuery.of(context).size.width / 2.42,
|
||||||
.shadowEffect)
|
width: MediaQuery.of(context).size.width / 2.42,
|
||||||
BoxShadow(
|
decoration: BoxDecoration(
|
||||||
offset: const Offset(0, 21),
|
boxShadow: [
|
||||||
blurRadius: 23.0,
|
if (Provider.of<SettingsProvider>(context, listen: false)
|
||||||
color: Theme.of(context).shadowColor,
|
.shadowEffect)
|
||||||
),
|
BoxShadow(
|
||||||
],
|
offset: const Offset(0, 21),
|
||||||
),
|
blurRadius: 23.0,
|
||||||
child: ClipRRect(
|
color: Theme.of(context).shadowColor,
|
||||||
borderRadius: BorderRadius.circular(16.0),
|
),
|
||||||
child: Image.memory(
|
],
|
||||||
const Base64Decoder().convert(e.content),
|
),
|
||||||
fit: BoxFit.cover,
|
child: ClipRRect(
|
||||||
gaplessPlayback: true,
|
borderRadius: BorderRadius.circular(16.0),
|
||||||
|
child: Image.memory(
|
||||||
|
const Base64Decoder().convert(e.content),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
gaplessPlayback: true,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -289,6 +316,7 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -299,10 +327,20 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"notes".i18n,
|
"notes".i18n,
|
||||||
style: TextStyle(
|
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
||||||
color: AppColors.of(context).text,
|
'' &&
|
||||||
fontSize: 32.0,
|
Provider.of<SettingsProvider>(context).titleOnlyFont
|
||||||
fontWeight: FontWeight.bold),
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(context).fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -313,6 +351,8 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
.fetch(
|
.fetch(
|
||||||
from: DateTime.now().subtract(const Duration(days: 30)));
|
from: DateTime.now().subtract(const Duration(days: 30)));
|
||||||
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||||
|
Provider.of<SelfNoteProvider>(context, listen: false)
|
||||||
|
.restoreTodo();
|
||||||
|
|
||||||
generateTiles();
|
generateTiles();
|
||||||
|
|
||||||
@@ -410,7 +450,159 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10.0,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
color: Theme.of(context).colorScheme.background),
|
||||||
|
child: ListTile(
|
||||||
|
title: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.task_outlined),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10.0,
|
||||||
|
),
|
||||||
|
Text('new_task'.i18n),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||||
|
.hasScope(PremiumScopes.unlimitedSelfNotes)) {
|
||||||
|
PlusLockedFeaturePopup.show(
|
||||||
|
context: context, feature: PremiumFeature.selfNotes);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showTaskCreation(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showTaskCreation(context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
||||||
|
contentPadding: const EdgeInsets.only(top: 10.0),
|
||||||
|
title: Text("new_task".i18n),
|
||||||
|
content: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 10.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: _taskName,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
hintText: "task_name".i18n,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
FeatherIcons.x,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_taskName.text = "";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10.0,
|
||||||
|
),
|
||||||
|
TextField(
|
||||||
|
controller: _taskContent,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
hintText: "task_content".i18n,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
FeatherIcons.x,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_taskContent.text = "";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"cancel".i18n,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).maybePop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"next".i18n,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
todoItems.add(TodoItem.fromJson({
|
||||||
|
'id': const Uuid().v4(),
|
||||||
|
'title': _taskName.text.replaceAll(' ', '') != ""
|
||||||
|
? _taskName.text
|
||||||
|
: 'no_title'.i18n,
|
||||||
|
'content': _taskContent.text,
|
||||||
|
'done': false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
await databaseProvider.userStore
|
||||||
|
.storeSelfTodoItems(todoItems, userId: user.id!);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_taskName.text = "";
|
||||||
|
_taskContent.text = "";
|
||||||
|
});
|
||||||
|
|
||||||
|
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||||
|
Provider.of<SelfNoteProvider>(context, listen: false)
|
||||||
|
.restoreTodo();
|
||||||
|
|
||||||
|
generateTiles();
|
||||||
|
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ extension ScreensLocalization on String {
|
|||||||
"hint_t": "Note title...",
|
"hint_t": "Note title...",
|
||||||
"your_notes": "Your Notes",
|
"your_notes": "Your Notes",
|
||||||
"new_image": "New Image",
|
"new_image": "New Image",
|
||||||
|
"no_title": "No title",
|
||||||
|
"task_content": "Task content...",
|
||||||
|
"task_name": "Task title...",
|
||||||
|
"new_task": "New Task",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"notes": "Füzet",
|
"notes": "Füzet",
|
||||||
@@ -26,6 +30,10 @@ extension ScreensLocalization on String {
|
|||||||
"hint_t": "Jegyzet címe...",
|
"hint_t": "Jegyzet címe...",
|
||||||
"your_notes": "Jegyzeteid",
|
"your_notes": "Jegyzeteid",
|
||||||
"new_image": "Új kép",
|
"new_image": "Új kép",
|
||||||
|
"no_title": "Nincs cím",
|
||||||
|
"task_content": "Feladat tartalma...",
|
||||||
|
"task_name": "Feladat címe...",
|
||||||
|
"new_task": "Új feladat",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"notes": "Broschüre",
|
"notes": "Broschüre",
|
||||||
@@ -38,6 +46,10 @@ extension ScreensLocalization on String {
|
|||||||
"hint_t": "Titel notieren...",
|
"hint_t": "Titel notieren...",
|
||||||
"your_notes": "Deine Noten",
|
"your_notes": "Deine Noten",
|
||||||
"new_image": "Neues Bild",
|
"new_image": "Neues Bild",
|
||||||
|
"no_title": "Kein Titel",
|
||||||
|
"task_content": "Aufgabeninhalt...",
|
||||||
|
"task_name": "Aufgabentitel...",
|
||||||
|
"new_task": "Neue Aufgabe",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,8 @@ class AddNoteScreenState extends State<AddNoteScreen> {
|
|||||||
style: const TextStyle(fontSize: 16.0),
|
style: const TextStyle(fontSize: 16.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (MediaQuery.of(context).viewInsets.bottom != 0)
|
||||||
|
const SizedBox(height: 60),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:image_crop/image_crop.dart';
|
import 'package:image_crop/image_crop.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@@ -27,6 +28,8 @@ class ImageNoteEditor extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
||||||
|
final _title = TextEditingController();
|
||||||
|
|
||||||
final cropKey = GlobalKey<CropState>();
|
final cropKey = GlobalKey<CropState>();
|
||||||
File? _file;
|
File? _file;
|
||||||
File? _sample;
|
File? _sample;
|
||||||
@@ -62,7 +65,7 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
|||||||
child: Crop.file(
|
child: Crop.file(
|
||||||
_sample!,
|
_sample!,
|
||||||
key: cropKey,
|
key: cropKey,
|
||||||
aspectRatio: 1.0,
|
// aspectRatio: 1.0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -135,7 +138,8 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
|||||||
selfNotes.add(SelfNote.fromJson({
|
selfNotes.add(SelfNote.fromJson({
|
||||||
'id': const Uuid().v4(),
|
'id': const Uuid().v4(),
|
||||||
'content': base64Image,
|
'content': base64Image,
|
||||||
'note_type': 'image'
|
'note_type': 'image',
|
||||||
|
'title': _title.text,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await Provider.of<DatabaseProvider>(context, listen: false)
|
await Provider.of<DatabaseProvider>(context, listen: false)
|
||||||
@@ -143,6 +147,7 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
|||||||
.storeSelfNotes(selfNotes, userId: widget.u.id);
|
.storeSelfNotes(selfNotes, userId: widget.u.id);
|
||||||
|
|
||||||
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||||
|
Provider.of<SelfNoteProvider>(context, listen: false).restoreTodo();
|
||||||
|
|
||||||
debugPrint('$file');
|
debugPrint('$file');
|
||||||
}
|
}
|
||||||
@@ -170,6 +175,37 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
|||||||
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
||||||
child: _sample == null ? openImageWidget() : cropImageWidget(),
|
child: _sample == null ? openImageWidget() : cropImageWidget(),
|
||||||
),
|
),
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: _title,
|
||||||
|
onEditingComplete: () async {},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
hintText: 'title'.i18n,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
FeatherIcons.x,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_title.text = '';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
// if (widget.u.picture != "")
|
// if (widget.u.picture != "")
|
||||||
// TextButton(
|
// TextButton(
|
||||||
// child: Text(
|
// child: Text(
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:refilc/api/providers/self_note_provider.dart';
|
import 'package:refilc/api/providers/self_note_provider.dart';
|
||||||
import 'package:refilc/models/self_note.dart';
|
import 'package:refilc/models/self_note.dart';
|
||||||
@@ -8,6 +10,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:markdown/markdown.dart' as md;
|
import 'package:markdown/markdown.dart' as md;
|
||||||
|
import 'notes_screen.i18n.dart';
|
||||||
|
|
||||||
class NoteViewScreen extends StatefulWidget {
|
class NoteViewScreen extends StatefulWidget {
|
||||||
const NoteViewScreen({super.key, required this.note});
|
const NoteViewScreen({super.key, required this.note});
|
||||||
@@ -30,7 +33,9 @@ class NoteViewScreenState extends State<NoteViewScreen> {
|
|||||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
leading: BackButton(color: AppColors.of(context).text),
|
leading: BackButton(color: AppColors.of(context).text),
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.note.title ?? '${widget.note.content.split(' ')[0]}...',
|
widget.note.noteType == NoteType.text
|
||||||
|
? (widget.note.title ?? '${widget.note.content.split(' ')[0]}...')
|
||||||
|
: 'image_note'.i18n,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppColors.of(context).text,
|
color: AppColors.of(context).text,
|
||||||
fontSize: 26.0,
|
fontSize: 26.0,
|
||||||
@@ -38,52 +43,55 @@ class NoteViewScreenState extends State<NoteViewScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
ClipRRect(
|
if (widget.note.noteType == NoteType.text)
|
||||||
borderRadius: BorderRadius.circular(10.1),
|
ClipRRect(
|
||||||
child: GestureDetector(
|
borderRadius: BorderRadius.circular(10.1),
|
||||||
onTap: () {
|
child: GestureDetector(
|
||||||
// handle tap
|
onTap: () {
|
||||||
Navigator.of(context, rootNavigator: true).push(
|
// handle tap
|
||||||
CupertinoPageRoute(
|
Navigator.of(context, rootNavigator: true).push(
|
||||||
builder: (context) =>
|
CupertinoPageRoute(
|
||||||
AddNoteScreen(initialNote: widget.note)));
|
builder: (context) =>
|
||||||
},
|
AddNoteScreen(initialNote: widget.note)));
|
||||||
child: Container(
|
},
|
||||||
color: Theme.of(context).colorScheme.secondary.withOpacity(0.2),
|
child: Container(
|
||||||
child: Padding(
|
color:
|
||||||
padding: const EdgeInsets.all(8.0),
|
Theme.of(context).colorScheme.secondary.withOpacity(0.2),
|
||||||
child: Stack(
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.all(8.0),
|
||||||
IconTheme(
|
child: Stack(
|
||||||
data: IconThemeData(
|
children: [
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
IconTheme(
|
||||||
|
data: IconThemeData(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
FeatherIcons.edit,
|
||||||
|
size: 20.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: const Icon(
|
IconTheme(
|
||||||
FeatherIcons.edit,
|
data: IconThemeData(
|
||||||
size: 20.0,
|
color:
|
||||||
|
Theme.of(context).brightness == Brightness.light
|
||||||
|
? Colors.black.withOpacity(.5)
|
||||||
|
: Colors.white.withOpacity(.3),
|
||||||
|
),
|
||||||
|
child: const Icon(
|
||||||
|
FeatherIcons.edit,
|
||||||
|
size: 20.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
IconTheme(
|
),
|
||||||
data: IconThemeData(
|
|
||||||
color:
|
|
||||||
Theme.of(context).brightness == Brightness.light
|
|
||||||
? Colors.black.withOpacity(.5)
|
|
||||||
: Colors.white.withOpacity(.3),
|
|
||||||
),
|
|
||||||
child: const Icon(
|
|
||||||
FeatherIcons.edit,
|
|
||||||
size: 20.0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (widget.note.noteType == NoteType.text)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(10.1),
|
borderRadius: BorderRadius.circular(10.1),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
@@ -140,21 +148,30 @@ class NoteViewScreenState extends State<NoteViewScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: MarkdownBody(
|
child: widget.note.noteType == NoteType.text
|
||||||
data: widget.note.content,
|
? MarkdownBody(
|
||||||
extensionSet: md.ExtensionSet(
|
data: widget.note.content,
|
||||||
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
extensionSet: md.ExtensionSet(
|
||||||
<md.InlineSyntax>[
|
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
||||||
md.EmojiSyntax(),
|
<md.InlineSyntax>[
|
||||||
...md.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
md.EmojiSyntax(),
|
||||||
],
|
...md.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
||||||
),
|
],
|
||||||
styleSheet: MarkdownStyleSheet(
|
),
|
||||||
p: const TextStyle(
|
styleSheet: MarkdownStyleSheet(
|
||||||
fontSize: 15.0,
|
p: const TextStyle(
|
||||||
),
|
fontSize: 15.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
child: Image.memory(
|
||||||
|
const Base64Decoder().convert(widget.note.content),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
gaplessPlayback: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// Expanded(
|
// Expanded(
|
||||||
// child: Text(
|
// child: Text(
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ class NotesScreenState extends State<NotesScreen> {
|
|||||||
Provider.of<HomeworkProvider>(context, listen: false)
|
Provider.of<HomeworkProvider>(context, listen: false)
|
||||||
.fetch(from: DateTime.now().subtract(const Duration(days: 30)));
|
.fetch(from: DateTime.now().subtract(const Duration(days: 30)));
|
||||||
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||||
|
Provider.of<SelfNoteProvider>(context, listen: false).restoreTodo();
|
||||||
|
|
||||||
return Future(() => null);
|
return Future(() => null);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ extension SettingsLocalization on String {
|
|||||||
"click_here": "Click here",
|
"click_here": "Click here",
|
||||||
"select_image": "to select an image",
|
"select_image": "to select an image",
|
||||||
"new_image": "New Image",
|
"new_image": "New Image",
|
||||||
|
"image_note": "Image",
|
||||||
|
"title": "Image title...",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"notes": "Füzet",
|
"notes": "Füzet",
|
||||||
@@ -34,6 +36,8 @@ extension SettingsLocalization on String {
|
|||||||
"click_here": "Kattints ide",
|
"click_here": "Kattints ide",
|
||||||
"select_image": "kép kiválasztásához",
|
"select_image": "kép kiválasztásához",
|
||||||
"new_image": "Új kép",
|
"new_image": "Új kép",
|
||||||
|
"image_note": "Kép",
|
||||||
|
"title": "Kép címe...",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"notes": "Broschüre",
|
"notes": "Broschüre",
|
||||||
@@ -50,6 +54,8 @@ extension SettingsLocalization on String {
|
|||||||
"click_here": "Klicken Sie hier",
|
"click_here": "Klicken Sie hier",
|
||||||
"select_image": "um ein Bild auszuwählen",
|
"select_image": "um ein Bild auszuwählen",
|
||||||
"new_image": "Neues Bild",
|
"new_image": "Neues Bild",
|
||||||
|
"image_note": "Bild",
|
||||||
|
"title": "Bildtitel...",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:refilc/utils/format.dart';
|
import 'package:refilc/utils/format.dart';
|
||||||
@@ -50,11 +53,26 @@ class _DayTitleState extends State<DayTitle> {
|
|||||||
width: MediaQuery.of(context).size.width / 1.5,
|
width: MediaQuery.of(context).size.width / 1.5,
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.dayTitle(index).capital(),
|
widget.dayTitle(index).capital(),
|
||||||
style: TextStyle(
|
style: Provider.of<SettingsProvider>(context)
|
||||||
color:
|
.fontFamily !=
|
||||||
AppColors.of(context).text.withOpacity(opacity),
|
'' &&
|
||||||
fontSize: 32.0,
|
Provider.of<SettingsProvider>(context)
|
||||||
fontWeight: FontWeight.bold),
|
.titleOnlyFont
|
||||||
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(context).fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: AppColors.of(context)
|
||||||
|
.text
|
||||||
|
.withOpacity(opacity),
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
color: AppColors.of(context)
|
||||||
|
.text
|
||||||
|
.withOpacity(opacity),
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:i18n_extension/i18n_extension.dart';
|
import 'package:i18n_extension/i18n_extension.dart';
|
||||||
import 'package:refilc/api/providers/database_provider.dart';
|
import 'package:refilc/api/providers/database_provider.dart';
|
||||||
import 'package:refilc/api/providers/update_provider.dart';
|
import 'package:refilc/api/providers/update_provider.dart';
|
||||||
@@ -19,7 +20,7 @@ import 'package:refilc_mobile_ui/common/empty.dart';
|
|||||||
import 'package:refilc_mobile_ui/common/profile_image/profile_button.dart';
|
import 'package:refilc_mobile_ui/common/profile_image/profile_button.dart';
|
||||||
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
|
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
|
||||||
import 'package:refilc_mobile_ui/common/system_chrome.dart';
|
import 'package:refilc_mobile_ui/common/system_chrome.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_view.dart';
|
// import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_view.dart';
|
||||||
import 'package:refilc_kreta_api/controllers/timetable_controller.dart';
|
import 'package:refilc_kreta_api/controllers/timetable_controller.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_viewable.dart';
|
import 'package:refilc_mobile_ui/common/widgets/lesson/lesson_viewable.dart';
|
||||||
import 'package:refilc_mobile_ui/pages/timetable/day_title.dart';
|
import 'package:refilc_mobile_ui/pages/timetable/day_title.dart';
|
||||||
@@ -60,7 +61,11 @@ class TimetablePage extends StatefulWidget {
|
|||||||
NavigationScreen.of(context)?.setPage("timetable");
|
NavigationScreen.of(context)?.setPage("timetable");
|
||||||
|
|
||||||
// Show initial Lesson
|
// Show initial Lesson
|
||||||
if (lesson != null) LessonView.show(lesson, context: context);
|
// if (lesson != null) LessonView.show(lesson, context: context);
|
||||||
|
// changed to new popup
|
||||||
|
if (lesson != null) {
|
||||||
|
TimetableLessonPopup.show(context: context, lesson: lesson);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -316,6 +321,7 @@ class TimetablePageState extends State<TimetablePage>
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -374,11 +380,25 @@ class TimetablePageState extends State<TimetablePage>
|
|||||||
} else {
|
} else {
|
||||||
return Text(
|
return Text(
|
||||||
"timetable".i18n,
|
"timetable".i18n,
|
||||||
style: TextStyle(
|
style: Provider.of<SettingsProvider>(context)
|
||||||
fontSize: 32.0,
|
.fontFamily !=
|
||||||
fontWeight: FontWeight.bold,
|
'' &&
|
||||||
color: AppColors.of(context).text,
|
Provider.of<SettingsProvider>(context)
|
||||||
),
|
.titleOnlyFont
|
||||||
|
? GoogleFonts.getFont(
|
||||||
|
Provider.of<SettingsProvider>(context)
|
||||||
|
.fontFamily,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: TextStyle(
|
||||||
|
fontSize: 32.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}(),
|
}(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/plus/activation_view/activation_view.dart';
|
import 'package:refilc_plus/ui/mobile/plus/activation_view/activation_view.dart';
|
||||||
import 'package:refilc_mobile_ui/plus/plus_screen.i18n.dart';
|
import 'package:refilc_mobile_ui/plus/plus_screen.i18n.dart';
|
||||||
@@ -50,6 +51,20 @@ class PlusPlanCard extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Provider.of<SettingsProvider>(context, listen: false).xFilcId ==
|
||||||
|
"none") {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
|
||||||
|
content: Text(
|
||||||
|
"Be kell kapcsolnod a Névtelen Analitikát a beállítások főoldalán, mielőtt reFilc+ előfizetést vásárolnál!",
|
||||||
|
style:
|
||||||
|
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Provider.of<PlusProvider>(context, listen: false).hasPremium) {
|
if (Provider.of<PlusProvider>(context, listen: false).hasPremium) {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
launchUrl(
|
launchUrl(
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ class PlusScreenState extends State<PlusScreen> {
|
|||||||
['🎓', 'rfp_6'.i18n],
|
['🎓', 'rfp_6'.i18n],
|
||||||
['👕', 'rfp_14'.i18n],
|
['👕', 'rfp_14'.i18n],
|
||||||
['👑', 'rfp_15'.i18n],
|
['👑', 'rfp_15'.i18n],
|
||||||
|
['📩', 'rfp_17'.i18n],
|
||||||
['🔜', 'more_soon'.i18n],
|
['🔜', 'more_soon'.i18n],
|
||||||
],
|
],
|
||||||
docsAccepted: docsAccepted,
|
docsAccepted: docsAccepted,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ extension SettingsLocalization on String {
|
|||||||
"rfp_14": "Discount in reFilc Shop (soon)",
|
"rfp_14": "Discount in reFilc Shop (soon)",
|
||||||
"rfp_15": "Subscriber role in our Discord community",
|
"rfp_15": "Subscriber role in our Discord community",
|
||||||
"rfp_16": "Private leaks and informations about upcoming features",
|
"rfp_16": "Private leaks and informations about upcoming features",
|
||||||
|
"rfp_17": "Grade exporting",
|
||||||
// other
|
// other
|
||||||
"and": " and ",
|
"and": " and ",
|
||||||
"every": "Every ",
|
"every": "Every ",
|
||||||
@@ -96,6 +97,7 @@ extension SettingsLocalization on String {
|
|||||||
"rfp_14": "Kedvezmény a reFilc Shop-ban (hamarosan)",
|
"rfp_14": "Kedvezmény a reFilc Shop-ban (hamarosan)",
|
||||||
"rfp_15": "Előfizetői rang a Discord szerverünkön",
|
"rfp_15": "Előfizetői rang a Discord szerverünkön",
|
||||||
"rfp_16": "Privát betekintések és információk közelgő újításokról",
|
"rfp_16": "Privát betekintések és információk közelgő újításokról",
|
||||||
|
"rfp_17": "Jegy exportálás",
|
||||||
// other
|
// other
|
||||||
"and": " és ",
|
"and": " és ",
|
||||||
"every": "Minden ",
|
"every": "Minden ",
|
||||||
@@ -133,30 +135,32 @@ extension SettingsLocalization on String {
|
|||||||
"Der Preis wird in Euro angegeben im Bezug zum aktuellen Wechselkurs. 1 EUR ≈ 390 HUF",
|
"Der Preis wird in Euro angegeben im Bezug zum aktuellen Wechselkurs. 1 EUR ≈ 390 HUF",
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
// benefits
|
// benefits
|
||||||
"rfp_1": "Előzetes hozzáférés új verziókhoz",
|
"rfp_1": "Frühzeitiger Zugriff auf Updates",
|
||||||
"rfp_2": "2 fiók használata egyszerre",
|
"rfp_2": "Verwendung von zwei Konten gleichzeitig",
|
||||||
"rfp_3": "Egyedi üdvözlő üzenet",
|
"rfp_3": "Individuelle Begrüßungsnachricht",
|
||||||
"rfp_4": "Korlátlan saját jegyzet és feladat a füzet oldalon",
|
"rfp_4":
|
||||||
"rfp_5": "Egyedi jegy ritkaságok",
|
"Unbegrenzte eigene Notizen und Aufgaben auf der Notizbuchseite",
|
||||||
"rfp_6": "Összesített átlagszámoló",
|
"rfp_5": "Individuelle Notenraritäten",
|
||||||
"rfp_7": "Órarend jegyzetek",
|
"rfp_6": "Gesamtdurchschnittsberechner",
|
||||||
"rfp_8": "Egyedi betütípusok",
|
"rfp_7": "Stundenplan-Notizen",
|
||||||
"rfp_9": "Korlátlan fiók használata egyszerre",
|
"rfp_8": "Individuelle Schriftarten",
|
||||||
"rfp_10": "Alkalmazás ikonjának megváltoztatása (v5.1-től)",
|
"rfp_9": "Unbegrenzte Konten",
|
||||||
"rfp_11": "Live Activity szín",
|
"rfp_10": "Anpassung des App-Symbols (ab v5.1)",
|
||||||
"rfp_12": "Fejlettebb cél kitűzés",
|
"rfp_11": "Änderung der Live-Aktivitätsfarbe",
|
||||||
"rfp_13": "Naptár szinkronizálás",
|
"rfp_12": "Verbesserter Zielplaner",
|
||||||
"rfp_14": "Kedvezmény a reFilc Shop-ban (hamarosan)",
|
"rfp_13": "Importieren Sie Ihren Stundenplan in Ihre Kalender-App",
|
||||||
"rfp_15": "Előfizetői rang a Discord szerverünkön",
|
"rfp_14": "Rabatt im reFilc Shop (bald)",
|
||||||
"rfp_16": "Privát betekintések és információk közelgő újításokról",
|
"rfp_15": "Abonnentenrolle in unserer Discord-Community",
|
||||||
|
"rfp_16": "Private Leaks und Informationen über kommende Funktionen",
|
||||||
|
"rfp_17": "Notenexport",
|
||||||
// other
|
// other
|
||||||
"and": " és ",
|
"and": " und ",
|
||||||
"every": "Minden ",
|
"every": "Jeder ",
|
||||||
"benefit": " előny",
|
"benefit": " Vorteil",
|
||||||
"show_lifetime": "Für immer Pakete",
|
"show_lifetime": "Für immer Pakete",
|
||||||
"more_soon": "Mehr folgt bald...",
|
"more_soon": "Mehr folgt bald...",
|
||||||
"faq_dc":
|
"faq_dc":
|
||||||
"Az előnyök beváltásához írj nekünk Discord-on privát üzenetet!",
|
"Um Ihre Vorteile einzulösen, schreiben Sie uns eine private Nachricht auf Discord!",
|
||||||
"reactivate": "Bestehendes Abonnement reaktivieren",
|
"reactivate": "Bestehendes Abonnement reaktivieren",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -276,4 +276,4 @@ class ErrorDetail extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ extension SettingsLocalization on String {
|
|||||||
{
|
{
|
||||||
"en_en": {
|
"en_en": {
|
||||||
"ekretaYou": "e-KRÉTA, you",
|
"ekretaYou": "e-KRÉTA, you",
|
||||||
"description": "An error occurred!",
|
"description": "Unexpected error while using the application!",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"goback": "Go back",
|
"goback": "Go back",
|
||||||
"details": "Details",
|
"details": "Details",
|
||||||
@@ -15,11 +15,11 @@ extension SettingsLocalization on String {
|
|||||||
"stack": "Stack Trace",
|
"stack": "Stack Trace",
|
||||||
"done": "Done",
|
"done": "Done",
|
||||||
"smth_went_wrong":
|
"smth_went_wrong":
|
||||||
"Something went wrong, it is of course the fault of Educational Development Informatikai Zrt. (e-KRÉTA) in any case! /s",
|
"An unexpected error occurred while using the app.",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"ekretaYou": "e-KRÉTA, te",
|
"ekretaYou": "e-KRÉTA, te",
|
||||||
"description": "Fasz-emulátor hivatásos balfasz!",
|
"description": "Váratlan hiba az alkalmazás használata közben!",
|
||||||
"submit": "Hiba jelentése",
|
"submit": "Hiba jelentése",
|
||||||
"goback": "Vissza",
|
"goback": "Vissza",
|
||||||
"details": "Részletek",
|
"details": "Részletek",
|
||||||
@@ -29,11 +29,11 @@ extension SettingsLocalization on String {
|
|||||||
"stack": "Stacktrace",
|
"stack": "Stacktrace",
|
||||||
"done": "Kész",
|
"done": "Kész",
|
||||||
"smth_went_wrong":
|
"smth_went_wrong":
|
||||||
"Valami probléma történt, ez természetesen az Educational Development Informatikai Zrt. (e-KRÉTA) hibája minden esetben! /s",
|
"Nem várt hiba következett be az alkalmazás használata közben.",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"ekretaYou": "e-KRÉTA, du",
|
"ekretaYou": "e-KRÉTA, du",
|
||||||
"description": "Ein Fehler ist aufgetreten!",
|
"description": "Unerwarteter Fehler bei der Benutzung der Anwendung!",
|
||||||
"submit": "Abschicken",
|
"submit": "Abschicken",
|
||||||
"goback": "Zurück",
|
"goback": "Zurück",
|
||||||
"details": "Details",
|
"details": "Details",
|
||||||
@@ -43,7 +43,7 @@ extension SettingsLocalization on String {
|
|||||||
"stack": "Stack Trace",
|
"stack": "Stack Trace",
|
||||||
"done": "Fertig",
|
"done": "Fertig",
|
||||||
"smth_went_wrong":
|
"smth_went_wrong":
|
||||||
"Irgendetwas ist schief gelaufen, es ist natürlich auf jeden Fall die Schuld der Educational Development Informatikai Zrt. (e-KRÉTA)! /s",
|
"Bei der Benutzung der Anwendung ist ein unerwarteter Fehler aufgetreten.",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
183
refilc_mobile_ui/lib/screens/login/kreten_login.dart
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:refilc_kreta_api/client/api.dart';
|
||||||
|
import 'package:refilc_kreta_api/client/client.dart';
|
||||||
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
|
class KretenLoginScreen extends StatefulWidget {
|
||||||
|
const KretenLoginScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<KretenLoginScreen> createState() => _KretenLoginScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _KretenLoginScreenState extends State<KretenLoginScreen> {
|
||||||
|
late final WebViewController controller;
|
||||||
|
var loadingPercentage = 0;
|
||||||
|
var currentUrl = '';
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
controller = WebViewController()
|
||||||
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||||
|
..setNavigationDelegate(NavigationDelegate(
|
||||||
|
onPageStarted: (url) async {
|
||||||
|
setState(() {
|
||||||
|
loadingPercentage = 0;
|
||||||
|
currentUrl = url;
|
||||||
|
});
|
||||||
|
|
||||||
|
List<String> requiredThings = url
|
||||||
|
.replaceAll(
|
||||||
|
'https://mobil.e-kreta.hu/ellenorzo-student/prod/oauthredirect?code=',
|
||||||
|
'')
|
||||||
|
.replaceAll(
|
||||||
|
'&scope=openid email offline_access kreta-ellenorzo-webapi.public kreta-eugyintezes-webapi.public kreta-fileservice-webapi.public kreta-mobile-global-webapi.public kreta-dkt-webapi.public kreta-ier-webapi.public&state=refilc_student_mobile&session_state=',
|
||||||
|
':')
|
||||||
|
.split(':');
|
||||||
|
|
||||||
|
String code = requiredThings[0];
|
||||||
|
// String sessionState = requiredThings[1];
|
||||||
|
|
||||||
|
debugPrint('url: $url');
|
||||||
|
|
||||||
|
// actual login (token grant) logic
|
||||||
|
Map<String, String> headers = {
|
||||||
|
"content-type": "application/x-www-form-urlencoded",
|
||||||
|
"accept": "*/*",
|
||||||
|
"user-agent":
|
||||||
|
"eKretaStudent/264745 CFNetwork/1494.0.7 Darwin/23.4.0",
|
||||||
|
"code_verifier": "THDUSddKOOndwCkqBtVHvRjh2LK0V2kMyLP2QirqVWQ",
|
||||||
|
};
|
||||||
|
|
||||||
|
Map? res = await Provider.of<KretaClient>(context, listen: false)
|
||||||
|
.postAPI(KretaAPI.login, headers: headers, body: {
|
||||||
|
"code": code,
|
||||||
|
"redirect_uri":
|
||||||
|
"https://mobil.e-kreta.hu/ellenorzo-student/prod/oauthredirect",
|
||||||
|
"client_id": "kreta-ellenorzo-student-mobile-ios",
|
||||||
|
"grant_type": "authorization_code",
|
||||||
|
});
|
||||||
|
if (res != null) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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"];
|
||||||
|
// Map? studentJson =
|
||||||
|
// await Provider.of<KretaClient>(context, listen: false)
|
||||||
|
// .getAPI(KretaAPI.student(instituteCode));
|
||||||
|
// Student student = Student.fromJson(studentJson!);
|
||||||
|
// var user = User(
|
||||||
|
// username: username,
|
||||||
|
// password: password,
|
||||||
|
// instituteCode: instituteCode,
|
||||||
|
// name: student.name,
|
||||||
|
// student: student,
|
||||||
|
// role: JwtUtils.getRoleFromJWT(res["access_token"])!,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onProgress: (progress) {
|
||||||
|
setState(() {
|
||||||
|
loadingPercentage = progress;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPageFinished: (url) {
|
||||||
|
setState(() {
|
||||||
|
loadingPercentage = 100;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
))
|
||||||
|
..loadRequest(
|
||||||
|
Uri.parse(
|
||||||
|
'https://idp.e-kreta.hu/connect/authorize?prompt=login&nonce=refilc&response_type=code&code_challenge_method=S256&scope=openid%20email%20offline_access%20kreta-ellenorzo-webapi.public%20kreta-eugyintezes-webapi.public%20kreta-fileservice-webapi.public%20kreta-mobile-global-webapi.public%20kreta-dkt-webapi.public%20kreta-ier-webapi.public&code_challenge=Oj_aVMRJHYsv00mrtGJY72NJa7HY54lVnU2Cb4CWbWw&redirect_uri=https://mobil.e-kreta.hu/ellenorzo-student/prod/oauthredirect&client_id=kreta-ellenorzo-student-mobile-ios&state=refilc_student_mobile'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<void> loadLoginUrl() async {
|
||||||
|
// String nonceStr = await Provider.of<KretaClient>(context, listen: false)
|
||||||
|
// .getAPI(KretaAPI.nonce, json: false);
|
||||||
|
|
||||||
|
// Nonce nonce = getNonce(nonceStr, );
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: const BackButton(),
|
||||||
|
title: const Text('e-KRÉTA Bejelentkezés'),
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
WebViewWidget(
|
||||||
|
controller: controller,
|
||||||
|
),
|
||||||
|
if (loadingPercentage < 100)
|
||||||
|
LinearProgressIndicator(
|
||||||
|
value: loadingPercentage / 100.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,6 +56,9 @@ class AccountView extends StatelessWidget {
|
|||||||
Detail(
|
Detail(
|
||||||
title: "parents".plural(user.student.parents.length),
|
title: "parents".plural(user.student.parents.length),
|
||||||
description: user.student.parents.join(", ")),
|
description: user.student.parents.join(", ")),
|
||||||
|
const SizedBox(
|
||||||
|
height: 10.0,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,21 +8,22 @@ extension Localization on String {
|
|||||||
"school": "School",
|
"school": "School",
|
||||||
"class": "Class",
|
"class": "Class",
|
||||||
"address": "Home address",
|
"address": "Home address",
|
||||||
"parents": "Parents".one("Parent"),
|
"parents": "Parent(s)",
|
||||||
|
"parents_phone": "Parents' phone number: ",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"birthdate": "Születési dátum",
|
"birthdate": "Születési dátum",
|
||||||
"school": "Iskola",
|
"school": "Iskola",
|
||||||
"class": "Osztály",
|
"class": "Osztály",
|
||||||
"address": "Lakcím",
|
"address": "Lakcím",
|
||||||
"parents": "Szülők".one("Szülő"),
|
"parents": "Szülő(k)",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"birthdate": "Geburtsdatum",
|
"birthdate": "Geburtsdatum",
|
||||||
"school": "Schule",
|
"school": "Schule",
|
||||||
"class": "Klasse",
|
"class": "Klasse",
|
||||||
"address": "Wohnanschrift",
|
"address": "Wohnanschrift",
|
||||||
"parents": "Eltern",
|
"parents": "Elter(n)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ import 'package:flutter_material_color_picker/flutter_material_color_picker.dart
|
|||||||
import 'package:refilc/models/icon_pack.dart';
|
import 'package:refilc/models/icon_pack.dart';
|
||||||
import 'package:refilc/utils/format.dart';
|
import 'package:refilc/utils/format.dart';
|
||||||
import 'package:refilc_mobile_ui/screens/settings/theme_screen.dart';
|
import 'package:refilc_mobile_ui/screens/settings/theme_screen.dart';
|
||||||
|
import 'package:refilc_plus/models/premium_scopes.dart';
|
||||||
|
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
|
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||||
// import 'package:refilc_plus/models/premium_scopes.dart';
|
// import 'package:refilc_plus/models/premium_scopes.dart';
|
||||||
// import 'package:refilc_plus/providers/plus_provider.dart';
|
// import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
// import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
// import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||||
@@ -900,6 +903,15 @@ class _LiveActivityColorSettingState extends State<LiveActivityColorSetting> {
|
|||||||
allowShades: false,
|
allowShades: false,
|
||||||
selectedColor: settings.liveActivityColor,
|
selectedColor: settings.liveActivityColor,
|
||||||
onMainColorChange: (k) {
|
onMainColorChange: (k) {
|
||||||
|
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||||
|
.hasScope(PremiumScopes.liveActivityColor)) {
|
||||||
|
PlusLockedFeaturePopup.show(
|
||||||
|
context: context,
|
||||||
|
feature: PremiumFeature.liveActivity,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
currentColor = k as Color;
|
currentColor = k as Color;
|
||||||
settings.update(
|
settings.update(
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import 'package:refilc_mobile_ui/common/bottom_sheet_menu/bottom_sheet_menu.dart
|
|||||||
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||||
import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
|
||||||
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
|
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/soon_alert/soon_alert.dart';
|
||||||
// import 'package:refilc_mobile_ui/common/soon_alert/soon_alert.dart';
|
// import 'package:refilc_mobile_ui/common/soon_alert/soon_alert.dart';
|
||||||
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
||||||
// import 'package:refilc_mobile_ui/common/system_chrome.dart';
|
// import 'package:refilc_mobile_ui/common/system_chrome.dart';
|
||||||
@@ -320,6 +321,7 @@ class SettingsScreenState extends State<SettingsScreen>
|
|||||||
badge: updateProvider.available,
|
badge: updateProvider.available,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
profilePictureString: user.picture,
|
profilePictureString: user.picture,
|
||||||
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||||
backgroundColor: Theme.of(context)
|
backgroundColor: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.tertiary, //!settings.presentationMode
|
.tertiary, //!settings.presentationMode
|
||||||
@@ -702,6 +704,46 @@ class SettingsScreenState extends State<SettingsScreen>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
|
if ((user.gradeStreak ?? 0) > 1)
|
||||||
|
SplittedPanel(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
bottom: 12.0, left: 24.0, right: 24.0),
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
SoonAlert.show(context: context);
|
||||||
|
},
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(
|
||||||
|
"grade_streak".i18n,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.95),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
"grade_streak_subtitle".i18n,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.75),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
leading: const Text(
|
||||||
|
"🔥",
|
||||||
|
style: TextStyle(fontSize: 22.0),
|
||||||
|
),
|
||||||
|
trailing: Text(
|
||||||
|
"${user.gradeStreak}",
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.95),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 18.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
// plus subscribe inline
|
// plus subscribe inline
|
||||||
const PlusSettingsInline(),
|
const PlusSettingsInline(),
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ extension SettingsLocalization on String {
|
|||||||
static final _t = Translations.byLocale("hu_hu") +
|
static final _t = Translations.byLocale("hu_hu") +
|
||||||
{
|
{
|
||||||
"en_en": {
|
"en_en": {
|
||||||
|
"heads_up": "Heads up!",
|
||||||
|
"export_warning": "Exported grades are currently not yet viewable in reFilc, you'll only be able to view them manually in JSON format. In the future, this functionality will be extended and you will be able to view the tickets in the app interface.",
|
||||||
"personal_details": "Personal Details",
|
"personal_details": "Personal Details",
|
||||||
"open_dkt": "Open DCS",
|
"open_dkt": "Open DCS",
|
||||||
"edit_nickname": "Edit Nickname",
|
"edit_nickname": "Edit Nickname",
|
||||||
@@ -116,8 +118,18 @@ extension SettingsLocalization on String {
|
|||||||
"exp_settings": "Export Settings",
|
"exp_settings": "Export Settings",
|
||||||
"manage_subs": "Manage Subscription",
|
"manage_subs": "Manage Subscription",
|
||||||
"copy_plus_id": "Copy reFilc+ ID",
|
"copy_plus_id": "Copy reFilc+ ID",
|
||||||
|
// grade streak
|
||||||
|
"grade_streak": "Grade 5 Streak",
|
||||||
|
"grade_streak_subtitle": "So many 5s in a row?!",
|
||||||
|
// other
|
||||||
|
"only_ch_title_font": "Font Only for Titles",
|
||||||
|
"new_popups": "New Popups",
|
||||||
|
"export_method": "Export Method",
|
||||||
|
"grade_exporting": "Grade Exporting",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
|
"heads_up": "Figyelem!",
|
||||||
|
"export_warning": "Az exportált jegyek jelenleg még nem megtekinthetők a reFilc-ben, csak te magad tudod átnézni őket JSON formátumban. A jövőben ez a funkció bővülni fog, és a jegyeket meg is tekintheted majd a reFilc felületén.",
|
||||||
"personal_details": "Személyes információk",
|
"personal_details": "Személyes információk",
|
||||||
"open_dkt": "DKT megnyitása",
|
"open_dkt": "DKT megnyitása",
|
||||||
"edit_nickname": "Becenév szerkesztése",
|
"edit_nickname": "Becenév szerkesztése",
|
||||||
@@ -230,8 +242,18 @@ extension SettingsLocalization on String {
|
|||||||
"exp_settings": "Beállítások exportálása",
|
"exp_settings": "Beállítások exportálása",
|
||||||
"manage_subs": "Előfizetés kezelése",
|
"manage_subs": "Előfizetés kezelése",
|
||||||
"copy_plus_id": "reFilc+ ID másolása",
|
"copy_plus_id": "reFilc+ ID másolása",
|
||||||
|
// grade streak
|
||||||
|
"grade_streak": "5-ös sorozat",
|
||||||
|
"grade_streak_subtitle": "Egymás után ennyi 5-ös?!",
|
||||||
|
// other
|
||||||
|
"only_ch_title_font": "Betűtípus csak címekre",
|
||||||
|
"new_popups": "Új felugró ablakok",
|
||||||
|
"export_method": "Exportálási mód",
|
||||||
|
"grade_exporting": "Jegy exportálás",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
|
"heads_up": "Achtung!",
|
||||||
|
"export_warning": "Exportierte Tickets sind derzeit noch nicht in reFilc einsehbar, Sie können sie nur selbst im JSON- Format überprüfen. In Zukunft wird diese Funktionalität erweitert und Sie werden die Tickets in der reFilc-Oberfläche anzeigen können",
|
||||||
"personal_details": "Persönliche Angaben",
|
"personal_details": "Persönliche Angaben",
|
||||||
"open_dkt": "Öffnen RDZ",
|
"open_dkt": "Öffnen RDZ",
|
||||||
"edit_nickname": "Spitznamen bearbeiten",
|
"edit_nickname": "Spitznamen bearbeiten",
|
||||||
@@ -344,6 +366,14 @@ extension SettingsLocalization on String {
|
|||||||
"exp_settings": "Einstellungen exportieren",
|
"exp_settings": "Einstellungen exportieren",
|
||||||
"manage_subs": "Abonnement verwalten",
|
"manage_subs": "Abonnement verwalten",
|
||||||
"copy_plus_id": "reFilc+ ID kopieren",
|
"copy_plus_id": "reFilc+ ID kopieren",
|
||||||
|
// grade streak
|
||||||
|
"grade_streak": "5er-Streak",
|
||||||
|
"grade_streak_subtitle": "So viele 5er in Folge?!",
|
||||||
|
// other
|
||||||
|
"only_ch_title_font": "Schriftart nur für Titel",
|
||||||
|
"new_popups": "Neue Popups",
|
||||||
|
"export_method": "Exportmethode",
|
||||||
|
"grade_exporting": "Noten exportieren",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/settings/submenu/calendar_sync.dart';
|
import 'package:refilc_plus/ui/mobile/settings/submenu/calendar_sync.dart';
|
||||||
|
import 'package:refilc_plus/ui/mobile/settings/submenu/grade_exporting.dart';
|
||||||
import 'package:refilc_plus/models/premium_scopes.dart';
|
import 'package:refilc_plus/models/premium_scopes.dart';
|
||||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||||
@@ -158,6 +159,16 @@ class ExtrasSettingsScreenState extends State<ExtrasSettingsScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
SplittedPanel(
|
||||||
|
padding: const EdgeInsets.only(top: 9.0),
|
||||||
|
cardPadding: const EdgeInsets.all(4.0),
|
||||||
|
isSeparated: true,
|
||||||
|
children: [
|
||||||
|
MenuGradeExporting(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
381
refilc_mobile_ui/lib/screens/settings/submenu/grade_colors.dart
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
import 'package:refilc/models/settings.dart';
|
||||||
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:refilc/ui/flutter_colorpicker/colorpicker.dart';
|
||||||
|
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
||||||
|
import 'package:refilc_kreta_api/models/grade.dart';
|
||||||
|
import 'package:refilc_mobile_ui/screens/settings/theme_screen.dart';
|
||||||
|
import 'submenu_screen.i18n.dart';
|
||||||
|
|
||||||
|
enum SelectedGrade { one, two, three, four, five }
|
||||||
|
|
||||||
|
class GradeColorsSettingsScreen extends StatefulWidget {
|
||||||
|
const GradeColorsSettingsScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
GradeColorsSettingsScreenState createState() =>
|
||||||
|
GradeColorsSettingsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class GradeColorsSettingsScreenState extends State<GradeColorsSettingsScreen> {
|
||||||
|
late SettingsProvider settingsProvider;
|
||||||
|
|
||||||
|
SelectedGrade currentEditGrade = SelectedGrade.one;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
SettingsProvider settingsProvider = Provider.of<SettingsProvider>(context);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
leading: BackButton(
|
||||||
|
color: AppColors.of(context).text,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
// made this cuz else it will be ugly
|
||||||
|
currentEditGrade = SelectedGrade.one;
|
||||||
|
});
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
"grade_colors".i18n,
|
||||||
|
style: TextStyle(color: AppColors.of(context).text),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
List<Color> colors = List.castFrom(settingsProvider.gradeColors);
|
||||||
|
var defaultColors =
|
||||||
|
SettingsProvider.defaultSettings().gradeColors;
|
||||||
|
colors[currentEditGrade.index] =
|
||||||
|
defaultColors[currentEditGrade.index];
|
||||||
|
settingsProvider.update(gradeColors: colors);
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.restore,
|
||||||
|
size: 26.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: double.infinity,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.14,
|
||||||
|
),
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
borderRadius: BorderRadius.circular(75.0),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.shadow
|
||||||
|
.withOpacity(.1),
|
||||||
|
blurRadius: 10.0,
|
||||||
|
offset: const Offset(0, 5),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.all(6.0),
|
||||||
|
child: GradeValueWidget(
|
||||||
|
GradeValue(currentEditGrade.index + 1, '', '', 100),
|
||||||
|
fill: true,
|
||||||
|
size: 75.0,
|
||||||
|
// color:
|
||||||
|
// settingsProvider.gradeColors[currentEditGrade.index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// before grades
|
||||||
|
if (currentEditGrade.index > 0)
|
||||||
|
Transform.translate(
|
||||||
|
offset: const Offset(-110, 16.5),
|
||||||
|
child: GradeValueWidget(
|
||||||
|
GradeValue(currentEditGrade.index, '', '', 100),
|
||||||
|
fill: true,
|
||||||
|
size: 60.0,
|
||||||
|
// color:
|
||||||
|
// settingsProvider.gradeColors[currentEditGrade.index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (currentEditGrade.index > 1)
|
||||||
|
Transform.translate(
|
||||||
|
offset: const Offset(-200, 23),
|
||||||
|
child: GradeValueWidget(
|
||||||
|
GradeValue(currentEditGrade.index - 1, '', '', 100),
|
||||||
|
fill: true,
|
||||||
|
size: 50.0,
|
||||||
|
// color:
|
||||||
|
// settingsProvider.gradeColors[currentEditGrade.index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// after grades
|
||||||
|
if (currentEditGrade.index < 4)
|
||||||
|
Transform.translate(
|
||||||
|
offset: const Offset(142, 16.5),
|
||||||
|
child: GradeValueWidget(
|
||||||
|
GradeValue(currentEditGrade.index + 2, '', '', 100),
|
||||||
|
fill: true,
|
||||||
|
size: 60.0,
|
||||||
|
// color:
|
||||||
|
// settingsProvider.gradeColors[currentEditGrade.index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (currentEditGrade.index < 3)
|
||||||
|
Transform.translate(
|
||||||
|
offset: const Offset(245, 23),
|
||||||
|
child: GradeValueWidget(
|
||||||
|
GradeValue(currentEditGrade.index + 3, '', '', 100),
|
||||||
|
fill: true,
|
||||||
|
size: 50.0,
|
||||||
|
// color:
|
||||||
|
// settingsProvider.gradeColors[currentEditGrade.index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.14,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
child: SafeArea(
|
||||||
|
child: FilcColorPicker(
|
||||||
|
colorMode: CustomColorMode.grade,
|
||||||
|
pickerColor:
|
||||||
|
settingsProvider.gradeColors[currentEditGrade.index],
|
||||||
|
onColorChanged: (c) {
|
||||||
|
setState(() {
|
||||||
|
// update grade color
|
||||||
|
settingsProvider.update(
|
||||||
|
gradeColors: settingsProvider.gradeColors
|
||||||
|
..[currentEditGrade.index] = c);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onColorChangeEnd: (c, {adaptive}) {
|
||||||
|
// update grade color
|
||||||
|
},
|
||||||
|
onThemeIdProvided: (t) {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 20.0, top: 16.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => setState(() {
|
||||||
|
currentEditGrade = SelectedGrade.one;
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
width: 45.0,
|
||||||
|
height: 45.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: currentEditGrade == SelectedGrade.one
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.2),
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
color: currentEditGrade == SelectedGrade.one
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'1',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: currentEditGrade == SelectedGrade.one
|
||||||
|
? Colors.white
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10.0),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => setState(() {
|
||||||
|
currentEditGrade = SelectedGrade.two;
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
width: 45.0,
|
||||||
|
height: 45.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: currentEditGrade == SelectedGrade.two
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.2),
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
color: currentEditGrade == SelectedGrade.two
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'2',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: currentEditGrade == SelectedGrade.two
|
||||||
|
? Colors.white
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10.0),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => setState(() {
|
||||||
|
currentEditGrade = SelectedGrade.three;
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
width: 45.0,
|
||||||
|
height: 45.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: currentEditGrade == SelectedGrade.three
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.2),
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
color: currentEditGrade == SelectedGrade.three
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'3',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: currentEditGrade == SelectedGrade.three
|
||||||
|
? Colors.white
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10.0),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => setState(() {
|
||||||
|
currentEditGrade = SelectedGrade.four;
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
width: 45.0,
|
||||||
|
height: 45.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: currentEditGrade == SelectedGrade.four
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.2),
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
color: currentEditGrade == SelectedGrade.four
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'4',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: currentEditGrade == SelectedGrade.four
|
||||||
|
? Colors.white
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10.0),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => setState(() {
|
||||||
|
currentEditGrade = SelectedGrade.five;
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
width: 45.0,
|
||||||
|
height: 45.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: currentEditGrade == SelectedGrade.five
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(.2),
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
color: currentEditGrade == SelectedGrade.five
|
||||||
|
? Theme.of(context).colorScheme.secondary
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'5',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: currentEditGrade == SelectedGrade.five
|
||||||
|
? Colors.white
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
||||||
|
import 'package:refilc_mobile_ui/screens/settings/submenu/share_theme_popup.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
class MenuPaintList extends StatelessWidget {
|
class MenuPaintList extends StatelessWidget {
|
||||||
@@ -251,18 +252,7 @@ class PaintListScreenState extends State<PaintListScreen>
|
|||||||
subject: 'share_subj_theme'.i18n,
|
subject: 'share_subj_theme'.i18n,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
SharedGradeColors gradeColors = await shareProvider
|
ShareThemeDialog.show(context);
|
||||||
.shareCurrentGradeColors(context);
|
|
||||||
SharedTheme theme =
|
|
||||||
await shareProvider.shareCurrentTheme(
|
|
||||||
context,
|
|
||||||
gradeColors: gradeColors,
|
|
||||||
);
|
|
||||||
|
|
||||||
Share.share(
|
|
||||||
theme.id,
|
|
||||||
subject: 'share_subj_theme'.i18n,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
longPressInstead: true,
|
longPressInstead: true,
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import 'package:refilc_plus/providers/plus_provider.dart';
|
|||||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
import 'grade_colors.dart';
|
||||||
|
|
||||||
class MenuPersonalizeSettings extends StatelessWidget {
|
class MenuPersonalizeSettings extends StatelessWidget {
|
||||||
const MenuPersonalizeSettings({
|
const MenuPersonalizeSettings({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -459,6 +461,49 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
// new popup toggle
|
||||||
|
SplittedPanel(
|
||||||
|
padding: const EdgeInsets.only(top: 9.0),
|
||||||
|
cardPadding: const EdgeInsets.all(4.0),
|
||||||
|
isSeparated: true,
|
||||||
|
children: [
|
||||||
|
PanelButton(
|
||||||
|
padding: const EdgeInsets.only(left: 14.0, right: 6.0),
|
||||||
|
onPressed: () async {
|
||||||
|
settingsProvider.update(
|
||||||
|
newPopups: !settingsProvider.newPopups);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: Text(
|
||||||
|
"new_popups".i18n,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(
|
||||||
|
settingsProvider.newPopups ? .95 : .25),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
leading: Icon(
|
||||||
|
FeatherIcons.alertOctagon,
|
||||||
|
size: 22.0,
|
||||||
|
color: AppColors.of(context).text.withOpacity(
|
||||||
|
settingsProvider.newPopups ? .95 : .25),
|
||||||
|
),
|
||||||
|
trailing: Switch(
|
||||||
|
onChanged: (v) async {
|
||||||
|
settingsProvider.update(newPopups: v);
|
||||||
|
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
value: settingsProvider.newPopups,
|
||||||
|
activeColor: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
top: Radius.circular(12.0),
|
||||||
|
bottom: Radius.circular(12.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
// change subject icons
|
// change subject icons
|
||||||
// SplittedPanel(
|
// SplittedPanel(
|
||||||
// padding: const EdgeInsets.only(top: 9.0),
|
// padding: const EdgeInsets.only(top: 9.0),
|
||||||
@@ -499,8 +544,14 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
|||||||
children: [
|
children: [
|
||||||
PanelButton(
|
PanelButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
SettingsHelper.gradeColors(context);
|
// SettingsHelper.gradeColors(context);
|
||||||
setState(() {});
|
// setState(() {});
|
||||||
|
Navigator.of(context, rootNavigator: true).push(
|
||||||
|
CupertinoPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
const GradeColorsSettingsScreen(),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
title: Text(
|
title: Text(
|
||||||
"grade_colors".i18n,
|
"grade_colors".i18n,
|
||||||
@@ -670,16 +721,6 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
|||||||
children: [
|
children: [
|
||||||
PanelButton(
|
PanelButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (!Provider.of<PlusProvider>(context,
|
|
||||||
listen: false)
|
|
||||||
.hasScope(PremiumScopes.liveActivityColor)) {
|
|
||||||
PlusLockedFeaturePopup.show(
|
|
||||||
context: context,
|
|
||||||
feature: PremiumFeature.liveActivity,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsHelper.liveActivityColor(context);
|
SettingsHelper.liveActivityColor(context);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
@@ -882,7 +923,7 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
|||||||
title: Text('fonts'.i18n),
|
title: Text('fonts'.i18n),
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
cardPadding: const EdgeInsets.all(4.0),
|
cardPadding: const EdgeInsets.all(4.0),
|
||||||
isSeparated: true,
|
isSeparated: false,
|
||||||
children: [
|
children: [
|
||||||
PanelButton(
|
PanelButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@@ -920,11 +961,72 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
|||||||
),
|
),
|
||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(12.0),
|
top: Radius.circular(12.0),
|
||||||
|
bottom: Radius.circular(6.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PanelButton(
|
||||||
|
padding: const EdgeInsets.only(left: 14.0, right: 6.0),
|
||||||
|
onPressed: () async {
|
||||||
|
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||||
|
.hasScope(PremiumScopes.customFont)) {
|
||||||
|
PlusLockedFeaturePopup.show(
|
||||||
|
context: context,
|
||||||
|
feature: PremiumFeature.fontChange);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
settingsProvider.update(
|
||||||
|
titleOnlyFont: !settingsProvider.titleOnlyFont);
|
||||||
|
Provider.of<ThemeModeObserver>(context, listen: false)
|
||||||
|
.changeTheme(settingsProvider.theme,
|
||||||
|
updateNavbarColor: false);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
title: Text(
|
||||||
|
"only_ch_title_font".i18n,
|
||||||
|
style: TextStyle(
|
||||||
|
color: AppColors.of(context).text.withOpacity(
|
||||||
|
settingsProvider.titleOnlyFont ? .95 : .25),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
leading: Icon(
|
||||||
|
Icons.text_increase_rounded,
|
||||||
|
size: 22.0,
|
||||||
|
color: AppColors.of(context).text.withOpacity(
|
||||||
|
settingsProvider.titleOnlyFont ? .95 : .25),
|
||||||
|
),
|
||||||
|
trailing: Switch(
|
||||||
|
onChanged: (v) async {
|
||||||
|
if (!Provider.of<PlusProvider>(context,
|
||||||
|
listen: false)
|
||||||
|
.hasScope(PremiumScopes.customFont)) {
|
||||||
|
PlusLockedFeaturePopup.show(
|
||||||
|
context: context,
|
||||||
|
feature: PremiumFeature.fontChange);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
settingsProvider.update(titleOnlyFont: v);
|
||||||
|
Provider.of<ThemeModeObserver>(context,
|
||||||
|
listen: false)
|
||||||
|
.changeTheme(settingsProvider.theme,
|
||||||
|
updateNavbarColor: false);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
value: settingsProvider.titleOnlyFont,
|
||||||
|
activeColor: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
top: Radius.circular(4.0),
|
||||||
bottom: Radius.circular(12.0),
|
bottom: Radius.circular(12.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
// bottom padding
|
||||||
|
const SizedBox(
|
||||||
|
height: 20.0,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
// import 'package:refilc/models/settings.dart';
|
||||||
|
import 'package:refilc/models/shared_theme.dart';
|
||||||
|
import 'package:refilc_kreta_api/providers/share_provider.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/action_button.dart';
|
||||||
|
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import 'submenu_screen.i18n.dart';
|
||||||
|
|
||||||
|
class ShareThemeDialog extends StatefulWidget {
|
||||||
|
const ShareThemeDialog({super.key});
|
||||||
|
|
||||||
|
static void show(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
shape:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
||||||
|
title: Text("attention".i18n),
|
||||||
|
content: Text("share_disclaimer".i18n),
|
||||||
|
actions: [
|
||||||
|
ActionButton(
|
||||||
|
label: "understand".i18n,
|
||||||
|
onTap: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => const ShareThemeDialog());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ShareThemeDialogState createState() => ShareThemeDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShareThemeDialogState extends State<ShareThemeDialog> {
|
||||||
|
final _title = TextEditingController();
|
||||||
|
bool isPublic = false;
|
||||||
|
|
||||||
|
late ShareProvider shareProvider;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
shareProvider = Provider.of<ShareProvider>(context, listen: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
shape: const RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(14.0))),
|
||||||
|
contentPadding: const EdgeInsets.only(top: 10.0),
|
||||||
|
title: Text("share_theme".i18n),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
||||||
|
child: TextField(
|
||||||
|
controller: _title,
|
||||||
|
onEditingComplete: () async {},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.grey, width: 1.5),
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
hintText: 'paint_title'.i18n,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
FeatherIcons.x,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_title.text = '';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SplittedPanel(
|
||||||
|
children: [
|
||||||
|
SwitchListTile(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(16.0),
|
||||||
|
),
|
||||||
|
value: isPublic,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
isPublic = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
title: Text("is_public".i18n),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 15.0, right: 10.0),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"cancel".i18n,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).maybePop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"share_it".i18n,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
// share the fucking theme
|
||||||
|
SharedGradeColors gradeColors =
|
||||||
|
await shareProvider.shareCurrentGradeColors(context);
|
||||||
|
SharedTheme theme = await shareProvider.shareCurrentTheme(
|
||||||
|
context,
|
||||||
|
gradeColors: gradeColors,
|
||||||
|
isPublic: isPublic,
|
||||||
|
displayName: _title.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
// save theme id in settings
|
||||||
|
// Provider.of<SettingsProvider>(context, listen: false)
|
||||||
|
// .update(currentThemeId: theme.id);
|
||||||
|
|
||||||
|
// close this popup shit
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
|
||||||
|
// show the share popup
|
||||||
|
Share.share(
|
||||||
|
theme.id,
|
||||||
|
subject: 'share_subj_theme'.i18n,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,17 @@ extension SettingsLocalization on String {
|
|||||||
"rare": "Rare",
|
"rare": "Rare",
|
||||||
"epic": "Epic",
|
"epic": "Epic",
|
||||||
"legendary": "Legendary",
|
"legendary": "Legendary",
|
||||||
|
// grade colors
|
||||||
|
"grade_colors": "Grade Colors",
|
||||||
|
// theme share popup
|
||||||
|
"share_theme": "Share Paint",
|
||||||
|
"paint_title": "Paint title...",
|
||||||
|
"share_it": "Share it!",
|
||||||
|
"is_public": "Public Paint",
|
||||||
|
"attention": "Attention!",
|
||||||
|
"share_disclaimer":
|
||||||
|
"By sharing the theme, you agree that the nickname you set and all settings of the theme will be shared publicly.",
|
||||||
|
"understand": "I understand",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"general": "Általános",
|
"general": "Általános",
|
||||||
@@ -32,6 +43,17 @@ extension SettingsLocalization on String {
|
|||||||
"rare": "Ritka",
|
"rare": "Ritka",
|
||||||
"epic": "Epikus",
|
"epic": "Epikus",
|
||||||
"legendary": "Legendás",
|
"legendary": "Legendás",
|
||||||
|
// grade colors
|
||||||
|
"grade_colors": "Jegyek színei",
|
||||||
|
// theme share popup
|
||||||
|
"share_theme": "Téma megosztása",
|
||||||
|
"paint_title": "Téma neve...",
|
||||||
|
"share_it": "Megosztás!",
|
||||||
|
"is_public": "Nyilvános téma",
|
||||||
|
"attention": "Figyelem!",
|
||||||
|
"share_disclaimer":
|
||||||
|
"A téma megosztásával elfogadod, hogy az általad beállított becenév és a téma minden beállítása nyilvánosan megosztásra kerüljön.",
|
||||||
|
"understand": "Értem",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"general": "Allgemeine",
|
"general": "Allgemeine",
|
||||||
@@ -47,6 +69,17 @@ extension SettingsLocalization on String {
|
|||||||
"rare": "Selten",
|
"rare": "Selten",
|
||||||
"epic": "Episch",
|
"epic": "Episch",
|
||||||
"legendary": "Legendär",
|
"legendary": "Legendär",
|
||||||
|
// grade colors
|
||||||
|
"grade_colors": "Notenfarben",
|
||||||
|
// theme share popup
|
||||||
|
"share_theme": "Thema teilen",
|
||||||
|
"paint_title": "Thema Titel...",
|
||||||
|
"share_it": "Teilen!",
|
||||||
|
"is_public": "Öffentliches Thema",
|
||||||
|
"attention": "Achtung!",
|
||||||
|
"share_disclaimer":
|
||||||
|
"Durch das Teilen des Themes erklären Sie sich damit einverstanden, dass der von Ihnen festgelegte Spitzname und alle Einstellungen des Themes öffentlich geteilt werden.",
|
||||||
|
"understand": "Ich verstehe",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
|
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
|
||||||
|
|
||||||
import 'package:refilc/models/settings.dart';
|
import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/models/shared_theme.dart';
|
// import 'package:refilc/models/shared_theme.dart';
|
||||||
import 'package:refilc/theme/colors/accent.dart';
|
import 'package:refilc/theme/colors/accent.dart';
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:refilc/theme/observer.dart';
|
import 'package:refilc/theme/observer.dart';
|
||||||
@@ -10,7 +10,7 @@ import 'package:refilc/ui/widgets/message/message_tile.dart';
|
|||||||
import 'package:refilc_kreta_api/models/grade.dart';
|
import 'package:refilc_kreta_api/models/grade.dart';
|
||||||
import 'package:refilc_kreta_api/models/homework.dart';
|
import 'package:refilc_kreta_api/models/homework.dart';
|
||||||
import 'package:refilc_kreta_api/models/message.dart';
|
import 'package:refilc_kreta_api/models/message.dart';
|
||||||
import 'package:refilc_mobile_ui/common/action_button.dart';
|
// import 'package:refilc_mobile_ui/common/action_button.dart';
|
||||||
import 'package:refilc_mobile_ui/common/filter_bar.dart';
|
import 'package:refilc_mobile_ui/common/filter_bar.dart';
|
||||||
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
||||||
import 'package:refilc_mobile_ui/common/widgets/grade/new_grades.dart';
|
import 'package:refilc_mobile_ui/common/widgets/grade/new_grades.dart';
|
||||||
@@ -24,6 +24,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:refilc_mobile_ui/screens/settings/submenu/share_theme_popup.dart';
|
||||||
import 'theme_screen.i18n.dart';
|
import 'theme_screen.i18n.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ enum CustomColorMode {
|
|||||||
text,
|
text,
|
||||||
icon,
|
icon,
|
||||||
enterId,
|
enterId,
|
||||||
|
grade,
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PremiumCustomAccentColorSettingState
|
class _PremiumCustomAccentColorSettingState
|
||||||
@@ -158,6 +160,9 @@ class _PremiumCustomAccentColorSettingState
|
|||||||
case CustomColorMode.enterId:
|
case CustomColorMode.enterId:
|
||||||
// do nothing here lol
|
// do nothing here lol
|
||||||
break;
|
break;
|
||||||
|
case CustomColorMode.grade:
|
||||||
|
// do nothing here as well
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +223,9 @@ class _PremiumCustomAccentColorSettingState
|
|||||||
settings.update(customAccentColor: accent, store: store);
|
settings.update(customAccentColor: accent, store: store);
|
||||||
settings.update(customIconColor: icon, store: store);
|
settings.update(customIconColor: icon, store: store);
|
||||||
break;
|
break;
|
||||||
|
case CustomColorMode.grade:
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,40 +305,48 @@ class _PremiumCustomAccentColorSettingState
|
|||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
// );
|
// );
|
||||||
showDialog(
|
// showDialog(
|
||||||
context: context,
|
// context: context,
|
||||||
builder: (context) => WillPopScope(
|
// builder: (context) => WillPopScope(
|
||||||
onWillPop: () async => false,
|
// onWillPop: () async => false,
|
||||||
child: AlertDialog(
|
// child: AlertDialog(
|
||||||
shape: RoundedRectangleBorder(
|
// shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0)),
|
// borderRadius: BorderRadius.circular(12.0)),
|
||||||
title: Text("attention".i18n),
|
// title: Text("attention".i18n),
|
||||||
content: Text("share_disclaimer".i18n),
|
// content: Text("share_disclaimer".i18n),
|
||||||
actions: [
|
// actions: [
|
||||||
ActionButton(
|
// ActionButton(
|
||||||
label: "understand".i18n,
|
// label: "understand".i18n,
|
||||||
onTap: () async {
|
// onTap: () async {
|
||||||
Navigator.of(context).pop();
|
// Navigator.of(context).pop();
|
||||||
|
|
||||||
SharedGradeColors gradeColors =
|
// SharedGradeColors gradeColors =
|
||||||
await shareProvider
|
// await shareProvider
|
||||||
.shareCurrentGradeColors(context);
|
// .shareCurrentGradeColors(context);
|
||||||
SharedTheme theme =
|
// SharedTheme theme =
|
||||||
await shareProvider.shareCurrentTheme(
|
// await shareProvider.shareCurrentTheme(
|
||||||
context,
|
// context,
|
||||||
gradeColors: gradeColors,
|
// gradeColors: gradeColors,
|
||||||
);
|
// );
|
||||||
|
|
||||||
Share.share(
|
// Share.share(
|
||||||
theme.id,
|
// theme.id,
|
||||||
subject: 'share_subj_theme'.i18n,
|
// subject: 'share_subj_theme'.i18n,
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
|
if (settings.currentThemeId != '') {
|
||||||
|
Share.share(
|
||||||
|
settings.currentThemeId,
|
||||||
|
subject: 'share_subj_theme'.i18n,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ShareThemeDialog.show(context);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
FeatherIcons.share2,
|
FeatherIcons.share2,
|
||||||
|
|||||||
@@ -24,26 +24,17 @@ extension SettingsLocalization on String {
|
|||||||
"dontfelt": "You didn't like this...",
|
"dontfelt": "You didn't like this...",
|
||||||
"youlate": "You're late!",
|
"youlate": "You're late!",
|
||||||
// allsum page
|
// allsum page
|
||||||
"test": "tests"
|
"test": "test(s)",
|
||||||
.one("test"),
|
"closingtest": "module test(s)",
|
||||||
"closingtest": "module tests"
|
"grade": "grade(s)",
|
||||||
.one("module test"),
|
"hw": "homework(s)",
|
||||||
"grade": "grades"
|
"subject": "subject(s)",
|
||||||
.one("grade"),
|
"lesson": "lesson(s)",
|
||||||
"hw": "homeworks"
|
"absence_sum": "absence(s)",
|
||||||
.one("homework"),
|
|
||||||
"subject": "subjects"
|
|
||||||
.one("subject"),
|
|
||||||
"lesson": "lessons"
|
|
||||||
.one("lesson"),
|
|
||||||
"absence_sum": "absences"
|
|
||||||
.one("absence"),
|
|
||||||
"excused": "excused",
|
"excused": "excused",
|
||||||
"unexcused": "unexcused",
|
"unexcused": "unexcused",
|
||||||
"delay_sum": "delays"
|
"delay_sum": "delay(s)",
|
||||||
.one("delay"),
|
"min": "minute(s)",
|
||||||
"min": "minutes"
|
|
||||||
.one("minute"),
|
|
||||||
// personality page
|
// personality page
|
||||||
"click_reveal": "Click to reveal...",
|
"click_reveal": "Click to reveal...",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ dependencies:
|
|||||||
markdown: ^7.2.2
|
markdown: ^7.2.2
|
||||||
carousel_slider: ^4.2.1
|
carousel_slider: ^4.2.1
|
||||||
flutter_portal: ^1.1.4
|
flutter_portal: ^1.1.4
|
||||||
|
webview_flutter: ^4.8.0
|
||||||
|
file_picker: ^6.2.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^3.0.1
|
flutter_lints: ^3.0.1
|
||||||
|
|||||||