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
+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'