From 92098a793e91a7fb818ca3213641eaf8b5f794f8 Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sat, 25 Nov 2023 16:08:07 +0000 Subject: [PATCH 1/2] 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 zcmb2{6=RTTEj(PSr1bxv-QT-gM|j9nYHE%7LCI{?{=t74Wi^+b?yXY5M(XnQB}8)IWYT?fQN*acYgt z(SE;s8YNoKG-h4ROz2k2=RBJ0z>xo0Vp+gvrA?h`xxaaWHLTb??L;mIsFc;{e)5t4=#&q-a|0~^2W+Wg|hqraN#-~K&1qi8|o{+4}jr%69^eB99dqpZgG^VPKArQzEI zr^e1$uU-*zH*a;$k1fd>?Hxv&_P)!!`)l)oNgHLmtIx~-J#d@tw3Ei;gKM*OmdgKE zImBtIBC!3|sjaN1p8hb^ZJHTYdVOJT-#QJq^`5+2DrMz!9h&m`uk2!NH_*Kq$n@N)LjQwx?F-3UE*LL}&8 zP5Y+9M=!6MT(nhpdVuH3e|7=u-hKK|@pVd!y7|ess&^KyuGO0N;ycgAt>Ri!0s{44 zZ733xyZ%t*zx|_6cAd!@;(t>E3PQdmeGz`6wD?Fuppauo{@m1CJf}B*of*Tg8d85H zW2?|)uRKNBo{F|j-4-u0?tFf_=;^XRxrY`vqWsHT&i2Qwo$OrL*JRDNtb(cZsFnHR z$#%D*+a$l}FO6jV;^C#L@8r1RXRKG~vz_NBJwEyRMoYp6`{}_iDxdXk^V_pds%E9= zA+A>s#;Nd;DL$ zf6ump?~CR>`H{%Gq5ewwkHC{!v#%G0a;^&AeroE=7f-t~?-nnu>F2y6zIo@Ik3lj^ zw@-O}^YMkJzkaSfu72;Q>g1LW7xv7m4;8PfZaeaCi-yO3y)$a_&AxmRQQP_@{^%5~ zfOk_uUfdIT`K8~vFe6)j^48EpmD55JQp6IX-u$_laNzv3{V)12%rX7bvO#33@3GE> zyOU}zPT;D&5dFixVrAO5PYO&y8zblF&X~RP@TFx8t(%oIoP_nGmrp*!>G<}%R<6xU z>$lB8miBJ0D}s0un~jS0O|i+F#VfbV|J;k13zH+SRvd5Ln!N7Se)U4LA92rp#nSGn{?Lv+ zH>34~@rU_o?I-l|6gkvG1fvh=p71>3JYgY2>(8#IFVo(i_0DoIfuzAj&KA-n7S2aR-)}rfr@kq~t96p|HpKiy#zUl9ju_EaIEytv1LCq%@FK*)a^VqPs@QX=m z?5qPpS`C>GO6}_p2O6$E{BVWTBL|^^$)^N4zjbWiH|MY7t!c+kYG*L?X#4T5Enh5` zF`a4IlP`0^1KEEXX`WL$XezOOzsKf)FK=cYw3cU_u{`$6wSwz^Y69&QH5_HUzWxfG zyMOC}qAe}z0@_u#6q5vI_6f3XuvXT;EwSeN=7bs3#HYr4G8jiIE7{K#Jo0zB!H*c7 bro(RoRR|otdO(C literal 1036 zcmb0(6JU^OEljozd{SQ}sL0pad20R5KdY9u%-l0W=l<{br7OgC7yBjqoQcw|cN0vv zwpm&F>Ve?hkO^1!R?j`Vdi8`8ArdV|6J?4xug4YbTsKAactqdaKfm9+J@&a+vi-Bi zwksbbe6BBSa9#J`I-{e|OMQ>@fkpcF%`e?aD7No-y;X4k=f^&O<|cn}7BsOEF>ZVI zH=ww!t^DZx+YJr1-om#dK3i<6G+FuAe%rfa@8QR=Y>ern=3*yveN=y*VKtOSu(00^-oHc$memcVo~Bm5q72ra?l~-hZ!a@3$qPt3$Typ7vPcQO_S{ zdtXOxdw7!iw?`X#l&x+q*ScDt-r>7=!m^ev`zAI|-TYyP+ob>Zk3OptxUHb^GGfM!s(YrPNSE~;${1Uo&ri)Mbrq+~zM-H23S4_yebJ)?* zsd%}&1)tf~V9Q0%w8M*^1f042v#)ujZR4DGR^k^t^;b&@X8mt4S#4}PY1bt03zirD zbX>WhoHT#doRhCJ+<1P>KOOjv>26ch^1bVHYF1Vqn!z?NhV7iM_QK!;d`~~0$oM~V zvz%;!gmb_5Ts}5)AD!;qt@+oc-TU$IR=LUl{fA%N7JDaW?a?Ryjs4p3+T*+Z)b7R9 z`)M_nWX*o%6D{6#b=POn`sv(PR!7d6ZsTvcw0hOPnl+~l_u7>{ITP+o8fv_mMf};1vL7#<_2Q`k+m1!9I_XE! z)HChzZTwr0+pMA*ls<6~nh4hSvh4*{7Rln9)YCAnjN-+y@I~RSj@^a3Hf*%Fz z*~K$oc2u!>JnH+e0k^VLrhL@W*%dXnq9=D6WbPrJ6K4V~CrbP`w)FI8 F002}j{#gJ3 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