Moved configuration to utilities

This commit is contained in:
squidfunk 2020-02-14 17:36:31 +01:00
parent 29d15a2e22
commit 2c11f0f36c
4 changed files with 126 additions and 94 deletions

View File

@ -28,7 +28,7 @@ import {
Key, Key,
SearchQuery, SearchQuery,
Viewport, Viewport,
WorkerHandler, WorkerHandler
} from "observables" } from "observables"
import { SearchMessage } from "workers" import { SearchMessage } from "workers"

View File

@ -26,19 +26,23 @@
import "../stylesheets/app.scss" import "../stylesheets/app.scss"
import "../stylesheets/app-palette.scss" import "../stylesheets/app-palette.scss"
import { identity, values } from "ramda" import { values } from "ramda"
import { import {
EMPTY, EMPTY,
merge, merge,
of, of,
fromEvent NEVER
} from "rxjs" } from "rxjs"
import { import {
delay, delay,
filter,
map, map,
switchMap, switchMap,
tap tap,
skip,
take,
bufferCount,
startWith,
pluck
} from "rxjs/operators" } from "rxjs/operators"
import { import {
@ -55,12 +59,12 @@ import {
watchViewport, watchViewport,
watchKeyboard, watchKeyboard,
watchToggleMap, watchToggleMap,
useToggle useToggle,
setViewportOffset
} from "./observables" } from "./observables"
import { setupSearchWorker } from "./workers" import { setupSearchWorker } from "./workers"
import { renderSource } from "templates" import { renderSource } from "templates"
import { fetchGitHubStats } from "integrations/source/github" import { fetchGitHubStats } from "integrations/source/github"
import { renderTable } from "templates/table"
import { setToggle } from "actions" import { setToggle } from "actions"
import { import {
Component, Component,
@ -74,21 +78,7 @@ import {
} from "components2" } from "components2"
import { mountClipboard } from "./integrations/clipboard" import { mountClipboard } from "./integrations/clipboard"
import { patchTables, patchDetails } from "patches" import { patchTables, patchDetails } from "patches"
import { takeIf, not, isConfig } from "utilities"
/* ----------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------- */
/**
* Configuration
*/
export interface Config {
base: string /* Base URL */
worker: {
search: string /* Search worker URL */
packer: string /* Packer worker URL */
}
}
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* TODO: where do we put this stuff? * TODO: where do we put this stuff?
@ -121,24 +111,6 @@ const names: Component[] = [
* Helper functions * Helper functions
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
/**
* Ensure that the given value is a valid configuration
*
* We could use `jsonschema` or any other schema validation framework, but that
* would just add more bloat to the bundle, so we'll keep it plain and simple.
*
* @param config - Configuration
*
* @return Test result
*/
function isConfig(config: any): config is Config {
return typeof config === "object"
&& typeof config.base === "string"
&& typeof config.worker === "object"
&& typeof config.worker.search === "string"
&& typeof config.worker.packer === "string"
}
/** /**
* Yes, this is a super hacky implementation. Needs clean up. * Yes, this is a super hacky implementation. Needs clean up.
*/ */
@ -284,22 +256,8 @@ export function initialize(config: unknown) {
// setToggle(toggle, true) // setToggle(toggle, true)
// }) // })
const search = getElement<HTMLInputElement>("[data-md-toggle=search]")!
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
// patches... table, details, pre, ...
/* Open details before printing */
merge(
watchMedia("print").pipe(filter(identity)), // Webkit
fromEvent(window, "beforeprint") // IE, FF
)
.subscribe(() => {
for (const detail of getElements("details"))
detail.setAttribute("open", "")
})
// Close drawer and search on hash change // Close drawer and search on hash change
hash$.subscribe(() => { hash$.subscribe(() => {
@ -332,54 +290,69 @@ export function initialize(config: unknown) {
} }
}) })
// TODO: this is just a re-rendering patch...
patchTables({ document$ }) patchTables({ document$ })
.subscribe(console.log) .subscribe(console.log)
patchDetails({ document$ }) patchDetails({ document$ })
.subscribe(console.log) .subscribe(console.log)
// /* Wrap all data tables for better overflow scrolling */ // // TODO: must be reset when tablet/toggle is left
// const placeholder = document.createElement("table") // const toggle$ = useToggle("search")
// for (const table of getElements<HTMLTableElement>("table:not([class])")) { // toggle$
// table.replaceWith(placeholder) // .pipe(
// placeholder.replaceWith(renderTable(table)) // switchMap(watchToggle),
// } // skip(1),
// switchMap(toggle => viewport$
// .pipe(
// take(1),
// pluck("offset"),
// delay(toggle ? 400 : 100)
// )
// ),
// startWith({ x: 0, y: 0 }),
// bufferCount(2, 1),
// takeIf(not(tablet$)), // TODO: wrong position
// map(([offset]) => offset)
// )
// .subscribe(offset => {
// // TODO: this will also trigger if we started at the top.
// document.body.dataset.mdState = offset.y ? "" : "lock" // TODO: refactor
// setViewportOffset(offset)
// })
// accidentally triggers on resize // accidentally triggers on resize
let lastOffset = 0 // let lastOffset = 0
tablet$.pipe( // tablet$.pipe(
switchMap(active => { // switchMap(active => {
return !active ? watchToggle(search) : EMPTY // return !active ? watchToggle(search) : NEVER
}), // }),
switchMap(toggle => { // switchMap(toggle => {
if (toggle) { // if (toggle) {
console.log("ACTIVE") // console.log("ACTIVE")
return of(document.body) // return of(document.body)
.pipe( // .pipe(
tap(() => lastOffset = window.pageYOffset), // tap(() => lastOffset = window.pageYOffset),
delay(400), // delay(400),
tap(() => { // tap(() => {
window.scrollTo(0, 0), // window.scrollTo(0, 0),
console.log("scrolled... to top, locked body") // console.log("scrolled... to top, locked body")
document.body.dataset.mdState = "lock" // document.body.dataset.mdState = "lock"
}) // })
) // )
} else { // } else {
console.log("INACTIVE") // console.log("INACTIVE")
return of(document.body) // return of(document.body)
.pipe( // .pipe(
tap(() => document.body.dataset.mdState = ""), // tap(() => document.body.dataset.mdState = ""),
delay(100), // delay(100),
tap(() => { // tap(() => {
window.scrollTo(0, lastOffset) // window.scrollTo(0, lastOffset) // setViewportOffset !
}) // })
) // )
} // }
return EMPTY // })
}) // )
) // .subscribe(x => console.log("SEARCHLOCK", x))
.subscribe(x => console.log("SEARCHLOCK", x))
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/* ----------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------- */
/**
* Configuration
*/
export interface Config {
base: string /* Base URL */
worker: {
search: string /* Search worker URL */
packer: string /* Packer worker URL */
}
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
/**
* Ensure that the given value is a valid configuration
*
* We could use `jsonschema` or any other schema validation framework, but that
* would just add more bloat to the bundle, so we'll keep it plain and simple.
*
* @param config - Configuration
*
* @return Test result
*/
export function isConfig(config: any): config is Config {
return typeof config === "object"
&& typeof config.base === "string"
&& typeof config.worker === "object"
&& typeof config.worker.search === "string"
&& typeof config.worker.packer === "string"
}

View File

@ -20,6 +20,7 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
export * from "./config"
export * from "./jsx" export * from "./jsx"
export * from "./rxjs" export * from "./rxjs"
export * from "./string" export * from "./string"