Seven reasons why FriendFeed sucks

posted 11:37PM Jun 15, 2008 with tags criticism friendfeed productmanagement by Lars Trieloff

Well, FriendFeed does not really suck, it has managed to convert me from a naysayer to fanboy (I think writing userscripts and user-css qualifies me as a fanboy) by giving me a communication platform that allows me to interact with my peers, but now that I have your attention, I would like to tell you five things where FriendFeed actually needs improvements. If you are on FriendFeed, feel free to like or comment this post to bring it to the attention of FriendFeed's product managers.
  1. no feed for daily, weekly and monthly toplinks: Friendfeed introduced a new feature, daily toplinks only few days ago and while it is insanely cool to have use your FriendFeed contacts as a personal attention filter and aggregator, I do not like the fact that there is no Atom or RSS feed for it. Come on, this thing is called FriendFeed, so you must be aware that there is a thing called feeds in the interwebs.
  2. no link-based aggregation: if one person posts a link twice in separate services, for instance directly on FriendFeed via Mento and later to del.icio.us, it will show up twice in the Feed, leading to clutter and noise (not the smart noise we are looking for at FriendFeed) in the feed and finally to a fragmentation of the discussion, as I have to chose which entry I like or comment. As a second example, if someone in my network posts a link that someone else posted as well, we have the same situation: two links, two discussions, two sets of likes. An easy solution would be a add a "also posted at ..., also posted by ..." line next to the list of people that liked a post. This way you could reduce clutter and join conversations that spread across multiple postings.
  3. bad recommendations for contacts: FriendFeed is a superb implementation of the "Activity feed" pattern of social networking, but its social networking capabilities are mediocre at best. Example number one: FriendFeed's recommended friends dialog suggests that I should subscribe to Dave Winer, Jason Calacanis, Leo Laporte, Loic Le Meur, Michael Arrington, Robert Scoble, Steve Rubel and some of the FriendFeed founders. While I think they are surely great people and I could learn a lot from them, it is too much information to handle (I tried to follow these suggestions, and removed them one by one later). Additionally as soon as they write something that is interesting for someone in my network, it will appear in my feed as well, which is a great feature. The only problem is: the recommended friends page does not make any sense if it is just a list of the top-users at FriendFeed. What I need are reasons to subscribe like: many of my important (measured in likes and comments) friends find them important (measured in likes and comments) as well.
  4. not notifying me when friends join: I wish everyone I know would be on FriendFeed. Unfortunately this will not happen and I will also not send an email requesting them to join yet another social network, because I know how distracting this would be for most of my contacts. However, I wish there were tools to make it a bit easier for me: If someone joins who has an e-mail address that was found in my address book before, please inform me. If someone adds a feed or a service that matches an imaginary friend that I created, please inform me. If you can read my address book, why can't you offer me to automatically create imaginary friends for my flickr, twitter, etc. contacts?
  5. bad Facebook integration: Like it or not, Facebook is popular. But FriendFeed's Facebook application is a joke. It is simply FriendFeed in an IFrame, but I cannot see which of my Facebook friends are on FriendFeed, I cannot invite them as it is possible with other social applications that offer Facebook integration. Probably the best example for this is dopplr.com which is a champion of social network interoperability. Another point in case that FriendFeed's social networking capabilities need some work.
  6. bad customer service at getsatisfaction.com: FriendFeed managed to move conversations from the blog comments to FriendFeed. Some bloggers objected, but that's the way it works. Conversations move and if you would like to take part in the conversation, you have to follow. The best place for customer care (and conversations with users of your product) today is getsatisfaction.com. There is a room for ~FriendFeed at getsatisfaction.com, but FriendFeed is not listening. As I am sure these guys know that they have to take part in the conversation where it happens, and I am also sure they know that customer service is part of the product design, it looks like they do not want to listen, because it does not matter to them.
  7. no search for URLs: Early adopters and developers are craving to integrate FriendFeed with their tools and services they use. The main integration point, the most important social object is content and content is identified by an URL in the web, yet FriendFeed's advanced search (and API) does not allow searches for URLs. This means, people looking to integrate FriendFeed with their blogs, using FriendFeed from Yahoo! Pipes or creating Mashups with FriendFeed are left out in the rain.
