1
0
This commit is contained in:
Lamp 2023-10-26 02:29:00 -07:00
parent d1de5350e1
commit f748d0b771
5 changed files with 123 additions and 42 deletions

4
.gitignore vendored Normal file

@ -0,0 +1,4 @@
node_modules
react
package.json
package-lock.json

@ -45,7 +45,7 @@ async function instantiateRow(url, internalId, animationStyle) {
c0.appendChild(img);
let select = document.createElement("select");
animationStyles.forEach(a => {
ANIMATION_STYLES.forEach(a => {
let option = document.createElement("option");
option.innerText = a;
option.value = a.toLowerCase();

@ -25,8 +25,5 @@
"background": {
"service_worker": "background.js",
"type": "module"
},
"action": {
"default_popup": "toggle.html"
}
}

@ -1,11 +1,7 @@
<!DOCTYPE html><html><head>
<meta charset="UTF-8" />
<style>
#topright {
position: absolute;
top: 5px;
right: 5px;
}
#emojigrid {
display: flex;
flex-wrap: wrap;
@ -19,6 +15,7 @@
width: 64px;
height: 64px;
margin: auto;
display: flex;
}
.emojisquare .imgcontainer img {
max-width: 100%;
@ -26,15 +23,20 @@
object-fit: contain;
}
.enabled {
[data-state=enabled] {
background-color:rgba(0, 255, 0, 0.5);
}
.disabled {
[data-state=disabled] {
background-color:rgba(255, 0, 0, 0.5);
}
.pending {
[data-state=pending] {
background-color:rgba(255, 255, 0, 0.5);
}
#emojiadd {
margin-top: 8px;
}
#errorDiv {
color: red;
}
@ -43,6 +45,7 @@
<h1>VRChat Emoji Manager</h1>
<div id="emojigrid"></div>
<div id="errorDiv"></div>
<div id="emojiadd">Add more!!! <input type="file" id="fileinput" accept="image/png,image/jpeg" multiple /> <select id="default_animation_style_select" value="aura"><option value="aura">Aura</option><option value="bats">Bats</option><option value="bees">Bees</option><option value="bounce">Bounce</option><option value="cloud">Cloud</option><option value="confetti">Confetti</option><option value="crying">Crying</option><option value="dislike">Dislike</option><option value="fire">Fire</option><option value="idea">Idea</option><option value="lasers">Lasers</option><option value="like">Like</option><option value="magnet">Magnet</option><option value="mistletoe">Mistletoe</option><option value="money">Money</option><option value="noise">Noise</option><option value="orbit">Orbit</option><option value="pizza">Pizza</option><option value="rain">Rain</option><option value="rotate">Rotate</option><option value="shake">Shake</option><option value="snow">Snow</option><option value="snowball">Snowball</option><option value="spin">Spin</option><option value="splash">Splash</option><option value="stop">Stop</option><option value="zzz">ZZZ</option></select> <input type="submit" id="submit" value="Add" /></div>
<div><button id="deletemodebtn">Delete Emojis</button></div>
<script src="toggle.js"></script>
</body></html>

135
toggle.js

@ -1,4 +1,4 @@
var animationStyles = `Aura
const ANIMATION_STYLES = `Aura
Bats
Bees
Bounce
@ -28,7 +28,7 @@ ZZZ`.split('\n');
function createAnimationStyleSelect() {
let select = document.createElement("select");
animationStyles.forEach(a => {
ANIMATION_STYLES.forEach(a => {
let option = document.createElement("option");
option.innerText = a;
option.value = a.toLowerCase();
@ -43,6 +43,48 @@ function createAnimationStyleSelect() {
submit.onclick = async () => {
submit.disabled = true;
var newEmoji = [];
for (let file of fileinput.files) {
let e = {
internalId: randomId(),
animationStyle: default_animation_style_select.value,
};
let data = await fileToDataURL(file);
//todo convert/resize
await chrome.storage.local.set({["data-"+e.internalId]: data});
newEmoji.push(e);
instantiateRow(data, e.internalId, e.animationStyle);
}
var {emoji} = await chrome.storage.local.get("emoji");
emoji = emoji.concat(newEmoji);
await chrome.storage.local.set({emoji});
fileinput.value = "";
submit.disabled = false;
};
var deleteMode = false;
deletemodebtn.onclick = () => {
if (deleteMode) {
deleteMode = false;
deletemodebtn.innerText = "Delete Emojis";
return;
}
alert("Delete mode activated, click emojis to delete.");
deleteMode = true;
deletemodebtn.innerText = "CANCEL DELETE MODE";
};
loadEmojis().catch(displayError);
@ -80,14 +122,13 @@ async function loadEmojis() {
}
async function loadToggleState() {
console.debug("loadToggleState");
var elements = document.querySelectorAll(".emojisquare");
if (elements.length === 0) return;
var currentEmojis = await callContentScript("getEmojis");
var active = currentEmojis?.map(e => e.id);
elements.forEach(e => {
var yes = active.includes(e.dataset.currentId);
e.classList.add(yes ? "enabled" : "disabled");
e.classList.remove(yes ? "disabled" : "enabled");
e.dataset.state = active.includes(e.dataset.currentId) ? "enabled" : "disabled";
});
}
@ -119,46 +160,52 @@ async function callContentScript(method, ...args) {
};
async function toggleEmoji(event) {
if (this.classList.contains("pending")) return;
this.classList.add("pending");
if (this.dataset.state == "pending") return;
var selectedState = this.dataset.state;
this.dataset.state = "pending";
errorDiv.innerText = "";
if (document.querySelectorAll(".enabled").length + document.querySelectorAll(".disabled").length < document.querySelectorAll(".emojisquare").length) {
if (emojigrid.querySelector(".emojisquare:not([data-state])")) {
try {
await loadToggleState();
} catch (error) {
displayError(error);
this.classList.remove("pending");
this.dataset.state = selectedState;
return;
}
}
if (this.classList.contains("enabled")) {
if (selectedState == "enabled") {
// disable
callContentScript("deleteEmoji", this.dataset.currentId).then(() => {
this.classList.remove("pending");
this.classList.remove("enabled");
this.classList.add("disabled");
this.dataset.state = "disabled";
}).catch(error => {
this.classList.remove("pending");
displayError(error);
});
} else {
// enable
callContentScript("createEmoji", this.querySelector("img").src, this.dataset.animationStyle).then(newEmoji => {
chrome.storage.local.get("emoji").then(({emoji}) => {
emoji.find(e => e.internalId == this.dataset.internalId).currentId = newEmoji.id;
chrome.storage.local.set({emoji});
this.dataset.currentId = newEmoji.id;
this.classList.remove("pending");
this.classList.remove("disabled");
this.classList.add("enabled");
});
}).catch(error => {
this.classList.remove("pending");
this.dataset.state = selectedState;
displayError(error);
});
if (!deleteMode) return;
}
if (deleteMode) {
let {emoji} = await chrome.storage.local.get("emoji");
emoji = emoji.filter(e => e.internalId != this.dataset.internalId);
await chrome.storage.local.set({emoji});
this.remove();
return;
}
// enable
callContentScript("createEmoji", this.querySelector("img").src, this.dataset.animationStyle).then(newEmoji => {
chrome.storage.local.get("emoji").then(({emoji}) => {
emoji.find(e => e.internalId == this.dataset.internalId).currentId = newEmoji.id;
chrome.storage.local.set({emoji});
this.dataset.currentId = newEmoji.id;
this.dataset.state = "enabled";
});
}).catch(error => {
this.dataset.state = selectedState;
displayError(error);
});
}
async function setAnimationStyle(internalId, animationStyle) {
@ -166,4 +213,34 @@ async function setAnimationStyle(internalId, animationStyle) {
var e = emoji.find(e => e.internalId == internalId);
e.animationStyle = animationStyle;
await chrome.storage.local.set({emoji});
}
function fileToDataURL(file) {
return new Promise(function(resolve, reject){
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
});
}
function randomId() {
let id = "";
const CHARS = "abcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 16; i++) {
id += CHARS[Math.floor(Math.random() * CHARS.length)];
}
return id;
}