forked from firka/student-legacy
Merge branch 'master' of github.com:refilc/naplo
This commit is contained in:
commit
0586da3742
56
Jenkinsfile
vendored
Normal file
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:text="1."
|
||||
android:textColor="@color/filc"
|
||||
android:textColorLink="#ff3D7BF4"
|
||||
android:textColorLink="#ff052460"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="HardcodedText" />
|
||||
@ -110,4 +110,4 @@
|
||||
android:textColor="@color/white"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -27,7 +27,7 @@
|
||||
<color name="yellow_light">#ffFFCC00</color>
|
||||
<color name="light_yellow_light">#40FFD60A</color>
|
||||
<color name="green_light">#ff34C759</color>
|
||||
<color name="filc_light">#ff3D7BF4</color>
|
||||
<color name="filc_light">#ff052460</color>
|
||||
<color name="teal_light">#ff5AC8FA</color>
|
||||
<color name="blue_light">#ff007AFF</color>
|
||||
<color name="indigo_light">#ff5856D6</color>
|
||||
@ -49,8 +49,8 @@
|
||||
<color name="yellow">#ffFFD60A</color>
|
||||
<color name="light_yellow">#40FFD60A</color>
|
||||
<color name="green">#ff32D74B</color>
|
||||
<color name="filc">#ff3D7BF4</color>
|
||||
<color name="filc_gradient">#ff3D93F5</color>
|
||||
<color name="filc">#ff052460</color>
|
||||
<color name="filc_gradient">#ff06348f</color>
|
||||
<color name="teal">#ff64D2FF</color>
|
||||
<color name="blue">#ff0A84FF</color>
|
||||
<color name="indigo">#ff5E5CE6</color>
|
||||
@ -66,4 +66,4 @@
|
||||
<color name="pink_shade300">#FFF06292</color>
|
||||
<color name="purple_shade300">#FFBA68C8</color>
|
||||
<color name="teal_shade300">#FF22AC9B</color>
|
||||
</resources>
|
||||
</resources>
|
||||
|
43
refilc/assets/svg/cover_arts/grid.svg
Normal file
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
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
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
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 |
@ -52,14 +52,31 @@ struct LockScreenLiveActivityView: View {
|
||||
VStack(alignment: .center) {
|
||||
// Jelenlegi óra
|
||||
VStack {
|
||||
Text(context.state.index + " " + context.state.title)
|
||||
.font(.body)
|
||||
.bold()
|
||||
.multilineTextAlignment(.center)
|
||||
if(context.state.title.contains("Az első órádig")) {
|
||||
Text(context.state.title)
|
||||
.font(.system(size: 15))
|
||||
.bold()
|
||||
.multilineTextAlignment(.center)
|
||||
} else if(context.state.title == "Szünet") {
|
||||
Text(context.state.title)
|
||||
.font(.body)
|
||||
.bold()
|
||||
.padding(.trailing, 90)
|
||||
|
||||
Text("Terem: \(context.state.subtitle)")
|
||||
.italic()
|
||||
.font(.caption)
|
||||
} else {
|
||||
MultilineTextView(text: "\(context.state.index) \(context.state.title)", limit: 25)
|
||||
.font(.body)
|
||||
.bold()
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
|
||||
//Terem
|
||||
if (!context.state.subtitle.isEmpty) {
|
||||
Text(context.state.subtitle)
|
||||
.italic()
|
||||
.bold()
|
||||
.font(.system(size: 13))
|
||||
}
|
||||
}
|
||||
|
||||
// Leírás
|
||||
@ -69,6 +86,7 @@ struct LockScreenLiveActivityView: View {
|
||||
}
|
||||
|
||||
// Következő óra
|
||||
if(context.state.nextSubject != "" && context.state.nextRoom != "") {
|
||||
HStack {
|
||||
Image(systemName: "arrow.right")
|
||||
.resizable()
|
||||
@ -80,18 +98,24 @@ struct LockScreenLiveActivityView: View {
|
||||
.font(.caption2)
|
||||
}
|
||||
.multilineTextAlignment(.center)
|
||||
} else {
|
||||
Spacer(minLength: 5)
|
||||
Text("Ez az utolsó óra! Kitartást!")
|
||||
.font(.system(size: 15))
|
||||
}
|
||||
|
||||
}
|
||||
.padding(15)
|
||||
|
||||
Spacer()
|
||||
|
||||
|
||||
// Visszaszámláló
|
||||
Text(timerInterval: context.state.date, countsDown: true)
|
||||
.multilineTextAlignment(.center)
|
||||
.frame(width: 85)
|
||||
.font(.title2)
|
||||
.monospacedDigit()
|
||||
.padding(.trailing, CGFloat(24))
|
||||
.padding(.trailing)
|
||||
}
|
||||
.activityBackgroundTint(
|
||||
context.state.color != "#676767"
|
||||
@ -109,7 +133,7 @@ struct LiveCardWidget: Widget {
|
||||
LockScreenLiveActivityView(context: context)
|
||||
/// Dynamic Island
|
||||
} dynamicIsland: { context in
|
||||
|
||||
|
||||
/// Expanded
|
||||
return DynamicIsland {
|
||||
DynamicIslandExpandedRegion(.leading) {
|
||||
@ -133,39 +157,95 @@ struct LiveCardWidget: Widget {
|
||||
).progressViewStyle(.circular)
|
||||
}
|
||||
}
|
||||
DynamicIslandExpandedRegion(.center) {
|
||||
VStack(alignment: .center) {
|
||||
Text(context.state.index + context.state.title)
|
||||
.lineLimit(1)
|
||||
.font(.body)
|
||||
.bold()
|
||||
|
||||
Text(context.state.subtitle)
|
||||
.lineLimit(1)
|
||||
.font(.subheadline)
|
||||
Spacer()
|
||||
|
||||
Text(context.state.description)
|
||||
.lineLimit(2)
|
||||
.font(.caption)
|
||||
}.padding(EdgeInsets(top: 0.0, leading: 5.0, bottom: 0.0, trailing: 0.0))
|
||||
}
|
||||
DynamicIslandExpandedRegion(.center) {
|
||||
VStack(alignment: .center) {
|
||||
// Első óra előtti expanded DynamicIsland
|
||||
if(context.state.title.contains("Az első órádig")) {
|
||||
Text("Az első órád:")
|
||||
.font(.body)
|
||||
.bold()
|
||||
.padding(.trailing, -15)
|
||||
MultilineTextView(text: "\(context.state.nextSubject)", limit: 25)
|
||||
.font(.body)
|
||||
.padding(.trailing, -25)
|
||||
|
||||
Text("Ebben a teremben:")
|
||||
.font(.body)
|
||||
.bold()
|
||||
.padding(.leading, 15)
|
||||
Text(context.state.nextRoom)
|
||||
.font(.body)
|
||||
.padding(.leading, 15)
|
||||
} else if(context.state.title == "Szünet") {
|
||||
// Amikor szünet van, expanded DynamicIsland
|
||||
Text(context.state.title)
|
||||
.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
|
||||
} compactLeading: {
|
||||
Label {
|
||||
Text(context.state.title)
|
||||
} icon: {
|
||||
Image(systemName: context.state.icon)
|
||||
}
|
||||
.font(.caption2)
|
||||
Image(systemName: context.state.icon)
|
||||
}
|
||||
compactTrailing: {
|
||||
Text(timerInterval: context.state.date, countsDown: true)
|
||||
.multilineTextAlignment(.center)
|
||||
.frame(width: 40)
|
||||
.font(.caption2)
|
||||
|
||||
|
||||
/// Collapsed
|
||||
} minimal: {
|
||||
VStack(alignment: .center, content: {
|
||||
@ -191,7 +271,59 @@ struct LiveCardWidget: Widget {
|
||||
context.state.color != "#676767"
|
||||
? Color(hex: context.state.color)
|
||||
: 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) {
|
||||
return (jsonDecode(res.body) as Map);
|
||||
} else if (res.statusCode == 404) {
|
||||
return {"public_id": ""};
|
||||
} else {
|
||||
throw "HTTP ${res.statusCode}: ${res.body}";
|
||||
}
|
||||
|
@ -88,24 +88,24 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
case LiveCardState.morning:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": nextLesson != null
|
||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||
: "book",
|
||||
"title": "Első órádig:",
|
||||
"title": "Jó reggelt! Az első órádig:",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"startDate": storeFirstRunDate != null
|
||||
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
||||
(_delay.inMilliseconds))
|
||||
.toString()
|
||||
(_delay.inMilliseconds))
|
||||
.toString()
|
||||
: "",
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
@ -113,24 +113,24 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
case LiveCardState.afternoon:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": nextLesson != null
|
||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||
: "book",
|
||||
"title": "Első órádig:",
|
||||
"title": "Jó napot! Az első órádig:",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"startDate": storeFirstRunDate != null
|
||||
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
||||
(_delay.inMilliseconds))
|
||||
.toString()
|
||||
(_delay.inMilliseconds))
|
||||
.toString()
|
||||
: "",
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
@ -138,24 +138,24 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
case LiveCardState.night:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": nextLesson != null
|
||||
? SubjectIcon.resolveName(subject: nextLesson?.subject)
|
||||
: "book",
|
||||
"title": "Első órádig:",
|
||||
"title": "Jó estét! Az első órádig:",
|
||||
"subtitle": "",
|
||||
"description": "",
|
||||
"startDate": storeFirstRunDate != null
|
||||
? ((storeFirstRunDate?.millisecondsSinceEpoch ?? 0) -
|
||||
(_delay.inMilliseconds))
|
||||
.toString()
|
||||
(_delay.inMilliseconds))
|
||||
.toString()
|
||||
: "",
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
@ -163,28 +163,28 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
case LiveCardState.duringLesson:
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": currentLesson != null
|
||||
? SubjectIcon.resolveName(subject: currentLesson?.subject)
|
||||
: "book",
|
||||
"index":
|
||||
currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
||||
currentLesson != null ? '${currentLesson!.lessonIndex}. ' : "",
|
||||
"title": currentLesson != null
|
||||
? currentLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: currentLesson?.subject)
|
||||
.capital()
|
||||
ShortSubject.resolve(subject: currentLesson?.subject)
|
||||
.capital()
|
||||
: "",
|
||||
"subtitle": currentLesson?.room.replaceAll("_", " ") ?? "",
|
||||
"subtitle": "Terem: ${currentLesson?.room.replaceAll("_", " ") ?? ""}",
|
||||
"description": currentLesson?.description ?? "",
|
||||
"startDate": ((currentLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"endDate": ((currentLesson?.end.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
ShortSubject.resolve(subject: nextLesson?.subject).capital()
|
||||
: "",
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
};
|
||||
@ -200,23 +200,23 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
|
||||
return {
|
||||
"color":
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
'#${_settings.liveActivityColor.toString().substring(10, 16)}',
|
||||
"icon": iconFloorMap[diff] ?? "cup.and.saucer",
|
||||
"title": "Szünet",
|
||||
"description": "go $diff".i18n.fill([
|
||||
diff != "to room" ? (nextLesson!.getFloor() ?? 0) : nextLesson!.room
|
||||
]),
|
||||
"startDate": ((prevLesson?.end.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"endDate": ((nextLesson?.start.millisecondsSinceEpoch ?? 0) -
|
||||
_delay.inMilliseconds)
|
||||
_delay.inMilliseconds)
|
||||
.toString(),
|
||||
"nextSubject": (nextLesson != null
|
||||
? nextLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: nextLesson?.subject)
|
||||
.capital()
|
||||
: "")
|
||||
? nextLesson?.subject.renamedTo ??
|
||||
ShortSubject.resolve(subject: nextLesson?.subject)
|
||||
.capital()
|
||||
: "")
|
||||
.capital(),
|
||||
"nextRoom": nextLesson?.room.replaceAll("_", " ") ?? "",
|
||||
"index": "",
|
||||
@ -243,8 +243,8 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
DateTime now = _now().add(_delay);
|
||||
|
||||
if ((currentState == LiveCardState.morning ||
|
||||
currentState == LiveCardState.afternoon ||
|
||||
currentState == LiveCardState.night) &&
|
||||
currentState == LiveCardState.afternoon ||
|
||||
currentState == LiveCardState.night) &&
|
||||
storeFirstRunDate == null) {
|
||||
storeFirstRunDate = now;
|
||||
}
|
||||
@ -253,9 +253,9 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
// Filter label lessons #128
|
||||
today = today
|
||||
.where((lesson) =>
|
||||
lesson.status?.name != "Elmaradt" &&
|
||||
lesson.subject.id != '' &&
|
||||
!lesson.isEmpty)
|
||||
lesson.status?.name != "Elmaradt" &&
|
||||
lesson.subject.id != '' &&
|
||||
!lesson.isEmpty)
|
||||
.toList();
|
||||
|
||||
if (today.isNotEmpty) {
|
||||
@ -263,7 +263,7 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
today.sort((a, b) => a.start.compareTo(b.start));
|
||||
|
||||
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({}));
|
||||
|
||||
if (_lesson.start.year != 0) {
|
||||
@ -328,7 +328,7 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
hasActivityStarted = true;
|
||||
} else if (!hasActivityStarted &&
|
||||
((currentState == LiveCardState.duringLesson &&
|
||||
currentLesson != null) ||
|
||||
currentLesson != null) ||
|
||||
currentState == LiveCardState.duringBreak)) {
|
||||
debugPrint("Óra van, vagy szünet, de nincs LiveActivity. létrehozás...");
|
||||
PlatformChannel.createLiveActivity(toMap());
|
||||
@ -362,7 +362,12 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
//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 &&
|
||||
nextLesson == null &&
|
||||
now.isAfter(prevLesson!.end)) {
|
||||
@ -384,4 +389,4 @@ class LiveCardProvider extends ChangeNotifier {
|
||||
List<Lesson> _today(TimetableProvider p) => (p.getWeek(Week.current()) ?? [])
|
||||
.where((l) => _sameDate(l.date, _now()))
|
||||
.toList();
|
||||
}
|
||||
}
|
@ -7,17 +7,23 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class SelfNoteProvider with ChangeNotifier {
|
||||
late List<SelfNote> _notes;
|
||||
late List<TodoItem> _todoItems;
|
||||
late BuildContext _context;
|
||||
|
||||
List<SelfNote> get notes => _notes;
|
||||
List<TodoItem> get todos => _todoItems;
|
||||
|
||||
SelfNoteProvider({
|
||||
List<SelfNote> initialNotes = const [],
|
||||
List<TodoItem> initialTodoItems = const [],
|
||||
required BuildContext context,
|
||||
}) {
|
||||
_notes = List.castFrom(initialNotes);
|
||||
_todoItems = List.castFrom(initialTodoItems);
|
||||
_context = context;
|
||||
|
||||
if (_notes.isEmpty) restore();
|
||||
if (_todoItems.isEmpty) restoreTodo();
|
||||
}
|
||||
|
||||
// restore self notes from db
|
||||
@ -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)
|
||||
// Future<void> fetch() async {
|
||||
// }
|
||||
@ -54,4 +78,17 @@ class SelfNoteProvider with ChangeNotifier {
|
||||
_notes = notes;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// store todo items in db
|
||||
Future<void> storeTodo(List<TodoItem> todos) async {
|
||||
User? user = Provider.of<UserProvider>(_context, listen: false).user;
|
||||
if (user == null) throw "Cannot store Self Notes for User null";
|
||||
String userId = user.id;
|
||||
|
||||
await Provider.of<DatabaseProvider>(_context, listen: false)
|
||||
.userStore
|
||||
.storeSelfTodoItems(todos, userId: userId);
|
||||
_todoItems = todos;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class UserProvider with ChangeNotifier {
|
||||
String? get nickname => user?.nickname;
|
||||
String get picture => user?.picture ?? "";
|
||||
String? get displayName => user?.displayName;
|
||||
int? get gradeStreak => user?.gradeStreak;
|
||||
|
||||
final SettingsProvider _settings;
|
||||
|
||||
|
@ -45,6 +45,7 @@ const settingsDB = DatabaseStruct("settings", {
|
||||
// more
|
||||
"show_breaks": int,
|
||||
"font_family": String,
|
||||
"title_only_font": int,
|
||||
"plus_session_id": String,
|
||||
"cal_sync_room_location": String, "cal_sync_show_exams": int,
|
||||
"cal_sync_show_teacher": int, "cal_sync_renamed": int,
|
||||
@ -52,6 +53,7 @@ const settingsDB = DatabaseStruct("settings", {
|
||||
"nav_shadow": int,
|
||||
"new_colors": int,
|
||||
"uwu_mode": int,
|
||||
"new_popups": int,
|
||||
// quick settings
|
||||
"q_timetable_lesson_num": int, "q_timetable_sub_tiles": int,
|
||||
"q_subjects_sub_tiles": int,
|
||||
@ -61,7 +63,8 @@ const settingsDB = DatabaseStruct("settings", {
|
||||
const usersDB = DatabaseStruct("users", {
|
||||
"id": String, "name": String, "username": String, "password": String,
|
||||
"institute_code": String, "student": String, "role": int,
|
||||
"nickname": String, "picture": String // premium only
|
||||
"nickname": String, "picture": String, // premium only (it's now plus btw)
|
||||
"grade_streak": int,
|
||||
});
|
||||
const userDataDB = DatabaseStruct("user_data", {
|
||||
"id": String, "grades": String, "timetable": String, "exams": String,
|
||||
@ -84,12 +87,13 @@ const userDataDB = DatabaseStruct("user_data", {
|
||||
"goal_befores": String,
|
||||
"goal_pin_dates": String,
|
||||
// todo and notes
|
||||
"todo_items": String, "self_notes": String,
|
||||
"todo_items": String, "self_notes": String, "self_todo": String,
|
||||
// v5 shit
|
||||
"roundings": String,
|
||||
"grade_rarities": String,
|
||||
"linked_accounts": String,
|
||||
"custom_lesson_desc": String,
|
||||
"watch_data": String,
|
||||
});
|
||||
|
||||
Future<void> createTable(Database db, DatabaseStruct struct) =>
|
||||
@ -129,7 +133,12 @@ Future<Database> initDB(DatabaseProvider database) async {
|
||||
await migrateDB(
|
||||
db,
|
||||
struct: usersDB,
|
||||
defaultValues: {"role": 0, "nickname": "", "picture": ""},
|
||||
defaultValues: {
|
||||
"role": 0,
|
||||
"nickname": "",
|
||||
"picture": "",
|
||||
"grade_streak": 0
|
||||
},
|
||||
);
|
||||
await migrateDB(db, struct: userDataDB, defaultValues: {
|
||||
"grades": "[]", "timetable": "[]", "exams": "[]", "homework": "[]",
|
||||
@ -152,12 +161,13 @@ Future<Database> initDB(DatabaseProvider database) async {
|
||||
"goal_befores": "{}",
|
||||
"goal_pin_dates": "{}",
|
||||
// todo and notes
|
||||
"todo_items": "{}", "self_notes": "[]",
|
||||
"todo_items": "{}", "self_notes": "[]", "self_todo": "[]",
|
||||
// v5 shit
|
||||
"roundings": "{}",
|
||||
"grade_rarities": "{}",
|
||||
"linked_accounts": "[]",
|
||||
"custom_lesson_desc": "{}",
|
||||
"watch_data": "{}",
|
||||
});
|
||||
} catch (error) {
|
||||
print("ERROR: migrateDB: $error");
|
||||
|
@ -317,6 +317,18 @@ class UserDatabaseQuery {
|
||||
return selfNotes;
|
||||
}
|
||||
|
||||
Future<List<TodoItem>> getTodoItems({required String userId}) async {
|
||||
List<Map> userData =
|
||||
await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.isEmpty) return [];
|
||||
String? todoItemsJson = userData.elementAt(0)["self_todo"] as String?;
|
||||
if (todoItemsJson == null) return [];
|
||||
List<TodoItem> todoItems = (jsonDecode(todoItemsJson) as List)
|
||||
.map((e) => TodoItem.fromJson(e))
|
||||
.toList();
|
||||
return todoItems;
|
||||
}
|
||||
|
||||
// v5
|
||||
Future<Map<String, String>> getRoundings({required String userId}) async {
|
||||
List<Map> userData =
|
||||
|
@ -196,6 +196,13 @@ class UserDatabaseStore {
|
||||
where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future<void> storeSelfTodoItems(List<TodoItem> todoItems,
|
||||
{required String userId}) async {
|
||||
String todoItemsJson = jsonEncode(todoItems.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"self_todo": todoItemsJson},
|
||||
where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
// v5
|
||||
Future<void> storeRoundings(Map<String, String> roundings,
|
||||
{required String userId}) async {
|
||||
|
@ -212,7 +212,7 @@ nem lesz tőle használhatatlan az app, de kikommenteltem, mert még a végén k
|
||||
),
|
||||
notificationDetails,
|
||||
payload: "grades");
|
||||
} else if (settingsProvider.gradeOpeningFun) {
|
||||
} else if (settingsProvider.gradeOpeningFun) {
|
||||
// if surprise grades are enabled, show a notification without the grade
|
||||
await flutterLocalNotificationsPlugin.show(
|
||||
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.name,
|
||||
dayTitle(lesson.date),
|
||||
lesson.substituteTeacher!.isRenamed
|
||||
? lesson.substituteTeacher!.renamedTo!
|
||||
: lesson.substituteTeacher!.name
|
||||
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||
? lesson.substituteTeacher?.renamedTo!
|
||||
: lesson.substituteTeacher?.name) ??
|
||||
'',
|
||||
],
|
||||
),
|
||||
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),
|
||||
lesson.lessonIndex,
|
||||
lesson.name,
|
||||
lesson.substituteTeacher!.isRenamed
|
||||
? lesson.substituteTeacher!.renamedTo!
|
||||
: lesson.substituteTeacher!.name
|
||||
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||
? lesson.substituteTeacher?.renamedTo!
|
||||
: lesson.substituteTeacher?.name) ??
|
||||
'',
|
||||
],
|
||||
),
|
||||
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.name,
|
||||
dayTitle(lesson.date),
|
||||
lesson.substituteTeacher!.isRenamed
|
||||
? lesson.substituteTeacher!.renamedTo!
|
||||
: lesson.substituteTeacher!.name
|
||||
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||
? lesson.substituteTeacher?.renamedTo!
|
||||
: lesson.substituteTeacher?.name) ??
|
||||
'',
|
||||
],
|
||||
),
|
||||
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.name,
|
||||
dayTitle(lesson.date),
|
||||
lesson.substituteTeacher!.isRenamed
|
||||
? lesson.substituteTeacher!.renamedTo!
|
||||
: lesson.substituteTeacher!.name
|
||||
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||
? lesson.substituteTeacher?.renamedTo!
|
||||
: lesson.substituteTeacher?.name) ??
|
||||
'',
|
||||
],
|
||||
),
|
||||
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),
|
||||
lesson.lessonIndex,
|
||||
lesson.name,
|
||||
lesson.substituteTeacher!.isRenamed
|
||||
? lesson.substituteTeacher!.renamedTo!
|
||||
: lesson.substituteTeacher!.name
|
||||
((lesson.substituteTeacher?.isRenamed ?? false)
|
||||
? lesson.substituteTeacher?.renamedTo!
|
||||
: lesson.substituteTeacher?.name) ??
|
||||
'',
|
||||
],
|
||||
),
|
||||
notificationDetails,
|
||||
|
@ -292,3 +292,105 @@ class ShortSubject {
|
||||
return subject?.name.capital() ?? subjectName?.capital() ?? "?";
|
||||
}
|
||||
}
|
||||
|
||||
// new v5 thingie
|
||||
class SubjectBooklet {
|
||||
// static String resolveName({GradeSubject? subject, String? subjectName}) =>
|
||||
// _resolve(subject: subject, subjectName: subjectName).name;
|
||||
static String resolveVariant(
|
||||
{GradeSubject? subject,
|
||||
String? subjectName,
|
||||
required BuildContext context}) =>
|
||||
_resolve(subject: subject, subjectName: subjectName);
|
||||
|
||||
static String _resolve({GradeSubject? subject, String? subjectName}) {
|
||||
assert(!(subject == null && subjectName == null));
|
||||
|
||||
String name = (subject?.name ?? subjectName ?? "")
|
||||
.toLowerCase()
|
||||
.specialChars()
|
||||
.trim();
|
||||
String category =
|
||||
subject?.category.description.toLowerCase().specialChars() ?? "";
|
||||
|
||||
String basePath = "assets/svg/cover_arts";
|
||||
|
||||
// todo: check for categories
|
||||
if (RegExp("mate(k|matika)").hasMatch(name) || category == "matematika") {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("magyar nyelv|nyelvtan").hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("irodalom").hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("tor(i|tenelem)").hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("foldrajz").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("rajz|muvtori|muveszet|vizualis").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("fizika").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("^enek|zene|szolfezs|zongora|korus").hasMatch(name)) {
|
||||
return "$basePath/vocal.svg";
|
||||
} else if (RegExp("^tes(i|tneveles)|sport|edzeselmelet").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("kemia").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("biologia").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp(
|
||||
"kornyezet|termeszet ?(tudomany|ismeret)|hon( es nep)?ismeret")
|
||||
.hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("(hit|erkolcs)tan|vallas|etika|bibliaismeret")
|
||||
.hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("penzugy").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("informatika|szoftver|iroda|digitalis").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("prog").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("halozat").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("szinhaz").hasMatch(name)) {
|
||||
return "$basePath/vocal.svg";
|
||||
} else if (RegExp("film|media").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("elektro(tech)?nika").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("gepesz|mernok|ipar").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("technika").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("tanc").hasMatch(name)) {
|
||||
return "$basePath/vocal.svg";
|
||||
} else if (RegExp("filozofia").hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("osztaly(fonoki|kozosseg)|kozossegi|neveles")
|
||||
.hasMatch(name) ||
|
||||
name == "ofo") {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("gazdasag").hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("szorgalom").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("magatartas").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp(
|
||||
"angol|nemet|francia|olasz|orosz|spanyol|latin|kinai|nyelv")
|
||||
.hasMatch(name)) {
|
||||
return "$basePath/line.svg";
|
||||
} else if (RegExp("linux").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
} else if (RegExp("adatbazis").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("asztali alkalmazasok").hasMatch(name)) {
|
||||
return "$basePath/grid.svg";
|
||||
} else if (RegExp("projekt").hasMatch(name)) {
|
||||
return "$basePath/plain.svg";
|
||||
}
|
||||
|
||||
return "$basePath/plain.svg";
|
||||
}
|
||||
}
|
||||
|
@ -33,3 +33,37 @@ class SelfNote {
|
||||
'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
|
||||
bool _showBreaks;
|
||||
String _fontFamily;
|
||||
bool _titleOnlyFont;
|
||||
String _plusSessionId;
|
||||
String _calSyncRoomLocation;
|
||||
bool _calSyncShowExams;
|
||||
@ -105,6 +106,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
bool _navShadow;
|
||||
bool _newColors;
|
||||
bool _uwuMode;
|
||||
bool _newPopups;
|
||||
// quick settings
|
||||
bool _qTimetableLessonNum;
|
||||
bool _qTimetableSubTiles;
|
||||
@ -167,6 +169,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
required String pinSetNotify,
|
||||
required String pinSetExtras,
|
||||
required String fontFamily,
|
||||
required bool titleOnlyFont,
|
||||
required String plusSessionId,
|
||||
required String calSyncRoomLocation,
|
||||
required bool calSyncShowExams,
|
||||
@ -176,6 +179,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
required bool navShadow,
|
||||
required bool newColors,
|
||||
required bool uwuMode,
|
||||
required bool newPopups,
|
||||
required bool qTimetableLessonNum,
|
||||
required bool qTimetableSubTiles,
|
||||
required bool qSubjectsSubTiles,
|
||||
@ -235,6 +239,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
_pinSetNotify = pinSetNotify,
|
||||
_pinSetExtras = pinSetExtras,
|
||||
_fontFamily = fontFamily,
|
||||
_titleOnlyFont = titleOnlyFont,
|
||||
_plusSessionId = plusSessionId,
|
||||
_calSyncRoomLocation = calSyncRoomLocation,
|
||||
_calSyncShowExams = calSyncShowExams,
|
||||
@ -244,6 +249,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
_navShadow = navShadow,
|
||||
_newColors = newColors,
|
||||
_uwuMode = uwuMode,
|
||||
_newPopups = newPopups,
|
||||
_qTimetableLessonNum = qTimetableLessonNum,
|
||||
_qTimetableSubTiles = qTimetableSubTiles,
|
||||
_qSubjectsSubTiles = qSubjectsSubTiles;
|
||||
@ -322,6 +328,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
pinSetNotify: map['notify_s_pin'],
|
||||
pinSetExtras: map['extras_s_pin'],
|
||||
fontFamily: map['font_family'],
|
||||
titleOnlyFont: map['title_only_font'] == 1,
|
||||
plusSessionId: map['plus_session_id'],
|
||||
calSyncRoomLocation: map['cal_sync_room_location'],
|
||||
calSyncShowExams: map['cal_sync_show_exams'] == 1,
|
||||
@ -331,6 +338,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
navShadow: map['nav_shadow'] == 1,
|
||||
newColors: map['new_colors'] == 1,
|
||||
uwuMode: map['uwu_mode'] == 1,
|
||||
newPopups: map['new_popups'] == 1,
|
||||
qTimetableLessonNum: map['q_timetable_lesson_num'] == 1,
|
||||
qTimetableSubTiles: map['q_timetable_sub_tiles'] == 1,
|
||||
qSubjectsSubTiles: map['q_subjects_sub_tiles'] == 1,
|
||||
@ -397,6 +405,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
"notify_s_pin": _pinSetNotify,
|
||||
"extras_s_pin": _pinSetExtras,
|
||||
"font_family": _fontFamily,
|
||||
"title_only_font": _titleOnlyFont ? 1 : 0,
|
||||
"plus_session_id": _plusSessionId,
|
||||
"cal_sync_room_location": _calSyncRoomLocation,
|
||||
"cal_sync_show_exams": _calSyncShowExams ? 1 : 0,
|
||||
@ -406,6 +415,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
"nav_shadow": _navShadow ? 1 : 0,
|
||||
"new_colors": _newColors ? 1 : 0,
|
||||
"uwu_mode": _uwuMode ? 1 : 0,
|
||||
"new_popups": _newPopups ? 1 : 0,
|
||||
"q_timetable_lesson_num": _qTimetableLessonNum ? 1 : 0,
|
||||
"q_timetable_sub_tiles": _qTimetableSubTiles ? 1 : 0,
|
||||
"q_subjects_sub_tiles": _qSubjectsSubTiles ? 1 : 0,
|
||||
@ -476,6 +486,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
pinSetNotify: '',
|
||||
pinSetExtras: '',
|
||||
fontFamily: '',
|
||||
titleOnlyFont: false,
|
||||
plusSessionId: '',
|
||||
calSyncRoomLocation: 'location',
|
||||
calSyncShowExams: true,
|
||||
@ -485,6 +496,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
navShadow: true,
|
||||
newColors: true,
|
||||
uwuMode: false,
|
||||
newPopups: true,
|
||||
qTimetableLessonNum: true,
|
||||
qTimetableSubTiles: true,
|
||||
qSubjectsSubTiles: true,
|
||||
@ -546,6 +558,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
String get currentThemeCreator => _currentThemeCreator;
|
||||
bool get showBreaks => _showBreaks;
|
||||
String get fontFamily => _fontFamily;
|
||||
bool get titleOnlyFont => _titleOnlyFont;
|
||||
String get plusSessionId => _plusSessionId;
|
||||
String get calSyncRoomLocation => _calSyncRoomLocation;
|
||||
bool get calSyncShowExams => _calSyncShowExams;
|
||||
@ -555,6 +568,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
bool get navShadow => _navShadow;
|
||||
bool get newColors => _newColors;
|
||||
bool get uwuMode => _uwuMode;
|
||||
bool get newPopups => _newPopups;
|
||||
bool get qTimetableLessonNum => _qTimetableLessonNum;
|
||||
bool get qTimetableSubTiles => _qTimetableSubTiles;
|
||||
bool get qSubjectsSubTiles => _qSubjectsSubTiles;
|
||||
@ -612,6 +626,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
String? currentThemeCreator,
|
||||
bool? showBreaks,
|
||||
String? fontFamily,
|
||||
bool? titleOnlyFont,
|
||||
String? plusSessionId,
|
||||
String? calSyncRoomLocation,
|
||||
bool? calSyncShowExams,
|
||||
@ -621,6 +636,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
bool? navShadow,
|
||||
bool? newColors,
|
||||
bool? uwuMode,
|
||||
bool? newPopups,
|
||||
bool? qTimetableLessonNum,
|
||||
bool? qTimetableSubTiles,
|
||||
bool? qSubjectsSubTiles,
|
||||
@ -777,6 +793,9 @@ class SettingsProvider extends ChangeNotifier {
|
||||
if (fontFamily != null && fontFamily != _fontFamily) {
|
||||
_fontFamily = fontFamily;
|
||||
}
|
||||
if (titleOnlyFont != null && titleOnlyFont != _titleOnlyFont) {
|
||||
_titleOnlyFont = titleOnlyFont;
|
||||
}
|
||||
if (plusSessionId != null && plusSessionId != _plusSessionId) {
|
||||
_plusSessionId = plusSessionId;
|
||||
}
|
||||
@ -806,6 +825,9 @@ class SettingsProvider extends ChangeNotifier {
|
||||
if (uwuMode != null && uwuMode != _uwuMode) {
|
||||
_uwuMode = uwuMode;
|
||||
}
|
||||
if (newPopups != null && newPopups != _newPopups) {
|
||||
_newPopups = newPopups;
|
||||
}
|
||||
if (qTimetableLessonNum != null &&
|
||||
qTimetableLessonNum != _qTimetableLessonNum) {
|
||||
_qTimetableLessonNum = qTimetableLessonNum;
|
||||
|
@ -16,8 +16,10 @@ class User {
|
||||
Role role;
|
||||
String nickname;
|
||||
String picture;
|
||||
int gradeStreak;
|
||||
|
||||
String get displayName => nickname != '' ? nickname : name;
|
||||
bool get hasStreak => gradeStreak > 0;
|
||||
|
||||
User({
|
||||
String? id,
|
||||
@ -29,6 +31,7 @@ class User {
|
||||
required this.role,
|
||||
this.nickname = "",
|
||||
this.picture = "",
|
||||
this.gradeStreak = 0,
|
||||
}) {
|
||||
if (id != null) {
|
||||
this.id = id;
|
||||
@ -57,6 +60,7 @@ class User {
|
||||
role: Role.values[map["role"] ?? 0],
|
||||
nickname: map["nickname"] ?? "",
|
||||
picture: map["picture"] ?? "",
|
||||
gradeStreak: map["grade_streak"] ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -104,9 +104,10 @@ class AppTheme {
|
||||
brightness: Brightness.light,
|
||||
useMaterial3: true,
|
||||
fontFamily: _defaultFontFamily,
|
||||
textTheme:
|
||||
googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor) ??
|
||||
const TextTheme().apply(bodyColor: textColor),
|
||||
textTheme: !settings.titleOnlyFont
|
||||
? (googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor) ??
|
||||
const TextTheme().apply(bodyColor: textColor))
|
||||
: null,
|
||||
scaffoldBackgroundColor: backgroundColor,
|
||||
primaryColor: lightColors.filc,
|
||||
dividerColor: const Color(0x00000000),
|
||||
@ -229,8 +230,9 @@ class AppTheme {
|
||||
brightness: Brightness.dark,
|
||||
useMaterial3: true,
|
||||
fontFamily: _defaultFontFamily,
|
||||
textTheme:
|
||||
googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor),
|
||||
textTheme: !settings.titleOnlyFont
|
||||
? (googleFontsMap[settings.fontFamily]?.apply(bodyColor: textColor))
|
||||
: null,
|
||||
scaffoldBackgroundColor: backgroundColor,
|
||||
primaryColor: darkColors.filc,
|
||||
dividerColor: const Color(0x00000000),
|
||||
|
@ -192,6 +192,8 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool advOverride = widget.colorMode == CustomColorMode.grade ? true : false;
|
||||
|
||||
if (MediaQuery.of(context).orientation == Orientation.portrait ||
|
||||
widget.portraitOnly) {
|
||||
return Column(
|
||||
@ -218,7 +220,7 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
||||
child: colorPickerSlider(TrackType.saturation),
|
||||
),
|
||||
),
|
||||
if (isAdvancedView)
|
||||
if (isAdvancedView || advOverride)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12.0, right: 12.0),
|
||||
child: SizedBox(
|
||||
@ -230,7 +232,7 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
||||
],
|
||||
),
|
||||
),
|
||||
if (isAdvancedView &&
|
||||
if ((isAdvancedView || advOverride) &&
|
||||
widget.colorMode != CustomColorMode.theme &&
|
||||
widget.colorMode != CustomColorMode.enterId)
|
||||
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(
|
||||
height: 70 * (widget.colorMode == CustomColorMode.theme ? 2 : 1),
|
||||
child: BlockPicker(
|
||||
@ -347,7 +350,8 @@ class FilcColorPickerState extends State<FilcColorPicker> {
|
||||
),
|
||||
),
|
||||
if (widget.colorMode != CustomColorMode.theme &&
|
||||
widget.colorMode != CustomColorMode.enterId)
|
||||
widget.colorMode != CustomColorMode.enterId &&
|
||||
!advOverride)
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc_kreta_api/providers/exam_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_mobile_ui/common/panel/panel.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:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
@ -109,7 +111,8 @@ class LessonTile extends StatelessWidget {
|
||||
title: exam.description != ""
|
||||
? exam.description
|
||||
: 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(
|
||||
offset: const Offset(0, -2.0),
|
||||
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,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
|
@ -3,7 +3,7 @@ description: "Egy nem hivatalos e-KRÉTA kliens, diákoktól diákoknak."
|
||||
homepage: https://refilc.hu
|
||||
publish_to: "none"
|
||||
|
||||
version: 5.0.0+257
|
||||
version: 5.0.1+265
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <=3.3.2"
|
||||
@ -104,6 +104,7 @@ flutter:
|
||||
- assets/svg/menu_icons/
|
||||
- assets/other/dirtywords.xml
|
||||
- assets/svg/
|
||||
- assets/svg/cover_arts/
|
||||
|
||||
fonts:
|
||||
- family: FilcIcons
|
||||
|
@ -268,7 +268,7 @@ class GradesPageState extends State<GradesPage> {
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Text(
|
||||
"Grades".i18n,
|
||||
"page_title_grades".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text,
|
||||
fontSize: 32.0,
|
||||
|
@ -11,6 +11,7 @@ class Student {
|
||||
String? address;
|
||||
String? groupId;
|
||||
List<String> parents;
|
||||
// List<String> parentsPhone;
|
||||
String? className;
|
||||
|
||||
Student({
|
||||
@ -21,6 +22,7 @@ class Student {
|
||||
required this.yearId,
|
||||
this.address,
|
||||
required this.parents,
|
||||
// required this.parentsPhone,
|
||||
this.json,
|
||||
});
|
||||
|
||||
|
@ -50,7 +50,8 @@ class GradeProvider with ChangeNotifier {
|
||||
String? userId = _user.id;
|
||||
if (userId != null) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -59,7 +60,8 @@ class GradeProvider with ChangeNotifier {
|
||||
String? userId = _user.id;
|
||||
if (userId != null) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -73,9 +75,11 @@ class GradeProvider with ChangeNotifier {
|
||||
|
||||
_grades = await userQuery.getGrades(userId: userId);
|
||||
await convertBySettings();
|
||||
await getGradeStreak();
|
||||
_groupAvg = await userQuery.getGroupAverages(userId: userId);
|
||||
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 ||
|
||||
lastSeenDB.year == 0 ||
|
||||
!_settings.gradeOpeningFun) {
|
||||
@ -133,6 +137,30 @@ class GradeProvider with ChangeNotifier {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
print(gradeStreak);
|
||||
|
||||
user.gradeStreak = gradeStreak;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// Fetches Grades from the Kreta API then stores them in the database
|
||||
Future<void> fetch() async {
|
||||
// test cucc
|
||||
@ -173,6 +201,7 @@ class GradeProvider with ChangeNotifier {
|
||||
await _database.userStore.storeGrades(grades, userId: userId);
|
||||
_grades = grades;
|
||||
await convertBySettings();
|
||||
await getGradeStreak();
|
||||
}
|
||||
|
||||
Future<void> storeGroupAvg(List<GroupAverage> groupAvgs) async {
|
||||
|
@ -19,11 +19,13 @@ class ShareProvider extends ChangeNotifier {
|
||||
// }
|
||||
|
||||
// themes
|
||||
Future<SharedTheme> shareCurrentTheme(BuildContext context,
|
||||
{bool isPublic = false,
|
||||
bool shareNick = true,
|
||||
required SharedGradeColors gradeColors,
|
||||
String displayName = ''}) async {
|
||||
Future<SharedTheme> shareCurrentTheme(
|
||||
BuildContext context, {
|
||||
bool isPublic = false,
|
||||
bool shareNick = true,
|
||||
required SharedGradeColors gradeColors,
|
||||
String displayName = '',
|
||||
}) async {
|
||||
final SettingsProvider settings =
|
||||
Provider.of<SettingsProvider>(context, listen: false);
|
||||
|
||||
@ -69,7 +71,25 @@ class ShareProvider extends ChangeNotifier {
|
||||
|
||||
if (gradeColorsJson != null) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -93,7 +113,25 @@ class ShareProvider extends ChangeNotifier {
|
||||
|
||||
if (gradeColorsJson != null) {
|
||||
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);
|
||||
}
|
||||
@ -134,8 +172,25 @@ class ShareProvider extends ChangeNotifier {
|
||||
Map? gradeColorsJson = await FilcAPI.getSharedGradeColors(id);
|
||||
|
||||
if (gradeColorsJson != null) {
|
||||
SharedGradeColors gradeColors =
|
||||
SharedGradeColors.fromJson(gradeColorsJson);
|
||||
SharedGradeColors gradeColors = 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 gradeColors;
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,22 @@
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
|
||||
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 bool border;
|
||||
final bool dashed;
|
||||
final double scale;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -20,25 +29,44 @@ class AverageDisplay extends StatelessWidget {
|
||||
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(
|
||||
width: border ? 57.0 : 54.0,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 6.0 - (border ? 2 : 0), vertical: 5.0 - (border ? 2 : 0)),
|
||||
width: (border ? 57.0 : 54.0) * scale,
|
||||
padding: (border && dashed)
|
||||
? null
|
||||
: EdgeInsets.symmetric(
|
||||
horizontal: (6.0 - (border ? 2 : 0)) * scale,
|
||||
vertical: (5.0 - (border ? 2 : 0))) *
|
||||
scale,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(45.0),
|
||||
border: border
|
||||
borderRadius:
|
||||
(border && dashed) ? null : BorderRadius.circular(45.0 * scale),
|
||||
border: border && !dashed
|
||||
? Border.fromBorderSide(
|
||||
BorderSide(color: color.withOpacity(.5), width: 1.0))
|
||||
BorderSide(color: color.withOpacity(.5), width: 1.0 * scale))
|
||||
: null,
|
||||
color: !border ? color.withOpacity(average == 0.0 ? .15 : .25) : null,
|
||||
),
|
||||
child: Text(
|
||||
average == 0.0 ? "-" : averageText,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: color, fontWeight: FontWeight.w600, fontSize: 15.0),
|
||||
maxLines: 1,
|
||||
),
|
||||
child: (border && dashed)
|
||||
? DottedBorder(
|
||||
strokeWidth: 1.0 * scale,
|
||||
padding: EdgeInsets.all(4.0 * scale),
|
||||
color: color.withOpacity(.5),
|
||||
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:refilc/helpers/subject.dart';
|
||||
import 'package:refilc/theme/colors/colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:refilc/theme/colors/utils.dart';
|
||||
@ -113,7 +114,9 @@ class HeroScrollViewState extends State<HeroScrollView> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 26.0),
|
||||
child: SvgPicture.asset(
|
||||
"assets/svg/mesh_bg.svg",
|
||||
// "assets/svg/mesh_bg.svg",
|
||||
SubjectBooklet.resolveVariant(
|
||||
context: context, subjectName: widget.title),
|
||||
// ignore: deprecated_member_use
|
||||
color: ColorsUtils()
|
||||
.darken(
|
||||
|
@ -49,6 +49,8 @@ extension Localization on String {
|
||||
"d_npc":
|
||||
"You're such a non-player character, we couldn't give you a personality.",
|
||||
"s_npc": "In-game playtime (hours)",
|
||||
// other
|
||||
"year_index": "Lesson Number",
|
||||
},
|
||||
"hu_hu": {
|
||||
// main
|
||||
@ -96,6 +98,8 @@ extension Localization on String {
|
||||
"d_npc":
|
||||
"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)",
|
||||
// other
|
||||
"year_index": "Éves óraszám",
|
||||
},
|
||||
"de_de": {
|
||||
// main
|
||||
@ -144,6 +148,8 @@ extension Localization on String {
|
||||
"d_npc":
|
||||
"Du bist einfach so sehr wie ein Computer, dass wir dir nicht einmal eine Persönlichkeit geben konnten.",
|
||||
"s_npc": "Spielzeit (Stunden)",
|
||||
// other
|
||||
"year_index": "Ordinalzahl",
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -65,6 +65,7 @@ class ProfileButton extends StatelessWidget {
|
||||
radius: child.radius,
|
||||
badge: child.badge,
|
||||
role: child.role,
|
||||
gradeStreak: child.gradeStreak,
|
||||
profilePictureString: child.profilePictureString,
|
||||
onTap: () {
|
||||
showSlidingBottomSheet(
|
||||
|
@ -21,6 +21,7 @@ class ProfileImage extends StatefulWidget {
|
||||
this.censored = false,
|
||||
this.profilePictureString = "",
|
||||
this.isNotePfp = false,
|
||||
this.gradeStreak = false,
|
||||
});
|
||||
|
||||
final void Function()? onTap;
|
||||
@ -35,6 +36,7 @@ class ProfileImage extends StatefulWidget {
|
||||
final bool censored;
|
||||
final String profilePictureString;
|
||||
final bool isNotePfp;
|
||||
final bool gradeStreak;
|
||||
|
||||
@override
|
||||
State<ProfileImage> createState() => _ProfileImageState();
|
||||
@ -145,6 +147,20 @@ class _ProfileImageState extends State<ProfileImage> {
|
||||
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(
|
||||
color: Colors.transparent,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
|
@ -1,6 +1,7 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.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_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/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:flutter/material.dart';
|
||||
import 'package:refilc_mobile_ui/common/widgets/exam/exam_view.dart';
|
||||
|
||||
class ExamViewable extends StatelessWidget {
|
||||
const ExamViewable(this.exam,
|
||||
@ -26,22 +30,25 @@ class ExamViewable extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => ExamPopup.show(context: context, exam: exam),
|
||||
child: ExamTile(
|
||||
if (Provider.of<SettingsProvider>(context).newPopups) {
|
||||
return GestureDetector(
|
||||
onTap: () => ExamPopup.show(context: context, exam: exam),
|
||||
child: ExamTile(
|
||||
exam,
|
||||
showSubject: showSubject,
|
||||
padding: tilePadding,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Viewable(
|
||||
tile: ExamTile(
|
||||
exam,
|
||||
showSubject: showSubject,
|
||||
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(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/svg/mesh_bg.svg",
|
||||
// "assets/svg/mesh_bg.svg",
|
||||
SubjectBooklet.resolveVariant(
|
||||
context: context, subject: exam.subject),
|
||||
// ignore: deprecated_member_use
|
||||
color: ColorsUtils()
|
||||
.fade(context, Theme.of(context).colorScheme.secondary,
|
||||
@ -210,13 +219,19 @@ class ExamPopup extends StatelessWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
exam.description.capital(),
|
||||
style: TextStyle(
|
||||
color:
|
||||
AppColors.of(context).text.withOpacity(0.9),
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w600,
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.7,
|
||||
child: Text(
|
||||
exam.description.capital(),
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(0.9),
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
@ -288,7 +303,7 @@ class ExamPopup extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
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(
|
||||
color:
|
||||
AppColors.of(context).text.withOpacity(0.85),
|
||||
|
@ -12,6 +12,7 @@ extension Localization on String {
|
||||
"l_desc": "Description...",
|
||||
"done": "Done",
|
||||
"cancel": "Cancel",
|
||||
"year_index": "Lesson Number",
|
||||
},
|
||||
"hu_hu": {
|
||||
"Room": "Terem",
|
||||
@ -22,6 +23,7 @@ extension Localization on String {
|
||||
"l_desc": "Leírás...",
|
||||
"done": "Kész",
|
||||
"cancel": "Mégse",
|
||||
"year_index": "Éves óraszám",
|
||||
},
|
||||
"de_de": {
|
||||
"Room": "Raum",
|
||||
@ -32,6 +34,7 @@ extension Localization on String {
|
||||
"l_desc": "Beschreibung...",
|
||||
"done": "Erledigt",
|
||||
"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:intl/intl.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/utils.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/providers/exam_provider.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/ui/widgets/lesson/lesson_tile.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 {
|
||||
const LessonViewable(
|
||||
@ -59,174 +70,169 @@ class LessonViewableState extends State<LessonViewable> {
|
||||
|
||||
if (lsn.subject.id == '' || tile.lesson.isEmpty) return tile;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => TimetableLessonPopup.show(
|
||||
context: context,
|
||||
lesson: lsn,
|
||||
),
|
||||
child: LessonTile(
|
||||
lsn,
|
||||
swapDesc: widget.swapDesc,
|
||||
showSubTiles: widget.showSubTiles,
|
||||
// onTap: () => TimetableLessonPopup.show(
|
||||
// context: context,
|
||||
// lesson: lsn,
|
||||
// ),
|
||||
),
|
||||
// check if new popup needed
|
||||
if (Provider.of<SettingsProvider>(context).newPopups) {
|
||||
return GestureDetector(
|
||||
onTap: () => TimetableLessonPopup.show(
|
||||
context: context,
|
||||
lesson: lsn,
|
||||
),
|
||||
child: tile,
|
||||
);
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -283,6 +289,18 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
|
||||
@override
|
||||
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(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
@ -295,7 +313,9 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
Stack(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/svg/mesh_bg.svg",
|
||||
// "assets/svg/mesh_bg.svg",
|
||||
SubjectBooklet.resolveVariant(
|
||||
context: context, subject: lesson.subject),
|
||||
// ignore: deprecated_member_use
|
||||
color: ColorsUtils()
|
||||
.fade(context, Theme.of(context).colorScheme.secondary,
|
||||
@ -319,13 +339,13 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
.withOpacity(0.1),
|
||||
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,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 175.0,
|
||||
height: 200.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -340,16 +360,27 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
width: 40,
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsUtils()
|
||||
.fade(
|
||||
context, Theme.of(context).colorScheme.secondary,
|
||||
darkenAmount: 0.1, lightenAmount: 0.1)
|
||||
.withOpacity(0.33),
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(
|
||||
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(
|
||||
height: 38.0,
|
||||
),
|
||||
@ -387,11 +418,9 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: const Radius.circular(12.0),
|
||||
bottom: (lesson.description.replaceAll(' ', '') != '')
|
||||
? const Radius.circular(6.0)
|
||||
: const Radius.circular(12.0),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12.0),
|
||||
bottom: Radius.circular(6.0),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(14.0),
|
||||
@ -466,7 +495,15 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
height: 8.0,
|
||||
),
|
||||
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(
|
||||
color: AppColors.of(context).text.withOpacity(0.9),
|
||||
fontSize: 14.0,
|
||||
@ -487,7 +524,7 @@ class TimetableLessonPopup extends StatelessWidget {
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(6.0),
|
||||
bottom: Radius.circular(12.0),
|
||||
bottom: Radius.circular(6.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(
|
||||
// height: 24.0,
|
||||
// ),
|
||||
|
@ -4,7 +4,9 @@ import 'dart:math';
|
||||
|
||||
import 'package:animations/animations.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:google_fonts/google_fonts.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/ui/date_widget.dart';
|
||||
import 'package:refilc_kreta_api/models/absence.dart';
|
||||
@ -169,6 +171,7 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
badge: updateProvider.available,
|
||||
role: user.role,
|
||||
profilePictureString: user.picture,
|
||||
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -179,10 +182,22 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Text(
|
||||
"Absences".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold),
|
||||
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
||||
'' &&
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
bottom: FilterBar(
|
||||
@ -504,7 +519,9 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.of(context).green,
|
||||
color: value1 > 0
|
||||
? AppColors.of(context).green
|
||||
: AppColors.of(context).text,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
@ -513,12 +530,14 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1.1,
|
||||
color: ColorsUtils().fade(
|
||||
context,
|
||||
AppColors.of(context).green,
|
||||
darkenAmount: 0.5,
|
||||
lightenAmount: 0.4,
|
||||
),
|
||||
color: value1 > 0
|
||||
? ColorsUtils().fade(
|
||||
context,
|
||||
AppColors.of(context).green,
|
||||
darkenAmount: 0.5,
|
||||
lightenAmount: 0.4,
|
||||
)
|
||||
: AppColors.of(context).text,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -535,7 +554,9 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.of(context).red,
|
||||
color: value2 > 0
|
||||
? AppColors.of(context).red
|
||||
: AppColors.of(context).text,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
@ -544,12 +565,14 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1.1,
|
||||
color: ColorsUtils().fade(
|
||||
context,
|
||||
AppColors.of(context).red,
|
||||
darkenAmount: 0.4,
|
||||
lightenAmount: 0.2,
|
||||
),
|
||||
color: value2 > 0
|
||||
? ColorsUtils().fade(
|
||||
context,
|
||||
AppColors.of(context).red,
|
||||
darkenAmount: 0.4,
|
||||
lightenAmount: 0.2,
|
||||
)
|
||||
: AppColors.of(context).text,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -597,8 +620,9 @@ class AbsencesPageState extends State<AbsencesPage>
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.av_timer_rounded,
|
||||
color: value3 > 0 ? Colors.orange : null,
|
||||
),
|
||||
const SizedBox(
|
||||
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/graph.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/providers/plus_provider.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_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:refilc_plus/ui/mobile/goal_planner/goal_track_popup.dart';
|
||||
import 'grades_page.i18n.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(
|
||||
// const SnackBar(content: Text("Hamarosan...")));
|
||||
|
||||
Navigator.of(context).push(CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
GoalPlannerScreen(subject: widget.subject)));
|
||||
// Navigator.of(context).push(CupertinoPageRoute(
|
||||
// builder: (context) =>
|
||||
// GoalPlannerScreen(subject: widget.subject)));
|
||||
GoalTrackPopup.show(context, subject: widget.subject);
|
||||
},
|
||||
child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||
),
|
||||
|
@ -4,6 +4,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:refilc/api/providers/update_provider.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc/ui/widgets/grade/grade_tile.dart';
|
||||
@ -267,6 +268,12 @@ class GradesPageState extends State<GradesPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (hasHomework &&
|
||||
nearestExam != null &&
|
||||
Provider.of<SettingsProvider>(context).qSubjectsSubTiles)
|
||||
const SizedBox(
|
||||
height: 6.0,
|
||||
),
|
||||
if (nearestExam != null &&
|
||||
Provider.of<SettingsProvider>(context).qSubjectsSubTiles)
|
||||
Container(
|
||||
@ -560,6 +567,7 @@ class GradesPageState extends State<GradesPage> {
|
||||
badge: updateProvider.available,
|
||||
role: user.role,
|
||||
profilePictureString: user.picture,
|
||||
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -568,11 +576,21 @@ class GradesPageState extends State<GradesPage> {
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: Text(
|
||||
"Grades".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold),
|
||||
"page_title_grades".i18n,
|
||||
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
||||
'' &&
|
||||
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),
|
||||
),
|
||||
),
|
||||
shadowColor: Theme.of(context).shadowColor,
|
||||
@ -667,6 +685,8 @@ class GradesPageState extends State<GradesPage> {
|
||||
|
||||
// SoonAlert.show(context: context);
|
||||
gradeCalcTotal(context);
|
||||
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -31,7 +31,8 @@ extension Localization on String {
|
||||
"grade_calc": "Grade Calculator",
|
||||
},
|
||||
"hu_hu": {
|
||||
"Grades": "Tantárgyak",
|
||||
"Grades": "Jegyek",
|
||||
"page_title_grades": "Tantárgyak",
|
||||
"Ghost Grades": "Szellem jegyek",
|
||||
"Subjects": "Tantárgyaid",
|
||||
"Subjects_changes": "Tantárgyi változások",
|
||||
|
@ -248,11 +248,12 @@ class GradeGraphState extends State<GradeGraph> {
|
||||
),
|
||||
if (ghostData.isNotEmpty && ghostSpots.isNotEmpty)
|
||||
LineChartBarData(
|
||||
preventCurveOverShooting: true,
|
||||
preventCurveOverShooting: false,
|
||||
spots: ghostSpots,
|
||||
isCurved: true,
|
||||
colors: [AppColors.of(context).text],
|
||||
barWidth: 8,
|
||||
barWidth: 6,
|
||||
curveSmoothness: 0.2,
|
||||
isStrokeCapRound: true,
|
||||
dotData: FlDotData(show: false),
|
||||
belowBarData: BarAreaData(
|
||||
|
@ -3,6 +3,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:flutter/cupertino.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/theme/colors/colors.dart';
|
||||
import 'package:refilc/ui/date_widget.dart';
|
||||
@ -244,14 +245,34 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
||||
greeting,
|
||||
overflow: TextOverflow.fade,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18.0,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium
|
||||
?.color,
|
||||
),
|
||||
style:
|
||||
Provider.of<SettingsProvider>(context)
|
||||
.fontFamily !=
|
||||
'' &&
|
||||
Provider.of<SettingsProvider>(
|
||||
context)
|
||||
.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(
|
||||
DateFormat('EEEE, MMM d',
|
||||
@ -317,6 +338,7 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
||||
badge: updateProvider.available,
|
||||
role: user.role,
|
||||
profilePictureString: user.picture,
|
||||
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -355,7 +377,7 @@ class HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
||||
LiveCardState.duringLesson ||
|
||||
_liveCard.currentState ==
|
||||
LiveCardState.duringBreak)
|
||||
? 55.0
|
||||
? 62.0
|
||||
: 52.0),
|
||||
),
|
||||
child: Transform.scale(
|
||||
|
@ -404,7 +404,7 @@ class LiveCardStateA extends State<LiveCard> {
|
||||
swapRoom: true,
|
||||
currentLessonIndicator: false,
|
||||
padding:
|
||||
const EdgeInsets.only(top: 6.0, bottom: 4.0),
|
||||
const EdgeInsets.only(top: 2.0, bottom: 4.0),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
showSubTiles: false,
|
||||
),
|
||||
@ -911,6 +911,37 @@ class LiveCardStateA extends State<LiveCard> {
|
||||
Row(
|
||||
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(
|
||||
width: 10,
|
||||
),
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:google_fonts/google_fonts.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_kreta_api/providers/message_provider.dart';
|
||||
import 'package:refilc/api/providers/user_provider.dart';
|
||||
@ -109,6 +111,7 @@ class MessagesPageState extends State<MessagesPage>
|
||||
badge: updateProvider.available,
|
||||
role: user.role,
|
||||
profilePictureString: user.picture,
|
||||
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -128,10 +131,22 @@ class MessagesPageState extends State<MessagesPage>
|
||||
),
|
||||
Text(
|
||||
"Messages".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold),
|
||||
style: Provider.of<SettingsProvider>(context)
|
||||
.fontFamily !=
|
||||
'' &&
|
||||
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_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/self_note_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/ui/mobile/plus/premium_inline.dart';
|
||||
import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'notes_page.i18n.dart';
|
||||
|
||||
enum AbsenceFilter { absences, delays, misses }
|
||||
@ -65,9 +67,14 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
||||
|
||||
Map<String, bool> doneItems = {};
|
||||
List<Widget> noteTiles = [];
|
||||
List<TodoItem> todoItems = [];
|
||||
|
||||
final TextEditingController _taskName = TextEditingController();
|
||||
final TextEditingController _taskContent = TextEditingController();
|
||||
|
||||
void generateTiles() async {
|
||||
doneItems = await databaseProvider.userQuery.toDoItems(userId: user.id!);
|
||||
todoItems = await databaseProvider.userQuery.getTodoItems(userId: user.id!);
|
||||
|
||||
List<Widget> tiles = [];
|
||||
|
||||
@ -82,7 +89,7 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
||||
List<Widget> toDoTiles = [];
|
||||
|
||||
if (hw.isNotEmpty &&
|
||||
!Provider.of<PlusProvider>(context, listen: false)
|
||||
Provider.of<PlusProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.unlimitedSelfNotes)) {
|
||||
toDoTiles.addAll(hw.map((e) => TickTile(
|
||||
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) {
|
||||
tiles.add(const SizedBox(
|
||||
height: 10.0,
|
||||
@ -128,26 +150,31 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => NoteViewScreen(note: e))),
|
||||
)
|
||||
: Container(
|
||||
height: MediaQuery.of(context).size.width / 2.42,
|
||||
width: MediaQuery.of(context).size.width / 2.42,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
if (Provider.of<SettingsProvider>(context, listen: false)
|
||||
.shadowEffect)
|
||||
BoxShadow(
|
||||
offset: const Offset(0, 21),
|
||||
blurRadius: 23.0,
|
||||
color: Theme.of(context).shadowColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
child: Image.memory(
|
||||
const Base64Decoder().convert(e.content),
|
||||
fit: BoxFit.cover,
|
||||
gaplessPlayback: true,
|
||||
: GestureDetector(
|
||||
onTap: () => Navigator.of(context, rootNavigator: true).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => NoteViewScreen(note: e))),
|
||||
child: Container(
|
||||
height: MediaQuery.of(context).size.width / 2.42,
|
||||
width: MediaQuery.of(context).size.width / 2.42,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [
|
||||
if (Provider.of<SettingsProvider>(context, listen: false)
|
||||
.shadowEffect)
|
||||
BoxShadow(
|
||||
offset: const Offset(0, 21),
|
||||
blurRadius: 23.0,
|
||||
color: Theme.of(context).shadowColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
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,
|
||||
role: user.role,
|
||||
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),
|
||||
child: Text(
|
||||
"notes".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold),
|
||||
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
||||
'' &&
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -313,6 +351,8 @@ class NotesPageState extends State<NotesPage> with TickerProviderStateMixin {
|
||||
.fetch(
|
||||
from: DateTime.now().subtract(const Duration(days: 30)));
|
||||
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||
Provider.of<SelfNoteProvider>(context, listen: false)
|
||||
.restoreTodo();
|
||||
|
||||
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...",
|
||||
"your_notes": "Your Notes",
|
||||
"new_image": "New Image",
|
||||
"no_title": "No title",
|
||||
"task_content": "Task content...",
|
||||
"task_name": "Task title...",
|
||||
"new_task": "New Task",
|
||||
},
|
||||
"hu_hu": {
|
||||
"notes": "Füzet",
|
||||
@ -26,6 +30,10 @@ extension ScreensLocalization on String {
|
||||
"hint_t": "Jegyzet címe...",
|
||||
"your_notes": "Jegyzeteid",
|
||||
"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": {
|
||||
"notes": "Broschüre",
|
||||
@ -38,6 +46,10 @@ extension ScreensLocalization on String {
|
||||
"hint_t": "Titel notieren...",
|
||||
"your_notes": "Deine Noten",
|
||||
"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),
|
||||
),
|
||||
),
|
||||
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/services.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:image_crop/image_crop.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -27,6 +28,8 @@ class ImageNoteEditor extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
||||
final _title = TextEditingController();
|
||||
|
||||
final cropKey = GlobalKey<CropState>();
|
||||
File? _file;
|
||||
File? _sample;
|
||||
@ -62,7 +65,7 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
||||
child: Crop.file(
|
||||
_sample!,
|
||||
key: cropKey,
|
||||
aspectRatio: 1.0,
|
||||
// aspectRatio: 1.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -135,7 +138,8 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
||||
selfNotes.add(SelfNote.fromJson({
|
||||
'id': const Uuid().v4(),
|
||||
'content': base64Image,
|
||||
'note_type': 'image'
|
||||
'note_type': 'image',
|
||||
'title': _title.text,
|
||||
}));
|
||||
|
||||
await Provider.of<DatabaseProvider>(context, listen: false)
|
||||
@ -143,6 +147,7 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
||||
.storeSelfNotes(selfNotes, userId: widget.u.id);
|
||||
|
||||
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||
Provider.of<SelfNoteProvider>(context, listen: false).restoreTodo();
|
||||
|
||||
debugPrint('$file');
|
||||
}
|
||||
@ -170,6 +175,37 @@ class _ImageNoteEditorState extends State<ImageNoteEditor> {
|
||||
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
|
||||
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 != "")
|
||||
// TextButton(
|
||||
// child: Text(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:refilc/api/providers/self_note_provider.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:provider/provider.dart';
|
||||
import 'package:markdown/markdown.dart' as md;
|
||||
import 'notes_screen.i18n.dart';
|
||||
|
||||
class NoteViewScreen extends StatefulWidget {
|
||||
const NoteViewScreen({super.key, required this.note});
|
||||
@ -30,7 +33,9 @@ class NoteViewScreenState extends State<NoteViewScreen> {
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
leading: BackButton(color: AppColors.of(context).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(
|
||||
color: AppColors.of(context).text,
|
||||
fontSize: 26.0,
|
||||
@ -38,52 +43,55 @@ class NoteViewScreenState extends State<NoteViewScreen> {
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.1),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// handle tap
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
AddNoteScreen(initialNote: widget.note)));
|
||||
},
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.secondary.withOpacity(0.2),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Stack(
|
||||
children: [
|
||||
IconTheme(
|
||||
data: IconThemeData(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
if (widget.note.noteType == NoteType.text)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.1),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// handle tap
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
AddNoteScreen(initialNote: widget.note)));
|
||||
},
|
||||
child: Container(
|
||||
color:
|
||||
Theme.of(context).colorScheme.secondary.withOpacity(0.2),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Stack(
|
||||
children: [
|
||||
IconTheme(
|
||||
data: IconThemeData(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
child: const Icon(
|
||||
FeatherIcons.edit,
|
||||
size: 20.0,
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
if (widget.note.noteType == NoteType.text)
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.1),
|
||||
child: GestureDetector(
|
||||
@ -140,21 +148,30 @@ class NoteViewScreenState extends State<NoteViewScreen> {
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: MarkdownBody(
|
||||
data: widget.note.content,
|
||||
extensionSet: md.ExtensionSet(
|
||||
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
||||
<md.InlineSyntax>[
|
||||
md.EmojiSyntax(),
|
||||
...md.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
||||
],
|
||||
),
|
||||
styleSheet: MarkdownStyleSheet(
|
||||
p: const TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: widget.note.noteType == NoteType.text
|
||||
? MarkdownBody(
|
||||
data: widget.note.content,
|
||||
extensionSet: md.ExtensionSet(
|
||||
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
||||
<md.InlineSyntax>[
|
||||
md.EmojiSyntax(),
|
||||
...md.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
||||
],
|
||||
),
|
||||
styleSheet: MarkdownStyleSheet(
|
||||
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(
|
||||
// child: Text(
|
||||
|
@ -268,6 +268,7 @@ class NotesScreenState extends State<NotesScreen> {
|
||||
Provider.of<HomeworkProvider>(context, listen: false)
|
||||
.fetch(from: DateTime.now().subtract(const Duration(days: 30)));
|
||||
Provider.of<SelfNoteProvider>(context, listen: false).restore();
|
||||
Provider.of<SelfNoteProvider>(context, listen: false).restoreTodo();
|
||||
|
||||
return Future(() => null);
|
||||
},
|
||||
|
@ -18,6 +18,8 @@ extension SettingsLocalization on String {
|
||||
"click_here": "Click here",
|
||||
"select_image": "to select an image",
|
||||
"new_image": "New Image",
|
||||
"image_note": "Image",
|
||||
"title": "Image title...",
|
||||
},
|
||||
"hu_hu": {
|
||||
"notes": "Füzet",
|
||||
@ -34,6 +36,8 @@ extension SettingsLocalization on String {
|
||||
"click_here": "Kattints ide",
|
||||
"select_image": "kép kiválasztásához",
|
||||
"new_image": "Új kép",
|
||||
"image_note": "Kép",
|
||||
"title": "Kép címe...",
|
||||
},
|
||||
"de_de": {
|
||||
"notes": "Broschüre",
|
||||
@ -50,6 +54,8 @@ extension SettingsLocalization on String {
|
||||
"click_here": "Klicken Sie hier",
|
||||
"select_image": "um ein Bild auszuwählen",
|
||||
"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:flutter/material.dart';
|
||||
import 'package:refilc/utils/format.dart';
|
||||
@ -50,11 +53,26 @@ class _DayTitleState extends State<DayTitle> {
|
||||
width: MediaQuery.of(context).size.width / 1.5,
|
||||
child: Text(
|
||||
widget.dayTitle(index).capital(),
|
||||
style: TextStyle(
|
||||
color:
|
||||
AppColors.of(context).text.withOpacity(opacity),
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold),
|
||||
style: Provider.of<SettingsProvider>(context)
|
||||
.fontFamily !=
|
||||
'' &&
|
||||
Provider.of<SettingsProvider>(context)
|
||||
.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 'package:animations/animations.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:i18n_extension/i18n_extension.dart';
|
||||
import 'package:refilc/api/providers/database_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_image.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_mobile_ui/common/widgets/lesson/lesson_viewable.dart';
|
||||
import 'package:refilc_mobile_ui/pages/timetable/day_title.dart';
|
||||
@ -60,7 +61,11 @@ class TimetablePage extends StatefulWidget {
|
||||
NavigationScreen.of(context)?.setPage("timetable");
|
||||
|
||||
// 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
|
||||
@ -316,6 +321,7 @@ class TimetablePageState extends State<TimetablePage>
|
||||
badge: updateProvider.available,
|
||||
role: user.role,
|
||||
profilePictureString: user.picture,
|
||||
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -374,11 +380,25 @@ class TimetablePageState extends State<TimetablePage>
|
||||
} else {
|
||||
return Text(
|
||||
"timetable".i18n,
|
||||
style: TextStyle(
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColors.of(context).text,
|
||||
),
|
||||
style: Provider.of<SettingsProvider>(context)
|
||||
.fontFamily !=
|
||||
'' &&
|
||||
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:provider/provider.dart';
|
||||
import 'package:refilc/models/settings.dart';
|
||||
import 'package:refilc_plus/providers/plus_provider.dart';
|
||||
import 'package:refilc_plus/ui/mobile/plus/activation_view/activation_view.dart';
|
||||
import 'package:refilc_mobile_ui/plus/plus_screen.i18n.dart';
|
||||
@ -50,6 +51,20 @@ class PlusPlanCard extends StatelessWidget {
|
||||
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 (!active) {
|
||||
launchUrl(
|
||||
|
@ -225,6 +225,7 @@ class PlusScreenState extends State<PlusScreen> {
|
||||
['🎓', 'rfp_6'.i18n],
|
||||
['👕', 'rfp_14'.i18n],
|
||||
['👑', 'rfp_15'.i18n],
|
||||
['📩', 'rfp_17'.i18n],
|
||||
['🔜', 'more_soon'.i18n],
|
||||
],
|
||||
docsAccepted: docsAccepted,
|
||||
|
@ -45,6 +45,7 @@ extension SettingsLocalization on String {
|
||||
"rfp_14": "Discount in reFilc Shop (soon)",
|
||||
"rfp_15": "Subscriber role in our Discord community",
|
||||
"rfp_16": "Private leaks and informations about upcoming features",
|
||||
"rfp_17": "Grade exporting",
|
||||
// other
|
||||
"and": " and ",
|
||||
"every": "Every ",
|
||||
@ -96,6 +97,7 @@ extension SettingsLocalization on String {
|
||||
"rfp_14": "Kedvezmény a reFilc Shop-ban (hamarosan)",
|
||||
"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_17": "Jegy exportálás",
|
||||
// other
|
||||
"and": " és ",
|
||||
"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",
|
||||
"active": "Aktiv",
|
||||
// benefits
|
||||
"rfp_1": "Előzetes hozzáférés új verziókhoz",
|
||||
"rfp_2": "2 fiók használata egyszerre",
|
||||
"rfp_3": "Egyedi üdvözlő üzenet",
|
||||
"rfp_4": "Korlátlan saját jegyzet és feladat a füzet oldalon",
|
||||
"rfp_5": "Egyedi jegy ritkaságok",
|
||||
"rfp_6": "Összesített átlagszámoló",
|
||||
"rfp_7": "Órarend jegyzetek",
|
||||
"rfp_8": "Egyedi betütípusok",
|
||||
"rfp_9": "Korlátlan fiók használata egyszerre",
|
||||
"rfp_10": "Alkalmazás ikonjának megváltoztatása (v5.1-től)",
|
||||
"rfp_11": "Live Activity szín",
|
||||
"rfp_12": "Fejlettebb cél kitűzés",
|
||||
"rfp_13": "Naptár szinkronizálás",
|
||||
"rfp_14": "Kedvezmény a reFilc Shop-ban (hamarosan)",
|
||||
"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_1": "Frühzeitiger Zugriff auf Updates",
|
||||
"rfp_2": "Verwendung von zwei Konten gleichzeitig",
|
||||
"rfp_3": "Individuelle Begrüßungsnachricht",
|
||||
"rfp_4":
|
||||
"Unbegrenzte eigene Notizen und Aufgaben auf der Notizbuchseite",
|
||||
"rfp_5": "Individuelle Notenraritäten",
|
||||
"rfp_6": "Gesamtdurchschnittsberechner",
|
||||
"rfp_7": "Stundenplan-Notizen",
|
||||
"rfp_8": "Individuelle Schriftarten",
|
||||
"rfp_9": "Unbegrenzte Konten",
|
||||
"rfp_10": "Anpassung des App-Symbols (ab v5.1)",
|
||||
"rfp_11": "Änderung der Live-Aktivitätsfarbe",
|
||||
"rfp_12": "Verbesserter Zielplaner",
|
||||
"rfp_13": "Importieren Sie Ihren Stundenplan in Ihre Kalender-App",
|
||||
"rfp_14": "Rabatt im reFilc Shop (bald)",
|
||||
"rfp_15": "Abonnentenrolle in unserer Discord-Community",
|
||||
"rfp_16": "Private Leaks und Informationen über kommende Funktionen",
|
||||
"rfp_17": "Notenexport",
|
||||
// other
|
||||
"and": " és ",
|
||||
"every": "Minden ",
|
||||
"benefit": " előny",
|
||||
"and": " und ",
|
||||
"every": "Jeder ",
|
||||
"benefit": " Vorteil",
|
||||
"show_lifetime": "Für immer Pakete",
|
||||
"more_soon": "Mehr folgt bald...",
|
||||
"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",
|
||||
},
|
||||
};
|
||||
|
179
refilc_mobile_ui/lib/screens/login/kreten_login.dart
Normal file
179
refilc_mobile_ui/lib/screens/login/kreten_login.dart
Normal file
@ -0,0 +1,179 @@
|
||||
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) {
|
||||
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,13 @@ class AccountView extends StatelessWidget {
|
||||
Detail(
|
||||
title: "parents".plural(user.student.parents.length),
|
||||
description: user.student.parents.join(", ")),
|
||||
const SizedBox(
|
||||
height: 10.0,
|
||||
),
|
||||
// Detail(
|
||||
// title: "parents".i18n,
|
||||
// description: user.student.parents.join(", ")),
|
||||
Detail(title: "school".i18n, description: user.student.school.name),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -9,6 +9,7 @@ extension Localization on String {
|
||||
"class": "Class",
|
||||
"address": "Home address",
|
||||
"parents": "Parents".one("Parent"),
|
||||
"parents_phone": "Parents' phone number: ".one("Parent"),
|
||||
},
|
||||
"hu_hu": {
|
||||
"birthdate": "Születési dátum",
|
||||
|
@ -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/utils/format.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/providers/plus_provider.dart';
|
||||
// import 'package:refilc_plus/ui/mobile/plus/upsell.dart';
|
||||
@ -900,6 +903,15 @@ class _LiveActivityColorSettingState extends State<LiveActivityColorSetting> {
|
||||
allowShades: false,
|
||||
selectedColor: settings.liveActivityColor,
|
||||
onMainColorChange: (k) {
|
||||
if (!Provider.of<PlusProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.liveActivityColor)) {
|
||||
PlusLockedFeaturePopup.show(
|
||||
context: context,
|
||||
feature: PremiumFeature.liveActivity,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
currentColor = k as Color;
|
||||
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_button.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/splitted_panel/splitted_panel.dart';
|
||||
// import 'package:refilc_mobile_ui/common/system_chrome.dart';
|
||||
@ -320,6 +321,7 @@ class SettingsScreenState extends State<SettingsScreen>
|
||||
badge: updateProvider.available,
|
||||
role: user.role,
|
||||
profilePictureString: user.picture,
|
||||
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.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
|
||||
const PlusSettingsInline(),
|
||||
|
||||
|
@ -116,6 +116,14 @@ extension SettingsLocalization on String {
|
||||
"exp_settings": "Export Settings",
|
||||
"manage_subs": "Manage Subscription",
|
||||
"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": {
|
||||
"personal_details": "Személyes információk",
|
||||
@ -230,6 +238,14 @@ extension SettingsLocalization on String {
|
||||
"exp_settings": "Beállítások exportálása",
|
||||
"manage_subs": "Előfizetés kezelése",
|
||||
"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": {
|
||||
"personal_details": "Persönliche Angaben",
|
||||
@ -344,6 +360,14 @@ extension SettingsLocalization on String {
|
||||
"exp_settings": "Einstellungen exportieren",
|
||||
"manage_subs": "Abonnement verwalten",
|
||||
"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:provider/provider.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/providers/plus_provider.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),
|
||||
),
|
||||
],
|
||||
),
|
||||
SplittedPanel(
|
||||
padding: const EdgeInsets.only(top: 9.0),
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
|
381
refilc_mobile_ui/lib/screens/settings/submenu/grade_colors.dart
Normal file
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:provider/provider.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';
|
||||
|
||||
class MenuPaintList extends StatelessWidget {
|
||||
@ -251,18 +252,7 @@ class PaintListScreenState extends State<PaintListScreen>
|
||||
subject: 'share_subj_theme'.i18n,
|
||||
);
|
||||
} else {
|
||||
SharedGradeColors gradeColors = await shareProvider
|
||||
.shareCurrentGradeColors(context);
|
||||
SharedTheme theme =
|
||||
await shareProvider.shareCurrentTheme(
|
||||
context,
|
||||
gradeColors: gradeColors,
|
||||
);
|
||||
|
||||
Share.share(
|
||||
theme.id,
|
||||
subject: 'share_subj_theme'.i18n,
|
||||
);
|
||||
ShareThemeDialog.show(context);
|
||||
}
|
||||
},
|
||||
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:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'grade_colors.dart';
|
||||
|
||||
class MenuPersonalizeSettings extends StatelessWidget {
|
||||
const MenuPersonalizeSettings({
|
||||
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
|
||||
// SplittedPanel(
|
||||
// padding: const EdgeInsets.only(top: 9.0),
|
||||
@ -499,8 +544,14 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () {
|
||||
SettingsHelper.gradeColors(context);
|
||||
setState(() {});
|
||||
// SettingsHelper.gradeColors(context);
|
||||
// setState(() {});
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
const GradeColorsSettingsScreen(),
|
||||
),
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
"grade_colors".i18n,
|
||||
@ -670,16 +721,6 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () {
|
||||
if (!Provider.of<PlusProvider>(context,
|
||||
listen: false)
|
||||
.hasScope(PremiumScopes.liveActivityColor)) {
|
||||
PlusLockedFeaturePopup.show(
|
||||
context: context,
|
||||
feature: PremiumFeature.liveActivity,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
SettingsHelper.liveActivityColor(context);
|
||||
setState(() {});
|
||||
},
|
||||
@ -882,7 +923,7 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
||||
title: Text('fonts'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
isSeparated: true,
|
||||
isSeparated: false,
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () {
|
||||
@ -920,11 +961,72 @@ class PersonalizeSettingsScreenState extends State<PersonalizeSettingsScreen>
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
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 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",
|
||||
"epic": "Epic",
|
||||
"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": {
|
||||
"general": "Általános",
|
||||
@ -32,6 +43,17 @@ extension SettingsLocalization on String {
|
||||
"rare": "Ritka",
|
||||
"epic": "Epikus",
|
||||
"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": {
|
||||
"general": "Allgemeine",
|
||||
@ -47,6 +69,17 @@ extension SettingsLocalization on String {
|
||||
"rare": "Selten",
|
||||
"epic": "Episch",
|
||||
"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
|
||||
|
||||
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/colors.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/homework.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/panel/panel.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_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:refilc_mobile_ui/screens/settings/submenu/share_theme_popup.dart';
|
||||
import 'theme_screen.i18n.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
@ -44,6 +45,7 @@ enum CustomColorMode {
|
||||
text,
|
||||
icon,
|
||||
enterId,
|
||||
grade,
|
||||
}
|
||||
|
||||
class _PremiumCustomAccentColorSettingState
|
||||
@ -158,6 +160,9 @@ class _PremiumCustomAccentColorSettingState
|
||||
case CustomColorMode.enterId:
|
||||
// do nothing here lol
|
||||
break;
|
||||
case CustomColorMode.grade:
|
||||
// do nothing here as well
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,6 +223,9 @@ class _PremiumCustomAccentColorSettingState
|
||||
settings.update(customAccentColor: accent, store: store);
|
||||
settings.update(customIconColor: icon, store: store);
|
||||
break;
|
||||
case CustomColorMode.grade:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,40 +305,48 @@ class _PremiumCustomAccentColorSettingState
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
child: 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) => WillPopScope(
|
||||
// onWillPop: () async => false,
|
||||
// child: 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();
|
||||
|
||||
SharedGradeColors gradeColors =
|
||||
await shareProvider
|
||||
.shareCurrentGradeColors(context);
|
||||
SharedTheme theme =
|
||||
await shareProvider.shareCurrentTheme(
|
||||
context,
|
||||
gradeColors: gradeColors,
|
||||
);
|
||||
// SharedGradeColors gradeColors =
|
||||
// await shareProvider
|
||||
// .shareCurrentGradeColors(context);
|
||||
// SharedTheme theme =
|
||||
// await shareProvider.shareCurrentTheme(
|
||||
// context,
|
||||
// gradeColors: gradeColors,
|
||||
// );
|
||||
|
||||
Share.share(
|
||||
theme.id,
|
||||
subject: 'share_subj_theme'.i18n,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
// Share.share(
|
||||
// theme.id,
|
||||
// subject: 'share_subj_theme'.i18n,
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
if (settings.currentThemeId != '') {
|
||||
Share.share(
|
||||
settings.currentThemeId,
|
||||
subject: 'share_subj_theme'.i18n,
|
||||
);
|
||||
} else {
|
||||
ShareThemeDialog.show(context);
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
FeatherIcons.share2,
|
||||
|
@ -71,6 +71,7 @@ dependencies:
|
||||
markdown: ^7.2.2
|
||||
carousel_slider: ^4.2.1
|
||||
flutter_portal: ^1.1.4
|
||||
webview_flutter: ^4.8.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^3.0.1
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 1f5cca7b8e2ac896155a6c494e79fb057628379e
|
||||
Subproject commit 9bd46b81f230cd094787e1436cd5e8cdee7b5529
|
Loading…
x
Reference in New Issue
Block a user