The Official Power User Tips, Tricks & Productivity Thread

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
i've been using copyq scripts and redirector to get rid of tracking parameters in instagram and twitter urls especially from the coli but I decided to go to get to the root of the problem as best as I could and try to modify the urls directly in the embeds. I used a LLM to create a userscript that removes everything after "?" in the urls. it isn't site specific but you can replace // @match *://*/* with // @match https://www.thecoli.com/* if you only want it to work on this site. you can easily modify the script to also work on urls other than twitter or instagram too.

7YTLQCW.png

Code:
// ==UserScript==
// @name         Remove Tracking Parameters from Twitter and Instagram Links
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Removes tracking parameters from links in embedded tweets and Instagram posts
// @author       Your Name
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function cleanLinks() {
        var links = document.querySelectorAll('a[href^="https://twitter.com/"], a[href^="https://instagram.com/"]');
        for (var i = 0; i < links.length; i++) {
            var link = links[i];
            var url = new URL(link.href);
            url.search = '';
            link.href = url.toString();
        }
    }

    // Run the script on page load
    window.addEventListener('load', cleanLinks);

    // Run the script on AJAX content updates
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList') {
                cleanLinks();
            }
        });
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();
update: added reddit.com and tiktok.com
not making it site specific right now to see if it breaks anything websurfing,
Code:
// ==UserScript==
// @name         Remove Tracking Parameters from Tweets, Instagram Posts, Reddit, and TikTok Links
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Removes tracking parameters from links in embedded tweets, Instagram posts, Reddit, and TikTok
// @author       Your Name
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function cleanLinks() {
        var links = document.querySelectorAll('a[href^="https://twitter.com/"], a[href^="https://instagram.com/"], a[href^="https://www.instagram.com/"], a[href^="https://www.reddit.com/"], a[href^="https://www.tiktok.com/"]');
        for (var i = 0; i < links.length; i++) {
            var link = links[i];
            var url = new URL(link.href);
            url.search = '';
            link.href = url.toString();
        }
    }

    // Run the script on page load
    window.addEventListener('load', cleanLinks);

    // Run the script on AJAX content updates
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList') {
                cleanLinks();
            }
        });
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();

AI generated explanation
claude-3-haiku


Bookmarklet:
- The bookmarklet is a small piece of JavaScript code that you can save as a bookmark in your web browser.
- When you click on the bookmarklet, it will automatically find all the links on the current web page that start with "https://twitter.com/" or "Instagram".
- For each of those links, the bookmarklet will remove the part of the link that contains the tracking parameters (the stuff after the "?" in the URL).
- This allows you to copy the clean, tracking-free links from the page.

Userscript:
- The userscript is a small program that runs automatically in your web browser whenever you visit a web page.
- The userscript is designed to work with browser extensions like Tampermonkey or Greasemonkey, which allow you to install and run custom scripts.
- When the userscript runs, it will automatically find all the links on the page that start with "https://twitter.com/" or "Instagram".
- For each of those links, the userscript will remove the part of the link that contains the tracking parameters.
- The userscript will also continue to monitor the page for any changes, and will automatically remove the tracking parameters from any new links that are added to the page.

In both cases, the goal is to make it easier for you to copy and share the links from embedded tweets and Instagram posts without the extra tracking information that the social media platforms sometimes add to the URLs.

