Update Timeline, make text-only posts opt-in by default

This commit is contained in:
Daniel Supernault 2021-07-21 02:00:57 -06:00
parent 08f492bd3d
commit 0153ed6d64
No known key found for this signature in database
GPG key ID: 0DEF1C662C9033F7
5 changed files with 140 additions and 65 deletions

View file

@ -16,6 +16,7 @@ use App\{
UserFilter UserFilter
}; };
use Auth, Cache; use Auth, Cache;
use Illuminate\Support\Facades\Redis;
use Carbon\Carbon; use Carbon\Carbon;
use League\Fractal; use League\Fractal;
use App\Transformer\Api\{ use App\Transformer\Api\{
@ -401,6 +402,11 @@ class PublicApiController extends Controller
} }
$filtered = $user ? UserFilterService::filters($user->profile_id) : []; $filtered = $user ? UserFilterService::filters($user->profile_id) : [];
$textOnlyPosts = Redis::zscore('pf:tl:top', $pid) !== false;
$textOnlyReplies = Redis::zscore('pf:tl:replies', $pid) !== false;
$types = $textOnlyPosts ?
['text', 'photo', 'photo:album', 'video', 'video:album', 'photo:video:album'] :
['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'];
if($min || $max) { if($min || $max) {
$dir = $min ? '>' : '<'; $dir = $min ? '>' : '<';
@ -425,12 +431,14 @@ class PublicApiController extends Controller
'created_at', 'created_at',
'updated_at' 'updated_at'
) )
->whereIn('type', ['text','photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) ->whereIn('type', $types)
->when(!$textOnlyReplies, function($q, $textOnlyReplies) {
return $q->whereNull('in_reply_to_id');
})
->with('profile', 'hashtags', 'mentions') ->with('profile', 'hashtags', 'mentions')
->where('id', $dir, $id) ->where('id', $dir, $id)
->whereIn('profile_id', $following) ->whereIn('profile_id', $following)
->whereNotIn('profile_id', $filtered) ->whereNotIn('profile_id', $filtered)
->whereNull('in_reply_to_id')
->whereIn('visibility',['public', 'unlisted', 'private']) ->whereIn('visibility',['public', 'unlisted', 'private'])
->orderBy('created_at', 'desc') ->orderBy('created_at', 'desc')
->limit($limit) ->limit($limit)
@ -456,11 +464,13 @@ class PublicApiController extends Controller
'created_at', 'created_at',
'updated_at' 'updated_at'
) )
->whereIn('type', ['text','photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) ->whereIn('type', $types)
->when(!$textOnlyReplies, function($q, $textOnlyReplies) {
return $q->whereNull('in_reply_to_id');
})
->with('profile', 'hashtags', 'mentions') ->with('profile', 'hashtags', 'mentions')
->whereIn('profile_id', $following) ->whereIn('profile_id', $following)
->whereNotIn('profile_id', $filtered) ->whereNotIn('profile_id', $filtered)
->whereNull('in_reply_to_id')
->whereIn('visibility',['public', 'unlisted', 'private']) ->whereIn('visibility',['public', 'unlisted', 'private'])
->orderBy('created_at', 'desc') ->orderBy('created_at', 'desc')
->simplePaginate($limit); ->simplePaginate($limit);

View file

@ -8,6 +8,7 @@ use App\ProfileSponsor;
use App\Report; use App\Report;
use App\UserFilter; use App\UserFilter;
use Auth, Cookie, DB, Cache, Purify; use Auth, Cookie, DB, Cache, Purify;
use Illuminate\Support\Facades\Redis;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@ -223,5 +224,33 @@ class SettingsController extends Controller
return redirect(route('settings'))->with('status', 'Sponsor settings successfully updated!');; return redirect(route('settings'))->with('status', 'Sponsor settings successfully updated!');;
} }
public function timelineSettings(Request $request)
{
$pid = $request->user()->profile_id;
$top = Redis::zscore('pf:tl:top', $pid) != false;
$replies = Redis::zscore('pf:tl:replies', $pid) != false;
return view('settings.timeline', compact('top', 'replies'));
}
public function updateTimelineSettings(Request $request)
{
$pid = $request->user()->profile_id;
$top = $request->has('top') && $request->input('top') === 'on';
$replies = $request->has('replies') && $request->input('replies') === 'on';
if($top) {
Redis::zadd('pf:tl:top', $pid, $pid);
} else {
Redis::zrem('pf:tl:top', $pid, $pid);
}
if($replies) {
Redis::zadd('pf:tl:replies', $pid, $pid);
} else {
Redis::zrem('pf:tl:replies', $pid, $pid);
}
return redirect(route('settings.timeline'));
}
} }

View file

