1

I've go a small application that display live feeds and uses livestamp + moment to update the time in a format similar to what Stackoverflow does to its messages.

Now I would like to change it slightly to show things past 24hs in a different format.

I found this thread which was exactly what I was looking for

Unhappily it doesn't work for my case, an example of my element is as follow:

<div id="container">
 <div something else>
 </div>
 <div id="feed">
  <div class="timestamp" title="Less than 1 minute ago">7 minutes ago</div>
 </div>
</div>

Of course the above is after livestamp has modified it, since my feed is added dynamically with jquery/ajax.

So considering the above I changed that code as follow:

$('.timestamp').on('change.livestamp', function(event, from, to)
{
    event.preventDefault(); // Stop the text from changing automatically

    // Get the original timestamp out of the event
    var originalTS = event.timeStamp;
    // Make a new moment object to compare the timestamp to
    var newDate = moment();
    // Use moment's .diff method to get the ms difference between timestamps
    var delta = newDate.diff(originalTS);

    // If the difference is less than a day's worth of ms
    if (delta < 86400000){
        // Use formatted text provided by the change event
        console.log("if: " + newDate.format("dddd M/D/YYYY"));
        $(this).html(to);
    }
    else {
        // Format the moment object with whatever moment format you want
        console.log("Else: " + newDate.format("dddd M/D/YYYY"));
        $(this).html( newDate.format("dddd M/D/YYYY") );
    }
}).livestamp();

And added it inside my $(document).ready(function(), however due to my .timestamp being dynamically added(I believe), the onchange never triggers.

If I instead use #container, it triggers, and I assume with that I would have to iterate thru all the items to manually update it and the problem is, I can't, because the timestamp is only present for 1 item(not per item) in this case, thus I won't be able to know which timestamp to update for the rest as livestamp removes it after the first iteration.

Is there any way to make it properly recognize the dynamic elements and do the onchange per element, as in the proposed above code in this scenario? or am I overlooking something?

Or maybe its possible to set the custom formatting directly on livestamp.js?

Something like:

var newDate = moment();
var delta = newDate.diff(to);
if (delta >= 86400000)
{
    to = to.format("dddd M/D/YYYY");
}

After line 59 on moment.js?

Community
  • 1
  • 1
Prix
  • 19,417
  • 15
  • 73
  • 132

1 Answers1

1

As you see in line 59 of livestamp code, the library uses moment fromNow to format relative time.

Moment has an API to customize the way it displays relative time, described in the Relative time section of the docs.

In you case you can use something like the following code:

const CUSTOM_FORMAT = 'dddd M/D/YYYY';

moment.updateLocale('en', {
  relativeTime : {
    future: function (number, withoutSuffix, key, isFuture){
      if( moment(number, CUSTOM_FORMAT, true).isValid() ){
        return number;
      }
      return "in " + number;
    },
    past: function (number, withoutSuffix, key, isFuture){
      if( moment(number, CUSTOM_FORMAT, true).isValid() ){
        return number;
      }
      return number + " ago";
    },
    dd: function (number, withoutSuffix, key, isFuture){
      var day = moment();
      if(isFuture){
        day.add(number, 'd');
      } else {
        day.subtract(number, 'd')
      }
      return day.format(CUSTOM_FORMAT);
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/livestamp/1.1.2/livestamp.min.js"></script>

<div id="container">
 <div> something else
 </div>
 <div id="feed">
  <div class="timestamp" data-livestamp="2017-02-26T00:29:22+01:00"></div>
  <div class="timestamp" data-livestamp="2017-02-20T00:29:22+01:00"></div>
  <div class="timestamp" data-livestamp="2017-02-28T05:26:22+01:00"></div>
 </div>
</div>

It should manage both past and future dates, but it might need some changes to handle correctly differences greater than 1 month.

VincenzoC
  • 30,117
  • 12
  • 90
  • 112
  • that's interesting, but aside from past dddd I also have a Yesterday HH:mm, is that also possible in there? And thanks for the reply that is much easier than what I had to do. – Prix Feb 26 '17 at 02:23
  • You can use single `d` key of `relativeTime` to customize "Yesterday", but I fear that is difficult to get the desidered output including the `HH:mm` part. Anyway maybe these [1](http://stackoverflow.com/q/42216583/), [2](http://stackoverflow.com/q/41508796/), [3](http://stackoverflow.com/q/38367038/) questions providing further examples of relative time customization could help you. – VincenzoC Feb 26 '17 at 16:30
  • 1
    VincenzoC thank you very much for writing up the above code and taking the time to explain it to me and adding extra information all that was very helpful and I was able to come up with what I wanted and that's much better than having to change the core files and lose further customization it allows ;) In case you're wondering here is what I came down to https://jsfiddle.net/7d6bfLwg/1/ – Prix Feb 27 '17 at 04:49