ptrharmonic / Audio Widget Player

// ==UserScript==
// @name     Audio Widget Player
// @version  1
// @grant    none
// @include https://*.fandom.com/*
// @require https://unpkg.com/preact
// @require https://unpkg.com/htm
// @copyright 2022, ptrharmonic (https://openuserjs.org/users/ptrharmonic)
// @license MIT
// @updateURL https://openuserjs.org/meta/ptrharmonic/Audio_Widget_Player.meta.js
// @downloadURL https://openuserjs.org/install/ptrharmonic/Audio_Widget_Player.user.js
// ==/UserScript==

const { h, Component, render } = preact;
// const { htm } = htm;
console.log(htm, htm.preact);
const html = htm.bind(h);

config = {
	"fandom.com": {
    "mount": ".main-container"
  }
}


class Controls extends Component {
  state = {
  	"playing": false,
    "elems": [],
    "index": 0
  }
  constructor(props) {
    super(props);
    this.playButton = this.playButton.bind(this);
    this.scan = this.scan.bind(this);
    this.playbackEnded = this.playbackEnded.bind(this);
    this.play = this.play.bind(this);
    this.pause = this.pause.bind(this);
  }

	componentDidMount() {
    this.scan();
  }

	componentDidUpdate(prevProps, prevState) {
  	if (prevState.index !== this.state.index && this.state.playing) {
    	this.play();
    }
  }

	currentElem() {
  	return this.state.elems[this.state.index];
  }

	play() {
    let elem = this.currentElem();
    elem.play();
    elem.onended = this.playbackEnded;
    this.setState({"playing": true});
  }
	
  pause() {
      this.currentElem().pause();
    	this.setState({"playing": false});
  }

	playButton() {
    if (!this.state.playing) {
    	this.play();
    } else {
    	this.pause();
    }
  }
	
	playbackEnded() {
  	this.setState({"index": this.state.index + 1});
  }
        
	scan() {
  	let audioElems = document.querySelectorAll("audio");
  	console.log(audioElems);
    this.setState({"elems": audioElems});
  }

	seek(value) {
  	this.currentElem().pause();
    this.setState({"index": this.state.index + value});
  }
  
	render(props, state) {
    return html`
				<div style="position: sticky;">
					<button onClick=${this.playButton}>${(state.playing ? "Pause" : "Play")}</button>
					<button onClick=${this.scan}>Scan</button>
					<p>Found ${state.elems.length} audio elems</p>
					<button onClick=${() => this.seek(-1)}>Prev</button>
					<button onClick=${() => this.seek(1)}>Next</button>
					<span>${state.index}</span>
				</div>
			`;
  }
}


let parts = window.location.host.split(".");
let mountParent = document.body;

for (let i=0;i<parts.length;i++) {
	let url = parts.join(".");
  console.log(url);
	if (url in config) {
    console.log("hiya");
  	mountParent = document.querySelector(config[url].mount);
  }
  parts.splice(0, 1);
}



const elemMount = document.createElement("div");
elemMount.style.cssText = "position: fixed; min-width:5rem; min-height: 5rem; background-color: white; top:0; right:0; z-index:1000";
mountParent.insertAdjacentElement("beforeend", elemMount);

const app = html`<${Controls}/>`
render(app, elemMount);