add open in app link

This commit is contained in:
Sean Yesmunt 2019-12-06 16:12:48 -05:00
parent d2a1852a8d
commit 2944ed3664
15 changed files with 170 additions and 27 deletions

View file

@ -128,7 +128,7 @@
"json-loader": "^0.5.4",
"lbry-format": "https://github.com/lbryio/lbry-format.git",
"lbry-redux": "lbryio/lbry-redux#9b11cfed62af7f0f8eb6fa3c88a1f8d2cce46afc",
"lbryinc": "lbryio/lbryinc#2aedf5a188f028f61c45bc7ed0c747a2d4ae453a",
"lbryinc": "lbryio/lbryinc#1e897d2c9108848637e1915700d3ae8ce176f9f8",
"lint-staged": "^7.0.2",
"localforage": "^1.7.1",
"lodash-es": "^4.17.14",

View file

@ -298,7 +298,6 @@
"Continue Anyway": "Continue Anyway",
"This app is running with an incompatible version of the LBRY protocol. You can still use it, but there may be issues. Re-run the installation package for best results.": "This app is running with an incompatible version of the LBRY protocol. You can still use it, but there may be issues. Re-run the installation package for best results.",
"Update ready to install": "Update ready to install",
"Install now": "Install now",
"Upgrade available": "Upgrade available",
"LBRY Leveled Up": "LBRY Leveled Up",
"Upgrade": "Upgrade",
@ -903,5 +902,6 @@
"Error Starting Up": "Error Starting Up",
"Reach out to hello@lbry.com for help, or check out %help_link%.": "Reach out to hello@lbry.com for help, or check out %help_link%.",
"You're not following any tags. Smash that %customize% button!": "You're not following any tags. Smash that %customize% button!",
"customize": "customize"
"customize": "customize",
"An upgrade is available.": "An upgrade is available."
}

View file

