Browse Source

Update StatusController, allow license edits without 24 hour limit

Daniel Supernault 4 years ago
parent
commit
c799a01aa9
2 changed files with 404 additions and 500 deletions
  1. 391 415
      app/Http/Controllers/StatusController.php
  2. 13 85
      resources/views/status/edit.blade.php

+ 391 - 415
app/Http/Controllers/StatusController.php

@@ -21,422 +21,398 @@ use App\Util\Media\Filter;
 use Illuminate\Support\Str;
 use App\Services\HashidService;
 use App\Services\StatusService;
+use App\Util\Media\License;
 
 class StatusController extends Controller
 {
-    public function show(Request $request, $username, int $id)
-    {
-        $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
-
-        if($user->status != null) {
-            return ProfileController::accountCheck($user);
-        }
-
-        $status = Status::whereProfileId($user->id)
-                ->whereNull('reblog_of_id')
-                ->whereIn('scope', ['public','unlisted', 'private'])
-                ->findOrFail($id);
-
-        if($status->uri || $status->url) {
-            $url = $status->uri ?? $status->url;
-            if(ends_with($url, '/activity')) {
-                $url = str_replace('/activity', '', $url);
-            }
-            return redirect($url);
-        }
-
-        if($status->visibility == 'private' || $user->is_private) {
-            if(!Auth::check()) {
-                abort(404);
-            }
-            $pid = Auth::user()->profile;
-            if($user->followedBy($pid) == false && $user->id !== $pid->id && Auth::user()->is_admin == false) {
-                abort(404);
-            }
-        }
-
-        if($status->type == 'archived') {
-            if(Auth::user()->profile_id !== $status->profile_id) {
-                abort(404);
-            }
-        }
-
-        if($request->user() && $request->user()->profile_id != $status->profile_id) {
-            StatusView::firstOrCreate([
-                'status_id' => $status->id,
-                'status_profile_id' => $status->profile_id,
-                'profile_id' => $request->user()->profile_id
-            ]);
-        }
-
-        if ($request->wantsJson() && config('federation.activitypub.enabled')) {
-            return $this->showActivityPub($request, $status);
-        }
-
-        $template = $status->in_reply_to_id ? 'status.reply' : 'status.show';
-        // $template = $status->type === 'video' &&
-        //     $request->has('video_beta') && 
-        //     $request->video_beta == 1 &&
-        //     $request->user() ?
-        //     'status.show_video' : 'status.show';
-
-        return view($template, compact('user', 'status'));
-    }
-
-    public function shortcodeRedirect(Request $request, $id)
-    {
-        abort_if(strlen($id) < 5, 404);
-        if(!Auth::check()) {
-            return redirect('/login?next='.urlencode('/' . $request->path()));
-        }
-        $id = HashidService::decode($id);
-        $status = Status::find($id);
-        if(!$status) {
-            return redirect('/404');
-        }
-        return redirect($status->url());
-    }
-
-    public function showId(int $id)
-    {
-        abort(404);
-        $status = Status::whereNull('reblog_of_id')
-                ->whereIn('scope', ['public', 'unlisted'])
-                ->findOrFail($id);
-        return redirect($status->url());
-    }
-
-    public function showEmbed(Request $request, $username, int $id)
-    {
-        $profile = Profile::whereNull(['domain','status'])
-            ->whereIsPrivate(false)
-            ->whereUsername($username)
-            ->first();
-        if(!$profile) {
-            $content = view('status.embed-removed');
-            return response($content)->header('X-Frame-Options', 'ALLOWALL');
-        }
-        $status = Status::whereProfileId($profile->id)
-            ->whereNull('uri')
-            ->whereScope('public')
-            ->whereIsNsfw(false)
-            ->whereIn('type', ['photo', 'video','photo:album'])
-            ->find($id);
-        if(!$status) {
-            $content = view('status.embed-removed');
-            return response($content)->header('X-Frame-Options', 'ALLOWALL');
-        }
-        $showLikes = $request->filled('likes') && $request->likes == true;
-        $showCaption = $request->filled('caption') && $request->caption !== false;
-        $layout = $request->filled('layout') && $request->layout == 'compact' ? 'compact' : 'full';
-        $content = view('status.embed', compact('status', 'showLikes', 'showCaption', 'layout'));
-        return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']);
-    }
-
-    public function showObject(Request $request, $username, int $id)
-    {
-        $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
-
-        if($user->status != null) {
-            return ProfileController::accountCheck($user);
-        }
-
-        $status = Status::whereProfileId($user->id)
-                ->whereNotIn('visibility',['draft','direct'])
-                ->findOrFail($id);
-
-        abort_if($status->uri, 404);
-
-        if($status->visibility == 'private' || $user->is_private) {
-            if(!Auth::check()) {
-                abort(403);
-            }
-            $pid = Auth::user()->profile;
-            if($user->followedBy($pid) == false && $user->id !== $pid->id) {
-                abort(403);
-            }
-        }
-
-        return $this->showActivityPub($request, $status);
-    }
-
-    public function compose()
-    {
-        $this->authCheck();
-
-        return view('status.compose');
-    }
-
-    public function store(Request $request)
-    {
-        return;
-    }
-
-    public function delete(Request $request)
-    {
-        $this->authCheck();
-
-        $this->validate($request, [
-          'item'  => 'required|integer|min:1',
-        ]);
-
-        $status = Status::findOrFail($request->input('item'));
-
-        $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();
-        }
-
-        Cache::forget('_api:statuses:recent_9:' . $status->profile_id);
-        Cache::forget('profile:status_count:' . $status->profile_id);
-        Cache::forget('profile:embed:' . $status->profile_id);
-        StatusService::del($status->id);
-        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($user->url());
-        }
-    }
-
-    public function storeShare(Request $request)
-    {
-        $this->authCheck();
-        
-        $this->validate($request, [
-          'item'    => 'required|integer|min:1',
-        ]);
-
-        $user = Auth::user();
-        $profile = $user->profile;
-        $status = Status::withCount('shares')
-            ->whereIn('scope', ['public', 'unlisted'])
-            ->findOrFail($request->input('item'));
-
-        $count = $status->shares()->count();
-
-        $exists = Status::whereProfileId(Auth::user()->profile->id)
-                  ->whereReblogOfId($status->id)
-                  ->count();
-        if ($exists !== 0) {
-            $shares = Status::whereProfileId(Auth::user()->profile->id)
-                  ->whereReblogOfId($status->id)
-                  ->get();
-            foreach ($shares as $share) {
-                $share->delete();
-                $count--;
-            }
-        } else {
-            $share = new Status();
-            $share->profile_id = $profile->id;
-            $share->reblog_of_id = $status->id;
-            $share->in_reply_to_profile_id = $status->profile_id;
-            $share->save();
-            $count++;
-            SharePipeline::dispatch($share);
-        }
- 
-        if($count >= 0) {
-            $status->reblogs_count = $count;
-            $status->save();
-        }
- 
-        Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id);
-        StatusService::del($status->id);
-        
-        if ($request->ajax()) {
-            $response = ['code' => 200, 'msg' => 'Share saved', 'count' => $count];
-        } else {
-            $response = redirect($status->url());
-        }
-
-        return $response;
-    }
-
-    public function showActivityPub(Request $request, $status)
-    {
-        $fractal = new Fractal\Manager();
-        $resource = new Fractal\Resource\Item($status, new Note());
-        $res = $fractal->createData($resource)->toArray();
-
-        return response()->json($res['data'], 200, ['Content-Type' => 'application/activity+json'], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
-    }
-
-    public function edit(Request $request, $username, $id)
-    {
-        $this->authCheck();
-        $user = Auth::user()->profile;
-        $status = Status::whereProfileId($user->id)
-                ->with(['media'])
-                ->where('created_at', '>', now()->subHours(24))
-                ->findOrFail($id);
-        return view('status.edit', compact('user', 'status'));
-    }
-
-    public function editStore(Request $request, $username, $id)
-    {
-        $this->authCheck();
-        $user = Auth::user()->profile;
-        $status = Status::whereProfileId($user->id)
-                ->with(['media'])
-                ->where('created_at', '>', now()->subHours(24))
-                ->findOrFail($id);
-
-        $this->validate($request, [
-          'id'      => 'required|integer|min:1',
-          'caption' => 'nullable',
-          'filter'  => 'nullable|alpha_dash|max:30',
-        ]);
-
-        $id = $request->input('id');
-        $caption = $request->input('caption');
-        $filter = $request->input('filter');
-
-        $media = Media::whereProfileId($user->id)
-            ->whereStatusId($status->id)
-            ->findOrFail($id);
-
-        $changed = false;
-
-        if ($media->caption != $caption) {
-            $media->caption = $caption;
-            $changed = true;
-        }
-
-        if ($media->filter_class != $filter && in_array($filter, Filter::classes())) {
-            $media->filter_class = $filter;
-            $changed = true;
-        }
-
-        if ($changed === true) {
-            $media->save();
-            Cache::forget('status:transformer:media:attachments:'.$media->status_id);
-        }
-
-        return response()->json([], 200);
-    }
-
-    protected function authCheck()
-    {
-        if (Auth::check() == false) {
-            abort(403);
-        }
-    }
-
-    protected function validateVisibility($visibility)
-    {
-        $allowed = ['public', 'unlisted', 'private'];
-        return in_array($visibility, $allowed) ? $visibility : 'public';
-    }
-
-    public static function mimeTypeCheck($mimes)
-    {
-        $allowed = explode(',', config('pixelfed.media_types'));
-        $count = count($mimes);
-        $photos = 0;
-        $videos = 0;
-        foreach($mimes as $mime) {
-            if(in_array($mime, $allowed) == false && $mime !== 'video/mp4') {
-                continue;
-            }
-            if(str_contains($mime, 'image/')) {
-                $photos++;
-            }
-            if(str_contains($mime, 'video/')) {
-                $videos++;
-            }
-        }
-        if($photos == 1 && $videos == 0) {
-            return 'photo';
-        }
-        if($videos == 1 && $photos == 0) {
-            return 'video';
-        }
-        if($photos > 1 && $videos == 0) {
-            return 'photo:album';
-        }
-        if($videos > 1 && $photos == 0) {
-            return 'video:album';
-        }
-        if($photos >= 1 && $videos >= 1) {
-            return 'photo:video:album';
-        }
-    }
-
-    public function toggleVisibility(Request $request) {
-        $this->authCheck();
-        $this->validate($request, [
-            'item' => 'required|string|min:1|max:20',
-            'disableComments' => 'required|boolean'
-        ]);
-
-        $user = Auth::user();
-        $id = $request->input('item');
-        $state = $request->input('disableComments');
-
-        $status = Status::findOrFail($id);
-
-        if($status->profile_id != $user->profile->id && $user->is_admin == false) {
-            abort(403);
-        }
-
-        $status->comments_disabled = $status->comments_disabled == true ? false : true;
-        $status->save();
-
-        return response()->json([200]);
-    }
-
-    public function storeView(Request $request)
-    {
-        abort_if(!$request->user(), 403);
-
-        $this->validate($request, [
-            'status_id' => 'required|integer|exists:statuses,id',
-            'profile_id' => 'required|integer|exists:profiles,id'
-        ]);
-
-        $sid = (int) $request->input('status_id');
-        $pid = (int) $request->input('profile_id');
-
-        StatusView::firstOrCreate([
-                'status_id' => $sid,
-                'status_profile_id' => $pid,
-                'profile_id' => $request->user()->profile_id
-        ]);
-
-        return response()->json(1);
-    }
+	public function show(Request $request, $username, int $id)
+	{
+		$user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
+
+		if($user->status != null) {
+			return ProfileController::accountCheck($user);
+		}
+
+		$status = Status::whereProfileId($user->id)
+				->whereNull('reblog_of_id')
+				->whereIn('scope', ['public','unlisted', 'private'])
+				->findOrFail($id);
+
+		if($status->uri || $status->url) {
+			$url = $status->uri ?? $status->url;
+			if(ends_with($url, '/activity')) {
+				$url = str_replace('/activity', '', $url);
+			}
+			return redirect($url);
+		}
+
+		if($status->visibility == 'private' || $user->is_private) {
+			if(!Auth::check()) {
+				abort(404);
+			}
+			$pid = Auth::user()->profile;
+			if($user->followedBy($pid) == false && $user->id !== $pid->id && Auth::user()->is_admin == false) {
+				abort(404);
+			}
+		}
+
+		if($status->type == 'archived') {
+			if(Auth::user()->profile_id !== $status->profile_id) {
+				abort(404);
+			}
+		}
+
+		if($request->user() && $request->user()->profile_id != $status->profile_id) {
+			StatusView::firstOrCreate([
+				'status_id' => $status->id,
+				'status_profile_id' => $status->profile_id,
+				'profile_id' => $request->user()->profile_id
+			]);
+		}
+
+		if ($request->wantsJson() && config('federation.activitypub.enabled')) {
+			return $this->showActivityPub($request, $status);
+		}
+
+		$template = $status->in_reply_to_id ? 'status.reply' : 'status.show';
+
+		return view($template, compact('user', 'status'));
+	}
+
+	public function shortcodeRedirect(Request $request, $id)
+	{
+		abort_if(strlen($id) < 5, 404);
+		if(!Auth::check()) {
+			return redirect('/login?next='.urlencode('/' . $request->path()));
+		}
+		$id = HashidService::decode($id);
+		$status = Status::find($id);
+		if(!$status) {
+			return redirect('/404');
+		}
+		return redirect($status->url());
+	}
+
+	public function showId(int $id)
+	{
+		abort(404);
+		$status = Status::whereNull('reblog_of_id')
+				->whereIn('scope', ['public', 'unlisted'])
+				->findOrFail($id);
+		return redirect($status->url());
+	}
+
+	public function showEmbed(Request $request, $username, int $id)
+	{
+		$profile = Profile::whereNull(['domain','status'])
+			->whereIsPrivate(false)
+			->whereUsername($username)
+			->first();
+		if(!$profile) {
+			$content = view('status.embed-removed');
+			return response($content)->header('X-Frame-Options', 'ALLOWALL');
+		}
+		$status = Status::whereProfileId($profile->id)
+			->whereNull('uri')
+			->whereScope('public')
+			->whereIsNsfw(false)
+			->whereIn('type', ['photo', 'video','photo:album'])
+			->find($id);
+		if(!$status) {
+			$content = view('status.embed-removed');
+			return response($content)->header('X-Frame-Options', 'ALLOWALL');
+		}
+		$showLikes = $request->filled('likes') && $request->likes == true;
+		$showCaption = $request->filled('caption') && $request->caption !== false;
+		$layout = $request->filled('layout') && $request->layout == 'compact' ? 'compact' : 'full';
+		$content = view('status.embed', compact('status', 'showLikes', 'showCaption', 'layout'));
+		return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']);
+	}
+
+	public function showObject(Request $request, $username, int $id)
+	{
+		$user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail();
+
+		if($user->status != null) {
+			return ProfileController::accountCheck($user);
+		}
+
+		$status = Status::whereProfileId($user->id)
+				->whereNotIn('visibility',['draft','direct'])
+				->findOrFail($id);
+
+		abort_if($status->uri, 404);
+
+		if($status->visibility == 'private' || $user->is_private) {
+			if(!Auth::check()) {
+				abort(403);
+			}
+			$pid = Auth::user()->profile;
+			if($user->followedBy($pid) == false && $user->id !== $pid->id) {
+				abort(403);
+			}
+		}
+
+		return $this->showActivityPub($request, $status);
+	}
+
+	public function compose()
+	{
+		$this->authCheck();
+
+		return view('status.compose');
+	}
+
+	public function store(Request $request)
+	{
+		return;
+	}
+
+	public function delete(Request $request)
+	{
+		$this->authCheck();
+
+		$this->validate($request, [
+		  'item'  => 'required|integer|min:1',
+		]);
+
+		$status = Status::findOrFail($request->input('item'));
+
+		$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();
+		}
+
+		Cache::forget('_api:statuses:recent_9:' . $status->profile_id);
+		Cache::forget('profile:status_count:' . $status->profile_id);
+		Cache::forget('profile:embed:' . $status->profile_id);
+		StatusService::del($status->id);
+		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($user->url());
+		}
+	}
+
+	public function storeShare(Request $request)
+	{
+		$this->authCheck();
+
+		$this->validate($request, [
+		  'item'    => 'required|integer|min:1',
+		]);
+
+		$user = Auth::user();
+		$profile = $user->profile;
+		$status = Status::withCount('shares')
+			->whereIn('scope', ['public', 'unlisted'])
+			->findOrFail($request->input('item'));
+
+		$count = $status->shares()->count();
+
+		$exists = Status::whereProfileId(Auth::user()->profile->id)
+				  ->whereReblogOfId($status->id)
+				  ->count();
+		if ($exists !== 0) {
+			$shares = Status::whereProfileId(Auth::user()->profile->id)
+				  ->whereReblogOfId($status->id)
+				  ->get();
+			foreach ($shares as $share) {
+				$share->delete();
+				$count--;
+			}
+		} else {
+			$share = new Status();
+			$share->profile_id = $profile->id;
+			$share->reblog_of_id = $status->id;
+			$share->in_reply_to_profile_id = $status->profile_id;
+			$share->save();
+			$count++;
+			SharePipeline::dispatch($share);
+		}
+
+		if($count >= 0) {
+			$status->reblogs_count = $count;
+			$status->save();
+		}
+
+		Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id);
+		StatusService::del($status->id);
+
+		if ($request->ajax()) {
+			$response = ['code' => 200, 'msg' => 'Share saved', 'count' => $count];
+		} else {
+			$response = redirect($status->url());
+		}
+
+		return $response;
+	}
+
+	public function showActivityPub(Request $request, $status)
+	{
+		$fractal = new Fractal\Manager();
+		$resource = new Fractal\Resource\Item($status, new Note());
+		$res = $fractal->createData($resource)->toArray();
+
+		return response()->json($res['data'], 200, ['Content-Type' => 'application/activity+json'], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
+	}
+
+	public function edit(Request $request, $username, $id)
+	{
+		$this->authCheck();
+		$user = Auth::user()->profile;
+		$status = Status::whereProfileId($user->id)
+				->with(['media'])
+				->findOrFail($id);
+		$licenses = License::get();
+		return view('status.edit', compact('user', 'status', 'licenses'));
+	}
+
+	public function editStore(Request $request, $username, $id)
+	{
+		$this->authCheck();
+		$user = Auth::user()->profile;
+		$status = Status::whereProfileId($user->id)
+				->with(['media'])
+				->findOrFail($id);
+
+		$this->validate($request, [
+		  'license'      => 'nullable|integer|min:1|max:16',
+		]);
+
+		$licenseId = $request->input('license');
+
+		$status->media->each(function($media) use($licenseId) {
+			$media->license = $licenseId;
+			$media->save();
+			Cache::forget('status:transformer:media:attachments:'.$media->status_id);
+		});
+
+		return redirect($status->url());
+	}
+
+	protected function authCheck()
+	{
+		if (Auth::check() == false) {
+			abort(403);
+		}
+	}
+
+	protected function validateVisibility($visibility)
+	{
+		$allowed = ['public', 'unlisted', 'private'];
+		return in_array($visibility, $allowed) ? $visibility : 'public';
+	}
+
+	public static function mimeTypeCheck($mimes)
+	{
+		$allowed = explode(',', config('pixelfed.media_types'));
+		$count = count($mimes);
+		$photos = 0;
+		$videos = 0;
+		foreach($mimes as $mime) {
+			if(in_array($mime, $allowed) == false && $mime !== 'video/mp4') {
+				continue;
+			}
+			if(str_contains($mime, 'image/')) {
+				$photos++;
+			}
+			if(str_contains($mime, 'video/')) {
+				$videos++;
+			}
+		}
+		if($photos == 1 && $videos == 0) {
+			return 'photo';
+		}
+		if($videos == 1 && $photos == 0) {
+			return 'video';
+		}
+		if($photos > 1 && $videos == 0) {
+			return 'photo:album';
+		}
+		if($videos > 1 && $photos == 0) {
+			return 'video:album';
+		}
+		if($photos >= 1 && $videos >= 1) {
+			return 'photo:video:album';
+		}
+	}
+
+	public function toggleVisibility(Request $request) {
+		$this->authCheck();
+		$this->validate($request, [
+			'item' => 'required|string|min:1|max:20',
+			'disableComments' => 'required|boolean'
+		]);
+
+		$user = Auth::user();
+		$id = $request->input('item');
+		$state = $request->input('disableComments');
+
+		$status = Status::findOrFail($id);
+
+		if($status->profile_id != $user->profile->id && $user->is_admin == false) {
+			abort(403);
+		}
+
+		$status->comments_disabled = $status->comments_disabled == true ? false : true;
+		$status->save();
+
+		return response()->json([200]);
+	}
+
+	public function storeView(Request $request)
+	{
+		abort_if(!$request->user(), 403);
+
+		$this->validate($request, [
+			'status_id' => 'required|integer|exists:statuses,id',
+			'profile_id' => 'required|integer|exists:profiles,id'
+		]);
+
+		$sid = (int) $request->input('status_id');
+		$pid = (int) $request->input('profile_id');
+
+		StatusView::firstOrCreate([
+				'status_id' => $sid,
+				'status_profile_id' => $pid,
+				'profile_id' => $request->user()->profile_id
+		]);
+
+		return response()->json(1);
+	}
 }

