Cleanup network provider (#3)

This commit is contained in:
Justin Starry
2020-03-16 15:17:51 +08:00
committed by Michael Vines
parent d7b2612915
commit de1df895a0
3 changed files with 37 additions and 48 deletions

View File

@ -6,15 +6,11 @@ function NetworkStatusButton() {
switch (status) { switch (status) {
case NetworkStatus.Connected: case NetworkStatus.Connected:
return ( return <a className="btn btn-primary lift">{url}</a>;
<a href="#networkModal" className="btn btn-primary lift">
{url}
</a>
);
case NetworkStatus.Connecting: case NetworkStatus.Connecting:
return ( return (
<a href="#networkModal" className="btn btn-warning lift"> <a className="btn btn-warning lift">
{"Connecting "} {"Connecting "}
<span <span
className="spinner-grow spinner-grow-sm text-dark" className="spinner-grow spinner-grow-sm text-dark"
@ -25,11 +21,7 @@ function NetworkStatusButton() {
); );
case NetworkStatus.Failure: case NetworkStatus.Failure:
return ( return <a className="btn btn-danger lift">Disconnected</a>;
<a href="#networkModal" className="btn btn-danger lift">
Disconnected
</a>
);
} }
} }

View File

@ -1,12 +1,20 @@
import React from "react"; import React from "react";
import { testnetChannelEndpoint, Connection } from "@solana/web3.js"; import { testnetChannelEndpoint, Connection } from "@solana/web3.js";
import { findGetParameter } from "../utils";
enum NetworkStatus { export const DEFAULT_URL = testnetChannelEndpoint("stable");
export enum NetworkStatus {
Connected, Connected,
Connecting, Connecting,
Failure Failure
} }
interface State {
url: string;
status: NetworkStatus;
}
interface Connecting { interface Connecting {
status: NetworkStatus.Connecting; status: NetworkStatus.Connecting;
url: string; url: string;
@ -23,14 +31,6 @@ interface Failure {
type Action = Connected | Connecting | Failure; type Action = Connected | Connecting | Failure;
type Dispatch = (action: Action) => void; type Dispatch = (action: Action) => void;
interface State {
url: string;
status: NetworkStatus;
}
const StateContext = React.createContext<State | undefined>(undefined);
const DispatchContext = React.createContext<Dispatch | undefined>(undefined);
function networkReducer(state: State, action: Action): State { function networkReducer(state: State, action: Action): State {
switch (action.status) { switch (action.status) {
case NetworkStatus.Connected: case NetworkStatus.Connected:
@ -43,20 +43,7 @@ function networkReducer(state: State, action: Action): State {
} }
} }
function findGetParameter(parameterName: string): string | null { function initState(url: string): State {
let result = null,
tmp = [];
window.location.search
.substr(1)
.split("&")
.forEach(function(item) {
tmp = item.split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
});
return result;
}
function init(url: string): State {
const networkUrlParam = findGetParameter("networkUrl"); const networkUrlParam = findGetParameter("networkUrl");
return { return {
url: networkUrlParam || url, url: networkUrlParam || url,
@ -64,10 +51,16 @@ function init(url: string): State {
}; };
} }
const DEFAULT_URL = testnetChannelEndpoint("stable"); const StateContext = React.createContext<State | undefined>(undefined);
const DispatchContext = React.createContext<Dispatch | undefined>(undefined);
type NetworkProviderProps = { children: React.ReactNode }; type NetworkProviderProps = { children: React.ReactNode };
function NetworkProvider({ children }: NetworkProviderProps) { export function NetworkProvider({ children }: NetworkProviderProps) {
const [state, dispatch] = React.useReducer(networkReducer, DEFAULT_URL, init); const [state, dispatch] = React.useReducer(
networkReducer,
DEFAULT_URL,
initState
);
React.useEffect(() => { React.useEffect(() => {
// Connect to network immediately // Connect to network immediately
@ -83,7 +76,7 @@ function NetworkProvider({ children }: NetworkProviderProps) {
); );
} }
async function updateNetwork(dispatch: Dispatch, newUrl: string) { export async function updateNetwork(dispatch: Dispatch, newUrl: string) {
dispatch({ dispatch({
status: NetworkStatus.Connecting, status: NetworkStatus.Connecting,
url: newUrl url: newUrl
@ -99,7 +92,7 @@ async function updateNetwork(dispatch: Dispatch, newUrl: string) {
} }
} }
function useNetwork() { export function useNetwork() {
const context = React.useContext(StateContext); const context = React.useContext(StateContext);
if (!context) { if (!context) {
throw new Error(`useNetwork must be used within a NetworkProvider`); throw new Error(`useNetwork must be used within a NetworkProvider`);
@ -107,18 +100,10 @@ function useNetwork() {
return context; return context;
} }
function useNetworkDispatch() { export function useNetworkDispatch() {
const context = React.useContext(DispatchContext); const context = React.useContext(DispatchContext);
if (!context) { if (!context) {
throw new Error(`useNetworkDispatch must be used within a NetworkProvider`); throw new Error(`useNetworkDispatch must be used within a NetworkProvider`);
} }
return context; return context;
} }
export {
NetworkProvider,
useNetwork,
useNetworkDispatch,
updateNetwork,
NetworkStatus
};

12
explorer/src/utils.ts Normal file
View File

@ -0,0 +1,12 @@
export function findGetParameter(parameterName: string): string | null {
let result = null,
tmp = [];
window.location.search
.substr(1)
.split("&")
.forEach(function(item) {
tmp = item.split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
});
return result;
}