Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
…into ir-2543-create-prefab
  • Loading branch information
JT00y committed Jun 17, 2024
2 parents cce1d1b + ee03b64 commit 059023b
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import { SnackbarProvider, VariantType } from 'notistack'
import { SnackbarKey, SnackbarProvider, VariantType, closeSnackbar } from 'notistack'
import React, { CSSProperties, Fragment, useEffect, useRef } from 'react'

import multiLogger from '@etherealengine/common/src/logger'
import { AudioEffectPlayer } from '@etherealengine/engine/src/audio/systems/MediaSystem'
import { defineState, getState } from '@etherealengine/hyperflux'
import { defineState, getState, useMutableState } from '@etherealengine/hyperflux'

import { defaultAction } from '../components/NotificationActions'
import Icon from '@etherealengine/ui/src/primitives/mui/Icon'
import IconButton from '@etherealengine/ui/src/primitives/mui/IconButton'

const logger = multiLogger.child({ component: 'client-core:Notification' })

Expand All @@ -45,6 +47,15 @@ export type NotificationOptions = {
actionType?: keyof typeof NotificationActions
}

export const defaultAction = (key: SnackbarKey, content?: React.ReactNode) => {
return (
<Fragment>
{content}
<IconButton onClick={() => closeSnackbar(key)} icon={<Icon type="Close" sx={{ color: 'white' }} />} />
</Fragment>
)
}

export const NotificationActions = {
default: defaultAction
}
Expand All @@ -63,3 +74,22 @@ export const NotificationService = {
})
}
}

export const NotificationSnackbar = (props: { style?: CSSProperties }) => {
const notistackRef = useRef<SnackbarProvider>()
const notificationstate = useMutableState(NotificationState)

useEffect(() => {
notificationstate.snackbar.set(notistackRef.current)
}, [notistackRef.current])

return (
<SnackbarProvider
ref={notistackRef as any}
maxSnack={7}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
action={defaultAction}
style={props.style}
/>
)
}
6 changes: 2 additions & 4 deletions packages/client-core/src/common/services/ThemeService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import React, { useEffect } from 'react'
import { useEffect } from 'react'

import { defineState, getMutableState, syncStateWithLocalStorage, useMutableState } from '@etherealengine/hyperflux'

Expand Down Expand Up @@ -96,7 +96,7 @@ export const ThemeState = defineState({
extension: syncStateWithLocalStorage(['theme'])
})

