Compare commits

..

No commits in common. "705b1f5e1242c4fb0e92d91f644a4adf915b44c6" and "b5a0d8bda291aa721e3ce72969242e5012a3f078" have entirely different histories.

8 changed files with 12845 additions and 3427 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,18 +25,3 @@
.App-menu { .App-menu {
max-width: 98%; max-width: 98%;
} }
.Footer {
max-width: 98%;
background-color: #6207a4 !important;
}
.Footer a {
color: white;
font-weight: bold;
}
.FooterCell {
border: none !important;
color: white !important;
}

View File

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import logo from './../../logo.svg'; import logo from './../../logo.svg';
import './App.css'; import './App.css';
import Container from '@material-ui/core/Container';
import Typography from '@material-ui/core/Typography'; import Typography from '@material-ui/core/Typography';
import { Button, Paper, Container, AppBar, Table, TableBody, TableCell, TableContainer, TableRow } from '@material-ui/core'; import { Button, Paper } from '@material-ui/core';
function App() { function App() {
const client_id = "sau3e70wvs369jw1u25ex8g3cve599" const client_id = "sau3e70wvs369jw1u25ex8g3cve599"
@ -43,22 +44,6 @@ function App() {
<Typography component="p" gutterBottom> <Typography component="p" gutterBottom>
...Coming "Soon"(tm) ...Coming "Soon"(tm)
</Typography> </Typography>
<AppBar position="static" className="Footer">
<TableContainer component={Container}>
<Table><TableBody>
<TableRow className="FooterRow">
<TableCell className="FooterCell"><a href="https://discord.gg/sVgZeRt">Discord</a></TableCell>
<TableCell className="FooterCell"><a href="https://git.martyn.berlin/martyn/twitchsingstools">Source Code</a></TableCell>
<TableCell className="FooterCell"><a href="https://twitch.tv/iMartynOnTwitch">Martyn's Twitch</a></TableCell>
</TableRow>
<TableRow className="FooterRow">
<TableCell className="FooterCell">Announcements, Support, Optional notifications</TableCell>
<TableCell className="FooterCell">Geek out at the really hacky source code from an SRE type person</TableCell>
<TableCell className="FooterCell">Streaming and singing is my hobby, not my job, so only if you want to...</TableCell>
</TableRow>
</TableBody></Table>
</TableContainer>
</AppBar>
</Paper> </Paper>
</Container> </Container>
); );

View File

@ -26,18 +26,3 @@
.App-menu { .App-menu {
max-width: 98%; max-width: 98%;
} }
.Footer {
max-width: 98%;
background-color: #6207a4 !important;
}
.Footer a {
color: white;
font-weight: bold;
}
.FooterCell {
border: none !important;
color: white !important;
}

View File

@ -7,8 +7,6 @@ import Typography from '@material-ui/core/Typography';
import TopTenSongs from "../TopTenSongs/TopTenSongs"; import TopTenSongs from "../TopTenSongs/TopTenSongs";
import TopTenSingers from "../TopTenSingers/TopTenSingers"; import TopTenSingers from "../TopTenSingers/TopTenSingers";
import DuetData from "../DuetData/DuetData"; import DuetData from "../DuetData/DuetData";
import CacheDeets from "../CacheDeets/CacheDeets";
import BotDeets from "../BotDeets/BotDeets";
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@material-ui/core'; import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@material-ui/core';
import ProblemContainer from "../ProblemContainer/ProblemContainer"; import ProblemContainer from "../ProblemContainer/ProblemContainer";
@ -42,68 +40,22 @@ function a11yProps(index) {
}; };
} }
class AppAdmin extends React.Component { function AppAdmin() {
constructor(props) { const [page, setPage] = React.useState(0);
super(props);
this.setPage = this.setPage.bind(this);
this.reloadSongComponent = this.reloadSongComponent.bind(this);
this.reloadSingersComponent = this.reloadSingersComponent.bind(this);
this.reloadDuetComponent = this.reloadDuetComponent.bind(this);
this.state = {
page: 0,
reloadSongComponent: false,
reloadSingersComponent: false,
reloadDuetComponent: false,
};
}
setPage(pageNum) {
let newState = this.state;
newState.page = pageNum;
this.setState(newState);
}
reloadSongComponent(components) {
let newState = this.state;
newState.reloadComponents = components;
this.setState(newState);
}
reloadSingersComponent(components) {
let newState = this.state;
newState.reloadComponents = components;
this.setState(newState);
}
reloadDuetComponent(components) {
let newState = this.state;
newState.reloadDuetComponent = components;
console.log("I'm trying!")
this.setState(newState);
}
render() {
const page = this.state.page
if ( if (
(window.location.href.split("/").length < 6) || (window.location.href.split("/").length < 6) ||
(window.location.href.split("/")[3].search(/^admin/) < 0) || (window.location.href.split("/")[3].search(/^admin/) < 0) ||
(window.location.href.split("/")[5].length !== 48) (window.location.href.split("/")[5].length !== 48)
) { ) {
if (window.location.href.split("/")[2] !== "192.168.1.111:3000") {
return ( return (
<ProblemContainer /> <ProblemContainer />
) )
} }
}
const channelName = window.location.href.split("/")[4] const channelName = window.location.href.split("/")[4]
const adminToken = window.location.href.split("/")[5] const adminToken = window.location.href.split("/")[5]
const csvURL = "/csv/"+ channelName + "/" + adminToken const csvURL = "/csv/"+ channelName + "/" + adminToken
const tsvURL = "/tsv/"+ channelName + "/" + adminToken const tsvURL = "/tsv/"+ channelName + "/" + adminToken
const setPage = this.setPage
const reloadDuetComponent = this.state.reloadDuetComponent
const reloadSongComponent = this.state.reloadSongComponent
const reloadSingersComponent = this.state.reloadSingersComponent
function handleChange(event, newValue) { function handleChange(event, newValue) {
setPage(newValue); setPage(newValue);
@ -122,21 +74,16 @@ class AppAdmin extends React.Component {
<Tab label="Top Singers" {...a11yProps(1)}/> <Tab label="Top Singers" {...a11yProps(1)}/>
<Tab label="Data" {...a11yProps(2)}/> <Tab label="Data" {...a11yProps(2)}/>
<Tab label="Export" {...a11yProps(3)}/> <Tab label="Export" {...a11yProps(3)}/>
<Tab label="Cache Details" {...a11yProps(4)}/>
<Tab label="Chatbot" {...a11yProps(4)}/>
</Tabs> </Tabs>
</AppBar> </AppBar>
<TabPanel value={page} index={0}> <TabPanel value={page} index={0}>
<TopTenSongs reloadSongComponent={reloadSongComponent} <TopTenSongs />
onReloadedChange={this.reloadSongComponent}/>
</TabPanel> </TabPanel>
<TabPanel value={page} index={1}> <TabPanel value={page} index={1}>
<TopTenSingers reloadSingersComponent={reloadSingersComponent} <TopTenSingers />
onReloadedChange={this.reloadSingersComponent}/>
</TabPanel> </TabPanel>
<TabPanel value={page} index={2}> <TabPanel value={page} index={2}>
<DuetData reloadDuetComponent={reloadDuetComponent} <DuetData />
onReloadedChange={this.reloadDuetComponent}/>
</TabPanel> </TabPanel>
<TabPanel value={page} index={3}> <TabPanel value={page} index={3}>
<Typography variant="h5" component="h2" gutterBottom> <Typography variant="h5" component="h2" gutterBottom>
@ -166,35 +113,9 @@ class AppAdmin extends React.Component {
<Typography component="p" gutterBottom>LibreOffice calc kinda just works...just sayin' ;-)</Typography> <Typography component="p" gutterBottom>LibreOffice calc kinda just works...just sayin' ;-)</Typography>
</TabPanel> </TabPanel>
<TabPanel value={page} index={4}>
<CacheDeets
onReloadSongsChange={this.reloadSongComponent}
onReloadSingersChange={this.reloadSingersComponent}
onReloadDuetChange={this.reloadDuetComponent}
/>
</TabPanel>
<TabPanel value={page} index={5}>
<BotDeets />
</TabPanel>
<AppBar position="static" className="Footer">
<TableContainer component={Container}>
<Table><TableBody>
<TableRow className="FooterRow">
<TableCell className="FooterCell"><a href="https://discord.gg/sVgZeRt">Discord</a></TableCell>
<TableCell className="FooterCell"><a href="https://git.martyn.berlin/martyn/twitchsingstools">Source Code</a></TableCell>
<TableCell className="FooterCell"><a href="https://twitch.tv/iMartynOnTwitch">Martyn's Twitch</a></TableCell>
</TableRow>
<TableRow className="FooterRow">
<TableCell className="FooterCell">Announcements, Support, Optional notifications</TableCell>
<TableCell className="FooterCell">Geek out at the really hacky source code from an SRE type person</TableCell>
<TableCell className="FooterCell">Streaming and singing is my hobby, not my job, so only if you want to...</TableCell>
</TableRow>
</TableBody></Table>
</TableContainer>
</AppBar>
</Paper> </Paper>
</Container> </Container>
); );
}
} }
export default AppAdmin; export default AppAdmin;

View File

@ -1,53 +0,0 @@
import React, { useEffect } from 'react';
import { Container, Typography, Button } from '@material-ui/core';
const channelName = window.location.href.split("/")[4]
const adminToken = window.location.href.split("/")[5]
const dataURL = "/botdeets/"+ channelName + "/" + adminToken
function BotDeets() {
const [botState, setBotState] = React.useState({loading: true, botData: []})
useEffect(() => {
// We should only fetch once!
if (botState.loading) {
fetch(dataURL).then((res) => res.json().then((data)=>{
setBotState({botData: data, loading: false })
}));
}
}, [setBotState, botState.loading]);
if (botState.loading) {
return <p>Sorry, still loading...</p>
}
let dd = botState.botData
if (dd.hasleft) {
return (
<Container>
<Typography variant="h5" component="h2" gutterBottom>
The chatbot is currently <b>not</b> in your channel. To change the settings, invite it to your channel using the button below :
</Typography>
<Typography variant="p">
You really don't wanna do that, because it's not ready yet.
</Typography>
<Typography variant="p">
<Button variant="contained" color="primary">Join my channel!</Button>
</Typography>
</Container>
)
} else {
return (
<Container>
<Typography variant="h5" component="h2" gutterBottom>
Coming soon! Bot control panel!
</Typography>
<Typography component="tt" gutterBottom>
{dd}
</Typography>
</Container>
);
}
}
export default BotDeets;

View File

@ -1,81 +0,0 @@
import React from 'react';
import { Container, Typography, Button } from '@material-ui/core';
const channelName = window.location.href.split("/")[4]
const adminToken = window.location.href.split("/")[5]
const dataURL = "/cachedeets/"+ channelName + "/" + adminToken
const forceURL = "/force/"+ channelName + "/" + adminToken
class CacheDeets extends React.Component {
constructor(props) {
super(props);
this.state = {
cacheData: [],
loading: true
};
this.setCacheData = this.setCacheData.bind(this);
this.setLoading = this.setLoading.bind(this);
}
setCacheData(data) {
let newState = this.state
newState.cacheData = data
this.setState(newState)
}
setLoading(data) {
let newState = this.state
newState.loading = data
this.setState(newState)
}
componentDidMount() {
// We should only fetch once!
if (this.state.loading) {
let actualURL = dataURL
if (window.location.href.split("/")[2] === "192.168.1.111:3000") {
//Frontend dev mode only
actualURL = "/sampleData/cache.json"
}
fetch(actualURL).then((res) => res.json().then((data)=>{
this.setLoading(false)
this.setCacheData(data)
}));
}
}
render() {
const loading = this.state.loading
const setLoading = this.setLoading
const cacheData = this.state.cacheData
function handleClick(e) {
setLoading(true)
fetch(forceURL).then((data)=>{
setLoading(false)
window.location.reload()
})
console.log('The link was clicked.');
}
if (loading) {
return <p>Sorry, still loading...</p>
}
let dd = cacheData
return (
<Container>
<Typography variant="h5" component="h2" gutterBottom>
Server has cached data from <b>{dd.SongCount} published</b> performances
</Typography>
<Typography component="p" gutterBottom>
Cache data is from about {dd.AgeStr} - it automatically gets updated if it's older than an hour. If you're convinced using Martyn's bandwidth to refresh the cache earlier than that is worth it, here's the button below :
</Typography>
<Button variant="contained" color="primary" onClick={handleClick}>Force refresh cache</Button>
</Container>
);
}
}
export default CacheDeets;