update #3:
since I left it to work on any site, i realized the old code broke reddit search url parameter so made updated the userscript to have an exclude option that ignores "/search/" in the url when it match's the domain.
Code:
// ==UserScript==
// @name         Remove Tracking Parameters from Tweets, Instagram Posts, Reddit, and TikTok Links
// @namespace    http://tampermonkey.net/
// @version      0.8
// @description  Removes tracking parameters from links in embedded tweets, Instagram posts, Reddit, and TikTok
// @author       Your Name
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // List of domains to include
    const includedDomains = [
        'twitter.com',
        'instagram.com',
        'www.instagram.com',
        'reddit.com',
        'www.reddit.com',
        'tiktok.com',
        'www.tiktok.com'
    ];

    // List of URL patterns to exclude
    // To add a new exclusion pattern, use a regular expression
    // Example: /\/search\/\?q=/ will exclude URLs containing "/search/?q="
    // Example: /\/some-other-pattern/ will exclude URLs containing "/some-other-pattern"
    const excludedPatterns = [
        /\/search\/\?q=/,
        /cdninstagram.com/,
        /\/search\?/,
        /\?limit=/,
        /out.reddit.com/,
        /\/some-other-pattern/
    ];

    function cleanLinks() {
        var links = document.querySelectorAll('a[href]');
        for (var i = 0; i < links.length; i++) {
            var link = links[i];
            var url = new URL(link.href);

            // Check if the domain is included and the URL doesn't match any excluded patterns
            if (includedDomains.some(domain => url.hostname.endsWith(domain)) && !excludedPatterns.some(pattern => pattern.test(url.href))) {
                url.search = '';
                link.href = url.toString();
            }
        }
    }

    // Run the script on page load
    window.addEventListener('load', cleanLinks);

    // Run the script on AJAX content updates
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList') {
                cleanLinks();
            }
        });
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();

Changelog:

**Version 0.1 (Initial Code):**
- The initial code provided removes tracking parameters from links in embedded tweets, Instagram posts, Reddit, and TikTok.
- The script runs on page load and also observes the DOM for AJAX content updates, running the cleanup function whenever new content is added.

**Version 0.8 (Final Code):**
- Added a list of included domains (e.g., twitter.com, instagram.com, reddit.com, tiktok.com) to specify which links should be cleaned.
- Added a list of URL patterns to exclude from being cleaned, using regular expressions.
- Improved the exclusion logic to check if the domain is included and the URL doesn't match any of the excluded patterns.
- Added comments to explain how to add new exclusion patterns using regular expressions.

Layman's Summary:

This userscript is designed to clean up links in various social media and content platforms, such as Twitter, Instagram, Reddit, and TikTok. It removes any tracking parameters (e.g., `?utm_source=...`) from the links, making them more readable and less cluttered.

The script runs automatically when the page loads and also monitors the page for any AJAX-based content updates, cleaning up the links as new content is added.

The script is highly customizable, allowing you to specify which domains should be included (e.g., twitter.com, reddit.com) and which URL patterns should be excluded from the cleaning process (e.g., URLs containing "/search/?q="). This makes it easy to tailor the script to your specific needs and preferences.

Overall, this userscript helps to improve the user experience by removing unnecessary tracking parameters from links, making them more clean and readable.
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
i wanted to copy https://www.chatsplitter.com/ and make it a offline app, i used AI to help me create the prompt.

my prompt:


you can paste the code into a powershell window or save it as a "ChatGPT-Text-Splitter.PS1" file and run it.
Code:
removed... go to original post

the code from the first reply was missing a field a user could set the max numbers of characters to split so I told it to add one.

Code:
removed... go to original post

agY6jdC.png


how it looks after text split operation:
aw6BReR.png


so gpt-4o is pretty damn good considering I used this prompt on multiple LLM's and none of them got the UI or functionality quite right without significant errors and it was able to do so on the first try,


I reached my gpt-4o message limit so I used llama-3-sonar-large-32k-chat to make additional modifications to the code I now know works,

Code:
# Import necessary assemblies for the GUI
Add-Type -AssemblyName PresentationFramework

