From 58dd7a4ffb316c0f73c5d323a0e324161d60fe3b Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Sun, 26 May 2024 16:56:30 -0400 Subject: [PATCH] Add bookmark item search (#15) - Implement form styling throughout - Modify header links for narrower views - Clean up CSS --- src/lib/ItemList.php | 11 ++-- src/public/assets/style.css | 102 ++++++++++++++++++++++-------------- src/public/feed/index.php | 3 +- src/public/search.php | 30 +++++++++-- src/public/user/log-on.php | 5 +- src/start.php | 23 +++++--- 6 files changed, 116 insertions(+), 58 deletions(-) diff --git a/src/lib/ItemList.php b/src/lib/ItemList.php index 4bb4c29..2f9866b 100644 --- a/src/lib/ItemList.php +++ b/src/lib/ItemList.php @@ -138,13 +138,16 @@ class ItemList { * Create an item list with items matching given search terms * * @param string $search The item search terms / query + * @param bool $isBookmarked Whether to restrict the search to bookmarked items * @param SQLite3 $db The database connection to use to obtain items * @return static An item list match the given search terms */ - public static function matchingSearch(string $search, SQLite3 $db): static { - $list = new static($db, - self::makeQuery($db, ['item.id IN (SELECT ROWID FROM item_search WHERE content MATCH :search)'], - [[':search', $search]]), 'Matching', "/search?search=$search"); + public static function matchingSearch(string $search, bool $isBookmarked, SQLite3 $db): static { + $where = $isBookmarked ? ['item.is_bookmarked = 1'] : []; + $where[] = 'item.id IN (SELECT ROWID FROM item_search WHERE content MATCH :search)'; + $list = new static($db, self::makeQuery($db, $where, [[':search', $search]]), + 'Matching' . ($isBookmarked ? ' Bookmarked' : ''), + "/search?search=$search&items=" . ($isBookmarked ? 'bookmarked' : 'all')); $list->showIndicators = true; $list->displayFeed = true; return $list; diff --git a/src/public/assets/style.css b/src/public/assets/style.css index f12b9bd..22e8d88 100644 --- a/src/public/assets/style.css +++ b/src/public/assets/style.css @@ -25,28 +25,28 @@ header { flex-flow: row wrap; justify-content: space-between; align-items: baseline; - - div { + div, nav { margin-bottom: .25rem; } - .title { font-size: 1.5rem; } - .version { font-size: .85rem; padding-left: .5rem; color: rgba(255, 255, 255, .75); } - a:link, a:visited { color: white; } + nav { + display: flex; + flex-flow: row wrap; + gap: 0 .4rem; + } } main { padding: 0 .5rem; - .refresh, .loading { font-style: italic; font-size: .9rem; @@ -54,14 +54,12 @@ main { .htmx-request .refresh { display: none; } - .loading { display: none; } .htmx-request .loading { display: inline; } - .user_messages { display: flex; flex-flow: column; @@ -74,11 +72,9 @@ main { background-color: rgba(255, 255, 255, .75); padding: .25rem; } - .user_messages + h1 { margin-top: .25rem; } - .item_published { margin-bottom: 1rem; line-height: 1.2; @@ -87,35 +83,73 @@ main { article { max-width: 60rem; margin: auto; - .item_content { border: solid 1px navy; border-radius: .5rem; background-color: white; padding: .5rem; - img { max-width: 100%; object-fit: contain; } } - .meta { font-size: .9rem; } + &.docs { + line-height: 1.4rem; + } } -article.docs { - line-height: 1.4rem; +form { + display: flex; + flex-flow: row wrap; + justify-content: center; + gap: 0 2rem; + label { + font-size: .9rem; + font-weight: bold; + input, select { + display: block; + } + } + .break { + flex-basis: 100%; + height: 1rem; + width: 0; + } + input[type=url], + input[type=text], + input[type=email], + input[type=password], + select { + min-width: 12rem; + max-width: 100%; + font-size: 1rem; + padding: .25rem; + border-radius: .25rem; + background-color: white; + border: solid 2px navy; + } + select { + min-width: unset; + max-width: unset; + } } - -input[type=url], -input[type=text], -input[type=email], -input[type=password] { - width: 40%; - font-size: 1rem; - padding: .25rem; - border-radius: .25rem; +@media all and (min-width: 60rem) { + form { + input[type=url], + input[type=text], + input[type=email], + input[type=password] { + min-width: 25rem; + } + } +} +.action_buttons { + margin: 1rem 0; + display: flex; + flex-flow: row nowrap; + justify-content: space-evenly; } button, .action_buttons a:link, @@ -128,18 +162,11 @@ button, border-radius: .25rem; cursor: pointer; border: none; -} -button:hover, -.action_buttons a:hover { - text-decoration: none; - cursor: pointer; - background: linear-gradient(navy, #000032); -} -.action_buttons { - margin: 1rem 0; - display: flex; - flex-flow: row nowrap; - justify-content: space-evenly; + &:hover { + text-decoration: none; + cursor: pointer; + background: linear-gradient(navy, #000032); + } } code { font-size: .9rem; @@ -149,12 +176,10 @@ p.back-link { } .item_heading { margin-bottom: 0; - .bookmark { padding: 0; border: solid 1px black; border-radius: .5rem; - &.add { background-color: lightgray; &:hover { @@ -167,7 +192,6 @@ p.back-link { background: linear-gradient(gray, lightgreen); } } - img { max-width: 1.5rem; max-height: 1.5rem; diff --git a/src/public/feed/index.php b/src/public/feed/index.php index dd84544..f9dba42 100644 --- a/src/public/feed/index.php +++ b/src/public/feed/index.php @@ -61,7 +61,8 @@ page_head($title); ?>
+ +

Item Search

-// TODO: search form render(); +
+
+ + + + +
+
render(); + } ?> +
close(); diff --git a/src/public/user/log-on.php b/src/public/user/log-on.php index 4a9c60d..3133f0f 100644 --- a/src/public/user/log-on.php +++ b/src/public/user/log-on.php @@ -26,12 +26,13 @@ page_head('Log On'); ?>

+ + $sep$link"; +} + /** * Render the title bar for the page */ @@ -52,7 +57,7 @@ function title_bar(): void { }; ?>
Feed Reader Centralv
-
bindValue(':id', $_SESSION[Key::USER_ID]); $bookResult = $bookQuery->execute(); $hasBookmarks = $bookResult && $bookResult->fetchArray(SQLITE3_NUM)[0]; - echo hx_get('/feeds', 'Feeds') . ' | '; - if ($hasBookmarks) echo hx_get('/?bookmarked', 'Bookmarked') . ' | '; - echo hx_get('/search', 'Search') . ' | ' . hx_get('/docs/', 'Docs') - . ' | Log Off'; + nav_link(hx_get('/feeds', 'Feeds'), true); + if ($hasBookmarks) nav_link(hx_get('/?bookmarked', 'Bookmarked')); + nav_link(hx_get('/search', 'Search')); + nav_link(hx_get('/docs/', 'Docs')); + nav_link('Log Off'); if ($_SESSION[Key::USER_EMAIL] != Security::SINGLE_USER_EMAIL) { - echo " | {$_SESSION[Key::USER_EMAIL]}"; + nav_link($_SESSION[Key::USER_EMAIL]); } } finally { $db->close(); } } else { - echo hx_get('/user/log-on', 'Log On') . ' | ' . hx_get('/docs/', 'Docs'); + nav_link(hx_get('/user/log-on', 'Log On'), true); + nav_link(hx_get('/docs/', 'Docs')); } ?> -
+