Skip to content

Commit

Permalink
Quickload for Homepage on low connectivity (#1707)
Browse files Browse the repository at this point in the history
* Start on making homepage nicer for low connectivity devices

* Conditionally load homepage content.

* Allow everything to be seen nods

* Also check device memory

* Betterchecking by running multiple times

* Allow Blue Anouncment Banner to have variable height so it can take an announcement of any number of characters and still display on an screens size

* Continuously improving

* Remove unused code and make poster rock

* Add fade out transition

* Looks so good

* Improve file size check

* Add transition to mobile style

* Fix lock

* fix ordering
  • Loading branch information
aaronmgdr authored and cmcewen committed Dec 11, 2019
1 parent 300558c commit f84ca28
Show file tree
Hide file tree
Showing 11 changed files with 472 additions and 179 deletions.
1 change: 1 addition & 0 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"memoize-one": "^5.1.1",
"mobile-detect": "^1.4.2",
"net": "^1.0.2",
"network-speed": "^2.0.3",
"next": "^8.0.3",
"next-i18next": "^0.36.5",
"next-images": "^1.1.1",
Expand Down
10 changes: 4 additions & 6 deletions packages/web/src/about/VideoCover.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react'
import { createElement, Image, NetInfo, StyleSheet, View, ViewStyle } from 'react-native'
import { BeautifulMoneyPreview } from 'src/about/images/index'
import { createElement, Image, StyleSheet, View, ViewStyle } from 'react-native'
import { H1, H3 } from 'src/fonts/Fonts'
import { I18nProps, NameSpaces, withNamespaces } from 'src/i18n'
import { ScreenProps, ScreenSizes, withScreenSize } from 'src/layout/ScreenSize'
Expand All @@ -9,7 +8,7 @@ import { PlayCircle2 } from 'src/shared/PlayCircle'
import VideoModal from 'src/shared/VideoModal'
import { standardStyles, textStyles } from 'src/styles'

import { getEffectiveConnection, SLOW_CONNECTIONS } from 'src/utils/utils'
import { hasGoodConnection } from 'src/utils/utils'
interface State {
isHovering: boolean
supportsVideo: boolean
Expand Down Expand Up @@ -41,9 +40,8 @@ class VideoCover extends React.PureComponent<I18nProps & ScreenProps, State> {
this.setState({ isHovering: false })
}

componentDidMount = () => {
const connectionType = getEffectiveConnection(window.navigator)
if (!SLOW_CONNECTIONS.has(connectionType)) {
componentDidMount = async () => {
if (await hasGoodConnection()) {
this.setState({ supportsVideo: true })
}
}
Expand Down
24 changes: 19 additions & 5 deletions packages/web/src/header/BlueBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ interface Props {
link: string
children: React.ReactNode
isVisible: boolean
getRealHeight: (n: number) => void
}

export class BlueBanner extends React.PureComponent<Props> {
ref = React.createRef<View>()
componentDidUpdate = () => {
this.ref.current.measure((x, y, w, height) => {
this.props.getRealHeight(height)
})
}
render() {
return (
<View style={[styles.container, styles.slideDown, this.props.isVisible && styles.isVisible]}>
<View ref={this.ref} style={[styles.container, this.props.isVisible && styles.isVisible]}>
<View style={styles.insideContainer}>
<Text
accessibilityRole="link"
Expand Down Expand Up @@ -48,11 +55,12 @@ export const styles = StyleSheet.create({
flex: 1,
},
slideDown: {
transitionProperty: 'height, top',
transitionProperty: 'top',
transitionDuration: '300ms',
},
isVisible: {
height: BANNER_HEIGHT,
minHeight: BANNER_HEIGHT,
height: 'contents',
},
insideContainer: {
width: '100%',
Expand All @@ -61,7 +69,8 @@ export const styles = StyleSheet.create({
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 40,
paddingHorizontal: 30,
paddingVertical: 5,
},
text: {
color: colors.white,
Expand All @@ -82,6 +91,7 @@ interface State {

interface AnnouncementProps {
onVisibilityChange: (visible: boolean) => void
getHeight: (n: number) => void
}

export default class Announcement extends React.Component<AnnouncementProps, State> {
Expand All @@ -108,7 +118,11 @@ export default class Announcement extends React.Component<AnnouncementProps, Sta

render() {
return (
<BlueBanner isVisible={this.state.live} link={this.state.link}>
<BlueBanner
isVisible={this.state.live}
link={this.state.link}
getRealHeight={this.props.getHeight}
>
{this.state.text}
</BlueBanner>
)
Expand Down
12 changes: 10 additions & 2 deletions packages/web/src/header/Header.3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface State {
menuFaded: boolean
belowFoldUpScroll: boolean
isBannerShowing: boolean
bannerHeight: number
}

function scrollOffset() {
Expand Down Expand Up @@ -121,6 +122,7 @@ export class Header extends React.PureComponent<Props, State> {
mobileMenuActive: false,
belowFoldUpScroll: false,
isBannerShowing: false,
bannerHeight: 0,
}
}

Expand Down Expand Up @@ -183,6 +185,10 @@ export class Header extends React.PureComponent<Props, State> {
this.setState({ isBannerShowing })
}

setBannerHeight = (height: number) => {
this.setState({ bannerHeight: height })
}

render() {
const { t } = this.props
const foreground = this.getForegroundColor()
Expand All @@ -195,7 +201,7 @@ export class Header extends React.PureComponent<Props, State> {
style={[
styles.container,
bannerStyle.slideDown,
{ top: isHomePage && this.state.isBannerShowing ? BANNER_HEIGHT : 0 },
{ top: isHomePage && this.state.isBannerShowing ? this.state.bannerHeight : 0 },
this.state.mobileMenuActive && styles.mobileMenuActive,
]}
>
Expand All @@ -206,7 +212,9 @@ export class Header extends React.PureComponent<Props, State> {
background-color: ${hamburger} !important;
}
`}</style>
{isHomePage && <BlueBanner onVisibilityChange={this.toggleBanner} />}
{isHomePage && (
<BlueBanner onVisibilityChange={this.toggleBanner} getHeight={this.setBannerHeight} />
)}
{this.state.menuFaded || (
<Animated.View
style={[
Expand Down
68 changes: 58 additions & 10 deletions packages/web/src/home/HomeAnimation.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import * as React from 'react'
import { StyleSheet } from 'react-native'
import { StyleSheet, View } from 'react-native'
import { createElement } from 'react-native-web'
import HomeOracle from 'src/home/HomeOracle'
import { ScreenProps, ScreenSizes, withScreenSize } from 'src/layout/ScreenSize'
import Responsive from 'src/shared/Responsive'
import { HEADER_HEIGHT } from 'src/shared/Styles'
import { standardStyles } from 'src/styles'

const Video = React.forwardRef((props, ref) => createElement('video', { ...props, ref }))
const Source = (props) => createElement('source', props)

interface Props {
export interface Props {
mode: Mode
onLoaded: () => void
onFinished: () => void
}
export enum Mode {
'wait',
'transition',
'video',
'graphic',
}

class HomeAnimation extends React.Component<Props & ScreenProps> {
video: any
Expand Down Expand Up @@ -55,13 +63,30 @@ class HomeAnimation extends React.Component<Props & ScreenProps> {
}

render() {
const { mode } = this.props
if (mode === Mode.graphic || mode === Mode.wait || mode === Mode.transition) {
return (
<Responsive
large={[
styles.still,
standardStyles.centered,
mode === Mode.transition && styles.fadeOut,
]}
>
<View style={[styles.stillMobile, mode === Mode.transition && styles.fadeOut]}>
<HomeOracle />
</View>
</Responsive>
)
}

return (
<Responsive large={styles.video}>
{/*
// @ts-ignore */}
<Video
ref={this.videoRef}
style={styles.videoMedium}
style={styles.videoSmall}
preload={'auto'}
muted={true}
playsInline={true}
Expand All @@ -75,16 +100,39 @@ class HomeAnimation extends React.Component<Props & ScreenProps> {

export default withScreenSize(HomeAnimation)

const styles = StyleSheet.create({
export const styles = StyleSheet.create({
fadeOut: {
animationFillMode: 'both',
animationDelay: '2700ms',
animationDuration: '300ms',
animationKeyframes: [
{
from: {
opacity: 1,
},
to: {
opacity: 0.1,
},
},
],
},
still: {
height: 'calc(100% - 250px)',
justifyContent: 'center',
},
stillMobile: {
height: '100%',
paddingTop: 50,
justifyContent: 'center',
},
video: {
height: '80vh',
height: '75vh',
width: '100vw',
objectFit: 'contain',
},
videoMedium: {
videoSmall: {
width: '100vw',
objectFit: 'contain',
marginBottom: 400,
marginTop: HEADER_HEIGHT,
marginTop: 50,
},
})
Loading

0 comments on commit f84ca28

Please sign in to comment.