Admit defeat to timezones. Style and file structure tweaks.
This commit is contained in:
		
							parent
							
								
									22a7ae948f
								
							
						
					
					
						commit
						dd2d22c812
					
				| @ -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"). | ||||
| 
 | ||||
|  | ||||
| @ -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'); | ||||
|  | ||||
| @ -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 { | ||||
| @ -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(); | ||||
|  | ||||
| @ -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'; | ||||
| } | ||||
|  | ||||
| @ -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(); | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
| @ -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 ?>">« Newer</a> | ||||
| <?php endif; ?>
 | ||||
| 
 | ||||
| <?php if (count($ticks) === $limit): ?>
 | ||||
|                     <a href="?page=<?= $page + 1 ?>">Older »</a> | ||||
| <?php endif; ?>
 | ||||
|  | ||||
| @ -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): ?>
 | ||||
|  | ||||
| @ -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 = []; | ||||
|  | ||||
| @ -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)); | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| <?php | ||||
| require '/app/config.php'; | ||||
| require '/app/Config.php'; | ||||
| 
 | ||||
| $path = $_GET['path'] ?? ''; | ||||
| $parts = explode('/', $path); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user