mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 08:37:43 +01:00
[MIRROR] Lua UI improvements [MDB IGNORE] (#15561)
* Lua UI improvements (#68887) Atomized from #68816, with a little addition. Fixes some dumb formatting issues with the lua editor, adds a "jump to bottom" button when viewing the state log, and paginates the state logs. * Lua UI improvements Co-authored-by: Y0SH1M4S73R <legoboyo@earthlink.net>
This commit is contained in:
@@ -2017,8 +2017,6 @@
|
||||
if(log_index <= state_to_view.log.len)
|
||||
var/list/log_entry = state_to_view.log[log_index]
|
||||
if(log_entry["chunk"])
|
||||
LAZYINITLIST(editor.tgui_shared_states)
|
||||
editor.tgui_shared_states["viewedChunk"] = json_encode(log_entry["chunk"])
|
||||
editor.tgui_shared_states["modal"] = json_encode("viewChunk")
|
||||
editor.force_view_chunk = log_entry["chunk"]
|
||||
editor.force_modal = "viewChunk"
|
||||
editor.ui_interact(usr)
|
||||
editor.tgui_shared_states = null
|
||||
|
||||
@@ -7,8 +7,17 @@
|
||||
/// Arguments for a function call or coroutine resume
|
||||
var/list/arguments = list()
|
||||
|
||||
/// If set, the global table and the
|
||||
var/show_debug_info = FALSE
|
||||
/// If set, the global table will not be shown in the lua editor
|
||||
var/show_global_table = FALSE
|
||||
|
||||
/// The log page we are currently on
|
||||
var/page = 0
|
||||
|
||||
/// If set, we will force the editor's modal to be this
|
||||
var/force_modal
|
||||
|
||||
/// If set, we will force the editor to look at this chunk
|
||||
var/force_view_chunk
|
||||
|
||||
/datum/lua_editor/New(state, _quick_log_index)
|
||||
. = ..()
|
||||
@@ -39,16 +48,24 @@
|
||||
/datum/lua_editor/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["noStateYet"] = !current_state
|
||||
data["showDebugInfo"] = show_debug_info
|
||||
data["showGlobalTable"] = show_global_table
|
||||
if(current_state)
|
||||
if(current_state.log && show_debug_info)
|
||||
data["stateLog"] = kvpify_list(refify_list(current_state.log))
|
||||
if(current_state.log)
|
||||
data["stateLog"] = kvpify_list(refify_list(current_state.log.Copy((page*50)+1, min((page+1)*50+1, current_state.log.len+1))))
|
||||
data["page"] = page
|
||||
data["pageCount"] = CEILING(current_state.log.len/50, 1)
|
||||
data["tasks"] = current_state.get_tasks()
|
||||
if(show_debug_info)
|
||||
if(show_global_table)
|
||||
current_state.get_globals()
|
||||
data["globals"] = kvpify_list(refify_list(current_state.globals))
|
||||
data["states"] = SSlua.states
|
||||
data["callArguments"] = kvpify_list(refify_list(arguments))
|
||||
if(force_modal)
|
||||
data["forceModal"] = force_modal
|
||||
force_modal = null
|
||||
if(force_view_chunk)
|
||||
data["forceViewChunk"] = force_view_chunk
|
||||
force_view_chunk = null
|
||||
return data
|
||||
|
||||
/datum/lua_editor/proc/traverse_list(list/path, list/root, traversal_depth_offset = 0)
|
||||
@@ -96,12 +113,14 @@
|
||||
LAZYREMOVEASSOC(SSlua.editors, "\ref[current_state]", src)
|
||||
current_state = new_state
|
||||
LAZYADDASSOCLIST(SSlua.editors, "\ref[current_state]", src)
|
||||
page = 0
|
||||
return TRUE
|
||||
if("switchState")
|
||||
var/state_index = params["index"]
|
||||
LAZYREMOVEASSOC(SSlua.editors, "\ref[current_state]", src)
|
||||
current_state = SSlua.states[state_index]
|
||||
LAZYADDASSOCLIST(SSlua.editors, "\ref[current_state]", src)
|
||||
page = 0
|
||||
return TRUE
|
||||
if("runCode")
|
||||
var/code = params["code"]
|
||||
@@ -191,8 +210,14 @@
|
||||
if("clearArgs")
|
||||
arguments.Cut()
|
||||
return TRUE
|
||||
if("toggleShowDebugInfo")
|
||||
show_debug_info = !show_debug_info
|
||||
if("toggleShowGlobalTable")
|
||||
show_global_table = !show_global_table
|
||||
return TRUE
|
||||
if("nextPage")
|
||||
page = min(page+1, CEILING(current_state.log.len/50, 1)-1)
|
||||
return TRUE
|
||||
if("previousPage")
|
||||
page = max(page-1, 0)
|
||||
return TRUE
|
||||
|
||||
/datum/lua_editor/ui_close(mob/user)
|
||||
|
||||
@@ -58,7 +58,7 @@ GLOBAL_PROTECT(lua_usr)
|
||||
break
|
||||
if(append_to_log)
|
||||
log += list(weakrefify_list(result))
|
||||
INVOKE_ASYNC(src, .proc/update_editors)
|
||||
INVOKE_ASYNC(src, /datum/lua_state.proc/update_editors)
|
||||
|
||||
/datum/lua_state/proc/load_script(script)
|
||||
GLOB.IsLuaCall = TRUE
|
||||
|
||||
@@ -66,6 +66,7 @@ export class Section extends Component<SectionProps> {
|
||||
scrollable,
|
||||
scrollableHorizontal,
|
||||
children,
|
||||
onScroll,
|
||||
...rest
|
||||
} = this.props;
|
||||
const hasTitle = canRender(title) || canRender(buttons);
|
||||
@@ -89,7 +90,10 @@ export class Section extends Component<SectionProps> {
|
||||
</div>
|
||||
)}
|
||||
<div className="Section__rest">
|
||||
<div ref={this.scrollableRef} className="Section__content">
|
||||
<div
|
||||
ref={this.scrollableRef}
|
||||
onScroll={onScroll}
|
||||
className="Section__content">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,9 @@ export const CallModal = (props, context) => {
|
||||
const [toCall, setToCall] = useLocalState(context, 'toCallTaskInfo');
|
||||
const { type, params } = toCall;
|
||||
return (
|
||||
<Modal height="600px" width="600px">
|
||||
<Modal
|
||||
height={`${window.innerHeight * 0.8}px`}
|
||||
width={`${window.innerWidth * 0.5}px`}>
|
||||
<Section
|
||||
fill
|
||||
scrollable
|
||||
|
||||
@@ -7,7 +7,9 @@ export const ChunkViewModal = (props, context) => {
|
||||
const [, setModal] = useLocalState(context, 'modal');
|
||||
const [viewedChunk, setViewedChunk] = useLocalState(context, 'viewedChunk');
|
||||
return (
|
||||
<Modal height="600px" width="500px">
|
||||
<Modal
|
||||
height={`${window.innerHeight * 0.8}px`}
|
||||
width={`${window.innerWidth * 0.5}px`}>
|
||||
<Section
|
||||
fill
|
||||
scrollable
|
||||
|
||||
@@ -7,7 +7,9 @@ export const StateSelectModal = (props, context) => {
|
||||
const [input, setInput] = useLocalState(context, 'newStateName', '');
|
||||
const { states } = data;
|
||||
return (
|
||||
<Modal height="400px" width="300px">
|
||||
<Modal
|
||||
height={`${window.innerHeight * 0.5}px`}
|
||||
width={`${window.innerWidth * 0.3}px`}>
|
||||
<Section
|
||||
fill
|
||||
title="States"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useBackend, useLocalState } from '../../backend';
|
||||
import { Box, Button, Flex, Section, Tabs, TextArea, Modal, Stack } from '../../components';
|
||||
import { Box, Button, Flex, Section, Tabs, TextArea, Modal, Stack, ProgressBar } from '../../components';
|
||||
import { Window } from '../../layouts';
|
||||
import { CallModal } from './CallModal';
|
||||
import { ChunkViewModal } from './ChunkViewModal';
|
||||
@@ -9,203 +9,332 @@ import { Log } from './Log';
|
||||
import { TaskManager } from './TaskManager';
|
||||
import { sanitizeText } from '../../sanitize';
|
||||
import { marked } from 'marked';
|
||||
import { Component, createRef } from 'inferno';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import lua from 'highlight.js/lib/languages/lua';
|
||||
hljs.registerLanguage('lua', lua);
|
||||
|
||||
export const LuaEditor = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { noStateYet, globals, documentation, tasks, showDebugInfo } = data;
|
||||
const [modal, setModal] = useLocalState(
|
||||
context,
|
||||
'modal',
|
||||
noStateYet ? 'states' : null
|
||||
);
|
||||
const [activeTab, setActiveTab] = useLocalState(
|
||||
context,
|
||||
'activeTab',
|
||||
'tasks'
|
||||
);
|
||||
const [input, setInput] = useLocalState(context, 'scriptInput', '');
|
||||
let tabContent;
|
||||
switch (activeTab) {
|
||||
case 'globals': {
|
||||
if (!globals) {
|
||||
tabContent = (
|
||||
<h1>
|
||||
Could not retrieve the global table. Was it corrupted or shadowed?
|
||||
</h1>
|
||||
);
|
||||
} else {
|
||||
tabContent = (
|
||||
<ListMapper
|
||||
list={globals}
|
||||
skipNulls
|
||||
vvAct={(path) => act('vvGlobal', { indices: path })}
|
||||
callType="callFunction"
|
||||
/>
|
||||
);
|
||||
export class LuaEditor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.sectionRef = createRef();
|
||||
this.state = {
|
||||
showJumpToBottomButton: false,
|
||||
activeTab: 'tasks',
|
||||
scriptInput: '',
|
||||
};
|
||||
|
||||
this.handleSectionScroll = () => {
|
||||
const { showJumpToBottomButton } = this.state;
|
||||
const scrollableCurrent = this.sectionRef.current?.scrollableRef.current;
|
||||
if (
|
||||
!showJumpToBottomButton &&
|
||||
scrollableCurrent?.scrollHeight >
|
||||
scrollableCurrent?.scrollTop + scrollableCurrent?.clientHeight
|
||||
) {
|
||||
this.setState({ showJumpToBottomButton: true });
|
||||
} else if (
|
||||
showJumpToBottomButton &&
|
||||
scrollableCurrent?.scrollTop + scrollableCurrent?.clientHeight >=
|
||||
scrollableCurrent?.scrollHeight
|
||||
) {
|
||||
this.setState({ showJumpToBottomButton: false });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'tasks': {
|
||||
if (!tasks) {
|
||||
tabContent = (
|
||||
<h1>
|
||||
Could not retrieve task info. Was the global table corrupted or
|
||||
shadowed?
|
||||
</h1>
|
||||
);
|
||||
} else {
|
||||
tabContent = <TaskManager />;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'log': {
|
||||
tabContent = <Log />;
|
||||
break;
|
||||
};
|
||||
|
||||
window.addEventListener('resize', () =>
|
||||
this.forceUpdate(this.handleSectionScroll)
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { data } = useBackend(this.context);
|
||||
const { forceModal, forceViewChunk } = data;
|
||||
if (forceModal || forceViewChunk) {
|
||||
const [, setModal] = useLocalState(this.context, 'modal');
|
||||
const [, setViewedChunk] = useLocalState(this.context, 'viewedChunk');
|
||||
setModal(forceModal);
|
||||
setViewedChunk(forceViewChunk);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Window width={1280} height={720}>
|
||||
<Window.Content>
|
||||
<Button icon="file" onClick={() => setModal('states')}>
|
||||
States
|
||||
</Button>
|
||||
{noStateYet ? (
|
||||
<Flex
|
||||
width="100%"
|
||||
height="100%"
|
||||
align="center"
|
||||
justify="space-around">
|
||||
<h1>Please select or create a lua state to get started.</h1>
|
||||
</Flex>
|
||||
) : (
|
||||
<Stack height="calc(100% - 16px)">
|
||||
<Stack.Item grow shrink basis="55%">
|
||||
<Section
|
||||
fill
|
||||
pb="16px"
|
||||
title="Input"
|
||||
buttons={
|
||||
<>
|
||||
<Button.File
|
||||
onSelectFiles={(file) => setInput(file)}
|
||||
accept=".lua,.luau">
|
||||
Import
|
||||
</Button.File>
|
||||
<Button onClick={() => setModal('documentation')}>
|
||||
Help
|
||||
</Button>
|
||||
</>
|
||||
}>
|
||||
<TextArea
|
||||
fluid
|
||||
width="100%"
|
||||
height="100%"
|
||||
value={input}
|
||||
fontFamily="Consolas"
|
||||
onInput={(_, value) => setInput(value)}
|
||||
displayedValue={
|
||||
<Box
|
||||
style={{
|
||||
'pointer-events': 'none',
|
||||
}}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: hljs.highlight(input, { language: 'lua' })
|
||||
.value,
|
||||
}}
|
||||
/>
|
||||
|
||||
componentDidUpdate() {
|
||||
this.handleSectionScroll();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { act, data } = useBackend(this.context);
|
||||
const {
|
||||
noStateYet,
|
||||
globals,
|
||||
documentation,
|
||||
tasks,
|
||||
showGlobalTable,
|
||||
page,
|
||||
pageCount,
|
||||
} = data;
|
||||
const [modal, setModal] = useLocalState(
|
||||
this.context,
|
||||
'modal',
|
||||
noStateYet ? 'states' : null
|
||||
);
|
||||
const { activeTab, showJumpToBottomButton, scriptInput } = this.state;
|
||||
let tabContent;
|
||||
switch (activeTab) {
|
||||
case 'globals': {
|
||||
if (!globals) {
|
||||
tabContent = (
|
||||
<h1>
|
||||
Could not retrieve the global table. Was it corrupted or shadowed?
|
||||
</h1>
|
||||
);
|
||||
} else {
|
||||
tabContent = (
|
||||
<ListMapper
|
||||
list={globals}
|
||||
skipNulls
|
||||
vvAct={(path) => act('vvGlobal', { indices: path })}
|
||||
callType="callFunction"
|
||||
/>
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'tasks': {
|
||||
if (!tasks) {
|
||||
tabContent = (
|
||||
<h1>
|
||||
Could not retrieve task info. Was the global table corrupted or
|
||||
shadowed?
|
||||
</h1>
|
||||
);
|
||||
} else {
|
||||
tabContent = <TaskManager />;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'log': {
|
||||
tabContent = <Log />;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Window width={1280} height={720}>
|
||||
<Window.Content>
|
||||
<Button icon="file" onClick={() => setModal('states')}>
|
||||
States
|
||||
</Button>
|
||||
{noStateYet ? (
|
||||
<Flex
|
||||
width="100%"
|
||||
height="100%"
|
||||
align="center"
|
||||
justify="space-around">
|
||||
<h1>Please select or create a lua state to get started.</h1>
|
||||
</Flex>
|
||||
) : (
|
||||
<Stack height="calc(100% - 16px)">
|
||||
<Stack.Item grow shrink basis="55%">
|
||||
<Section
|
||||
fill
|
||||
pb="16px"
|
||||
title="Input"
|
||||
buttons={
|
||||
<>
|
||||
<Button.File
|
||||
onSelectFiles={(file) =>
|
||||
this.setState({ scriptInput: file })
|
||||
}
|
||||
accept=".lua,.luau">
|
||||
Import
|
||||
</Button.File>
|
||||
<Button onClick={() => setModal('documentation')}>
|
||||
Help
|
||||
</Button>
|
||||
</>
|
||||
}>
|
||||
<TextArea
|
||||
fluid
|
||||
width="100%"
|
||||
height="100%"
|
||||
value={scriptInput}
|
||||
fontFamily="Consolas"
|
||||
onInput={(_, value) =>
|
||||
this.setState({ scriptInput: value })
|
||||
}
|
||||
displayedValue={
|
||||
<Box
|
||||
style={{
|
||||
'pointer-events': 'none',
|
||||
}}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: hljs.highlight(scriptInput, {
|
||||
language: 'lua',
|
||||
}).value,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Button onClick={() => act('runCode', { code: scriptInput })}>
|
||||
Run
|
||||
</Button>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow shrink basis="45%">
|
||||
<Section
|
||||
fill
|
||||
pb="24px"
|
||||
height={
|
||||
activeTab === 'log'
|
||||
? showJumpToBottomButton
|
||||
? 'calc(100% - 48px)'
|
||||
: 'calc(100% - 32px)'
|
||||
: '100%'
|
||||
}
|
||||
/>
|
||||
<Button onClick={() => act('runCode', { code: input })}>
|
||||
Run
|
||||
</Button>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow shrink basis="45%">
|
||||
<Section fill pb="24px" height="100%" width="100%" buttons>
|
||||
<Stack justify="space-between">
|
||||
<Stack.Item>
|
||||
<Tabs>
|
||||
{!!showDebugInfo && (
|
||||
width="100%">
|
||||
<Stack justify="space-between">
|
||||
<Stack.Item>
|
||||
<Tabs>
|
||||
{!!showGlobalTable && (
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'globals'}
|
||||
onClick={() => {
|
||||
this.setState({ activeTab: 'globals' });
|
||||
}}>
|
||||
Globals
|
||||
</Tabs.Tab>
|
||||
)}
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'globals'}
|
||||
onClick={() => {
|
||||
setActiveTab('globals');
|
||||
}}>
|
||||
Globals
|
||||
selected={activeTab === 'tasks'}
|
||||
onClick={() => this.setState({ activeTab: 'tasks' })}>
|
||||
Tasks
|
||||
</Tabs.Tab>
|
||||
)}
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'tasks'}
|
||||
onClick={() => setActiveTab('tasks')}>
|
||||
Tasks
|
||||
</Tabs.Tab>
|
||||
{!!showDebugInfo && (
|
||||
<Tabs.Tab
|
||||
selected={activeTab === 'log'}
|
||||
onClick={() => {
|
||||
setActiveTab('log');
|
||||
this.setState({ activeTab: 'log' });
|
||||
setTimeout(this.handleSectionScroll, 0);
|
||||
}}>
|
||||
Log
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button.Checkbox
|
||||
inline
|
||||
checked={showGlobalTable}
|
||||
tooltip="WARNING: Displaying the global table can cause significant lag for the entire server, especially when there is a large number of global variables."
|
||||
onClick={() => {
|
||||
if (showGlobalTable && activeTab === 'globals') {
|
||||
this.setState({ activeTab: 'tasks' });
|
||||
}
|
||||
act('toggleShowGlobalTable');
|
||||
}}>
|
||||
Show Global Table
|
||||
</Button.Checkbox>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
<Section
|
||||
ref={this.sectionRef}
|
||||
fill
|
||||
scrollable
|
||||
scrollableHorizontal
|
||||
onScroll={this.handleSectionScroll}
|
||||
width="100%">
|
||||
{tabContent}
|
||||
</Section>
|
||||
{activeTab === 'log' && (
|
||||
<>
|
||||
<Stack justify="space-between">
|
||||
<Stack.Item width="25%">
|
||||
<Button
|
||||
width="100%"
|
||||
align="center"
|
||||
icon="arrow-left"
|
||||
disabled={page <= 0}
|
||||
onClick={() => {
|
||||
act('previousPage');
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{!!pageCount && (
|
||||
<Stack.Item width="50%">
|
||||
<ProgressBar
|
||||
width="100%"
|
||||
value={page / (pageCount - 1)}>
|
||||
<Box width="100%" align="center">
|
||||
{`Page ${page + 1}/${pageCount}`}
|
||||
</Box>
|
||||
</ProgressBar>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item width="25%">
|
||||
<Button
|
||||
width="100%"
|
||||
align="center"
|
||||
icon="arrow-right"
|
||||
disabled={page >= pageCount - 1}
|
||||
onClick={() => {
|
||||
act('nextPage');
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
{showJumpToBottomButton && (
|
||||
<Button
|
||||
width="100%"
|
||||
onClick={() => {
|
||||
const sectionCurrent = this.sectionRef.current;
|
||||
const scrollableCurrent =
|
||||
sectionCurrent.scrollableRef.current;
|
||||
scrollableCurrent.scrollTop =
|
||||
scrollableCurrent.scrollHeight;
|
||||
}}>
|
||||
Jump to Bottom
|
||||
</Button>
|
||||
)}
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button.Checkbox
|
||||
inline
|
||||
checked={showDebugInfo}
|
||||
tooltip="WARNING: Enabling debug info can cause significant lag for the entire server, especially when there is a large number of global variables."
|
||||
onClick={() => {
|
||||
if (showDebugInfo && activeTab !== 'tasks') {
|
||||
setActiveTab('tasks');
|
||||
}
|
||||
act('toggleShowDebugInfo');
|
||||
}}>
|
||||
Show Debug Info
|
||||
</Button.Checkbox>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
<Section fill scrollable scrollableHorizontal width="100%">
|
||||
{tabContent}
|
||||
</>
|
||||
)}
|
||||
</Section>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</Window.Content>
|
||||
{modal === 'states' && <StateSelectModal />}
|
||||
{modal === 'viewChunk' && <ChunkViewModal />}
|
||||
{modal === 'call' && <CallModal />}
|
||||
{modal === 'documentation' && (
|
||||
<Modal>
|
||||
<Button
|
||||
color="red"
|
||||
icon="window-close"
|
||||
onClick={() => {
|
||||
setModal(null);
|
||||
}}>
|
||||
Close
|
||||
</Button>
|
||||
<Section
|
||||
height={`${window.innerHeight * 0.8}px`}
|
||||
width={`${window.innerWidth * 0.5}px`}
|
||||
fill
|
||||
scrollable>
|
||||
<Box
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(sanitizeText(documentation), {
|
||||
breaks: true,
|
||||
smartypants: true,
|
||||
smartLists: true,
|
||||
langPrefix: 'hljs language-',
|
||||
highlight: (code) => {
|
||||
return hljs.highlight(code, { language: 'lua' }).value;
|
||||
},
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
</Modal>
|
||||
)}
|
||||
</Window.Content>
|
||||
{modal === 'states' && <StateSelectModal />}
|
||||
{modal === 'viewChunk' && <ChunkViewModal />}
|
||||
{modal === 'call' && <CallModal />}
|
||||
{modal === 'documentation' && (
|
||||
<Modal>
|
||||
<Button
|
||||
color="red"
|
||||
icon="window-close"
|
||||
onClick={() => {
|
||||
setModal(null);
|
||||
}}>
|
||||
Close
|
||||
</Button>
|
||||
<Section height="500px" width="700px" fill scrollable>
|
||||
<Box
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(sanitizeText(documentation), {
|
||||
breaks: true,
|
||||
smartypants: true,
|
||||
smartLists: true,
|
||||
langPrefix: 'hljs language-',
|
||||
highlight: (code) => {
|
||||
return hljs.highlight(code, { language: 'lua' }).value;
|
||||
},
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
</Modal>
|
||||
)}
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
</Window>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user