Skip to content

Commit

Permalink
Basic schedule ticker.
Browse files Browse the repository at this point in the history
It doesn't animate or anything, but the idea is there.
  • Loading branch information
faultyserver committed Nov 13, 2018
0 parents commit 28997aa
Show file tree
Hide file tree
Showing 12 changed files with 6,689 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.cache/
dist/
node_modules/
yarn-error.log
26 changes: 26 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"license": "MIT",
"dependencies": {
"bulma": "^0.7.2",
"preact": "^8.3.1",
"preact-compat": "^3.18.4",
"preact-redux": "^2.0.3"
},
"devDependencies": {
"@babel/core": "^7.1.2",
"babel-core": "^6.26.3",
"babel-preset-env": "^1.7.0",
"node-sass": "^4.10.0",
"parcel-bundler": "^1.10.3"
},
"scripts": {
"start": "parcel watch ./src/index.html -d ../public --no-hmr",
"build": "parcel build ./src/index.html -d ../public"
},
"babel": {
"presets": [
"env"
],
"plugins": []
}
}
19 changes: 19 additions & 0 deletions shinatra
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env crystal run
require "http"

# Handle Ctrl+C and kill signal.
# Needed for hosting this process in a docker
# as the entry point command
Signal::INT.trap { puts "Caught Ctrl+C..."; exit }
Signal::TERM.trap { puts "Caught kill..."; exit }

port = (ENV["PORT"]? || "80").to_i
server = HTTP::Server.new([
HTTP::ErrorHandler.new,
HTTP::LogHandler.new,
HTTP::StaticFileHandler.new("./"),
])

server.bind_tcp "0.0.0.0", 8080
puts "Listening on http://0.0.0.0:#{port}"
server.listen
6 changes: 6 additions & 0 deletions src/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function fetchSchedule(scheduleID) {
fetch(`https://horaro.org/-/api/v1/schedules/${scheduleID}`)
.then((response) => response.json())
.then((data) => callback(data))
.catch((error) => console.log(error));
}
25 changes: 25 additions & 0 deletions src/components/horaro_ticker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { h, Component } from 'preact';
import TickerEntry from './ticker_entry';

class HoraroTicker extends Component {
getItemField(column, item, columns) {
return item.data[columns.indexOf(column)];
}

render({data}) {
const {name, link, columns, items} = data;
let lastDate = -1;

return (
<div class="horaro-ticker">
{
items.map((item) => {
return <TickerEntry item={item} columns={columns} />;
})
}
</div>
);
}
}

export default HoraroTicker;
33 changes: 33 additions & 0 deletions src/components/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { h, Component } from 'preact';
import { formatTime } from '../util';

class Run extends Component {
render({run, children}, _state) {
const {game, category, runner} = run;

return (
<div class="run">
<div class="columns">
<div class="column">
<div class="is-pulled-right">
<p class="time estimate"><strong>EST: { formatTime(run.estimate) }</strong></p>
<p class="time pb">PB: { formatTime(run.pb) }</p>
</div>
<p class="game-name">{game.name}</p>
<p>
<span class="category-name">{category.name}</span> &mdash; <span class="runner-name">{runner.name}</span>
</p>
</div>

{ children.length > 0 &&
<div class="column is-narrow">
{children}
</div>
}
</div>
</div>
);
}
}

export default Run;
40 changes: 40 additions & 0 deletions src/components/ticker_entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { h, Component } from 'preact';
import { relativeTimeString } from '../util';

