From b24d2554a895d2fb2f5d3f70fb8b08b0529aa565 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Mon, 17 Jun 2024 23:02:16 -0600 Subject: [PATCH] Update DirectMessageController, add timestamps to threads --- .../Controllers/DirectMessageController.php | 828 +++++++++--------- 1 file changed, 414 insertions(+), 414 deletions(-) diff --git a/app/Http/Controllers/DirectMessageController.php b/app/Http/Controllers/DirectMessageController.php index af51d508..ff532807 100644 --- a/app/Http/Controllers/DirectMessageController.php +++ b/app/Http/Controllers/DirectMessageController.php @@ -2,31 +2,27 @@ namespace App\Http\Controllers; -use Auth, Cache; -use Illuminate\Http\Request; -use App\{ - DirectMessage, - Media, - Notification, - Profile, - Status, - User, - UserFilter, - UserSetting -}; -use App\Services\MediaPathService; -use App\Services\MediaBlocklistService; -use App\Jobs\StatusPipeline\NewStatusPipeline; -use App\Jobs\StatusPipeline\StatusDelete; -use Illuminate\Support\Str; -use App\Util\ActivityPub\Helpers; -use App\Services\AccountService; -use App\Services\StatusService; -use App\Services\WebfingerService; -use App\Models\Conversation; +use App\DirectMessage; use App\Jobs\DirectPipeline\DirectDeletePipeline; use App\Jobs\DirectPipeline\DirectDeliverPipeline; +use App\Jobs\StatusPipeline\StatusDelete; +use App\Media; +use App\Models\Conversation; +use App\Notification; +use App\Profile; +use App\Services\AccountService; +use App\Services\MediaBlocklistService; +use App\Services\MediaPathService; +use App\Services\StatusService; +use App\Services\UserFilterService; use App\Services\UserRoleService; +use App\Services\WebfingerService; +use App\Status; +use App\UserFilter; +use App\Util\ActivityPub\Helpers; +use Cache; +use Illuminate\Http\Request; +use Illuminate\Support\Str; class DirectMessageController extends Controller { @@ -39,260 +35,260 @@ class DirectMessageController extends Controller { $this->validate($request, [ 'a' => 'nullable|string|in:inbox,sent,filtered', - 'page' => 'nullable|integer|min:1|max:99' + 'page' => 'nullable|integer|min:1|max:99', ]); $user = $request->user(); - if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id)) { + if ($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id)) { return []; } $profile = $user->profile_id; $action = $request->input('a', 'inbox'); $page = $request->input('page'); - if(config('database.default') == 'pgsql') { - if($action == 'inbox') { + if (config('database.default') == 'pgsql') { + if ($action == 'inbox') { $dms = DirectMessage::select('id', 'type', 'to_id', 'from_id', 'id', 'status_id', 'is_hidden', 'meta', 'created_at', 'read_at') - ->whereToId($profile) - ->with(['author','status']) - ->whereIsHidden(false) - ->when($page, function($q, $page) { - if($page > 1) { - return $q->offset($page * 8 - 8); - } - }) - ->latest() - ->get() - ->unique('from_id') - ->take(8) - ->map(function($r) use($profile) { - return $r->from_id !== $profile ? [ - 'id' => (string) $r->from_id, - 'name' => $r->author->name, - 'username' => $r->author->username, - 'avatar' => $r->author->avatarUrl(), - 'url' => $r->author->url(), - 'isLocal' => (bool) !$r->author->domain, - 'domain' => $r->author->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ] : [ - 'id' => (string) $r->to_id, - 'name' => $r->recipient->name, - 'username' => $r->recipient->username, - 'avatar' => $r->recipient->avatarUrl(), - 'url' => $r->recipient->url(), - 'isLocal' => (bool) !$r->recipient->domain, - 'domain' => $r->recipient->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ]; - })->values(); + ->whereToId($profile) + ->with(['author', 'status']) + ->whereIsHidden(false) + ->when($page, function ($q, $page) { + if ($page > 1) { + return $q->offset($page * 8 - 8); + } + }) + ->latest() + ->get() + ->unique('from_id') + ->take(8) + ->map(function ($r) use ($profile) { + return $r->from_id !== $profile ? [ + 'id' => (string) $r->from_id, + 'name' => $r->author->name, + 'username' => $r->author->username, + 'avatar' => $r->author->avatarUrl(), + 'url' => $r->author->url(), + 'isLocal' => (bool) ! $r->author->domain, + 'domain' => $r->author->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ] : [ + 'id' => (string) $r->to_id, + 'name' => $r->recipient->name, + 'username' => $r->recipient->username, + 'avatar' => $r->recipient->avatarUrl(), + 'url' => $r->recipient->url(), + 'isLocal' => (bool) ! $r->recipient->domain, + 'domain' => $r->recipient->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ]; + })->values(); } - if($action == 'sent') { + if ($action == 'sent') { $dms = DirectMessage::select('id', 'type', 'to_id', 'from_id', 'id', 'status_id', 'is_hidden', 'meta', 'created_at', 'read_at') - ->whereFromId($profile) - ->with(['author','status']) - ->orderBy('id', 'desc') - ->when($page, function($q, $page) { - if($page > 1) { - return $q->offset($page * 8 - 8); - } - }) - ->get() - ->unique('to_id') - ->take(8) - ->map(function($r) use($profile) { - return $r->from_id !== $profile ? [ - 'id' => (string) $r->from_id, - 'name' => $r->author->name, - 'username' => $r->author->username, - 'avatar' => $r->author->avatarUrl(), - 'url' => $r->author->url(), - 'isLocal' => (bool) !$r->author->domain, - 'domain' => $r->author->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ] : [ - 'id' => (string) $r->to_id, - 'name' => $r->recipient->name, - 'username' => $r->recipient->username, - 'avatar' => $r->recipient->avatarUrl(), - 'url' => $r->recipient->url(), - 'isLocal' => (bool) !$r->recipient->domain, - 'domain' => $r->recipient->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ]; - }); + ->whereFromId($profile) + ->with(['author', 'status']) + ->orderBy('id', 'desc') + ->when($page, function ($q, $page) { + if ($page > 1) { + return $q->offset($page * 8 - 8); + } + }) + ->get() + ->unique('to_id') + ->take(8) + ->map(function ($r) use ($profile) { + return $r->from_id !== $profile ? [ + 'id' => (string) $r->from_id, + 'name' => $r->author->name, + 'username' => $r->author->username, + 'avatar' => $r->author->avatarUrl(), + 'url' => $r->author->url(), + 'isLocal' => (bool) ! $r->author->domain, + 'domain' => $r->author->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ] : [ + 'id' => (string) $r->to_id, + 'name' => $r->recipient->name, + 'username' => $r->recipient->username, + 'avatar' => $r->recipient->avatarUrl(), + 'url' => $r->recipient->url(), + 'isLocal' => (bool) ! $r->recipient->domain, + 'domain' => $r->recipient->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ]; + }); } - if($action == 'filtered') { + if ($action == 'filtered') { $dms = DirectMessage::select('id', 'type', 'to_id', 'from_id', 'id', 'status_id', 'is_hidden', 'meta', 'created_at', 'read_at') - ->whereToId($profile) - ->with(['author','status']) - ->whereIsHidden(true) - ->orderBy('id', 'desc') - ->when($page, function($q, $page) { - if($page > 1) { - return $q->offset($page * 8 - 8); - } - }) - ->get() - ->unique('from_id') - ->take(8) - ->map(function($r) use($profile) { - return $r->from_id !== $profile ? [ - 'id' => (string) $r->from_id, - 'name' => $r->author->name, - 'username' => $r->author->username, - 'avatar' => $r->author->avatarUrl(), - 'url' => $r->author->url(), - 'isLocal' => (bool) !$r->author->domain, - 'domain' => $r->author->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ] : [ - 'id' => (string) $r->to_id, - 'name' => $r->recipient->name, - 'username' => $r->recipient->username, - 'avatar' => $r->recipient->avatarUrl(), - 'url' => $r->recipient->url(), - 'isLocal' => (bool) !$r->recipient->domain, - 'domain' => $r->recipient->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ]; - }); + ->whereToId($profile) + ->with(['author', 'status']) + ->whereIsHidden(true) + ->orderBy('id', 'desc') + ->when($page, function ($q, $page) { + if ($page > 1) { + return $q->offset($page * 8 - 8); + } + }) + ->get() + ->unique('from_id') + ->take(8) + ->map(function ($r) use ($profile) { + return $r->from_id !== $profile ? [ + 'id' => (string) $r->from_id, + 'name' => $r->author->name, + 'username' => $r->author->username, + 'avatar' => $r->author->avatarUrl(), + 'url' => $r->author->url(), + 'isLocal' => (bool) ! $r->author->domain, + 'domain' => $r->author->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ] : [ + 'id' => (string) $r->to_id, + 'name' => $r->recipient->name, + 'username' => $r->recipient->username, + 'avatar' => $r->recipient->avatarUrl(), + 'url' => $r->recipient->url(), + 'isLocal' => (bool) ! $r->recipient->domain, + 'domain' => $r->recipient->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ]; + }); } - } elseif(config('database.default') == 'mysql') { - if($action == 'inbox') { + } elseif (config('database.default') == 'mysql') { + if ($action == 'inbox') { $dms = DirectMessage::selectRaw('*, max(created_at) as createdAt') - ->whereToId($profile) - ->with(['author','status']) - ->whereIsHidden(false) - ->groupBy('from_id') - ->latest() - ->when($page, function($q, $page) { - if($page > 1) { - return $q->offset($page * 8 - 8); - } - }) - ->limit(8) - ->get() - ->map(function($r) use($profile) { - return $r->from_id !== $profile ? [ - 'id' => (string) $r->from_id, - 'name' => $r->author->name, - 'username' => $r->author->username, - 'avatar' => $r->author->avatarUrl(), - 'url' => $r->author->url(), - 'isLocal' => (bool) !$r->author->domain, - 'domain' => $r->author->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ] : [ - 'id' => (string) $r->to_id, - 'name' => $r->recipient->name, - 'username' => $r->recipient->username, - 'avatar' => $r->recipient->avatarUrl(), - 'url' => $r->recipient->url(), - 'isLocal' => (bool) !$r->recipient->domain, - 'domain' => $r->recipient->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ]; - }); + ->whereToId($profile) + ->with(['author', 'status']) + ->whereIsHidden(false) + ->groupBy('from_id') + ->latest() + ->when($page, function ($q, $page) { + if ($page > 1) { + return $q->offset($page * 8 - 8); + } + }) + ->limit(8) + ->get() + ->map(function ($r) use ($profile) { + return $r->from_id !== $profile ? [ + 'id' => (string) $r->from_id, + 'name' => $r->author->name, + 'username' => $r->author->username, + 'avatar' => $r->author->avatarUrl(), + 'url' => $r->author->url(), + 'isLocal' => (bool) ! $r->author->domain, + 'domain' => $r->author->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ] : [ + 'id' => (string) $r->to_id, + 'name' => $r->recipient->name, + 'username' => $r->recipient->username, + 'avatar' => $r->recipient->avatarUrl(), + 'url' => $r->recipient->url(), + 'isLocal' => (bool) ! $r->recipient->domain, + 'domain' => $r->recipient->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ]; + }); } - if($action == 'sent') { + if ($action == 'sent') { $dms = DirectMessage::selectRaw('*, max(created_at) as createdAt') - ->whereFromId($profile) - ->with(['author','status']) - ->groupBy('to_id') - ->orderBy('createdAt', 'desc') - ->when($page, function($q, $page) { - if($page > 1) { - return $q->offset($page * 8 - 8); - } - }) - ->limit(8) - ->get() - ->map(function($r) use($profile) { - return $r->from_id !== $profile ? [ - 'id' => (string) $r->from_id, - 'name' => $r->author->name, - 'username' => $r->author->username, - 'avatar' => $r->author->avatarUrl(), - 'url' => $r->author->url(), - 'isLocal' => (bool) !$r->author->domain, - 'domain' => $r->author->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ] : [ - 'id' => (string) $r->to_id, - 'name' => $r->recipient->name, - 'username' => $r->recipient->username, - 'avatar' => $r->recipient->avatarUrl(), - 'url' => $r->recipient->url(), - 'isLocal' => (bool) !$r->recipient->domain, - 'domain' => $r->recipient->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ]; - }); + ->whereFromId($profile) + ->with(['author', 'status']) + ->groupBy('to_id') + ->orderBy('createdAt', 'desc') + ->when($page, function ($q, $page) { + if ($page > 1) { + return $q->offset($page * 8 - 8); + } + }) + ->limit(8) + ->get() + ->map(function ($r) use ($profile) { + return $r->from_id !== $profile ? [ + 'id' => (string) $r->from_id, + 'name' => $r->author->name, + 'username' => $r->author->username, + 'avatar' => $r->author->avatarUrl(), + 'url' => $r->author->url(), + 'isLocal' => (bool) ! $r->author->domain, + 'domain' => $r->author->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ] : [ + 'id' => (string) $r->to_id, + 'name' => $r->recipient->name, + 'username' => $r->recipient->username, + 'avatar' => $r->recipient->avatarUrl(), + 'url' => $r->recipient->url(), + 'isLocal' => (bool) ! $r->recipient->domain, + 'domain' => $r->recipient->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ]; + }); } - if($action == 'filtered') { + if ($action == 'filtered') { $dms = DirectMessage::selectRaw('*, max(created_at) as createdAt') - ->whereToId($profile) - ->with(['author','status']) - ->whereIsHidden(true) - ->groupBy('from_id') - ->orderBy('createdAt', 'desc') - ->when($page, function($q, $page) { - if($page > 1) { - return $q->offset($page * 8 - 8); - } - }) - ->limit(8) - ->get() - ->map(function($r) use($profile) { - return $r->from_id !== $profile ? [ - 'id' => (string) $r->from_id, - 'name' => $r->author->name, - 'username' => $r->author->username, - 'avatar' => $r->author->avatarUrl(), - 'url' => $r->author->url(), - 'isLocal' => (bool) !$r->author->domain, - 'domain' => $r->author->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ] : [ - 'id' => (string) $r->to_id, - 'name' => $r->recipient->name, - 'username' => $r->recipient->username, - 'avatar' => $r->recipient->avatarUrl(), - 'url' => $r->recipient->url(), - 'isLocal' => (bool) !$r->recipient->domain, - 'domain' => $r->recipient->domain, - 'timeAgo' => $r->created_at->diffForHumans(null, true, true), - 'lastMessage' => $r->status->caption, - 'messages' => [] - ]; - }); + ->whereToId($profile) + ->with(['author', 'status']) + ->whereIsHidden(true) + ->groupBy('from_id') + ->orderBy('createdAt', 'desc') + ->when($page, function ($q, $page) { + if ($page > 1) { + return $q->offset($page * 8 - 8); + } + }) + ->limit(8) + ->get() + ->map(function ($r) use ($profile) { + return $r->from_id !== $profile ? [ + 'id' => (string) $r->from_id, + 'name' => $r->author->name, + 'username' => $r->author->username, + 'avatar' => $r->author->avatarUrl(), + 'url' => $r->author->url(), + 'isLocal' => (bool) ! $r->author->domain, + 'domain' => $r->author->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ] : [ + 'id' => (string) $r->to_id, + 'name' => $r->recipient->name, + 'username' => $r->recipient->username, + 'avatar' => $r->recipient->avatarUrl(), + 'url' => $r->recipient->url(), + 'isLocal' => (bool) ! $r->recipient->domain, + 'domain' => $r->recipient->domain, + 'timeAgo' => $r->created_at->diffForHumans(null, true, true), + 'lastMessage' => $r->status->caption, + 'messages' => [], + ]; + }); } } @@ -304,11 +300,11 @@ class DirectMessageController extends Controller $this->validate($request, [ 'to_id' => 'required', 'message' => 'required|string|min:1|max:500', - 'type' => 'required|in:text,emoji' + 'type' => 'required|in:text,emoji', ]); $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); abort_if($user->created_at->gt(now()->subHours(72)), 400, 'You need to wait a bit before you can DM another account'); $profile = $user->profile; $recipient = Profile::where('id', '!=', $profile->id)->findOrFail($request->input('to_id')); @@ -316,8 +312,8 @@ class DirectMessageController extends Controller abort_if(in_array($profile->id, $recipient->blockedIds()->toArray()), 403); $msg = $request->input('message'); - if((!$recipient->domain && $recipient->user->settings->public_dm == false) || $recipient->is_private) { - if($recipient->follows($profile) == true) { + if ((! $recipient->domain && $recipient->user->settings->public_dm == false) || $recipient->is_private) { + if ($recipient->follows($profile) == true) { $hidden = false; } else { $hidden = true; @@ -346,35 +342,35 @@ class DirectMessageController extends Controller Conversation::updateOrInsert( [ 'to_id' => $recipient->id, - 'from_id' => $profile->id + 'from_id' => $profile->id, ], [ 'type' => $dm->type, 'status_id' => $status->id, 'dm_id' => $dm->id, - 'is_hidden' => $hidden + 'is_hidden' => $hidden, ] ); - if(filter_var($msg, FILTER_VALIDATE_URL)) { - if(Helpers::validateUrl($msg)) { + if (filter_var($msg, FILTER_VALIDATE_URL)) { + if (Helpers::validateUrl($msg)) { $dm->type = 'link'; $dm->meta = [ 'domain' => parse_url($msg, PHP_URL_HOST), 'local' => parse_url($msg, PHP_URL_HOST) == - parse_url(config('app.url'), PHP_URL_HOST) + parse_url(config('app.url'), PHP_URL_HOST), ]; $dm->save(); } } $nf = UserFilter::whereUserId($recipient->id) - ->whereFilterableId($profile->id) - ->whereFilterableType('App\Profile') - ->whereFilterType('dm.mute') - ->exists(); + ->whereFilterableId($profile->id) + ->whereFilterableType('App\Profile') + ->whereFilterType('dm.mute') + ->exists(); - if($recipient->domain == null && $hidden == false && !$nf) { + if ($recipient->domain == null && $hidden == false && ! $nf) { $notification = new Notification(); $notification->profile_id = $recipient->id; $notification->actor_id = $profile->id; @@ -384,7 +380,7 @@ class DirectMessageController extends Controller $notification->save(); } - if($recipient->domain) { + if ($recipient->domain) { $this->remoteDeliver($dm); } @@ -393,12 +389,12 @@ class DirectMessageController extends Controller 'isAuthor' => $profile->id == $dm->from_id, 'reportId' => (string) $dm->status_id, 'hidden' => (bool) $dm->is_hidden, - 'type' => $dm->type, + 'type' => $dm->type, 'text' => $dm->status->caption, 'media' => null, - 'timeAgo' => $dm->created_at->diffForHumans(null,null,true), + 'timeAgo' => $dm->created_at->diffForHumans(null, null, true), 'seen' => $dm->read_at != null, - 'meta' => $dm->meta + 'meta' => $dm->meta, ]; return response()->json($res); @@ -407,10 +403,10 @@ class DirectMessageController extends Controller public function thread(Request $request) { $this->validate($request, [ - 'pid' => 'required' + 'pid' => 'required', ]); $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); $uid = $user->profile_id; $pid = $request->input('pid'); @@ -419,54 +415,57 @@ class DirectMessageController extends Controller $r = Profile::findOrFail($pid); - if($min_id) { + if ($min_id) { $res = DirectMessage::select('*') - ->where('id', '>', $min_id) - ->where(function($q) use($pid,$uid) { - return $q->where([['from_id',$pid],['to_id',$uid] - ])->orWhere([['from_id',$uid],['to_id',$pid]]); - }) - ->latest() - ->take(8) - ->get(); - } else if ($max_id) { + ->where('id', '>', $min_id) + ->where(function ($q) use ($pid, $uid) { + return $q->where([['from_id', $pid], ['to_id', $uid], + ])->orWhere([['from_id', $uid], ['to_id', $pid]]); + }) + ->latest() + ->take(8) + ->get(); + } elseif ($max_id) { $res = DirectMessage::select('*') - ->where('id', '<', $max_id) - ->where(function($q) use($pid,$uid) { - return $q->where([['from_id',$pid],['to_id',$uid] - ])->orWhere([['from_id',$uid],['to_id',$pid]]); - }) - ->latest() - ->take(8) - ->get(); + ->where('id', '<', $max_id) + ->where(function ($q) use ($pid, $uid) { + return $q->where([['from_id', $pid], ['to_id', $uid], + ])->orWhere([['from_id', $uid], ['to_id', $pid]]); + }) + ->latest() + ->take(8) + ->get(); } else { - $res = DirectMessage::where(function($q) use($pid,$uid) { - return $q->where([['from_id',$pid],['to_id',$uid] - ])->orWhere([['from_id',$uid],['to_id',$pid]]); + $res = DirectMessage::where(function ($q) use ($pid, $uid) { + return $q->where([['from_id', $pid], ['to_id', $uid], + ])->orWhere([['from_id', $uid], ['to_id', $pid]]); }) - ->latest() - ->take(8) - ->get(); + ->latest() + ->take(8) + ->get(); } - $res = $res->filter(function($s) { + $res = $res->filter(function ($s) { return $s && $s->status; }) - ->map(function($s) use ($uid) { - return [ - 'id' => (string) $s->id, - 'hidden' => (bool) $s->is_hidden, - 'isAuthor' => $uid == $s->from_id, - 'type' => $s->type, - 'text' => $s->status->caption, - 'media' => $s->status->firstMedia() ? $s->status->firstMedia()->url() : null, - 'timeAgo' => $s->created_at->diffForHumans(null,null,true), - 'seen' => $s->read_at != null, - 'reportId' => (string) $s->status_id, - 'meta' => json_decode($s->meta,true) - ]; - }) - ->values(); + ->map(function ($s) use ($uid) { + return [ + 'id' => (string) $s->id, + 'hidden' => (bool) $s->is_hidden, + 'isAuthor' => $uid == $s->from_id, + 'type' => $s->type, + 'text' => $s->status->caption, + 'media' => $s->status->firstMedia() ? $s->status->firstMedia()->url() : null, + 'created_at' => $s->created_at->format('c'), + 'timeAgo' => $s->created_at->diffForHumans(null, null, true), + 'seen' => $s->read_at != null, + 'reportId' => (string) $s->status_id, + 'meta' => json_decode($s->meta, true), + ]; + }) + ->values(); + + $filters = UserFilterService::mutes($uid); $w = [ 'id' => (string) $r->id, @@ -474,25 +473,23 @@ class DirectMessageController extends Controller 'username' => $r->username, 'avatar' => $r->avatarUrl(), 'url' => $r->url(), - 'muted' => UserFilter::whereUserId($uid) - ->whereFilterableId($r->id) - ->whereFilterableType('App\Profile') - ->whereFilterType('dm.mute') - ->first() ? true : false, - 'isLocal' => (bool) !$r->domain, + 'muted' => in_array($r->id, $filters), + 'isLocal' => (bool) ! $r->domain, 'domain' => $r->domain, + 'created_at' => $r->created_at->format('c'), + 'updated_at' => $r->updated_at->format('c'), 'timeAgo' => $r->created_at->diffForHumans(null, true, true), 'lastMessage' => '', - 'messages' => $res + 'messages' => $res, ]; - return response()->json($w, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + return response()->json($w, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); } public function delete(Request $request) { $this->validate($request, [ - 'id' => 'required' + 'id' => 'required', ]); $sid = $request->input('id'); @@ -507,30 +504,30 @@ class DirectMessageController extends Controller $recipient = AccountService::get($dm->to_id); - if(!$recipient) { + if (! $recipient) { return response('', 422); } - if($recipient['local'] == false) { + if ($recipient['local'] == false) { $dmc = $dm; $this->remoteDelete($dmc); } else { StatusDelete::dispatch($status)->onQueue('high'); } - if(Conversation::whereStatusId($sid)->count()) { + if (Conversation::whereStatusId($sid)->count()) { $latest = DirectMessage::where(['from_id' => $dm->from_id, 'to_id' => $dm->to_id]) ->orWhere(['to_id' => $dm->from_id, 'from_id' => $dm->to_id]) ->latest() ->first(); - if($latest->status_id == $sid) { + if ($latest->status_id == $sid) { Conversation::where(['to_id' => $dm->from_id, 'from_id' => $dm->to_id]) ->update([ 'updated_at' => $latest->updated_at, 'status_id' => $latest->status_id, 'type' => $latest->type, - 'is_hidden' => false + 'is_hidden' => false, ]); Conversation::where(['to_id' => $dm->to_id, 'from_id' => $dm->from_id]) @@ -538,19 +535,19 @@ class DirectMessageController extends Controller 'updated_at' => $latest->updated_at, 'status_id' => $latest->status_id, 'type' => $latest->type, - 'is_hidden' => false + 'is_hidden' => false, ]); } else { Conversation::where([ 'status_id' => $sid, 'to_id' => $dm->from_id, - 'from_id' => $dm->to_id + 'from_id' => $dm->to_id, ])->delete(); Conversation::where([ 'status_id' => $sid, 'from_id' => $dm->from_id, - 'to_id' => $dm->to_id + 'to_id' => $dm->to_id, ])->delete(); } } @@ -558,41 +555,43 @@ class DirectMessageController extends Controller StatusService::del($status->id, true); $status->forceDeleteQuietly(); + return [200]; } public function get(Request $request, $id) { $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); $pid = $request->user()->profile_id; $dm = DirectMessage::whereStatusId($id)->firstOrFail(); abort_if($pid !== $dm->to_id && $pid !== $dm->from_id, 404); - return response()->json($dm, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + + return response()->json($dm, 200, [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); } public function mediaUpload(Request $request) { $this->validate($request, [ - 'file' => function() { + 'file' => function () { return [ 'required', - 'mimetypes:' . config_cache('pixelfed.media_types'), - 'max:' . config_cache('pixelfed.max_photo_size'), + 'mimetypes:'.config_cache('pixelfed.media_types'), + 'max:'.config_cache('pixelfed.max_photo_size'), ]; }, - 'to_id' => 'required' + 'to_id' => 'required', ]); $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); $profile = $user->profile; $recipient = Profile::where('id', '!=', $profile->id)->findOrFail($request->input('to_id')); abort_if(in_array($profile->id, $recipient->blockedIds()->toArray()), 403); - if((!$recipient->domain && $recipient->user->settings->public_dm == false) || $recipient->is_private) { - if($recipient->follows($profile) == true) { + if ((! $recipient->domain && $recipient->user->settings->public_dm == false) || $recipient->is_private) { + if ($recipient->follows($profile) == true) { $hidden = false; } else { $hidden = true; @@ -601,8 +600,8 @@ class DirectMessageController extends Controller $hidden = false; } - if(config_cache('pixelfed.enforce_account_limit') == true) { - $size = Cache::remember($user->storageUsedKey(), now()->addDays(3), function() use($user) { + if (config_cache('pixelfed.enforce_account_limit') == true) { + $size = Cache::remember($user->storageUsedKey(), now()->addDays(3), function () use ($user) { return Media::whereUserId($user->id)->sum('size') / 1000; }); $limit = (int) config_cache('pixelfed.max_account_size'); @@ -613,11 +612,11 @@ class DirectMessageController extends Controller $photo = $request->file('file'); $mimes = explode(',', config_cache('pixelfed.media_types')); - if(in_array($photo->getMimeType(), $mimes) == false) { + if (in_array($photo->getMimeType(), $mimes) == false) { abort(403, 'Invalid or unsupported mime type.'); } - $storagePath = MediaPathService::get($user, 2) . Str::random(8); + $storagePath = MediaPathService::get($user, 2).Str::random(8); $path = $photo->storePublicly($storagePath); $hash = \hash_file('sha256', $photo); @@ -656,17 +655,17 @@ class DirectMessageController extends Controller Conversation::updateOrInsert( [ 'to_id' => $recipient->id, - 'from_id' => $profile->id + 'from_id' => $profile->id, ], [ 'type' => $dm->type, 'status_id' => $status->id, 'dm_id' => $dm->id, - 'is_hidden' => $hidden + 'is_hidden' => $hidden, ] ); - if($recipient->domain) { + if ($recipient->domain) { $this->remoteDeliver($dm); } @@ -674,7 +673,7 @@ class DirectMessageController extends Controller 'id' => $dm->id, 'reportId' => (string) $dm->status_id, 'type' => $dm->type, - 'url' => $media->url() + 'url' => $media->url(), ]; } @@ -686,55 +685,56 @@ class DirectMessageController extends Controller ]); $user = $request->user(); - if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id)) { + if ($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id)) { return []; } $q = $request->input('q'); $r = $request->input('remote', false); - if($r && !Str::of($q)->contains('.')) { + if ($r && ! Str::of($q)->contains('.')) { return []; } - if($r && Helpers::validateUrl($q)) { + if ($r && Helpers::validateUrl($q)) { Helpers::profileFetch($q); } - if(Str::of($q)->startsWith('@')) { - if(strlen($q) < 3) { + if (Str::of($q)->startsWith('@')) { + if (strlen($q) < 3) { return []; } - if(substr_count($q, '@') == 2) { + if (substr_count($q, '@') == 2) { WebfingerService::lookup($q); } $q = mb_substr($q, 1); } $blocked = UserFilter::whereFilterableType('App\Profile') - ->whereFilterType('block') - ->whereFilterableId($request->user()->profile_id) - ->pluck('user_id'); + ->whereFilterType('block') + ->whereFilterableId($request->user()->profile_id) + ->pluck('user_id'); $blocked->push($request->user()->profile_id); - $results = Profile::select('id','domain','username') - ->whereNotIn('id', $blocked) - ->where('username','like','%'.$q.'%') - ->orderBy('domain') - ->limit(8) - ->get() - ->map(function($r) { - $acct = AccountService::get($r->id); - return [ - 'local' => (bool) !$r->domain, - 'id' => (string) $r->id, - 'name' => $r->username, - 'privacy' => true, - 'avatar' => $r->avatarUrl(), - 'account' => $acct - ]; - }); + $results = Profile::select('id', 'domain', 'username') + ->whereNotIn('id', $blocked) + ->where('username', 'like', '%'.$q.'%') + ->orderBy('domain') + ->limit(8) + ->get() + ->map(function ($r) { + $acct = AccountService::get($r->id); + + return [ + 'local' => (bool) ! $r->domain, + 'id' => (string) $r->id, + 'name' => $r->username, + 'privacy' => true, + 'avatar' => $r->avatarUrl(), + 'account' => $acct, + ]; + }); return $results; } @@ -743,21 +743,21 @@ class DirectMessageController extends Controller { $this->validate($request, [ 'pid' => 'required', - 'sid' => 'required' + 'sid' => 'required', ]); $pid = $request->input('pid'); $sid = $request->input('sid'); $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); $dms = DirectMessage::whereToId($request->user()->profile_id) - ->whereFromId($pid) - ->where('status_id', '>=', $sid) - ->get(); + ->whereFromId($pid) + ->where('status_id', '>=', $sid) + ->get(); $now = now(); - foreach($dms as $dm) { + foreach ($dms as $dm) { $dm->read_at = $now; $dm->save(); } @@ -768,11 +768,11 @@ class DirectMessageController extends Controller public function mute(Request $request) { $this->validate($request, [ - 'id' => 'required' + 'id' => 'required', ]); $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); $fid = $request->input('id'); $pid = $request->user()->profile_id; @@ -781,7 +781,7 @@ class DirectMessageController extends Controller 'user_id' => $pid, 'filterable_id' => $fid, 'filterable_type' => 'App\Profile', - 'filter_type' => 'dm.mute' + 'filter_type' => 'dm.mute', ] ); @@ -791,20 +791,20 @@ class DirectMessageController extends Controller public function unmute(Request $request) { $this->validate($request, [ - 'id' => 'required' + 'id' => 'required', ]); $user = $request->user(); - abort_if($user->has_roles && !UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); + abort_if($user->has_roles && ! UserRoleService::can('can-direct-message', $user->id), 403, 'Invalid permissions for this action'); $fid = $request->input('id'); $pid = $request->user()->profile_id; $f = UserFilter::whereUserId($pid) - ->whereFilterableId($fid) - ->whereFilterableType('App\Profile') - ->whereFilterType('dm.mute') - ->firstOrFail(); + ->whereFilterableId($fid) + ->whereFilterableType('App\Profile') + ->whereFilterType('dm.mute') + ->firstOrFail(); $f->delete(); @@ -821,7 +821,7 @@ class DirectMessageController extends Controller 'type' => 'Mention', 'href' => $dm->recipient->permalink(), 'name' => $dm->recipient->emailUrl(), - ] + ], ]; $body = [ @@ -829,34 +829,34 @@ class DirectMessageController extends Controller 'https://w3id.org/security/v1', 'https://www.w3.org/ns/activitystreams', ], - 'id' => $dm->status->permalink(), - 'type' => 'Create', - 'actor' => $dm->status->profile->permalink(), - 'published' => $dm->status->created_at->toAtomString(), - 'to' => [$dm->recipient->permalink()], - 'cc' => [], + 'id' => $dm->status->permalink(), + 'type' => 'Create', + 'actor' => $dm->status->profile->permalink(), + 'published' => $dm->status->created_at->toAtomString(), + 'to' => [$dm->recipient->permalink()], + 'cc' => [], 'object' => [ - 'id' => $dm->status->url(), - 'type' => 'Note', - 'summary' => null, - 'content' => $dm->status->rendered ?? $dm->status->caption, - 'inReplyTo' => null, - 'published' => $dm->status->created_at->toAtomString(), - 'url' => $dm->status->url(), - 'attributedTo' => $dm->status->profile->permalink(), - 'to' => [$dm->recipient->permalink()], - 'cc' => [], - 'sensitive' => (bool) $dm->status->is_nsfw, - 'attachment' => $dm->status->media()->orderBy('order')->get()->map(function ($media) { + 'id' => $dm->status->url(), + 'type' => 'Note', + 'summary' => null, + 'content' => $dm->status->rendered ?? $dm->status->caption, + 'inReplyTo' => null, + 'published' => $dm->status->created_at->toAtomString(), + 'url' => $dm->status->url(), + 'attributedTo' => $dm->status->profile->permalink(), + 'to' => [$dm->recipient->permalink()], + 'cc' => [], + 'sensitive' => (bool) $dm->status->is_nsfw, + 'attachment' => $dm->status->media()->orderBy('order')->get()->map(function ($media) { return [ - 'type' => $media->activityVerb(), + 'type' => $media->activityVerb(), 'mediaType' => $media->mime, - 'url' => $media->url(), - 'name' => $media->caption, + 'url' => $media->url(), + 'name' => $media->caption, ]; })->toArray(), - 'tag' => $tags, - ] + 'tag' => $tags, + ], ]; DirectDeliverPipeline::dispatch($profile, $url, $body)->onQueue('high'); @@ -873,14 +873,14 @@ class DirectMessageController extends Controller ], 'id' => $dm->status->permalink('#delete'), 'to' => [ - 'https://www.w3.org/ns/activitystreams#Public' + 'https://www.w3.org/ns/activitystreams#Public', ], 'type' => 'Delete', 'actor' => $dm->status->profile->permalink(), 'object' => [ 'id' => $dm->status->url(), - 'type' => 'Tombstone' - ] + 'type' => 'Tombstone', + ], ]; DirectDeletePipeline::dispatch($profile, $url, $body)->onQueue('high'); }