mirror of
https://github.com/NyaaStudios/nyaabooru.git
synced 2025-12-09 21:42:57 +00:00
add models, setup livewire, setup mongodb
This commit is contained in:
parent
c0590a3412
commit
be4c848eee
27 changed files with 2508 additions and 0 deletions
39
app/Http/Controllers/AuthController.php
Normal file
39
app/Http/Controllers/AuthController.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function handleRedirect()
|
||||
{
|
||||
return Socialite::driver('authentik')->redirect();
|
||||
}
|
||||
|
||||
public function handleCallback()
|
||||
{
|
||||
$user = Socialite::driver('authentik')->user();
|
||||
|
||||
$authUser = User::updateOrCreate(
|
||||
[ 'email' => $user->getEmail() ],
|
||||
[ 'name' => $user->getName() ]
|
||||
);
|
||||
|
||||
if ($authUser)
|
||||
{
|
||||
Auth::login($authUser);
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
abort(401);
|
||||
}
|
||||
|
||||
public function handleLogout()
|
||||
{
|
||||
Auth::logout();
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
13
app/Livewire/App/Home.php
Normal file
13
app/Livewire/App/Home.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\App;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Home extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.app.home');
|
||||
}
|
||||
}
|
||||
13
app/Livewire/App/Navbar.php
Normal file
13
app/Livewire/App/Navbar.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\App;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Navbar extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.app.navbar');
|
||||
}
|
||||
}
|
||||
64
app/Livewire/Pages/Upload.php
Normal file
64
app/Livewire/Pages/Upload.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Pages;
|
||||
|
||||
use App\Models\Post;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\Laravel\Facades\Image;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
|
||||
class Upload extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
#[Validate('extensions:jpg,jpeg,bmp,gif,png,webp,apng,mp4,wmv,mkv|mimes:jpg,jpeg,bmp,gif,png,webp,apng,mp4,wmv,mkv|max:81920')]
|
||||
public $file;
|
||||
|
||||
#[Validate('required|in:safe,suggestive,explicit')]
|
||||
public $rating = 'safe';
|
||||
|
||||
#[Title('Upload')]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.pages.upload');
|
||||
}
|
||||
|
||||
public function createPost()
|
||||
{
|
||||
$this->validate();
|
||||
$author = Auth::user();
|
||||
|
||||
if ($this->file)
|
||||
{
|
||||
$post = Post::create([
|
||||
'extension' => $this->file->getClientOriginalExtension(),
|
||||
'rating' => $this->rating,
|
||||
]);
|
||||
|
||||
if ($post)
|
||||
{
|
||||
$author->posts()->save($post);
|
||||
|
||||
// Save the full image
|
||||
$this->file->storeAs("posts/$post->id", 'full');
|
||||
$fullImg = Storage::get("posts/$post->id/full");
|
||||
|
||||
// Create thumbnail preview
|
||||
$thumb = Image::read($fullImg)->scaleDown(width: 512, height: 512);
|
||||
Storage::put("posts/$post->id/thumb", $thumb->encodeByExtension($post->extension, quality: 70));
|
||||
|
||||
// Create smaller preview image
|
||||
$preview = Image::read($fullImg)->scaleDown(width: 1280, height: 720);
|
||||
Storage::put("posts/$post->id/preview", $preview->encodeByExtension($post->extension, quality: 70));
|
||||
|
||||
return $this->redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->redirect('/upload');
|
||||
}
|
||||
}
|
||||
33
app/Livewire/PostFeature.php
Normal file
33
app/Livewire/PostFeature.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Post;
|
||||
use Livewire\Component;
|
||||
|
||||
class PostFeature extends Component
|
||||
{
|
||||
public ?Post $post = null;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->post = Post::raw(function($collection)
|
||||
{
|
||||
return $collection->aggregate([
|
||||
['$match' => ['featured' => 'on']],
|
||||
['$sample' => ['size' => 1]]
|
||||
]);
|
||||
})->first();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
if ($this->post == null)
|
||||
{
|
||||
return <<<'HTML'
|
||||
<div></div>
|
||||
HTML;
|
||||
}
|
||||
return view('livewire.post-feature');
|
||||
}
|
||||
}
|
||||
81
app/Livewire/Posts/Edit.php
Normal file
81
app/Livewire/Posts/Edit.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Posts;
|
||||
|
||||
use App\Models\Post;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class Edit extends Component
|
||||
{
|
||||
public Post $post;
|
||||
public Collection $tags;
|
||||
public Collection $selectableTags;
|
||||
|
||||
#[Validate('exists:tags,id')]
|
||||
public string $tag = '';
|
||||
|
||||
#[Validate('required|in:safe,suggestive,explicit')]
|
||||
public string $rating = 'unknown';
|
||||
|
||||
public $featured = false;
|
||||
|
||||
public string $deleteTagId = '';
|
||||
|
||||
public function mount(Post $post)
|
||||
{
|
||||
$this->post = $post;
|
||||
$this->tags = $post->tags;
|
||||
$this->rating = $post->rating;
|
||||
$this->featured = $post->featured;
|
||||
$this->selectableTags = Tag::whereDoesntHave('posts', function ($query) {
|
||||
$query->where('id', $this->post->id);
|
||||
})->get();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.posts.edit')->title("Edit post {$this->post->id}");
|
||||
}
|
||||
|
||||
public function updated()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
if ($this->tag)
|
||||
{
|
||||
if ($tag = Tag::find($this->tag))
|
||||
{
|
||||
$this->post->tags()->attach($tag);
|
||||
if ($tag->implies)
|
||||
{
|
||||
foreach ($tag->implies as $implied_id)
|
||||
{
|
||||
if ($impliedTag = Tag::find($implied_id))
|
||||
{
|
||||
$this->post->tags()->attach($impliedTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->post->rating = $this->rating;
|
||||
if ($this->post->rating == 'safe')
|
||||
{
|
||||
$this->post->featured = $this->featured;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->post->featured = null;
|
||||
}
|
||||
$this->post->save();
|
||||
|
||||
$this->tags = $this->post->tags;
|
||||
$this->selectableTags = Tag::whereDoesntHave('posts', function ($query) {
|
||||
$query->where('id', $this->post->id);
|
||||
})->get();
|
||||
}
|
||||
}
|
||||
27
app/Livewire/Posts/Image.php
Normal file
27
app/Livewire/Posts/Image.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Posts;
|
||||
|
||||
use App\Models\Post;
|
||||
use Livewire\Component;
|
||||
|
||||
class Image extends Component
|
||||
{
|
||||
public Post $post;
|
||||
|
||||
public function placeholder()
|
||||
{
|
||||
return <<<'HTML'
|
||||
<div class="wa-stack" style="display: flex; align-items: center; justify-content: center; max-height: 80vh;">
|
||||
<div class="wa-frame wa-border-radius-l" style="max-inline-size: 100%;">
|
||||
<wa-spinner></wa-spinner>
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.posts.image');
|
||||
}
|
||||
}
|
||||
21
app/Livewire/Posts/Index.php
Normal file
21
app/Livewire/Posts/Index.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Posts;
|
||||
|
||||
use App\Models\Post;
|
||||
use Livewire\Attributes\Title;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
#[Title('Posts')]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.posts.index', [
|
||||
'posts' => Post::orderBy('created_at', 'desc')->paginate(25),
|
||||
]);
|
||||
}
|
||||
}
|
||||
26
app/Livewire/Posts/Thumbnail.php
Normal file
26
app/Livewire/Posts/Thumbnail.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Posts;
|
||||
|
||||
use App\Models\Post;
|
||||
use Livewire\Component;
|
||||
|
||||
class Thumbnail extends Component
|
||||
{
|
||||
public Post $post;
|
||||
|
||||
public function placeholder()
|
||||
{
|
||||
return <<<'HTML'
|
||||
<div style="display: flex; align-items: center; justify-content: center; width: 256px; height: 256px;">
|
||||
<wa-spinner style="font-size: 4rem;"></wa-spinner>
|
||||
</div>
|
||||
HTML;
|
||||
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.posts.thumbnail');
|
||||
}
|
||||
}
|
||||
22
app/Livewire/Posts/View.php
Normal file
22
app/Livewire/Posts/View.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Posts;
|
||||
|
||||
use App\Models\Post;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class View extends Component
|
||||
{
|
||||
public Post $post;
|
||||
|
||||
#[Validate('string|max:240')]
|
||||
public $comment = '';
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.posts.view', [
|
||||
// 'comments' => $this->post->comments
|
||||
])->title("Post {$this->post->id}");
|
||||
}
|
||||
}
|
||||
109
app/Models/Post.php
Normal file
109
app/Models/Post.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use MongoDB\Laravel\Eloquent\Model;
|
||||
use MongoDB\Laravel\Relations\BelongsTo;
|
||||
use MongoDB\Laravel\Relations\BelongsToMany;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class Post extends Model
|
||||
{
|
||||
protected $fillable = [ 'rating', 'extension', 'featured' ];
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function tags(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Tag::class);
|
||||
}
|
||||
|
||||
protected function toBase64(string $path): string
|
||||
{
|
||||
$ext = $this->extension;
|
||||
$file = Storage::get($path);
|
||||
$data = base64_encode($file);
|
||||
return "data:image/$ext;base64,$data";
|
||||
}
|
||||
|
||||
public function getThumbUrl(): ?string
|
||||
{
|
||||
if (Storage::has("posts/$this->id/thumb"))
|
||||
{
|
||||
return $this->toBase64("posts/$this->id/thumb");
|
||||
}
|
||||
return $this->getPreviewUrl();
|
||||
}
|
||||
|
||||
public function getPreviewUrl(): ?string
|
||||
{
|
||||
if (Storage::has("posts/$this->id/preview"))
|
||||
{
|
||||
return $this->toBase64("posts/$this->id/preview");
|
||||
}
|
||||
return $this->getFullUrl();
|
||||
}
|
||||
|
||||
public function getFullUrl(): ?string
|
||||
{
|
||||
if (Storage::has("posts/$this->id/full"))
|
||||
{
|
||||
return $this->toBase64("posts/$this->id/full");
|
||||
}
|
||||
abort(404);
|
||||
}
|
||||
|
||||
public function getMimeType(): ?string
|
||||
{
|
||||
return Storage::mimeType("posts/$this->id/full");
|
||||
}
|
||||
|
||||
public function getDimensions(): false|array
|
||||
{
|
||||
return getimagesize($this->getFullUrl());
|
||||
}
|
||||
|
||||
public function getAspectRatio(): string
|
||||
{
|
||||
list($width, $height) = $this->getDimensions();
|
||||
$divisor = gmp_intval(gmp_gcd($width, $height));
|
||||
$w = $width / $divisor;
|
||||
$h = $height / $divisor;
|
||||
return "aspect-ratio: $w/$h;";
|
||||
}
|
||||
|
||||
public function download(): StreamedResponse
|
||||
{
|
||||
return Storage::download("posts/$this->id/full");
|
||||
}
|
||||
|
||||
public function getNextPost(): ?Post
|
||||
{
|
||||
return Post::where('created_at', '>', $this->created_at)
|
||||
->orderBy('created_at', 'asc')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function getPreviousPost(): ?Post
|
||||
{
|
||||
return Post::where('created_at', '<', $this->created_at)
|
||||
->orderBy('created_at', 'desc')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function getRatingColor(): string
|
||||
{
|
||||
return match ($this->rating)
|
||||
{
|
||||
'safe' => 'success',
|
||||
'suggestive' => 'warning',
|
||||
'explicit' => 'danger',
|
||||
default => 'default',
|
||||
};
|
||||
}
|
||||
}
|
||||
16
app/Models/Tag.php
Normal file
16
app/Models/Tag.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use MongoDB\Laravel\Eloquent\Model;
|
||||
use MongoDB\Laravel\Relations\BelongsToMany;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
protected $fillable = [ 'name', 'slug', 'implies' ];
|
||||
|
||||
public function posts(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Post::class);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue