Skip to content

Commit

Permalink
Added skeleton for themes (#160)
Browse files Browse the repository at this point in the history
Added themes
  • Loading branch information
githubsaturn authored Oct 15, 2024
1 parent ae940de commit a3fa39b
Show file tree
Hide file tree
Showing 17 changed files with 855 additions and 329 deletions.
15 changes: 13 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="theme-color" content="#1b8ad3" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,500" rel="stylesheet" />

<!-- font begins -->

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
rel="stylesheet">


<!-- font ends -->

<title>CapRover | Server Dashboard</title>
</head>
Expand All @@ -17,4 +27,5 @@
<noscript> You need to enable JavaScript to run this app. </noscript>
<div id="root"></div>
</body>
</html>

</html>
116 changes: 102 additions & 14 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { App as AntdApp, ConfigProvider, theme } from 'antd'
import { App as AntdApp, ConfigProvider, theme, ThemeConfig } from 'antd'
import { useState } from 'react'
import { Provider } from 'react-redux'
import { HashRouter, Route, Switch } from 'react-router-dom'
import { applyMiddleware, createStore } from 'redux'
import thunk from 'redux-thunk'
import CenteredSpinner from './containers/global/CenteredSpinner'
import Login from './containers/Login'
import PageRoot from './containers/PageRoot'
import CapRoverThemeContext from './contexts/CapRoverThemeContext'
import DarkModeContext from './contexts/DarkModeContext'
import LanguageContext from './contexts/LanguageContext'
import reducers from './redux/reducers'
import './styles/style.css'
import CapRoverTheme from './styles/theme/CapRoverTheme'
import ThemeParser from './styles/theme/ThemeParser'
import { ThemeProvider } from './styles/theme/ThemeProvider'
import CrashReporter from './utils/CrashReporter'
import { getCurrentLanguageOption } from './utils/Language'
import StorageHelper from './utils/StorageHelper'
import Toaster from './utils/Toaster'

CrashReporter.getInstance().init()

Expand All @@ -32,26 +38,95 @@ const MainComponent = () => {
)
}

let themeState: undefined | 'LOADING' | 'LOADED' | 'TIMED_OUT' = undefined

const contentPushedToHead = [] as string[]

function App() {
const { defaultAlgorithm, darkAlgorithm } = theme

const [isDarkMode, setIsDarkMode] = useState(
StorageHelper.getDarkModeFromLocalStorage()
)
const [currTheme, setTheme] = useState(
undefined as undefined | CapRoverTheme
)
const [refreshCounter, setRefreshCounter] = useState(0)
const [currentLang, setCurrentLang] = useState(getCurrentLanguageOption())

const defaultTheme = {
algorithm: isDarkMode ? darkAlgorithm : defaultAlgorithm,
components: {
Menu: {
// itemBg:'',
darkItemBg: '#001529',
darkPopupBg: '#001529',
},
Layout: {
// lightSiderBg: '#ff00ff',
// siderBg: '#ff0000',
// headerBg: '#ff0000',
},
},
token: {
colorPrimary: '#4f5bff',
colorLink: '#2672c9',
fontFamily: `'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
},
}

if (
currTheme &&
currTheme.headEmbed &&
!contentPushedToHead.some((it) => it === currTheme.headEmbed)
) {
contentPushedToHead.push(currTheme.headEmbed)

const headElement = document.head
const injectionElement = document.createElement('div')
injectionElement.innerHTML = currTheme.headEmbed
Array.from(injectionElement.childNodes).forEach((node) => {
headElement.appendChild(node)
})
}

const customTheme = currTheme
? ThemeParser.parseTheme(
currTheme,
isDarkMode,
defaultAlgorithm,
darkAlgorithm
)
: undefined

const themeToUse: ThemeConfig = customTheme || defaultTheme

if (!themeState) {
themeState = 'LOADING'
setTimeout(() => {
if (themeState === 'LOADING') {
themeState = 'TIMED_OUT'
setRefreshCounter(refreshCounter + 1)
}
}, 600)
ThemeProvider.getInstance()
.getCurrentTheme()
.then((t) => {
setTheme(t.theme)
})
.catch(Toaster.createCatcher())
.then(() => {
themeState = 'LOADED'
setRefreshCounter(refreshCounter + 1)
})
}

return (
<ConfigProvider
direction={currentLang.rtl ? 'rtl' : 'ltr'}
theme={{
algorithm: isDarkMode ? darkAlgorithm : defaultAlgorithm,
token: {
colorPrimary: '#1b8ad3',
colorLink: '#1b8ad3',
fontFamily: `QuickSand, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
},
}}
theme={themeToUse}
locale={currentLang.antdLocale}
>
<LanguageContext.Provider
Expand All @@ -71,9 +146,22 @@ function App() {
},
}}
>
<Provider store={store}>
<MainComponent />
</Provider>
<CapRoverThemeContext.Provider
value={{
currentTheme: currTheme,
setCapRoverThemeContext: (value) => {
setTheme(value)
},
}}
>
<Provider store={store}>
{themeState === 'LOADING' ? (
<CenteredSpinner />
) : (
<MainComponent />
)}
</Provider>
</CapRoverThemeContext.Provider>
</DarkModeContext.Provider>
</LanguageContext.Provider>
</ConfigProvider>
Expand Down
49 changes: 49 additions & 0 deletions src/api/ApiManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { IRegistryInfo } from '../models/IRegistryInfo'
import { IVersionInfo } from '../models/IVersionInfo'
import ProjectDefinition from '../models/ProjectDefinition'
import CapRoverTheme from '../styles/theme/CapRoverTheme'
import ErrorFactory from '../utils/ErrorFactory'
import Logger from '../utils/Logger'
import StorageHelper from '../utils/StorageHelper'
Expand Down Expand Up @@ -100,6 +101,54 @@ export default class ApiManager {
})
}

getAllThemes(): Promise<{ themes: CapRoverTheme[] | undefined }> {
const http = this.http

return Promise.resolve() //
.then(http.fetch(http.GET, '/user/system/themes/all', {}))
}

getCurrentTheme(): Promise<{ theme: CapRoverTheme }> {
const http = this.http

return Promise.resolve() //
.then(http.fetch(http.GET, '/theme/current', {}))
}

setCurrentTheme(themeName: string): any {
const http = this.http

return Promise.resolve() //
.then(
http.fetch(http.POST, '/user/system/themes/setcurrent', {
themeName,
})
)
}
saveTheme(oldName: string, theme: CapRoverTheme): any {
const http = this.http

return Promise.resolve() //
.then(
http.fetch(http.POST, '/user/system/themes/update', {
oldName,
name: theme.name,
content: theme.content,
})
)
}

deleteTheme(themeName: string): any {
const http = this.http

return Promise.resolve() //
.then(
http.fetch(http.POST, '/user/system/themes/delete', {
themeName,
})
)
}

getProFeaturesState(): Promise<{ proFeaturesState: IProFeatures }> {
const http = this.http

Expand Down
Loading

0 comments on commit a3fa39b

Please sign in to comment.