View web dev levels. Add proper victory modal game/webpage share links. Fix playing game dev levels. Add generic change transition to all web-dev pages.

This commit is contained in:
Nick Winter 2016-07-15 20:03:12 -07:00
parent 0570644943
commit 224ad54bdd
17 changed files with 183 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -16,6 +16,12 @@
<script src="/javascripts/app/vendor/aether-html.js"></script>
<style>
* {
transition: 1s ease-in-out;
}
</style>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

View file

@ -131,6 +131,7 @@ module.exports = class CocoRouter extends Backbone.Router
'play/ladder': go('ladder/MainLadderView')
'play/level/:levelID': go('play/level/PlayLevelView')
'play/game-dev-level/:levelID/:sessionID': go('play/level/PlayGameDevLevelView')
'play/web-dev-level/:levelID/:sessionID': go('play/level/PlayWebDevLevelView')
'play/spectate/:levelID': go('play/SpectateView')
'play/:map': go('play/CampaignView')

View file

@ -96,8 +96,8 @@ module.exports = class LevelSession extends CocoModel
generateSpellsObject: ->
{createAetherOptions} = require 'lib/aether_utils'
aetherOptions = createAetherOptions functionName: 'plan', codeLanguage: @get('codeLanguage')
spellThang = aether: new Aether aetherOptions
spells = "hero-placeholder/plan": thangs: {'Hero Placeholder': spellThang}, name: 'plan'
spellThang = thang: {id: 'Hero Placeholder'}, aether: new Aether aetherOptions
spells = "hero-placeholder/plan": thang: spellThang, name: 'plan'
source = @get('code')['hero-placeholder'].plan
try
spellThang.aether.transpile source

View file

@ -9,6 +9,9 @@
padding-top: 0
width: 750px
@media screen and ( max-height: 625px )
margin-top: -50px
.modal-content
position: relative
margin-top: -251px
@ -55,10 +58,14 @@
top: 80px
margin-top: 80px
@media screen and ( max-height: 650px )
padding-top: 10px
.well-parchment
margin-top: 20px
@media screen and ( max-height: 675px )
margin-top: 0
html.no-borderimage

View file

@ -298,6 +298,33 @@
height: 100%
position: absolute
#share-level-container
width: 709px
height: 96px
background: transparent url(/images/pages/play/level/modal/share_level_parchment.png)
position: relative
text-align: left
padding: 12px 20px 0 20px
text-align: center
.share-level-label
color: rgb(103, 92, 76)
text-transform: uppercase
font-weight: bold
font-family: $headings-font-family
font-size: 18px
margin-top: 13px
line-height: 18px
text-align: center
#share-level-input
font-size: 12px
margin-top: 8px
#share-level-btn
width: 100%
margin-top: 7px
//- Footer - other stuff

View file

@ -4,10 +4,18 @@
color: black
margin-bottom: 5px
p
margin-top: 30px
.next-level-description
p
margin-top: 30px
.course-title
white-space: nowrap
text-overflow: ellipsis
overflow: hidden
#share-level-input
font-size: 12px
margin-top: 5px
#share-level-btn
width: 100%

View file

@ -0,0 +1,18 @@
#play-web-dev-level-view
#web-surface-view
position: absolute
top: 0
right: 0
bottom: 0
left: 0
z-index: 0
#info-bar
position: absolute
right: 0
bottom: 0
left: 0
height: 100px
z-index: 1
background-color: transparent
text-align: center

View file

@ -108,6 +108,23 @@ block modal-footer-content
.total-count#gem-total 0
.total-label(data-i18n="play_level.victory_gems_gained") Gems Gained
if view.shareURL
#share-level-container
span.share-level-label
span(data-i18n='') Share this link to invite your friends & family to
span= ' '
a(href=view.shareURL, target='_blank')
if view.level.isType('game-dev')
span(data-i18n='') play your game level
else
span(data-i18n='') view your webpage
.row
.col-sm-9
input.text-h4.semibold.form-control.input-md#share-level-input(value=view.shareURL)
.col-sm-3
button#share-level-btn.btn.btn-md.btn-success.btn-illustrated
span(data-i18n='') Copy URL
if me.get('anonymous')
.sign-up-poke.hide
.sign-up-blurb(data-i18n="play_level.victory_sign_up_poke") Want to save your code? Create a free account!
@ -127,8 +144,6 @@ block modal-footer-content
button.btn.btn-illustrated.btn-success.leaderboard-button.btn-lg(data-dismiss="modal", data-i18n="leaderboard.view_other_solutions") View Other Solutions
else if showReturnToCourse
button.btn.btn-illustrated.btn-warning.return-to-course-button.btn-lg(data-dismiss="modal", data-i18n="play_level.victory_go_home") Go Home
else if level.isType('game-dev', 'web-dev')
button.btn.btn-illustrated.btn-primary.btn-lg ...
if showHourOfCodeDoneButton
.hour-of-code-done

