Results and style refactor

trunk
HeNine 2 years ago
parent 8ef95dd40e
commit e7dd50af70

@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Escher Desert Bus Search Engine</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

@ -1,56 +0,0 @@
{
"timespan": {
"start_time": "2021-11-16T10:11:12",
"start_bus_time": "101:11:12",
"end_time": "2021-11-16T10:11:13",
"end_bus_time": "101:11:13"
},
"transcript": [
{
"id": 1,
"start_time": "2021-11-16T10:11:12",
"start_bus_time": "101:11:12",
"end_time": "2021-11-16T10:11:13",
"end_bus_time": "101:11:13",
"verifier": null,
"speakers": null,
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
}
],
"video": "https://www.youtube.com/watch?v=_joyWwiR7hc",
"chat": [
{
"sender": "thorsokar",
"tags": {
"turbo": "0",
"tmi-sent-ts": "1637151090414",
"color": "#FF0000",
"room-id": "24856654",
"emotes": "",
"subscriber": "0",
"first-msg": "0",
"badge-info": "",
"user-type": "",
"flags": "",
"display-name": "ThorSokar",
"user-id": "51499685",
"id": "aacd022e-c4ad-4bfb-9163-48da3f039d52",
"badges": "",
"mod": "0"
},
"receivers": {
"1d71e65d0054": 1637151090.610583,
"9e9eeb5cc336": 1637151090.555941
},
"time_range": 0,
"host": "thorsokar.tmi.twitch.tv",
"params": [
"#desertbus",
"let me tell you, I would remember this happening before"
],
"user": "thorsokar",
"time": 1637151090.414,
"command": "PRIVMSG"
}
]
}

@ -0,0 +1,157 @@
[
{
"timespan": {
"start_time": "2021-11-16T10:11:12",
"start_bus_time": "101:11:12",
"end_time": "2021-11-16T10:11:13",
"end_bus_time": "101:11:13"
},
"transcript": [
{
"id": 1,
"start_time": "2021-11-16T10:11:12",
"start_bus_time": "101:11:12",
"end_time": "2021-11-16T10:11:13",
"end_bus_time": "101:11:13",
"verifier": null,
"speakers": null,
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
},
{
"id": 2,
"start_time": "2021-11-16T10:11:12",
"start_bus_time": "101:11:12",
"end_time": "2021-11-16T10:11:13",
"end_bus_time": "101:11:13",
"verifier": null,
"speakers": ["Graham", "James"],
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
}
],
"video": "https://youtu.be/k-OMEk7UUvM",
"chat": [
{
"sender": "thorsokar",
"tags": {
"turbo": "0",
"tmi-sent-ts": "1637151090414",
"color": "#FF0000",
"room-id": "24856654",
"emotes": "",
"subscriber": "0",
"first-msg": "0",
"badge-info": "",
"user-type": "",
"flags": "",
"display-name": "ThorSokar",
"user-id": "51499685",
"id": "aacd022e-c4ad-4bfb-9163-48da3f039d52",
"badges": "",
"mod": "0"
},
"receivers": {
"1d71e65d0054": 1637151090.610583,
"9e9eeb5cc336": 1637151090.555941
},
"time_range": 0,
"host": "thorsokar.tmi.twitch.tv",
"params": [
"#desertbus",
"let me tell you, I would remember this happening before"
],
"user": "thorsokar",
"time": 1637151090.414,
"command": "PRIVMSG"
},
{
"sender": "thorsokar",
"tags": {
"turbo": "0",
"tmi-sent-ts": "1637151090414",
"color": "#FF0000",
"room-id": "24856654",
"emotes": "",
"subscriber": "0",
"first-msg": "0",
"badge-info": "",
"user-type": "",
"flags": "",
"display-name": "ThorSokar",
"user-id": "51499685",
"id": "aacd022e-c4ad-4bfb-9163-48da3f039d52",
"badges": "",
"mod": "0"
},
"receivers": {
"1d71e65d0054": 1637151090.610583,
"9e9eeb5cc336": 1637151090.555941
},
"time_range": 0,
"host": "thorsokar.tmi.twitch.tv",
"params": [
"#desertbus",
"let me tell you, I would remember this happening before"
],
"user": "thorsokar",
"time": 1637151090.414,
"command": "PRIVMSG"
}
]
},
{
"timespan": {
"start_time": "2021-11-16T10:11:15",
"start_bus_time": "101:11:15",
"end_time": "2021-11-16T10:11:16",
"end_bus_time": "101:11:16"
},
"transcript": [
{
"id": 1,
"start_time": "2021-11-16T10:11:12",
"start_bus_time": "101:11:12",
"end_time": "2021-11-16T10:11:13",
"end_bus_time": "101:11:13",
"verifier": null,
"speakers": null,
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
}
],
"video": "https://youtu.be/k-OMEk7UUvM",
"chat": [
{
"sender": "thorsokar",
"tags": {
"turbo": "0",
"tmi-sent-ts": "1637151090414",
"color": "#FF0000",
"room-id": "24856654",
"emotes": "",
"subscriber": "0",
"first-msg": "0",
"badge-info": "",
"user-type": "",
"flags": "",
"display-name": "ThorSokar",
"user-id": "51499685",
"id": "aacd022e-c4ad-4bfb-9163-48da3f039d52",
"badges": "",
"mod": "0"
},
"receivers": {
"1d71e65d0054": 1637151090.610583,
"9e9eeb5cc336": 1637151090.555941
},
"time_range": 0,
"host": "thorsokar.tmi.twitch.tv",
"params": [
"#desertbus",
"let me tell you, I would remember this happening before"
],
"user": "thorsokar",
"time": 1637151090.414,
"command": "PRIVMSG"
}
]
}
]