class TickerEntry extends Component {
getItemField(column, item, columns) {
return item.data[columns.indexOf(column)];
}

render({item, columns}) {
const game = this.getItemField("Game", item, columns);
const category = this.getItemField("Category", item, columns);
const runners = this.getItemField("Runners", item, columns);
const isRace = this.getItemField("Race?", item, columns);
const startTime = new Date(item.scheduled);
const estimate = item.length_t;

return (
<div class="ticker__entry">
<div class="ticker-entry__section ticker-entry__section--leader">
</div>
<div class="ticker-entry__section">
<p class="ticker-entry__game">{game}</p>
<p class="ticker-entry__category">
{category}
{ isRace &&
" Race"
}
</p>
</div>
<div class="ticker-entry__separator is-pulled-right"></div>
<div class="ticker-entry__section is-pulled-right has-text-right">
<p class="ticker-entry__runners">{runners}</p>
<p class="ticker-entry__start-time">{relativeTimeString(startTime, new Date())}</p>
</div>
</div>
);
}
}

export default TickerEntry;
14 changes: 14 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<html>
<head>
<link rel="stylesheet" href="./style/main.scss">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
</head>

<body>
<div class="layout">
<div id="horaro-ticker"></div>
</div>
</body>

<script src="./index.js"></script>
</html>
11 changes: 11 additions & 0 deletions src/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 88 additions & 0 deletions src/style/main.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
@import "../../node_modules/bulma/bulma";

* {
box-sizing: border-box;
}

html {
font-size: 1.25rem;
font-family: 'Lato';
}

.layout {
position: relative;
width: 1920px;
height: 1080px;
background: url('../assets/Solo_SD.png');
background-size: cover;
}

.horaro-ticker {
position: absolute;
bottom: 0;
left: 0;
width: 1920px;
height: 55px;
/*max-height: 55px;*/
overflow-x: scroll;
/*background: #777;*/
}

.ticker__entry {
min-width: 340px;
display: inline-block;
padding: 0 0.4rem;
color: #f7f7f7;
margin: 3px 0;
line-height: 1.2em;
text-shadow: 0.02em 0.04em 0.5em #000;
}

.ticker-entry__separator {
width: 0;
margin-left: 12px;
height: 47px;
/*border-right: 4px solid #c13ef7;*/
border-right: 4px solid #000;
/*box-shadow: 0 0 1em 2px #a735d6;*/
}

.ticker-entry__section {
display: inline-block;
height: 47px;
margin: 0 4px 0 0;
}

.ticker-entry__section--leader {
vertical-align: middle;
margin-right: 12px;
}

.ticker-entry__section--leader:empty {
margin: 0;
}

.ticker-entry__icon {
margin-left: 1ch;
}

.ticker-entry__section--centered {
vertical-align: middle;
}

.ticker-entry__game {
font-size: 1.1em;
font-weight: bold;
}

.ticker-entry__category {
font-size: 0.9em;
}

.ticker-entry__runners {
font-size: 0.9em;
}

.ticker-entry__start-time {
font-size: 0.8em;
}
63 changes: 63 additions & 0 deletions src/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
export function formatTime(millis, isSeconds) {
if(isSeconds) millis *= 1000;

const h = Math.floor(millis / 1000 / 60 / 60),
m = Math.floor(millis / 1000 / 60 % 60),
s = Math.floor(millis / 1000 % 60);

const hour = `${h}`.padStart(2, '0'),
minute = `${m}`.padStart(2, '0'),
second = `${s}`.padStart(2, '0');

return `${hour}:${minute}:${second}`;
}


// Taken and adapted from https://github.com/bevacqua/fuzzysearch/blob/master/index.js
// Adaptations:
// - ignore case
export function fuzzysearch(needle, haystack) {
needle = needle.toLowerCase();
haystack = haystack.toLowerCase();
var hlen = haystack.length;
var nlen = needle.length;
if (nlen > hlen) {
return false;
}
if (nlen === hlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < nlen; i++) {
var nch = needle.charCodeAt(i);
while (j < hlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}


export function relativeTimeString(current, previous) {
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;

var elapsed = current - previous;

if (elapsed < msPerMinute) {
return `in ${Math.round(elapsed/1000)}s`;
}

else if (elapsed < msPerHour) {
return `in ${Math.round(elapsed/msPerMinute)} mins`;
}

else {
return `in ${Math.round(elapsed/msPerHour)} hrs`;
}
}
Loading

0 comments on commit 28997aa

Please sign in to comment.