sunnyok / CRAnimere

// ==UserScript==
// @name      CRAnimere
// @namespace Sunnyok
// @description Animere on CR
// @copyright 2014, Sunnyok
// @oujs:author Sunnyok
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
// @include   http://www.crunchyroll.com/*
// @include   http://www.crunchyroll.ca/*
// @version   1.2.1
// @grant     GM_addStyle
// @grant     GM_getResourceText
// @grant     GM_xmlhttpRequest
// @resource  CCL_BASE https://sunnyli.github.io/CommentCorePlayer/build/style.css
// @resource  CSS https://sunnyli.github.io/CommentCorePlayer/style.css
// @require   https://sunnyli.github.io/CommentCorePlayer/build/CommentCoreLibrary.js
// @require   https://sunnyli.github.io/CommentCorePlayer/demo/libxml.js
// @require   https://code.jquery.com/jquery-1.11.1.min.js
// ==/UserScript==

GM_addStyle ( GM_getResourceText ('CCL_BASE') );
GM_addStyle ( GM_getResourceText ('CSS') );
GM_addStyle ( '                                 \
  .abp .container .cmt{                         \
    pointer-events: none;                       \
  }                                             \
                                                \
  /* FS */                                      \
  #showmedia_video_player{ width: 100%; }       \
  :-moz-full-screen div.abp{                    \
      height: calc(100% - 25px) !important;     \
      width: 100% !important;                   \
  }                                             \
  :-moz-full-screen #danmu{                     \
    background-color: #111 !important;          \
  }                                             \
  :-moz-full-screen #danmu input,               \
  :-moz-full-screen #danmu select{              \
    background-color: transparent;              \
    border-color: #333;                         \
    color: #3f3f3f;                             \
  }                                             \
  :-moz-full-screen #danmu input[type=text]{    \
    color: lightgray;                           \
  }                                             \
  :-webkit-full-screen,                         \
  :-webkit-full-screen #showmedia_video_player, \
  :-webkit-full-screen div#showmedia_video_box, \
  :-webkit-full-screen div#showmedia_video_box_wide{\
    float: none;                                \
    height: 100%;                               \
    width: 100%;                                \
  }                                             \
  :-webkit-full-screen .abp{                    \
    height: calc(100% - 25px) !important;       \
    width: 100% !important;                     \
  }                                             \
  :-webkit-full-screen #danmu{                  \
    background-color: #111 !important;          \
  }                                             \
  :-webkit-full-screen #danmu input,            \
  :-webkit-full-screen #danmu select{           \
    background-color: transparent;              \
    border-color: #333;                         \
    color: #3f3f3f;                             \
  }                                             \
  :-webkit-full-screen #danmu input[type=text]{ \
    color: lightgray;                           \
  }                                             \
');

