Lemmy mlmym community bar customisation

Allows customisation of the lemmy community bar

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Lemmy mlmym community bar customisation
// @namespace    https://greatest.deepsurf.us/
// @version      0.3
// @description  Allows customisation of the lemmy community bar
// @author       9point6
// @match        https://old.lemmy.world/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=lemmy.world
// @grant        none
// @license      MIT
// ==/UserScript==


(function() {
    'use strict';

    const INITIAL_COMMUNITIES = [
        'football',
        '[email protected]',
        '[email protected]',
    ];

    const LOCAL_STORAGE_KEY = 'lemmyCommunityBarSettings';

    const updateSettings = (newCommunitiesList) => {
        const settings = {
            settingsVersion: 1,
            communities: newCommunitiesList.filter((item) => typeof item === 'string')
        };

        window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(settings));

        return settings;
    }

    const loadSettings = () => {
        try {
            const existingSettings = window.localStorage.getItem(LOCAL_STORAGE_KEY);
            if (existingSettings) {
                return JSON.parse(existingSettings);
            }
        } catch (ex) {}

        return updateSettings(INITIAL_COMMUNITIES);
    }

    const hideEditMenu = () => {
        const container = document.querySelector('#community-bar-editor');
        if (container) {
            container.remove();
        }
    }

    const createConfigButton = (icon, title, callback) => {
        const configButton = document.createElement('button');
        const configText = document.createTextNode(icon);

        configButton.title = title;
        configButton.style.padding = '0';
        configButton.style.fontSize = '10px';
        configButton.style.marginRight = '4px';
        configButton.style.cursor = 'pointer';
        configButton.style.background = 'none';
        configButton.style.border = 'none';
        configButton.style.transition = 'filter 0.1s ease-in-out, background-color 0.1s ease-in-out';

        configButton.append(configText);

        configButton.addEventListener('mouseover', (e) => {
            if (!configButton.disabled) {
                configButton.style.filter = 'brightness(1.2)';
                configButton.style.background = 'white';
            }
        });

        configButton.addEventListener('mouseout', (e) => {
            if (!configButton.disabled) {
                configButton.style.filter = 'none';
                configButton.style.background = 'none';
            }
        });

        configButton.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            callback();
        });

        return configButton;
    }

    const showEditMenu = () => {
        hideEditMenu();

        const settings = loadSettings();

        const communties = document.querySelector('.communities');
        const background = document.createElement('div');
        const container = document.createElement('ol');

        background.id = 'community-bar-editor';
        background.style.backgroundColor = 'rgba(0,0,0,0.5)';
        background.style.position = 'absolute';
        background.style.top = 0;
        background.style.left = 0;
        background.style.width = '100%';
        background.style.height = '100vh';
        background.style.zIndex = '102';

        container.style.backgroundColor = '#ccc';
        container.style.position = 'absolute';
        container.style.top = '8px';
        container.style.right = 0;
        container.style.padding = '4px';
        container.style.border = '1px #ccc solid';

        background.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            hideEditMenu();
        });

        background.append(container);
        communties.append(background);

        settings.communities.map((community, communityIndex) => {
            const item = document.createElement('li');
            const text = document.createTextNode(community);

            const deleteButton = createConfigButton('❌', 'Remove community from your favourites', () => {
                updateSettings(settings.communities.filter((communityName) =>
                    communityName !== community
                ));
                showEditMenu();
            });

            const upButton = createConfigButton('⬆️', 'Move this community up in the list', () => {
                const { communities } = settings;
                [
                    communities[communityIndex - 1],
                    communities[communityIndex]
                ] = [
                    communities[communityIndex],
                    communities[communityIndex - 1]
                ];

                updateSettings(communities);
                showEditMenu();
            });

            if (communityIndex === 0) {
                upButton.disabled = true;
                upButton.style.cursor = 'default';
            }

            const downButton = createConfigButton('⬇️', 'Move this community down in the list', () => {
                const { communities } = settings;
                [
                    communities[communityIndex + 1],
                    communities[communityIndex]
                ] = [
                    communities[communityIndex],
                    communities[communityIndex + 1]
                ];

                updateSettings(communities);
                showEditMenu();
            });

            if (communityIndex === settings.communities.length - 1) {
                downButton.disabled = true;
                downButton.style.cursor = 'default';
            }

            item.style.display = 'block';
            item.style.fontSize = '10px';
            item.style.fontWeight = '400';
            item.style.color = '#000';

            item.append(deleteButton);
            item.append(upButton);
            item.append(downButton);
            item.append(text);
            container.append(item);
        })

        const buttonRow = document.createElement('li');
        const addButton = document.createElement('button')
        const addText = document.createTextNode('add');
        const closeButton = document.createElement('button')
        const closeText = document.createTextNode('finish editing');
        const separatorText = document.createTextNode(' ');

        addButton.append(addText);
        closeButton.append(closeText);
        buttonRow.append(addButton);
        buttonRow.append(separatorText);
        buttonRow.append(closeButton);
        container.append(buttonRow);

        addButton.style.cursor = 'pointer';
        addButton.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            const newCommunity = prompt('New community to add, make sure you include the instance suffix if it isn\'t a local community');
            updateSettings(settings.communities.concat(newCommunity));
            showEditMenu();
        })

        closeButton.style.cursor = 'pointer';
        closeButton.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            hideEditMenu();
            window.location.reload();
        })
    };

    const addFavouriteButton = () => {
        const { pathname } = window.location;
        if (!(pathname.startsWith('/c/') || pathname.startsWith('/post/'))) {
            return;
        }

        const { communities } = loadSettings();

        const thisCommunityTitle = document.querySelector('nav .title').textContent.trim();
        const alreadySubscribed = communities.includes(thisCommunityTitle);

        const sidebar = document.querySelector('.side');
        const blockButton = document.querySelector('.side .block');
        const favouriteButton = document.createElement('button');
        const favouriteText = document.createTextNode( alreadySubscribed ? 'unfavourite' : 'favourite');


        favouriteButton.style.fontSize = '10px';
        favouriteButton.style.fontWeight = 'bold';
        favouriteButton.style.display = 'inline-block';
        favouriteButton.style.padding = '1px 4px';
        favouriteButton.style.borderRadius = '4px';
        favouriteButton.style.border = '1px solid #444444';
        favouriteButton.style.color = 'white';
        favouriteButton.style.position = 'relative';
        favouriteButton.style.bottom = '1px';
        favouriteButton.style.cursor = 'pointer';
        favouriteButton.style.backgroundColor = alreadySubscribed ? '#cf6165' : 'green';
        favouriteButton.style.marginRight = '4px';

        favouriteButton.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();

            updateSettings(
                alreadySubscribed
                ? communities.filter((title) => title !== thisCommunityTitle)
                : communities.concat(thisCommunityTitle)
            );

            window.location.reload();
        });

        favouriteButton.append(favouriteText);
        sidebar.insertBefore(favouriteButton, blockButton);
    }

    const addEditButton = () => {
        const more = document.querySelector('.communities .more');
        const communties = document.querySelector('.communities');
        const button = document.createElement('button');
        const buttonSpan = document.createElement('span');
        const buttonText = document.createTextNode('⚙️');

        buttonSpan.append(buttonText);
        button.append(buttonSpan);
        communties.append(button);

        more.style.right = '20px';

        button.title = 'Edit favourite communities';
        button.style.backgroundColor = '#ccc';
        button.style.position = 'absolute';
        button.style.top = 0;
        button.style.right = 0;
        button.style.border = 0;
        button.style.fontSize = '10px';
        button.style.cursor = 'pointer';
        buttonSpan.style.filter = 'brightness(0.5)';

        button.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            const container = document.querySelector('#community-bar-editor');
            if (container) {
                hideEditMenu();
            } else {
                showEditMenu();
            }
        });
    }

    const addCommunityToBar = (name) => {
        const shortName = name.split('@')[0];

        const a = document.createElement('a');
        const link = document.createTextNode(shortName);
        const separator = document.createTextNode(" - ");

        a.appendChild(link);
        a.href = `/c/${name}`;
        a.title = `Go to !${name}`;


        const communities = document.querySelector('.communities')
        const firstLink = document.querySelector('.communities a:nth-child(5)')

        communities.insertBefore(separator, firstLink);
        communities.insertBefore(a, separator);
    }

    loadSettings().communities.reverse().map(addCommunityToBar)
    addEditButton();
    addFavouriteButton();

})();