Initial commit

This commit is contained in:
Joey Kimsey
2024-08-04 21:15:59 -04:00
parent c9d1fb983f
commit 0d469501ee
695 changed files with 70184 additions and 71 deletions

View File

@ -0,0 +1,42 @@
<?php
/**
* app/controllers/api/users.php
*
* This is the users' api controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Api;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Models\Timers as Timer;
class Timers extends ApiController {
public static $timers;
public function __construct() {
parent::__construct();
self::$timers = new Timer;
Template::setTemplate( 'api' );
}
public function create() {
$name = Input::exists('name') ? Input::post('name') : '';
$type = Input::exists('type') ? Input::post('type') : 'stopwatch';
$currentSeconds = Input::exists('currentSeconds') ? Input::post('currentSeconds') : 0;
$pausedAt = 0;
$hours = Input::exists('hours') ? Input::post('hour') : '00';
$minutes = Input::exists('minutes') ? Input::post('minute') : '00';
$seconds = Input::exists('seconds') ? Input::post('seconds') : '00';
$response = self::$timers->create( $name, $currentSeconds, $type, $pausedAt, $hours, $minutes, $seconds);
Views::view( 'api.response', ['response' => json_encode( [ 'data' => $response ], true )]);
}
}

View File

@ -0,0 +1,113 @@
<?php
/**
* app/plugins/timers/controllers/timers.php
*
* This is the home controller for the timers plugin.
*
* @package TP Timers
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Models\Timers as Timer;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Bedrock\Bedrock;
class Timers extends Controller {
protected static $timers;
public function __construct() {
self::$title = 'Timers - {SITENAME}';
self::$pageDescription = 'This is for tracking any number of things using timers.';
self::$timers = new Timer;
if ( ! App::$isLoggedIn ) {
Issues::add( 'info', 'If you register an account and log in, you can save your timers for reuse.' );
Components::set( 'timers', '' );
Components::set( 'stopWatches', '' );
} else {
$timers = self::$timers->userTimers();
$timerView = Views::simpleView( 'timers.timerElement', $timers );
Components::set( 'timers', $timerView );
$stopwatches = self::$timers->userStopWatches();
$stopWatcheView = Views::simpleView( 'timers.stopwatchElement', $stopwatches );
Components::set( 'stopWatches', $stopWatcheView );
}
parent::__construct();
}
public function index() {
Views::view( 'timers.index' );
}
public function save() {
Template::setTemplate( 'api' );
$name = Input::post('name') ? Input::post('name') : 'unnamed';
$type = Input::post('type') ? Input::post('type') : 'stopwatch';
$currentSeconds = Input::post('currentSeconds') ? Input::post('currentSeconds') : 0;
$pausedAt = 0;
$hours = Input::post('hours') ? Input::post('hours') : '00';
$minutes = Input::post('minutes') ? Input::post('minutes') : '00';
$seconds = Input::post('seconds') ? Input::post('seconds') : '00';
$response = self::$timers->create( $name, $currentSeconds, $type, $pausedAt, $hours, $minutes, $seconds );
$out = [
'id' => $response,
];
Views::view( 'api.response', ['response' => json_encode( [ 'data' => $out ], true )]);
}
public function update( $id = null ) {
if ( empty( $id ) ) {
$id = Input::postNull('id');
}
Template::setTemplate( 'api' );
$timer = self::$timers->findById( $id );
if ( $timer == false || $timer->createdBy != App::$activeUser->ID ) {
$response = $id;
} else {
if ( Input::post('paused') ) {
$pausedAt = time();
} else {
$pausedAt = 0;
}
$response = self::$timers->update( $id, Input::post('currentSeconds'), $pausedAt );
}
Views::view( 'api.response', ['response' => json_encode( [ 'data' => $response ], true )]);
}
public function remove( $id = null ) {
if ( empty( $id ) ) {
$id = Input::postNull('id');
}
Template::setTemplate( 'api' );
$timer = self::$timers->findById( $id );
if ( $timer == false || $timer->createdBy != App::$activeUser->ID ) {
$response = $id;
} else {
$response = self::$timers->delete( $id );
}
Views::view( 'api.response', ['response' => json_encode( [ 'data' => $response ], true )]);
}
public function resume() {
$this->index();
}
public function pause() {
$this->index();
}
public function archive() {
$this->index();
}
}

View File

@ -0,0 +1,8 @@
.panel-footer .btn {
margin-left: 5px;
margin-right: 5px;
}
.panel {
margin-bottom: 10px;
}

View File

@ -0,0 +1,38 @@
<?php
/**
* app/plugins/timers/forms.php
*
* This houses all of the form checking functions for this plugin.
*
* @package TP Timers
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Plugins\Suggestions;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Classes\Forms;
class TimerForms extends Forms {
/**
* Adds these functions to the form list.
*/
public function __construct() {
self::addHandler( 'saveTimer', __CLASS__, 'saveTimer' );
self::addHandler( 'pauseTimer', __CLASS__, 'pauseTimer' );
self::addHandler( 'resumeTimer', __CLASS__, 'resumeTimer' );
}
public static function saveTimer() {
return true;
}
public static function pauseTimer() {
return true;
}
public static function resumeTimer() {
return true;
}
}
new TimerForms;

