🏠 Home 

Akinator Progression Visualizer

Adds visualization of Akinator's progression (aka. certainity, probability). Inspired by the moving vertical background of the app's old version.

// ==UserScript==
// @name         Akinator Progression Visualizer
// @namespace    Hans5958
// @version      1.0.4
// @description  Adds visualization of Akinator's progression (aka. certainity, probability). Inspired by the moving vertical background of the app's old version.
// @author       Hans5958
// @match        https://*.akinator.com/game
// @match        https://*.akinator.com/rapport
// @match        https://*.akinator.com/choice
// @grant        none
// @license      MIT
// @homepageURL  https://github.com/Hans5958/userscripts
// @supportURL   https://github.com/Hans5958/userscripts/issues
// ==/UserScript==
const generateProgressionReport = () => `${localStorage.getItem('progression')}% in ${localStorage.getItem('step')} steps`
if (document.location.pathname.startsWith('/rapport')) {
if (!localStorage.getItem('progression') || !localStorage.getItem('step')) return
document.querySelector('.game-report > table:nth-child(1) > caption:nth-child(1)').innerHTML += `<br>${generateProgressionReport()}`
return
} else if (document.location.pathname.startsWith('/choice')) {
if (!localStorage.getItem('progression') || !localStorage.getItem('step')) return
const bodyObserver = new MutationObserver(() => {
if (!document.querySelector('.bubble-standard > p:nth-child(2)')) return
document.querySelector('.bubble-standard > p:nth-child(2)').innerHTML += `<span class="win-subtitle">${generateProgressionReport()}</span>`
bodyObserver.disconnect()
})
bodyObserver.observe(document.body.parentElement, {
subtree: true,
childList: true,
})
return
}
let lastData = {}
let disconnectTimeout
let sliderElement = document.createElement('div')
const sidebarElement = document.querySelector('div.col-md-2:nth-child(3), div.col-md-2:nth-child(4)')
const questionGameBlockEl = document.querySelector("#questionGameBlock")
localStorage.removeItem('pid')
sliderElement.innerHTML = `<div style="position: absolute; height: 100%; ">
<div style="height: 100%; display: flex; flex-direction: row-reverse; ">
<div style="width: 1rem; border: black solid 0.125rem; z-index: 200; display: flex; flex-direction: column-reverse; height: 100%; z-index: 10; ">
<div id="progression-slider" style="background-color: black; display: flex; height: 0%; transition: height 0.25s ease-in-out; "></div>
<div id="progression-text" style="position: relative; text-align: right; right: 10.5rem; margin-bottom: -1rem; width: 10rem; bottom: 0%;">
<span id="progression-text-checkmark"></span>
<span id="progression-text-percentage">0%</span>
</div>
</div>
</div>
</div>`
sliderElement = sliderElement.firstChild
sidebarElement.parentElement.style.display = "flex"
sidebarElement.innerHTML = ""
sidebarElement.appendChild(sliderElement)
sidebarElement.style.display = "flex"
sidebarElement.style.flexDirection = "row-reverse"
const progressionTextCheckmarkEl = sliderElement.querySelector('#progression-text-checkmark')
const progressionTextPercentageEl = sliderElement.querySelector('#progression-text-percentage')
const progressionSliderEl = sliderElement.querySelector('#progression-slider')
const watchForGameDataChanges = async () => {
const currentProgression = Number(localStorage.getItem('progression')) || 0
const currentStep = Number(localStorage.getItem('step')) || 0
if (currentStep === lastData.step && currentProgression === lastData.progression) return
// console.info(`Step: ${currentStep}\nProgression: ${currentProgression}%`)
progressionSliderEl.style.height = currentProgression + "%"
// sliderElement.querySelector('#progression-text').style.bottom = currentProgression + "%"
progressionTextPercentageEl.textContent = currentProgression + "%"
progressionTextCheckmarkEl.textContent = ''
lastData.step = currentStep
lastData.progression = currentProgression
disconnectTimeout = setTimeout(() => questionGameBlockObserver.disconnect(), 2000)
}
const watchForPidChanges = async () => {
const currentPid = localStorage.getItem('pid')
if (currentPid === lastData.pid) return
if (currentPid) progressionTextCheckmarkEl.textContent = '✓'
lastData.pid = currentPid
questionGameBlockObserver.disconnect()
}
const questionGameBlockObserver = new MutationObserver(() => {
watchForGameDataChanges()
watchForPidChanges()
})
const startListening = () => {
questionGameBlockObserver.observe(questionGameBlockEl.parentElement, {
subtree: true,
childList: true,
})
}
questionGameBlockEl.parentElement.addEventListener('mouseup', () => {
startListening()
}, true)