From f498b1d5d52b87f898b89158b9d71a48e2906ce8 Mon Sep 17 00:00:00 2001 From: Ryan Florence Date: Mon, 1 Oct 2018 22:44:25 -0400 Subject: [PATCH] Clean up suspense lecture code --- .../{workouts/Refactor.js => App.Refactor.js} | 151 +++----- .../src/{workouts/AppOld.js => App.js} | 179 +++++---- 08-suspense/lecture/src/api/data.js | 364 ------------------ 08-suspense/lecture/src/api/index.js | 67 ---- 08-suspense/lecture/src/components/App.js | 70 ---- .../src/components/ContributorListPage.js | 74 ---- .../lecture/src/components/Spinner.css | 75 ---- 08-suspense/lecture/src/components/Spinner.js | 51 --- .../lecture/src/components/UserPage.js | 169 -------- 08-suspense/lecture/src/favicon.ico | Bin 15086 -> 0 bytes 08-suspense/lecture/src/index.js | 6 +- .../src/{workouts => lib}/Competitions.js | 0 .../src/{components => lib}/ManageScroll.js | 0 08-suspense/lecture/src/{ => lib}/cache.js | 0 08-suspense/lecture/src/{ => lib}/index.css | 0 .../lecture/src/{workouts => lib}/utils.js | 66 +++- 08-suspense/lecture/src/workouts/App.js | 283 -------------- 08-suspense/lecture/src/workouts/Img.js | 20 - 08-suspense/lecture/src/workouts/withCache.js | 8 - 19 files changed, 215 insertions(+), 1368 deletions(-) rename 08-suspense/lecture/src/{workouts/Refactor.js => App.Refactor.js} (75%) rename 08-suspense/lecture/src/{workouts/AppOld.js => App.js} (51%) delete mode 100644 08-suspense/lecture/src/api/data.js delete mode 100644 08-suspense/lecture/src/api/index.js delete mode 100644 08-suspense/lecture/src/components/App.js delete mode 100644 08-suspense/lecture/src/components/ContributorListPage.js delete mode 100644 08-suspense/lecture/src/components/Spinner.css delete mode 100644 08-suspense/lecture/src/components/Spinner.js delete mode 100644 08-suspense/lecture/src/components/UserPage.js delete mode 100644 08-suspense/lecture/src/favicon.ico rename 08-suspense/lecture/src/{workouts => lib}/Competitions.js (100%) rename 08-suspense/lecture/src/{components => lib}/ManageScroll.js (100%) rename 08-suspense/lecture/src/{ => lib}/cache.js (100%) rename 08-suspense/lecture/src/{ => lib}/index.css (100%) rename 08-suspense/lecture/src/{workouts => lib}/utils.js (79%) delete mode 100644 08-suspense/lecture/src/workouts/App.js delete mode 100644 08-suspense/lecture/src/workouts/Img.js delete mode 100644 08-suspense/lecture/src/workouts/withCache.js diff --git a/08-suspense/lecture/src/workouts/Refactor.js b/08-suspense/lecture/src/App.Refactor.js similarity index 75% rename from 08-suspense/lecture/src/workouts/Refactor.js rename to 08-suspense/lecture/src/App.Refactor.js index 0c6dbf7..3de4a94 100644 --- a/08-suspense/lecture/src/workouts/Refactor.js +++ b/08-suspense/lecture/src/App.Refactor.js @@ -3,84 +3,23 @@ import { createElement } from "glamor/react"; // eslint-disable-line /* @jsx createElement */ -import Spinner from "react-svg-spinner"; -import ManageScroll from "../components/ManageScroll"; import React, { Placeholder } from "react"; import { Router, Link } from "@reach/router"; -import Component from "@reach/component-component"; +import Spinner from "react-svg-spinner"; +import Competitions from "./lib/Competitions"; +import ManageScroll from "./lib/ManageScroll"; +import { cache } from "./lib/cache"; + import { - fetchWorkouts, fetchWorkout, fetchExercises, fetchNextWorkout, - WorkoutsResource, - WorkoutResource, - ExercisesResource, - NextWorkoutResource, - network -} from "./utils"; -import { cache } from "../cache"; -let patience = 1; - -const link = { - display: "inline-block", - width: "200px", - height: "200px", - lineHeight: "200px", - background: "#f0f0f0", - textAlign: "center", - margin: "20px", - ":hover": { - background: "#ddd" - }, - position: "relative" -}; + WorkoutsResource +} from "./lib/utils"; -const Home = () => ( -
-

Workout App!

-
- - Workouts - - - Competitions - -
-
-); - -const Workouts = () => { - const workouts = WorkoutsResource.read(cache, 10); - return ( -
- Home -

Workouts

- {workouts.map(workout => ( - - {workout.name} - - ))} -
- ); -}; - -const Competitions = () =>
Competitions
; - -const LoadingSpinner = () => ( -
- -
-); +let patience = 1; /////////////////////////////////////////////////// - class Workout extends React.Component { state = { workout: null, @@ -118,19 +57,13 @@ class Workout extends React.Component { } render() { - const { workoutId } = this.props; const { workout, exercises, nextWorkout } = this.state; return workout ? (
- Home /{" "} - Workouts + Home / Workouts