View File

@ -0,0 +1,356 @@
$(document).ready(function() {
function createStopwatch(name, id, currentTime = 0, pausedAt = 0) {
if (!id) {
id = 'stopwatch' + ($('#stopWatches').children().length + 1);
}
var panelHtml = generatePanelHtml( name, id, 'glyphicon-time', 'stopwatch', 0, currentTime, pausedAt );
$('#stopWatches').append(panelHtml);
setupStopwatch( id, currentTime, pausedAt );
}
function createTimer( name, id, totalTime = 0, currentTime = 0, pausedAt = 0 ) {
if (!id) {
id = 'timer' + ($('#timers').children().length + 1);
}
var panelHtml = generatePanelHtml( name, id, 'glyphicon-hourglass', 'timer', totalTime, currentTime, pausedAt );
$('#timers').append(panelHtml);
setupTimer( id, totalTime, currentTime, pausedAt );
}
function generatePanelHtml(name, id, iconClass, type, totalSeconds, currentSeconds = 0, pausedAt = 0) {
var panelColor, readout, defaultTime, resumeButtons;
if (type === 'timer') {
panelColor = 'primary';
defaultTime = `<b>Default Time:</b>
<span class="pull-right">
${formatTime(totalSeconds)}
</span>
<br />`;
readout = `<p id="${id}">Time left: ${formatTime(currentSeconds)}</p>`;
} else {
panelColor = 'info';
defaultTime = '';
readout = `<p id="${id}">Time elapsed: ${formatTime(currentSeconds)}</p>`;
}
if ( 0 != pausedAt ) {
resumeButtons = `<button id="Resume${id}" class="btn btn-sm btn-success"><i class="glyphicon glyphicon-play"></i></button>
<button id="Pause${id}" class="btn btn-sm btn-default" style="display:none"><i class="glyphicon glyphicon-pause"></i></button>`;
} else {
resumeButtons = `<button id="Resume${id}" class="btn btn-sm btn-success" style="display:none"><i class="glyphicon glyphicon-play"></i></button>
<button id="Pause${id}" class="btn btn-sm btn-default"><i class="glyphicon glyphicon-pause"></i></button>`;
}
return `
<span class="col-lg-4" id="Panel${id}">
<div class="panel panel-${panelColor}" role="tab">
<div class="pull-left panel-heading">
<button type="button" class="btn btn-default btn-sm" data-target="#Collapse${id}" data-toggle="collapse" aria-expanded="true" aria-controls="#Collapse${id}">
<i class="glyphicon ${iconClass}"></i> ${name}
</button>
</div>
<div class="panel-heading text-center">
${resumeButtons}
<span class="pull-right">${readout}</span>
</div>
<div id="Collapse${id}" class="panel-collapse collapse in" style="width:100%; position: relative;" role="tabpanel" aria-expanded="true">
<div class="panel-body">
<b>Name:</b>
<span class="pull-right timer-name">
${name}
</span>
<br />
${defaultTime}
<b>Created At:</b>
<span class="pull-right">
${getFormattedDate()}
</span>
<br />
</div>
<div class="panel-footer">
${generateButtons(id, type)}
</div>
</div>
</div>
</span>`;
}
function generateButtons(id, type) {
var duplicate = '';
if (type === 'timer') {
duplicate = `<button id="Duplicate${id}" class="btn btn-sm btn-info"><i class="glyphicon glyphicon-copy"></i></button>`;
}
return `
<button id="Reset${id}" class="btn btn-sm btn-primary"><i class="glyphicon glyphicon-refresh"></i></button>
<span class="pull-right">
${duplicate}
<button id="Remove${id}" class="btn btn-sm btn-danger"><i class="glyphicon glyphicon-trash"></i></button>
<button id="Save${id}" class="btn btn-sm btn-success" onclick="saveTimer('${id}')"><i class="glyphicon glyphicon-save"></i></button>
</span>
`;
}
function setupStopwatch(id, currentTime, pausedAt) {
var interval;
if ( 0 == pausedAt ) {
interval = setInterval(() => updateDisplay(id, ++currentTime), 1000);
} else {
updateDisplay( id, currentTime );
}
setData(id, interval, currentTime);
setupControlButtons(id, 'stopwatch', () => updateDisplay(id, ++currentTime));
}
function setupTimer( id, totalTime, currentTime, pausedAt = 0 ) {
var interval;
if ( 0 == pausedAt ) {
interval = setInterval(() => {
if (currentTime <= 0) {
clearInterval(interval);
$('#' + id).html("Time's up!");
} else {
updateDisplay(id, --currentTime);
}
}, 1000);
} else {
updateDisplay( id, currentTime );
}
setData( id, interval, currentTime, totalTime );
setupControlButtons(id, 'timer', () => {
if (currentTime <= 0) {
clearInterval(interval);
$('#' + id).html("Time's up!");
} else {
updateDisplay(id, --currentTime);
}
});
}
function setData( id, interval, elapsed, original = 0 ) {
$('#' + id).data({ 'interval': interval, 'elapsed': elapsed, 'original': original });
}
function updateDisplay(id, time) {
$('#' + id).html(`Time: ${formatTime(time)}`);
$('#' + id).data({ 'elapsed': time });
}
function setupControlButtons(id, type, updateFn) {
var $pause = $(`#Pause${id}`);
var $resume = $(`#Resume${id}`);
var $remove = $(`#Remove${id}`);
var $reset = $(`#Reset${id}`);
var $duplicate = $(`#Duplicate${id}`);
if (type === 'timer') {
$duplicate.click(function() {
var element = $( '#Panel' + id );
var name = element.find('.timer-name').text();
createTimer( name + ' Copy', 0, $('#' + id).data('original'), $('#' + id).data('original'), true );
});
}
$pause.click(function() {
clearInterval($('#' + id).data('interval'));
$pause.hide();
$resume.show();
});
$resume.click(function() {
var element = $( '#' + id );
var elapsedTime = element.data('elapsed') || 0;
if ( type === 'timer') {
var newInterval = setInterval( function() {
elapsedTime--;
updateDisplay( id, elapsedTime );
element.data('elapsed', elapsedTime );
}, 1000);
} else {
var newInterval = setInterval(function() {
elapsedTime++;
updateDisplay( id, elapsedTime );
element.data( 'elapsed', elapsedTime );
}, 1000);
}
element.data( 'interval', newInterval );
$resume.hide();
$pause.show();
});
$remove.click(function() {
clearInterval($('#' + id).data('interval'));
$.post('/timers/remove', {
id: id,
}).done(function(response) {
$('#' + id).closest('.panel').remove();
alert('Timer removed successfully!');
}).fail(function() {
alert('Error removing timer.');
});
});
$reset.click(function() {
var element = $( '#' + id ); // get the element we are working with
var originalTime = $( '#' + id ).data('original') || 0; // get the original time
clearInterval( element.data('interval') ); //stop the countdown
if ( type === 'timer') {
element.data( 'elapsed', originalTime ); // set time remaining to original time
updateDisplay( id, originalTime ); // let the display know things have changed
// if its currently ticking, make it keep ticking
if ( ! $resume.is(":visible") ) {
var newInterval = setInterval( function() {
if ( originalTime <= 0 ) {
clearInterval( newInterval );
} else {
originalTime--;
element.data('elapsed', originalTime );
}
updateDisplay( id, originalTime );
}, 1000);
element.data( 'interval', newInterval );
}
} else {
var elapsedTime = 0;
element.data( 'elapsed', elapsedTime );
updateDisplay( id, elapsedTime );
var newInterval = setInterval(function() {
elapsedTime++;
updateDisplay( id, elapsedTime );
element.data( 'elapsed', elapsedTime );
}, 1000);
element.data( 'interval', newInterval );
}
});
}
function getFormattedDate() {
var date = new Date();
var options = { year: 'numeric', month: 'long', day: 'numeric' };
return date.toLocaleDateString('en-US', options);
}
function changeId( currentID, newID ) {
$(`#${currentID}`).attr('id', newID);
$(`#Resume${currentID}`).attr('id', `Resume${newID}`);
$(`#Pause${currentID}`).attr('id', `Pause${newID}`);
$(`#Panel${currentID}`).attr('id', `Panel${newID}`);
$(`#Collapse${currentID}`).attr('id', `Collapse${newID}`);
$(`#Save${currentID}`).attr('id', `Save${newID}`).attr('onclick', `saveTimer('${newID}')`);
$(`#Remove${currentID}`).attr('id', `Remove${newID}`);
$(`#Reset${currentID}`).attr('id', `Reset${newID}`);
$(`#Duplicate${currentID}`).attr('id', `Duplicate${newID}`);
$(`button[data-target="#Collapse${currentID}"]`).attr('data-target', `#Collapse${newID}`);
$(`button[aria-controls="#Collapse${currentID}"]`).attr('aria-controls', `#Collapse${newID}`)
}
function formatTime(seconds) {
var hrs = Math.floor(seconds / 3600);
var mins = Math.floor((seconds % 3600) / 60);
var secs = seconds % 60;
return `${hrs > 0 ? hrs + 'h ' : ''}${mins > 0 ? mins + 'm ' : ''}${secs}s`;
}
$('#addStopwatch').click(function() {
createStopwatch($('#stopwatchName').val());
});
$('#addTimer').click(function() {
var name = $('#name').val();
var hours = parseInt($('#hours').val()) || 0;
var minutes = parseInt($('#minutes').val()) || 0;
var seconds = parseInt($('#seconds').val()) || 0;
var totalTime = hours * 3600 + minutes * 60 + seconds;
if ( totalTime > 0 ) {
createTimer( name, '', totalTime, totalTime ); // for new timers, it starts at max time
} else {
alert( 'Please enter a valid number of hours, minutes, or seconds.' );
}
});
$('.timer-row').each( function() {
var $row = $(this);
var name = $row.find('.timer-name').text();
var currentSeconds = parseInt($row.find('.timer-current').text(), 10);
var pausedAt = $row.find('.timer-paused').text();
var hours = parseInt($row.find('.timer-hours').text(), 10);
var minutes = parseInt($row.find('.timer-minutes').text(), 10);
var seconds = parseInt($row.find('.timer-seconds').text(), 10);
var id = $row.find('.timer-id').text();
var totalTime = hours * 3600 + minutes * 60 + seconds;
var createdAt = $row.find('.timer-created').text();
createTimer( name, id, totalTime, currentSeconds, pausedAt );
$row.remove();
});
$('.stopwatch-row').each( function() {
var $row = $(this);
var name = $row.find('.timer-name').text();
var currentSeconds = parseInt($row.find('.timer-current').text(), 10);
var pausedAt = $row.find('.timer-paused').text();
var id = $row.find('.timer-id').text();
var createdAt = $row.find('.timer-created').text();
createStopwatch( name, id, currentSeconds, pausedAt );
$row.remove();
});
window.saveTimer = function( elementId ) {
var type;
if ( elementId.includes('timer') ) {
type = 'timer';
} else if ( elementId.includes('stopwatch') ) {
type = 'stopwatch';
} else {
return updateTimer( elementId );
}
var element = $( '#Panel' + elementId );
var name = element.find('.timer-name').text();
var originalTime = $('#' + elementId).data('original') || 0;
var totalSeconds = $('#' + elementId).data('elapsed') || 0;
var hours = Math.floor(originalTime / 3600);
var minutes = Math.floor((originalTime % 3600) / 60);
var seconds = originalTime % 60;
$.post('/timers/save', {
name: name.trim(),
type: type,
hours: hours,
minutes: minutes,
seconds: seconds,
currentSeconds: totalSeconds,
}).done(function(response) {
var responseData = JSON.parse(response);
var timerId = responseData.data.id;
alert('Timer saved successfully! ID: ' + timerId);
}).fail(function() {
alert('Error saving timer.');
});
};
function updateTimer( elementId ) {
var $resume = $(`#Resume${elementId}`);
var totalSeconds = $('#' + elementId).data('elapsed') || 0;
var fields = {};
if ( $resume.is(":visible") ) {
fields.paused = true;
}
fields.currentSeconds = totalSeconds;
$.post( '/timers/update/' + elementId, fields ).done(function(response) {
alert('Timer updated successfully!');
}).fail(function() {
alert('Error saving timer.');
});
}
});

