Skip to content

Commit c822f09

Browse files
committed
feat: optimize mobile responsive layout
1 parent 8f35ed8 commit c822f09

2 files changed

Lines changed: 74 additions & 48 deletions

File tree

src/index.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,14 @@ textarea::-webkit-scrollbar-thumb {
4343
background: rgba(99, 102, 241, 0.2);
4444
border-radius: 3px;
4545
}
46+
47+
@media (max-width: 768px) {
48+
html, body {
49+
overflow-x: hidden;
50+
}
51+
52+
::-webkit-scrollbar {
53+
width: 4px;
54+
height: 4px;
55+
}
56+
}

src/pages/Home.tsx

Lines changed: 63 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useCallback } from 'react'
1+
import { useState, useCallback, useEffect } from 'react'
22
import type { MusicStyle, MusicResult, ParseResult } from '../core/index'
33
import { parseCode, mapCodeToMusic } from '../core/index'
44
import Visualizer from '../components/Visualizer'
@@ -216,7 +216,19 @@ const STYLES: { value: MusicStyle; label: string; emoji: string }[] = [
216216
{ value: 'lofi', label: 'Lo-Fi', emoji: '☕' },
217217
]
218218

219+
function useIsMobile() {
220+
const [isMobile, setIsMobile] = useState(false)
221+
useEffect(() => {
222+
const check = () => setIsMobile(window.innerWidth < 768)
223+
check()
224+
window.addEventListener('resize', check)
225+
return () => window.removeEventListener('resize', check)
226+
}, [])
227+
return isMobile
228+
}
229+
219230
export default function Home() {
231+
const isMobile = useIsMobile()
220232
const [code, setCode] = useState(SAMPLE_CODES.python)
221233
const [language, setLanguage] = useState('python')
222234
const [style, setStyle] = useState<MusicStyle>('piano')
@@ -357,7 +369,7 @@ export default function Home() {
357369
}}>
358370
{/* Header */}
359371
<header style={{
360-
padding: '16px 24px',
372+
padding: isMobile ? '12px 16px' : '16px 24px',
361373
display: 'flex',
362374
alignItems: 'center',
363375
justifyContent: 'space-between',
@@ -367,36 +379,38 @@ export default function Home() {
367379
position: 'sticky',
368380
top: 0,
369381
zIndex: 100,
382+
flexWrap: isMobile ? 'wrap' : 'nowrap',
383+
gap: 8,
370384
}}>
371-
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
372-
<span style={{ fontSize: 28 }}>🎵</span>
385+
<div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? 8 : 12 }}>
386+
<span style={{ fontSize: isMobile ? 22 : 28 }}>🎵</span>
373387
<div>
374388
<h1 style={{
375389
margin: 0,
376-
fontSize: 22,
390+
fontSize: isMobile ? 18 : 22,
377391
fontWeight: 700,
378392
background: 'linear-gradient(135deg, #6366f1, #ec4899)',
379393
WebkitBackgroundClip: 'text',
380394
WebkitTextFillColor: 'transparent',
381395
}}>
382396
CodeBeats
383397
</h1>
384-
<p style={{ margin: 0, fontSize: 12, color: '#94a3b8' }}>Hear what your code sounds like</p>
398+
<p style={{ margin: 0, fontSize: isMobile ? 10 : 12, color: '#94a3b8' }}>Hear what your code sounds like</p>
385399
</div>
386400
</div>
387-
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
401+
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
388402
{['python', 'javascript', 'rust', 'c'].map(lang => (
389403
<button
390404
key={lang}
391405
onClick={() => handleSampleCode(lang)}
392406
style={{
393-
padding: '6px 14px',
407+
padding: isMobile ? '4px 10px' : '6px 14px',
394408
border: language === lang ? '1px solid #6366f1' : '1px solid rgba(99, 102, 241, 0.3)',
395409
borderRadius: 20,
396410
background: language === lang ? 'rgba(99, 102, 241, 0.2)' : 'transparent',
397411
color: language === lang ? '#a5b4fc' : '#94a3b8',
398412
cursor: 'pointer',
399-
fontSize: 13,
413+
fontSize: isMobile ? 11 : 13,
400414
fontFamily: 'monospace',
401415
transition: 'all 0.2s',
402416
}}
@@ -409,15 +423,15 @@ export default function Home() {
409423

410424
<div style={{
411425
display: 'grid',
412-
gridTemplateColumns: '1fr 1fr',
413-
gap: 16,
414-
padding: 16,
426+
gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr',
427+
gap: isMobile ? 10 : 16,
428+
padding: isMobile ? 10 : 16,
415429
maxWidth: 1400,
416430
margin: '0 auto',
417-
minHeight: 'calc(100vh - 70px)',
431+
minHeight: isMobile ? 'auto' : 'calc(100vh - 70px)',
418432
}}>
419433
{/* Left: Code Editor */}
420-
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, maxHeight: 'calc(100vh - 100px)', overflow: 'hidden' }}>
434+
<div style={{ display: 'flex', flexDirection: 'column', gap: isMobile ? 8 : 12, maxHeight: isMobile ? 'none' : 'calc(100vh - 100px)', overflow: 'hidden' }}>
421435
<div style={{
422436
background: 'rgba(15, 15, 35, 0.8)',
423437
borderRadius: 12,
@@ -454,13 +468,13 @@ export default function Home() {
454468
border: 'none',
455469
color: '#e2e8f0',
456470
fontFamily: '"Fira Code", "Cascadia Code", "JetBrains Mono", monospace',
457-
fontSize: 13,
471+
fontSize: isMobile ? 11 : 13,
458472
lineHeight: 1.6,
459-
padding: 16,
473+
padding: isMobile ? 10 : 16,
460474
resize: 'none',
461475
outline: 'none',
462476
tabSize: 2,
463-
maxHeight: '50vh',
477+
maxHeight: isMobile ? '35vh' : '50vh',
464478
overflowY: 'auto',
465479
}}
466480
/>
@@ -471,24 +485,24 @@ export default function Home() {
471485
background: 'rgba(15, 15, 35, 0.8)',
472486
borderRadius: 12,
473487
border: '1px solid rgba(99, 102, 241, 0.15)',
474-
padding: 12,
488+
padding: isMobile ? 8 : 12,
475489
}}>
476-
<div style={{ fontSize: 12, color: '#94a3b8', marginBottom: 8, fontWeight: 600 }}>
490+
<div style={{ fontSize: 11, color: '#94a3b8', marginBottom: 6, fontWeight: 600 }}>
477491
MUSIC STYLE
478492
</div>
479-
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
493+
<div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
480494
{STYLES.map(s => (
481495
<button
482496
key={s.value}
483497
onClick={() => handleStyleChange(s.value)}
484498
style={{
485-
padding: '6px 12px',
499+
padding: isMobile ? '4px 8px' : '6px 12px',
486500
border: style === s.value ? '1px solid #6366f1' : '1px solid rgba(99, 102, 241, 0.2)',
487501
borderRadius: 8,
488502
background: style === s.value ? 'rgba(99, 102, 241, 0.2)' : 'rgba(255,255,255,0.03)',
489503
color: style === s.value ? '#a5b4fc' : '#94a3b8',
490504
cursor: 'pointer',
491-
fontSize: 12,
505+
fontSize: isMobile ? 10 : 12,
492506
transition: 'all 0.2s',
493507
}}
494508
>
@@ -503,26 +517,27 @@ export default function Home() {
503517
background: 'rgba(15, 15, 35, 0.8)',
504518
borderRadius: 12,
505519
border: '1px solid rgba(99, 102, 241, 0.15)',
506-
padding: 16,
520+
padding: isMobile ? 10 : 16,
507521
display: 'flex',
508522
alignItems: 'center',
509-
gap: 12,
523+
gap: isMobile ? 8 : 12,
524+
flexWrap: isMobile ? 'wrap' : 'nowrap',
510525
}}>
511526
<button
512527
onClick={handlePlay}
513528
style={{
514-
padding: '10px 24px',
529+
padding: isMobile ? '8px 18px' : '10px 24px',
515530
border: 'none',
516531
borderRadius: 8,
517532
background: isPlaying
518533
? 'linear-gradient(135deg, #ef4444, #dc2626)'
519534
: 'linear-gradient(135deg, #6366f1, #8b5cf6)',
520535
color: 'white',
521536
cursor: 'pointer',
522-
fontSize: 14,
537+
fontSize: isMobile ? 13 : 14,
523538
fontWeight: 600,
524539
transition: 'all 0.2s',
525-
minWidth: 100,
540+
minWidth: isMobile ? 80 : 100,
526541
}}
527542
>
528543
{isPlaying ? '⏹ Stop' : '▶ Play'}
@@ -531,21 +546,21 @@ export default function Home() {
531546
<button
532547
onClick={handleAnalyze}
533548
style={{
534-
padding: '10px 20px',
549+
padding: isMobile ? '8px 14px' : '10px 20px',
535550
border: '1px solid rgba(99, 102, 241, 0.3)',
536551
borderRadius: 8,
537552
background: 'rgba(99, 102, 241, 0.1)',
538553
color: '#a5b4fc',
539554
cursor: 'pointer',
540-
fontSize: 14,
555+
fontSize: isMobile ? 12 : 14,
541556
transition: 'all 0.2s',
542557
}}
543558
>
544559
🔍 Analyze
545560
</button>
546561

547-
<div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8 }}>
548-
<span style={{ fontSize: 16 }}>🔊</span>
562+
<div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8, minWidth: isMobile ? '100%' : 'auto' }}>
563+
<span style={{ fontSize: 14 }}>🔊</span>
549564
<input
550565
type="range"
551566
min="0"
@@ -561,13 +576,13 @@ export default function Home() {
561576
<button
562577
onClick={handleShare}
563578
style={{
564-
padding: '10px 16px',
579+
padding: isMobile ? '8px 12px' : '10px 16px',
565580
border: '1px solid rgba(99, 102, 241, 0.3)',
566581
borderRadius: 8,
567582
background: 'rgba(99, 102, 241, 0.1)',
568583
color: '#a5b4fc',
569584
cursor: 'pointer',
570-
fontSize: 14,
585+
fontSize: isMobile ? 12 : 14,
571586
}}
572587
>
573588
📤 Share
@@ -577,15 +592,15 @@ export default function Home() {
577592
</div>
578593

579594
{/* Right: Visualizer + Info */}
580-
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
595+
<div style={{ display: 'flex', flexDirection: 'column', gap: isMobile ? 8 : 12 }}>
581596
{/* Visualizer */}
582597
<div style={{
583598
background: 'rgba(15, 15, 35, 0.8)',
584599
borderRadius: 12,
585600
border: '1px solid rgba(99, 102, 241, 0.15)',
586601
overflow: 'hidden',
587602
flex: 1,
588-
minHeight: 300,
603+
minHeight: isMobile ? 200 : 300,
589604
}}>
590605
<Visualizer
591606
music={music}
@@ -601,15 +616,15 @@ export default function Home() {
601616
background: 'rgba(15, 15, 35, 0.8)',
602617
borderRadius: 12,
603618
border: '1px solid rgba(99, 102, 241, 0.15)',
604-
padding: 16,
619+
padding: isMobile ? 10 : 16,
605620
}}>
606-
<div style={{ fontSize: 12, color: '#94a3b8', marginBottom: 10, fontWeight: 600 }}>
621+
<div style={{ fontSize: 11, color: '#94a3b8', marginBottom: 8, fontWeight: 600 }}>
607622
CODE ANALYSIS
608623
</div>
609624
<div style={{
610625
display: 'grid',
611-
gridTemplateColumns: 'repeat(4, 1fr)',
612-
gap: 8,
626+
gridTemplateColumns: isMobile ? 'repeat(4, 1fr)' : 'repeat(4, 1fr)',
627+
gap: isMobile ? 4 : 8,
613628
}}>
614629
{[
615630
{ label: 'Functions', value: parseResult.stats.functions, emoji: '🎵' },
@@ -624,12 +639,12 @@ export default function Home() {
624639
<div key={stat.label} style={{
625640
background: 'rgba(99, 102, 241, 0.08)',
626641
borderRadius: 8,
627-
padding: '8px 10px',
642+
padding: isMobile ? '6px 4px' : '8px 10px',
628643
textAlign: 'center',
629644
}}>
630-
<div style={{ fontSize: 18 }}>{stat.emoji}</div>
631-
<div style={{ fontSize: 18, fontWeight: 700, color: '#e2e8f0' }}>{stat.value}</div>
632-
<div style={{ fontSize: 10, color: '#94a3b8' }}>{stat.label}</div>
645+
<div style={{ fontSize: isMobile ? 14 : 18 }}>{stat.emoji}</div>
646+
<div style={{ fontSize: isMobile ? 14 : 18, fontWeight: 700, color: '#e2e8f0' }}>{stat.value}</div>
647+
<div style={{ fontSize: isMobile ? 8 : 10, color: '#94a3b8' }}>{stat.label}</div>
633648
</div>
634649
))}
635650
</div>
@@ -642,12 +657,12 @@ export default function Home() {
642657
background: 'rgba(15, 15, 35, 0.8)',
643658
borderRadius: 12,
644659
border: '1px solid rgba(99, 102, 241, 0.15)',
645-
padding: 16,
660+
padding: isMobile ? 10 : 16,
646661
}}>
647-
<div style={{ fontSize: 12, color: '#94a3b8', marginBottom: 10, fontWeight: 600 }}>
662+
<div style={{ fontSize: 11, color: '#94a3b8', marginBottom: 8, fontWeight: 600 }}>
648663
MUSIC INFO
649664
</div>
650-
<div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
665+
<div style={{ display: 'flex', gap: isMobile ? 8 : 16, flexWrap: 'wrap', fontSize: isMobile ? 11 : 13 }}>
651666
<span style={{ color: '#a5b4fc', fontFamily: 'monospace' }}>
652667
🎼 {music.key} {music.scale}
653668
</span>
@@ -667,7 +682,7 @@ export default function Home() {
667682

668683
{/* Section Timeline */}
669684
<div style={{
670-
marginTop: 12,
685+
marginTop: isMobile ? 8 : 12,
671686
display: 'flex',
672687
gap: 2,
673688
overflow: 'hidden',
@@ -680,7 +695,7 @@ export default function Home() {
680695
onClick={() => setActiveSectionIndex(idx)}
681696
style={{
682697
flex: section.notes.length || 1,
683-
height: 24,
698+
height: isMobile ? 18 : 24,
684699
background: idx === activeSectionIndex
685700
? 'linear-gradient(135deg, #6366f1, #ec4899)'
686701
: 'rgba(99, 102, 241, 0.2)',

0 commit comments

Comments
 (0)