您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
GINZAwatchに時計復活。 ついでに過去ログ時間選択も使いやすくする
// ==UserScript== // @name WatchWatch // @namespace https://github.com/segabito/ // @description GINZAwatchに時計復活。 ついでに過去ログ時間選択も使いやすくする // @include http://www.nicovideo.jp/watch/* // @version 0.1.6 // @grant none // ==/UserScript== (function() { var monkey = (function() { 'use strict'; if (!window.WatchJsApi) { return; } window.WatchWatch = {}; var console = { log: function() {}, trace: function() {} }; if (localStorage.watchItLater_debugMode === 'true') { console = window.console; } var _ = require('lodash'); var inherit = require('cjs!inherit'); var advice = require('advice'); var EventDispatcher = require('watchapp/event/EventDispatcher'); var TimeMachine = (function() { function TimeMachine(playerInitializer) { EventDispatcher.call(this); this._initialize(playerInitializer); } inherit(TimeMachine, EventDispatcher); _.assign(TimeMachine.prototype, { _initialize: function(playerInitializer) { var commentPanelView = this._commentPanelView = playerInitializer.rightSidePanelViewController._playerPanelTabsView._commentPanelView; advice.after(commentPanelView, '_showLogForm', _.bind(function(date) { this.dispatchEvent('timeMachine-changePastMode', true, date); }, this)); advice.after(commentPanelView, '_hideLogForm', _.bind(function() { this.dispatchEvent('timeMachine-changePastMode', false); }, this)); }, goToPast: function(tm) { this._commentPanelView.loadPastComments(tm); }, goToPresent: function() { this._commentPanelView.loadPastComments(); } }); return TimeMachine; })(); _.assign(window.WatchWatch, { _isPastMode: false, _pastTime: (new Date()).getTime(), getPastTime: function() { if (this._isPastMode) { return this._pastTime; } else { return (new Date()).getTime(); } }, initialize: function() { var PlayerInitializer = require('watchapp/init/PlayerInitializer'); this._watchInfoModel = require('watchapp/model/WatchInfoModel').getInstance(); this._playerAreaConnector = PlayerInitializer.playerAreaConnector; this._nicoPlayerConnector = PlayerInitializer.nicoPlayerConnector; this._timeMachine = new TimeMachine(PlayerInitializer); var EventDispatcher = require('watchapp/event/EventDispatcher'); this.event = new EventDispatcher(); this.initializeCss(); this.initializeUserConfig(); this.initializeDom(); this.initializeTimeMachine(); this.initializeTimer(); }, addStyle: function(styles, id) { var elm = document.createElement('style'); elm.type = 'text/css'; if (id) { elm.id = id; } var text = styles.toString(); text = document.createTextNode(text); elm.appendChild(text); var head = document.getElementsByTagName('head'); head = head[0]; head.appendChild(elm); return elm; }, initializeCss: function() { var __css__ = (function() {/* .watchWatch #playerCommentPanel .playerCommentPanelHeader .currentThreadName, .watchWatch .select-box.comment-type { width: 120px; } .watchWatch #playerCommentPanel .playerCommentPanelHeader .comment, .watchWatch .header-icon.comment-log { display: none; } .watchWatch #playerCommentPanel #commentLogHeader form, .watchWatch .comment-panel .log-form { display: none; } .watchWatch #playerCommentPanel .section #commentLog.commentTable, .watchWatch .comment-panel.log-form-opened .panel-body { top: 28px; } .watchWatch .commentPanelAlert, .watchWatch .comment-panel .panel-alert { top: 28px; } .watchWatchContainer { position: absolute; left: 139px; top: 5px; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; width: 140px; font-size: 10px; padding: 5px 4px 2px; text-align: center; white-space: nowrap; overflow: hidden; background: #f4f4f4; border: 1px solid #999; cursor: pointer; z-index: 10060; } .watchWatchContainer:hover { background: #fff; color: #008; } .watchWatchContainer.past { color: red; } .timeMachineControl.show { display: block; } .timeMachineControl { position: absolute; display: none; top: 34px; left: 6px; z-index: 10060; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; width: 313px; overflow: hidden; background: #fff; box-shadow: 0 0 4px black; } .timeMachineControl .reset, .timeMachineControl .title { margin: 8px; } .timeMachineControl .datepickerContainer { } .timeMachineControl .datepickerContainer .ui-datepicker { display: block; margin: auto; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; width: 100%; } .timeMachineControl .datepickerContainer .ui-datepicker .ui-datepicker-title select.ui-datepicker-year { width: 40%; } .timeMachineControl .datepickerContainer .ui-datepicker .ui-datepicker-title select.ui-datepicker-month { width: 40%; } .timeMachineControl .ui-widget-content { border: none; } .timeMachineControl .inputFormContainer { text-align: center; } .timeMachineControl .dateInput { text-align: center; width: 150px; } .timeMachineControl .hourInput:after { content: ' : '; font-weight: boler; } .timeMachineControl .submitButtonContainer { text-align: center; padding: 8px; } .timeMachineControl .reset { display: none; } .timeMachineControl.past .reset { display: inline-block; } .timeMachineControl .reset, .timeMachineControl .submit { padding: 8px; cursor: pointer; } {* *} .watchWatchContainer .year:after { content: '/'; } .watchWatchContainer .month:after { content: '/'; } .watchWatchContainer .date:after { content: ''; } .watchWatchContainer .day:before { content: '('; } .watchWatchContainer .day:after { content: ') '; } .watchWatchContainer.sun .day .inner:after { content: '日'; } .watchWatchContainer.mon .day .inner:after { content: '月'; } .watchWatchContainer.tue .day .inner:after { content: '火'; } .watchWatchContainer.wed .day .inner:after { content: '水'; } .watchWatchContainer.thu .day .inner:after { content: '木'; } .watchWatchContainer.fri .day .inner:after { content: '金'; } .watchWatchContainer.sat .day .inner:after { content: '土'; } .watchWatchContainer .hour:after { content: ':'; } .watchWatchContainer .min:after { content: ':'; } .watchWatchContainer .sec:after { content: ''; } */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1].replace(/\{\*/g, '/*').replace(/\*\}/g, '*/'); this.addStyle(__css__, 'WatchWatchCss'); }, initializeUserConfig: function() { var prefix = 'WatchWatch_'; var conf = {}; this.config = { get: function(key) { try { if (window.localStorage.hasOwnProperty(prefix + key)) { return JSON.parse(window.localStorage.getItem(prefix + key)); } return conf[key]; } catch (e) { return conf[key]; } }, set: function(key, value) { window.localStorage.setItem(prefix + key, JSON.stringify(value)); } }; }, initializeTimeMachine: function() { var timeMachine = this._timeMachine; var watchInfoModel = this._watchInfoModel; var playerAreaConnector = this._playerAreaConnector; timeMachine.addEventListener('reset', $.proxy(function() { this._isPastMode = false; this.event.dispatchEvent('timeMachine-changePastMode', false, new Date()); }, this)); timeMachine.addEventListener('error', $.proxy(function() { this.event.dispatchEvent('timeMachine.error'); }, this)); playerAreaConnector.addEventListener('onTimeMachineDateUpdated', $.proxy(function(isPast, time) { console.log('dispatch.timeMachine-changePastMode', isPast, time); if (isPast) { this._isPastMode = true; this._pastTime = time; this.event.dispatchEvent('timeMachine-changePastMode', true, new Date(time)); } else { this._isPastMode = false; this.event.dispatchEvent('timeMachine-changePastMode', false, new Date()); } }, this)); watchInfoModel.addEventListener('reset', $.proxy(function() { this._isPastMode = false; if (initialized) { beforeShow(); } }, this)); var beforeShow = $.proxy(function() { var md = watchInfoModel.postedAt.split(' ')[0].split('/'); var $date = this._$datepickerContainer; $date.datepicker('option', 'minDate', new Date(md[0], md[1] - 1, md[2])); $date.datepicker('option', 'maxDate', new Date()); var v = this._$dateInput.val(); if (v.match(/^(\d{4})[¥/-](\d{2})[¥/-](\d{2})$/)) { var dt = new Date(RegExp.$1, RegExp.$2 - 1, RegExp.$3); if (dt) $date.datepicker('setDate', dt); } }, this); var initialize = $.proxy(function() { if (initialized) { return; } this._$datepickerContainer.datepicker({ dateFormat: 'yy/mm/dd', // beforeShow: beforeShow, altField: this._$dateInput, changeMonth: true, changeYear: true }); initialized = true; }, this), initialized = false; this.resetDatepicker = $.proxy(function() { initialize(); beforeShow(); }, this); this.event.addEventListener('popup.toggle', $.proxy(function(v) { if (!v) { return; } this.resetDatepicker(); }, this)); this.timeMachineController = { goToPast: function(tm) { if (!tm) tm = (new Date()).getTime(); if (typeof tm === 'object' && tm.getTime) tm = tm.getTime(); tm = Math.min(window.WatchApp.ns.util.TimeUtil.now(), tm); var postedAt = new Date(watchInfoModel.postedAt.substring(0, 16).replace(/-/g, '/').split(' ')); console.log('postedAt', postedAt.getTime(), tm); // 投稿直後より前は指定できない。マイメモリーやチャンネルだと怪しいかも // 投稿日時ぴったりもだめっぽい。 おそらく投稿確定後にスレッドが作られるため。 tm = Math.max(postedAt.getTime() + 300 * 1000, tm); timeMachine.goToPast(tm); }, now: function() { timeMachine.goToPresent(); } }; }, initializeDom: function() { $('#playerTabWrapper').addClass('watchWatch'); var $watch = this._$watch = $([ '<div id="watchWatch" class="watchWatchContainer sun">', '<span class="year">2014</span>', '<span class="month">01</span>', '<span class="date">01</span>', '<span class="day">', '<span class="inner"></span>', '</span>', '<span class="hour">00</span>', '<span class="min">00</span>', '<span class="sec">00</span>', '</div>', ''].join('')); var $popup = this._$popup = $([ '<div id="watchWatchTimeMachine" class="timeMachineControl">', '<h1 class="title">過去のコメントを開く</h1>', '<div class="datepickerContainer"></div>', '<div class="inputFormContainer">', '<input type="text" name="date" value="2014/01/01" class="dateInput">', '<select name="hour" class="hourInput"></select>', '<select name="minute" class="minuteInput"></select>', '</div>', '', '<div class="submitButtonContainer">', '<button class="submit">過去ログを見る</button>', '<button class="reset">最新ログに戻る</button>', '</div>', '</div>', ''].join('')); $('#playerCommentPanel, #playerTabContainer .comment-panel').after($watch).after($popup); this._$datepickerContainer = $popup.find('.datepickerContainer'); this._$dateInput = $popup.find('.dateInput'); this._$hourInput = $popup.find('.hourInput'); this._$minuteInput = $popup.find('.minuteInput'); this._$submitButton = $popup.find('.submit'); this._$resetButton = $popup.find('.reset'); var options = []; for (var i = 0; i < 60; i++) { var m = ('0' + i).slice(-2); options.push(['<option value="', m, '">', m, '</option>'].join('')); } this._$hourInput.html(options.slice(0, 24).join('')); this._$minuteInput.html(options.join('')); var resetInput = $.proxy(function(time) { var date; if (typeof time === 'number') { date = new Date(time); } else if (typeof time === 'object' && time.getTime) date = time; else if (!time) date = new Date(); console.log('resetInput', time, date); var y = date.getFullYear(); var m = (date.getMonth() + 101).toString().slice(-2); var d = ('0' + date.getDate()).slice(-2); var hh = ('0' + date.getHours()).slice(-2); var mm = ('0' + date.getMinutes()).slice(-2); this._$dateInput .val(y + '/' + m + '/' + d); this._$hourInput .val(hh); this._$minuteInput.val(mm); //console.log('dt', y, m, d, hh, mm); }, this); $watch.on('click', $.proxy(function() { this.togglePopup(); }, this)); this.togglePopup = $.proxy(function(v) { if (typeof v === 'boolean') { this._$popup.toggleClass('show', v); } else { this._$popup.toggleClass('show'); } resetInput(this.getPastTime()); this.event.dispatchEvent('popup.toggle', this._$popup.hasClass('show')); }, this); this.showPopup = $.proxy(function() { this.togglePopup(true); }, this); this.hidePopup = $.proxy(function() { this.togglePopup(false); }, this); this.event.addEventListener('timeMachine-changePastMode', $.proxy(function(isPast, time) { this.hidePopup(); console.log('initializeDom.timeMachine-changePastMode', isPast, time); this._$watch.toggleClass('past', isPast); this._$popup.toggleClass('past', isPast); resetInput(time); }, this)); this.event.addEventListener('timeMachine.error', $.proxy(function() { this.hidePopup(); // エラーメッセージが見えないので閉じる }, this)); this._$submitButton.on('click', $.proxy(function() { var dd = this._$dateInput.val().replace(/-/g, '/'); var tt = this._$hourInput.val() + ':' + this._$minuteInput.val(); var dt = new Date(dd + ' ' + tt + ':00'); this.timeMachineController.goToPast(dt); }, this)); this._$resetButton.on('click', $.proxy(function() { this.timeMachineController.now(); }, this)); $watch = $popup = null; }, initializeTimer: function() { var date = new window.Date(); var $watch = this._$watch; var $year = $watch.find('.year'); var $month = $watch.find('.month'); var $date = $watch.find('.date'); var $hour = $watch.find('.hour'); var $min = $watch.find('.min'); var $sec = $watch.find('.sec'); var days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; var timer; var update = function(force, time) { if (time) { date.setTime(time); console.log('setTime', time, date); } else { date.setTime((new Date()).getTime()); } var sec = date.getSeconds(); $sec.text(('0' + sec).slice(-2)); if (force || sec === 0) { var min = date.getMinutes(); $min.text(('0' + min).slice(-2)); if (force || min === 0) { $hour .text(('0' + date.getHours()).slice(-2)); $date .text(('0' + date.getDate()) .slice(-2)); var month = date.getMonth(); $month.text((date.getMonth() + 101).toString().slice(-2)); $year .text(date.getFullYear()); var day = date.getDay(); $watch .removeClass('month' + (((month + 11) % 12) + 1)) .addClass( 'month' + (month + 1)) .removeClass(days[(day + 6) % 7] ) .addClass( days[day]); } } }; var onTimer = this._onTimer = $.proxy(function() { if (this._isPastMode) { return; } update(false); }, this); this.event.addEventListener('timeMachine-changePastMode', function(isPast, time) { console.log('timer.timeMachine-changePastMode', isPast, time, new Date(time)); if (isPast) { window.setTimeout(function() { update(true, time); }, 1000); } else { update(true); } }); update(true); window.WatchApp.mixin(this, { watch: { start: function() { if (timer) return; timer = window.setInterval($.proxy(onTimer, this), 600); }, stop: function() { window.clearInterval(timer); timer = null; }, refresh: function() { update(true); } } }); this.watch.start(); } }); if (window.PlayerApp) { require(['WatchApp'], function() { var watchInfoModel = require('watchapp/model/WatchInfoModel').getInstance(); if (watchInfoModel.initialized) { window.WatchWatch.initialize(); } else { var onReset = function() { watchInfoModel.removeEventListener('reset', onReset); window.setTimeout(function() { watchInfoModel.removeEventListener('reset', onReset); window.WatchWatch.initialize(); }, 0); }; watchInfoModel.addEventListener('reset', onReset); } }); } }); var script = document.createElement('script'); script.id = 'WatchWatchLoader'; script.setAttribute('type', 'text/javascript'); script.setAttribute('charset', 'UTF-8'); script.appendChild(document.createTextNode('(' + monkey + ')()')); document.body.appendChild(script); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址