308 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			308 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
Copyright 2023 Liz Cray
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
// TODO:
 | 
						|
// - 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 adjustTransition = () => {
 | 
						|
    let transition = localStorage.getItem('transition_time')
 | 
						|
    console.log(`%cTransition Time: ${transition}s`, 'color: #EBCB8B; font-family: monospace;')
 | 
						|
    if (transition == null) {
 | 
						|
        transition = 5
 | 
						|
    }
 | 
						|
    let wallpaper = document.getElementById('wallpaper')
 | 
						|
    wallpaper.style.transition = `background ${transition}s linear`
 | 
						|
    wallpaper.style.webkitTransition = `background ${transition}s linear`
 | 
						|
    wallpaper.style.mozTransition = `background ${transition}s linear`
 | 
						|
    wallpaper.style.oTransition = `background ${transition}s linear`
 | 
						|
    wallpaper.style.msTransition = `background ${transition}s linear`
 | 
						|
}
 | 
						|
 | 
						|
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('  Fade Delay:' + localStorage.getItem('transition_time'))
 | 
						|
    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.transition_time) {
 | 
						|
            localStorage.setItem('transition_time', properties.transition_time.value)
 | 
						|
            adjustTransition()
 | 
						|
        }
 | 
						|
        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()
 | 
						|
}
 |