@@ -4,7 +4,7 @@ import { useWebSocket, GitHubEvent } from './hooks/useWebSocket';
44import { useAudio } from './hooks/useAudio' ;
55import Visualization from './components/Visualization' ;
66
7- // Styled Components
7+ // Styled Components - Optimized to reduce DOM elements
88const AppContainer = styled . div `
99 margin: 0;
1010 padding: 0;
@@ -40,6 +40,7 @@ const PlayButton = styled.img`
4040 }
4141` ;
4242
43+ // Combined Header with all header elements
4344const Header = styled . header < { $isOnline : boolean } > `
4445 position: relative;
4546 width: 100%;
@@ -49,109 +50,96 @@ const Header = styled.header<{ $isOnline: boolean }>`
4950 padding: 20px;
5051 z-index: 1000;
5152 transition: background-color 0.3s ease;
52- ` ;
53-
54- const HeaderText = styled . h1 `
55- float: left;
56- font-size: 1.6em;
57- line-height: 1em;
58- margin: 0;
59- ` ;
60-
61- const OfflineText = styled . span < { $show : boolean } > `
62- font-size: 0.4em;
63- visibility: ${ props => props . $show ? 'visible' : 'hidden' } ;
64- ` ;
65-
66- const VolumeSlider = styled . input `
67- position: absolute;
68- top: 30px;
69- right: 40px;
70- width: 100px;
71- opacity: 0.3;
72- transition: opacity 0.2s ease;
73- cursor: pointer;
7453
75- &:hover {
76- opacity: 0.9;
54+ h1 {
55+ float: left;
56+ font-size: 1.6em;
57+ line-height: 1em;
58+ margin: 0;
59+
60+ span {
61+ font-size: 0.4em;
62+ visibility: ${ props => props . $isOnline ? 'hidden' : 'visible' } ;
63+ }
64+ }
65+
66+ input[type="range"] {
67+ position: absolute;
68+ top: 30px;
69+ right: 40px;
70+ width: 100px;
71+ opacity: 0.3;
72+ transition: opacity 0.2s ease;
73+ cursor: pointer;
74+
75+ &:hover {
76+ opacity: 0.9;
77+ }
7778 }
7879` ;
7980
81+ // Combined MainArea with blob background
8082const MainArea = styled . div < { $isOnline : boolean } > `
8183 width: 100%;
8284 position: relative;
8385 min-height: 100vh;
8486 background-color: transparent;
8587 transition: background-color 0.3s ease;
8688 overflow: hidden;
87- ` ;
88-
89- const BlobOuterContainer = styled . div `
90- width: 100%;
91- height: 100%;
89+
90+ &::before {
91+ content: '';
9292 position: absolute;
9393 top: 0;
9494 left: 0;
95+ width: 80%;
96+ height: 80%;
9597 z-index: 0;
9698 filter: blur(100px);
97- ` ;
98-
99- const BlobInnerContainer = styled . div `
10099 border-radius: 99999px;
101- position: absolute;
102- inset: 0;
103100 margin: auto;
104- width: 100%;
105- height: 100%;
106- overflow: hidden;
107101 transform: scale(0.8);
108- ` ;
109-
110- const Blob = styled . div `
111- position: absolute;
112- width: 100%;
113- height: 100%;
114- inset: 0;
115- margin: auto;
116102 background: conic-gradient(
117- from 0deg,
118- #90D1CA 0%,
119- #7BCDC1 10%,
120- #129990 20%,
121- #6C4E4E 30%,
122- #CB0404 40%,
123- #D93C1B 50%,
124- #FE5D26 60%,
125- #FF7F35 70%,
126- #FF9B45 80%,
127- #927AF5 90%,
128- #4B70F5 100%
103+ from 0deg,
104+ #90D1CA 0%,
105+ #7BCDC1 10%,
106+ #129990 20%,
107+ #6C4E4E 30%,
108+ #CB0404 40%,
109+ #D93C1B 50%,
110+ #FE5D26 60%,
111+ #FF7F35 70%,
112+ #FF9B45 80%,
113+ #927AF5 90%,
114+ #4B70F5 100%
129115 );
130116 animation: spinAndPulseBlob 30s cubic-bezier(0.77, 0, 0.175, 1) infinite,
131117 fadeBlob 15s ease-in-out infinite;
118+ }
132119
133- @keyframes spinAndPulseBlob {
134- 0% {
135- transform: rotate(0deg) scale(1.95);
136- }
137- 50% {
138- transform: rotate(180deg) scale(2.05);
139- }
140- 100% {
141- transform: rotate(360deg) scale(1.95);
142- }
120+ @keyframes spinAndPulseBlob {
121+ 0% {
122+ transform: rotate(0deg) scale(1.95);
123+ }
124+ 50% {
125+ transform: rotate(180deg) scale(2.05);
126+ }
127+ 100% {
128+ transform: rotate(360deg) scale(1.95);
143129 }
130+ }
144131
145- @keyframes fadeBlob {
146- 0%, 100% {
147- opacity: 0.85;
148- }
149- 50% {
150- opacity: 1;
151- }
132+ @keyframes fadeBlob {
133+ 0%, 100% {
134+ opacity: 0.85;
152135 }
136+ 50% {
137+ opacity: 1;
138+ }
139+ }
153140` ;
154141
142+ // Combined ConfigArea with all config elements
155143const ConfigArea = styled . div `
156144 width: 100%;
157145 background: #FFFFFF;
@@ -160,25 +148,25 @@ const ConfigArea = styled.div`
160148 color: #555555;
161149 font-family: 'Inter', sans-serif;
162150 font-weight: 400;
163- ` ;
164-
165- const FilterDiv = styled . div `
166- width: 50% ;
167- margin: 0 auto 20px auto ;
168- text-align: center;
169- ` ;
170-
171- const FilterInput = styled . input `
172- width: 320px ;
173- padding: 8px 12px ;
174- border: 1px solid #ccc ;
175- border-radius: 4px;
176- font-family: 'Inter', sans-serif;
177- ` ;
178-
179- const SiteDescription = styled . div `
180- text-align: center ;
181- margin-bottom: 20px;
151+
152+ .filter-section {
153+ width: 50%;
154+ margin: 0 auto 20px auto ;
155+ text-align: center ;
156+
157+ input {
158+ width: 320px;
159+ padding: 8px 12px;
160+ border: 1px solid #ccc ;
161+ border-radius: 4px ;
162+ font-family: 'Inter', sans-serif ;
163+ }
164+ }
165+
166+ .description {
167+ text-align: center;
168+ margin-bottom: 20px ;
169+ }
182170` ;
183171
184172const Footer = styled . footer `
@@ -281,42 +269,37 @@ const App: React.FC = () => {
281269
282270 < MainArea $isOnline = { isOnline } >
283271 < Header $isOnline = { isOnline } >
284- < HeaderText >
272+ < h1 >
285273 Project Audio for GitHub
286- < OfflineText $show = { ! isOnline } > offline</ OfflineText >
287- </ HeaderText >
288- < VolumeSlider
274+ < span > offline</ span >
275+ </ h1 >
276+ < input
289277 type = "range"
290278 min = "0"
291279 max = "100"
292280 value = { volume * 100 }
293281 onChange = { handleVolumeChange }
294- />
282+ />
295283 </ Header >
296284 < Visualization
297285 events = { processedEvents }
298286 isOnline = { isOnline }
299287 />
300- < BlobOuterContainer >
301- < BlobInnerContainer >
302- < Blob />
303- </ BlobInnerContainer >
304- </ BlobOuterContainer >
305288 </ MainArea >
306289
307290 < ConfigArea >
308- < FilterDiv >
291+ < div className = "filter-section" >
309292 Enter your organization's or repository's names to filter events
310- < FilterInput
293+ < input
311294 type = "text"
312295 value = { orgRepoFilter }
313296 onChange = { handleFilterChange }
314297 placeholder = "e.g. facebook react"
315298 />
316- </ FilterDiv >
317- < SiteDescription >
299+ </ div >
300+ < div className = "description" >
318301 < p > Track events happening across GitHub and convert them to music notes.</ p >
319- </ SiteDescription >
302+ </ div >
320303 </ ConfigArea >
321304
322305 < Footer >
0 commit comments