diff --git a/src/App.tsx b/src/App.tsx index e1b0198b..db7d147d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; // import { Helmet } from 'react-helmet'; import { Global } from '@emotion/core'; import { ThemeProvider, Text } from 'theme-ui'; -import { Router, Redirect, globalHistory } from '@reach/router'; +import { Router, globalHistory } from '@reach/router'; import { ApolloProvider } from '@apollo/react-hooks'; import AppMobileWrapper from 'containers/AppMobileWrapper'; import BrowserDetector from 'components/BrowserDetector'; @@ -54,11 +54,11 @@ const App: React.FC = () => { - - - - - + + + + + {version} diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx index 6afd6dd8..31c79e7b 100644 --- a/src/components/AccountList.tsx +++ b/src/components/AccountList.tsx @@ -11,8 +11,8 @@ import {useProject} from "providers/Project/projectHooks"; import Avatar from "components/Avatar"; import styled from "@emotion/styled"; import {ExportButton} from "components/ExportButton"; +import {getParams, isUUUID, LOCAL_PROJECT_ID} from "../util/url"; import {ResourcesExplorerButton} from "components/ResourcesExplorerButton"; -import {getParams, isUUUID} from "util/url"; function getDeployedContracts(account: Account): string { const contracts = account.deployedContracts.map( @@ -38,8 +38,8 @@ const AccountList: React.FC = () => { const accountSelected = active.type === EntityType.Account const location = useLocation(); - const params = getParams(location.search); - const projectPath = isUUUID(project.id) ? project.id : "local" + const params = getParams(location.search) + const projectPath = isUUUID(project.id) ? project.id : LOCAL_PROJECT_ID return ( diff --git a/src/components/Arguments/components.tsx b/src/components/Arguments/components.tsx index 84ee3c92..06909bb7 100644 --- a/src/components/Arguments/components.tsx +++ b/src/components/Arguments/components.tsx @@ -229,7 +229,7 @@ export const Hints: React.FC = (props: HintsProps) => { const getLabel = (type: EntityType) => { const { project, active } = useProject(); const { accounts } = project; - + switch (true) { case type === EntityType.Account: return accounts[active.index].deployedCode ? 'Redeploy' : 'Deploy'; diff --git a/src/components/ExportButton.tsx b/src/components/ExportButton.tsx index 5fe60e3a..f88b5fa8 100644 --- a/src/components/ExportButton.tsx +++ b/src/components/ExportButton.tsx @@ -3,7 +3,8 @@ import useClipboard from 'react-use-clipboard'; import { FaClipboard, FaClipboardCheck } from 'react-icons/fa'; import { SidebarItemExport } from 'layout/SidebarItemExport'; import { useProject } from 'providers/Project/projectHooks'; -import { generateCode } from 'util/generate-code'; +import { generateCode } from '../util/generate-code'; +import { LOCAL_PROJECT_ID } from '../util/url' type ExportButtonProps = { id: string; @@ -18,7 +19,7 @@ export const ExportButton = (props: ExportButtonProps) => { successDuration: 1000, }); - return project.id === 'LOCAL-project' ? null : ( + return project.id === LOCAL_PROJECT_ID ? null : ( { const { @@ -23,7 +23,7 @@ const Sidebar: React.FC = () => { if (isLoading) return

Loading...

