Last active
December 6, 2016 19:28
-
-
Save machty/3905fae0735e597f417215ac33e95391 to your computer and use it in GitHub Desktop.
New Twiddle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
import { task, timeout } from 'ember-concurrency'; | |
export default Ember.Controller.extend({ | |
showDialogs: task(function * () { | |
yield alert("Hey, I heard you liked alert()"); | |
yield timeout(50); | |
let name = yield prompt("May I prompt() you for your name?"); | |
yield timeout(50); | |
if (yield confirm(`Please confirm() your name is ${name}`)) { | |
yield alert("Yes!"); | |
} else { | |
yield alert("No!"); | |
} | |
}).drop(), | |
}); | |
function alert(message) { | |
return request('dialog', { message }); | |
} | |
function prompt(message) { | |
return request('dialog', { | |
message, | |
showInput: true, | |
showCancel: true, | |
}); | |
} | |
function confirm(message) { | |
return request('dialog', { | |
message, | |
showCancel: true, | |
value: true | |
}); | |
} | |
// TODO: add this as an import | |
const YIELDABLE = "__ec_yieldable__"; | |
// NOTE: everything below here is stuff library/addon authors | |
// would write. The whole point of the yieldables API is to | |
// let addon authors experiment with solutions to common | |
// UI problems involving async. | |
let INVOKE = "__invoke_symbol__"; | |
let locations = [ | |
'ember-glimmer/helpers/action', | |
'ember-routing-htmlbars/keywords/closure-action', | |
'ember-routing/keywords/closure-action' | |
]; | |
for (let i = 0; i < locations.length; i++) { | |
if (locations[i] in Ember.__loader.registry) { | |
INVOKE = Ember.__loader.require(locations[i])['INVOKE']; | |
break; | |
} | |
} | |
let Channel; | |
function request(name, payload) { | |
return { | |
[YIELDABLE](taskInstance, index) { | |
let obj = taskInstance.context; | |
payload.respond = response => { | |
taskInstance.proceed(index, "next", response); | |
}; | |
payload.cancel = () => { | |
taskInstance.proceed(index, "cancel", null); | |
}; | |
obj.set(name, payload); | |
return () => { | |
obj.set(name, null); | |
}; | |
}, | |
}; | |
} | |
Channel = Ember.Object.extend({ | |
init() { | |
this._super(); | |
this._takes = []; | |
this._puts = []; | |
this._refreshState(); | |
this.put = (...args) => this._put(...args); | |
}, | |
isActive: Ember.computed.or('isPutting', 'isTaking'), | |
isPutting: false, | |
isTaking: false, | |
[YIELDABLE](...args) { | |
// `yield channel` is the same as | |
// `yield channel.take()`; | |
return this.take()[YIELDABLE](...args); | |
}, | |
take() { | |
let takeAttempt = { | |
defer: Ember.RSVP.defer(), | |
active: true, | |
[YIELDABLE](taskInstance, resumeIndex) { | |
console.log("take yieldable"); | |
this.defer.promise.then(value => { | |
console.log(`resolve ${value}`); | |
taskInstance.proceed(resumeIndex, "next", value); | |
}); | |
return () => { | |
this.active = false; | |
}; | |
}, | |
}; | |
this._takes.push(takeAttempt); | |
this._scheduleFlush(); | |
return takeAttempt; | |
}, | |
_put(value) { | |
let putAttempt = { | |
value, | |
defer: Ember.RSVP.defer(), | |
active: true, | |
[YIELDABLE](taskInstance, resumeIndex) { | |
console.log("put yieldable"); | |
this.defer.promise.then(() => { | |
taskInstance.proceed(resumeIndex, "next", null); | |
}); | |
return () => { | |
this.active = false; | |
}; | |
}, | |
}; | |
this._puts.push(putAttempt); | |
this._scheduleFlush(); | |
return putAttempt; | |
}, | |
_scheduleFlush() { | |
Ember.run.schedule('actions', this, this._flush); | |
}, | |
_flush() { | |
let oldTakes = this._takes; | |
let puts = this._puts; | |
let newTakes = []; | |
for (let i = 0; i < oldTakes.length; ++i) { | |
let take = oldTakes[i]; | |
if (!take.active) { continue; } | |
while(puts.length) { | |
let put = puts.shift(); | |
if (!put.active) { continue; } | |
console.log("resolving take ", take, " with ", put.value); | |
take.defer.resolve(put.value); | |
put.defer.resolve(); | |
continue; | |
} | |
newTakes.push(take); | |
} | |
this._takes = newTakes; | |
this._refreshState(); | |
}, | |
_refreshState() { | |
this.setProperties({ | |
isTaking: this._takes.length > 0, | |
isPutting: this._putting.length > 0, | |
}); | |
}, | |
}); | |
function channel() { | |
return Ember.computed(function() { | |
return Channel.create(); | |
}); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin: 12px 16px; | |
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
font-size: 12pt; | |
} | |
.dialog { | |
position: fixed; | |
top: 20%; | |
left: 50%; | |
} | |
.dialog input { | |
position: relative; | |
width: 100%; | |
display: block; | |
margin-top: 10px; | |
} | |
.dialog-inner { | |
width: 400px; | |
margin-left: -200px; | |
background: #d4d0c7; | |
border-right: 1px solid #404040; | |
border-bottom: 1px solid #404040; | |
position: relative; | |
min-height: 100px; | |
box-sizing: border-box; | |
padding: 70px 70px 100px 70px; | |
} | |
.dialog-inner::before{ | |
position: absolute; | |
top: 1px; | |
left: 1px; | |
right: 0px; | |
bottom: 0px; | |
border-right: 1px solid #808080; | |
border-bottom: 1px solid #808080; | |
border-left: 1px solid #ffffff; | |
border-top: 1px solid #ffffff; | |
content: ' '; | |
} | |
.dialog-header { | |
position: absolute; | |
top: 3px; | |
left: 3px; | |
right: 3px; | |
background: blue; | |
color: white; | |
padding: 2px 3px; | |
} | |
.dialog-message { | |
text-align: center; | |
} | |
.dialog-buttons { | |
position: absolute; | |
bottom: 30px; | |
left: 0; | |
right: 0; | |
text-align: center; | |
} | |
.dialog-button { | |
display: inline-block; | |
border: 1px solid black; | |
min-width: 100px; | |
padding: 8px; | |
text-align: center; | |
position: relative; | |
margin: 0 4px; | |
} | |
.dialog-button::after { | |
content: ' '; | |
position: absolute; | |
top: 1px; | |
left: 1px; | |
right: 0px; | |
bottom: 0px; | |
border-top: 1px solid #ffffff; | |
border-left: 1px solid #ffffff; | |
border-right: 1px solid #808080; | |
border-bottom: 1px solid #808080; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": "0.10.1", | |
"EmberENV": { | |
"FEATURES": {} | |
}, | |
"options": { | |
"use_pods": false, | |
"enable-testing": false | |
}, | |
"dependencies": { | |
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js", | |
"ember": "2.6.0", | |
"ember-data": "2.6.1", | |
"ember-template-compiler": "2.6.0" | |
}, | |
"addons": { | |
"ember-concurrency": "pr-100" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment