Improved flow of observables/emissions

This commit is contained in:
squidfunk 2020-03-16 14:59:59 +01:00
parent 47aa47ee4c
commit 653d535a22
16 changed files with 86 additions and 93 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,10 @@
{
"assets/javascripts/bundle.js": "assets/javascripts/bundle.5a96f0ab.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.5a96f0ab.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.daf35bb7.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.daf35bb7.min.js.map",
"assets/javascripts/bundle.js": "assets/javascripts/bundle.bdb82690.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.bdb82690.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.aad0415a.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.aad0415a.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.784c5235.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.784c5235.min.js.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.1f420948.min.css",
"assets/stylesheets/main.css": "assets/stylesheets/main.acbb280a.min.css",
"assets/stylesheets/palette.css": "assets/stylesheets/palette.31180ff2.min.css"
}

View File

@ -41,7 +41,7 @@
{% endif %}
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.1f420948.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.acbb280a.min.css' | url }}">
{% if palette.primary or palette.accent %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.31180ff2.min.css' | url }}">
{% endif %}
@ -177,8 +177,8 @@
<script>var __config={}</script>
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/vendor.daf35bb7.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.5a96f0ab.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/vendor.aad0415a.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.bdb82690.min.js' | url }}"></script>
{%- set translations = {} -%}
{%- for key in [
"clipboard.copy",

View File

@ -93,9 +93,11 @@ export function watchViewport(): Observable<Viewport> {
export function watchViewportAt(
el: HTMLElement, { header$, viewport$ }: WatchAtOptions
): Observable<Viewport> {
const offset$ = viewport$
const offset$ = combineLatest([
viewport$.pipe(distinctUntilKeyChanged("size")),
header$
])
.pipe(
distinctUntilKeyChanged("size"),
map((): ViewportOffset => ({
x: el.offsetLeft,
y: el.offsetTop

View File

@ -92,7 +92,7 @@ export function mountHeader(
): OperatorFunction<HTMLElement, Header> {
return pipe(
switchMap(el => {
const header$ = watchHeader(el, { viewport$ })
const header$ = watchHeader(el)
/* Compute whether the header should switch to page header */
const type$ = useComponent("main")

View File

@ -28,14 +28,14 @@ import {
pipe
} from "rxjs"
import {
distinctUntilKeyChanged,
finalize,
map,
observeOn,
switchMap,
shareReplay,
tap
} from "rxjs/operators"
import { Viewport } from "browser"
import { watchElementSize } from "browser"
import { Header, HeaderType } from "../_"
import {
@ -43,17 +43,6 @@ import {
setHeaderTitleActive
} from "../set"
/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
/**
* Watch options
*/
interface WatchOptions {
viewport$: Observable<Viewport> /* Viewport observable */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
@ -61,32 +50,32 @@ interface WatchOptions {
/**
* Watch header
*
* The header is wrapped in an observable to pave the way for auto-hiding or
* other dynamic behaviors that may be implemented later on.
*
* @param el - Header element
* @param options - Options
*
* @return Header observable
*/
export function watchHeader(
el: HTMLElement, { viewport$ }: WatchOptions
el: HTMLElement
): Observable<Omit<Header, "type">> {
return viewport$
.pipe(
distinctUntilKeyChanged("size"),
switchMap(() => {
const styles = getComputedStyle(el)
const sticky = [
"sticky", /* Modern browsers */
"-webkit-sticky" /* Safari */
].includes(styles.position)
return of({
sticky,
height: sticky ? el.offsetHeight : 0
})
})
)
const styles = getComputedStyle(el)
if ([
"sticky", /* Modern browsers */
"-webkit-sticky" /* Safari */
].includes(styles.position)) {
return watchElementSize(el)
.pipe(
map(({ height }) => ({
sticky: true,
height
})),
shareReplay(1)
)
} else {
return of({
sticky: false,
height: 0
})
}
}
/* ------------------------------------------------------------------------- */

View File

@ -29,11 +29,13 @@ import {
} from "rxjs"
import {
distinctUntilChanged,
distinctUntilKeyChanged,
finalize,
map,
observeOn,
pluck,
shareReplay,
switchMap,
tap
} from "rxjs/operators"
@ -81,17 +83,23 @@ export function watchMain(
/* Compute necessary adjustment for header */
const adjust$ = header$
.pipe(
pluck("height")
pluck("height"),
distinctUntilChanged(),
shareReplay(1)
)
/* Compute the main area's top and bottom markers */
const marker$ = watchElementSize(el)
const marker$ = adjust$
.pipe(
map(({ height }) => ({
top: el.offsetTop,
bottom: el.offsetTop + height
})),
distinctUntilChanged(),
switchMap(() => watchElementSize(el)
.pipe(
map(({ height }) => ({
top: el.offsetTop,
bottom: el.offsetTop + height
}))
)
),
distinctUntilKeyChanged("top"),
shareReplay(1)
)

View File

@ -25,7 +25,6 @@ import {
Observable,
animationFrameScheduler,
combineLatest,
of,
pipe
} from "rxjs"
import {
@ -90,15 +89,13 @@ interface ApplyOptions {
export function watchSidebar(
el: HTMLElement, { main$, viewport$ }: WatchOptions
): Observable<Sidebar> {
const inner = el.parentElement!
const outer = inner.parentElement!
const adjust = el.parentElement!.offsetTop
- el.parentElement!.parentElement!.offsetTop
/* Compute the sidebar's available height */
const adjust$ = of(inner.offsetTop - outer.offsetTop)
const height$ = viewport$
const height$ = combineLatest([main$, viewport$])
.pipe(
withLatestFrom(adjust$, main$),
map(([{ offset: { y } }, adjust, { offset, height }]) => (
map(([{ offset, height }, { offset: { y } }]) => (
height
+ Math.min(adjust, Math.max(0, y - offset))
- adjust
@ -107,12 +104,9 @@ export function watchSidebar(
)
/* Compute whether the sidebar should be locked */
const lock$ = viewport$
const lock$ = combineLatest([main$, viewport$])
.pipe(
withLatestFrom(adjust$, main$),
map(([{ offset: { y } }, adjust, { offset }]) => (
y >= offset + adjust
)),
map(([{ offset }, { offset: { y } }]) => y >= offset + adjust),
distinctUntilChanged()
)