diff --git a/features/asset-size/data.json b/features/asset-size/data.json new file mode 100644 index 00000000..ab88577f --- /dev/null +++ b/features/asset-size/data.json @@ -0,0 +1,14 @@ +{ + "title": "Asset Size", + "description": "Allows you to hover over any asset (costumes and sounds) in the editor to view the file size.", + "credits": [ + { + "url": "https://scratch.mit.edu/users/rgantzos/", + "username": "rgantzos" + } + ], + "type": ["Editor"], + "dynamic": true, + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }] + } + \ No newline at end of file diff --git a/features/asset-size/script.js b/features/asset-size/script.js new file mode 100644 index 00000000..382c7046 --- /dev/null +++ b/features/asset-size/script.js @@ -0,0 +1,59 @@ +export default async function ({ feature, console }) { + ScratchTools.waitForElements( + "div[class*='asset-panel_wrapper_'] div[class*='selector_list-area_'] > div", + function (asset) { + if (asset.dataset.ste === "ste-file-size") return; + asset.dataset.ste = "ste-file-size"; + + let content = asset.querySelector( + "div[class*='sprite-selector-item_sprite-info_-'] div[class*='sprite-selector-item_sprite-details_']" + ); + + asset.firstChild.addEventListener("mouseover", function () { + if (!feature.self.enabled) return; + + let scratchAsset = ScratchTools.Scratch.vm.editingTarget; + let targetAssets = + feature.traps.gui().editorTab?.activeTabIndex === 1 + ? scratchAsset.getCostumes() + : scratchAsset.getSounds(); + let data = targetAssets[getElementIndex(asset)].asset.data.byteLength; + + content.dataset.previousContent = content.textContent; + content.textContent = formatBytes(data); + }); + + asset.firstChild.addEventListener("mouseout", function () { + if (content.dataset.previousContent) { + content.textContent = content.dataset.previousContent; + } + }); + } + ); + + function getElementIndex(element) { + const parent = element.parentElement; + + const children = parent.children; + + for (let i = 0; i < children.length; i++) { + if (children[i] === element) { + return i; + } + } + + return -1; + } + + function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return "0 Bytes"; + + const k = 1024; + const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + const sizeInUnits = parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)); + + return `${sizeInUnits} ${sizes[i]}`; + } +} diff --git a/features/features.json b/features/features.json index 6ccffea7..9f0054a1 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "asset-size", + "versionAdded": "v4.0.0" + }, { "version": 2, "id": "disable-cloud", diff --git a/features/remaining-replies/script.js b/features/remaining-replies/script.js index b9193f80..ac444348 100644 --- a/features/remaining-replies/script.js +++ b/features/remaining-replies/script.js @@ -1,6 +1,4 @@ export default async function ({ feature, console }) { - window.feature = feature - ScratchTools.waitForElements(".flex-row.comment", function (comment) { let data = feature.redux .getState()