diff --git a/mobile/app/src/main/java/com/odweta/solen/AboutFragment.kt b/mobile/app/src/main/java/com/odweta/solen/AboutFragment.kt index af24acc..e3e8e3d 100644 --- a/mobile/app/src/main/java/com/odweta/solen/AboutFragment.kt +++ b/mobile/app/src/main/java/com/odweta/solen/AboutFragment.kt @@ -23,7 +23,7 @@ import androidx.fragment.app.DialogFragment class AboutFragment : DialogFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, R.style.Theme_Solen_PrimaryStatusBar) + setStyle(STYLE_NORMAL, R.style.Theme_Solen) } override fun onCreateView( diff --git a/mobile/app/src/main/java/com/odweta/solen/CalWeekFragment.kt b/mobile/app/src/main/java/com/odweta/solen/CalWeekFragment.kt index 85fec22..3b712bb 100644 --- a/mobile/app/src/main/java/com/odweta/solen/CalWeekFragment.kt +++ b/mobile/app/src/main/java/com/odweta/solen/CalWeekFragment.kt @@ -5,15 +5,14 @@ import android.content.res.Resources import android.graphics.Typeface import android.graphics.drawable.GradientDrawable import android.os.Bundle -import android.util.Log import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.ViewTreeObserver import android.widget.FrameLayout +import android.widget.ImageView import android.widget.LinearLayout -import android.widget.RelativeLayout import android.widget.ScrollView import android.widget.Space import android.widget.TextView @@ -40,7 +39,15 @@ class CalWeekFragment : Fragment() { adapter.addFragment(DayFragment(i)) } + viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + Vars.selectedDay = position + } + }) + viewPager.adapter = adapter + viewPager.currentItem = Vars.selectedDay return view } @@ -102,10 +109,41 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { rootLayout.addView(nameDateTextView) - for (subj in day.subjects) { + var prevSubj = Subject() + prevSubj.name = "" + prevSubj.place = "" + prevSubj.substitute = "" + prevSubj.teacher = "" + prevSubj.number = "" + prevSubj.start = "" + prevSubj.end = "" + prevSubj.free = false + + var firstDone = false + + for ((i, subj) in day.subjects.withIndex()) { val subjectBackground = when (subj.substitute) { "0" -> if (subj.place != "Volno") { - R.color.cal_week_subject + R.color.primary_transparent_bg + } else { + R.color.cal_week_free_transparent_bg + } + "1" -> if (subj.place != "Volno") { + R.color.cal_week_substitute_transparent_bg + } else { + R.color.cal_week_free_transparent_bg + } + "2" -> if (subj.place != "Volno") { + R.color.cal_week_event_transparent_bg + } else { + R.color.cal_week_free_transparent_bg + } + else -> R.color.primary_transparent_bg + } + + val subjectStroke = when (subj.substitute) { + "0" -> if (subj.place != "Volno") { + R.color.primary } else { R.color.cal_week_free } @@ -119,7 +157,7 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { } else { R.color.cal_week_free } - else -> R.color.cal_week_subject + else -> R.color.primary } val subjectDrawable = GradientDrawable() @@ -131,26 +169,34 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { requireContext(), subjectBackground ) - ) // Use your desired background color + ) + subjectDrawable.setStroke( + 10, + ContextCompat.getColor( + requireContext(), + subjectStroke + ) + ) val subjectLayout = LinearLayout(requireContext()) subjectLayout.orientation = LinearLayout.HORIZONTAL subjectLayout.gravity = Gravity.CENTER_VERTICAL subjectLayout.background = subjectDrawable - val subjectRelativeLayout = RelativeLayout(requireContext()) - subjectRelativeLayout.layoutParams = RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.MATCH_PARENT, - RelativeLayout.LayoutParams.MATCH_PARENT - ) - val subjectNumberDrawable = GradientDrawable() subjectNumberDrawable.shape = GradientDrawable.RECTANGLE - subjectNumberDrawable.cornerRadius = resources.getDimension((R.dimen.corner_radius)) + subjectNumberDrawable.cornerRadius = resources.getDimension(R.dimen.corner_radius) subjectNumberDrawable.setColor( ContextCompat.getColor( requireContext(), - R.color.cal_week_bg + subjectBackground + ) + ) + subjectNumberDrawable.setStroke( + 10, + ContextCompat.getColor( + requireContext(), + subjectStroke ) ) @@ -159,7 +205,7 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { subjectNumberTextView.text = subj.number subjectNumberTextView.textSize = 30f subjectNumberTextView.setPadding(20, 20, 20, 20) - subjectNumberTextView.gravity = Gravity.CENTER_VERTICAL // Center text vertically + subjectNumberTextView.gravity = Gravity.CENTER // Center text vertically subjectNumberTextView.setTextColor( ContextCompat.getColor( requireContext(), @@ -170,9 +216,10 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { val frameLayout = FrameLayout(requireContext()) val layoutParams = LinearLayout.LayoutParams( - FrameLayout.LayoutParams.WRAP_CONTENT, + 120, FrameLayout.LayoutParams.MATCH_PARENT, ) + frameLayout.foregroundGravity = Gravity.CENTER frameLayout.layoutParams = layoutParams frameLayout.addView(subjectNumberTextView) @@ -196,7 +243,7 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { subjectNameTextView.setTextColor( ContextCompat.getColor( requireContext(), - R.color.black + R.color.white ) ) @@ -211,17 +258,25 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { subjectPlaceTextView.text = subj.place if (subj.free) { // underline - subjectPlaceTextView.setTypeface(null, Typeface.ITALIC) + subjectPlaceTextView.setTypeface(customFont, Typeface.ITALIC) } subjectPlaceTextView.textSize = 22f subjectPlaceTextView.gravity = Gravity.CENTER_VERTICAL subjectPlaceTextView.setTextColor( ContextCompat.getColor( requireContext(), - R.color.black + R.color.white ) ) + if (subj.free) { + subjectPlaceTextView.layoutParams = + LinearLayout.LayoutParams( + 220, + LinearLayout.LayoutParams.MATCH_PARENT + ) + } + if (day.subjects[0].substitute != "2") { subjectLayout.addView(subjectPlaceTextView) } @@ -242,12 +297,12 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { subjectTimeTextView.typeface = customFont subjectTimeTextView.text = subjectTimeString subjectTimeTextView.textSize = 20f - subjectTimeTextView.setPadding(10, 10, 20, 10) + subjectTimeTextView.setPadding(10, 0, 20, 0) subjectTimeTextView.textAlignment = View.TEXT_ALIGNMENT_TEXT_END subjectTimeTextView.setTextColor( ContextCompat.getColor( requireContext(), - R.color.black + R.color.white ) ) @@ -255,30 +310,26 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { subjectTeacherTextView.text = subj.teacher subjectTeacherTextView.typeface = customFont subjectTeacherTextView.textSize = 15f - subjectTeacherTextView.setPadding(10, 10, 20, 10) + subjectTeacherTextView.setPadding(10, 0, 20, 10) subjectTeacherTextView.textAlignment = View.TEXT_ALIGNMENT_TEXT_END subjectTeacherTextView.setTextColor( ContextCompat.getColor( requireContext(), - R.color.black + R.color.white ) ) timeTeacherLayout.addView(subjectTimeTextView) if (subj.name != "Volno") { + subjectTimeTextView.setPadding(10, 10, 20, 0) timeTeacherLayout.addView(subjectTeacherTextView) } + timeTeacherLayout.setPadding(0, 0, 10, 0) if (day.subjects[0].substitute != "2") { subjectLayout.addView(timeTeacherLayout) } - val subjectSeparator = Space(requireContext()) - subjectSeparator.layoutParams = LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources - ) - // drawables val substituteDrawable = GradientDrawable() substituteDrawable.shape = GradientDrawable.RECTANGLE @@ -333,20 +384,54 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { ) subjectLayoutParams.setMargins(20, 0, 20, 0) subjectLayout.layoutParams = subjectLayoutParams + + if (prevSubj.name != subj.name && i != 0) { + val subjectSeparator = Space(requireContext()) + subjectSeparator.layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources + ) + + dayLayout.addView(subjectSeparator) + } else if (i != 0) { + val subjectSeparator = ImageView(requireContext()) + subjectSeparator.setImageResource(R.drawable.squiggly_line_100x100) + subjectSeparator.layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + Util.pixelsToDp(20, resources) + ) + + dayLayout.addView(subjectSeparator) + } + dayLayout.addView(subjectLayout) - dayLayout.addView(subjectSeparator) + + prevSubj = subj } + val subjectSeparator = Space(requireContext()) + subjectSeparator.layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) // Specify separator height in resources + ) + + dayLayout.addView(subjectSeparator) + val dayEndTextView = TextView(requireContext()) val endTime = day.subjects[day.subjects.size - 1].end - val dayEndString = "Den končí v $endTime" - dayEndTextView.text = dayEndString + Vars.dayEndString = "Den končí v $endTime" + dayEndTextView.text = Vars.dayEndString dayEndTextView.typeface = customFont dayEndTextView.textSize = 20f dayEndTextView.setPadding(0, 30, 0, 30) dayEndTextView.textAlignment = View.TEXT_ALIGNMENT_CENTER dayEndTextView.gravity = Gravity.CENTER - dayEndTextView.setTextColor(ContextCompat.getColor(requireContext(), R.color.white)) + dayEndTextView.setTextColor( + ContextCompat.getColor( + requireContext(), + R.color.white + ) + ) val dayEndDrawable = GradientDrawable() dayEndDrawable.shape = GradientDrawable.RECTANGLE @@ -354,7 +439,14 @@ class DayFragment(private val position: Int) : Fragment(R.layout.fragment_day) { dayEndDrawable.setColor( ContextCompat.getColor( requireContext(), - R.color.cal_week_bg + R.color.primary_transparent_bg + ) + ) + dayEndDrawable.setStroke( + 10, + ContextCompat.getColor( + requireContext(), + R.color.primary ) ) dayEndTextView.background = dayEndDrawable diff --git a/mobile/app/src/main/java/com/odweta/solen/Dialogs.kt b/mobile/app/src/main/java/com/odweta/solen/Dialogs.kt index 190282b..0d1b350 100644 --- a/mobile/app/src/main/java/com/odweta/solen/Dialogs.kt +++ b/mobile/app/src/main/java/com/odweta/solen/Dialogs.kt @@ -6,32 +6,6 @@ import android.view.LayoutInflater import androidx.fragment.app.DialogFragment class Dialogs { - class SignOut(context: Context) : AlertDialog(context) { - init { - // Initialize your dialog properties - setTitle("Opravdu se chcete odhlásit a ukončit aplikaci?") - //setMessage("Uložené přihlašovací údaje budou vymazány.") - setCancelable(true) // Set whether the dialog can be canceled by tapping outside - - // Set positive button (e.g., "OK" button) - setButton( - BUTTON_POSITIVE, - "Ano" - ) { _, _ -> - Account.clearAccountFile() - MainActivity.quit(context) - } - - // Set negative button (e.g., "Cancel" button) - setButton( - BUTTON_NEGATIVE, - "Ne" - ) { _, _ -> - dismiss() - } - } - } - class LanguageChange(context: Context) : AlertDialog(context) { init { // Initialize your dialog properties diff --git a/mobile/app/src/main/java/com/odweta/solen/MainActivity.kt b/mobile/app/src/main/java/com/odweta/solen/MainActivity.kt index 7b7234f..c2c501c 100644 --- a/mobile/app/src/main/java/com/odweta/solen/MainActivity.kt +++ b/mobile/app/src/main/java/com/odweta/solen/MainActivity.kt @@ -3,9 +3,11 @@ package com.odweta.solen import android.content.Context import android.content.Intent import android.os.Bundle +import android.util.Log import android.widget.Button import android.widget.EditText import android.widget.ImageView +import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat @@ -24,7 +26,7 @@ class MainActivity : AppCompatActivity() { private var toastShown: Boolean = false private var toast2Shown: Boolean = false private var done: Boolean = false - private lateinit var toolbar: androidx.appcompat.widget.Toolbar + private lateinit var toolbar: TextView private var role: String = " - Student" private lateinit var navbar: BottomNavigationView @@ -110,7 +112,7 @@ class MainActivity : AppCompatActivity() { } } else if (!Vars.internetAvail) { Vars.internetAvail = Util.internetAvail(applicationContext) - supportActionBar?.title = "Bez připojení k internetu." + toolbar.text = "Bez připojení k internetu." } else { Vars.internetAvail = Util.internetAvail(applicationContext) } @@ -123,13 +125,13 @@ class MainActivity : AppCompatActivity() { lifecycleScope.launch { done = false while (!done) { - supportActionBar?.title = "Načítání nových dat" + toolbar.text = "Načítání nových dat" delay(300) - supportActionBar?.title = "Načítání nových dat." + toolbar.text = "Načítání nových dat." delay(300) - supportActionBar?.title = "Načítání nových dat.." + toolbar.text = "Načítání nových dat.." delay(300) - supportActionBar?.title = "Načítání nových dat..." + toolbar.text = "Načítání nových dat..." delay(300) } @@ -139,7 +141,7 @@ class MainActivity : AppCompatActivity() { " - Student" } - supportActionBar?.title = + toolbar.text = JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("fullName") + role } @@ -191,9 +193,13 @@ class MainActivity : AppCompatActivity() { ) lifecycleScope.launch { - // check if the file is available offline, if yes, load the data and don't connect to the internet + // check if the file is available offline, + // if yes, load the data and don't connect to the internet Vars.internetAvail = Util.internetAvail(applicationContext) - Vars.timeTableAvailOffline = Util.fileExists(Vars.timeTableFilePath) && !Util.fileIsEmpty(Vars.timeTableFilePath) + Vars.timeTableAvailOffline = + Util.fileExists(Vars.timeTableFilePath) && !Util.fileIsEmpty(Vars.timeTableFilePath) + Vars.marksAvailOffline = + Util.fileExists(Vars.marksFilePath) && !Util.fileIsEmpty(Vars.marksFilePath) if (toastShown && Vars.internetAvail && !toast2Shown) { toast2Shown = true @@ -220,6 +226,20 @@ class MainActivity : AppCompatActivity() { // parse the data week = Parsing.parseTimeTableJSON(timeTableJSON) + // fetch and parse marks + lifecycleScope.launch { + Vars.marksJSON = """{"message": "Zatím žádné známky, zkuste aktualizovat data."}""" + + Vars.marksJSON = Network.getMarksJSON() + + //Log.d("MARKS_JSON", JSONObject(Vars.marksJSON).getJSONArray("subjects").toString()) + + Vars.marksAvailOffline = + Util.saveStringToFile(Vars.marksFilePath, Vars.marksJSON) + + Vars.marks = Parsing.parseMarksJSON(Vars.marksJSON) + } + // continue to launch phase 2 launchPhase2() } else { @@ -274,6 +294,12 @@ class MainActivity : AppCompatActivity() { // load the offline data val timeTableJSON = Util.fileToString(Vars.timeTableFilePath) + Vars.marksJSON = Util.fileToString(Vars.marksFilePath) + if (Vars.marksJSON == "") { + Vars.marksJSON = + """{"message": "Zatím žádné známky, zkuste aktualizovat data."}""" + } + // parse the data if (timeTableJSON != "") { // cancel a toast, if any @@ -284,6 +310,8 @@ class MainActivity : AppCompatActivity() { // parse the data week = Parsing.parseTimeTableJSON(timeTableJSON) + Vars.marks = Parsing.parseMarksJSON(Vars.marksJSON) + // continue launching launchPhase2() } else { @@ -311,12 +339,18 @@ class MainActivity : AppCompatActivity() { toolbar = findViewById(R.id.toolbar) - setSupportActionBar(toolbar) + if ( + Util.fileToString(Vars.userDataFilePath) != "" && + JSONObject(Util.fileToString(Vars.userDataFilePath)).has("fullName") + ) { + toolbar.text = + JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("fullName") + + role + } else { + toolbar.text = "Přihlašte se, prosím." + } - supportActionBar?.title = - JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("fullName") + role - - window.statusBarColor = ContextCompat.getColor(applicationContext, R.color.primary) + //window.statusBarColor = ContextCompat.getColor(applicationContext, R.color.primary) navbar = findViewById(R.id.bottomNav) diff --git a/mobile/app/src/main/java/com/odweta/solen/MarksFragment.kt b/mobile/app/src/main/java/com/odweta/solen/MarksFragment.kt index f1905e5..c33efef 100644 --- a/mobile/app/src/main/java/com/odweta/solen/MarksFragment.kt +++ b/mobile/app/src/main/java/com/odweta/solen/MarksFragment.kt @@ -1,24 +1,281 @@ package com.odweta.solen -import android.app.Dialog +import android.graphics.Typeface +import android.graphics.drawable.GradientDrawable import android.os.Bundle -import androidx.fragment.app.DialogFragment +import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.view.Window -import android.widget.Button -import android.widget.ImageView +import android.widget.FrameLayout +import android.widget.HorizontalScrollView +import android.widget.LinearLayout +import android.widget.Space +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch + +// TODO: MARK DETAILS class MarksFragment : Fragment() { - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.activity_marks, container, false) + val root = view.findViewById(R.id.root) + + if (Vars.marksAvailOffline && !Util.fileIsEmpty(Vars.marksFilePath)) { + Vars.marksJSON = Util.fileToString(Vars.marksFilePath) + Vars.marksAvailOffline = Util.saveStringToFile(Vars.marksFilePath, Vars.marksJSON) + Vars.marks = Parsing.parseMarksJSON(Vars.marksJSON) + } else { + lifecycleScope.launch { + Vars.marksJSON = Network.getMarksJSON() + Vars.marksAvailOffline = Util.saveStringToFile(Vars.marksFilePath, Vars.marksJSON) + Vars.marks = Parsing.parseMarksJSON(Vars.marksJSON) + } + } + + root.addView(createSpace()) + for (subject in Vars.marks.keys) { + root.addView(Vars.marks[subject]?.let { createMarkView(it) }) + root.addView(createSpace()) + } + return view } + + private fun createSpace(): Space { + val space = Space(requireContext()) + space.layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + resources.getDimensionPixelSize(R.dimen.cal_week_separator_height) + ) + + return space + } + + private fun avg(marks: MutableList): String { + var sum = 0f + var len = 0 + + for (mark in marks) { + len += 1 + sum += (mark.grade.toFloat() * mark.weight.toFloat()) + } + + val weights = mutableListOf() + + for (mark in marks) { + weights.add(mark.weight.toFloat()) + } + + return String.format("%.2f", (sum / sum(weights))).replace(',', '.') + } + + private fun sum(nums: List): Float { + var sum = 0f + for (num in nums) { + sum += num + } + + return sum + } + + private fun getAvgBgColor(avg: String): Int { + var color: Int = R.color.pastel_orange_transparent + + if (avg.toFloat() in 1f..<2f) { + color = R.color.pastel_green_transparent + } else if (avg.toFloat() in 2f..<3f) { + color = R.color.pastel_yellow_transparent + } else if (avg.toFloat() in 3f..<4f) { + color = R.color.pastel_orange_transparent + } else if (avg.toFloat() in 4f..5f) { + color = R.color.pastel_red_transparent + } + + return ContextCompat.getColor( + requireContext(), + color + ) + } + private fun getAvgStrokeColor(avg: String): Int { + var color: Int = R.color.pastel_orange + + if (avg.toFloat() in 1f..<2f) { + color = R.color.pastel_green + } else if (avg.toFloat() in 2f..<3f) { + color = R.color.pastel_yellow + } else if (avg.toFloat() in 3f..<4f) { + color = R.color.pastel_orange + } else if (avg.toFloat() in 4f..5f) { + color = R.color.pastel_red + } + + return ContextCompat.getColor( + requireContext(), + color + ) + } + + private fun createMarkView(marks: MutableList): LinearLayout { + val markRoot = LinearLayout(requireContext()) + markRoot.orientation = LinearLayout.HORIZONTAL + val params = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + params.setMargins(20, 0, 20, 0) + params.height = 210 + markRoot.layoutParams = params + + val customFont = context?.let { ResourcesCompat.getFont(it, R.font.roboto) } + + val markDrawable = GradientDrawable() + markDrawable.shape = GradientDrawable.RECTANGLE + markDrawable.cornerRadius = resources.getDimension(R.dimen.corner_radius) + markDrawable.setColor( + ContextCompat.getColor( + requireContext(), + R.color.primary_transparent_bg + ) + ) + markDrawable.setStroke( + 10, + ContextCompat.getColor( + requireContext(), + R.color.primary + ) + ) + markRoot.background = markDrawable + + val avgDrawable = GradientDrawable() + avgDrawable.shape = GradientDrawable.RECTANGLE + avgDrawable.cornerRadius = resources.getDimension(R.dimen.corner_radius) + avgDrawable.setColor( + if (!marks.contains(Mark().none())) { + getAvgBgColor(avg(marks)) + } else { + ContextCompat.getColor( + requireContext(), + R.color.pastel_orange_transparent + ) + } + ) + avgDrawable.setStroke( + 10, + if (!marks.contains(Mark().none())) { + getAvgStrokeColor(avg(marks)) + } else { + ContextCompat.getColor( + requireContext(), + R.color.pastel_orange + ) + } + ) + + val avgTextView = TextView(requireContext()) + avgTextView.typeface = customFont + + val text = if (!marks.contains(Mark().none())) { + avg(marks) + } else { + "-" + } + avgTextView.text = text + avgTextView.textSize = 30f + avgTextView.setPadding(20, 20, 20, 20) + avgTextView.gravity = Gravity.CENTER // Center text vertically + avgTextView.setTextColor( + ContextCompat.getColor( + requireContext(), + R.color.white + ) + ) + avgTextView.background = avgDrawable + + val frameLayout = FrameLayout(requireContext()) + val layoutParams = LinearLayout.LayoutParams( + 210, + FrameLayout.LayoutParams.MATCH_PARENT, + ) + frameLayout.layoutParams = layoutParams + frameLayout.addView(avgTextView) + + markRoot.addView(frameLayout) + + val nameAndMarksLayout = LinearLayout(requireContext()) + nameAndMarksLayout.orientation = LinearLayout.VERTICAL + nameAndMarksLayout.gravity = Gravity.START + + val subjectTextView = TextView(requireContext()) + subjectTextView.text = marks[0].subject.uppercase() + subjectTextView.setPadding(20, 15, 20, 0) + subjectTextView.textSize = 30f + subjectTextView.setTextColor( + ContextCompat.getColor( + requireContext(), + R.color.white + ) + ) + subjectTextView.setTypeface(customFont, Typeface.BOLD) + + nameAndMarksLayout.addView(subjectTextView) + + val marksTextView = TextView(requireContext()) + var markString = "" + for ((i, mark) in marks.withIndex()) { + markString += mark.grade + if (i < marks.size - 1) { + markString += ", " + } + } + marksTextView.text = markString + marksTextView.setPadding(20, -15, 20, 0) + marksTextView.textSize = 23f + marksTextView.setTextColor( + ContextCompat.getColor( + requireContext(), + R.color.white + ) + ) + + val marksScrollView = HorizontalScrollView(requireContext()) + marksScrollView.addView(marksTextView) + + nameAndMarksLayout.addView(marksScrollView) + + markRoot.addView(nameAndMarksLayout) + + return markRoot + } +} + +class Mark { + lateinit var grade: String // markText + lateinit var weight: String // weight + lateinit var subject: String // subjectId -> parse that + lateinit var date: String // markDate + lateinit var theme: String // theme + + override fun toString(): String { + return "mark: ${this.grade} * ${this.weight}, subject: ${this.subject}, description: ${this.theme}, date: ${this.date}" + } + + fun none(): Mark { + val mark = Mark() + mark.subject = "Zatím žádné známky." + mark.grade = "0" + mark.weight = "0" + mark.date = "-" + mark.theme = "-" + + return mark + } } diff --git a/mobile/app/src/main/java/com/odweta/solen/MenuFragment.kt b/mobile/app/src/main/java/com/odweta/solen/MenuFragment.kt index f6f4eda..621defb 100644 --- a/mobile/app/src/main/java/com/odweta/solen/MenuFragment.kt +++ b/mobile/app/src/main/java/com/odweta/solen/MenuFragment.kt @@ -19,8 +19,6 @@ class MenuFragment : Fragment() { ): View? { val view = inflater.inflate(R.layout.activity_menu, container, false) - - addCallbacks(view) return view diff --git a/mobile/app/src/main/java/com/odweta/solen/Network.kt b/mobile/app/src/main/java/com/odweta/solen/Network.kt index c1ce1dc..64ed87c 100644 --- a/mobile/app/src/main/java/com/odweta/solen/Network.kt +++ b/mobile/app/src/main/java/com/odweta/solen/Network.kt @@ -58,14 +58,40 @@ class Network { Vars.userData = getUserDataJSON() Util.saveStringToFile(Vars.userDataFilePath, Vars.userData) Vars.studentId = getStudentId() + Vars.syid = getSYID() + + //Log.d("SYID", Vars.syid) + + Vars.marksUrl = "${Vars.apiBaseUrl}/v1/students/${Vars.studentId}/marks/list?SemesterId=${Vars.syid}" + + Vars.isAPISetUp = true } } + fun getSYID(): String { + val syidRoot = JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("schoolYearId") + val toAdd = JSONObject(Util.fileToString(Vars.userDataFilePath)).getString("studyYear") + + val syidStart = syidRoot[0] + var syidNum = syidRoot.slice(1..> { + if (!JSONObject(jsonString).has("marks")) { + val noMarks = mutableMapOf>() + val list = mutableListOf() + list.add(Mark().none()) + noMarks["-"] = list + + return noMarks + } + + val marks = mutableMapOf>() + + val marksList = mutableListOf() + + val marksJSONArray = JSONObject(jsonString).getJSONArray("marks") + + val subjectsJSONArray = JSONObject(jsonString).getJSONArray("subjects") + val subjectMap = mutableMapOf() + + for (i in 0.. parse that + * lateinit var date: String // markDate + * lateinit var theme: String // theme + * } + */ + + for (markJSON in marksList) { + val mark = Mark() + + mark.grade = markJSON.getString("markText") + + mark.weight = markJSON.getString("weight") + + mark.subject = subjectMap[markJSON.getString("subjectId")].toString() + + mark.date = markJSON.getString("markDate") + + mark.theme = markJSON.getString("theme") + + marks[mark.subject]?.add(mark) + } + + return marks + } } } \ No newline at end of file diff --git a/mobile/app/src/main/java/com/odweta/solen/SettingsFragment.kt b/mobile/app/src/main/java/com/odweta/solen/SettingsFragment.kt index 5eb8e95..7aa318c 100644 --- a/mobile/app/src/main/java/com/odweta/solen/SettingsFragment.kt +++ b/mobile/app/src/main/java/com/odweta/solen/SettingsFragment.kt @@ -14,7 +14,7 @@ class SettingsFragment : DialogFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen) + setStyle(STYLE_NORMAL, R.style.Theme_Solen) } override fun onCreateView( diff --git a/mobile/app/src/main/java/com/odweta/solen/Util.kt b/mobile/app/src/main/java/com/odweta/solen/Util.kt index 898c102..8be3f73 100644 --- a/mobile/app/src/main/java/com/odweta/solen/Util.kt +++ b/mobile/app/src/main/java/com/odweta/solen/Util.kt @@ -1,6 +1,7 @@ package com.odweta.solen import android.content.Context +import android.content.res.Resources import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.util.DisplayMetrics @@ -109,5 +110,13 @@ class Util { return true } } + + fun pixelsToDp(pixels: Int, resources: Resources): Int { + return (pixels * resources.displayMetrics.density).toInt() + } + + fun dpToPixels(dp: Int, resources: Resources): Int { + return (dp / resources.displayMetrics.density).toInt() + } } } \ No newline at end of file diff --git a/mobile/app/src/main/java/com/odweta/solen/Vars.kt b/mobile/app/src/main/java/com/odweta/solen/Vars.kt index 074ea4e..0589cbf 100644 --- a/mobile/app/src/main/java/com/odweta/solen/Vars.kt +++ b/mobile/app/src/main/java/com/odweta/solen/Vars.kt @@ -1,5 +1,6 @@ package com.odweta.solen +import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import java.io.File @@ -8,30 +9,39 @@ class Vars { const val accountDataFilePath: String = "account_data.txt" const val timeTableFilePath: String = "timetable.json" const val userDataFilePath: String = "userdata.json" - //const val marksFilePath: String = "marks.json" - lateinit var fileDir: File + const val marksFilePath: String = "marks.json" + var fileDir: File = File("") var width: Int = 0 var height: Int = 0 var internetAvail: Boolean = false var timeTableAvailOffline: Boolean = false - //var marksAvailOffline: Boolean = false + var marksAvailOffline: Boolean = false val dayMap = mutableMapOf() var days = listOf() - lateinit var username: String - lateinit var password: String + var marksJSON: String = "" + var marks: MutableMap> = mutableMapOf() + + var username: String = "" + var password: String = "" val client = OkHttpClient() - private const val apiBaseUrl = "https://aplikace.skolaonline.cz/solapi/api" + var isAPISetUp: Boolean = false + + var selectedDay: Int = 0 + var dayEndString: String = "" + + const val apiBaseUrl = "https://aplikace.skolaonline.cz/solapi/api" const val tokenUrl = "$apiBaseUrl/connect/token" - lateinit var token: String + var token: String = "" const val userDataUrl = "$apiBaseUrl/v1/user" - lateinit var userData: String - lateinit var studentId: String + var userData: String = "" + var studentId: String = "" const val timeTableUrl = "$apiBaseUrl/v1/timeTable" - //val marksUrl = "$apiBaseUrl/v1/students/$studentId/marks/list" + var syid = "" // school year id + var marksUrl = "$apiBaseUrl/v1/students/$studentId/marks/list?SemesterId=$syid" } } \ No newline at end of file diff --git a/mobile/app/src/main/res/drawable/button_background.xml b/mobile/app/src/main/res/drawable/button_background.xml new file mode 100644 index 0000000..47662de --- /dev/null +++ b/mobile/app/src/main/res/drawable/button_background.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/mobile/app/src/main/res/drawable/squiggly_line_100x100.png b/mobile/app/src/main/res/drawable/squiggly_line_100x100.png new file mode 100644 index 0000000..e197cc3 Binary files /dev/null and b/mobile/app/src/main/res/drawable/squiggly_line_100x100.png differ diff --git a/mobile/app/src/main/res/drawable/squiggly_line_20x20.png b/mobile/app/src/main/res/drawable/squiggly_line_20x20.png new file mode 100644 index 0000000..9d9c14a Binary files /dev/null and b/mobile/app/src/main/res/drawable/squiggly_line_20x20.png differ diff --git a/mobile/app/src/main/res/layout/activity_about.xml b/mobile/app/src/main/res/layout/activity_about.xml index 9281739..04e7ee2 100644 --- a/mobile/app/src/main/res/layout/activity_about.xml +++ b/mobile/app/src/main/res/layout/activity_about.xml @@ -42,10 +42,10 @@ + app:layout_constraintVertical_bias="0.658" /> + + - - + app:layout_constraintVertical_bias="0.106" /> + + \ No newline at end of file diff --git a/mobile/app/src/main/res/layout/activity_cal_week.xml b/mobile/app/src/main/res/layout/activity_cal_week.xml index 798d127..6a3ecfd 100644 --- a/mobile/app/src/main/res/layout/activity_cal_week.xml +++ b/mobile/app/src/main/res/layout/activity_cal_week.xml @@ -12,9 +12,4 @@ android:id="@+id/dayPager" android:layout_width="match_parent" android:layout_height="match_parent" /> - - \ No newline at end of file diff --git a/mobile/app/src/main/res/layout/activity_loading_with_bar.xml b/mobile/app/src/main/res/layout/activity_loading_with_bar.xml deleted file mode 100644 index ff00cb3..0000000 --- a/mobile/app/src/main/res/layout/activity_loading_with_bar.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mobile/app/src/main/res/layout/activity_main.xml b/mobile/app/src/main/res/layout/activity_main.xml index 2988d57..113dd6a 100644 --- a/mobile/app/src/main/res/layout/activity_main.xml +++ b/mobile/app/src/main/res/layout/activity_main.xml @@ -8,46 +8,42 @@ tools:context=".MainActivity"> + android:id="@+id/toolbarFrame" + android:background="@color/black"> - - - - - - - - - - + android:layout_height="wrap_content" + android:background="@drawable/button_background" + android:gravity="center" + android:layout_marginTop="20dp" + android:layout_marginHorizontal="5dp" + android:padding="10dp" + android:textColor="@color/white" + android:textSize="25dp" /> + + + app:menu="@menu/menu_navbar" /> - \ No newline at end of file + diff --git a/mobile/app/src/main/res/layout/activity_marks.xml b/mobile/app/src/main/res/layout/activity_marks.xml index 0ef7f3c..c401717 100644 --- a/mobile/app/src/main/res/layout/activity_marks.xml +++ b/mobile/app/src/main/res/layout/activity_marks.xml @@ -6,21 +6,26 @@ android:layout_height="match_parent" android:background="@color/black"> - + app:layout_constraintTop_toTopOf="parent"> + + + + + + \ No newline at end of file diff --git a/mobile/app/src/main/res/layout/activity_menu.xml b/mobile/app/src/main/res/layout/activity_menu.xml index d9fb3ec..cfa89e2 100644 --- a/mobile/app/src/main/res/layout/activity_menu.xml +++ b/mobile/app/src/main/res/layout/activity_menu.xml @@ -9,52 +9,63 @@