+ 13 - 85
resources/views/status/edit.blade.php

@@ -5,99 +5,27 @@
 <div class="container">
 	<div class="col-12 col-md-8 offset-md-2 pt-4">
 
-		<div class="card">
+		<div class="card shadow-none border">
 			<div class="card-header bg-white font-weight-bold d-flex justify-content-between align-items-center">
 				<span>Edit Status</span>
 				<a class="btn btn-outline-primary btn-sm font-weight-bold" href="{{$status->url()}}">Back to post</a>
 			</div>
 			<div class="card-body">
-				@csrf
-				<div class="form-group mb-0">
-					<label class="font-weight-bold text-muted small">CW/NSFW</label>
-					<div class="switch switch-sm">
-						<input type="checkbox" class="switch" id="cw-switch" name="cw" {{$status->is_nsfw==true?'checked=""':''}} disabled="">
-						<label for="cw-switch" class="small font-weight-bold">(Default off)</label>
+				<form method="post">
+					@csrf
+					<div class="form-group">
+						<label class="font-weight-bold text-muted small">License</label>
+						<select class="form-control" name="license">
+							@foreach($licenses as $license)
+							<option value="{{$license['id']}}" {{$status->firstMedia()->license == $license['id'] ? 'selected' : ''}}>{{$license['title']}}</option>
+							@endforeach
+						</select>
 					</div>
