[TGchat] Annihilation Dropdowns & Tweaks (#24502)

* New TGchat settings section

* New Chat Settings Tab & Reorder Tabs

* Annihilate dropdowns

* Normal Divider

* Max Total Messages 10000 -> 2000

* Remove removed things

* Rebuild
This commit is contained in:
Aylong
2024-03-20 22:01:20 +02:00
committed by GitHub
parent d02d54bfd4
commit 5dfc4e76ed
10 changed files with 429 additions and 300 deletions
@@ -13,7 +13,13 @@ import {
Section,
Stack,
} from 'tgui/components';
import { removeChatPage, toggleAcceptedType, updateChatPage } from './actions';
import {
moveChatPageLeft,
moveChatPageRight,
removeChatPage,
toggleAcceptedType,
updateChatPage,
} from './actions';
import { MESSAGE_TYPES } from './constants';
import { selectCurrentChatPage } from './selectors';
@@ -23,7 +29,22 @@ export const ChatPageSettings = (props, context) => {
return (
<Section fill>
<Stack align="center">
<Stack.Item grow>
{!page.isMain && (
<Stack.Item>
<Button
tooltip={'Reorder tab to the left'}
icon={'angle-left'}
onClick={() =>
dispatch(
moveChatPageLeft({
pageId: page.id,
})
)
}
/>
</Stack.Item>
)}
<Stack.Item grow ml={0.5}>
<Input
width="100%"
value={page.name}
@@ -37,6 +58,21 @@ export const ChatPageSettings = (props, context) => {
}
/>
</Stack.Item>
{!page.isMain && (
<Stack.Item ml={0.5}>
<Button
tooltip={'Reorder tab to the right'}
icon={'angle-right'}
onClick={() =>
dispatch(
moveChatPageRight({
pageId: page.id,
})
)
}
/>
</Stack.Item>
)}
<Stack.Item>
<Button.Checkbox
content="Mute"
@@ -58,6 +94,7 @@ export const ChatPageSettings = (props, context) => {
content="Remove"
icon="times"
color="red"
disabled={page.isMain}
onClick={() =>
dispatch(
removeChatPage({
+2
View File
@@ -20,3 +20,5 @@ export const toggleAcceptedType = createAction('chat/toggleAcceptedType');
export const removeChatPage = createAction('chat/removePage');
export const changeScrollTracking = createAction('chat/changeScrollTracking');
export const saveChatToDisk = createAction('chat/saveToDisk');
export const moveChatPageLeft = createAction('chat/movePageLeft');
export const moveChatPageRight = createAction('chat/movePageRight');
+5 -1
View File
@@ -20,6 +20,8 @@ import {
changeScrollTracking,
clearChat,
loadChat,
moveChatPageLeft,
moveChatPageRight,
rebuildChat,
toggleAcceptedType,
updateMessageCount,
@@ -152,7 +154,9 @@ export const chatMiddleware = (store) => {
type === changeChatPage.type ||
type === addChatPage.type ||
type === removeChatPage.type ||
type === toggleAcceptedType.type
type === toggleAcceptedType.type ||
type === moveChatPageLeft.type ||
type === moveChatPageRight.type
) {
next(action);
const page = selectCurrentChatPage(store.getState());
+3 -1
View File
@@ -18,8 +18,9 @@ export const createPage = (obj) => {
}
return {
id: createUuid(),
name: 'New Tab',
id: createUuid(),
isMain: false,
acceptedTypes: acceptedTypes,
unreadCount: 0,
hideUnreadCount: false,
@@ -35,6 +36,7 @@ export const createMainPage = () => {
}
return createPage({
name: 'Main',
isMain: true,
acceptedTypes,
});
};
+49
View File
@@ -13,6 +13,8 @@ import {
updateChatPage,
updateMessageCount,
changeScrollTracking,
moveChatPageLeft,
moveChatPageRight,
} from './actions';
import { canPageAcceptType, createMainPage } from './model';
@@ -188,5 +190,52 @@ export const chatReducer = (state = initialState, action) => {
}
return nextState;
}
if (type === moveChatPageLeft.type) {
const { pageId } = payload;
const nextState = {
...state,
pages: [...state.pages],
pageById: {
...state.pageById,
},
};
const tmpPage = nextState.pageById[pageId];
const fromIndex = nextState.pages.indexOf(tmpPage.id);
const toIndex = fromIndex - 1;
// don't ever move leftmost page
if (fromIndex > 0) {
// don't ever move anything to the leftmost page
if (toIndex > 0) {
const tmp = nextState.pages[fromIndex];
nextState.pages[fromIndex] = nextState.pages[toIndex];
nextState.pages[toIndex] = tmp;
}
}
return nextState;
}
if (type === moveChatPageRight.type) {
const { pageId } = payload;
const nextState = {
...state,
pages: [...state.pages],
pageById: {
...state.pageById,
},
};
const tmpPage = nextState.pageById[pageId];
const fromIndex = nextState.pages.indexOf(tmpPage.id);
const toIndex = fromIndex + 1;
// don't ever move leftmost page
if (fromIndex > 0) {
// don't ever move anything out of the array
if (toIndex < nextState.pages.length) {
const tmp = nextState.pages[fromIndex];
nextState.pages[fromIndex] = nextState.pages[toIndex];
nextState.pages[toIndex] = tmp;
}
}
return nextState;
}
return state;
};
+134 -107
View File
@@ -4,6 +4,7 @@
* @license MIT
*/
import { capitalize } from 'common/string';
import { toFixed } from 'common/math';
import { useLocalState } from 'tgui/backend';
import { useDispatch, useSelector } from 'common/redux';
@@ -12,7 +13,6 @@ import {
Button,
ColorBox,
Divider,
Dropdown,
Input,
LabeledList,
NumberInput,
@@ -20,6 +20,7 @@ import {
Stack,
Tabs,
TextArea,
Collapsible,
} from 'tgui/components';
import { ChatPageSettings } from '../chat';
import { clearChat, rebuildChat, saveChatToDisk } from '../chat/actions';
@@ -82,118 +83,144 @@ export const SettingsGeneral = (props, context) => {
const dispatch = useDispatch(context);
const [freeFont, setFreeFont] = useLocalState(context, 'freeFont', false);
return (
<Section height="150px">
<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">
<Section fill>
<Stack fill vertical>
<LabeledList>
<LabeledList.Item label="Theme">
{THEMES.map((THEME) => (
<Button
key={THEME}
content={capitalize(THEME)}
selected={theme === THEME}
color="transparent"
onClick={() =>
dispatch(
updateSettings({
theme: THEME,
})
)
}
/>
))}
</LabeledList.Item>
<LabeledList.Item label="Font style">
<Stack.Item>
{(!freeFont && (
<Dropdown
selected={fontFamily}
options={FONTS}
onSelected={(value) =>
dispatch(
updateSettings({
fontFamily: value,
})
)
<Collapsible
title={fontFamily}
width={'100%'}
buttons={
<Button
content="Custom font"
icon={freeFont ? 'lock-open' : 'lock'}
color={freeFont ? 'good' : 'bad'}
onClick={() => {
setFreeFont(!freeFont);
}}
/>
}
/>
>
{FONTS.map((FONT) => (
<Button
key={FONT}
content={FONT}
fontFamily={FONT}
selected={fontFamily === FONT}
color="transparent"
onClick={() =>
dispatch(
updateSettings({
fontFamily: FONT,
})
)
}
/>
))}
</Collapsible>
)) || (
<Input
value={fontFamily}
onChange={(e, value) =>
dispatch(
updateSettings({
fontFamily: value,
})
)
}
/>
<Stack>
<Input
width={'100%'}
value={fontFamily}
onChange={(e, value) =>
dispatch(
updateSettings({
fontFamily: value,
})
)
}
/>
<Button
ml={0.5}
content="Custom font"
icon={freeFont ? 'lock-open' : 'lock'}
color={freeFont ? 'good' : 'bad'}
onClick={() => {
setFreeFont(!freeFont);
}}
/>
</Stack>
)}
</Stack.Item>
<Stack.Item>
<Button
content="Custom font"
icon={freeFont ? 'lock-open' : 'lock'}
color={freeFont ? 'good' : 'bad'}
onClick={() => {
setFreeFont(!freeFont);
}}
/>
</Stack.Item>
</Stack>
</LabeledList.Item>
<LabeledList.Item label="Font size">
<NumberInput
width="4.2em"
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="4.2em"
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 />
<Stack fill>
<Stack.Item grow mt={0.15}>
<Button
content="Save chat log"
icon="save"
tooltip="Export current tab history into HTML file"
onClick={() => dispatch(saveChatToDisk())}
/>
</Stack.Item>
<Stack.Item mt={0.15}>
<Button.Confirm
icon="trash"
confirmContent="Are you sure?"
content="Clear chat"
tooltip="Erase current tab history"
onClick={() => dispatch(clearChat())}
/>
</Stack.Item>
</LabeledList.Item>
<LabeledList.Item label="Font size">
<NumberInput
width="4.2em"
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="4.2em"
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 />
<Stack>
<Stack.Item grow>
<Button
content="Save chat log"
icon="save"
tooltip="Export current tab history into HTML file"
onClick={() => dispatch(saveChatToDisk())}
/>
</Stack.Item>
<Stack.Item>
<Button.Confirm
icon="trash"
confirmContent="Are you sure?"
content="Clear chat"
tooltip="Erase current tab history"
onClick={() => dispatch(clearChat())}
/>
</Stack.Item>
</Stack>
</Stack>
</Section>
);
@@ -9,7 +9,6 @@ export const SETTINGS_TABS = [
id: 'general',
name: 'General',
},
{
id: 'textHighlight',
name: 'Text Highlights',
+10 -1
View File
@@ -8,6 +8,7 @@ import { BooleanLike, classes, pureComponentHooks } from 'common/react';
import { InfernoNode } from 'inferno';
import { Box, unit } from './Box';
import { Divider } from './Divider';
import { Tooltip } from './Tooltip';
type LabeledListProps = {
children: InfernoNode;
@@ -27,6 +28,7 @@ type LabeledListItemProps = {
color?: string | BooleanLike;
textAlign?: string | BooleanLike;
buttons?: InfernoNode;
tooltip?: string | BooleanLike;
/** @deprecated */
content?: any;
children?: InfernoNode;
@@ -40,10 +42,11 @@ const LabeledListItem = (props: LabeledListItemProps) => {
color,
textAlign,
buttons,
tooltip,
content,
children,
} = props;
return (
let listItem = (
<tr className={classes(['LabeledList__row', className])}>
<Box
as="td"
@@ -67,6 +70,12 @@ const LabeledListItem = (props: LabeledListItemProps) => {
)}
</tr>
);
if (tooltip) {
listItem = <Tooltip content={tooltip}>{listItem}</Tooltip>;
}
return listItem;
};
LabeledListItem.defaultHooks = pureComponentHooks;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long