These are the most important changes and improvements I am looking forward at FriendFeed, not the addition of six (or sixty) more social networks. Improve the features you already have, improve search, improve social networking, improve aggregation and improve integration and I will be happy.

| Comments[2]

Black Friendfeed Widget with Fluid

posted 02:42PM May 15, 2008 with tags fluid friendfeed hud macosx ssb by Lars Trieloff

My Favorite SSB application Fluid got an update some days ago that allows you to fiddle with some window settings, namely the window opacity and the window decoration and the window placement (normal, above all windows, below all windows, above the dashboard). With the window decoration comes a black-window style with dark window borders and scroll bars that looks very cool. But using this style with Friendfeed for which I provided a custom userscript before yielded unpleasant results as the white background of friendfeed and the dark window borders do not match.

So I modified the user CSS file that is embedded in every Fluid SSB application (Right-click the application icon in Finder, select "Show package contents", browse to Contents/Resources) called default.css to give me a black background with white text and links (and I removed all the sidebar and clutter to make it a minimal interface)

The result looks like that and gives specialized desktop applications such as Twhirl or AlertThingy a run for it's money.

http://weblogs.goshaky.com/weblogs/lars/resource/friendfeed-hud.png

Fluid userscript for Friendfeed and Mento

posted 12:07AM Apr 26, 2008 with tags fluid friendfeed greasekit growl macosx mashup mento by Lars Trieloff

Being alone this evening I had the opportunity to spend some time programming interesting stuff. As I am currently researching lifestreaming applications, in particular Friendfeed, which is an excellent implementation of this concept I wrote a plugin for Blogbridge that will automatically send "pinned" entries to Friendfeed, similar to "shared items" in Google reader. Secondly, I got an invite to Mento, a social link sharing application (not bookmarking) that is focused around finding interesting links and sending them to friends, services (like Twitter, Friendfeed or del.icio.us/trieloff) or channels, which lead to my third activity: Integrating Friendfeed and Mento.

As Friendfeed is giving me lots of input from interesting people, I would like to save some links directly from the Friendfeed interface. Additionally, I am using Fluid in order to create a site-specific browser (SSB) for Friendfeed, basically a small desktop application that does nothing but running Friendfeed. Aside from this interesting concept, which is also being implemented by Mozilla Prism for instance, Fluid is currently the best implementation of this concept. Todd, the developer is working hard to integrate it with Mac OS X and make it a seamless user experience and he is adding easy programmability as one of the core aspects to SSBs. With Fluid it is possible to run userscripts that not only change the appearance and behavior of the website, these userscripts are also able to invoke advanced desktop integration features like adding an "unread items" badge to the dock item or display Growl notifications.

The small user script you find below does two things: on the one hand it adds a "Share" button to all links posted on Friendfeed. Clicking the "Share" button will invoke the Mento bookmarklet which allows you to send the link to friends and colleagues. On the other hand, the script will track which links have been added to the feed while the Friendfeed window has been in the background. For each new, unread item, it will increase the counter in the badge and display a Growl notification.

Sharing a link on Mento
Sharing a link on Mento

Growl showing an update Notification
Growl showing an update notification. (In the background there is Dashcode, the IDE I have been using to write this userscript)

One unread item
There is one unread item waiting for me in Friendfeed.

The user script that accomplishes this can be found here. You are free to use and modify and redistribute it of course.

// ==UserScript==
// @name        Share With Mento
// @namespace   http://fluidapp.com
// @description Adds a Share link to links listed on friendfeed.
// @include     *
// @author      Lars Trieloff http://weblogs.goshaky.com/weblogs/lars
// ==/UserScript==

