From a039026e7ec345150b730e10eebbb4c646ece49e Mon Sep 17 00:00:00 2001 From: Greg Sarjeant <1686767+gsarjeant@users.noreply.github.com> Date: Wed, 28 May 2025 20:32:25 -0400 Subject: [PATCH] Add mood feature. --- tkr/bootstrap.php | 3 +- tkr/lib/config.php | 6 + tkr/lib/emoji.php | 304 +++++++++++++++++++++++++++++++++++++++ tkr/lib/mood.php | 67 +++++++++ tkr/public/css/tkr.css | 54 +++++++ tkr/public/index.php | 13 +- tkr/public/login.php | 5 +- tkr/public/save_tick.php | 13 +- tkr/public/set_mood.php | 44 ++++++ 9 files changed, 490 insertions(+), 19 deletions(-) create mode 100644 tkr/lib/emoji.php create mode 100644 tkr/lib/mood.php create mode 100644 tkr/public/css/tkr.css create mode 100644 tkr/public/set_mood.php diff --git a/tkr/bootstrap.php b/tkr/bootstrap.php index 454de86..0f46872 100644 --- a/tkr/bootstrap.php +++ b/tkr/bootstrap.php @@ -38,7 +38,8 @@ function confirm_setup(): void { id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, display_name TEXT NOT NULL, - password_hash TEXT NOT NULL + password_hash TEXT NOT NULL, + mood TEXT NULL )"); $db->exec("CREATE TABLE IF NOT EXISTS settings ( diff --git a/tkr/lib/config.php b/tkr/lib/config.php index 012c885..4d998f0 100644 --- a/tkr/lib/config.php +++ b/tkr/lib/config.php @@ -3,23 +3,29 @@ require_once __DIR__ . '/../bootstrap.php'; confirm_setup(); +// Made this a class so it could be more obvious where config settings are coming from. +// Felt too much like magic constants in other files before. class Config { + // properties and default values public string $siteTitle = 'My tkr'; public string $siteDescription = ''; public string $basePath = '/'; public int $itemsPerPage = 25; + // load config from sqlite database public static function load(): self { $db = get_db(); $stmt = $db->query("SELECT site_title, site_description, base_path, items_per_page FROM settings WHERE id=1"); $row = $stmt->fetch(PDO::FETCH_ASSOC); $c = new self(); + if ($row) { $c->siteTitle = $row['site_title']; $c->siteDescription = $row['site_description']; $c->basePath = $row['base_path']; $c->itemsPerPage = (int) $row['items_per_page']; } + return $c; } } \ No newline at end of file diff --git a/tkr/lib/emoji.php b/tkr/lib/emoji.php new file mode 100644 index 0000000..7cb450f --- /dev/null +++ b/tkr/lib/emoji.php @@ -0,0 +1,304 @@ + [ + ['๐Ÿ˜€', 'grinning face'], + ['๐Ÿ˜ƒ', 'grinning face with big eyes'], + ['๐Ÿ˜„', 'grinning face with smiling eyes'], + ['๐Ÿ˜', 'beaming face with smiling eyes'], + ['๐Ÿ˜†', 'grinning squinting face'], + ['๐Ÿ˜…', 'grinning face with sweat'], + ['๐Ÿ˜‚', 'face with tears of joy'], + ['๐Ÿคฃ', 'rolling on the floor laughing'], + ['๐Ÿ˜Š', 'smiling face with smiling eyes'], + ['๐Ÿ˜‡', 'smiling face with halo'], + ['๐Ÿ™‚', 'slightly smiling face'], + ['๐Ÿ™ƒ', 'upside-down face'], + ['๐Ÿ˜‰', 'winking face'], + ['๐Ÿ˜Œ', 'relieved face'], + ['๐Ÿ˜', 'smiling face with heart-eyes'], + ['๐Ÿฅฐ', 'smiling face with hearts'], + ['๐Ÿ˜˜', 'face blowing a kiss'], + ['๐Ÿ˜—', 'kissing face'], + ['๐Ÿ˜š', 'kissing face with closed eyes'], + ['๐Ÿ˜‹', 'face savoring food'], + ['๐Ÿ˜›', 'face with tongue'], + ['๐Ÿ˜œ', 'winking face with tongue'], + ['๐Ÿ˜', 'squinting face with tongue'], + ['๐Ÿคช', 'zany face'], + ['๐Ÿคจ', 'face with raised eyebrow'], + ], + 'gestures' => [ + ['๐Ÿ‘‹', 'waving hand'], + ['๐Ÿคš', 'raised back of hand'], + ['๐Ÿ–๏ธ', 'hand with fingers splayed'], + ['โœ‹', 'raised hand'], + ['๐Ÿ––', 'vulcan salute'], + ['๐Ÿ‘Œ', 'OK hand'], + ['๐ŸคŒ', 'pinched fingers'], + ['๐Ÿค', 'pinching hand'], + ['โœŒ๏ธ', 'victory hand'], + ['๐Ÿคž', 'crossed fingers'], + ['๐ŸคŸ', 'love-you gesture'], + ['๐Ÿค˜', 'sign of the horns'], + ['๐Ÿค™', 'call me hand'], + ['๐Ÿ‘ˆ', 'backhand index pointing left'], + ['๐Ÿ‘‰', 'backhand index pointing right'], + ['๐Ÿ‘†', 'backhand index pointing up'], + ['๐Ÿ–•', 'middle finger'], + ['๐Ÿ‘‡', 'backhand index pointing down'], + ['โ˜๏ธ', 'index pointing up'], + ['๐Ÿ‘', 'thumbs up'], + ['๐Ÿ‘Ž', 'thumbs down'], + ['โœŠ', 'raised fist'], + ['๐Ÿ‘Š', 'oncoming fist'], + ['๐Ÿค›', 'left-facing fist'], + ['๐Ÿคœ', 'right-facing fist'], + ], + 'nature' => [ + ['โ˜€๏ธ', 'sun'], + ['๐ŸŒค๏ธ', 'sun behind small cloud'], + ['โ›…', 'sun behind cloud'], + ['๐ŸŒฅ๏ธ', 'sun behind large cloud'], + ['๐ŸŒฆ๏ธ', 'sun behind rain cloud'], + ['๐ŸŒง๏ธ', 'cloud with rain'], + ['๐ŸŒจ๏ธ', 'cloud with snow'], + ['โ„๏ธ', 'snowflake'], + ['๐ŸŒฉ๏ธ', 'cloud with lightning'], + ['๐ŸŒช๏ธ', 'tornado'], + ['๐ŸŒˆ', 'rainbow'], + ['๐Ÿ”ฅ', 'fire'], + ['๐Ÿ’ง', 'droplet'], + ['๐ŸŒŠ', 'water wave'], + ['๐ŸŒซ๏ธ', 'fog'], + ['๐ŸŒฌ๏ธ', 'wind face'], + ['๐Ÿƒ', 'leaf fluttering in wind'], + ['๐Ÿ‚', 'fallen leaf'], + ['๐Ÿ', 'maple leaf'], + ['๐ŸŒพ', 'sheaf of rice'], + ['๐ŸŒต', 'cactus'], + ['๐ŸŒด', 'palm tree'], + ['๐ŸŒณ', 'deciduous tree'], + ['๐ŸŒฒ', 'evergreen tree'], + ['๐ŸŒธ', 'cherry blossom'], + ], + 'animals' => [ + ['๐Ÿถ', 'dog face'], + ['๐Ÿฑ', 'cat face'], + ['๐Ÿญ', 'mouse face'], + ['๐Ÿน', 'hamster face'], + ['๐Ÿฐ', 'rabbit face'], + ['๐ŸฆŠ', 'fox face'], + ['๐Ÿป', 'bear face'], + ['๐Ÿผ', 'panda face'], + ['๐Ÿจ', 'koala'], + ['๐Ÿฏ', 'tiger face'], + ['๐Ÿฆ', 'lion face'], + ['๐Ÿฎ', 'cow face'], + ['๐Ÿท', 'pig face'], + ['๐Ÿธ', 'frog face'], + ['๐Ÿต', 'monkey face'], + ['๐Ÿ™ˆ', 'see-no-evil monkey'], + ['๐Ÿ™‰', 'hear-no-evil monkey'], + ['๐Ÿ™Š', 'speak-no-evil monkey'], + ['๐Ÿ”', 'chicken'], + ['๐Ÿง', 'penguin'], + ['๐Ÿฆ', 'bird'], + ['๐Ÿค', 'baby chick'], + ['๐Ÿฃ', 'hatching chick'], + ['๐Ÿบ', 'wolf face'], + ['๐Ÿฆ„', 'unicorn face'], + ], + 'people' => [ + ['๐Ÿง‘', 'person'], + ['๐Ÿ‘ฉ', 'woman'], + ['๐Ÿ‘จ', 'man'], + ['๐Ÿ‘ถ', 'baby'], + ['๐Ÿ‘ง', 'girl'], + ['๐Ÿ‘ฆ', 'boy'], + ['๐Ÿง’', 'child'], + ['๐Ÿ‘ต', 'older woman'], + ['๐Ÿ‘ด', 'older man'], + ['๐Ÿง“', 'older adult'], + ['๐Ÿ‘ฒ', 'person with skullcap'], + ['๐Ÿง•', 'woman with headscarf'], + ['๐Ÿ‘ณ', 'person wearing turban'], + ['๐Ÿ‘ฎ', 'police officer'], + ['๐Ÿ•ต๏ธ', 'detective'], + ['๐Ÿ‘ท', 'construction worker'], + ['๐Ÿ’‚', 'guard'], + ['๐Ÿ‘ธ', 'princess'], + ['๐Ÿคด', 'prince'], + ['๐Ÿฆธ', 'superhero'], + ['๐Ÿฆน', 'supervillain'], + ['๐Ÿง™', 'mage'], + ['๐Ÿง›', 'vampire'], + ['๐ŸงŸ', 'zombie'], + ['๐Ÿงž', 'genie'], + ], + 'emotions' => [ + ['โค๏ธ', 'red heart'], + ['๐Ÿงก', 'orange heart'], + ['๐Ÿ’›', 'yellow heart'], + ['๐Ÿ’š', 'green heart'], + ['๐Ÿ’™', 'blue heart'], + ['๐Ÿ’œ', 'purple heart'], + ['๐Ÿ–ค', 'black heart'], + ['๐Ÿค', 'white heart'], + ['๐ŸคŽ', 'brown heart'], + ['๐Ÿ’–', 'sparkling heart'], + ['๐Ÿ’—', 'growing heart'], + ['๐Ÿ’“', 'beating heart'], + ['๐Ÿ’ž', 'revolving hearts'], + ['๐Ÿ’•', 'two hearts'], + ['๐Ÿ’˜', 'heart with arrow'], + ['๐Ÿ’', 'heart with ribbon'], + ['๐Ÿ’”', 'broken heart'], + ['โฃ๏ธ', 'heart exclamation'], + ['๐Ÿ’Ÿ', 'heart decoration'], + ['๐Ÿ’ค', 'zzz'], + ['๐Ÿคฏ', 'exploding head'], + ['๐Ÿ˜ฑ', 'face screaming in fear'], + ['๐Ÿฅต', 'hot face'], + ['๐Ÿฅถ', 'cold face'], + ['๐Ÿคฌ', 'face with symbols on mouth'], + ], + 'activities' => [ + ['๐Ÿšด', 'person biking'], + ['๐Ÿšต', 'person mountain biking'], + ['๐Ÿƒ', 'person running'], + ['๐Ÿƒโ€โ™€๏ธ', 'woman running'], + ['๐Ÿ‹๏ธ', 'person lifting weights'], + ['๐ŸŠ', 'person swimming'], + ['๐Ÿ„', 'person surfing'], + ['๐Ÿšฃ', 'person rowing boat'], + ['๐Ÿคฝ', 'person playing water polo'], + ['๐Ÿคพ', 'person playing handball'], + ['โ›น๏ธ', 'person bouncing ball'], + ['๐Ÿคธ', 'person cartwheeling'], + ['๐Ÿง˜', 'person in lotus position'], + ['๐Ÿ‡', 'horse racing'], + ['๐Ÿง—', 'person climbing'], + ['๐Ÿ•๏ธ', 'camping'], + ['๐ŸŽฃ', 'fishing pole'], + ['โ›บ', 'tent'], + ['๐ŸŽฟ', 'skis'], + ['๐Ÿ‚', 'snowboarder'], + ['๐Ÿ›น', 'skateboard'], + ['๐Ÿ›ผ', 'roller skate'], + ['๐Ÿงบ', 'basket'], + ['๐ŸŽฏ', 'bullseye'], + ['๐ŸŒ๏ธ', 'person golfing'], + ], + 'hobbies' => [ + ['๐Ÿ“š', 'books'], + ['๐Ÿ“–', 'open book'], + ['๐ŸŽง', 'headphone'], + ['๐ŸŽต', 'musical note'], + ['๐ŸŽถ', 'musical notes'], + ['๐ŸŽค', 'microphone'], + ['๐ŸŽผ', 'musical score'], + ['๐ŸŽท', 'saxophone'], + ['๐ŸŽธ', 'guitar'], + ['๐ŸŽน', 'musical keyboard'], + ['๐ŸŽบ', 'trumpet'], + ['๐ŸŽป', 'violin'], + ['๐Ÿช•', 'banjo'], + ['โœ๏ธ', 'writing hand'], + ['๐Ÿ–Š๏ธ', 'pen'], + ['๐Ÿ“', 'memo'], + ['๐Ÿ“ท', 'camera'], + ['๐Ÿ“ธ', 'camera with flash'], + ['๐ŸŽจ', 'artist palette'], + ['๐Ÿงต', 'thread'], + ['๐Ÿงถ', 'yarn'], + ['๐Ÿชก', 'sewing needle'], + ['๐Ÿ“น', 'video camera'], + ['๐ŸŽฌ', 'clapper board'], + ['๐Ÿงฉ', 'puzzle piece'], + ], + 'tech' => [ + ['๐Ÿ’ป', 'laptop'], + ['๐Ÿ–ฅ๏ธ', 'desktop computer'], + ['๐Ÿ–จ๏ธ', 'printer'], + ['๐Ÿ–ฑ๏ธ', 'computer mouse'], + ['โŒจ๏ธ', 'keyboard'], + ['๐Ÿ“ฑ', 'mobile phone'], + ['๐Ÿ“ฒ', 'mobile phone with arrow'], + ['๐Ÿ“ž', 'telephone receiver'], + ['โ˜Ž๏ธ', 'telephone'], + ['๐Ÿ“Ÿ', 'pager'], + ['๐Ÿ“ ', 'fax machine'], + ['๐Ÿ”‹', 'battery'], + ['๐Ÿ”Œ', 'electric plug'], + ['๐Ÿ’ฝ', 'computer disk'], + ['๐Ÿ’พ', 'floppy disk'], + ['๐Ÿ’ฟ', 'optical disk'], + ['๐Ÿ“€', 'dvd'], + ['๐Ÿงฎ', 'abacus'], + ['๐Ÿ•น๏ธ', 'joystick'], + ['๐Ÿ“ก', 'satellite antenna'], + ['๐Ÿ”', 'magnifying glass tilted left'], + ['๐Ÿ”Ž', 'magnifying glass tilted right'], + ['๐Ÿงญ', 'compass'], + ['๐Ÿ“Š', 'bar chart'], + ['๐Ÿ“ˆ', 'chart increasing'], + ], + 'travel' => [ + ['โœˆ๏ธ', 'airplane'], + ['๐Ÿ›ซ', 'airplane departure'], + ['๐Ÿ›ฌ', 'airplane arrival'], + ['๐Ÿš—', 'automobile'], + ['๐Ÿš•', 'taxi'], + ['๐Ÿš™', 'sport utility vehicle'], + ['๐ŸšŒ', 'bus'], + ['๐ŸšŽ', 'trolleybus'], + ['๐ŸŽ๏ธ', 'racing car'], + ['๐Ÿš“', 'police car'], + ['๐Ÿš‘', 'ambulance'], + ['๐Ÿš’', 'fire engine'], + ['๐Ÿš', 'minibus'], + ['๐Ÿ›ป', 'pickup truck'], + ['๐Ÿšš', 'delivery truck'], + ['๐Ÿš›', 'articulated lorry'], + ['๐Ÿšœ', 'tractor'], + ['๐Ÿšฒ', 'bicycle'], + ['๐Ÿ›ด', 'kick scooter'], + ['๐Ÿšจ', 'police car light'], + ['โ›ต', 'sailboat'], + ['๐Ÿšค', 'speedboat'], + ['๐Ÿ›ณ๏ธ', 'passenger ship'], + ['โ›ด๏ธ', 'ferry'], + ['๐Ÿš', 'helicopter'], + ], + 'food' => [ + ['๐ŸŽ', 'red apple'], + ['๐ŸŒ', 'banana'], + ['๐Ÿ‡', 'grapes'], + ['๐Ÿ“', 'strawberry'], + ['๐Ÿ‰', 'watermelon'], + ['๐Ÿ', 'pineapple'], + ['๐Ÿฅญ', 'mango'], + ['๐Ÿ‘', 'peach'], + ['๐Ÿ’', 'cherries'], + ['๐Ÿ…', 'tomato'], + ['๐Ÿฅฆ', 'broccoli'], + ['๐Ÿฅ•', 'carrot'], + ['๐ŸŒฝ', 'ear of corn'], + ['๐Ÿฅ”', 'potato'], + ['๐Ÿž', 'bread'], + ['๐Ÿฅ', 'croissant'], + ['๐Ÿฅ–', 'baguette bread'], + ['๐Ÿง€', 'cheese wedge'], + ['๐Ÿ•', 'pizza'], + ['๐Ÿ”', 'hamburger'], + ['๐ŸŸ', 'french fries'], + ['๐ŸŒญ', 'hot dog'], + ['๐Ÿฅช', 'sandwich'], + ['๐ŸŒฎ', 'taco'], + ['๐Ÿฃ', 'sushi'], + ], + + //'custom' => get_user_emojis($db), + ]; +} diff --git a/tkr/lib/mood.php b/tkr/lib/mood.php new file mode 100644 index 0000000..4b1c44d --- /dev/null +++ b/tkr/lib/mood.php @@ -0,0 +1,67 @@ +prepare("SELECT mood FROM user WHERE username=?"); + $stmt->execute([$_SESSION['username']]); + $row = $stmt->fetch(); + + return $row['mood']; +} + +function save_mood(string $mood): void { + $config = Config::load(); + $db = get_db(); + + $stmt = $db->prepare("UPDATE user SET mood=? WHERE username=?"); + $stmt->execute([$mood, $_SESSION['username']]); + + header("Location: $config->basePath"); + exit; +} + +function render_emoji_tabs(?string $selected_emoji = null): string { + $emoji_groups = get_emojis_with_labels(); + + ob_start(); + ?> + + $emojis): ?> +
+ + + + +
+ +
+ + + +
+ <?= $config->siteTitle ?> - +

siteDescription ?>

@@ -55,9 +50,9 @@ $ticks = iterator_to_array(stream_ticks($limit, $offset)); - +

Current mood: | Set your mood

Logout

diff --git a/tkr/public/login.php b/tkr/public/login.php index 0f6ddd4..fb02e53 100644 --- a/tkr/public/login.php +++ b/tkr/public/login.php @@ -1,7 +1,9 @@ basePath); exit; \ No newline at end of file diff --git a/tkr/public/set_mood.php b/tkr/public/set_mood.php new file mode 100644 index 0000000..574e858 --- /dev/null +++ b/tkr/public/set_mood.php @@ -0,0 +1,44 @@ +basePath); + exit; +} +?> + + + + + <?= $config->siteTitle ?> + + + + + +

How are you feeling?

+ + + + Back to home + + \ No newline at end of file