Lemmy Plugins and Userscripts

2528 readers
1 users here now

A general repository for user scripts and plugins used to enhance the Lemmy browsing experience.

Post (or cross-post) your favorite Lemmy enhancements here!

General posting suggestions:

Thanks!

founded 2 years ago
MODERATORS
1
 
 

Browser Extensions:

Mullem (Firefox):

lemmy-keyboard-navigation (Chrome):

Instance Assistant:

Lemmy Link:

Lemmy Go:

Lemmy Modern UI (Firefox Addon):

Lemmy Home Instance Helper:

Userscripts:

LemmyTools:

Lemmy Image Expand:

Lemmy Universal Link Switcher:

Compact Lemmy to old.Reddit Re-format:

Lemmy/KBin Redir:

GM Lemmy NewTab:

Lemmy Style Cleanup:

lemmy-keyboard-navigation:

Lemmy Federation Awareness:

Lemmy Subscription Helper:

Block lemmy instances:

Lemmy Local Community Redirect:

Lemmy Custom Navbar Links:

beehaw lemmy add home-instance name to username:

beehaw lemmy separate spacing of delete and edit buttons:

Lemmy post filter - Filter posts by title:

Lemmy Post Keyword Filter:

Filter lemmy.ml communities:

2
 
 

Table of Contents

  1. Introduction
  2. What is a UserScript?
  3. Installing a UserScript Manager
    • Installing Tampermonkey on Chrome
    • Installing Violentmonkey on Chrome
    • Installing Tampermonkey on Firefox
    • Installing Greasemonkey on Firefox
    • Installing Violentmonkey on Firefox
  4. Adding a UserScript
  5. Conclusion

Introduction

UserScripts are an incredible way to enhance and customize your browsing experience. They allow you to alter the functionality and layout of web pages, like Lemmy UI, by executing JavaScript codes on the client side. In this guide, we'll walk you through the process of installing UserScripts in your Chrome or Firefox browser.

What is a UserScript?

UserScripts are bits of code written in JavaScript that run in your web browser. They can modify the content, layout, and behavior of web pages. The true power of UserScripts lies in their ability to tailor your browsing experience to your needs.

Installing a UserScript Manager

To run UserScripts, you'll need to install a UserScript manager extension. Two popular ones are Tampermonkey and Greasemonkey.

Installing Tampermonkey on Chrome

  1. Open the Chrome web browser.
  2. Go to the Tampermonkey page on the Chrome Web Store.
  3. Click the "Add to Chrome" button.
  4. Confirm by clicking "Add extension" in the pop-up window.

Installing Violentmonkey on Chrome

  1. Open the Chrome web browser.
  2. Go to the Violentmonkey page on the Chrome Web Store.
  3. Click the "Add to Chrome" button.
  4. Confirm by clicking "Add extension" in the pop-up window.

Installing Tampermonkey on Firefox

  1. Open the Firefox web browser.
  2. Go to the Tampermonkey page on the Firefox Add-ons site.
  3. Click the "Add to Firefox" button.
  4. Confirm by clicking "Add" in the pop-up window.

Installing Greasemonkey on Firefox

  1. Open the Firefox web browser.
  2. Go to the Greasemonkey page on the Firefox Add-ons site.
  3. Click the "Add to Firefox" button.
  4. Confirm by clicking "Add" in the pop-up window.

Installing Violentmonkey on Firefox

  1. Open the Firefox web browser.
  2. Go to the Violentmonkey page on the Firefox Add-ons site.
  3. Click the "Add to Firefox" button.
  4. Confirm by clicking "Add" in the pop-up window.

Adding a UserScript

Now that you have a UserScript manager installed, you can add your own scripts. Here's how:

  1. Click on the Tampermonkey or Greasemonkey icon in your browser toolbar.
  2. Choose "Create a new script..." from the dropdown menu.
  3. You'll be taken to a new tab with a script template. Delete this template.
  4. Copy your UserScript and paste it into the empty field.
  5. Click "File" and then "Save" in the editor menu.

That's it! Your UserScript is now installed and will run on the sites specified in its metadata.

Conclusion

UserScripts offer an incredible way to customize your web browsing experience. Whether you're using Chrome or Firefox, Tampermonkey, Greasemonkey or Violentmonkey, you can create a browsing environment that's uniquely suited to your needs. Happy scripting!

Remember, while UserScripts are powerful tools, they should be used responsibly. Don't install scripts from sources you don't trust, as they can pose security risks. Always review the code of a UserScript before installing it to ensure it doesn't contain anything malicious.

3
 
 

Feel free to give it a spin and add any feature requests on github!

4
 
 

