Skip to content

Commit

Permalink
option to load custom theme
Browse files Browse the repository at this point in the history
  • Loading branch information
joneugster committed Nov 22, 2023
1 parent 866770c commit 5ecdf61
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
4 changes: 2 additions & 2 deletions client/src/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const Editor: React.FC<{setRestart?, onDidChangeContent?, value: string, theme:
const [restartMessage, setRestartMessage] = useState<boolean | null>(false)

useEffect(() => {
if (theme == 'lightPlus') {
monaco.editor.setTheme('lightPlus')
if (['lightPlus', 'custom'].includes(theme)) {
monaco.editor.setTheme(theme)
} else {
//monaco.editor.setTheme(theme)
fetch(`./themes/${theme}.json`,{
Expand Down
51 changes: 48 additions & 3 deletions client/src/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { useEffect } from 'react'
import Switch from '@mui/material/Switch';
import Select from '@mui/material/Select';
import { useWindowDimensions } from './window_width';
import { FormControl, InputLabel, MenuItem } from '@mui/material';
import { Button, FormControl, InputLabel, MenuItem } from '@mui/material';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'

const Settings: React.FC<{closeNav, theme, setTheme}> =
({closeNav, theme, setTheme}) => {
Expand All @@ -22,13 +23,15 @@ const Settings: React.FC<{closeNav, theme, setTheme}> =
If screen width is below 800, default to vertical layout instead. */
const {width, height} = useWindowDimensions()
const [verticalLayout, setVerticalLayout] = React.useState(width < 800)
const [customTheme, setCustomTheme] = React.useState<string>('initial')

// Synchronize state with initial local store
useEffect(() => {
let _abbreviationCharacter = window.localStorage.getItem("abbreviationCharacter")
let _verticalLayout = window.localStorage.getItem("verticalLayout")
let _theme = window.localStorage.getItem("theme")
let _savingAllowed = window.localStorage.getItem("savingAllowed")
let _customTheme = window.localStorage.getItem("customTheme")
if (_abbreviationCharacter) {
setAbbreviationCharacter(_abbreviationCharacter)
setSavingAllowed(true)
Expand All @@ -41,7 +44,18 @@ const Settings: React.FC<{closeNav, theme, setTheme}> =
setTheme(_theme)
setSavingAllowed(true)
}

if (_customTheme) {
setCustomTheme(_customTheme)
setSavingAllowed(true)
try {
var loadedTheme = JSON.parse(_customTheme)
monaco.editor.defineTheme('custom', loadedTheme)
} catch (error) {
// invalid custom theme
setCustomTheme('')
if (_theme == 'custom') {setTheme('lightPlus')}
}
}
}, [])

/** Synchronize config and local store whenever there is a change to any of the config
Expand All @@ -55,10 +69,12 @@ const Settings: React.FC<{closeNav, theme, setTheme}> =
window.localStorage.setItem("abbreviationCharacter", abbreviationCharacter)
window.localStorage.setItem("verticalLayout", verticalLayout ? 'true' : 'false')
window.localStorage.setItem("theme", theme)
window.localStorage.setItem("customTheme", customTheme)
} else {
window.localStorage.removeItem("abbreviationCharacter")
window.localStorage.removeItem("verticalLayout")
window.localStorage.removeItem("theme")
window.localStorage.removeItem("customTheme")
}
}, [savingAllowed, abbreviationCharacter, verticalLayout, theme])

Expand All @@ -75,6 +91,26 @@ const Settings: React.FC<{closeNav, theme, setTheme}> =
// ev.stopPropagation()
}

/** Load a custom monaco theme, store it in local storage and activate it */
function uploadTheme(ev) {
const fileToLoad = ev.target.files[0]
var fileReader = new FileReader()
fileReader.onload = (fileLoadedEvent) => {
var loadedThemeRaw = fileLoadedEvent.target.result as string
window.localStorage.setItem("customTheme", loadedThemeRaw)
try {
var loadedTheme = JSON.parse(loadedThemeRaw)
} catch (error) {
return
}
setTheme('custom')
setCustomTheme(loadedThemeRaw)
monaco.editor.defineTheme('custom', loadedTheme)
monaco.editor.setTheme('custom')
}
fileReader.readAsText(fileToLoad, "UTF-8")
}

return <>
<span className="nav-link" onClick={handleOpen}>
<FontAwesomeIcon icon={faGear} /> Settings
Expand All @@ -91,7 +127,7 @@ const Settings: React.FC<{closeNav, theme, setTheme}> =
<input id="abbreviationCharacter" type="text"
onChange={(ev) => {setAbbreviationCharacter(ev.target.value)}} value={abbreviationCharacter} />
</p>
<p>
<p className="flex">
<label htmlFor="theme">Theme: </label>
<select
id="theme"
Expand All @@ -102,7 +138,16 @@ const Settings: React.FC<{closeNav, theme, setTheme}> =
<option value="GithubDark">github dark</option>
<option value="Amy">amy</option>
<option value="Cobalt">cobalt</option>
<option value="custom">custom</option>
</select>

<label htmlFor="theme-upload" className="file-upload-button" >Load from Disk</label>
<input id="theme-upload" type="file" onChange={uploadTheme} />

{/* <Button variant="contained" component="label" className='file-upload-button' onClick={uploadTheme}>
Load from Disk
<input id="theme-upload" type="file" onChange={uploadTheme} />
</Button> */}
</p>
<p>
<Switch id="verticalLayout" onChange={handleLayoutChange} checked={verticalLayout} />
Expand Down
3 changes: 2 additions & 1 deletion client/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export const config = {
'inputModeCustomTranslations': {},
'eagerReplacementEnabled': true,
'verticalLayout': false, // value here irrelevant, will be overwritten with `width < 800` in Settings.tsx
'theme': 'light', // options: light, dark
'theme': 'lightPlus',
'customTheme': '',
}
19 changes: 14 additions & 5 deletions client/src/css/Modal.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ input[type="file"] {
width: 100%;
}

.modal select {
float: right;
}

.modal textarea {
height: 10em;
}
Expand All @@ -65,17 +61,30 @@ input[type="file"] {
font-weight: bold;
}

.modal input[type="submit"] {
.modal input[type="submit"], .modal .file-upload-button {
border: none;
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
cursor: pointer;
padding: .5rem 1rem;
border-radius: .2rem;
}

.modal input[type="submit"]{
display: block;
margin: 1rem auto;
}

.modal .flex {
display: flex;
justify-content: space-between;
}

.modal .flex label {
margin-top: auto;
margin-bottom: auto;
}

.modal-close {
float: right;
scale: 2;
Expand Down

0 comments on commit 5ecdf61

Please sign in to comment.