19 Commits
0.3.1 ... 0.3.3

Author SHA1 Message Date
5a1a07cd42 minor gui updates 2019-03-03 20:46:51 +01:00
dbfdaffe99 the app can now display multiple lessons per time slot
* display multiple lessons per slot if needed
* material dialogs 2.0.0 -> 2.0.3
2019-03-01 18:59:17 +01:00
58eb217ab7 added a new timetable parser implementation
* added supports for multiple lessons per slot
* added support for lessons which take 2 slots
2019-02-28 14:52:40 +01:00
24f920c05f Added PreferenceController
* all preferences and global variables are now inside the PreferenceController, this makes it much easier to extend the apps functionality
* CourseTTLink is now Course with courseLink and courseName as values
2019-02-17 15:05:03 +01:00
6301308d76 Update 'README.md' 2019-02-16 17:38:24 +01:00
8e205fa889 updated the gradle plugin to 3.3.1 2019-02-14 16:27:29 +01:00
e9bdcee443 some clean up
* removed unnecessary MainActivity dependencies
2019-02-14 16:25:23 +01:00
b214cfccb2 „README.md“ ändern 2019-02-13 21:16:17 +01:00
404ddd58b8 „README.md“ ändern 2019-02-13 21:14:34 +01:00
137ff7df0c „README.md“ ändern 2019-02-13 21:10:38 +01:00
b4071d7456 updated some libs
* material-dialogs 2.0.0-rc5 -> 2.0.0
2019-02-09 21:58:35 +01:00
5e6e6cfde6 updated gradle plugin to 3.3.0 2019-01-15 18:55:06 +01:00
ffeb09a37f fixed a possible issue with the mensa parser 2019-01-04 23:58:54 +01:00
75a457312d major bug fixes & version 0.3.2
* fixed a issue that prevented the app from showing the second weeks schedule, until now the app showed always the current week as next week
* minor color chooser improvements
* minor code clean up
2019-01-03 13:46:09 +01:00
87bf614d28 added color saving
** WARNING this contains issues, many issues **
2019-01-03 01:45:28 +01:00
e69354af96 clean up 2018-12-18 11:49:46 +01:00
ec74a8e4f8 basic color selection 2018-12-14 15:02:19 +01:00
b49d16b1a1 updated some libs, meal tomorrow shows correct string if there's no meal 2018-12-02 00:05:23 +01:00
70059b4b0c added moodle webview 2018-11-30 13:54:39 +01:00
24 changed files with 520 additions and 282 deletions

View File