View file

@ -38,18 +38,31 @@
span :
h2.text-uppercase= i18n(view.nextLevel.attributes, 'name').replace('Course: ', '')
div!= view.nextLevelDescription
div.next-level-description!= view.nextLevelDescription
.well.well-sm.well-parchment
h3.text-uppercase
| Share this level so your friends and family can play it:
.row
.col-sm-8
input.text-h4.semibold.form-control.input-lg#share-level-input(value='lkasjdflkjasdf')
.col-sm-3
button#share-level-btn.btn.btn-lg.btn-success.btn-illustrated
span(data-i18n='') Copy URL
if view.shareURL
.well.well-sm.well-parchment
h3.text-uppercase
if view.level.isType('game-dev')
span(data-i18n='') Share This Game
else
span(data-i18n='') Share This Webpage
p
span(data-i18n='') This link will let your friends & family
span= ' '
a(href=view.shareURL, target='_blank')
if view.level.isType('game-dev')
span(data-i18n='') play the game
else
span(data-i18n='') view the webpage
span= ' '
span(data-i18n='') you just created.
.row
.col-sm-9
input.text-h4.semibold.form-control.input-lg#share-level-input(value=view.shareURL)
.col-sm-3
button#share-level-btn.btn.btn-lg.btn-success.btn-illustrated
span(data-i18n='') Copy URL
.row
.col-sm-5.col-sm-offset-2

View file

@ -0,0 +1,10 @@
#web-surface-view
#info-bar.style-flat
if !view.supermodel.finished()
h1(data-i18n="common.loading")
else
h1
span Creator:
| #{view.session.get('creatorName')}

View file

@ -17,7 +17,7 @@ TEAM = 'humans'
module.exports = class PlayGameDevLevelView extends RootView
id: 'play-game-dev-level-view'
template: require 'templates/play/level/play-game-dev-level-view'
events:
'click #play-btn': 'onClickPlayButton'
@ -26,7 +26,7 @@ module.exports = class PlayGameDevLevelView extends RootView
loading: true
progress: 0
})
@supermodel.on 'update-progress', (progress) =>
@state.set({progress: (progress*100).toFixed(1)+'%'})
@level = new Level()
@ -41,7 +41,7 @@ module.exports = class PlayGameDevLevelView extends RootView
.then (levelLoader) =>
{ @level, @session, @world } = levelLoader
@god.setLevel(@level.serialize(@supermodel, @session))
@god.setLevel(@level.serialize {@supermodel, @session})
@god.setWorldClassMap(@world.classMap)
@goalManager = new GoalManager(@world, @level.get('goals'), @team)
@god.setGoalManager(@goalManager)
@ -52,7 +52,7 @@ module.exports = class PlayGameDevLevelView extends RootView
scripts: @world.scripts or [], view: @, @session, levelID: @level.get('slug')})
@scriptManager.loadFromSession() # Should we? TODO: Figure out how scripts work for game dev levels
@supermodel.finishLoading()
.then (supermodel) =>
@levelLoader.destroy()
@levelLoader = null
@ -74,7 +74,8 @@ module.exports = class PlayGameDevLevelView extends RootView
@state.set('loading', false)
.catch ({message}) =>
@state.set('errorMessage', message)
console.error message
@state.set('errorMessage', message)
onClickPlayButton: ->
@god.createWorld(@spells, false, true)

View file

@ -0,0 +1,37 @@
RootView = require 'views/core/RootView'
Level = require 'models/Level'
LevelSession = require 'models/LevelSession'
WebSurfaceView = require './WebSurfaceView'
module.exports = class PlayWebDevLevelView extends RootView
id: 'play-web-dev-level-view'
template: require 'templates/play/level/play-web-dev-level-view'
# events:
# 'click #play-btn': 'onClickPlayButton'
initialize: (@options, @levelID, @sessionID) ->
@courseID = @getQueryVariable 'course'
@level = @supermodel.loadModel(new Level _id: @levelID).model
@session = @supermodel.loadModel(new LevelSession _id: @sessionID).model
onLoaded: ->
super()
@insertSubView @webSurface = new WebSurfaceView {level: @level}
Backbone.Mediator.publish 'tome:html-updated', html: @getHTML() ? '<h1>Player has no HTML</h1>', create: true
@$el.find('#info-bar').delay(4000).fadeOut(2000)
$('body').css('overflow', 'hidden')
showError: (jqxhr) ->
$('h1').text jqxhr.statusText
getHTML: ->
playerHTML = @session.get('code')?['hero-placeholder']?.plan
return playerHTML unless hero = _.find @level.get('thangs'), id: 'Hero Placeholder'
return playerHTML unless programmableConfig = _.find(hero.components, (component) -> component.config?.programmableMethods).config
return programmableConfig.programmableMethods.plan.languages.html.replace /<playercode>[\s\S]*<\/playercode>/, playerHTML
destroy: ->
@webSurface?.destroy()
super()

