The community websdr-plus-github can be found here: https://github.com/ny4qphil/PhantomSDR-Plus ..it is compatible with the normal version, but enhanced.

Suggestions for App.svelte and other components

Started by Emmanuel SV1BTL, Jan 04, 2025, 12:11 PM

Previous topic - Next topic

Phil - NY4Q

Maybe I misunderstand.

The issue I am referring to is when the mouse cursor is on the frequency display and the tuning step is set to 100 Hz, then the mouse wheel moves the frequency steps of 100 Hz.

But when the mouse cursor is on the waterfall and you roll the mouse wheel, the tuning steps are not based on the chosen step setting and is also different for each mode. I believe Gianni mentioned this?

Emmanuel SV1BTL

Quote from: Phil - NY4Q on Jan 10, 2025, 06:54 PMThe issue I am referring to is when the mouse cursor is on the frequency display and the tuning step is set to 100 Hz, then the mouse wheel moves the frequency steps of 100 Hz.

This is resolved by me, as the video shoes.

Quote from: Phil - NY4Q on Jan 10, 2025, 06:54 PMBut when the mouse cursor is on the waterfall and you roll the mouse wheel, the tuning steps are not based on the chosen step setting and is also different for each mode. I believe Gianni mentioned this?

I was the one that I've mentioned it 2-3 days before. I think that it has a relation to this part of the code:
function handleWheel(node) {
    function onWheel(event) {
      event.preventDefault();
      const delta = event.deltaY > 0 ? -1 : 1;
      const isShiftPressed = event.shiftKey;
      const isAltPressed = event.altKey;

      // Convert frequency to Hz for calculations
      let frequencyHz = Math.round(parseFloat(frequency) * 1e3);

      function adjustFrequency(freq, direction, shiftPressed, altPressed) {
        const step = currentTuneStep || (altPressed ? 10000 : shiftPressed ? 1000 : defaultStep);
        const lastDigits = freq % step;

        if (lastDigits === 0) {
          return freq + direction * step;
        } else if (direction > 0) {
          return Math.ceil(freq / step) * step;
        } else {
          return Math.floor(freq / step) * step;
        }
      }

      frequencyHz = adjustFrequency(frequencyHz, delta, isShiftPressed, isAltPressed);

      // Convert back to kHz and ensure 2 decimal places
      frequency = (frequencyHz / 1e3).toFixed(2);

      // Ensure frequency is not negative
      frequency = Math.max(0, parseFloat(frequency));

      frequencyInputComponent.setFrequency(frequencyHz);
      handleFrequencyChange({ detail: frequencyHz });
    }

    node.addEventListener("wheel", onWheel);

    return {
      destroy() {
        node.removeEventListener("wheel", onWheel);
      },
    };
  }


Phil - NY4Q

I will look at this, but I think a better way to tune would be to place the mouse over the display and depending on which digit you are hovering, then that digit moves and the frequency changes.

If you hover over 1 MHz, then the steps are 1 MHz. If you hover over 10 Hz, then the step is 10 Hz. Or maybe click above or below the digit so you still easy use on a mobile device?

Eliminate the buttons and clutter.

Emmanuel SV1BTL

Quote from: Phil - NY4Q on Jan 10, 2025, 07:14 PMI will look at this, but I think a better way to tune would be to place the mouse over the display and depending on which digit you are hovering, then that digit moves and the frequency changes.

If you hover over 1 MHz, then the steps are 1 MHz. If you hover over 10 Hz, then the step is 10 Hz. Or maybe click above or below the digit so you still easy use on a mobile device?

Eliminate the buttons and clutter.

Excellent, I wish you success with it!

Phil - NY4Q


I am thinking. The interface even as advanced as it is, is clunky. I am looking at my FTdx-10. One half is waterfall and such things, and the other half is buttons. If I tap a button and let's say band, then an additional menu pops up on the waterfall with all the band options. I choose a band, and the system moves to that band and the band menu disappears. As it should. We need to build a system like this. I do not have those skills as of yet. We need some better artistic coding than I am capable of.

Anyway, just thoughts.

magicint1337

