Admit defeat to timezones. Style and file structure tweaks.

This commit is contained in:
Greg Sarjeant 2025-05-31 20:56:05 -04:00
parent 22a7ae948f
commit dd2d22c812
15 changed files with 107 additions and 53 deletions

View File

@ -8,7 +8,7 @@ Currently very much a work in progress, but it's baically functional.
Deploy the `/tkr` directory to a web server that supports php. It will work either as the root of a (sub)domain (e.g. tky.mydomain.com) or if served from a subdirectory (e.g. mydomain.com/tkr).
If you serve it from a subdirectory, set the value of `$basePath` in `/app/config.php` to the subdirectory name, excluding the trailing slash (e.g. `/tkr`)
If you serve it from a subdirectory, set the value of `$basePath` in `/app/Config.php` to the subdirectory name, excluding the trailing slash (e.g. `/tkr`)
It provides an rss feed at `/rss` relative to where it's being served (e.g. `/tkr/rss` if served from `/tkr/`). Each rss entry links to an individual post (which I call "ticks").

View File

@ -1,7 +1,8 @@
<?php
define('APP_ROOT', dirname(__FILE__));
define('LIB_ROOT', APP_ROOT . '/lib');
define('CLASSES_DIR', APP_ROOT . '/classes');
define('LIB_DIR', APP_ROOT . '/lib');
define('TICKS_DIR', APP_ROOT . '/storage/ticks');
define('DATA_DIR', APP_ROOT . '/storage/db');
define('DB_FILE', DATA_DIR . '/tkr.sqlite');

View File

