mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
[MIRROR] tgchat part 1 (#7273)
Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com> Co-authored-by: Selis <selis@xynolabs.com>
This commit is contained in:
311
tgui/packages/tgui-panel/settings/SettingsPanel.js
Normal file
311
tgui/packages/tgui-panel/settings/SettingsPanel.js
Normal file
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* @file
|
||||
* @copyright 2020 Aleksej Komarov
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { toFixed } from 'common/math';
|
||||
import { useLocalState } from 'tgui_ch/backend'; // CHOMPEdit - tgui_ch
|
||||
import { useDispatch, useSelector } from 'common/redux';
|
||||
import { Box, Button, ColorBox, Divider, Dropdown, Flex, Input, LabeledList, NumberInput, Section, Stack, Tabs, TextArea } from 'tgui_ch/components'; // CHOMPEdit - tgui_ch
|
||||
import { ChatPageSettings } from '../chat';
|
||||
import { rebuildChat, saveChatToDisk } from '../chat/actions';
|
||||
import { THEMES } from '../themes';
|
||||
import { changeSettingsTab, updateSettings, addHighlightSetting, removeHighlightSetting, updateHighlightSetting } from './actions';
|
||||
import { SETTINGS_TABS, FONTS, MAX_HIGHLIGHT_SETTINGS } from './constants';
|
||||
import { selectActiveTab, selectSettings, selectHighlightSettings, selectHighlightSettingById } from './selectors';
|
||||
|
||||
export const SettingsPanel = (props, context) => {
|
||||
const activeTab = useSelector(context, selectActiveTab);
|
||||
const dispatch = useDispatch(context);
|
||||
return (
|
||||
<Stack fill>
|
||||
<Stack.Item>
|
||||
<Section fitted fill minHeight="8em">
|
||||
<Tabs vertical>
|
||||
{SETTINGS_TABS.map((tab) => (
|
||||
<Tabs.Tab
|
||||
key={tab.id}
|
||||
selected={tab.id === activeTab}
|
||||
onClick={() =>
|
||||
dispatch(
|
||||
changeSettingsTab({
|
||||
tabId: tab.id,
|
||||
})
|
||||
)
|
||||
}>
|
||||
{tab.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow={1} basis={0}>
|
||||
{activeTab === 'general' && <SettingsGeneral />}
|
||||
{activeTab === 'chatPage' && <ChatPageSettings />}
|
||||
{activeTab === 'textHighlight' && <TextHighlightSettings />}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export const SettingsGeneral = (props, context) => {
|
||||
const { theme, fontFamily, fontSize, lineHeight } = useSelector(
|
||||
context,
|
||||
selectSettings
|
||||
);
|
||||
const dispatch = useDispatch(context);
|
||||
const [freeFont, setFreeFont] = useLocalState(context, 'freeFont', false);
|
||||
return (
|
||||
<Section>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Theme">
|
||||
<Dropdown
|
||||
selected={theme}
|
||||
options={THEMES}
|
||||
onSelected={(value) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
theme: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Font style">
|
||||
<Stack inline align="baseline">
|
||||
<Stack.Item>
|
||||
{(!freeFont && (
|
||||
<Dropdown
|
||||
selected={fontFamily}
|
||||
options={FONTS}
|
||||
onSelected={(value) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
fontFamily: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
)) || (
|
||||
<Input
|
||||
value={fontFamily}
|
||||
onChange={(e, value) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
fontFamily: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
content="Custom font"
|
||||
icon={freeFont ? 'lock-open' : 'lock'}
|
||||
color={freeFont ? 'good' : 'bad'}
|
||||
ml={1}
|
||||
onClick={() => {
|
||||
setFreeFont(!freeFont);
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Font size">
|
||||
<NumberInput
|
||||
width="4em"
|
||||
step={1}
|
||||
stepPixelSize={10}
|
||||
minValue={8}
|
||||
maxValue={32}
|
||||
value={fontSize}
|
||||
unit="px"
|
||||
format={(value) => toFixed(value)}
|
||||
onChange={(e, value) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
fontSize: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Line height">
|
||||
<NumberInput
|
||||
width="4em"
|
||||
step={0.01}
|
||||
stepPixelSize={2}
|
||||
minValue={0.8}
|
||||
maxValue={5}
|
||||
value={lineHeight}
|
||||
format={(value) => toFixed(value, 2)}
|
||||
onDrag={(e, value) =>
|
||||
dispatch(
|
||||
updateSettings({
|
||||
lineHeight: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<Divider />
|
||||
<Button icon="save" onClick={() => dispatch(saveChatToDisk())}>
|
||||
Save chat log
|
||||
</Button>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const TextHighlightSettings = (props, context) => {
|
||||
const highlightSettings = useSelector(context, selectHighlightSettings);
|
||||
const dispatch = useDispatch(context);
|
||||
return (
|
||||
<Section fill scrollable height="200px">
|
||||
<Section p={0}>
|
||||
<Flex direction="column">
|
||||
{highlightSettings.map((id, i) => (
|
||||
<TextHighlightSetting
|
||||
key={i}
|
||||
id={id}
|
||||
mb={i + 1 === highlightSettings.length ? 0 : '10px'}
|
||||
/>
|
||||
))}
|
||||
{highlightSettings.length < MAX_HIGHLIGHT_SETTINGS && (
|
||||
<Flex.Item>
|
||||
<Button
|
||||
color="transparent"
|
||||
icon="plus"
|
||||
content="Add Highlight Setting"
|
||||
onClick={() => {
|
||||
dispatch(addHighlightSetting());
|
||||
}}
|
||||
/>
|
||||
</Flex.Item>
|
||||
)}
|
||||
</Flex>
|
||||
</Section>
|
||||
<Divider />
|
||||
<Box>
|
||||
<Button icon="check" onClick={() => dispatch(rebuildChat())}>
|
||||
Apply now
|
||||
</Button>
|
||||
<Box inline fontSize="0.9em" ml={1} color="label">
|
||||
Can freeze the chat for a while.
|
||||
</Box>
|
||||
</Box>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const TextHighlightSetting = (props, context) => {
|
||||
const { id, ...rest } = props;
|
||||
const highlightSettingById = useSelector(context, selectHighlightSettingById);
|
||||
const dispatch = useDispatch(context);
|
||||
const {
|
||||
highlightColor,
|
||||
highlightText,
|
||||
highlightWholeMessage,
|
||||
matchWord,
|
||||
matchCase,
|
||||
} = highlightSettingById[id];
|
||||
return (
|
||||
<Flex.Item {...rest}>
|
||||
<Flex mb={1} color="label" align="baseline">
|
||||
<Flex.Item grow>
|
||||
<Button
|
||||
content="Delete"
|
||||
color="transparent"
|
||||
icon="times"
|
||||
onClick={() =>
|
||||
dispatch(
|
||||
removeHighlightSetting({
|
||||
id: id,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
<Button.Checkbox
|
||||
checked={highlightWholeMessage}
|
||||
content="Whole Message"
|
||||
tooltip="If this option is selected, the entire message will be highlighted in yellow."
|
||||
mr="5px"
|
||||
onClick={() =>
|
||||
dispatch(
|
||||
updateHighlightSetting({
|
||||
id: id,
|
||||
highlightWholeMessage: !highlightWholeMessage,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
<Button.Checkbox
|
||||
content="Exact"
|
||||
checked={matchWord}
|
||||
tooltipPosition="bottom-start"
|
||||
tooltip="If this option is selected, only exact matches (no extra letters before or after) will trigger. Not compatible with punctuation. Overriden if regex is used."
|
||||
onClick={() =>
|
||||
dispatch(
|
||||
updateHighlightSetting({
|
||||
id: id,
|
||||
matchWord: !matchWord,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
<Button.Checkbox
|
||||
content="Case"
|
||||
tooltip="If this option is selected, the highlight will be case-sensitive."
|
||||
checked={matchCase}
|
||||
onClick={() =>
|
||||
dispatch(
|
||||
updateHighlightSetting({
|
||||
id: id,
|
||||
matchCase: !matchCase,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Flex.Item>
|
||||
<Flex.Item shrink={0}>
|
||||
<ColorBox mr={1} color={highlightColor} />
|
||||
<Input
|
||||
width="5em"
|
||||
monospace
|
||||
placeholder="#ffffff"
|
||||
value={highlightColor}
|
||||
onInput={(e, value) =>
|
||||
dispatch(
|
||||
updateHighlightSetting({
|
||||
id: id,
|
||||
highlightColor: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<TextArea
|
||||
height="3em"
|
||||
value={highlightText}
|
||||
placeholder="Put words to highlight here. Separate terms with commas, i.e. (term1, term2, term3)"
|
||||
onChange={(e, value) =>
|
||||
dispatch(
|
||||
updateHighlightSetting({
|
||||
id: id,
|
||||
highlightText: value,
|
||||
})
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Flex.Item>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user