Initial effort to convert craft page to new models

This commit is contained in:
Andrew Miner
2017-07-01 18:06:11 -07:00
parent 997ff114b4
commit 20119cf8e4
20 changed files with 459 additions and 406 deletions
+2 -1
View File
@@ -112,7 +112,7 @@ module.exports = class BaseController extends Backbone.View
newModel = @onWillChangeModel @_model, newModel
@_model = newModel
@tryRefresh()
@onDidModelChange()
rendered:
get: -> @_rendered
@@ -149,6 +149,7 @@ module.exports = class BaseController extends Backbone.View
@$el.data $renderedEl.data()
@delegateEvents()
@$el.controller = this
@_rendered = true
@onDidRender()
@@ -5,39 +5,47 @@
# All rights reserved.
#
BaseController = require '../../base_controller'
SlotController = require '../slot/slot_controller'
BaseController = require "../../base_controller"
{Recipe} = require("crafting-guide-common").models
SlotController = require "../slot/slot_controller"
########################################################################################################################
module.exports = class CraftingGridController extends BaseController
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.modPack? then throw new Error 'options.modPack is required'
if not options.router? then throw new Error 'options.router is required'
# options.model should be a recipe
options.templateName = 'common/crafting_grid'
if not options.imageLoader? then throw new Error "options.imageLoader is required"
if not options.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error "options.router is required"
options.templateName = "common/crafting_grid"
super options
@_imageLoader = options.imageLoader
@_modPack = options.modPack
@_router = options.router
@_modPack.on c.event.change, => @tryRefresh()
# BaseController Methods #######################################################################
onWillChangeModel: (oldModel, newModel)->
if newModel? and (newModel.constructor isnt Recipe) then throw new Error "options.model must be a Recipe"
super
onDidRender: ->
@_slotControllers = []
for el in @$('.view__slot')
for el in @$(".view__slot")
controller = new SlotController el:el, imageLoader:@_imageLoader, modPack:@_modPack, router:@_router
controller.render()
@_slotControllers.push controller
super
refresh: ->
for controller, index in @_slotControllers
controller.model = @model?.getStackAtSlot(index)
index = 0
for y in [0..2]
for x in [0..2]
controller = @_slotControllers[index++]
if @model?
controller.model = @model.getInputAt x, y
else
controller.model = null
super
@@ -47,8 +47,6 @@ module.exports = class InventoryController extends BaseController
@_stackControllers = []
@listenTo @_modPack, c.event.change, => @tryRefresh()
# Event Methods ################################################################################
onClearButtonClicked: ->
@@ -61,31 +59,33 @@ module.exports = class InventoryController extends BaseController
@trigger c.event.change, this
onFirstButtonClicked: (stackController)->
tracker.trackEvent @_trackingContext, 'remove-from', "#{stackController?.model?.itemSlug}"
@trigger c.event.button.first, this, stackController?.model?.itemSlug
itemId = stackController.model?.item.id
tracker.trackEvent @_trackingContext, 'remove-from', itemId
@trigger c.event.button.first, this, itemId
onItemSelectorButtonClicked: ->
return unless @model?
tracker.trackEvent @_trackingContext, 'launch-add-to'
@_selector.launch()
.then (itemSlug)=>
if not itemSlug?
.then (item)=>
if not item?
tracker.trackEvent @_trackingContext, 'cancel-add-to'
return
tracker.trackEvent @_trackingContext, 'complete-add-to', "#{itemSlug}"
@model.add itemSlug, 1
@trigger c.event.add, this, itemSlug
tracker.trackEvent @_trackingContext, 'complete-add-to', "#{item.id}"
@model.add item, 1
@trigger c.event.add, this, item.id
@trigger c.event.change, this
onSecondButtonClicked: (stackController)->
itemId = stackController.model?.item.id
@trigger c.event.button.second, this, stackController?.model?.itemSlug
# BaseController Overrides #####################################################################
onDidRender: ->
@_selector = @addChild ItemSelectorController, null, isAcceptable: @_isAcceptable, modPack: @_modPack
@_selector = @addChild ItemSelectorController, null, isAcceptable:@_isAcceptable, modPack:@_modPack
@$clearButton = @$('.button.clear')
@$emptyPlaceholder = @$('.empty_placeholder')
@@ -131,7 +131,7 @@ module.exports = class InventoryController extends BaseController
index = 0
if @model?
@model.each (stack)=>
for itemId, stack of @model.stacks
controller = @_stackControllers[index]
if not controller?
controller = new StackController
@@ -153,6 +153,7 @@ module.exports = class InventoryController extends BaseController
@$itemContainer.append controller.$el
else
controller.model = stack
index += 1
while @_stackControllers.length > index
@@ -5,58 +5,63 @@
# All rights reserved.
#
BaseController = require '../../../base_controller'
BaseController = require "../../../base_controller"
ItemDisplay = require "../../../../models/site/item_display"
########################################################################################################################
module.exports = class ElementController extends BaseController
constructor: (options={})->
if not options.model? then throw new Error 'options.model is required'
options.onClicked ?= (controller)-> # do nothing
options.onSelected ?= (controller)-> # do nothing
options.templateName = 'common/item_selector/element'
if not options.model? then throw new Error "options.model is required"
options.templateName = "common/item_selector/element"
options.useAnimations = false
super options
@onClicked = options.onClicked
@onSelected = options.onSelected
@onClicked = options.onClicked or (controller)-> # do nothing
@onSelected = options.onSelected or (controller)-> # do nothing
# Property Methods #############################################################################
isSelected: ->
return @_selected
setSelected: (newSelected)->
oldSelected = @_selected
return if newSelected is oldSelected
@_selected = newSelected
@tryRefresh()
@trigger c.event.change + ':selected', this, oldSelected, newSelected
@trigger c.event.change, this
Object.defineProperties @prototype,
selected: {get:@prototype.isSelected, set:@prototype.setSelected}
display:
get: -> return @_display ?= new ItemDisplay @model
set: -> throw new Error "display cannot be assigned"
isSelected:
get: -> return @_selected
set: (newSelected)->
oldSelected = @_selected
return if newSelected is oldSelected
@_selected = newSelected
@tryRefresh()
@trigger c.event.change + ":selected", this, oldSelected, newSelected
@trigger c.event.change, this
# BaseController Overrides #####################################################################
onDidModelChange: ->
@_display = null
super
onDidRender: ->
@$icon = @$('img')
@$name = @$('.name')
@$modName = @$('.modName')
@$icon = @$("img")
@$name = @$(".name")
@$modName = @$(".modName")
super
refresh: ->
@$icon.attr 'src', @model.iconUrl
@$name.html @model.itemName
@$modName.html @model.modName
@$icon.attr "src", @display.iconUrl
@$name.html @model.displayName
@$modName.html @model.mod.displayName
if @_selected
@$el.addClass 'selected'
@$el.addClass "selected"
else
@$el.removeClass 'selected'
@$el.removeClass "selected"
super
@@ -64,15 +69,15 @@ module.exports = class ElementController extends BaseController
events: ->
return _.extend super,
'click': '_onClick'
'mouseenter': '_onMouseEnter'
"click": "_onClick"
"mouseenter": "_onMouseEnter"
# Private Methods ##############################################################################
_onClick: (event)->
event.preventDefault()
@onClicked this
return false
_onMouseEnter: (event)->
event.preventDefault()
@onSelected this
return false
@@ -5,21 +5,22 @@
# All rights reserved.
#
BaseController = require '../../base_controller'
ItemSelector = require '../../../models/site/item_selector'
ElementController = require './element/element_controller'
BaseController = require "../../base_controller"
ItemDisplay = require "../../../models/site/item_display"
ItemSelector = require "../../../models/site/item_selector"
ElementController = require "./element/element_controller"
w = require "when"
########################################################################################################################
module.exports = class ItemSelectorController extends BaseController
constructor: (options)->
if not options.modPack? then throw new Error 'options.modPack is required'
constructor: (options={})->
if not options.modPack? then throw new Error "options.modPack is required"
options.isAcceptable ?= null
options.model ?= new ItemSelector {}, modPack:options.modPack, isAcceptable:options.isAcceptable
options.model ?= new ItemSelector options.modPack, isAcceptable:options.isAcceptable
options.onChoseItem ?= (item)-> # do nothing
options.templateName = 'common/item_selector'
options.templateName = "common/item_selector"
super options
@_modPack = options.modPack
@@ -29,25 +30,25 @@ module.exports = class ItemSelectorController extends BaseController
# Public Methods ###############################################################################
launch: (hint='')->
launch: (hint="")->
@model.hint = hint
if @rendered then @refresh()
@_disableWindowScrolling()
@$page.addClass 'blur'
@$page.addClass "blur"
@$screen.append @$popup
@$screen.css 'display', ''
@$screen.css "display", ""
@$popup.off c.event.click
@$popup.on c.event.click, (event)=> @onPopupClicked(event)
@$hintField.off 'keyup input'
@$hintField.on 'keyup', (event)=> @onHintKeyPress(event)
@$hintField.on 'input', (event)=> @onHintChanged(event)
@$hintField.off "keyup input"
@$hintField.on "keyup", (event)=> @onHintKeyPress(event)
@$hintField.on "input", (event)=> @onHintChanged(event)
@$hintField.focus()
@$closeButton.one 'click', (event)=> @_close()
@$closeButton.one "click", (event)=> @_close()
@$screen.one c.event.click, (event)=> @onScreenClicked(event)
@@ -85,17 +86,17 @@ module.exports = class ItemSelectorController extends BaseController
return false
onResultClicked: (controller)->
@_session.resolve controller.model.slug
@_session.resolve controller.model
@_session = null
@_close()
return false
onResultSelected: (controller)->
for c in @_elementControllers
c.selected = false
c.isSelected = false
if controller?
controller.selected = true
controller.isSelected = true
return false
@@ -106,14 +107,14 @@ module.exports = class ItemSelectorController extends BaseController
# BaseController Overrides #####################################################################
onDidRender: ->
@$page = $('.page') # find the shared, global page
@$screen = $('.view__screen') # find the shared, global screen
@$page = $(".page") # find the shared, global page
@$screen = $(".view__screen") # find the shared, global screen
@$closeButton = @$('img.close')
@$popup = @$('.view__item_selector_popup')
@$hintField = @$('.view__item_selector_popup input')
@$searchInput = @$('.search input')
@$resultsContainer = @$('.results')
@$closeButton = @$("img.close")
@$popup = @$(".view__item_selector_popup")
@$hintField = @$(".view__item_selector_popup input")
@$searchInput = @$(".search input")
@$resultsContainer = @$(".results")
@$popup.detach()
super
@@ -127,16 +128,16 @@ module.exports = class ItemSelectorController extends BaseController
_chooseSelected: ->
for controller in @_elementControllers
if controller.selected
if controller.isSelected
@onResultClicked controller
return
_close: ->
@_enableWindowScrolling()
@$page.removeClass 'blur'
@$screen.css 'display', 'none'
@$page.removeClass "blur"
@$screen.css "display", "none"
@$popup.detach()
@model.hint = ''
@model.hint = ""
if @_session
@_session.resolve null
@@ -144,28 +145,27 @@ module.exports = class ItemSelectorController extends BaseController
_disableWindowScrolling: ->
@_windowScrollPosition = $(window).scrollTop()
$('body').addClass('scrollDisabled').css('margin-top', -@_windowScrollPosition)
$("body").addClass("scrollDisabled").css("margin-top", -@_windowScrollPosition)
_enableWindowScrolling: ->
$('body').removeClass('scrollDisabled').css('margin-top', 0)
$("body").removeClass("scrollDisabled").css("margin-top", 0)
$(window).scrollTop @_windowScrollPosition
_refreshResults: ->
index = 0
for itemSlug in @model.results
displayModel = @_modPack.findItemDisplay itemSlug
for item in @model.results
controller = @_elementControllers[index]
if not controller?
controller = new ElementController
model: displayModel
model: item
onClicked: (c)=> @onResultClicked(c)
onSelected: (c)=> @onResultSelected(c)
controller.render show:false
@_elementControllers[index] = controller
@$resultsContainer.append controller.$el
else
controller.model = displayModel
controller.model = item
controller.show()
index += 1
@@ -180,14 +180,17 @@ module.exports = class ItemSelectorController extends BaseController
controller = @_elementControllers[i]
nextController = @_elementControllers[i + 1]
if controller.selected
controller.selected = false
nextController.selected = true
if controller.isSelected
controller.isSelected = false
nextController.isSelected = true
@_showElement nextController.$el
return
[..., controller] = @_elementControllers
controller.isSelected = false
controller = @_elementControllers[0]
controller.selected = true
controller.isSelected = true
@_showElement controller.$el
_selectPrevious: ->
@@ -197,14 +200,17 @@ module.exports = class ItemSelectorController extends BaseController
previousController = @_elementControllers[i - 1]
controller = @_elementControllers[i]
if controller.selected
previousController.selected = true
controller.selected = false
if controller.isSelected
previousController.isSelected = true
controller.isSelected = false
@_showElement previousController.$el
return
controller = @_elementControllers[@_elementControllers.length - 1]
controller.selected = true
controller = @_elementControllers[0]
controller.isSelected = false
[..., controller] = @_elementControllers
controller.isSelected = true
@_showElement controller.$el
_showElement: ($el)->
@@ -5,20 +5,21 @@
# All rights reserved.
#
BaseController = require '../../base_controller'
CraftingGridController = require '../crafting_grid/crafting_grid_controller'
SlotController = require '../slot/slot_controller'
{StringBuilder} = require('crafting-guide-common').util
BaseController = require "../../base_controller"
CraftingGridController = require "../crafting_grid/crafting_grid_controller"
ItemDisplay = require "../../../models/site/item_display"
SlotController = require "../slot/slot_controller"
{StringBuilder} = require("crafting-guide-common").util
########################################################################################################################
module.exports = class RecipeController extends BaseController
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.modPack? then throw new Error 'options.modPack is required'
if not options.router? then throw new Error 'options.router is required'
options.templateName = 'common/recipe'
if not options.imageLoader? then throw new Error "options.imageLoader is required"
if not options.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error "options.router is required"
options.templateName = "common/recipe"
super options
@_imageLoader = options.imageLoader
@@ -29,26 +30,26 @@ module.exports = class RecipeController extends BaseController
# BaseController Overrides #####################################################################
onDidRender: ->
@_gridController = @addChild CraftingGridController, '.view__crafting_grid',
@_gridController = @addChild CraftingGridController, ".view__crafting_grid",
modPack: @_modPack
imageLoader: @_imageLoader
router: @_router
@_outputSlotController = @addChild SlotController, '.output .view__slot',
@_outputSlotController = @addChild SlotController, ".output .view__slot",
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
@$multiplier = @$('.multiplier')
@$outputImg = @$('.output img')
@$outputLink = @$('.output a')
@$outputQuantity = @$('.quantity')
@$toolContainer = @$('.tool')
@$multiplier = @$(".multiplier")
@$outputImg = @$(".output img")
@$outputLink = @$(".output a")
@$outputQuantity = @$(".quantity")
@$toolContainer = @$(".tool")
super
refresh: ->
@_gridController.model = @model
@_outputSlotController.model = @model?.output?[0]
@_outputSlotController.model = @model?.output
@_refreshMultiplier()
@_refreshTools()
@@ -69,14 +70,14 @@ module.exports = class RecipeController extends BaseController
@_multiplier = newMultiplier
@_refreshMultiplier()
@trigger Event.change + ':multiplier', this, oldMultiplier, newMultiplier
@trigger Event.change + ":multiplier", this, oldMultiplier, newMultiplier
@trigger Event.change, this
# Backbone.View Methods ########################################################################
events: ->
return _.extend super,
'click a': 'routeLinkClick'
"click a": "routeLinkClick"
# Private Methods ##############################################################################
@@ -84,14 +85,15 @@ module.exports = class RecipeController extends BaseController
if @multiplier > 1
@$multiplier.html "x#{@multiplier}"
else
@$multiplier.html ''
@$multiplier.html ""
_refreshTools: ->
@$toolContainer.empty()
return unless @model?
builder = new StringBuilder
builder.loop @model.tools, delimiter:', ', onEach:(b, stack)=>
display = @_modPack.findItemDisplay stack.itemSlug
b.push "<a href=\"#{display.itemUrl}\">#{display.itemName}</a>"
@$toolContainer.html builder.toString()
toolLinks = []
for itemId, item of @model.tools
display = new ItemDisplay item
toolLinks.push "<a href=\"#{display.url}\">#{display.name}</a>"
@$toolContainer.html toolLinks.join ", "
@@ -5,18 +5,19 @@
# All rights reserved.
#
BaseController = require '../../base_controller'
BaseController = require "../../base_controller"
ItemDisplay = require "../../../models/site/item_display"
{Stack} = require("crafting-guide-common").models
########################################################################################################################
module.exports = class SlotController extends BaseController
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.modPack? then throw new Error 'options.modPack is required'
if not options.router? then throw new Error 'options.router is required'
# options.model should be a Stack
options.templateName = 'common/slot'
if not options.imageLoader? then throw new Error "options.imageLoader is required"
if not options.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error "options.router is required"
options.templateName = "common/slot"
options.useAnimations = false
super options
@@ -27,27 +28,31 @@ module.exports = class SlotController extends BaseController
# BaseController Overrides #####################################################################
onDidRender: ->
@$link = @$('a')
@$image = @$('img')
@$quantity = @$('.quantity')
@$link = @$("a")
@$image = @$("img")
@$quantity = @$(".quantity")
super
onWillChangeModel: (oldModel, newModel)->
if newModel? and (newModel.constructor isnt Stack) then throw new Error "newModel must be a Stack"
super
refresh: ->
if @model?
display = @_modPack.findItemDisplay @model.itemSlug
@$link.attr 'href', display.itemUrl
display = new ItemDisplay @model.item
@$link.attr "href", display.url
@_imageLoader.load display.iconUrl, @$image
if @model.quantity > 1
@$quantity.html @model.quantity
else
@$quantity.html ''
@$quantity.html ""
else
@$link.removeAttr 'href'
@$quantity.html ''
@$link.removeAttr "href"
@$quantity.html ""
@$image.attr 'src', '/images/empty.png'
@$image.attr "src", "/images/empty.png"
super
@@ -55,4 +60,4 @@ module.exports = class SlotController extends BaseController
events: ->
return _.extend super,
'click a': 'routeLinkClick'
"click a": "routeLinkClick"
@@ -6,6 +6,7 @@
#
BaseController = require '../../base_controller'
ItemDisplay = require "../../../models/site/item_display"
########################################################################################################################
@@ -38,8 +39,6 @@ module.exports = class StackController extends BaseController
@_shouldEnableButton = options.shouldEnableButton ?= (model, button)-> true
@_trackingContext = options.trackingContext ?= null
@_modPack.on c.event.change, => @tryRefresh()
# Event Methods ################################################################################
onFirstButtonClicked: (event)->
@@ -71,7 +70,7 @@ module.exports = class StackController extends BaseController
@trigger c.event.change + ':quantity', this, oldQuantity, newQuantity
@trigger c.event.change, this
tracker.trackEvent @_trackingContext, 'update-quantity', @model.itemSlug, @model.quantity
tracker.trackEvent @_trackingContext, 'update-quantity', @model.item.id, @model.quantity
onQuantityFieldChanged: ->
return unless @_editable
@@ -119,10 +118,10 @@ module.exports = class StackController extends BaseController
refresh: ->
if not @model? then throw new Error "must have a model to render"
display = @_modPack.findItemDisplay @model.itemSlug
display = new ItemDisplay @model.item
@_imageLoader.load display.iconUrl, @$image
@$nameLink.html display.itemName
@$nameLink.html display.name
@$nameLink.attr 'href', display.itemUrl
quantityText = if @model.quantity > 10000 then "#{@model.quantity / 1000}k" else "#{@model.quantity}"
+1 -1
View File
@@ -53,4 +53,4 @@
h2 Steps
.panel
section.view__craftsman_working
section.view__working_panel
@@ -5,14 +5,13 @@
# All rights reserved.
#
BaseController = require '../base_controller'
CraftPage = require '../../models/site/craft_page'
{Craftsman} = require('crafting-guide-common').deprecated.crafting
CraftsmanWorkingController = require './craftsman_working/craftsman_working_controller'
InventoryController = require '../common/inventory/inventory_controller'
PageController = require '../page_controller'
{SimpleInventory} = require('crafting-guide-common').deprecated.crafting
StepController = require './step/step_controller'
CraftPage = require "../../models/site/craft_page"
WorkingPanelController = require "./working_panel/working_panel_controller"
{Inventory} = require("crafting-guide-common").models
InventoryController = require "../common/inventory/inventory_controller"
{Observable} = require("crafting-guide-common").util
PageController = require "../page_controller"
StepController = require "./step/step_controller"
########################################################################################################################
@@ -21,12 +20,12 @@ module.exports = class CraftPageController extends PageController
@::SCROLL_BUFFER = 8 # px
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.modPack? then throw new Error 'options.modPack is required'
if not options.router? then throw new Error 'options.router is required'
if not options.storage? then throw new Error 'options.storage is required'
if not options.imageLoader? then throw new Error "options.imageLoader is required"
if not options.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error "options.router is required"
if not options.storage? then throw new Error "options.storage is required"
options.model ?= new CraftPage modPack:options.modPack
options.model ?= new CraftPage modPack:options.modPack, params:options.params
options.templateName = 'craft_page'
super options
@@ -35,41 +34,46 @@ module.exports = class CraftPageController extends PageController
@_router = options.router
@_storage = options.storage
@model.have.on Observable::ANY, this, "onHaveInventoryChanged"
@model.want.on Observable::ANY, this, "onWantInventoryChanged"
# Event Methods ################################################################################
onHaveInventoryChanged: ->
@_storage.store 'crafting-plan:have', @model.craftsman.have.unparse()
@_storage.store 'crafting-plan:have', @model.have.toUrlString()
onMoveNeedToHave: (itemSlug)->
quantity = @_needInventoryController.model.quantityOf itemSlug
@model.craftsman.have.add itemSlug, quantity
onMoveNeedToHave: (itemId)->
quantity = @_needInventoryController.model.getQuantity itemId
item = @_modPack.findItem itemId
@model.have.add item, quantity
onRemoveFromHaveInventory: (itemSlug)->
@model.craftsman.have.remove itemSlug
onRemoveFromHave: (itemId)->
@model.have.remove itemId
onRemoveFromWant: (itemSlug)->
@model.craftsman.want.remove itemSlug
onRemoveFromWant: (itemId)->
@model.want.remove itemId
@onWantInventoryChanged()
onSampleClicked: (event)->
$el = $(event.target)
while $el.length > 0
inventoryText = $el.attr 'data-slug'
inventoryText = $el.attr "data-slug"
break if inventoryText
$el = $el.parent()
if inventoryText?
tracker.trackEvent c.tracking.category.craft, 'add-sample', inventoryText
sampleInventory = new SimpleInventory
sampleInventory.parse inventoryText
@model.craftsman.want.addInventory sampleInventory
@_scrollTo @$workingSection
@onWantInventoryChanged()
try
tracker.trackEvent c.tracking.category.craft, "add-sample", inventoryText
sampleInventory = Inventory.fromUrlString inventoryText, @_modPack
@model.want.merge sampleInventory
@_scrollTo @$workingSection
catch e
logger.error e
return false
onWantInventoryChanged: ->
text = @model.craftsman.want.unparse()
text = @model.want.toUrlString()
url = c.url.crafting inventoryText:text
@router.navigate url
@@ -79,7 +83,7 @@ module.exports = class CraftPageController extends PageController
return c.text.craftDescription()
getTitle: ->
description = @model.craftsman.want.toDescription()
description = @model.want.toDescription()
return null unless description?
return "Crafting Plan for #{description}"
@@ -91,21 +95,19 @@ module.exports = class CraftPageController extends PageController
imageLoader: @_imageLoader
isAcceptable: (item)=> item.isCraftable
modPack: @_modPack
model: @model.craftsman.want
model: @model.want
router: @_router
trackingContext: c.tracking.category.craftWant
@_wantInventoryController.on c.event.button.first, (c, s)=> @onRemoveFromWant(s)
@_wantInventoryController.on c.event.change, (c)=> @onWantInventoryChanged()
@_wantInventoryController.on c.event.button.first, (controller, itemId)=> @onRemoveFromWant itemId
@_haveInventoryController = @addChild InventoryController, '.have .view__inventory',
firstButtonType: 'down'
imageLoader: @_imageLoader
modPack: @_modPack
model: @model.craftsman.have
model: @model.have
router: @_router
trackingContext: c.tracking.category.craftHave
@_haveInventoryController.on c.event.button.first, (controller, itemSlug)=>
@onRemoveFromHaveInventory itemSlug
@_haveInventoryController.on c.event.button.first, (controller, itemId)=> @onRemoveFromHave itemId
@_needInventoryController = @addChild InventoryController, '.need .view__inventory',
editable: false
@@ -115,11 +117,9 @@ module.exports = class CraftPageController extends PageController
model: null
router: @_router
trackingContext: c.tracking.category.craftNeed
@_needInventoryController.on c.event.button.first, (c, s)=> @onMoveNeedToHave(s)
@_needInventoryController.on c.event.button.first, (controller, itemId)=> @onMoveNeedToHave itemId
@_workingSectionController = @addChild CraftsmanWorkingController, '.view__craftsman_working',
model: @model.craftsman
@_workingSectionController.on c.event.click, => @_scrollTo @$workingSection
@_workingPanelController = @addChild WorkingPanelController, '.view__working_panel', model:@model
@$haveSection = @$('section.have')
@$instructionsSection = @$('section.instructions')
@@ -128,7 +128,7 @@ module.exports = class CraftPageController extends PageController
@$stepsContainer = @$('section.steps .panel')
@$stepsSection = @$('section.steps')
@$toolsSection = @$('section.tools')
@$workingSection = @$('.view__craftsman_working')
@$workingSection = @$('.view__working_panel')
if c.screen.type.compute() is c.screen.type.mobile
@$('.view__inventory.large').removeClass 'large'
@@ -136,20 +136,15 @@ module.exports = class CraftPageController extends PageController
super
onWillRender: ->
@model.craftsman.have.clear()
@model.craftsman.have.parse @_storage.load('crafting-plan:have')
@model.craftsman.have.on c.event.change, => @onHaveInventoryChanged()
@model.craftsman.want.on c.event.change, => @refresh()
@model.craftsman.on c.event.change + ":stage", =>
return unless @model.craftsman.stage is Craftsman::STAGE.COMPLETE
@_scrollTo @$needSection
@model.have.clear()
@model.have.merge Inventory.fromUrlString @_storage.load('crafting-plan:have')
@model.have.on Observable::ANY, this, "onHaveInventoryChanged"
@model.want.on Observable::ANY, this, "tryRefresh"
super
refresh: ->
@_needInventoryController.model = @model.craftsman.plan?.need
@_needInventoryController.model = @model.currentPlan?.need
@_refreshOutdated()
@_refreshSectionVisibility()
@_refreshSteps()
@@ -165,33 +160,30 @@ module.exports = class CraftPageController extends PageController
# Private Methods ################################################################################
_addTools: (controller)->
controller.model.addToolsTo @model.craftsman.want
controller.model.addToolsTo @model.want
_completeStep: (controller)->
controller.markComplete @model.craftsman.have
controller.markComplete @model.have
_isAddingToolsPossible: (controller)->
tools = controller.model.recipe.tools
return false unless tools.length > 0
have = @model.craftsman.have
want = @model.craftsman.want
have = @model.have
want = @model.want
for stack in tools
return false if have.hasAtLeast stack.itemSlug
return false if want.hasAtLeast stack.itemSlug
return false if @model.have.contains stack.item.id
return false if @model.want.contains stack.item.id
return true
_isStepCompletable: (controller)->
recipe = controller.model.recipe
for stack in recipe.output
return false if @model.craftsman.want.hasAtLeast stack.itemSlug
return true
wantsOutput = @model.want.contains controller.model.recipe.output.item.id
return wantsOutput
_refreshOutdated: ->
if @model.craftsman.stage is Craftsman::STAGE.OUTDATED
if @model.isOutdated
@$el.addClass 'outdated'
else
@$el.removeClass 'outdated'
@@ -205,22 +197,25 @@ module.exports = class CraftPageController extends PageController
visibleSections = []
if @model.craftsman.want.isEmpty
# TODO: Figure out what to do if the planner can't make a valid plan
# else if @model.craftsman.stage is Craftsman::STAGE.INVALID
# visibleSections.push el for el in [@$wantSection, @$haveSection, @$workingSection]
# TODO: Play around and see if the algo ever takes too long
# else if not @model.craftsman.complete
# visibleSections.push el for el in [@$wantSection, @$haveSection, @$workingSection]
if @model.want.isEmpty
visibleSections.push el for el in [@$instructionsSection, @$wantSection]
else if @model.craftsman.stage is Craftsman::STAGE.INVALID
visibleSections.push el for el in [@$wantSection, @$haveSection, @$workingSection]
else if not @model.craftsman.complete
visibleSections.push el for el in [@$wantSection, @$haveSection, @$workingSection]
else
visibleSections.push el for el in [@$haveSection, @$wantSection, @$workingSection]
if @model.craftsman.plan?
if @model.currentPlan?
visibleSections.push el for el in [@$needSection, @$stepsSection]
@hide $el for $el in allSections
@show $el for $el in visibleSections
_refreshSteps: ->
steps = @model.craftsman.plan?.steps or []
steps = @model.currentPlan?.steps or []
@_stepControllers ?= []
index = 0
@@ -1,106 +0,0 @@
#
# Crafting Guide - craftsman_working_controller.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require '../../base_controller'
{Craftsman} = require('crafting-guide-common').deprecated.crafting
########################################################################################################################
module.exports = class CraftsmanWorkingController extends BaseController
@::HIDE_TIMER_DURATION = 2000
constructor: (options={})->
if not options.model then throw new Error 'options.model is required'
options.templateName = 'craft_page/craftsman_working'
super options
@_hideTimer = null
# Event Methods ################################################################################
onButtonClicked: ->
tracker.trackEvent c.tracking.category.craft, 'start'
@trigger c.event.click
@model.reset()
@model.work()
return false
# BaseController Methods #######################################################################
onDidModelChange: ->
@refresh()
onDidRender: ->
@$button = @$('.button')
@$count = @$('.count p')
@$message = @$('.message p')
@$outdated = @$('.outdated')
@$waiting = @$('.waiting')
@_controls = [@$button, @$count, @$message, @$outdated, @$waiting]
super
refresh: ->
return unless @$message? and @$count?
button = count = message = outdated = waiting = null
switch @model.stage
when Craftsman::STAGE.READY
message = 'Ready to compute crafting plan!'
count = 'Click "Calculate" to continue.'
button = true
when Craftsman::STAGE.GRAPHING
message = 'Researching recipes...'
count = "Found #{@model.stageCount} recipes so far..."
watiing = true
when Craftsman::STAGE.PLANNING
message = 'Figuring out possible crafting plans...'
count = "Found #{@model.stageCount} possibilities so far..."
watiing = true
when Craftsman::STAGE.ANALYZING
message = 'Looking for the best plan...'
count = "Finished checking #{@model.stageCount} so far..."
watiing = true
when Craftsman::STAGE.COMPLETE
message = 'Crafting plan is complete.'
when Craftsman::STAGE.INVALID
message = 'Couldn\'t make a crafting plan!'
count = 'Please report this problem using the Feedback box.'
when Craftsman::STAGE.OUTDATED
message = 'Your crafting plan is out of date!'
count = 'Click "Calculate" to re-compute.'
button = true
outdated = true
@hide(control) for control in @_controls
if button?
@show @$button
if count?
@show @$count
@$count.html count
if message?
@show @$message
@$message.html message
if outdated?
@show @$outdated
if waiting?
@show @$waiting
super
# Backbone.View Overrides ######################################################################
events: ->
return _.extend super,
'click .button': 'onButtonClicked'
@@ -6,16 +6,19 @@
#
BaseController = require '../../base_controller'
{Inventory} = require("crafting-guide-common").models
{CraftingPlanStep} = require("crafting-guide-common").crafting
InventoryController = require '../../common/inventory/inventory_controller'
RecipeController = require '../../common/recipe/recipe_controller'
{SimpleInventory} = require('crafting-guide-common').deprecated.crafting
########################################################################################################################
module.exports = class StepController extends BaseController
constructor: (options={})->
if not options.model? then throw new Error 'options.model is required'
if options.model?.constructor isnt CraftingPlanStep
throw new Error "options.model must be a CraftingPlanStep"
if not options.modPack? then throw new Error 'options.modPack is required'
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
options.templateName = 'craft_page/step'
@@ -41,7 +44,7 @@ module.exports = class StepController extends BaseController
onCompleteButtonClicked: (event)->
return if @$completeButton.hasClass 'disabled'
tracker.trackEvent c.tracking.category.craft, 'mark-complete', null, @model.number
tracker.trackEvent c.tracking.category.craft, 'mark-complete', null, @model.count
@onComplete this
onShowToolPlan: (event)->
@@ -54,7 +57,7 @@ module.exports = class StepController extends BaseController
@inventoryController = @addChild InventoryController, '.view__inventory',
editable: false
imageLoader: @_imageLoader
model: @model.inventory
model: @model.inputInventory
modPack: @_modPack
router: @_router
@@ -78,12 +81,11 @@ module.exports = class StepController extends BaseController
return super
refresh: ->
itemDisplay = @_modPack.findItemDisplay @model.recipe.output[0].itemSlug
@$header.html "#{@model.number}. #{itemDisplay.itemName}"
@$header.html "#{@model.number}. #{@model.recipe.output.item.displayName}"
@inventoryController.model = @model.inventory
@inventoryController.model = @model.inputInventory
@recipeController.model = @model.recipe
@recipeController.multiplier = @model.multiplier
@recipeController.multiplier = @model.count
@_refreshCompleteButton()
@_refreshToolButton()
@@ -100,12 +102,11 @@ module.exports = class StepController extends BaseController
# Private Methods ##############################################################################
_refreshToolButton: ->
inventory = new SimpleInventory {}, modPack:@_modPack
for toolStack in @model.recipe.tools
inventory.add toolStack.itemSlug, toolStack.quantity
inventory.localize()
inventory = new Inventory
for itemId, item in @model.recipe.tools
inventory.add item
inventoryText = inventory.unparse()
inventoryText = inventory.toUrlString()
@$toolButton.attr 'href', "/craft/#{inventoryText}"
@$toolButton.attr 'target', inventoryText
@@ -0,0 +1,89 @@
#
# Crafting Guide - working_panel_controller.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require '../../base_controller'
CraftPage = require "../../../models/site/craft_page"
########################################################################################################################
module.exports = class WorkingPanelController extends BaseController
@::HIDE_TIMER_DURATION = 2000
constructor: (options={})->
if not options.model?.constructor is CraftPage then throw new Error "options.model must be a CraftPage"
options.templateName = "craft_page/working_panel"
super options
@_hideTimer = null
# Event Methods ################################################################################
onButtonClicked: ->
tracker.trackEvent c.tracking.category.craft, "start"
@trigger c.event.click
@model.createPlan()
return false
# BaseController Methods #######################################################################
onDidModelChange: ->
@refresh()
onDidRender: ->
@$button = @$('.button')
@$count = @$('.count p')
@$message = @$('.message p')
@$outdated = @$('.outdated')
@$waiting = @$('.waiting')
@_controls = [@$button, @$count, @$message, @$outdated, @$waiting]
super
refresh: ->
return unless @$message? and @$count?
button = count = message = outdated = null
if @model.isOutdated
message = "Your crafting plan is out of date!"
count = 'Click "Calculate" to re-compute.'
button = true
outdated = true
else if @model.currentPlan?
message = "Crafting plan is complete."
else
message = "Ready to compute crafting plan!"
count = 'Click "Calculate" to continue.'
button = true
@hide(control) for control in @_controls
if button?
@show @$button
if count?
@show @$count
@$count.html count
if message?
@show @$message
@$message.html message
if outdated?
@show @$outdated
if waiting?
@show @$waiting
super
# Backbone.View Overrides ######################################################################
events: ->
return _.extend super,
'click .button': 'onButtonClicked'
+1 -2
View File
@@ -117,8 +117,7 @@ module.exports = class Router extends Backbone.Router
@route__craft()
route__craft: (text)->
controller = new CraftPageController @_makeOptions {}
controller.model.params = inventoryText:text
controller = new CraftPageController @_makeOptions params:inventoryText:text
@_siteController.setPage 'craft', controller
route__login: ->