Steemit By Tag - Now set tags in browser!

in #utopian-io6 years ago (edited)

Just My Tags New Features

I'm pretty excited to say I've knocked out the two main items on the roadmap and we now have a menu to set your tags! I've also combined the previous two scripts so now both menus are updated from one script.

I've just added this as another sidebar on the right. Unless it's not obvious, I make absolutely no claim to having even the most rudimentary design skills. That said, if you can make this look pretty, just comment here or I'd be happy to merge a pull request at github.

set_tags.png

Click Set tags to show the menu and update your tags.

menu.png

Just enter a comma separate list of your favorite tags, click save, and the page will refresh to display these tags!

Updates and Changes

Uninstall

Before you get started, remove the old scripts if you had previously installed them.

In Chrome, click the Tampermonkey icon and select Dashboard

dashboard.png

Then, just click the trash icon in the list, to the far right.

chrome_delete.png

In Firefox, click the Greasemonkey icon and click on the name of the script.

grease_delete.png

A new menu will appear. Click uninstall for each script and a timer will begin.

grease_uninstall.png

GM Object and Promises

The main feature implemented here is the GM.setValue and GM.getValue functions which allow us to set variables to local storage in the browser.

I began using GM_setValue and GM_getValue which was working without issue in Chrome, but immediately failed in Firefox. You may not even notice the tiny syntax change replacing the _ with a . which seems small, but is actually a considerable change.

This change came with the release of Greasemonkey 4 which notes.

At its core, this set of APIs is completely asynchronous. Greasemonkey's old "GM_" APIs are typically synchronous.

The announcement itself goes further and states clearly.

We've elected to make a rare backwards incompatible change.

Now, they did write a polyfill that is honestly a hack to allow you continue using the old syntax so I opted to just move forward and use the GM object.

Previously, GM_getValue would return the actual value that was previously set. Pretty simple and straighforward. Now, GM.setValue returns a Promise and requires nothing short of magic to extract the value from this object. A promise is an object returned by an asyncronous function, so the trick to get at the values in the promise object is to wrap it in an async function.

Now, I'm a server side coder so I remember when javascript was just an 'addition' to the browser, while today full stack javascript developer is truly a thing. I see a TON of javascript developers around here so I'd love some comments from anyone more knowledgable about Promises and how to truly work with them. This is a rudimentary implementation here so I'd like to really understand the fundamentals better.

Code Changes

To implement these GM functions we need to first grant them both.

// @grant        GM.setValue
// @grant        GM.getValue

This script opens with the async which wraps everything herein.

