Ver Fonte

Merge pull request #3398 from pixelfed/staging

Staging
daniel há 3 anos atrás
pai
commit
3668f3d406

+ 17 - 12
app/Http/Controllers/Api/ApiV1Controller.php

@@ -81,6 +81,7 @@ use App\Jobs\MediaPipeline\MediaSyncLicensePipeline;
 use App\Services\DiscoverService;
 use App\Services\CustomEmojiService;
 use App\Services\MarkerService;
+use App\Models\Conversation;
 
 class ApiV1Controller extends Controller
 {
@@ -1867,27 +1868,31 @@ class ApiV1Controller extends Controller
 
 		if(config('database.default') == 'pgsql') {
 			$dms = DirectMessage::when($scope === 'inbox', function($q, $scope) use($pid) {
-					return $q->whereIsHidden(false)->whereToId($pid)->orWhere('from_id', $pid);
+					return $q->whereIsHidden(false)->where('to_id', $pid)->orWhere('from_id', $pid);
 				})
 				->when($scope === 'sent', function($q, $scope) use($pid) {
-					return $q->whereFromId($pid);
+					return $q->whereFromId($pid)->groupBy(['to_id', 'id']);
 				})
 				->when($scope === 'requests', function($q, $scope) use($pid) {
 					return $q->whereToId($pid)->whereIsHidden(true);
 				});
 		} else {
-			$dms = DirectMessage::when($scope === 'inbox', function($q, $scope) use($pid) {
-					return $q->whereIsHidden(false)->whereToId($pid)->orWhere('from_id', $pid)->groupBy('to_id');
-				})
-				->when($scope === 'sent', function($q, $scope) use($pid) {
-					return $q->whereFromId($pid)->groupBy('to_id');
-				})
-				->when($scope === 'requests', function($q, $scope) use($pid) {
-					return $q->whereToId($pid)->whereIsHidden(true);
-				});
+			$dms = Conversation::when($scope === 'inbox', function($q, $scope) use($pid) {
+				return $q->whereIsHidden(false)
+					->where('to_id', $pid)
+					->orWhere('from_id', $pid)
+					->orderByDesc('status_id')
+					->groupBy(['to_id', 'from_id']);
+			})
+			->when($scope === 'sent', function($q, $scope) use($pid) {
+				return $q->whereFromId($pid)->groupBy('to_id');
+			})
+			->when($scope === 'requests', function($q, $scope) use($pid) {
+				return $q->whereToId($pid)->whereIsHidden(true);
+			});
 		}
 
-		$dms = $dms->latest()
+		$dms = $dms->orderByDesc('status_id')
 			->simplePaginate($limit)
 			->map(function($dm) use($pid) {
 				$from = $pid == $dm->to_id ? $dm->from_id : $dm->to_id;

+ 27 - 0
app/Http/Controllers/DirectMessageController.php

@@ -20,6 +20,7 @@ use App\Jobs\StatusPipeline\NewStatusPipeline;
 use Illuminate\Support\Str;
 use App\Util\ActivityPub\Helpers;
 use App\Services\WebfingerService;
+use App\Models\Conversation;
 
 class DirectMessageController extends Controller
 {
@@ -329,6 +330,19 @@ class DirectMessageController extends Controller
 		$dm->type = $request->input('type');
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $recipient->id,
+				'from_id' => $profile->id
+			],
+			[
+				'type' => $dm->type,
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => $hidden
+			]
+		);
+
 		if(filter_var($msg, FILTER_VALIDATE_URL)) {
 			if(Helpers::validateUrl($msg)) {
 				$dm->type = 'link';
@@ -573,6 +587,19 @@ class DirectMessageController extends Controller
 		$dm->is_hidden = $hidden;
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $recipient->id,
+				'from_id' => $profile->id
+			],
+			[
+				'type' => $dm->type,
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => $hidden
+			]
+		);
+
 		if($recipient->domain) {
 			$this->remoteDeliver($dm);
 		}

+ 34 - 0
app/Http/Controllers/FederationController.php

@@ -121,6 +121,23 @@ class FederationController extends Controller
 		$obj = json_decode($payload, true, 8);
 
 		if(isset($obj['type']) && $obj['type'] === 'Delete') {
+			if(!isset($obj['id'])) {
+				return;
+			}
+			$lockKey = 'pf:ap:del-lock:' . hash('sha256', $obj['id']);
+			if( isset($obj['actor']) &&
+				isset($obj['object']) &&
+				isset($obj['id']) &&
+				is_string($obj['id']) &&
+				is_string($obj['actor']) &&
+				is_string($obj['object']) &&
+				$obj['actor'] == $obj['object']
+			) {
+				if(Cache::get($lockKey) !== null) {
+					return;
+				}
+			}
+			Cache::put($lockKey, 1, 3600);
 			dispatch(new DeleteWorker($headers, $payload))->onQueue('delete');
 		} else {
 			dispatch(new InboxValidator($username, $headers, $payload))->onQueue('high');
@@ -138,6 +155,23 @@ class FederationController extends Controller
 		$obj = json_decode($payload, true, 8);
 
 		if(isset($obj['type']) && $obj['type'] === 'Delete') {
+			if(!isset($obj['id'])) {
+				return;
+			}
+			$lockKey = 'pf:ap:del-lock:' . hash('sha256', $obj['id']);
+			if( isset($obj['actor']) &&
+				isset($obj['object']) &&
+				isset($obj['id']) &&
+				is_string($obj['id']) &&
+				is_string($obj['actor']) &&
+				is_string($obj['object']) &&
+				$obj['actor'] == $obj['object']
+			) {
+				if(Cache::get($lockKey) !== null) {
+					return;
+				}
+			}
+			Cache::put($lockKey, 1, 3600);
 			dispatch(new DeleteWorker($headers, $payload))->onQueue('delete');
 		} else {
 			dispatch(new InboxWorker($headers, $payload))->onQueue('high');

+ 27 - 0
app/Http/Controllers/StoryComposeController.php

@@ -28,6 +28,7 @@ use App\Jobs\StoryPipeline\StoryReplyDeliver;
 use App\Jobs\StoryPipeline\StoryFanout;
 use App\Jobs\StoryPipeline\StoryDelete;
 use ImageOptimizer;
+use App\Models\Conversation;
 
 class StoryComposeController extends Controller
 {
@@ -420,6 +421,19 @@ class StoryComposeController extends Controller
 		]);
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $story->profile_id,
+				'from_id' => $pid
+			],
+			[
+				'type' => 'story:react',
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => false
+			]
+		);
+
 		if($story->local) {
 			// generate notification
 			$n = new Notification;
@@ -481,6 +495,19 @@ class StoryComposeController extends Controller
 		]);
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $story->profile_id,
+				'from_id' => $pid
+			],
+			[
+				'type' => 'story:comment',
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => false
+			]
+		);
+
 		if($story->local) {
 			// generate notification
 			$n = new Notification;

+ 0 - 9
app/Jobs/InboxPipeline/DeleteWorker.php

@@ -49,15 +49,6 @@ class DeleteWorker implements ShouldQueue
 		$headers = $this->headers;
 		$payload = json_decode($this->payload, true, 8);
 
-		if(isset($payload['id'])) {
-			$lockKey = 'pf:ap:del-lock:' . hash('sha256', $payload['id']);
-			if(Cache::get($lockKey) !== null) {
-				// Job processed already
-				return 1;
-			}
-			Cache::put($lockKey, 1, 300);
-		}
-
 		if(!isset($headers['signature']) || !isset($headers['date'])) {
 			return;
 		}

+ 11 - 0
app/Models/Conversation.php

@@ -0,0 +1,11 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class Conversation extends Model
+{
+    use HasFactory;
+}

+ 5 - 0
app/Services/StatusLabelService.php

@@ -19,6 +19,11 @@ class StatusLabelService
 		}
 		
 		return Cache::remember(self::CACHE_KEY . $status->id, now()->addDays(7), function() use($status) {
+			if(!$status->caption) {
+				return [
+					'covid' => false
+				];
+			}
 			return [
 				'covid' => Str::of(strtolower($status->caption))->contains(['covid','corona', 'coronavirus', 'vaccine', 'vaxx', 'vaccination', 'plandemic'])
 			];

+ 1 - 1
app/Services/StatusService.php

@@ -131,7 +131,7 @@ class StatusService
 
 		$fractal = new Fractal\Manager();
 		$fractal->setSerializer(new ArraySerializer());
-		$resource = new Fractal\Resource\Item($status, new StatusTransformer());
+		$resource = new Fractal\Resource\Item($status, new StatusStatelessTransformer());
 		return $fractal->createData($resource)->toArray();
 	}
 

+ 1 - 1
app/Transformer/Api/AccountTransformer.php

@@ -30,7 +30,7 @@ class AccountTransformer extends Fractal\TransformerAbstract
 			'following_count' => (int) $profile->followingCount(),
 			'statuses_count' => (int) $profile->statusCount(),
 			'note' => $profile->bio ?? '',
-			'note_text' => strip_tags($profile->bio),
+			'note_text' => $profile->bio ? strip_tags($profile->bio) : null,
 			'url' => $profile->url(),
 			'avatar' => $profile->avatarUrl(),
 			'website' => $profile->website,

+ 40 - 0
app/Util/ActivityPub/Inbox.php

@@ -36,6 +36,7 @@ use App\Util\ActivityPub\Validator\UndoFollow as UndoFollowValidator;
 
 use App\Services\PollService;
 use App\Services\FollowerService;
+use App\Models\Conversation;
 
 class Inbox
 {
@@ -368,6 +369,19 @@ class Inbox
 		$dm->type = 'text';
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $profile->id,
+				'from_id' => $actor->id
+			],
+			[
+				'type' => 'text',
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => $hidden
+			]
+		);
+
 		if(count($activity['attachment'])) {
 			$photos = 0;
 			$videos = 0;
@@ -911,6 +925,19 @@ class Inbox
 		]);
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $story->profile_id,
+				'from_id' => $actorProfile->id
+			],
+			[
+				'type' => 'story:react',
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => false
+			]
+		);
+
 		$n = new Notification;
 		$n->profile_id = $dm->to_id;
 		$n->actor_id = $dm->from_id;
