mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-12-22 21:13:16 +00:00
Update FollowerController, remove deprecated /i/follow endpoint
This commit is contained in:
parent
60fbf0e7d5
commit
4739d6146f
4 changed files with 63 additions and 144 deletions
|
@ -23,109 +23,7 @@ class FollowerController extends Controller
|
|||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'item' => 'required|string',
|
||||
'force' => 'nullable|boolean',
|
||||
]);
|
||||
$force = (bool) $request->input('force', true);
|
||||
$item = (int) $request->input('item');
|
||||
$url = $this->handleFollowRequest($item, $force);
|
||||
if($request->wantsJson() == true) {
|
||||
return response()->json(200);
|
||||
} else {
|
||||
return redirect($url);
|
||||
}
|
||||
}
|
||||
|
||||
protected function handleFollowRequest($item, $force)
|
||||
{
|
||||
$user = Auth::user()->profile;
|
||||
|
||||
$target = Profile::where('id', '!=', $user->id)->whereNull('status')->findOrFail($item);
|
||||
$private = (bool) $target->is_private;
|
||||
$remote = (bool) $target->domain;
|
||||
$blocked = UserFilter::whereUserId($target->id)
|
||||
->whereFilterType('block')
|
||||
->whereFilterableId($user->id)
|
||||
->whereFilterableType('App\Profile')
|
||||
->exists();
|
||||
|
||||
if($blocked == true) {
|
||||
abort(400, 'You cannot follow this user.');
|
||||
}
|
||||
|
||||
$isFollowing = Follower::whereProfileId($user->id)->whereFollowingId($target->id)->exists();
|
||||
|
||||
if($private == true && $isFollowing == 0) {
|
||||
if($user->following()->count() >= Follower::MAX_FOLLOWING) {
|
||||
abort(400, 'You cannot follow more than ' . Follower::MAX_FOLLOWING . ' accounts');
|
||||
}
|
||||
|
||||
if($user->following()->where('followers.created_at', '>', now()->subHour())->count() >= Follower::FOLLOW_PER_HOUR) {
|
||||
abort(400, 'You can only follow ' . Follower::FOLLOW_PER_HOUR . ' users per hour');
|
||||
}
|
||||
|
||||
$follow = FollowRequest::firstOrCreate([
|
||||
'follower_id' => $user->id,
|
||||
'following_id' => $target->id
|
||||
]);
|
||||
if($remote == true && config('federation.activitypub.remoteFollow') == true) {
|
||||
$this->sendFollow($user, $target);
|
||||
}
|
||||
|
||||
FollowerService::add($user->id, $target->id);
|
||||
} elseif ($private == false && $isFollowing == 0) {
|
||||
if($user->following()->count() >= Follower::MAX_FOLLOWING) {
|
||||
abort(400, 'You cannot follow more than ' . Follower::MAX_FOLLOWING . ' accounts');
|
||||
}
|
||||
|
||||
if($user->following()->where('followers.created_at', '>', now()->subHour())->count() >= Follower::FOLLOW_PER_HOUR) {
|
||||
abort(400, 'You can only follow ' . Follower::FOLLOW_PER_HOUR . ' users per hour');
|
||||
}
|
||||
$follower = new Follower();
|
||||
$follower->profile_id = $user->id;
|
||||
$follower->following_id = $target->id;
|
||||
$follower->save();
|
||||
|
||||
if($remote == true && config('federation.activitypub.remoteFollow') == true) {
|
||||
$this->sendFollow($user, $target);
|
||||
}
|
||||
FollowerService::add($user->id, $target->id);
|
||||
FollowPipeline::dispatch($follower);
|
||||
} else {
|
||||
if($force == true) {
|
||||
$request = FollowRequest::whereFollowerId($user->id)->whereFollowingId($target->id)->exists();
|
||||
$follower = Follower::whereProfileId($user->id)->whereFollowingId($target->id)->exists();
|
||||
if($remote == true && $request && !$follower) {
|
||||
$this->sendFollow($user, $target);
|
||||
}
|
||||
if($remote == true && $follower) {
|
||||
$this->sendUndoFollow($user, $target);
|
||||
}
|
||||
Follower::whereProfileId($user->id)
|
||||
->whereFollowingId($target->id)
|
||||
->delete();
|
||||
FollowerService::remove($user->id, $target->id);
|
||||
}
|
||||
}
|
||||
|
||||
Cache::forget('profile:following:'.$target->id);
|
||||
Cache::forget('profile:followers:'.$target->id);
|
||||
Cache::forget('profile:following:'.$user->id);
|
||||
Cache::forget('profile:followers:'.$user->id);
|
||||
Cache::forget('api:local:exp:rec:'.$user->id);
|
||||
Cache::forget('user:account:id:'.$target->user_id);
|
||||
Cache::forget('user:account:id:'.$user->user_id);
|
||||
Cache::forget('px:profile:followers-v1.3:'.$user->id);
|
||||
Cache::forget('px:profile:followers-v1.3:'.$target->id);
|
||||
Cache::forget('px:profile:following-v1.3:'.$user->id);
|
||||
Cache::forget('px:profile:following-v1.3:'.$target->id);
|
||||
Cache::forget('profile:follower_count:'.$target->id);
|
||||
Cache::forget('profile:follower_count:'.$user->id);
|
||||
Cache::forget('profile:following_count:'.$target->id);
|
||||
Cache::forget('profile:following_count:'.$user->id);
|
||||
|
||||
return $target->url();
|
||||
abort(422, 'Deprecated API Endpoint, use /api/v1/accounts/{id}/follow or /api/v1/accounts/{id}/unfollow instead.');
|
||||
}
|
||||
|
||||
public function sendFollow($user, $target)
|
||||
|
|
|
@ -122,12 +122,6 @@
|
|||
</a>
|
||||
</div> -->
|
||||
|
||||
<!-- <div v-else-if="n.type == 'follow' && n.relationship.following == false">
|
||||
<a href="#" class="btn btn-primary py-0 font-weight-bold" @click.prevent="followProfile(n);">
|
||||
Follow
|
||||
</a>
|
||||
</div> -->
|
||||
|
||||
<!-- <div v-else-if="n.status && n.status.parent && !n.status.parent.media_attachments && n.type == 'like' && n.relationship.following == false">
|
||||
<a href="#" class="btn btn-primary py-0 font-weight-bold">
|
||||
Follow
|
||||
|
@ -290,24 +284,6 @@ export default {
|
|||
return '/p/' + username + '/' + id;
|
||||
},
|
||||
|
||||
followProfile(n) {
|
||||
let self = this;
|
||||
let id = n.account.id;
|
||||
axios.post('/i/follow', {
|
||||
item: id
|
||||
}).then(res => {
|
||||
self.notifications.map(notification => {
|
||||
if(notification.account.id === id) {
|
||||
notification.relationship.following = true;
|
||||
}
|
||||
});
|
||||
}).catch(err => {
|
||||
if(err.response.data.message) {
|
||||
swal('Error', err.response.data.message, 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
viewContext(n) {
|
||||
switch(n.type) {
|
||||
case 'follow':
|
||||
|
|
|
@ -131,14 +131,20 @@
|
|||
break;
|
||||
|
||||
case 'unfollow':
|
||||
axios.post('/i/follow', {
|
||||
item: id
|
||||
}).then(res => {
|
||||
axios.post('/api/v1/accounts/' + id + '/unfollow')
|
||||
.then(res => {
|
||||
swal(
|
||||
'Unfollow Successful',
|
||||
'You have successfully unfollowed that user',
|
||||
'success'
|
||||
);
|
||||
})
|
||||
.catch(err => {
|
||||
swal(
|
||||
'Error',
|
||||
'An error occured when attempting to unfollow this user',
|
||||
'error'
|
||||
);
|
||||
});
|
||||
break;
|
||||
|
||||
|
@ -163,4 +169,4 @@
|
|||
})
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endpush
|
||||
|
|
|
@ -11,25 +11,35 @@
|
|||
</div>
|
||||
<div class="card-body">
|
||||
<div class="text-center mt-n5 mb-4">
|
||||
<img class="rounded-circle p-1 border mt-n4 bg-white shadow" src="{{$profile->avatarUrl()}}" width="90px" height="90px;">
|
||||
<img
|
||||
class="rounded-circle p-1 border mt-n4 bg-white shadow"
|
||||
src="{{$profile->avatarUrl()}}"
|
||||
width="90"
|
||||
height="90"
|
||||
loading="lazy"
|
||||
onerror="this.src='/storage/avatars/default.jpg?v=0';this.onerror=null;">
|
||||
</div>
|
||||
<p class="text-center lead font-weight-bold mb-1">{{$profile->username}}</p>
|
||||
<p class="text-center text-muted small text-uppercase mb-4">{{$profile->followerCount()}} followers</p>
|
||||
<div class="d-flex justify-content-center">
|
||||
@if($following == true)
|
||||
<form class="d-inline-block" action="/i/follow" method="post">
|
||||
@csrf
|
||||
<input type="hidden" name="item" value="{{(string)$profile->id}}">
|
||||
<input type="hidden" name="force" value="0">
|
||||
<button type="submit" class="btn btn-outline-secondary btn-sm py-1 px-4 text-uppercase font-weight-bold mr-3" style="font-weight: 500">Unfollow</button>
|
||||
</form>
|
||||
<button
|
||||
id="unfollow"
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm py-1 px-4 text-uppercase font-weight-bold mr-3"
|
||||
style="font-weight: 500"
|
||||
onclick="unfollowProfile()">
|
||||
Unfollow
|
||||
</button>
|
||||
@else
|
||||
<form class="d-inline-block" action="/i/follow" method="post">
|
||||
@csrf
|
||||
<input type="hidden" name="item" value="{{(string)$profile->id}}">
|
||||
<input type="hidden" name="force" value="0">
|
||||
<button type="submit" class="btn btn-primary btn-sm py-1 px-4 text-uppercase font-weight-bold mr-3" style="font-weight: 500">Follow</button>
|
||||
</form>
|
||||
<button
|
||||
id="follow"
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm py-1 px-4 text-uppercase font-weight-bold mr-3"
|
||||
style="font-weight: 500"
|
||||
onclick="followProfile()">
|
||||
Follow
|
||||
</button>
|
||||
@endif
|
||||
<a class="btn btn-outline-primary btn-sm py-1 px-4 text-uppercase font-weight-bold" href="{{$profile->url()}}" style="font-weight: 500">View Profile</a>
|
||||
</div>
|
||||
|
@ -51,3 +61,32 @@
|
|||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
function followProfile() {
|
||||
let btn = document.querySelector('#follow');
|
||||
btn.setAttribute('disabled', 'disabled');
|
||||
axios.post('/api/v1/accounts/{{$profile->id}}/follow')
|
||||
.then(res => {
|
||||
setTimeout(() => location.reload(), 1000);
|
||||
})
|
||||
.catch(err => {
|
||||
location.href = '/login?next=' + encodeURI(location.href);
|
||||
})
|
||||
}
|
||||
|
||||
function unfollowProfile() {
|
||||
let btn = document.querySelector('#unfollow');
|
||||
btn.setAttribute('disabled', 'disabled');
|
||||
axios.post('/api/v1/accounts/{{$profile->id}}/unfollow')
|
||||
.then(res => {
|
||||
setTimeout(() => location.reload(), 1000);
|
||||
})
|
||||
.catch(err => {
|
||||
location.href = '/login?next=' + encodeURI(location.href);
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
@endpush
|
||||
|
|
Loading…
Reference in a new issue