feat: Installable PWA (#1882)

This commit is contained in:
Tom Moor
2021-02-15 15:19:51 -08:00
committed by GitHub
parent 4b603460cb
commit 7e922d8716
22 changed files with 1093 additions and 75 deletions

View File

@@ -11,7 +11,7 @@ type Props = {|
const Container = styled.div`
width: 100%;
max-width: 100vw;
padding: ${(props) => (props.withStickyHeader ? "4px 20px" : "60px 20px")};
padding: ${(props) => (props.withStickyHeader ? "4px 12px" : "60px 12px")};
${breakpoint("tablet")`
padding: ${(props) => (props.withStickyHeader ? "4px 60px" : "60px")};

View File

@@ -163,8 +163,11 @@ const DocumentLink = styled(Link)`
padding: 6px 8px;
border-radius: 8px;
max-height: 50vh;
min-width: 100%;
max-width: calc(100vw - 40px);
width: calc(100vw - 8px);
${breakpoint("tablet")`
width: auto;
`};
${Actions} {
opacity: 0;

View File

@@ -7,7 +7,7 @@ import { Helmet } from "react-helmet";
import { withTranslation, type TFunction } from "react-i18next";
import keydown from "react-keydown";
import { Switch, Route, Redirect } from "react-router-dom";
import styled, { withTheme } from "styled-components";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import AuthStore from "stores/AuthStore";
import DocumentsStore from "stores/DocumentsStore";
@@ -24,7 +24,6 @@ import Sidebar from "components/Sidebar";
import SettingsSidebar from "components/Sidebar/Settings";
import SkipNavContent from "components/SkipNavContent";
import SkipNavLink from "components/SkipNavLink";
import { type Theme } from "types";
import { meta } from "utils/keyboard";
import {
homeUrl,
@@ -40,7 +39,6 @@ type Props = {
auth: AuthStore,
ui: UiStore,
notifications?: React.Node,
theme: Theme,
i18n: Object,
t: TFunction,
};
@@ -51,24 +49,12 @@ class Layout extends React.Component<Props> {
@observable redirectTo: ?string;
@observable keyboardShortcutsOpen: boolean = false;
constructor(props: Props) {
super();
this.updateBackground(props);
}
componentDidUpdate() {
this.updateBackground(this.props);
if (this.redirectTo) {
this.redirectTo = undefined;
}
}
updateBackground(props: Props) {
// ensure the wider page color always matches the theme
window.document.body.style.background = props.theme.background;
}
@keydown(`${meta}+.`)
handleToggleSidebar() {
this.props.ui.toggleCollapsedSidebar();
@@ -212,5 +198,5 @@ const Content = styled(Flex)`
`;
export default withTranslation()<Layout>(
inject("auth", "ui", "documents")(withTheme(Layout))
inject("auth", "ui", "documents")(Layout)
);

View File

@@ -0,0 +1,35 @@
// @flow
import * as React from "react";
import { useTheme } from "styled-components";
import useStores from "hooks/useStores";
export default function PageTheme() {
const { ui } = useStores();
const theme = useTheme();
React.useEffect(() => {
// wider page background beyond the React root
if (document.body) {
document.body.style.background = theme.background;
}
// theme-color adjusts the title bar color for desktop PWA
const themeElement = document.querySelector('meta[name="theme-color"]');
if (themeElement) {
themeElement.setAttribute("content", theme.background);
}
// status bar color for iOS PWA
const statusElement = document.querySelector(
'meta[name="apple-mobile-web-app-status-bar-style"]'
);
if (statusElement) {
statusElement.setAttribute(
"content",
ui.resolvedTheme === "dark" ? "black-translucent" : "default"
);
}
}, [theme, ui.resolvedTheme]);
return null;
}

View File

@@ -46,6 +46,7 @@ export const ToggleButton = styled.button`
`;
export const Positioner = styled.div`
display: none;
z-index: 2;
position: absolute;
top: 0;
@@ -56,6 +57,10 @@ export const Positioner = styled.div`
&:hover ${ToggleButton}, &:focus-within ${ToggleButton} {
opacity: 1;
}
${breakpoint("tablet")`
display: block;
`}
`;
export default Toggle;

View File

@@ -33,7 +33,7 @@ const Sticky = styled.div`
padding: 0 8px;
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
z-index: ${(props) => props.theme.depths.stickyHeader};
z-index: 1;
`;
const Subheading = ({ children, ...rest }: Props) => {

View File

@@ -19,7 +19,7 @@ const Sticky = styled.div`
padding: 0 8px;
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
z-index: ${(props) => props.theme.depths.stickyHeader};
z-index: 1;
`;
export const Separator = styled.span`