Finished more-or-less stable web version
This commit is contained in:
parent
060ce6964c
commit
d3d1b752ed
8 changed files with 284 additions and 20 deletions
29
juggl-server/api/getRunningRecords.php
Normal file
29
juggl-server/api/getRunningRecords.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
session_start();
|
||||
require_once(__DIR__ . "/services/apiBranch.inc.php");
|
||||
require_once(__DIR__ . "/services/jsonBuilder.inc.php");
|
||||
require_once(__DIR__ . "/services/responses.inc.php");
|
||||
require_once(__DIR__ . "/services/jugglDbApi.inc.php");
|
||||
|
||||
class GetRunningRecordsBranch extends ApiBranch
|
||||
{
|
||||
function get(ParamCleaner $params)
|
||||
{
|
||||
respondStatus(405);
|
||||
}
|
||||
|
||||
function post(ParamCleaner $params)
|
||||
{
|
||||
$user_id = $params->get("user_id");
|
||||
|
||||
$records = getRunningRecords($user_id);
|
||||
|
||||
$json = new JsonBuilder();
|
||||
$json->addRecords($records);
|
||||
|
||||
respondJson($json);
|
||||
}
|
||||
}
|
||||
|
||||
$branch = new GetRunningRecordsBranch();
|
||||
$branch->execute();
|
|
@ -18,6 +18,8 @@ class JsonBuilder
|
|||
|
||||
function addRecords(array $records)
|
||||
{
|
||||
if ($records === null) return;
|
||||
|
||||
$columns = array(
|
||||
"record_id" => "",
|
||||
"start_time" => "",
|
||||
|
@ -37,6 +39,8 @@ class JsonBuilder
|
|||
|
||||
function addProjects(array $projects)
|
||||
{
|
||||
if ($projects === null) return;
|
||||
|
||||
$columns = array(
|
||||
"project_id" => "",
|
||||
"name" => "",
|
||||
|
|
|
@ -98,13 +98,12 @@ function getProjectRecord($user_id, $project_id, $finished = null)
|
|||
$db->where("user_id", Comparison::EQUAL, $user_id);
|
||||
$db->where("project_id", Comparison::EQUAL, $project_id);
|
||||
|
||||
if ($finished != null) {
|
||||
$comp = Comparison::UNEQUAL;
|
||||
if ($finished == false) {
|
||||
$comp = Comparison::EQUAL;
|
||||
if ($finished !== null) {
|
||||
if ($finished) {
|
||||
$db->addSql(" AND end_time IS NOT NULL");
|
||||
} else {
|
||||
$db->addSql(" AND end_time IS NULL");
|
||||
}
|
||||
|
||||
$db->where("end_time", $comp, null);
|
||||
}
|
||||
|
||||
$db->orderBy("start_time", Order::DESC);
|
||||
|
@ -123,12 +122,30 @@ function getProjectRecord($user_id, $project_id, $finished = null)
|
|||
return $result;
|
||||
}
|
||||
|
||||
function getRunningRecords($user_id)
|
||||
{
|
||||
$db = new DbOperations();
|
||||
$db->select("time_records");
|
||||
$db->where("user_id", Comparison::EQUAL, $user_id);
|
||||
$db->addSql(" AND end_time IS NULL");
|
||||
$results = $db->execute();
|
||||
|
||||
// Is still running?
|
||||
foreach ($results as $key => $value) {
|
||||
$results[$key]["duration"] = calcDuration($results[$key]["start_time"]);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function updateEndRecord($user_id, $params)
|
||||
{
|
||||
$record_id = $params->get("record_id");
|
||||
|
||||
// Get start instance to calculate duration
|
||||
$start_time = getTimeRecord($user_id, $record_id)[0]["start_time"];
|
||||
$start_time = getTimeRecord($user_id, $record_id)["start_time"];
|
||||
var_dump($start_time);
|
||||
var_dump($params->get("end_time"));
|
||||
|
||||
$data = [
|
||||
"end_time" => $params->get("end_time"),
|
||||
|
@ -202,5 +219,5 @@ function isDeviceValid($start_device_id, $user_id)
|
|||
|
||||
function calcDuration($start_time, $end_time = "NOW")
|
||||
{
|
||||
return (int)((new DateTime($start_time))->diff(new DateTime($end_time))->format("%s"));
|
||||
return (int)(strtotime($end_time) - strtotime($start_time));
|
||||
}
|
||||
|
|
|
@ -122,4 +122,12 @@ thead * {
|
|||
color: #AAA;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#current-record-duration {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
#update-notice {
|
||||
margin-bottom: 20px;
|
||||
}
|
|
@ -16,15 +16,70 @@
|
|||
<script src="js/helper.js"></script>
|
||||
|
||||
<script>
|
||||
var intervallId = undefined;
|
||||
window.onblur = () => {
|
||||
stopBackgroundUpdates();
|
||||
}
|
||||
window.onfocus = () => {
|
||||
startBackgroundUpdates();
|
||||
}
|
||||
window.onload = () => {
|
||||
// Create Callbacks
|
||||
callbacks.leaving[States.PUBLIC] = () => {
|
||||
loadProjectList();
|
||||
callbacks.entering[States.RECORDING] = () => {
|
||||
updateProgess();
|
||||
};
|
||||
|
||||
initState();
|
||||
onLogIn();
|
||||
updateVisibility();
|
||||
updateAuthBtnText();
|
||||
startBackgroundUpdates();
|
||||
}
|
||||
|
||||
function onLogIn() {
|
||||
loadProjectList().then(() => {
|
||||
checkForUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
function checkForUpdate() {
|
||||
if (currentRecord !== undefined) {
|
||||
updateProgess();
|
||||
} else {
|
||||
initRunningRecords().then(() => {
|
||||
if (currentRecord !== undefined) {
|
||||
setState(States.RECORDING);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateProgess () {
|
||||
if (currentRecord === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateCurrentRecord().then((record) => {
|
||||
if (record.end_time != null) {
|
||||
currentRecord = undefined;
|
||||
setState(States.IDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
u("#current-project-name").text(currentProject.name);
|
||||
u("#current-record-duration").text((parseInt(record.duration) / 60).toFixed(1) + " min.");
|
||||
});
|
||||
}
|
||||
|
||||
function startBackgroundUpdates () {
|
||||
if (intervallId !== undefined) return;
|
||||
intervallId = setInterval(checkForUpdate, 30000);
|
||||
checkForUpdate();
|
||||
}
|
||||
|
||||
function stopBackgroundUpdates () {
|
||||
clearInterval(intervallId);
|
||||
intervallId = undefined;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
@ -36,20 +91,28 @@
|
|||
<img src="assets/logo_title.png">
|
||||
</li>
|
||||
<li style="float: right">
|
||||
<input id="user-id" class="public" type="text" placeholder="User ID" />
|
||||
<input id="api-key" class="public" type="password" placeholder="API Key" />
|
||||
<input id="user-id" class="public hidden" type="text" placeholder="User ID" />
|
||||
<input id="api-key" class="public hidden" type="password" placeholder="API Key" />
|
||||
<button id="auth-btn" onclick="handleAuthBtn()">Log In</button>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
<main>
|
||||
<div class="idle hidden">
|
||||
<div class="idle hidden" style="text-align: center;">
|
||||
<h1>
|
||||
Select project to track
|
||||
</h1>
|
||||
<div id="project-list">
|
||||
</div>
|
||||
</div>
|
||||
<div class="recording hidden" style="text-align: center;">
|
||||
<h1>
|
||||
Tracking <span id="current-project-name"></span>
|
||||
</h1>
|
||||
<h2 id="current-record-duration" style="color: red;"></h2>
|
||||
<small id="update-notice" >Updated every 30 seconds</small><br/>
|
||||
<button id="stop-btn" onclick="stopRecord()">Stop</button>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -11,9 +11,67 @@ const api = {
|
|||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
return [];
|
||||
return {};
|
||||
});
|
||||
},
|
||||
startRecord(projectId, startTime = new Date()) {
|
||||
return request("/startRecord.php", {
|
||||
project_id: projectId,
|
||||
start_time: dateToString(startTime),
|
||||
})
|
||||
.then((r) => {
|
||||
return r.json();
|
||||
})
|
||||
.then((j) => {
|
||||
return addDuration(j.records[0]);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
getRecord(recordId) {
|
||||
return request("/getRecord.php", {
|
||||
record_id: recordId,
|
||||
})
|
||||
.then((r) => {
|
||||
return r.json();
|
||||
})
|
||||
.then((j) => {
|
||||
return addDuration(j.records[0]);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
getRunningRecords() {
|
||||
return request("/getRunningRecords.php")
|
||||
.then((r) => {
|
||||
return r.json();
|
||||
})
|
||||
.then((j) => {
|
||||
var records = Object.values(j.records);
|
||||
records.forEach((r) => {
|
||||
r = addDuration(r);
|
||||
});
|
||||
|
||||
return records;
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
endRecord(recordId, endTime = new Date()) {
|
||||
return request("/endRecord.php", {
|
||||
record_id: recordId,
|
||||
end_time: dateToString(endTime),
|
||||
}).catch((e) => {
|
||||
console.log(e);
|
||||
return undefined;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
function request(path, json = {}, options = {}) {
|
||||
|
@ -30,3 +88,28 @@ function request(path, json = {}, options = {}) {
|
|||
|
||||
return fetch(url, options);
|
||||
}
|
||||
|
||||
function addDuration(record) {
|
||||
if (record.end_time != null) return record;
|
||||
|
||||
record.duration =
|
||||
(new Date().getTime() - new Date(record.start_time).getTime()) / 1000;
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
function dateToString(date) {
|
||||
return (
|
||||
date.getFullYear() +
|
||||
"-" +
|
||||
(date.getMonth() + 1) +
|
||||
"-" +
|
||||
date.getDate() +
|
||||
" " +
|
||||
date.getHours() +
|
||||
":" +
|
||||
date.getMinutes() +
|
||||
":" +
|
||||
date.getSeconds()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,3 @@ function updateAuthBtnText() {
|
|||
btn.text("Log In");
|
||||
}
|
||||
}
|
||||
|
||||
function onLogIn() {
|
||||
loadProjectList();
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
const PROJECT_OBJECT = "div";
|
||||
const PROJECT_TITLE = "h1";
|
||||
const PROJECT_META = "p";
|
||||
let currentRecord = undefined;
|
||||
let currentProject = undefined;
|
||||
let projectList = undefined;
|
||||
|
||||
function loadProjectList() {
|
||||
api.getProjects().then((projects) => {
|
||||
return api.getProjects().then((projects) => {
|
||||
projectList = Object.values(projects);
|
||||
|
||||
var container = u(u("#project-list").first());
|
||||
Object.values(projects).forEach((project) => {
|
||||
var obj = createNode(PROJECT_OBJECT);
|
||||
|
@ -46,5 +51,64 @@ function append(parent, el) {
|
|||
}
|
||||
|
||||
function projectClicked(event) {
|
||||
console.log(event);
|
||||
var projectObject = event.target;
|
||||
|
||||
if (projectObject.tagName !== "DIV") {
|
||||
projectObject = projectObject.parentElement;
|
||||
}
|
||||
|
||||
var projectId = u(projectObject).data("project-id");
|
||||
|
||||
return api.startRecord(projectId).then((record) => {
|
||||
currentRecord = record;
|
||||
currentProject = getProjectById(record.project_id);
|
||||
setState(States.RECORDING);
|
||||
});
|
||||
}
|
||||
|
||||
function getProjectById(id) {
|
||||
for (let i = 0; i < projectList.length; i++) {
|
||||
const element = projectList[i];
|
||||
|
||||
if (element.project_id == id) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function updateCurrentRecord() {
|
||||
if (currentRecord === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
return api.getRecord(currentRecord.record_id).then((record) => {
|
||||
currentRecord = record;
|
||||
currentProject = getProjectById(record.project_id);
|
||||
return record;
|
||||
});
|
||||
}
|
||||
|
||||
function stopRecord() {
|
||||
if (currentRecord === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
return api.endRecord(currentRecord.record_id).then(() => {
|
||||
setState(States.IDLE);
|
||||
currentRecord = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
function initRunningRecords() {
|
||||
return api.getRunningRecords().then((records) => {
|
||||
if (records === undefined || records.length <= 0) {
|
||||
currentRecord = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
// Assuming, there is only one
|
||||
currentRecord = records[0];
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue