commit 3902114ac0b9f0dce6b4b23f1156a6e38b466c0d
parent 0143d70112d3224be416591dd2b0ac4ad2efcfd4
Author: St John Karp <stjohn@fuzzjunket.com>
Date: Sun, 12 Aug 2018 16:28:45 -0700
Introduce pagination and action icons
Added action icons (reply, favourite, etc.) to the bottom of
every status. Implemented pagination on the timeline views.
Diffstat:
6 files changed, 131 insertions(+), 11 deletions(-)
diff --git a/app/Http/Controllers/LoginController.php b/app/Http/Controllers/LoginController.php
@@ -68,6 +68,6 @@ class LoginController extends Controller
$user = Socialite::driver('mastodon')->user();
session(['user' => $user]);
- return redirect()->route('friends');
+ return redirect()->route('home');
}
}
diff --git a/app/Http/Controllers/TimelineController.php b/app/Http/Controllers/TimelineController.php
@@ -4,29 +4,102 @@ namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Mastodon;
+use GuzzleHttp\Psr7;
+use Illuminate\Http\Request;
class TimelineController extends Controller
{
- public function public_timeline()
+ public function public_timeline(Request $request)
{
+ $params = $this->compile_params($request);
+ $params['local'] = true;
+
$timeline = Mastodon::domain(env('MASTODON_DOMAIN'))
- ->get('/timelines/public', ['local' => true]);
+ ->get('/timelines/public', $params);
+
+ $vars = [
+ 'statuses' => $timeline,
+ 'mastodon_domain' => explode('//', env('MASTODON_DOMAIN'))[1],
+ 'timeline' => 'Public Timeline',
+ 'links' => $this->compile_links('public')
+ ];
- return view('timeline', ['statuses' => $timeline]);
+ return view('timeline', $vars);
}
- public function home_timeline()
+ public function home_timeline(Request $request)
{
if (!session()->has('user'))
{
return redirect()->route('login');
}
+ $params = $this->compile_params($request);
+
$user = session('user');
$timeline = Mastodon::domain(env('MASTODON_DOMAIN'))
->token($user->token)
- ->get('/timelines/home');
+ ->get('/timelines/home', $params);
+
+ $vars = [
+ 'statuses' => $timeline,
+ 'mastodon_domain' => explode('//', env('MASTODON_DOMAIN'))[1],
+ 'timeline' => 'Timeline',
+ 'links' => $this->compile_links('home')
+ ];
+
+ return view('timeline', $vars);
+ }
+
+ 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 view('timeline', ['statuses' => $timeline]);
+ return $params;
}
}
diff --git a/public/css/styles.css b/public/css/styles.css
@@ -46,6 +46,14 @@ div.status img.avatar {
max-width: 48px;
}
+.favourited {
+ color: gold;
+}
+
+div.actions span {
+ margin-right: 1em;
+}
+
/* Tooltip container */
.tooltip {
position: relative;
diff --git a/resources/views/status.blade.php b/resources/views/status.blade.php
@@ -30,4 +30,26 @@
@component('status', ['status' => $status['reblog']])
@endcomponent
@endif
+
+ <div class="actions">
+ <!-- Reply -->
+ <span>
+ ↵
+ </span>
+
+ <!-- Reblog -->
+ <span>
+ ⇄ {{ $status['reblogs_count'] }}
+ </span>
+
+ <!-- Favourite -->
+ <span>
+ @if ($status['favourited'] === true)
+ <span class="favourited">★</span>
+ @else
+ ☆
+ @endif
+ {{ $status['favourites_count'] }}
+ </span>
+ </div>
</div>
diff --git a/resources/views/timeline.blade.php b/resources/views/timeline.blade.php
@@ -5,14 +5,24 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jank.town | Public Timeline</title>
+ <title>{{ $mastodon_domain }} | {{ $timeline }}</title>
<link rel="stylesheet" href="/css/styles.css" />
</head>
<body>
+ <h1>{{ $mastodon_domain }} | {{ $timeline }}</h1>
+
@foreach ($statuses as $status)
@component('status', ['status' => $status])
@endcomponent
@endforeach
+
+ @if ($links['prev'] !== null)
+ <span><a href="{{ $links['prev'] }}">Previous</a></span>
+ @endif
+
+ @if ($links['next'] !== null)
+ <span><a href="{{ $links['next'] }}">Next</a></span>
+ @endif
</body>
</html>
diff --git a/routes/web.php b/routes/web.php
@@ -12,14 +12,21 @@
*/
Route::get('/', function() {
- return redirect()->route('public');
+ if (!session()->has('user'))
+ {
+ return redirect()->route('public');
+ }
+ else
+ {
+ return redirect()->route('home');
+ }
});
Route::get('/timeline/public', 'TimelineController@public_timeline')
->name('public');
-Route::get('/timeline/friends', 'TimelineController@home_timeline')
- ->name('friends');
+Route::get('/timeline/home', 'TimelineController@home_timeline')
+ ->name('home');
Route::get('/login', 'LoginController@login')
->name('login');