@ -1,5 +1,6 @@
import React from 'react';
import TimeGrid from './TimeGrid';
import Results from './Results'
import './App.scss';
function App() {
@ -8,6 +9,7 @@ function App() {
<h1>Escher</h1>
<SearchToolbox />
<TimeGrid />
<Results />
</div>
);
}

@ -21,85 +21,3 @@ h1 {
#searchToolbox {
margin-top: 1em;
}
#timeGrid {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
width: 100%;
padding: 1em;
box-sizing: border-box;
.day_histogram {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-end;
width: 100%;
margin: 3px;
background-color: constants.$medium_gray;
.info {
flex-direction: column;
box-sizing: border-box;
padding: 0.5em;
margin: 2px;
.day_date {
font-family: constants.$monospace;
font-size: small;
}
}
.shift_histogram {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-end;
// box-sizing: border-box;
flex-grow: 1;
align-self: stretch;
margin: 3px;
border-bottom: 1px solid aliceblue;
.histogram_bar {
box-sizing: content-box;
flex-grow: 1;
$border: 1px solid;
// border-left: $border;
border-top: $border;
// border-right: $border;
}
.histogram_bar.zeta_shift {
background-color: constants.$zeta_shift_purple;
border-color: constants.$zeta_shift_pink;
}
.histogram_bar.dawn_guard {
background-color: constants.$dawn_guard_orange;
border-color: constants.$dawn_guard_yellow;
}
.histogram_bar.alpha_flight {
background-color: constants.$alpha_flight_dark_red;
border-color: constants.$alpha_flight_red;
}
.histogram_bar.night_watch {
background-color: constants.$night_watch_blue;
border-color: constants.$night_watch_light_blue;
}
}
}
}

