Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Center (read-only) #625

Merged
merged 62 commits into from
Apr 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
1a0746f
ZoomableCards: first version
bpierre Feb 20, 2019
e0b8778
ESLint fixes
bpierre Feb 20, 2019
64a5c73
Merge branch 'master' into app-center
bpierre Feb 23, 2019
09e4491
Prevent unnecessary renders of MenuPanel
bpierre Feb 25, 2019
6339dd6
Prevent unnecessary renders of SignerPanel
bpierre Feb 25, 2019
1280e61
Add known apps
bpierre Feb 25, 2019
b6ccfd6
Add “Label” as a text style component
bpierre Feb 26, 2019
639476f
Start using a constant for grid units
bpierre Feb 26, 2019
73dd19c
ZoomableCards: tweaks and performance optimizations
bpierre Feb 26, 2019
d838766
App store main interface
bpierre Feb 26, 2019
070e994
AppContent: breakpoints without the menu width
bpierre Feb 26, 2019
ea818d9
Add missing info block below app versions
bpierre Feb 26, 2019
501665e
ESLint fixes
bpierre Feb 26, 2019
99e0da8
Fix small viewports layout
bpierre Feb 27, 2019
928aa3e
Known apps: add source URL
bpierre Feb 27, 2019
f682c05
Upgrade panel
bpierre Feb 27, 2019
6a6982b
ESLint fixes
bpierre Feb 27, 2019
5f0f48f
Merge branch 'master' into app-center
bpierre Feb 28, 2019
8370f06
Merge master into app-center
bpierre Feb 28, 2019
efdcc15
Merge master (Swipe Menu Panel)
bpierre Mar 1, 2019
9aab685
Prop types: add AppCenterAppType
bpierre Mar 4, 2019
d93b9ff
Add apps-utils
bpierre Mar 4, 2019
24997a5
ZoomCard: fix the cards width
bpierre Mar 4, 2019
885f5df
Apps params: move from ?params= to ?p=
bpierre Mar 4, 2019
a7efdee
Use real app data
bpierre Mar 4, 2019
3a572b4
ESLint fix
bpierre Mar 5, 2019
66d253f
Merge master
bpierre Mar 5, 2019
184736b
Apps => App Center
bpierre Mar 5, 2019
d13a4a3
Fix App Center title
bpierre Mar 5, 2019
a968f82
Merge branch 'master' into app-center
bpierre Mar 20, 2019
9903e08
Spacing
bpierre Mar 20, 2019
3e0127d
Fix ESLint
bpierre Mar 20, 2019
d35b3dc
Merge branch 'master' into app-center
sohkai Apr 9, 2019
b5296a3
fix: propagate dao name rather than full locator
sohkai Apr 9, 2019
3046119
fix: propagating params is now done with rather than
sohkai Apr 9, 2019
0608191
fix: remove unused blank component
sohkai Apr 9, 2019
96cb694
fix: remove unused icons
sohkai Apr 10, 2019
db8c94e
fix: cosmetic code improvements to remove unused bits do some clean up
sohkai Apr 10, 2019
7d55fec
fix: add RenderFnType proptype for optional render functions
sohkai Apr 10, 2019
15ffa22
fix: avoid proptypes warnings
sohkai Apr 10, 2019
8bd7100
fix: import lerp rather than redefine it
sohkai Apr 10, 2019
b61d437
UpgradeAppPanel: update text
sohkai Apr 10, 2019
bdd3a3d
Merge branch 'master' into app-center
sohkai Apr 10, 2019
84d82ae
fix: remove transaction notification hooks
sohkai Apr 10, 2019
f993d14
fix: proptypes warnings for SignerPanel
sohkai Apr 10, 2019
fcc9f1f
feat: use local identity badge in app center
sohkai Apr 10, 2019
0c1e9b3
ActionPathsContent: use getAppPath() + coding style
bpierre Apr 14, 2019
dd5c35b
Always define cardRect in the state
bpierre Apr 14, 2019
2dc4f40
Syntax
bpierre Apr 14, 2019
06b1dd6
TABS => SCREENS
bpierre Apr 14, 2019
2648b8e
Update Discover App
bpierre Apr 14, 2019
ac5e14a
Screenshots: remove the open / close state
bpierre Apr 14, 2019
9fa6c4e
Discover Apps: missing icons
bpierre Apr 14, 2019
82fd33e
AppsGrid: pass cards as children instead of a render function
bpierre Apr 14, 2019
4c659b7
Comment + style
bpierre Apr 14, 2019
021a1e4
ESLint fixes
bpierre Apr 14, 2019
2c84c1a
Discover Apps: sort by readiness, update some details, and add pando
sohkai Apr 14, 2019
e8cd486
feat: restart app worker when upgraded (#688)
sohkai Apr 14, 2019
e7a8ba6
fix: update for @aragon/wrapper api cleanup (#690)
sohkai Apr 14, 2019
954b448
App Center: connect to installed repos (#694)
sohkai Apr 14, 2019
8e252e1
chore: upgrade @aragon/wrapper
sohkai Apr 14, 2019
104cff4
UpgradeAppPanel: disable for now
sohkai Apr 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"dependencies": {
"@aragon/templates-tokens": "^1.1.1",
"@aragon/ui": "^0.33.0",
"@aragon/wrapper": "^4.0.0",
"@aragon/wrapper": "^5.0.0-beta.1",
"@babel/polyfill": "^7.0.0",
"bn.js": "4.11.6",
"date-fns": "2.0.0-alpha.22",
Expand Down
62 changes: 46 additions & 16 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,23 @@ import {
DAO_CREATION_STATUS_ERROR,
} from './symbols'

const INITIAL_DAO_STATE = {
apps: [],
appIdentifiers: {},
appsStatus: APPS_STATUS_LOADING,
daoAddress: { address: '', domain: '' },
permissions: {},
permissionsLoading: true,
repos: [],
}

class App extends React.Component {
state = {
...INITIAL_DAO_STATE,
account: '',
apps: [],
appsStatus: APPS_STATUS_LOADING,
balance: getUnknownBalance(),
buildData: null, // data returned by aragon.js when a DAO is created
connected: false,
daoAddress: { address: '', domain: '' },
// daoCreationStatus is one of:
// - DAO_CREATION_STATUS_NONE
// - DAO_CREATION_STATUS_SUCCESS
Expand All @@ -45,8 +53,6 @@ class App extends React.Component {
fatalError: null,
identityIntent: null,
locator: {},
permissions: {},
permissionsLoading: true,
prevLocator: null,
selectorNetworks: [
['main', 'Ethereum Mainnet', 'https://mainnet.aragon.org/'],
Expand Down Expand Up @@ -193,19 +199,20 @@ class App extends React.Component {

updateDao(dao = null) {
// Cancel the subscriptions / unload the wrapper
if (dao === null && this.state.wrapper) {
if (this.state.wrapper) {
this.state.wrapper.cancel()
this.setState({ wrapper: null })
return
}

// Reset the DAO state
this.setState({
appsStatus: APPS_STATUS_LOADING,
apps: [],
daoAddress: { address: '', domain: '' },
...INITIAL_DAO_STATE,
})

if (dao === null) {
return
}

log('Init DAO', dao)
initWrapper(dao, contractAddresses.ensRegistry, {
provider: web3Providers.default,
Expand Down Expand Up @@ -239,6 +246,14 @@ class App extends React.Component {
onForwarders: forwarders => {
log('forwarders', forwarders)
},
onAppIdentifiers: appIdentifiers => {
log('app identifiers', appIdentifiers)
this.setState({ appIdentifiers })
},
onInstalledRepos: repos => {
log('installed repos', repos)
this.setState({ repos })
},
onTransaction: transactionBag => {
log('transaction bag', transactionBag)
this.setState({ transactionBag })
Expand Down Expand Up @@ -325,6 +340,7 @@ class App extends React.Component {
const {
account,
apps,
appIdentifiers,
appsStatus,
balance,
connected,
Expand All @@ -335,6 +351,7 @@ class App extends React.Component {
locator,
permissions,
permissionsLoading,
repos,
selectorNetworks,
showDeprecatedBanner,
transactionBag,
Expand All @@ -345,18 +362,30 @@ class App extends React.Component {
} = this.state

const { mode, dao } = locator
if (!mode) return null
const { address: intentAddress = null, label: intentLabel = '' } =
identityIntent || {}

if (!mode) {
return null
}
if (mode === 'invalid') {
throw new Error(
`URL contained invalid organization name or address (${dao}).\nPlease modify it to be a valid ENS name or address.`
)
}

if (fatalError !== null) {
throw fatalError
}
const { address: intentAddress = null, label: intentLabel = '' } =
identityIntent || {}

const appsWithIdentifiers = apps.map(app => {
const identifier = appIdentifiers[app.proxyAddress]
return identifier
? {
identifier,
...app,
}
: app
})

return (
<IdentityProvider onResolve={this.handleIdentityResolve}>
Expand All @@ -374,12 +403,12 @@ class App extends React.Component {
<FavoriteDaosProvider>
<PermissionsProvider
wrapper={wrapper}
apps={apps}
apps={appsWithIdentifiers}
permissions={permissions}
>
<Wrapper
account={account}
apps={apps}
apps={appsWithIdentifiers}
appsStatus={appsStatus}
banner={
showDeprecatedBanner && <DeprecatedBanner dao={dao} />
Expand All @@ -393,6 +422,7 @@ class App extends React.Component {
onRequestAppsReload={this.handleRequestAppsReload}
onRequestEnable={this.handleRequestEnable}
permissionsLoading={permissionsLoading}
repos={repos}
transactionBag={transactionBag}
walletNetwork={walletNetwork}
walletWeb3={walletWeb3}
Expand Down
119 changes: 69 additions & 50 deletions src/Wrapper.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import memoize from 'lodash.memoize'
import { Viewport } from '@aragon/ui'
import { Apps, Permissions, Settings } from './apps'
import { AppCenter, Permissions, Settings } from './apps'
import AppIFrame from './components/App/AppIFrame'
import App404 from './components/App404/App404'
import Home from './components/Home/Home'
Expand All @@ -18,9 +19,9 @@ import {
AragonType,
DaoAddressType,
EthereumAddressType,
RepoType,
} from './prop-types'
import { getAppPath } from './routing'
import { staticApps } from './static-apps'
import { APPS_STATUS_LOADING } from './symbols'
import { addressesEqual } from './web3-utils'
import ethereumLoadingAnimation from './assets/ethereum-loading.svg'
Expand All @@ -30,6 +31,7 @@ class Wrapper extends React.PureComponent {
account: EthereumAddressType,
apps: PropTypes.arrayOf(AppType).isRequired,
appsStatus: AppsStatusType.isRequired,
autoClosingPanel: PropTypes.bool.isRequired,
banner: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.shape({
Expand All @@ -44,7 +46,7 @@ class Wrapper extends React.PureComponent {
onRequestAppsReload: PropTypes.func.isRequired,
onRequestEnable: PropTypes.func.isRequired,
permissionsLoading: PropTypes.bool.isRequired,
autoClosingPanel: PropTypes.bool.isRequired,
repos: PropTypes.arrayOf(RepoType).isRequired,
transactionBag: PropTypes.object,
walletNetwork: PropTypes.string,
walletProviderId: PropTypes.string,
Expand All @@ -63,7 +65,6 @@ class Wrapper extends React.PureComponent {
}

state = {
appInstance: {},
menuPanelOpened: !this.props.autoClosingPanel,
preferencesOpened: false,
notificationOpen: false,
Expand Down Expand Up @@ -113,11 +114,16 @@ class Wrapper extends React.PureComponent {
wrapper,
locator: { instanceId },
} = this.props
if (
!wrapper ||
!apps.find(app => addressesEqual(app.proxyAddress, instanceId))
) {
console.error('The app cannot be connected to aragon.js')
if (!wrapper) {
console.error(
`Attempted to connect app (${instanceId}) before aragonAPI was ready`
)
return
}
if (!apps.find(app => addressesEqual(app.proxyAddress, instanceId))) {
console.error(
`The requested app (${instanceId}) could not be found in the installed apps`
)
return
}

Expand Down Expand Up @@ -176,13 +182,44 @@ class Wrapper extends React.PureComponent {
}
}

isAppInstalled(instanceId) {
const { apps } = this.props
return (
staticApps.has(instanceId) &&
!!apps.find(app => addressesEqual(app.proxyAddress, instanceId))
)
}
getAppInstancesGroups = memoize(apps =>
apps.reduce((groups, app) => {
const group = groups.find(({ appId }) => appId === app.appId)

const {
// This is not technically fully true, but let's assume that only these
// aspects be different between multiple instances of the same app
codeAddress: instanceCodeAddress,
identifier: instanceIdentifier,
proxyAddress: instanceProxyAddress,
...sharedAppInfo
} = app

const instance = {
codeAddress: instanceCodeAddress,
identifier: instanceIdentifier,
instanceId: instanceProxyAddress,
proxyAddress: instanceProxyAddress,
}

// Append the instance to the existing app group
if (group) {
group.instances.push(instance)
return groups
}

return groups.concat([
{
app: sharedAppInfo,
appId: app.appId,
name: app.name,
instances: [instance],
hasWebApp: app.hasWebApp,
repoName: app.appName,
},
])
}, [])
)

render() {
const {
Expand Down Expand Up @@ -212,7 +249,7 @@ class Wrapper extends React.PureComponent {
return (
<Main>
<Preferences
locator={locator}
dao={locator.dao}
opened={preferencesOpened}
onClose={this.handleClosePreferences}
wrapper={wrapper}
Expand All @@ -227,7 +264,7 @@ class Wrapper extends React.PureComponent {
{progress => (
<React.Fragment>
<MenuPanel
apps={apps.filter(app => app.hasWebApp)}
appInstanceGroups={this.getAppInstancesGroups(apps)}
appsStatus={appsStatus}
activeInstanceId={locator.instanceId}
connected={connected}
Expand Down Expand Up @@ -256,41 +293,12 @@ class Wrapper extends React.PureComponent {
<SignerPanel
account={account}
apps={apps}
locator={locator}
dao={locator.dao}
onRequestEnable={onRequestEnable}
transactionBag={transactionBag}
walletNetwork={walletNetwork}
walletProviderId={walletProviderId}
walletWeb3={walletWeb3}
onTransactionSuccess={({ data, name, description, identifier }) =>
this.setState(state => ({
queuedNotifications: [
{
id: data,
type: 'transaction',
title: `${name} ${identifier}`,
content: description,
},
...state.queuedNotifications,
],
}))
}
onClose={() => {
if (this.state.queuedNotifications.length) {
// Wait a little, then update notifications
setTimeout(
() =>
this.setState(state => ({
queuedNotifications: [],
notifications: [
...state.queuedNotifications,
...state.notifications,
],
})),
250
)
}
}}
/>
</Main>
)
Expand All @@ -304,20 +312,22 @@ class Wrapper extends React.PureComponent {
daoAddress,
locator,
permissionsLoading,
repos,
walletNetwork,
walletWeb3,
wrapper,
} = this.props

const appsLoading = appsStatus === APPS_STATUS_LOADING
const reposLoading = appsLoading || (apps.length && !repos.length)

if (instanceId === 'home') {
return (
<Home
apps={apps}
appsLoading={appsLoading}
connected={connected}
locator={locator}
dao={locator.dao}
onMessage={this.handleAppMessage}
onOpenApp={this.openApp}
/>
Expand All @@ -338,7 +348,16 @@ class Wrapper extends React.PureComponent {
}

if (instanceId === 'apps') {
return <Apps onMessage={this.handleAppMessage} />
return (
<AppCenter
appInstanceGroups={this.getAppInstancesGroups(apps)}
params={params}
repos={repos}
reposLoading={reposLoading}
onMessage={this.handleAppMessage}
onParamsRequest={this.handleParamsRequest}
/>
)
}

if (instanceId === 'settings') {
Expand Down
Loading