made v0.9 release, added: show/hide button on sign in (password), made parent accounts work (when a user is a parent, the data that is shown corresponds to the first child in alphabetical order -> maybe this should get fixed if a parent has multiple children on the same school)

This commit is contained in:
Odweta
2024-02-17 20:37:17 +01:00
parent df41d4a285
commit 35fc8bc97a
18 changed files with 155 additions and 47 deletions
+1 -2
View File
@@ -12,7 +12,7 @@ android {
minSdk = 28 minSdk = 28
targetSdk = 34 targetSdk = 34
versionCode = 1 versionCode = 1
versionName = "0.8" versionName = "0.9"
} }
buildTypes { buildTypes {
@@ -47,5 +47,4 @@ dependencies {
implementation("androidx.viewpager2:viewpager2:1.0.0") implementation("androidx.viewpager2:viewpager2:1.0.0")
implementation("com.github.bumptech.glide:glide:4.16.0") implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("com.google.android.material:material:1.11.0") implementation("com.google.android.material:material:1.11.0")
implementation("com.github.bumptech.glide:glide:4.16.0")
} }
@@ -27,7 +27,9 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalTime import java.time.LocalTime
import java.time.MonthDay
import kotlin.math.floor import kotlin.math.floor
import kotlin.time.Duration.Companion.days
class CalWeekFragment : Fragment() { class CalWeekFragment : Fragment() {
override fun onCreateView( override fun onCreateView(
@@ -176,6 +178,14 @@ class DayFragment(private val i: Int) : Fragment() {
subjectStroke subjectStroke
) )
) )
} else if (i == day.subjects.size - 1) {
subjectDrawable.setStroke(
10,
ContextCompat.getColor(
requireContext(),
subjectStroke
)
)
} }
} else if ( } else if (
nowD == subjD && nowD == subjD &&
@@ -221,8 +231,8 @@ class DayFragment(private val i: Int) : Fragment() {
} }
requireView().postInvalidate() requireView().postInvalidate()
// repeat every 40 seconds // repeat every second
handler.postDelayed(this, 40000L) handler.postDelayed(this, 1000L)
} }
}, 0L) }, 0L)
} }
@@ -45,7 +45,6 @@ class Dialogs {
val okButton = getButton(BUTTON_POSITIVE) val okButton = getButton(BUTTON_POSITIVE)
okButton?.setTextColor(ContextCompat.getColor(context, R.color.white)) okButton?.setTextColor(ContextCompat.getColor(context, R.color.white))
val cancelButton = getButton(BUTTON_NEGATIVE) val cancelButton = getButton(BUTTON_NEGATIVE)
Log.d("debug", "$okButton $cancelButton")
cancelButton?.setTextColor(ContextCompat.getColor(context, R.color.white)) cancelButton?.setTextColor(ContextCompat.getColor(context, R.color.white))
} }
} }
@@ -1,6 +1,7 @@
package com.odweta.solon package com.odweta.solon
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -38,6 +39,12 @@ class MainFragment : Fragment() {
private fun setup(view: View) { private fun setup(view: View) {
toolbar = view.findViewById(R.id.toolbar) toolbar = view.findViewById(R.id.toolbar)
role = if (Parsing.userIsParent()) {
" - Rodič"
} else {
" - Student"
}
if ( if (
Util.fileToString(Vars.userDataFilePath) != "" && Util.fileToString(Vars.userDataFilePath) != "" &&
JSONObject(Util.fileToString(Vars.userDataFilePath)).has("fullName") JSONObject(Util.fileToString(Vars.userDataFilePath)).has("fullName")
@@ -157,7 +157,7 @@ class MarkDetailsFragment(private val marks: MutableList<Mark>, private var idx:
val dateDesc = makeTV("Datum:", Typeface.BOLD, Util.getDisplayWidth(requireContext())/3) val dateDesc = makeTV("Datum:", Typeface.BOLD, Util.getDisplayWidth(requireContext())/3)
val dateTV = makeTV(getDate(marks[idx!!].date), Typeface.NORMAL, 22f) val dateTV = makeTV(getDate(marks[idx!!].date), Typeface.NORMAL, 22f)
val weightDesc = makeTV("Váha:", Typeface.BOLD, Util.getDisplayWidth(requireContext())/3) val weightDesc = makeTV("Váha:", Typeface.BOLD, Util.getDisplayWidth(requireContext())/3)
val weightTV = makeTV(marks[idx!!].weight, Typeface.NORMAL, 22f) val weightTV = makeTV((marks[idx!!].weight).replace(".", ","), Typeface.NORMAL, 22f)
val subjectRow = makeRow(subjectDesc, subjectTV) val subjectRow = makeRow(subjectDesc, subjectTV)
val descRow = makeRow(descDesc, descTV) val descRow = makeRow(descDesc, descTV)
@@ -178,7 +178,7 @@ class MarksFragment : Fragment() {
avgTextView.typeface = customFont avgTextView.typeface = customFont
val text = if (!marks.contains(Mark().none())) { val text = if (!marks.contains(Mark().none())) {
Util.avg(marks) Util.avg(marks).replace(".", ",")
} else { } else {
"-" "-"
} }
@@ -152,7 +152,7 @@ class MarksOneSubjectFragment(private val marks: MutableList<Mark>) : DialogFrag
subjectDetailsLL.addView(wholeNameTV) subjectDetailsLL.addView(wholeNameTV)
val avgTV = TextView(requireContext()) val avgTV = TextView(requireContext())
avgTV.text = "${Util.avg(marks)} " // plus a space for the italic stuff avgTV.text = "${Util.avg(marks).replace(".", ",")} " // plus a space for the italic stuff
avgTV.textSize = 28f avgTV.textSize = 28f
avgTV.setTypeface(customFont, Typeface.BOLD_ITALIC) avgTV.setTypeface(customFont, Typeface.BOLD_ITALIC)
avgTV.textAlignment = View.TEXT_ALIGNMENT_TEXT_END avgTV.textAlignment = View.TEXT_ALIGNMENT_TEXT_END
@@ -24,14 +24,14 @@ class MenuFragment : Fragment() {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addCallbacks(view: View) { private fun addCallbacks(view: View) {
val settings = view.findViewById<Button>(R.id.menu_button_settings) //val settings = view.findViewById<Button>(R.id.menu_button_settings)
val signOut = view.findViewById<Button>(R.id.menu_button_sign_out) val signOut = view.findViewById<Button>(R.id.menu_button_sign_out)
val signIn = view.findViewById<Button>(R.id.menu_button_sign_in) val signIn = view.findViewById<Button>(R.id.menu_button_sign_in)
val about = view.findViewById<Button>(R.id.menu_button_about) val about = view.findViewById<Button>(R.id.menu_button_about)
settings.setOnClickListener { //settings.setOnClickListener {
SettingsFragment().show(requireFragmentManager(), "fragment_settings") // SettingsFragment().show(requireFragmentManager(), "fragment_settings")
} //}
signOut.setOnClickListener { signOut.setOnClickListener {
val builder: AlertDialog.Builder = AlertDialog.Builder(context, R.style.Theme_Solon_AlertDialog) val builder: AlertDialog.Builder = AlertDialog.Builder(context, R.style.Theme_Solon_AlertDialog)
@@ -1,5 +1,6 @@
package com.odweta.solon package com.odweta.solon
import android.util.Log
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.FormBody import okhttp3.FormBody
@@ -57,17 +58,35 @@ class Network {
Vars.userData = getUserDataJSON() Vars.userData = getUserDataJSON()
Util.saveStringToFile(Vars.userDataFilePath, Vars.userData) Util.saveStringToFile(Vars.userDataFilePath, Vars.userData)
Vars.studentId = getStudentId() Vars.studentId = getStudentId()
Vars.syid = getSYID() //Vars.syid = getSYID()
Vars.syid = ""
Vars.marksUrl = "${Vars.apiBaseUrl}/v1/students/${Vars.studentId}/marks/list?SemesterId=${Vars.syid}" Vars.marksUrl = "${Vars.apiBaseUrl}/v1/students/${Vars.studentId}/marks/list"//?SemesterId=${Vars.syid}"
Vars.isAPISetUp = true Vars.isAPISetUp = true
} }
} }
private fun getSYID(): String { /*private fun getSYID(): String {
val syidRoot = JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("schoolYearId") val f = Util.fileToString(Vars.userDataFilePath)
val toAdd = JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("studyYear")
lateinit var syidRoot: String
lateinit var toAdd: String
if (!Parsing.userIsParent()) {
syidRoot = JSONObject(f).getString("schoolYearId")
toAdd = JSONObject(f).getString("studyYear")
} else {
syidRoot = JSONObject(f)
.getJSONArray("children")
.getJSONObject(0)
.getString("schoolYearId")
toAdd = JSONObject(f)
.getJSONArray("children")
.getJSONObject(0)
.getString("studyYear")
}
val syidStart = syidRoot[0] val syidStart = syidRoot[0]
var syidNum = syidRoot.slice(1..<syidRoot.length).toInt() var syidNum = syidRoot.slice(1..<syidRoot.length).toInt()
@@ -76,11 +95,8 @@ class Network {
syidNum += 1 syidNum += 1
} }
// TODO: REMOVE LATER, JUST FOR DEBUG (NO MARKS IN THE CURRENT SEMESTER)
syidNum -= 1
return syidStart.toString() + syidNum.toString() return syidStart.toString() + syidNum.toString()
} }*/
private fun getStudentId(): String { private fun getStudentId(): String {
return if (!Parsing.userIsParent()) { return if (!Parsing.userIsParent()) {
@@ -1,5 +1,6 @@
package com.odweta.solon package com.odweta.solon
import android.util.Log
import org.json.JSONObject import org.json.JSONObject
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@@ -7,9 +8,11 @@ import java.time.format.DateTimeFormatter
class Parsing { class Parsing {
companion object { companion object {
fun userIsParent(): Boolean { fun userIsParent(): Boolean {
return if (Vars.userData != "") JSONObject(Vars.userData).get("userType") return if (Vars.userData != "") {
.toString() == "parent" JSONObject(Vars.userData).getString("userType") == "parent"
else false } else {
false
}
} }
fun parseTimeTableJSON(jsonString: String): List<Day> { fun parseTimeTableJSON(jsonString: String): List<Day> {
@@ -1,8 +1,11 @@
package com.odweta.solon package com.odweta.solon
import android.app.Dialog import android.app.Dialog
import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.text.InputType
import android.view.GestureDetector import android.view.GestureDetector
import android.view.Gravity
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
@@ -10,6 +13,14 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.Window import android.view.Window
import android.widget.Button import android.widget.Button
import android.widget.CompoundButton
import android.widget.EditText
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.ToggleButton
import androidx.core.content.res.ResourcesCompat
import com.google.android.material.textfield.TextInputEditText
import kotlin.math.abs import kotlin.math.abs
class SignInFragment : DialogFragment() { class SignInFragment : DialogFragment() {
@@ -57,6 +68,30 @@ class SignInFragment : DialogFragment() {
Vars.resetNav = true Vars.resetNav = true
MainActivity.callOnSignIn(view, false, dialog) MainActivity.callOnSignIn(view, false, dialog)
} }
// Find views
val passwordEditText = view.findViewById<EditText>(R.id.passwordField)
val showPasswordToggleButton = view.findViewById<ImageButton>(R.id.showPasswordToggleButton)
showPasswordToggleButton.bringToFront()
showPasswordToggleButton.background = ResourcesCompat.getDrawable(resources, R.drawable.hide, null)
// Set up toggle button to reveal/hide password
showPasswordToggleButton.setOnClickListener { _ ->
if (Vars.isChecked) {
// Show password
passwordEditText.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
showPasswordToggleButton.background = ResourcesCompat.getDrawable(resources, R.drawable.show, null)
Vars.isChecked = false
} else {
// Hide password
passwordEditText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
passwordEditText.typeface = context?.let { ResourcesCompat.getFont(it, R.font.roboto) }
showPasswordToggleButton.background = ResourcesCompat.getDrawable(resources, R.drawable.hide, null)
Vars.isChecked = true
}
// Move cursor to the end of the text
passwordEditText.setSelection(passwordEditText.text?.length ?: 0)
}
} }
inner class SwipeGestureListener : GestureDetector.SimpleOnGestureListener() { inner class SwipeGestureListener : GestureDetector.SimpleOnGestureListener() {
@@ -1,10 +1,14 @@
package com.odweta.solon package com.odweta.solon
import android.os.Bundle import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.EditText
import android.widget.ImageButton
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
class SignInMainFragment : Fragment() { class SignInMainFragment : Fragment() {
@@ -20,6 +24,30 @@ class SignInMainFragment : Fragment() {
MainActivity.callOnSignIn(view, true, null) MainActivity.callOnSignIn(view, true, null)
} }
// Find views
val passwordEditText = view.findViewById<EditText>(R.id.passwordField)
val showPasswordToggleButton = view.findViewById<ImageButton>(R.id.showPasswordToggleButton)
showPasswordToggleButton.bringToFront()
showPasswordToggleButton.background = ResourcesCompat.getDrawable(resources, R.drawable.hide, null)
// Set up toggle button to reveal/hide password
showPasswordToggleButton.setOnClickListener { _ ->
if (Vars.isChecked) {
// Show password
passwordEditText.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
showPasswordToggleButton.background = ResourcesCompat.getDrawable(resources, R.drawable.show, null)
Vars.isChecked = false
} else {
// Hide password
passwordEditText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
passwordEditText.typeface = context?.let { ResourcesCompat.getFont(it, R.font.roboto) }
showPasswordToggleButton.background = ResourcesCompat.getDrawable(resources, R.drawable.hide, null)
Vars.isChecked = true
}
// Move cursor to the end of the text
passwordEditText.setSelection(passwordEditText.text?.length ?: 0)
}
return view return view
} }
} }
@@ -37,6 +37,8 @@ class Vars {
var selectedDay: Int = 0 var selectedDay: Int = 0
var dayEndString: String = "" var dayEndString: String = ""
var isChecked: Boolean = true
const val apiBaseUrl = "https://aplikace.skolaonline.cz/solapi/api" const val apiBaseUrl = "https://aplikace.skolaonline.cz/solapi/api"
const val tokenUrl = "$apiBaseUrl/connect/token" const val tokenUrl = "$apiBaseUrl/connect/token"
var token: String = "" var token: String = ""
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

@@ -4,7 +4,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<Button <!--<Button
android:id="@+id/menu_button_settings" android:id="@+id/menu_button_settings"
android:layout_width="190dp" android:layout_width="190dp"
android:layout_height="80dp" android:layout_height="80dp"
@@ -17,28 +17,25 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497" app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />-->
<Button <Button
android:id="@+id/menu_button_sign_out" android:id="@+id/menu_button_sign_out"
android:layout_width="190dp" android:layout_width="190dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_marginBottom="50dp"
android:background="@drawable/button_background_selector" android:background="@drawable/button_background_selector"
android:text="@string/sign_out" android:text="@string/sign_out"
android:textSize="22sp" android:textSize="22sp"
app:cornerRadius="@dimen/corner_radius" app:cornerRadius="@dimen/corner_radius"
app:layout_constraintBottom_toTopOf="@+id/menu_button_sign_in" app:layout_constraintBottom_toTopOf="@+id/menu_button_sign_in"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/menu_button_settings" /> app:layout_constraintTop_toTopOf="parent" />
<Button <Button
android:id="@+id/menu_button_sign_in" android:id="@+id/menu_button_sign_in"
android:layout_width="190dp" android:layout_width="190dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_marginBottom="50dp"
android:background="@drawable/button_background_selector" android:background="@drawable/button_background_selector"
android:ellipsize="none" android:ellipsize="none"
android:scrollHorizontally="false" android:scrollHorizontally="false"
@@ -55,9 +52,6 @@
android:id="@+id/menu_button_about" android:id="@+id/menu_button_about"
android:layout_width="190dp" android:layout_width="190dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_marginStart="158dp"
android:layout_marginEnd="159dp"
android:layout_marginBottom="200dp"
android:background="@drawable/button_background_selector" android:background="@drawable/button_background_selector"
android:text="@string/about_app" android:text="@string/about_app"
android:textSize="22sp" android:textSize="22sp"
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true"> android:fillViewport="true">
@@ -52,22 +53,36 @@
android:theme="@style/sign_in_field" android:theme="@style/sign_in_field"
app:circularflow_radiusInDP="20dp" /> app:circularflow_radiusInDP="20dp" />
<EditText <LinearLayout
android:id="@+id/passwordField"
android:layout_width="240dp" android:layout_width="240dp"
android:layout_height="50dp" android:layout_height="50dp"
android:background="@drawable/button_background" android:orientation="horizontal"
android:ems="10" android:gravity="center_vertical"
android:hint="@string/password" android:background="@drawable/button_background">
android:importantForAutofill="no"
android:inputType="textPassword" <EditText
android:paddingHorizontal="20dp" android:id="@+id/passwordField"
android:textColor="@color/white" android:layout_width="190dp"
android:textColorHighlight="@color/white" android:layout_height="match_parent"
android:textColorHint="#C8FFFFFF" android:ems="10"
android:textColorLink="@color/white" android:background="@color/transparent"
android:textCursorDrawable="@drawable/cursor" android:hint="@string/password"
android:theme="@style/sign_in_field" /> android:importantForAutofill="no"
android:inputType="textPassword"
android:paddingHorizontal="20dp"
android:textColor="@color/white"
android:textColorHighlight="@color/white"
android:textColorHint="#C8FFFFFF"
android:textColorLink="@color/white"
android:textCursorDrawable="@drawable/cursor"
android:theme="@style/sign_in_field" />
<ImageButton
android:id="@+id/showPasswordToggleButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="20dp"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
<Button <Button
BIN
View File
Binary file not shown.