@ -1,12 +1,13 @@
# ProjectLaogai "hso App" # ProjectLaogai "hso App"
Some info about the app ... ProjectLaogai is a app to access the timetable for any course of the Hochschule Offenburg. You can also check the current weeks mensa menus.
## Features ## Features
* look up what you can eat in the mensa * look up what you can eat in the mensa
* check your timetable * check your timetable
* probably many many bugs * probably some funny bugs
## Screenshots ## Screenshots
[<img src="https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/ProjectLaogai_HomeScreen.png" width=180>](https://github.com/Seil0/Seil0.github.io/blob/master/images/ProjectLaogai_HomeScreen.png)
[<img src="https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/ProjectLaogai_Mensa.png" width=180>](https://github.com/Seil0/Seil0.github.io/blob/master/images/ProjectLaogai_Mensa.png)
[<img src="https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/ProjectLaogai_NavDrawer.png" width=180>](https://github.com/Seil0/Seil0.github.io/blob/master/images/ProjectLaogai_NavDrawer.png)
ProjectLaogai © 2019 mosad [www.mosad.xyz](http://www.mosad.xyz), Project by [@Seil0](https://git.mosad.xyz/Seil0)
ProjectLaogai © 2018 mosad www.mosad.xyz, Project by [@Seil0](https://git.mosad.xyz/Seil0)

View File

@ -12,8 +12,8 @@ android {
applicationId "org.mosad.seil0.projectlaogai" applicationId "org.mosad.seil0.projectlaogai"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 9 versionCode 11
versionName "0.3.1" versionName "0.3.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@ -32,12 +32,14 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
implementation 'org.jsoup:jsoup:1.11.3' implementation 'org.jsoup:jsoup:1.11.3'
implementation 'org.jetbrains.anko:anko-commons:0.10.8' implementation 'org.jetbrains.anko:anko-commons:0.10.8'
implementation 'com.afollestad.material-dialogs:core:2.0.0-rc1' implementation 'com.afollestad:aesthetic:1.0.0-beta05'
implementation 'com.afollestad.material-dialogs:color:2.0.0-rc1' implementation 'com.afollestad.material-dialogs:core:2.0.3'
implementation 'com.afollestad.material-dialogs:color:2.0.3'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0' androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
} }

View File

@ -13,12 +13,12 @@
<activity <activity
android:name=".SplashActivity" android:name=".SplashActivity"
android:label="@string/app_name"
android:theme="@style/SplashTheme" android:theme="@style/SplashTheme"
android:screenOrientation="portrait"> android:screenOrientation="portrait">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,49 +22,67 @@
package org.mosad.seil0.projectlaogai package org.mosad.seil0.projectlaogai
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar_main.* import kotlinx.android.synthetic.main.app_bar_main.*
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.PreferencesController.Companion.cColor
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cCourse
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cCourseTTLinkList
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableCurrentWeek
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableNextWeek
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cWeekMenus
import org.mosad.seil0.projectlaogai.fragments.* import org.mosad.seil0.projectlaogai.fragments.*
import org.mosad.seil0.projectlaogai.hsoparser.* import org.mosad.seil0.projectlaogai.hsoparser.MensaParser
import org.mosad.seil0.projectlaogai.hsoparser.TimeTableParser
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private val mensaParser = MensaParser() private val mensaParser = MensaParser()
private val timeTableParser = TimeTableParser() private val timeTableParser = TimeTableParser()
private var activeFragment: Fragment = HomeFragment() // the currently active fragment, home at the start
private var weekMenus = ArrayList<Meal>()
private var courseTTLinkList = ArrayList<CourseTTLink>()
private var timeTableCurrentWeek = arrayOf<Array<Lesson>>()
private var timeTableNextWeek = arrayOf<Array<Lesson>>()
private lateinit var course: CourseTTLink
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
Aesthetic.attach(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
// load mensa, timetable and color
// load mensa and timetable
load() load()
//init home fragment TODO make a abstract fragment class // If we haven't set any defaults, do that now
val homeFragment = HomeFragment() if (Aesthetic.isFirstTime) {
homeFragment.setMainActivity(this) // this is executed on the first app start, use this to show tutorial etc.
Aesthetic.config {
colorPrimary(Color.BLACK)
colorPrimaryDark(Color.BLACK)
apply()
}
} else {
Aesthetic.config {
colorPrimary(cColor)
colorPrimaryDark(cColor)
apply()
}
}
//init home fragment
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction() val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, homeFragment) fragmentTransaction.replace(R.id.fragment_container, activeFragment)
fragmentTransaction.commit() fragmentTransaction.commit()
val toggle = ActionBarDrawerToggle( val toggle = ActionBarDrawerToggle(
@ -76,6 +94,16 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
nav_view.setNavigationItemSelectedListener(this) nav_view.setNavigationItemSelectedListener(this)
} }
override fun onResume() {
super.onResume()
Aesthetic.resume(this)
}
override fun onPause() {
super.onPause()
Aesthetic.pause(this)
}
override fun onBackPressed() { override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) { if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START) drawer_layout.closeDrawer(GravityCompat.START)
@ -104,107 +132,58 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
// Handle navigation view item clicks here. // Handle navigation view item clicks here.
when (item.itemId) { when (item.itemId) {
R.id.nav_home -> { R.id.nav_home -> {
val homeFragment = HomeFragment() activeFragment = HomeFragment()
homeFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, homeFragment)
fragmentTransaction.commit()
} }
R.id.nav_mensa -> { R.id.nav_mensa -> {
val mensaFragment = MensaFragment() activeFragment = MensaFragment()
mensaFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, mensaFragment)
fragmentTransaction.commit()
} }
R.id.nav_timetable -> { R.id.nav_timetable -> {
val timeTableFragment = TimeTableFragment() activeFragment = TimeTableFragment()
timeTableFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, timeTableFragment)
fragmentTransaction.commit()
} }
R.id.nav_moodle -> { R.id.nav_moodle -> {
// val moodleFragment = MoodleFragment() activeFragment = MoodleFragment()
//
// val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
// fragmentTransaction.replace(R.id.fragment_container, moodleFragment)
// fragmentTransaction.commit()
} }
R.id.nav_settings -> { R.id.nav_settings -> {
val settingsFragment = SettingsFragment() activeFragment = SettingsFragment()
settingsFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, settingsFragment)
fragmentTransaction.commit()
} }
} }
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, activeFragment)
fragmentTransaction.commit()
drawer_layout.closeDrawer(GravityCompat.START) drawer_layout.closeDrawer(GravityCompat.START)
return true return true
} }
/**
* update the gui with the data of the new selected course
* save selected course and courseTTLink
*/
fun updateCourse(course: CourseTTLink) {
println(course.course)
println(course.courseTTLink)
this.course = course
// save new selected course
val sharedPref = getPreferences(MODE_PRIVATE) ?: return
with (sharedPref.edit()) {
putString(getString(R.string.save_key_course), course.course)
putString(getString(R.string.save_key_courseTTLink), course.courseTTLink.replace("http", "https"))
apply()
}
timeTableCurrentWeek = timeTableParser.getTimeTable(course.courseTTLink.replace("http", "https"))
}
/** /**
* load the mensa menus of the current week * load the mensa menus of the current week
*/ */
private fun load() { private fun load() {
// load the settings
// load saved course PreferencesController.load(this) // this must be finished before doing anything else
val sharedPref = getPreferences(MODE_PRIVATE) ?: return
course = CourseTTLink(
sharedPref.getString(getString(R.string.save_key_courseTTLink),
"https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0")!!,
sharedPref.getString(getString(R.string.save_key_course), "AI3")!!
)
/** /**
* load mensa, course timetable and courselist from the swfr/hso website * load mensa, course timetable and courselist from the swfr/hso website
* TODO make an API see https://git.mosad.xyz/Seil0/TheCitadelofRicks * TODO make an API see https://git.mosad.xyz/Seil0/TheCitadelofRicks
*/ */
val time = measureTimeMillis { val time = measureTimeMillis {
/* getting the course list should be faster than the timetable, /* getting the course list should be faster than the timetable,
* we need have time until the user opens the dialog * we need have time until the user opens the dialog
*/ */
doAsync { doAsync {
courseTTLinkList = timeTableParser.getCourseTTLinks() cCourseTTLinkList = timeTableParser.getCourseTTLinks()
} }
doAsync { val jobMenus = doAsync {
cWeekMenus = mensaParser.getMensaMenu()
}
val jobTTCurrentWeek = doAsync {
try { try {
timeTableNextWeek = timeTableParser.getTimeTable(course.courseTTLink.replace("week=0","week=1")) cTimeTableCurrentWeek = timeTableParser.getTimeTable(cCourse.courseLink)
} catch (e: Exception) { timeTableParser.printTimeTableWeek(cTimeTableCurrentWeek)
e.stackTrace
}
}
val t1 = doAsync {
weekMenus = mensaParser.getMensaMenu()
}
val t2 = doAsync {
try {
timeTableCurrentWeek = timeTableParser.getTimeTable(course.courseTTLink)
} catch (e: Exception) { } catch (e: Exception) {
uiThread { uiThread {
@ -218,31 +197,19 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
} }
} }
t1.get() val jobTTNextWeek = doAsync {
t2.get() try {
cTimeTableNextWeek = timeTableParser.getTimeTable(cCourse.courseLink.replace("week=0","week=1"))
} catch (e: Exception) {
e.stackTrace
}
}
jobMenus.get()
jobTTCurrentWeek.get()
jobTTNextWeek.get()
} }
println("Completed in $time ms") println("Completed in $time ms")
}
fun getCourseTTLinkList(): ArrayList<CourseTTLink>{
return courseTTLinkList
}
fun getTimeTableCurrentWeek(): Array<Array<Lesson>> {
return timeTableCurrentWeek
}
fun getTimeTableNextWeek(): Array<Array<Lesson>> {
return timeTableNextWeek
}
fun getWeekMenu(): ArrayList<Meal>{
return weekMenus
}
fun getCourse(): CourseTTLink {
return course
} }
} }

View File