export const ThemeProvider = ({ children }) => {
export const useThemeProvider = () => {
const themeState = useMutableState(ThemeState)

useEffect(() => {
Expand All @@ -120,6 +120,4 @@ export const ThemeProvider = ({ children }) => {
}
}
}

return <>{children}</>
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,32 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import { SnackbarKey, useSnackbar } from 'notistack'
import React, { Fragment } from 'react'
import { NO_PROXY } from '@etherealengine/hyperflux'
import { loadWebappInjection } from '@etherealengine/projects/loadWebappInjection'
import LoadingView from '@etherealengine/ui/src/primitives/tailwind/LoadingView'
import { useHookstate } from '@hookstate/core'
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'

import Icon from '@etherealengine/ui/src/primitives/mui/Icon'
import IconButton from '@etherealengine/ui/src/primitives/mui/IconButton'
export const LoadWebappInjection = (props) => {
const { t } = useTranslation()

export const defaultAction = (key: SnackbarKey, content?: React.ReactNode) => {
const { closeSnackbar } = useSnackbar()
const projectComponents = useHookstate(null as null | any[])

useEffect(() => {
loadWebappInjection().then((result) => {
projectComponents.set(result)
})
}, [])

if (!projectComponents.value) return <LoadingView title={t('common:loader.authenticating')} />

return (
<Fragment>
{content}
<IconButton onClick={() => closeSnackbar(key)} icon={<Icon type="Close" sx={{ color: 'white' }} />} />
</Fragment>
<>
{projectComponents.get(NO_PROXY)!.map((Component, i) => (
<Component key={i} />
))}
{props.children}
</>
)
}
17 changes: 16 additions & 1 deletion packages/client-core/src/user/services/AuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ import {
dispatchAction,
getMutableState,
getState,
syncStateWithLocalStorage
syncStateWithLocalStorage,
useHookstate
} from '@etherealengine/hyperflux'

import { API } from '../../API'
Expand Down Expand Up @@ -759,3 +760,17 @@ function parseLoginDisplayCredential(credentials) {

return { displayName, displayIcon }
}

export const useAuthenticated = () => {
const authState = useHookstate(getMutableState(AuthState))

useEffect(() => {
AuthService.doLoginAuto()
}, [])

useEffect(() => {
Engine.instance.userID = authState.user.id.value
}, [authState.user.id])

return authState.isLoggedIn.value
}
27 changes: 19 additions & 8 deletions packages/client/src/engine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import React, { createRef, Suspense } from 'react'
import React, { Suspense, useEffect } from 'react'
import { useTranslation } from 'react-i18next'

import { API } from '@etherealengine/client-core/src/API'
import { LoadingCircle } from '@etherealengine/client-core/src/components/LoadingCircle'
import { BrowserRouter, history } from '@etherealengine/client-core/src/common/services/RouterService'
import waitForClientAuthenticated from '@etherealengine/client-core/src/util/wait-for-client-authenticated'
import { pipeLogs } from '@etherealengine/common/src/logger'
import { Engine } from '@etherealengine/ecs/src/Engine'
Expand All @@ -36,6 +36,7 @@ import { getMutableState } from '@etherealengine/hyperflux'
import { EngineState } from '@etherealengine/spatial/src/EngineState'
import { createEngine } from '@etherealengine/spatial/src/initializeEngine'

import LoadingView from '@etherealengine/ui/src/primitives/tailwind/LoadingView'
import { initializei18n } from './util'

const initializeLogs = async () => {
Expand All @@ -53,12 +54,22 @@ initializeBrowser()
API.createAPI()
initializeLogs()

export default function ({ children, tailwind = false }): JSX.Element {
const ref = createRef()
export default function ({ children }): JSX.Element {
const { t } = useTranslation()
return !tailwind ? (
<Suspense fallback={<LoadingCircle message={t('common:loader.loadingClient')} />}>{children}</Suspense>
) : (
children

useEffect(() => {
const urlSearchParams = new URLSearchParams(window.location.search)
const redirectUrl = urlSearchParams.get('redirectUrl')
if (redirectUrl) {
history.push(redirectUrl)
}
}, [])

return (
<>
<BrowserRouter history={history}>
<Suspense fallback={<LoadingView title={t('common:loader.loadingClient')} />}>{children}</Suspense>
</BrowserRouter>
</>
)
}
27 changes: 6 additions & 21 deletions packages/client/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ Ethereal Engine. All Rights Reserved.
*/

import { t } from 'i18next'
import React, { lazy, Suspense, useEffect } from 'react'
import React, { lazy, Suspense } from 'react'
import { createRoot } from 'react-dom/client'
import { Route, Routes } from 'react-router-dom'

import ErrorBoundary from '@etherealengine/client-core/src/common/components/ErrorBoundary'
import { BrowserRouter, history } from '@etherealengine/client-core/src/common/services/RouterService'
import { LoadingCircle } from '@etherealengine/client-core/src/components/LoadingCircle'

import './pages/styles.scss'
Expand All @@ -45,27 +44,17 @@ const AppPage = lazy(() => import('./pages/_app'))
const TailwindPage = lazy(() => import('./pages/_app_tw'))

const App = () => {
useEffect(() => {
const urlSearchParams = new URLSearchParams(window.location.search)
const redirectUrl = urlSearchParams.get('redirectUrl')
if (redirectUrl) {
history.push(redirectUrl)
}
}, [])

return (
<ErrorBoundary>
<BrowserRouter history={history}>
<Engine>
<Routes>
{/* @todo - these are for backwards compatibility with non tailwind pages - they will be removed eventually */}
<Route
key="location"
path="/location/*"
element={
<Suspense fallback={<LoadingCircle message={t('common:loader.starting')} />}>
<Engine>
<AppPage route={'location'} />
</Engine>
<AppPage route={'location'} />
</Suspense>
}
/>
Expand All @@ -74,9 +63,7 @@ const App = () => {
path="/offline/*"
element={
<Suspense fallback={<LoadingCircle message={t('common:loader.starting')} />}>
<Engine>
<AppPage route={'offline'} />
</Engine>
<AppPage route={'offline'} />
</Suspense>
}
/>
Expand All @@ -86,14 +73,12 @@ const App = () => {
path="/*"
element={
<Suspense>
<Engine tailwind>
<TailwindPage />
</Engine>
<TailwindPage />
</Suspense>
}
/>
</Routes>
</BrowserRouter>
</Engine>
</ErrorBoundary>
)
}
Expand Down
59 changes: 15 additions & 44 deletions packages/client/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,22 @@ Ethereal Engine. All Rights Reserved.
*/

// import * as chapiWalletPolyfill from 'credential-handler-polyfill'
import { SnackbarProvider } from 'notistack'
import React, { useEffect, useRef, useState } from 'react'
import React, { useEffect } from 'react'

import { initGA, logPageView } from '@etherealengine/client-core/src/common/analytics'
import { defaultAction } from '@etherealengine/client-core/src/common/components/NotificationActions'
import { NotificationState } from '@etherealengine/client-core/src/common/services/NotificationService'
import { NotificationSnackbar } from '@etherealengine/client-core/src/common/services/NotificationService'
import Debug from '@etherealengine/client-core/src/components/Debug'
import InviteToast from '@etherealengine/client-core/src/components/InviteToast'
import { AuthService, AuthState } from '@etherealengine/client-core/src/user/services/AuthService'
import { useAuthenticated } from '@etherealengine/client-core/src/user/services/AuthService'

import '@etherealengine/client-core/src/util/GlobalStyle.css'

import { StyledEngineProvider, Theme } from '@mui/material/styles'
import { useTranslation } from 'react-i18next'

import { LoadingCircle } from '@etherealengine/client-core/src/components/LoadingCircle'
import { Engine } from '@etherealengine/ecs/src/Engine'
import { useMutableState } from '@etherealengine/hyperflux'
import { loadWebappInjection } from '@etherealengine/projects/loadWebappInjection'

import { LoadWebappInjection } from '@etherealengine/client-core/src/components/LoadWebappInjection'
import RouterComp from '../route/public'
import { ThemeContextProvider } from './themeContext'

Expand All @@ -54,60 +50,35 @@ declare module '@mui/styles/defaultTheme' {

/** @deprecated see https://github.com/EtherealEngine/etherealengine/issues/6485 */
const AppPage = ({ route }: { route: string }) => {
const notistackRef = useRef<SnackbarProvider>()
const authState = useMutableState(AuthState)
const isLoggedIn = useMutableState(AuthState).isLoggedIn
const selfUser = authState.user
const [projectComponents, setProjectComponents] = useState<Array<any> | null>(null)
const notificationstate = useMutableState(NotificationState)
const isLoggedIn = useAuthenticated()
const { t } = useTranslation()

useEffect(() => {
AuthService.doLoginAuto()
initGA()
logPageView()
}, [])

useEffect(() => {
notificationstate.snackbar.set(notistackRef.current)
}, [notistackRef.current])

useEffect(() => {
if (!isLoggedIn.value || projectComponents) return
loadWebappInjection().then((result) => {
setProjectComponents(result)
})
}, [isLoggedIn])

useEffect(() => {
Engine.instance.userID = selfUser.id.value
}, [selfUser.id])

if (!isLoggedIn.value) {
if (!isLoggedIn) {
return <LoadingCircle message={t('common:loader.authenticating')} />
}

return (
<>
<ThemeContextProvider>
<StyledEngineProvider injectFirst>
<SnackbarProvider
ref={notistackRef as any}
maxSnack={7}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
action={defaultAction}
<NotificationSnackbar
style={{
fontFamily: 'var(--lato)',
fontSize: '12px'
}}
>
<div style={{ pointerEvents: 'auto' }}>
<InviteToast />
<Debug />
</div>
{projectComponents && <RouterComp route={route} />}
{projectComponents?.map((Component, i) => <Component key={i} />)}
</SnackbarProvider>
/>
<div style={{ pointerEvents: 'auto' }}>
<InviteToast />
<Debug />
</div>
<LoadWebappInjection>
<RouterComp route={route} />
</LoadWebappInjection>
</StyledEngineProvider>
</ThemeContextProvider>
</>
Expand Down
Loading

0 comments on commit 059023b

Please sign in to comment.