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'); + }); + } +}