// ==UserScript==
// @name Video Celebs Search And UI Tweaks
// @version 1.0.0
// @namespace brazenvoid
// @author brazenvoid
// @license GPL-3.0-only
// @description Video filters and UI manipulations
// @include https://videocelebs.net/*
// @require https://greasyfork.org/scripts/375557-base-resource/code/Base%20Resource.js?version=854444
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
GM_addStyle(`.form-group{display:flex}label.form-label{flex-grow:1}input.form-input{height:auto}input.form-input.check-radio-input{width:auto;margin:0 5px 1px 0}label.form-label{padding: 0}label.title{margin: 0}div.form-group.form-range-input-group>input+input{margin-left: 5px;margin-right:0}`)
const PAGE_PATH_NAME = window.location.pathname
const IS_VIDEO_PAGE = PAGE_PATH_NAME.endsWith('.html')
const FILTER_RATING_VIDEOS_KEY = 'Rating'
const FILTER_VIDEOS_YEAR_KEY = 'Year'
const OPTION_ALWAYS_SHOW_UI = 'Always Show This Settings Pane'
const OPTION_DISABLE_VIDEO_FILTERS = 'Disable All Video Filters'
const OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY = 'Reposition Attributes Section'
const OPTION_REMOVE_COMMENTS_SECTION_KEY = 'Remove Comments Section'
const OPTION_REMOVE_IFRAME_SECTION_KEY = 'Remove Iframe Share Section'
const OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY = 'Remove Related Videos Section'
class VideoCelebsSearchAndUITweaks extends BaseHandler
{
/**
* @typedef {{disableItemComplianceValidation: boolean, rating: {maximum: number, minimum: number}, year: {maximum: number, minimum: number},
* moveVideoAttributesBelowDescription: boolean, removeCommentsSection: boolean, removeIFrameSection: boolean, removeRelatedVideosSection: boolean, showUIAlways: boolean
* }} VideoCelebsSearchAndUITweaksSettings
*/
static initialize ()
{
return (new VideoCelebsSearchAndUITweaks).init()
}
constructor ()
{
super('vc-sui-', 'item.big', {
rating: {
minimum: 0,
maximum: 0,
},
year: {
minimum: 0,
maximum: 0,
},
moveVideoAttributesBelowDescription: false,
removeCommentsSection: false,
removeIFrameSection: false,
removeRelatedVideosSection: false,
})
// UI Events
this._onBeforeUIBuild = () => {
if (IS_VIDEO_PAGE) {
this._moveVideoAttributesBelowDescription()
this._removeCommentsSection()
this._removeIFrameSection()
this._removeRelatedVideosSection()
}
}
this._onUIBuild = () =>
this._uiGen.createSection('settings', '#ffa31a', '15vh', '250px').addSectionChildren([
this._uiGen.createTabsSection(['Filters', 'UI', 'Stats'], [
this._uiGen.createTabPanel('Filters', [
this._createFormRangeInputGroup(FILTER_RATING_VIDEOS_KEY, 'number'),
this._createFormRangeInputGroup(FILTER_VIDEOS_YEAR_KEY, 'number'),
this._uiGen.createSeparator(),
this._uiGen.createFormInputGroup(OPTION_DISABLE_VIDEO_FILTERS, 'checkbox', 'Disables all video filters.'),
this._uiGen.createSeparator(),
this._createSettingsFormActions(),
this._uiGen.createSeparator(),
this._uiGen.createStoreFormSection(this._settingsStore),
]),
this._uiGen.createTabPanel('UI', [
this._uiGen.createFormInputGroup(OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY, 'checkbox', 'Move the video attributes section from below the screenshot area to under the description.'),
this._uiGen.createFormInputGroup(OPTION_REMOVE_COMMENTS_SECTION_KEY, 'checkbox', 'Remove comments area on video pages.'),
this._uiGen.createFormInputGroup(OPTION_REMOVE_IFRAME_SECTION_KEY, 'checkbox', 'Remove iframe share section under video player.'),
this._uiGen.createFormInputGroup(OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY, 'checkbox', 'Remove related videos section on video pages.'),
this._uiGen.createSeparator(),
this._uiGen.createFormInputGroup(OPTION_ALWAYS_SHOW_UI, 'checkbox', 'Always show this interface.'),
this._uiGen.createSeparator(),
this._createSettingsFormActions(),
this._uiGen.createSeparator(),
this._uiGen.createStoreFormSection(this._settingsStore),
]),
this._uiGen.createTabPanel('Stats', [
this._uiGen.createStatisticsFormGroup(FILTER_RATING_VIDEOS_KEY),
this._uiGen.createStatisticsFormGroup(FILTER_VIDEOS_YEAR_KEY),
this._uiGen.createSeparator(),
this._uiGen.createStatisticsTotalsGroup(),
]),
]),
this._uiGen.createStatusSection(),
])
// Compliance Events
this._onGetItemLists = () => document.querySelectorAll('.midle_div,.list_videos')
this._complianceFilters = [
(videoItem) => this._validateRating(videoItem),
(videoItem) => this._validateYear(videoItem),
]
// Store Events
this._onSettingsStoreUpdate = () => {
/** @type {VideoCelebsSearchAndUITweaksSettings} */
let store = this._settingsStore.get()
this._uiGen.setSettingsInputCheckedStatus(OPTION_ALWAYS_SHOW_UI, store.showUIAlways)
this._uiGen.setSettingsInputCheckedStatus(OPTION_DISABLE_VIDEO_FILTERS, store.disableItemComplianceValidation)
this._uiGen.setSettingsInputCheckedStatus(OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY, store.moveVideoAttributesBelowDescription)
this._uiGen.setSettingsInputCheckedStatus(OPTION_REMOVE_COMMENTS_SECTION_KEY, store.removeCommentsSection)
this._uiGen.setSettingsInputCheckedStatus(OPTION_REMOVE_IFRAME_SECTION_KEY, store.removeIFrameSection)
this._uiGen.setSettingsInputCheckedStatus(OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY, store.removeRelatedVideosSection)
this._uiGen.setSettingsRangeInputValue(FILTER_RATING_VIDEOS_KEY, store.rating.minimum, store.rating.maximum)
this._uiGen.setSettingsRangeInputValue(FILTER_VIDEOS_YEAR_KEY, store.year.minimum, store.year.maximum)
}
this._onSettingsApply = () => {
/** @type {VideoCelebsSearchAndUITweaksSettings} */
let settings = this._settings
settings.disableItemComplianceValidation = this._uiGen.getSettingsInputCheckedStatus(OPTION_DISABLE_VIDEO_FILTERS)
settings.moveVideoAttributesBelowDescription = this._uiGen.getSettingsInputCheckedStatus(OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY)
settings.rating.minimum = this._uiGen.getSettingsRangeInputValue(FILTER_RATING_VIDEOS_KEY, true)
settings.rating.maximum = this._uiGen.getSettingsRangeInputValue(FILTER_RATING_VIDEOS_KEY, false)
settings.removeCommentsSection = this._uiGen.getSettingsInputCheckedStatus(OPTION_REMOVE_COMMENTS_SECTION_KEY)
settings.removeIFrameSection = this._uiGen.getSettingsInputCheckedStatus(OPTION_REMOVE_IFRAME_SECTION_KEY)
settings.removeRelatedVideosSection = this._uiGen.getSettingsInputCheckedStatus(OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY)
settings.showUIAlways = this._uiGen.getSettingsInputCheckedStatus(OPTION_ALWAYS_SHOW_UI)
settings.year.minimum = this._uiGen.getSettingsRangeInputValue(FILTER_VIDEOS_YEAR_KEY, true)
settings.year.maximum = this._uiGen.getSettingsRangeInputValue(FILTER_VIDEOS_YEAR_KEY, false)
}
}
_moveVideoAttributesBelowDescription ()
{
if (this._settings.moveVideoAttributesBelowDescription) {
let videoInfoBlock = document.querySelector('.entry-utility')
videoInfoBlock.parentNode.insertBefore(videoInfoBlock, videoInfoBlock.previousSibling.previousSibling)
}
}
_removeCommentsSection ()
{
if (this._settings.removeCommentsSection) {
document.querySelector('.comments-area').remove()
}
}
_removeIFrameSection ()
{
if (this._settings.removeIFrameSection) {
document.querySelector('#tab_share').remove()
}
}
_removeRelatedVideosSection ()
{
if (this._settings.removeRelatedVideosSection) {
document.querySelector('.related').remove()
}
}
/**
* Validate video source release year
* @param {Node|HTMLElement} videoItem
* @return {boolean}
* @private
*/
_validateRating (videoItem)
{
if (this._settings.rating.minimum > 0 || this._settings.rating.maximum > 0) {
let rating = parseInt(videoItem.querySelector('.rating').textContent.trim().replace('%', ''))
return this._validator.validateRange(FILTER_RATING_VIDEOS_KEY, rating, [this._settings.rating.minimum, this._settings.rating.maximum])
}
return true
}
/**
* Validate video view count
* @param {Node|HTMLElement} videoItem
* @return {boolean}
* @private
*/
_validateYear (videoItem)
{
if (this._settings.year.minimum > 0 || this._settings.year.maximum > 0) {
let yearFragments = videoItem.querySelector('.title a').textContent.trim().split('(')
let year = parseInt(yearFragments[yearFragments.length - 1].replace(')', ''))
return this._validator.validateRange(FILTER_RATING_VIDEOS_KEY, year, [this._settings.year.minimum, this._settings.year.maximum])
}
return true
}
/**
* @param {string} label
* @param {string} inputsType
*
* @return {HTMLElement}
* @private
*/
_createFormRangeInputGroup (label, inputsType = 'text')
{
let maxInputSelector = this._uiGen._selectorGenerator.getSettingsRangeInputSelector(label, false)
let minInputSelector = this._uiGen._selectorGenerator.getSettingsRangeInputSelector(label, true)
let divFormInputGroup = this._uiGen.createFormGroup([
this._uiGen.createFormGroupLabel(label, '', inputsType),
this._uiGen.createFormGroupInput(minInputSelector, inputsType),
this._uiGen.createFormGroupInput(maxInputSelector, inputsType),
])
divFormInputGroup.classList.add('form-range-input-group')
return divFormInputGroup
}
}
VideoCelebsSearchAndUITweaks.initialize()