@ -11,6 +11,7 @@ class Config {
public string $siteDescription = '';
public string $basePath = '/';
public int $itemsPerPage = 25;
public string $timezone = 'relative';
// load config from sqlite database
public static function load(): self {

View File

@ -1,9 +1,9 @@
<?php
require_once __DIR__ . '/../bootstrap.php';
require_once LIB_ROOT . '/config.php';
require_once LIB_ROOT . '/user.php';
require_once CLASSES_DIR . '/Config.php';
require_once CLASSES_DIR . '/User.php';
require LIB_ROOT . '/emoji.php';
require LIB_DIR . '/emoji.php';
function save_mood(string $mood): void {
$config = Config::load();

View File

@ -13,3 +13,28 @@ function escape_and_linkify(string $text): string {
return $safe;
}
// For relative time display, compare the stored time to the current time
// and display it as "X second/minutes/hours/days etc. "ago
function relative_time(string $tickTime): string {
$datetime = new DateTime($tickTime);
$now = new DateTime('now', $datetime->getTimezone());
$diff = $now->diff($datetime);
if ($diff->y > 0) {
return $diff->y . ' year' . ($diff->y > 1 ? 's' : '') . ' ago';
}
if ($diff->m > 0) {
return $diff->m . ' month' . ($diff->m > 1 ? 's' : '') . ' ago';
}
if ($diff->d > 0) {
return $diff->d . ' day' . ($diff->d > 1 ? 's' : '') . ' ago';
}
if ($diff->h > 0) {
return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago';
}
if ($diff->i > 0) {
return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago';
}
return $diff->s . ' second' . ($diff->s != 1 ? 's' : '') . ' ago';
}

View File

@ -3,14 +3,14 @@ require_once __DIR__ . '/../bootstrap.php';
confirm_setup();
require_once LIB_ROOT . '/config.php';
require LIB_ROOT . '/session.php';
require_once CLASSES_DIR . '/Config.php';
require LIB_DIR . '/session.php';
if (!$isLoggedIn){
header('Location: ' . $config->basePath . 'login.php');
}
require LIB_ROOT . '/user.php';
require CLASSES_DIR . '/User.php';
$config = Config::load();
$user = User::load();

View File

@ -8,13 +8,17 @@ body {
color: black;
}
a {
font-weight: bold;
}
/*
The two common display options for responsive layouts are flex and grid.
flex (aka Flexbox) aligns items either horizontally or vertically.
grid can align items in two dimensions.
grid also allows more precise positioning of elements, so I'm using that.
*/
.container {
.home-container {
display: grid;
}
@ -25,7 +29,7 @@ body {
Once the width exceeds that (e.g. desktops), it will convert to horizontal alignment
*/
@media (min-width: 600px) {
.container {
.home-container {
grid-template-columns: 1fr 2fr;
grid-gap: 2em;
}
@ -143,3 +147,15 @@ body {
background-color: #ddeeff;
outline: 2px solid #339;
}
#timezones {
max-height: 300px;
overflow-y: auto;
border: 1px solid #ccc;
padding: 1em;
}
.timezone-option {
display: block;
margin-bottom: 0.5em;
}

View File

@ -3,11 +3,11 @@ require_once __DIR__ . '/../bootstrap.php';
confirm_setup();
require_once LIB_ROOT . '/config.php';
require_once LIB_ROOT . '/user.php';
require LIB_ROOT . '/session.php';
require LIB_ROOT . '/ticks.php';
require LIB_ROOT . '/util.php';
require_once CLASSES_DIR . '/Config.php';
require_once CLASSES_DIR . '/User.php';
require LIB_DIR . '/session.php';
require LIB_DIR . '/ticks.php';
require LIB_DIR . '/util.php';
$config = Config::load();
// I can get away with this before login because there's only one user.
@ -28,9 +28,20 @@ $ticks = iterator_to_array(stream_ticks($limit, $offset));
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css?v=<?= time() ?>">
</head>
<body>
<div class="container">
<section id="sidebar">
<h2>Hi, I'm <?= $user->displayName ?></h2>
<div class="home-navbar">
<a href="<?= $config->basePath ?>rss">rss</a>
<?php if (!$isLoggedIn): ?>
<a href="<?= $config->basePath ?>login.php">login</a>
<?php else: ?>
<a href="<?= $config->basePath ?>admin.php">admin</a>
<a href="<?= $config->basePath ?>logout.php">logout</a>
<?php endif; ?>
</div>
<div class="home-container">
<section id="sidebar" class="home-sidebar">
<div class="home-header">
<h2>Hi, I'm <?= $user->displayName ?></h2>
</div>
<p><?= $user->about ?></p>
<p>Website: <?= escape_and_linkify($user->website) ?></p>
<div class="profile-row">
@ -50,32 +61,24 @@ $ticks = iterator_to_array(stream_ticks($limit, $offset));
<button type="submit">Tick</button>
</form>
</div>
<?php endif; ?>
<?php if ($isLoggedIn): ?>
<div class="admin-bar">
<a href="<?= $config->basePath . '/admin.php' ?>">Admin</a>
<div class="admin-right">
<a href="<?= $config->basePath ?>logout.php">Logout</a>
<span><?= htmlspecialchars($user->username) ?></span>
</div>
</div>
<?php else: ?>
<p><a href="<?= $config->basePath ?>login.php">Login</a></p>
<?php endif; ?>
</section>
<section id="ticks">
<h2><?= $config->siteDescription ?></h2>
<section id="ticks" class="home-ticks">
<div class="home-ticks-header">
<h2><?= $config->siteDescription ?></h2>
</div>
<div class="home-ticks-list">
<?php foreach ($ticks as $tick): ?>
<article class="tick">
<div class="tick-time"><?= htmlspecialchars($tick['timestamp']) ?></div>
<span class="tick-text"><?= escape_and_linkify($tick['tick']) ?></span>
</article>
<article class="tick">
<div class="tick-time"><?= htmlspecialchars(relative_time($tick['timestamp'])) ?></div>
<span class="tick-text"><?= escape_and_linkify($tick['tick']) ?></span>
</article>
<?php endforeach; ?>
<div class="pagination">
</div>
<div class="home-ticks-pagination">
<?php if ($page > 1): ?>
<a href="?page=<?= $page - 1 ?>">&laquo; Newer</a>
<?php endif; ?>
<?php if (count($ticks) === $limit): ?>
<a href="?page=<?= $page + 1 ?>">Older &raquo;</a>
<?php endif; ?>

View File

@ -3,8 +3,8 @@ require_once __DIR__ . '/../bootstrap.php';
confirm_setup();
require_once LIB_ROOT . '/config.php';
require LIB_ROOT . '/session.php';
require_once CLASSES_DIR . '/Config.php';
require LIB_DIR . '/session.php';
$config = Config::load();
@ -40,7 +40,12 @@ $csrf_token = generateCsrfToken();
<!DOCTYPE html>
<html>
<head><title>Login</title></head>
<head>
<title><?= $config->siteTitle ?></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css?v=<?= time() ?>">
</head>
<body>
<h2>Login</h2>
<?php if ($error): ?>

View File

@ -1,8 +1,10 @@
<?php
require_once __DIR__ . '/../bootstrap.php';
require LIB_ROOT . '/config.php';
require LIB_ROOT . '/session.php';
confirm_setup();
require_once CLASSES_DIR . '/Config.php';
require LIB_DIR . '/session.php';
$config = Config::load();
$_SESSION = [];

View File

@ -3,8 +3,8 @@ require_once __DIR__ . '/../../bootstrap.php';
confirm_setup();
require LIB_ROOT . '/config.php';
require_once LIB_ROOT . '/ticks.php';
require_once CLASSES_DIR . '/Config.php';
require_once LIB_DIR . '/ticks.php';
$config = Config::load();
$ticks = iterator_to_array(stream_ticks($config->itemsPerPage));

View File

@ -1,13 +1,14 @@
<?php
require_once __DIR__ . '/../bootstrap.php';
require LIB_ROOT . '/config.php';
require LIB_ROOT . '/session.php';
require LIB_ROOT . '/ticks.php';
require LIB_ROOT . '/util.php';
confirm_setup();
require_once CLASSES_DIR . '/Config.php';
require LIB_DIR . '/session.php';
require LIB_DIR . '/ticks.php';
require LIB_DIR . '/util.php';
// ticks must be sent via POST
if ($_SERVER['REQUEST_METHOD'] === 'POST' and isset($_POST['tick'])) {
// ensure that the session is valid before proceeding

View File

@ -3,9 +3,9 @@ require_once __DIR__ . '/../bootstrap.php';
confirm_setup();
require_once LIB_ROOT . '/config.php';
require LIB_ROOT . '/session.php';
require LIB_ROOT . '/mood.php';
require_once CLASSES_DIR . '/Config.php';
require LIB_DIR . '/session.php';
require LIB_DIR . '/mood.php';
// get the config

View File

@ -1,5 +1,5 @@
<?php
require '/app/config.php';
require '/app/Config.php';
$path = $_GET['path'] ?? '';
$parts = explode('/', $path);