@ -1,5 +1,4 @@
// @flow
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import React, { useEffect, useRef, useState } from 'react';
import classnames from 'classnames';
@ -14,8 +13,9 @@ import Yrbl from 'component/yrbl';
import FileViewer from 'component/fileViewer';
import { withRouter } from 'react-router';
import usePrevious from 'effects/use-previous';
import Button from 'component/button';
import Nag from 'component/common/nag';
// @if TARGET='web'
import OpenInAppLink from 'component/openInAppLink';
import YoutubeWelcome from 'component/youtubeWelcome';
// @endif
@ -199,20 +199,12 @@ function App(props: Props) {
{/* @if TARGET='web' */}
<YoutubeWelcome />
<OpenInAppLink uri={uri} />
{/* @endif */}
{/* @if TARGET='app' */}
{showUpgradeButton && (
<div className="snack-bar--upgrade">
{__('Upgrade is ready')}
<Button
className="snack-bar__action"
button="alt"
icon={ICONS.DOWNLOAD}
label={__('Install now')}
onClick={requestDownloadUpgrade}
/>
</div>
<Nag message={__('An upgrade is available.')} actionText={__('Install Now')} onClick={requestDownloadUpgrade} />
)}
{/* @endif */}
{isEnhancedLayout && <Yrbl className="yrbl--enhanced" />}

View file

@ -0,0 +1,28 @@
// @flow
import * as ICONS from 'constants/icons';
import React from 'react';
import Button from 'component/button';
type Props = {
message: string,
actionText: string,
href?: string,
onClick?: () => void,
onClose?: () => void,
};
export default function Nag(props: Props) {
const { message, actionText, href, onClick, onClose } = props;
const buttonProps = onClick ? { onClick } : { href };
return (
<div className="nag">
{message}
<Button className="nag__button" {...buttonProps}>
{actionText}
</Button>
{onClose && <Button className="nag__button nag__close" icon={ICONS.REMOVE} onClick={onClose} />}
</div>
);
}

View file

@ -0,0 +1,9 @@
import { connect } from 'react-redux';
import { selectUser } from 'lbryinc';
import OpenInAppLink from './view';
const select = state => ({
user: selectUser(state),
});
export default connect(select)(OpenInAppLink);

View file

@ -0,0 +1,66 @@
// @flow
import React from 'react';
import { withRouter } from 'react-router';
import userPersistedState from 'effects/use-persisted-state';
import { formatWebUrlIntoLbryUrl } from 'util/url';
import Nag from 'component/common/nag';
const userAgent = navigator.userAgent.toLowerCase();
const isAndroid = userAgent.includes('android');
const isDesktop = typeof window.orientation === 'undefined';
type Props = {
history: { replace: string => void, push: string => void },
location: { search: string, pathname: string },
uri: string,
user: ?User,
};
function OpenInAppLink(props: Props) {
const {
history: { replace },
location,
uri,
user,
} = props;
const { pathname, search } = location;
let params = new URLSearchParams(search);
const hasSrcParam = params.get('src');
const initialShouldShowNag = hasSrcParam && (isAndroid || isDesktop);
const isWebUserOnly =
user && !user.device_types.some(usedDevice => usedDevice === 'mobile' || usedDevice === 'desktop');
const [hideNagForGood, setHideNagForGood] = userPersistedState('open-in-app-nag', false);
const [showNag, setShowNag] = React.useState(initialShouldShowNag);
let appLink = uri;
if (!appLink) {
appLink = formatWebUrlIntoLbryUrl(pathname, search);
}
function handleClose() {
if (!isWebUserOnly) {
setHideNagForGood(true);
}
setShowNag(false);
}
React.useEffect(() => {
if (hasSrcParam) {
params.delete('src');
const newParams = params.toString();
const newUrl = `${pathname}?${newParams}`;
replace(newUrl);
}
}, [search, pathname, replace]);
if (!showNag || hideNagForGood) {
return null;
}
return (
<Nag message={__('Want even more freedom?')} actionText={__('Use the App')} href={appLink} onClose={handleClose} />
);
}
export default withRouter(OpenInAppLink);

View file

@ -29,7 +29,7 @@ const YoutubeWelcome = (props: Props) => {
</React.Fragment>
}
actions={
<React.Fragment>
<div className="card__actions">
<Button
button="primary"
label={__('Create an Account')}
@ -37,7 +37,7 @@ const YoutubeWelcome = (props: Props) => {
onClick={doHideModal}
/>
<Button button="link" label={__('Not Yet')} onClick={doHideModal} />
</React.Fragment>
</div>
}
/>
</Modal>

View file

@ -27,6 +27,7 @@
@import 'component/media';
@import 'component/menu-button';
@import 'component/modal';
@import 'component/nag';
@import 'component/navigation';
@import 'component/pagination';
@import 'component/placeholder';

View file

@ -160,10 +160,6 @@
padding-bottom: 0;
margin-bottom: var(--spacing-large);
border-top: 1px solid var(--color-border);
.button + .button {
margin-left: var(--spacing-medium);
}
}
.card__body--with-icon,

View file

@ -1,4 +1,5 @@
.splash {
-webkit-app-region: drag;
width: 100vw;
height: 100vh;

View file

@ -0,0 +1,36 @@
.nag {
position: fixed;
bottom: 0;
width: 100%;
padding: var(--spacing-small);
background-color: var(--color-nag);
color: var(--color-white);
font-weight: var(--font-weight-bold);
text-align: center;
}
.nag__button {
line-height: 1;
margin-left: var(--spacing-small);
border-radius: var(--border-radius);
border: 1px solid var(--color-white);
padding: var(--spacing-miniscule);
color: var(--color-white);
font-weight: var(--font-weight-bold);
&:hover {
background-color: var(--color-white);
color: var(--color-nag);
}
}
.nag__close {
margin-left: auto;
right: var(--spacing-medium);
position: absolute;
border: none;
svg {
stroke-width: 4px;
}
}

View file

@ -36,10 +36,6 @@
content: '';
}
&[data-selected] {
color: var(--color-link-active);
}
&:focus {
box-shadow: none;
}

View file

@ -9,6 +9,7 @@
--color-background--splash: #212529;
--color-border: #ededed;
--color-background-overlay: #21252980;
--color-nag: #f26522;
// Text
--color-text-selection-bg: var(--color-secondary-alt);

View file

@ -1,3 +1,6 @@
// Can't use aliases here because we're doing exports/require
const PAGES = require('../constants/pages');
exports.formatLbryUrlForWeb = uri => {
return uri.replace('lbry://', '/').replace(/#/g, ':');
};
@ -41,3 +44,17 @@ exports.formatInAppUrl = path => {
// Regular claim url
return path;
};
exports.formatWebUrlIntoLbryUrl = (pathname, search) => {
// If there is no uri, the user is on an internal page
// pathname will either be "/" or "/$/{page}"
const path = pathname.startsWith('/$/') ? pathname.slice(3) : pathname.slice(1);
let appLink = `lbry://?${path || PAGES.DISCOVER}`;
if (search) {
// We already have a leading "?" for the query param on internal pages
appLink += search.replace('?', '&');
}
return appLink;
};

View file

@ -7074,9 +7074,9 @@ lbry-redux@lbryio/lbry-redux#9b11cfed62af7f0f8eb6fa3c88a1f8d2cce46afc:
reselect "^3.0.0"
uuid "^3.3.2"
lbryinc@lbryio/lbryinc#2aedf5a188f028f61c45bc7ed0c747a2d4ae453a:
lbryinc@lbryio/lbryinc#1e897d2c9108848637e1915700d3ae8ce176f9f8:
version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/2aedf5a188f028f61c45bc7ed0c747a2d4ae453a"
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/1e897d2c9108848637e1915700d3ae8ce176f9f8"
dependencies:
reselect "^3.0.0"