commit d8c1ed68840b5caf6c94d890a2e10a2ceac45345
parent 7e617469ccc104acd1e355be2f8e90a8f26b0c19
Author: St John Karp <stjohn@fuzzjunket.com>
Date: Sat, 25 Aug 2018 17:29:36 -0700
Implement notifications page
Created a new page that displays notifications and added it to the
global nav. Abstracted out the pagination methods from the timeline
controller and put it in a helper class. Abstracted out the event info
(account, timestamp, etc.) into its own component.
Diffstat:
10 files changed, 177 insertions(+), 77 deletions(-)
diff --git a/app/Helpers/Pagination.php b/app/Helpers/Pagination.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Helpers;
+
+use Mastodon;
+use GuzzleHttp\Psr7;
+use Illuminate\Http\Request;
+
+class Pagination
+{
+ public static function compile_links(string $route)
+ {
+ $links = [
+ 'next' => null,
+ 'prev' => null
+ ];
+
+ # Parse out the links header returned from the Mastodon API.
+ $links_header = Mastodon::getResponse()->getHeader('link');
+ foreach (Psr7\parse_header($links_header) as $link)
+ {
+ # Find the prev and next links.
+ if ($link['rel'] === 'prev' || $link['rel'] === 'next')
+ {
+ $url = parse_url(trim($link[0], '<>'));
+ foreach (explode('&', $url['query']) as $query_param)
+ {
+ # Grab the ID query parameters from the link.
+ if (strpos($query_param, 'max_id=') === 0
+ || strpos($query_param, 'since_id=') === 0)
+ {
+ # Construct new links with the correct offset.
+ $links[$link['rel']] = route($route) . '?' . $query_param;
+ }
+ }
+ }
+ }
+
+ return $links;
+ }
+
+ public static function compile_params(Request $request)
+ {
+ $params = [];
+
+ if ($request->has('max_id') && $request->has('since_id'))
+ {
+ # This scenario makes no sense. Someone's trying to dicker with the URL.
+ abort(400);
+ }
+ elseif ($request->has('max_id'))
+ {
+ $params['max_id'] = $request->max_id;
+ }
+ elseif ($request->has('since_id'))
+ {
+ $params['since_id'] = $request->since_id;
+ }
+
+ return $params;
+ }
+}
diff --git a/app/Http/Controllers/NotificationsController.php b/app/Http/Controllers/NotificationsController.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Controllers\Controller;
+use Mastodon;
+use Illuminate\Http\Request;
+use App\Helpers\Pagination;
+
+class NotificationsController extends Controller
+{
+ public function get_notifications(Request $request)
+ {
+ $user = session('user');
+ $params = Pagination::compile_params($request);
+
+ $notifications = Mastodon::domain(env('MASTODON_DOMAIN'))
+ ->token($user->token)
+ ->get('/notifications', $params);
+
+ $vars = [
+ 'notifications' => $notifications,
+ 'mastodon_domain' => explode('//', env('MASTODON_DOMAIN'))[1],
+ 'links' => Pagination::compile_links('notifications')
+ ];
+
+ return view('notifications', $vars);
+ }
+}
diff --git a/app/Http/Controllers/TimelineController.php b/app/Http/Controllers/TimelineController.php
@@ -4,14 +4,14 @@ namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Mastodon;
-use GuzzleHttp\Psr7;
use Illuminate\Http\Request;
+use App\Helpers\Pagination;
class TimelineController extends Controller
{
public function public_timeline(Request $request)
{
- $params = $this->compile_params($request);
+ $params = Pagination::compile_params($request);
$params['local'] = true;
$timeline = Mastodon::domain(env('MASTODON_DOMAIN'))
@@ -20,7 +20,7 @@ class TimelineController extends Controller
$vars = [
'statuses' => $timeline,
'mastodon_domain' => explode('//', env('MASTODON_DOMAIN'))[1],
- 'links' => $this->compile_links('public')
+ 'links' => Pagination::compile_links('public')
];
return view('public_timeline', $vars);
@@ -30,7 +30,7 @@ class TimelineController extends Controller
{
$user = session('user');
- $params = $this->compile_params($request);
+ $params = Pagination::compile_params($request);
$timeline = Mastodon::domain(env('MASTODON_DOMAIN'))
->token($user->token)
@@ -39,7 +39,7 @@ class TimelineController extends Controller
$vars = [
'statuses' => $timeline,
'mastodon_domain' => explode('//', env('MASTODON_DOMAIN'))[1],
- 'links' => $this->compile_links('home')
+ 'links' => Pagination::compile_links('home')
];
return view('home_timeline', $vars);
@@ -82,56 +82,4 @@ class TimelineController extends Controller
return redirect()->route('home');
}
-
- private function compile_links(string $route)
- {
- $links = [
- 'next' => null,
- 'prev' => null
- ];
-
- # Parse out the links header returned from the Mastodon API.
- $links_header = Mastodon::getResponse()->getHeader('link');
- foreach (Psr7\parse_header($links_header) as $link)
- {
- # Find the prev and next links.
- if ($link['rel'] === 'prev' || $link['rel'] === 'next')
- {
- $url = parse_url(trim($link[0], '<>'));
- foreach (explode('&', $url['query']) as $query_param)
- {
- # Grab the ID query parameters from the link.
- if (strpos($query_param, 'max_id=') === 0
- || strpos($query_param, 'since_id=') === 0)
- {
- # Construct new links with the correct offset.
- $links[$link['rel']] = route($route) . '?' . $query_param;
- }
- }
- }
- }
-
- return $links;
- }
-
- private function compile_params(Request $request)
- {
- $params = [];
-
- if ($request->has('max_id') && $request->has('since_id'))
- {
- # This scenario makes no sense. Someone's trying to dicker with the URL.
- abort(400);
- }
- elseif ($request->has('max_id'))
- {
- $params['max_id'] = $request->max_id;
- }
- elseif ($request->has('since_id'))
- {
- $params['since_id'] = $request->since_id;
- }
-
- return $params;
- }
}
diff --git a/public/css/styles.css b/public/css/styles.css
@@ -71,7 +71,7 @@ div.actions span.reblogged a {
color: green;
}
-time {
+time, span.action-notification {
font-size: smaller;
margin-left: 1em;
}
diff --git a/resources/views/account_time_info.blade.php b/resources/views/account_time_info.blade.php
@@ -0,0 +1,19 @@
+<span title="{{ $account['acct'] }}">
+ <a href="{{ $account['url'] }}">
+ <img
+ src="{{ $account['avatar'] }}"
+ alt="{{ $account['acct'] }}"
+ class="avatar"
+ />
+ {{ $account['display_name'] }}
+ </a>
+</span>
+<time datetime="{{ $created_at }}">
+ @php
+ $created_at_datetime = new Carbon\Carbon($created_at);
+ @endphp
+ @if (env('SHOW_BEATS') === true)
+ {{ '@' . $created_at_datetime->format('B') }} |
+ @endif
+ {{ $created_at_datetime->diffForHumans(null, false, true) }}
+</time>
diff --git a/resources/views/navigation.blade.php b/resources/views/navigation.blade.php
@@ -2,5 +2,6 @@
<ul>
<li><a href="/timeline/home">Timeline</a></li>
<li><a href="/timeline/public">Public Timeline</a></li>
+ <li><a href="/notifications">Notifications</a></li>
</ul>
</nav>
diff --git a/resources/views/notification.blade.php b/resources/views/notification.blade.php
@@ -0,0 +1,24 @@
+<article>
+ @component('account_time_info', [
+ 'account' => $notification['account'],
+ 'created_at' => $notification['created_at']
+ ])
+ @endcomponent
+
+ <span class="action-notification">
+ @if ($notification['type'] === 'mention')
+ mentioned
+ @elseif ($notification['type'] === 'reblog')
+ reblogged
+ @elseif ($notification['type'] === 'favourite')
+ favourited
+ @elseif ($notification['type'] === 'follow')
+ followed you.
+ @endif
+ </span>
+
+ @if ($notification['status'] ?? null !== null)
+ @component('status', ['status' => $notification['status']])
+ @endcomponent
+ @endif
+</article>
diff --git a/resources/views/notifications.blade.php b/resources/views/notifications.blade.php
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="{{ app()->getLocale() }}">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ <title>{{ $mastodon_domain }} | Notifications</title>
+
+ <link rel="stylesheet" href="/css/styles.css" />
+ </head>
+ <body>
+ <h1>{{ $mastodon_domain }} | Notifications</h1>
+
+ @component('navigation')
+ @endcomponent
+
+ @foreach ($notifications as $notification)
+ @component('notification', ['notification' => $notification])
+ @endcomponent
+ @endforeach
+
+ @component('pagination', ['links' => $links])
+ @endcomponent
+ </body>
+</html>
diff --git a/resources/views/status.blade.php b/resources/views/status.blade.php
@@ -1,24 +1,11 @@
<hr />
<article>
- <span title="{{ $status['account']['acct'] }}">
- <a href="{{ $status['account']['url'] }}">
- <img
- src="{{ $status['account']['avatar'] }}"
- alt="{{ $status['account']['acct'] }}"
- class="avatar"
- />
- {{ $status['account']['display_name'] }}
- </a>
- </span>
- <time datetime="{{ $status['created_at'] }}">
- @php
- $created_at = new Carbon\Carbon($status['created_at']);
- @endphp
- @if (env('SHOW_BEATS') === true)
- {{ '@' . $created_at->format('B') }} |
- @endif
- {{ $created_at->diffForHumans(null, false, true) }}
- </time>
+ @component('account_time_info', [
+ 'account' => $status['account'],
+ 'created_at' => $status['created_at']
+ ])
+ @endcomponent
+
@if ($status['spoiler_text'] !== '')
<details>
<summary>{{ $status['spoiler_text'] }}</summary>
diff --git a/routes/web.php b/routes/web.php
@@ -35,6 +35,10 @@ Route::post('/timeline/home', 'TimelineController@post_status')
Route::get('/status/{status_id}', 'StatusController@show_status')
->name('status');
+Route::get('/notifications', 'NotificationsController@get_notifications')
+ ->name('notifications')
+ ->middleware('authorize');
+
Route::get('/login', 'LoginController@login')
->name('login');