From 92098a793e91a7fb818ca3213641eaf8b5f794f8 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sat, 25 Nov 2023 16:08:07 +0000 Subject: [PATCH] feat: Add webmention counts and icons for replies, likes, and reposts. - Add new SVG icons for the "reply", "like", and "repost" actions - Update webmention info display in note template to include counts and icons for replies, likes, and reposts - Add webmention counts to FrontPageController.php and modify queries in NotesController.php - Modify WebMentionsTableSeeder.php to change URLs, commentable ID, and add new WebMentions --- app/Http/Controllers/FrontPageController.php | 12 ++++- app/Http/Controllers/NotesController.php | 19 +++++++- app/Http/Controllers/SearchController.php | 11 ++++- database/seeders/NotesTableSeeder.php | 2 +- database/seeders/WebMentionsTableSeeder.php | 27 +++++++---- public/assets/app.css | 2 +- public/assets/app.css.br | Bin 1036 -> 1347 bytes resources/css/app.css | 1 + resources/css/content.css | 29 ++++++++++++ resources/css/notes.css | 38 ++++++++++++++++ resources/views/icons/like.blade.php | 1 + resources/views/icons/reply.blade.php | 1 + resources/views/icons/repost.blade.php | 1 + resources/views/notes/show.blade.php | 45 +++++++++++-------- resources/views/templates/note.blade.php | 25 +++++++++++ 15 files changed, 179 insertions(+), 35 deletions(-) create mode 100644 resources/css/notes.css create mode 100644 resources/views/icons/like.blade.php create mode 100644 resources/views/icons/reply.blade.php create mode 100644 resources/views/icons/repost.blade.php diff --git a/app/Http/Controllers/FrontPageController.php b/app/Http/Controllers/FrontPageController.php index 191887a9..9d236bdc 100644 --- a/app/Http/Controllers/FrontPageController.php +++ b/app/Http/Controllers/FrontPageController.php @@ -20,9 +20,17 @@ class FrontPageController extends Controller */ public function index(): Response|View { - $notes = Note::latest()->with(['media', 'client', 'place'])->get(); + $notes = Note::latest()->with(['media', 'client', 'place'])->withCount(['webmentions AS replies' => function ($query) { + $query->where('type', 'in-reply-to'); + }]) + ->withCount(['webmentions AS likes' => function ($query) { + $query->where('type', 'like-of'); + }]) + ->withCount(['webmentions AS reposts' => function ($query) { + $query->where('type', 'repost-of'); + }])->get(); $articles = Article::latest()->get(); - $bookmarks = Bookmark::latest()->get(); + $bookmarks = Bookmark::latest()->with('tags')->get(); $likes = Like::latest()->get(); $items = collect($notes) diff --git a/app/Http/Controllers/NotesController.php b/app/Http/Controllers/NotesController.php index 834ce907..bef422cb 100644 --- a/app/Http/Controllers/NotesController.php +++ b/app/Http/Controllers/NotesController.php @@ -26,8 +26,14 @@ class NotesController extends Controller { $notes = Note::latest() ->with('place', 'media', 'client') - ->withCount(['webmentions As replies' => function ($query) { + ->withCount(['webmentions AS replies' => function ($query) { $query->where('type', 'in-reply-to'); + }]) + ->withCount(['webmentions AS likes' => function ($query) { + $query->where('type', 'like-of'); + }]) + ->withCount(['webmentions AS reposts' => function ($query) { + $query->where('type', 'repost-of'); }])->paginate(10); return view('notes.index', compact('notes')); @@ -39,7 +45,16 @@ class NotesController extends Controller public function show(string $urlId): View|JsonResponse|Response { try { - $note = Note::nb60($urlId)->with('webmentions')->firstOrFail(); + $note = Note::nb60($urlId)->with('place', 'media', 'client') + ->withCount(['webmentions AS replies' => function ($query) { + $query->where('type', 'in-reply-to'); + }]) + ->withCount(['webmentions AS likes' => function ($query) { + $query->where('type', 'like-of'); + }]) + ->withCount(['webmentions AS reposts' => function ($query) { + $query->where('type', 'repost-of'); + }])->firstOrFail(); } catch (ModelNotFoundException $exception) { abort(404); } diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 42e9e00d..a8116c88 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -20,7 +20,16 @@ class SearchController extends Controller /** @var Note $note */ foreach ($notes as $note) { - $note->load('place', 'media', 'client'); + $note->load('place', 'media', 'client') + ->loadCount(['webmentions AS replies' => function ($query) { + $query->where('type', 'in-reply-to'); + }]) + ->loadCount(['webmentions AS likes' => function ($query) { + $query->where('type', 'like-of'); + }]) + ->loadCount(['webmentions AS reposts' => function ($query) { + $query->where('type', 'repost-of'); + }]); } return view('search', compact('search', 'notes')); diff --git a/database/seeders/NotesTableSeeder.php b/database/seeders/NotesTableSeeder.php index 308eab66..e952afa2 100644 --- a/database/seeders/NotesTableSeeder.php +++ b/database/seeders/NotesTableSeeder.php @@ -145,7 +145,7 @@ class NotesTableSeeder extends Seeder $now = Carbon::now()->subHours(6); $noteWithTextLinkandEmoji = Note::create([ - 'note' => 'I love https://duckduckgo.com 💕', // there’s a two-heart emoji at the end of this + 'note' => 'I love https://kagi.com 💕', // there’s a two-heart emoji at the end of this 'created_at' => $now, ]); DB::table('notes') diff --git a/database/seeders/WebMentionsTableSeeder.php b/database/seeders/WebMentionsTableSeeder.php index facf42df..afd1ffb7 100644 --- a/database/seeders/WebMentionsTableSeeder.php +++ b/database/seeders/WebMentionsTableSeeder.php @@ -14,23 +14,32 @@ class WebMentionsTableSeeder extends Seeder */ public function run(): void { - // WebMention Aaron + // WebMention reply Aaron WebMention::create([ 'source' => 'https://aaronpk.localhost/reply/1', - 'target' => config('app.url') . '/notes/E', - 'commentable_id' => '14', + 'target' => config('app.url') . '/notes/Z', + 'commentable_id' => '5', 'commentable_type' => 'App\Models\Note', 'type' => 'in-reply-to', 'mf2' => '{"rels": [], "items": [{"type": ["h-entry"], "properties": {"url": ["https://aaronpk.localhost/reply/1"], "name": ["Hi too"], "author": [{"type": ["h-card"], "value": "Aaron Parecki", "properties": {"url": ["https://aaronpk.localhost"], "name": ["Aaron Parecki"], "photo": ["https://aaronparecki.com/images/profile.jpg"]}}], "content": [{"html": "Hi too", "value": "Hi too"}], "published": ["' . date(DATE_W3C) . '"], "in-reply-to": ["https://aaronpk.loclahost/reply/1", "' . config('app.url') .'/notes/E"]}}]}', ]); - // WebMention Tantek + // WebMention like Tantek WebMention::create([ - 'source' => 'http://tantek.com/', - 'target' => config('app.url') . '/notes/D', - 'commentable_id' => '13', + 'source' => 'https://tantek.com/likes/1', + 'target' => config('app.url') . '/notes/G', + 'commentable_id' => '16', 'commentable_type' => 'App\Models\Note', - 'type' => 'in-reply-to', - 'mf2' => '{"rels": [], "items": [{"type": ["h-entry"], "properties": {"url": ["http://tantek.com/"], "name": ["KUTGW"], "author": [{"type": ["h-card"], "value": "Tantek Celik", "properties": {"url": ["http://tantek.com/"], "name": ["Tantek Celik"]}}], "content": [{"html": "kutgw", "value": "kutgw"}], "published": ["' . date(DATE_W3C) . '"], "in-reply-to": ["' . config('app.url') . '/notes/D"]}}]}', + 'type' => 'like-of', + 'mf2' => '{"rels": [], "items": [{"type": ["h-entry"], "properties": {"url": ["https://tantek.com/likes/1"], "name": ["KUTGW"], "author": [{"type": ["h-card"], "value": "Tantek Celik", "properties": {"url": ["https://tantek.com/"], "name": ["Tantek Celik"], "photo": ["https://tantek.com/photo.jpg"]}}], "content": [{"html": "kutgw", "value": "kutgw"}], "published": ["' . date(DATE_W3C) . '"], "u-like-of": ["' . config('app.url') . '/notes/G"]}}]}', + ]); + // WebMention repost Barry + WebMention::create([ + 'source' => 'https://barryfrost.com/reposts/1', + 'target' => config('app.url') . '/notes/C', + 'commentable_id' => '12', + 'commentable_type' => 'App\Models\Note', + 'type' => 'repost-of', + 'mf2' => '{"rels": [], "items": [{"type": ["h-entry"], "properties": {"url": ["https://barryfrost.com/reposts/1"], "name": ["Kagi is the best"], "author": [{"type": ["h-card"], "value": "Barry Frost", "properties": {"url": ["https://barryfrost.com/"], "name": ["Barry Frost"], "photo": ["https://barryfrost.com/barryfrost.jpg"]}}], "content": [{"html": "Kagi is the Best", "value": "Kagi is the Best"}], "published": ["' . date(DATE_W3C) . '"], "u-repost-of": ["' . config('app.url') . '/notes/C"]}}]}', ]); } } diff --git a/public/assets/app.css b/public/assets/app.css index d04d4d8e..c935785f 100644 --- a/public/assets/app.css +++ b/public/assets/app.css @@ -1 +1 @@ -:root{--font-family-headings:"Archer SSm A","Archer SSm B",serif;--font-family-body:"Verlag A","Verlag B",sans-serif;--font-family-monospace:"Operator Mono SSm A","Operator Mono SSm B",monospace;--font-size-sm:0.75rem;--font-size-base:1rem;--font-size-md:1.25rem;--font-size-lg:1.5rem;--font-size-xl:1.75rem;--font-size-xxl:2rem;--font-size-xxxl:2.25rem;--color-primary:#334700;--color-secondary:#e3ffb7;--color-link:#00649e;--color-link-visited:#bc7aff;--color-primary-shadow:rgba(16,25,0,.4)}@supports (color:color(display-p3 0 0 0)){:root{--color-primary:color(display-p3 0.21567 0.27838 0.03615)}}@supports (color:oklab(0% 0 0)){:root{--color-primary:oklch(36.8% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-secondary:color(display-p3 0.91016 0.99842 0.74082)}}@supports (color:oklab(0% 0 0)){:root{--color-secondary:oklch(96.3% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link:color(display-p3 0.01045 0.38351 0.63618)}}@supports (color:oklab(0% 0 0)){:root{--color-link:oklch(48.09% 0.146 241.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link-visited:color(display-p3 0.70467 0.47549 0.99958)}}@supports (color:oklab(0% 0 0)){:root{--color-link-visited:oklch(70.44% 0.21 304.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-primary-shadow:color(display-p3 0.06762 0.09646 0.00441/0.4)}}@supports (color:oklab(0% 0 0)){:root{--color-primary-shadow:oklch(19.56% 0.054 125.505deg/40%)}}body{background-color:var(--color-secondary);color:var(--color-primary);font-family:var(--font-family-body);font-size:var(--font-size-md)}code{font-family:var(--font-family-monospace)}h1,h2,h3,h4,h5,h6{font-family:var(--font-family-headings)}.grid{display:grid;grid-template-columns:5vw 1fr 5vw;grid-template-rows:-webkit-min-content 1fr -webkit-min-content;grid-template-rows:min-content 1fr min-content;row-gap:1rem}#site-header{grid-column:2/3;grid-row:1/2}main{grid-column:2/3;grid-row:2/3}.h-feed{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:2rem}.h-entry h1:first-of-type,.h-entry p:first-of-type{-webkit-margin-before:0;margin-block-start:0}.pagination{-webkit-margin-before:1rem;margin-block-start:1rem}footer{grid-column:2/3;grid-row:3/4}footer .iwc-logo{max-width:85vw}footer .footer-actions{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}a{color:var(--color-link)}a:visited{color:var(--color-link-visited)}#site-header a:visited,a.auth:visited{color:var(--color-link)}.hljs{border-radius:.5rem}.h-card .hovercard{-webkit-box-orient:vertical;-webkit-box-direction:normal;background-color:var(--color-secondary);border-radius:1rem;-webkit-box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);display:none;-ms-flex-direction:column;flex-direction:column;gap:.5rem;opacity:0;padding:1rem;position:absolute;-webkit-transition:opacity .5s ease-in-out;transition:opacity .5s ease-in-out;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:100}.h-card .hovercard .u-photo{max-width:6rem}.h-card .hovercard .social-icon{height:1rem;width:1rem}.h-card:hover .hovercard{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.h-entry{-webkit-border-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;border-inline-start:1px solid var(--color-primary);padding-inline-start:.5rem}.h-entry .reply-to{font-style:italic}.h-entry .post-info a{text-decoration:none}.h-entry .note-metadata{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}.h-entry .note-metadata .syndication-links{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.h-entry .note-metadata .syndication-links a{text-decoration:none}.h-entry .note-metadata .syndication-links a svg{height:1rem;width:1rem} +:root{--font-family-headings:"Archer SSm A","Archer SSm B",serif;--font-family-body:"Verlag A","Verlag B",sans-serif;--font-family-monospace:"Operator Mono SSm A","Operator Mono SSm B",monospace;--font-size-sm:0.75rem;--font-size-base:1rem;--font-size-md:1.25rem;--font-size-lg:1.5rem;--font-size-xl:1.75rem;--font-size-xxl:2rem;--font-size-xxxl:2.25rem;--color-primary:#334700;--color-secondary:#e3ffb7;--color-link:#00649e;--color-link-visited:#bc7aff;--color-primary-shadow:rgba(16,25,0,.4)}@supports (color:color(display-p3 0 0 0)){:root{--color-primary:color(display-p3 0.21567 0.27838 0.03615)}}@supports (color:oklab(0% 0 0)){:root{--color-primary:oklch(36.8% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-secondary:color(display-p3 0.91016 0.99842 0.74082)}}@supports (color:oklab(0% 0 0)){:root{--color-secondary:oklch(96.3% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link:color(display-p3 0.01045 0.38351 0.63618)}}@supports (color:oklab(0% 0 0)){:root{--color-link:oklch(48.09% 0.146 241.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link-visited:color(display-p3 0.70467 0.47549 0.99958)}}@supports (color:oklab(0% 0 0)){:root{--color-link-visited:oklch(70.44% 0.21 304.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-primary-shadow:color(display-p3 0.06762 0.09646 0.00441/0.4)}}@supports (color:oklab(0% 0 0)){:root{--color-primary-shadow:oklch(19.56% 0.054 125.505deg/40%)}}body{background-color:var(--color-secondary);color:var(--color-primary);font-family:var(--font-family-body);font-size:var(--font-size-md)}code{font-family:var(--font-family-monospace)}h1,h2,h3,h4,h5,h6{font-family:var(--font-family-headings)}.grid{display:grid;grid-template-columns:5vw 1fr 5vw;grid-template-rows:-webkit-min-content 1fr -webkit-min-content;grid-template-rows:min-content 1fr min-content;row-gap:1rem}#site-header{grid-column:2/3;grid-row:1/2}main{grid-column:2/3;grid-row:2/3}.h-feed{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:2rem}.h-entry h1:first-of-type,.h-entry p:first-of-type{-webkit-margin-before:0;margin-block-start:0}.pagination{-webkit-margin-before:1rem;margin-block-start:1rem}footer{grid-column:2/3;grid-row:3/4}footer .iwc-logo{max-width:85vw}footer .footer-actions{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}a{color:var(--color-link)}a:visited{color:var(--color-link-visited)}#site-header a:visited,a.auth:visited{color:var(--color-link)}.hljs{border-radius:.5rem}.h-card .hovercard{-webkit-box-orient:vertical;-webkit-box-direction:normal;background-color:var(--color-secondary);border-radius:1rem;-webkit-box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);display:none;-ms-flex-direction:column;flex-direction:column;gap:.5rem;opacity:0;padding:1rem;position:absolute;-webkit-transition:opacity .5s ease-in-out;transition:opacity .5s ease-in-out;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:100}.h-card .hovercard .u-photo{max-width:6rem}.h-card .hovercard .social-icon{height:1rem;width:1rem}.h-card:hover .hovercard{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.h-entry{-webkit-border-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;border-inline-start:1px solid var(--color-primary);padding-inline-start:.5rem}.h-entry .reply-to{font-style:italic}.h-entry .post-info a{text-decoration:none}.h-entry .note-metadata{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}.h-entry .note-metadata .likes,.h-entry .note-metadata .replies,.h-entry .note-metadata .reposts{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-ms-flex-direction:row;flex-direction:row;gap:.5rem}.h-entry .note-metadata .syndication-links{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.h-entry .note-metadata .syndication-links a{text-decoration:none}.h-entry .note-metadata .syndication-links a svg{height:1rem;width:1rem}.feather{stroke:currentcolor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;fill:none;height:24px;width:24px}.sr-only{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}main>.u-comment{-webkit-margin-before:2rem;-webkit-margin-start:2rem;-webkit-border-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;border-inline-start:1px solid var(--color-primary);margin-block-start:2rem;margin-inline-start:2rem;padding-inline-start:.5rem}main>.u-comment .mini-h-card{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-ms-flex-direction:row;flex-direction:row}main>.u-comment .mini-h-card .u-photo{-webkit-margin-after:.5rem;border-radius:50%;height:2rem;margin-block-end:.5rem;width:2rem}main .notes-subtitle{font-size:1.2rem;font-weight:600}main .webmentions-author-list{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;gap:1rem}main .webmentions-author-list img{border-radius:50%;height:4rem;width:4rem} diff --git a/public/assets/app.css.br b/public/assets/app.css.br index b71b212b9b58e79e4d48533f859adcf90f24b13d..9f5f9941e06e6bd9556445dadfb91bd2b7450d36 100644 GIT binary patch literal 1347 zcmV-J1-$wjjTQhLg>l1uA|n6&Ll8v_!->jDUG`}zg{_(25S+q&sub0|Uu2R64ry$X zZB;F%xtZ8*psV0rx~m{7KYlF*+MJ7!ksDzmY+Q_sB;jsn=KVSP7vv(j@`o+616f5Z zRBfHFEKA#SvclMY46NHDQAx=EegmZtNckCwh@(Gn6D>zT-|P~ zZ1}WeD2IqLvc2wU-TJe@lCd3&d(R*Jz}p7PLMY?Gt!pf$AO9r62{j}Tx7y0J1*7P=r`zxfJ7<>~SUeRlcY^fAH^L?B zsm^b(li zc=eQACpXFMCETH_eJY;l_YASM7b=ucQ7`JSauy!f;S~Qr;_^O;V<;E>Wl(Tb_G0uC z>>{JYU{Ml5RBxSS+6>FH^_g4`B~*XZXtffPN^T(?jCh8!i#X_L-1Ft4<)%>{;W*e@ zPj*Djk6f*jLvfCRI}WCJ0(HeYH=~n2+FOPh^e?4Z1@uTtB`-ojsQFz=RpzNWU)3CZ9I+ z@)Rbu^k2o4Dp2l}ROsFm>GY37acFBFleJaCd6raQWENmr?EKkaz|WSy=#S8xHT;CI z6qQZJiJ`kf}8TDx(i4*XYqOY&{ml0Y<309f^ zk~H)4%+78z(%iFxfYuGUPAc8(|L>+yG)7%`$Az_HuIj%haW?o~=S>!7-X-`eUCx+= z@H6nAW{1cwZXpOKR1sUiEyzj8Ly(~Wh53r*>1OZEOKj)zU!a3c#F^ui){cTfREuX2 zKi@p7jzQb8+-EWnG%UQYwIH;B`NL z!%;D-!{MkJ;y@B`lgbeZ_K3H>oc$r%mdD8}XaI~WP7SShqaJ9N0;c5joL5l?`7$Za zBEdBnufIsMQ1tAY!8;!Tn5SLz)^OMSd{I9kC_x-b_4-wvzqP<}w1g)RD|*@?Vi1{* z5e2Y2BQM(+toO5En3flnUr7KnTO%Sroe{+Sr!e?jEahoZnz}rNMm(ADqpi$6%eh$a F${wtcv&8@a literal 1036 zcmV+n1oQhFHV^hp&QRIJm5g`tRiOR3p{HmpdnY@@R-}_&ss200(PGd~WS}T7> z5obF*sdeh$5#3af)xCS2&8w@B$W$1F#bF$B3D;h7xvrEY$5@V?{QKvNYi3aEe0~>#IRPidPi3wVR(BQy9Y3Gb z*b|3P4r4q4SqiZcyOs2Dnm zDs*)Ro^60Y)Ld#)=VA*DZd3x+y~i4%mM_<0D#m2IB$j1cArlrUE#0c`jEg+>!i}@ewc2B~dw<*u^RUj*|2#-G zU9Uy}Dpeg^<*a}h6+chCMUD2PRjX9DEz3xxNPiDjJ>M)Iw^w2(_TsRNBRbiqD%F2y zh)tuAri8STlD-uU6#cQpUM!|2-< z?jAcxjvw|1*2jIvyG|zFTz^g~fplt{>P%Y~iq*RF6@Qlt)T>#Xmpo57rF*Kre5}hc zy*_o~z^<4_B4-|mtJP0+fxENB_A{a&{ko`b@@b=9uEw;M{w+?aBFb*55#0-sW?l}p zL!12w*6ImkloVkm3NS5p{%kPBPfWk*kMKNt6fNRBX)rA(hHiZ*CJkwF4{PFUXl GNlyS&F8)~n diff --git a/resources/css/app.css b/resources/css/app.css index ca75b3e5..9e91b28a 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -4,3 +4,4 @@ @import url('colours.css'); @import url('code.css'); @import url('content.css'); +@import url('notes.css'); diff --git a/resources/css/content.css b/resources/css/content.css index c656acef..acbb031c 100644 --- a/resources/css/content.css +++ b/resources/css/content.css @@ -19,6 +19,15 @@ flex-direction: row; gap: 1rem; + & .replies, + & .likes, + & .reposts { + display: inline-flex; + flex-direction: row; + gap: .5rem; + align-items: center; + } + & .syndication-links { flex-flow: row wrap; @@ -33,3 +42,23 @@ } } } + +.feather { + width: 24px; + height: 24px; + stroke: currentcolor; + stroke-width: 2; + stroke-linecap: round; + stroke-linejoin: round; + fill: none; +} + +.sr-only { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; +} diff --git a/resources/css/notes.css b/resources/css/notes.css new file mode 100644 index 00000000..639067b8 --- /dev/null +++ b/resources/css/notes.css @@ -0,0 +1,38 @@ +main { + & > .u-comment { + margin-block-start: 2rem; + margin-inline-start: 2rem; + border-inline-start: 1px solid var(--color-primary); + padding-inline-start: .5rem; + + & .mini-h-card { + display: inline-flex; + flex-direction: row; + align-items: baseline; + + & .u-photo { + width: 2rem; + height: 2rem; + border-radius: 50%; + margin-block-end: 0.5rem; + } + } + } + + & .notes-subtitle { + font-size: 1.2rem; + font-weight: 600; + } + + & .webmentions-author-list { + display: flex; + flex-flow: row wrap; + gap: 1rem; + + & img { + width: 4rem; + height: 4rem; + border-radius: 50%; + } + } +} diff --git a/resources/views/icons/like.blade.php b/resources/views/icons/like.blade.php new file mode 100644 index 00000000..b5b136d5 --- /dev/null +++ b/resources/views/icons/like.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/icons/reply.blade.php b/resources/views/icons/reply.blade.php new file mode 100644 index 00000000..b2daaf1d --- /dev/null +++ b/resources/views/icons/reply.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/icons/repost.blade.php b/resources/views/icons/repost.blade.php new file mode 100644 index 00000000..0f89d0e7 --- /dev/null +++ b/resources/views/icons/repost.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/notes/show.blade.php b/resources/views/notes/show.blade.php index ed8c49cb..de7aa93b 100644 --- a/resources/views/notes/show.blade.php +++ b/resources/views/notes/show.blade.php @@ -25,29 +25,36 @@ @endforeach @if($note->webmentions->filter(function ($webmention) { - return ($webmention->type == 'like-of'); -})->count() > 0)

Likes

-@foreach($note->webmentions->filter(function ($webmention) { - return ($webmention->type == 'like-of'); -}) as $like) - -@endforeach + return ($webmention->type === 'like-of'); +})->count() > 0) +

Likes

+
+ @foreach($note->webmentions->filter(function ($webmention) { + return ($webmention->type === 'like-of'); + }) as $like) + + + + @endforeach +
@endif @if($note->webmentions->filter(function ($webmention) { - return ($webmention->type == 'repost-of'); -})->count() > 0)

Reposts

-@foreach($note->webmentions->filter(function ($webmention) { - return ($webmention->type == 'repost-of'); -}) as $repost) -

- - {{ $repost['author']['properties']['name'][0] }} - reposted this at {{ $repost['published'] }}. -

-@endforeach + return ($webmention->type === 'repost-of'); +})->count() > 0) +

Reposts

+
+ @foreach($note->webmentions->filter(function ($webmention) { + return ($webmention->type == 'repost-of'); + }) as $repost) + + {{ $repost['author']['properties']['name'][0] }} reposted this at {{ $repost['published'] }} + + @endforeach +
@endif @stop @section('scripts') - + @parent + @stop diff --git a/resources/views/templates/note.blade.php b/resources/views/templates/note.blade.php index e8bc60f1..eef657ff 100644 --- a/resources/views/templates/note.blade.php +++ b/resources/views/templates/note.blade.php @@ -40,6 +40,31 @@ in {!! $note->address !!} @endif + @if($note->replies > 0 || $note->likes > 0 || $note->reposts > 0) +
+ @if($note->replies > 0) +
+ @include('icons.reply') + {{ $note->replies }} + replies +
+ @endif + @if($note->likes > 0) + + @endif + @if($note->reposts > 0) +
+ @include('icons.repost') + {{ $note->reposts }} + reposts +
+ @endif +
+ @endif