undergroundwires / privacy.sexy

Open-source tool to enforce privacy & security best-practices on Windows, macOS and Linux, because privacy is sexy
https://privacy.sexy
GNU Affero General Public License v3.0
3.64k stars 154 forks source link

[Feature] The search string as query parameters in the URL #345

Open Drovosek01 opened 1 month ago

Drovosek01 commented 1 month ago

I think it will be convenient if you can save the string and search settings in the URL so that when you click on the URL, the necessary search query and its settings are displayed

For example:

For just search word "defender" will URL like https://privacy.sexy/?s=defender or https://privacy.sexy/?s=defender&os=all

For search word "defender" for Windows will URL like https://privacy.sexy/?s=defender&os=win or https://privacy.sexy/?s=defender&os=windows

For search word "defender" and select all results URL like https://privacy.sexy/?s=defender&select=all

etc

undergroundwires commented 1 month ago

Thank you @Drovosek01. It's great idea. I'll try to get this as one of the highest priority features, but I find it hard to find time to add features while a lot effort is going to getting stuff stable, so no timelines are promised :)

plantindesk commented 1 month ago

Thank you @Drovosek01. It's great idea. I'll try to get this as one of the highest priority features, but I find it hard to find time to add features while a lot effort is going to getting stuff stable, so no timelines are promised :)

12 days. Nevermind,

Let me do it then

plantindesk commented 1 month ago

@undergroundwires

insert this code next to searchQuery variable in TheSearchBar.vue

const searchQuery = ref<string | undefined>();
    onMounted(() => {
      updateSearchQueryFromURL();
    });

    onUpdated(() => {
      updateSearchQueryFromURL();
    });

    function updateSearchQueryFromURL() {
      const urlParams = new URLSearchParams(window.location.search);
      const searchParam = urlParams.get('s');
      if (searchParam) {
        searchQuery.value = searchParam;
        updateFilter(searchParam);
      }
    }

insert this code next to changOs function in TheOsChanger.vue

onMounted(updateOsFromURL);
    onUpdated(updateOsFromURL);

    function updateOsFromURL() {
      const urlParams = new URLSearchParams(window.location.search);
      const osParam = urlParams.get('os');
      if (osParam) {
        const matchingOs = allOses.value.find((os) => os.os === OperatingSystem[osParam as keyof typeof OperatingSystem]);
        if (matchingOs) {
          changeOs(matchingOs.os);
        } else {
          console.warn(`Invalid 'os' parameter: ${osParam}`); // Or handle the error as needed
        }
      }
    }

insert this code next to selectRecommendationStatusType function in TheRecommendationSelector.vue

onMounted(updateRecommendationStatusFromURL);
    onUpdated(updateRecommendationStatusFromURL);

    function updateRecommendationStatusFromURL() {
      const urlParams = new URLSearchParams(window.location.search);
      const selectParam = urlParams.get('select');

      if (selectParam) {
        let recommendationStatusType: RecommendationStatusType | undefined;

        switch (selectParam.toLowerCase()) {
          case 'none':
            recommendationStatusType = RecommendationStatusType.None;
            break;
          case 'standard':
            recommendationStatusType = RecommendationStatusType.Standard;
            break;
          case 'strict':
            recommendationStatusType = RecommendationStatusType.Strict;
            break;
          case 'all':
            recommendationStatusType = RecommendationStatusType.All;
            break;
          default:
            console.warn(`Invalid 'select' query parameter value: ${selectParam}`);
        }

        if (recommendationStatusType !== undefined) {
          selectRecommendationStatusType(recommendationStatusType);
        }
      }
    }

image

The OS Query Parameters are based on enumerations that are defined in OperatingSystem.ts

undergroundwires commented 1 month ago

@plantindesk, thank you for the code, it's the first time front-end code is getting functional code from someone else ❤️

As you see, most of my time is going to fixing bugs and stability issues, so features get delayed, weeks/months sometimes years if there are no other contributions, so great to see this.


Here are my thoughts:

TheSearchBar.vue:

I do not think that onUpdated hook does anything here. We need to listen to URL changes instead.

We should listen to URL changes using Navigation API like this:

window.navigation.addEventListener('navigate', (event) => {
    updateSearchQueryFromURL();
})

Let me know if I'm missing something.

TheOsChanger.vue, TheRecommendationSelector.vue:

Same thing, using Navigation API instead of onUpdated.

As this logic used many times, we can create a custom hook like this to safely get current URL:

function useCurrentUrl() {
  const currentUrl = ref('');
  onMounted(() => {
     currentUrl.value = window.location.search;
  })
  const urlUpdater = () => {
     currentUrl.value =window.location.search;
  };
  window.navigation.addEventListener('navigate', urlUpdater);
  onUnmounted(() => {
     window.navigation.removeEventListener('navigate', urlUpdater);  
  });
  return readonly(currentUrl);
}

This way other components can just use:

const currentUrl = useCurrentUrl();
watch(currentUrl, (newUrl) => {
  // Do their thing
});

This would be more reusable and reactive way.

I blind coded this completely, this needs to be integrated.

Another thing to consider is that we just not be reactive to URL changes, but we should change the URL on changes too. So the URL becomes dynamic.


Would you like to create a PR for this? Then we can work on this instead of this issue.

undergroundwires commented 1 month ago

Length: Another consideration is the length of URLs. s can become quite long so URLs should not update more than lets say 50 characters for sanity to not get close to max URL limits and uglify stuff.

Naming: For the naming, how about this:

What do you think? Verbose (collection, search) etc or one char query strings (s, c) etc? I tend more towards to verbose approach for clarity.

plantindesk commented 1 month ago

Ok Let me try using Navigation API as you said

Also As you said

undergroundwires commented 1 month ago

Preset instead of select sounds great. Let's have search for q. If all of those will be verbose (full words), there's no need to obfuscate this. Thank you for driving this further @plantindesk