feat: Reorganize PromptHero mobile layout with scrollable toolbars and sticky-style buttons
Some checks are pending
CI / build (18.x) (push) Waiting to run
CI / build (20.x) (push) Waiting to run

This commit is contained in:
Khoa Vo 2026-01-07 21:16:34 +07:00
parent 3d8fe9c782
commit d8cb0fb176

View file

@ -538,68 +538,6 @@ export function PromptHero() {
/>
</div>
{/* Controls Area */}
<div className="flex flex-col md:flex-row items-center justify-between gap-3 pt-1">
{/* Left Controls: References */}
{/* For Meta AI: Only Subject is enabled (for video generation), Scene/Style disabled */}
<div className="flex flex-wrap gap-2 w-full md:w-auto">
{((settings.provider === 'meta'
? ['subject']
: ['subject', 'scene', 'style']) as ReferenceCategory[]).map((cat) => {
const refs = references[cat] || [];
const hasRefs = refs.length > 0;
const isUploading = uploadingRefs[cat];
return (
<div key={cat} className="relative group">
<button
onClick={() => toggleReference(cat)}
onDragOver={handleDragOver}
onDrop={(e) => handleDrop(e, cat)}
title={settings.provider === 'meta' && cat === 'subject'
? "Upload image to animate into video"
: undefined}
className={cn(
"flex items-center gap-1.5 rounded-lg px-3 py-2 md:px-3 md:py-1.5 text-xs md:text-[10px] font-medium transition-all border relative overflow-hidden min-h-[44px] md:min-h-0",
hasRefs
? "bg-purple-500/10 text-purple-200 border-purple-500/30 hover:bg-purple-500/20"
: "bg-white/5 text-white/40 border-white/5 hover:bg-white/10 hover:text-white/70 hover:border-white/10",
isUploading && "animate-pulse cursor-wait"
)}
>
{isUploading ? (
<div className="h-3 w-3 animate-spin rounded-full border-2 border-current border-t-transparent" />
) : hasRefs ? (
<div className="flex -space-x-1.5">
{refs.slice(0, 4).map((ref, idx) => (
<img
key={ref.id}
src={ref.thumbnail}
alt=""
className="h-4 w-4 rounded-sm object-cover ring-1 ring-white/20"
style={{ zIndex: 10 - idx }}
/>
))}
</div>
) : (
<Upload className="h-3 w-3" />
)}
<span className="capitalize tracking-wide">{cat}</span>
{refs.length > 0 && (
<span className="text-[9px] bg-purple-500/30 text-purple-100 rounded-full px-1.5 h-3 flex items-center">{refs.length}</span>
)}
</button>
{/* Clear all button */}
{hasRefs && !isUploading && (
<button
className="absolute -top-1 -right-1 p-0.5 rounded-full bg-red-500/80 text-white opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-500"
onClick={(e) => { e.stopPropagation(); clearReferences(cat); }}
title={`Clear all ${cat} references`}
>
<X className="h-2 w-2" />
</button>
)}
</div>
);
})}
@ -634,10 +572,11 @@ export function PromptHero() {
{/* Right Controls: Settings & Generate */ }
<div className="flex flex-wrap items-center gap-2 w-full md:w-auto justify-end">
<div className="flex flex-col md:flex-row items-center gap-3 w-full md:w-auto md:ml-auto">
{/* Settings Group */}
<div className="flex items-center gap-0.5 bg-[#0E0E10] p-1 rounded-lg border border-white/10">
<div className="flex items-center gap-2 w-full md:w-auto overflow-x-auto md:overflow-visible pb-2 md:pb-0 scrollbar-none snap-x">
<div className="flex items-center gap-0.5 bg-[#0E0E10] p-1 rounded-lg border border-white/10 flex-shrink-0 snap-start">
{/* Image Count */}
<button
onClick={settings.provider === 'meta' ? undefined : cycleImageCount}
@ -682,17 +621,18 @@ export function PromptHero() {
<span>Precise</span>
</button>
</div>
</div>
{/* Generate Button */}
<button
onClick={handleGenerate}
disabled={isGenerating || !prompt.trim()}
className={cn(
"relative overflow-hidden px-5 py-2.5 md:px-4 md:py-1.5 rounded-xl md:rounded-lg font-bold text-base md:text-sm text-white shadow-lg transition-all active:scale-95 group border border-white/10 min-h-[44px] md:min-h-0",
"relative overflow-hidden px-5 py-3 md:px-4 md:py-1.5 rounded-xl md:rounded-lg font-bold text-base md:text-sm text-white shadow-lg transition-all active:scale-95 group border border-white/10 w-full md:w-auto min-h-[48px] md:min-h-0 mt-2 md:mt-0 z-30",
"bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-500 hover:to-indigo-500 hover:shadow-indigo-500/25"
)}
>
<div className="relative z-10 flex items-center gap-1.5">
<div className="relative z-10 flex items-center justify-center gap-1.5">
{isGenerating ? (
<>
<div className="h-3 w-3 animate-spin rounded-full border-2 border-white border-t-transparent" />
@ -712,7 +652,8 @@ export function PromptHero() {
</div >
{/* Reference Preview Panel - shows when any references exist */ }
{(references.subject?.length || references.scene?.length || references.style?.length) ? (
{
(references.subject?.length || references.scene?.length || references.style?.length) ? (
<div className="mt-4 p-3 rounded-xl bg-white/5 border border-white/10">
<div className="flex flex-wrap gap-4">
{(['subject', 'scene', 'style'] as ReferenceCategory[]).map((cat) => {
@ -755,7 +696,8 @@ export function PromptHero() {
})}
</div>
</div>
) : null}
) : null
}
</div >
</div >
);