{workout.name}

- {exercises ? ( - - ) : ( - - )} + {exercises ? : } {workout.completed && (nextWorkout ? ( @@ -146,24 +79,65 @@ class Workout extends React.Component { } } -const Exercises = ({ exercises }) => { +//////////////////////////////////////////////////////////// +const link = { + display: "inline-block", + width: "200px", + height: "200px", + lineHeight: "200px", + background: "#f0f0f0", + textAlign: "center", + margin: "20px", + ":hover": { + background: "#ddd" + }, + position: "relative" +}; + +const Home = () => ( +
+

Workout App!

+
+ + Workouts + + + Competitions + +
+
+); + +const Workouts = () => { + const workouts = WorkoutsResource.read(cache, 10); return ( -
    - {exercises.map((exercise, i) => ( -
  • {exercise}
  • +
    + Home +

    Workouts

    + {workouts.map(workout => ( + + {workout.name} + ))} -
+
); }; +const Exercises = ({ exercises }) => { + return ; +}; + const NextWorkout = ({ nextWorkout }) => { return (

- Up Next!{" "} - - {nextWorkout.name} - + Up Next! {nextWorkout.name}

); @@ -171,10 +145,7 @@ const NextWorkout = ({ nextWorkout }) => { const App = () => { return ( - } - > + }> diff --git a/08-suspense/lecture/src/workouts/AppOld.js b/08-suspense/lecture/src/App.js similarity index 51% rename from 08-suspense/lecture/src/workouts/AppOld.js rename to 08-suspense/lecture/src/App.js index 33ba5e3..30c7b06 100644 --- a/08-suspense/lecture/src/workouts/AppOld.js +++ b/08-suspense/lecture/src/App.js @@ -1,27 +1,31 @@ import { createElement } from "glamor/react"; // eslint-disable-line /* @jsx createElement */ -import "./index.css"; -import Spinner from "react-svg-spinner"; -import ManageScroll from "../components/ManageScroll"; -import React, { Placeholder } from "react"; +import React, { Placeholder, lazy } from "react"; import { Router, Link } from "@reach/router"; import Component from "@reach/component-component"; +import Spinner from "react-svg-spinner"; +import ManageScroll from "./lib/ManageScroll"; import { - readWorkouts, - readWorkout, - readExercises, - readNextWorkout, - patience -} from "./utils"; -// import Img, { preload as preloadImg } from "./Img"; -import { cache } from "../cache"; + WorkoutsResource, + WorkoutResource, + ExercisesResource, + NextWorkoutResource, + network +} from "./lib/utils"; +import { cache } from "./lib/cache"; + +const Competitions = lazy(() => import("./lib/Competitions")); + +let qpatience = [5000, 5000, 1, 1, 2000, 2000, 2000]; +let search = window.location.search.substr(1); +let patience = qpatience[search] || 10000; const link = { display: "inline-block", width: "200px", height: "200px", lineHeight: "200px", - background: "#fff", + background: "#eee", textAlign: "center", margin: "20px", ":hover": { @@ -30,26 +34,7 @@ const link = { position: "relative" }; -const Home = () => ( -
-

Workout App!

-
- - Workouts - - - Competitions - -
-
-); - +// use ?1 const LoadingLink = ({ children, ...props }) => ( {({ state, setState }) => ( @@ -79,63 +64,78 @@ const LoadingLink = ({ children, ...props }) => ( ); +const Home = () => ( +
+

Workout App!

+
+ + Workouts + + + Competitions + +
+
+); + const Workouts = () => { - const workouts = readWorkouts.read(cache, 10); + const workouts = WorkoutsResource.read(cache, 10); return (
Home

Workouts

{workouts.map(workout => ( - + {workout.name} - + ))}
); }; const Exercises = ({ workoutId }) => { - const exercises = readExercises.read(cache, workoutId); - return ( -
    - {exercises.map((exercise, i) => ( -
  • {exercise}
  • - ))} -
- ); + const exercises = ExercisesResource.read(cache, workoutId); + return
    {exercises.map((exercise, i) =>
  • {exercise}
  • )}
; }; -const Workout = ({ workoutId }) => { - readNextWorkout.preload(cache, workoutId); - readWorkout.preload(cache, workoutId); - readExercises.preload(cache, workoutId); - const workout = readWorkout.read(cache, workoutId); +class Workout extends React.Component { + render() { + const { workoutId } = this.props; - return ( -
- Home / Workouts -

{workout.name}

- }> - - - {workout.completed && ( - - Up Next! - - } - > - + const workout = WorkoutResource.read(cache, workoutId); + + return ( +
+ Home / Workouts +

{workout.name}

+ }> + - )} -
- ); -}; + {workout.completed && ( + + Up Next! + + } + > + + + )} +
+ ); + } +} const NextWorkout = ({ workoutId }) => { - const nextWorkout = readNextWorkout.read(cache, workoutId); + const nextWorkout = NextWorkoutResource.read(cache, workoutId); return (

@@ -145,25 +145,40 @@ const NextWorkout = ({ workoutId }) => { ); }; -const Competitions = () =>
Competitions
; - const LoadingSpinner = () => (
); +const Network = () => ( +
+ Network: {network} +
+); + const App = () => { return ( - }> - - - - - - - - + + }> + + + + + + + + + + ); }; diff --git a/08-suspense/lecture/src/api/data.js b/08-suspense/lecture/src/api/data.js deleted file mode 100644 index 67fd371..0000000 --- a/08-suspense/lecture/src/api/data.js +++ /dev/null @@ -1,364 +0,0 @@ -export const coreContributorListJSON = [ - { - id: "acdlite", - name: "Andrew Clark" - }, - { - id: "bvaughn", - name: "Brian Vaughn" - }, - { - id: "gaearon", - name: "Dan Abramov" - }, - { - id: "trueadm", - name: "Dominic Gannaway" - }, - { - id: "flarnie", - name: "Flarnie Marchan" - }, - { - id: "sebmarkbage", - name: "Sebastian Markbåge" - }, - { - id: "sophiebits", - name: "Sophie Alpert" - }, - { - id: "ryanflorence", - name: "Ryan Florence" - } -]; - -export const userProfileJSON = { - ryanflorence: { - id: "ryanflorence", - name: "Ryan Florence", - image: "/img/ryanflorence.jpeg", - location: "Seattle, WA", - email: "hello@reach.tech", - tagline: "Not React core at Facebook. Hi!" - }, - acdlite: { - id: "acdlite", - name: "Andrew Clark", - image: "/img/acdlite.jpeg", - location: "Redwood City, CA", - email: "acdlite@me.com", - tagline: "React core at Facebook. Hi!" - }, - bvaughn: { - id: "bvaughn", - name: "Brian Vaughn", - image: "/img/bvaughn.jpeg", - location: "Mountain View, CA", - email: "brian.david.vaughn@gmail.com", - tagline: - "React JS core team at @facebook; formerly at @treasure-data and @google." - }, - gaearon: { - id: "gaearon", - name: "Dan Abramov", - image: "/img/gaearon.jpeg", - location: "London, UK", - email: "dan.abramov@me.com", - tagline: - "Working on @reactjs. Co-author of Redux and Create React App. Building tools for humans." - }, - flarnie: { - id: "flarnie", - name: "Flarnie Marchan", - image: "/img/flarnie.jpeg", - location: "Oakland, CA", - email: null, - tagline: - "Software Engineer at Facebook React Core Team & Co-maintainer of Draft.js" - }, - sebmarkbage: { - id: "sebmarkbage", - name: "Sebastian Markbåge", - image: "/img/sebmarkbage.jpeg", - location: "San Francisco", - email: "sebastian@calyptus.eu", - tagline: null - }, - sophiebits: { - id: "sophiebits", - name: "Sophie Alpert", - image: "/img/sophiebits.jpeg", - location: "California", - email: "hi@sophiebits.com", - tagline: - "I like fixing things. eng manager of @reactjs at Facebook. ex-@khanacademy. 💎🌸 she/her. kindness, intersectional feminism, music." - }, - trueadm: { - id: "trueadm", - name: "Dominic Gannaway", - image: "/img/trueadm.jpeg", - location: "London, United Kingdom", - email: null, - tagline: - "Currently an engineer on the React core team at @facebook. Author of @infernojs and t7. Enjoys coding + being a Dad." - } -}; -export const userRepositoriesListJSON = { - ryanflorence: [ - { - name: "Reach Router", - url: "https://github.com/reach/router", - description: "Next Generation Routing for React.js" - }, - { - name: "Reach UI", - url: "https://github.com/reach/reach-ui", - description: "The Missing (Accessible) Components for React Web." - }, - { - name: "React Component Component", - url: "https://github.com/reactions/component", - description: - "Dynamic React Component Definitions. A joke component turned awesome." - } - ], - acdlite: [ - { - name: "recompose", - url: "https://github.com/acdlite/recompose", - description: - "A React utility belt for function components and higher-order components." - }, - { - name: "react-fiber-architecture", - url: "https://github.com/acdlite/react-fiber-architecture", - description: "A description of React's new core algorithm, React Fiber" - }, - { - name: "redux-router", - url: "https://github.com/acdlite/redux-router", - description: - "Redux bindings for React Router – keep your router state inside your Redux store" - }, - { - name: "flummox", - url: "https://github.com/acdlite/flummox", - description: "Minimal, isomorphic Flux." - }, - { - name: "redux-rx", - url: "https://github.com/acdlite/redux-rx", - description: "RxJS utilities for Redux." - }, - { - name: "react-remarkable", - url: "https://github.com/acdlite/react-remarkable", - description: "A React component for rendering Markdown with remarkable" - } - ], - bvaughn: [ - { - name: "react-virtualized", - url: "https://github.com/bvaughn/react-virtualized", - description: - "React components for efficiently rendering large lists and tabular data" - }, - { - name: "redux-search", - url: "https://github.com/bvaughn/redux-search", - description: "Redux bindings for client-side search" - }, - { - name: "react-window", - url: "https://github.com/bvaughn/react-window", - description: - "React components for efficiently rendering large lists and tabular data" - }, - { - name: "react-virtualized-select", - url: "https://github.com/bvaughn/react-virtualized-select", - description: - "HOC that uses react-virtualized and react-select to display large lists of options in a drop-down" - }, - { - name: "js-search", - url: "https://github.com/bvaughn/js-search", - description: - "JS Search is an efficient, client-side search library for JavaScript and JSON objects" - }, - { - name: "react-highlight-words", - url: "https://github.com/bvaughn/react-highlight-words", - description: - "React component to highlight words within a larger body of text" - } - ], - gaearon: [ - { - name: "facebook/react", - url: "https://github.com/facebook/react", - description: - "A declarative, efficient, and flexible JavaScript library for building user interfaces." - }, - { - name: "reduxjs/redux", - url: "https://github.com/reduxjs/redux", - description: "Predictable state container for JavaScript apps" - }, - { - name: "facebook/create-react-app", - url: "https://github.com/facebook/create-react-app", - description: "Create React apps with no build configuration." - }, - { - name: "reduxjs/redux-devtools", - url: "https://github.com/reduxjs/redux-devtools", - description: - "DevTools for Redux with hot reloading, action replay, and customizable UI" - }, - { - name: "react-dnd/react-dnd", - url: "https://github.com/react-dnd/react-dnd", - description: "Drag and Drop for React" - }, - { - name: "paularmstrong/normalizr", - url: "https://github.com/paularmstrong/normalizr", - description: "Normalizes nested JSON according to a schema" - } - ], - flarnie: [ - { - name: "diffux/diffux", - url: "https://github.com/diffux/diffux", - description: "Perceptual diffs of responsive screenshots made simple." - }, - { - name: "facebook/draft-js", - url: "https://github.com/facebook/draft-js", - description: "A React framework for building text editors." - }, - { - name: "facebook/react", - url: "https://github.com/facebook/react", - description: - "A declarative, efficient, and flexible JavaScript library for building user interfaces." - }, - { - name: "facebook/jest", - url: "https://github.com/facebook/jest", - description: "🃏 Delightful JavaScript Testing." - }, - { - name: "Galooshi/import-js", - url: "https://github.com/Galooshi/import-js", - description: "A tool to simplify importing JS modules" - }, - { - name: "webpack_rails_demo", - url: "https://github.com/flarnie/webpack_rails_demo", - description: "Setting up webpack with Ruby on Rails: a basic demo" - } - ], - sebmarkbage: [ - { - name: "art", - url: "https://github.com/sebmarkbage/art", - description: - "Retained mode vector drawing API designed for multiple output modes. There's also a built-in SVG parser." - }, - { - name: "ecmascript-immutable-data-structures", - url: - "https://github.com/sebmarkbage/ecmascript-immutable-data-structures", - description: null - }, - { - name: "ocamlrun-wasm", - url: "https://github.com/sebmarkbage/ocamlrun-wasm", - description: "OCamlrun WebAssembly - OCaml Bytecode Interpreter in WASM" - }, - { - name: "ecmascript-generator-expression", - url: "https://github.com/sebmarkbage/ecmascript-generator-expression", - description: - "Proposal for do Generator Expressions in ECMAScript. Work in progress. Edit Add topics" - }, - { - name: "ecmascript-undefined-propagation", - url: "https://github.com/sebmarkbage/ecmascript-undefined-propagation", - description: - "ECMAScript proposal to relax the rules to return `undefined` for property access on `null` or `undefined` instead of throwing." - }, - { - name: "ecmascript-shallow-equal", - url: "https://github.com/sebmarkbage/ecmascript-shallow-equal", - description: "A proposal for ECMAScript for Object.shallowEqual" - } - ], - sophiebits: [ - { - name: "facebook/react", - url: "https://github.com/facebook/react", - description: - "A declarative, efficient, and flexible JavaScript library for building user interfaces." - }, - { - name: "Khan/KaTeX", - url: "https://github.com/Khan/KaTeX", - description: "Fast math typesetting for the web." - }, - { - name: "facebook/react-devtools", - url: "https://github.com/facebook/react-devtools", - description: - "An extension that allows inspection of React component hierarchy in the Chrome and Firefox Developer Tools." - }, - { - name: "vim-awesome/vim-awesome", - url: "https://github.com/vim-awesome/vim-awesome", - description: "Awesome Vim plugins from across the universe" - }, - { - name: "facebook/draft-js", - url: "https://github.com/facebook/draft-js", - description: "A React framework for building text editors." - }, - { - name: "es3ify", - url: "https://github.com/sophiebits/es3ify", - description: - "Browserify transform to convert ES5 syntax to be ES3-compatible." - } - ], - trueadm: [ - { - name: "facebook/react", - url: "https://github.com/facebook/react", - description: - "A declarative, efficient, and flexible JavaScript library for building user interfaces." - }, - { - name: "infernojs/inferno", - url: "https://github.com/infernojs/inferno", - description: - "An extremely fast, React-like JavaScript library for building modern user interfaces" - }, - { - name: "facebook/prepack", - url: "https://github.com/facebook/prepack", - description: "A JavaScript bundle optimizer." - }, - { - name: "t7", - url: "https://github.com/trueadm/t7", - description: "Lightweight virtual DOM templating library" - }, - { - name: "infernojs/babel-plugin-inferno", - url: "https://github.com/infernojs/babel-plugin-inferno", - description: null - } - ] -}; diff --git a/08-suspense/lecture/src/api/index.js b/08-suspense/lecture/src/api/index.js deleted file mode 100644 index 37d8f43..0000000 --- a/08-suspense/lecture/src/api/index.js +++ /dev/null @@ -1,67 +0,0 @@ -import { - coreContributorListJSON, - userProfileJSON, - userRepositoriesListJSON -} from "./data"; - -export function fetchCoreContributorListJSON() { - return makeFakeAPICall("/react/contributors", coreContributorListJSON); -} - -export function fetchUserProfileJSON(id) { - return makeFakeAPICall(`/${id}/details`, userProfileJSON[id]); -} - -export function fetchUserRepositoriesListJSON(id) { - return makeFakeAPICall(`/${id}/repositories`, userRepositoriesListJSON[id]); -} - -let fakeRequestTime = 3000; -let onProgress = () => true; - -export function setFakeRequestTime(val) { - fakeRequestTime = val; -} - -export function setProgressHandler(handler) { - onProgress = handler; -} - -export function setPauseNewRequests(value) { - shouldPauseNewRequests = value; -} - -let shouldPauseNewRequests = false; -let notifiers = {}; -let isPausedUrl = {}; - -export function setPaused(url, isPaused) { - const wasPaused = isPausedUrl[url]; - isPausedUrl[url] = isPaused; - if (isPaused !== wasPaused) { - notifiers[url](); - } -} - -function makeFakeAPICall(url, result) { - let i = 1; - return new Promise(resolve => { - isPausedUrl[url] = shouldPauseNewRequests; - function notify() { - if (!isPausedUrl[url]) { - i++; - } - onProgress(url, i, isPausedUrl[url]); - if (isPausedUrl[url]) { - return; - } - if (i === 100) { - resolve(result); - } else { - setTimeout(notify, fakeRequestTime / 100); - } - } - notifiers[url] = notify; - notify(); - }); -} diff --git a/08-suspense/lecture/src/components/App.js b/08-suspense/lecture/src/components/App.js deleted file mode 100644 index 7854e66..0000000 --- a/08-suspense/lecture/src/components/App.js +++ /dev/null @@ -1,70 +0,0 @@ -import React, { Placeholder, PureComponent, Fragment } from "react"; -import { unstable_deferredUpdates } from "react-dom"; -import { createResource } from "simple-cache-provider"; -import { cache } from "../cache"; -import Spinner from "./Spinner"; -import ContributorListPage from "./ContributorListPage"; -import { Router, Link, Location } from "@reach/router"; -import ManageScroll from "./ManageScroll"; - -const UserPageResource = createResource(() => import("./UserPage")); - -function UserPageLoader(props) { - const UserPage = UserPageResource.read(cache).default; - return ; -} - -class App extends PureComponent { - state = { - loadingId: null - }; - - handleUserClick = id => { - this.setState({ loadingId: id }); - }; - - render() { - const { loadingId } = this.state; - return ( - }> - - - ); - } -} - -class Detail extends PureComponent { - render() { - const { id } = this.props; - return ( -
- - Return to list - - }> - - -
- ); - } -} - -export default () => ( - - - - - - - -); diff --git a/08-suspense/lecture/src/components/ContributorListPage.js b/08-suspense/lecture/src/components/ContributorListPage.js deleted file mode 100644 index 3da8844..0000000 --- a/08-suspense/lecture/src/components/ContributorListPage.js +++ /dev/null @@ -1,74 +0,0 @@ -import React, { Fragment } from "react"; -import { createResource } from "simple-cache-provider"; -import { cache } from "../cache"; -import Spinner from "./Spinner"; -import { fetchCoreContributorListJSON } from "../api"; -import { Link } from "@reach/router"; - -const ContributorListResource = createResource(fetchCoreContributorListJSON); - -const ContributorListPage = ({ loadingId, onUserClick }) => ( - -

React Core Team

-
    - {ContributorListResource.read(cache).map(user => ( - onUserClick(user.id)} - isLoading={loadingId && user.id === loadingId} - user={user} - /> - ))} -
