-
Notifications
You must be signed in to change notification settings - Fork 362
add extension: ShareSheet #2269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 11 commits
e0e0185
294e12f
21ff49a
7d25bd4
c3822bf
40806a3
5678928
80cf8fb
81037d1
fd75851
3ac2dfc
3e06b64
8171270
c62d67a
1b4c111
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,254 @@ | ||
| // Name: ShareSheet | ||
| // ID: gamercreepernoobssharesheetextension | ||
| // Description: Share data from your browser. | ||
| // By: GamerCreeper12 <https://scratch.mit.edu/users/GamerCreeper12/> | ||
| // License: MPL-2.0 | ||
|
|
||
| (function (Scratch) { | ||
| "use strict"; | ||
|
|
||
| if (!Scratch.extensions.unsandboxed) { | ||
| throw new Error("Share Sheet must run unsandboxed"); | ||
| } | ||
|
|
||
| const Cast = Scratch.Cast; | ||
|
|
||
| class GamerCreeperNoobsShareSheetExtension { | ||
|
CreeperNewGamer marked this conversation as resolved.
Outdated
|
||
| constructor() { | ||
| this.dataType = "text"; | ||
| this.title = ""; | ||
| this.data = null; | ||
| this.shareData = {}; | ||
| this.cancelled = false; | ||
| this.hasError = false; | ||
| this.errorMsg = ""; | ||
| } | ||
| getInfo() { | ||
| return { | ||
| id: "gamercreepernoobssharesheetextension", | ||
| name: Scratch.translate("ShareSheet"), | ||
| color1: "#742DEB", | ||
| color3: "#a176e8", | ||
| blocks: [ | ||
| { | ||
| opcode: "issupported", | ||
| blockType: Scratch.BlockType.BOOLEAN, | ||
| text: Scratch.translate("is share sheet supported?"), | ||
| }, | ||
| { | ||
| opcode: "settitleandtextto", | ||
| blockType: Scratch.BlockType.COMMAND, | ||
| text: Scratch.translate("set title [TITLE]"), | ||
| arguments: { | ||
| TITLE: { | ||
| type: Scratch.ArgumentType.STRING, | ||
| defaultValue: Scratch.translate("Check out this file!"), | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| opcode: "setdatatotxt", | ||
| blockType: Scratch.BlockType.COMMAND, | ||
| text: Scratch.translate("set data to text [TXT]"), | ||
| arguments: { | ||
| TXT: { | ||
| type: Scratch.ArgumentType.STRING, | ||
| defaultValue: Scratch.translate("Hello, World!"), | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| opcode: "setdatatourl", | ||
| blockType: Scratch.BlockType.COMMAND, | ||
| text: Scratch.translate("set data to url [URL]"), | ||
| arguments: { | ||
| URL: { | ||
| type: Scratch.ArgumentType.STRING, | ||
| defaultValue: Scratch.translate("https://example.com"), | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| opcode: "setdatatoimageurl", | ||
| blockType: Scratch.BlockType.COMMAND, | ||
| text: Scratch.translate("set data to image url [URL]"), | ||
| arguments: { | ||
| URL: { | ||
| type: Scratch.ArgumentType.STRING, | ||
| defaultValue: Scratch.translate("https://example.com/myimage/"), | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| opcode: "setdatatocostume", | ||
| blockType: Scratch.BlockType.COMMAND, | ||
| text: Scratch.translate("set data to costume [COSTUME]"), | ||
| arguments: { | ||
| COSTUME: { | ||
| type: Scratch.ArgumentType.COSTUME, | ||
| }, | ||
| }, | ||
| }, | ||
| { | ||
| opcode: "share", | ||
| blockType: Scratch.BlockType.COMMAND, | ||
| text: Scratch.translate("share data"), | ||
| }, | ||
| { | ||
| opcode: "isdatatosharesupported", | ||
| blockType: Scratch.BlockType.BOOLEAN, | ||
| text: Scratch.translate("is last data to share supported?"), | ||
| }, | ||
| { | ||
| opcode: "iscancelled", | ||
| blockType: Scratch.BlockType.BOOLEAN, | ||
| text: Scratch.translate("is sharing cancelled?"), | ||
| }, | ||
| { | ||
| opcode: "gotaerrortwhilesharing", | ||
| blockType: Scratch.BlockType.BOOLEAN, | ||
| text: Scratch.translate("got a error while sharing?"), | ||
| }, | ||
| { | ||
| opcode: "lasterrormsg", | ||
| blockType: Scratch.BlockType.REPORTER, | ||
| text: Scratch.translate("last error message"), | ||
| }, | ||
| ], | ||
| }; | ||
| } | ||
| // helpers | ||
| isShareSheetSupported() { | ||
| return !!(navigator.share && navigator.canShare); | ||
| } | ||
|
|
||
| isShareSheetDataSupported(shareData) { | ||
| if (!this.isShareSheetSupported()) return false; | ||
| return !!navigator.canShare(shareData); | ||
| } | ||
|
|
||
| async shareDataFunc(shareData) { | ||
| if (!this.isShareSheetDataSupported(shareData)) return; | ||
| await navigator.share(shareData); | ||
| } | ||
|
|
||
| async shareDataForShareSheet() { | ||
| if (!this.isShareSheetSupported()) return; | ||
| this.shareData = {}; | ||
| this.cancelled = false; | ||
| this.hasError = false; | ||
| try { | ||
| switch (this.dataType) { | ||
| case "text": | ||
| if (this.title) this.shareData["title"] = this.title; | ||
| if (this.data) this.shareData["text"] = this.data; | ||
| await this.shareDataFunc(this.shareData); | ||
| break; | ||
|
|
||
| case "url": | ||
| if (this.title) this.shareData["title"] = this.title; | ||
| if (this.data) this.shareData["url"] = this.data; | ||
| await this.shareDataFunc(this.shareData); | ||
| break; | ||
|
|
||
| case "image": | ||
| if (this.title) this.shareData["title"] = this.title; | ||
| if (this.data) this.shareData["files"] = [this.data]; | ||
| await this.shareDataFunc(this.shareData); | ||
| break; | ||
|
|
||
| default: | ||
| return; | ||
| } | ||
| } catch (err) { | ||
| if (err.name === "AbortError") { | ||
| this.cancelled = true; | ||
| } else { | ||
| this.hasError = true; | ||
| this.errorMsg = err; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // blocks | ||
| issupported() { | ||
| return Cast.toBoolean(this.isShareSheetSupported()); | ||
| } | ||
|
|
||
| settitleandtextto({ TITLE: title }) { | ||
| this.title = Cast.toString(title) || "Share"; | ||
| } | ||
|
|
||
| setdatatotxt({ TXT: text }) { | ||
| this.dataType = "text"; | ||
| this.data = Cast.toString(text); | ||
| } | ||
|
|
||
| setdatatourl({ URL: url }) { | ||
| this.dataType = "url"; | ||
| this.data = Cast.toString(url); | ||
| } | ||
|
|
||
| async setdatatoimageurl({ URL: url }) { | ||
| this.hasError = false; | ||
| try { | ||
| const response = await Scratch.fetch(url); | ||
| const blob = await response.blob(); | ||
|
|
||
| const imageFile = new File([blob], "image.png", { | ||
| type: blob.type, | ||
| }); | ||
|
Comment on lines
+200
to
+202
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This assumes the image is a PNG?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it should detect the type of the asset |
||
|
|
||
| this.dataType = "image"; | ||
| this.data = imageFile; | ||
| } catch (err) { | ||
| this.hasError = true; | ||
| this.errorMsg = err.message; | ||
| } | ||
| } | ||
|
|
||
| async setdatatocostume({ COSTUME: costumeName }, util) { | ||
| const target = util.target; | ||
| const costumeIndex = target.getCostumeIndexByName(costumeName); | ||
| const costume = target.sprite.costumes[costumeIndex]; | ||
| const asset = costume.asset.encodeDataURI(); | ||
|
|
||
| this.hasError = false; | ||
| try { | ||
| const response = await Scratch.fetch(asset); | ||
| const blob = await response.blob(); | ||
|
|
||
| const imageFile = new File([blob], "image.png", { | ||
| type: blob.type, | ||
| }); | ||
|
|
||
| this.dataType = "image"; | ||
| this.data = imageFile; | ||
| } catch (err) { | ||
| this.hasError = true; | ||
| this.errorMsg = err.message; | ||
| } | ||
| } | ||
|
Comment on lines
+212
to
+233
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was only able to get this block to work with bitmap costumes. Many costumes will be vector. Either specify "set data to bitmap costume" or, better, convert the costume to bitmap before setting the data. |
||
|
|
||
| async share() { | ||
| await this.shareDataForShareSheet(); | ||
| } | ||
|
|
||
| isdatatosharesupported() { | ||
| return this.isShareSheetDataSupported(this.shareData); | ||
| } | ||
|
|
||
| iscancelled() { | ||
| return this.cancelled; | ||
| } | ||
|
|
||
| gotaerrortwhilesharing() { | ||
| return this.hasError; | ||
| } | ||
|
|
||
| lasterrormsg() { | ||
| return this.errorMsg; | ||
| } | ||
| } | ||
| Scratch.extensions.register(new GamerCreeperNoobsShareSheetExtension()); | ||
| })(Scratch); | ||
Uh oh!
There was an error while loading. Please reload this page.