function Create-MainWindow {
    [xml]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ChatGPT Text Splitter" Height="500" Width="800" ResizeMode="CanResizeWithGrip">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <!-- Header -->
        <TextBlock Grid.Row="0" Text="ChatGPT Text Splitter" FontSize="20" FontWeight="Bold" Margin="10" HorizontalAlignment="Center"/>

        <!-- Content Area -->
        <DockPanel Grid.Row="1" Margin="10">
            <StackPanel DockPanel.Dock="Top" Orientation="Vertical">
                <TextBox Name="InputTextBox" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" Height="200" Margin="0,0,0,10"/>
                <TextBlock Name="CharCountText" Text="Characters: 0" Margin="0,0,0,5"/>
                <TextBlock Name="WordCountText" Text="Words: 0" Margin="0,0,0,5"/>
                <TextBlock Name="ParagraphCountText" Text="Paragraphs: 0" Margin="0,0,0,10"/>
                <StackPanel Orientation="Horizontal" Margin="0">
                    <TextBlock Text="Max Characters Per Part:" VerticalAlignment="Center" Margin="0,0,5,0"/>
                    <TextBox Name="MaxCharCountTextBox" Width="100" Text="2048" Margin="0,0,5,0"/>
                    <Button Name="SplitButton" Content="Split" Width="100" Margin="0,0,5,0" HorizontalAlignment="Right"/>
                </StackPanel>
            </StackPanel>
            <ScrollViewer DockPanel.Dock="Bottom" Height="200" VerticalScrollBarVisibility="Auto">
                <StackPanel Name="OutputStackPanel" Orientation="Vertical"/>
            </ScrollViewer>
            <ProgressBar Name="ProgressBar" Visibility="Collapsed" Height="20" Margin="10" />
        </DockPanel>

        <!-- Footer -->
        <TextBlock Grid.Row="2" Text="© 2024 Your Company" HorizontalAlignment="Center" Margin="10"/>
    </Grid>
</Window>
"@

    $reader = (New-Object System.Xml.XmlNodeReader $xaml)
    $window = [Windows.Markup.XamlReader]::Load($reader)

    # Find elements
    $inputTextBox = $window.FindName("InputTextBox")
    $charCountText = $window.FindName("CharCountText")
    $wordCountText = $window.FindName("WordCountText")
    $paragraphCountText = $window.FindName("ParagraphCountText")
    $splitButton = $window.FindName("SplitButton")
    $outputStackPanel = $window.FindName("OutputStackPanel")
    $maxCharCountTextBox = $window.FindName("MaxCharCountTextBox")
    $progressBar = $window.FindName("ProgressBar")

    # Event Handlers
    $inputTextBox.Add_TextChanged({
        $charCountText.Text = "Characters: " + $inputTextBox.Text.Length
        $wordCountText.Text = "Words: " + ($inputTextBox.Text -split '\s+').Count
        $paragraphCountText.Text = "Paragraphs: " + ($inputTextBox.Text -split '\r\n|\r|\n').Count
    })

    $splitButton.Add_Click({
        $progressBar.Visibility = "Visible"
        $outputStackPanel.Children.Clear()
        $text = $inputTextBox.Text
        [int]$maxCharCount = [int]$maxCharCountTextBox.Text
        $parts = [math]::Ceiling($text.Length / $maxCharCount)
        $quickCopyButtonStackPanel = New-Object System.Windows.Controls.WrapPanel
        $quickCopyButtonStackPanel.Orientation = "Horizontal"
        for ($i = 0; $i -lt $parts; $i++) {
            $start = $i * $maxCharCount
            $length = [math]::Min($maxCharCount, $text.Length - $start)
            $partText = $text.Substring($start, $length)
            $partLabel = "Part " + ($i + 1) + " of " + $parts
            $outputText = "Do not answer yet. This is just another part of the text I want to send you. Just receive and acknowledge as `$partLabel` and wait for the next part.`n[START $partLabel]`n$partText"
            $textBox = New-Object System.Windows.Controls.TextBox
            $textBox.Text = $outputText
            $textBox.Margin = "0,0,0,10"
            $textBox.AcceptsReturn = $true
            $textBox.VerticalScrollBarVisibility = "Auto"
            $textBox.IsReadOnly = $true
            $textBox.MaxLines = 8
            $textBox.VerticalScrollBarVisibility = "Auto"
            $textBox.HorizontalScrollBarVisibility = "Auto"
            $textBox.ResizeMode = "CanResizeWithGrip"
            $copyButton = New-Object System.Windows.Controls.Button
            $copyButton.Content = "Copy"
            $copyButton.Tag = $outputText
            $copyButton.Add_Click({
                $currentButton = $_.Source
                [System.Windows.Clipboard]::SetText($currentButton.Tag)
            })
            $quickCopyButton = New-Object System.Windows.Controls.Button
            $quickCopyButton.Content = "Copy " + ($i + 1) + "/" + $parts
            $quickCopyButton.Tag = $outputText
            $quickCopyButton.Add_Click({
                if ($quickCopyButton.Background -eq "LightBlue") {
                    $quickCopyButton.Background = "Transparent"
                } else {
                    $quickCopyButton.Background = "LightBlue"
                }
                $currentButton = $_.Source
                [System.Windows.Clipboard]::SetText($currentButton.Tag)
            })
            $quickCopyButtonStackPanel.Children.Add($quickCopyButton)
            $stackPanel = New-Object System.Windows.Controls.StackPanel
            $stackPanel.Orientation = "Vertical"
            $stackPanel.Children.Add($textBox)
            $stackPanel.Children.Add($copyButton)
            $separator = New-Object System.Windows.Controls.Separator
            $separator.Margin = "0,5,0,5"
            $outputStackPanel.Children.Add($quickCopyButtonStackPanel)
            $outputStackPanel.Children.Add($stackPanel)
            $outputStackPanel.Children.Add($separator)
        }
        $progressBar.Visibility = "Collapsed"
    })

    # Show the window
    $window.ShowDialog() | Out-Null
}

