Posts

STEEM编程练习记录 四

avatar of @lnakuma
25
@lnakuma
·
0 views
·
1 min read

相信这几天大家在STEEM的生活一定是异常丰富的。从可以尽情的啪啪啪,到突然间上不去SteemCN,再到哪个结点都上不去,再到可以上Steempeak,再到只可以用Chrome扩展程序鼓掌,再到连扩展程序都不行了。最后到终于全恢复了。

一天之内大起大落,也算玩了个刺激。当然也有想我这样没什么分量的人,基本上属于在吃瓜围观。

五天前,村长@ericet和我商量能够在Liker Extension中增加一个开关,在浏览器中可以选择是否显示LikeCoin拍手键;我也想降低访问Steem API结点的次数,以免被列入黑名单。

今天我就来讲一讲如何能够增加以上两个功能。

设计思路

Figure 1

点击浏览器右上角likecoin-extension的图标,可以打开一个小小的视窗。这个视窗其实就是一同包装在扩展程序包中的*popup.html。作为一个HTML形式小网页,它可以读取JavaScript的程序,和CSS**样式。正可谓麻雀虽小但五脏俱全。在这个小网页中,我们可以增加一个普通的开关,并运行相关的JavaScript event。

但是popup.html不能把任何数据变量直接送到**liker.js当中去。所以必须使用Chrome**浏览器自己的传送功能传递数据。

当每次运行扩展程序的时候,程序在浏览器的背景中连接STEEM API的方程,从而获取following的列表。在STEEM编程练习记录 三中曾经提到测试中由于过度的更新页面,anyx.io暂时把我block掉了。所以我需要在程序中增加一个时间的记录,这样我可以在自己规定的时间能,使用已经下载下来的following列表检查当前文章的作者是否是一个注册Matters.news的作者。

编写程序

  1. 首先,先要给自己使用**Chrome API*的权限。在manifest.json中添加下面的数据,这两个权限分别给与扩展程序应用当前页面和Chrome自己的存储。

    "permissions": [ 
       "activeTab", "storage" 
    ] 
    

    很多时候,网页需要在浏览器中存储一些数据,Storage便是网页在浏览器中寄存数据的地方。打个比方,就像我现在码字的这个页面,然后我们到developer tool里面的Application->Local Storage内,我们就可以看到一下的数据。这也是为什么在我们还没有敲完所有的字,却更新页面之后,我们之前写的东西还在的原因。 Figure 2

  2. 从**popup.html传送数据到liker.js里面需要使用Chrome API* *chrome.tabs.sendMessage()

    const clickButton = (data) => { 
      chrome.tabs.query({ active: true, currentWindow: true}, function (tabs) { 
        chrome.tabs.executeScript(tabs[0].id, { file: "liker.js" }); 
        chrome.tabs.sendMessage(tabs[0].id, !data); 
      }); 
    }; 
    

    上面的代码中,扩展程序先调用chrome.tabs的API运行liker.js,再想当前的浏览器的页面发送需要发送的数据。这里的数据就是我们要显示的开关的数值。
    liker.js中增加一个随时倾听Message的触发。

     chrome.runtime.onMessage.addListener( function(message) { 
       chrome.storage.local.set({disableRunning: message}); 
     }); 
    

    由于JavaScript异步的特性,liker.js在等待从popup.html传送过来的数据的同时,回继续运行下面的指令。这一特性将会导致程序不知道当时popup.html中是否是真正的打开还是关闭。所以,我用到了chrome的另一个API:storage。把开关的状态存在storage里面还有一个好处,就是在重新打开popup.html*的小视窗的时候,还可以随时更新开关的数值。

  3. 减少访问结点的次数其实是最简单的事情之一。

    let rightNow = Math.floor(Date.now()); 
      if (rightNow >= fTimeout) { 
        following = await getFollowing(); 
        fTimeout = fTimeout + 100000; 
        fList = following; 
        console.log("Refresh following list"); 
      } 
      else { 
        console.log("Use existing following list"); 
      } 
    

    设置两个便令分辨储存当前时间和十分钟之后的时间;如果需要访问结点,便更新一次十分钟后的时间。每次需要读取following列表的时候,更新当前时间,并和上一次更新十分钟后的时间做比较,如果还没有到十分钟之后,便是用上次访问结点取得的数据。

扩展程序使用效果

这次我的实验小白鼠是@bring老吴的新介绍 Introducing Myself。上面Figuer 1就是在打开扩展程序时候,likeCoin button被显示的效果。

Figure 3

上面Figure 1则展示的是关掉扩展程序之后,拍手键自动消失。

作为向我这样的马大哈,当然在测试的时候发现没有想到的BUG。当我关闭扩展程序,退回到文章列表,在打开开关之后,拍手键将在也无法出现。

根据分析,我发现在我原本的程序中我并没有在每一次更新拍手键的时候强制取消取消隐藏拍手键的CSS样式。只要在原来的createLikerButton程式中加上

document.getElementById("likecoin-iframe").classList.remove("elem-hide"); 

便可解决问题。

我还无意间发现新版SteemCN自带的拍手键和扩展程序中的拍手键记录了不同的网址。

Figure 4

现在很多浏览器都省略掉了网址前端的www。而JavaScript读取网址的程式没有这么做。这个小小的BUG倒给与我们一篇文章啪啪十次的机会。当然,现在Liker Land上面还没有显示是否有五啪不奏效。这个要等到明天我才能测试出最后的结果。

以后还可以做什么

自动拍手。其实在SteemCN刚刚增加拍拍手的时候,我就尝试着做了一个扩张程序。但是由于设计思路的问题,并没有成功。村长@ericet昨天介绍了LikeCoin的API。我觉得有时间的话,可行性很高。只要不用每天在STEEM上读一堆你骂我我骂你的文章,应该有时间开发自动拍手的功能。

*但是有个问题来了,如果自动拍手了,大家还看文章吗?