From 9969cafdaea8113b3ca6c80afce399c9c30f8f9d Mon Sep 17 00:00:00 2001
From: squidfunk <martin.donath@squidfunk.com>
Date: Tue, 6 Mar 2018 19:51:52 +0100
Subject: [PATCH] Merge master

---
 src/assets/javascripts/device/breakpoint.ts |   6 +-
 src/assets/javascripts/device/viewport.ts   |  30 ++---
 src/assets/javascripts/index.ts             | 137 ++++++++++++++++++++
 3 files changed, 153 insertions(+), 20 deletions(-)

diff --git a/src/assets/javascripts/device/breakpoint.ts b/src/assets/javascripts/device/breakpoint.ts
index 0234fd2d..780ca8d0 100644
--- a/src/assets/javascripts/device/breakpoint.ts
+++ b/src/assets/javascripts/device/breakpoint.ts
@@ -35,13 +35,13 @@ import "rxjs/add/observable/fromEventPattern"
  * @param media - Media query
  */
 export function query(media: MediaQueryList) {
-  const subject$ = new BehaviorSubject<boolean>(media.matches)
+  const media$ = new BehaviorSubject<boolean>(media.matches)
   Observable.fromEventPattern<boolean>(next =>
     media.addListener(
       (mq: MediaQueryList) => next(mq.matches)
     ))
-    .subscribe(subject$)
-  return subject$
+    .subscribe(media$)
+  return media$
 }
 
 /**
diff --git a/src/assets/javascripts/device/viewport.ts b/src/assets/javascripts/device/viewport.ts
index dee0f361..fed67ea1 100644
--- a/src/assets/javascripts/device/viewport.ts
+++ b/src/assets/javascripts/device/viewport.ts
@@ -55,18 +55,14 @@ export interface ViewportSize {
  * ------------------------------------------------------------------------- */
 
 /**
- * Create an observable for window scroll events
- *
- * @return Observable
+ * Observable for window scroll events
  */
-const scroll = () => Observable.fromEvent<UIEvent>(window, "scroll")
+const scroll$ = Observable.fromEvent<UIEvent>(window, "scroll")
 
 /**
- * Create an observable for window resize events
- *
- * @return Observable
+ * Observable for window resize events
  */
-const resize = () => Observable.fromEvent<UIEvent>(window, "resize")
+const resize$ = Observable.fromEvent<UIEvent>(window, "resize")
 
 /* ----------------------------------------------------------------------------
  * Functions
@@ -91,18 +87,18 @@ const resize = () => Observable.fromEvent<UIEvent>(window, "resize")
  * @return Subject
  */
 export function offset() {
-  const subject$ = new BehaviorSubject<ViewportOffset>({
+  const offset$ = new BehaviorSubject<ViewportOffset>({
     x: window.pageXOffset,
     y: window.pageYOffset
   })
-  scroll()
-    .merge(resize())
+  scroll$
+    .merge(resize$)
     .map<UIEvent, ViewportOffset>(() => ({
       x: window.pageXOffset,
       y: window.pageYOffset
     }))
-    .subscribe(subject$)
-  return subject$
+    .subscribe(offset$)
+  return offset$
     .distinctUntilChanged((x, y) => !isUndefined(y) && isEqual(x, y))
 }
 
@@ -114,16 +110,16 @@ export function offset() {
  * @return Subject
  */
 export function size() {
-  const subject$ = new BehaviorSubject<ViewportSize>({
+  const size$ = new BehaviorSubject<ViewportSize>({
     width: window.innerWidth,
     height: window.innerHeight
   })
-  resize()
+  resize$
     .map<UIEvent, ViewportSize>(() => ({
       width: window.innerWidth,
       height: window.innerHeight
     }))
-    .subscribe(subject$)
-  return subject$
+    .subscribe(size$)
+  return size$
     .distinctUntilChanged((x, y) => !isUndefined(y) && isEqual(x, y))
 }
diff --git a/src/assets/javascripts/index.ts b/src/assets/javascripts/index.ts
index 481a62a4..1b474f22 100644
--- a/src/assets/javascripts/index.ts
+++ b/src/assets/javascripts/index.ts
@@ -1 +1,138 @@
+/*
+ * Copyright (c) 2016-2018 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.
+ */
+
+import { Observable } from "rxjs/Observable"
+
+import "rxjs/add/observable/empty"
+import "rxjs/add/operator/map"
+import "rxjs/add/operator/scan"
+import "rxjs/add/operator/switchMap"
+
+import * as breakpoint from "./device/breakpoint"
+import * as viewport from "./device/viewport"
+
+/* ----------------------------------------------------------------------------
+ * TODO
+ * ------------------------------------------------------------------------- */
+
+// abstract state into component (active) and compose/extend interfaces
+//
+// state: T extends BaseState
+
+interface State {
+  active: boolean
+  offset?: number
+}
+
+interface CustomState extends State {
+  active: boolean
+  offset?: number
+  bar?: true
+}
+
+// TODO: abstract this behavior... generic typings! create, destroy, update
+
+type Reducer = <S extends State>(state: S) => S
+
+interface Lifecycle {
+  create: Reducer
+  destroy: Reducer
+  update: Reducer
+}
+
+// function foo(lifecycle: Lifecycle) {
+//   factory(lifecycle, viewport.offset()
+//     .map(({ y }) => ({ ...state, offset: y })))
+// }
+
+// A Breakpoint observable factory... maybe move update into parameters?
+function factory<T extends State>(lifecycle: Lifecycle, observable: Observable<T>) {
+  const { create, destroy, update } = lifecycle
+  return breakpoint.from(1200)
+
+    /* Initialize component and handle state change */
+    .scan<boolean, State>((state, active) => {
+      return (active ? create : destroy)({ ...state, active })
+    }, { active: false })
+
+    /* Augment state */
+    .switchMap(state => {
+      if (state.active) {
+        // return observable
+        //   .map((newState: State) => update({ ...state, ...newState }))
+        return viewport.offset()
+          .map(({ y }) => update({ ...state, offset: y }))
+      } else {
+        return Observable.empty<State>()
+      }
+    })
+}
+
+const create2 = (state: CustomState) => {
+  console.log("create")
+  return state
+}
+
+const update2 = (state: CustomState) => {
+  console.log("update")
+  return state
+}
+
+const destroy2 = (state: CustomState) => {
+  console.log("destroy")
+  return state
+}
+
+factory({
+  create: create2,
+  update: update2,
+  destroy: destroy2
+}).subscribe(console.log)
+
+// const break$ = breakpoint.from(1200)
+//
+//   /* Initialize component and handle state change */
+//   .scan<boolean, State>((state, active) => {
+//     // const reducer = active ? state.create : state.destroy
+//     return { ...state, active }
+//   }, { active: false })
+//
+//   /* Augment state */
+//   .switchMap(state => {
+//     if (state.active) {
+//       return viewport.offset()
+//         .map(({ y }) => ({ ...state, offset: y }))
+//     } else {
+//       return Observable.empty<State>()
+//     }
+//   })
+//
+//   /* Update state */
+//   .map(state => {         // pass state + props (create, update, destroy)
+//     console.log(state)
+//
+//     return state
+//   })
+//
+// break$.subscribe(console.log)
+
 console.log("it works!")
-- 
GitLab