mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-12-23 05:23:17 +00:00
Merge pull request #263 from dansup/frontend-ui-refactor
Frontend ui refactor
This commit is contained in:
commit
60bbb22454
19 changed files with 337 additions and 71 deletions
|
@ -3,8 +3,16 @@
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Avatar extends Model
|
class Avatar extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ class CommentController extends Controller
|
||||||
|
|
||||||
$reply = new Status();
|
$reply = new Status();
|
||||||
$reply->profile_id = $profile->id;
|
$reply->profile_id = $profile->id;
|
||||||
$reply->caption = $comment;
|
$reply->caption = e(strip_tags($comment));
|
||||||
$reply->rendered = e($comment);
|
$reply->rendered = $comment;
|
||||||
$reply->in_reply_to_id = $status->id;
|
$reply->in_reply_to_id = $status->id;
|
||||||
$reply->in_reply_to_profile_id = $status->profile_id;
|
$reply->in_reply_to_profile_id = $status->profile_id;
|
||||||
$reply->save();
|
$reply->save();
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Auth, Cache;
|
use Auth, Cache;
|
||||||
use App\Jobs\StatusPipeline\{NewStatusPipeline, StatusDelete};
|
use App\Jobs\StatusPipeline\{NewStatusPipeline, StatusDelete};
|
||||||
|
use App\Jobs\ImageOptimizePipeline\ImageOptimize;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\{Media, Profile, Status, User};
|
use App\{Media, Profile, Status, User};
|
||||||
use Vinkla\Hashids\Facades\Hashids;
|
use Vinkla\Hashids\Facades\Hashids;
|
||||||
|
@ -14,7 +15,7 @@ class StatusController extends Controller
|
||||||
{
|
{
|
||||||
$user = Profile::whereUsername($username)->firstOrFail();
|
$user = Profile::whereUsername($username)->firstOrFail();
|
||||||
$status = Status::whereProfileId($user->id)
|
$status = Status::whereProfileId($user->id)
|
||||||
->withCount(['likes', 'comments'])
|
->withCount(['likes', 'comments', 'media'])
|
||||||
->findOrFail($id);
|
->findOrFail($id);
|
||||||
if(!$status->media_path && $status->in_reply_to_id) {
|
if(!$status->media_path && $status->in_reply_to_id) {
|
||||||
return redirect($status->url());
|
return redirect($status->url());
|
||||||
|
@ -32,36 +33,47 @@ class StatusController extends Controller
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'photo' => 'required|mimes:jpeg,png,bmp,gif|max:' . config('pixelfed.max_photo_size'),
|
'photo.*' => 'required|mimes:jpeg,png,bmp,gif|max:' . config('pixelfed.max_photo_size'),
|
||||||
'caption' => 'string|max:' . config('pixelfed.max_caption_length'),
|
'caption' => 'string|max:' . config('pixelfed.max_caption_length'),
|
||||||
'cw' => 'nullable|string'
|
'cw' => 'nullable|string',
|
||||||
|
'filter_class' => 'nullable|string',
|
||||||
|
'filter_name' => 'nullable|string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$cw = $request->filled('cw') && $request->cw == 'on' ? true : false;
|
$cw = $request->filled('cw') && $request->cw == 'on' ? true : false;
|
||||||
$monthHash = hash('sha1', date('Y') . date('m'));
|
$monthHash = hash('sha1', date('Y') . date('m'));
|
||||||
$userHash = hash('sha1', $user->id . (string) $user->created_at);
|
$userHash = hash('sha1', $user->id . (string) $user->created_at);
|
||||||
$storagePath = "public/m/{$monthHash}/{$userHash}";
|
|
||||||
$path = $request->photo->store($storagePath);
|
|
||||||
$profile = $user->profile;
|
$profile = $user->profile;
|
||||||
|
|
||||||
$status = new Status;
|
$status = new Status;
|
||||||
$status->profile_id = $profile->id;
|
$status->profile_id = $profile->id;
|
||||||
$status->caption = $request->caption;
|
$status->caption = strip_tags($request->caption);
|
||||||
$status->is_nsfw = $cw;
|
$status->is_nsfw = $cw;
|
||||||
|
|
||||||
$status->save();
|
$status->save();
|
||||||
|
|
||||||
$media = new Media;
|
$photos = $request->file('photo');
|
||||||
$media->status_id = $status->id;
|
$order = 1;
|
||||||
$media->profile_id = $profile->id;
|
foreach ($photos as $k => $v) {
|
||||||
$media->user_id = $user->id;
|
$storagePath = "public/m/{$monthHash}/{$userHash}";
|
||||||
$media->media_path = $path;
|
$path = $v->store($storagePath);
|
||||||
$media->size = $request->file('photo')->getClientSize();
|
$media = new Media;
|
||||||
$media->mime = $request->file('photo')->getClientMimeType();
|
$media->status_id = $status->id;
|
||||||
$media->save();
|
$media->profile_id = $profile->id;
|
||||||
NewStatusPipeline::dispatch($status, $media);
|
$media->user_id = $user->id;
|
||||||
|
$media->media_path = $path;
|
||||||
|
$media->size = $v->getClientSize();
|
||||||
|
$media->mime = $v->getClientMimeType();
|
||||||
|
$media->filter_class = $request->input('filter_class');
|
||||||
|
$media->filter_name = $request->input('filter_name');
|
||||||
|
$media->order = $order;
|
||||||
|
$media->save();
|
||||||
|
ImageOptimize::dispatch($media);
|
||||||
|
$order++;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewStatusPipeline::dispatch($status);
|
||||||
|
|
||||||
// TODO: Parse Caption
|
|
||||||
// TODO: Send to subscribers
|
// TODO: Send to subscribers
|
||||||
|
|
||||||
return redirect($status->url());
|
return redirect($status->url());
|
||||||
|
|
|
@ -16,17 +16,15 @@ class NewStatusPipeline implements ShouldQueue
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
protected $status;
|
protected $status;
|
||||||
protected $media;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Status $status, $media = false)
|
public function __construct(Status $status)
|
||||||
{
|
{
|
||||||
$this->status = $status;
|
$this->status = $status;
|
||||||
$this->media = $media;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,13 +35,10 @@ class NewStatusPipeline implements ShouldQueue
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$status = $this->status;
|
$status = $this->status;
|
||||||
$media = $this->media;
|
|
||||||
|
|
||||||
StatusEntityLexer::dispatch($status);
|
StatusEntityLexer::dispatch($status);
|
||||||
StatusActivityPubDeliver::dispatch($status);
|
//StatusActivityPubDeliver::dispatch($status);
|
||||||
if($media) {
|
|
||||||
ImageOptimize::dispatch($media);
|
|
||||||
}
|
|
||||||
Cache::forever('post.' . $status->id, $status);
|
Cache::forever('post.' . $status->id, $status);
|
||||||
|
|
||||||
$redis = Redis::connection();
|
$redis = Redis::connection();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Jobs\StatusPipeline;
|
namespace App\Jobs\StatusPipeline;
|
||||||
|
|
||||||
use App\{Media, StatusHashtag, Status};
|
use App\{Media, Notification, StatusHashtag, Status};
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
@ -60,6 +60,9 @@ class StatusDelete implements ShouldQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
$status->likes()->delete();
|
$status->likes()->delete();
|
||||||
|
Notification::whereItemType('App\Status')
|
||||||
|
->whereItemId($status->id)
|
||||||
|
->delete();
|
||||||
StatusHashtag::whereStatusId($status->id)->delete();
|
StatusHashtag::whereStatusId($status->id)->delete();
|
||||||
$status->delete();
|
$status->delete();
|
||||||
|
|
||||||
|
|
|
@ -6,21 +6,28 @@ use Cache;
|
||||||
use App\{
|
use App\{
|
||||||
Hashtag,
|
Hashtag,
|
||||||
Media,
|
Media,
|
||||||
|
Mention,
|
||||||
|
Profile,
|
||||||
Status,
|
Status,
|
||||||
StatusHashtag
|
StatusHashtag
|
||||||
};
|
};
|
||||||
use App\Util\Lexer\Hashtag as HashtagLexer;
|
use App\Util\Lexer\Hashtag as HashtagLexer;
|
||||||
|
use App\Util\Lexer\{Autolink, Extractor};
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use App\Jobs\MentionPipeline\MentionPipeline;
|
||||||
|
|
||||||
class StatusEntityLexer implements ShouldQueue
|
class StatusEntityLexer implements ShouldQueue
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
protected $status;
|
protected $status;
|
||||||
|
protected $entities;
|
||||||
|
protected $autolink;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
|
@ -39,22 +46,40 @@ class StatusEntityLexer implements ShouldQueue
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$status = $this->status;
|
$status = $this->status;
|
||||||
$this->parseHashtags();
|
$this->parseEntities();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseHashtags()
|
public function parseEntities()
|
||||||
|
{
|
||||||
|
$this->extractEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractEntities()
|
||||||
|
{
|
||||||
|
$this->entities = Extractor::create()->extract($this->status->caption);
|
||||||
|
$this->autolinkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function autolinkStatus()
|
||||||
|
{
|
||||||
|
$this->autolink = Autolink::create()->autolink($this->status->caption);
|
||||||
|
$this->storeEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function storeEntities()
|
||||||
{
|
{
|
||||||
$status = $this->status;
|
$status = $this->status;
|
||||||
$text = e($status->caption);
|
$this->storeHashtags();
|
||||||
$tags = HashtagLexer::getHashtags($text);
|
$this->storeMentions();
|
||||||
$rendered = $text;
|
$status->rendered = $this->autolink;
|
||||||
if(count($tags) > 0) {
|
$status->entities = json_encode($this->entities);
|
||||||
$rendered = HashtagLexer::replaceHashtagsWithLinks($text);
|
|
||||||
}
|
|
||||||
$status->rendered = $rendered;
|
|
||||||
$status->save();
|
$status->save();
|
||||||
|
}
|
||||||
Cache::forever('post.' . $status->id, $status);
|
|
||||||
|
public function storeHashtags()
|
||||||
|
{
|
||||||
|
$tags = array_unique($this->entities['hashtags']);
|
||||||
|
$status = $this->status;
|
||||||
|
|
||||||
foreach($tags as $tag) {
|
foreach($tags as $tag) {
|
||||||
$slug = str_slug($tag);
|
$slug = str_slug($tag);
|
||||||
|
@ -64,11 +89,32 @@ class StatusEntityLexer implements ShouldQueue
|
||||||
['slug' => $slug]
|
['slug' => $slug]
|
||||||
);
|
);
|
||||||
|
|
||||||
$stag = new StatusHashtag;
|
StatusHashtag::firstOrCreate(
|
||||||
$stag->status_id = $status->id;
|
['status_id' => $status->id],
|
||||||
$stag->hashtag_id = $htag->id;
|
['hashtag_id' => $htag->id]
|
||||||
$stag->save();
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function storeMentions()
|
||||||
|
{
|
||||||
|
$mentions = array_unique($this->entities['mentions']);
|
||||||
|
$status = $this->status;
|
||||||
|
|
||||||
|
foreach($mentions as $mention) {
|
||||||
|
$mentioned = Profile::whereUsername($mention)->first();
|
||||||
|
|
||||||
|
if(empty($mentioned) || !isset($mentioned->id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$m = new Mention;
|
||||||
|
$m->status_id = $status->id;
|
||||||
|
$m->profile_id = $mentioned->id;
|
||||||
|
$m->save();
|
||||||
|
|
||||||
|
MentionPipeline::dispatch($status, $m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
10
app/Like.php
10
app/Like.php
|
@ -3,9 +3,19 @@
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Like extends Model
|
class Like extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
public function actor()
|
public function actor()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Profile::class, 'profile_id', 'id');
|
return $this->belongsTo(Profile::class, 'profile_id', 'id');
|
||||||
|
|
|
@ -2,11 +2,21 @@
|
||||||
|
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Storage;
|
use Storage;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Media extends Model
|
class Media extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
public function url()
|
public function url()
|
||||||
{
|
{
|
||||||
$path = $this->media_path;
|
$path = $this->media_path;
|
||||||
|
|
|
@ -3,9 +3,18 @@
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Mention extends Model
|
class Mention extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
public function profile()
|
public function profile()
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,28 +3,37 @@
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Notification extends Model
|
class Notification extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
public function actor()
|
/**
|
||||||
{
|
* The attributes that should be mutated to dates.
|
||||||
return $this->belongsTo(Profile::class, 'actor_id', 'id');
|
*
|
||||||
}
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
|
public function actor()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Profile::class, 'actor_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
public function profile()
|
public function profile()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Profile::class, 'profile_id', 'id');
|
return $this->belongsTo(Profile::class, 'profile_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function item()
|
public function item()
|
||||||
{
|
{
|
||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function status()
|
public function status()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Status::class, 'item_id', 'id');
|
return $this->belongsTo(Status::class, 'item_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,18 @@ namespace App;
|
||||||
use Storage;
|
use Storage;
|
||||||
use App\Util\Lexer\PrettyNumber;
|
use App\Util\Lexer\PrettyNumber;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Profile extends Model
|
class Profile extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'private_key',
|
'private_key',
|
||||||
];
|
];
|
||||||
|
|
|
@ -2,12 +2,21 @@
|
||||||
|
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Storage;
|
use Storage;
|
||||||
use Vinkla\Hashids\Facades\Hashids;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Status extends Model
|
class Status extends Model
|
||||||
{
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
public function profile()
|
public function profile()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Profile::class);
|
return $this->belongsTo(Profile::class);
|
||||||
|
@ -25,7 +34,7 @@ class Status extends Model
|
||||||
|
|
||||||
public function thumb()
|
public function thumb()
|
||||||
{
|
{
|
||||||
if($this->media->count() == 0) {
|
if($this->media->count() == 0 || $this->is_nsfw) {
|
||||||
return "data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
|
return "data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
|
||||||
}
|
}
|
||||||
return url(Storage::url($this->firstMedia()->thumbnail_path));
|
return url(Storage::url($this->firstMedia()->thumbnail_path));
|
||||||
|
@ -43,6 +52,11 @@ class Status extends Model
|
||||||
return url($path);
|
return url($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function editUrl()
|
||||||
|
{
|
||||||
|
return $this->url() . '/edit';
|
||||||
|
}
|
||||||
|
|
||||||
public function mediaUrl()
|
public function mediaUrl()
|
||||||
{
|
{
|
||||||
$media = $this->firstMedia();
|
$media = $this->firstMedia();
|
||||||
|
|
10
app/User.php
10
app/User.php
|
@ -3,11 +3,19 @@
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
use Notifiable;
|
use Notifiable, SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be mutated to dates.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dates = ['deleted_at'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddFiltersToMediaTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('media', function (Blueprint $table) {
|
||||||
|
$table->string('filter_name')->nullable()->after('orientation');
|
||||||
|
$table->string('filter_class')->nullable()->after('filter_name');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('media', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('filter_name');
|
||||||
|
$table->dropColumn('filter_class');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddSoftDeletesToModels extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('avatars', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('likes', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('media', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('mentions', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('notifications', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('profiles', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('statuses', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('users', function ($table) {
|
||||||
|
$table->softDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
BIN
public/css/app.css
vendored
BIN
public/css/app.css
vendored
Binary file not shown.
Binary file not shown.
|
@ -16,7 +16,47 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-8 status-photo px-0">
|
<div class="col-12 col-md-8 status-photo px-0">
|
||||||
<img src="{{$status->mediaUrl()}}" width="100%">
|
@if($status->is_nsfw && $status->media_count == 1)
|
||||||
|
<details class="details-animated">
|
||||||
|
<p>
|
||||||
|
<summary>NSFW / Hidden Image</summary>
|
||||||
|
<a class="max-hide-overflow {{$status->firstMedia()->filter_class}}" href="{{$status->url()}}">
|
||||||
|
<img class="card-img-top" src="{{$status->mediaUrl()}}">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</details>
|
||||||
|
@elseif(!$status->is_nsfw && $status->media_count == 1)
|
||||||
|
<div class="{{$status->firstMedia()->filter_class}}">
|
||||||
|
<img src="{{$status->mediaUrl()}}" width="100%">
|
||||||
|
</div>
|
||||||
|
@elseif($status->is_nsfw && $status->media_count > 1)
|
||||||
|
|
||||||
|
@elseif(!$status->is_nsfw && $status->media_count > 1)
|
||||||
|
<div id="photoCarousel" class="carousel slide carousel-fade" data-ride="carousel">
|
||||||
|
<ol class="carousel-indicators">
|
||||||
|
@for($i = 0; $i < $status->media_count; $i++)
|
||||||
|
<li data-target="#photoCarousel" data-slide-to="{{$i}}" class="{{$i == 0 ? 'active' : ''}}"></li>
|
||||||
|
@endfor
|
||||||
|
</ol>
|
||||||
|
<div class="carousel-inner">
|
||||||
|
@foreach($status->media()->orderBy('order')->get() as $media)
|
||||||
|
<div class="carousel-item {{$loop->iteration == 1 ? 'active' : ''}}">
|
||||||
|
<figure class="{{$media->filter_class}}">
|
||||||
|
<img class="d-block w-100" src="{{$media->url()}}" alt="{{$status->caption}}">
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
<a class="carousel-control-prev" href="#photoCarousel" role="button" data-slide="prev">
|
||||||
|
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||||
|
<span class="sr-only">Previous</span>
|
||||||
|
</a>
|
||||||
|
<a class="carousel-control-next" href="#photoCarousel" role="button" data-slide="next">
|
||||||
|
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||||
|
<span class="sr-only">Next</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-4 px-0 d-flex flex-column border-left border-md-left-0">
|
<div class="col-12 col-md-4 px-0 d-flex flex-column border-left border-md-left-0">
|
||||||
<div class="d-md-flex d-none align-items-center justify-content-between card-header py-3 bg-white">
|
<div class="d-md-flex d-none align-items-center justify-content-between card-header py-3 bg-white">
|
||||||
|
@ -40,7 +80,7 @@
|
||||||
@foreach($status->comments->reverse()->take(10) as $item)
|
@foreach($status->comments->reverse()->take(10) as $item)
|
||||||
<p class="mb-0">
|
<p class="mb-0">
|
||||||
<span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="{{$item->profile->url()}}">{{$item->profile->username}}</a></bdi></span>
|
<span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="{{$item->profile->url()}}">{{$item->profile->username}}</a></bdi></span>
|
||||||
<span class="comment-text">{!!$item->rendered!!} <a href="{{$item->url()}}" class="text-dark small font-weight-bold float-right">{{$item->created_at->diffForHumans(null, true, true ,true)}}</a></span>
|
<span class="comment-text">{!! $item->rendered ?? e($item->caption) !!} <a href="{{$item->url()}}" class="text-dark small font-weight-bold float-right">{{$item->created_at->diffForHumans(null, true, true ,true)}}</a></span>
|
||||||
</p>
|
</p>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<a class="dropdown-item" href="#">Embed</a>
|
<a class="dropdown-item" href="#">Embed</a>
|
||||||
@if(Auth::check())
|
@if(Auth::check())
|
||||||
@if(Auth::user()->profile->id === $item->profile->id || Auth::user()->is_admin == true)
|
@if(Auth::user()->profile->id === $item->profile->id || Auth::user()->is_admin == true)
|
||||||
|
<a class="dropdown-item" href="{{$item->editUrl()}}">Edit</a>
|
||||||
<form method="post" action="/i/delete">
|
<form method="post" action="/i/delete">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="type" value="post">
|
<input type="hidden" name="type" value="post">
|
||||||
|
@ -29,16 +30,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if($item->is_nsfw)
|
@if($item->is_nsfw)
|
||||||
<details>
|
<details class="details-animated">
|
||||||
<p>
|
<p>
|
||||||
<summary>NSFW / Hidden Image</summary>
|
<summary>NSFW / Hidden Image</summary>
|
||||||
<a class="max-hide-overflow" href="{{$item->url()}}">
|
<a class="max-hide-overflow {{$item->firstMedia()->filter_class}}" href="{{$item->url()}}">
|
||||||
<img class="card-img-top" src="{{$item->mediaUrl()}}">
|
<img class="card-img-top" src="{{$item->mediaUrl()}}">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
@else
|
@else
|
||||||
<a class="max-hide-overflow" href="{{$item->url()}}">
|
<a class="max-hide-overflow {{$item->firstMedia()->filter_class}}" href="{{$item->url()}}">
|
||||||
<img class="card-img-top" src="{{$item->mediaUrl()}}">
|
<img class="card-img-top" src="{{$item->mediaUrl()}}">
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
@ -84,7 +85,7 @@
|
||||||
<a class="text-dark" href="{{$status->profile->url()}}">{{$status->profile->username}}</a>
|
<a class="text-dark" href="{{$status->profile->url()}}">{{$status->profile->username}}</a>
|
||||||
</bdi>
|
</bdi>
|
||||||
</span>
|
</span>
|
||||||
<span class="comment-text">{!!$status->rendered!!}</span>
|
<span class="comment-text">{!! $item->rendered ?? e($item->caption) !!}</span>
|
||||||
<span class="float-right">
|
<span class="float-right">
|
||||||
<a href="{{$status->url()}}" class="text-dark small font-weight-bold">
|
<a href="{{$status->url()}}" class="text-dark small font-weight-bold">
|
||||||
{{$status->created_at->diffForHumans(null, true, true, true)}}
|
{{$status->created_at->diffForHumans(null, true, true, true)}}
|
||||||
|
@ -95,7 +96,7 @@
|
||||||
@foreach($item->comments->reverse()->take(3) as $comment)
|
@foreach($item->comments->reverse()->take(3) as $comment)
|
||||||
<p class="mb-0">
|
<p class="mb-0">
|
||||||
<span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="{{$comment->profile->url()}}">{{$comment->profile->username}}</a></bdi></span>
|
<span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="{{$comment->profile->url()}}">{{$comment->profile->username}}</a></bdi></span>
|
||||||
<span class="comment-text">{{ str_limit($comment->caption, 125) }}</span>
|
<span class="comment-text">{!! str_limit($item->rendered ?? e($item->caption), 150) !!}</span>
|
||||||
</p>
|
</p>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
|
|
Loading…
Reference in a new issue