forked from coracle/flotilla
Pin scroll position to at'd event until user scrolls
This commit is contained in:
@@ -13,7 +13,6 @@ import {
|
|||||||
isDefined,
|
isDefined,
|
||||||
filterVals,
|
filterVals,
|
||||||
fromPairs,
|
fromPairs,
|
||||||
HOUR,
|
|
||||||
} from "@welshman/lib"
|
} from "@welshman/lib"
|
||||||
import {
|
import {
|
||||||
EVENT_TIME,
|
EVENT_TIME,
|
||||||
@@ -48,7 +47,7 @@ export const makeFeed = ({
|
|||||||
onForwardExhausted?: () => void
|
onForwardExhausted?: () => void
|
||||||
at?: number
|
at?: number
|
||||||
}) => {
|
}) => {
|
||||||
const interval = int(12, HOUR)
|
const interval = int(DAY)
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
const events = writable<TrustedEvent[]>([])
|
const events = writable<TrustedEvent[]>([])
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount, tick} from "svelte"
|
||||||
import {readable} from "svelte/store"
|
import {readable} from "svelte/store"
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import type {Readable} from "svelte/store"
|
import type {Readable} from "svelte/store"
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onScroll = () => {
|
const manageScrollPosition = () => {
|
||||||
showScrollButton = Math.abs(element?.scrollTop || 0) > 1500
|
showScrollButton = Math.abs(element?.scrollTop || 0) > 1500
|
||||||
|
|
||||||
const newMessages = document.getElementById("new-messages")
|
const newMessages = document.getElementById("new-messages")
|
||||||
@@ -181,6 +181,28 @@
|
|||||||
showFixedNewMessages = y < 0
|
showFixedNewMessages = y < 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userHasScrolled && $page.url.searchParams.get("at")) {
|
||||||
|
const targetEvent = $events.find(event => event.created_at >= at)
|
||||||
|
|
||||||
|
if (targetEvent) {
|
||||||
|
const target = element?.querySelector(`[data-event="${targetEvent.id}"]`)
|
||||||
|
|
||||||
|
if (target instanceof HTMLElement) {
|
||||||
|
isProgrammaticScroll = true
|
||||||
|
target.scrollIntoView({block: "center"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onScroll = () => {
|
||||||
|
if (!isProgrammaticScroll) {
|
||||||
|
userHasScrolled = true
|
||||||
|
manageScrollPosition()
|
||||||
|
}
|
||||||
|
|
||||||
|
isProgrammaticScroll = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollToNewMessages = () =>
|
const scrollToNewMessages = () =>
|
||||||
@@ -197,6 +219,8 @@
|
|||||||
|
|
||||||
let joining = $state(false)
|
let joining = $state(false)
|
||||||
let leaving = $state(false)
|
let leaving = $state(false)
|
||||||
|
let userHasScrolled = $state(false)
|
||||||
|
let isProgrammaticScroll = $state(false)
|
||||||
let loadingBackward = $state(true)
|
let loadingBackward = $state(true)
|
||||||
let loadingForward = $state(true)
|
let loadingForward = $state(true)
|
||||||
let at = $state(parseInt($page.url.searchParams.get("at") || String(now())))
|
let at = $state(parseInt($page.url.searchParams.get("at") || String(now())))
|
||||||
@@ -272,7 +296,7 @@
|
|||||||
|
|
||||||
elements.reverse()
|
elements.reverse()
|
||||||
|
|
||||||
setTimeout(onScroll, 100)
|
tick().then(manageScrollPosition)
|
||||||
|
|
||||||
return elements
|
return elements
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount, tick} from "svelte"
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import type {Readable} from "svelte/store"
|
import type {Readable} from "svelte/store"
|
||||||
import {readable} from "svelte/store"
|
import {readable} from "svelte/store"
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onScroll = () => {
|
const manageScrollPosition = () => {
|
||||||
showScrollButton = Math.abs(element?.scrollTop || 0) > 1500
|
showScrollButton = Math.abs(element?.scrollTop || 0) > 1500
|
||||||
|
|
||||||
const newMessages = document.getElementById("new-messages")
|
const newMessages = document.getElementById("new-messages")
|
||||||
@@ -119,6 +119,28 @@
|
|||||||
showFixedNewMessages = y < 0
|
showFixedNewMessages = y < 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!userHasScrolled && $page.url.searchParams.get("at")) {
|
||||||
|
const targetEvent = $events.find(event => event.created_at >= at)
|
||||||
|
|
||||||
|
if (targetEvent) {
|
||||||
|
const target = element?.querySelector(`[data-event="${targetEvent.id}"]`)
|
||||||
|
|
||||||
|
if (target instanceof HTMLElement) {
|
||||||
|
isProgrammaticScroll = true
|
||||||
|
target.scrollIntoView({block: "center"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onScroll = () => {
|
||||||
|
if (!isProgrammaticScroll) {
|
||||||
|
userHasScrolled = true
|
||||||
|
manageScrollPosition()
|
||||||
|
}
|
||||||
|
|
||||||
|
isProgrammaticScroll = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollToNewMessages = () =>
|
const scrollToNewMessages = () =>
|
||||||
@@ -135,6 +157,8 @@
|
|||||||
|
|
||||||
let loadingBackward = $state(true)
|
let loadingBackward = $state(true)
|
||||||
let loadingForward = $state(true)
|
let loadingForward = $state(true)
|
||||||
|
let userHasScrolled = $state(false)
|
||||||
|
let isProgrammaticScroll = $state(false)
|
||||||
let at = $state(parseInt($page.url.searchParams.get("at") || String(now())))
|
let at = $state(parseInt($page.url.searchParams.get("at") || String(now())))
|
||||||
let share = $state(popKey<TrustedEvent | undefined>("share"))
|
let share = $state(popKey<TrustedEvent | undefined>("share"))
|
||||||
let parent: TrustedEvent | undefined = $state()
|
let parent: TrustedEvent | undefined = $state()
|
||||||
@@ -208,7 +232,7 @@
|
|||||||
|
|
||||||
elements.reverse()
|
elements.reverse()
|
||||||
|
|
||||||
setTimeout(onScroll, 100)
|
tick().then(manageScrollPosition)
|
||||||
|
|
||||||
return elements
|
return elements
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user