function CommentDisplay() {
  var self = this,
    retries = 10;

  this.cm = null;
  this.player = null;
  this.server = 'https://anime.re/';
  this.title = jQuery('link[rel="index"]')[0].title;
  this.episode = jQuery('.collection-carousel-media-link-current')
    .find('.collection-carousel-overlay-top.ellipsis')[0]
    .textContent.trim();
  this.mid = parseInt(jQuery('.collection-carousel-media-link-current')
    .parent()[0].getAttribute('media_id'));

  (function construct() {
    if (jQuery('#commentCanvas').length) {
      self.cm = new CommentManager(jQuery('#commentCanvas')[0]);
      self.cm.init();
      self.cm.def.scrollScale = 2;
      commentInit();
      self.cm.startTimer();

      jQuery('#danmu')[0].addEventListener('submit', self.onComment);
      jQuery(document).bind('fullscreenchange mozfullscreenchange webkitfullscreenchange', function(){
        setTimeout(function() {self.cm.setBounds()}, 1000);
        if (window.fullScreen) {
          self.player.style.height = window.screen.availHeight + 10 + 'px';
        } else {
          self.player.style.height = '';
        }
      })
    }else{
      if (retries-- < 0) return
      setTimeout(construct, 100);
      console.log('waiting for commentCanvas node');
    }
  })();

  this.load = this.loadCmt = function(url,mode){
    CommentLoader(url,this.cm,function(){},mode);
  }

  function commentInit() {
    GM_xmlhttpRequest({
      method: "POST",
      url: self.server + 'cr/init',
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      data: jQuery.param({
        id: self.mid,
        a: self.title,
        e: self.episode
      }),
      onload: function (response) {
        if (response.status == 200) {
          self.cid = String(response.responseText);
          self.load(self.server + 'solver/resolve?d=' + self.cid
            + '&r=' + Math.round(Math.random() * new Date / 1000));
          jQuery('form#danmu').find('*').attr('disabled', false);
          jQuery('input:text[name="comment"]').attr("placeholder", " leave a comment")
        } else {
          jQuery('form#danmu').find('*').attr('disabled', true);
          jQuery('input:text[name="comment"]').attr("placeholder", " cannot connect.. π_π")
        }
      }
    });
  }

  this.toggleFullscreen = function() {
    var element = jQuery('div.ls')[0];
    if ((document.fullScreenElement && document.fullScreenElement !== null) ||
      (!document.mozFullScreen && !document.webkitIsFullScreen)) {
      if (element.requestFullScreen) {
        element.requestFullScreen();
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
      } else if (element.webkitRequestFullScreen) {
        element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
      }
    } else {
      if (document.cancelFullScreen) {
        document.cancelFullScreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
      }
    }
  }

  this.onComment = function (event) {
    event.preventDefault();

    if (jQuery('input:text[name="comment"]').val() === 'fs') {
      jQuery('input:text[name="comment"]').val('');
      self.toggleFullscreen();
    }

    if (jQuery('input:text[name="comment"]').val() !== '') {
      var cmt = {};
        cmt.stime = self.player.getPlayhead() * 1000,
        cmt.mode = parseInt(jQuery('select#mode').val(), 10),
        cmt.size = jQuery('select#fontsize').val(),
        cmt.text = jQuery('input:text[name="comment"]').val(),
        cmt.border = true;

      function displaySentDanmaku () {
        self.cm.timeline.binsert(cmt,function(a,b){
          if(a.stime < b.stime){
            return -1;
          }else if (a.stime == b.stime){
            return 0;
          }else{return 1;}
        });

        jQuery('input:text[name="comment"]').attr("placeholder", "comment sent")
      }

      function displaySendFailure () {
        jQuery('input:text[name="comment"]').attr("placeholder", "comment failed")
      }

      GM_xmlhttpRequest({
        method: "POST",
        url: self.server + 'danmaku',
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        },
        data: jQuery.param({
          cid: self.cid,
          stime: (cmt.stime / 1000).toFixed(2),
          mode: cmt.mode,
          message: cmt.text,
          size: cmt.size
        }),
        onload: function (response) {
          if (response.status == 201) {
            displaySentDanmaku();
          } else {
            displaySendFailure();
          }
        }
      });

      jQuery('input:text[name="comment"]').val('');
    }
    return false;
  }

  var video_div;
  if (jQuery('#showmedia_video_box_wide').length > 0) {
    video_div = jQuery('#showmedia_video_box_wide');
  } else {
    video_div = jQuery('#showmedia_video_box');
  }

  video_div.wrap('<div class="ls"><div class="abp">'
    + '<div id="commentCanvas" class="container"></div></div>'
    + '<form id="danmu">Styles: <select name="mode" id="mode">'
    + '<option value="1" selected>default</option>'
    + '<option value="5">top</option>'
    + '<option value="4">Bottom</option></select>'
    + '<select name="fontsize" id="fontsize">'
    + '<option value="15">Small</option>'
    + '<option value="25" selected>Medium</option>'
    + '<option value="38">Large</option></select>'
    + '<input type="text" name="comment" maxlength="50"'
    + ' placeholder=" connecting to server.." autofocus>'
    + '<input type="submit" value="Comment"></form></div>'
  );
  jQuery('form#danmu').find('*').attr('disabled', true);

  // fix styles
  setTimeout(function(){
    self.player = unsafeWindow.jQuery('#showmedia_video_player')[0];
    jQuery('.abp')[0].style.height = self.player.getAttribute("height") + 'px';
    jQuery('.abp')[0].style.width = self.player.getAttribute("width") + 'px';
  }, 0);

  setInterval(function(){
    self.cm.time(self.player.getPlayhead() * 1000);
  }, 500);
}

CommentDisplay();