From c3547f189d865e62f280840b6fa62731485e477a Mon Sep 17 00:00:00 2001 From: gingervitis Date: Sat, 23 Jan 2021 20:16:01 -0800 Subject: [PATCH] edit social handles in modal, wip --- web/pages/components/config/constants.tsx | 7 +- .../config/social-icons-dropdown.tsx | 6 +- web/pages/config-social-links.tsx | 186 +++++++++++++++++- web/types/config-section.ts | 15 +- 4 files changed, 203 insertions(+), 11 deletions(-) diff --git a/web/pages/components/config/constants.tsx b/web/pages/components/config/constants.tsx index 1fc7d357b..51b6fd954 100644 --- a/web/pages/components/config/constants.tsx +++ b/web/pages/components/config/constants.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { CheckCircleFilled, ExclamationCircleFilled } from '@ant-design/icons'; import { fetchData, SERVER_CONFIG_UPDATE_URL } from '../../../utils/apis'; -import { ApiPostArgs, VideoVariant } from '../../../types/config-section'; +import { ApiPostArgs, VideoVariant, SocialHandle } from '../../../types/config-section'; export const DEFAULT_NAME = 'Owncast User'; export const DEFAULT_TITLE = 'Owncast Server'; @@ -234,3 +234,8 @@ export const DEFAULT_VARIANT_STATE:VideoVariant = { audioBitrate: 0, encoderPreset: 'veryfast', }; + +export const DEFAULT_SOCIAL_HANDLE:SocialHandle = { + url: '', + platform: '', +}; \ No newline at end of file diff --git a/web/pages/components/config/social-icons-dropdown.tsx b/web/pages/components/config/social-icons-dropdown.tsx index 1a4e8732a..8368a84ca 100644 --- a/web/pages/components/config/social-icons-dropdown.tsx +++ b/web/pages/components/config/social-icons-dropdown.tsx @@ -2,15 +2,15 @@ import React, { useState } from 'react'; import { PlusOutlined } from "@ant-design/icons"; import { Select, Divider, Input } from "antd"; import classNames from 'classnames'; -import { SocialHandleItem } from "../../../types/config-section"; +import { SocialHandleDropdownItem } from "../../../types/config-section"; import { NEXT_PUBLIC_API_HOST } from '../../../utils/apis'; interface DropdownProps { - iconList: SocialHandleItem[]; + iconList: SocialHandleDropdownItem[]; selectedOption?: string; } -interface DropdownOptionProps extends SocialHandleItem { +interface DropdownOptionProps extends SocialHandleDropdownItem { isSelected: boolean; } diff --git a/web/pages/config-social-links.tsx b/web/pages/config-social-links.tsx index 9cfb4999e..f4af7cde3 100644 --- a/web/pages/config-social-links.tsx +++ b/web/pages/config-social-links.tsx @@ -1,8 +1,12 @@ import React, { useState, useContext, useEffect } from 'react'; -import { Typography } from 'antd'; +import { Typography, Table, Button, Modal } from 'antd'; +import { ColumnsType } from 'antd/lib/table'; +import { DeleteOutlined } from '@ant-design/icons'; import SocialDropdown from './components/config/social-icons-dropdown'; -import { fetchData, SOCIAL_PLATFORMS_LIST } from '../utils/apis'; +import { fetchData, NEXT_PUBLIC_API_HOST, SOCIAL_PLATFORMS_LIST } from '../utils/apis'; import { ServerStatusContext } from '../utils/server-status-context'; +import { API_SOCIAL_HANDLES, postConfigUpdateToAPI, RESET_TIMEOUT, SUCCESS_STATES, DEFAULT_SOCIAL_HANDLE } from './components/config/constants'; +import { SocialHandle } from '../types/config-section'; const { Title } = Typography; @@ -13,12 +17,25 @@ export default function ConfigSocialLinks() { const [availableIconsList, setAvailableIconsList] = useState([]); const [currentSocialHandles, setCurrentSocialHandles] = useState([]); + const [displayModal, setDisplayModal] = useState(false); + const [modalProcessing, setModalProcessing] = useState(false); + const [editId, setEditId] = useState(0); + + // current data inside modal + const [modalDataState, setModalDataState] = useState(DEFAULT_SOCIAL_HANDLE); + + const [submitStatus, setSubmitStatus] = useState(null); + const [submitStatusMessage, setSubmitStatusMessage] = useState(''); + + const serverStatusData = useContext(ServerStatusContext); const { serverConfig, setFieldInConfigState } = serverStatusData || {}; const { instanceDetails } = serverConfig; const { socialHandles: initialSocialHandles } = instanceDetails; + let resetTimer = null; + const getAvailableIcons = async () => { try { const result = await fetchData(SOCIAL_PLATFORMS_LIST, { auth: false }); @@ -44,13 +61,176 @@ export default function ConfigSocialLinks() { }, [instanceDetails]); + const resetStates = () => { + setSubmitStatus(null); + setSubmitStatusMessage(''); + resetTimer = null; + clearTimeout(resetTimer); + } + + const handleModalCancel = () => { + setDisplayModal(false); + setEditId(-1); + } + + + // posts all the variants at once as an array obj + const postUpdateToAPI = async (postValue: any) => { + await postConfigUpdateToAPI({ + apiPath: API_SOCIAL_HANDLES, + data: { value: postValue }, + onSuccess: () => { + setFieldInConfigState({ fieldName: 'socialHandles', value: postValue, path: 'instancesDetails' }); + + // close modal + setModalProcessing(false); + handleModalCancel(); + + setSubmitStatus('success'); + setSubmitStatusMessage('Variants updated.'); + resetTimer = setTimeout(resetStates, RESET_TIMEOUT); + }, + onError: (message: string) => { + setSubmitStatus('error'); + setSubmitStatusMessage(message); + resetTimer = setTimeout(resetStates, RESET_TIMEOUT); + }, + }); + }; + + + // on Ok, send all of dataState to api + // show loading + // close modal when api is done + const handleModalOk = () => { + setModalProcessing(true); + + const postData = [ + ...currentSocialHandles, + ]; + if (editId === -1) { + postData.push(modalDataState); + } else { + postData.splice(editId, 1, modalDataState); + } + postUpdateToAPI(postData); + }; + + const handleDeleteVariant = index => { + const postData = [ + ...currentSocialHandles, + ]; + postData.splice(index, 1); + postUpdateToAPI(postData) + }; + + + const socialHandlesColumns: ColumnsType = [ + { + title: "#", + dataIndex: "key", + key: "key" + }, + { + title: "Platform", + dataIndex: "platform", + key: "platform", + render: (platform: string) => { + const platformInfo = availableIconsList[platform]; + if (!platformInfo) { + return platform; + } + const { icon, platform: platformName } = platformInfo; + return ( + <> + + + + {platformName} + + ); + }, + }, + + { + title: "Url to profile", + dataIndex: "url", + key: "url", + }, + { + title: '', + dataIndex: '', + key: 'edit', + render: (data, record, index) => { + return ( + + +