|
| 1 | +export default async function ({ feature, console }) { |
| 2 | + const ALLOW_INTERACTIVITY = false |
| 3 | + |
| 4 | + await new Promise(async (resolve, reject) => { |
| 5 | + (async () => { |
| 6 | + const rem = await ScratchTools.waitForElement(".preview .inner .flex-row.action-buttons") |
| 7 | + resolve(rem); |
| 8 | + })(); |
| 9 | + (async () => { |
| 10 | + const rem = await ScratchTools.waitForElement(".menu-bar_account-info-group_MeJZP") |
| 11 | + resolve(rem); |
| 12 | + })(); |
| 13 | + }) |
| 14 | + |
| 15 | + const canvas = feature.traps.vm.renderer.canvas; |
| 16 | + let openPopup = document.createElement("button"); |
| 17 | + |
| 18 | + ScratchTools.waitForElements(".preview .inner .flex-row.action-buttons", async function (row) { |
| 19 | + if (row.querySelector(".ste-picture-in-picture")) return; |
| 20 | + openPopup = document.createElement("button"); |
| 21 | + openPopup.className = "button action-button ste-picture-in-picture"; |
| 22 | + openPopup.textContent = "Picture in Picture"; |
| 23 | + row.insertAdjacentElement("afterbegin", openPopup); |
| 24 | + openPopup.addEventListener('click', () => { |
| 25 | + popup() |
| 26 | + }) |
| 27 | + }) |
| 28 | + ScratchTools.waitForElements(".menu-bar_account-info-group_MeJZP", async function (row) { |
| 29 | + if (row.querySelector(".ste-picture-in-picture")) return; |
| 30 | + openPopup = document.createElement("div"); |
| 31 | + openPopup.className = "menu-bar_menu-bar-item_oLDa- menu-bar_hoverable_c6WFB"; |
| 32 | + let rem = document.createElement("div"); |
| 33 | + rem.textContent = "Picture in Picture"; |
| 34 | + openPopup.append(rem); |
| 35 | + row.insertAdjacentElement("afterbegin", openPopup); |
| 36 | + openPopup.addEventListener('click', () => { |
| 37 | + popup() |
| 38 | + }) |
| 39 | + }) |
| 40 | + |
| 41 | + let popup; |
| 42 | + |
| 43 | + // Code for allowing interactivity (not yet ready) |
| 44 | + if (ALLOW_INTERACTIVITY) { |
| 45 | + if (!"documentPictureInPicture" in window) console.error("Picture in Picture not supported") |
| 46 | + |
| 47 | + let pipWindow |
| 48 | + |
| 49 | + let docPopup = document.createElement("div"); |
| 50 | + docPopup.insertAdjacentHTML("afterbegin", await (await fetch(feature.self.getResource("popup-html"))).text()) |
| 51 | + docPopup = docPopup.querySelector("div.popup-GUI") |
| 52 | + |
| 53 | + let video = docPopup.querySelector("video"); |
| 54 | + |
| 55 | + const greenFlag = document.querySelector(".green-flag_green-flag_1kiAo") |
| 56 | + docPopup.querySelector(".popup-greenflag").addEventListener("click", () => { |
| 57 | + greenFlag.click() |
| 58 | + }); |
| 59 | + const redFlag = document.querySelector(".stop-all_stop-all_1Y8P9") |
| 60 | + docPopup.querySelector(".popup-redflag").addEventListener("click", () => { |
| 61 | + redFlag.click() |
| 62 | + }); |
| 63 | + |
| 64 | + // video.addEventListener("mousedown", (old_event) => { |
| 65 | + function translateEvent_pointer(old_event) { |
| 66 | + // Calculate the canvas position relative to the viewport |
| 67 | + const a_rect = canvas.getBoundingClientRect(); |
| 68 | + const b_rect = video.getBoundingClientRect(); |
| 69 | + |
| 70 | + // console.log(old_event) |
| 71 | + // Create a new event with the adjusted coordinates |
| 72 | + |
| 73 | + let new_event = new old_event.constructor(old_event.type, { |
| 74 | + bubbles: old_event.bubbles, |
| 75 | + cancelable: old_event.cancelable, |
| 76 | + clientX: (old_event.clientX - b_rect.left) * (a_rect.width / b_rect.width) + a_rect.left, |
| 77 | + clientY: (old_event.clientY - b_rect.top) * (a_rect.height / b_rect.height) + a_rect.top, |
| 78 | + // Copy over other necessary properties from the old event |
| 79 | + screenX: (old_event.screenX - pipWindow.screenLeft + window.screenLeft - b_rect.left) * (a_rect.width / b_rect.width) + a_rect.left, |
| 80 | + screenY: (old_event.screenY - pipWindow.screenTop + window.screenTop - b_rect.top) * (a_rect.height / b_rect.height) + a_rect.top, |
| 81 | + layerX: old_event.layerX, |
| 82 | + layerY: old_event.layerY, |
| 83 | + button: old_event.button, |
| 84 | + buttons: old_event.buttons, |
| 85 | + relatedTarget: old_event.relatedTarget, |
| 86 | + altKey: old_event.altKey, |
| 87 | + ctrlKey: old_event.ctrlKey, |
| 88 | + shiftKey: old_event.shiftKey, |
| 89 | + metaKey: old_event.metaKey, |
| 90 | + movementX: old_event.movementX, |
| 91 | + movementY: old_event.movementY, |
| 92 | + }); |
| 93 | + |
| 94 | + // Dispatch the new event |
| 95 | + canvas.dispatchEvent(new_event); |
| 96 | + } |
| 97 | + video.addEventListener("mousedown", translateEvent_pointer) |
| 98 | + video.addEventListener("mouseup", translateEvent_pointer) |
| 99 | + video.addEventListener("mousemove", translateEvent_pointer) |
| 100 | + video.addEventListener("wheel", translateEvent_pointer) |
| 101 | + video.addEventListener("touchstart", translateEvent_pointer) |
| 102 | + video.addEventListener("touchend", translateEvent_pointer) |
| 103 | + video.addEventListener("touchmove", translateEvent_pointer) |
| 104 | + |
| 105 | + function translateEvent_key(old_event) { |
| 106 | + let new_event = new KeyboardEvent(old_event.type, old_event) |
| 107 | + document.dispatchEvent(new_event); |
| 108 | + } |
| 109 | + |
| 110 | + let buttonClickedTimes = 0 |
| 111 | + popup = async function () { |
| 112 | + if (buttonClickedTimes === 0) { |
| 113 | + video.srcObject = canvas.captureStream() |
| 114 | + buttonClickedTimes++ |
| 115 | + } |
| 116 | + // Open a Picture-in-Picture window. |
| 117 | + pipWindow = await window.documentPictureInPicture.requestWindow({ |
| 118 | + width: canvas.width, |
| 119 | + height: canvas.height + 20 + 6 * 2, |
| 120 | + }); |
| 121 | + |
| 122 | + // Move the player to the Picture-in-Picture window. |
| 123 | + pipWindow.document.body.append(docPopup); |
| 124 | + |
| 125 | + pipWindow.document.addEventListener("keydown", translateEvent_key) |
| 126 | + pipWindow.document.addEventListener("keypress", translateEvent_key) |
| 127 | + pipWindow.document.addEventListener("keyup", translateEvent_key) |
| 128 | + } |
| 129 | + } |
| 130 | + else { |
| 131 | + let video = document.createElement("video"); |
| 132 | + // video.setAttribute("controls", "controls"); |
| 133 | + video.setAttribute("autoplay", "autoplay"); |
| 134 | + video.setAttribute("style", "width: 100%; height: 100%"); |
| 135 | + // document.querySelector(".preview .inner").append(video); |
| 136 | + |
| 137 | + video.srcObject = canvas.captureStream() |
| 138 | + |
| 139 | + popup = function () { |
| 140 | + try { |
| 141 | + video.requestPictureInPicture() |
| 142 | + } |
| 143 | + catch { |
| 144 | + console.log("Picture in Picture not supported or failed to request") |
| 145 | + } |
| 146 | + } |
| 147 | + } |
| 148 | +} |
0 commit comments