Greasy Fork

Niconico Live Auto Enter

開場したら自動で入場します

当前为 2016-01-17 提交的版本,查看 最新版本

// ==UserScript==
// @name        Niconico Live Auto Enter
// @description 開場したら自動で入場します
// @version     0.1.0
// @include     http://live.nicovideo.jp/watch/*
// @grant       GM_notification
// @author      xulapp
// @namespace   /
// @license     MIT
// ==/UserScript==
'use strict';

(() => {
  const notificationTitle = 'Niconico Live Auto Enter';
  const notificationIconClosed = '//live.nicovideo.jp/img/gate/large/door_premium_close.gif';
  const notificationIconOpened = '//live.nicovideo.jp/img/gate/large/door_premium.gif';
  const notificationTag = 'niconico-live-auto-enter';
  const notificationClose = 5000;

  function shouldNotify(remaining) {
    switch (remaining) {
      case 1:
      case 3:
      case 5:
      case 10:
      case 20:
      case 30:
        return true;
    }

    return remaining % 60 === 0;
  }

  {
    let remaining = getRemaining();

    if (remaining === null || remaining <= 0)
      return;
  }

  notifyRemaining();

  let notified = {};

  setInterval(() => {
    let remaining = getRemaining();

    if (!shouldNotify(remaining))
      return;

    if (remaining in notified)
      return;

    if (remaining) {
      notifyRemaining();
    } else {
      notifyEnter();
      enter();
    }

    notified[remaining] = true;
  }, 1000);

  function enter() {
    location.reload(true);
  }

  function getRemaining() {
    let meta = document.querySelector('.kaijo meta[itemprop="datePublished"]');

    if (!meta)
      return null;

    let remaining = Date.parse(meta.content) - Date.now();

    return Math.ceil(remaining / 1000 / 60);
  }

  function notify(message, options, autoClose = 0) {
    let defaultOptions = {
      body: message,
      icon: notificationIconClosed,
      tag: notificationTag,
    };

    options = Object.assign({}, defaultOptions, options);

    return new Promise((resolve, reject) => {
      Notification.requestPermission(status => {
        if (status !== 'granted') {
          reject(status);
          return;
        }

        let n = new Notification(notificationTitle, options);

        if (autoClose)
          setTimeout(() => n.close(), autoClose);

        resolve(n);
      });
    });
  }

  function notifyRemaining() {
    let remaining = getRemaining();
    let minutes = remaining % 60;
    let hours = remaining / 60 % 24 | 0;
    let days = remaining / 60 / 24 | 0;

    let timeStr = [];

    if (days)
      timeStr.push(`${days} 日`);

    if (hours)
      timeStr.push(`${hours} 時間`);

    if (minutes || !timeStr.length)
      timeStr.push(`${minutes} 分`);

    notify(`開場まで、あと ${timeStr.join(' ')} です。`, {
      autoClose: notificationClose,
    });
  }

  function notifyEnter() {
    notify('入場します!', {
      icon: notificationIconOpened,
      autoClose: notificationClose,
    });
  }
})();