reworked the way the timetable date is calculated

* cleaned up some timetable gui code
* close #33
This commit is contained in:
Jannik 2019-09-22 20:51:36 +02:00
parent 889c673c5d
commit 6e6c9f71a0
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
7 changed files with 146 additions and 160 deletions

View File

@ -7,13 +7,13 @@ apply plugin: 'kotlin-android-extensions'
android { android {
signingConfigs { signingConfigs {
} }
compileSdkVersion 28 compileSdkVersion 29
defaultConfig { defaultConfig {
applicationId "org.mosad.seil0.projectlaogai" applicationId "org.mosad.seil0.projectlaogai"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 28 targetSdkVersion 29
versionCode 14 versionCode 14
versionName "0.5.0" versionName "0.4.99"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "build_time", buildTime() resValue "string", "build_time", buildTime()
setProperty("archivesBaseName", "projectlaogai-$versionName") setProperty("archivesBaseName", "projectlaogai-$versionName")

View File

@ -30,19 +30,16 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.afollestad.materialdialogs.MaterialDialog
import kotlinx.android.synthetic.main.fragment_home.* import kotlinx.android.synthetic.main.fragment_home.*
import org.jetbrains.anko.doAsync import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread import org.jetbrains.anko.uiThread
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.mensaMenu import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.mensaMenu
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timetables import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timetables
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.Meal import org.mosad.seil0.projectlaogai.hsoparser.Meal
import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar
import org.mosad.seil0.projectlaogai.hsoparser.TimetableDay import org.mosad.seil0.projectlaogai.hsoparser.TimetableDay
import org.mosad.seil0.projectlaogai.uicomponents.DayCardView import org.mosad.seil0.projectlaogai.uicomponents.DayCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonLinearLayout
import org.mosad.seil0.projectlaogai.uicomponents.MealLinearLayout import org.mosad.seil0.projectlaogai.uicomponents.MealLinearLayout
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -53,7 +50,7 @@ import java.util.*
*/ */
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
private val className = "MyActivity" private val className = "HomeFragment"
private val formatter = SimpleDateFormat("E dd.MM", Locale.getDefault()) private val formatter = SimpleDateFormat("E dd.MM", Locale.getDefault())
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -80,10 +77,10 @@ class HomeFragment : Fragment() {
if (isAdded) { if (isAdded) {
if (cal.get(Calendar.HOUR_OF_DAY) < 15) { if (cal.get(Calendar.HOUR_OF_DAY) < 15) {
dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar().getDayOfWeekIndex()].meals dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar.getDayOfWeekIndex()].meals
mensaCardView.setDayHeading(activity!!.resources.getString(R.string.today_date, formatter.format(cal.time))) mensaCardView.setDayHeading(activity!!.resources.getString(R.string.today_date, formatter.format(cal.time)))
} else { } else {
dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar().getTomorrowWeekIndex()].meals dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar.getTomorrowWeekIndex()].meals
cal.add(Calendar.DATE, 1) cal.add(Calendar.DATE, 1)
mensaCardView.setDayHeading(activity!!.resources.getString(R.string.tomorrow_date, formatter.format(cal.time))) mensaCardView.setDayHeading(activity!!.resources.getString(R.string.tomorrow_date, formatter.format(cal.time)))
} }
@ -121,101 +118,52 @@ class HomeFragment : Fragment() {
* add the current timetable to the home screen * add the current timetable to the home screen
*/ */
private fun addTimeTable() = doAsync { private fun addTimeTable() = doAsync {
val dayIndex = NotRetardedCalendar().getDayOfWeekIndex()
val cal = Calendar.getInstance()
var dayCardView: DayCardView
uiThread { uiThread {
if (isAdded) { if (isAdded && timetables.isNotEmpty()) {
if (timetables.isNotEmpty() && dayIndex < 6) { try {
val dayCardView = findNextDay(NotRetardedCalendar.getDayOfWeekIndex())
// first check the current day
dayCardView = addDayTimetable(timetables[0].timetable.days[dayIndex])
dayCardView.setDayHeading(resources.getString(R.string.today_date, formatter.format(cal.time)))
// if there are no lessons try to find the next day with a lesson
if (dayCardView.getLinLayoutDay().childCount <= 1)
dayCardView = findNextDay(0, dayIndex + 1)
linLayout_Home.addView(dayCardView) linLayout_Home.addView(dayCardView)
} else if (dayIndex == 6) { } catch (ex: Exception) {
// if that's the case it's sunday Log.e(className, "could not load timetable", ex) // TODO send feedback
dayCardView = findNextDay(1, 0)
linLayout_Home.addView(dayCardView)
} else {
MaterialDialog(context!!)
.title(R.string.error)
.message(R.string.timetable_error)
.show()
Log.e(className, "could not load timetable") // TODO send feedback
} }
} }
} }
} }
/**
* add the timetable of one day to the home-screen
* @param dayTimetable the day you wish to add
*/
private fun addDayTimetable(dayTimetable: TimetableDay) : DayCardView{
var helpLesson = LessonLinearLayout(context)
val dayCardView = DayCardView(context!!)
for ((tsIndex, timeslot) in dayTimetable.timeslots.withIndex()) {
for(lesson in timeslot) {
if(lesson.lessonSubject.isNotEmpty()) {
val lessonLayout = LessonLinearLayout(context)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
if (lesson != timeslot.last()) {
lessonLayout.disableDivider()
}
helpLesson = lessonLayout
}
}
}
helpLesson.disableDivider()
return dayCardView
}
/** /**
* find the next day with a lesson * find the next day with a lesson
* @param startWeekIndex the week you want to start searching * start at week 0, startDayIndex and search every cached week until we find a) a day with a timetable
* or b) we find no timetable and add a no lesson card
* @param startDayIndex the day index you want to start searching * @param startDayIndex the day index you want to start searching
* @return a DayCardView with all lessons added * @return a DayCardView with all lessons added
*/ */
private fun findNextDay(startWeekIndex: Int, startDayIndex: Int) : DayCardView { private fun findNextDay(startDayIndex: Int) : DayCardView {
val cal = Calendar.getInstance() val dayCardView = DayCardView(context!!)
var dayCardView = DayCardView(context!!)
var dayTimetable: TimetableDay? = null var dayTimetable: TimetableDay? = null
var dayIndexSearch = startDayIndex var dayIndexSearch = startDayIndex
var weekIndexSearch = startWeekIndex var weekIndexSearch = 0
loop@ while (dayTimetable == null && weekIndexSearch <= timetables.size) { while (dayTimetable == null && weekIndexSearch < timetables.size) {
for (i in (dayIndexSearch) ..5) { for (dayIndex in dayIndexSearch..5) {
dayTimetable = timetables[weekIndexSearch].timetable.days[i] dayTimetable = timetables[weekIndexSearch].timetable.days[dayIndex]
cal.add(Calendar.DATE, 1)
// add the timetable to the card, if it contains at least one lesson break! // some wired calendar magic, calculate the correct date to be shown ((timetable week - current week * 7) + days of calendar week + 1)
dayCardView = addDayTimetable(dayTimetable) val daysToAdd = (timetables[weekIndexSearch].meta.weekNumberYear - NotRetardedCalendar.getWeekOfYear() - 1) * 7 + dayIndex +1
dayCardView.setDayHeading(formatter.format(cal.time)) dayCardView.addTimetableDay(dayTimetable, daysToAdd)
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1) if (dayCardView.getLinLayoutDay().childCount > 1)
return dayCardView return dayCardView
} }
dayIndexSearch = 0
weekIndexSearch++ weekIndexSearch++
cal.add(Calendar.DATE, 1) dayIndexSearch = 0
} }
// there was no day found in the cached weeks, add no lesson card
dayCardView.setDayHeading(formatter.format(Calendar.getInstance().time)) dayCardView.setDayHeading(formatter.format(Calendar.getInstance().time))
dayCardView.getLinLayoutDay().addView(getNoCard(resources.getString(R.string.no_lesson_today))) // if there is no lecture at all show the no lesson card dayCardView.getLinLayoutDay().addView(getNoCard(resources.getString(R.string.no_lesson_today))) // if there is no lecture at all show the no lesson card
return dayCardView return dayCardView

View File

@ -54,7 +54,7 @@ class MensaFragment : Fragment() {
refreshAction() refreshAction()
// add the current week (week starts on sunday) // add the current week (week starts on sunday)
val dayCurrent = if(NotRetardedCalendar().getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar().getDayOfWeekIndex() val dayCurrent = if(NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex()
addWeek(mensaMenu.currentWeek, dayCurrent).get() addWeek(mensaMenu.currentWeek, dayCurrent).get()
// add the next week // add the next week
@ -128,7 +128,7 @@ class MensaFragment : Fragment() {
linLayout_Mensa.removeAllViews() linLayout_Mensa.removeAllViews()
// add the refreshed menus // add the refreshed menus
val dayCurrent = if (NotRetardedCalendar().getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar().getDayOfWeekIndex() val dayCurrent = if (NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex()
addWeek(mensaMenu.currentWeek, dayCurrent).get() addWeek(mensaMenu.currentWeek, dayCurrent).get()
// add the next week // add the next week

View File

@ -38,11 +38,8 @@ import org.mosad.seil0.projectlaogai.controller.CacheController
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timetables import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timetables
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse
import org.mosad.seil0.projectlaogai.controller.TCoRAPIController import org.mosad.seil0.projectlaogai.controller.TCoRAPIController
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar
import org.mosad.seil0.projectlaogai.hsoparser.TimetableWeek
import org.mosad.seil0.projectlaogai.uicomponents.DayCardView import org.mosad.seil0.projectlaogai.uicomponents.DayCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonLinearLayout
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -52,7 +49,6 @@ import java.util.*
*/ */
class TimeTableFragment : Fragment() { class TimeTableFragment : Fragment() {
private val formatter = SimpleDateFormat("E dd.MM", Locale.getDefault())
private lateinit var scrollViewTimetable: ScrollView private lateinit var scrollViewTimetable: ScrollView
private lateinit var faBtnAddLesson: FloatingActionButton private lateinit var faBtnAddLesson: FloatingActionButton
@ -111,53 +107,30 @@ class TimeTableFragment : Fragment() {
* add the current and next weeks lessons * add the current and next weeks lessons
*/ */
private fun addInitWeeks() = doAsync { private fun addInitWeeks() = doAsync {
val dayIndex = NotRetardedCalendar().getDayOfWeekIndex() val currentDayIndex = NotRetardedCalendar.getDayOfWeekIndex()
val calendar = Calendar.getInstance()
// add current week addWeek(currentDayIndex, 5, 0).get() // add current week
addWeek(dayIndex, 5, timetables[0].timetable, calendar).get() addWeek(0, currentDayIndex - 1, 1) // add next week
// add next week
addWeek(0, dayIndex - 1, timetables[1].timetable, calendar)
} }
private fun addWeek(dayStart: Int, dayEnd: Int, timetable: TimetableWeek, calendar: Calendar) = doAsync { private fun addWeek(startDayIndex: Int, dayEndIndex: Int, weekIndex: Int) = doAsync {
val timetable = timetables[weekIndex].timetable
val timetableMeta = timetables[weekIndex].meta
uiThread { uiThread {
for (day in dayStart..dayEnd) { for (dayIndex in startDayIndex..dayEndIndex) {
var helpLesson = LessonLinearLayout(context)
val dayCardView = DayCardView(context!!) val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(formatter.format(calendar.time))
// for each timeslot of the day // some wired calendar magic, calculate the correct date to be shown ((timetable week - current week * 7) + days of calendar week + 1)
for ((tsIndex, timeslot) in timetable.days[day].timeslots.withIndex()) { val daysToAdd = (timetableMeta.weekNumberYear - NotRetardedCalendar.getWeekOfYear() - 1) * 7 + dayIndex +1
dayCardView.addTimetableDay(timetable.days[dayIndex], daysToAdd)
for(lesson in timeslot) {
if(lesson.lessonSubject.isNotEmpty()) {
val lessonLayout = LessonLinearLayout(context)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
if (lesson != timeslot.last())
lessonLayout.disableDivider()
helpLesson = lessonLayout
}
}
}
helpLesson.disableDivider()
calendar.add(Calendar.DATE, 1)
// if there are no lessons don't show the dayCardView // if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1) if (dayCardView.getLinLayoutDay().childCount > 1)
linLayout_Timetable.addView(dayCardView) linLayout_Timetable.addView(dayCardView)
} }
calendar.add(Calendar.DATE, 1) // before this we are at a sunday (no lecture on sundays!)
} }
} }
@ -174,14 +147,13 @@ class TimeTableFragment : Fragment() {
linLayout_Timetable.removeAllViews() linLayout_Timetable.removeAllViews()
// add the refreshed timetables // add the refreshed timetables
val dayIndex = NotRetardedCalendar().getDayOfWeekIndex() val dayIndex = NotRetardedCalendar.getDayOfWeekIndex()
val calendar = Calendar.getInstance()
// add current week // add current week
addWeek(dayIndex, 5, timetables[0].timetable, calendar).get() addWeek(dayIndex, 5, 0).get()
// add next week // add next week
addWeek(0, dayIndex - 1, timetables[1].timetable, calendar) addWeek(0, dayIndex - 1, 1)
refreshLayout_Timetable.isRefreshing = false refreshLayout_Timetable.isRefreshing = false
} }

View File

@ -83,31 +83,40 @@ class DataTypes {
} }
class NotRetardedCalendar { class NotRetardedCalendar {
private val calendar = Calendar.getInstance()!! companion object {
private val calendar = Calendar.getInstance()
fun getDayOfWeekIndex(): Int { fun getDayOfWeekIndex(): Int {
return when (calendar.get(Calendar.DAY_OF_WEEK)) { return when (calendar.get(Calendar.DAY_OF_WEEK)) {
Calendar.MONDAY -> 0 Calendar.MONDAY -> 0
Calendar.TUESDAY -> 1 Calendar.TUESDAY -> 1
Calendar.WEDNESDAY -> 2 Calendar.WEDNESDAY -> 2
Calendar.THURSDAY -> 3 Calendar.THURSDAY -> 3
Calendar.FRIDAY -> 4 Calendar.FRIDAY -> 4
Calendar.SATURDAY -> 5 Calendar.SATURDAY -> 5
Calendar.SUNDAY -> 6 Calendar.SUNDAY -> 6
else -> 7 else -> 7
}
} }
}
fun getTomorrowWeekIndex(): Int { fun getTomorrowWeekIndex(): Int {
return when (calendar.get(Calendar.DAY_OF_WEEK)) { return when (calendar.get(Calendar.DAY_OF_WEEK)) {
Calendar.MONDAY -> 1 Calendar.MONDAY -> 1
Calendar.TUESDAY -> 2 Calendar.TUESDAY -> 2
Calendar.WEDNESDAY -> 3 Calendar.WEDNESDAY -> 3
Calendar.THURSDAY -> 4 Calendar.THURSDAY -> 4
Calendar.FRIDAY -> 5 Calendar.FRIDAY -> 5
Calendar.SATURDAY -> 6 Calendar.SATURDAY -> 6
Calendar.SUNDAY -> 0 Calendar.SUNDAY -> 0
else -> 7 else -> 7
}
}
fun getWeekOfYear(): Int {
return when (calendar.get(Calendar.DAY_OF_WEEK)) {
Calendar.SUNDAY -> Calendar.getInstance().get(Calendar.WEEK_OF_YEAR) - 1
else -> Calendar.getInstance().get(Calendar.WEEK_OF_YEAR)
}
} }
} }
} }
@ -138,6 +147,6 @@ data class TimetableDay(val timeslots: Array<ArrayList<Lesson>> = Array(6) { Arr
data class TimetableWeek(val days: Array<TimetableDay> = Array(6) { TimetableDay() }) data class TimetableWeek(val days: Array<TimetableDay> = Array(6) { TimetableDay() })
data class TimetableCourseMeta(var updateTime: Long = 0, val courseName: String = "", val week: Int = 0, val link: String = "") data class TimetableCourseMeta(val updateTime: Long = 0, val courseName: String = "", val weekIndex: Int = 0, val weekNumberYear: Int = 0, val link: String = "")
data class TimetableCourseWeek(val meta: TimetableCourseMeta = TimetableCourseMeta(), var timetable: TimetableWeek = TimetableWeek()) data class TimetableCourseWeek(val meta: TimetableCourseMeta = TimetableCourseMeta(), var timetable: TimetableWeek = TimetableWeek())

View File

@ -28,9 +28,15 @@ import android.widget.LinearLayout
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import kotlinx.android.synthetic.main.cardview_day.view.* import kotlinx.android.synthetic.main.cardview_day.view.*
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.TimetableDay
import java.text.SimpleDateFormat
import java.util.*
class DayCardView(context: Context) : CardView(context) { class DayCardView(context: Context) : CardView(context) {
private val formatter = SimpleDateFormat("E dd.MM", Locale.getDefault())
init { init {
inflate(context, R.layout.cardview_day,this) inflate(context, R.layout.cardview_day,this)
@ -46,4 +52,38 @@ class DayCardView(context: Context) : CardView(context) {
txtView_DayHeading.text = heading txtView_DayHeading.text = heading
} }
/**
* add the lessons of one day to the dayCardView
* @param timetable a timetable containing the day (and it's lessons) to be added
*/
fun addTimetableDay(timetable: TimetableDay, daysToAdd: Int) {
var lastLesson = LessonLinearLayout(context)
// set the heading
val cal = Calendar.getInstance()
cal.add(Calendar.DATE, daysToAdd)
txtView_DayHeading.text = formatter.format(cal.time)
// for every timeslot of that timetable
for ((tsIndex, timeslot) in timetable.timeslots.withIndex()) {
for (lesson in timeslot) {
if (lesson.lessonSubject.isNotEmpty()) {
val lessonLayout = LessonLinearLayout(context)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
linLayout_Day.addView(lessonLayout)
if (lesson != timeslot.last()) {
lessonLayout.disableDivider()
}
lastLesson = lessonLayout
}
}
}
lastLesson.disableDivider() // disable the divider for the last lesson of the day
}
} }

View File

@ -1,35 +1,52 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:id="@+id/linLayout_lesson"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/linLayout_lesson" android:padding="7dp"> android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="7dp"
android:paddingTop="2dp"
android:paddingRight="7dp"
android:paddingBottom="3dp">
<LinearLayout <LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView <TextView
android:id="@+id/txtView_lessonSubject"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/txtView_lessonSubject" android:layout_weight="1" android:layout_height="wrap_content"
android:textSize="15sp"/> android:layout_weight="1"
android:textSize="15sp" />
<TextView <TextView
android:id="@+id/txtView_lessonTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:text="@string/a_time" android:text="@string/a_time"
android:layout_width="wrap_content" android:textColor="@color/textSecondary" />
android:layout_height="wrap_content" android:id="@+id/txtView_lessonTime" android:layout_weight="1"
android:textColor="@color/textSecondary" android:gravity="end"/>
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/txtView_lessonTeacher"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/txtView_lessonTeacher" android:textSize="15sp" android:layout_height="wrap_content"
/> android:textSize="15sp" />
<TextView <TextView
android:id="@+id/txtView_lessonRoom"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/txtView_lessonRoom" android:layout_height="wrap_content" />
/>
<View <View
android:id="@+id/divider_lesson" android:id="@+id/divider_lesson"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:background="?dividerColor"/> android:layout_marginTop="2dp"
android:background="?dividerColor" />
</LinearLayout> </LinearLayout>