dart-pad icon indicating copy to clipboard operation
dart-pad copied to clipboard

share button that doesn't require manually creating a gist

Open DetachHead opened this issue 3 years ago • 5 comments
trafficstars

it's annoying to have to manually create a gist just to be able to share a dart pad link. it would be cool if you could just click a "share" button like you can in the typescript and mypy playgrounds. (the "gist" button on the mypy playground creates a gist for you)

DetachHead avatar Jul 28 '22 10:07 DetachHead

Hey @timmaffett, how hard is this to implement?

domesticmouse avatar Jul 28 '22 23:07 domesticmouse

@domesticmouse Well it would depend on how we went about it. If the user was logged into GitHub with their own account it would be trivial to have the share button create a gist and then share the URL of dartpad with the new gist's ID included.

I don't think that this is what @DetachHead is exactly requesting though. On the typescript and mypy playgrounds they are using a system account to create the gist and then share the link to that:

Pressing the Gist button on mypy adds these links to the bottom of the page:

Gist URL: https://gist.github.com/1e336d1e73b3321cec3456f039b8708f Playground URL: https://mypy-play.net/?mypy=latest&python=3.10&gist=1e336d1e73b3321cec3456f039b8708f

If you go to that gist.github.com link you can see that the gist is owned by a user 'mypy-play'. In fact if you go to https://gist.github.com/mypy-play you can see that this 'user' has >5000 gists.

We could create similarly a new user GitHub user, 'dartpad-playground' for example, and then if the user is not GitHub authenticated we could instead create the gist for the 'dartpad-playground' user and share that.

I would image that we would store the OAuth credentials for the 'dartpad-playground' within Dart Services, and when a Gist needs to be created we would use a new grpc endpoint that would take all the files and create the gist and return back the URL/Gist id. The endpoint would be very similar to the new multifile endpoints, it would just create the Gist using the passed files. The reason I propose doing this on the Dart Services side is that we can protect the OAuth credentials and prevent malicious use, like deleting some/all of the gists (for example). There is no granularity to the gist scope so we can't just have a 'create only' credential, it would always include 'delete'/'write' capabilities. For this reason I think we would want to keep it protected on the server side.

Does that make sense ? This is not the first request for something like this (being able to create a gist from a global account and not having to log into GitHub yourself) https://github.com/dart-lang/dart-pad/issues/2239 for example. If it is something that sounds good I can create PR's for dart-pad and dart-services which implement it.

timmaffett avatar Jul 29 '22 21:07 timmaffett

Creating gists on a shared account is a change that requires some discussion. @johnpryan

domesticmouse avatar Jul 29 '22 22:07 domesticmouse

it doesn't necessarily have to be a gist, i think the typescript playground encodes the content in the URL or something: https://www.typescriptlang.org/play?#code/MYGwhgzhAECC0G9pmgXmgRmgXwFCkhgCFoBTADwBdSA7AExniQCM1Md9wpoBhMq2gziJowNljy58AexoRKyNjVIB3OAAoAlAG4Zcha3TK1RLbuCz5opat5mprSMKc9tQA

DetachHead avatar Jul 30 '22 05:07 DetachHead

@DetachHead Your comment about the typescriptlang.org url got me investigating and I discovered a few interesting more interesting things.. The url does included gzip'ed source code, as well as a diff of all settings that differ from defaults. This allows the URL to reproduce the exact code environment the original author was using (DartPad does not have a lot of options to change, but different Dart-Services backend/versions are a possibility). They also include the current text selection, which is also an interesting idea. The advantages of this approach of not being dependent on any outside element are obvious. There are size limits on urls (2mb for chome i think), but for many (most?) examples that would be plenty and we could just inform the user to use a gist if the code size did not allow url encoding. We could use the same json encoding we currently use for reading/writing gists, but additionally gzip/base64 encode to allow our shareable urls to be an additional target/source. (Additionally I think such decoded urls/source examples would not be automatically executed, pressing [Run] would explicitly be required).

I have included some comments below from their code reguarding the URL - just to possibly spark minds and ideas for the future..

// With the new Playground, URLs contain a lot more
// information about your settings. This makes reproductions
// accurate, and you don't have to tell someone to hit a
// particular compiler flag to replicate your setup.

// The URL contains:
//
// - Whether you are on an example
// - The gzipped source code for your TypeScript/JavaScript
// - Backwards compatibility for older non-gzipped URLs
// - Which language you are working in
// - The diff of your compiler settings from the defaults
//   example:new-compiler-defaults
// - Your text selection if you have some code highlighted
//
// The URL is updated live when any of the above changes
// using HTML5's replaceState, so your back button will
// still work as expected.

// When loading an example, you'll see an occasional e=[number]
// which is used to ensure the browser correctly reloads when
// you jump between examples. It's harmless.

// You can see the URL change on this page by editing some
// of the comments, or start selecting some text. Pressing
// reload on your browser will take you back to the same
// state.

timmaffett avatar Aug 01 '22 16:08 timmaffett

Can this be closed now that https://github.com/dart-lang/dart-pad/pull/2227 has landed?

johnpryan avatar Oct 05 '22 23:10 johnpryan