Files
2026-07-14 00:01:48 +03:00

530 lines
24 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('frontend.layouts.app')
@section('title', $user->name . ' — Profil — Animexe')
@section('meta_description', ($user->bio ? $user->bio . ' — ' : '') . $user->name . ' Animexe profili.')
@push('styles')
<style>
.pub-hero{
position:relative;overflow:hidden;background:#05050e;
}
.pub-hero-animated{
background:linear-gradient(135deg,#05050e,#0a0520);
}
.pub-hero-bg{
position:absolute;inset:0;
background:
radial-gradient(ellipse 80% 60% at 20% 50%,rgba(0,245,255,.06),transparent),
radial-gradient(ellipse 60% 80% at 80% 30%,rgba(255,45,125,.05),transparent);
}
.pub-hero-inner{
position:relative;z-index:1;max-width:900px;margin:0 auto;
padding:calc(var(--nav-h) + 36px) 24px 0;
}
.pub-top{display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;margin-bottom:28px}
.pub-top-main{display:flex;align-items:flex-end;gap:20px;flex:1;min-width:0}
.pub-avatar{
width:96px;height:96px;border-radius:24px;flex-shrink:0;
background:linear-gradient(135deg,var(--accent2),var(--accent));
display:flex;align-items:center;justify-content:center;
font-size:2.4rem;font-weight:900;color:#fff;overflow:hidden;
box-shadow:0 0 0 3px rgba(0,245,255,.2),0 16px 48px rgba(0,0,0,.5);
}
.pub-info{flex:1;min-width:0;padding-bottom:4px}
.pub-name{font-size:1.7rem;font-weight:900;color:#fff;line-height:1.1;margin-bottom:4px}
.pub-handle{font-size:.84rem;color:rgba(255,255,255,.35);margin-bottom:10px}
.pub-badges{display:flex;gap:7px;flex-wrap:wrap}
.pbadge{padding:4px 12px;border-radius:20px;font-size:.7rem;font-weight:700;letter-spacing:.05em;display:inline-flex;align-items:center;gap:5px}
.pbadge-admin{background:rgba(255,45,125,.15);border:1px solid rgba(255,45,125,.35);color:var(--accent)}
.pbadge-premium{background:rgba(255,208,0,.12);border:1px solid rgba(255,208,0,.3);color:#ffd700}
.pbadge-member{background:rgba(0,245,255,.07);border:1px solid rgba(0,245,255,.2);color:var(--accent2)}
.pub-stats{
display:flex;gap:6px;flex-wrap:wrap;
padding:20px 0 0;border-top:1px solid rgba(255,255,255,.06);margin-top:8px;
}
.pub-stat{
display:flex;flex-direction:column;align-items:center;
padding:10px 20px;border-radius:12px;
background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);
min-width:80px;flex:1;
}
.pub-stat .v{font-size:1.25rem;font-weight:800;color:#fff;line-height:1}
.pub-stat .l{font-size:.62rem;text-transform:uppercase;letter-spacing:.1em;color:rgba(255,255,255,.35);margin-top:4px;font-weight:600}
.pub-actions{display:flex;gap:8px;flex-wrap:wrap;align-self:flex-start;flex-shrink:0}
.pub-btn{
padding:8px 16px;border-radius:10px;font-size:.82rem;font-weight:700;
display:inline-flex;align-items:center;gap:7px;cursor:pointer;
border:none;font-family:inherit;transition:all .2s;text-decoration:none;white-space:nowrap;
}
.pub-btn-follow{background:var(--accent2);color:#05050e}
.pub-btn-follow:hover{background:#00d4de}
.pub-btn-follow.following{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.15);color:rgba(255,255,255,.6)}
.pub-btn-follow.following:hover{background:rgba(255,80,80,.12);border-color:rgba(255,80,80,.3);color:#ff5050}
.pub-btn-msg{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);color:rgba(255,255,255,.6)}
.pub-btn-msg:hover{background:rgba(255,255,255,.12);color:#fff}
.pub-btn-edit{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);color:rgba(255,255,255,.6)}
.pub-btn-edit:hover{background:rgba(255,255,255,.12);color:#fff}
.pub-compat{
display:flex;align-items:center;gap:10px;
background:rgba(0,245,255,.06);border:1px solid rgba(0,245,255,.15);
border-radius:12px;padding:10px 16px;margin-top:14px;
}
.pub-compat-bar{flex:1;height:6px;background:rgba(255,255,255,.08);border-radius:3px;overflow:hidden}
.pub-compat-fill{height:100%;background:linear-gradient(90deg,var(--accent2),var(--accent));border-radius:3px;transition:width .8s ease}
.pub-compat-label{font-size:.75rem;color:var(--accent2);font-weight:700;white-space:nowrap}
.pub-tabs{
display:flex;gap:2px;border-top:1px solid rgba(255,255,255,.06);
margin-top:20px;overflow-x:auto;scrollbar-width:none;
}
.pub-tabs::-webkit-scrollbar{display:none}
.pub-tab{
padding:12px 18px;background:none;border:none;
border-bottom:2px solid transparent;
color:rgba(255,255,255,.35);font-size:.82rem;font-weight:600;
cursor:pointer;font-family:inherit;transition:all .15s;
white-space:nowrap;flex-shrink:0;display:flex;align-items:center;gap:6px;
margin-bottom:-1px;
}
.pub-tab:hover{color:rgba(255,255,255,.65)}
.pub-tab.on{color:var(--accent2);border-bottom-color:var(--accent2)}
.pub-body{max-width:900px;margin:0 auto;padding:32px 24px 64px}
.pub-pane{display:none}
.pub-pane.on{display:block}
.pub-sec-h{
font-size:.68rem;text-transform:uppercase;letter-spacing:.12em;
color:rgba(255,255,255,.3);font-weight:700;
margin-bottom:16px;display:flex;align-items:center;gap:8px;
}
.pub-sec-h::before{content:'';width:3px;height:14px;background:linear-gradient(180deg,var(--accent2),var(--accent));border-radius:2px}
.pub-wl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px}
.pub-wl-card{
border-radius:9px;overflow:hidden;text-decoration:none;display:block;
background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);
transition:transform .15s,border-color .15s;
}
.pub-wl-card:hover{transform:translateY(-2px);border-color:rgba(255,255,255,.18)}
.pub-wl-card img{width:100%;aspect-ratio:2/3;object-fit:cover;display:block}
.pub-wl-card-ph{aspect-ratio:2/3;background:rgba(255,255,255,.04);display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,.2)}
.pub-wl-card-title{padding:7px 8px;font-size:.72rem;font-weight:600;color:rgba(255,255,255,.7);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pub-ach-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px}
.pub-ach-card{
display:flex;align-items:center;gap:14px;
background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.07);
border-radius:12px;padding:14px 16px;
}
.pub-ach-icon{width:44px;height:44px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:1.4rem;flex-shrink:0}
.pub-ach-title{font-size:.85rem;font-weight:700;color:#fff;margin-bottom:2px}
.pub-ach-desc{font-size:.72rem;color:rgba(255,255,255,.35);line-height:1.4}
.pub-comment-card{
background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.07);
border-radius:12px;padding:14px 16px;margin-bottom:10px;
}
.pub-cm-top{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.pub-cm-anime{font-size:.78rem;font-weight:600;color:var(--accent2);text-decoration:none}
.pub-cm-anime:hover{text-decoration:underline}
.pub-cm-time{font-size:.7rem;color:rgba(255,255,255,.25);margin-left:auto}
.pub-cm-text{font-size:.87rem;color:rgba(255,255,255,.6);line-height:1.6}
.pub-empty{text-align:center;padding:48px 20px;color:rgba(255,255,255,.2);font-size:.9rem}
.pub-empty i{font-size:2.5rem;display:block;margin-bottom:12px;opacity:.25}
@media(max-width:600px){
.pub-hero-inner{padding:calc(var(--nav-h) + 16px) 16px 0}
.pub-body{padding:24px 16px 48px}
.pub-avatar{width:72px;height:72px;border-radius:18px;font-size:1.8rem}
.pub-name{font-size:1.3rem}
.pub-top{flex-direction:column;gap:14px}
.pub-ach-grid{grid-template-columns:1fr}
}
</style>
@endpush
@section('content')
@php
$pColor = $user->profile_color ?? '#00f5ff';
$profBg = ($user->profile_bg && $user->hasPerk('profile_bg')) ? $user->profile_bg : null;
$animBanner = $user->hasPerk('animated_banner') && $user->animated_banner;
$watchRank = $user->watchRank();
$musicUrl = ($user->profile_music_url && $user->hasPerk('profile_music')) ? $user->profile_music_url : null;
@endphp
<div class="pub-hero {{ $profBg ? 'profile-bg-'.$profBg : '' }} {{ $animBanner ? 'pub-hero-animated' : '' }}" style="--pr-color:{{ $pColor }}">
@if($animBanner)
<canvas id="banner-canvas" style="position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0"></canvas>
@endif
@if($user->banner_image)
<div style="position:absolute;inset:0;overflow:hidden;z-index:0">
<img src="{{ \App\Support\MediaUrl::fromStoragePath($user->banner_image) }}" alt=""
style="width:100%;height:100%;object-fit:cover;opacity:.35;filter:blur(1px)">
<div style="position:absolute;inset:0;background:linear-gradient(to bottom,rgba(5,5,14,.3) 0%,rgba(5,5,14,.85) 100%)"></div>
</div>
@else
<div class="pub-hero-bg" style="background:radial-gradient(ellipse 80% 60% at 20% 50%,{{ $pColor }}18,transparent),radial-gradient(ellipse 60% 80% at 80% 30%,{{ $pColor }}10,transparent)"></div>
@endif
<div class="pub-hero-inner">
<div class="pub-top">
<div class="pub-top-main">
@php
$hasFrame = $user->profile_frame && $user->hasPerk('profile_frame');
$avatarSrc = $user->gif_avatar && $user->hasPerk('gif_avatar')
? $user->gif_avatar
: ($user->avatar ? \App\Support\MediaUrl::fromStoragePath($user->avatar) : null);
@endphp
<div class="{{ $hasFrame ? 'avatar-wrap' : '' }}" style="{{ $hasFrame ? 'width:96px;height:96px' : '' }}">
@if($hasFrame)
<div class="avatar-frame frame-{{ $user->profile_frame }}"></div>
@endif
<div class="pub-avatar" style="{{ $hasFrame ? 'border-radius:50%;position:relative;z-index:3' : 'background:linear-gradient(135deg,'.$pColor.','.$pColor.'88);box-shadow:0 0 0 3px '.$pColor.'33,0 16px 48px rgba(0,0,0,.5)' }}">
@if($avatarSrc)
<img src="{{ $avatarSrc }}" alt="{{ $user->name }}"
style="width:100%;height:100%;object-fit:cover;border-radius:inherit">
@else
{{ mb_strtoupper(mb_substr($user->name,0,1)) }}
@endif
</div>
</div>
<div class="pub-info">
@php
$unColor = $user->username_color && $user->hasPerk('username_color') ? 'username-color-'.$user->username_color : '';
$unEffect = $user->username_effect && $user->hasPerk('username_effect') ? 'username-effect-'.$user->username_effect : '';
@endphp
<div class="pub-name {{ $unColor }} {{ $unEffect }}"
@if($user->username_effect==='glitch' && $unEffect) data-text="{{ $user->name }}" @endif>{{ $user->name }}</div>
@if($user->username)
<div class="pub-handle">@php echo '@' . e($user->username); @endphp</div>
@endif
@if($user->bio)
<div style="font-size:.83rem;color:rgba(255,255,255,.55);margin-bottom:10px;max-width:500px;line-height:1.5">{{ $user->bio }}</div>
@endif
<div class="pub-badges">
@if($user->role==='admin')
<span class="pbadge pbadge-admin"><i class="bi bi-shield-fill"></i> Admin</span>
@elseif($user->role==='moderator')
<span class="pbadge pbadge-admin"><i class="bi bi-shield-half"></i> Moderatör</span>
@endif
@if($user->isPremium())
<span class="pbadge pbadge-premium"><i class="bi bi-star-fill"></i> Premium</span>
@else
<span class="pbadge pbadge-member"><i class="bi bi-person-check"></i> Üye</span>
@endif
@if($user->profile_badge && $user->hasPerk('profile_badge'))
<span class="premium-badge user-badge-custom">{{ $user->profile_badge }}</span>
@endif
@if($watchRank)
<span class="pbadge" style="background:rgba(255,255,255,.06);border:1px solid {{ $watchRank['color'] }}44;color:{{ $watchRank['color'] }}">
<i class="bi {{ $watchRank['icon'] }}"></i> {{ $watchRank['label'] }}
</span>
@endif
<span class="pbadge" style="background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);color:rgba(255,255,255,.35)"><i class="bi bi-calendar3"></i> {{ $user->created_at->format('Y') }}'den beri</span>
</div>
</div>
</div>
<div class="pub-actions">
@if($isOwnProfile)
<a href="{{ route('profile.settings') }}" class="pub-btn pub-btn-edit">
<i class="bi bi-pencil-square"></i> Profili Düzenle
</a>
@elseif(auth()->check())
<button id="follow-btn" onclick="toggleFollow()"
class="pub-btn pub-btn-follow {{ $isFollowing ? 'following' : '' }}"
data-following="{{ $isFollowing ? '1' : '0' }}">
<i class="bi {{ $isFollowing ? 'bi-person-check-fill' : 'bi-person-plus' }}" id="follow-icon"></i>
<span id="follow-label">{{ $isFollowing ? 'Takip Ediliyor' : 'Takip Et' }}</span>
</button>
<form method="POST" action="{{ route('messages.start', $user) }}">
@csrf
<button type="submit" class="pub-btn pub-btn-msg">
<i class="bi bi-chat-dots"></i> Mesaj
</button>
</form>
@endif
</div>
</div>
@if($compatibility !== null)
<div class="pub-compat">
<i class="bi bi-heart-pulse" style="color:var(--accent2);font-size:1rem;flex-shrink:0"></i>
<div style="flex:1;min-width:0">
<div style="font-size:.72rem;color:rgba(255,255,255,.4);margin-bottom:5px">Anime zevk uyumu</div>
<div class="pub-compat-bar"><div class="pub-compat-fill" id="compat-fill" style="width:0%"></div></div>
</div>
<span class="pub-compat-label" id="compat-pct">%{{ $compatibility }}</span>
</div>
@endif
<div class="pub-stats">
<div class="pub-stat"><span class="v">{{ $watchStats['episodes'] }}</span><span class="l">Bölüm</span></div>
<div class="pub-stat"><span class="v">{{ $watchStats['hours'] }}</span><span class="l">Saat</span></div>
<div class="pub-stat"><span class="v" id="follower-count">{{ $followerCount }}</span><span class="l">Takipçi</span></div>
<div class="pub-stat"><span class="v">{{ $followingCount }}</span><span class="l">Takip</span></div>
<div class="pub-stat"><span class="v">{{ $commentCount }}</span><span class="l">Yorum</span></div>
</div>
<div class="pub-tabs">
<button class="pub-tab on" onclick="switchTab('watchlist',this)"><i class="bi bi-bookmark"></i> İzleme Listesi</button>
<button class="pub-tab" onclick="switchTab('achievements',this)"><i class="bi bi-trophy"></i> Başarımlar</button>
<button class="pub-tab" onclick="switchTab('comments',this)"><i class="bi bi-chat-dots"></i> Yorumlar</button>
</div>
</div>
</div>
@if($musicUrl)
<div id="profile-music-bar" style="
position:fixed;bottom:0;left:0;right:0;z-index:900;
background:rgba(5,5,14,.92);backdrop-filter:blur(12px);
border-top:1px solid rgba(0,245,255,.15);
display:flex;align-items:center;gap:12px;padding:10px 20px;
font-size:.82rem;
">
<button id="music-toggle" onclick="toggleMusic()" style="
background:rgba(0,245,255,.12);border:1px solid rgba(0,245,255,.3);color:#00f5ff;
border-radius:50%;width:36px;height:36px;display:flex;align-items:center;justify-content:center;
cursor:pointer;flex-shrink:0;font-size:1rem;
"><i class="bi bi-play-fill" id="music-icon"></i></button>
<div style="flex:1;min-width:0">
<div style="color:rgba(255,255,255,.5);font-size:.7rem;margin-bottom:2px">{{ $user->name }} · Profil Müziği</div>
<div id="music-progress-bar" style="width:100%;height:3px;background:rgba(255,255,255,.1);border-radius:2px;overflow:hidden">
<div id="music-progress-fill" style="width:0%;height:100%;background:linear-gradient(90deg,#00f5ff,#b84dff);transition:width .5s linear;border-radius:2px"></div>
</div>
</div>
<button onclick="document.getElementById('profile-music-bar').remove()" style="
background:none;border:none;color:rgba(255,255,255,.3);cursor:pointer;font-size:1.1rem;padding:4px;
"><i class="bi bi-x"></i></button>
<audio id="profile-audio" src="" preload="none"></audio>
</div>
@endif
<div class="pub-body">
{{-- İzleme Listesi --}}
<div class="pub-pane on" id="pane-watchlist">
@php $watching = $watchlistItems->get('watching',[]);
$completed = $watchlistItems->get('completed',[]);
$planToWatch = $watchlistItems->get('plan_to_watch',[]); @endphp
@if($watchlistItems->isEmpty())
<div class="pub-empty"><i class="bi bi-bookmark"></i> Henüz izleme listesi yok.</div>
@else
@foreach(['watching'=>'İzliyor','completed'=>'Tamamladı','plan_to_watch'=>'İzleyecek'] as $status => $label)
@php $items = $watchlistItems->get($status, collect()); @endphp
@if($items->count())
<div class="pub-sec-h">{{ $label }} <span style="color:rgba(255,255,255,.2)">({{ $items->count() }})</span></div>
<div class="pub-wl-grid" style="margin-bottom:28px">
@foreach($items->take(12) as $wl)
@if($wl->anime)
<a href="{{ $wl->anime->detailUrl }}" class="pub-wl-card">
@if($wl->anime->cover_image)
<img src="{{ \App\Support\MediaUrl::fromStoragePath($wl->anime->cover_image) }}" alt="{{ $wl->anime->title }}" loading="lazy">
@else
<div class="pub-wl-card-ph"><i class="bi bi-image"></i></div>
@endif
<div class="pub-wl-card-title">{{ $wl->anime->title }}</div>
</a>
@endif
@endforeach
</div>
@endif
@endforeach
@endif
</div>
{{-- Başarımlar --}}
<div class="pub-pane" id="pane-achievements">
@if($achievements->isEmpty())
<div class="pub-empty"><i class="bi bi-trophy"></i> Henüz başarım kazanılmamış.</div>
@else
<div class="pub-ach-grid">
@foreach($achievements as $ua)
<div class="pub-ach-card">
<div class="pub-ach-icon" style="background:{{ substr($ua->achievement->color ?? '#ffffff',0,7) }}22">
<i class="bi {{ $ua->achievement->icon ?? 'bi-trophy' }}" style="color:{{ $ua->achievement->color ?? '#ffffff' }}"></i>
</div>
<div>
<div class="pub-ach-title">{{ $ua->achievement->name }}</div>
<div class="pub-ach-desc">{{ $ua->achievement->description }}</div>
</div>
</div>
@endforeach
</div>
@endif
</div>
{{-- Yorumlar --}}
<div class="pub-pane" id="pane-comments">
@if($recentComments->isEmpty())
<div class="pub-empty"><i class="bi bi-chat-dots"></i> Henüz yorum yok.</div>
@else
@foreach($recentComments as $c)
@php $ep = $c->episode; $anime = $ep?->anime ?? $c->anime; @endphp
<div class="pub-comment-card">
<div class="pub-cm-top">
@if($anime)
<a href="{{ $anime->detailUrl }}" class="pub-cm-anime"><i class="bi bi-play-circle"></i> {{ $anime->title }}</a>
@endif
<span class="pub-cm-time">{{ $c->created_at->diffForHumans() }}</span>
</div>
<div class="pub-cm-text">{{ Str::limit($c->content, 200) }}</div>
</div>
@endforeach
@endif
</div>
</div>
@endsection
@push('scripts')
<script>
function switchTab(name, btn) {
document.querySelectorAll('.pub-pane').forEach(p => p.classList.remove('on'));
document.querySelectorAll('.pub-tab').forEach(t => t.classList.remove('on'));
document.getElementById('pane-' + name).classList.add('on');
btn.classList.add('on');
}
// Uyum barı animasyonu
document.addEventListener('DOMContentLoaded', () => {
const fill = document.getElementById('compat-fill');
if (fill) setTimeout(() => fill.style.width = '{{ $compatibility ?? 0 }}%', 300);
});
// ── Animasyonlu Banner ────────────────────────────────────────────────────
@if($animBanner)
(function(){
const canvas = document.getElementById('banner-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const color = '{{ $pColor }}';
let W, H, particles = [];
function resize(){
W = canvas.width = canvas.offsetWidth;
H = canvas.height = canvas.offsetHeight;
}
resize();
window.addEventListener('resize', resize);
for (let i = 0; i < 55; i++) {
particles.push({
x: Math.random()*1000, y: Math.random()*300,
r: Math.random()*2+.5, vx: (Math.random()-.5)*.4,
vy: (Math.random()-.5)*.4, a: Math.random()*.6+.1
});
}
function hex2rgb(h){ const r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16); return `${r},${g},${b}`; }
const rgb = hex2rgb(color.length===7 ? color : '#00f5ff');
function draw(){
ctx.clearRect(0,0,W,H);
particles.forEach(p => {
p.x += p.vx; p.y += p.vy;
if (p.x<0) p.x=W; if (p.x>W) p.x=0;
if (p.y<0) p.y=H; if (p.y>H) p.y=0;
ctx.beginPath();
ctx.arc(p.x,p.y,p.r,0,Math.PI*2);
ctx.fillStyle = `rgba(${rgb},${p.a})`;
ctx.fill();
});
// connecting lines
particles.forEach((a,i) => {
particles.slice(i+1).forEach(b => {
const d = Math.hypot(a.x-b.x,a.y-b.y);
if (d < 90) {
ctx.beginPath();
ctx.moveTo(a.x,a.y); ctx.lineTo(b.x,b.y);
ctx.strokeStyle = `rgba(${rgb},${(1-d/90)*.12})`;
ctx.lineWidth = .6;
ctx.stroke();
}
});
});
requestAnimationFrame(draw);
}
draw();
})();
@endif
// ── Profil Müziği ─────────────────────────────────────────────────────────
@if($musicUrl)
(function(){
const audio = document.getElementById('profile-audio');
const icon = document.getElementById('music-icon');
const fill = document.getElementById('music-progress-fill');
if (!audio) return;
const src = {{ json_encode($musicUrl) }};
// YouTube/SoundCloud embedding via iframe is complex; for direct audio URLs autoplay
if (src.match(/\.(mp3|ogg|wav|m4a|aac|flac)(\?|$)/i)) {
audio.src = src;
audio.volume = 0.5;
} else {
// Not a direct audio file — show the bar with a link instead
const bar = document.getElementById('profile-music-bar');
if (bar) {
const btn = document.getElementById('music-toggle');
btn.innerHTML = '<i class="bi bi-box-arrow-up-right"></i>';
btn.onclick = () => window.open(src, '_blank');
fill.style.width = '100%';
}
return;
}
audio.addEventListener('timeupdate', () => {
if (audio.duration) fill.style.width = (audio.currentTime/audio.duration*100)+'%';
});
audio.addEventListener('ended', () => {
icon.className = 'bi bi-play-fill';
fill.style.width = '0%';
});
window.toggleMusic = function(){
if (audio.paused) { audio.play(); icon.className = 'bi bi-pause-fill'; }
else { audio.pause(); icon.className = 'bi bi-play-fill'; }
};
})();
@else
window.toggleMusic = function(){};
@endif
// Takip toggle
const FOLLOW_URL = '{{ route("user.follow", $user) }}';
const CSRF = document.querySelector('meta[name=csrf-token]')?.content || '';
async function toggleFollow() {
const btn = document.getElementById('follow-btn');
if (!btn || btn.disabled) return;
btn.disabled = true;
try {
const res = await fetch(FOLLOW_URL, {
method: 'POST',
headers: { 'X-CSRF-TOKEN': CSRF, 'Accept': 'application/json' }
});
const d = await res.json();
const icon = document.getElementById('follow-icon');
const label = document.getElementById('follow-label');
const cnt = document.getElementById('follower-count');
if (d.following) {
btn.classList.add('following');
icon.className = 'bi bi-person-check-fill';
label.textContent = 'Takip Ediliyor';
} else {
btn.classList.remove('following');
icon.className = 'bi bi-person-plus';
label.textContent = 'Takip Et';
}
if (cnt) cnt.textContent = d.followers_count;
} catch(e) {}
btn.disabled = false;
}
</script>
@endpush