I know it could be stupid but please someone offer some help in this regard :(

5
 
 

Hi everyone, I'm excited to announce one more release before I take a short break. I have some other stuff starting up, so I won't be pushing out new features as fast, but I'll still be around to manage the project. (more at the end)

Links:


❓ What is Instance Assistant?

If you're new to Instance Assistant, it is a browser extension with a collection of tools and features to simplify your browsing experience on Lemmy and Kbin. It is available on Chrome, Firefox, and Edge; you can also install it from the releases page on GitHub.

For a full list of features, please see the GitHub homepage: https://github.com/cynber/lemmy-instance-assistant


⭐ What's new in v1.2.5?

  • Redirect posts to your home instance!: Post pages now have a redirect button that will find the same post on your home instance(1). You don't have to hunt it down yourself anymore.
  • Posts related to this webpage buttons in popup & sidebar
    • Make a post: You can now create a post from any webpage! Click the 'Make a Post' button in the extension popup or sidebar to generate a draft post with autofilled title, URL, and body contents. Afterwards, just select a community and hit post. (This currently works for both Lemmy & Kbin, but custom frontends are untested while they develop). Try it here: https://lemmy.ca/post/4478560
    • Open Posts: This will find any posts about the webpage/article/video that you are looking at. Use it to see if something has already been posted, or to find related discussions about it. When there are multiple posts, it will ask before opening them all. (see note on risks and why it doesn't count automatically)
  • Post an image: You can now right-click on an image, anywhere on the web, and hit "Post this image". It will open a new tab and autofill the title, image link, and add the page URL to the body as "Source: URL". Try it here: https://lemmy.ca/post/1282303
  • Reorganizing popup:
    • I fixed the issue where the popup would still display a button after removing all instances from the list.
    • The number of default instances in the popup was reduced to 4
  • Added settings:
    • You can now hide onboardining guides to make the interfaces less wordy
  • General styling changes, wording improvements, and bugfixes

(1) This is an important feature to me because this little annoyance was part of why I set out to create the extension in the first place. Thanks to some help from @zero_gravitas, I was able to use the Lemmy API to grab the post details, and then run a search for it on your home instance. While most posts should only bring one result, there is a chance that there are multiple posts by the same user, in the same community, with the same title. If this is an issue, I'll make this search more specific.


🗣️ My questions for you:

Improving 'post to Lemmy'

  • Right now the 'Post to Lemmy' button does a very basic search in the page meta tags for information. This works for most websites, but it is not perfect. What websites do you usually post from, and is the extension doing a good job of replicating how you format the post? Please share both good and bad examples, so we can fix what isn't working and keep what is.

Improving Post search

  • Having the extension automatically count the number of posts and display it in the icon would be pretty nice, since then you would know about any posts for the news article / blog / video that you are looking at. However, there are privacy implications with this since it needs to send the URL to your home instance to do the search.
  • I would like to add the option to whitelist specific websites, so the user can choose what browsing data they want to find posts for. Is this something you would list to use? What websites would you whitelist?

Anything else?

Please share any issues that you find. Lemmy and Kbin instances have a lot of variation in how things are structured, so there are bound to be some bugs that I haven't found yet. If you have any ideas for new features, please share them too! I'm always looking for new ideas to add to the project.


🔮 Cool ideas being discussed for the future

  • Account switcher & ability to save login info to extension
  • Reddit migrator tools
    • multireddit input should convert subscriptions to official Threadiverse replacements, or large related communities
    • embeds on Subreddit sidebars to search for similar community
    • button on post pages to cross-post to home instance
  • Prepping for Firefox Mobile app, now that they are opening mobile up to all extensions!
  • Keyboard hotkeys, possibly collaborating with someone that already implemented something similar

For the most up to date information, see the issues or the project road map


💛 Finally

Thank you for all the suggestions and feedback so far! I'm really happy to see that people are using the extension and finding it useful. I'm looking forward to seeing what we can do with it in the future.

Like I said above, I won't be as active over the next few months in terms of getting new features out. The extension is now in good shape, and it covers most of the important use cases. There's still lots of cool stuff we can do with it, so please contribute ideas and expertise! When I get a chance, I'll pop in and grab a few more issues.

Cheers :)

6
 
 

I mean, I wanted to start work on it, but if someone's already released/working on one then I'd just happily use those instead.

Also, the absence of a thing usually means it's not possible to have. In my mind I think it's easy to have userscript code make API posts on behalf of the user, but maybe somehow in the intricate layers of tech it's made impossible or tedious. If so, I'd like to know before I learn it the hard way.

7
3
submitted 2 years ago* (last edited 2 years ago) by ShittyKopper@lemmy.blahaj.zone to c/plugins@sh.itjust.works
 
 

There are likely various edge cases I've missed, and I am not too sure on performance compared to a purpose-built userscript, but these seem to work well enough for my use cases.

Throw these to My filters in uBO settings. May also work with AdGuard, but I can't support you there as I don't use it. Other ad blockers probably won't work, but then why are you using an ad blocker that isn't uBO anyway?

Remove the exclamation mark preceding the rules and adjust the placeholders accordingly. If you need multiple filters copy paste the appropriate lines.

You may need to replace the lemmy.* part if your home instance is on a different (sub)domain. I'm not using .lemmy-site and a global selector for performance reasons.

! Post filters use :has instead of :upward to take advantage of native CSS support on browsers that implement it.
! If :has is not implemented, uBO will emulate it via JS. :upward might be more efficient on those cases.

! Lemmy: Filter post by link domain
! lemmy.*##.post-listing:has(.fst-italic[href*="example.com"])

! Lemmy: Filter post by keyword in title
! lemmy.*##.post-listing:has(.post-title:has-text(/\bkeyword\b/i))

! Lemmy: Filter post by author instance
! lemmy.*##.post-listing:has(.person-listing[title$="@example.com"])

! Lemmy: Filter post by community instance
! lemmy.*##.post-listing:has(.community-link[title$="@example.com"])

! Lemmy: Filter post by instance (author or community)
! lemmy.*##.post-listing:has([title$="@example.com"]:is(.person-listing, .community-link))

! Lemmy: Filter post by community name (any remote instance)
! lemmy.*##.post-listing:has(.community-link[title^="!politics@"])

! Lemmy: Filter post by community name (home instance, though in this case you can just use lemmy's own blocking)
! lemmy.*##.post-listing:has(.community-link[title="!politics"])

! Lemmy: Filter comment by keyword 
! lemmy.*##.md-div:has-text(/\bkeyword\b/i):upward(.comment)

! Lemmy: Filter comment by author instance
! lemmy.*##.person-listing[title$="@example.com"]:upward(.comment)

! Lemmy: Filter both by author instance
! lemmy.*##.person-listing[title$="@example.com"]:upward(:is(.post-listing, .comment))
8
 
 

cross-posted from: https://lemmy.blahaj.zone/post/1312795

[Image description: A screenshot of the lemmy.blahaj.zone front page with a custom userstyle applied. The userstyle features a dark gray background with medium gray text and brightly-colored accents of purple, pink, orange, and cyan. The right sidebar cards are a light shade of gray with lighter gray text, pink buttons, and orange links]

A few weeks ago I decided to try my hand at bringing my favorite theme to Lemmy and this userscript was born. It's still in the early stages so there are some wrinkles to iron out, but I just pushed a big update with better contrast, style fixes, and streamlined code.

I've received several requests to turn it into a native Lemmy theme but have no idea how to do that. If anyone has any tips on theming, interest in collaborating, or a Lemmy instance where I could test a native theme, hit me up! You can find all the code here on Codeberg.

9
 
 

Currently, Lemmy sorts the comments by Hot, and there is no way to change this. This scripts changes the default behavior to sort by Top, this default can be changed by editing the defaultSort variable in the code.

10
 
 

cross-posted from: https://thesimplecorner.org/post/91450

LemmyTools 0.2.0.5 is released! I believe this is the most functional release yet mainly due to some fantastic contributions from other folks on github who are definitely better programmers than I am! I just want to personally say thank you to:

  • @cwagner@lemmy.cwagner.me - For coding, code cleanup, and mentoring.
  • Charles Machalow - csm10495 - Coding contribution(s).
  • jimmyhiggs337 - Coding contribution(s).

I am happy to say that the image expansion, and "show all" functionality is much more reliable and customizable now.

More improvements/features are being developed. Please check back often and check updates at least every day. Please create a ticket on github or message me with your issues, thoughts and feature requests.

Also, if anyone is able to message me about beginning to start moving this UserScript to a browser addon please see this post.

Installation and Configuration:

1 - Browser must have a Userscript addon (Tampermonkey, Greasemonkey, Etc...). Tested with Greasemonkey.

2 - Download either the .JS file or install from greasyfork.

3 - Set home lemmy instance via options page once script is loaded (and manually edit the homeInstance variable in script for all functionality)

This script is all done by a complete amateur for fun. Enjoy and feel free to fork it!

Get it here: Github or GreasyFork

Please submit issues to the github for feature requests and problems: Github LemmyTools Issues

11
 
 

cross-posted from: https://lemmy.ca/post/1418762

I've made a number of improvements since the last time I was posting about my extension. The update is now available on both Firefox and Chrome web stores.

For questions / support: !instance_assistant@lemmy.ca

TLDR: See the respective download pages on Firefox & Chrome. The screenshots and features list are mostly self-explanatory.

Note on versions:

  • Firefox has a more recent 1.2.1 version, because my build script missed some files while uploading v1.2.0. It doesn't look like Chrome had this issue.
  • I'm uploading v1.2.2 to both stores today, which will bring the two missing features to Chrome as well. After 1.2.2, all browsers should have the same features. See below for details.

So how is this different from other similar extensions?

You may have noticed the extension's name changed to be more generic (and include Kbin 🥳). I'm trying to make this a more well-rounded extension, and that means I've incorporated some features from the other extensions, in my own way.

Lemmy Links, Kbin Links, and the other forks:

This is a great extension that replaces links on your page with versions that go to your home instance. However, in order for this to work, it needs to recursively check every element on your page whenever DOM content (the stuff the browser is reading) changes. This is somewhat resource intensive, and while testing I ran into lag and freezing issues. As such, I decided to not include this functionality in the same way.

Instead, I've added a right click context menu that does the same thing. This way the user can pick which links they want the extension to convert, and it's a lot more efficient resource wise. While it's an extra click, I felt this was a reasonable compromise. However, I'm open to feedback!

NOTE: The context menu is available on Firefox, and it will be available in Chrome in about a week, depending on when they approve my update.

Lemmy Home Instance Helper

This is another extension which checks if you are logged in to an instance, and it creates a button to the search page if you are not. As my extension creates a button on any foreign instance, the search page is only helpful when a community hasn't been loaded into your home instance yet (ex. because you're the first one to try accessing it).

To deal with this, my extension modifies the "Community not found" pages with more instructions, as well as buttons to trigger the fetch process or to open the community elsewhere. See this screenshot for an example. Again, open to feedback!


As always, I'd love to collaborate with other people while building this. I'm still cleaning up my code, but feel free to look at the GitHub. If this extension gets popular, I will definitely need help for translations and for things like getting the extension on Safari (I don't have a recent Apple device to sign the extension with).


Note on permissions:

  • The current versions request "Access to all sites". This is because the extension needs access to any page that contains "/c/", "/m/", or "/post/" in order to create the sidebar buttons. While the extension only looks for those pages, it will show up as "Access to all sites" when installing. Once I have a proper welcome message and settings page, I plan on making this permission optional so you can just use the popup menu if you would like.

Summary of Recent Changes:

  • Added support for Kbin
  • Fixed issue where button wouldn't load when navigating to a community within Lemmy (available on Firefox, should be on Chrome in a week).
  • (NEW) Right-click context menu on Lemmy/Kbin community links to let you open them directly. You can test them out here: https://lemmy.ca/post/1282303 (available on Firefox, should be on Chrome in a week)
  • (NEW) Information and buttons added to "Community Not Found" error pages to let you fetch the community or open it elsewhere.
  • Updates to sidebar button to state the current selected instance and provide more detailed instructions as a dropdownList
  • Refactored the code to remove more unnecessary permissions.
  • Another pile of bugfixes, UI improvements, and better wording for instructions.

Future Plans:

  • This is complete and will be in v1.2.2. ~~Bringing over the new changes to Google Chrome. Since chrome requires Manifest 3, I still need to iron out some issues with the service workers. The missing features are all related to the background processes that are running on the Firefox version~~
  • Pushing to other browsers: Microsoft Edge & Opera are still reviewing v1.2.0. Unfortunately, I don't have any immediate plans for Safari, as I don't have a device that can sign the extension. I am looking into getting help for that.
  • Setting up a proper Welcome page, Settings page, and Options menu to allow users to turn off features that they don't like. This will also let me make "access to all sites" optional.
  • Finishing the translations' setup so that people can contribute other languages to the extension.
  • Adding an option to save your own instances to the popup, for those that have multiple home instances.
12
 
 

cross-posted from: https://lemmy.ml/post/1999101

tl;dr: With Lemmy Go you type lg beekeeping on the address bar and it takes you to the most popular beekeeping community, or you can pick one from the given suggestions.

Get Lemmy Go for Firefox

Get Lemmy Go for Chrome

More information about Lemmy Go on GitHub

Why

On Reddit, I had a simple search keyword for navigating directly to subreddits, where I could just type r firefox and be taken to reddit.com/r/firefox.

I wanted to have the same behavior for Lemmy, but the Fediverse makes this a lot more complicated.

So I made Lemmy Go to try and make it as simple as possible to jump to a community, or even find new ones more easily.

It's still a work in progress, so it might be a bit unstable and missing a bunch of features. But I've been using it myself for a few days, and it's already pretty helpful.

Usage

Type lg followed by a space (some browsers also accept tab instead), and then type the name of the community you're looking for.

Example: lg linux

Lemmy Go will search its database for any community that has the text linux in its name (e.g. linux_gaming) or title (Linux Gaming).

If you just type a community name and press enter, Lemmy Go will take you to the most popular community from that list.

If you don't press enter right away, you will be shown a list of communities that match that query. You can then select the specific one you want.

Preferred Instance

If you set your preferred instance in the user settings (click the extension icon), Lemmy Go will try its best to navigate to that community in your preferred instance, although this isn't always possible (in which case Lemmy Go will just navigate to the remote instance instead).

For instance, if your preferred instance is set to lemmy.ml and you select firefox@lemmy.world, Lemmy Go will take you to lemmy.ml/c/firefox@lemmy.world.

But if lemmy.ml blocks the lemmy.world instance, then Lemmy Go will take you to lemmy.world/c/firefox instead.

Read the readme on GitHub for more information about how Lemmy Go works

13
42
submitted 2 years ago* (last edited 2 years ago) by howdy@thesimplecorner.org to c/plugins@sh.itjust.works
 
 

cross-posted from: https://thesimplecorner.org/post/83502

LemmyTools - ReadMe

Current Features: 0.2.0.1

  • All external links open in new tab with noreferrer enabled
  • Adds a positional side bar that has a searchable list of communities
  • Click&drag to resize images
  • Set image size after clicking thumbnail
  • Hide Lemmy Sidebars
  • Show all images on page automatically or by a button click - 0.2.0.1 - (works with all languages now and can be disabled)
  • Adds the ability to use the old.reddit style script by soundjester/lemmy_monkey: https://github.com/soundjester/lemmy_monkey (Also: Option to edit post and comment size for easier reading).
  • Auto unblur NSFW images
  • A link back to home instance on remote instances
  • Browse remote community on home instance
  • Subscribe to instance easier that doesn't exist on your home instance.
  • Works and styled for mobile use as well.

Installation and Configuration:

1 - Browser must have a Userscript addon (Tampermonkey, Greasemonkey, Etc...). Tested with Greasemonkey.

2 - Download either the .JS file or install from greasyfork.

3 - Set home lemmy instance via options page once script is loaded (and manually edit the homeInstance variable in script for all functionality)

This script is all done by a complete amateur for fun. Enjoy and feel free to fork it!

Get it here: Github or GreasyFork

Please submit issues to the github for feature requests and problems: Github LemmyTools Issues

___

14
 
 

This is a style I primarily made for myself, but why not share it. It's inspired by some of the old subreddit styles and the old youtube design.

  • Should work with litely and darkly plus compact variants.
  • Uses rounded thumbnails to external links.
  • Uses square thumbnails to internal images.
  • Colored proprietary social media thumbs with their brand colors. (So you don't accidentally click on a youtube link for example).

There still are some things I have to fix in the dark theme, like buttons and card headers for example.

15
 
 

Using this with Stylus:

li .comment-node {
    padding: 0.5ex;
    border: 0.1ex solid #80808060 !important;
    border-radius: 1ex;
}

li li .comment-node {
    border-left: none !important;
    border-top: none !important;
    border-radius: 1ex 1ex 1ex 0 !important;
}

Or for a more lightweight change:

.comment-node {
    border-bottom: 0.1ex solid #80808060 !important;

It's the lack of clearly visible separation between comments that just doesn't look right to me.

16
 
 

Forked from @boobslider100@lem.ee's script - I just modified it to navigate Lemmy with arrows instead. I find it much easier than using J/K. Right/Left arrows have dual usage also, as they can both change the page and jump to next/previous same level comment :)

Down = Next post / comment
Up = Previous post / comment
Right = Next page / parent comment
Left = Previous page / parent comment
A = Upvote
Z = Downvote
X = Expand
C = View Comments
Enter = View Link

I made it for me but feel free to give it a go and let me know what you think!

17
 
 

cross-posted from: https://thesimplecorner.org/post/75779

#LemmyTools - 0.1.2.7 Released:

  • New Feature: Open All Images Button and Option.

  • Added "Browse community on home instance button on remote page".

A note about font size:

With the release of Lemmy 0.18.1 - The overall font for desktop users is slightly uncomfortably small... not due to the script but lemmy dev's stylistic choices that changed then entire lemmy UI at 0.18.1... Disabling the old.reddit pack may help or try to adjust your browser zoom. If this persists I will add some styling to fix the issue but don't want to have to work on all of that if it is a transient deal in 0.18.1. I'd rather add new features.

Thank you. --

18
7
submitted 2 years ago* (last edited 2 years ago) by tristar@lemmyfly.org to c/plugins@sh.itjust.works
 
 

Install

Hi,

This is just a little helper script which adds buttons to posts and comments on any Lemmy instance except your own which lead to a search page in your home instance allowing you to quickly interact with content.

For now this is just a bunch of buttons, but ideally it'd be a fully-featured script that presents you with a proper text field for commenting/replying and buttons for voting. This is just the initial release and I'll be working to make the script better and save even more time while slacking off on Lemmy :P

Usage

Click the big 'Install' button above, then approve the script on the page displayed by your userscript manager. I've tested it on Violentmonkey and Tampermonkey with Firefox.

After installing, go to any Lemmy instance and enter your home instance's domain into the prompt (just the domain, like lemmy.world or sh.itjust.works and nothing else). You can change this domain later by clicking on your manager's icon, then on "Change home instance" below the script's name.

From now on you'll see blue buttons ("[ comment on own instance instead ]" on posts and "[ C ]" on comments) outside your specified home instance. Click on any to go to a search page on your own instance, then click the link icon if you're interacting with a comment or post title if with a post, then reply or vote on content as you desire.

This is the first release, so might be prone to breaking and isn't very beautiful yet. Please report any issues and send suggestions via DM or in the comments below.

Thanks and happy using.

19
 
 

cross-posted from: https://lemmy.world/post/1060796

See the linked page for information about how it works, limitations, etc. and I'll of course answer any questions below!

As I have stated in the release section, this software is alpha so please don't be afraid to report bugs!

Releases are here: https://github.com/CMahaff/lasim/releases

Right now the program only supports Lemmy BE 0.18.1-rc9, but new releases will try to support new versions as they are released. The Lemmy API is changing a ton right now, but I'll try to keep up.

Note: Supports 0.18.1-rc9+ - I have tested it with rc9, rc10, and the final release of 0.18.1.

20
 
 

cross-posted from: https://thesimplecorner.org/post/69244

Github: https://github.com/howdy-tsc/LemmyTools

Greasyfork: https://greasyfork.org/en/scripts/469169-lemmytools

Installation and Configuration as of 0.1.2.5

1 - Browser must have a Userscript addon (Tampermonkey, Greasemonkey, ViolentMonkey, Etc…).

2 - Install from greasyfork or download LemmyTools.js from GitHub.

3 - Set home lemmy instance via options page once script is loaded (and manually edit the homeInstance variable in script for all functionality.)

This script is all done by a complete amateur for fun. Enjoy and feel free to fork it!

Get it here: Github or GreasyFork

Please submit issues to the github for feature requests and problems: Github LemmyTools Issues

21
 
 

I'm currently using const prefersDarkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches; but it doesn't take into consideration users that use a light system with a dark website.

EDIT: Solved with the following:

const element = document.getElementById("app");
const themeVariant = element.getAttribute("data-bs-theme");
if (themeVariant === "light") {
    var primaryBackground = "#f0f0f0";
} else {
    var primaryBackground = "#121317";
}
22
 
 

cross-posted from: https://thesimplecorner.org/post/62430

New/Fixes: 0.1.2.3:

  • Completely re-worked expanding images. Should be much better.
  • LemmyTools Bar is hidden by default. Option added in settings to keep it open. Now all CSS. -Comments and Feedback on this versus the click to toggle method used before.
  • Removed scroll bars persisting in google chrome on LemmyTools bar.
  • Message for homeInstance variable added to option page if not added.
  • Elemenation of poor eventHandlers leads to much better perforamnce.
  • old.reddit theme from soundjester/lemmy_monkey now being added from cdn instead of manually.

Installation and Configuration:

1 - Browser must have a Userscript addon (Tampermonkey, Greasemonkey, Etc...). Tested with Greasemonkey.

2 - Download either the .JS file or install from greasyfork.

3 - Set home lemmy instance via options page once script is loaded (and manually edit the homeInstance variable for the offsite home instance fix.

This script is all done by a complete amateur for fun. Enjoy and feel free to fork it!

Github: https://github.com/howdy-tsc/LemmyTools

Greasyfork: https://greasyfork.org/en/scripts/469169-lemmytools

Please submit issues to the github for feature requests and problems: Github LemmyTools Issues

Minimized by default:

LemmyTools Bar:

23
 
 

Rewrote something I made for kbin to work with lemmy. Mimics some of RES' keyboard navigation functionality.

Edit: updated so that expanded images scroll into view.

Edit 2: 2023/07/04

  • added ability to open links/comments (hold shift to open in new tab, might have to disable popup blocker)
  • traversing through entries while expand was toggled on will collapse previous entry and expand current entry preview
  • handle expanding of text posts

Edit 3: 2023/07/04

  • add ability to change to next/previous page

Edit 4: 2023/07/06

  • updated scroll into view logic
  • prevent shortcut actions when modifier keys are held (ctrl+c won't load comment page anymore)
  • updated open link button to also consider images with external links
  • updated user script metadata section for compatibility per @God@sh.itjust.works
  • navigating to next/previous page while in "expand mode" will auto-expand the first post of the new page
// ==UserScript==
// @name             lemmy navigation
// @description      Lemmy hotkeys for navigating.
// @match            https://sh.itjust.works/*
// @match            https://burggit.moe/*
// @match            https://vlemmy.net/*
// @match            https://lemmy.world/*
// @match            https://lemm.ee/*
// @version          1.2
// @run-at           document-start
// ==/UserScript==

// Set selected entry colors
const backgroundColor = 'darkslategray';
const textColor = 'white';

// Set navigation keys with keycodes here: https://www.toptal.com/developers/keycode
const nextKey = 'KeyJ';
const prevKey = 'KeyK';
const expandKey = 'KeyX';
const openCommentsKey = 'KeyC';
const openLinkKey = 'Enter';
const nextPageKey = 'KeyN';
const prevPageKey = 'KeyP';


const css = [
".selected {",
"  background-color: " + backgroundColor + " !important;",
"  color: " + textColor + ";",
"}"
].join("\n");

if (typeof GM_addStyle !== "undefined") {
    GM_addStyle(css);
} else if (typeof PRO_addStyle !== "undefined") {
    PRO_addStyle(css);
} else if (typeof addStyle !== "undefined") {
    addStyle(css);
} else {
    let node = document.createElement("style");
    node.type = "text/css";
    node.appendChild(document.createTextNode(css));
    let heads = document.getElementsByTagName("head");
    if (heads.length > 0) {
        heads[0].appendChild(node);
    } else {
        // no head yet, stick it whereever
        document.documentElement.appendChild(node);
    }
}
const selectedClass = "selected";

let currentEntry;
let entries = [];
let previousUrl = "";
let expand = false;

const targetNode = document.documentElement;
const config = { childList: true, subtree: true };

const observer = new MutationObserver(() => {
    entries = document.querySelectorAll(".post-listing, .comment-node");

    if (entries.length > 0) {
        if (location.href !== previousUrl) {
            previousUrl = location.href;
            currentEntry = null;
        }
        init();
    }
});

observer.observe(targetNode, config);

function init() {
    // If jumping to comments
    if (window.location.search.includes("scrollToComments=true") &&
        entries.length > 1 &&
        (!currentEntry || Array.from(entries).indexOf(currentEntry) < 0)
    ) {
        selectEntry(entries[1], true);
    }
    // If jumping to comment from anchor link
    else if (window.location.pathname.includes("/comment/") &&
            (!currentEntry || Array.from(entries).indexOf(currentEntry) < 0)
    ) {
        const commentId = window.location.pathname.replace("/comment/", "");
        const anchoredEntry = document.getElementById("comment-" + commentId);

        if (anchoredEntry) {
            selectEntry(anchoredEntry, true);
        }
    }
    // If no entries yet selected, default to first
    else if (!currentEntry || Array.from(entries).indexOf(currentEntry) < 0) {
        selectEntry(entries[0]);
        if (expand) expandEntry();
    }

    Array.from(entries).forEach(entry => {
        entry.removeEventListener("click", clickEntry, true);
        entry.addEventListener('click', clickEntry, true);
    });

    document.removeEventListener("keydown", handleKeyPress, true);
    document.addEventListener("keydown", handleKeyPress, true);
}

function handleKeyPress(event) {
    if (["TEXTAREA", "INPUT"].indexOf(event.target.tagName) > -1) {
        return;
    }

    // Ignore when modifier keys held
    if (event.altKey || event.ctrlKey || event.metaKey) {
        return;
    }

    switch (event.code) {
        case nextKey:
        case prevKey:
            let selectedEntry;

            // Next button
            if (event.code === nextKey) {
                // if shift key also pressed
                if (event.shiftKey) {
                    selectedEntry = getNextEntrySameLevel(currentEntry);
                } else {
                    selectedEntry = getNextEntry(currentEntry);
                }
            }

            // Previous button
            if (event.code === prevKey) {
                // if shift key also pressed
                if (event.shiftKey) {
                    selectedEntry = getPrevEntrySameLevel(currentEntry);
                } else {
                    selectedEntry = getPrevEntry(currentEntry);
                }
            }

            if (selectedEntry) {
                if (expand) collapseEntry();
                selectEntry(selectedEntry, true);
                if (expand) expandEntry();
            }
            break;
        case expandKey:
            toggleExpand();
            expand = isExpanded() ? true : false;
            break;
        case openCommentsKey:
            if (event.shiftKey) {
                window.open(
                    currentEntry.querySelector("a.btn[title$='Comments']").href,
                );
            } else {
                currentEntry.querySelector("a.btn[title$='Comments']").click();
            }
            break;
        case openLinkKey:
            const linkElement = currentEntry.querySelector(".col.flex-grow-0.px-0>div>a") || currentEntry.querySelector(".col.flex-grow-1>p>a");
            if (linkElement) {
                if (event.shiftKey) {
                    window.open(linkElement.href);
                } else {
                    linkElement.click();
                }
            }
            break;
        case nextPageKey:
        case prevPageKey:
            const pageButtons = Array.from(document.querySelectorAll(".paginator>button"));

            if (pageButtons) {
                const buttonText = event.code === nextPageKey ? "Next" : "Prev";
                pageButtons.find(btn => btn.innerHTML === buttonText).click();
            }
    }
}

function getNextEntry(e) {
    const currentEntryIndex = Array.from(entries).indexOf(e);
    
    if (currentEntryIndex + 1 >= entries.length) {
        return e;
    }
    
    return entries[currentEntryIndex + 1];
}

function getPrevEntry(e) {
    const currentEntryIndex = Array.from(entries).indexOf(e);
    
    if (currentEntryIndex - 1 < 0) {
        return e;
    }
    
    return entries[currentEntryIndex - 1];
}

function getNextEntrySameLevel(e) {
    const nextSibling = e.parentElement.nextElementSibling;

    if (!nextSibling || nextSibling.getElementsByTagName("article").length < 1) {
        return getNextEntry(e);
    }
    
    return nextSibling.getElementsByTagName("article")[0];
}

function getPrevEntrySameLevel(e) {
    const prevSibling = e.parentElement.previousElementSibling;

    if (!prevSibling || prevSibling.getElementsByTagName("article").length < 1) {
        return getPrevEntry(e);
    }
    
    return prevSibling.getElementsByTagName("article")[0];
}

function clickEntry(event) {
    const e = event.currentTarget;
    const target = event.target;

    // Deselect if already selected, also ignore if clicking on any link/button
    if (e === currentEntry && e.classList.contains(selectedClass) &&
        !(
            target.tagName.toLowerCase() === "button" || target.tagName.toLowerCase() === "a" ||
            target.parentElement.tagName.toLowerCase() === "button" ||
            target.parentElement.tagName.toLowerCase() === "a" ||
            target.parentElement.parentElement.tagName.toLowerCase() === "button" ||
            target.parentElement.parentElement.tagName.toLowerCase() === "a"
        )
    ) {
        e.classList.remove(selectedClass);
    } else {
        selectEntry(e);
    }
}

function selectEntry(e, scrollIntoView=false) {
    if (currentEntry) {
        currentEntry.classList.remove(selectedClass);
    }
    currentEntry = e;
    currentEntry.classList.add(selectedClass);

    if (scrollIntoView) {
        scrollIntoViewWithOffset(e, 15)
    }
}

function isExpanded() {
    if (
        currentEntry.querySelector("a.d-inline-block:not(.thumbnail)") ||
        currentEntry.querySelector("#postContent") ||
        currentEntry.querySelector(".card-body")
    ) {
        return true;
    }

    return false;
}

function toggleExpand() {
    const expandButton = currentEntry.querySelector("button[aria-label='Expand here']");
    const textExpandButton = currentEntry.querySelector(".post-title>button");

    if (expandButton) {
        expandButton.click();

        // Scroll into view if picture/text preview cut off
        const imgContainer = currentEntry.querySelector("a.d-inline-block");
        if (imgContainer) {
            // Check container positions once image is loaded
            imgContainer.querySelector("img").addEventListener("load", function() {
                scrollIntoViewWithOffset(currentEntry, 0);
            }, true);
        }
    }

    if (textExpandButton) {
        textExpandButton.click();
    }

    scrollIntoViewWithOffset(currentEntry, 0);
}

function expandEntry() {
    if (!isExpanded()) toggleExpand();
}

function collapseEntry() {
    if (isExpanded()) toggleExpand();
}

function scrollIntoViewWithOffset(e, offset) {
    if (e.getBoundingClientRect().top < 0 ||
        e.getBoundingClientRect().bottom > window.innerHeight
    ) {
        const y = e.getBoundingClientRect().top + window.pageYOffset - offset;
        window.scrollTo({
            top: y
        });
    }
}
24
74
submitted 2 years ago* (last edited 2 years ago) by muchtooleft@kerala.party to c/plugins@sh.itjust.works
 
 

This is the best reddit like frontend I've seen. It's so good it reminds me of how the older days of reddit were like and lemmy feels just like it on some days.

See source if you want to self host it.

25
 
 

cross-posted from: https://sopuli.xyz/post/1027579

Hi,

i'm new to lemmy, trying it out if i like it. One thing that bothers me is how inconsistent the UI is so i made this css to make lemmy-ui more easy for my eyes and thought why not share it. Maybe someone else would like it too.

You can install it with Stylus browser extension or whatever method you prefer.

Be aware that it may break some things, but i will likely improve it if i decide to stay on lemmy.

Added Lemmy Darker @ userstyles.world!

view more: next ›