@@ -10,6 +10,8 @@ const runBtn = document.getElementById('run-btn');
1010const outputConsole = document . getElementById ( 'output-console' ) ;
1111const clearConsoleBtn = document . getElementById ( 'clear-console' ) ;
1212const refreshFilesBtn = document . getElementById ( 'refresh-files' ) ;
13+ const fileSearchInput = document . getElementById ( 'file-search' ) ;
14+ const copyBtn = document . getElementById ( 'copy-btn' ) ;
1315
1416const CACHE_KEY = 'php_repos_cache_v1' ;
1517const CACHE_DURATION = 5 * 60 * 1000 ; // 5 minutes
@@ -30,6 +32,19 @@ document.addEventListener('DOMContentLoaded', () => {
3032 fetchFiles ( ) ;
3133 } ) ;
3234 }
35+
36+ // Search functionality
37+ if ( fileSearchInput ) {
38+ fileSearchInput . addEventListener ( 'input' , ( e ) => {
39+ const searchTerm = e . target . value . toLowerCase ( ) ;
40+ filterFiles ( searchTerm ) ;
41+ } ) ;
42+ }
43+
44+ // Copy functionality
45+ if ( copyBtn ) {
46+ copyBtn . addEventListener ( 'click' , copyToClipboard ) ;
47+ }
3348} ) ;
3449
3550// Fetch files from GitHub
@@ -84,10 +99,16 @@ async function fetchFiles(isBackground = false) {
8499 "Constants.php" ,
85100 "Data_Type.php" ,
86101 "Dot_Operator.php" ,
102+ "Even_Odd.php" ,
103+ "Factorial.php" ,
104+ "Fibonacci.php" ,
105+ "For_Loop_Table.php" ,
87106 "HelloWorld.php" ,
88107 "Increment-&-Decrement-Operators.php" ,
89108 "Operator.php" ,
109+ "Prime_Number.php" ,
90110 "String.php" ,
111+ "Switch_Case.php" ,
91112 "array.php" ,
92113 "bitwise.php" ,
93114 "calculate_truth_table.php" ,
@@ -133,6 +154,19 @@ async function fetchFiles(isBackground = false) {
133154 } ) ;
134155}
135156
157+ // Filter files based on search term
158+ function filterFiles ( term ) {
159+ const items = fileListEl . querySelectorAll ( '.file-item' ) ;
160+ items . forEach ( item => {
161+ const fileName = item . innerText . toLowerCase ( ) ;
162+ if ( fileName . includes ( term ) ) {
163+ item . style . display = 'flex' ;
164+ } else {
165+ item . style . display = 'none' ;
166+ }
167+ } ) ;
168+ }
169+
136170// Poll for updates every 5 minutes (reduced from 60s to save API calls)
137171setInterval ( ( ) => fetchFiles ( true ) , 300000 ) ;
138172
@@ -168,13 +202,47 @@ async function loadFile(file, element) {
168202
169203 runBtn . disabled = false ;
170204 runBtn . innerHTML = '<ion-icon name="play"></ion-icon> Run Code' ;
205+
206+ if ( copyBtn ) copyBtn . disabled = false ;
171207
172208 // Log to terminal
173209 renderOutput ( `Loaded file: ${ file . name } \nReady to execute...` , true ) ;
174210
175211 } catch ( error ) {
176212 codeDisplayEl . innerHTML = `// Error loading file: ${ error . message } ` ;
177213 runBtn . innerHTML = '<ion-icon name="alert-circle"></ion-icon> Error' ;
214+ if ( copyBtn ) copyBtn . disabled = true ;
215+ }
216+ }
217+
218+ // Copy Code to Clipboard
219+ async function copyToClipboard ( ) {
220+ if ( ! currentCode ) return ;
221+
222+ try {
223+ await navigator . clipboard . writeText ( currentCode ) ;
224+
225+ // Show success tooltip
226+ const tooltip = document . createElement ( 'div' ) ;
227+ tooltip . className = 'copy-tooltip' ;
228+ tooltip . innerText = 'Copied!' ;
229+ copyBtn . parentElement . appendChild ( tooltip ) ;
230+
231+ setTimeout ( ( ) => tooltip . classList . add ( 'show' ) , 10 ) ;
232+ setTimeout ( ( ) => {
233+ tooltip . classList . remove ( 'show' ) ;
234+ setTimeout ( ( ) => tooltip . remove ( ) , 300 ) ;
235+ } , 2000 ) ;
236+
237+ // Change icon temporarily
238+ const originalIcon = copyBtn . querySelector ( 'ion-icon' ) . name ;
239+ copyBtn . querySelector ( 'ion-icon' ) . name = 'checkmark-outline' ;
240+ setTimeout ( ( ) => {
241+ copyBtn . querySelector ( 'ion-icon' ) . name = originalIcon ;
242+ } , 2000 ) ;
243+
244+ } catch ( err ) {
245+ console . error ( 'Failed to copy: ' , err ) ;
178246 }
179247}
180248
0 commit comments