-
-); - -const ContributorListItem = ({ isLoading, onClick, user }) => ( -
  • - -
    - {user.name} -
    {user.id}
    -
    - {isLoading ? ( - - ) : ( - - - - - )} - -
  • -); - -export default ContributorListPage; diff --git a/08-suspense/lecture/src/components/Spinner.css b/08-suspense/lecture/src/components/Spinner.css deleted file mode 100644 index 552c85b..0000000 --- a/08-suspense/lecture/src/components/Spinner.css +++ /dev/null @@ -1,75 +0,0 @@ -.Spinner { - animation: rotate 1.3s linear infinite; -} - -.SpinnerContainer-large { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - -@keyframes rotate { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(270deg); } -} - -.SmallSpinnerPath { - stroke-dasharray: 100; - stroke-dashoffset: 0; - transform-origin: center; - animation: - SmallDash 1.3s ease-in-out infinite; -} - -@keyframes SmallDash { - 0% { stroke-dashoffset: 100; } - 50% { - stroke-dashoffset: 50; - transform:rotate(135deg); - } - 100% { - stroke-dashoffset: 100; - transform:rotate(450deg); - } -} - -.MediumSpinnerPath { - stroke-dasharray: 150; - stroke-dashoffset: 0; - transform-origin: center; - animation: - MediumDash 1.3s ease-in-out infinite; -} - -@keyframes MediumDash { - 0% { stroke-dashoffset: 150; } - 50% { - stroke-dashoffset: 50; - transform:rotate(135deg); - } - 100% { - stroke-dashoffset: 150; - transform:rotate(450deg); - } -} - -.LargeSpinnerPath { - stroke-dasharray: 200; - stroke-dashoffset: 0; - transform-origin: center; - animation: - LargeDash 1.3s ease-in-out infinite; -} - -@keyframes LargeDash { - 0% { stroke-dashoffset: 200; } - 50% { - stroke-dashoffset: 50; - transform:rotate(135deg); - } - 100% { - stroke-dashoffset: 200; - transform:rotate(450deg); - } -} diff --git a/08-suspense/lecture/src/components/Spinner.js b/08-suspense/lecture/src/components/Spinner.js deleted file mode 100644 index 8ea7251..0000000 --- a/08-suspense/lecture/src/components/Spinner.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import './Spinner.css'; - -const SPINNER_SIZES = { - small: 30, - medium: 50, - large: 70, -}; - -const STROKE_WIDTHS = { - small: 4, - medium: 5, - large: 6, -}; - -const PATH_CLASS_NAMES = { - small: 'SmallSpinnerPath', - medium: 'MediumSpinnerPath', - large: 'LargeSpinnerPath', -}; - -// Heavily inspired by https://codepen.io/mrrocks/pen/EiplA -export default function Spinner({size = 'small'}) { - const baseSize = SPINNER_SIZES[size]; - const pathSize = baseSize / 2; - const strokeWidth = STROKE_WIDTHS[size]; - const pathRadius = `${baseSize / 2 - strokeWidth}px`; - const className = PATH_CLASS_NAMES[size]; - const containerClassName = `SpinnerContainer SpinnerContainer-${size}`; - - return ( -
    - - - -
    - ); -} diff --git a/08-suspense/lecture/src/components/UserPage.js b/08-suspense/lecture/src/components/UserPage.js deleted file mode 100644 index a1b96de..0000000 --- a/08-suspense/lecture/src/components/UserPage.js +++ /dev/null @@ -1,169 +0,0 @@ -import React, {Placeholder} from 'react'; -import {createResource} from 'simple-cache-provider'; -import Spinner from './Spinner'; -import {cache} from '../cache'; -import {fetchUserProfileJSON, fetchUserRepositoriesListJSON} from '../api'; - -export default function UserPage({id}) { - return ( -
    - - }> - - -
    - ); -} - -const UserDetailsResource = createResource(fetchUserProfileJSON); - -function UserDetails({id}) { - const user = UserDetailsResource.read(cache, id); - return ( -
    - -
    - {user.name} -
    -
    {user.id}
    - {user.tagline !== null &&
    {user.tagline}
    } -
    - {user.location && } - {user.email && } -
    - ); -} - -const Location = ({location}) => ( -
    - - - - - {location} -
    -); - -const Email = ({email}) => ( -
    - - - - - {email} -
    -); - -const ImageResource = createResource( - src => - new Promise(resolve => { - const img = new Image(); - img.onload = () => resolve(src); - img.src = src; - }) -); - -function Img({src, alt, ...rest}) { - return {alt}; -} - -function UserPicture({source}) { - return ( - }> - profile picture - - ); -} - -const UserRepositoriesResource = createResource(fetchUserRepositoriesListJSON); - -function Repositories({id}) { - const repos = UserRepositoriesResource.read(cache, id); - return ( -
      - {repos.map(repo => )} -
    - ); -} - -function Repository({description, name, url}) { - return ( -
  • - - {name} - -
    {description}
    -
  • - ); -} diff --git a/08-suspense/lecture/src/favicon.ico b/08-suspense/lecture/src/favicon.ico deleted file mode 100644 index d392c1d17f50067c1d9ad519e14048d211269de3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 diff --git a/08-suspense/lecture/src/workouts/Competitions.js b/08-suspense/lecture/src/lib/Competitions.js similarity index 100% rename from 08-suspense/lecture/src/workouts/Competitions.js rename to 08-suspense/lecture/src/lib/Competitions.js diff --git a/08-suspense/lecture/src/components/ManageScroll.js b/08-suspense/lecture/src/lib/ManageScroll.js similarity index 100% rename from 08-suspense/lecture/src/components/ManageScroll.js rename to 08-suspense/lecture/src/lib/ManageScroll.js diff --git a/08-suspense/lecture/src/cache.js b/08-suspense/lecture/src/lib/cache.js similarity index 100% rename from 08-suspense/lecture/src/cache.js rename to 08-suspense/lecture/src/lib/cache.js diff --git a/08-suspense/lecture/src/index.css b/08-suspense/lecture/src/lib/index.css similarity index 100% rename from 08-suspense/lecture/src/index.css rename to 08-suspense/lecture/src/lib/index.css diff --git a/08-suspense/lecture/src/workouts/utils.js b/08-suspense/lecture/src/lib/utils.js similarity index 79% rename from 08-suspense/lecture/src/workouts/utils.js rename to 08-suspense/lecture/src/lib/utils.js index b8bf700..ed40711 100644 --- a/08-suspense/lecture/src/workouts/utils.js +++ b/08-suspense/lecture/src/lib/utils.js @@ -1,7 +1,15 @@ import { createResource } from "simple-cache-provider"; //////////////////////////////////////////////////////////// -let qnetworks = ["fast", "slow", "slow", "fast", "slow", "fast", "nextIsSlow"]; +let qnetworks = [ + "fast", + "slow", + "slow", + "fast", + "slow", + "fast", + "nextIsSlow" +]; let search = window.location.search.substr(1); let network = qnetworks[search] || "fast"; @@ -10,7 +18,8 @@ export { network }; //////////////////////////////////////////////////////////// -const sleep = (ms = 1000) => new Promise(res => setTimeout(res, ms)); +const sleep = (ms = 1000) => + new Promise(res => setTimeout(res, ms)); let token = null; @@ -42,9 +51,17 @@ const fakeWorkouts = [ completed: true }, { name: "Cardio", id: "cardio", completed: true }, - { name: "Lower Body", id: "lower", completed: false }, + { + name: "Lower Body", + id: "lower", + completed: false + }, { name: "Core", id: "core", completed: false }, - { name: "Upper Body", id: "upper-body", completed: false } + { + name: "Upper Body", + id: "upper-body", + completed: false + } ]; const fakeExercises = { @@ -63,7 +80,12 @@ const fakeExercises = { "jab punch sprawl", "burpees" ], - lower: ["lunges", "jump squats", "side-kicks", "hip raises"], + lower: [ + "lunges", + "jump squats", + "side-kicks", + "hip raises" + ], core: ["crunches"], "upper-body": ["curls"] }; @@ -99,6 +121,8 @@ export const fetchExercises = id => console.logTakeoff(`fetchExercises ${id}`); await sleep(2000); console.logLanding(`fetchExercises ${id}`); + console.log("-------"); + console.log(fakeExercises[id]); res(fakeExercises[id]); }); @@ -107,7 +131,11 @@ export const fetchNextWorkout = id => console.logTakeoff(`fetchNext ${id}`); await sleep(3000); console.logLanding(`fetchNext ${id}`); - res(fakeWorkouts.find(workout => workout.id === fakeNextWorkouts[id])); + res( + fakeWorkouts.find( + workout => workout.id === fakeNextWorkouts[id] + ) + ); }); //////////////////////////////////////////////////////////// @@ -148,14 +176,22 @@ export const NextWorkoutResource = createResource( console.logTakeoff(`readRelated ${id}`); await sleep(networks[network].next); console.logLanding(`readRelated ${id}`); - res(fakeWorkouts.find(workout => workout.id === fakeNextWorkouts[id])); + res( + fakeWorkouts.find( + workout => + workout.id === fakeNextWorkouts[id] + ) + ); }) ); //////////////////////////////////////////////////////// // Contacts const API = `https://contacts.now.sh`; -const fetchContacts = async (url, opts = { headers: {} }) => { +const fetchContacts = async ( + url, + opts = { headers: {} } +) => { return fetch(`${API}${url}`, { ...opts, headers: { authorization: token, ...opts.headers } @@ -168,7 +204,9 @@ const fetchContacts = async (url, opts = { headers: {} }) => { }); }; -export const readContacts = createResource(() => fetchContacts("/contacts")); +export const readContacts = createResource(() => + fetchContacts("/contacts") +); export const readContact = createResource(id => fetchContacts(`/contacts/${id}`) @@ -186,9 +224,15 @@ export const createContact = contact => //////////////////////////////////////////////////////// // logging stuff console.logTakeoff = str => { - console.log(`%c🛫 ${str}`, "font-size: 20px; color: hsl(10, 50%, 50%)"); + console.log( + `%c🛫 ${str}`, + "font-size: 20px; color: hsl(10, 50%, 50%)" + ); }; console.logLanding = str => { - console.log(`%c🛬 ${str}`, "font-size: 20px; color: hsl(170, 50%, 50%)"); + console.log( + `%c🛬 ${str}`, + "font-size: 20px; color: hsl(170, 50%, 50%)" + ); }; diff --git a/08-suspense/lecture/src/workouts/App.js b/08-suspense/lecture/src/workouts/App.js deleted file mode 100644 index 81a7b54..0000000 --- a/08-suspense/lecture/src/workouts/App.js +++ /dev/null @@ -1,283 +0,0 @@ -import { createElement } from "glamor/react"; // eslint-disable-line -/* @jsx createElement */ -import "./index.css"; -import Spinner from "react-svg-spinner"; -import ManageScroll from "../components/ManageScroll"; -import React, { Placeholder, lazy } from "react"; -import { Router, Link, redirectTo } from "@reach/router"; -import Component from "@reach/component-component"; -import { - fetchWorkouts, - fetchWorkout, - fetchExercises, - fetchNextWorkout, - WorkoutsResource, - WorkoutResource, - ExercisesResource, - NextWorkoutResource, - network -} from "./utils"; -import { cache } from "../cache"; - -const Competitions = React.lazy(() => - import("./Competitions") -); - -// Chantastic said this is okay to do. -console.warn = () => {}; - -let qpatience = [5000, 5000, 1, 1, 2000, 2000, 2000]; -let search = window.location.search.substr(1); -let patience = qpatience[search] || 10000; - -const link = { - display: "inline-block", - width: "200px", - height: "200px", - lineHeight: "200px", - background: "#fff", - textAlign: "center", - margin: "20px", - ":hover": { - background: "#ddd" - }, - position: "relative" -}; - -const LoadingLink = ({ children, ...props }) => ( - - {({ state, setState }) => ( - { - setState({ isLoading: true }); - }} - > - {children} -
    - -
    - - )} -
    -); - -const Home = () => ( -
    -

    Workout App!

    -
    - - Workouts - - - Competitions - -
    -
    -); - -const Workouts = () => { - const workouts = WorkoutsResource.read(cache, 10); - return ( -
    - Home -

    Workouts

    - {workouts.map(workout => ( - - {workout.name} - - ))} -
    - ); -}; - -const Exercises = ({ workoutId }) => { - const exercises = ExercisesResource.read( - cache, - workoutId - ); - return ( -
      - {exercises.map((exercise, i) => ( -
    • {exercise}
    • - ))} -
    - ); -}; - -class Workout extends React.Component { - state = { - workout: null, - exercises: null, - nextWorkout: null - }; - - componentDidMount() { - this.fetch(); - } - - fetch() { - const { workoutId } = this.props; - fetchWorkout(workoutId).then(workout => { - this.setState({ workout }); - }); - fetchExercises(workoutId).then(exercises => { - this.setState({ exercises }); - }); - fetchNextWorkout(workoutId).then(nextWorkout => { - console.log(nextWorkout); - this.setState({ nextWorkout }); - }); - } - - componentDidUpdate(prevProps) { - if (prevProps.workoutId !== this.props.workoutId) { - this.setState({ - exercises: null, - workout: null, - nextWorkout: null - }); - this.fetch(); - } - } - - render() { - const { workoutId } = this.props; - const { workout, exercises, nextWorkout } = this.state; - - WorkoutResource.read(cache, workoutId); - - return workout ? ( -
    - Home /{" "} - Workouts -

    {workout.name}

    - {exercises ? ( - - ) : ( - - )} - {workout.completed && - (nextWorkout ? ( - - ) : ( -

    - Up Next! -

    - ))} -
    - ) : ( - - ); - } -} - -// class Workout extends React.Component { -// render() { -// const { workoutId } = this.props; - -// const workout = WorkoutResource.read(cache, workoutId); - -// return ( -//
    -// Home /{" "} -// Workouts -//

    {workout.name}

    -// } -// > -// -// -// {workout.completed && ( -// -// Up Next! -//

    -// } -// > -// -// -// )} -//
    -// ); -// } -// } - -const NextWorkout = ({ workoutId }) => { - const nextWorkout = NextWorkoutResource.read( - cache, - workoutId - ); - return ( -
    -

    - Up Next!{" "} - - {nextWorkout.name} - -

    -
    - ); -}; - -const LoadingSpinner = () => ( -
    - -
    -); - -const Network = () => ( -
    - Network: {network} -
    -); - -const App = () => { - return ( - - } - > - - - - - - - - - - - ); -}; - -export default App; diff --git a/08-suspense/lecture/src/workouts/Img.js b/08-suspense/lecture/src/workouts/Img.js deleted file mode 100644 index 91e53d6..0000000 --- a/08-suspense/lecture/src/workouts/Img.js +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable jsx-a11y/alt-text */ -import React from "react"; -import { createResource } from "simple-cache-provider"; -import withCache from "./withCache"; - -const ImageResource = createResource(src => { - const image = new Image(); - return new Promise(resolve => { - image.onload = () => resolve(src); - image.src = src; - }); -}); - -function Img({ cache, src, ...props }) { - return ; -} - -export const preload = ImageResource.preload; - -export default withCache(Img); diff --git a/08-suspense/lecture/src/workouts/withCache.js b/08-suspense/lecture/src/workouts/withCache.js deleted file mode 100644 index 8edb126..0000000 --- a/08-suspense/lecture/src/workouts/withCache.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; -import { SimpleCache } from "simple-cache-provider"; - -export default Comp => props => ( - - {cache => } - -);