// TODO: // + Add adjustable timing // - Add random timing option let socket let socketStatus = false let mimes = {} let timer let jsonValid = (json) => { try { JSON.parse(json); if (json == null) { return false; } } catch (e) { return false; } return true; } let loadMime = () => { return new Promise((resolve, reject) => { let request = new XMLHttpRequest() request.open('GET', 'image.csv', true) request.onload = () => { if (request.readyState = 4 && request.status === 200) { let mimeCSV = request.responseText mimeCSV.split('\n').forEach(line => { line = line.split(',') let extension = line[0] let mime = line[1] let RFC = line[2] mimes[extension] = { mime: mime, RFC: RFC } }) resolve() }else{ reject('Failed to load image.csv') } } request.send() }) } let urlExists = (url, callback) => { var request = new XMLHttpRequest() request.open('GET', url, true) request.onreadystatechange = () => { if (request.readyState === 4){ if (request.status === 404) { callback(false) } else { callback(true) } } }; request.send(); } let preloadImage = (url, callback) => { console.log(`%cPreloading ${url}`, 'color: #ECEFF4; font-family: monospace;') let request = new XMLHttpRequest() request.responseType = 'blob' request.open('GET', url, true) request.onload = () => { console.log(`%cLoaded (${request.status}) ${url} `, 'color: #ECEFF4; font-family: monospace;') if (request.readyState = 4 && request.status === 200) { let reader = new FileReader() reader.readAsArrayBuffer(request.response) reader.onload = () => { let imageData = btoa(new Uint8Array(reader.result).reduce((data, byte) => data + String.fromCharCode(byte), '')) let header = "data:"//";base64," let extension = url.split('.').pop() + "" if (mimes[extension.toLowerCase()]) { header += mimes[extension].mime } else { header += "image/" + extension } header += ";base64," // console.log(("%c" + header + imageData), "color: #A3BE8C; font-family: monospace; font-size: 8px;") callback(header + imageData) } }else { callback(false) } } request.send() } let setWallpaper = (path) => { preloadImage(path, (image) => { if (image) { console.log(`Setting wallpaper to ${path}`) let wallpaper = document.getElementById('wallpaper') // wallpaper.style.backgroundImage = `url(${path})` wallpaper.style.backgroundImage = `url(${image})` } }) } let dumpStorage = () => { console.log('%cDumping Local Storage', 'color: #EBCB8B; font-family: monospace; font-size: 18px;') console.log(' Member:' + localStorage.getItem('member')) // console.log(' Token' + localStorage.getItem('token')) console.log(' System:' + localStorage.getItem('systemId')) console.log(' Socket:' + localStorage.getItem('socket')) console.log(' Slide Delay:' + localStorage.getItem('timeout_m') + "m " + localStorage.getItem('timeout_s') + "s") console.log(' Wallpapers:') console.log(("%c "+localStorage.getItem('wallpapers')), "color: #A3BE8C; font-family: monospace; font-size: 8px;") } let grabLatestFronter = () => { let systemId = localStorage.getItem('systemId') if (systemId != null) { var xhr = new XMLHttpRequest() xhr.withCredentials = true xhr.addEventListener("readystatechange", function() { if(this.readyState === 4) { // console.log(this.responseText) let fronter = JSON.parse(this.responseText).members[0].id localStorage.setItem('member', fronter) console.log(`%cFronter: ${fronter}`, 'color: #ECEFF4; font-family: monospace;') pickWallpaper() } }) xhr.open("GET", "https://api.pluralkit.me/v2/systems/"+systemId+"/fronters") xhr.send() }else{ localStorage.setItem('member', 'null') } } let pickWallpaper = () => { let wallpapers = localStorage.getItem('wallpapers') if (jsonValid(wallpapers)) { wallpapers = JSON.parse(localStorage.getItem('wallpapers')) } else { wallpapers = [] console.log('%cWallpapers not found in Local Storage', 'color: #BF616A; font-size: 18px; font-family: monospace;') } let validWallpapers = [] wallpapers.forEach(wp => { if (wp.toLowerCase().includes(localStorage.getItem('member').toLowerCase())) { validWallpapers.push(wp) } }) let chosenWallpaper = validWallpapers[Math.floor(Math.random() * validWallpapers.length)] let wallpaper = "file:///" + chosenWallpaper if (validWallpapers.length == 0) { wallpaper = "https://picsum.photos/3840/2160" } urlExists(wallpaper, (exists) => { if (exists) { let delay_s = localStorage.getItem('timeout_s') if (delay_s == null) { delay_s = 30 localStorage.setItem('timeout_s', delay_s) } let delay_m = localStorage.getItem('timeout_m') if (delay_m == null) { delay_m = 0 localStorage.setItem('timeout_m', delay_m) } let delay = (parseFloat(delay_s) * 1000) + (parseInt(delay_m) * 60000) setWallpaper(wallpaper) timer = setTimeout(() => { pickWallpaper() }, delay) } else { console.log(`%c${wallpaper} does not exist`, 'color: #BF616A; font-size: 18px; font-family: monospace;') // Remove wallpaper from list let index = wallpapers.indexOf(chosenWallpaper) if (index > -1) { wallpapers.splice(index, 1) } localStorage.setItem('wallpapers', JSON.stringify(wallpapers)) pickWallpaper() } }) } let loadSocket = () => { console.log('%cLoading Socket', 'color: #ECEFF4; font-family: monospace;') if (socket){ try { socket.close() } catch (error) { console.log('%cSocket not found', 'color: #BF616A; font-size: 18px; font-family: monospace;') } } socket = new WebSocket(localStorage.getItem('socket')) socket.onopen = (e) => { console.log('%cSocket Opened', 'color: #A3BE8C; font-size: 18px; font-family: serif;') socketStatus = true } socket.onmessage = (e) => { console.log('%cMessage Received', 'color: #ECEFF4; font-family: monospace;') // e.data contains member ID // console.dir(e) localStorage.setItem('member', e.data) if (timer) { clearTimeout(timer) } pickWallpaper() } socket.onclose = (e) => { console.log('%cSocket Closed', 'color: #BF616A; font-size: 18px; font-family: serif;') socketStatus = false setTimeout(() => { window.location.reload() }, 3000) } socket.onerror = (e) => { console.log('%cSocket Error', 'color: #BF616A; font-size: 18px; font-family: monospace;') console.dir(e) } } window.wallpaperPropertyListener = { applyUserProperties: async (properties) => { if (properties.timeout_s) { localStorage.setItem('timeout_s', properties.timeout_s.value) } if (properties.timeout_m) { localStorage.setItem('timeout_m', properties.timeout_m.value) } if (properties.systemid) { localStorage.setItem('systemId', properties.systemid.value) } if (properties.uri) { localStorage.setItem('socket', properties.uri.value) // Reload Socket if (socketStatus) { socketStatus = false socket.close() } loadSocket() } dumpStorage() }, userDirectoryFilesAddedOrChanged: async (propertyName, changedFiles) => { // Do something with the list of added files here // console.dir(propertyName) console.dir(changedFiles) // Array of filepaths added let wallpapers = localStorage.getItem('wallpapers') if (jsonValid(wallpapers)) { wallpapers = JSON.parse(localStorage.getItem('wallpapers')) } else { wallpapers = [] console.log('%cWallpapers not found in Local Storage', 'color: #BF616A; font-size: 18px; font-family: monospace;') } changedFiles.forEach((file) => { if (!wallpapers.includes(file)) { wallpapers.push(file) } }) localStorage.setItem('wallpapers', JSON.stringify(wallpapers)) }, } window.onload = async () => { console.log("%cPage Loaded.", "background: #2E3440; color: #A3BE8C; font-size: 24px;") // Set default member dumpStorage() grabLatestFronter() await loadMime() loadSocket() }