@ -0,0 +1,134 @@
import React from 'react';
import './Results.scss'
export default class Results extends React.Component {
constructor(props) {
super(props);
this.state = {
results: null
}
}
componentDidMount() {
fetch("/mock/results.json")
.then(res => res.json())
.then(
(result) => {
this.setState({
results: result
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
error
});
}
)
}
render() {
if (this.state.results === null) {
return (
<div id='results'>
Loading...
</div>
)
}
return (
<div id='results'>
{
this.state.results.map((result) => <Result key={`${result.timespan.start_bus_time}to${result.timespan.end_bus_time}`} {...result} />)
}
</div>
)
}
}
function Result(props) {
return (
<div className='result'>
<div className='info'>
<div className='bus_time_span'>
{props.timespan.start_bus_time} {props.timespan.end_bus_time}
</div>
<div className='time_span'>
{props.timespan.start_time} {props.timespan.end_time}
</div>
</div>
<div className='result_content'>
<Transcript transcript={props.transcript} />
<Video video={props.video} />
<Chat chat={props.chat} />
</div>
</div>
)
}
/*
* Transcript
*/
function Transcript(props) {
return (
<div className='transcript'>
{props.transcript.map((line) => <TranscriptLine key={line.id} line={line} />)}
</div>
)
}
function TranscriptLine(props) {
return (
<div className='transcript_line'>
{/* <div className="transcript_line_start_bus_time">{props.line.start_bus_time}</div> */}
<div className="transcript_line_speakers">{props.line.speakers == null ? <br /> : props.line.speakers.join(", ")}</div>
{/* <div className="transcript_line_start_time">{props.line.start_time}</div> */}
<div className="transcript_line_text">{props.line.text}</div>
</div>
)
}
/*
* Video
*/
function Video(props) {
const video_id = props.video.split("/").at(-1);
const width = 300;
return (
<div className='video'>
<iframe width={width} height={Math.round(width / 16 * 9)} src={`https://www.youtube.com/embed/${video_id}`} title="YouTube video player"
frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen></iframe>
</div>
)
}
/*
* Chat
*/
function Chat(props) {
return (
<div className='chat'>
{
props.chat.map((line) => <ChatLine key={line.tags.id} {...line} />)
}
</div>
)
}
function ChatLine(props) {
return (
<div className='chat_line'>
<span className='chat_line_user'>{props.tags["display-name"]}: </span>
<span className='chat_line_text'>{props.params[1]}</span>
</div>
)
}

@ -0,0 +1,95 @@
@use 'constants';
#results {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
width: 100%;
padding: 0.5em;
box-sizing: border-box;
.result {
width: 100%;
.info {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0.25em 0.5em;
margin: 3px 0px;
background-color: constants.$medium_gray;
.time_span {
font-family: constants.$monospace;
font-size: small;
}
}
.result_content {
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
padding: 0.25em 0.5em;
margin: 3px 0px;
background-color: constants.$medium_gray;
.transcript {
flex-grow: 1;
flex-shrink: 4;
max-width: 5.5in;
flex-basis: 2in;
padding: 0.25em 0.5em;
margin: 3px;
background-color: constants.$dark_gray;
.transcript_line_speakers {
font-weight: bold;
font-size: small;
margin: 0.75em 0em 0.25em 0em;
}
.transcript_line {
text-align: justify;
hyphens: auto;
}
}
.video {
flex-grow: 0;
flex-shrink: 0;
margin: 3px;
}
.chat {
flex-grow: 1;
flex-shrink: 1;
max-width: 5.5in;
flex-basis: 2in;
padding: 0.25em 0.5em;
margin: 3px;
background-color: constants.$dark_gray;
.chat_line {
margin: 0.25em 0em 0.5em 0em;
}
.chat_line_user {
font-weight: bold;
text-align: right;
}
}
}
}
}

@ -1,4 +1,5 @@
import React from 'react';
import './TimeGrid.scss';
export default class TimeGrid extends React.Component {

@ -0,0 +1,80 @@
@use 'constants';
#timeGrid {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
width: 100%;
padding: 0.25em 0.5em;
box-sizing: border-box;
.day_histogram {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-end;
width: 100%;
margin: 3px;
background-color: constants.$medium_gray;
.info {
flex-direction: column;
box-sizing: border-box;
padding: 0.25em 0.5em;
margin: 2px;
.day_date {
font-family: constants.$monospace;
font-size: small;
}
}
.shift_histogram {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-end;
flex-grow: 1;
align-self: stretch;
margin: 3px;
border-bottom: 1px solid aliceblue;
.histogram_bar {
box-sizing: content-box;
flex-grow: 1;
$border: 1px solid;
border-top: $border;
}
.histogram_bar.zeta_shift {
background-color: constants.$zeta_shift_purple;
border-color: constants.$zeta_shift_pink;
}
.histogram_bar.dawn_guard {
background-color: constants.$dawn_guard_orange;
border-color: constants.$dawn_guard_yellow;
}
.histogram_bar.alpha_flight {
background-color: constants.$alpha_flight_dark_red;
border-color: constants.$alpha_flight_red;
}
.histogram_bar.night_watch {
background-color: constants.$night_watch_blue;
border-color: constants.$night_watch_light_blue;
}
}
}
}
Loading…
Cancel
Save