218 lines
6.2 KiB
PHP
218 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\User;
|
|
use App\Models\Video;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
public function __construct()
|
|
{
|
|
$this->middleware('auth')->except(['channel']);
|
|
}
|
|
|
|
// Profile page - view own profile
|
|
public function profile()
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return view('user.profile', compact('user'));
|
|
}
|
|
|
|
// Update profile
|
|
public function updateProfile(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
$request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'avatar' => 'nullable|image|mimes:jpg,jpeg,png,webp|max:5120',
|
|
'bio' => 'nullable|string|max:500',
|
|
'website' => 'nullable|string|max:255',
|
|
'twitter' => 'nullable|string|max:100',
|
|
'instagram' => 'nullable|string|max:100',
|
|
'facebook' => 'nullable|string|max:100',
|
|
'youtube' => 'nullable|string|max:100',
|
|
'linkedin' => 'nullable|string|max:100',
|
|
'tiktok' => 'nullable|string|max:100',
|
|
'birthday' => 'nullable|date',
|
|
'location' => 'nullable|string|max:100',
|
|
]);
|
|
|
|
$data = [
|
|
'name' => $request->name,
|
|
'bio' => $request->bio,
|
|
'website' => $request->website,
|
|
'twitter' => $request->twitter,
|
|
'instagram' => $request->instagram,
|
|
'facebook' => $request->facebook,
|
|
'youtube' => $request->youtube,
|
|
'linkedin' => $request->linkedin,
|
|
'tiktok' => $request->tiktok,
|
|
'birthday' => $request->birthday,
|
|
'location' => $request->location,
|
|
];
|
|
|
|
if ($request->hasFile('avatar')) {
|
|
// Delete old avatar
|
|
if ($user->avatar) {
|
|
Storage::delete('public/avatars/'.$user->avatar);
|
|
}
|
|
$filename = Str::uuid().'.'.$request->file('avatar')->getClientOriginalExtension();
|
|
$request->file('avatar')->storeAs('public/avatars', $filename);
|
|
$data['avatar'] = $filename;
|
|
}
|
|
|
|
$user->update($data);
|
|
|
|
return redirect()->route('profile')->with('success', 'Profile updated successfully!');
|
|
}
|
|
|
|
// Settings page
|
|
public function settings()
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return view('user.settings', compact('user'));
|
|
}
|
|
|
|
// Update settings (password)
|
|
public function updateSettings(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
$request->validate([
|
|
'current_password' => 'required',
|
|
'new_password' => 'required|min:8|confirmed',
|
|
]);
|
|
|
|
if (! Hash::check($request->current_password, $user->password)) {
|
|
return back()->withErrors(['current_password' => 'Current password is incorrect']);
|
|
}
|
|
|
|
$user->update([
|
|
'password' => Hash::make($request->new_password),
|
|
]);
|
|
|
|
return redirect()->route('settings')->with('success', 'Password updated successfully!');
|
|
}
|
|
|
|
// User's channel page - view videos
|
|
public function channel($userId = null)
|
|
{
|
|
if ($userId) {
|
|
$user = User::findOrFail($userId);
|
|
} else {
|
|
$user = Auth::user();
|
|
}
|
|
|
|
// If viewing own channel, show all videos including private
|
|
// If viewing someone else's channel, show only public videos
|
|
if (Auth::check() && Auth::user()->id === $user->id) {
|
|
$videos = Video::where('user_id', $user->id)
|
|
->latest()
|
|
->paginate(12);
|
|
|
|
// Also get user's playlists for their own channel
|
|
$playlists = $user->playlists()->orderBy('created_at', 'desc')->get();
|
|
} else {
|
|
$videos = Video::public()
|
|
->where('user_id', $user->id)
|
|
->latest()
|
|
->paginate(12);
|
|
$playlists = null;
|
|
}
|
|
|
|
return view('user.channel', compact('user', 'videos', 'playlists'));
|
|
}
|
|
|
|
// Watch history
|
|
public function history()
|
|
{
|
|
$user = Auth::user();
|
|
|
|
// Get videos the user has watched, ordered by most recently watched
|
|
// Include private videos since they are the user's own
|
|
$videoIds = \DB::table('video_views')
|
|
->where('user_id', $user->id)
|
|
->orderBy('watched_at', 'desc')
|
|
->pluck('video_id')
|
|
->unique();
|
|
|
|
$videos = Video::whereIn('id', $videoIds)
|
|
->where(function ($q) use ($user) {
|
|
$q->where('visibility', '!=', 'private')
|
|
->orWhere('user_id', $user->id);
|
|
})
|
|
->get()
|
|
->sortByDesc(function ($video) use ($videoIds) {
|
|
return $videoIds->search($video->id);
|
|
});
|
|
|
|
return view('user.history', compact('videos'));
|
|
}
|
|
|
|
// Liked videos
|
|
public function liked()
|
|
{
|
|
$user = Auth::user();
|
|
// Include private videos in liked (user's own private videos)
|
|
$videos = $user->likes()
|
|
->where(function ($q) use ($user) {
|
|
$q->where('visibility', '!=', 'private')
|
|
->orWhere('videos.user_id', $user->id);
|
|
})
|
|
->latest()
|
|
->paginate(12);
|
|
|
|
return view('user.liked', compact('videos'));
|
|
}
|
|
|
|
// Like a video
|
|
public function like(Video $video)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
if (! $video->isLikedBy($user)) {
|
|
$video->likes()->attach($user->id);
|
|
}
|
|
|
|
return back();
|
|
}
|
|
|
|
// Unlike a video
|
|
public function unlike(Video $video)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
$video->likes()->detach($user->id);
|
|
|
|
return back();
|
|
}
|
|
|
|
// Toggle like (API)
|
|
public function toggleLike(Video $video)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
if ($video->isLikedBy($user)) {
|
|
$video->likes()->detach($user->id);
|
|
$liked = false;
|
|
} else {
|
|
$video->likes()->attach($user->id);
|
|
$liked = true;
|
|
}
|
|
|
|
return response()->json([
|
|
'liked' => $liked,
|
|
'like_count' => $video->like_count,
|
|
]);
|
|
}
|
|
}
|