Compare commits

..

No commits in common. "f748d0b771b1c04dfb4ef2435fc31b292f03b811" and "6e7f3d4b4c9704f010eb63729a1414a157fad0ad" have entirely different histories.

6 changed files with 56 additions and 208 deletions

4
.gitignore vendored
View File

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

View File

@ -17,7 +17,7 @@
</tr>
</table>
<h1>Add emoji</h1>
<input type="file" id="fileinput" accept="image/png,image/jpeg" multiple /><input type="submit" id="submit" />
<input type="file" id="fileinput" accept="image/*" multiple /><input type="submit" id="submit" />
<script src="edit.js" charset="UTF-8"></script>
</body></html>

17
edit.js
View File

@ -45,7 +45,7 @@ async function instantiateRow(url, internalId, animationStyle) {
c0.appendChild(img);
let select = document.createElement("select");
ANIMATION_STYLES.forEach(a => {
animationStyles.forEach(a => {
let option = document.createElement("option");
option.innerText = a;
option.value = a.toLowerCase();
@ -59,16 +59,20 @@ async function instantiateRow(url, internalId, animationStyle) {
let button = document.createElement("button");
button.innerText = "🗑️";
button.onclick = async () => {
//if (!confirm("Delete emoji from storage. Are you sure?")) return;
var {emoji} = await chrome.storage.local.get("emoji");
emoji = emoji.filter(e => e.internalId != internalId);
await chrome.storage.local.set({emoji});
button.onclick = () => {
deleteEmoji(internalId);
row.remove();
};
c2.appendChild(button);
}
async function deleteEmoji(internalId) {
if (!confirm("Delete emoji from storage. Are you sure?")) return;
var {emoji} = await chrome.storage.local.get("emoji");
emoji = emoji.filter(e => e.internalId != internalId);
await chrome.storage.local.set({emoji});
}
async function setAnimationStyle(internalId, animationStyle) {
var {emoji} = await chrome.storage.local.get("emoji");
var e = emoji.find(e => e.internalId == internalId);
@ -94,7 +98,6 @@ submit.onclick = async () => {
var {emoji} = await chrome.storage.local.get("emoji");
emoji = emoji.concat(newEmoji);
await chrome.storage.local.set({emoji});
fileinput.value = "";
submit.disabled = false;
};

View File

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

View File

@ -1,51 +1,39 @@
<!DOCTYPE html><html><head>
<meta charset="UTF-8" />
<style>
#emojigrid {
display: flex;
flex-wrap: wrap;
width: 269px;
}
.emojisquare {
width: 50px;
height: 50px;
border: 1px solid gray;
margin: 1px;
padding: 4px;
}
.emojisquare .imgcontainer {
width: 64px;
height: 64px;
margin: auto;
display: flex;
}
.emojisquare .imgcontainer img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
.emojisquare img {
width: 48px;
height: 48px;
margin: auto;
}
[data-state=enabled] {
.enabled {
background-color:rgba(0, 255, 0, 0.5);
}
[data-state=disabled] {
.disabled {
background-color:rgba(255, 0, 0, 0.5);
}
[data-state=pending] {
.pending {
background-color:rgba(255, 255, 0, 0.5);
}
#emojiadd {
margin-top: 8px;
}
#errorDiv {
color: red;
}
</style>
</head><body>
<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>

200
toggle.js
View File

@ -1,92 +1,3 @@
const ANIMATION_STYLES = `Aura
Bats
Bees
Bounce
Cloud
Confetti
Crying
Dislike
Fire
Idea
Lasers
Like
Magnet
Mistletoe
Money
Noise
Orbit
Pizza
Rain
Rotate
Shake
Snow
Snowball
Spin
Splash
Stop
ZZZ`.split('\n');
function createAnimationStyleSelect() {
let select = document.createElement("select");
ANIMATION_STYLES.forEach(a => {
let option = document.createElement("option");
option.innerText = a;
option.value = a.toLowerCase();
select.appendChild(option);
});
return select;
}
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);
async function loadEmojis() {
@ -95,26 +6,15 @@ async function loadEmojis() {
if (!store.emoji) throw new Error("No emoji.");
for (let emoji of store.emoji) {
let div = document.createElement("div");
div.className = "emojisquare";
div.dataset.animationStyle = emoji.animationStyle;
div.dataset.internalId = emoji.internalId;
div.dataset.currentId = emoji.currentId;
div.classList.add("emojisquare");
div.onclick = toggleEmoji;
let imgdiv = document.createElement("div");
imgdiv.className = "imgcontainer";
let img = document.createElement("img");
img.src = store["data-" + emoji.internalId];
imgdiv.appendChild(img);
div.appendChild(imgdiv);
let select = createAnimationStyleSelect();
select.value = emoji.animationStyle;
select.onclick = event => event.stopPropagation();
select.onchange = event => {
setAnimationStyle(emoji.internalId, event.target.value);
};
div.appendChild(select);
div.appendChild(img);
emojigrid.appendChild(div);
}
@ -122,13 +22,14 @@ 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 => {
e.dataset.state = active.includes(e.dataset.currentId) ? "enabled" : "disabled";
var yes = active.includes(e.dataset.currentId);
e.classList.add(yes ? "enabled" : "disabled");
e.classList.remove(yes ? "disabled" : "enabled");
});
}
@ -160,87 +61,44 @@ async function callContentScript(method, ...args) {
};
async function toggleEmoji(event) {
if (this.dataset.state == "pending") return;
var selectedState = this.dataset.state;
this.dataset.state = "pending";
if (this.classList.contains("pending")) return;
this.classList.add("pending");
errorDiv.innerText = "";
if (emojigrid.querySelector(".emojisquare:not([data-state])")) {
if (document.querySelectorAll(".enabled").length + document.querySelectorAll(".disabled").length < document.querySelectorAll(".emojisquare").length) {
try {
await loadToggleState();
} catch (error) {
displayError(error);
this.dataset.state = selectedState;
this.classList.remove("pending");
return;
}
}
if (selectedState == "enabled") {
if (this.classList.contains("enabled")) {
// disable
callContentScript("deleteEmoji", this.dataset.currentId).then(() => {
this.dataset.state = "disabled";
this.classList.remove("pending");
this.classList.remove("enabled");
this.classList.add("disabled");
}).catch(error => {
this.dataset.state = selectedState;
this.classList.remove("pending");
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";
} 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");
displayError(error);
});
}).catch(error => {
this.dataset.state = selectedState;
displayError(error);
});
}
async function setAnimationStyle(internalId, animationStyle) {
var {emoji} = await chrome.storage.local.get("emoji");
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;
}
}