Create-MainWindow
qDCnqrd.png


A.I Generated changelog:

1. **Reorganized layout**: The layout of the content area has been reorganized to improve usability. The max character count text box, split button, and progress bar are now aligned horizontally.
2. **Added progress bar**: A progress bar has been added to the GUI to indicate when the text is being split.
3. **Improved text box functionality**: The text boxes now have a maximum number of lines set to 8, and they can be resized with a grip.
4. **Added quick copy buttons**: Quick copy buttons have been added to allow users to quickly copy each part of the text without having to open each text box.
5. **Improved copy button functionality**: The copy buttons now toggle their background color when clicked to indicate that the text has been copied.
6. **Added separators**: Separators have been added between each part of the text to improve readability.
7. **Improved performance**: The progress bar is now shown while the text is being split, and hidden when the operation is complete, to improve the user experience.

* The XAML code has been reformatted for better readability.
 
Last edited:

Heimdall

Pro
Joined
Dec 13, 2019
Messages
359
Reputation
211
Daps
839
Twstalker had random popups and not sure what they were doing w/ my data.

I dragged my feet a month but on the bright side, someone came up w/ a guide to self-host nitter:

Instructions are detailed, which I like, but a little convoluted in places. Took me about an hour of troubleshooting to get it working, then had to disable the proxy option in nitter to get videos to play. Since libredirect yanked nitter from their options, I had to double back to good ole redirector and edit my old twstalker redirect:

nNrQRpH.png


Testing w/ random TLR thread w/ a tweet :
5fl2ovM.png


@bnew if you know how to use redirector for embedded tweets, lemme know
I had to block some script with Twstalker to get it to work reasonably okay. My biggest issue with it was that it did not show many replies.

So, I have very reluctantly just set up an instance with the guide you posted, and made an account for that hellhole 🙃

Twitter has been removed from LibRedirect so I have had to update a userscript again.

This is nice though, PaaS is very nice.
 

Macallik86

Superstar
Supporter
Joined
Dec 4, 2016
Messages
6,357
Reputation
1,367
Daps
20,747
👆🏿 On a related note, today I had to add another redirector to account for twitter updating its origin tweets to come from x.com instead of twitter.com

5Dgowbe.png
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
👆🏿 On a related note, today I had to add another redirector to account for twitter updating its origin tweets to come from x.com instead of twitter.com

5Dgowbe.png

you could update it with a capture group and OR pipe to include the x.com so it's in a single rule,

https?://(?:www.)?(?:x|twitter)\.com/(.*?).*
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240

About​

