Store want/have in URL/local storage

This commit is contained in:
Andrew Miner
2015-01-31 15:48:24 -08:00
parent 6d63824d76
commit e0c642e787
6 changed files with 79 additions and 45 deletions
@@ -10,6 +10,7 @@ CraftingTableController = require './crafting_table_controller'
{Event} = require '../constants'
ImageLoader = require './image_loader'
InventoryController = require './inventory_controller'
InventoryParser = require '../models/inventory_parser'
ItemPage = require '../models/item_page'
ModPackController = require './mod_pack_controller'
NameFinder = require '../models/name_finder'
@@ -27,6 +28,7 @@ module.exports = class ItemPageController extends BaseController
super options
@_imageLoader = options.imageLoader
@_parser = new InventoryParser modPack:options.modPack
@_storage = options.storage
# Event Methods ################################################################################
@@ -38,6 +40,7 @@ module.exports = class ItemPageController extends BaseController
onWillRender: ->
@_storage.register 'crafting-plan', @model.plan, 'includingTools'
@_parser.parse @_storage.load('crafting-plan:have'), @model.plan.have
super
onDidRender: ->
@@ -55,6 +58,7 @@ module.exports = class ItemPageController extends BaseController
imageLoader: @_imageLoader
model: @model.plan.have
modPack: @model.modPack
onChange: => @_saveHaveInventory()
nameFinder: new NameFinder @model.modPack, includeGatherable:true
title: 'Items you have'
@@ -95,10 +99,12 @@ module.exports = class ItemPageController extends BaseController
# Private Methods ##############################################################################
_saveHaveInventory: ->
@_storage.store 'crafting-plan:have', @_parser.unparse @model.plan.have
_updateLocation: ->
list = @model.plan.want.toList()
if list.length is 1
slug = if _.isArray(list[0]) then list[0][1] else list[0]
router.navigate "/item/#{slug}"
text = @_parser.unparse @model.plan.want
if @model.plan.want.isEmpty
router.navigate '/'
else
router.navigate "/"
router.navigate "/item/#{text}"
+11 -3
View File
@@ -62,11 +62,19 @@ module.exports = class CraftingGuideRouter extends Backbone.Router
root: ->
params = new UrlParams recipeName:{type:'string'}, count:{type:'integer'}
@item params.recipeName, params.count
item: (name, quantity=1)->
arg = null
if params.recipeName?
if params.count?
arg = "#{params.count}:#{params.recipeName}"
else
arg = "#{params.recipeName}"
@item arg
item: (inventoryText)->
controller = new ItemPageController @_defaultOptions
controller.model.params = name:name, quantity:quantity
controller.model.params = inventoryText:inventoryText
@_setPage 'item', controller
mod: (slug)->
+22 -14
View File
@@ -18,7 +18,9 @@ module.exports = class InventoryParser
# Class Methods ################################################################################
@ITEM_REGEX = /^([0-9]+)(.*)$/
@STACK_DELIMITER = ':'
@ITEM_DELIMITER = '.'
# Public Methods ###############################################################################
@@ -26,25 +28,31 @@ module.exports = class InventoryParser
inventory ?= new Inventory
return inventory if not data? or data.length is 0
lines = data.split '\n'
for line in lines
match = InventoryParser.ITEM_REGEX.exec line
name = if match? then match[2].trim() else line
quantity = if match? then parseInt(match[1]) else 1
stacks = data.split InventoryParser.STACK_DELIMITER
for stackText in stacks
stackParts = stackText.split InventoryParser.ITEM_DELIMITER
if stackParts.length is 2
quantity = parseInt stackParts[0]
slug = _.slugify stackParts[1]
else if stackParts.length is 1
quantity = 1
slug = _.slugify stackParts[0]
else
throw new Error "expected #{stackText} to have 0 or 1 parts"
if name.length > 0
inventory.add _.slugify(name), quantity
if slug.length > 0
inventory.add slug, quantity
return inventory
unparse: (inventory)->
if not @modPack? then throw new Error 'this.modPack is needed to unparse'
builder = new StringBuilder
for item in inventory.toList()
if _.isString item
builder.line @modPack.findName item
parts = []
inventory.each (stack)->
if stack.quantity is 1
parts.push stack.slug
else
builder.line item[0], ' ', @modPack.findName item[1]
parts.push "#{stack.quantity}#{InventoryParser.ITEM_DELIMITER}#{stack.slug}"
return builder.toString()
return parts.join InventoryParser.STACK_DELIMITER
+12 -6
View File
@@ -9,6 +9,7 @@ BaseModel = require './base_model'
CraftingPlan = require './crafting_plan'
CraftingTable = require './crafting_table'
{Event} = require '../constants'
InventoryParser = require './inventory_parser'
ModPack = require './mod_pack'
########################################################################################################################
@@ -22,22 +23,27 @@ module.exports = class ItemPage extends BaseModel
attributes.table ?= new CraftingTable plan:attributes.plan
super attributes, options
@_parser = new InventoryParser
@modPack.on Event.change, => @_consumeParams()
@on Event.change + ':params', => @_consumeParams()
# Private Methods ##############################################################################
_consumeParams: ->
logger.debug "consuming params: #{util.inspect(@params)}"
return unless @params?
@plan.want.clear()
if not @params?.name?
if not @params.inventoryText?
@params = null
else
item = @modPack.findItemByName @params.name, enableAsNeeded:true
inventory = @_parser.parse @params.inventoryText
inventory.each (stack)=>
item = @modPack.findItemByName stack.slug, enableAsNeeded:true
return unless item? and item.isCraftable
@plan.want.add stack.slug, stack.quantity
inventory.remove stack.slug
quantity = if @params.quantity? then parseInt(@params.quantity) else 1
@plan.want.add item.slug, quantity
@params = null
if inventory.isEmpty then @params = null
+15 -9
View File
@@ -17,16 +17,25 @@ module.exports = class Storage
# Public Methods ###############################################################################
load: (key)->
value = @storage.getItem key
logger.verbose "loaded #{value} from #{key}"
return value
store: (key, value)->
@storage.setItem key, value
logger.verbose "stored #{value} into #{key}"
register: (key, model, properties...)->
modelData = @_models[key]
if not modelData? then modelData = @_models[key] = model:model, properties:{}
makeStoreMethod = (k, m, p)=> return => @_store(k, m, p)
makeStoreMethod = (k, m, p)=> return => @_storeProperty(k, m, p)
for property in properties
continue if modelData.properties[property]?
modelData.properties[property] = property
@_load key, model, property
@_loadProperty key, model, property
model.on "change:#{property}", makeStoreMethod(key, model, property)
unregister: (key, property)->
@@ -36,16 +45,13 @@ module.exports = class Storage
# Private Methods ##############################################################################
_load: (key, model, property)->
value = @storage.getItem "#{key}:#{property}"
_loadProperty: (key, model, property)->
value = @load "#{key}:#{property}"
value = JSON.parse(value) if value?
logger.verbose "loaded #{value} from #{key}:#{property}"
return unless value?
model[property] = value
_store: (key, model, property)->
_storeProperty: (key, model, property)->
value = JSON.stringify model[property]
@storage.setItem "#{key}:#{property}", value
logger.verbose "stored #{value} into #{key}:#{property}"
@store "#{key}:#{property}", value
+3 -3
View File
@@ -28,15 +28,15 @@ describe 'inventory_parser.coffee', ->
result.toList().should.eql ['wool']
it 'can parse a single item with quantity', ->
result = parser.parse '4 wool'
result = parser.parse '4.wool'
result.toList().should.eql [[4, 'wool']]
it 'can parse multiple mixed-type items', ->
result = parser.parse '4 Wool\n10 String\nBoat\n\n'
result = parser.parse '4.Wool:10.String:Boat'
result.toList().should.eql ['boat', [10, 'string'], [4, 'wool']]
it 're-uses the given inventory object', ->
inventory = new Inventory
inventory.add 'string', 8
result = parser.parse '4 Wool', inventory
result = parser.parse '4.Wool', inventory
result.toList().should.eql [[8, 'string'], [4, 'wool']]