@ -0,0 +1,79 @@
/**
* ProjectLaogai
*
* Copyright 2019 <seil0@mosad.xyz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
package org.mosad.seil0.projectlaogai
import android.content.Context
import android.graphics.Color
import org.jetbrains.anko.defaultSharedPreferences
import org.mosad.seil0.projectlaogai.hsoparser.Course
import org.mosad.seil0.projectlaogai.hsoparser.Meal
import org.mosad.seil0.projectlaogai.hsoparser.TimeTable
/**
* The PreferencesController class
* contains all preferences and global variables that exist in this app
*/
class PreferencesController {
companion object {
var cCourseTTLinkList = ArrayList<Course>()
var cWeekMenus = ArrayList<Meal>()
var cTimeTableCurrentWeek = TimeTable()
var cTimeTableNextWeek = TimeTable()
var cColor: Int = Color.BLACK
var cCourse = Course("https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0", "AI3")
// the save function
fun save(context: Context) {
println(cCourse.courseLink)
// save the course
val sharedPref = context.defaultSharedPreferences
with (sharedPref.edit()) {
putString(context.getString(R.string.save_key_course), cCourse.courseName)
putString(context.getString(R.string.save_key_courseTTLink), cCourse.courseLink)
apply()
}
// save the primary color
with (sharedPref.edit()) {
putInt(context.getString(R.string.save_key_colorPrimary), cColor)
apply()
}
}
// the load function
fun load(context: Context) {
// load saved course
val sharedPref = context.defaultSharedPreferences
cCourse = Course(
sharedPref.getString(context.getString(R.string.save_key_courseTTLink), "https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0")!!,
sharedPref.getString(context.getString(R.string.save_key_course), "AI3")!!
)
// load saved color
cColor = sharedPref.getInt(context.getString(R.string.save_key_colorPrimary), Color.BLACK)
}
}
}

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -32,10 +32,12 @@ 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.MainActivity import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableCurrentWeek
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cWeekMenus
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.hsoparser.* import org.mosad.seil0.projectlaogai.hsoparser.*
import org.mosad.seil0.projectlaogai.uicomponents.LessonCardView import org.mosad.seil0.projectlaogai.uicomponents.LessonCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonTextView
import java.util.* import java.util.*
/** /**
@ -45,7 +47,6 @@ import java.util.*
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
private lateinit var linLayoutTimeTable: LinearLayout private lateinit var linLayoutTimeTable: LinearLayout
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -71,11 +72,10 @@ class HomeFragment : Fragment() {
val cal = Calendar.getInstance() val cal = Calendar.getInstance()
if (cal.get(Calendar.HOUR_OF_DAY) < 15) { if (cal.get(Calendar.HOUR_OF_DAY) < 15) {
dayMenus = MensaParser().getMensaMenuDay(mainActivity.getWeekMenu(), cal.get(Calendar.DAY_OF_WEEK)) dayMenus = MensaParser().getMensaMenuDay(cWeekMenus, cal.get(Calendar.DAY_OF_WEEK))
} else { } else {
dayMenus = MensaParser().getMensaMenuDay(mainActivity.getWeekMenu(), cal.get(Calendar.DAY_OF_WEEK) + 1) dayMenus = MensaParser().getMensaMenuDay(cWeekMenus, cal.get(Calendar.DAY_OF_WEEK) + 1)
uiThread { uiThread {
// TODO Mensa closed today is showing
txtView_Menu1Heading.text = resources.getString(R.string.meal_1_tomorrow) txtView_Menu1Heading.text = resources.getString(R.string.meal_1_tomorrow)
txtView_Menu2Heading.text = resources.getString(R.string.meal_2_tomorrow) txtView_Menu2Heading.text = resources.getString(R.string.meal_2_tomorrow)
} }
@ -86,16 +86,16 @@ class HomeFragment : Fragment() {
if (dayMenus.size >= 2) { if (dayMenus.size >= 2) {
// get the index of the first meal, not a "Schneller Teller" // get the index of the first meal, not a "Schneller Teller"
loop@ for ((i, meal) in dayMenus.withIndex()) { loop@ for ((i, meal) in dayMenus.withIndex()) {
if(meal.heading.contains("Essen")) { if (meal.heading.contains("Essen")) {
for ((j, part) in dayMenus[i].parts.withIndex()) { for ((j, part) in dayMenus[i].parts.withIndex()) {
txtViewMenu1.append(part) txtViewMenu1.append(part)
if(j < (dayMenus[i].parts.size - 2)) if (j < (dayMenus[i].parts.size - 2))
txtViewMenu1.append("\n") txtViewMenu1.append("\n")
} }
for ((j, part) in dayMenus[i + 1].parts.withIndex()) { for ((j, part) in dayMenus[i + 1].parts.withIndex()) {
txtViewMenu2.append(part) txtViewMenu2.append(part)
if(j < (dayMenus[i + 1].parts.size - 2)) if (j < (dayMenus[i + 1].parts.size - 2))
txtViewMenu2.append("\n") txtViewMenu2.append("\n")
} }
@ -104,8 +104,13 @@ class HomeFragment : Fragment() {
} }
} else { } else {
txtViewMenu1.text = resources.getString(R.string.no_meal_today) if (txtView_Menu1Heading.text == resources.getString(R.string.meal_1_tomorrow)) {
txtViewMenu2.text = resources.getString(R.string.no_meal_today) txtViewMenu1.text = resources.getString(R.string.no_meal_tomorrow)
txtViewMenu2.text = resources.getString(R.string.no_meal_tomorrow)
} else {
txtViewMenu1.text = resources.getString(R.string.no_meal_today)
txtViewMenu2.text = resources.getString(R.string.no_meal_today)
}
} }
} }
} }
@ -118,34 +123,48 @@ class HomeFragment : Fragment() {
private fun addCurrentTimeTable() { private fun addCurrentTimeTable() {
val dayIndex = NotRetardedCalendar().getDayOfWeekIndex() val dayIndex = NotRetardedCalendar().getDayOfWeekIndex()
if (mainActivity.getTimeTableCurrentWeek().isNotEmpty() && dayIndex < 6) { if (cTimeTableCurrentWeek.days.isNotEmpty() && dayIndex < 6) {
val timeTableDay = mainActivity.getTimeTableCurrentWeek()[dayIndex] val timeTableDay = cTimeTableCurrentWeek.days[dayIndex]
for (i in 0..5) { // for all timeslots of the day
for ((i, timeslot) in timeTableDay.timeslots.withIndex()) {
val lessonCardView = LessonCardView(context!!, null) val lessonCardView = LessonCardView(context!!, null)
lessonCardView.getTxtViewLesson().text = resources.getString(R.string.string_new_line, timeTableDay[i].lessonSubject)
lessonCardView.getTxtViewLesson().append(timeTableDay[i].lessonTeacher + "\n")
lessonCardView.getTxtViewLesson().append(timeTableDay[i].lessonRoom)
lessonCardView.getTxtViewTime().text = DataTypes().getTime()[i] lessonCardView.getTxtViewTime().text = DataTypes().getTime()[i]
if(lessonCardView.getTxtViewLesson().text.length > 2) for (lesson in timeslot) {
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setLesson(lesson)
// TODO why does this exist
if (lessonTxtView.text.length > 3)
lessonCardView.getLinLayoutLesson().addView(lessonTxtView)
}
if (lessonCardView.getLinLayoutLesson().childCount > 2)
linLayoutTimeTable.addView(lessonCardView) linLayoutTimeTable.addView(lessonCardView)
} }
// add a card if there is no lesson today // add a card if there is no lesson today
if (linLayoutTimeTable.childCount == 0) { if (linLayoutTimeTable.childCount == 0) {
// TODO we could display the next day with a lecture // TODO we could display the next day with a lecture
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setText(resources.getString(R.string.no_lesson_today))
val noLessonCardView = LessonCardView(context!!, null) val noLessonCardView = LessonCardView(context!!, null)
noLessonCardView.getTxtViewLesson().text = resources.getString(R.string.no_lesson_today) noLessonCardView.getLinLayoutLesson().addView(lessonTxtView)
linLayoutTimeTable.addView(noLessonCardView) linLayoutTimeTable.addView(noLessonCardView)
} }
} else { } else {
if (dayIndex == 6) { if (dayIndex == 6) {
// if that's the case it's sunday // if that's the case it's sunday
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setText(resources.getString(R.string.no_lesson_today))
val noLessonCardView = LessonCardView(context!!, null) val noLessonCardView = LessonCardView(context!!, null)
noLessonCardView.getTxtViewLesson().text = resources.getString(R.string.no_lesson_today) noLessonCardView.getLinLayoutLesson().addView(lessonTxtView)
linLayoutTimeTable.addView(noLessonCardView) linLayoutTimeTable.addView(noLessonCardView)
} else { } else {
MaterialDialog(context!!) MaterialDialog(context!!)
@ -158,8 +177,4 @@ class HomeFragment : Fragment() {
} }
} }
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
} }

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@ import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.LinearLayout
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.MainActivity import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cWeekMenus
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.uicomponents.MensaDayCardView import org.mosad.seil0.projectlaogai.uicomponents.MensaDayCardView
import org.mosad.seil0.projectlaogai.uicomponents.MenuCardView import org.mosad.seil0.projectlaogai.uicomponents.MenuCardView
@ -43,7 +43,6 @@ import java.util.*
class MensaFragment : Fragment() { class MensaFragment : Fragment() {
private lateinit var linLayoutMensaFragment: LinearLayout private lateinit var linLayoutMensaFragment: LinearLayout
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -77,7 +76,7 @@ class MensaFragment : Fragment() {
val cardViewMensaDay = MensaDayCardView(context!!, null) val cardViewMensaDay = MensaDayCardView(context!!, null)
var add = false var add = false
for (meal in mainActivity.getWeekMenu()) { for (meal in cWeekMenus) {
//println("Day: " + meal.day) //println("Day: " + meal.day)
if (meal.day.contains(strDay)) { if (meal.day.contains(strDay)) {
@ -90,7 +89,7 @@ class MensaFragment : Fragment() {
menuViewMenu.getTxtViewMenu().append("\n") menuViewMenu.getTxtViewMenu().append("\n")
} }
cardViewMensaDay.setDayHeading(meal.day) //TODO move this out of the first for loop, performance!! cardViewMensaDay.setDayHeading(meal.day)
cardViewMensaDay.getLinLayoutMensaDay().addView(menuViewMenu) cardViewMensaDay.getLinLayoutMensaDay().addView(menuViewMenu)
add = true add = true
} }
@ -112,8 +111,4 @@ class MensaFragment : Fragment() {
} }
} }
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
} }

View File

@ -1,3 +1,25 @@
/**
* ProjectLaogai
*
* Copyright 2019 <seil0@mosad.xyz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
package org.mosad.seil0.projectlaogai.fragments package org.mosad.seil0.projectlaogai.fragments
import android.os.Bundle import android.os.Bundle
@ -5,8 +27,10 @@ import androidx.fragment.app.Fragment
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 kotlinx.android.synthetic.main.fragment_moodle.* import android.webkit.WebSettings
import android.webkit.WebView
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import android.webkit.WebViewClient
/** /**
* The moodle screen controller class * The moodle screen controller class
@ -14,18 +38,21 @@ import org.mosad.seil0.projectlaogai.R
*/ */
class MoodleFragment : Fragment() { class MoodleFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { private lateinit var webView: WebView
val view: View = inflater.inflate(R.layout.fragment_settings, container, false) private lateinit var webSettings: WebSettings
//webView.loadUrl("www.google.de") override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_moodle, container, false)
webView = view.findViewById(R.id.webView)
webView.loadUrl("https://elearning.hs-offenburg.de/moodle/")
webSettings = webView.getSettings()
//webSettings.setJavaScriptEnabled(true) // Enable Javascript
webView.setWebViewClient(WebViewClient()) // Force links and redirects to open in the WebView instead of in a browser
return view return view
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//webView.loadUrl("www.google.de")
}
} }

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,11 +24,12 @@ package org.mosad.seil0.projectlaogai.fragments
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
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.LinearLayout import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.color.colorChooser import com.afollestad.materialdialogs.color.colorChooser
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
@ -36,10 +37,15 @@ import com.afollestad.materialdialogs.list.listItems
import kotlinx.android.synthetic.main.fragment_settings.* import kotlinx.android.synthetic.main.fragment_settings.*
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.MainActivity import org.mosad.seil0.projectlaogai.PreferencesController
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cColor
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cCourse
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cCourseTTLinkList
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableCurrentWeek
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableNextWeek
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.hsoparser.CourseTTLink import org.mosad.seil0.projectlaogai.hsoparser.TimeTableParser
import java.util.ArrayList import java.util.*
/** /**
* The settings controller class * The settings controller class
@ -52,9 +58,6 @@ class SettingsFragment : Fragment() {
private lateinit var linLayoutInfo: LinearLayout private lateinit var linLayoutInfo: LinearLayout
private lateinit var linLayoutMainColor: LinearLayout private lateinit var linLayoutMainColor: LinearLayout
private lateinit var viewPrimaryColor: View private lateinit var viewPrimaryColor: View
private lateinit var courseTTLinkList: ArrayList<CourseTTLink>
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -75,7 +78,7 @@ class SettingsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
txtView_Course.text = mainActivity.getCourse().course txtView_Course.text = cCourse.courseName
} }
/** /**
@ -90,12 +93,11 @@ class SettingsFragment : Fragment() {
// open a new dialog // open a new dialog
val courseList = ArrayList<String>() val courseList = ArrayList<String>()
courseTTLinkList = mainActivity.getCourseTTLinkList() cCourseTTLinkList.forEach { (_, course) ->
courseTTLinkList.forEach { (_, course) ->
courseList.add(course) courseList.add(course)
} }
MaterialDialog(context!!).listItems(items = courseList){ _, index, text -> MaterialDialog(context!!).listItems(items = courseList) { _, index, text ->
txtView_Course.text = text // update txtView txtView_Course.text = text // update txtView
val dialog = MaterialDialog(context!!).cancelable(false) val dialog = MaterialDialog(context!!).cancelable(false)
@ -104,7 +106,12 @@ class SettingsFragment : Fragment() {
dialog.show() dialog.show()
doAsync { doAsync {
mainActivity.updateCourse(courseTTLinkList[index]) cCourse = cCourseTTLinkList[index] // set the course
PreferencesController.save(context!!)
// update current & next weeks timetable
cTimeTableCurrentWeek = TimeTableParser().getTimeTable(cCourse.courseLink)
cTimeTableNextWeek = TimeTableParser().getTimeTable(cCourse.courseLink.replace("week=0","week=1"))
uiThread { uiThread {
dialog.dismiss() dialog.dismiss()
@ -112,7 +119,7 @@ class SettingsFragment : Fragment() {
} }
} }
.show() .show()
} }
linLayoutInfo.setOnClickListener { linLayoutInfo.setOnClickListener {
@ -125,20 +132,24 @@ class SettingsFragment : Fragment() {
linLayoutMainColor.setOnClickListener { linLayoutMainColor.setOnClickListener {
// open a new color chooser dialog // open a new color chooser dialog
val colors = intArrayOf(Color.BLACK, Color.RED, Color.GREEN, Color.BLUE) val colors = intArrayOf(Color.BLACK, Color.DKGRAY, Color.RED, Color.GREEN, Color.YELLOW)
MaterialDialog(context!!) MaterialDialog(context!!)
.title(R.string.primary_color) .title(R.string.primary_color)
.colorChooser(colors, initialSelection = Color.BLACK) { _, color -> .colorChooser(colors, allowCustomArgb = true, initialSelection = cColor) { _, color ->
viewPrimaryColor.setBackgroundColor(color) viewPrimaryColor.setBackgroundColor(color)
Aesthetic.config {
colorPrimary(color)
colorPrimaryDark(color)
apply()
}
cColor = color
PreferencesController.save(context!!)
} }
.positiveButton(R.string.select) .positiveButton(R.string.select)
.show() .show()
} }
} }
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
} }

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,20 +22,21 @@
package org.mosad.seil0.projectlaogai.fragments package org.mosad.seil0.projectlaogai.fragments
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
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.LinearLayout import android.widget.LinearLayout
import androidx.fragment.app.Fragment
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.MainActivity import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableCurrentWeek
import org.mosad.seil0.projectlaogai.PreferencesController.Companion.cTimeTableNextWeek
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.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar
import org.mosad.seil0.projectlaogai.uicomponents.LessonCardView import org.mosad.seil0.projectlaogai.uicomponents.LessonCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonTextView
import org.mosad.seil0.projectlaogai.uicomponents.MensaDayCardView import org.mosad.seil0.projectlaogai.uicomponents.MensaDayCardView
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -47,7 +48,6 @@ import java.util.*
class TimeTableFragment : Fragment() { class TimeTableFragment : Fragment() {
private lateinit var linLayoutTTFragment: LinearLayout private lateinit var linLayoutTTFragment: LinearLayout
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -55,7 +55,7 @@ class TimeTableFragment : Fragment() {
linLayoutTTFragment = view.findViewById(R.id.linLayout_TTFragment) linLayoutTTFragment = view.findViewById(R.id.linLayout_TTFragment)
if (mainActivity.getTimeTableCurrentWeek().isNotEmpty()) { if (cTimeTableCurrentWeek.days.isNotEmpty()) {
addCurrentWeek() addCurrentWeek()
} else { } else {
// TODO show card with error msg // TODO show card with error msg
@ -77,64 +77,95 @@ class TimeTableFragment : Fragment() {
uiThread { uiThread {
// add current weeks days // add current weeks days
for(day in dayIndex..5) { for (day in dayIndex..5) {
val cardViewTimeTableDay = MensaDayCardView(context!!, null) val cardViewTimeTableDay = MensaDayCardView(context!!, null)
cardViewTimeTableDay.setDayHeading(formatter.format(calendar.time)) cardViewTimeTableDay.setDayHeading(formatter.format(calendar.time))
// for each lessen of the day // for each timeslot of the day
for((i, lesson) in mainActivity.getTimeTableCurrentWeek()[day].withIndex()) { for ((i, timeslot) in cTimeTableCurrentWeek.days[day].timeslots.withIndex()) {
val lessonCardView = LessonCardView(context!!, null) val lessonCardView = LessonCardView(context!!, null)
lessonCardView.setBackgroundColor(Color.TRANSPARENT)
lessonCardView.getTxtViewLesson().text = resources.getString(R.string.string_new_line, lesson.lessonSubject)
lessonCardView.getTxtViewLesson().append(lesson.lessonTeacher + "\n")
lessonCardView.getTxtViewLesson().append(lesson.lessonRoom)
lessonCardView.getTxtViewTime().text = DataTypes().getTime()[i] lessonCardView.getTxtViewTime().text = DataTypes().getTime()[i]
if(lessonCardView.getTxtViewLesson().text.length > 2) //println(timeslot)
for (lesson in timeslot) {
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setLesson(lesson)
// TODO why does this exist
if (lessonTxtView.text.length > 3)
lessonCardView.getLinLayoutLesson().addView(lessonTxtView)
}
// only add the lesson if it contains data
if (lessonCardView.getLinLayoutLesson().childCount > 1)
cardViewTimeTableDay.getLinLayoutMensaDay().addView(lessonCardView) cardViewTimeTableDay.getLinLayoutMensaDay().addView(lessonCardView)
} }
calendar.add(Calendar.DATE,1) calendar.add(Calendar.DATE, 1)
// if the day contains no lessons add a text "No lesson today"
if (cardViewTimeTableDay.getLinLayoutMensaDay().childCount <= 1) {
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setText(resources.getString(R.string.no_lesson_today))
val lessonCardView = LessonCardView(context!!, null)
lessonCardView.getLinLayoutLesson().addView(lessonTxtView)
cardViewTimeTableDay.getLinLayoutMensaDay().addView(lessonCardView)
}
linLayoutTTFragment.addView(cardViewTimeTableDay) linLayoutTTFragment.addView(cardViewTimeTableDay)
} }
// add next weeks days, max number = dayIndex, if timetable was loaded // add next weeks days, max number = dayIndex, if timetable was loaded
if (mainActivity.getTimeTableNextWeek().isNotEmpty()) { if (cTimeTableNextWeek.days.isNotEmpty()) {
calendar.add(Calendar.DATE,1) // before this we are at a sunday (no lecture on sundays!) calendar.add(Calendar.DATE, 1) // before this we are at a sunday (no lecture on sundays!)
for(day in 0..(dayIndex - 1)) { for (day in 0..(dayIndex - 1)) {
val cardViewTimeTableDay = MensaDayCardView(context!!, null) val cardViewTimeTableDay = MensaDayCardView(context!!, null)
cardViewTimeTableDay.setDayHeading(formatter.format(calendar.time)) cardViewTimeTableDay.setDayHeading(formatter.format(calendar.time))
// for each lessen of the day // for each timeslot of the day
for((i, lesson) in mainActivity.getTimeTableNextWeek()[day].withIndex()) { for ((i, timeslot) in cTimeTableNextWeek.days[day].timeslots.withIndex()) {
val lessonCardView = LessonCardView(context!!, null) val lessonCardView = LessonCardView(context!!, null)
lessonCardView.setBackgroundColor(Color.TRANSPARENT)
lessonCardView.getTxtViewLesson().text = resources.getString(R.string.string_new_line, lesson.lessonSubject)
lessonCardView.getTxtViewLesson().append(lesson.lessonTeacher + "\n")
lessonCardView.getTxtViewLesson().append(lesson.lessonRoom)
lessonCardView.getTxtViewTime().text = DataTypes().getTime()[i] lessonCardView.getTxtViewTime().text = DataTypes().getTime()[i]
if(lessonCardView.getTxtViewLesson().text.length > 2)
for (lesson in timeslot) {
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setLesson(lesson)
if (lessonTxtView.text.length > 3)
lessonCardView.getLinLayoutLesson().addView(lessonTxtView)
}
// only add the lesson if it contains data
if (lessonCardView.getLinLayoutLesson().childCount > 1)
cardViewTimeTableDay.getLinLayoutMensaDay().addView(lessonCardView) cardViewTimeTableDay.getLinLayoutMensaDay().addView(lessonCardView)
} }
calendar.add(Calendar.DATE,1) calendar.add(Calendar.DATE, 1)
// if the day contains no lessons add a text "No lesson today"
if (cardViewTimeTableDay.getLinLayoutMensaDay().childCount <= 1) {
val lessonTxtView = LessonTextView(context!!)
lessonTxtView.setText(resources.getString(R.string.no_lesson_today))
val lessonCardView = LessonCardView(context!!, null)
lessonCardView.getLinLayoutLesson().addView(lessonTxtView)
cardViewTimeTableDay.getLinLayoutMensaDay().addView(lessonCardView)
}
linLayoutTTFragment.addView(cardViewTimeTableDay) linLayoutTTFragment.addView(cardViewTimeTableDay)
} }
} }
// TODO if there is no lesson at one day , show a no lesson card
} }
} }
} }
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
} }

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -56,8 +56,12 @@ class NotRetardedCalendar {
} }
data class Course(val courseLink: String, val courseName: String)
data class Meal(val day: String, val heading: String, val parts: ArrayList<String>, val additives: String)
data class Lesson(val lessonSubject: String, val lessonTeacher: String, val lessonRoom:String, val lessonRemark: String) data class Lesson(val lessonSubject: String, val lessonTeacher: String, val lessonRoom:String, val lessonRemark: String)
data class CourseTTLink(val courseTTLink: String, val course: String) data class TimeTableDay( val timeslots: Array<ArrayList<Lesson>> = Array(6) { ArrayList<Lesson>()})
data class Meal(val day: String, val heading: String, val parts: ArrayList<String>, val additives: String) data class TimeTable(val days: Array<TimeTableDay> = Array(6) { TimeTableDay() })

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -26,16 +26,12 @@ import org.jsoup.Jsoup
import java.util.* import java.util.*
class MensaParser { class MensaParser {
private var mealList = ArrayList<Meal>()
init {
// do something
}
/** /**
* returns the mensa menu for the whole week * returns the mensa menu for the whole week
*/ */
fun getMensaMenu(): ArrayList<Meal> { fun getMensaMenu(): ArrayList<Meal> {
val mealList = ArrayList<Meal>()
val menuHTML = Jsoup.connect("https://www.swfr.de/de/essen-trinken/speiseplaene/mensa-offenburg/").get() val menuHTML = Jsoup.connect("https://www.swfr.de/de/essen-trinken/speiseplaene/mensa-offenburg/").get()
menuHTML.select("#speiseplan-tabs").select("div.tab-content").select("div.menu-tagesplan").forEachIndexed { _, element -> menuHTML.select("#speiseplan-tabs").select("div.tab-content").select("div.menu-tagesplan").forEachIndexed { _, element ->

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -26,52 +26,98 @@ import org.jsoup.Jsoup
class TimeTableParser { class TimeTableParser {
private val days = arrayOf("Monday", "Tuesday" ,"Wednesday", "Thursday", "Friday", "Saturday") private val days = arrayOf("Monday", "Tuesday" ,"Wednesday", "Thursday", "Friday", "Saturday")
private var courseTTLinkList = ArrayList<CourseTTLink>() private var courseTTLinkList = ArrayList<Course>()
private var timeTableWeek = arrayOf<Array<Lesson>>()
init {
// create the timetable array
for (i in 0..5) {
var timeTableDay = arrayOf<Lesson>()
for (j in 0..5) {
timeTableDay += Lesson("", "","","")
}
timeTableWeek += timeTableDay
}
}
/** /**
* get the timetable from the given url * get the timetable from the given url
* the timetable is organised per row not per column; * the timetable is organised per row not per column;
* Mon 1, Tue 1, Wed 1, Thur 1, Fri 1, Sat 1, Mon 2 and so on * Mon 1, Tue 1, Wed 1, Thur 1, Fri 1, Sat 1, Mon 2 and so on
*/ */
fun getTimeTable(courseTTURL: String): Array<Array<Lesson>> { fun getTimeTable(courseTTURL: String): TimeTable {
var timeTableWeek = TimeTable() // this must be a var!
val scheduleHTML = Jsoup.connect(courseTTURL).get() val scheduleHTML = Jsoup.connect(courseTTURL).get()
// create the timetable array
/* for (i in 0..5) {
var timeTableDay = arrayOf<Lesson>()
for (j in 0..5) {
timeTableDay += Lesson("", "","","")
}
timeTableWeek += timeTableDay
}*/
//val week = scheduleHTML.select("h1.timetable-caption").text() //val week = scheduleHTML.select("h1.timetable-caption").text()
//println("$week successful!\n") //println("$week successful!\n")
scheduleHTML.select("table.timetable").select("td.lastcol").forEachIndexed { index, element -> val rows= scheduleHTML.select("table.timetable").select("tr[scope=\"row\"]")
timeTableWeek[index % 6][index / 6] = Lesson(element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), element.select("div.lesson-room").text(), element.select("div.lesson-remark").text()) var sDay = -1
var sRow = -1
var sLesson = Lesson("", "", "", "")
// get each row with index, reflects 1 timeslot per day
for ((rowIndex, row) in rows.withIndex()) {
var day = 0
row.select("td.lastcol, td[style]").forEach { element ->
// elements are now all lessons, including empty ones
//println("-------------> Element (Day.Timeslot: " + day + "." + rowIndex + "): " + element)
//println("Day.Timeslot: " + day + "." + rowIndex + " lesson: " + element.select("div.lesson-subject").text() + ", " + element.select("div.lesson-teacher").text())
// if there is a lecture with rowspan="2", we need to shift everything by one to the left. This is stupid and ugly there needs to bee an API
if ((sDay > -1 && sRow > -1) && (sDay == day && ((sRow + 1) == rowIndex))) {
// we found a lecture that is longer than 1 lesson
timeTableWeek.days[day].timeslots[rowIndex].add(sLesson) // this just works if there is one lecture per slot
// adjust the following slot
sDay++
sLesson = Lesson(element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), element.select("div.lesson-room").text(), element.select("div.lesson-remark").text())
// adjust the slot directly as we don't get there anymore
if(sDay == 5) {
timeTableWeek.days[day + 1].timeslots[rowIndex].add(sLesson)
}
} else {
timeTableWeek.days[day].timeslots[rowIndex].add(Lesson(element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), element.select("div.lesson-room").text(), element.select("div.lesson-remark").text()))
}
// we found a lecture with rowspan="2", save day, row and lesson for later adjustment
if(element.toString().contains("rowspan=\"2\"")) {
sDay = day
sRow = rowIndex
sLesson = timeTableWeek.days[day].timeslots[rowIndex].get(index = 0)
}
if(element.hasClass("lastcol")) day++
}
} }
printTimeTableWeek(timeTableWeek)
/*scheduleHTML.select("table.timetable").select("td.lastcol").forEachIndexed { index, element ->
//println("Index: " + index + " lesson: " + element.select("div.lesson-subject").text() + ", " + element.select("div.lesson-teacher").text())
timeTableWeek[index % 6][index / 6] = Lesson(element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), element.select("div.lesson-room").text(), element.select("div.lesson-remark").text())
}*/
return timeTableWeek return timeTableWeek
} }
/** /**
* parse all courses from the courses site at https://www.hs-offenburg.de/studium/vorlesungsplaene/ * parse all courses from the courses site at https://www.hs-offenburg.de/studium/vorlesungsplaene/
*/ */
fun getCourseTTLinks(): ArrayList<CourseTTLink> { fun getCourseTTLinks(): ArrayList<Course> {
val courseHTML = Jsoup.connect("https://www.hs-offenburg.de/studium/vorlesungsplaene/").get() val courseHTML = Jsoup.connect("https://www.hs-offenburg.de/studium/vorlesungsplaene/").get()
courseHTML.select("ul.index-group").select("li.Class").select("a[href]").forEachIndexed { _, element -> courseHTML.select("ul.index-group").select("li.Class").select("a[href]").forEachIndexed { _, element ->
courseTTLinkList.add(CourseTTLink(element.attr("href"),element.text())) courseTTLinkList.add(Course(element.attr("href").replace("http", "https"),element.text()))
} }
return courseTTLinkList return courseTTLinkList
} }
@Suppress("unused") @Suppress("unused")
fun printTimeTableWeek (timeTableWeek: Array<Array<Lesson>>) { fun printTimeTableWeekOLD (timeTableWeek: Array<Array<Lesson>>) {
for (j in 0..5) print(days[j].padEnd(25 ,' ') + " | ") for (j in 0..5) print(days[j].padEnd(25 ,' ') + " | ")
println() println()
@ -88,7 +134,51 @@ class TimeTableParser {
for (j in 0..5) print("-".padEnd(26 + (j.toFloat().div(j).toInt()), '-') + "+") for (j in 0..5) print("-".padEnd(26 + (j.toFloat().div(j).toInt()), '-') + "+")
println() println()
} }
println(" \n")
}
@Suppress("unused")
fun printTimeTableWeek(timetable: TimeTable) {
for (j in 0..5) print(days[j].padEnd(75 ,' ') + " | ")
println() println()
for (j in 0..5) print("-".padEnd(76 + (j.toFloat().div(j).toInt()), '-') + "+")
println()
// the timeslot
for (i in 0..5) {
for (j in 0..5) {
val ldiff = if (timetable.days[j].timeslots[i].size == 0) 1 else timetable.days[j].timeslots[i].size
for (lesson in timetable.days[j].timeslots[i]) print(lesson.lessonSubject.padEnd(75/ldiff ,' '))
if (ldiff == 2) print(" ")
print(" | ")
}
println()
for (j in 0..5) {
val ldiff = if (timetable.days[j].timeslots[i].size == 0) 1 else timetable.days[j].timeslots[i].size
for (lesson in timetable.days[j].timeslots[i]) print(lesson.lessonTeacher.padEnd(75/ldiff ,' '))
if (ldiff == 2) print(" ")
print(" | ")
}
println()
for (j in 0..5) {
val ldiff = if (timetable.days[j].timeslots[i].size == 0) 1 else timetable.days[j].timeslots[i].size
for (lesson in timetable.days[j].timeslots[i]) print(lesson.lessonRoom.padEnd(75/ldiff ,' '))
if (ldiff == 2) print(" ")
print(" | ")
}
println()
for (j in 0..5) print("-".padEnd(76 + (j.toFloat().div(j).toInt()), '-') + "+")
println()
}
println(" \n")
} }
} }

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,26 +25,27 @@ package org.mosad.seil0.projectlaogai.uicomponents
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.util.AttributeSet import android.util.AttributeSet
import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
class LessonCardView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : androidx.cardview.widget.CardView(context, attrs){ class LessonCardView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : androidx.cardview.widget.CardView(context, attrs){
private var txtViewLesson: TextView private var linLayoutLesson: LinearLayout
private var txtViewTime: TextView private var txtViewTime: TextView
init { init {
inflate(context, R.layout.lesson_cardview,this) inflate(context, R.layout.lesson_cardview,this)
txtViewLesson = findViewById(R.id.txtView_Lesson) linLayoutLesson = findViewById(R.id.linLayout_Lesson)
txtViewTime = findViewById(R.id.txtView_Time) txtViewTime = findViewById(R.id.txtView_Time)
// workaround to prevent a white border // workaround to prevent a white border
this.setBackgroundColor(Color.TRANSPARENT) this.setBackgroundColor(Color.TRANSPARENT)
} }
fun getTxtViewLesson(): TextView { fun getLinLayoutLesson(): LinearLayout {
return txtViewLesson return linLayoutLesson
} }
fun getTxtViewTime(): TextView { fun getTxtViewTime(): TextView {

View File

@ -0,0 +1,26 @@
package org.mosad.seil0.projectlaogai.uicomponents
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.widget.TextView
import org.mosad.seil0.projectlaogai.hsoparser.Lesson
class LessonTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : TextView(context, attrs) {
init {
this.setTextColor(Color.BLACK)
this.textSize = 16F
this.setPadding(0,6,0,0)
}
fun setLesson(lesson: Lesson) {
this.text = resources.getString(org.mosad.seil0.projectlaogai.R.string.string_new_line, lesson.lessonSubject)
this.append(lesson.lessonTeacher + "\n")
this.append(lesson.lessonRoom)
}
fun setText(text: String) {
this.text = text
}
}

View File

@ -1,7 +1,7 @@
/** /**
* ProjectLaogai * ProjectLaogai
* *
* Copyright 2018 <seil0@mosad.xyz> * Copyright 2019 <seil0@mosad.xyz>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -2,8 +2,8 @@
android:shape="rectangle"> android:shape="rectangle">
<gradient <gradient
android:angle="135" android:angle="135"
android:centerColor="@color/colorPrimary" android:centerColor="?colorPrimary"
android:endColor="@color/colorPrimaryDark" android:endColor="?colorPrimaryDark"
android:startColor="@color/colorPrimary" android:startColor="?colorPrimary"
android:type="linear"/> android:type="linear"/>
</shape> </shape>

View File

@ -20,7 +20,7 @@
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary" android:background="?colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/> app:popupTheme="@style/AppTheme.PopupOverlay"/>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@ -137,7 +137,7 @@
<View <View
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:id="@+id/view_PrimaryColor" android:layout_height="40dp" android:id="@+id/view_PrimaryColor"
android:background="@color/colorPrimary"/> android:background="?colorPrimary"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -9,20 +9,9 @@
app:cardUseCompatPadding="true" app:cardPreventCornerOverlap="false" app:contentPadding="5dp"> app:cardUseCompatPadding="true" app:cardPreventCornerOverlap="false" app:contentPadding="5dp">
<LinearLayout <LinearLayout
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent" android:id="@+id/linLayout_Lesson">
android:orientation="horizontal">
<TextView
android:id="@+id/txtView_Lesson"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/a_lesson"
android:textColor="@android:color/primary_text_light"
android:textSize="14sp"
android:textStyle="bold"
android:typeface="sans"/>
<TextView <TextView
android:id="@+id/txtView_Time" android:id="@+id/txtView_Time"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -4,14 +4,15 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height" android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar" android:background="@color/colorPrimary"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark" android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:orientation="vertical" android:orientation="vertical"
android:gravity="bottom"> android:gravity="bottom"
android:id="@+id/nav_header_main">
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -10,8 +10,9 @@
<string name="meal_1_tomorrow">Essen 1, Morgen</string> <string name="meal_1_tomorrow">Essen 1, Morgen</string>
<string name="meal_2_tomorrow">Essen 1, Morgen</string> <string name="meal_2_tomorrow">Essen 1, Morgen</string>
<string name="no_meal_today">heute keine Essensausgabe</string> <string name="no_meal_today">heute keine Essensausgabe</string>
<string name="no_meal_tomorrow">morgen keine Essensausgabe</string>
<string name="no_more_food">Diese Woche keine weitere Essensausgabe</string> <string name="no_more_food">Diese Woche keine weitere Essensausgabe</string>
<string name="no_lesson_today">heute keine Vorlesung</string> <string name="no_lesson_today">heute keine Vorlesung!</string>
<string name="error">Fehler</string> <string name="error">Fehler</string>
<string name="no_tt_error">Stundenplan konnte nicht geladen werden!</string> <string name="no_tt_error">Stundenplan konnte nicht geladen werden!</string>
<string name="gen_tt_error">Allgemeiner Stundenplan Fehler!"</string> <string name="gen_tt_error">Allgemeiner Stundenplan Fehler!"</string>

View File

@ -2,7 +2,7 @@
<string name="app_name" translatable="false">Project Laogai</string> <string name="app_name" translatable="false">Project Laogai</string>
<string name="navigation_drawer_open">Open navigation drawer</string> <string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string> <string name="navigation_drawer_close">Close navigation drawer</string>
<string name="nav_header_title" translatable="false">hso App 0.3.1</string> <string name="nav_header_title" translatable="false">hso App 0.3.3</string>
<string name="nav_header_subtitle" translatable="false">seil0@mosad.xyz</string> <string name="nav_header_subtitle" translatable="false">seil0@mosad.xyz</string>
<string name="nav_header_desc" translatable="false">Project Laogai</string> <string name="nav_header_desc" translatable="false">Project Laogai</string>
@ -17,9 +17,10 @@
<string name="meal_1_tomorrow">Meal 1, tomorrow</string> <string name="meal_1_tomorrow">Meal 1, tomorrow</string>
<string name="meal_2_tomorrow">Meal 2, tomorrow</string> <string name="meal_2_tomorrow">Meal 2, tomorrow</string>
<string name="no_meal_today">Mensa closed today</string> <string name="no_meal_today">Mensa closed today</string>
<string name="no_meal_tomorrow">Mensa closed tomorrow</string>
<string name="no_more_food">No more Food this week</string> <string name="no_more_food">No more Food this week</string>
<string name="no_lesson_today">"no lecture today "</string> <string name="no_lesson_today">"No lecture today!"</string>
<string name="error">Error</string> <string name="error">Error</string>
<string name="no_tt_error">Could not load timetable!"</string> <string name="no_tt_error">Could not load timetable!"</string>
<string name="gen_tt_error">There was an error with the timetable!"</string> <string name="gen_tt_error">There was an error with the timetable!"</string>
@ -36,11 +37,11 @@
<string name="primary_color">primary color</string> <string name="primary_color">primary color</string>
<string name="main_color_desc">The primary color, default is black</string> <string name="main_color_desc">The primary color, default is black</string>
<string name="select">select</string> <string name="select">select</string>
<string name="version" translatable="false">version 0.3.1</string> <string name="version" translatable="false">version 0.3.3</string>
<string name="about">about</string> <string name="about">about</string>
<string name="about_txtView" translatable="false">hso App by @Seil0</string> <string name="about_txtView" translatable="false">hso App by @Seil0</string>
<string name="about_text" translatable="false">"This software is made by @Seil0 and is published under the terms and <string name="about_text" translatable="false">"This software is made by @Seil0 and is published under the terms and
conditions of GPL 3. For further information visit \ngit.mosad.xyz/Seil0/ProjectLaogai \n\n© 2018 conditions of GPL 3. For further information visit \ngit.mosad.xyz/Seil0/ProjectLaogai \n\n© 2018-2019
seil0@mosad.xyz " seil0@mosad.xyz "
</string> </string>
<string name="loading_timetable">loading timetable …</string> <string name="loading_timetable">loading timetable …</string>
@ -50,4 +51,5 @@
<string name="save_key_course" translatable="false">org.mosad.seil0.projectlaogai.course</string> <string name="save_key_course" translatable="false">org.mosad.seil0.projectlaogai.course</string>
<string name="save_key_courseTTLink" translatable="false">org.mosad.seil0.projectlaogai.courseTTLink</string> <string name="save_key_courseTTLink" translatable="false">org.mosad.seil0.projectlaogai.courseTTLink</string>
<string name="save_key_colorPrimary" translatable="false">org.mosad.seil0.projectlaogai.colorPrimary</string>
</resources> </resources>

View File

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.3.10' ext.kotlin_version = '1.3.21'
repositories { repositories {
google() google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.2.1' classpath 'com.android.tools.build:gradle:3.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong