Convos

 view release on metacpan or  search on metacpan

lib/Convos/public/packed/convos.chat-a1c530de1c4ea0dc495e1329d9cc0bcd.js  view on Meta::CPAN


  convos.goForwardInHistory = function(e) {
    $(this).closest('li').remove();
    if (e) e.preventDefault();
    if (!convos.current.end_time) return;
    $.get(location.href.replace(/\?.*/, ''), { from: convos.current.end_time }, function(data) {
      var $ul = $(data).find('ul[data-network]');
      var $li = $ul.children('li:gt(0)');
      $('body').removeClass('loading');
      if (!$li.length) return;
      convos.current.end_time = parseFloat($ul.data('end-time'));
      convos.current.state = $ul.attr('data-state');
      $li.addToMessages();
    });
    convos.current.end_time = 0;
    $('body').addClass('loading');
  };

  convos.makeMessage = function(content) {
    var $m = $('<li class="message" data-sender="convos"></li>');
    $m.append('<img class="avatar" src="' + $.url_for('/image/avatar-convos.png') + '">');
    $m.append('<h3>convos</h3>');
    $m.append('<div class="content">' + content + '</div>');
    return $m;
  };

  var firstTimeConnected = convos.on('idle', function() {
    if ($('nav ul.conversations a[data-network="' + convos.current.network + '"]').length) return convos.unsubscribe('idle', firstTimeConnected);
    if (convos.current.state != 'connected') return;
    convos.unsubscribe('idle', firstTimeConnected);
    console.log('firstTimeConnected');
    convos.makeMessage('Hi ' + convos.current.nick + '. Welcome to ' + convos.current.network + '.').addToMessages();
    convos.makeMessage('Already know what channel you want to talk in? Press shift+enter or click the list icon next to the bell in the top menu, enter the channel name and click "Join" to add it to your connection.').addToMessages();
    convos.makeMessage('Otherwise, please hold on while I try to fetch the server channel list for you. (It could take a while)').addToMessages();
    convos.makeMessage('While you wait, try the help command: Type <b>/help</b> in the input field at the bottom on the page and hit enter. You can also use the &lt;tab> key to get suggestions for commands and nicks.').addToMessages();
    convos.send('/list');
    $(window).scrollTo('bottom');
  });

  $.fn.addToMessages = function(func) { // func = {prepend,append}
    return this.attachEventsToMessage().each(function() {
      var $message = $(this);
      var $messages = $('div.messages ul');
      var $same = $messages.children('li').not('.message-pending').eq(func == 'prepend' ? 0 : -1);
      var same_nick = $same.data('sender') || '';

      if ($message.hasClass('message') && $same.hasClass('message') && same_nick == $message.data('sender')) {
        (func == 'prepend' ? $same : $message).addClass('same-nick');
      }
      if (!$message.hasClass('hidden')) {
        $messages[func || 'append']($message);
      }

      $message.trigger('addedToMessages');
    });
  };

  $.fn.attachEventsToMessage = function() {
    this.find('a.internal').click(function(e) {
      e.preventDefault();
      $.pjax.click(e, { container: 'div.messages', fragment: 'div.messages' });
    });
    this.find('a.autocomplete').click(function(e) {
      var str = this.href.match(/.*complete:\/\/(.+)/);
      str = str ? str[1] : $(this).text();
      if (str.indexOf('/') != 0 && convos.input.val().length == 0) str += ':';
      if (convos.input.val().length) str = ' ' + str;
      e.preventDefault();
      convos.input.val(convos.input.val().replace(/\s+$/, '') + str + ' ').focus();
    });
    this.find('a[href^="http"].external').each(function(e) {
      var $a = $(this);
      $.get($.url_for('/oembed'), { url: this.href }, function(embed_code) {
        if (embed_code.match(/^\s*<a/)) return; // do not want to embed plain links
        var $embed_code = $(embed_code).wrap('<div class="embed"></div>').parent();
        var at_bottom = convos.at_bottom;
        $a.closest('div').after($embed_code).closest('li').data('at_bottom', at_bottom);
        $embed_code.find('img').one('load', function() { if (at_bottom) $(window).scrollTo('bottom'); });
        $embed_code.find('.text-gist-github').each(function() {
          var self = this;
          window[self.id] = function(g) { self.innerHTML = g.div; if (at_bottom) $(window).scrollTo('bottom'); };
        });
        if (at_bottom) $(window).scrollTo('bottom');
      });
    });
    this.find('[data-avatar^="http"]').each(function(e) {
      $(this).replaceWith('<img src="' + $(this).attr('data-avatar') + '" class="avatar">');
    });

    this.find('a.go-forward-in-history').click(convos.goForwardInHistory);

    return this;
  };

  $.noCache = function(args) {
    args._ts = new Date().getTime();
    return args;
  };

  $.fn.scrollTo = function(pos) {
    if(pos === 'bottom') { $(this).scrollTop($('body').height()); }
    else { $(this).scrollTop(pos); }
    return this;
  };

  var focusFirst = function() {
    if (document.activeElement && $(document.activeElement).is(':input')) return;
    if (convos.input.length) return convos.input.focus();
    $('form input[type="text"]:visible').eq(0).focus();
  };

  var goBackwardInHistory = function() {
    if (!convos.current.start_time) return;
    var $loading = $('<li class="message notice"><div class="content">Loading historic messages...</div></li>');
    $.get(location.href.replace(/\?.*/, ''), { 'last-read-time': convos.current.last_read_time, to: convos.current.start_time }, function(data) {
      var $ul = $(data).find('ul[data-network]');
      var $li = $ul.children('li:lt(-1)');
      var height_before_prepend = $('body').height();
      $loading.remove();
      if (!$li.length) return;
      convos.current.start_time = parseFloat($ul.data('start-time'));
      $($li.get().reverse()).addToMessages('prepend');
      $(window).scrollTop($('body').height() - height_before_prepend);
    });
    $loading.addToMessages('prepend');
    convos.current.start_time = 0;
  };

  var initPjax = function() {
    $.pjax.defaults.maxCacheLength = 0; // Will refresh conversation when going back/forward, fixes #111
    $(document).on('pjax:timeout', function(e) { e.preventDefault(); });
    $(document).pjax('nav ul a', 'div.messages', { fragment: 'div.messages' });
    $(document).pjax('.sidebar-right a', 'div.messages', { fragment: 'div.messages' });

    $('div.messages').on('pjax:beforeReplace', function(xhr, options) { $('body').removeClass('loading'); });
    $('div.messages').on('pjax:beforeSend', function(xhr, options) { return !$(this).hasClass('no-pjax'); });
    $('div.messages').on('pjax:start', function(xhr, options) { $('body').addClass('loading'); });

    $('div.messages').on('pjax:success', function(e, data, status_text, xhr, options) {
      var $doc = data.match(/<\w/) ? $(data) : $('body');
      var $messages = $('div.messages ul'); // injected to the document using pjax

      convos.emit('conversation-loaded', $doc);

      convos.current.channels = {};
      convos.current.end_time = parseFloat($messages.attr('data-end-time'));
      convos.current.start_time = parseFloat($messages.attr('data-start-time'));
      convos.current.last_read_time = parseFloat($messages.attr('data-last-read-time'));
      convos.current.nick = $messages.attr('data-nick') || '';
      convos.current.network = $messages.attr('data-network') || '';
      convos.current.state = $messages.attr('data-state');
      convos.current.target = $messages.attr('data-target') || '';
      convos.send(convos.isChannel(convos.current.target) ? '/names' : ''); // get nick list or open socket

      $messages.find('li').attachEventsToMessage();
      $doc.filter('form.sidebar').each(function() {
        $('form.sidebar').attr('action', this.action);
        $('form.sidebar ul').html($(this).find('ul:first').children());
      });
      $doc.filter('nav').each(function() { $('nav ul.conversations').html($(this).find('ul.conversations').children()); });

      // Do not want pjax to follow redirects. It makes the location bar act up
      $('nav a.convos').attr('href', $.url_for($('nav a[data-network]:first').data('network')));

      if (location.href.indexOf('from=') > 0) {
        $messages.find('li:first').addClass('history-starting-point');
        goBackwardInHistory();
      }
      if (convos.current.nick) {
        convos.input.removeAttr('disabled');
        convos.input.attr('placeholder', 'What is on your mind, ' + convos.current.nick + '?');
      }
      else {
        convos.input.attr('disabled', 'disabled');
        convos.input.attr('placeholder', '');
      }

      if (!navigator.is_touch_device) focusFirst();
      if (data) $('body').hideSidebar();

      convos.at_bottom = true; // make "resize" scroll to bottom
      $(window).resize();
    });
  };

  $(document).ready(function() {
    $.ajaxSetup({ error: function(jqXHR, exception) { console.log('ajax: ' + this.url + ' failed: ' + exception); } });
    $.post($.url_for('/profile/timezone/offset'), { hour: new Date().getHours() });

    initPjax();

    $('body, input').bind('keydown', 'shift+return', function(e) {
      e.preventDefault();



( run in 0.559 second using v1.01-cache-2.11-cpan-364913b4093 )