View file

@ -12,7 +12,7 @@ module.exports = class WebSurfaceView extends CocoView
initialize: (options) ->
@state = new State
blah: 'blah'
@goals = (goal for goal in options.goalManager.goals when goal.html)
@goals = (goal for goal in options.goalManager?.goals ? [] when goal.html)
# Consider https://www.npmjs.com/package/css-select to do this on virtualDOM instead of in iframe on concreteDOM
super(options)

View file

@ -44,11 +44,11 @@ module.exports = class CourseVictoryModal extends ModalView
@levelSessions = @supermodel.loadCollection(@levelSessions, 'sessions', {
data: { project: 'state.complete level.original playtime changed' }
}).model
if not @course
@course = new Course()
@supermodel.trackRequest @course.fetchForCourseInstance(@courseInstanceID)
window.tracker?.trackEvent 'Play Level Victory Modal Loaded', category: 'Students', levelSlug: @level.get('slug'), ['Mixpanel']
onResourceLoadFailed: (e) ->
@ -69,6 +69,7 @@ module.exports = class CourseVictoryModal extends ModalView
course: @course
classroom: @classroom
levelSessions: @levelSessions
session: @session
})
progressView.once 'done', @onDone, @

View file

@ -32,6 +32,7 @@ module.exports = class HeroVictoryModal extends ModalView
'click .sign-up-button': 'onClickSignupButton'
'click .continue-from-offer-button': 'onClickContinueFromOffer'
'click .skip-offer-button': 'onClickSkipOffer'
'click #share-level-btn': 'onClickShareLevelButton'
# Feedback events
'mouseover .rating i': (e) -> @showStars(@starNum($(e.target)))
@ -73,7 +74,9 @@ module.exports = class HeroVictoryModal extends ModalView
if @level.isType('course', 'course-ladder')
@saveReviewEventually = _.debounce(@saveReviewEventually, 2000)
@loadExistingFeedback()
# TODO: support 'game-dev' and 'web-dev' (not the same as 'course' since can be played outside of courses)
if @level.isType('game-dev', 'web-dev')
@shareURL = "#{window.location.origin}/play/#{@level.get('type')}-level/#{@level.get('slug')}/#{@session.id}"
destroy: ->
clearInterval @sequentialAnimationInterval
@ -499,6 +502,10 @@ module.exports = class HeroVictoryModal extends ModalView
onClickSkipOffer: (e) ->
Backbone.Mediator.publish 'router:navigate', @navigationEventUponCompletion
onClickShareLevelButton: ->
@$('#share-level-input').val(@shareURL).select()
@tryCopy()
# Ratings and reviews
starNum: (starEl) -> starEl.prevAll('i').length + 1

View file

@ -19,10 +19,14 @@ module.exports = class ProgressView extends CocoView
@classroom = options.classroom
@nextLevel = options.nextLevel
@levelSessions = options.levelSessions
@session = options.session
# Translate and Markdownify level description, but take out any images (we don't have room for arena banners, etc.).
# Images in Markdown are like ![description](url)
@nextLevel.get('description', true) # Make sure the defaults are available
@nextLevelDescription = marked(utils.i18n(@nextLevel.attributesWithDefaults, 'description').replace(/!\[.*?\]\(.*?\)\n*/g, ''))
if @level.isType('game-dev', 'web-dev')
@shareURL = "#{window.location.origin}/play/#{@level.get('type')}-level/#{@level.get('slug')}/#{@session.id}"
@shareURL += "?course=#{@course.id}" if @course
onClickDoneButton: ->
@trigger 'done'
@ -34,5 +38,5 @@ module.exports = class ProgressView extends CocoView
@trigger 'ladder'
onClickShareLevelButton: ->
@$('#share-level-input').val('alskdjfla').select()
@$('#share-level-input').val(@shareURL).select()
@tryCopy()