-				</div>
+					<hr>
+					<button class="btn btn-primary btn-block font-weight-bold">Save</button>
+				</form>
 			</div>
 		</div>
-		<div class="accordion" id="accordionWrapper">
-			@foreach($status->media()->orderBy('order')->get() as $media)
-			<div class="card mt-4 media-card">
-				<div class="card-header bg-white font-weight-bold" data-toggle="collapse" href="#collapseMedia{{$loop->iteration}}">
-					Media #{{$media->order + 1}}
-					<span class="float-right">
-						<span class="badge badge-primary">
-							{{$media->mime}}
-						</span>
-					</span>
-				</div>
-				<div class="collapse {{$loop->iteration==1?'show':''}}" id="collapseMedia{{$loop->iteration}}" data-parent="#accordionWrapper">
-					<div class="card-body p-0">
-						<form method="post" enctype="multipart/form-data" class="media-form">
-							@csrf
-							<input type="hidden" name="media_id" value="{{$media->id}}">
-							<div class="filter-wrapper {{$media->filter_class}}" data-filter="{{$media->filter_class}}">
-								<img class="img-fluid" src="{{$media->url()}}" width="100%">
-							</div>
-							<div class="p-3">
-								<div class="form-group">
-									<label class="font-weight-bold text-muted small">Description</label>
-									<input class="form-control" name="media_caption" value="{{$media->caption}}" placeholder="Add a descriptive caption for screenreaders" autocomplete="off">
-								</div>
-							@if($media->activityVerb() == 'Image')
-								<div class="form-group form-filters" data-filter="{{$media->filter_class}}">
-									<label for="filterSelectDropdown" class="font-weight-bold text-muted small">Select Filter</label>
-									<select class="form-control filter-dropdown" name="media_filter"><option value="" selected="">No Filter</option><option value="filter-1977">1977</option><option value="filter-aden">Aden</option><option value="filter-amaro">Amaro</option><option value="filter-ashby">Ashby</option><option value="filter-brannan">Brannan</option><option value="filter-brooklyn">Brooklyn</option><option value="filter-charmes">Charmes</option><option value="filter-clarendon">Clarendon</option><option value="filter-crema">Crema</option><option value="filter-dogpatch">Dogpatch</option><option value="filter-earlybird">Earlybird</option><option value="filter-gingham">Gingham</option><option value="filter-ginza">Ginza</option><option value="filter-hefe">Hefe</option><option value="filter-helena">Helena</option><option value="filter-hudson">Hudson</option><option value="filter-inkwell">Inkwell</option><option value="filter-kelvin">Kelvin</option><option value="filter-juno">Kuno</option><option value="filter-lark">Lark</option><option value="filter-lofi">Lo-Fi</option><option value="filter-ludwig">Ludwig</option><option value="filter-maven">Maven</option><option value="filter-mayfair">Mayfair</option><option value="filter-moon">Moon</option><option value="filter-nashville">Nashville</option><option value="filter-perpetua">Perpetua</option><option value="filter-poprocket">Poprocket</option><option value="filter-reyes">Reyes</option><option value="filter-rise">Rise</option><option value="filter-sierra">Sierra</option><option value="filter-skyline">Skyline</option><option value="filter-slumber">Slumber</option><option value="filter-stinson">Stinson</option><option value="filter-sutro">Sutro</option><option value="filter-toaster">Toaster</option><option value="filter-valencia">Valencia</option><option value="filter-vesper">Vesper</option><option value="filter-walden">Walden</option><option value="filter-willow">Willow</option><option value="filter-xpro-ii">X-Pro II</option></select>
-								</div>
-							@endif
-								<hr>
-								<div class="form-group d-flex justify-content-between align-items-center mb-0">
-									<p class="text-muted font-weight-bold mb-0 small">Last Updated: {{$media->updated_at->diffForHumans()}}</p>
-									<button type="submit" class="btn btn-primary btn-sm font-weight-bold px-4">Update</button>
-								</div>  
-							</div>
-						</form>
-					</div>
-				</div>
-			</div>
-			@endforeach
-		</div>
-
 	</div>
 </div>
 @endsection
-
-@push('scripts')
-<script type="text/javascript">
-	$(document).ready(function() {
-		App.boot();
-		$('.form-filters').each(function(i,d) {
-			let el = $(d);
-			let filter = el.data('filter');
-			if(filter) {
-				var opt = el.find('option[value='+filter+']')[0];
-				$(opt).attr('selected','');
-			}
-		});
-
-		$('.media-form').on('submit', function(e){
-			e.preventDefault();
-			let el = $(this);
-			let id = el.find('input[name=media_id]').val();
-			let caption = el.find('input[name=media_caption]').val();
-			let filter = el.find('.filter-dropdown option:selected').val();
-			axios.post(window.location.href, {
-				'id': id,
-				'caption': caption,
-				'filter': filter
-			}).then((res) => {
-				window.location.href = '{{$status->url()}}';
-			}).catch((err) => {
-				swal('Something went wrong', 'An error occurred, please try again later', 'error');
-			});
-		});
-	});
-
-</script>
-@endpush