mirror of
https://github.com/zhigang1992/connect.git
synced 2026-01-12 22:46:28 +08:00
resolve conflicts, update per review
This commit is contained in:
1
.prettierrc.js
Normal file
1
.prettierrc.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('@blockstack/prettier-config');
|
||||
35
package.json
35
package.json
@@ -18,8 +18,6 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"blockstack": "^19",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"styled-components": "^4.4"
|
||||
},
|
||||
"husky": {
|
||||
@@ -30,17 +28,23 @@
|
||||
"prettier": "@blockstack/prettier-config",
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.7.5",
|
||||
"@blockstack/prettier-config": "^0.0.3",
|
||||
"@types/jest": "^24.0.23",
|
||||
"@typescript-eslint/eslint-plugin": "^2.10.0",
|
||||
"@typescript-eslint/parser": "^2.10.0",
|
||||
"@blockstack/prettier-config": "^0.0.4",
|
||||
"@types/jest": "^24.0.25",
|
||||
"@typescript-eslint/eslint-plugin": "^2.15.0",
|
||||
"@typescript-eslint/parser": "^2.15.0",
|
||||
"blockstack": "^19.3.0",
|
||||
"eslint": "^6.7.2",
|
||||
"husky": "^3.1.0",
|
||||
"bundlesize": "^0.18.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.9.0",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"eslint-plugin-react": "^7.17.0",
|
||||
"husky": "^4.0.1",
|
||||
"prettier": "^1.19.1",
|
||||
"tsdx": "^0.11.0",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"tsdx": "^0.12.1",
|
||||
"tslib": "^1.10.0",
|
||||
"typescript": "^3.7.2"
|
||||
"typescript": "^3.7.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -48,9 +52,14 @@
|
||||
"dependencies": {
|
||||
"@blockstack/ui": "^1.0.0-alpha.22",
|
||||
"mdi-react": "^6.5.0",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"styled-components": "^4.4.1",
|
||||
"use-events": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"bundlesize": [
|
||||
{
|
||||
"path": "./dist/**/*.js",
|
||||
"maxSize": "9 kB"
|
||||
}
|
||||
],
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
34
src/auth.ts
34
src/auth.ts
@@ -1,7 +1,8 @@
|
||||
import { UserSession, AppConfig } from 'blockstack';
|
||||
import './types';
|
||||
import { popupCenter } from './popup';
|
||||
|
||||
const dataVaultHost = 'https://vault.hankstoever.com';
|
||||
const defaultVaultURL = 'https://vault.hankstoever.com';
|
||||
|
||||
interface FinishedData {
|
||||
authResponse: string;
|
||||
@@ -22,30 +23,15 @@ export interface AuthOptions {
|
||||
};
|
||||
}
|
||||
|
||||
// To allow the ability to on-the-fly pass any of these keys to update the state
|
||||
export interface OptionalAuthOptions {
|
||||
redirectTo?: string;
|
||||
manifestPath?: string;
|
||||
finished?: (data: FinishedData) => void;
|
||||
vaultUrl?: string;
|
||||
sendToSignIn?: boolean;
|
||||
userSession?: UserSession;
|
||||
appDetails?: {
|
||||
name?: string;
|
||||
icon?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const authenticate = ({
|
||||
export const authenticate = async ({
|
||||
redirectTo,
|
||||
manifestPath,
|
||||
finished,
|
||||
vaultUrl,
|
||||
sendToSignIn = false,
|
||||
userSession,
|
||||
appDetails
|
||||
appDetails,
|
||||
}: AuthOptions) => {
|
||||
const dataVaultURL = new URL(vaultUrl || dataVaultHost);
|
||||
if (!userSession) {
|
||||
const appConfig = new AppConfig(
|
||||
['store_write', 'publish_data'],
|
||||
@@ -67,12 +53,14 @@ export const authenticate = ({
|
||||
undefined,
|
||||
{
|
||||
sendToSignIn,
|
||||
appDetails
|
||||
appDetails,
|
||||
}
|
||||
);
|
||||
|
||||
const extensionURL = await window.BlockstackProvider?.getURL();
|
||||
const dataVaultURL = new URL(extensionURL || vaultUrl || defaultVaultURL);
|
||||
const popup = popupCenter({
|
||||
url: `${dataVaultURL.origin}/actions.html?authRequest=${authRequest}`
|
||||
url: `${dataVaultURL.origin}/actions.html?authRequest=${authRequest}`,
|
||||
});
|
||||
|
||||
setupListener({ popup, authRequest, finished, dataVaultURL, userSession });
|
||||
@@ -97,14 +85,14 @@ const setupListener = ({
|
||||
authRequest,
|
||||
finished,
|
||||
dataVaultURL,
|
||||
userSession
|
||||
userSession,
|
||||
}: ListenerParams) => {
|
||||
const interval = setInterval(() => {
|
||||
if (popup) {
|
||||
try {
|
||||
popup.postMessage(
|
||||
{
|
||||
authRequest
|
||||
authRequest,
|
||||
},
|
||||
dataVaultURL.origin
|
||||
);
|
||||
@@ -125,7 +113,7 @@ const setupListener = ({
|
||||
await userSession.handlePendingSignIn(authResponse);
|
||||
finished({
|
||||
authResponse,
|
||||
userSession
|
||||
userSession,
|
||||
});
|
||||
}
|
||||
window.removeEventListener('message', receiveMessageCallback);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './auth';
|
||||
export * from './react';
|
||||
export * from './popup';
|
||||
export * from './types';
|
||||
|
||||
@@ -13,7 +13,7 @@ export const popupCenter = ({
|
||||
url,
|
||||
title = defaultTitle,
|
||||
w = defaultWidth,
|
||||
h = defaultHeight
|
||||
h = defaultHeight,
|
||||
}: PopupOptions) => {
|
||||
const dualScreenLeft = window.screenLeft || window.screenX;
|
||||
const dualScreenTop = window.screenTop || window.screenY;
|
||||
@@ -32,10 +32,10 @@ export const popupCenter = ({
|
||||
const top = (height - h) / 2 / systemZoom + dualScreenTop;
|
||||
const options = {
|
||||
scrollbars: 'no',
|
||||
width: w / systemZoom,
|
||||
height: h / systemZoom,
|
||||
width: w,
|
||||
height: h,
|
||||
top: top,
|
||||
left: left
|
||||
left: left,
|
||||
};
|
||||
const optionsString = Object.keys(options).map(key => {
|
||||
return `${key}=${options[key as keyof typeof options]}`;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, { useReducer, createContext } from 'react';
|
||||
import { AuthOptions } from '../../../auth';
|
||||
|
||||
const MODAL_OPEN = 'modal/open';
|
||||
const MODAL_CLOSE = 'modal/close';
|
||||
const UPDATE_AUTH_OPTIONS = 'data/update-auth-options';
|
||||
const SCREENS_INTRO = 'screens/intro';
|
||||
const SCREENS_HOW_IT_WORKS = 'screens/how-it-works';
|
||||
const SCREENS_SIGN_IN = 'screens/sign-in';
|
||||
enum States {
|
||||
MODAL_OPEN = 'modal/open',
|
||||
MODAL_CLOSE = 'modal/close',
|
||||
UPDATE_AUTH_OPTIONS = 'data/update-auth-options',
|
||||
SCREENS_INTRO = 'screens/intro',
|
||||
SCREENS_HOW_IT_WORKS = 'screens/how-it-works',
|
||||
SCREENS_SIGN_IN = 'screens/sign-in',
|
||||
}
|
||||
|
||||
type Action = { type: string; payload?: any };
|
||||
|
||||
@@ -14,9 +16,9 @@ type Dispatch = (action: Action) => void;
|
||||
|
||||
type State = { isOpen: boolean; screen: string; authOptions: AuthOptions };
|
||||
|
||||
const initialState = {
|
||||
const initialState: State = {
|
||||
isOpen: false,
|
||||
screen: SCREENS_INTRO,
|
||||
screen: States.SCREENS_INTRO,
|
||||
authOptions: {
|
||||
redirectTo: '',
|
||||
manifestPath: '',
|
||||
@@ -25,9 +27,9 @@ const initialState = {
|
||||
sendToSignIn: false,
|
||||
appDetails: {
|
||||
name: '',
|
||||
icon: ''
|
||||
}
|
||||
}
|
||||
icon: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const connectReducer = (
|
||||
@@ -35,38 +37,38 @@ const connectReducer = (
|
||||
{ type, payload }: { type: string; payload?: any }
|
||||
) => {
|
||||
switch (type) {
|
||||
case MODAL_OPEN: {
|
||||
case States.MODAL_OPEN: {
|
||||
return { ...state, isOpen: true };
|
||||
}
|
||||
case MODAL_CLOSE: {
|
||||
case States.MODAL_CLOSE: {
|
||||
return { ...state, isOpen: false };
|
||||
}
|
||||
case SCREENS_INTRO: {
|
||||
case States.SCREENS_INTRO: {
|
||||
return {
|
||||
...state,
|
||||
screen: SCREENS_INTRO
|
||||
screen: States.SCREENS_INTRO,
|
||||
};
|
||||
}
|
||||
case SCREENS_HOW_IT_WORKS: {
|
||||
case States.SCREENS_HOW_IT_WORKS: {
|
||||
return {
|
||||
...state,
|
||||
screen: SCREENS_HOW_IT_WORKS
|
||||
screen: States.SCREENS_HOW_IT_WORKS,
|
||||
};
|
||||
}
|
||||
case SCREENS_SIGN_IN: {
|
||||
case States.SCREENS_SIGN_IN: {
|
||||
return {
|
||||
...state,
|
||||
screen: SCREENS_SIGN_IN
|
||||
screen: States.SCREENS_SIGN_IN,
|
||||
};
|
||||
}
|
||||
|
||||
case UPDATE_AUTH_OPTIONS: {
|
||||
case States.UPDATE_AUTH_OPTIONS: {
|
||||
return {
|
||||
...state,
|
||||
authOptions: {
|
||||
...state.authOptions,
|
||||
...payload
|
||||
}
|
||||
...payload,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,7 +84,7 @@ const ConnectDispatchContext = createContext<Dispatch | undefined>(undefined);
|
||||
|
||||
const ConnectProvider = ({
|
||||
authOptions,
|
||||
children
|
||||
children,
|
||||
}: {
|
||||
authOptions: AuthOptions;
|
||||
children: any;
|
||||
@@ -103,10 +105,5 @@ export {
|
||||
ConnectContext,
|
||||
ConnectDispatchContext,
|
||||
ConnectProvider,
|
||||
MODAL_OPEN,
|
||||
MODAL_CLOSE,
|
||||
SCREENS_INTRO,
|
||||
SCREENS_HOW_IT_WORKS,
|
||||
SCREENS_SIGN_IN,
|
||||
UPDATE_AUTH_OPTIONS
|
||||
States,
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AuthOptions } from '../../../auth';
|
||||
* const auth = {
|
||||
manifestPath: '/static/manifest.json',
|
||||
redirectTo: '/',
|
||||
finished: () => {
|
||||
finished: ({userSession}) => {
|
||||
doFinishSignIn();
|
||||
},
|
||||
vaultUrl,
|
||||
@@ -22,7 +22,6 @@ import { AuthOptions } from '../../../auth';
|
||||
*
|
||||
* <Connect authOptions={authOptions} />
|
||||
*/
|
||||
|
||||
const Connect = ({
|
||||
authOptions,
|
||||
children
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Text, Box } from '@blockstack/ui';
|
||||
import { BoxProps } from '@blockstack/ui/dist/box/types';
|
||||
import { Text, Box, BoxProps } from '@blockstack/ui';
|
||||
|
||||
interface LinkProps extends BoxProps {
|
||||
_hover?: BoxProps;
|
||||
|
||||
@@ -6,19 +6,16 @@ import {
|
||||
CSSReset,
|
||||
Flex,
|
||||
Box,
|
||||
Text
|
||||
Text,
|
||||
} from '@blockstack/ui';
|
||||
// import ChevronRightIcon from 'mdi-react/ChevronRightIcon';
|
||||
import CloseIcon from 'mdi-react/CloseIcon';
|
||||
import { useHover } from 'use-events';
|
||||
import { Logo } from '../logo';
|
||||
import { Intro } from '../screens/intro';
|
||||
import { HowItWorks } from '../screen/how-it-works';
|
||||
import { ContinueWithDataVault } from '../screen/sign-in';
|
||||
// import { AppIcon } from '../app-icon';
|
||||
import { useConnect } from '../../hooks/useConnect';
|
||||
import { SCREENS_HOW_IT_WORKS, SCREENS_SIGN_IN } from '../connect/context';
|
||||
// import { useAppDetails } from '../../hooks/useAppDetails';x
|
||||
import { States } from '../connect/context';
|
||||
|
||||
interface HeaderTitleProps {
|
||||
title: string;
|
||||
@@ -27,7 +24,7 @@ interface HeaderTitleProps {
|
||||
|
||||
const HeaderTitle: React.FC<HeaderTitleProps> = ({
|
||||
hideIcon = false,
|
||||
title
|
||||
title,
|
||||
}) => (
|
||||
<Flex align="center">
|
||||
{hideIcon ? null : <Logo mr={2} />}
|
||||
@@ -90,10 +87,10 @@ const ModalHeader = ({ title, hideIcon, close, ...rest }: IModalHeader) => {
|
||||
const RenderScreen: React.FC = () => {
|
||||
const { screen } = useConnect();
|
||||
switch (screen) {
|
||||
case SCREENS_HOW_IT_WORKS: {
|
||||
case States.SCREENS_HOW_IT_WORKS: {
|
||||
return <HowItWorks />;
|
||||
}
|
||||
case SCREENS_SIGN_IN: {
|
||||
case States.SCREENS_SIGN_IN: {
|
||||
return (
|
||||
<Box width="100%">
|
||||
<ContinueWithDataVault />
|
||||
@@ -115,7 +112,7 @@ const Modal = () => {
|
||||
headerComponent={
|
||||
<ModalHeader
|
||||
close
|
||||
title={screen === SCREENS_SIGN_IN ? 'Sign In' : 'Data Vault'}
|
||||
title={screen === States.SCREENS_SIGN_IN ? 'Sign In' : 'Data Vault'}
|
||||
/>
|
||||
}
|
||||
isOpen={isOpen}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Button, Flex, Box, Spinner, Stack } from '@blockstack/ui';
|
||||
import { Button, Flex, Box, Spinner, Stack, BoxProps } from '@blockstack/ui';
|
||||
import { Title, Pretitle, Body, BackLink } from '../typography';
|
||||
import { BoxProps } from '@blockstack/ui/dist/box';
|
||||
import { Link } from '../link';
|
||||
|
||||
const Footer = ({ content }: { content: any }) =>
|
||||
|
||||
@@ -24,7 +24,7 @@ const ContinueWithDataVault: React.FC = props => {
|
||||
bg={hovered ? 'rgba(0,0,0,0.02)' : 'white'}
|
||||
transform={hovered ? 'translateY(-2px)' : 'none'}
|
||||
onClick={() => {
|
||||
authenticate(authOptions);
|
||||
authenticate({ ...authOptions, sendToSignIn: true });
|
||||
}}
|
||||
{...bind}
|
||||
{...props}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Text, Box } from '@blockstack/ui';
|
||||
import { Text, Box, BoxProps } from '@blockstack/ui';
|
||||
import ChevronLeftIcon from 'mdi-react/ChevronLeftIcon';
|
||||
import { BoxProps } from '@blockstack/ui/dist/box';
|
||||
|
||||
const Title: React.FC = props => (
|
||||
<Text
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import { useContext } from 'react';
|
||||
import { authenticate, OptionalAuthOptions } from '../../auth';
|
||||
import { authenticate, AuthOptions } from '../../auth';
|
||||
import {
|
||||
ConnectContext,
|
||||
ConnectDispatchContext,
|
||||
MODAL_CLOSE,
|
||||
MODAL_OPEN,
|
||||
SCREENS_SIGN_IN,
|
||||
SCREENS_HOW_IT_WORKS,
|
||||
SCREENS_INTRO,
|
||||
UPDATE_AUTH_OPTIONS
|
||||
States,
|
||||
} from '../components/connect/context';
|
||||
|
||||
const useConnectDispatch = () => {
|
||||
@@ -23,24 +18,25 @@ const useConnect = () => {
|
||||
const { isOpen, screen, authOptions } = useContext(ConnectContext);
|
||||
const dispatch = useConnectDispatch();
|
||||
|
||||
const doUpdateAuthOptions = (payload: OptionalAuthOptions) =>
|
||||
dispatch({ type: UPDATE_AUTH_OPTIONS, payload });
|
||||
const doUpdateAuthOptions = (payload: Partial<AuthOptions>) =>
|
||||
dispatch({ type: States.UPDATE_AUTH_OPTIONS, payload });
|
||||
|
||||
const doChangeScreen = (newScreen: string) => dispatch({ type: newScreen });
|
||||
const doGoToIntroScreen = () => doChangeScreen(SCREENS_INTRO);
|
||||
const doGoToHowItWorksScreen = () => doChangeScreen(SCREENS_HOW_IT_WORKS);
|
||||
const doGoToSignInScreen = () => doChangeScreen(SCREENS_SIGN_IN);
|
||||
const doGoToIntroScreen = () => doChangeScreen(States.SCREENS_INTRO);
|
||||
const doGoToHowItWorksScreen = () =>
|
||||
doChangeScreen(States.SCREENS_HOW_IT_WORKS);
|
||||
const doGoToSignInScreen = () => doChangeScreen(States.SCREENS_SIGN_IN);
|
||||
|
||||
const doOpenDataVault = (
|
||||
signIn?: boolean,
|
||||
authOptions?: OptionalAuthOptions
|
||||
authOptions?: Partial<AuthOptions>
|
||||
) => {
|
||||
signIn && doGoToSignInScreen();
|
||||
authOptions && doUpdateAuthOptions(authOptions);
|
||||
dispatch({ type: MODAL_OPEN });
|
||||
dispatch({ type: States.MODAL_OPEN });
|
||||
};
|
||||
const doCloseDataVault = () => {
|
||||
dispatch({ type: MODAL_CLOSE });
|
||||
dispatch({ type: States.MODAL_CLOSE });
|
||||
setTimeout(doGoToIntroScreen, 250);
|
||||
};
|
||||
|
||||
@@ -54,7 +50,7 @@ const useConnect = () => {
|
||||
doGoToIntroScreen,
|
||||
doGoToHowItWorksScreen,
|
||||
doGoToSignInScreen,
|
||||
authenticate
|
||||
authenticate,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
9
src/types.ts
Normal file
9
src/types.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface BlockstackProvider {
|
||||
getURL: () => Promise<string>;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
BlockstackProvider?: BlockstackProvider;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user