Skip to content

Commit 68ebe96

Browse files
[Feature] Add MetaMask Home and Portfolio Pages (#83)
* other: move extensions folder to public folder * fix: git ignoring js extensions file * chore: updated electron and electron-builder * fix: extension manifest permissions * chore: check on frontend it window.ethereum is available * fix: popup not found * add latest metamask chrome extension * rm metamask 10.22.2 * Update hyperplay-extension-helper * rm webRequest permission and calls, log ext error * Update manifest.json * rm mm v10.23.22 add mm v10.22.2 * don't upgrade electron * return correct tab url for packaged build * mv electron to dev dep * dont format mm js files on save * rm webRequest permission * fix mm for file protocol pages and handle streamMiddleware as warnings not errors * fix window.ethereum retry * add declaration for css modules * add mm full screen home page * Update hyperplay-extension-helper * add metamask portfolio page * open mm home page instead of separate browser window * Fix mm sidebar links * only show mm sidebar links if mm extension was selected * fix merge * Update hyperplay-extension-helper * fix home extension id * Update hyperplay-extension-helper Co-authored-by: Flavio F Lima <flavioislima@gmail.com>
1 parent ef0d055 commit 68ebe96

File tree

16 files changed

+152
-13
lines changed

16 files changed

+152
-13
lines changed

src/common/typings.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module '*.module.css'

src/frontend/App.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { ControllerHints, OfflineMessage } from './components/UI'
1717
import DownloadManager from './screens/DownloadManager'
1818
import DialogHandler from './components/UI/DialogHandler'
1919
import ExtensionHandler from './ExtensionHandler'
20+
import MetaMaskHome from './screens/MetaMaskHome'
21+
import MetaMaskPortfolio from './screens/MetaMaskPortfolio'
2022
import ExtensionManager from './ExtensionManager'
2123
import onboardingStore from './store/OnboardingStore'
2224
import { observer } from 'mobx-react-lite'
@@ -40,6 +42,8 @@ function App() {
4042
<Route path="epicstore" element={<WebView />} />
4143
<Route path="gogstore" element={<WebView />} />
4244
<Route path="wiki" element={<WebView />} />
45+
<Route path="metamaskHome" element={<MetaMaskHome />} />
46+
<Route path="metamaskPortfolio" element={<MetaMaskPortfolio />} />
4347
<Route path="/gamepage">
4448
<Route path=":runner">
4549
<Route path=":appName" element={<GamePage />} />

src/frontend/ExtensionHandler/index.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import React, { useEffect } from 'react'
2+
import { useNavigate } from 'react-router-dom'
23

34
const ExtensionHandler = function () {
5+
const navigate = useNavigate()
6+
47
async function handleRequest(
58
event: Event,
69
id: number,
@@ -16,6 +19,10 @@ const ExtensionHandler = function () {
1619
}
1720
}
1821

22+
async function handleOpenMMHomePage() {
23+
navigate('metamaskHome')
24+
}
25+
1926
const bindEthereumListeners = function () {
2027
window.addEventListener('message', (event: MessageEvent) => {
2128
console.log('window message received = ', JSON.stringify(event, null, 4))
@@ -39,8 +46,11 @@ const ExtensionHandler = function () {
3946

4047
const removeRequestListener =
4148
window.api.handleMetamaskExtensionRequests(handleRequest)
49+
const removeOpenMetaMaskHomePageListener =
50+
window.api.handleOpenMetaMaskHomePage(handleOpenMMHomePage)
4251
return () => {
4352
removeRequestListener()
53+
removeOpenMetaMaskHomePageListener()
4454
}
4555
}
4656

Loading

src/frontend/components/UI/Sidebar/components/SidebarLinks/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export default function SidebarLinks() {
136136
<span>{t('library.label', 'Library')}</span>
137137
</>
138138
</NavLink>
139+
139140
<h6 className="Sidebar__categoryTitle">ACCOUNTS</h6>
140141
{!loggedIn && (
141142
<NavLink

src/frontend/components/UI/Sidebar/index.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
z-index: 10;
66
display: grid;
77
grid-template-rows: min-content 2fr min-content min-content;
8-
grid-template-areas: 'links' 'utils' 'updates' 'version' 'wallet';
8+
grid-template-areas: 'links' 'utils' 'updates' 'version' 'mmHome' 'wallet';
99
grid-area: sidebar;
1010
height: 100%;
1111
padding: 0;

src/frontend/components/UI/Sidebar/index.tsx

+48-7
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@ import SidebarLinks from './components/SidebarLinks'
1313
import './index.css'
1414
import Wallet from './components/wallet'
1515
import { DMQueueElement } from 'common/types'
16+
import { NavLink } from 'react-router-dom'
17+
import { ReactComponent as MetaMaskRoundedOutline } from 'frontend/assets/metamask-rounded-outline.svg'
1618
import { observer } from 'mobx-react-lite'
1719

1820
const Sidebar = observer(() => {
1921
const { t } = useTranslation()
20-
const { sidebarCollapsed, setSideBarCollapsed } = useContext(ContextProvider)
22+
const {
23+
sidebarCollapsed,
24+
setSideBarCollapsed,
25+
showMetaMaskBrowserSidebarLinks
26+
} = useContext(ContextProvider)
2127
const [currentDMElement, setCurrentDMElement] = useState<DMQueueElement>()
2228
const [badgeText, setBadgeText] = useState('0')
2329

@@ -59,12 +65,47 @@ const Sidebar = observer(() => {
5965
)}
6066
</div>
6167

62-
<button
63-
className="Sidebar__item"
64-
onClick={async () => window.api.showPopup()}
65-
>
66-
<span>Open MetaMask {badgeText}</span>
67-
</button>
68+
{showMetaMaskBrowserSidebarLinks ? (
69+
<>
70+
<button
71+
className="Sidebar__item"
72+
onClick={async () => window.api.showPopup()}
73+
>
74+
<>
75+
<div className="Sidebar__itemIcon">
76+
<MetaMaskRoundedOutline />
77+
</div>
78+
<span>MetaMask Popup {badgeText}</span>
79+
</>
80+
</button>
81+
<NavLink
82+
className={({ isActive }) =>
83+
classNames('Sidebar__item', { active: isActive })
84+
}
85+
to={'metamaskPortfolio'}
86+
>
87+
<>
88+
<div className="Sidebar__itemIcon">
89+
<MetaMaskRoundedOutline />
90+
</div>
91+
<span>{'MetaMask Portfolio'}</span>
92+
</>
93+
</NavLink>
94+
<NavLink
95+
className={({ isActive }) =>
96+
classNames('Sidebar__item', { active: isActive })
97+
}
98+
to={'metamaskHome'}
99+
>
100+
<>
101+
<div className="Sidebar__itemIcon">
102+
<MetaMaskRoundedOutline />
103+
</div>
104+
<span>{'MetaMask Home'}</span>
105+
</>
106+
</NavLink>
107+
</>
108+
) : null}
68109

69110
<Wallet onClick={() => onboardingStore.openOnboarding()} />
70111
<button
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.homeDiv {
2+
height: 100%;
3+
}
4+
5+
.homeWebview {
6+
height: 100%;
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React, { useEffect, useState } from 'react'
2+
import MetaMaskHomeStyles from './index.module.css'
3+
4+
const MetaMaskHome = function () {
5+
const [extId, setExtId] = useState('')
6+
7+
useEffect(() => {
8+
window.api.getExtensionId().then((id) => setExtId(id))
9+
}, [])
10+
11+
return (
12+
<>
13+
<div className={MetaMaskHomeStyles.homeDiv}>
14+
<webview
15+
className={MetaMaskHomeStyles.homeWebview}
16+
src={`chrome-extension://${extId}/home.html`}
17+
/>
18+
</div>
19+
</>
20+
)
21+
}
22+
23+
export default MetaMaskHome
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.homeDiv {
2+
height: 100%;
3+
}
4+
5+
.homeWebview {
6+
height: 100%;
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react'
2+
import MetaMaskPortfolioStyles from './index.module.css'
3+
4+
const MetaMaskPortfolio = function () {
5+
return (
6+
<>
7+
<div className={MetaMaskPortfolioStyles.homeDiv}>
8+
<webview
9+
className={MetaMaskPortfolioStyles.homeWebview}
10+
src="https://portfolio.metamask.io/"
11+
/>
12+
</div>
13+
</>
14+
)
15+
}
16+
17+
export default MetaMaskPortfolio

src/frontend/screens/Onboarding/index.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
ConnectionRequestRejectedType
66
} from 'backend/hyperplay-proxy-server/commonProxyTypes'
77
import { PROVIDERS } from 'common/types/proxy-types'
8-
import React, { Reducer, useEffect, useReducer } from 'react'
8+
import React, { Reducer, useEffect, useReducer, useContext } from 'react'
99
import './index.css'
1010
import Scan from './scan'
1111
import { ONBOARDING_CONTENT, OnboardingModalConfig } from './types'
@@ -16,6 +16,7 @@ import Success from './success'
1616
import Rejected from './rejected'
1717
import Download from './download'
1818
import { BackArrow, CloseX } from 'frontend/assets/hyperplay'
19+
import ContextProvider from 'frontend/state/ContextProvider'
1920

2021
interface OnboardingProps {
2122
disableOnboarding: () => void
@@ -37,7 +38,10 @@ const Onboarding: React.FC<OnboardingProps> = function (props) {
3738
Reducer<ContentParams, Partial<ContentParams>>
3839
>((state, newState) => ({ ...state, ...newState }), contentParamsInit)
3940

41+
const { setShowMetaMaskBrowserSidebarLinks } = useContext(ContextProvider)
42+
4043
async function handleProviderClicked(provider: PROVIDERS) {
44+
setShowMetaMaskBrowserSidebarLinks(false)
4145
const uris: UrisReturn = await window.api.getConnectionUris(provider)
4246
const qrCodeLink: IMobileRegistryEntryWithQrLink = uris.metamask
4347
const qrCode = qrCodeLink.qrCodeLink
@@ -54,6 +58,7 @@ const Onboarding: React.FC<OnboardingProps> = function (props) {
5458
}
5559

5660
async function handleMmExtensionProviderClicked() {
61+
setShowMetaMaskBrowserSidebarLinks(true)
5762
await window.api.getConnectionUris(PROVIDERS.METAMASK_EXTENSION)
5863
props.disableOnboarding()
5964
}

src/frontend/state/ContextProvider.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ const initialContext: ContextType = {
6767
setSecondaryFontFamily: () => null,
6868
dialogModalOptions: { showDialog: false },
6969
showDialogModal: () => null,
70-
showResetDialog: () => null
70+
showResetDialog: () => null,
71+
showMetaMaskBrowserSidebarLinks: false,
72+
setShowMetaMaskBrowserSidebarLinks: () => null
7173
}
7274

7375
export default React.createContext(initialContext)

src/frontend/state/GlobalState.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ interface StateProps {
8888
connectivity: { status: ConnectivityStatus; retryIn: number }
8989
dialogModalOptions: DialogModalOptions
9090
sideloadedLibrary: GameInfo[]
91+
showMetaMaskBrowserSidebarLinks: boolean
9192
}
9293

9394
export class GlobalState extends PureComponent<Props> {
@@ -164,7 +165,8 @@ export class GlobalState extends PureComponent<Props> {
164165
activeController: '',
165166
connectivity: { status: 'offline', retryIn: 0 },
166167
sideloadedLibrary: sideloadLibrary.get('games', []) as GameInfo[],
167-
dialogModalOptions: { showDialog: false }
168+
dialogModalOptions: { showDialog: false },
169+
showMetaMaskBrowserSidebarLinks: false
168170
}
169171

170172
setLanguage = (newLanguage: string) => {
@@ -222,6 +224,10 @@ export class GlobalState extends PureComponent<Props> {
222224
this.setState({ sidebarCollapsed: value })
223225
}
224226

227+
setShowMetaMaskBrowserSidebarLinks = (value: boolean) => {
228+
this.setState({ showMetaMaskBrowserSidebarLinks: value })
229+
}
230+
225231
hideGame = (appNameToHide: string, appTitle: string) => {
226232
const newHiddenGames = [
227233
...this.state.hiddenGames,
@@ -743,7 +749,9 @@ export class GlobalState extends PureComponent<Props> {
743749
setPrimaryFontFamily: this.setPrimaryFontFamily,
744750
setSecondaryFontFamily: this.setSecondaryFontFamily,
745751
showDialogModal: this.handleShowDialogModal,
746-
showResetDialog: this.showResetDialog
752+
showResetDialog: this.showResetDialog,
753+
setShowMetaMaskBrowserSidebarLinks:
754+
this.setShowMetaMaskBrowserSidebarLinks
747755
}}
748756
>
749757
{this.props.children}

src/frontend/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ export interface ContextType {
7979
showDialogModal: (options: DialogModalOptions) => void
8080
showResetDialog: () => void
8181
sideloadedLibrary: GameInfo[]
82+
showMetaMaskBrowserSidebarLinks: boolean
83+
setShowMetaMaskBrowserSidebarLinks: (value: boolean) => void
8284
}
8385

8486
export type DialogModalOptions = {

0 commit comments

Comments
 (0)