The humble incremental-search task switcher for Windows

Switcheroo Switcheroo Build Status GPL License

Switcheroo is for anyone who spends more time using a keyboard than a mouse. Instead of alt-tabbing through a (long) list of open windows, Switcheroo allows you to quickly switch to any window by typing in just a few characters of its title.

Screenshot​

Screenshot of Switcheroo in action

Download​

Download Switcheroo here

If you use Chocolatey, Switcheroo can be installed with choco install switcheroo.

Usage​


ActionShortcutRemarks
Activate SwitcherooAlt + SpaceThis shortcut can be customized in Options
Activate SwitcherooAlt + TabOnly works if enabled under Options
When Switcheroo is open
Switch to selected windowEnter
Close selected windowCtrl + W
Dismiss SwitcherooEsc
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
used an Llama3 70B Instruct LLM to create this after using a userscript I recently installed for reddit which loaded more comments automatically as a i scrolled .. i've actually tried to do this from scratch a few months ago but couldn't get it to work but building off someone else's examples works a lot better in some cases. two prompts and VOILA!

< AI summary >
This userscript does one simple thing:

Automatically loads more content on twstalker.com when you scroll down to the "Load More" button.

In other words, when you're scrolling through a page on twstalker.com and you get close to the "Load More" button, the script will automatically click that button for you, loading more content without you having to click it yourself.

3nmHP2j.gif


Code:
// ==UserScript==
// @name         Twstalker Load More
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Automatically loads "Load More" on twstalker.com when scrolled near.
// @author       You
// @match        https://twstalker.com/*
// @grant        none
// ==/UserScript==

(function() {
  'use strict';
  const loadMoreSelector = 'a.add-nw-event';
  const loadMoreThreshold = 200; // adjust this value to change the scroll threshold

  function getLoadMoreButton() {
    return document.querySelector(loadMoreSelector);
  }

  function isLoadMoreVisible() {
    const loadMoreButton = getLoadMoreButton();
    if (!loadMoreButton) return false;
    const rect = loadMoreButton.getBoundingClientRect();
    return rect.top <= window.innerHeight + loadMoreThreshold;
  }

  function loadMore() {
    const loadMoreButton = getLoadMoreButton();
    if (loadMoreButton) loadMoreButton.click();
  }

  window.addEventListener('scroll', () => {
    if (isLoadMoreVisible()) loadMore();
  });
})();

image.png

xCF2jiJ.jpeg

second prompt:
Code:
write a userscript for "twstalker.com" that automatically loads "Load More" when i scroll near it. the other values after '="' are dynamic and shouldn't be hardcoded.
```
<a class="add-nw-event" href="#" data-cursor="DAABCgABGP3ntI9__-sKAAIYq-xvbZthAwgAAwAAAAIAAA" data-query="79293791" data-username="rihanna" data-ec="2">Load
                                        More</a>
```

i got the relevant code from a twstalker.com profile
eASvQhK.png


44J93mp.png
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
created another userscript with "llama-3-sonar-large-32k-chat"

AI generated summary:

What it does:
Automatically clicks "Show" and "Yes, view profile" buttons on Twitter and x.com when you scroll near them.

Why it's useful: This script saves you time and effort by automatically clicking these buttons for you, so you don't have to manually click on them every time you want to view content that's hidden behind a warning or a profile preview.

How it works: The script uses a special technique to detect when you're scrolling near a "Show" or "Yes, view profile" button, and then automatically clicks the button for you. This way, you can easily view the content you want to see without having to manually click on the button.



Code:
// ==UserScript==
// @name         Auto-click "Show" and "Yes, view profile" buttons
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Auto-click "Show" and "Yes, view profile" buttons when scrolling near them.
// @author       You
// @match        https://twitter.com/*
// @match        https://x.com/*
// @grant        none
// ==/UserScript==

