diff --git a/src/js/chat.js b/src/js/chat.js index 050ff8b..9f8035f 100644 --- a/src/js/chat.js +++ b/src/js/chat.js @@ -27,7 +27,7 @@ class Chat extends ElemJS { // connect to the new room's timeline updater if (store.activeRoom.exists()) { const timeline = store.activeRoom.value().timeline - const beforeChangeSubscription = () => { + const subscription = () => { // scroll anchor does not work if the timeline is scrolled to the top. // at the start, when there are not enough messages for a full screen, this is the case. // once there are enough messages that scrolling is necessary, we initiate a scroll down to activate the scroll anchor. @@ -40,29 +40,12 @@ class Chat extends ElemJS { } }, 0) } - this.addSubscription("beforeChange", timeline, beforeChangeSubscription) - - //Make sure after loading scrollback we don't move the scroll position - const beforeScrollbackLoadSubscription = () => { - const lastScrollHeight = chatMessages.scrollHeight; - - const afterScrollbackLoadSub = () => { - const scrollDiff = chatMessages.scrollHeight - lastScrollHeight; - chatMessages.scrollTop += scrollDiff; - - timeline.unsubscribe("afterScrollbackLoad", afterScrollbackLoadSub) - } - - timeline.subscribe("afterScrollbackLoad", afterScrollbackLoadSub) - } - this.addSubscription("beforeScrollbackLoad", timeline, beforeScrollbackLoadSubscription) + const name = "beforeChange" + this.removableSubscriptions.push({name, target: timeline, subscription}) + timeline.subscribe(name, subscription) } this.render() } - addSubscription(name, target, subscription) { - this.removableSubscriptions.push({name, target, subscription}) - target.subscribe(name, subscription) - } render() { this.clearChildren() diff --git a/src/js/timeline.js b/src/js/timeline.js index 270b5c8..0819ff8 100644 --- a/src/js/timeline.js +++ b/src/js/timeline.js @@ -33,9 +33,9 @@ function eventSearch(list, event, min = 0, max = NO_MAX) { } } // recurse (below) - if (list[mid].data.origin_server_ts > event.data.origin_server_ts) return eventSearch(list, event, min, mid - 1) + if (list[mid].data.origin_server_ts > event.data.origin_server_ts) return eventSearch(list, event, min, mid-1) // recurse (above) - else return eventSearch(list, event, mid + 1, max) + else return eventSearch(list, event, mid+1, max) } class Event extends ElemJS { @@ -176,43 +176,16 @@ class EventGroup extends ElemJS { } } - -/** Displays a spinner and creates an event to notify timeline to load more messages */ -class LoadMore extends ElemJS { - constructor(id) { - super("div") - this.class("c-message-notice") - this.id = id - - this.child( - ejs("div").class("c-message-notice__inner").child( - ejs("span").class("loading-icon"), - ejs("span").text("Loading more...") - ) - ) - const intersection_observer = new IntersectionObserver(e => this.intersectionHandler(e)) - intersection_observer.observe(this.element) - } - - intersectionHandler(e) { - if (e.some(e => e.isIntersecting)) { - store.rooms.get(this.id).value().timeline.loadScrollback() - } - } -} - class ReactiveTimeline extends ElemJS { constructor(id, list) { super("div") this.class("c-event-groups") this.id = id this.list = list - this.loadMore = new LoadMore(this.id) this.render() } addEvent(event) { - this.loadMore.remove() // if (debug) console.log("running search", this.list, event) // if (debug) debugger; const search = eventSearch(this.list, event) @@ -220,7 +193,7 @@ class ReactiveTimeline extends ElemJS { if (!search.success) { if (search.i >= 1) { // add at end - this.tryAddGroups(event, [search.i - 1, search.i]) + this.tryAddGroups(event, [search.i-1, search.i]) } else { // add at start this.tryAddGroups(event, [0, -1]) @@ -228,8 +201,6 @@ class ReactiveTimeline extends ElemJS { } else { this.tryAddGroups(event, [search.i]) } - this.loadMore = new LoadMore(this.id) - this.childAt(0, this.loadMore) } tryAddGroups(event, indices) { @@ -262,7 +233,6 @@ class ReactiveTimeline extends ElemJS { render() { this.clearChildren() - this.child(this.loadMore) this.list.forEach(group => this.child(group)) this.anchor = new Anchor() this.child(this.anchor) @@ -274,15 +244,11 @@ class Timeline extends Subscribable { super() Object.assign(this.events, { beforeChange: [], - afterChange: [], - beforeScrollbackLoad: [], - afterScrollbackLoad: [], + afterChange: [] }) Object.assign(this.eventDeps, { beforeChange: [], - afterChange: [], - beforeScrollbackLoad: [], - afterScrollbackLoad: [], + afterChange: [] }) this.room = room this.id = this.room.id @@ -383,21 +349,16 @@ class Timeline extends Subscribable { url.searchParams.set("access_token", lsm.get("access_token")) url.searchParams.set("from", this.from) url.searchParams.set("dir", "b") - url.searchParams.set("limit", "20") + url.searchParams.set("limit", 10) const filter = { lazy_load_members: true } url.searchParams.set("filter", JSON.stringify(filter)) - const root = await fetch(url.toString()).then(res => res.json()) - - this.broadcast("beforeScrollbackLoad") - this.from = root.end - // console.log(this.updateEvents, root.chunk) + console.log(this.updateEvents, root.chunk) if (root.state) this.updateStateEvents(root.state) this.updateEvents(root.chunk) - this.broadcast("afterScrollbackLoad") } send(body) { @@ -424,8 +385,32 @@ class Timeline extends Subscribable { headers: { "Content-Type": "application/json" } - }) + })/*.then(() => { + const subscription = () => { + this.removeEvent(id) + this.unsubscribe("afterChange", subscription) + } + this.subscribe("afterChange", subscription) + })*/ } +/* + getGroupedEvents() { + let currentSender = Symbol("N/A") + let groups = [] + let currentGroup = [] + for (const event of this.list) { + if (event.sender === currentSender) { + currentGroup.push(event) + } else { + if (currentGroup.length) groups.push(currentGroup) + currentGroup = [event] + currentSender = event.sender + } + } + if (currentGroup.length) groups.push(currentGroup) + return groups + } + */ } module.exports = {Timeline} diff --git a/src/sass/loading.sass b/src/sass/loading.sass deleted file mode 100644 index 9705bbe..0000000 --- a/src/sass/loading.sass +++ /dev/null @@ -1,13 +0,0 @@ -@keyframes spin - 0% - transform: rotate(0deg) - 100% - transform: rotate(180deg) - -.loading-icon - display: inline-block - background-color: #ccc - width: 12px - height: 12px - margin-right: 6px - animation: spin 0.7s infinite diff --git a/src/sass/login.sass b/src/sass/login.sass index 74d08ac..235fad4 100644 --- a/src/sass/login.sass +++ b/src/sass/login.sass @@ -1,8 +1,6 @@ @use "./base" -@use "./loading.sass" @use "./colors.sass" as c - .main justify-content: center align-items: center @@ -43,6 +41,19 @@ .form-error color: red +@keyframes spin + 0% + transform: rotate(0deg) + 100% + transform: rotate(180deg) + +.loading-icon + display: inline-block + background-color: #ccc + width: 12px + height: 12px + margin-right: 6px + animation: spin 0.7s infinite input, button font-family: inherit diff --git a/src/sass/main.sass b/src/sass/main.sass index 150af73..d342bbb 100644 --- a/src/sass/main.sass +++ b/src/sass/main.sass @@ -5,4 +5,3 @@ @use "./components/chat" @use "./components/chat-input" @use "./components/anchor" -@use "./loading"