23 Commits
0.3.0 ... 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
3d7f6f961a the menus text is now selectable
* fixed some formating errors at the mensa screen
2018-11-26 12:56:06 +01:00
f97e8b2b14 fixed text overlapping and some crashes 2018-11-26 11:17:07 +01:00
deaf139b70 updated some libraries 2018-11-22 18:07:30 +01:00
bf48bec16b minor fixes 2018-11-19 12:00:39 +01:00
27 changed files with 585 additions and 286 deletions

View File

@ -1,12 +1,13 @@
# 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
* look up what you can eat in the mensa
* check your timetable
* probably many many bugs
* probably some funny bugs
## 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 © 2018 mosad www.mosad.xyz, Project by [@Seil0](https://git.mosad.xyz/Seil0)
ProjectLaogai © 2019 mosad [www.mosad.xyz](http://www.mosad.xyz), Project by [@Seil0](https://git.mosad.xyz/Seil0)

View File

@ -12,8 +12,8 @@ android {
applicationId "org.mosad.seil0.projectlaogai"
minSdkVersion 21
targetSdkVersion 28
versionCode 8
versionName "0.3.0"
versionCode 11
versionName "0.3.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@ -32,12 +32,14 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.legacy:legacy-support-v4: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.jetbrains.anko:anko-commons:0.10.7'
implementation 'com.afollestad.material-dialogs:core:2.0.0-beta5'
implementation 'com.afollestad.material-dialogs:color:2.0.0-beta5'
implementation 'org.jetbrains.anko:anko-commons:0.10.8'
implementation 'com.afollestad:aesthetic:1.0.0-beta05'
implementation 'com.afollestad.material-dialogs:core:2.0.3'
implementation 'com.afollestad.material-dialogs:color:2.0.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

View File

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

View File

@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -22,52 +22,67 @@
package org.mosad.seil0.projectlaogai
import android.graphics.Color
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.navigation.NavigationView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar_main.*
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import org.mosad.seil0.projectlaogai.fragments.HomeFragment
import org.mosad.seil0.projectlaogai.fragments.MensaFragment
import org.mosad.seil0.projectlaogai.fragments.SettingsFragment
import org.mosad.seil0.projectlaogai.fragments.TimeTableFragment
import org.mosad.seil0.projectlaogai.hsoparser.*
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.hsoparser.MensaParser
import org.mosad.seil0.projectlaogai.hsoparser.TimeTableParser
import kotlin.system.measureTimeMillis
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
//TODO make toolbar and navbar global
private val mensaParser = MensaParser()
private val timeTableParser = TimeTableParser()
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
private var activeFragment: Fragment = HomeFragment() // the currently active fragment, home at the start
override fun onCreate(savedInstanceState: Bundle?) {
Aesthetic.attach(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
// load mensa and timetable
// load mensa, timetable and color
load()
//init home fragment TODO make a abstract fragment class
val homeFragment = HomeFragment()
homeFragment.setMainActivity(this)
// If we haven't set any defaults, do that now
if (Aesthetic.isFirstTime) {
// 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()
fragmentTransaction.replace(R.id.fragment_container, homeFragment)
fragmentTransaction.replace(R.id.fragment_container, activeFragment)
fragmentTransaction.commit()
val toggle = ActionBarDrawerToggle(
@ -79,6 +94,16 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
nav_view.setNavigationItemSelectedListener(this)
}
override fun onResume() {
super.onResume()
Aesthetic.resume(this)
}
override fun onPause() {
super.onPause()
Aesthetic.pause(this)
}
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
drawer_layout.closeDrawer(GravityCompat.START)
@ -107,104 +132,58 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
// Handle navigation view item clicks here.
when (item.itemId) {
R.id.nav_home -> {
val homeFragment = HomeFragment()
homeFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, homeFragment)
fragmentTransaction.commit()
activeFragment = HomeFragment()
}
R.id.nav_mensa -> {
val mensaFragment = MensaFragment()
mensaFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, mensaFragment)
fragmentTransaction.commit()
activeFragment = MensaFragment()
}
R.id.nav_timetable -> {
val timeTableFragment = TimeTableFragment()
timeTableFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, timeTableFragment)
fragmentTransaction.commit()
activeFragment = TimeTableFragment()
}
R.id.nav_moodle -> {
activeFragment = MoodleFragment()
}
R.id.nav_settings -> {
val settingsFragment = SettingsFragment()
settingsFragment.setMainActivity(this)
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, settingsFragment)
fragmentTransaction.commit()
activeFragment = SettingsFragment()
}
}
val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragment_container, activeFragment)
fragmentTransaction.commit()
drawer_layout.closeDrawer(GravityCompat.START)
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
* TODO evaluate if we should use a timeout here
*/
private fun load() {
// load saved course
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 the settings
PreferencesController.load(this) // this must be finished before doing anything else
/**
* load mensa, course timetable and courselist from the swfr/hso website
* TODO make an API see https://git.mosad.xyz/Seil0/TheCitadelofRicks
*/
val time = measureTimeMillis {
/* getting the course list should be faster than the timetable,
* we need have time until the user opens the dialog
*/
doAsync {
courseTTLinkList = timeTableParser.getCourseTTLinks()
cCourseTTLinkList = timeTableParser.getCourseTTLinks()
}
doAsync {
val jobMenus = doAsync {
cWeekMenus = mensaParser.getMensaMenu()
}
val jobTTCurrentWeek = doAsync {
try {
timeTableNextWeek = timeTableParser.getTimeTable(course.courseTTLink.replace("week=0","week=1"))
} catch (e: Exception) {
e.stackTrace
}
}
val t1 = doAsync {
weekMenus = mensaParser.getMensaMenu()
}
val t2 = doAsync {
try {
timeTableCurrentWeek = timeTableParser.getTimeTable(course.courseTTLink)
cTimeTableCurrentWeek = timeTableParser.getTimeTable(cCourse.courseLink)
timeTableParser.printTimeTableWeek(cTimeTableCurrentWeek)
} catch (e: Exception) {
uiThread {
@ -218,31 +197,19 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
}
}
t1.get()
t2.get()
val jobTTNextWeek = doAsync {
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")
}
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
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -32,10 +32,12 @@ import com.afollestad.materialdialogs.MaterialDialog
import kotlinx.android.synthetic.main.fragment_home.*
import org.jetbrains.anko.doAsync
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.hsoparser.*
import org.mosad.seil0.projectlaogai.uicomponents.LessonCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonTextView
import java.util.*
/**
@ -45,7 +47,6 @@ import java.util.*
class HomeFragment : Fragment() {
private lateinit var linLayoutTimeTable: LinearLayout
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -70,13 +71,11 @@ class HomeFragment : Fragment() {
val dayMenus: ArrayList<Meal>
val cal = Calendar.getInstance()
// TODO needs testing
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 {
dayMenus = MensaParser().getMensaMenuDay(mainActivity.getWeekMenu(), cal.get(Calendar.DAY_OF_WEEK) + 1)
dayMenus = MensaParser().getMensaMenuDay(cWeekMenus, cal.get(Calendar.DAY_OF_WEEK) + 1)
uiThread {
// TODO Mensa closed today is showing
txtView_Menu1Heading.text = resources.getString(R.string.meal_1_tomorrow)
txtView_Menu2Heading.text = resources.getString(R.string.meal_2_tomorrow)
}
@ -87,13 +86,17 @@ class HomeFragment : Fragment() {
if (dayMenus.size >= 2) {
// get the index of the first meal, not a "Schneller Teller"
loop@ for ((i, meal) in dayMenus.withIndex()) {
if(meal.heading.contains("Essen")) {
for (part in dayMenus[i].parts) {
if (meal.heading.contains("Essen")) {
for ((j, part) in dayMenus[i].parts.withIndex()) {
txtViewMenu1.append(part)
if (j < (dayMenus[i].parts.size - 2))
txtViewMenu1.append("\n")
}
for (part in dayMenus[i + 1].parts) {
for ((j, part) in dayMenus[i + 1].parts.withIndex()) {
txtViewMenu2.append(part)
if (j < (dayMenus[i + 1].parts.size - 2))
txtViewMenu2.append("\n")
}
break@loop
@ -101,8 +104,13 @@ class HomeFragment : Fragment() {
}
} else {
txtViewMenu1.text = resources.getString(R.string.no_meal_today)
txtViewMenu2.text = resources.getString(R.string.no_meal_today)
if (txtView_Menu1Heading.text == resources.getString(R.string.meal_1_tomorrow)) {
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)
}
}
}
}
@ -115,34 +123,48 @@ class HomeFragment : Fragment() {
private fun addCurrentTimeTable() {
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)
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]
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)
}
// add a card if there is no lesson today
if (linLayoutTimeTable.childCount == 0) {
// 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)
noLessonCardView.getTxtViewLesson().text = resources.getString(R.string.no_lesson_today)
noLessonCardView.getLinLayoutLesson().addView(lessonTxtView)
linLayoutTimeTable.addView(noLessonCardView)
}
} else {
if (dayIndex == 6) {
// 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)
noLessonCardView.getTxtViewLesson().text = resources.getString(R.string.no_lesson_today)
noLessonCardView.getLinLayoutLesson().addView(lessonTxtView)
linLayoutTimeTable.addView(noLessonCardView)
} else {
MaterialDialog(context!!)
@ -155,8 +177,4 @@ class HomeFragment : Fragment() {
}
}
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
}

View File

@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -30,7 +30,7 @@ import android.view.ViewGroup
import android.widget.LinearLayout
import org.jetbrains.anko.doAsync
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.uicomponents.MensaDayCardView
import org.mosad.seil0.projectlaogai.uicomponents.MenuCardView
@ -43,7 +43,6 @@ import java.util.*
class MensaFragment : Fragment() {
private lateinit var linLayoutMensaFragment: LinearLayout
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -77,18 +76,20 @@ class MensaFragment : Fragment() {
val cardViewMensaDay = MensaDayCardView(context!!, null)
var add = false
for (meal in mainActivity.getWeekMenu()) {
for (meal in cWeekMenus) {
//println("Day: " + meal.day)
if (meal.day.contains(strDay)) {
val menuViewMenu = MenuCardView(context!!, null)
menuViewMenu.setMenuHeading(meal.heading)
for(part in meal.parts) {
for ((i, part) in meal.parts.withIndex()) {
menuViewMenu.getTxtViewMenu().append(part)
if(i < (meal.parts.size - 2))
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)
add = true
}
@ -110,8 +111,4 @@ class MensaFragment : Fragment() {
}
}
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
}

View File

@ -0,0 +1,58 @@
/**
* 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
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebSettings
import android.webkit.WebView
import org.mosad.seil0.projectlaogai.R
import android.webkit.WebViewClient
/**
* The moodle screen controller class
* contains all needed parts to display and the moodle screen
*/
class MoodleFragment : Fragment() {
private lateinit var webView: WebView
private lateinit var webSettings: WebSettings
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
}
}

View File

@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -24,11 +24,12 @@ package org.mosad.seil0.projectlaogai.fragments
import android.graphics.Color
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import com.afollestad.aesthetic.Aesthetic
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.color.colorChooser
import com.afollestad.materialdialogs.customview.customView
@ -36,10 +37,15 @@ import com.afollestad.materialdialogs.list.listItems
import kotlinx.android.synthetic.main.fragment_settings.*
import org.jetbrains.anko.doAsync
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.hsoparser.CourseTTLink
import java.util.ArrayList
import org.mosad.seil0.projectlaogai.hsoparser.TimeTableParser
import java.util.*
/**
* The settings controller class
@ -52,9 +58,6 @@ class SettingsFragment : Fragment() {
private lateinit var linLayoutInfo: LinearLayout
private lateinit var linLayoutMainColor: LinearLayout
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? {
@ -75,7 +78,7 @@ class SettingsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
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
val courseList = ArrayList<String>()
courseTTLinkList = mainActivity.getCourseTTLinkList()
courseTTLinkList.forEach { (_, course) ->
cCourseTTLinkList.forEach { (_, course) ->
courseList.add(course)
}
MaterialDialog(context!!).listItems(items = courseList){ _, index, text ->
MaterialDialog(context!!).listItems(items = courseList) { _, index, text ->
txtView_Course.text = text // update txtView
val dialog = MaterialDialog(context!!).cancelable(false)
@ -104,7 +106,12 @@ class SettingsFragment : Fragment() {
dialog.show()
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 {
dialog.dismiss()
@ -112,7 +119,7 @@ class SettingsFragment : Fragment() {
}
}
.show()
.show()
}
linLayoutInfo.setOnClickListener {
@ -125,20 +132,24 @@ class SettingsFragment : Fragment() {
linLayoutMainColor.setOnClickListener {
// open a new color chooser dialog
val colors = intArrayOf(Color.parseColor("#3F51B5"), Color.RED, Color.GREEN, Color.BLUE)
val colors = intArrayOf(Color.BLACK, Color.DKGRAY, Color.RED, Color.GREEN, Color.YELLOW)
MaterialDialog(context!!)
.title(R.string.primary_color)
.colorChooser(colors, initialSelection = Color.parseColor("#3F51B5")) { _, color ->
.colorChooser(colors, allowCustomArgb = true, initialSelection = cColor) { _, color ->
viewPrimaryColor.setBackgroundColor(color)
Aesthetic.config {
colorPrimary(color)
colorPrimaryDark(color)
apply()
}
cColor = color
PreferencesController.save(context!!)
}
.positiveButton(R.string.select)
.show()
}
}
fun setMainActivity(mainActivity: MainActivity) {
this.mainActivity = mainActivity
}
}

View File

@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -22,20 +22,21 @@
package org.mosad.seil0.projectlaogai.fragments
import android.graphics.Color
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import org.jetbrains.anko.doAsync
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.hsoparser.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar
import org.mosad.seil0.projectlaogai.uicomponents.LessonCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonTextView
import org.mosad.seil0.projectlaogai.uicomponents.MensaDayCardView
import java.text.SimpleDateFormat
import java.util.*
@ -47,7 +48,6 @@ import java.util.*
class TimeTableFragment : Fragment() {
private lateinit var linLayoutTTFragment: LinearLayout
private var mainActivity = MainActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@ -55,7 +55,11 @@ class TimeTableFragment : Fragment() {
linLayoutTTFragment = view.findViewById(R.id.linLayout_TTFragment)
addCurrentWeek()
if (cTimeTableCurrentWeek.days.isNotEmpty()) {
addCurrentWeek()
} else {
// TODO show card with error msg
}
return view
}
@ -73,64 +77,95 @@ class TimeTableFragment : Fragment() {
uiThread {
// add current weeks days
for(day in dayIndex..5) {
for (day in dayIndex..5) {
val cardViewTimeTableDay = MensaDayCardView(context!!, null)
cardViewTimeTableDay.setDayHeading(formatter.format(calendar.time))
// for each lessen of the day
for((i, lesson) in mainActivity.getTimeTableCurrentWeek()[day].withIndex()) {
// for each timeslot of the day
for ((i, timeslot) in cTimeTableCurrentWeek.days[day].timeslots.withIndex()) {
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]
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)
}
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)
}
// add next weeks days, max number = dayIndex, if timetable was loaded
if (mainActivity.getTimeTableNextWeek().isNotEmpty()) {
calendar.add(Calendar.DATE,1) // before this we are at a sunday (no lecture on sundays!)
if (cTimeTableNextWeek.days.isNotEmpty()) {
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)
cardViewTimeTableDay.setDayHeading(formatter.format(calendar.time))
// for each lessen of the day
for((i, lesson) in mainActivity.getTimeTableNextWeek()[day].withIndex()) {
// for each timeslot of the day
for ((i, timeslot) in cTimeTableNextWeek.days[day].timeslots.withIndex()) {
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]
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)
}
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)
}
}
// 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
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -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 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
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -26,16 +26,12 @@ import org.jsoup.Jsoup
import java.util.*
class MensaParser {
private var mealList = ArrayList<Meal>()
init {
// do something
}
/**
* returns the mensa menu for the whole week
*/
fun getMensaMenu(): ArrayList<Meal> {
val mealList = ArrayList<Meal>()
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 ->
@ -43,7 +39,7 @@ class MensaParser {
for (i in 0 .. (element.select("div.row h4").size - 1)) {
try {
val heading = element.select("div.row h4")[i].text()
val parts = ArrayList<String>(element.select("div.row").select("div.menu-info")[i].html().substringBefore("<span").replace("<br>", "|").split("|"))
val parts = ArrayList<String>(element.select("div.row").select("div.menu-info")[i].html().substringBefore("<span").replace("<br>", " ").split("\n"))
val additives = element.select("div.row").select("div.menu-info")[i].select("span.show-with-allergenes").text()
mealList.add(Meal(day, heading, parts, additives))
@ -52,6 +48,7 @@ class MensaParser {
}
}
}
return mealList
}

View File

@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -26,52 +26,98 @@ import org.jsoup.Jsoup
class TimeTableParser {
private val days = arrayOf("Monday", "Tuesday" ,"Wednesday", "Thursday", "Friday", "Saturday")
private var courseTTLinkList = ArrayList<CourseTTLink>()
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
}
}
private var courseTTLinkList = ArrayList<Course>()
/**
* get the timetable from the given url
* 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
*/
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()
// 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()
//println("$week successful!\n")
scheduleHTML.select("table.timetable").select("td.lastcol").forEachIndexed { index, element ->
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())
val rows= scheduleHTML.select("table.timetable").select("tr[scope=\"row\"]")
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
}
/**
* 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()
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
}
@Suppress("unused")
fun printTimeTableWeek (timeTableWeek: Array<Array<Lesson>>) {
fun printTimeTableWeekOLD (timeTableWeek: Array<Array<Lesson>>) {
for (j in 0..5) print(days[j].padEnd(25 ,' ') + " | ")
println()
@ -88,7 +134,51 @@ class TimeTableParser {
for (j in 0..5) print("-".padEnd(26 + (j.toFloat().div(j).toInt()), '-') + "+")
println()
}
println(" \n")
}
@Suppress("unused")
fun printTimeTableWeek(timetable: TimeTable) {
for (j in 0..5) print(days[j].padEnd(75 ,' ') + " | ")
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
*
* Copyright 2018 <seil0@mosad.xyz>
* 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
@ -25,26 +25,27 @@ package org.mosad.seil0.projectlaogai.uicomponents
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.widget.LinearLayout
import android.widget.TextView
import org.mosad.seil0.projectlaogai.R
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
init {
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)
// workaround to prevent a white border
this.setBackgroundColor(Color.TRANSPARENT)
}
fun getTxtViewLesson(): TextView {
return txtViewLesson
fun getLinLayoutLesson(): LinearLayout {
return linLayoutLesson
}
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
*
* Copyright 2018 <seil0@mosad.xyz>
* 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

View File

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

View File

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

View File

@ -13,7 +13,7 @@
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="0dp"
android:layout_height="125dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
@ -28,7 +28,7 @@
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent" android:layout_marginBottom="2dp">
<TextView
android:text="@string/meal_1"
android:layout_width="match_parent"
@ -36,20 +36,22 @@
android:textStyle="bold" android:textAlignment="center" android:textSize="16sp"
android:typeface="sans" android:fontFamily="sans-serif" android:paddingBottom="5dp"/>
<TextView
android:id="@+id/txtViewMenu1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:textAlignment="center"
android:textSize="16sp"
android:textStyle="bold"
android:typeface="sans" android:id="@+id/txtViewMenu1"/>
android:typeface="sans"
android:textIsSelectable="true"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardView2"
android:layout_width="0dp"
android:layout_height="125dp"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
@ -60,7 +62,7 @@
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent" android:layout_marginBottom="2dp">
<TextView
android:text="@string/meal_2"
android:layout_width="match_parent"
@ -75,7 +77,8 @@
android:textAlignment="center"
android:textSize="16sp"
android:textStyle="bold"
android:typeface="sans"/>
android:typeface="sans"
android:textIsSelectable="true"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<ScrollView

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.MoodleFragment">
<!-- TODO: Update blank fragment layout -->
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="@+id/webView"/>
</FrameLayout>

View File

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

View File

@ -9,20 +9,9 @@
app:cardUseCompatPadding="true" app:cardPreventCornerOverlap="false" app:contentPadding="5dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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"/>
android:layout_height="match_parent" android:id="@+id/linLayout_Lesson">
<TextView
android:id="@+id/txtView_Time"
android:layout_width="match_parent"

View File

@ -35,7 +35,8 @@
android:textAlignment="center"
android:textSize="16sp"
android:textStyle="bold"
android:typeface="sans"/>
android:typeface="sans"
android:textIsSelectable="true"/>
</LinearLayout>
</androidx.cardview.widget.CardView>

View File

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

View File

@ -10,8 +10,9 @@
<string name="meal_1_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_tomorrow">morgen keine 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="no_tt_error">Stundenplan konnte nicht geladen werden!</string>
<string name="gen_tt_error">Allgemeiner Stundenplan Fehler!"</string>
@ -19,10 +20,10 @@
<string name="user">Benutzer</string>
<string name="course_desc">Tippen, um den Kurs zu ändern</string>
<string name="primary_color">Primärfarbe</string>
<string name="main_color_desc">Die Primärfarbe, standard ist Indigo</string>
<string name="main_color_desc">Die Primärfarbe, standard ist Schwarz</string>
<string name="select">auswählen</string>
<string name="about">über</string>
<string name="loading_timetable">lade Stundenplan …</string>
<string name="navigation_drawer_close">Navigationsleiste schließen</string>
<string name="navigation_drawer_open">Navigationsleiste öffnen</string>
</resources>
</resources>

View File

@ -2,7 +2,7 @@
<string name="app_name" translatable="false">Project Laogai</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="nav_header_title" translatable="false">hso App 0.3.0</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_desc" translatable="false">Project Laogai</string>
@ -17,9 +17,10 @@
<string name="meal_1_tomorrow">Meal 1, tomorrow</string>
<string name="meal_2_tomorrow">Meal 2, tomorrow</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_lesson_today">"no lecture today "</string>
<string name="no_lesson_today">"No lecture today!"</string>
<string name="error">Error</string>
<string name="no_tt_error">Could not load timetable!"</string>
<string name="gen_tt_error">There was an error with the timetable!"</string>
@ -34,12 +35,15 @@
<string name="user">User</string>
<string name="course_desc">Tap to change course</string>
<string name="primary_color">primary color</string>
<string name="main_color_desc">The primary color, default is indigo</string>
<string name="main_color_desc">The primary color, default is black</string>
<string name="select">select</string>
<string name="version" translatable="false">version 0.3.0</string>
<string name="version" translatable="false">version 0.3.3</string>
<string name="about">about</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 conditions of GPL 3. For further information visit \ngit.mosad.xyz/Seil0/ProjectLaogai \n\n© 2018 seil0@mosad.xyz "</string>
<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-2019
seil0@mosad.xyz "
</string>
<string name="loading_timetable">loading timetable …</string>
@ -47,4 +51,5 @@
<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_colorPrimary" translatable="false">org.mosad.seil0.projectlaogai.colorPrimary</string>
</resources>

View File

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.10'
ext.kotlin_version = '1.3.21'
repositories {
google()
jcenter()
}
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"
// NOTE: Do not place your application dependencies here; they belong