(function() {
  'use strict';
  var buttons = document.querySelectorAll('button[type="button"]');
  var observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        var button = entry.target;
        if (button.textContent.trim() === 'Show' || button.textContent.trim() === 'Yes, view profile') {
          button.click();
        }
      }
    });
  }, { threshold: 1.0 });

  buttons.forEach((button) => {
    observer.observe(button);
  });

  document.addEventListener('scroll', () => {
    buttons = document.querySelectorAll('button[type="button"]');
    buttons.forEach((button) => {
      observer.observe(button);
    });
  });
})();
 

Pressure

#PanthersPosse
Supporter
Joined
Nov 19, 2016
Messages
44,865
Reputation
6,792
Daps
142,843
Reppin
CookoutGang
created another userscript with "llama-3-sonar-large-32k-chat"

AI generated summary:

What it does:
Automatically clicks "Show" and "Yes, view profile" buttons on Twitter and x.com when you scroll near them.

Why it's useful: This script saves you time and effort by automatically clicking these buttons for you, so you don't have to manually click on them every time you want to view content that's hidden behind a warning or a profile preview.

How it works: The script uses a special technique to detect when you're scrolling near a "Show" or "Yes, view profile" button, and then automatically clicks the button for you. This way, you can easily view the content you want to see without having to manually click on the button.



Code:
// ==UserScript==
// @name         Auto-click "Show" and "Yes, view profile" buttons
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Auto-click "Show" and "Yes, view profile" buttons when scrolling near them.
// @author       You
// @match        https://twitter.com/*
// @match        https://x.com/*
// @grant        none
// ==/UserScript==

(function() {
  'use strict';
  var buttons = document.querySelectorAll('button[type="button"]');
  var observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        var button = entry.target;
        if (button.textContent.trim() === 'Show' || button.textContent.trim() === 'Yes, view profile') {
          button.click();
        }
      }
    });
  }, { threshold: 1.0 });

  buttons.forEach((button) => {
    observer.observe(button);
  });

  document.addEventListener('scroll', () => {
    buttons = document.querySelectorAll('button[type="button"]');
    buttons.forEach((button) => {
      observer.observe(button);
    });
  });
})();
Degenerate brehs rejoice :shaq::mjlit::mjgrin:
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
created another userscript using DeepSeek-Coder-V2, I use pixwox since i don't have an instagram account but the video posts always loads in a new tab. I wanted the video to play right there on the post page instead. it works seamlessly with posts that have a mixture of photos and videos too.

AI generated summary:

The code is a userscript designed to enhance the browsing experience on a website called "pixwox.com" when viewing posts that contain a mix of images and videos.

1. **Identifies Video Previews**: The script looks for special links on the page that are used to show video previews. These links are marked with a specific class name, indicating that they are video containers.

2. **Replaces Previews with Video Players**: When it finds these links, it replaces them with actual video players. This means that instead of just seeing a still image representing the video, you can now play the video directly within the page.

3. **Ensures Proper Sizing and Controls**: The script makes sure that the video player fits well within the space it occupies on the page, maintaining its original aspect ratio. It also adds controls to the video player so you can play, pause, and adjust the volume of the video.

4. **Maintains Gallery Functionality**: Importantly, the script does not disrupt the way you navigate through the gallery of images and videos. You can still swipe or click through the gallery to see the next or previous item, whether it's an image or a video.

In summary, this script improves the way videos are displayed on "pixwox.com" by turning video previews into fully playable videos, all while keeping the gallery's navigation features intact.

Code:
// ==UserScript==
// @name         Replace Video Preview Images with Video Players
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Replace video preview images with HTML5 video players on pixwox.com/post
// @author       Your Name
// @match        https://www.pixwox.com/post/*
// @match        https://www.piokok.com/post/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var videoContainers = document.querySelectorAll('.video_img a');
    videoContainers.forEach(function(container) {
        var videoUrl = container.href;
        var videoElement = document.createElement('video');
        videoElement.src = videoUrl;
        videoElement.controls = true;
        videoElement.style.width = '100%';
        videoElement.style.height = '100%';
        videoElement.style.objectFit = 'contain';
        videoElement.style.position = 'absolute';
        videoElement.style.top = '0';
        videoElement.style.left = '0';
        container.parentNode.replaceChild(videoElement, container);
    });
})();