@ -1,63 +1,66 @@
<div class="col-12 col-md-3 py-3" style="border-right:1px solid #ccc;"> <div class="col-12 col-md-3 py-3" style="border-right:1px solid #ccc;">
<ul class="nav flex-column settings-nav"> <ul class="nav flex-column settings-nav">
<li class="nav-item pl-3 {{request()->is('settings/home')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/home')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings')}}">Account</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings')}}">Account</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/accessibility')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/accessibility')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.accessibility')}}">Accessibility</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.accessibility')}}">Accessibility</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/email')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/email')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.email')}}">Email</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.email')}}">Email</a>
</li> </li>
@if(config('pixelfed.user_invites.enabled')) @if(config('pixelfed.user_invites.enabled'))
<li class="nav-item pl-3 {{request()->is('settings/invites*')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/invites*')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.invites')}}">Invites</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.invites')}}">Invites</a>
</li> </li>
@endif @endif
<li class="nav-item pl-3 {{request()->is('settings/notifications')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/notifications')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.notifications')}}">Notifications</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.notifications')}}">Notifications</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/password')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/password')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.password')}}">Password</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.password')}}">Password</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/privacy*')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/privacy*')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.privacy')}}">Privacy</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.privacy')}}">Privacy</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/relationships*')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/relationships*')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.relationships')}}">Relationships</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.relationships')}}">Relationships</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/security*')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/security*')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.security')}}">Security</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.security')}}">Security</a>
</li> </li>
<li class="nav-item"> <li class="nav-item pl-3 {{request()->is('settings/timeline*')?'active':''}}">
<hr> <a class="nav-link font-weight-light text-muted" href="{{route('settings.timeline')}}">Timelines</a>
</li> </li>
@if(config_cache('pixelfed.import.instagram.enabled')) <li class="nav-item">
<li class="nav-item pl-3 {{request()->is('*import*')?'active':''}}"> <hr>
<a class="nav-link font-weight-light text-muted" href="{{route('settings.import')}}">Import</a> </li>
</li> @if(config_cache('pixelfed.import.instagram.enabled'))
@endif <li class="nav-item pl-3 {{request()->is('*import*')?'active':''}}">
<li class="nav-item pl-3 {{request()->is('settings/data-export')?'active':''}}"> <a class="nav-link font-weight-light text-muted" href="{{route('settings.import')}}">Import</a>
<a class="nav-link font-weight-light text-muted" href="{{route('settings.dataexport')}}">Data Export</a> </li>
</li> @endif
<li class="nav-item pl-3 {{request()->is('settings/data-export')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.dataexport')}}">Data Export</a>
</li>
@if(config_cache('pixelfed.oauth_enabled') == true) @if(config_cache('pixelfed.oauth_enabled') == true)
<li class="nav-item"> <li class="nav-item">
<hr> <hr>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/applications')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/applications')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.applications')}}">Applications</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.applications')}}">Applications</a>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/developers')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/developers')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.developers')}}">Developers</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.developers')}}">Developers</a>
</li> </li>
@endif @endif
<li class="nav-item"> <li class="nav-item">
<hr> <hr>
</li> </li>
<li class="nav-item pl-3 {{request()->is('settings/labs*')?'active':''}}"> <li class="nav-item pl-3 {{request()->is('settings/labs*')?'active':''}}">
<a class="nav-link font-weight-light text-muted" href="{{route('settings.labs')}}">Labs</a> <a class="nav-link font-weight-light text-muted" href="{{route('settings.labs')}}">Labs</a>
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -0,0 +1,30 @@
@extends('settings.template')
@section('section')
<div class="title">
<h3 class="font-weight-bold">Timeline Settings</h3>
</div>
<hr>
<form method="post">
@csrf
<div class="form-check pb-3">
<input class="form-check-input" type="checkbox" name="top" {{$top ? 'checked':''}}>
<label class="form-check-label font-weight-bold" for="">Show text-only posts</label>
<p class="text-muted small help-text">Show text-only posts from accounts you follow. (Home timeline only)</p>
</div>
<div class="form-check pb-3">
<input class="form-check-input" type="checkbox" name="replies" {{$replies ? 'checked':''}}>
<label class="form-check-label font-weight-bold" for="">Show replies</label>
<p class="text-muted small help-text">Show replies from accounts you follow. (Home timeline only)</p>
</div>
<div class="form-group row mt-5 pt-5">
<div class="col-12 text-right">
<hr>
<button type="submit" class="btn btn-primary font-weight-bold py-0 px-5">Submit</button>
</div>
</div>
</form>
@endsection

View file

@ -426,6 +426,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
Route::get('/', 'ImportController@mastodon')->name('settings.import.mastodon'); Route::get('/', 'ImportController@mastodon')->name('settings.import.mastodon');
}); });
}); });
Route::get('timeline', 'SettingsController@timelineSettings')->name('settings.timeline');
Route::post('timeline', 'SettingsController@updateTimelineSettings');
}); });
Route::group(['prefix' => 'site'], function () { Route::group(['prefix' => 'site'], function () {