(function () {
  var knownclusters = {};
  var unknownclusters = 0;

  function updateMento() {
    refreshMento(true);
  }
  
  function initMento() {
    refreshMento(false);
  }
  
  function refreshMento(background) {
    var infos = document.getElementsByClassName("info");
    for (var i=0;i<infos.length;i++) {
      var link = infos[i].previousSibling.previousSibling.firstChild;
      var parent = infos[i].parentNode.parentNode.parentNode.parentNode;
      var eventid = parent.getAttribute("eid");
      var header = 
      $(parent).find(".summary").get(0).innerHTML.replace(/<(.|\n)+?>/g, "");
      var description = 
      infos[i].previousSibling.previousSibling.innerHTML.replace(/<(.|\n)+?>/g, "");
      
      if (eventid in knownclusters) {
        
      } else {
        unknownclusters++;
        knownclusters[eventid] = "a";
        if (background) {
          window.fluid.showGrowlNotification({
            title: header, 
            description: description, 
            priority: 1, 
            sticky: false,
            identifier: eventid,
          });
        }
        if (link.href) {
        //alert(link.innerHTML);
        
        infos[i].innerHTML = infos[i].innerHTML + " - <a href=\"javascript:(" +
        "function(){o='location=0,width=515,height=375,resizable=1';u='http:" + 
        "//www.mento.info/qp/#v=bk&vn=1&';w=window;d=w.top.document;e=encode" +
        "URIComponent;u+='title='+'"+encodeURIComponent(link.innerHTML)+"'+'" +
        "&url='+'"+encodeURIComponent(link.href)+"'+'&via='+'"
        +encodeURIComponent("http://friendfeed.com/e/"
        +parent.getAttribute("eid"))+"';var%20mw=w.open(u,'_blank',o);if(mw)" +
        "setTimeout(function(){mw.focus()},%20250);else{alert('A%20popup%20b" + 
        "locker%20got%20in%20the%20way.%20Hold%20the%20CTRL%20key%20and%20tr" +
        "y%20again.');}})();\">Share</a>";
        }
      }
      if (background) {
        if (unknownclusters==0) {
          window.fluid.dockBadge = "";
        } else {
          window.fluid.dockBadge = unknownclusters;
        }
      } else {
        window.fluid.dockBadge = "";
        unknownclusters = 0;
      }
      
    }
  }

  function jquery_wait() {
    
    if(typeof window.jQuery == 'undefined') { 
      window.setTimeout(jquery_wait,100); 
    }
    else {
      $ = window.jQuery; initMento();
      window.setInterval(updateMento, 1000); 
    }
  }

    if (window.fluid) {
    window.onfocus = initMento;
    //initMento(true);
    jquery_wait();
    }
})();

My Weblog integrates FriendFeed now

posted 12:42AM Apr 14, 2008 with tags friendfeed mashp weblog by Lars Trieloff

I created a small mashup that combines my weblog with the Friendfeed API. The first thing I did was replacing my Planet-generated Activity feed and activity index calculation with one based on the Friendfeed JSON API. The JSON provided by Friendfeed even allowed me to add additional information, so I am highlighting every piece of activity that has been commented or liked in bold type.

http://weblogs.goshaky.com/weblogs/lars/resource/Picture%209.png

Additionally, I integrated the Friendfeed comment API with the footer of every weblog post. What I am doing here is using the search API to find the post you are watching on Friendfeed and listing the number of comments and likes in the footer of the blog. Given the ability of the Friendfeed API of specifing callback functions, this was really a piece of cake to implement.

http://weblogs.goshaky.com/weblogs/lars/resource/Picture%2010.png

Why I keep using my own pulse

posted 01:52PM Oct 23, 2007 with tags aggregation atom friendfeed istalkr plaxo pulse rss suprglu by Lars Trieloff

I've been a fan of personal feed aggregation services for a long time. I've been trying: I've even built my own pulse once and twice. Now Plaxo announces something new: The Plaxo Pulse Widget allows you to embed your pulse (your feed of anything you do on the web) in your weblog. Actually it is not that new, because with the help of Mysyndicaat you could already do this before and it is not that good, because you cannot completely control the look and feel, as I can with the custom widget you see in the sidebar of my blog.

