Skip to content
This repository has been archived by the owner on Jan 10, 2024. It is now read-only.

Added extra days to month-view #1600

Merged
merged 15 commits into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import de.tum.`in`.tumcampusapp.utils.Utils
import de.tum.`in`.tumcampusapp.utils.sync.SyncManager
import org.joda.time.DateTime
import org.joda.time.LocalDate
import java.time.YearMonth
import java.util.*
import kotlin.math.abs
CommanderStorm marked this conversation as resolved.
Show resolved Hide resolved

/**
* Calendar Manager, handles database stuff, external imports.
Expand Down Expand Up @@ -62,22 +64,44 @@ class CalendarController(private val context: Context) : ProvidesCard, ProvidesN
fun getFromDbNotCancelledBetweenDates(begin: DateTime, end: DateTime) =
applyEventColors(calendarDao.getAllNotCancelledBetweenDates(begin, end))

fun getEventsForMonth(date: LocalDate): Map<String, List<CalendarItem>> {
fun getEventsForMonth(date: LocalDate): Map<Int, List<CalendarItem>> {
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
val startOfMonth = date.withDayOfMonth(1)
val endOfMonth = date.withDayOfMonth(date.dayOfMonth().maximumValue)
val events = getFromDbBetweenDates(startOfMonth.toDateTimeAtCurrentTime(), endOfMonth.toDateTimeAtCurrentTime())
val eventMap = mutableMapOf<String, MutableList<CalendarItem>>()
val yearMonth = YearMonth.of(date.year, date.monthOfYear)
val start = startOfMonth.minusDays(yearMonth.minusMonths(1).lengthOfMonth() - startOfMonth.dayOfWeek)
val end = endOfMonth.plusDays(abs(42 - yearMonth.lengthOfMonth() - startOfMonth.dayOfWeek - 1))
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
val events = getFromDbBetweenDates(start.toDateTimeAtCurrentTime(), end.toDateTimeAtCurrentTime())
val eventMap = mutableMapOf<Int, MutableList<CalendarItem>>()
for (event in events) {
val day = event.dtstart.toLocalDate().dayOfMonth.toString()
if (!eventMap.containsKey(day)) {
eventMap[day] = mutableListOf(event)
val day = event.dtstart.toLocalDate()
val index = dayToIndex(day, date)
if (!eventMap.containsKey(index)) {
eventMap[index] = mutableListOf(event)
} else {
eventMap[day]?.add(event)
eventMap[index]?.add(event)
}
}
return eventMap
}

private fun dayToIndex(eventDate: LocalDate, date: LocalDate): Int {
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
val yearMonth = YearMonth.of(date.year, date.monthOfYear)
val daysInMonth = yearMonth.lengthOfMonth()
val daysInPreviousMonth = yearMonth.minusMonths(1).lengthOfMonth()
val firstOfMonth = date.withDayOfMonth(1)
val lastOfMonth = date.withDayOfMonth(date.dayOfMonth().maximumValue)
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
val dayOfWeek = firstOfMonth.dayOfWeek

val index = if (eventDate < firstOfMonth) {
eventDate.dayOfMonth - daysInPreviousMonth + dayOfWeek
} else if (eventDate > lastOfMonth) {
eventDate.dayOfMonth + dayOfWeek + daysInMonth
} else {
eventDate.dayOfMonth + dayOfWeek
}
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
return index
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
}

private fun applyEventColors(calendarItems: List<CalendarItem>): List<CalendarItem> {
calendarItems.forEach {
it.color = eventColorProvider.getColor(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormat
import java.time.YearMonth
import java.util.*
import kotlin.math.abs

class CalendarFragment :
FragmentForAccessingTumOnline<EventsResponse>(
R.layout.fragment_calendar,
R.string.calendar
),
CalendarDetailsFragment.OnEventInteractionListener {
FragmentForAccessingTumOnline<EventsResponse>(
Marius1501 marked this conversation as resolved.
Show resolved Hide resolved
R.layout.fragment_calendar,
R.string.calendar
),
CalendarDetailsFragment.OnEventInteractionListener {

private val calendarController: CalendarController by lazy {
CalendarController(requireContext())
Expand Down Expand Up @@ -184,10 +185,10 @@ class CalendarFragment :
scheduleNotifications(events)

compositeDisposable += Completable
.fromAction { calendarController.importCalendar(events) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onCalendarImportedIntoDatabase)
.fromAction { calendarController.importCalendar(events) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onCalendarImportedIntoDatabase)
}

private fun onCalendarImportedIntoDatabase() {
Expand Down Expand Up @@ -282,7 +283,7 @@ class CalendarFragment :

private fun initFilterCheckboxes() {
val showCancelledEvents =
Utils.getSettingBool(requireContext(), Const.CALENDAR_FILTER_CANCELED, true)
Utils.getSettingBool(requireContext(), Const.CALENDAR_FILTER_CANCELED, true)
Utils.log(if (showCancelledEvents) "Show cancelled events" else "Hide cancelled events")

menuItemFilterCanceled?.isChecked = showCancelledEvents
Expand All @@ -304,40 +305,40 @@ class CalendarFragment :
}

compositeDisposable += Completable
.fromAction { CalendarController.syncCalendar(requireContext()) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
if (isAdded) {
displayCalendarSyncSuccessDialog()
}
}, { throwable ->
Utils.log(throwable)
Utils.showToast(requireContext(), R.string.export_to_google_error)
})
.fromAction { CalendarController.syncCalendar(requireContext()) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
if (isAdded) {
displayCalendarSyncSuccessDialog()
}
}, { throwable ->
Utils.log(throwable)
Utils.showToast(requireContext(), R.string.export_to_google_error)
})
}

private fun isPermissionGranted(id: Int): Boolean {
if (checkSelfPermission(
requireContext(),
Manifest.permission.READ_CALENDAR
) == PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_CALENDAR
) == PackageManager.PERMISSION_GRANTED
requireContext(),
Manifest.permission.READ_CALENDAR
) == PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(
requireContext(),
Manifest.permission.WRITE_CALENDAR
) == PackageManager.PERMISSION_GRANTED
) {
return true
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CALENDAR) ||
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CALENDAR)
shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CALENDAR)
) {
ThemedAlertDialogBuilder(requireContext())
.setMessage(getString(R.string.permission_calendar_explanation))
.setPositiveButton(R.string.ok) { _, _ ->
showPermissionRequestDialog(id)
}
.show()
.setMessage(getString(R.string.permission_calendar_explanation))
.setPositiveButton(R.string.ok) { _, _ ->
showPermissionRequestDialog(id)
}
.show()
} else {
showPermissionRequestDialog(id)
}
Expand All @@ -346,7 +347,7 @@ class CalendarFragment :
}

private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
val hasPermissions = permissions.all { it.value }
if (hasPermissions) {
Expand All @@ -365,10 +366,10 @@ class CalendarFragment :

private fun displayCalendarSyncSuccessDialog() {
ThemedAlertDialogBuilder(requireContext())
.setMessage(getString(R.string.dialog_show_calendar))
.setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes) { _, _ -> displayCalendarOnGoogleCalendar() }
.show()
.setMessage(getString(R.string.dialog_show_calendar))
.setNegativeButton(R.string.no, null)
.setPositiveButton(R.string.yes) { _, _ -> displayCalendarOnGoogleCalendar() }
.show()
}

private fun displayCalendarOnGoogleCalendar() {
Expand All @@ -381,11 +382,11 @@ class CalendarFragment :
}

private fun prepareCalendarItems(
begin: DateTime,
end: DateTime
begin: DateTime,
end: DateTime
): List<WeekViewDisplayable<CalendarItem>> {
val showCancelledEvents =
Utils.getSettingBool(requireContext(), Const.CALENDAR_FILTER_CANCELED, true)
Utils.getSettingBool(requireContext(), Const.CALENDAR_FILTER_CANCELED, true)

val calendarItems = if (showCancelledEvents) {
calendarController.getFromDbBetweenDates(begin, end)
Expand All @@ -410,8 +411,8 @@ class CalendarFragment :
location.append(calendarItem.location)

while (i + 1 < calendarItems.size && calendarItem.isSameEventButForLocation(
calendarItems[i + 1]
)
calendarItems[i + 1]
)
) {
i++
location.append(" + ")
Expand Down Expand Up @@ -457,17 +458,17 @@ class CalendarFragment :
}

private val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode != Activity.RESULT_OK) {
val failed = result.data?.getStringExtra("failed") ?: 1
val sum = result.data?.getStringExtra("sum") ?: 1
ThemedAlertDialogBuilder(requireContext())
.setTitle(R.string.error_something_wrong)
.setMessage(getString(R.string.create_event_some_failed, failed, sum))
.setPositiveButton(R.string.ok, null)
.show()
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode != Activity.RESULT_OK) {
val failed = result.data?.getStringExtra("failed") ?: 1
val sum = result.data?.getStringExtra("sum") ?: 1
ThemedAlertDialogBuilder(requireContext())
.setTitle(R.string.error_something_wrong)
.setMessage(getString(R.string.create_event_some_failed, failed, sum))
.setPositiveButton(R.string.ok, null)
.show()
}
}
}

override fun onEventDeleted(eventId: String) {
val db = TcaDb.getInstance(requireContext())
Expand Down Expand Up @@ -521,17 +522,17 @@ class CalendarFragment :
binding.weekView.dateTimeInterpreter = object : DateTimeInterpreter {

private val timeFormat =
DateTimeFormat.forPattern("HH:mm").withLocale(Locale.getDefault())
DateTimeFormat.forPattern("HH:mm").withLocale(Locale.getDefault())

override fun interpretDate(date: Calendar): String {
val weekDayFormat = if (shortDate) "E" else "EEEE"
val weekDay = DateTimeFormat.forPattern(weekDayFormat)
.withLocale(Locale.getDefault())
.print(DateTime(date.timeInMillis))
.withLocale(Locale.getDefault())
.print(DateTime(date.timeInMillis))

val dateString = DateUtils.formatDateTime(
requireContext(), date.timeInMillis,
DateUtils.FORMAT_NUMERIC_DATE or DateUtils.FORMAT_NO_YEAR
requireContext(), date.timeInMillis,
DateUtils.FORMAT_NUMERIC_DATE or DateUtils.FORMAT_NO_YEAR
)

return weekDay.uppercase(Locale.getDefault()) + ' '.toString() + dateString
Expand All @@ -550,20 +551,20 @@ class CalendarFragment :
}

ThemedAlertDialogBuilder(requireContext())
.setMessage(getString(R.string.dialog_delete_calendar))
.setPositiveButton(getString(R.string.yes)) { _, _ ->
val deleted = CalendarController.deleteLocalCalendar(requireContext())
Utils.setSetting(requireContext(), Const.SYNC_CALENDAR, false)
requireActivity().invalidateOptionsMenu()

if (deleted > 0) {
Utils.showToast(requireContext(), R.string.calendar_deleted_toast)
} else {
Utils.showToast(requireContext(), R.string.calendar_not_existing_toast)
.setMessage(getString(R.string.dialog_delete_calendar))
.setPositiveButton(getString(R.string.yes)) { _, _ ->
val deleted = CalendarController.deleteLocalCalendar(requireContext())
Utils.setSetting(requireContext(), Const.SYNC_CALENDAR, false)
requireActivity().invalidateOptionsMenu()

if (deleted > 0) {
Utils.showToast(requireContext(), R.string.calendar_deleted_toast)
} else {
Utils.showToast(requireContext(), R.string.calendar_not_existing_toast)
}
}
}
.setNegativeButton(getString(R.string.no), null)
.show()
.setNegativeButton(getString(R.string.no), null)
.show()
}

private fun refreshMonthView() {
Expand All @@ -573,10 +574,10 @@ class CalendarFragment :
val eventMap = calendarController.getEventsForMonth(selectedDate)

if (!::monthViewAdapter.isInitialized) {
monthViewAdapter = MonthViewAdapter(daysInMonth, eventMap)
monthViewAdapter = MonthViewAdapter(daysInMonth, eventMap, selectedDate)
monthRecyclerView.adapter = monthViewAdapter
} else {
monthViewAdapter.updateData(daysInMonth, eventMap)
monthViewAdapter.updateData(daysInMonth, eventMap, selectedDate)
}

val layoutManager: RecyclerView.LayoutManager = GridLayoutManager(requireContext(), 7)
Expand All @@ -587,11 +588,14 @@ class CalendarFragment :
val daysInMonthArray: ArrayList<String> = ArrayList()
val yearMonth = YearMonth.of(date.year, date.monthOfYear)
val daysInMonth = yearMonth.lengthOfMonth()
val daysInPreviousMonth = yearMonth.minusMonths(1).lengthOfMonth()
val firstOfMonth = date.withDayOfMonth(1)
var dayOfWeek = firstOfMonth.dayOfWeek().get() - 1 // Monday is the first day of the week in Europe
var dayOfWeek = firstOfMonth.dayOfWeek - 1 // Monday is the first day of the week in Europe
for (i in 1..42) {
if (i <= dayOfWeek || i > daysInMonth + dayOfWeek) {
daysInMonthArray.add("")
if (i <= dayOfWeek) {
daysInMonthArray.add((daysInPreviousMonth - dayOfWeek + i).toString())
} else if (i > daysInMonth + dayOfWeek) {
daysInMonthArray.add((abs(i - daysInMonth - dayOfWeek) ).toString())
CommanderStorm marked this conversation as resolved.
Show resolved Hide resolved
} else {
daysInMonthArray.add((i - dayOfWeek).toString())
}
Expand All @@ -618,14 +622,14 @@ class CalendarFragment :
const val RESULT_ERROR = 4

private val PERMISSIONS_CALENDAR = arrayOf(
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR
)

@JvmStatic
fun newInstance(
date: Long? = null,
eventId: String? = null
date: Long? = null,
eventId: String? = null
) = CalendarFragment().apply {
}
}
Expand Down
Loading