ChatGPT (https://chat.openai.com/chat)

boxerfan88

Well-known member
ChatGPT helped me write a simple volume controller webpage in 4 hours. Not bad at all !!


IMG-2823.jpg




HTML:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Display JSON Data and Post Data</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        .container {
            max-width: 600px;
            margin: auto;
            padding: 20px;
            border: 1px solid #ccc;
            border-radius: 5px;
        }
        h2 {
            text-align: center;
        }
        #output {
            margin-top: 20px;
        }
        .btn-container {
            margin-top: 10px;
            text-align: center;
        }
        button {
            padding: 8px 16px;
            font-size: 14px;
            margin: 0 5px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
    <div class="container">
        <h3 align=center>foobar_USB volume</h3>
        <div id="output">
            <!-- JSON data will be displayed here -->
        </div>
        <div class="btn-container">
            <button onclick="postData('decrement')">Vol-</button>
            <button onclick="postData('increment')">Vol+</button>
        </div>
    </div>

   <script>
        let fieldValue = -100; // Initial fieldValue
        let currVolume = -100; // Initial current volume

        function fetchData() {
            fetch('http://192.166.77.88:8888/api/query?player=true')
                .then(response => response.json())
                .then(data => {
                    const fieldValue = data.player.volume.value; // Replace 'field' with the actual field name you want to display
                    currVolume = fieldValue;
                    const fieldUnit = data.player.volume.type;
                    const outputDiv = document.getElementById('output');
                    outputDiv.innerHTML = `<h1 align=center>${currVolume}dB</h1>`;
                })
                .catch(error => {
                    console.error('Error fetching data:', error);
                    const outputDiv = document.getElementById('output');
                    outputDiv.innerHTML = '<p>Error fetching data. Please try again later.</p>';
                });
        }

        function displayFieldValue() {
            const outputDiv = document.getElementById('output');
            outputDiv.innerHTML = `<p>foobar current Volume2: ${fieldValue}</p>`;
        }

        function postData(operation) {
            if (operation === 'increment') {
                newVolume = currVolume + 1;
            } else if (operation === 'decrement') {
                newVolume = currVolume - 1;
            }

            // Replace 'https://api.example.com/post' with the actual URL where you want to post the data
            fetch('http://192.166.77.88:8888/api/player', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ volume: newVolume, isMuted: false }) // Adjust the payload structure as needed
            })
            .then(response => {
                if (response.ok) {
                    // alert('Data posted successfully!');
                    fetchData(); // Fetch updated data after posting
                } else {
                    throw new Error('Failed to post data');
                }
            })
            .catch(error => {
                console.error('Error posting data:', error);
                alert('Failed to post data. Please try again later.');
            });
        }

        // Initial fetch
        fetchData();

  
        // Refresh every 10 seconds
        setInterval(fetchData, 10000); // 10 seconds in milliseconds
   
    </script>
</body>
</html>

.
 
Last edited:

boxerfan88

Well-known member
Further ChatGPT help last night to add on control buttons, and retrieve current playing track information via JSON and then displaying it.


IMG-2825.jpg
 

boxerfan88

Well-known member
And after another hour of code modification with the help of ChatGPT.
Managed to code the retrieval & display of artwork. Swee boh?

IMG-2828.jpg


I still can't seem to get the onmousedown event to work properly on iPhone. Hmm...


.
 
Last edited:

boxerfan88

Well-known member
I still can't seem to get the onmousedown event to work properly on iPhone. Hmm...

Found it !!
  • onTouchStart="startChangingVolume('increment')"
  • onTouchEnd="stopChangingVolume()"
All good now. Works well with mouse on PC, and touch screen on iPhone. Yay !!!

.
 

boxerfan88

Well-known member
Getting a little more ambitious ... with the help of ChatGPT ... writing up a playlist controller. Swee boh?
The new playlist controller can now send a command to beefweb API to play a selected playlist item.


IMG-2836.jpg



Next feature, to add a button to search and jump to current playing item ... and display both playlist name & item trackname.

.
 
Last edited:

boxerfan88

Well-known member
Next feature, to add a button to search and jump to current playing item ... and display both playlist name & item trackname.

This time it is much tougher due to the asynchronous nature of JavaScript. Took a lot of debugging to get it right. At least ChatGPT helped to narrow down the problem areas.

I'm done coding for the night. Very satisfied with the outcome:

IMG-2837.jpg



.
 
Last edited:

boxerfan88

Well-known member
After a week of intermittent coding, no more changes to the UI of the volume controller & playlist controller, only stuff under the bonnet. Clearly ChatGPT can help get you to 70%-80% of the functionality very very quickly. After that it's pure hard work fine tuning & debugging.

