feat: Installable PWA (#1882)
This commit is contained in:
@@ -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")};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
35
app/components/PageTheme.js
Normal file
35
app/components/PageTheme.js
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user