(async () => {

Again, my understanding is basic, but it seems that Greasemonkey 4 is now asynchronous natively and this allows the same code to work properly in Chrome under Tampermonkey. Please correct me if I am wrong here.

This line reveals some more of the tricks in working with the Promise object.

let mytags = await GM.getValue("tags");

The docs for the await function says it plainly.

The await operator is used to wait for a Promise. It can only be used inside an async function.

Since the Promise is asynchronous we must await its completion before we can access the returned value.

When you first save the script, we have not yet called GM.setValue so we watch for that and set some default tags.

if(mytags == undefined){
    mytags = 'life,steemit';
}

We take our string of comma separate tags and split them into an array.

var tags = mytags.split(',');

For the left sidebar, it was easier to first remove the entire sidebar.

$(".c-sidebar--left").remove();

And then reconstruct all the HTML for the entire sidebar and append it back to the browser.

$(".PostsIndex").append(newTags);

Again, we manually construct the HTML, but on the right, we're able to just append that instead of replacing. Then we set the textarea to show the existing tags and hide the menu.

$(".c-sidebar--right").append(tagsSidebar);

$('textarea#tags_input').html(mytags);
$('#tags-form').hide();

In the save function, we're calling the GM.setValue, removing any spaces, hiding the menu, and then reloading the page to display the new tags.

$(".save_tags").click(function() {
    var tagsValue = $('#tags_input').val();
    tagsValue = tagsValue.replace(/\s/g,'');
    GM.setValue("tags", tagsValue);
    $('#tags-form').hide();
    location.reload();
});

The final part of the script reconstructs the <select> menu with all of our tags using the same code as our earlier script.

Conclusion

I'm pretty excited about these updates, this is working very well in my testing so please let me know of any issues. I'm finding that my interests do shift as I search and read more so this is a quick and easy way to update the tags I wanna follow.

Now, I'm trying to decide what other tweaks I can make to this script or new scripts for Steemit in general. If you have any ideas, please comment because I'm looking for new features to add or scripts to write.

The Script

// ==UserScript==
// @name         Steemit Just My Tags
// @version      0.2
// @description  Update both menu to list only your tags
// @author       blervin
// @include      https://steemit.com/*
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @grant        GM.setValue
// @grant        GM.getValue
// ==/UserScript==

(async () => {
    let mytags = await GM.getValue("tags");

    if(mytags == undefined){
        mytags = 'life,steemit';
    }

    var tags = mytags.split(',');

    $(".c-sidebar--left").remove();
    var newTags = '<aside class="c-sidebar c-sidebar--left">';
    newTags += '<div class="c-sidebar__module">';
    newTags += '<div class="c-sidebar__header">';
    newTags += '<h3 class="c-sidebar__h3">Just my tags...</h3></div>';
    newTags += '<div class="c-sidebar__content">';
    newTags += '<div class="c-sidebar__content">';
    newTags += '<ul class="c-sidebar__list">';

    for (var i = 0, len = tags.length; i < len; i++) {
        newTags += '<li class="c-sidebar__list-item"><a class="c-sidebar__link" href="/trending/' + tags[i] + '">' + tags[i] + '</a> <small><a href="/created/' + tags[i] + '">(new)</a></small></li>';
    }

    newTags += '<li class="c-sidebar__link"><a class="c-sidebar__link c-sidebar__link--emphasis" href="/tags">View all tags</a></li>';
    newTags += '</ul>';
    newTags += '</div>';
    newTags += '</div>';
    newTags += '</div>';
    newTags += '</aside>';

    $(".PostsIndex").append(newTags);

    tagsSidebar = '<div class="c-sidebar__module">';
    tagsSidebar += '<div class="c-sidebar__header"><h3 class="c-sidebar__h3">My tags</h3></div>';
    tagsSidebar += '<a class="c-sidebar__link tags_settings" href="#">Set tags</a>';
    tagsSidebar += '<div id="tags-form" padding-top:10px;" title="Set your tags">';
    tagsSidebar += '<label for="tags_input">Tags</label>';
    tagsSidebar += '<textarea type="text" name="tags_input" id="tags_input" placeholder="coding,programming"></textarea>';
    tagsSidebar += '<a href="#" class="save_tags">Save</a>';
    tagsSidebar += '</div>';
    tagsSidebar += '</div>';

    $(".c-sidebar--right").append(tagsSidebar);

    $('textarea#tags_input').html(mytags);
    $('#tags-form').hide();

    $(".save_tags").click(function() {
        var tagsValue = $('#tags_input').val();
        tagsValue = tagsValue.replace(/\s/g,'');
        GM.setValue("tags", tagsValue);
        $('#tags-form').hide();
        location.reload();
    });

    $(".tags_settings").click(function() {
        $('#tags-form').show();
    });

    function setMyTags(current_path){
        $(".Topics > option").each(function() {
            this.remove();
        });

        $(".Topics").append('<option value="/' + current_path + '/">All Tags</option>');
        $(".Topics").append('<option value="/' + current_path + '/"></option>');
        for (var i = 0, len = tags.length; i < len; i++) {
            $(".Topics").append('<option value="/' + current_path + '/' + tags[i] + '">' + tags[i] + '</option>');
        }
    }

    $("a").click(function() {
        var url = this.href;
        if(url.includes('created')){
            setMyTags('created');
        }

        if(url.includes('trending')){
            setMyTags('trending');
        }

        if(url.includes('hot')){
            setMyTags('hot');
        }

        if(url.includes('promoted')){
            setMyTags('promoted');
        }
    });

    setMyTags(window.location.pathname.split('/')[1]);
})();



Posted on Utopian.io - Rewarding Open Source Contributors

Sort:  

Hey @blervin I am @utopian-io. I have just upvoted you!

Achievements

  • You have less than 500 followers. Just gave you a gift to help you succeed!
  • Seems like you contribute quite often. AMAZING!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x

You got a 6.64% upvote from @postpromoter courtesy of @blervin!

Want to promote your posts too? Check out the Steem Bot Tracker website for more info. If you would like to support the development of @postpromoter and the bot tracker please vote for @yabapmatt for witness!

Thank you for the contribution. It has been approved.

You can contact us on Discord.
[utopian-moderator]

Coin Marketplace

STEEM 0.32
TRX 0.12
JST 0.034
BTC 64647.93
ETH 3160.25
USDT 1.00
SBD 4.09