The asynchronous nature of JavaScript/HTML can be very very painful -- race conditions, out of order execution, timing issues, etc... The last 30% of coding/programming is truly challenging, and ChatGPT help is quite limited, need to rely on own logical reasoning to fine tune and fix bugs. Volume controller is more or less done. Now my time is focused on getting the playlist controller to be as stable as possible.

I haven't done programming for over 20 years, this little project is a very nice segway for me back into the web/app programming scene. HiFi music accompaniment during programming certainly helps.

Quite fun indeed!

.
 
Last edited:

boxerfan88

Well-known member
Tired after a couple of hours of coding.

I asked ChatGPT to review the code.

I've reviewed the code you provided. Overall, it looks well-structured and functional for controlling a playlist through an external API (presumably for a media player like foobar2000 with beefweb). Here are some observations and recommendations:

### HTML and CSS

1. **HTML Structure**: The HTML structure is clean and organized. IDs and classes are appropriately used for styling and scripting purposes.

2. **Styling**: CSS is well-utilized for styling elements. It's good to see consistent use of classes (`playlist-item`, `playlist-item-X`, etc.) for styling different states of playlist items.

3. **Responsive Design**: Ensure that the design remains responsive across different screen sizes, especially since you're using `max-width` on `.container`. Consider testing on different devices if responsive behavior is critical.

### JavaScript

1. **Global Variables**: You have declared several global variables for maintaining state and controlling timers (`playerTimerID`, `gotoTimerID`, etc.). This is okay for a single-page application but consider encapsulating related variables into objects or classes for better organization.

2. **Debugging**: You've included debug flags (`debug1`, `debug2`) which can be helpful during development. Ensure these are disabled (`debug1 = false`) in production for security and performance reasons.

3. **Fetch and Data Handling**:
- The `fetchPlayerData` and `fetchPlaylistItemData` functions handle fetching data from your foobar2000 server API. They seem well-implemented.
- Error handling is present (`catch` blocks in fetch promises), which is good practice.

4. **DOM Manipulation**:
- The `fetchPlaylistItemData` function dynamically creates playlist items based on API data. Ensure memory management and performance optimizations, especially if dealing with large datasets.

5. **Event Handling**:
- Event listeners (`dblclick` on playlist items) are used effectively to trigger actions like playing specific playlist items.

6. **Viewport Visibility Check**:
- The `isElementInViewport` function is correctly implemented to check if an element is fully visible within the viewport. This is crucial for scrolling to playlist items as they become active.

7. **Timers**:
- Timers (`playerTimerID`, `syncCheckTimerID`, etc.) are set up to periodically fetch player data, check sync status, etc. Ensure these intervals are set based on actual performance needs and do not impact user experience negatively.

### Recommendations

1. **Security**: Ensure that any API endpoints (`fetch` requests) are secured appropriately, especially if dealing with user-sensitive data or control over a media player.

2. **Error Handling**: Consider adding more descriptive error messages or UI feedback for users if API calls fail or if unexpected conditions occur.

3. **Performance**: Test the application with a significant amount of data to ensure smooth performance, especially on older devices or slower network connections.

4. **Code Refactoring**: As the codebase grows, consider refactoring into smaller, modular functions or classes to improve readability and maintainability.

5. **Documentation**: Add comments or documentation for complex functions or logic to aid future maintenance or collaboration.

Overall, your code appears well-structured and functional for controlling a playlist via a web interface. If you encounter specific issues or need further optimization tips, feel free to ask!

foobar playlist controller is more or less done.

Now to deploy it into production for the stress testing this weekend under live workload. :)

.
 

boxerfan88

Well-known member
Today ChatGPT taught me about
  • async function & await
  • eventsource & streaming updates
  • hiding DIV & button
  • how to prevent iPhone browser from zooming in if i double click the screen

Definitely still got a lot to learn about JavaScript..
 

boxerfan88

Well-known member
Last week I forked my JavaScript code and experimented with eventsource & streaming updates from foobar. It sort of worked but the streaming updates from beefweb API wasn't at regular intervals and the streaming update interval is quite inconsistent. I gave up on it and went back to polling method which is quite deterministic and makes the controller updates smooth.
 
Last edited:

boxerfan88

Well-known member
Finally managed to clear the odd iPhone behavior of showing a graphic instead of the usual unicode text.
Need to add &#xfe0e; to avoid Apple Color Emoji.

&#x23ef; displays on the iPhone like that:
2024-07-06-2211-firefox-Chat-GPT-httpschat-openai-comchat-Page-3-hifive.png



&#x23ef;&#xfe0e; displays on the iPhone like this:
fe0e.png

looks exactly like the desktop browser on my pc, so much nicer...



.
 
Top