From f4273935cb6f30133dc6baa3cafe428ea263d408 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Thu, 23 May 2024 22:06:16 -0400 Subject: [PATCH] Add item bookmark buttons (#14) Implemented as a toggle button - Move init_cap func where web can see it - Bump version to alpha7 --- src/app-config.php | 16 ++++++++- src/cli-start.php | 14 -------- src/public/assets/bookmark-add.png | Bin 0 -> 1776 bytes src/public/assets/bookmark-added.png | Bin 0 -> 1984 bytes src/public/assets/style.css | 32 ++++++++++++++--- src/public/bookmark.php | 49 +++++++++++++++++++++++++++ src/public/feed/items.php | 1 + src/public/item.php | 2 ++ 8 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 src/public/assets/bookmark-add.png create mode 100644 src/public/assets/bookmark-added.png create mode 100644 src/public/bookmark.php diff --git a/src/app-config.php b/src/app-config.php index bc29c5a..76994d9 100644 --- a/src/app-config.php +++ b/src/app-config.php @@ -1,7 +1,7 @@ "", + 1 => strtoupper($value), + default => strtoupper(substr($value, 0, 1)) . substr($value, 1), + }; +} diff --git a/src/cli-start.php b/src/cli-start.php index 5a61045..b6dda7e 100644 --- a/src/cli-start.php +++ b/src/cli-start.php @@ -28,17 +28,3 @@ function cli_title(string $title): void { printfn(' | %s | %s |', $title, $appTitle); printfn($dashes . PHP_EOL); } - -/** - * Capitalize the first letter of the given string - * - * @param string $value The string to be capitalized - * @return string The given string with the first letter capitalized - */ -function init_cap(string $value): string { - return match (strlen($value)) { - 0 => "", - 1 => strtoupper($value), - default => strtoupper(substr($value, 0, 1)) . substr($value, 1), - }; -} diff --git a/src/public/assets/bookmark-add.png b/src/public/assets/bookmark-add.png new file mode 100644 index 0000000000000000000000000000000000000000..c50719a12cb3eb0784492661f703dd4b09824c3e GIT binary patch literal 1776 zcma(}dpMhU7XE$7mxxP9gUTQTsqIp?luE0K4^d(sChoVYSc7O)(?@GXwEdV>6cvV+ zXRJgV7@Ta8O;U3PW;+W&UXdCvPj=e+NE^LTzE9tJCBVxaH2!M*8vyv*T#j2%+OhelFY~FMdfN;3l0sOW z-bTU=W#=c+Nd&fK+i)Qvi$gk7&?HsZQMRzQ8C{`4Bt19Sxow!sgC95CmAk9MN2Qr) zi7&sLS%2!)jg8mmgMve=|33Mz6BJ7P%*V>6_LP~RSChJn4u!I=mAQi=3FzS>m>t|@ z&pu}b)cMBH+u{2Ec^LGBlJP=2RE^QnYn0bJJ^VTmEbU*vHwiQG3K+E*t>|lRB(g<= z+5xe2cwD90km4{ISjF!~$k%Zzch7l)!7_5dzH9I19Ry?<_J+j#R7}>`X`4xXS62fv zt*eb1HwInz8Lv7LNJrdD2ipX$wNIh~waBzzB7B3lam~&#Vng3zkjHDM%DOox6AyS` z=1RZS;CQ}CqjNd6Z%b8|c10YF$4SY^gtGXmxuJZ zfJ`gJrXEH1GPe4??520zv6hfIvfM!a?5)CD8(94JY5`54R;ilY`&vV(1&tI>RQ-TU za=L>K37Yf6JAF>H=s6f~K*Ff)&$JkTkC1Epw?(^2S*ntz@#mj7Q>`^+%Rl};n^JQ`ZLSsl*$KgwW85)+V~*~z?vFxO zqtH>E90p#H3mxALN6AW_q|1fpl37Jd8<3%14H+9rz<9_RY2hY#qW0<6R0$AGCM*uc zxuGSxHJX%{)1%sVX-J|s9jM!X8pK;&YklNmg@h=dnQE!m6p2DuCE$~iZ=Ra~tw!sG zPY@mS8#?Sq)29<@`Z8r`ciTPmqF6ZW8Y#!}ASt+|Uo$!u0Nq*))52()BAD?#h(ih) zg(+L%;2Q*=sfD@5L4_IlRk`9a zbwDzSBx8RjCWV@`fpc*ov&FXPA1!Os6to(2ah`?gy8R%V2$?MkZWV%|(!F8it0v%;QRX~W5eUpi2 zVHGS8t@eD@$`7-bqyQlNH}mD6&V=81`|k@bo}{?-`h>`US1KcqkbhjXNlFFd&iGax zSw5)p;Y-^r+rc7)R*PG{!ch>Y3b#l`Jy=@00jobz<3y&idb6^l;p7@nyM36+ffn%1 z3!59hyDobBzq^#L%YNZs`G#dghtjQNb)X8nSpFwPM0Yz*s3H3+mAV^NrNuUP-$S3j zR~w%V**Fc>UIOOh{HwZ-4hf6PfQ_f!UW_JwAq9|zkPsHGc0XFRoHaeW6eN& z(4fSGDvDIK zQbwtGZ&40RXud4pk`sx?QZp zFBshYutadoTvYrqKlXn5)0Ydv1-E4Trw?+5bP>N^j`H2+^}&@*kD!>;y2KV(va$Y` zbyLA=1ZS}aBTQu literal 0 HcmV?d00001 diff --git a/src/public/assets/bookmark-added.png b/src/public/assets/bookmark-added.png new file mode 100644 index 0000000000000000000000000000000000000000..b7d1e05b99aee23b5be8e0c003418bc9c27ea219 GIT binary patch literal 1984 zcmb_dX;71C5`MoVJUb;PrYpP|A z*&=Pj;V*4E>GsNKU{X{#%l8=ZEWgG6s*G-TzAsv7rM(LKS@QCb^l&{c=T<|};|t)3 z3IrK~>oMGr1sw=)H>F=8jy(WSZp}E8-NkA!I5L~~^w}BA|D>$CZ$+Gd2*-J{huQ#^ zBgCrtF}7+k2z|mAExpiN6N=`bVJc`yHWv%xSOx*knsbr}aQyb`-nu6N;#9y_@d@TN z*u>qmXjW?tFg~^IZCap9_y}aj-5PKvYNnHW#U7$mnbmKYEbh} z#YheD=u!FK^Q?%?Cc60|jFu2Ot z?`0M6UR1inerH7ZoGVcKmA>i@ZGSjM*rQAF|Hm8wVY+nhHP$Q!HwWg(@Km;MbMusu zmRzEx(&&dR?aBsqyWV~dyCm@#ir(ghO)Axk3? zLcVVPKG2Y?S-iuLzuW^NyDa?;FtTwiJdzXlmKf%2p+F%>4^I^et?{2b*gvjb2w9_W zouTt3a4?g)k=*|s#zz!82%x|n`7{No+Nom!#;RRelqaMRy3GQ?E={<2t{D44@F0pK ztQgN91VZF#-Yf&r2!egSDOM2d_CA`BIz66`0^FQ9F!weT=zk2l#kxX|MR7l^b5nMr zn%HhV8HHEV*+fMBCn_=Whh5Y~4YH}kbhc*chMtk8L?7m1r$>7kR^U-*HTp%>7N*GT zNkLz@v{cOy^cW(lC=DrrZ3)HqV!NIA#Zd)106piUL^38leK6CQ zOf_Wkc(|!%ofUi|0%aIe(jnz7L`qa7Ye2uV=$xdnaeaayb3(( za-OB&81^7`(<^(?B^Y+tRmfHDKGomx2A5bfwk|y+e0N z@I`QZlF<|5hq*DFlFeR;M4ydGhiy+}b<;iw)+&^NV2!r`Cybu9F^%@rlI?6qg$7D_{u9ib21f;2#n zIX`(Fu+W_Ae~$h1jE3R>q_c={e+RrTF`wErP&m^93WCa}k*Ij^VIxRaOsK#7d;|Q8 z(q$kzf3@$MZVALhyoMLCM|Vs!!WYD~`fYw%ne#QdyEo(AEv;~n+i``iFJbg$A+{*l zcVvxI(u%Q*FQ&RO)?eNS80-pFHupPv?89gIMN*42Umc9M-NsvjVka)<)-pm5TB)j< z_gkr)U8qGTp3u;d)>*jZlXn6o8w{-R`e9>EU=S$wvs!1j-3y*rQ}OB z(F^sqI?4Dnm7rtHtYeh7d?8x&p`qz)$F_R~GxKXB>RI_C?Z$r9`go+^uDa}$$COar zlkL;j!CDAB8*KW%Eq}nSm)lt+WlQ1l~)njlNZrc!F3{f zq72!68^>HmuU}K+YvS4#sX-N3@Q1AIYA!j!sC2sxk0vZj9Wi@-atz9D@e64Xeht;{ zoK5K3+#^fpB`erjyV93`{3H4{&OE}ftBmhtqQ}XK6NJrgQCb05Vk@pY_7nk@1UHbE q07Q<6@*%0icRrF&DF0u@v-O+&k?f>46&?9Y22T53>3j!f(!T%=ZFDRE literal 0 HcmV?d00001 diff --git a/src/public/assets/style.css b/src/public/assets/style.css index d63410c..da1fefa 100644 --- a/src/public/assets/style.css +++ b/src/public/assets/style.css @@ -79,10 +79,6 @@ main { margin-top: .25rem; } - .item_heading { - margin-bottom: 0; - } - .item_published { margin-bottom: 1rem; line-height: 1.2; @@ -153,3 +149,31 @@ code { p.back-link { margin-top: -1rem; } +.item_heading { + margin-bottom: 0; + + .bookmark { + padding: 0; + border: solid 1px black; + border-radius: .5rem; + + &.add { + background-color: lightgray; + :hover { + background: linear-gradient(lightgreen, gray); + } + } + &.remove { + background: linear-gradient(lightgreen, green); + :hover { + background: linear-gradient(gray, lightgreen); + } + } + + img { + max-width: 1.5rem; + max-height: 1.5rem; + padding: .5rem; + } + } +} diff --git a/src/public/bookmark.php b/src/public/bookmark.php new file mode 100644 index 0000000..4c16617 --- /dev/null +++ b/src/public/bookmark.php @@ -0,0 +1,49 @@ +prepare( + 'SELECT item.id FROM item INNER JOIN feed ON feed.id = item.feed_id WHERE item.id = :id AND feed.user_id = :user'); +$existsQuery->bindValue(':id', $id); +$existsQuery->bindValue(':user', $_SESSION[Key::USER_ID]); +$existsResult = $existsQuery->execute(); +$exists = $existsResult ? $existsResult->fetchArray(SQLITE3_ASSOC) : false; + +if (!$exists) not_found(); + +if (key_exists('action', $_GET)) { + if ($_GET['action'] == 'add') { + $flag = 1; + } elseif ($_GET['action'] == 'remove') { + $flag = 0; + } + if (isset($flag)) { + $update = $db->prepare('UPDATE item SET is_bookmarked = :flag WHERE id = :id'); + $update->bindValue(':id', $id); + $update->bindValue(':flag', $flag); + if (!$update->execute()) die(Data::error($db)['error']); + } +} + +$bookQuery = $db->prepare('SELECT id, is_bookmarked FROM item WHERE id = :id'); +$bookQuery->bindValue(':id', $id); +$bookResult = $bookQuery->execute(); +$bookmark = $bookResult ? $bookResult->fetchArray(SQLITE3_ASSOC) : ['id' => $id, 'is_bookmarked' => 0]; + +$action = $bookmark['is_bookmarked'] ? 'remove' : 'add'; +$icon = $bookmark['is_bookmarked'] ? 'added' : 'add'; ?> + while ($item) { ?>


New   ' : ''?> + Bookmarked   ' : ''?> fetchArray(SQLITE3_ASSOC); } diff --git a/src/public/item.php b/src/public/item.php index 21659c9..3633f87 100644 --- a/src/public/item.php +++ b/src/public/item.php @@ -75,6 +75,8 @@ $updated = isset($item['updated_on']) ? date_time($item['updated_on']) : null; page_head(htmlentities("{$item['item_title']} | {$item['feed_title']}")); ?>

+