edit:
7/8/2024
I noticed the domain changed today to piokok.com so I updated the userscript here:
Code:
// @match        https://www.pixwox.com/post/*
// @match        https://www.piokok.com/post/*
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
updated the twstalker userscript and replaced the nitter link with nitter.poast.org instead of the defunct nitter.unixfox.eu. fixed an issue with copy button not including twstalker.com for twstalker links. I also combined the auto load more code i posted previously so pages load automatically as you scroll.

Before:
yLCY4yF.png


After:
PfmLueO.png


Code:
// ==UserScript==
// @name         twstalker Tweet Date Modification & Auto Load More
// @namespace    your_namespace_here
// @description  Modifies tweet-date spans and adds auto-load more functionality for infinite scrolling on twstalker pages
// @include      https://twstalker.com/*
// @version      0.3
// @grant        none
// ==/UserScript==

(function() {
  'use strict';

  var observer = new MutationObserver(modifyTweetDates);

  function createAlertBox(message) {
    var alertBox = document.createElement('div');
    alertBox.textContent = message;
    alertBox.style.position = 'fixed';
    alertBox.style.bottom = '20px';
    alertBox.style.left = '20px';
    alertBox.style.backgroundColor = 'lightgray';
    alertBox.style.padding = '10px';
    alertBox.style.borderRadius = '5px';
    document.body.appendChild(alertBox);
    setTimeout(function() {
      alertBox.style.opacity = '0';
      setTimeout(function() {
        document.body.removeChild(alertBox);
      }, 1000);
    }, 3000);
  }

  function createCopyButton(link) {
    var copyButton = document.createElement('button');
    copyButton.innerHTML = '📋';
    copyButton.style.marginRight = '10px';
  
    if (link.href.startsWith('/')) {
        link.href = 'https://twstalker.com' + link.href;
    }

    copyButton.addEventListener('click', function(e) {
        e.preventDefault();
        navigator.clipboard.writeText(link.href).then(
            function() {
                createAlertBox('Copied!');
            },
            function() {
                createAlertBox('Failed to copy text to clipboard');
            }
        );
    });

    return copyButton;
  }

  // Function to extract the username from a Twitter URL
  function extractUsername(href) {
    var urlParts = href.split('/');
    var usernamePart = urlParts.find(part => /^[a-zA-Z0-9_]+$/.test(part));
    return usernamePart ? usernamePart : null;
  }

  function modifyTweetDates() {
    observer.disconnect();

    var tweetDates = document.querySelectorAll('.user-text3:not(.duplicated)');
  
    tweetDates.forEach(function(tweetDate) {
      var originalLink = tweetDate.querySelector('a[href*="/status/"]');
      var tweetId = originalLink.getAttribute('href').split('/').pop();
      var username = extractUsername(originalLink.getAttribute('href'));

      if (!username) return; // Skip if username couldn't be extracted

      var sLink = document.createElement('a');
      sLink.href = 'https://nitter.poast.org/' + username + '/status/' + tweetId;
      sLink.textContent = 'nitter';
      sLink.style.marginRight = '20px';

      var duplicatedLink = originalLink.cloneNode(true);
      duplicatedLink.href = 'https://twitter.com/' + username + '/status/' + tweetId;

      tweetDate.classList.add('duplicated');

      tweetDate.insertBefore(sLink, tweetDate.firstChild);
      tweetDate.insertBefore(createCopyButton(sLink), tweetDate.firstChild);
      tweetDate.insertBefore(duplicatedLink, tweetDate.firstChild);
      tweetDate.insertBefore(createCopyButton(duplicatedLink), tweetDate.firstChild);
      originalLink.parentNode.insertBefore(createCopyButton(originalLink), originalLink.nextSibling);
    });

    observer.observe(document.body, { childList: true, subtree: true });
  }

  function setupAutoLoadMore() {
    const loadMoreSelector = 'a.add-nw-event'; // Ensure this selector matches the load more button on twstalker.com
    const loadMoreThreshold = 200;

    function getLoadMoreButton() {
      return document.querySelector(loadMoreSelector);
    }

    function isLoadMoreVisible() {
      const loadMoreButton = getLoadMoreButton();
      if (!loadMoreButton) return false;
      const rect = loadMoreButton.getBoundingClientRect();
      return rect.top <= window.innerHeight + loadMoreThreshold;
    }

    function loadMore() {
      const loadMoreButton = getLoadMoreButton();
      if (loadMoreButton) loadMoreButton.click();
    }

    window.addEventListener('scroll', () => {
      if (isLoadMoreVisible()) loadMore();
    });
  }

  // Initialize the auto-load more function
  setupAutoLoadMore();

  modifyTweetDates();
})();