How I did it:

  1. I created an OPML file with my feeds. I simply re-used my personal OPML file, I created for the older incarnation of my personal aggregator.
  2. I downloaded and installed Sam Ruby's Planet Venus, a refactored version of the Planet software that powers many websites, for instance Planet Apache.
  3. I created a new profile that reads my OPML file:
# subscription list
[http://weblogs.goshaky.com/weblogs/lars/page/OPML]
content_type = opml
  1. I created a new theme that creates a JSON feed from my aggregated feed using following XSLT stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:atom="http://www.w3.org/2005/Atom"
                xmlns:xhtml="http://www.w3.org/1999/xhtml"
                xmlns:planet="http://planet.intertwingly.net/"
                xmlns="http://www.w3.org/1999/xhtml"
                exclude-result-prefixes="atom planet xhtml">
 
  <xsl:output method="text" omit-xml-declaration="yes"/>

  <xsl:template match="atom:feed">
var planet = [
    <xsl:apply-templates select="atom:entry[position()&lt;51]"/>
];
  </xsl:template>
 
  <xsl:template match="atom:entry">
  {
    title: "<xsl:call-template name="strip-quotes">
  <xsl:with-param name="text">
    <xsl:value-of select="atom:title" />
  </xsl:with-param>
</xsl:call-template>",
    href: "<xsl:call-template name="strip-quotes">
  <xsl:with-param name="text">
    <xsl:value-of select="atom:link[@rel='alternate']/@href" />
  </xsl:with-param>
</xsl:call-template>",
    icon: "<xsl:value-of select="atom:source/planet:css-id" />.png"
  }
  <xsl:if test="position()&lt;50">
  ,
  </xsl:if>
  </xsl:template>
  
  <!-- remove everything else -->
  <xsl:template match="@*|node()"></xsl:template>

  <xsl:template name="strip-quotes">
    <xsl:param name="text" />
    <xsl:if test="contains($text, '&#x22;')">
      <xsl:value-of select="substring-before(translate($text,'&#10;',''), '&#x22;')" />
      <xsl:text>\"</xsl:text>
      <xsl:call-template name="strip-quotes">
        <xsl:with-param name="text">
          <xsl:value-of select="substring-after(translate($text,'&#10;',''), '&#x22;')" />
        </xsl:with-param>
      </xsl:call-template>
    </xsl:if>
    <xsl:if test="not(contains($text, '&#x22;'))">
      <xsl:value-of select="translate($text,'&#10;','')" />
    </xsl:if>
  </xsl:template>
  
</xsl:stylesheet>
  1. Finally, I customized my blog's sidebar template to include the JSON feed as a list:
<li id="container">
    <h2>Activity</h2>
    <p><script type="text/javascript" src="http://del.icio.us/feeds/js/networkbadge/trieloff?name;nwcount;icon=s"></script></p> 
<script type="text/javascript" 
        src="http://internal.mindquarry.com/venus/lars/index.json"></script>

<script type="text/javascript">
    function showImage(img){ return (function(){ img.style.display='inline'; }) }

    var ul = document.createElement('ul')
    for (var i=0, post; post = planet[i]; i++) {
        var li = document.createElement('li');
        var a = document.createElement('a');
        a.setAttribute('href', post.href);
        a.appendChild(document.createTextNode(post.title));
        li.style.backgroundImage = "url(http://internal.mindquarry.com/venus/lars/"+post.icon+")";
        li.style.backgroundRepeat = "no-repeat";
        li.style.paddingLeft = "20px";
        li.appendChild(a);
        ul.appendChild(li);
    }
    document.getElementById('container').appendChild(ul);
</script>
   </li>

Using this method I am more flexible in adding feeds and supporting services, I can easily customize the appearance of the widget in my sidebar and I have all the super-powers that Planet Venus offers, for instance filtering Feedburner spam from my feeds.