Skip to content

Commit

Permalink
added base code for future end of stream report view
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusmcb committed Sep 25, 2024
1 parent 7b4d6b8 commit 424231e
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 29 deletions.
45 changes: 29 additions & 16 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,24 @@ import CredentialsPanel from './components/CredentialsPanel'
import PreferencesPanel from './components/PreferencesPanel'
import SessionPanel from './components/SessionPanel'
import MessagePanel from './components/MessagePanel'
import { ReportData } from './types'
import './App.css'

const App = (): JSX.Element => {

/* INTERFACE VALUES */

interface BotProcessResponse {
success: boolean
message?: any
error?: string
}

interface AuthSuccess {
_id: string
twitchRefreshToken: string
}

/* STATE VALUES */

const [formData, setFormData] = useState({
Expand Down Expand Up @@ -35,21 +50,12 @@ const App = (): JSX.Element => {
const [isConnectionReady, setIsConnectionReady] = useState(false)
const [messageQueue, setMessageQueue] = useState<string[]>([])
const [currentMessage, setCurrentMessage] = useState<string | null>(null)
const [reportData, setReportData] = useState<ReportData | null>(null);
const [isReportOpen, setIsReportOpen] = useState(false);
const messageTimeoutRef = useRef<NodeJS.Timeout | null>(null)
const ipcRenderer = window.electron.ipcRenderer

/* INTERFACE VALUES */

interface BotProcessResponse {
success: boolean
message?: any
error?: string
}

interface AuthSuccess {
_id: string
twitchRefreshToken: string
}


/* EFFECT HOOKS */

Expand Down Expand Up @@ -234,9 +240,14 @@ const App = (): JSX.Element => {
event: React.MouseEvent<HTMLButtonElement>
) => {
console.log('*** npChatbot disconnect event ***')
ipcRenderer.send('stopBotScript', { seratoDisplayName: formData.seratoDisplayName })
ipcRenderer.send('stopBotScript', {
seratoDisplayName: formData.seratoDisplayName,
})
ipcRenderer.once('stopBotResponse', (response) => {
if (response && response.success) {
console.log('Final Report Data: ', response.data)
setReportData(response.data as ReportData);
// setIsReportOpen(true);
addMessageToQueue('npChatbot has been disconnected')
setIsBotConnected(false)
} else if (response && response.error) {
Expand All @@ -256,7 +267,7 @@ const App = (): JSX.Element => {

// handle user credentials and preferences submission
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
setError("")
setError('')
event.preventDefault()
console.log('--- Form Data Submitted ---')
console.log(formData)
Expand Down Expand Up @@ -304,10 +315,10 @@ const App = (): JSX.Element => {
setIsConnectionReady(true)
} else if (response && response.error) {
console.log('Update error: ', response.error)
setCurrentMessage("")
setCurrentMessage('')
setError(response.error)
setTimeout(() => {
setError("")
setError('')
}, 5000)
} else {
console.log('Unexpected response when updating preferences')
Expand Down Expand Up @@ -357,6 +368,8 @@ const App = (): JSX.Element => {
isBotConnected={isBotConnected}
isAuthorized={isAuthorized}
isConnectionReady={isConnectionReady}
reportData={reportData || {} as ReportData}
isReportOpen={isReportOpen}
/>
</div>
</div>
Expand Down
24 changes: 24 additions & 0 deletions client/src/components/ReportViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// src/components/ReportViewer.js
import React from 'react';
import { ReportData } from '../types';

interface ReportDataProps {
reportData: ReportData | null
}

const ReportViewer: React.FC<ReportDataProps> = ({ reportData }): JSX.Element => {
if (!reportData) return <p>No report data available</p>;
console.log("Report Data: ", reportData);
return (
<div style={{ padding: '20px' }}>
<h1>npChatbot Final Report</h1>
<div className="report-section">
<h2>Report Summary</h2>
<p>{reportData.dj_name || 'Summary not available'}</p>
</div>
{/* Add more sections with styled data from the report */}
</div>
);
};

export default ReportViewer;
73 changes: 69 additions & 4 deletions client/src/components/SessionPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
import { ReportData } from '../types'
import ReportViewer from './ReportViewer'
import '../App.css'

// add logic to handle any errors returned
Expand All @@ -14,7 +17,49 @@ interface SessionPanelProps {
handleDisconnect: (event: React.MouseEvent<HTMLButtonElement>) => void
isBotConnected: boolean
isAuthorized: boolean
isConnectionReady: boolean
isConnectionReady: boolean
isReportOpen: boolean
reportData: ReportData | null

}

const openReportInNewWindow = (reportData: ReportData | null): void => {
// Open a new window
const reportWindow = window.open('', '_blank', 'width=800,height=600')

if (!reportWindow) {
console.error('Failed to open new window.')
return
}

// Write the initial HTML structure for the new window
reportWindow.document.write(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>npChatbot Final Report</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
`)

// Wait for the window to load its content before rendering
reportWindow.onload = () => {
if (reportWindow.document.getElementById('root')) {
// Render the ReportViewer component into the new window's DOM
ReactDOM.render(
<React.StrictMode>
<ReportViewer reportData={reportData} />
</React.StrictMode>,
reportWindow.document.getElementById('root')
)
}
}
}

const SessionPanel: React.FC<SessionPanelProps> = (props) => {
Expand All @@ -28,6 +73,12 @@ const SessionPanel: React.FC<SessionPanelProps> = (props) => {
setSeconds(0)
}

useEffect(() => {
if (props.isReportOpen && props.reportData) {
openReportInNewWindow(props.reportData)
}
}, [props.isReportOpen, props.reportData])

useEffect(() => {
let interval: NodeJS.Timeout

Expand Down Expand Up @@ -65,21 +116,35 @@ const SessionPanel: React.FC<SessionPanelProps> = (props) => {
className='bot-control-button'
type='submit'
onClick={props.handleConnect}
disabled={props.isBotConnected || !props.isAuthorized || !props.isConnectionReady}
disabled={
props.isBotConnected ||
!props.isAuthorized ||
!props.isConnectionReady
}
>
{!props.isBotConnected ? 'Connect' : 'Connected'}
</button>
<button
className='bot-control-button'
disabled={!props.isBotConnected}
type='submit'
onClick={(event) => {
resetUptime()
onClick={(event) => {
props.handleDisconnect(event)
resetUptime()
}}
>
End Session
</button>
{/* {props.isReportOpen && (
<button
className='bot-control-button'
onClick={() => {
openReportInNewWindow(props.reportData)
}}
>
Report
</button>
)} */}
</div>
<div className='app-form-title session-info'>Session Info:</div>
<div className='session-info-label'>
Expand Down
20 changes: 20 additions & 0 deletions client/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// src/types.ts
export interface ReportData {
dj_name: string;
set_start_time: string;
playlist_date: string;
set_length: string;
set_length_hours: number;
set_length_minutes: number;
set_length_seconds: number;
average_track_length: string;
shortest_track_name: string;
shortest_track_length: string;
shortest_track_minutes: number;
shortest_track_seconds: number;
longest_track_name: string;
longest_track_length: string;
longest_track_minutes: number;
longest_track_seconds: number;
total_tracks_played: number;
}
35 changes: 28 additions & 7 deletions electron-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,34 @@ ipcMain.on('startBotScript', async (event, arg) => {

// ipc method to disconnect npChatbot script from Twitch
ipcMain.on('stopBotScript', async (event, arg) => {
// const seratoDisplayName = arg.seratoDisplayName.replaceAll(' ', '_')
// const url = `https://serato.com/playlists/${seratoDisplayName}/7-21-2024`
// console.log('URL: ', url)
// const reportData = await createLiveReport(url)
const seratoDisplayName = arg.seratoDisplayName.replaceAll(' ', '_')
const url = `https://serato.com/playlists/${seratoDisplayName}/7-21-2024`
console.log('URL: ', url)
const reportData = await createLiveReport(url)

if (reportData !== undefined) {
console.log('FINAL REPORT DATA: ', reportData)
}

// if (reportData !== undefined) {
// console.log('FINAL REPORT DATA: ', reportData)
// }
const finalReportData = {
dj_name: reportData.dj_name,
set_start_time: reportData.set_start_time,
playlist_date: reportData.playlist_date,
set_length: reportData.set_length.length_value,
set_length_hours: reportData.set_length.hours,
set_length_minutes: reportData.set_length.minutes,
set_length_seconds: reportData.set_length.seconds,
average_track_length: reportData.average_track_length,
shortest_track_name: reportData.shortest_track.name,
shortest_track_length: reportData.shortest_track.length_value,
shortest_track_minutes: reportData.shortest_track.minutes,
shortest_track_seconds: reportData.shortest_track.seconds,
longest_track_name: reportData.longest_track.name,
longest_track_length: reportData.longest_track.length_value,
longest_track_minutes: reportData.longest_track.minutes,
longest_track_seconds: reportData.longest_track.seconds,
total_tracks_played: reportData.total_tracks_played,
}

if (tmiInstance) {
tmiInstance.disconnect()
Expand All @@ -276,6 +296,7 @@ ipcMain.on('stopBotScript', async (event, arg) => {
event.reply('stopBotResponse', {
success: true,
message: 'ipcMain: bot client successfully disconnected',
data: finalReportData,
})
} else {
event.reply('stopBotResponse', {
Expand Down
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const initializeBot = async (config) => {
const displayOBSMessage = config.isObsResponseEnabled
const seratoDisplayName = config.seratoDisplayName.replaceAll(" ", "_")

const url = `https://serato.com/playlists/${seratoDisplayName}/live`
// const url = `https://serato.com/playlists/${seratoDisplayName}/live`

// const url = `https://serato.com/playlists/${seratoDisplayName}/9-9-2024`

Expand All @@ -35,7 +35,7 @@ const initializeBot = async (config) => {
// const url = `https://serato.com/playlists/${seratoDisplayName}/6-17-2024_1`

/* 2 hour playlist examples */
// const url = `https://serato.com/playlists/${seratoDisplayName}/7-21-2024`
const url = `https://serato.com/playlists/${seratoDisplayName}/7-21-2024`
// const url = `https://serato.com/playlists/${seratoDisplayName}/7-5-2024_1`

/* 3 hour playlist examples */
Expand Down

0 comments on commit 424231e

Please sign in to comment.