Add scrolling to calendar

This commit is contained in:
Lars Westermann 2019-05-18 14:43:03 +02:00
parent 84f8e71239
commit d08caf7b8b
Signed by: lars.westermann
GPG key ID: 9D417FA5BB9D5E1D
4 changed files with 68 additions and 16 deletions

View file

@ -4,23 +4,41 @@ import de.kif.frontend.iterator
import de.kif.frontend.launch import de.kif.frontend.launch
import de.kif.frontend.repository.ScheduleRepository import de.kif.frontend.repository.ScheduleRepository
import de.westermann.kwebview.View import de.westermann.kwebview.View
import org.w3c.dom.HTMLElement import org.w3c.dom.*
import org.w3c.dom.get
import kotlin.browser.document import kotlin.browser.document
class Calendar(calendar: HTMLElement): View(calendar) { class Calendar(calendar: HTMLElement) : View(calendar) {
var calendarEntries: List<CalendarEntry> = emptyList() var calendarEntries: List<CalendarEntry> = emptyList()
var calendarCells: List<CalendarCell> = emptyList() var calendarCells: List<CalendarCell> = emptyList()
val day: Int 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 { init {
val editable = calendar.dataset["editable"]?.toBoolean() ?: false val editable = calendar.dataset["editable"]?.toBoolean() ?: false
day = calendar.dataset["day"]?.toIntOrNull() ?: -1 day = calendar.dataset["day"]?.toIntOrNull() ?: -1
calendarEntries = document.getElementsByClassName("calendar-entry") 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") calendarCells = document.getElementsByClassName("calendar-cell")
.iterator().asSequence().filter { it.dataset["time"] != null }.map(::CalendarCell).toList() .iterator().asSequence().filter { it.dataset["time"] != null }.map(::CalendarCell).toList()
@ -54,6 +72,7 @@ class Calendar(calendar: HTMLElement): View(calendar) {
for (entry in calendarEntries) { for (entry in calendarEntries) {
if (entry.scheduleId == it) { if (entry.scheduleId == it) {
entry.html.remove() entry.html.remove()
calendarEntries -= entry
} }
} }
} }

View file

@ -7,15 +7,14 @@ import de.kif.frontend.iterator
import de.kif.frontend.launch import de.kif.frontend.launch
import de.kif.frontend.repository.RepositoryDelegate import de.kif.frontend.repository.RepositoryDelegate
import de.kif.frontend.repository.ScheduleRepository import de.kif.frontend.repository.ScheduleRepository
import de.westermann.kwebview.Point import de.westermann.kwebview.*
import de.westermann.kwebview.View
import de.westermann.kwebview.components.Body 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.HTMLElement
import org.w3c.dom.events.MouseEvent import org.w3c.dom.events.MouseEvent
import kotlin.browser.window
import kotlin.dom.appendText import kotlin.dom.appendText
import kotlin.dom.isText import kotlin.dom.isText
import kotlin.js.Date
class CalendarEntry(private val calendar: Calendar, view: HTMLElement) : View(view) { 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 private lateinit var workGroup: WorkGroup
var pending by classList.property("pending") var pending by classList.property("pending")
private var nextScroll = 0.0
var editable: Boolean = false 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 newCell = cell
} }

View file

@ -65,9 +65,9 @@ fun delete(thing: dynamic, key: String) {
* @param timeout Optionally set a timeout for this call. Defaults to 1. * @param timeout Optionally set a timeout for this call. Defaults to 1.
* @param block Callback * @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!") 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 { fun interval(timeout: Int, block: () -> Unit): Int {
@ -75,6 +75,10 @@ fun interval(timeout: Int, block: () -> Unit): Int {
return window.setInterval(block, timeout) return window.setInterval(block, timeout)
} }
fun clearTimeout(id: Int) {
window.clearTimeout(id)
}
fun clearInterval(id: Int) { fun clearInterval(id: Int) {
window.clearInterval(id) window.clearInterval(id)
} }

View file

@ -451,7 +451,6 @@ form {
} }
.calendar-table { .calendar-table {
float: left;
width: 100%; width: 100%;
overflow-x: scroll; overflow-x: scroll;
overflow-y: visible; overflow-y: visible;
@ -462,18 +461,20 @@ form {
.calendar-edit { .calendar-edit {
width: 16rem; width: 16rem;
height: 100%;
display: block; display: block;
position: absolute; position: absolute;
right: 0; right: 0;
top: -3rem; top: -3rem;
padding-top: 3rem; padding-top: 3rem;
overflow: hidden;
.calendar-edit-main { .calendar-edit-main {
position: relative; position: sticky;
left: 16rem; margin-left: 16rem;
opacity: 0; 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 { .calendar-edit-main {
left: 0; margin-left: 0;
opacity: 1; opacity: 1;
visibility: visible;
} }
} }