i need to figure out how to incorporate blocking popups on that site.
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240

UserStyles.world​


Free and open-source, community-driven platform for sharing and browsing UserCSS userstyles, and a replacement for UserStyles.org, made by the userstyles community.



The "Stylus" extension is a fork of the popular Stylish extension which can be used to restyle the web. Not "ish", but "us", as in "us" the actual users. Stylus is a fork of Stylish that is based on the source code of version 1.5.2, which was the most up-to-date version before the original developer stopped working on the project. The objective in creating Stylus was to remove any and all analytics, and return to a more user-friendly UI. We recognize that the ability to transfer your database from Stylish is important, so this is the one and only feature we've implemented from the new version.

Features​



 

bnew

Veteran
Joined
Nov 1, 2015
Messages
51,004
Reputation
7,865
Daps
147,240
firefox can't save webpages to a single file natively like chromium/chrome based browsers can to ".mthml" files. SingleFile addon for firefox saves webpages quite well into a single .html . it even works to save reddit threads and chats on huggingface.co chats , preserving the css etc.



SingleFile by gildas

Recommended
Available on Firefox for Android™Available on Firefox for Android™
Save an entire web page—including images and styling—as a single HTML file.

Screenshots
Contextual menu of SingleFile
Using SingleFile to save a web page on Wikipedia
Using SingleFile to annotate and save a web page on Wikipedia

About this extension
SingleFile is an add-on for Firefox Desktop and Mobile that helps you to save an entire webpage including images, styling, frames, fonts etc. as a single HTML file.

Getting started
  • Wait until the page is fully loaded.
  • Click on the SingleFile button in the extension toolbar to process and save the page.
  • You can click again on the button to cancel the action when processing a page.
Demo: https://www.youtube.com/watch?v=oVvTmcwxvmc


Additional notes
  • Open the context menu by right-clicking the SingleFile button in the extension toolbar or on the webpage. It allows you to save:
    • the current tab,
    • the selected content,
    • the selected frame,
    • the selected link(s).
  • Select "Annotate and save the page..." in the context menu to:
    • Highlight text,
    • add notes,
    • remove content.
  • You can also process multiple tabs in one clickand save:
    • the selected tabs,
    • the unpinned tabs,
    • all the tabs.
  • The context menu also allows you to activate the auto-save (after pages are being loaded) of:
    • the current tab,
    • the unpinned tabs,
    • all the tabs.
  • Right-click on the SingleFile button and select "Manage extension" to open the options page.
  • Enable the option "Destination > save to Google Drive" to upload pages to Google Drive.
  • Enable the option "Destination > save to GitHub" to upload pages to GitHub.
  • Enable the option "Misc. > add proof of existence" to prove the existence of saved pages by linking the SHA256 of the pages into the blockchain.
  • You can use the customizable shortkey Ctrl+Shift+Y to save the current tab or selected tabs.
  • And more!
More info

FAQ: https://github.com/gildas-lormeau/SingleFile/blob/master/faq.md
Known issues: https://github.com/gildas-lormeau/SingleFile#known-issues

See the extension help in the options page for more detailed information about the options.
Project on GitHub: https://github.com/gildas-lormeau/SingleFile
 
Top