Skip to content

Commit

Permalink
New addon: "delete other assets" (delete-others) (ScratchAddons#7030)
Browse files Browse the repository at this point in the history
* initial commit

* remove dem dynamics

* confirm

* this should work, testing now

* here

* getting there

* DANGER!!!!

* fuck yes

* no r

* Window.addon is crucial to the working of this addon so we will remove it

Co-authored-by: Samq64 <[email protected]>

* smaller popup and string changes

* reverse

* dynam en dis

* stupid strings

* opti and var name change

* shit forgot that -1

* fix sounds being added in thr wrong order

* update ver

* Update versionAdded

Co-authored-by: Maximouse <[email protected]>

* Arrow fix by mxmou

Co-authored-by: Maximouse <[email protected]>

* Useless await

* Use internal variable instead of abusing Redux

* Cleanup variables

* Use editingTarget.addCostume instead

---------

Co-authored-by: Samq64 <[email protected]>
Co-authored-by: W_L <[email protected]>
Co-authored-by: Maximouse <[email protected]>
  • Loading branch information
4 people authored Jun 11, 2024
1 parent 7ad4a8b commit 0da7e1c
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
8 changes: 8 additions & 0 deletions addons-l10n/en/delete-others.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"delete-others/deleteOthers": "delete others",
"delete-others/confirmTitle": "Delete Others",
"delete-others/infoCostume": "Are you sure you want to delete all other costumes?\nThe deleted costumes can be restored by going to Edit \u2192 Restore Costumes.",
"delete-others/infoSound": "Are you sure you want to delete all other sounds?\nThe deleted sounds can be restored by going to Edit \u2192 Restore Sounds.",
"delete-others/multiCostumes": "Restore Costumes",
"delete-others/multiSounds": "Restore Sounds"
}
1 change: 1 addition & 0 deletions addons/addons.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"paint-skew",
"preview-project-description",
"collapse-footer",
"delete-others",
"download-button",
"reorder-custom-inputs",
"place-backpack-code-at-cursor",
Expand Down
15 changes: 15 additions & 0 deletions addons/delete-others/addon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Delete other assets",
"description": "Adds an option to the right click menu to easily delete all other costumes, backdrops, or sounds.",
"tags": ["editor", "costumeEditor", "recommended"],
"versionAdded": "1.39.0",
"userscripts": [
{
"matches": ["projects"],
"url": "userscript.js"
}
],
"credits": [{ "name": "Jazza", "link": "https://scratch.mit.edu/users/greeny--231" }],
"dynamicEnable": true,
"dynamicDisable": true
}
99 changes: 99 additions & 0 deletions addons/delete-others/userscript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
export default async function ({ addon, console, msg }) {
const vm = addon.tab.traps.vm;

const TYPES = ["sound", "costume"];
let deletedItems = [];
let target;
let shouldChangeRestoreButtonText = false;

function getRestoreFun(type) {
deletedItems.reverse();
if (type === "costume") {
deletedItems.forEach((costume) => {
target.addCostume(costume);
});
} else if (type === "sound") {
deletedItems.forEach((sound) => {
target.addSound(sound);
});
}
vm.emitTargetsUpdate();
deletedItems = [];
}

addon.tab.createEditorContextMenu(
async (ctx) => {
if (
await addon.tab.confirm(msg("confirmTitle"), msg(ctx.type === "costume" ? "infoCostume" : "infoSound"), {
useEditorClasses: true,
})
) {
const type = ctx.type === "costume" ? "Costume" : "Sound";

deletedItems = [];
target = vm.editingTarget;

const numberOfAssets = ctx.type === "costume" ? target.getCostumes().length : target.getSounds().length;

for (let i = numberOfAssets - 1; i > -1; i--) {
if (i !== ctx.index) {
let deleted = ctx.type === "costume" ? target.deleteCostume(i) : target.deleteSound(i);
if (deleted) deletedItems.push(deleted);
}
}

addon.tab.redux.dispatch({
type: "scratch-gui/restore-deletion/RESTORE_UPDATE",
state: {
restoreFun: getRestoreFun.bind(this, ctx.type),
deletedItem: type,
},
});
queueMicrotask(() => {
if (deletedItems.length > 1) {
shouldChangeRestoreButtonText = true;
}
});
}
},
{
types: TYPES,
position: "assetContextMenuAfterDelete",
order: 1,
label: msg("deleteOthers"),
dangerous: true,
condition: showDeleteOthers,
}
);

function showDeleteOthers(ctx) {
if (addon.self.disabled) return false;
if (ctx.type === "costume") {
return vm.editingTarget.getCostumes().length > 1;
} else {
return vm.editingTarget.getSounds().length > 1;
}
}

addon.tab.redux.initialize();
addon.tab.redux.addEventListener("statechanged", ({ detail }) => {
const e = detail;
if (!e.action || e.action.type !== "scratch-gui/restore-deletion/RESTORE_UPDATE") return;
shouldChangeRestoreButtonText = false;
});

while (true) {
const restoreButton = await addon.tab.waitForElement(
'[class*="menu-bar_menu-bar-item_"]:nth-child(4) [class*="menu_menu-item_"]:first-child > span',
{
markAsSeen: true,
reduxCondition: (state) => state.scratchGui.menus.editMenu,
condition: () => shouldChangeRestoreButtonText,
}
);

// We know that shouldChangeRestoreButtonText = true
const { deletedItem } = addon.tab.redux.state.scratchGui.restoreDeletion;
restoreButton.innerText = msg(`multi${deletedItem}s`);
}
}

0 comments on commit 0da7e1c

Please sign in to comment.