Quote from: Phil - NY4Q on Jan 10, 2025, 07:43 PMI am thinking. The interface even as advanced as it is, is clunky. I am looking at my FTdx-10. One half is waterfall and such things, and the other half is buttons. If I tap a button and let's say band, then an additional menu pops up on the waterfall with all the band options. I choose a band, and the system moves to that band and the band menu disappears. As it should. We need to build a system like this. I do not have those skills as of yet. We need some better artistic coding than I am capable of.

Anyway, just thoughts.

Im pretty good in artistic coding, if we have like visual samples i may be able to do something similiar in the new frontend. I was thinking about multiple styles anyway. My plan for the new frontend to make the code extremly maintainable and readable and easy adjustable for anybody :)
Maintainer and Developer of PhantomSDR-Plus

sv2amk

#66
Quote from: Phil - NY4Q on Jan 05, 2025, 05:14 PM
Quote from: Emmanuel SV1BTL on Jan 05, 2025, 03:48 PMP.S. Moving the cursor through the whole band, we all notice that the modulation and the band button indicator is changing. This is very good. Shall we think the same thing for the step also? E.g. Broadcasting band to automatically tuned to 5KHz step, european MW to 9KHz etc, but when we move away from the band with a cursor, the step to change to given default?

I will look into that too - that is a very good observation.

Phil

Hi Phill.
I have downloaded your App.svelte and waterfall.js of date Jan 09 2025, and I made some modifications to let the websdr auto tunning steps work as the Emmanuel's one.
So when you move the wheel and you enter a band the step takes the value the that I have inserted  in the waterfall.js database for the bands you have created and the corresponded step button "lights up".
When you exit the band -with mouse wheel- the step changes again and when you enter the next band it changes again and so on...
To do this I inserted a new variable named stepi in the band database in the waterfall.js like this:

        { ITU: 123,
            name: 'MW', startFreq: 530000, endFreq: 1700000, stepi: 9000, color: 'rgba(199, 12, 193, 0.6)',
            modes: [{ mode: MODES.AM, startFreq: 530000, endFreq: 1700000 }]
        },
        { ITU: 123,
            name: '', startFreq: 1700000, endFreq: 1800000, stepi: 5000, color: '#ffffff00',
            modes: [{ mode: MODES.AM, startFreq: 1700000, endFreq: 1800000 }]
        },
        { ITU: 123,
          name: '160m', startFreq: 1800000, endFreq: 2000000, stepi: 1000, color: 'rgba(50, 168, 72, 0.6)',
          modes: [
            { mode: MODES.CW, startFreq: 1800000, endFreq: 1840000 },
            { mode: MODES.LSB, startFreq: 1840000, endFreq: 2000000 }]
        },

Please note that there is an extra record between MW and 160m bands with no name and black line color to fill the band  "gap" and have another step...
Then I modified the App.svelte :
I declared a new var by the name prevBand Then I added one more "if " in your updateBandButton() function as follows:

function updateBandButton() {
    currentBand = -1;
    for (var i = 0; i < bandArray.length; i++) {
        if(frequency >= (bandArray[i].startFreq / 1000) && frequency <= (bandArray[i].endFreq / 1000) && ((bandArray[i].ITU === siteRegion) || bandArray[i].ITU === 123)) {
          currentBand = i; if (prevBand != currentBand) {currentTuneStep = (bandArray[i].stepi)};
        }
    }
    prevBand = currentBand;
  }

So the function additionally checks if the band has changed and updates currentTuneStep using "stepi" " prevBand" and "currentBand".
To avoid adding extra buttons with no name I added one more "if " to your band selection section to check if the name of the button is not empty before it creates it, like this:

<!-- Begin Band Selection Section -->
<div class="w-full mt-4">
<h3 class="text-white text-lg font-semibold mb-2">Bands</h3>
<div class="grid grid-cols-1 sm:grid-cols-8 gap-2">
    {#each bandArray as bandData, index}
      {#if verifyRegion(bandData.ITU)}
        {#if bandData.name != ""}
          {#if printBandButton(bandData.startFreq,bandData.endFreq)}
      <button id="band-selector" class="retro-button text-sm text-white fontrbold h-7 text-base rounded-md flex items-center justify-center border border-gray-600 shadow-inner transition-all duration-200 ease-in-out {currentBand === index ? 'bg-blue-600 pressed scale-95' : 'bg-gray-700 hover:bg-gray-600'}"
        on:click={() => handleBandChange(index)} title="{bandData.name}">{bandData.name}
      </button>
          {/if}
        {/if} 
      {:else}
    {/if}
  {/each}
</div>
<hr class="border-gray-600 my-2" />
</div>
<!-- End of Band Selection Area -->

It works well and you can check it in my test server : sv2amk.ddns.net:9002 which is not published in the phantom sdr list.
I have not edited the entire database and the step values are random  just for demo purposes.
I send the two files inside a compressed file:  appsvelte-warerfalljs.tgz
Please check them and include the changes if you like.
73 de sv2amk.

Emmanuel SV1BTL

#67
Bookmarks and Popup Window

As you have noticed, the Bookmarks (Memories) are stored, recalled, edited in a popup window, which when is activated, we cannot work the Main window. I have edited the code, so the Memory (bookmark) window to be shown into the main window, so to allow working in the rest of the area. This window can be opened or closed, without to affect the rest of the GUI.

The newer code is this (replace the lines 2389-2482 in App.svelte located in the reposity):

<!-- Begin Bookmark / Memories Section -->
              <button id="bookmark-button" class="glass-button text-white font-bold py-2 px-4 rounded-lg flex items-center w-full justify-center" on:click={toggleBookmarkPopup}>
                <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
                  <path d="M5 4a2 2 0 012-2h6a2 2 0 012 2v14l-5-2.5L5 18V4z" />
                </svg>
                Bookmarks
              </button>

              <div id="user_count_container" class="w-full mt-4 bg-gradient-to-r from-purple-600 to-blue-600 rounded-lg p-1">
                <div id="total_user_count" class="bg-gray-800 rounded-md p-2 text-center flex justify-between items-center">
                  <!-- Content will be populated by JavaScript -->
                </div>
              </div>

              <!-- Bookmark Popup Window -->
              {#if showBookmarkPopup}
                <div class="relative inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
                  <div class="bg-gray-800 p-6 rounded-lg max-w-lg w-full max-h-[80vh] flex flex-col">
                    <div class="flex justify-between items-center mb-3">
                      <h2 class="text-lg font-bold text-white">Bookmarks</h2>
                      <button class="text-gray-400 hover:text-white" on:click={toggleBookmarkPopup}>
                        <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
                        </svg>                       
                      </button>
                    </div>

                    <!-- Add Bookmark Section -->
                    <div class="mb-4">
                      <label class="block text-sm font-medium text-gray-300 mb-4">Add New Bookmark</label>
                      <div class="flex items-center gap-2">
                        <input class="glass-input text-white text-sm rounded-lg focus:outline-none px-3 py-2 flex-grow" bind:value={newBookmarkName} placeholder="Bookmark name" />
                        <button class="glass-button text-white py-1 px-3 mb-2 lg:mb-0 rounded-lg text-xs sm:text-sm" style="color:#ffffff" on:click={addBookmark}>                         
                          Add
                        </button>
                      </div>
                    </div>

                    <!-- Current Link Section -->
                    <div class="mb-4">
                      <label class="block text-sm font-medium text-gray-300 mb-2">Current Link</label>
                      <div class="flex items-center gap-2">
                        <input type="text" class="glass-input text-white text-sm rounded-lg focus:outline-none px-3 py-2 flex-grow" value={link} readonly />
                        <button class="glass-button text-white py-1 px-3 mb-2 lg:mb-0 rounded-lg text-xs sm:text-sm" style="color:#ffffff" on:click={handleLinkCopyClick}>                         
                          Copy
                        </button>
                      </div>
                    </div>

                    <!-- Bookmarks List -->
                    <div class="overflow-y-auto flex-grow h-80">
                      <label class="block text-sm font-medium text-gray-300 mb-2">Saved Bookmarks</label>
                      {#each $bookmarks as bookmark, index}
                        <div class="glass-panel rounded-lg p-3 flex items-center justify-between mb-2">
                          <div class="flex flex-col">
                            <span class="text-white text-sm">{bookmark.name}</span>
                            <span class="text-gray-400 text-xs">{(bookmark.frequency / 1000).toFixed(3)} kHz</span>
                          </div>
                          <div class="flex gap-2">
                            <button class="glass-button text-white py-1 px-3 mb-2 lg:mb-0 rounded-lg text-xs sm:text-sm" style="color:#ffffff" on:click={() => goToBookmark(bookmark)}>                             
                              Go
                            </button>
                            <button class="glass-button text-white py-1 px-3 mb-2 lg:mb-0 rounded-lg text-xs sm:text-sm" style="color:#ffffff" on:click={() => copy(bookmark.link)}>                             
                              Copy
                            </button>
                            <button class="glass-button text-white py-1 px-3 mb-2 lg:mb-0 rounded-lg text-xs sm:text-sm" style="color:#ffffff" on:click={() => deleteBookmark(index)}>                             
                              Delete
                            </button>
                          </div>
                        </div>
                      {/each}
                    </div>
                  </div>
                </div>
              {/if}

The final result can be shown here: SV1BTL PhantomSDR+

Phil - NY4Q

Just waking up here in the ole US. I will get these changes into the community App today sometime. I will also move the recording button over to audio section. I will also include the link to the audio player, but it will be pointed to your player Emmanuel. If that is a problem, let me know please.

Phil

Emmanuel SV1BTL

#69
Quote from: Phil - NY4Q on Jan 11, 2025, 10:51 AMJust waking up here in the ole US. I will get these changes into the community App today sometime. I will also move the recording button over to audio section. I will also include the link to the audio player, but it will be pointed to your player Emmanuel. If that is a problem, let me know please.

Phil

GM Phil,

1.- If you like the above changes to the Bookmarks/Memories code, please note that I have changed it once more, so the buttons to be the same format/design, as the rest of the GUI. So copy the newer code.

2.- I don't have problem to point to my player of course, but I wonder what will happen if my server is temporary closed.
If you don't wish to include player folder to the repository and include it to the compile procedure, so to be copied in to the frontend/dist, then you can of course point to my server.
I am including once more the folder as an attachment (zip file). It has to be uploaded in frontend/dist section and the link must point to href="{siteInformation}/audio/index.html where {siteInformation} is the ip address of the server.

9a7aof

#70
Quote from: Emmanuel SV1BTL on Jan 11, 2025, 08:58 AMThe final result can be shown here

It works fine. I delete the old block, copy the selected text from the forum, after compiling and restarting the popup disappears.

Quote from: Phil - NY4Q on Jan 11, 2025, 10:51 AMI will get these changes into the community App today sometime. I will also move the recording button over to audio section.

Phil, please don't forget to add the date and time to recorded_audio.wav. Just a reminder.
:)



Phil - NY4Q

Everything looks good. I'll post it in a bit.

I did move the Recording, but did not include the link to the audio player.

Other than little tweaks here and there, it is probably time to ease up and wait for Steven to get the next version posted. Personally I would prefer to stay with Svelte, but he is the author and is calling the shots.

Phil

Phil - NY4Q

Quote from: 9a7aof on Jan 11, 2025, 12:47 PMPhil, please don't forget to add the date and time to recorded_audio.wav. Just a reminder.
:)


Thank you for the reminder! I will add that before posting.

Bas ON5HB

#73
Take your time, make sure it works.

Test it a few days before uploading.

I suggest no more then 1 upload a month for the github, better maybe if needed after a week.

But uploading to many updates all the time will give problems for people that use their own code.
They have to adapt all the time....if they update.

I'm against daily updates. Test a few days, and if enough new stuff, update the github.

Sorry but I do ignore most, just because it takes too much time to test/backup/adapt etc.

Some people want to go tooooooo fast and update all the time...please don't.
Best regards,

Bas ON5HB

Ps. the Community Edition can be found here: https://github.com/ny4qphil/PhantomSDR-Plus

hb3xdc

Quote from: Phil - NY4Q on Jan 10, 2025, 06:54 PMMaybe I misunderstand.

The issue I am referring to is when the mouse cursor is on the frequency display and the tuning step is set to 100 Hz, then the mouse wheel moves the frequency steps of 100 Hz.

But when the mouse cursor is on the waterfall and you roll the mouse wheel, the tuning steps are not based on the chosen step setting and is also different for each mode. I believe Gianni mentioned this?
Hi Phil, I'll be updating my servers to the version you're currently working on, either today or tomorrow. And yes, that's exactly what I meant.
Gianni - HB3XDC
WebSDR Lucerne
Sardinia SDR

Powered by EzPortal