@@ -1007,6 +1034,19 @@ class Inbox
 		]);
 		$dm->save();
 
+		Conversation::updateOrInsert(
+			[
+				'to_id' => $story->profile_id,
+				'from_id' => $actorProfile->id
+			],
+			[
+				'type' => 'story:comment',
+				'status_id' => $status->id,
+				'dm_id' => $dm->id,
+				'is_hidden' => false
+			]
+		);
+
 		$n = new Notification;
 		$n->profile_id = $dm->to_id;
 		$n->actor_id = $dm->from_id;

+ 62 - 0
database/migrations/2022_04_20_061915_create_conversations_table.php

@@ -0,0 +1,62 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\DirectMessage;
+use App\Models\Conversation;
+use Illuminate\Support\Facades\DB;
+
+class CreateConversationsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('conversations', function (Blueprint $table) {
+            $table->bigIncrements('id');
+            $table->bigInteger('to_id')->unsigned()->index();
+            $table->bigInteger('from_id')->unsigned()->index();
+            $table->bigInteger('dm_id')->unsigned()->nullable();
+            $table->bigInteger('status_id')->unsigned()->nullable();
+            $table->string('type')->nullable();
+            $table->boolean('is_hidden')->default(false)->index();
+            $table->boolean('has_seen')->default(false)->index();
+            $table->json('metadata')->nullable();
+            $table->unique(['to_id', 'from_id']);
+            $table->timestamps();
+        });
+
+        sleep(10);
+
+        if(DirectMessage::count()) {
+
+        	foreach(DirectMessage::lazy() as $msg) {
+				Conversation::updateOrInsert([
+					'to_id' => $msg->to_id,
+					'from_id' => $msg->from_id,
+				],
+				[
+					'dm_id' => $msg->id,
+					'status_id' => $msg->status_id,
+					'type' => $msg->type,
+					'created_at' => $msg->created_at,
+					'updated_at' => $msg->updated_at
+				]);
+        	}
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('conversations');
+    }
+}