diff --git a/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt b/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt index abf806c..9d3d3ac 100644 --- a/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt +++ b/src/jsMain/kotlin/de/kif/frontend/views/calendar/Calendar.kt @@ -4,23 +4,41 @@ import de.kif.frontend.iterator import de.kif.frontend.launch import de.kif.frontend.repository.ScheduleRepository import de.westermann.kwebview.View -import org.w3c.dom.HTMLElement -import org.w3c.dom.get +import org.w3c.dom.* import kotlin.browser.document -class Calendar(calendar: HTMLElement): View(calendar) { +class Calendar(calendar: HTMLElement) : View(calendar) { var calendarEntries: List = emptyList() var calendarCells: List = emptyList() val day: Int + val htmlTag = document.documentElement as HTMLHtmlElement + val calendarTable = calendar.getElementsByClassName("calendar-table")[0] as HTMLElement + + fun scrollVerticalBy(pixel: Double) { + htmlTag.scrollBy(ScrollToOptions(0.0, pixel, ScrollBehavior.SMOOTH)) + } + + fun scrollHorizontalBy(pixel: Double) { + calendarTable.scrollBy(ScrollToOptions(pixel, 0.0, ScrollBehavior.SMOOTH)) + } + + fun scrollVerticalTo(pixel: Double) { + htmlTag.scrollTo(ScrollToOptions(0.0, pixel, ScrollBehavior.SMOOTH)) + } + + fun scrollHorizontalTo(pixel: Double) { + calendarTable.scrollTo (ScrollToOptions(pixel, 0.0, ScrollBehavior.SMOOTH)) + } + init { val editable = calendar.dataset["editable"]?.toBoolean() ?: false day = calendar.dataset["day"]?.toIntOrNull() ?: -1 calendarEntries = document.getElementsByClassName("calendar-entry") - .iterator().asSequence().map{ CalendarEntry(this, it) }.onEach { it.editable = editable }.toList() + .iterator().asSequence().map { CalendarEntry(this, it) }.onEach { it.editable = editable }.toList() calendarCells = document.getElementsByClassName("calendar-cell") .iterator().asSequence().filter { it.dataset["time"] != null }.map(::CalendarCell).toList() @@ -54,6 +72,7 @@ class Calendar(calendar: HTMLElement): View(calendar) { for (entry in calendarEntries) { if (entry.scheduleId == it) { entry.html.remove() + calendarEntries -= entry } } } diff --git a/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarEntry.kt b/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarEntry.kt index 9763d67..8a8a72e 100644 --- a/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarEntry.kt +++ b/src/jsMain/kotlin/de/kif/frontend/views/calendar/CalendarEntry.kt @@ -7,15 +7,14 @@ import de.kif.frontend.iterator import de.kif.frontend.launch import de.kif.frontend.repository.RepositoryDelegate import de.kif.frontend.repository.ScheduleRepository -import de.westermann.kwebview.Point -import de.westermann.kwebview.View +import de.westermann.kwebview.* import de.westermann.kwebview.components.Body -import de.westermann.kwebview.createHtmlView -import de.westermann.kwebview.toPoint import org.w3c.dom.HTMLElement import org.w3c.dom.events.MouseEvent +import kotlin.browser.window import kotlin.dom.appendText import kotlin.dom.isText +import kotlin.js.Date class CalendarEntry(private val calendar: Calendar, view: HTMLElement) : View(view) { @@ -32,6 +31,7 @@ class CalendarEntry(private val calendar: Calendar, view: HTMLElement) : View(vi private lateinit var workGroup: WorkGroup var pending by classList.property("pending") + private var nextScroll = 0.0 var editable: Boolean = false @@ -52,6 +52,33 @@ class CalendarEntry(private val calendar: Calendar, view: HTMLElement) : View(vi } } + async { + val now = Date.now() + if (now <= nextScroll) { + return@async + } + + val width = calendar.calendarTable.clientWidth + val height = window.innerHeight + val rect = html.getBoundingClientRect() + + if (rect.left < 0.0) { + nextScroll = now + 500.0 + calendar.scrollHorizontalBy(rect.left - 80.0) + } else if (rect.right > width) { + nextScroll = now + 0.500 + calendar.scrollHorizontalBy(rect.right - width + 50.0) + } + + if (rect.top < 20.0) { + nextScroll = now + 500.0 + calendar.scrollVerticalBy(rect.top - 50.0) + } else if (rect.bottom > height - 20.0) { + nextScroll = now + 500.0 + calendar.scrollVerticalBy(rect.bottom - height + 50.0) + } + } + newCell = cell } diff --git a/src/jsMain/kotlin/de/westermann/kwebview/extensions.kt b/src/jsMain/kotlin/de/westermann/kwebview/extensions.kt index 7750584..4cbf6ea 100644 --- a/src/jsMain/kotlin/de/westermann/kwebview/extensions.kt +++ b/src/jsMain/kotlin/de/westermann/kwebview/extensions.kt @@ -65,9 +65,9 @@ fun delete(thing: dynamic, key: String) { * @param timeout Optionally set a timeout for this call. Defaults to 1. * @param block Callback */ -fun async(timeout: Int = 1, block: () -> Unit) { +fun async(timeout: Int = 1, block: () -> Unit): Int { if (timeout < 1) throw IllegalArgumentException("Timeout must be greater than 0!") - window.setTimeout(block, timeout) + return window.setTimeout(block, timeout) } fun interval(timeout: Int, block: () -> Unit): Int { @@ -75,6 +75,10 @@ fun interval(timeout: Int, block: () -> Unit): Int { return window.setInterval(block, timeout) } +fun clearTimeout(id: Int) { + window.clearTimeout(id) +} + fun clearInterval(id: Int) { window.clearInterval(id) } diff --git a/src/jsMain/resources/style/style.scss b/src/jsMain/resources/style/style.scss index 747f5f0..c2c3166 100644 --- a/src/jsMain/resources/style/style.scss +++ b/src/jsMain/resources/style/style.scss @@ -451,7 +451,6 @@ form { } .calendar-table { - float: left; width: 100%; overflow-x: scroll; overflow-y: visible; @@ -462,18 +461,20 @@ form { .calendar-edit { width: 16rem; + height: 100%; display: block; position: absolute; right: 0; top: -3rem; padding-top: 3rem; - overflow: hidden; .calendar-edit-main { - position: relative; - left: 16rem; + position: sticky; + margin-left: 16rem; opacity: 0; - transition: left $transitionTime, opacity$transitionTime; + transition: margin-left $transitionTime, opacity $transitionTime, visibility $transitionTime; + top: 1rem; + visibility: hidden; } } @@ -546,8 +547,9 @@ form { } .calendar-edit-main { - left: 0; + margin-left: 0; opacity: 1; + visibility: visible; } }