; - const projectPath = isUUUID(project.id) ? project.id : "local" + const projectPath = isUUUID(project.id) ? project.id : LOCAL_PROJECT_ID const storageAcct = selectedResourceAccount || 'none' diff --git a/src/containers/Editor/index.tsx b/src/containers/Editor/index.tsx index af82aa5c..b13bfd8f 100644 --- a/src/containers/Editor/index.tsx +++ b/src/containers/Editor/index.tsx @@ -1,39 +1,144 @@ -import React from "react"; -import { Redirect } from "@reach/router"; -import { ProjectProvider } from "providers/Project"; -import { Base } from "layout/Base" - -import EditorLayout from "./layout"; -import { isUUUID, getParams, scriptTypes } from "util/url"; - -const Playground: any = (props: any) => { - const params = getParams(props.location.search) - const { projectId } = props; - - const isLocalProject = projectId === "local"; - const correctUUID = isUUUID(projectId); - - const wrongProjectUUID = !correctUUID && !isLocalProject - const correctProject = !isLocalProject && correctUUID; - - const correctScriptType = scriptTypes.includes(params.type) - - if (wrongProjectUUID){ - return - } - - if (correctProject && !correctScriptType){ - const to = `/${projectId}?type=account&id=0` - return - } - - return ( - - - - - - ); -}; - -export default Playground; +import React, { useEffect, useState } from "react"; +import { useApolloClient } from '@apollo/react-hooks'; +import { ProjectProvider } from "providers/Project"; +import { Base } from "layout/Base" +import { useGetActiveProjectQuery } from "api/apollo/generated/graphql"; +import useGetProject from '../../providers/Project/projectHooks'; +import { EntityType } from "providers/Project"; + +import EditorLayout from "./layout"; +import { isUUUID, getParams, scriptTypes, LOCAL_PROJECT_ID } from "../../util/url"; +import { navigate } from "@reach/router"; + +const Playground: any = (props: any) => { + + const { projectId } = props; + + const params = getParams(props.location.search); + const { type, id } = params; + + const isLocalProject = projectId === LOCAL_PROJECT_ID; + const correctUUID = isUUUID(projectId); + + const { data } = useGetActiveProjectQuery(); + const isActiveProject = data.activeProject; + + const client = useApolloClient(); + const resolvedProjectId = correctUUID ? projectId : null + + const { + project + } = useGetProject(client, resolvedProjectId, isActiveProject); + + const [active, setActive] = useState<{ type: EntityType; index: number }>({ + type: EntityType.Account, + index: 0, + }); + + useEffect(() => { + if (project) { + + let activeType; + if (type == '' || type === undefined || !scriptTypes.includes(type)) { + activeType = 'account'; + } else { + activeType = type; + }; + + if (id == '' || id === undefined) { + switch (activeType) { + case 'tx': + setActive({ + type: EntityType.TransactionTemplate, + index: 0, + }); + break; + case 'script': + setActive({ + type: EntityType.ScriptTemplate, + index: 0, + }); + break; + case 'account': + default: + setActive({ + type: EntityType.Account, + index: 0, + }); + break; + } + } else { + let foundIndex; + switch (activeType) { + case 'tx': + foundIndex = project.transactionTemplates.findIndex( + (template: { id: string; }) => template.id === id, + ); + if (foundIndex > 0) { + setActive({ + type: EntityType.TransactionTemplate, + index: foundIndex, + }); + } else { + setActive({ + type: EntityType.TransactionTemplate, + index: 0, + }); + navigate(`/${projectId}?type=tx&id=${project.transactionTemplates[0].id}`) + } + break; + case 'script': + foundIndex = project.scriptTemplates.findIndex( + (template: { id: string; }) => template.id === id, + ); + if (foundIndex > 0) { + setActive({ + type: EntityType.ScriptTemplate, + index: foundIndex, + }); + } else { + setActive({ + type: EntityType.ScriptTemplate, + index: 0, + }); + navigate(`/${projectId}?type=script&id=${project.scriptTemplates[0].id}`) + } + break; + case 'account': + default: + foundIndex = project.accounts.findIndex( + (template: { id: string; }) => template.id === id, + ); + if (foundIndex > 0) { + setActive({ + type: EntityType.Account, + index: foundIndex, + }); + + } else { + setActive({ + type: EntityType.Account, + index: 0, + }); + navigate(`/${projectId}?type=account&id=${project.accounts[0].id}`) + } + break; + } + } + } + },[project, type, id]) + + return ( + + + + + + ); +}; + +export default Playground; diff --git a/src/providers/Project/index.tsx b/src/providers/Project/index.tsx index b9a875ad..dcca8e29 100644 --- a/src/providers/Project/index.tsx +++ b/src/providers/Project/index.tsx @@ -1,6 +1,6 @@ import React, { createContext, useState } from 'react'; import { useApolloClient, useQuery } from '@apollo/react-hooks'; -import { navigate, Redirect, useLocation } from '@reach/router'; +import { navigate } from '@reach/router'; import ProjectMutator from './projectMutator'; import useGetProject from './projectHooks'; @@ -67,11 +67,15 @@ export const ProjectContext: React.Context = createContext( interface ProjectProviderProps { children: any; urlProjectId: string | null; + active: any; + setActive: any; } export const ProjectProvider: React.FC = ({ children, urlProjectId, + active, + setActive }) => { const client = useApolloClient(); @@ -97,7 +101,6 @@ export const ProjectProvider: React.FC = ({ navigate('/404'); } - const [initialLoad, setInitialLoad] = useState(true); const [transactionAccounts, setTransactionAccounts] = useState([0]); const [isSavingCode, setIsSaving] = useState(false); const [lastSigners, setLastSigners] = useState(null); @@ -108,7 +111,6 @@ export const ProjectProvider: React.FC = ({ }); const [selectedResourceAccount, setSelectedResourceAccount] = useState< string | null>(null) - const projectID = project ? project.id : null; const mutator = new ProjectMutator(client, projectID, isLocal); @@ -280,6 +282,7 @@ export const ProjectProvider: React.FC = ({ }; const getActiveEditor = (): ActiveEditor => { + switch (active.type) { case EntityType.Account: return { @@ -309,7 +312,7 @@ export const ProjectProvider: React.FC = ({ const location = useLocation(); if (isLoading) return null; if (!isLoading && !project) { - navigate('/404'); + navigate('/'); return null; } diff --git a/src/providers/Project/projectDefault.ts b/src/providers/Project/projectDefault.ts index 924691e6..7dc1f864 100644 --- a/src/providers/Project/projectDefault.ts +++ b/src/providers/Project/projectDefault.ts @@ -4,7 +4,8 @@ import { TransactionTemplate, ScriptTemplate } from "api/apollo/generated/graphql"; -import { strToSeed, uuid } from "util/rng"; +import { strToSeed, uuid } from "../../util/rng"; +import { LOCAL_PROJECT_ID } from "../../util/url"; const DEFAULT_ACCOUNT_1 = `// HelloWorld.cdc // @@ -159,7 +160,7 @@ export function createLocalProject( const accountEntities: Account[] = accounts.map((script, i) => { return { __typename: "Account", - id: `LOCAL-account-${i}`, + id: `local-account-${i}`, address: `000000000000000000000000000000000000000${i + 1}`, title: "", draftCode: script, @@ -174,7 +175,7 @@ export function createLocalProject( const { title, code } = script return { __typename: "TransactionTemplate", - id: `LOCAL-tx-temp-${i}`, + id: `local-tx-temp-${i}`, title: title || `Transaction ${i + 1}`, script: code, index: i, @@ -187,7 +188,7 @@ export function createLocalProject( const { title, code } = script return { __typename: "ScriptTemplate", - id: `LOCAL-script-temp-${i}`, + id: `local-script-temp-${i}`, title: title || `Script ${i + 1}`, script: code, index: i, @@ -197,7 +198,7 @@ export function createLocalProject( return { __typename: "Project", - id: "LOCAL-project", + id: LOCAL_PROJECT_ID, publicId: "", persist: false, mutable: false, diff --git a/src/providers/Project/projectMutator.ts b/src/providers/Project/projectMutator.ts index 8b2faff8..d165fd9e 100644 --- a/src/providers/Project/projectMutator.ts +++ b/src/providers/Project/projectMutator.ts @@ -100,14 +100,14 @@ export default class ProjectMutator { projectId: this.projectId, }, }); - + if (isFork) { Mixpanel.track('Project forked', { projectId: this.projectId }); } else { Mixpanel.track('Project saved', { projectId: this.projectId }); } - - navigate(`/${this.projectId}`, { replace: true }); + + navigate(`/${this.projectId}`, { replace: true}); } async updateAccountDraftCode(account: Account, code: string) { diff --git a/src/util/url.ts b/src/util/url.ts index 5edb7a12..feb102ee 100644 --- a/src/util/url.ts +++ b/src/util/url.ts @@ -12,3 +12,5 @@ export const getParams = (url: string): any => { } export const scriptTypes = ["account", "tx", "script"] + +export const LOCAL_PROJECT_ID = "local-project"