Browse Source

the homescreen now shows the next day with a lecture

* fixed getTomorrowWeekIndex() since it would return 7 which is out of the arrays bounds
* minor clean up
pull/20/head
Jannik 3 years ago
parent
commit
750a808fbe
  1. 2
      app/build.gradle
  2. 4
      app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt
  3. 200
      app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt
  4. 49
      app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt
  5. 101
      app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt
  6. 14
      app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt
  7. 3
      app/src/main/res/drawable/background_splash.xml
  8. 1
      app/src/main/res/layout/fragment_home.xml
  9. 2
      app/src/main/res/layout/fragment_mensa.xml
  10. 2
      app/src/main/res/layout/linearlayout_meal.xml
  11. 3
      app/src/main/res/values-de-rDE/strings.xml
  12. 6
      app/src/main/res/values/strings.xml

2
app/build.gradle

@ -13,7 +13,7 @@ android {
minSdkVersion 21
targetSdkVersion 28
versionCode 11
versionName "0.3.97"
versionName "0.3.98"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "build_time", buildTime()
}

4
app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt

@ -174,8 +174,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
cal.time = Date(timetableCacheTime * 1000)
val timetableCacheDay = cal.get(Calendar.DAY_OF_WEEK)
// if the last update was on moday and now its a sunday, update before displaying the timetable
// TODO this sill backfire if someone has to update before the server finished updateing the timetable at 0001/0101
// if the last update was on monday and now its a sunday, update before displaying the timetable
// TODO this sill backfire if someone has to update before the server finished updating the timetable at 0001/0101
if(currentDay == Calendar.MONDAY && timetableCacheDay == Calendar.SUNDAY) {
println("updating timetable after sunday!")
val jobA = tcor.getTimetable(cCourse.courseName, 0)

200
app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt

@ -40,6 +40,7 @@ import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timeta
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.Meal
import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar
import org.mosad.seil0.projectlaogai.hsoparser.TimetableDay
import org.mosad.seil0.projectlaogai.uicomponents.DayCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonLinearLayout
import org.mosad.seil0.projectlaogai.uicomponents.MealLinearLayout
@ -52,13 +53,13 @@ import java.util.*
*/
class HomeFragment : Fragment() {
val formatter = SimpleDateFormat("E dd.MM", Locale.GERMANY)
private val formatter = SimpleDateFormat("E dd.MM", Locale.getDefault())
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_home, container, false)
addMensaMenu()
addMensaMenu().get()
addTimeTable()
// Inflate the layout for this fragment
@ -68,56 +69,46 @@ class HomeFragment : Fragment() {
/**
* add the current mensa meal to the home screens
*/
private fun addMensaMenu() {
doAsync {
private fun addMensaMenu() = doAsync {
var dayMeals: ArrayList<Meal>
val cal = Calendar.getInstance()
val mensaCardView = DayCardView(context!!)
var dayMeals: ArrayList<Meal>
val cal = Calendar.getInstance()
val mensaCardView = DayCardView(context!!)
uiThread {
uiThread {
if (cal.get(Calendar.HOUR_OF_DAY) < 15) {
dayMeals = mensaCurrentWeek.days[NotRetardedCalendar().getDayOfWeekIndex()].meals
mensaCardView.setDayHeading(resources.getString(R.string.today_date, formatter.format(cal.time)))
} else {
dayMeals = mensaCurrentWeek.days[NotRetardedCalendar().getTomorrowWeekIndex()].meals
cal.add(Calendar.DATE, 1)
mensaCardView.setDayHeading(resources.getString(R.string.tomorrow_date, formatter.format(cal.time)))
}
if (cal.get(Calendar.HOUR_OF_DAY) < 15) {
dayMeals = mensaCurrentWeek.days[NotRetardedCalendar().getDayOfWeekIndex()].meals
mensaCardView.setDayHeading(resources.getString(R.string.today_date, formatter.format(cal.time)))
} else {
dayMeals = mensaCurrentWeek.days[NotRetardedCalendar().getTomorrowWeekIndex()].meals
cal.add(Calendar.DATE, 1)
mensaCardView.setDayHeading(resources.getString(R.string.tomorrow_date, formatter.format(cal.time)))
}
if (dayMeals.size >= 2) {
// get the index of the first meal, not a "Schneller Teller"
loop@ for ((i, meal) in dayMeals.withIndex()) {
if (meal.heading.contains("Essen")) {
if (dayMeals.size >= 2) {
// get the index of the first meal, not a "Schneller Teller"
loop@ for ((i, meal) in dayMeals.withIndex()) {
if (meal.heading.contains("Essen")) {
val meal1Layout = MealLinearLayout(context)
meal1Layout.setMeal(dayMeals[i])
mensaCardView.getLinLayoutDay().addView(meal1Layout)
val meal1Layout = MealLinearLayout(context)
meal1Layout.setMeal(dayMeals[i])
mensaCardView.getLinLayoutDay().addView(meal1Layout)
val meal2Layout = MealLinearLayout(context)
meal2Layout.setMeal(dayMeals[i + 1])
meal2Layout.disableDivider()
mensaCardView.getLinLayoutDay().addView(meal2Layout)
val meal2Layout = MealLinearLayout(context)
meal2Layout.setMeal(dayMeals[i + 1])
meal2Layout.disableDivider()
mensaCardView.getLinLayoutDay().addView(meal2Layout)
break@loop
}
break@loop
}
} else {
val noFood = TextView(context)
noFood.text = resources.getString(R.string.mensa_closed)
noFood.setTextColor(ContextCompat.getColor(context!!, R.color.textPrimary))
noFood.textSize = 18.0F
noFood.setTypeface(null, Typeface.BOLD)
noFood.textAlignment = View.TEXT_ALIGNMENT_CENTER
noFood.setPadding(7,7,7,7)
mensaCardView.getLinLayoutDay().addView(noFood)
}
linLayout_Home.addView(mensaCardView)
} else {
mensaCardView.getLinLayoutDay().addView(getNoCard(resources.getString(R.string.mensa_closed)))
}
linLayout_Home.addView(mensaCardView)
}
}
@ -125,67 +116,104 @@ class HomeFragment : Fragment() {
/**
* add the current timetable to the home screen
*/
private fun addTimeTable() {
private fun addTimeTable() = doAsync {
val dayIndex = NotRetardedCalendar().getDayOfWeekIndex()
var helpLesson = LessonLinearLayout(context!!)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(resources.getString(R.string.today_date, formatter.format(Calendar.getInstance().time)))
val cal = Calendar.getInstance()
var dayCardView = DayCardView(context!!)
uiThread {
if (timetables.isNotEmpty() && dayIndex < 6) {
// first check the current day
dayCardView = addDayTimetable(timetables[0].days[dayIndex])
dayCardView.setDayHeading(resources.getString(R.string.today_date, formatter.format(cal.time)))
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount <= 1) {
// get next day with at least one lecture
var dayTimetable: TimetableDay? = null
var weekIndex = 0
var dayIndexSearch = dayIndex + 1
loop@ while (dayTimetable == null && weekIndex <= timetables.size) {
for (i in (dayIndexSearch) ..5) {
dayTimetable = timetables[weekIndex].days[i]
cal.add(Calendar.DATE, 1)
// add the timetable to the card, if it contains at least one lesson break!
dayCardView = addDayTimetable(dayTimetable)
dayCardView.setDayHeading(formatter.format(cal.time))
if (dayCardView.getLinLayoutDay().childCount > 1)
break@loop
}
dayIndexSearch = 0
weekIndex++
cal.add(Calendar.DATE, 1)
}
}
doAsync {
uiThread {
if (dayCardView.getLinLayoutDay().childCount <= 1)
dayCardView.getLinLayoutDay().addView(getNoCard(resources.getString(R.string.no_lesson_today))) // if there is no lecture at all show the no lesson card
if (timetables[0].days.isNotEmpty() && dayIndex < 6) {
linLayout_Home.addView(dayCardView)
} else {
if (dayIndex == 6) {
// TODO iss this necessary?
// if that's the case it's sunday
dayCardView.getLinLayoutDay().addView(getNoCard(resources.getString(R.string.no_lesson_today)))
linLayout_Home.addView(dayCardView)
} else {
MaterialDialog(context!!)
.title(R.string.error)
.message(R.string.gen_tt_error)
.show()
// TODO log the error and send feedback
}
// for all timeslots of the day
for ((tsIndex, timeslot) in timetables[0].days[dayIndex].timeslots.withIndex()) {
}
for(lesson in timeslot) {
if(lesson.lessonSubject.isNotEmpty()) {
}
val lessonLayout = LessonLinearLayout(context!!)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
}
if (lesson != timeslot.last()) {
lessonLayout.disableDivider()
}
private fun addDayTimetable(dayTimetable: TimetableDay) : DayCardView{
var helpLesson = LessonLinearLayout(context)
val dayCardView = DayCardView(context!!)
helpLesson = lessonLayout
}
}
}
for ((tsIndex, timeslot) in dayTimetable.timeslots.withIndex()) {
helpLesson.disableDivider()
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1) {
linLayout_Home.addView(dayCardView)
} else {
// TODO we could display the next day with a lecture
val noLesson = DayCardView(context!!)
noLesson.setDayHeading(resources.getString(R.string.no_lesson_today))
for(lesson in timeslot) {
if(lesson.lessonSubject.isNotEmpty()) {
linLayout_Home.addView(noLesson)
}
} else {
if (dayIndex == 6) {
// if that's the case it's sunday
val noLesson = DayCardView(context!!)
noLesson.setDayHeading(resources.getString(R.string.no_lesson_today))
linLayout_Home.addView(noLesson)
} else {
MaterialDialog(context!!)
.title(R.string.error)
.message(R.string.gen_tt_error)
.show()
// TODO log the error and send feedback
val lessonLayout = LessonLinearLayout(context)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
if (lesson != timeslot.last()) {
lessonLayout.disableDivider()
}
helpLesson = lessonLayout
}
}
}
helpLesson.disableDivider()
return dayCardView
}
private fun getNoCard(text: String): TextView {
val noLesson = TextView(context)
noLesson.text = text
noLesson.setTextColor(ContextCompat.getColor(context!!, R.color.textPrimary))
noLesson.textSize = 18.0F
noLesson.setTypeface(null, Typeface.BOLD)
noLesson.textAlignment = View.TEXT_ALIGNMENT_CENTER
noLesson.setPadding(7,7,7,7)
return noLesson
}
}

49
app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt

@ -56,10 +56,10 @@ class MensaFragment : Fragment() {
// add the current week (week starts on sunday)
val dayCurrent = if(NotRetardedCalendar().getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar().getDayOfWeekIndex()
addWeek(mensaCurrentWeek, dayCurrent)
addWeek(mensaCurrentWeek, dayCurrent).get()
// add the next week
addWeek(mensaNextWeek, 0)
addWeek(mensaNextWeek, 0).get()
return view
}
@ -67,41 +67,32 @@ class MensaFragment : Fragment() {
/**
* add all menus from dayStart to Friday for a given week
*/
private fun addWeek(menusWeek: MensaWeek, dayStart: Int) {
private fun addWeek(menusWeek: MensaWeek, dayStart: Int) = doAsync {
doAsync {
uiThread {
uiThread {
// only add the days dayStart to Fri since the mensa is closed on Sat/Sun
for (dayIndex in dayStart..4) {
var helpMeal = MealLinearLayout(context)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(menusWeek.days[dayIndex].meals[0].day)
// only add the days dayStart to Fri since the mensa is closed on Sat/Sun
for (dayIndex in dayStart..4) {
var helpMeal = MealLinearLayout(context)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(menusWeek.days[dayIndex].meals[0].day)
for (meal in menusWeek.days[dayIndex].meals) {
val mealLayout = MealLinearLayout(context)
mealLayout.setMeal(meal)
for (meal in menusWeek.days[dayIndex].meals) {
val mealLayout = MealLinearLayout(context)
mealLayout.setMeal(meal)
if(meal.heading != "Buffet" || cShowBuffet) {
dayCardView.getLinLayoutDay().addView(mealLayout)
helpMeal = mealLayout
}
if(meal.heading != "Buffet" || cShowBuffet) {
dayCardView.getLinLayoutDay().addView(mealLayout)
helpMeal = mealLayout
}
helpMeal.disableDivider()
if(dayCardView.getLinLayoutDay().childCount > 1)
linLayoutMensaFragment.addView(dayCardView)
}
// add a card if there are no more meals in this week
if(linLayoutMensaFragment.childCount == 0) {
val noFood = DayCardView(context!!)
noFood.setDayHeading(resources.getString(R.string.no_more_food))
linLayout_Mensa.addView(noFood)
}
helpMeal.disableDivider()
if(dayCardView.getLinLayoutDay().childCount > 1)
linLayout_Mensa.addView(dayCardView)
}
}
}

101
app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt

@ -60,91 +60,84 @@ class TimeTableFragment : Fragment() {
/**
* add the all days with at least one lesson to the timetable screen
*/
private fun addWeeks() {
private fun addWeeks() = doAsync {
val dayIndex = NotRetardedCalendar().getDayOfWeekIndex()
val formatter = SimpleDateFormat("E dd.MM", Locale.GERMANY) // TODO change to android call when min api is 24
val calendar = Calendar.getInstance()
doAsync {
uiThread {
uiThread {
// add the current week
for (day in dayIndex..5) {
var helpLesson = LessonLinearLayout(context)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(formatter.format(calendar.time))
// add the current week
for (day in dayIndex..5) {
var helpLesson = LessonLinearLayout(context)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(formatter.format(calendar.time))
// for each timeslot of the day
for ((tsIndex, timeslot) in timetables[0].days[day].timeslots.withIndex()) {
// for each timeslot of the day
for ((tsIndex, timeslot) in timetables[0].days[day].timeslots.withIndex()) {
for(lesson in timeslot) {
for(lesson in timeslot) {
if(lesson.lessonSubject.isNotEmpty()) {
if(lesson.lessonSubject.isNotEmpty()) {
val lessonLayout = LessonLinearLayout(context)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
val lessonLayout = LessonLinearLayout(context)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
if (lesson != timeslot.last())
lessonLayout.disableDivider()
if (lesson != timeslot.last()) {
lessonLayout.disableDivider()
}
helpLesson = lessonLayout
}
helpLesson = lessonLayout
}
}
helpLesson.disableDivider()
calendar.add(Calendar.DATE, 1)
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1) {
linLayout_Timetable.addView(dayCardView)
}
}
helpLesson.disableDivider()
calendar.add(Calendar.DATE, 1)
calendar.add(Calendar.DATE, 1) // before this we are at a sunday (no lecture on sundays!)
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1)
linLayout_Timetable.addView(dayCardView)
// add the next week
for (day in 0..(dayIndex - 1)) {
var helpLesson = LessonLinearLayout(context!!)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(formatter.format(calendar.time))
}
// for each timeslot of the day
for ((tsIndex, timeslot) in timetables[1].days[day].timeslots.withIndex()) {
calendar.add(Calendar.DATE, 1) // before this we are at a sunday (no lecture on sundays!)
for(lesson in timeslot) {
// add the next week
for (day in 0..(dayIndex - 1)) {
var helpLesson = LessonLinearLayout(context!!)
val dayCardView = DayCardView(context!!)
dayCardView.setDayHeading(formatter.format(calendar.time))
if(lesson.lessonSubject.isNotEmpty()) {
// for each timeslot of the day
for ((tsIndex, timeslot) in timetables[1].days[day].timeslots.withIndex()) {
val lessonLayout = LessonLinearLayout(context!!)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
for(lesson in timeslot) {
if (lesson != timeslot.last()) {
lessonLayout.disableDivider()
}
if(lesson.lessonSubject.isNotEmpty()) {
helpLesson = lessonLayout
}
}
}
val lessonLayout = LessonLinearLayout(context!!)
lessonLayout.setLesson(lesson, DataTypes().getTime()[tsIndex])
dayCardView.getLinLayoutDay().addView(lessonLayout)
helpLesson.disableDivider()
calendar.add(Calendar.DATE, 1)
if (lesson != timeslot.last())
lessonLayout.disableDivider()
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1) {
linLayout_Timetable.addView(dayCardView)
helpLesson = lessonLayout
}
}
}
helpLesson.disableDivider()
calendar.add(Calendar.DATE, 1)
// if there are no lessons don't show the dayCardView
if (dayCardView.getLinLayoutDay().childCount > 1)
linLayout_Timetable.addView(dayCardView)
}
}
}

14
app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt

@ -98,14 +98,14 @@ class NotRetardedCalendar {
}
fun getTomorrowWeekIndex(): Int {
return when(calendar.get(Calendar.DAY_OF_WEEK) + 1) {
Calendar.MONDAY -> 0
Calendar.TUESDAY -> 1
return when(calendar.get(Calendar.DAY_OF_WEEK)) {
Calendar.MONDAY -> 1
Calendar.TUESDAY -> 2
Calendar.WEDNESDAY -> 2
Calendar.THURSDAY -> 3
Calendar.FRIDAY -> 4
Calendar.SATURDAY -> 5
Calendar.SUNDAY -> 6
Calendar.THURSDAY -> 4
Calendar.FRIDAY -> 5
Calendar.SATURDAY -> 6
Calendar.SUNDAY -> 0
else -> 7
}
}

3
app/src/main/res/drawable/background_splash.xml

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@color/colorPrimary"/>
<item android:drawable="@color/colorPrimary"/>
<!--TODO when minAPI is 23 use this-->
<!--<item android:gravity="center" android:width="144dp" android:height="144dp">-->

1
app/src/main/res/layout/fragment_home.xml

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.HomeFragment">

2
app/src/main/res/layout/fragment_mensa.xml

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.MensaFragment">

2
app/src/main/res/layout/linearlayout_meal.xml

@ -5,7 +5,7 @@
android:layout_height="match_parent" android:id="@+id/linLayout_Meal" android:padding="7dp">
<TextView
android:text="@string/meal_1"
android:text="@string/meal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:id="@+id/txtView_MealHeading" android:textSize="18sp"
android:textColor="@color/textPrimary" android:textAlignment="center" android:paddingBottom="5dp"

3
app/src/main/res/values-de-rDE/strings.xml

@ -5,8 +5,7 @@
<string name="timetable">Stundenplan</string>
<string name="moodle">Moodle</string>
<string name="settings">Einstellungen</string>
<string name="meal_1">Essen 1</string>
<string name="meal_2">Essen 2</string>
<string name="meal">Essen</string>
<string name="today_date">Heute, %1$s</string>
<string name="tomorrow_date">Morgen, %1$s</string>
<string name="mensa_closed">keine Essensausgabe</string>

6
app/src/main/res/values/strings.xml

@ -12,8 +12,7 @@
<string name="moodle">Moodle</string>
<string name="settings">Settings</string>
<string name="meal_1">Meal 1</string>
<string name="meal_2">Meal 2</string>
<string name="meal">Meal</string>
<string name="today_date">Today, %1$s</string>
<string name="tomorrow_date">Tomorrow, %1$s</string>
<string name="mensa_closed">the Mensa is closed</string>
@ -27,7 +26,6 @@
<string name="sample_user" translatable="false">SampleUser@stud.hs-offenburg.de</string>
<string name="sample_course" translatable="false">SampleCourse 3</string>
<string name="sample_date" translatable="false">Montag, 30.02</string>
<string name="a_lesson" translatable="false">a lesson\na teacher\na room</string>
<string name="a_time" translatable="false">0.00 – 23.59</string>
<string name="info">Info</string>
@ -46,8 +44,6 @@
<string name="about_dialog_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>
<string name="string_new_line" translatable="false">%1$s\n</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_colorPrimary" translatable="false">org.mosad.seil0.projectlaogai.colorPrimary</string>

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close