mirror of
https://github.com/owncast/owncast.git
synced 2024-11-25 22:31:09 +03:00
make toggle a separate component so we can display an outcome icon beside it
This commit is contained in:
parent
6cb8cee8b7
commit
310c6573d3
6 changed files with 133 additions and 70 deletions
|
@ -1,34 +1,18 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Table, Typography, Tooltip, Switch } from "antd";
|
||||
import { Table, Typography, Tooltip, Switch, Button, Result } from "antd";
|
||||
import { RowSelectionType } from "antd/es/table/interface";
|
||||
import { ColumnsType } from 'antd/es/table';
|
||||
import format from 'date-fns/format'
|
||||
|
||||
import {
|
||||
CHAT_HISTORY,
|
||||
UPDATE_CHAT_MESSGAE_VIZ,
|
||||
fetchData,
|
||||
} from "../utils/apis";
|
||||
import ToggleSwitch from './components/toggle';
|
||||
|
||||
import { CHAT_HISTORY, fetchData } from "../utils/apis";
|
||||
import { MessageType } from '../types/chat';
|
||||
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
interface Message {
|
||||
key: string;
|
||||
author: string;
|
||||
body: string;
|
||||
id: string;
|
||||
name: string;
|
||||
timestamp: string;
|
||||
type: string;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface MessageToggleProps {
|
||||
isVisible: boolean;
|
||||
message: Message;
|
||||
setMessage: (message: Message) => {},
|
||||
};
|
||||
|
||||
function createUserNameFilters(messages: Message[]) {
|
||||
function createUserNameFilters(messages: MessageType[]) {
|
||||
const filtered = messages.reduce((acc, curItem) => {
|
||||
const curAuthor = curItem.author;
|
||||
if (!acc.some(item => item.text === curAuthor)) {
|
||||
|
@ -52,38 +36,9 @@ function createUserNameFilters(messages: Message[]) {
|
|||
});
|
||||
}
|
||||
|
||||
function MessageToggle({ isVisible, message, setMessage }: MessageToggleProps) {
|
||||
const { id: messageId } = message;
|
||||
|
||||
const updateChatMessage = async () => {
|
||||
const result = await fetchData(UPDATE_CHAT_MESSGAE_VIZ, {
|
||||
auth: true,
|
||||
method: 'POST',
|
||||
data: {
|
||||
visible: !isVisible,
|
||||
id: messageId,
|
||||
},
|
||||
});
|
||||
|
||||
if (result.success && result.message === "changed") {
|
||||
setMessage({
|
||||
...message,
|
||||
visible: !isVisible,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Switch
|
||||
size="small"
|
||||
onChange={updateChatMessage}
|
||||
defaultChecked={isVisible}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Chat() {
|
||||
const [messages, setMessages] = useState([]);
|
||||
const [selectedRowKeys, setSelectedRows] = useState([]);
|
||||
|
||||
const getInfo = async () => {
|
||||
try {
|
||||
|
@ -96,6 +51,7 @@ export default function Chat() {
|
|||
|
||||
const updateMessage = message => {
|
||||
const messageIndex = messages.findIndex(m => m.id === message.id);
|
||||
console.log("====update?", message, messages[messageIndex])
|
||||
messages.splice(messageIndex, 1, message)
|
||||
setMessages([...messages]);
|
||||
};
|
||||
|
@ -105,17 +61,16 @@ export default function Chat() {
|
|||
}, []);
|
||||
|
||||
const nameFilters = createUserNameFilters(messages);
|
||||
const rowSelection = {
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||
|
||||
const rowSelection: RowSelectionType = {
|
||||
selectedRowKeys,
|
||||
onChange: selectedKeys => {
|
||||
setSelectedRows(selectedKeys);
|
||||
},
|
||||
getCheckboxProps: record => ({
|
||||
disabled: record.name === 'Disabled User', // Column configuration not to be checked
|
||||
name: record.name,
|
||||
}),
|
||||
};
|
||||
|
||||
const chatColumns: ColumnsType<Message> = [
|
||||
|
||||
const chatColumns: ColumnsType<MessageType> = [
|
||||
{
|
||||
title: 'Time',
|
||||
dataIndex: 'timestamp',
|
||||
|
@ -160,7 +115,7 @@ export default function Chat() {
|
|||
filters: [{ text: 'visible', value: true }, { text: 'hidden', value: false }],
|
||||
onFilter: (value, record) => record.visible === value,
|
||||
render: (visible, record) => (
|
||||
<MessageToggle
|
||||
<ToggleSwitch
|
||||
isVisible={visible}
|
||||
message={record}
|
||||
setMessage={updateMessage}
|
||||
|
@ -174,6 +129,16 @@ export default function Chat() {
|
|||
return (
|
||||
<div className="chat-messages">
|
||||
<Title level={2}>Chat Messages</Title>
|
||||
<p>click things and stuff</p>
|
||||
<Button
|
||||
type="primary"
|
||||
// onClick={}
|
||||
disabled={!selectedRowKeys.length}
|
||||
loading={false}
|
||||
>
|
||||
Bulk toggle
|
||||
</Button>
|
||||
<Switch />
|
||||
<Table
|
||||
size="small"
|
||||
className="messages-table"
|
||||
|
@ -183,12 +148,7 @@ export default function Chat() {
|
|||
dataSource={messages}
|
||||
columns={chatColumns}
|
||||
rowKey={(row) => row.id}
|
||||
|
||||
rowSelection={{
|
||||
type: "checkbox",
|
||||
...rowSelection,
|
||||
}}
|
||||
|
||||
rowSelection={rowSelection}
|
||||
/>
|
||||
</div>)
|
||||
}
|
||||
|
|
75
web/pages/components/toggle.tsx
Normal file
75
web/pages/components/toggle.tsx
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Wrapper for AntDesign Switch that makes an api call, then displays a confirmation icon upon
|
||||
// TODO: make it more generic, maybe. This one is currently just for message visiblity updates.
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Switch } from "antd";
|
||||
import { CheckCircleFilled, ExclamationCircleFilled } from "@ant-design/icons";
|
||||
import { fetchData, UPDATE_CHAT_MESSGAE_VIZ } from "../../utils/apis";
|
||||
import { MessageType } from '../../types/chat';
|
||||
|
||||
interface MessageToggleProps {
|
||||
isVisible: boolean;
|
||||
message: MessageType;
|
||||
setMessage: (message: MessageType) => {},
|
||||
};
|
||||
|
||||
const OUTCOME_TIMEOUT = 3000;
|
||||
|
||||
export default function ToggleSwitch({ isVisible, message, setMessage }: MessageToggleProps) {
|
||||
let outcomeTimeout = null;
|
||||
const [outcome, setOutcome] = useState(0);
|
||||
|
||||
const { id: messageId } = message;
|
||||
|
||||
const resetOutcome = () => {
|
||||
outcomeTimeout = setTimeout(() => { setOutcome(0)}, OUTCOME_TIMEOUT);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
clearTimeout(outcomeTimeout);
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
const updateChatMessage = async () => {
|
||||
clearTimeout(outcomeTimeout);
|
||||
setOutcome(0);
|
||||
const result = await fetchData(UPDATE_CHAT_MESSGAE_VIZ, {
|
||||
auth: true,
|
||||
method: 'POST',
|
||||
data: {
|
||||
visible: !isVisible,
|
||||
id: messageId,
|
||||
},
|
||||
});
|
||||
|
||||
if (result.success && result.message === "changed") {
|
||||
setMessage({ ...message, visible: !isVisible });
|
||||
setOutcome(1);
|
||||
} else {
|
||||
setMessage({ ...message, visible: isVisible });
|
||||
setOutcome(-1);
|
||||
}
|
||||
resetOutcome();
|
||||
}
|
||||
|
||||
|
||||
let outcomeIcon = <CheckCircleFilled style={{ color: 'transparent' }} />;
|
||||
if (outcome) {
|
||||
outcomeIcon = outcome > 0 ?
|
||||
<CheckCircleFilled style={{ color: 'var(--ant-success)' }} /> :
|
||||
<ExclamationCircleFilled style={{ color: 'var(--ant-warning)' }} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="toggle-switch">
|
||||
<span className="outcome-icon">{outcomeIcon}</span>
|
||||
<Switch
|
||||
size="small"
|
||||
onChange={updateChatMessage}
|
||||
checked={isVisible}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -17,4 +17,16 @@
|
|||
}
|
||||
.ant-table-filter-dropdown {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-end;
|
||||
|
||||
.outcome-icon {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
}
|
|
@ -3,4 +3,10 @@
|
|||
--owncast-purple-highlight: #ccd;
|
||||
|
||||
--online-color: #73dd3f;
|
||||
|
||||
|
||||
--ant-error: #ff4d4f;
|
||||
--ant-success: #52c41a;
|
||||
--ant-warning: #faad14;
|
||||
|
||||
}
|
||||
|
|
|
@ -41,4 +41,4 @@ pre {
|
|||
background-color: rgb(44, 44, 44);
|
||||
color:lightgrey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
web/types/chat.ts
Normal file
10
web/types/chat.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
export interface MessageType {
|
||||
author: string;
|
||||
body: string;
|
||||
id: string;
|
||||
key: string;
|
||||
name: string;
|
||||
timestamp: string;
|
||||
type: string;
|
||||
visible: boolean;
|
||||
}
|
Loading…
Reference in a new issue