浏览代码

Merge pull request #6068 from pixelfed/staging

Staging
(dan)iel (sup)ernault 1 周之前
父节点
当前提交
81858a8d20
共有 3 个文件被更改,包括 82 次插入64 次删除
  1. 8 0
      CHANGELOG.md
  2. 29 13
      app/Http/Controllers/ComposeController.php
  3. 45 51
      app/Jobs/StatusPipeline/RemoteStatusDelete.php

+ 8 - 0
CHANGELOG.md

@@ -41,6 +41,14 @@
 - Update Groups ImageResizePipeline with intervention/image v3 support ([616e37066](https://github.com/pixelfed/pixelfed/commit/616e37066))
 - Update app config, add Str alias ([5539dd0e1](https://github.com/pixelfed/pixelfed/commit/5539dd0e1))
 - Update PlaceController, fix show method ([f81a4acdc](https://github.com/pixelfed/pixelfed/commit/f81a4acdc))
+- Update Places, improve cache invalidation/ttl ([ece23d751](https://github.com/pixelfed/pixelfed/commit/ece23d751))
+- Update ComposeController, add addl compose settings data ([9048ab52c](https://github.com/pixelfed/pixelfed/commit/9048ab52c))
+- Update Admin Users dashboard ([b6bc1e50e](https://github.com/pixelfed/pixelfed/commit/b6bc1e50e))
+- Update TransformImports command, fix IG import bug ([c692c7655](https://github.com/pixelfed/pixelfed/commit/c692c7655))
+- Update ImportService and TransformImports to fix race condition bug ([a8d1d0f2e](https://github.com/pixelfed/pixelfed/commit/a8d1d0f2e))
+- Update ComposeController, prioritize followed users and follower_count first ([10eb1a8ac](https://github.com/pixelfed/pixelfed/commit/10eb1a8ac))
+- Update ComposeController, fix user tagging endpoint ([2a9c28b81](https://github.com/pixelfed/pixelfed/commit/2a9c28b81))
+- Update RemoteStatusDelete, fix decrement logic ([4ab85248e](https://github.com/pixelfed/pixelfed/commit/4ab85248e))
 -  ([](https://github.com/pixelfed/pixelfed/commit/))
 
 ## [v0.12.5 (2025-03-23)](https://github.com/pixelfed/pixelfed/compare/v0.12.5...dev)

+ 29 - 13
app/Http/Controllers/ComposeController.php

@@ -246,20 +246,19 @@ class ComposeController extends Controller
                 'string',
                 'min:1',
                 'max:300',
-                new \App\Rules\WebFinger,
             ],
         ]);
 
         $q = $request->input('q');
 
-        if (Str::of($q)->startsWith('@')) {
-            if (strlen($q) < 3) {
-                return [];
-            }
-            $q = mb_substr($q, 1);
+        $cleanQuery = Str::of($q)->startsWith('@') ? Str::substr($q, 1) : $q;
+
+        if (strlen($cleanQuery) < 2) {
+            return [];
         }
 
         $user = $request->user();
+        $currentUserId = $request->user()->profile_id;
 
         abort_if($user->has_roles && ! UserRoleService::can('can-post', $user->id), 403, 'Invalid permissions for this action');
 
@@ -271,10 +270,26 @@ class ComposeController extends Controller
         $blocked->push($request->user()->profile_id);
 
         $operator = config('database.default') === 'pgsql' ? 'ilike' : 'like';
-        $results = Profile::select('id', 'domain', 'username')
-            ->whereNotIn('id', $blocked)
-            ->whereNull('domain')
-            ->where('username', $operator, '%'.$q.'%')
+        $results = Profile::select([
+            'profiles.id',
+            'profiles.domain',
+            'profiles.username',
+            'profiles.followers_count',
+        ])
+            ->selectRaw('MAX(CASE WHEN followers.following_id IS NOT NULL THEN 1 ELSE 0 END) as is_followed')
+            ->leftJoin('followers', function ($join) use ($currentUserId) {
+                $join->on('followers.following_id', '=', 'profiles.id')
+                    ->where('followers.profile_id', '=', $currentUserId);
+            })
+            ->whereNotIn('profiles.id', $blocked)
+            ->where(function ($query) use ($cleanQuery, $operator) {
+                $query->where('profiles.username', $operator, $cleanQuery.'%')
+                    ->orWhere('profiles.username', $operator, '%'.$cleanQuery.'%');
+            })
+            ->groupBy('profiles.id', 'profiles.domain', 'profiles.username', 'profiles.followers_count')
+            ->orderByDesc('is_followed')
+            ->orderByDesc('profiles.followers_count')
+            ->orderBy('profiles.username')
             ->limit(15)
             ->get()
             ->map(function ($r) {
@@ -434,6 +449,7 @@ class ComposeController extends Controller
             ->push($request->user()->profile_id);
 
         $currentUserId = $request->user()->profile_id;
+        $operator = config('database.default') === 'pgsql' ? 'ilike' : 'like';
 
         $results = Profile::select([
             'profiles.id',
@@ -447,9 +463,9 @@ class ComposeController extends Controller
                     ->where('followers.profile_id', '=', $currentUserId);
             })
             ->whereNotIn('profiles.id', $blocked)
-            ->where(function ($query) use ($cleanQuery) {
-                $query->where('profiles.username', 'like', $cleanQuery.'%')
-                    ->orWhere('profiles.username', 'like', '%'.$cleanQuery.'%');
+            ->where(function ($query) use ($cleanQuery, $operator) {
+                $query->where('profiles.username', $operator, $cleanQuery.'%')
+                    ->orWhere('profiles.username', $operator, '%'.$cleanQuery.'%');
             })
             ->groupBy('profiles.id', 'profiles.domain', 'profiles.username', 'profiles.followers_count')
             ->orderByDesc('is_followed')

+ 45 - 51
app/Jobs/StatusPipeline/RemoteStatusDelete.php

@@ -2,47 +2,35 @@
 
 namespace App\Jobs\StatusPipeline;
 
-use DB, Cache, Storage;
-use App\{
-    AccountInterstitial,
-    Bookmark,
-    CollectionItem,
-    DirectMessage,
-    Like,
-    Media,
-    MediaTag,
-    Mention,
-    Notification,
-    Report,
-    Status,
-    StatusArchived,
-    StatusHashtag,
-    StatusView
-};
+use App\AccountInterstitial;
+use App\Bookmark;
+use App\CollectionItem;
+use App\DirectMessage;
+use App\Jobs\MediaPipeline\MediaDeletePipeline;
+use App\Like;
+use App\Media;
+use App\MediaTag;
+use App\Mention;
+use App\Notification;
+use App\Report;
+use App\Services\Account\AccountStatService;
+use App\Services\AccountService;
+use App\Services\CollectionService;
+use App\Services\NotificationService;
+use App\Services\StatusService;
+use App\Status;
+use App\StatusArchived;
+use App\StatusHashtag;
+use App\StatusView;
 use Illuminate\Bus\Queueable;
-use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
+use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Foundation\Bus\Dispatchable;
 use Illuminate\Queue\InteractsWithQueue;
-use Illuminate\Queue\SerializesModels;
 use Illuminate\Queue\Middleware\WithoutOverlapping;
-use League\Fractal;
-use Illuminate\Support\Str;
-use League\Fractal\Serializer\ArraySerializer;
-use App\Transformer\ActivityPub\Verb\DeleteNote;
-use App\Util\ActivityPub\Helpers;
-use GuzzleHttp\Pool;
-use GuzzleHttp\Client;
-use GuzzleHttp\Promise;
-use App\Util\ActivityPub\HttpSignature;
-use App\Services\AccountService;
-use App\Services\CollectionService;
-use App\Services\StatusService;
-use App\Jobs\MediaPipeline\MediaDeletePipeline;
-use App\Services\NotificationService;
-use App\Services\Account\AccountStatService;
+use Illuminate\Queue\SerializesModels;
 
-class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
+class RemoteStatusDelete implements ShouldBeUniqueUntilProcessing, ShouldQueue
 {
     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
@@ -56,8 +44,11 @@ class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
     public $deleteWhenMissingModels = true;
 
     public $tries = 3;
+
     public $maxExceptions = 3;
+
     public $timeout = 180;
+
     public $failOnTimeout = true;
 
     /**
@@ -72,7 +63,7 @@ class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
      */
     public function uniqueId(): string
     {
-        return 'status:remote:delete:' . $this->status->id;
+        return 'status:remote:delete:'.$this->status->id;
     }
 
     /**
@@ -104,11 +95,12 @@ class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
     {
         $status = $this->status;
 
-        if($status->deleted_at) {
+        if ($status->deleted_at) {
             return;
         }
 
         StatusService::del($status->id, true);
+
         // AccountStatService::decrementPostCount($status->profile_id);
         return $this->unlinkRemoveMedia($status);
     }
@@ -116,11 +108,13 @@ class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
     public function unlinkRemoveMedia($status)
     {
 
-        if($status->in_reply_to_id) {
+        if ($status->in_reply_to_id) {
             $parent = Status::find($status->in_reply_to_id);
-            if($parent) {
-                --$parent->reply_count;
-                $parent->save();
+            if ($parent) {
+                if ($parent->reply_count) {
+                    $parent->reply_count = $parent->reply_count - 1;
+                    $parent->save();
+                }
                 StatusService::del($parent->id);
             }
         }
@@ -132,16 +126,16 @@ class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
         CollectionItem::whereObjectType('App\Status')
             ->whereObjectId($status->id)
             ->get()
-            ->each(function($col) {
+            ->each(function ($col) {
                 CollectionService::removeItem($col->collection_id, $col->object_id);
                 $col->delete();
-        });
+            });
         $dms = DirectMessage::whereStatusId($status->id)->get();
-        foreach($dms as $dm) {
+        foreach ($dms as $dm) {
             $not = Notification::whereItemType('App\DirectMessage')
                 ->whereItemId($dm->id)
                 ->first();
-            if($not) {
+            if ($not) {
                 NotificationService::del($not->profile_id, $not->id);
                 $not->forceDeleteQuietly();
             }
@@ -149,16 +143,16 @@ class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
         }
         Like::whereStatusId($status->id)->forceDelete();
         Media::whereStatusId($status->id)
-        ->get()
-        ->each(function($media) {
-            MediaDeletePipeline::dispatch($media)->onQueue('mmo');
-        });
+            ->get()
+            ->each(function ($media) {
+                MediaDeletePipeline::dispatch($media)->onQueue('mmo');
+            });
         $mediaTags = MediaTag::where('status_id', $status->id)->get();
-        foreach($mediaTags as $mtag) {
+        foreach ($mediaTags as $mtag) {
             $not = Notification::whereItemType('App\MediaTag')
                 ->whereItemId($mtag->id)
                 ->first();
-            if($not) {
+            if ($not) {
                 NotificationService::del($not->profile_id, $not->id);
                 $not->forceDeleteQuietly();
             }