From cc1b081aa4e9d7fa4530930de56fc3104de57286 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:04:45 -0700 Subject: [PATCH 01/30] Update package.json, add blurhash --- package-lock.json | 5 +++++ package.json | 1 + 2 files changed, 6 insertions(+) diff --git a/package-lock.json b/package-lock.json index 494c83bfc..9ed8b9ea3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1649,6 +1649,11 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==" }, + "blurhash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/blurhash/-/blurhash-1.1.3.tgz", + "integrity": "sha512-yUhPJvXexbqbyijCIE/T2NCXcj9iNPhWmOKbPTuR/cm7Q5snXYIfnVnz6m7MWOXxODMz/Cr3UcVkRdHiuDVRDw==" + }, "bn.js": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz", diff --git a/package.json b/package.json index 4c1ccd439..3a6285a0b 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "dependencies": { "@trevoreyre/autocomplete-vue": "^2.2.0", "animate.css": "^4.1.0", + "blurhash": "^1.1.3", "bootstrap-vue": "^2.16.0", "filesize": "^3.6.1", "howler": "^2.2.0", From 39ed08cccae7cdc787815a105a0a60b694fd57c1 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:05:33 -0700 Subject: [PATCH 02/30] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbbad8716..eb4493726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,6 +106,8 @@ - Updated federation config, make sharedInbox enabled by default. ([6e3522c0](https://github.com/pixelfed/pixelfed/commit/6e3522c0)) - Updated PostComponent, change timestamp format. ([e51665f6](https://github.com/pixelfed/pixelfed/commit/e51665f6)) - Updated PostComponent, use proper username context for reply mentions. Fixes ([#2421](https://github.com/pixelfed/pixelfed/issues/2421)). ([dac06088](https://github.com/pixelfed/pixelfed/commit/dac06088)) +- Updated Navbar, added profile avatar. ([19abf1b4](https://github.com/pixelfed/pixelfed/commit/19abf1b4)) +- Updated package.json, add blurhash. ([cc1b081a](https://github.com/pixelfed/pixelfed/commit/cc1b081a)) ## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9) ### Added From 77bb2299bd1e46c31cedd8c903a4869f998d5f7b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:06:05 -0700 Subject: [PATCH 03/30] Add new migration, add index to likes table --- ...2_01_073200_add_indexes_to_likes_table.php | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 database/migrations/2020_12_01_073200_add_indexes_to_likes_table.php diff --git a/database/migrations/2020_12_01_073200_add_indexes_to_likes_table.php b/database/migrations/2020_12_01_073200_add_indexes_to_likes_table.php new file mode 100644 index 000000000..1a1256fbb --- /dev/null +++ b/database/migrations/2020_12_01_073200_add_indexes_to_likes_table.php @@ -0,0 +1,34 @@ +index('profile_id', 'likes_profile_id_index'); + $table->index('status_id', 'likes_status_id_index'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('likes', function (Blueprint $table) { + $table->dropIndex('likes_profile_id_index'); + $table->dropIndex('likes_status_id_index'); + }); + } +} From 8766ccfe4fd6d70f5c9fe3babcc48aae84d86a49 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:08:05 -0700 Subject: [PATCH 04/30] Add AccountInterstitial model and controller --- app/AccountInterstitial.php | 30 ++++++++ .../AccountInterstitialController.php | 76 +++++++++++++++++++ ...018_create_account_interstitials_table.php | 53 +++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 app/AccountInterstitial.php create mode 100644 app/Http/Controllers/AccountInterstitialController.php create mode 100644 database/migrations/2020_12_03_050018_create_account_interstitials_table.php diff --git a/app/AccountInterstitial.php b/app/AccountInterstitial.php new file mode 100644 index 000000000..d2626ab58 --- /dev/null +++ b/app/AccountInterstitial.php @@ -0,0 +1,30 @@ +belongsTo(User::class); + } + + public function status() + { + if($this->item_type != 'App\Status') { + return; + } + return $this->hasOne(Status::class, 'id', 'item_id'); + } +} diff --git a/app/Http/Controllers/AccountInterstitialController.php b/app/Http/Controllers/AccountInterstitialController.php new file mode 100644 index 000000000..96c102e00 --- /dev/null +++ b/app/Http/Controllers/AccountInterstitialController.php @@ -0,0 +1,76 @@ +middleware('auth'); + } + + public function get(Request $request) + { + $interstitial = $request->user() + ->interstitials() + ->whereNull('read_at') + ->first(); + if(!$interstitial) { + $user = $request->user(); + $user->has_interstitial = false; + $user->save(); + return redirect('/'); + } + $meta = json_decode($interstitial->meta); + $view = $interstitial->view; + return view($view, compact('interstitial', 'meta')); + } + + public function read(Request $request) + { + $this->validate($request, [ + 'id' => 'required', + 'type' => 'required|in:post.cw,post.removed,post.unlist', + 'action' => 'required|in:appeal,confirm', + 'appeal_message' => 'nullable|max:500' + ]); + + $redirect = '/'; + + $id = decrypt($request->input('id')); + $action = $request->input('action'); + $user = $request->user(); + + $ai = AccountInterstitial::whereUserId($user->id) + ->whereType($request->input('type')) + ->findOrFail($id); + + if($action == 'appeal') { + $ai->appeal_requested_at = now(); + $ai->appeal_message = $request->input('appeal_message'); + } + + $ai->read_at = now(); + $ai->save(); + + $more = AccountInterstitial::whereUserId($user->id) + ->whereNull('read_at') + ->exists(); + + if(!$more) { + $user->has_interstitial = false; + $user->save(); + } + + if(in_array($ai->type, ['post.cw', 'post.unlist'])) { + $redirect = Status::findOrFail($ai->item_id)->url(); + } + + return redirect($redirect); + } +} diff --git a/database/migrations/2020_12_03_050018_create_account_interstitials_table.php b/database/migrations/2020_12_03_050018_create_account_interstitials_table.php new file mode 100644 index 000000000..0b0e8862c --- /dev/null +++ b/database/migrations/2020_12_03_050018_create_account_interstitials_table.php @@ -0,0 +1,53 @@ +id(); + $table->unsignedInteger('user_id')->nullable()->index(); + $table->string('type')->nullable(); + $table->string('view')->nullable(); + $table->bigInteger('item_id')->unsigned()->nullable(); + $table->string('item_type')->nullable(); + $table->boolean('has_media')->default(false)->nullable(); + $table->string('blurhash')->nullable(); + $table->text('message')->nullable(); + $table->text('violation_header')->nullable(); + $table->text('violation_body')->nullable(); + $table->json('meta')->nullable(); + $table->text('appeal_message')->nullable(); + $table->timestamp('appeal_requested_at')->nullable()->index(); + $table->timestamp('appeal_handled_at')->nullable()->index(); + $table->timestamp('read_at')->nullable()->index(); + $table->timestamps(); + }); + + Schema::table('users', function(Blueprint $table) { + $table->boolean('has_interstitial')->default(false)->index(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('account_interstitials'); + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('has_interstitial'); + }); + } +} From 6ea1db538a6846beaeefbfef0742dcf18e0e0bb9 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:10:48 -0700 Subject: [PATCH 05/30] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb4493726..a53b842b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Add Password change email notification ([de1cca4f](https://github.com/pixelfed/pixelfed/commit/de1cca4f)) - Add shared inbox ([4733ca9f](https://github.com/pixelfed/pixelfed/commit/4733ca9f)) - Add federated photo filters ([0a5a0e86](https://github.com/pixelfed/pixelfed/commit/0a5a0e86)) +- Add AccountInterstitial model and controller ([8766ccfe](https://github.com/pixelfed/pixelfed/commit/8766ccfe)) ### Updated - Updated PostComponent, fix remote urls ([42716ccc](https://github.com/pixelfed/pixelfed/commit/42716ccc)) From 327ef1384bd4ccf254192f4121cce5c92429e801 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:12:08 -0700 Subject: [PATCH 06/30] Update Status model, fix thumb nsfw caching --- app/Status.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Status.php b/app/Status.php index 6232a3359..3b6f6120c 100644 --- a/app/Status.php +++ b/app/Status.php @@ -89,7 +89,8 @@ class Status extends Model public function thumb($showNsfw = false) { - return Cache::remember('status:thumb:'.$this->id, now()->addMinutes(15), function() use ($showNsfw) { + $key = $showNsfw ? 'status:thumb:nsfw1'.$this->id : 'status:thumb:nsfw0'.$this->id; + return Cache::remember($key, now()->addMinutes(15), function() use ($showNsfw) { $type = $this->type ?? $this->setType(); $is_nsfw = !$showNsfw ? $this->is_nsfw : false; if ($this->media->count() == 0 || $is_nsfw || !in_array($type,['photo', 'photo:album', 'video'])) { From bd321a72f07798eae3ba616df6d3af85557df7a1 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:13:24 -0700 Subject: [PATCH 07/30] Update User model, add interstitial relation --- app/User.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/User.php b/app/User.php index 717c4f316..4bd60a075 100644 --- a/app/User.php +++ b/app/User.php @@ -88,4 +88,9 @@ class User extends Authenticatable return $this->hasMany(AccountLog::class); } + public function interstitials() + { + return $this->hasMany(AccountInterstitial::class); + } + } From 4d22426da2604427cdf24004cbfb6f0ffbbc0ba9 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:14:29 -0700 Subject: [PATCH 08/30] Update StatusStatelessTransformer, add missing attributes --- app/Transformer/Api/StatusStatelessTransformer.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/Transformer/Api/StatusStatelessTransformer.php b/app/Transformer/Api/StatusStatelessTransformer.php index 07eefb4a2..9023586e1 100644 --- a/app/Transformer/Api/StatusStatelessTransformer.php +++ b/app/Transformer/Api/StatusStatelessTransformer.php @@ -5,6 +5,8 @@ namespace App\Transformer\Api; use App\Status; use League\Fractal; use Cache; +use App\Services\HashidService; +use App\Services\MediaTagService; class StatusStatelessTransformer extends Fractal\TransformerAbstract { @@ -17,8 +19,11 @@ class StatusStatelessTransformer extends Fractal\TransformerAbstract public function transform(Status $status) { + $taggedPeople = MediaTagService::get($status->id); + return [ 'id' => (string) $status->id, + 'shortcode' => HashidService::encode($status->id), 'uri' => $status->url(), 'url' => $status->url(), 'in_reply_to_id' => $status->in_reply_to_id, @@ -42,13 +47,17 @@ class StatusStatelessTransformer extends Fractal\TransformerAbstract 'language' => null, 'pinned' => null, + 'mentions' => [], + 'tags' => [], 'pf_type' => $status->type ?? $status->setType(), 'reply_count' => (int) $status->reply_count, 'comments_disabled' => $status->comments_disabled ? true : false, 'thread' => false, 'replies' => [], - 'parent' => $status->parent() ? $this->transform($status->parent()) : [], + 'parent' => [], + 'place' => $status->place, 'local' => (bool) $status->local, + 'taggedPeople' => $taggedPeople ]; } From fad102bf80d4bb266de93008750fcca7e1223cf5 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:16:27 -0700 Subject: [PATCH 09/30] Add Blurhash encoder --- app/Util/Blurhash/AC.php | 34 ++++++++ app/Util/Blurhash/Base83.php | 39 +++++++++ app/Util/Blurhash/Blurhash.php | 139 +++++++++++++++++++++++++++++++++ app/Util/Blurhash/Color.php | 19 +++++ app/Util/Blurhash/DC.php | 24 ++++++ 5 files changed, 255 insertions(+) create mode 100644 app/Util/Blurhash/AC.php create mode 100644 app/Util/Blurhash/Base83.php create mode 100644 app/Util/Blurhash/Blurhash.php create mode 100644 app/Util/Blurhash/Color.php create mode 100644 app/Util/Blurhash/DC.php diff --git a/app/Util/Blurhash/AC.php b/app/Util/Blurhash/AC.php new file mode 100644 index 000000000..a157c48b8 --- /dev/null +++ b/app/Util/Blurhash/AC.php @@ -0,0 +1,34 @@ + 0; + return $sign * pow(abs($base), $exp); + } +} \ No newline at end of file diff --git a/app/Util/Blurhash/Base83.php b/app/Util/Blurhash/Base83.php new file mode 100644 index 000000000..043ca2e60 --- /dev/null +++ b/app/Util/Blurhash/Base83.php @@ -0,0 +1,39 @@ + 9) || ($components_y < 1 || $components_y > 9)) { + throw new InvalidArgumentException("x and y component counts must be between 1 and 9 inclusive."); + } + $height = count($image); + $width = count($image[0]); + + $image_linear = $image; + if (!$linear) { + $image_linear = []; + for ($y = 0; $y < $height; $y++) { + $line = []; + for ($x = 0; $x < $width; $x++) { + $pixel = $image[$y][$x]; + $line[] = [ + Color::toLinear($pixel[0]), + Color::toLinear($pixel[1]), + Color::toLinear($pixel[2]) + ]; + } + $image_linear[] = $line; + } + } + + $components = []; + $scale = 1 / ($width * $height); + for ($y = 0; $y < $components_y; $y++) { + for ($x = 0; $x < $components_x; $x++) { + $normalisation = $x == 0 && $y == 0 ? 1 : 2; + $r = $g = $b = 0; + for ($i = 0; $i < $width; $i++) { + for ($j = 0; $j < $height; $j++) { + $color = $image_linear[$j][$i]; + $basis = $normalisation + * cos(M_PI * $i * $x / $width) + * cos(M_PI * $j * $y / $height); + + $r += $basis * $color[0]; + $g += $basis * $color[1]; + $b += $basis * $color[2]; + } + } + + $components[] = [ + $r * $scale, + $g * $scale, + $b * $scale + ]; + } + } + + $dc_value = DC::encode(array_shift($components) ?: []); + + $max_ac_component = 0; + foreach ($components as $component) { + $component[] = $max_ac_component; + $max_ac_component = max ($component); + } + + $quant_max_ac_component = (int) max(0, min(82, floor($max_ac_component * 166 - 0.5))); + $ac_component_norm_factor = ($quant_max_ac_component + 1) / 166; + + $ac_values = []; + foreach ($components as $component) { + $ac_values[] = AC::encode($component, $ac_component_norm_factor); + } + + $blurhash = Base83::encode($components_x - 1 + ($components_y - 1) * 9, 1); + $blurhash .= Base83::encode($quant_max_ac_component, 1); + $blurhash .= Base83::encode($dc_value, 4); + foreach ($ac_values as $ac_value) { + $blurhash .= Base83::encode((int) $ac_value, 2); + } + + return $blurhash; + } + + public static function decode (string $blurhash, int $width, int $height, float $punch = 1.0, bool $linear = false): array { + if (empty($blurhash) || strlen($blurhash) < 6) { + throw new InvalidArgumentException("Blurhash string must be at least 6 characters"); + } + + $size_info = Base83::decode($blurhash[0]); + $size_y = floor($size_info / 9) + 1; + $size_x = ($size_info % 9) + 1; + + $length = (int) strlen($blurhash); + $expected_length = (int) (4 + (2 * $size_y * $size_x)); + if ($length !== $expected_length) { + throw new InvalidArgumentException("Blurhash length mismatch: length is {$length} but it should be {$expected_length}"); + } + + $colors = [DC::decode(Base83::decode(substr($blurhash, 2, 4)))]; + + $quant_max_ac_component = Base83::decode($blurhash[1]); + $max_value = ($quant_max_ac_component + 1) / 166; + for ($i = 1; $i < $size_x * $size_y; $i++) { + $value = Base83::decode(substr($blurhash, 4 + $i * 2, 2)); + $colors[$i] = AC::decode($value, $max_value * $punch); + } + + $pixels = []; + for ($y = 0; $y < $height; $y++) { + $row = []; + for ($x = 0; $x < $width; $x++) { + $r = $g = $b = 0; + for ($j = 0; $j < $size_y; $j++) { + for ($i = 0; $i < $size_x; $i++) { + $color = $colors[$i + $j * $size_x]; + $basis = + cos((M_PI * $x * $i) / $width) * + cos((M_PI * $y * $j) / $height); + + $r += $color[0] * $basis; + $g += $color[1] * $basis; + $b += $color[2] * $basis; + } + } + + $row[] = $linear ? [$r, $g, $b] : [ + Color::toSRGB($r), + Color::toSRGB($g), + Color::toSRGB($b) + ]; + } + $pixels[] = $row; + } + + return $pixels; + } +} \ No newline at end of file diff --git a/app/Util/Blurhash/Color.php b/app/Util/Blurhash/Color.php new file mode 100644 index 000000000..4b64c32f7 --- /dev/null +++ b/app/Util/Blurhash/Color.php @@ -0,0 +1,19 @@ +> 16; + $g = ($value >> 8) & 255; + $b = $value & 255; + return [ + Color::toLinear($r), + Color::toLinear($g), + Color::toLinear($b) + ]; + } +} \ No newline at end of file From 9404a36c66c3a7005955791808f08e087fbc2808 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:17:45 -0700 Subject: [PATCH 10/30] Add Blurhash util --- app/Util/Media/Blurhash.php | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 app/Util/Media/Blurhash.php diff --git a/app/Util/Media/Blurhash.php b/app/Util/Media/Blurhash.php new file mode 100644 index 000000000..2be054e02 --- /dev/null +++ b/app/Util/Media/Blurhash.php @@ -0,0 +1,47 @@ +mime, ['image/png', 'image/jpeg'])) { + return; + } + + $file = storage_path('app/' . $media->thumbnail_path); + + if(!is_file($file)) { + return; + } + + $image = imagecreatefromstring(file_get_contents($file)); + $width = imagesx($image); + $height = imagesy($image); + + $pixels = []; + for ($y = 0; $y < $height; ++$y) { + $row = []; + for ($x = 0; $x < $width; ++$x) { + $index = imagecolorat($image, $x, $y); + $colors = imagecolorsforindex($image, $index); + + $row[] = [$colors['red'], $colors['green'], $colors['blue']]; + } + $pixels[] = $row; + } + + $components_x = 4; + $components_y = 4; + $blurhash = BlurhashEngine::encode($pixels, $components_x, $components_y); + if(strlen($blurhash) > 191) { + return; + } + return $blurhash; + } + +} \ No newline at end of file From 473e04952892ef1764d345304c83a8a4fc98aad8 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:18:34 -0700 Subject: [PATCH 11/30] Update media pipeline, add blurhash support --- app/Util/Media/Image.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/Util/Media/Image.php b/app/Util/Media/Image.php index bbc877ffa..0cf359237 100644 --- a/app/Util/Media/Image.php +++ b/app/Util/Media/Image.php @@ -182,6 +182,10 @@ class Image $media->save(); + + if($thumbnail) { + $this->generateBlurhash($media); + } Cache::forget('status:transformer:media:attachments:'.$media->status_id); Cache::forget('status:thumb:'.$media->status_id); } catch (Exception $e) { @@ -198,4 +202,13 @@ class Image return ['path' => $basePath, 'png' => $png]; } + + protected function generateBlurhash($media) + { + $blurhash = Blurhash::generate($media); + if($blurhash) { + $media->blurhash = $blurhash; + $media->save(); + } + } } From b3078f274f5fdc42f140e34824fd8722dc0fb4e6 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:20:45 -0700 Subject: [PATCH 12/30] Update DeleteAccountPipeline, add AccountInterstitial and DirectMessage purging --- app/Jobs/DeletePipeline/DeleteAccountPipeline.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Jobs/DeletePipeline/DeleteAccountPipeline.php b/app/Jobs/DeletePipeline/DeleteAccountPipeline.php index c9777df5e..a225b48d9 100644 --- a/app/Jobs/DeletePipeline/DeleteAccountPipeline.php +++ b/app/Jobs/DeletePipeline/DeleteAccountPipeline.php @@ -10,6 +10,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use DB; use Illuminate\Support\Str; use App\{ + AccountInterstitial, AccountLog, Activity, Avatar, @@ -68,6 +69,10 @@ class DeleteAccountPipeline implements ShouldQueue }); }); + DB::transaction(function() use ($user) { + AccountInterstitial::whereUserId($user->id)->delete(); + }); + DB::transaction(function() use ($user) { if($user->profile) { $avatar = $user->profile->avatar; @@ -79,6 +84,7 @@ class DeleteAccountPipeline implements ShouldQueue Bookmark::whereProfileId($user->profile_id)->forceDelete(); EmailVerification::whereUserId($user->id)->forceDelete(); StatusHashtag::whereProfileId($id)->delete(); + DirectMessage::whereFromId($user->profile_id)->delete(); FollowRequest::whereFollowingId($id) ->orWhere('follower_id', $id) ->forceDelete(); From f1ab44686bc34ea6f1a08ff822df99defb6ce5d8 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:23:22 -0700 Subject: [PATCH 13/30] Update app.js, add blurhash --- resources/assets/js/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index 4664ac4e6..dbfc5e607 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -6,6 +6,7 @@ require('bootstrap'); window.axios = require('axios'); window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; require('readmore-js'); +window.blurhash = require("blurhash"); let token = document.head.querySelector('meta[name="csrf-token"]'); if (token) { From e28d022f62f2911514a377c5d8b021cfb363bfb7 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:24:26 -0700 Subject: [PATCH 14/30] Update ComposeModal.vue component, reuse sharedData --- .../assets/js/components/ComposeModal.vue | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/resources/assets/js/components/ComposeModal.vue b/resources/assets/js/components/ComposeModal.vue index 3a85aad87..72ed91e81 100644 --- a/resources/assets/js/components/ComposeModal.vue +++ b/resources/assets/js/components/ComposeModal.vue @@ -635,15 +635,23 @@ export default { methods: { fetchProfile() { let self = this; - axios.get('/api/pixelfed/v1/accounts/verify_credentials').then(res => { - self.profile = res.data; - window.pixelfed.currentUser = res.data; - if(res.data.locked == true) { - self.visibility = 'private'; - self.visibilityTag = 'Followers Only'; + if(window._sharedData.curUser) { + self.profile = window._sharedData.curUser; + if(self.profile.locked == true) { + self.visibility = 'private'; + self.visibilityTag = 'Followers Only'; } - }).catch(err => { - }); + } else { + axios.get('/api/pixelfed/v1/accounts/verify_credentials').then(res => { + self.profile = res.data; + window.pixelfed.currentUser = res.data; + if(res.data.locked == true) { + self.visibility = 'private'; + self.visibilityTag = 'Followers Only'; + } + }).catch(err => { + }); + } }, addMedia(event) { From b5c4246f5033464801c6a3e15206ae0bf7a58196 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sat, 5 Dec 2020 00:29:27 -0700 Subject: [PATCH 15/30] Update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a53b842b8..efc7a309e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Add shared inbox ([4733ca9f](https://github.com/pixelfed/pixelfed/commit/4733ca9f)) - Add federated photo filters ([0a5a0e86](https://github.com/pixelfed/pixelfed/commit/0a5a0e86)) - Add AccountInterstitial model and controller ([8766ccfe](https://github.com/pixelfed/pixelfed/commit/8766ccfe)) +- Add Blurhash encoder ([fad102bf](https://github.com/pixelfed/pixelfed/commit/fad102bf)) ### Updated - Updated PostComponent, fix remote urls ([42716ccc](https://github.com/pixelfed/pixelfed/commit/42716ccc)) @@ -109,6 +110,12 @@ - Updated PostComponent, use proper username context for reply mentions. Fixes ([#2421](https://github.com/pixelfed/pixelfed/issues/2421)). ([dac06088](https://github.com/pixelfed/pixelfed/commit/dac06088)) - Updated Navbar, added profile avatar. ([19abf1b4](https://github.com/pixelfed/pixelfed/commit/19abf1b4)) - Updated package.json, add blurhash. ([cc1b081a](https://github.com/pixelfed/pixelfed/commit/cc1b081a)) +- Updated Status model, fix thumb nsfw caching. ([327ef138](https://github.com/pixelfed/pixelfed/commit/327ef138)) +- Updated User model, add interstitial relation. ([bd321a72](https://github.com/pixelfed/pixelfed/commit/bd321a72)) +- Updated StatusStatelessTransformer, add missing attributes. ([4d22426d](https://github.com/pixelfed/pixelfed/commit/4d22426d)) +- Updated media pipeline, add blurhash support. ([473e0495](https://github.com/pixelfed/pixelfed/commit/473e0495)) +- Updated DeleteAccountPipeline, add AccountInterstitial and DirectMessage purging. ([b3078f27](https://github.com/pixelfed/pixelfed/commit/b3078f27)) +- Updated ComposeModal.vue component, reuse sharedData. ([e28d022f](https://github.com/pixelfed/pixelfed/commit/e28d022f)) ## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9) ### Added From db646026bee08977bd4a20176b57771dd426e1b9 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:17:26 -0700 Subject: [PATCH 16/30] Update discover view, remove unused compose script --- resources/views/discover/home.blade.php | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/views/discover/home.blade.php b/resources/views/discover/home.blade.php index f7e27737e..a4e9f633b 100644 --- a/resources/views/discover/home.blade.php +++ b/resources/views/discover/home.blade.php @@ -8,6 +8,5 @@ @push('scripts') - @endpush \ No newline at end of file From 0718711d099b438752b6c722a4cf018f51654095 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:34:43 -0700 Subject: [PATCH 17/30] Update ApiController, return status object after deletion --- app/Http/Controllers/Api/ApiV1Controller.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 7bf0646e2..0243939b7 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -1761,6 +1761,7 @@ class ApiV1Controller extends Controller NewStatusPipeline::dispatch($status); Cache::forget('user:account:id:'.$user->id); + Cache::forget('_api:statuses:recent_9:'.$user->profile_id); Cache::forget('profile:status_count:'.$user->profile_id); Cache::forget($user->storageUsedKey()); @@ -1783,10 +1784,15 @@ class ApiV1Controller extends Controller $status = Status::whereProfileId($request->user()->profile->id) ->findOrFail($id); + $resource = new Fractal\Resource\Item($status, new StatusTransformer()); + Cache::forget('profile:status_count:'.$status->profile_id); StatusDelete::dispatch($status); - return response()->json(['Status successfully deleted.']); + $res = $this->fractal->createData($resource)->toArray(); + $res['text'] = $res['content']; + unset($res['content']); + return response()->json($res); } /** From 20681bcf14a51df2ad650e205051c79ecd051100 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:36:32 -0700 Subject: [PATCH 18/30] Update InternalApiController, add interstitial logic --- .../Controllers/InternalApiController.php | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/app/Http/Controllers/InternalApiController.php b/app/Http/Controllers/InternalApiController.php index 6fe9a5bdf..e3fc8c757 100644 --- a/app/Http/Controllers/InternalApiController.php +++ b/app/Http/Controllers/InternalApiController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; use App\{ + AccountInterstitial, DirectMessage, DiscoverCategory, Hashtag, @@ -213,6 +214,35 @@ class InternalApiController extends Controller ]) ->accessLevel('admin') ->save(); + + + if($status->uri == null) { + $media = $status->media; + $ai = new AccountInterstitial; + $ai->user_id = $status->profile->user_id; + $ai->type = 'post.cw'; + $ai->view = 'account.moderation.post.cw'; + $ai->item_type = 'App\Status'; + $ai->item_id = $status->id; + $ai->has_media = (bool) $media->count(); + $ai->blurhash = $media->count() ? $media->first()->blurhash : null; + $ai->meta = json_encode([ + 'caption' => $status->caption, + 'created_at' => $status->created_at, + 'type' => $status->type, + 'url' => $status->url(), + 'is_nsfw' => $status->is_nsfw, + 'scope' => $status->scope, + 'reblog' => $status->reblog_of_id, + 'likes_count' => $status->likes_count, + 'reblogs_count' => $status->reblogs_count, + ]); + $ai->save(); + + $u = $status->profile->user; + $u->has_interstitial = true; + $u->save(); + } break; case 'remcw': @@ -231,6 +261,14 @@ class InternalApiController extends Controller ]) ->accessLevel('admin') ->save(); + if($status->uri == null) { + $ai = AccountInterstitial::whereUserId($status->profile->user_id) + ->whereType('post.cw') + ->whereItemId($status->id) + ->whereItemType('App\Status') + ->first(); + $ai->delete(); + } break; case 'unlist': @@ -250,6 +288,34 @@ class InternalApiController extends Controller ]) ->accessLevel('admin') ->save(); + + if($status->uri == null) { + $media = $status->media; + $ai = new AccountInterstitial; + $ai->user_id = $status->profile->user_id; + $ai->type = 'post.unlist'; + $ai->view = 'account.moderation.post.unlist'; + $ai->item_type = 'App\Status'; + $ai->item_id = $status->id; + $ai->has_media = (bool) $media->count(); + $ai->blurhash = $media->count() ? $media->first()->blurhash : null; + $ai->meta = json_encode([ + 'caption' => $status->caption, + 'created_at' => $status->created_at, + 'type' => $status->type, + 'url' => $status->url(), + 'is_nsfw' => $status->is_nsfw, + 'scope' => $status->scope, + 'reblog' => $status->reblog_of_id, + 'likes_count' => $status->likes_count, + 'reblogs_count' => $status->reblogs_count, + ]); + $ai->save(); + + $u = $status->profile->user; + $u->has_interstitial = true; + $u->save(); + } break; } return ['msg' => 200]; @@ -364,6 +430,7 @@ class InternalApiController extends Controller NewStatusPipeline::dispatch($status); Cache::forget('user:account:id:'.$profile->user_id); + Cache::forget('_api:statuses:recent_9:'.$profile->id); Cache::forget('profile:status_count:'.$profile->id); Cache::forget($user->storageUsedKey()); return $status->url(); From 342e7a50c92f1d0594f9367e258294150976b227 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:40:24 -0700 Subject: [PATCH 19/30] Update PublicApiController, improve stateless object caching --- app/Http/Controllers/PublicApiController.php | 68 +++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/PublicApiController.php b/app/Http/Controllers/PublicApiController.php index 8dab9b65f..34757efa6 100644 --- a/app/Http/Controllers/PublicApiController.php +++ b/app/Http/Controllers/PublicApiController.php @@ -20,7 +20,8 @@ use League\Fractal; use App\Transformer\Api\{ AccountTransformer, RelationshipTransformer, - StatusTransformer + StatusTransformer, + StatusStatelessTransformer }; use App\Services\{ AccountService, @@ -86,6 +87,24 @@ class PublicApiController extends Controller $profile = Profile::whereUsername($username)->whereNull('status')->firstOrFail(); $status = Status::whereProfileId($profile->id)->findOrFail($postid); $this->scopeCheck($profile, $status); + if(!Auth::check()) { + $res = Cache::remember('wapi:v1:status:stateless_byid:' . $status->id, now()->addMinutes(30), function() use($status) { + $item = new Fractal\Resource\Item($status, new StatusStatelessTransformer()); + $res = [ + 'status' => $this->fractal->createData($item)->toArray(), + 'user' => [], + 'likes' => [], + 'shares' => [], + 'reactions' => [ + 'liked' => false, + 'shared' => false, + 'bookmarked' => false, + ], + ]; + return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + }); + return $res; + } $item = new Fractal\Resource\Item($status, new StatusTransformer()); $res = [ 'status' => $this->fractal->createData($item)->toArray(), @@ -419,7 +438,6 @@ class PublicApiController extends Controller } - public function networkTimelineApi(Request $request) { return response()->json([]); @@ -543,6 +561,50 @@ class PublicApiController extends Controller } } + $tag = in_array('private', $visibility) ? 'private' : 'public'; + if($min_id == 1 && $limit == 9 && $tag == 'public') { + $limit = 9; + $scope = ['photo', 'photo:album', 'video', 'video:album']; + $key = '_api:statuses:recent_9:'.$profile->id; + $res = Cache::remember($key, now()->addHours(24), function() use($profile, $scope, $visibility, $limit) { + $dir = '>'; + $id = 1; + $timeline = Status::select( + 'id', + 'uri', + 'caption', + 'rendered', + 'profile_id', + 'type', + 'in_reply_to_id', + 'reblog_of_id', + 'is_nsfw', + 'likes_count', + 'reblogs_count', + 'scope', + 'visibility', + 'local', + 'place_id', + 'comments_disabled', + 'cw_summary', + 'created_at', + 'updated_at' + )->whereProfileId($profile->id) + ->whereIn('type', $scope) + ->where('id', $dir, $id) + ->whereIn('visibility', $visibility) + ->limit($limit) + ->orderByDesc('id') + ->get(); + + $resource = new Fractal\Resource\Collection($timeline, new StatusStatelessTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + }); + return $res; + } + $dir = $min_id ? '>' : '<'; $id = $min_id ?? $max_id; $timeline = Status::select( @@ -560,6 +622,8 @@ class PublicApiController extends Controller 'scope', 'visibility', 'local', + 'place_id', + 'comments_disabled', 'cw_summary', 'created_at', 'updated_at' From 003caf7e8abf7a12b3977b9f1f20fa79868156ea Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:43:09 -0700 Subject: [PATCH 20/30] Update StatusController, add interstitial logic --- app/Http/Controllers/StatusController.php | 40 +++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/StatusController.php b/app/Http/Controllers/StatusController.php index f98fa5d63..c0bf8e06d 100644 --- a/app/Http/Controllers/StatusController.php +++ b/app/Http/Controllers/StatusController.php @@ -6,6 +6,7 @@ use App\Jobs\ImageOptimizePipeline\ImageOptimize; use App\Jobs\StatusPipeline\NewStatusPipeline; use App\Jobs\StatusPipeline\StatusDelete; use App\Jobs\SharePipeline\SharePipeline; +use App\AccountInterstitial; use App\Media; use App\Profile; use App\Status; @@ -162,14 +163,49 @@ class StatusController extends Controller $status = Status::findOrFail($request->input('item')); - if ($status->profile_id === Auth::user()->profile->id || Auth::user()->is_admin == true) { + $user = Auth::user(); + + if($status->profile_id != $user->profile->id && + $user->is_admin == true && + $status->uri == null + ) { + $media = $status->media; + + $ai = new AccountInterstitial; + $ai->user_id = $status->profile->user_id; + $ai->type = 'post.removed'; + $ai->view = 'account.moderation.post.removed'; + $ai->item_type = 'App\Status'; + $ai->item_id = $status->id; + $ai->has_media = (bool) $media->count(); + $ai->blurhash = $media->count() ? $media->first()->blurhash : null; + $ai->meta = json_encode([ + 'caption' => $status->caption, + 'created_at' => $status->created_at, + 'type' => $status->type, + 'url' => $status->url(), + 'is_nsfw' => $status->is_nsfw, + 'scope' => $status->scope, + 'reblog' => $status->reblog_of_id, + 'likes_count' => $status->likes_count, + 'reblogs_count' => $status->reblogs_count, + ]); + $ai->save(); + + $u = $status->profile->user; + $u->has_interstitial = true; + $u->save(); + } + + if ($status->profile_id == $user->profile->id || $user->is_admin == true) { Cache::forget('profile:status_count:'.$status->profile_id); StatusDelete::dispatch($status); } + if($request->wantsJson()) { return response()->json(['Status successfully deleted.']); } else { - return redirect(Auth::user()->url()); + return redirect($user->url()); } } From 9bc7fd63c8b718def35209636a845e58868f96e6 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:44:04 -0700 Subject: [PATCH 21/30] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efc7a309e..6654fe15b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -116,6 +116,10 @@ - Updated media pipeline, add blurhash support. ([473e0495](https://github.com/pixelfed/pixelfed/commit/473e0495)) - Updated DeleteAccountPipeline, add AccountInterstitial and DirectMessage purging. ([b3078f27](https://github.com/pixelfed/pixelfed/commit/b3078f27)) - Updated ComposeModal.vue component, reuse sharedData. ([e28d022f](https://github.com/pixelfed/pixelfed/commit/e28d022f)) +- Updated ApiController, return status object after deletion. ([0718711d](https://github.com/pixelfed/pixelfed/commit/0718711d)) +- Updated InternalApiController, add interstitial logic. ([20681bcf](https://github.com/pixelfed/pixelfed/commit/20681bcf)) +- Updated PublicApiController, improve stateless object caching. ([342e7a50](https://github.com/pixelfed/pixelfed/commit/342e7a50)) +- Updated StatusController, add interstitial logic. ([003caf7e](https://github.com/pixelfed/pixelfed/commit/003caf7e)) ## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9) ### Added From b8330b3d92e18558ae1713ad9cb1584e3782843e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:55:42 -0700 Subject: [PATCH 22/30] Add appeal/interstitial views --- .../account/moderation/post/cw.blade.php | 130 ++++++++++++++++++ .../account/moderation/post/removed.blade.php | 99 +++++++++++++ .../account/moderation/post/unlist.blade.php | 128 +++++++++++++++++ .../views/admin/reports/appeals.blade.php | 63 +++++++++ resources/views/admin/reports/home.blade.php | 9 ++ .../views/admin/reports/show_appeal.blade.php | 125 +++++++++++++++++ 6 files changed, 554 insertions(+) create mode 100644 resources/views/account/moderation/post/cw.blade.php create mode 100644 resources/views/account/moderation/post/removed.blade.php create mode 100644 resources/views/account/moderation/post/unlist.blade.php create mode 100644 resources/views/admin/reports/appeals.blade.php create mode 100644 resources/views/admin/reports/show_appeal.blade.php diff --git a/resources/views/account/moderation/post/cw.blade.php b/resources/views/account/moderation/post/cw.blade.php new file mode 100644 index 000000000..d1e1d3537 --- /dev/null +++ b/resources/views/account/moderation/post/cw.blade.php @@ -0,0 +1,130 @@ +@extends('layouts.blank') + +@section('content') + +
+
+
+

Your Post Contains Sensitive or Offensive Material

+

We applied a Content Warning to your post because it doesn't follow our Community Guidelines.

+

To continue you must click the "I Understand" button or "REQUEST APPEAL" button at the bottom of this page.

+
+
+
+
+
+

Post Details

+ @if($interstitial->has_media) +
+
+ @if($interstitial->blurhash) + + @else + No preview available + @endif +
+
+ @if($meta->caption) +

+ Caption: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+
+
+ @else +
+
+ @if($meta->caption) +

+ Comment: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+
+
+ @endif +
+
+
+

Review the Community Guidelines

+

We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.

+
+
+ +
+ +
+
+
+ @csrf +

Request Appeal

+

+

+ +
+

+ {{--

Learn more about what we remove.

--}} + + + + +
+
+ +
+ +
+ @csrf + + + + + +
+
+
+
+ +@endsection + +@push('scripts') + +@if($interstitial->blurhash) + +@endif +@endpush \ No newline at end of file diff --git a/resources/views/account/moderation/post/removed.blade.php b/resources/views/account/moderation/post/removed.blade.php new file mode 100644 index 000000000..123863489 --- /dev/null +++ b/resources/views/account/moderation/post/removed.blade.php @@ -0,0 +1,99 @@ +@extends('layouts.blank') + +@section('content') + +
+
+
+

Your Post Has Been Deleted

+

We removed your post because it doesn't follow our Community Guidelines. If you violate our guidelines again, your account may be restricted or disabled.

+

To continue you must click the "I Understand" button at the bottom of this page.

+
+
+
+
+
+

Post Details

+ @if($interstitial->has_media) +
+
+ @if($interstitial->blurhash) + + @else + No preview available + @endif +
+
+ @if($meta->caption) +

+ Caption: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+
+
+ @else +
+
+

+ Comment: {{$meta->caption}} +

+

+ Posted on {{$meta->created_at}} +

+

+ {{$meta->url}} +

+
+
+ @endif +
+
+
+

Review the Community Guidelines

+

We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.

+
+
+
+
+ @csrf + + + + + +
+
+
+
+@endsection + +@push('scripts') + +@if($interstitial->blurhash) + +@endif +@endpush \ No newline at end of file diff --git a/resources/views/account/moderation/post/unlist.blade.php b/resources/views/account/moderation/post/unlist.blade.php new file mode 100644 index 000000000..3c86acb76 --- /dev/null +++ b/resources/views/account/moderation/post/unlist.blade.php @@ -0,0 +1,128 @@ +@extends('layouts.blank') + +@section('content') + +
+
+
+

Your Post Was Unlisted

+

We removed your post from public timelines because it doesn't follow our Community Guidelines.

+
+
+
+
+
+

Post Details

+ @if($interstitial->has_media) +
+
+ @if($interstitial->blurhash) + + @else + No preview available + @endif +
+
+ @if($meta->caption) +

+ Caption: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+
+
+ @else +
+
+ @if($meta->caption) +

+ Comment: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+
+
+ @endif +
+
+
+

Review the Community Guidelines

+

We want to keep {{config('app.name')}} a safe place for everyone, and we created these Community Guidelines to support and protect our community.

+
+
+ +
+ +
+
+
+ @csrf + +

Request Appeal

+

+

+ +
+

+ + + + +
+
+ +
+
+ @csrf + + + + + +
+
+
+
+ +@endsection + +@push('scripts') + +@if($interstitial->blurhash) + +@endif +@endpush \ No newline at end of file diff --git a/resources/views/admin/reports/appeals.blade.php b/resources/views/admin/reports/appeals.blade.php new file mode 100644 index 000000000..5e2c21f7e --- /dev/null +++ b/resources/views/admin/reports/appeals.blade.php @@ -0,0 +1,63 @@ +@extends('admin.partial.template-full') + +@section('section') +
+

Appeals

+ + +
+
+
+
+
+

{{App\AccountInterstitial::whereNull('appeal_handled_at')->whereNotNull('appeal_requested_at')->count()}}

+

active appeals

+
+
+ +
+
+

{{App\AccountInterstitial::whereNotNull('appeal_handled_at')->whereNotNull('appeal_requested_at')->count()}}

+

closed appeals

+
+
+
+ +
+ +@endsection \ No newline at end of file diff --git a/resources/views/admin/reports/home.blade.php b/resources/views/admin/reports/home.blade.php index 001c282e3..d78924e5b 100644 --- a/resources/views/admin/reports/home.blade.php +++ b/resources/views/admin/reports/home.blade.php @@ -15,6 +15,15 @@ +@php($ai = App\AccountInterstitial::whereNotNull('appeal_requested_at')->whereNull('appeal_handled_at')->count()) +@if($ai) + +@endif @if($reports->count())
diff --git a/resources/views/admin/reports/show_appeal.blade.php b/resources/views/admin/reports/show_appeal.blade.php new file mode 100644 index 000000000..2839dbfa5 --- /dev/null +++ b/resources/views/admin/reports/show_appeal.blade.php @@ -0,0 +1,125 @@ +@extends('admin.partial.template-full') + +@section('section') +
+
+

Moderation Appeal

+

From @{{$appeal->user->username}} about {{$appeal->appeal_requested_at->diffForHumans()}}.

+
+
+
+
+
+
+ @if($appeal->type == 'post.cw') +
+
Content Warning applied to {{$appeal->has_media ? 'Post' : 'Comment'}}
+ @if($appeal->has_media) + + @endif +
+
+ @if($meta->caption) +

+ {{$appeal->has_media ? 'Caption' : 'Comment'}}: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+

+ Message: {{$appeal->appeal_message}} +

+
+
+
+ @elseif($appeal->type == 'post.unlist') +
+
{{$appeal->has_media ? 'Post' : 'Comment'}} was unlisted from timelines
+ @if($appeal->has_media) + + @endif +
+
+ @if($meta->caption) +

+ {{$appeal->has_media ? 'Caption' : 'Comment'}}: {{$meta->caption}} +

+ @endif +

+ Like Count: {{$meta->likes_count}} +

+

+ Share Count: {{$meta->reblogs_count}} +

+

+ Timestamp: {{now()->parse($meta->created_at)->format('r')}} +

+

+ URL: {{$meta->url}} +

+

+ Message: {{$appeal->appeal_message}} +

+
+
+
+ @endif +
+
+
+ @csrf + + +
+ +
+
+ @{{$appeal->user->username}} stats +
+
+

+ Open Appeals: {{App\AccountInterstitial::whereUserId($appeal->user_id)->whereNotNull('appeal_requested_at')->whereNull('appeal_handled_at')->count()}} +

+

+ Total Appeals: {{App\AccountInterstitial::whereUserId($appeal->user_id)->whereNotNull('appeal_requested_at')->count()}} +

+

+ Total Warnings: {{App\AccountInterstitial::whereUserId($appeal->user_id)->count()}} +

+

+ Status Count: {{$appeal->user->statuses()->count()}} +

+

+ Joined: {{$appeal->user->created_at->diffForHumans(null, null, false)}} +

+
+
+
+
+@endsection + +@push('scripts') + +@endpush \ No newline at end of file From 19d6e7df65f93d8139b3640877ef43ea3bd6802e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:59:16 -0700 Subject: [PATCH 23/30] Update middleware, add AccountInterstitial support --- app/Http/Kernel.php | 1 + app/Http/Middleware/AccountInterstitial.php | 48 +++++++++++++++++++++ routes/web.php | 10 ++++- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 app/Http/Middleware/AccountInterstitial.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 94597e211..c68302667 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -66,6 +66,7 @@ class Kernel extends HttpKernel 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'twofactor' => \App\Http\Middleware\TwoFactorAuth::class, 'validemail' => \App\Http\Middleware\EmailVerificationCheck::class, + 'interstitial' => \App\Http\Middleware\AccountInterstitial::class, // 'restricted' => \App\Http\Middleware\RestrictedAccess::class, ]; } diff --git a/app/Http/Middleware/AccountInterstitial.php b/app/Http/Middleware/AccountInterstitial.php new file mode 100644 index 000000000..19bf8ae1e --- /dev/null +++ b/app/Http/Middleware/AccountInterstitial.php @@ -0,0 +1,48 @@ +is($ar)) { + if($request->user()->has_interstitial) { + if($request->wantsJson()) { + $res = ['_refresh'=>true,'error' => 403, 'message' => \App\AccountInterstitial::JSON_MESSAGE]; + return response()->json($res, 403); + } else { + return redirect('/i/warning'); + } + } else { + return $next($request); + } + } else { + return $next($request); + } + } +} diff --git a/routes/web.php b/routes/web.php index 494116b3d..f5b0086d1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,6 +8,9 @@ Route::domain(config('pixelfed.domain.admin'))->prefix('i/admin')->group(functio Route::get('reports/show/{id}', 'AdminController@showReport'); Route::post('reports/show/{id}', 'AdminController@updateReport'); Route::post('reports/bulk', 'AdminController@bulkUpdateReport'); + Route::get('reports/appeals', 'AdminController@appeals'); + Route::get('reports/appeal/{id}', 'AdminController@showAppeal'); + Route::post('reports/appeal/{id}', 'AdminController@updateAppeal'); Route::redirect('statuses', '/statuses/list'); Route::get('statuses/list', 'AdminController@statuses')->name('admin.statuses'); Route::get('statuses/show/{id}', 'AdminController@showStatus'); @@ -73,7 +76,7 @@ Route::domain(config('pixelfed.domain.admin'))->prefix('i/admin')->group(functio Route::post('newsroom/create', 'AdminController@newsroomStore'); }); -Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofactor', 'localization'])->group(function () { +Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofactor', 'localization','interstitial'])->group(function () { Route::get('/', 'SiteController@home')->name('timeline.personal'); Route::post('/', 'StatusController@store'); @@ -125,6 +128,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('discover/tag', 'DiscoverController@getHashtags'); Route::post('status/compose', 'InternalApiController@composePost')->middleware('throttle:maxPostsPerHour,60')->middleware('throttle:maxPostsPerDay,1440'); }); + Route::group(['prefix' => 'pixelfed'], function() { Route::group(['prefix' => 'v1'], function() { Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials'); @@ -169,6 +173,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('discover/posts/places', 'DiscoverController@trendingPlaces'); }); }); + Route::group(['prefix' => 'local'], function () { // Route::get('accounts/verify_credentials', 'ApiController@verifyCredentials'); // Route::get('accounts/relationships', 'PublicApiController@relationships'); @@ -295,6 +300,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('redirect', 'SiteController@redirectUrl'); Route::post('admin/media/block/add', 'MediaBlocklistController@add'); Route::post('admin/media/block/delete', 'MediaBlocklistController@delete'); + + Route::get('warning', 'AccountInterstitialController@get'); + Route::post('warning', 'AccountInterstitialController@read'); }); Route::group(['prefix' => 'account'], function () { From f9e89a7df203fc235011674e4bdad966a218a32c Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 21:59:56 -0700 Subject: [PATCH 24/30] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6654fe15b..f76a69712 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -120,6 +120,7 @@ - Updated InternalApiController, add interstitial logic. ([20681bcf](https://github.com/pixelfed/pixelfed/commit/20681bcf)) - Updated PublicApiController, improve stateless object caching. ([342e7a50](https://github.com/pixelfed/pixelfed/commit/342e7a50)) - Updated StatusController, add interstitial logic. ([003caf7e](https://github.com/pixelfed/pixelfed/commit/003caf7e)) +- Updated middleware, add AccountInterstitial support. ([19d6e7df](https://github.com/pixelfed/pixelfed/commit/19d6e7df)) ## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9) ### Added From 16c43ed0c40734f1a72b02de5e9e19254434c609 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 22:05:42 -0700 Subject: [PATCH 25/30] Update compiled assets --- public/js/activity.js | Bin 8404 -> 8543 bytes public/js/app.js | Bin 10254 -> 15303 bytes public/js/collectioncompose.js | Bin 10010 -> 10149 bytes public/js/collections.js | Bin 21833 -> 21893 bytes public/js/compose.js | Bin 104724 -> 104869 bytes public/js/direct.js | Bin 55724 -> 55776 bytes public/js/discover.js | Bin 16077 -> 16218 bytes public/js/hashtag.js | Bin 13786 -> 13943 bytes public/js/mode-dot.js | Bin 8327 -> 8327 bytes public/js/profile-directory.js | Bin 3651 -> 3651 bytes public/js/profile.js | Bin 112555 -> 112617 bytes public/js/quill.js | Bin 237211 -> 237211 bytes public/js/rempos.js | Bin 60334 -> 60473 bytes public/js/rempro.js | Bin 23914 -> 23974 bytes public/js/search.js | Bin 28116 -> 28253 bytes public/js/status.js | Bin 81180 -> 81204 bytes public/js/story-compose.js | Bin 70685 -> 70685 bytes public/js/theme-monokai.js | Bin 3178 -> 3178 bytes public/js/timeline.js | Bin 131136 -> 131164 bytes public/js/vendor.js | Bin 356077 -> 356077 bytes public/mix-manifest.json | Bin 2001 -> 2077 bytes 21 files changed, 0 insertions(+), 0 deletions(-) diff --git a/public/js/activity.js b/public/js/activity.js index 66eea31c70578017092efa2b459f7d6b077b4337..4fdce4aea44ac3930007b233bf54c49f0afc79d0 100644 GIT binary patch delta 124 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 UuF3l!aietYL);CY{PZvX1rGp5zyJUM delta 639 zcmY*WO^XvT7$)0VJt=~&hXv^eJ0xrzx67V(2*nRPl!7AYMLf)A-q{AyOvz-Xu+w2- zFP;=@@P|k*dr&-j5O4Y`{1axT?W&jLeV_Mvo;N)CHhcH%{bwW=U+$n}@oTX7dD{}i zQDWbs@7I%(hlY##@JH;a^Cxuq-hN@=&)WGMRn4VaUoN<{g3=6O?0NO|euxXW=mNccJE)CI%36?xsHE0RNJ6*r1TA~m2u*S!k~Rz)1ww}wfQ!$`dRhqS^TNV$=w zH5Dep)WuZ86x9F5YwW4>->53CecbA}K;qWWou67e?)=eug2eLH)w^gpy0*WwEg0-| z@5AI6qCq#%U^1=R!hY!OI`T#Dz>$CVcDJ_6l0MHLo*r$!vJSOaHv2A0K}2n AwEzGB diff --git a/public/js/collectioncompose.js b/public/js/collectioncompose.js index 7d894f3fdb544472f6c6740bbcbc1867d93f51e3..8df735e945739bc199ebc344f5003f1110296cfe 100644 GIT binary patch delta 125 zcmbQ`x72?_JQJhNG zl1qz1i&KkiOY~BJT%GdFyp;TMJ;#Cqz0#7*9KF26GN5pghGwni<~XKaMdn1EyvgsB aCov{&Zd74sWK5jgsVdEww|S{*DI)-8Gc4@@ delta 62 zcmZ4LKg(}JJk#b^Og)Osc{+)cD^(^j=56LtWoMMl)2!7g(u*%HE(%Ib&nzxUEwWA4 Sv?^9p(@3^W+-#s$$_N0m&J?%+ diff --git a/public/js/collections.js b/public/js/collections.js index 7bba7df6db6330451cfbc3898c60423eb45b9311..2d8dc26b88513503fc4c1dda73b255285ab851f6 100644 GIT binary patch delta 266 zcmX@Pim`PyAUGz*J{uE1 zu-WL8XXd5km+QqBXCxM-rnn@QBZ_~ zSGeHBEwkb5$>EI72+kr#9|Y$cqtE7j#(Kl1pyY20w7Nc?1agD=AA4#iRNKIy(*jc Wde?LE*6Kt@8(QcX#Ky*IS_1%mm_Vrj diff --git a/public/js/compose.js b/public/js/compose.js index 809574fbbd98f052f344fd3ee54da71dfd752829..e7857291f946531d7cc145d546f5395c495857b2 100644 GIT binary patch delta 350 zcmbQTiEZg-whfiso9p=(3$rO1r@9y@O>WeYV#zn~4w?MWu5+`J@(d;xPeUiy$^OdP zn^o0jNwDO&7M4yf)RdciN0n0ytVPp0Q!h^=QByCmR!1o(Nxx)rfu{WCKKr-EV1p*w zn@--$t;n8aU~XxUWIFjacPN}~&Qkxlq}t+ErDJGo3s*N?hl|mPNz-ckVot`V(%=Bu-lNJGSq!sx`kNVy8UU^w BaBKho delta 259 zcmZ3wnQh7@whfisEQUVeh7;|~CU3}BWH&K4G%-vunS3KZ6wcmIC^gxyAOg-`TTl*X zYZunR*&7PI;B3aCWH>v!$PUilP?QU2s}zTCuHarG%xFHjzF2zmQ~4Su7DxZIjOqJX z809AWSab4cn;VrWXLqTDS2``h0ur43Mnekh?#T(ZO``zBS@d@yWN>EQc{W)~3UlU)TPJY5cXWhY=>+ zv%wO^JiTExj9Ig>4$7RgNrlDJ(8+c3g(U6GS*e0-EPjS&DU;{V7UQr@)KCIhKiO?l z=jQ6{+06L7AeJAe!(o(ak!o&ekvMs6lHBH5v%hgLI!~UsM3m8a^YSH&Ss2SFd$05c z3Qb?>z*xTd#>%x!ESbjXg&@l&+ijW%4uQ$}8FCV3iA4&6vvW5uP*t>LOR_MtG)S8KYoXlcr%44&ES`o=u9IIS zX>V4}7G&Fezi>A5<|(CdI_$=2hGynzX`6p86y;gvTTjLwr!uJ;BC ziEeOUblx1cVJ#C&ih*T)tg^!W@ZCA;N4DX&2rmJz5G0%{KS;ZymXyP+p_%36a@oY zTibH`w9>rflFa-(4bAFWtMbi8yZ&$hU8;YWUredOG}pumE?=UPs*|W$U6xp+P;8s1 zp#<{BeZa Gv<3hO7=ro$ diff --git a/public/js/discover.js b/public/js/discover.js index 6cd6bbc255b3287c297f0fd6d72740188b036568..fd516e6ca7db47732afd13bb67f7eb6075da433b 100644 GIT binary patch delta 288 zcmX?Gd#i3j2b+?zAb#Wu{feCl{rrq~?`mCgv0?Y3h|^q~>X8q?P6+mt^MWX_RPImuKds y)b#wK%+0&Fvsl26-K-(NFOBewy|(OTZQVBlEFiZ}Hq;g4u+7r|hsR_~yD0$F*&R59-*08xnh+mo`G0`%`AkoZZ@@!pMmJmzFl!<-5aKVX>9pLQA+Kf{X foD+-_H}BAWBftW(X!1T?F%FQeApMh%*-ZfeNqjOJ diff --git a/public/js/hashtag.js b/public/js/hashtag.js index 7ed5d4ab945c51e7c701b6c28a48800fdaa9e5e2..eae521b25592191091033b1f56bd33dd423f4436 100644 GIT binary patch delta 325 zcmcbW{XJ*HWhNFUFXyVs=at1cZ1Xgf{M@qqCp##2vUrq+WKU*ilanY*EK(>2NrBWU zXLqTz$mGPv0#@&2>dj$hY-wqbVqh_Os;R|hAIC8;TDYKaw@`NewasU;dp`iTXZ`URO4sX1w>Df(rG`iaTO`K5U!#rkEbMVV=p z@ySK0DIl$hImJqvdLUyoG}21*l1no4^E65{tIIRPZ*VDH=k6_PY_6xp3Z#;Z=Q8rv>O@Byn&}wC#>Q$|0{}hyYp(zR delta 190 zcmeyKb1QqpWv0!$m>t+QcX3@}+WechmzgCuBGq?uk6^Pfhe48QQksFG$z*X=S*36b zR}ZVS(!Au7%=|o!5}j0?Jk9E|#3F@a+dK`W{8Ih&$zPc|H=C&Da`C(BC1vKNXyldV zQh>eZav<3jiQa&aC diff --git a/public/js/mode-dot.js b/public/js/mode-dot.js index 74719c40f1542bb9f981430d2f6a9d65be1df1c5..3770f2662b30c6e82171a16bb72c215b0fbecd0a 100644 GIT binary patch delta 12 TcmZp7Ysb694A8KcEUa~?hb9i;=n delta 12 TcmX>sb694A8Ke0|a~?hb9iRih diff --git a/public/js/profile.js b/public/js/profile.js index dd544cad50a5d4c773c0e1f529b4cd386a7fd09b..2b806e3dae1cf347481dd7ea93f4886680e5c1a7 100644 GIT binary patch delta 973 zcmZXST}TvB6vsK+Htt&CM_+z~>9pC*cAMR`EioH4`&gBVjbWV8rFHhUJL?Kd z9}q+lMKHvD=tW-=@=1mmdoV~hwU;P@iU^@zqL+Lq$Ret{_Ax~;aPIH?|M#AI&fM`u z=G`K5eYd+df--DP8y+-HzX?rTyj@bCj%t1Jv~V&xASIN(1ClNYaw^f8R1%^h^if2= z9Q!a9QhGEdXwnc(Cpg~pm0sbU$Ge7P^ImhS=BkkbLHfyN!9+ICJbU+s%Nb4|mJREClQ zZ@oRYieZ>gxcY;<%z+Nkp5CD!_#`8k_j)BRqK%#Wbj}ysp!X}gGxN5a~v-=WaOA4 zC0aFINeoFb4(D##iC~)UDA@tQT;uHm48!`|75}qZFMaSLSIn$|n=5EMvKy|tiZN2f zsz7~IS|6U?;GIQN);t|Ob#|eHyy-CBb=h)`#vaPBwAKTl5j1Q6r(t&AQlhA zb^309=0DZKW|C}zjnsdo3AVa0zenbDgssUYXkc7ejP(Q}NG0D6ftR+-hoF~Q3tOO+ ejE10`uBSq|>02K{fa9yrpq`!}@<$>OzWxW66h6NI delta 865 zcmY+DT}TvB6vsL1?7FTGYNDnqyX|B)!(P{2zesKUs&F-{CG4ebg<Q~DfUBF~&w!kyY`OPgfxJ{qWu`2|7SJ28{abR1}{ zRoB;wnEf5iSaq%sYgv!4*#D3?QL8ek?0+5VNXn(wr8fN^P*S-Y1LY>nq;8lXE>xLt zd*PS~1&cdPh%9axFt#|gA+wY;;oZ_x6UILbnt+y%m@vBBV8ZKVg$WOI#8l(1)Kro= z==IXHtcSc1 zGbD~9a5LE0Fo$58CdSI3iq`4Rd@u-kRD4YA7L+zA(XE^kM9wJHJN@v+m|0c{*V3qc zUIQccO&G~RPoTaBb0XDQTFS}fcq1IN%1GfcnQVl^bYD>uoJhmIJ_5TS&x!Fv+6>$5n6Ha*3A(YO85(TaI4DK}QMxAXRZwqGAOQ|odef~|=%Ou? zAt)ry5ICvt4naQI7Xml+!yzcvheOaAw<6<0H_QmwXb}!~2AxAry&JA%8R) Hm diff --git a/public/js/rempos.js b/public/js/rempos.js index 870fcace926f9464ab1963d6a0092a8d1221f832..507035dc051cb40d07e7ffc78803d1b757145153 100644 GIT binary patch delta 487 zcmZ2?oq6XC<_V@uMg|+ro%vWCeGSYfFO;{OY+xbIk(_L3VPKh(IN9Gq48hrGAv?Lt zLLONl0>Kfq)Io4uEn^Uzm6o#+93LwS1gFQ!62UoZWrpBzTN@!buGXs&oFCTq2#&o? zG=j6prVYU{uticD3 zNObcBK1&W}qsm;6dQp&CB~9yMy*!OXO})fg9p9qDjLC@{Hk&=fcW|;qx*Pj}0&a7q zVzn4^MQYaOM2_uDlXc|yCtL7}Z|-(T5n$Ar+?%f|T$WmtnN}H}T$GxUnpcvUm{Y7Y zd18o&Re5G!N`ARsd~rr1P|78-BvCK9v?#PVwaB(aF9pcefvRvUD9|e{$;{EqODqEl i7inyM9q>|##TV$(%{Pjj{o%gftbBL@|{ZHc@89j2n1&azYcZx5DG{amMs z8>N{eDl#XY?*dVi55;7{jh$>9tHr7VvTkxbqnvzMVv$0gZKj42NSl(Tb*5gPMxLf# zVy%u+qHBou#Es&cH+$bm48)<8`yW%Is4Wcs{(?vz E0I4B!g8%>k delta 270 zcmZ3soAK2y#tCMO1{2N8Sj@u=0w-&GOEc%EB~JGA?%KGm>49bB&Qi}j&O?N&`q;V)=NrF%P&fGE=o--Nwr4h+NRk@$Lb~L z=OrhWXrxWP@8z+1z0Y?>wlv%5Se=y3Yy1{7F{eeRO%4idWK7$9CGY^FNSa<|UP@|( zf0{;#rgf^Ft$~_a+U6C(#mtP^n`OeaSQ)b?yT@cQrcB-#^MX|e!qibXej9?7G&xdWLBi+q@||lml^6OCMV~Y z=9Ludm!%eErd7r#7p118=9Oe7<`gSUJ}4q$Tb`Mhl3%VDU!0K$lyXTdNz_X&Eeb78 zEwU}qO966qpeh^-3iL`#GIR9u63c+XMH-s5nwwv8ZsB7ID9tI@yinr19fwh>g^_7e zlG)}3;rh&A@yR}Ha&l#fMGA?wsTxX^7KWxun%1d$c^ZkDdWp3Zng@npehF%FO`z?M4XP5}U))^sTV delta 186 zcmcb6hw;j7#tCMOh8xW{b8ar>+RVq|mt+yXSx54_9Y?BxS(1@SvdL!c2z_R-_~f`~ zb^g){Q+*{(>r}lwjYLho#LYWngxDF=C!a~)!k9FCdO#9fb5%mAV!?SHdR9jtodZ_ F6acrqJyQSx diff --git a/public/js/status.js b/public/js/status.js index 7448fe91169225b1e76b54c8e30c48d1458bba39..916ef53accf59faefaa6f9c35f3e0d9283cc66b3 100644 GIT binary patch delta 590 zcmbR9i)G6%mI-ED#<4opN=9AK$%S$XvEJ-ZV(9}uQ%S}zmOtej%evy+= za`RFlX+6G3pLAa(O`T#5r80N3!p-L#)=yA2OEobtFiJ{P(#b2$$Fq5N%LEh;4rQb)GyVG=SDmX1yn_2D3d@Cnis?C^a#;Br`v+I64IwBD!U|Fj zL?(yb(?D1c7MXR=1uioA**zTuN9ukIf>U>YHiD!0zyiTZd|-*-EP7yu;5>L>gy2X$ yT#ewIeQ1y1h&+l$aHQ@_O`iBD2O+@vSeFG9ZSc_HcL7F;5+ZcA-xgzZR09AUf5-0t delta 549 zcmdn;i)GF)mI-EDMzK28O4|M&-b&N=NimAE7i%cFT(*Qqr_8*2~jK)YMDdyzAm?Zf1}b3qM#+?-67aSA*$`)rrZ|D@sjFF3HT# zD~?V{EJ@TY(}l@S=M`dKcqc#ooG_yhLfH#pMoR=wQ-skB!AlomG(zweiZHH5@Ipix?Ge1$qKwf99?&6D z(hpdg%FctvjVgNvN};3z-}CEt7A0xY1QgGWn2c)l4ZS~h=rpU%jp zl;|3w4URLh%^N??lV<@-1A}z()pwF`iza`2=ZWCBzgIzUzP;0&JmGVVuMh&r4lN2*0P3t_pJdI*ay~J7_B_pqbT#%gn zWP3&S$rBz)Y^?pmyZOGzDRIg2%)FHRay`d_0=?3b%pASE#InSa#3BvN%`0@inX!OP z^-y9onS6mmd;0u&j2x4F=kiVdeT#FmLJCU_M{Y!KvkULvT*>>+{2`ja8_Q$%`qOe((sR=wvy89)zk*0@0jsRnr;2Fp5vs w6^ug2_Y2x0I9CJ@A~8cvHCq9 z!As|5Jc!^K@G-U`czgL6&mnk|`5AiHIw9eDZ( an0$c0b944f3$d+!jQcsa7Yi`Hd=CKotYi%U diff --git a/public/js/vendor.js b/public/js/vendor.js index 66d8d35cbcad9c2ef82122d581d5a489fd38a0d0..b545a291d7f69bbb9ccf29e99145928fc022e7a1 100644 GIT binary patch delta 29 lcmaERSM=>&(Fs&(FsXLeQ+4Uwb}3$YG1hOK=B zE3wvB$Yb~jV&ku+-7xdbeBU?U&EDtRpI$jBnY>Bzs8M4OU$kF;c)5=$mkemJ6p4vT z3wZtOp#zN+ya!U6_K=98eub@PTP_FVUK6YLQWW`UvVg0D?|fpI#2>KL(NV(YCV31dmp$M^Xo$3zlA ziWE#fddvuI{GK1UP+C>N0n3@LFXl+K}HHRbVk8epOflTHXG)qJLc zGQRB`+|RyGx~6w~DlJ=WNo2L&T`rg7&f@OaTRd}-~9s~hoi0l delta 506 zcmWMiyJ`?X5F{}Vh=oF~unrayL%7@9XB8Ad`~vIS+dB)fv9S^>3$Za=?I&0X)`DM< z%5Smr+L_szo%#Oo?!mXWDcGA(X6#@HC!tx{Ra1cV z`rhxvO>-$YdPk}bzHQrjdUTy4vN-S9?J-db7RL4N=qe4zK5~_P)kCx?i>@C>uh#S9 zi*v#j%HVC*JcbZYT_29G&INgjFjpIQdIh z>18SiPC;Q+J4^HElh@6uCf>hvbm>ms8d8y{>+2>)A6vLVP~j5WS9Se8y?$h}hwa^q OPUTJ#v&F^P$Fu)2;EBcn From c95085ca316c5baccca09ad092281d7a455ac3e8 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 22:08:32 -0700 Subject: [PATCH 26/30] Update AdminController, add appeals support --- app/Http/Controllers/AdminController.php | 62 ++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index f6b693430..f044ec9fa 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\{ + AccountInterstitial, Contact, Hashtag, Newsroom, @@ -85,6 +86,67 @@ class AdminController extends Controller return view('admin.reports.show', compact('report')); } + public function appeals(Request $request) + { + $appeals = AccountInterstitial::whereNotNull('appeal_requested_at') + ->whereNull('appeal_handled_at') + ->latest() + ->paginate(6); + return view('admin.reports.appeals', compact('appeals')); + } + + public function showAppeal(Request $request, $id) + { + $appeal = AccountInterstitial::whereNotNull('appeal_requested_at') + ->whereNull('appeal_handled_at') + ->findOrFail($id); + $meta = json_decode($appeal->meta); + return view('admin.reports.show_appeal', compact('appeal', 'meta')); + } + + public function updateAppeal(Request $request, $id) + { + $this->validate($request, [ + 'action' => 'required|in:dismiss,approve' + ]); + + $action = $request->input('action'); + $appeal = AccountInterstitial::whereNotNull('appeal_requested_at') + ->whereNull('appeal_handled_at') + ->findOrFail($id); + + if($action == 'dismiss') { + $appeal->appeal_handled_at = now(); + $appeal->save(); + + return redirect('/i/admin/reports/appeals'); + } + + switch ($appeal->type) { + case 'post.cw': + $status = $appeal->status; + $status->is_nsfw = false; + $status->save(); + break; + + case 'post.unlist': + $status = $appeal->status; + $status->scope = 'public'; + $status->visibility = 'public'; + $status->save(); + break; + + default: + # code... + break; + } + + $appeal->appeal_handled_at = now(); + $appeal->save(); + + return redirect('/i/admin/reports/appeals'); + } + public function profiles(Request $request) { $this->validate($request, [ From 1b2fd665bf962427636f570cbabd1c1a1defb716 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 22:22:56 -0700 Subject: [PATCH 27/30] Update compiled assets --- app/Http/Controllers/ProfileController.php | 7 +++-- public/js/memoryprofile.js | Bin 0 -> 61842 bytes resources/views/profile/memory.blade.php | 35 +++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 public/js/memoryprofile.js create mode 100644 resources/views/profile/memory.blade.php diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 7d0b4405c..6bd42d177 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -66,7 +66,9 @@ class ProfileController extends Controller 'list' => $settings->show_profile_followers ] ]; - return view('profile.show', compact('profile', 'settings')); + $ui = $request->has('ui') && $request->input('ui') == 'memory' ? 'profile.memory' : 'profile.show'; + + return view($ui, compact('profile', 'settings')); } else { $key = 'profile:settings:' . $user->id; $ttl = now()->addHours(6); @@ -103,7 +105,8 @@ class ProfileController extends Controller 'list' => $settings->show_profile_followers ] ]; - return view('profile.show', compact('profile', 'settings')); + $ui = $request->has('ui') && $request->input('ui') == 'memory' ? 'profile.memory' : 'profile.show'; + return view($ui, compact('profile', 'settings')); } } diff --git a/public/js/memoryprofile.js b/public/js/memoryprofile.js new file mode 100644 index 0000000000000000000000000000000000000000..caab9dabb1db21d1df108b50aff8a02c1e33f6a6 GIT binary patch literal 61842 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 $profile->username . " on " . config('app.name')]) + +@section('content') +@if (session('error')) +
+ {{ session('error') }} +
+@endif + + +@if($profile->website) +{{$profile->website}} +@endif + + + +@endsection + +@push('meta') + @if(false == $settings['crawlable'] || $profile->remote_url) + + @else + + + @endif +@endpush + +@push('scripts') + + +@endpush From 76353ca997d39c4408f69577a2cc700e7220cfc1 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 22:23:51 -0700 Subject: [PATCH 28/30] Update BaseApiController, add favourites method --- .../Controllers/Api/BaseApiController.php | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/BaseApiController.php b/app/Http/Controllers/Api/BaseApiController.php index 6c14d07a2..6a4497587 100644 --- a/app/Http/Controllers/Api/BaseApiController.php +++ b/app/Http/Controllers/Api/BaseApiController.php @@ -11,8 +11,9 @@ use Auth, Cache, Storage, URL; use Carbon\Carbon; use App\{ Avatar, - Notification, + Like, Media, + Notification, Profile, Status }; @@ -21,7 +22,8 @@ use App\Transformer\Api\{ NotificationTransformer, MediaTransformer, MediaDraftTransformer, - StatusTransformer + StatusTransformer, + StatusStatelessTransformer }; use League\Fractal; use App\Util\Media\Filter; @@ -338,4 +340,29 @@ class BaseApiController extends Controller $res = $this->fractal->createData($resource)->toArray(); return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); } + + public function accountLikes(Request $request) + { + $user = $request->user(); + abort_if(!$request->user(), 403); + + $limit = 10; + $page = (int) $request->input('page', 1); + + if($page > 20) { + return []; + } + + $favourites = $user->profile->likes() + ->latest() + ->simplePaginate($limit) + ->pluck('status_id'); + + $statuses = Status::find($favourites)->reverse(); + + $resource = new Fractal\Resource\Collection($statuses, new StatusStatelessTransformer()); + $res = $this->fractal->createData($resource)->toArray(); + + return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + } } From 386c4462eccc1ce8cb180031e7c0cf2e1e1d9740 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 22:24:27 -0700 Subject: [PATCH 29/30] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f76a69712..d40b7478c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,6 +121,7 @@ - Updated PublicApiController, improve stateless object caching. ([342e7a50](https://github.com/pixelfed/pixelfed/commit/342e7a50)) - Updated StatusController, add interstitial logic. ([003caf7e](https://github.com/pixelfed/pixelfed/commit/003caf7e)) - Updated middleware, add AccountInterstitial support. ([19d6e7df](https://github.com/pixelfed/pixelfed/commit/19d6e7df)) +- Updated BaseApiController, add favourites method. ([76353ca9](https://github.com/pixelfed/pixelfed/commit/76353ca9)) ## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9) ### Added From 2c95fd77c90594aeb33f9202274e2c3f98801957 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 9 Dec 2020 22:26:33 -0700 Subject: [PATCH 30/30] Update web routes --- routes/web.php | 1 + 1 file changed, 1 insertion(+) diff --git a/routes/web.php b/routes/web.php index f5b0086d1..432fd44c1 100644 --- a/routes/web.php +++ b/routes/web.php @@ -150,6 +150,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('timelines/home', 'PublicApiController@homeTimelineApi'); Route::get('newsroom/timeline', 'NewsroomController@timelineApi'); Route::post('newsroom/markasread', 'NewsroomController@markAsRead'); + Route::get('favourites', 'Api\BaseApiController@accountLikes'); }); Route::group(['prefix' => 'v2'], function() {