Skip to content
This repository has been archived by the owner on Sep 7, 2020. It is now read-only.

Commit

Permalink
Docs: try to use a banner for AppCache notifications
Browse files Browse the repository at this point in the history
Ref #277
  • Loading branch information
MoOx committed Jun 10, 2016
1 parent d15cf4e commit d9b58e5
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 0 deletions.
68 changes: 68 additions & 0 deletions docs/web_modules/AppcacheBanner/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.banner {
position: fixed;
position: sticky;
top: 0;
left: 0;
right: 0;
}

.banner:empty {
display: none;
}

.spinner {
height: 1rem;
width: 1rem;
border: 2px solid transparent;
border-top-color: #fff;
border-radius: 100%;
animation: PhenomicDocsAppCacheBannerRotation 0.6s infinite linear 0.25s;
opacity: 0;

margin-right: 0.6rem;
}

@keyframes PhenomicDocsAppCacheBannerRotation {
from {
opacity: 1;
transform: rotate(0deg);
}
to {
opacity: 1;
transform: rotate(359deg);
}
}

.content {
flex: 1;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;

font-size: 0.75rem;
padding: 0.4rem 0.6rem;
line-height: 1.4rem;

background: #1cae69;
color: #fff;
}

.message {
display: flex;
border: 1px solid transparent; /* to fit button border */
}

.actions {
display: flex;
}

.button {
display: inline-flex;
border: 1px solid currentColor;
border-radius: 3px;
padding: 0 0.3rem;
margin-left: 0.6rem;

cursor: pointer;
}
156 changes: 156 additions & 0 deletions docs/web_modules/AppcacheBanner/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, { Component, PropTypes } from "react"

import styles from "./index.css"

export default class AppCacheBanner extends Component {

static propTypes = {
color: PropTypes.string,
backgroundColor: PropTypes.string,
backgroundColorError: PropTypes.string,
}

static defaultProps = {
color: "#fff",
backgroundColor: "#1cae69",
backgroundColorError: "#d32f2f",
};

constructor(props) {
super(props)
this.state = {
event: undefined,
}

// for testing UI
if (typeof window !== "undefined") {
window.PhenomicAppCacheBanner = this
}
}

componentDidMount() {
if (typeof window !== "undefined" && window.applicationCache) {
window.applicationCache.addEventListener(
"downloading", this.appcacheDownloading, false
)
window.applicationCache.addEventListener(
"error", this.appcacheError, false
)
window.applicationCache.addEventListener(
"updateready", this.appcacheUpdateReady, false
)
// obsolete cache is when manifest is gone
// which require an update as well
window.applicationCache.addEventListener(
"obsolete", this.appcacheUpdateReady, false
)
}
}

appcacheDownloading = () => {
this.setState({ event: "downloading" })
};

appcacheError = () => {
// trigger a UI error only if the download fails
if (this.state.event === "downloading") {
this.setState({ event: "error" })
}
};

appcacheUpdateReady = () => {
this.setState({ event: "updateready" })
};

handleRefresh = () => {
try {
window.applicationCache.swapCache()
}
catch (e) {
window.location.reload()
}
};

handleDismiss = () => {
this.setState({ event: undefined })
};

render() {
const { props, state } = this

return (
<div className={ styles.banner }>
{
state.event === "downloading" &&
<div
className={ styles.content }
style={ {
backgroundColor: props.backgroundColor,
color: props.color,
} }
>
<div className={ styles.message }>
<div className={ styles.spinner } />
{ "Updating website cache..." }
</div>
</div>

}
{
state.event === "updateready" &&
<div
className={ styles.content }
style={ {
backgroundColor: props.backgroundColor,
color: props.color,
} }
>
<div className={ styles.message }>
{ "Website cache has been updated." }
</div>
<div className={ styles.action }>
<div
role="button"
className={ styles.button }
onClick={ this.handleRefresh }
>
{ "Refresh" }
</div>
<div
role="button"
className={ styles.button }
onClick={ this.handleDismiss }
>
{ "╳" }
</div>
</div>
</div>
}
{
state.event === "error" &&
<div
className={ styles.content }
style={ {
backgroundColor: props.backgroundColorError,
color: props.color,
} }
>
<div className={ styles.message }>
{ "An error occured during the website update. " }
{ "Check your network or try later." }
</div>
<div className={ styles.action }>
<div
role="button"
className={ styles.button }
onClick={ this.handleDismiss }
>
{ "╳" }
</div>
</div>
</div>
}
</div>
)
}
}
2 changes: 2 additions & 0 deletions docs/web_modules/LayoutContainer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Helmet from "react-helmet"
import Header from "../Header"
import Footer from "../Footer"
import GoogleAnalyticsTracker from "../GoogleAnalyticsTracker"
import AppCacheBanner from "../AppCacheBanner"

import "./index.global.css"
import "./hightlightjs.global.css"
Expand Down Expand Up @@ -53,6 +54,7 @@ export default class Layout extends Component {
<style>{ "@-ms-viewport { width: device-width; }" }</style>

<div className={ styles.layout }>
<AppCacheBanner />
<Header />
<div className={ styles.content }>
{ this.props.children }
Expand Down

0 comments on commit d9b58e5

Please sign in to comment.