View File

@ -0,0 +1,176 @@
<?php
/**
* app/plugins/suggestions/models/suggestions.php
*
* This class is used for the manipulation of the suggestions database table.
*
* @package TP Suggest
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Models;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Bedrock\Classes\CustomException;
use TheTempusProject\Classes\DatabaseModel;
use TheTempusProject\TheTempusProject as App;
class Timers extends DatabaseModel {
public $tableName = 'timers';
public $databaseMatrix = [
[ 'name', 'varchar', '86' ],
[ 'type', 'varchar', '24' ],
[ 'currentSeconds', 'int', '10' ],
[ 'hours', 'int', '10' ],
[ 'minutes', 'int', '10' ],
[ 'seconds', 'int', '10' ],
[ 'createdBy', 'int', '11' ],
[ 'createdAt', 'int', '11' ],
[ 'updatedAt', 'int', '11' ],
[ 'pausedAt', 'int', '11' ],
];
public function __construct() {
parent::__construct();
}
public function filter( $data, $params = [] ) {
return $data;
}
public function listByUser( $limit = 0 ) {
$where = [ 'createdBy', '=', App::$activeUser->ID ];
if ( empty( $limit ) ) {
$timers = self::$db->getPaginated( $this->tableName, $where, 'createdAt', 'DESC' );
} else {
$timers = self::$db->get( $this->tableName, $where, 'createdAt', 'DESC', [ 0, $limit ] );
}
if ( ! $timers->count() ) {
Debug::info( 'No timers found.' );
return [];
}
return $this->filter( $timers->results() );
}
public function userTimers( $limit = 0 ) {
$where = [ 'createdBy', '=', App::$activeUser->ID, 'AND', 'type', '=', 'timer' ];
if ( empty( $limit ) ) {
$timers = self::$db->getPaginated( $this->tableName, $where, 'createdAt', 'DESC' );
} else {
$timers = self::$db->get( $this->tableName, $where, 'createdAt', 'DESC', [ 0, $limit ] );
}
if ( ! $timers->count() ) {
Debug::info( 'No timers found.' );
return [];
}
return $this->filter( $timers->results() );
}
public function userStopWatches( $limit = 0 ) {
$where = [ 'createdBy', '=', App::$activeUser->ID, 'AND', 'type', '=', 'stopwatch' ];
if ( empty( $limit ) ) {
$timers = self::$db->getPaginated( $this->tableName, $where, 'createdAt', 'DESC' );
} else {
$timers = self::$db->get( $this->tableName, $where, 'createdAt', 'DESC', [ 0, $limit ] );
}
if ( ! $timers->count() ) {
Debug::info( 'No timers found.' );
return [];
}
return $this->filter( $timers->results() );
}
public function create( $name, $currentSeconds, $type = 'stopwatch', $pausedAt = 0, $hours = 0, $minutes = 0, $seconds = 0 ) {
$fields = [
'name' => $name,
'currentSeconds' => $currentSeconds,
'type' => $type,
'pausedAt' => $pausedAt,
'hours' => $hours,
'minutes' => $minutes,
'seconds' => $seconds,
'createdBy' => App::$activeUser->ID,
'createdAt' => time(),
];
if ( !self::$db->insert( $this->tableName, $fields ) ) {
new CustomException( $this->tableName );
return false;
}
return self::$db->lastId();
}
public function update( $ID, $currentSeconds, $pausedAt = 0 ) {
if ( !Check::id( $ID ) ) {
Debug::info( 'timer: illegal ID.' );
return false;
}
if ( !Check::id( $pausedAt ) ) {
Debug::info( 'timer: illegal pausedAt.' );
return false;
}
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND', 'ID', '=', $ID ];
$timer = self::$db->get( $this->tableName, $whereClause );
if ( ! $timer->count() ) {
Debug::info( "Timer: Doesn't exist or user doesn't have access" );
return false;
}
$fields = [
'pausedAt' => $pausedAt,
'currentSeconds' => $currentSeconds,
'updatedAt' => time(),
];
if ( !self::$db->update( $this->tableName, $ID, $fields ) ) {
new CustomException( $this->tableName );
return false;
}
return true;
}
public function pause( $ID, $currentSeconds ) {
if ( !Check::id( $ID ) ) {
Debug::info( 'Timer: illegal ID.' );
return false;
}
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND', 'ID', '=', $ID ];
$timer = self::$db->get( $this->tableName, $whereClause );
if ( ! $timer->count() ) {
Debug::info( "Timer: Doesn't exist or user doesn't have access" );
return false;
}
$fields = [
'pausedAt' => time(),
'currentSeconds' => $currentSeconds,
];
if ( !self::$db->update( $this->tableName, $ID, $fields ) ) {
new CustomException( $this->tableName );
return false;
}
return true;
}
public function resume( $I, $currentSecondsD ) {
if ( !Check::id( $ID ) ) {
Debug::info( 'Timer: illegal ID.' );
return false;
}
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND', 'ID', '=', $ID ];
$timer = self::$db->get( $this->tableName, $whereClause );
if ( ! $timer->count() ) {
Debug::info( "Timer: Doesn't exist or user doesn't have access" );
return false;
}
$fields = [
'pausedAt' => '',
'currentSeconds' => $currentSeconds,
];
if ( !self::$db->update( $this->tableName, $ID, $fields ) ) {
new CustomException( $this->tableName );
return false;
}
return true;
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* app/plugins/timers/plugin.php
*
* This houses all of the main plugin info and functionality.
*
* @package TP Timers
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Plugins;
use TheTempusProject\Classes\Plugin;
class Timers extends Plugin {
public $pluginName = 'TP Timers';
public $pluginAuthor = 'JoeyK';
public $pluginWebsite = 'https://TheTempusProject.com';
public $modelVersion = '1.0';
public $pluginVersion = '3.0';
public $pluginDescription = 'A simple plugin which adds various timers for tabletop gaming.';
public $configName = 'timers';
public $configMatrix = [
'enabled' => [
'type' => 'radio',
'pretty' => 'Enable timer usage.',
'default' => true,
],
];
public $permissionMatrix = [
'timers' => [
'pretty' => 'Can use timers',
'default' => true,
],
];
public $main_links = [
[
'text' => 'Timers',
'url' => '{ROOT_URL}timers/index',
],
];
}

View File

@ -0,0 +1,29 @@
<link rel="stylesheet" href="{ROOT_URL}app/plugins/timers/css/timers.css" crossorigin="anonymous">
<script src="{ROOT_URL}app/plugins/timers/js/timers.js" type="module" defer></script>
<h1 class="text-center">Timers</h1>
<div class="container">
<h2>Timers</h2>
<div class="form-inline">
<div class="form-group">
<input type="text" id="name" class="form-control" placeholder="Name">
<input type="text" id="hours" class="form-control" placeholder="Hours">
<input type="text" id="minutes" class="form-control" placeholder="Minutes">
<input type="text" id="seconds" class="form-control" placeholder="Seconds">
<button id="addTimer" class="btn btn-primary">Add</button>
</div>
</div>
<h2>StopWatch</h2>
<div class="form-inline">
<div class="form-group">
<input type="text" id="stopwatchName" class="form-control" placeholder="Name">
<button id="addStopwatch" class="btn btn-primary">Start</button>
</div>
</div>
</div>
<div id="timers" class="" style="margin-top: 20px;" role="tablist" aria-multiselectable="true">
{timers}
</div>
<div id="stopWatches" class="" style="margin-top: 20px;" role="tablist" aria-multiselectable="true">
{stopWatches}
</div>

View File

@ -0,0 +1,15 @@
{LOOP}
<div class="stopwatch-row">
<span class="timer-name">{name}</span>
<span class="timer-current">{currentSeconds}</span>
<span class="timer-paused">{pausedAt}</span>
<span class="timer-hours">{hours}</span>
<span class="timer-minutes">{minutes}</span>
<span class="timer-seconds">{seconds}</span>
<span class="timer-id">{ID}</span>
<span class="timer-created">{DTC}{createdAt}{/DTC}</span>
</div>
{/LOOP}
{ALT}
<span class=""></span>
{/ALT}

View File

@ -0,0 +1,15 @@
{LOOP}
<div class="timer-row">
<span class="timer-name">{name}</span>
<span class="timer-current">{currentSeconds}</span>
<span class="timer-paused">{pausedAt}</span>
<span class="timer-hours">{hours}</span>
<span class="timer-minutes">{minutes}</span>
<span class="timer-seconds">{seconds}</span>
<span class="timer-id">{ID}</span>
<span class="timer-created">{DTC}{createdAt}{/DTC}</span>
</div>
{/LOOP}
{ALT}
<span class=""></span>
{/ALT}