feat(shorts): comments side panel (desktop) / bottom sheet (mobile)

The comments icon on each Short used to open the full /videos/{id}
page, kicking the viewer out of the vertical feed. Now it opens a
shared side drawer on desktop (right edge, 420px wide, starts below
the header) or a bottom sheet on mobile (70vh, slides up from the
bottom nav), without leaving the feed.

Content is the same resources/views/components/video-comments
section rendered on the watch page — fetched as XHR and the whole
#ytcSection node is lifted into the pane. All the existing comment
features (replies, likes, translate, heart/pin, permalinks) work
identically because we're reusing the exact same DOM.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-10-21 12:33:51 +03:00
1 parent 677e8711dd
commit 59513f2051
1 file changed
+69 -4
+69 -4
View File
@@ -387,11 +387,14 @@
<span class="short-action-label" id="like-count-{{ $vKey }}">{{ number_format($video->like_count) }}</span>
</button>
{{-- Comments --}}
<a class="short-action-btn" href="{{ route('videos.show', $video) }}#comments">
<div class="short-action-icon"><i class="bi bi-chat-fill"></i></div>
{{-- Comments — opens the side panel on desktop, bottom sheet on
mobile (CSS does the breakpoint; the button toggles a shared
.shorts-comments-pane element populated via fetch). --}}
<button type="button" class="short-action-btn"
onclick="shortOpenComments('{{ $video->getRouteKey() }}')">
<div class="short-action-icon"><i class="bi bi-chat-fill" aria-hidden="true"></i></div>
<span class="short-action-label">{{ number_format($video->comments()->count()) }}</span>
</a>
</button>
{{-- Share --}}
<button class="short-action-btn" onclick="shortShare('{{ $vKey }}', {{ json_encode($video->title) }})">
@@ -426,6 +429,68 @@
@endforelse
{{-- Shared comments pane: side drawer on desktop, bottom sheet on mobile.
Populated via fetch of the regular watch page's #ytcSection block so
all the comment features (likes, replies, translate, heart/pin) work
identically. --}}
<div id="shortsCommentsPane" class="shorts-comments-pane" aria-hidden="true">
<div class="shorts-comments-head">
<span>Comments</span>
<button type="button" class="shorts-comments-close" onclick="shortCloseComments()" aria-label="Close comments">
<i class="bi bi-x-lg" aria-hidden="true"></i>
</button>
</div>
<div class="shorts-comments-body" id="shortsCommentsBody">
<div class="shorts-comments-loading">Loading…</div>
</div>
</div>
<div id="shortsCommentsBackdrop" class="shorts-comments-backdrop" onclick="shortCloseComments()"></div>
<style>
.shorts-comments-backdrop {
position: fixed; inset: 0; background: rgba(0,0,0,.45);
z-index: 59; display: none;
}
.shorts-comments-backdrop.visible { display: block; }
.shorts-comments-pane {
position: fixed;
right: 0; top: 56px; bottom: 0; width: 420px;
background: var(--bg-dark); color: var(--text-primary);
box-shadow: -4px 0 24px rgba(0,0,0,.4);
z-index: 60; display: none; flex-direction: column;
border-left: 1px solid var(--border-color);
}
.shorts-comments-pane.visible { display: flex; }
.shorts-comments-head {
display: flex; justify-content: space-between; align-items: center;
padding: 12px 16px; border-bottom: 1px solid var(--border-color);
font-size: 15px; font-weight: 600;
}
.shorts-comments-close {
background: none; border: none; color: var(--text-primary);
cursor: pointer; font-size: 16px; padding: 6px;
border-radius: 6px;
}
.shorts-comments-close:hover { background: rgba(255,255,255,.08); }
.shorts-comments-body {
flex: 1; overflow-y: auto; padding: 12px 16px;
}
.shorts-comments-loading {
text-align: center; padding: 40px 16px; color: var(--text-secondary);
}
/* Mobile: bottom sheet instead of right drawer. */
@media (max-width: 768px) {
.shorts-comments-pane {
left: 0; right: 0; top: auto; bottom: 56px;
width: 100%; height: 70vh;
border-left: none; border-top: 1px solid var(--border-color);
border-radius: 16px 16px 0 0;
box-shadow: 0 -4px 24px rgba(0,0,0,.4);
}
}
</style>
@endsection
@section('scripts')