Merge branch 'andrewminer/new-model-objects'

This commit is contained in:
Andrew Miner
2017-07-23 20:07:59 -07:00
61 changed files with 4545 additions and 1276 deletions
+1
View File
@@ -1,4 +1,5 @@
*.log *.log
*.swp
.DS_Store .DS_Store
.env .env
.sass-cache .sass-cache
+2917
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -36,7 +36,7 @@
"body-parser": "1.17.1", "body-parser": "1.17.1",
"client-sessions": "0.8.0", "client-sessions": "0.8.0",
"cookie-parser": "1.4.3", "cookie-parser": "1.4.3",
"crafting-guide-common": ">=3.0.0 <4.0.0", "crafting-guide-common": ">=5.0.0",
"dotenv": "4.0.0", "dotenv": "4.0.0",
"express": "4.15.2", "express": "4.15.2",
"express-session": "1.15.2", "express-session": "1.15.2",
+40 -31
View File
@@ -8,77 +8,86 @@
############################################################################################################ ############################################################################################################
# Allow Node.js-style `global` in addition to `window` # Allow Node.js-style `global` in addition to `window`
if typeof(global) is 'undefined' if typeof(global) is "undefined"
window.global = window window.global = window
global._ = require '../common/underscore' global._ = require "../common/underscore"
global.$ = require 'jquery' global.$ = require "jquery"
global.c = require '../common/constants' global.c = require "../common/constants"
global.π = Math.PI global.π = Math.PI
global.ε = 0.0001 global.ε = 0.0001
global.w = require 'when' global.w = require "when"
{Logger} = require('crafting-guide-common').util {Logger} = require("crafting-guide-common").util
global.logger = new Logger global.logger = new Logger
Tracker = require './tracker' Tracker = require "./tracker"
global.tracker = new Tracker global.tracker = new Tracker
marked = require 'marked' marked = require "marked"
marked.setOptions sanitize:true marked.setOptions sanitize:true
global.Backbone = Backbone = require 'backbone' global.Backbone = Backbone = require "backbone"
Backbone.$ = $ Backbone.$ = $
######################################################################################################################## ########################################################################################################################
global.hostName = window.location.hostname global.hostName = window.location.hostname
switch global.hostName switch global.hostName
when 'prerender.crafting-guide.com' when "prerender.crafting-guide.com"
global.env = 'prerender' global.env = "prerender"
logger.level = Logger.FATAL logger.level = Logger.FATAL
apiBaseUrl = 'http://prerender.crafting-guide.com:4347' apiBaseUrl = "http://prerender.crafting-guide.com:4347"
when 'local.crafting-guide.com', 'localhost' when "local.crafting-guide.com", "localhost"
global.env = 'local' global.env = "local"
logger.level = Logger.DEBUG logger.level = Logger.DEBUG
apiBaseUrl = "http://#{global.hostName}:4347" apiBaseUrl = "http://#{global.hostName}:4347"
when 'staging.crafting-guide.com' when "staging.crafting-guide.com"
global.env = 'staging' global.env = "staging"
logger.level = Logger.VERBOSE logger.level = Logger.VERBOSE
apiBaseUrl = 'http://api-staging.crafting-guide.com' apiBaseUrl = "http://api-staging.crafting-guide.com"
when 'crafting-guide.com' when "crafting-guide.com"
global.env = 'production' global.env = "production"
logger.level = Logger.INFO logger.level = Logger.INFO
tracker.enabled = true tracker.enabled = true
apiBaseUrl = 'http://api.crafting-guide.com' apiBaseUrl = "http://api.crafting-guide.com"
else else
throw new Error "cannot determine the environment of: #{window.location.hostname}" throw new Error "cannot determine the environment of: #{window.location.hostname}"
######################################################################################################################## ########################################################################################################################
Storage = require './storage' Storage = require "./storage"
storage = new Storage storage:global.localStorage storage = new Storage storage:global.localStorage
######################################################################################################################## ########################################################################################################################
tracker.trackPageView() tracker.trackPageView()
{CraftingGuideClient} = require('crafting-guide-common').api {CraftingGuideClient} = require("crafting-guide-common").api
client = _(new CraftingGuideClient(baseUrl:apiBaseUrl)).extend Backbone.Events client = _(new CraftingGuideClient(baseUrl:apiBaseUrl)).extend Backbone.Events
client.onStatusChanged = (client, oldStatus, newStatus)-> client.onStatusChanged = (client, oldStatus, newStatus)->
logger.info "Crafting Guide server status changed from #{oldStatus} to #{newStatus}" logger.info "Crafting Guide server status changed from #{oldStatus} to #{newStatus}"
client.trigger 'change:status', client, oldStatus, newStatus client.trigger "change:status", client, oldStatus, newStatus
client.trigger 'change', client client.trigger "change", client
client.startMonitoringStatus() client.startMonitoringStatus()
######################################################################################################################## ########################################################################################################################
SiteController = require './site/site_controller' {http, ModPackStore, ItemDetailStore} = require("crafting-guide-common").api
global.site = site = new SiteController client:client, storage:storage storeOptions = http:http, baseUrl:"#{location.protocol}//#{location.hostname}:#{location.port}"
site.render() global.stores =
site.loadDefaultModPack() modPack: new ModPackStore storeOptions
site.loadCurrentUser() itemDetail: new ItemDetailStore storeOptions
Backbone.history.start pushState:true ########################################################################################################################
logger.info -> "CraftingGuide is ready"
global.stores.modPack.load c.modPacks.default
.then (modPack)->
SiteController = require "./site/site_controller"
global.site = site = new SiteController client:client, storage:storage, modPack:modPack
site.render()
site.loadCurrentUser()
Backbone.history.start pushState:true
logger.info -> "CraftingGuide is ready"
+75 -30
View File
@@ -5,45 +5,90 @@
# All rights reserved. # All rights reserved.
# #
CraftingGuideCommon = require "crafting-guide-common" {Inventory} = require("crafting-guide-common").models
{Observable} = require("crafting-guide-common").util
{BaseModel} = CraftingGuideCommon.deprecated {PlanBuilder} = require("crafting-guide-common").crafting
{Craftsman} = CraftingGuideCommon.deprecated.crafting {ResourcesEvaluator} = require("crafting-guide-common").crafting
{Inventory} = CraftingGuideCommon.deprecated.game {StepsEvaluator} = require("crafting-guide-common").crafting
{ModPack} = CraftingGuideCommon.deprecated.game
######################################################################################################################## ########################################################################################################################
module.exports = class CraftPage extends BaseModel module.exports = class CraftPage extends Observable
constructor: (attributes={}, options={})-> constructor: (attributes={})->
if not attributes.modPack then throw new Error 'attributes.modPack is required' super
attributes.params ?= null
attributes.craftsman ?= new Craftsman attributes.modPack
super attributes, options
@modPack.on c.event.change, => @_consumeParams() @muted -> @modPack = attributes.modPack
@on c.event.change + ':params', => @_consumeParams()
@craftsman.on c.event.change + ':stage', => @trigger c.event.change, this @_currentPlan = null
@craftsman.on c.event.change + ':complete', => @trigger c.event.change, this @_have = new Inventory
@_planBuilder = new PlanBuilder new StepsEvaluator
@_want = new Inventory
@_consumeParams attributes.params
@_have.on Observable::ANY, this, "_onHaveChanged"
@_want.on Observable::ANY, this, "_onWantChanged"
# Properties ###################################################################################
Object.defineProperties @prototype,
currentPlan:
get: -> return @_currentPlan
set: -> throw new Error "currentPlan cannot be assigned"
have:
get: -> return @_have
set: -> throw new "have cannot be assigned"
isDirty:
get: -> return @_isDirty
set: -> throw new Error "isDirty cannot be assigned"
isOutdated:
get: -> return @currentPlan? and @isDirty
set: -> throw new Error "isOutdated cannot be assigned"
modPack:
get: -> return @_modPack
set: (modPack)->
if @_modPack? then throw new Error "modPack cannot be reassigned"
if not modPack? then throw new Error "modPack is required"
@_modPack = modPack
planBuilder:
get: -> return @_planBuilder
set: -> throw new Error "planBuilder cannot be assigned"
want:
get: -> return @_want
set: -> throw new Error "want cannot be assigned"
# Public Methods ###############################################################################
createPlan: ->
newPlan = @_planBuilder.createPlan @_want, @_have
@triggerPropertyChange "currentPlan", @_currentPlan, newPlan, ->
@_currentPlan = newPlan
@triggerPropertyChange "isDirty", @_isDirty, false
# Private Methods ############################################################################## # Private Methods ##############################################################################
_consumeParams: -> _consumeParams: (params)->
return unless @params? return unless params?.inventoryText?
@craftsman.want.clear() newWant = Inventory.fromUrlString params.inventoryText, @modPack
if not @params.inventoryText? @_want.clear()
@params = null
else
inventory = new Inventory
inventory.parse @params.inventoryText
inventory.each (stack)=> for itemId, stack of newWant.stacks
item = @modPack.findItem stack.itemSlug, enableAsNeeded:true continue unless stack.item.isCraftable
return unless item? and item.isCraftable @_want.add stack.item, stack.quantity
@craftsman.want.add stack.itemSlug, stack.quantity _onHaveChanged: ->
inventory.remove stack.itemSlug @triggerPropertyChange "isDirty", @_isDirty, true
if inventory.isEmpty then @params = null _onWantChanged: ->
@triggerPropertyChange "isDirty", @_isDirty, true, ->
@_isDirty = true
if @want.isEmpty then @triggerPropertyChange "currentPlan", @_currentPlan, null
@@ -0,0 +1,62 @@
#
# Crafting Guide - item_display.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
_ = require "../../../common/underscore"
c = require "../../../common/constants"
{Inventory} = require("crafting-guide-common").models
########################################################################################################################
module.exports = class ItemDisplay
constructor: (item)->
@item = item
# Properties ###################################################################################
Object.defineProperties @prototype,
craftingUrl:
get: ->
inventory = new Inventory
inventory.add @item
c.url.crafting inventoryText:inventory.toUrlString()
iconUrl:
get: -> return c.url.itemIcon this
set: -> throw new Error "iconUrl cannot be assigned"
item:
get: -> return @_item
set: (item)->
if @_item? then throw new Error "item cannot be re-assigned"
if not item? then throw new Error "item is required"
@_item = item
itemSlug:
get: -> return _.slugify @name
set: -> throw new Error "slug cannot be assigned"
mod:
get: -> return @_item.mod
set: -> throw new Error "mod cannot be assigned"
modId:
get: -> return @_item.mod.id
set: -> throw new Error "modId cannot be assigned"
modUrl:
get: -> return c.url.mod modId:@item.mod.id
set: -> throw new Error "modUrl cannot be assigned"
name:
get: -> return @item.displayName
set: -> throw new Error "name cannot be assigned"
url:
get: -> return c.url.item this
set: -> throw new Error "url cannot be assigned"
+71 -33
View File
@@ -5,53 +5,91 @@
# All rights reserved. # All rights reserved.
# #
{BaseModel} = require("crafting-guide-common").deprecated {Item} = require("crafting-guide-common").models
ItemDisplay = require "./item_display"
{Observable} = require("crafting-guide-common").util
######################################################################################################################## ########################################################################################################################
module.exports = class ItemPage extends BaseModel module.exports = class ItemPage extends Observable
constructor: (attributes={}, options={})-> constructor: (item)->
if not attributes.modPack? then throw new Error 'attributes.modPack is required' if item.constructor isnt Item then throw new Error "item must be an Item instance"
attributes.item ?= null @item = item
super attributes, options super
# Properties ###################################################################################
Object.defineProperties @prototype,
item:
get: -> return @_item
set: (item)->
if @_item? then throw new Error "item cannot be reassigned"
if not item? then throw new Error "item is required"
if @_item? then @_item.off Observable::ANY, this
@_item = item
@_item.on Observable::ANY, this, "_onItemChanged"
itemDisplay:
get: -> return @_itemDisplay ?= new ItemDisplay @item
mod:
get: -> return @_item.mod
set: -> throw new Error "mod cannot be assigned"
modPack:
get: -> return @mod.modPack
set: -> throw new Error "modPack cannot be assigned"
# Property Methods ############################################################################# # Property Methods #############################################################################
findComponentInItems: -> findComponentInItems: ->
return @_findRecipesMatching (recipe)=> recipe.requires @item.slug return @_findItemsWithMatchingRecipes (recipe)=>
recipe.computeQuantityRequired @item
findSimilarItems: ->
return null unless @item?.modVersion?
result = []
@item.modVersion.eachItemInGroup @item.group, (item)=>
result.push item
return null unless result.length > 0
return result
findRecipes: -> findRecipes: ->
return @modPack.findRecipes @item?.slug, [], alwaysFromOwningMod:true return (recipe for recipeId, recipe of @item.recipes)
findToolForRecipes: -> findSimilarItems: ->
return @_findRecipesMatching (recipe)=> recipe.requiresTool @item.slug group = @mod.itemGroups[@item.groupName]
return unless group?
return null unless group.length > 0
return group
findToolForItems: ->
return @_findItemsWithMatchingRecipes (recipe)=>
return recipe.tools[@item.id]?
loadDetails: ->
stores.itemDetail.loadDetailFor @item
.catch (error)=>
if error.message.indexOf("404") is -1
logger.error "Could not load details for item #{@item.id}: #{error.message}"
else
logger.info "Item #{@item.id} has no details file."
# Private Methods ############################################################################## # Private Methods ##############################################################################
_findRecipesMatching: (isAcceptable)-> _findItemsWithMatchingRecipes: (isMatching)->
return null unless @item?
result = {} result = {}
@modPack.eachMod (mod)=>
mod.eachRecipe (recipe)=>
if isAcceptable recipe
for outputStack in recipe.output
continue if recipe.isPassThroughFor outputStack.itemSlug
outputItem = @modPack.findItem outputStack.itemSlug, includeDisabled:true
result[outputItem.slug] = outputItem
result = _.values result for modId, mod of @modPack.mods
return null unless result.length > 0 for itemId, item of mod.items
for recipeId, recipe of item.recipes
if isMatching(recipe)
result[item.id] = item
result = (item for itemId, item of result)
result.sort (a, b)->
if not a?.displayName? and not b?.displayName? then return 0
if not b?.displayName? then return +1
if not a?.displayName? then return +1
return a.displayName.localeCompare b.displayName
return result
_onItemChanged: ->
@trigger Observable::CHANGE
return result.sort (a, b)-> a.compareTo b
+44 -43
View File
@@ -5,52 +5,49 @@
# All rights reserved. # All rights reserved.
# #
{BaseModel} = require('crafting-guide-common').deprecated {Observable} = require("crafting-guide-common").util
{ItemSlug} = require('crafting-guide-common').deprecated.game
######################################################################################################################## ########################################################################################################################
module.exports = class ItemSelector extends BaseModel module.exports = class ItemSelector extends Observable
constructor: (attributes={}, options={})-> constructor: (modPack, options={})->
if not options.modPack? then throw new Error 'options.modPack is required' super
options.isAcceptable ?= (item)-> return true # accept everything by default
super attributes, options
@_isAcceptable = options.isAcceptable @_isAcceptable = options.isAcceptable or (item)-> return true # accept everything by default
@_maxResults = 100 @_maxResults = 100
@_minHintLength = 3 @_minHintLength = 3
@_modPack = options.modPack
@_results = [] @_results = []
@modPack = modPack
# Property Methods ############################################################################# # Property Methods #############################################################################
Object.defineProperties @prototype, Object.defineProperties @prototype,
hint: hint:
get: -> get: -> return @_hint
return @_hint set: (hint)->
@triggerPropertyChange "hint", @_hint, hint, ->
@_hint = hint?.toLowerCase()
@_refreshResults()
set: (newHint)-> modPack:
oldHint = @_hint get: -> return @_modPack
return if newHint is oldHint set: (modPack)->
if not modPack? then throw new Error "modPack is required"
@_hint = newHint.toLowerCase() if @_modPack? then throw new Error "modPack cannot be reassigned"
@_modPack = modPack
@trigger c.event.change + ':hint', this, oldHint, newHint
@_refreshResults()
@trigger c.event.change, this
results: results:
get: -> get: -> return @_results
return @_results
# Private Methods ############################################################################## # Private Methods ##############################################################################
_computeScore: (name, itemSlug)-> _computeScore: (item)->
hintIndex = 0 hintIndex = 0
hintLetter = @_hint[hintIndex] hintLetter = @_hint[hintIndex]
name = name.toLowerCase() name = item.displayName.toLowerCase()
nextScore = 1 nextScore = 1
totalScore = 0 totalScore = 0
@@ -60,8 +57,6 @@ module.exports = class ItemSelector extends BaseModel
nextScore += 1 nextScore += 1
hintIndex += 1 hintIndex += 1
if hintIndex is @_hint.length if hintIndex is @_hint.length
item = @_modPack.findItem itemSlug
return 0 unless item?
return 0 unless @_isAcceptable item return 0 unless @_isAcceptable item
break break
@@ -70,34 +65,40 @@ module.exports = class ItemSelector extends BaseModel
nextScore = 1 nextScore = 1
return 0 if hintIndex < @_hint.length return 0 if hintIndex < @_hint.length
totalScore *= @_hint.length / name.length
return totalScore return totalScore
_refreshResults: -> _refreshResults: ->
oldResults = @_results
scoredItems = [] scoredItems = []
count = 0 count = 0
logger.verbose => "Looking for items which match: #{@_hint}"
if @_hint.length >= @_minHintLength if @_hint.length >= @_minHintLength
@_modPack.eachMod (mod)=> for modId, mod of @_modPack.mods
return if count >= @_maxResults return if count >= @_maxResults
return unless mod.enabled return unless mod.isEnabled
mod.eachName (name, itemSlug)=> for itemId, item of mod.items
return if scoredItems.length >= @_maxResults score = @_computeScore item
return unless itemSlug.isQualified if score > 0
scoredItems.push score:score, item:item
score = @_computeScore name, itemSlug
if score >= @_hint.length
scoredItems.push score:score, itemSlug:itemSlug
scoredItems.sort (a, b)-> scoredItems.sort (a, b)->
if a.score isnt b.score if a.score isnt b.score
return if a.score > b.score then -1 else +1 return if a.score > b.score then -1 else +1
return ItemSlug.compare a.itemSlug, b.itemSlug
newResults = (e.itemSlug for e in scoredItems) nameA = a.item.displayName
@_results = newResults nameB = b.item.displayName
@trigger c.event.change + ':results', this, oldResults, newResults if nameA.length isnt nameB.length
return if nameA.length < nameB.length then -1 else +1
if nameA isnt nameB
return if nameA < nameB then -1 else +1
return 0
@_results = []
for element in scoredItems
@_results.push element.item
break if @_results.length >= @_maxResults
@trigger c.event.change + ':results', this
@@ -5,26 +5,22 @@
# All rights reserved. # All rights reserved.
# #
{BaseModel} = require('crafting-guide-common').deprecated {Observable} = require("crafting-guide-common").util
MarkdownImage = require './markdown_image' MarkdownImage = require './markdown_image'
######################################################################################################################## ########################################################################################################################
module.exports = class MarkdownImageList extends BaseModel module.exports = class MarkdownImageList extends Observable
constructor: (attributes={}, options={})-> constructor: (options={})->
attributes.imageBase ?= '' super
attributes.markdownText ?= null
super attributes, options
@client = options.client @_images = []
@_images = {} @muted =>
@client = options.client
@imageBase = options.imageBase
@markdownText = options.markdownText
@on c.event.change + ':imageBase', =>
for fileName, image of @_images
image.path = @imageBase
@on c.event.change + ':markdownText', => @_analyzeMarkdownText()
@_analyzeMarkdownText() @_analyzeMarkdownText()
# Public Methods ############################################################################### # Public Methods ###############################################################################
@@ -46,22 +42,43 @@ module.exports = class MarkdownImageList extends BaseModel
# Property Methods ############################################################################# # Property Methods #############################################################################
getAll: ->
fileNames = (fileName for fileName, image of @_images).sort()
result = []
for fileName in fileNames
result.push @_images[fileName]
return result
isValid: ->
for fileName, image of @_images
return false unless image.valid
return true
Object.defineProperties @prototype, Object.defineProperties @prototype,
all: {get:@prototype.getAll}
valid: {get:@prototype.isValid} all:
get: ->
fileNames = (fileName for fileName, image of @_images).sort()
result = []
for fileName in fileNames
result.push @_images[fileName]
return result
client:
get: -> return @_client
set: (client)->
if not client? then throw new Error "client is required"
@_client = client
imageBase: ->
get: -> return @_imageBase
set: (imageBase)->
@triggerPropertyChange "imageBase", @_imageBase, imageBase, ->
@_imageBase = imageBase
for fileName, image of @_images
image.path = @imageBase
markdownText:
get: -> return @_markdownText
set: (markdownText)->
@triggerPropertyChange "markdownText", @_markdownText, markdownText, ->
@_markdownText = markdownText
@_analyzeMarkdownText()
valid:
get: ->
for fileName, image of @_images
return false unless image.valid
return true
# Private Methods ############################################################################## # Private Methods ##############################################################################
@@ -79,8 +96,8 @@ module.exports = class MarkdownImageList extends BaseModel
image = @_images[fileName] image = @_images[fileName]
if not image? if not image?
image = new MarkdownImage {fileName:fileName, path:@imageBase}, {client:@client} image = new MarkdownImage {fileName:fileName, path:@imageBase}, {client:@client}
@listenTo image, c.event.change, => @trigger c.event.change, this image.on Observable::CHANGE, this, "_onImageChanged"
@trigger c.event.add, this, image @trigger Observable::ADD, image
changed = true changed = true
newImages[fileName] = image newImages[fileName] = image
@@ -92,4 +109,7 @@ module.exports = class MarkdownImageList extends BaseModel
if changed if changed
@_images = newImages @_images = newImages
@trigger c.event.change, this @trigger Observable::CHANGE
_onImageChanged: ->
@trigger Observable::CHANGE
@@ -16,7 +16,7 @@ list = null
describe 'markdown_image_list.coffee', -> describe 'markdown_image_list.coffee', ->
beforeEach -> beforeEach ->
list = new MarkdownImageList {}, client:{fetchFile:sinon.stub().returns(w.promise(->))} list = new MarkdownImageList client:{fetchFile:sinon.stub().returns(w.promise(->))}
describe '_analyzeMarkdownText', -> describe '_analyzeMarkdownText', ->
@@ -0,0 +1,53 @@
#
# Crafting Guide - multiblock_display.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
{Inventory} = require("crafting-guide-common").models
{Observable} = require("crafting-guide-common").util
########################################################################################################################
module.exports = class MultiblockDisplay extends Observable
constructor: (recipe)->
@_layerInventories = []
@recipe = recipe
# Properties ###################################################################################
Object.defineProperties @prototype,
recipe:
get: -> return @_recipe
set: (recipe)->
if not recipe? then throw new Error "recipe is required"
if @_recipe? then throw new Error "recipe cannot be reassigned"
@_recipe = recipe
# Public Methods ###############################################################################
getInventory: (z)->
if not z?
return @_fullInventory ?= @_createFullInventory()
else
return @_layerInventories[z] ?= @_addLayerInventory z
# Private Methods ##############################################################################
_addLayerInventory: (z, inventory=null)->
inventory ?= new Inventory
for x in [0..@recipe.width]
for y in [0..@recipe.height]
stack = @recipe.getInputAt x, y, z
continue unless stack?
inventory.add stack.item, stack.quantity
return inventory
_createFullInventory: (inventory=null)->
inventory ?= new Inventory()
for z in [0..@recipe.depth]
@_addLayerInventory z, inventory
return inventory
@@ -0,0 +1,134 @@
#
# Crafting Guide - recipe_display.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
_ = require "../../../common/underscore"
c = require "../../../common/constants"
{Inventory} = require("crafting-guide-common").models
{Observable} = require("crafting-guide-common").util
########################################################################################################################
module.exports = class RecipeDisplay extends Observable
constructor: (options={})->
if not options.recipe? then throw new Error "options.recipe is required"
super
@_layerInventories = []
@multiplier = options.multiplier or 1
@recipe = options.recipe
@showInputInventory = if options.showInputInventory then options.showInputInventory or false
@showOutputInventory = if options.showOutputInventory then options.showOutputInventory or false
@showOutputSlot = if options.showOutputSlot then options.showOutputSlot or false
# Class Methods ################################################################################
@::RECIPE_TYPE =
CRAFTING_TABLE: "crafting_table"
MULTIBLOCK: "multiblock"
@::ALL_RECIPE_TYPES = (value for key, value of @::RECIPE_TYPE)
# Properties ###################################################################################
Object.defineProperties @prototype,
depth:
get: -> return @recipe.depth
set: -> throw new Error "depth cannot be assigned"
height:
get: -> return @recipe.height
set: -> throw new Error "height cannot be assigned"
multiplier:
get: -> return @_multiplier
set: (multiplier)->
if not _.isNumber(multiplier) then multiplier = 1
@triggerPropertyChange "multiplier", @_multiplier, multiplier
recipe:
get: -> return @_recipe
set: (recipe)->
return if recipe is @_recipe
if not recipe? then throw new Error "recipe is required"
if @_recipe? then throw new Error "recipe cannot be reassigned"
@_recipe = recipe
@_computeType()
showInputInventory:
get: -> return @_showInputInventory
set: (showInputInventory)->
@triggerPropertyChange "showInputInventory", @_showInputInventory, !!showInputInventory
showOutputInventory:
get: -> return @_showOutputInventory
set: (showOutputInventory)->
@triggerPropertyChange "showOutputInventory", @_showOutputInventory, !!showOutputInventory
showOutputSlot:
get: -> return @_showOutputSlot
set: (showOutputSlot)->
@triggerPropertyChange "showOutputSlot", @_showOutputSlot, !!showOutputSlot
tools:
get: -> return @recipe.tools
set: -> throw new Error "tools cannot be assigned"
type:
get: -> return @_type
set: -> throw new Error "type cannot be assigned"
width:
get: -> return @recipe.width
set: -> throw new Error "width cannot be assigned"
# Public Methods ###############################################################################
getInputAt: (x, y, z)->
return @recipe.getInputAt x, y, z
getInventory: (z)->
if not z?
return @_fullInventory ?= @_createFullInventory()
else
return @_layerInventories[z] ?= @_addLayerInventory z
getOutputInventory: ->
if not @_outputInventory?
@_outputInventory = new Inventory
for stack in @recipe.allProducts
@_outputInventory.add stack.item, stack.quantity
return @_outputInventory
# Private Methods ##############################################################################
_addLayerInventory: (z, inventory=null)->
inventory ?= new Inventory
for x in [0..@recipe.width]
for y in [0..@recipe.height]
stack = @recipe.getInputAt x, y, z
continue unless stack?
inventory.add stack.item, stack.quantity * @multiplier
return inventory
_computeType: ->
if not @recipe?
type = null
else if @recipe.depth > 1
type = @RECIPE_TYPE.MULTIBLOCK
else
type = @RECIPE_TYPE.CRAFTING_TABLE
@triggerPropertyChange "type", @_type, type
_createFullInventory: (inventory=null)->
inventory ?= new Inventory()
for z in [0..@recipe.depth]
@_addLayerInventory z, inventory
return inventory
@@ -1,56 +0,0 @@
#
# Crafting Guide - mod_pack_store.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
ModPackJsonParser = require "../parsing/mod_pack_json_parser"
w = require "when"
########################################################################################################################
module.exports = class ModPackStore
constructor: ->
@_data = {}
@_loading = {}
@_parser = new ModPackJsonParser
# Class Methods ################################################################################
Object.defineProperties ModPackStore,
instance:
get: ->
@_instance ?= new ModPackStore
return @_instance
set: ->
throw new Error "cannot assign instance"
# Public Methods ###############################################################################
get: (modPackId)->
return @_data[modPackId]
load: (modPackId)->
if not @_loading[modPackId]?
@_loading[modPackId] = w.promise (resolve, reject)->
url = c.url.modPackArchive modPackId:modPackId
onError = (xhr, status, message)=>
logger.error "failed to load mod pack #{modPackId}: #{status}#{message}"
reject new Error message
onSuccess = (data, status, xhr)=>
logger.info "laoded mod pack: #{modPackId}"
try
@_parser.reset()
modPack = @_parser.parse data, url
@_data[modPack.id] = modPack
resolve modPack
catch error
reject error
$.ajax dataType: "text", error: onError, success: onSuccess, url: url
return @_loading[modPackId]
+15 -12
View File
@@ -5,7 +5,8 @@
# All rights reserved. # All rights reserved.
# #
templates = require './templates' {Observable} = require("crafting-guide-common").util
templates = require './templates'
######################################################################################################################## ########################################################################################################################
@@ -84,9 +85,6 @@ module.exports = class BaseController extends Backbone.View
onDidModelChange: -> onDidModelChange: ->
@tryRefresh() @tryRefresh()
onDidModelSync: ->
@tryRefresh()
onWillRender: -> # do nothing onWillRender: -> # do nothing
onDidRender: -> # do nothing onDidRender: -> # do nothing
@@ -96,11 +94,12 @@ module.exports = class BaseController extends Backbone.View
onDidShow: -> # do nothing onDidShow: -> # do nothing
onWillChangeModel: (oldModel, newModel)-> onWillChangeModel: (oldModel, newModel)->
if oldModel?.on? if oldModel?.isObservable
@stopListening oldModel oldModel.off target:this
if newModel?.on?
@listenTo newModel, 'sync', (e)=> @onDidModelSync e if newModel?.isObservable
@listenTo newModel, 'change', (e)=> @onDidModelChange e newModel.on Observable::ANY, this, "onDidModelChange"
return newModel return newModel
# Property Methods ############################################################################# # Property Methods #############################################################################
@@ -113,7 +112,7 @@ module.exports = class BaseController extends Backbone.View
newModel = @onWillChangeModel @_model, newModel newModel = @onWillChangeModel @_model, newModel
@_model = newModel @_model = newModel
@tryRefresh() @onDidModelChange()
rendered: rendered:
get: -> @_rendered get: -> @_rendered
@@ -147,9 +146,13 @@ module.exports = class BaseController extends Backbone.View
@$el.append $renderedEl.children() @$el.append $renderedEl.children()
@$el.addClass $renderedEl.attr 'class' @$el.addClass $renderedEl.attr 'class'
@$el.data $renderedEl.data()
@delegateEvents()
elementData = $renderedEl.data()
elementData.controller = this
elementData.model = data
@$el.data elementData
@delegateEvents()
@_rendered = true @_rendered = true
@onDidRender() @onDidRender()
@@ -28,7 +28,6 @@ module.exports = class BrowsePageController extends PageController
@_tileControllers = [] @_tileControllers = []
@_client.on c.event.change, => @tryRefresh() @_client.on c.event.change, => @tryRefresh()
@_modPack.on c.event.change, => @tryRefresh()
# Property Methods ############################################################################# # Property Methods #############################################################################
@@ -81,7 +80,7 @@ module.exports = class BrowsePageController extends PageController
_refreshModTiles: -> _refreshModTiles: ->
index = 0 index = 0
mods = @_modPack.getAllMods() mods = (mod for modId, mod of @_modPack.mods)
for mod in mods for mod in mods
controller = @_tileControllers[index] controller = @_tileControllers[index]
if not controller if not controller
@@ -29,12 +29,12 @@ module.exports = class ModTileController extends BaseController
super super
refresh: -> refresh: ->
@$link.attr 'href', c.url.mod modSlug:@model.slug @$link.attr 'href', c.url.mod modId:@model.id
@$logoImage.attr 'src', c.url.modIcon modSlug:@model.slug @$logoImage.attr 'src', c.url.modIcon modId:@model.id
@$title.text @model.name @$title.text @model.displayName
@$description.text @model.description @$description.text @model.description
if @model.enabled if @model.isEnabled
@$el.removeClass 'disabled' @$el.removeClass 'disabled'
else else
@$el.addClass 'disabled' @$el.addClass 'disabled'
@@ -5,39 +5,47 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
SlotController = require '../slot/slot_controller' {Recipe} = require("crafting-guide-common").models
SlotController = require "../slot/slot_controller"
######################################################################################################################## ########################################################################################################################
module.exports = class CraftingGridController extends BaseController module.exports = class CraftingGridController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error 'options.router 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"
options.templateName = 'common/crafting_grid'
super options super options
@_imageLoader = options.imageLoader @_imageLoader = options.imageLoader
@_modPack = options.modPack @_modPack = options.modPack
@_router = options.router @_router = options.router
@_modPack.on c.event.change, => @tryRefresh()
# BaseController Methods ####################################################################### # BaseController Methods #######################################################################
onWillChangeModel: (oldModel, newModel)->
if newModel? and (newModel.constructor isnt Recipe) then throw new Error "options.model must be a Recipe"
super
onDidRender: -> onDidRender: ->
@_slotControllers = [] @_slotControllers = []
for el in @$('.view__slot') for el in @$(".view__slot")
controller = new SlotController el:el, imageLoader:@_imageLoader, modPack:@_modPack, router:@_router controller = new SlotController el:el, imageLoader:@_imageLoader, modPack:@_modPack, router:@_router
controller.render() controller.render()
@_slotControllers.push controller @_slotControllers.push controller
super super
refresh: -> refresh: ->
for controller, index in @_slotControllers index = 0
controller.model = @model?.getStackAtSlot(index) 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 super
@@ -47,8 +47,6 @@ module.exports = class InventoryController extends BaseController
@_stackControllers = [] @_stackControllers = []
@listenTo @_modPack, c.event.change, => @tryRefresh()
# Event Methods ################################################################################ # Event Methods ################################################################################
onClearButtonClicked: -> onClearButtonClicked: ->
@@ -61,31 +59,33 @@ module.exports = class InventoryController extends BaseController
@trigger c.event.change, this @trigger c.event.change, this
onFirstButtonClicked: (stackController)-> onFirstButtonClicked: (stackController)->
tracker.trackEvent @_trackingContext, 'remove-from', "#{stackController?.model?.itemSlug}" item = stackController.model?.item
@trigger c.event.button.first, this, stackController?.model?.itemSlug tracker.trackEvent @_trackingContext, 'remove-from', item.id
@trigger c.event.button.first, this, item
onItemSelectorButtonClicked: -> onItemSelectorButtonClicked: ->
return unless @model? return unless @model?
tracker.trackEvent @_trackingContext, 'launch-add-to' tracker.trackEvent @_trackingContext, 'launch-add-to'
@_selector.launch() @_selector.launch()
.then (itemSlug)=> .then (item)=>
if not itemSlug? if not item?
tracker.trackEvent @_trackingContext, 'cancel-add-to' tracker.trackEvent @_trackingContext, 'cancel-add-to'
return return
tracker.trackEvent @_trackingContext, 'complete-add-to', "#{itemSlug}" tracker.trackEvent @_trackingContext, 'complete-add-to', "#{item.id}"
@model.add itemSlug, 1 @model.add item, 1
@trigger c.event.add, this, itemSlug @trigger c.event.add, this, item.id
@trigger c.event.change, this @trigger c.event.change, this
onSecondButtonClicked: (stackController)-> onSecondButtonClicked: (stackController)->
itemId = stackController.model?.item.id
@trigger c.event.button.second, this, stackController?.model?.itemSlug @trigger c.event.button.second, this, stackController?.model?.itemSlug
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@_selector = @addChild ItemSelectorController, null, isAcceptable: @_isAcceptable, modPack: @_modPack @_selector = @addChild ItemSelectorController, null, isAcceptable:@_isAcceptable, modPack:@_modPack
@$clearButton = @$('.button.clear') @$clearButton = @$('.button.clear')
@$emptyPlaceholder = @$('.empty_placeholder') @$emptyPlaceholder = @$('.empty_placeholder')
@@ -131,7 +131,7 @@ module.exports = class InventoryController extends BaseController
index = 0 index = 0
if @model? if @model?
@model.each (stack)=> for itemId, stack of @model.stacks
controller = @_stackControllers[index] controller = @_stackControllers[index]
if not controller? if not controller?
controller = new StackController controller = new StackController
@@ -153,7 +153,9 @@ module.exports = class InventoryController extends BaseController
@$itemContainer.append controller.$el @$itemContainer.append controller.$el
else else
controller.model = stack controller.model = stack
index += 1 index += 1
while @_stackControllers.length > index while @_stackControllers.length > index
@_stackControllers.pop().remove() @_stackControllers.pop().remove()
@@ -5,39 +5,37 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../../base_controller' BaseController = require "../../../base_controller"
ItemDisplay = require "../../../../models/site/item_display"
######################################################################################################################## ########################################################################################################################
module.exports = class ItemTileController extends BaseController module.exports = class ItemTileController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required' if not options.imageLoader? then throw new Error "options.imageLoader is required"
if not options.model? then throw new Error 'options.model is required' if not options.model? then throw new Error "options.model is required"
if not options.modPack? then throw new Error 'options.modPack is required' options.templateName = "common/item_group/item_tile"
options.templateName = 'common/item_group/item_tile'
super options super options
@_imageLoader = options.imageLoader @_imageLoader = options.imageLoader
@_modPack = options.modPack @_display = new ItemDisplay @model
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@$icon = @$('img') @$icon = @$("img")
@$name = @$('.itemName') @$name = @$(".itemName")
@$nameLink = @$('a') @$nameLink = @$("a")
super super
refresh: -> refresh: ->
display = @_modPack.findItemDisplay @model.slug @_imageLoader.load @_display.iconUrl, @$icon
@$name.html @_display.name
@_imageLoader.load display.iconUrl, @$icon @$nameLink.attr "href", @_display.url
@$name.html display.itemName
@$nameLink.attr 'href', display.itemUrl
# Backbone.View Overrides ###################################################################### # Backbone.View Overrides ######################################################################
events: -> events: ->
return _.extend super, return _.extend super,
'click a': 'routeLinkClick' "click a": "routeLinkClick"
@@ -5,58 +5,63 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../../base_controller' BaseController = require "../../../base_controller"
ItemDisplay = require "../../../../models/site/item_display"
######################################################################################################################## ########################################################################################################################
module.exports = class ElementController extends BaseController module.exports = class ElementController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.model? then throw new Error 'options.model is required' if not options.model? then throw new Error "options.model is required"
options.onClicked ?= (controller)-> # do nothing options.templateName = "common/item_selector/element"
options.onSelected ?= (controller)-> # do nothing
options.templateName = 'common/item_selector/element'
options.useAnimations = false options.useAnimations = false
super options super options
@onClicked = options.onClicked @onClicked = options.onClicked or (controller)-> # do nothing
@onSelected = options.onSelected @onSelected = options.onSelected or (controller)-> # do nothing
# Property Methods ############################################################################# # 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, 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 ##################################################################### # BaseController Overrides #####################################################################
onDidModelChange: ->
@_display = null
super
onDidRender: -> onDidRender: ->
@$icon = @$('img') @$icon = @$("img")
@$name = @$('.name') @$name = @$(".name")
@$modName = @$('.modName') @$modName = @$(".modName")
super super
refresh: -> refresh: ->
@$icon.attr 'src', @model.iconUrl @$icon.attr "src", @display.iconUrl
@$name.html @model.itemName @$name.html @model.displayName
@$modName.html @model.modName @$modName.html @model.mod.displayName
if @_selected if @_selected
@$el.addClass 'selected' @$el.addClass "selected"
else else
@$el.removeClass 'selected' @$el.removeClass "selected"
super super
@@ -64,15 +69,15 @@ module.exports = class ElementController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'click': '_onClick' "click": "_onClick"
'mouseenter': '_onMouseEnter' "mouseenter": "_onMouseEnter"
# Private Methods ############################################################################## # Private Methods ##############################################################################
_onClick: (event)-> _onClick: (event)->
event.preventDefault()
@onClicked this @onClicked this
return false
_onMouseEnter: (event)-> _onMouseEnter: (event)->
event.preventDefault()
@onSelected this @onSelected this
return false
@@ -5,21 +5,22 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
ItemSelector = require '../../../models/site/item_selector' ItemDisplay = require "../../../models/site/item_display"
ElementController = require './element/element_controller' ItemSelector = require "../../../models/site/item_selector"
ElementController = require "./element/element_controller"
w = require "when" w = require "when"
######################################################################################################################## ########################################################################################################################
module.exports = class ItemSelectorController extends BaseController module.exports = class ItemSelectorController extends BaseController
constructor: (options)-> constructor: (options={})->
if not options.modPack? then throw new Error 'options.modPack is required' if not options.modPack? then throw new Error "options.modPack is required"
options.isAcceptable ?= null 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.onChoseItem ?= (item)-> # do nothing
options.templateName = 'common/item_selector' options.templateName = "common/item_selector"
super options super options
@_modPack = options.modPack @_modPack = options.modPack
@@ -29,25 +30,25 @@ module.exports = class ItemSelectorController extends BaseController
# Public Methods ############################################################################### # Public Methods ###############################################################################
launch: (hint='')-> launch: (hint="")->
@model.hint = hint @model.hint = hint
if @rendered then @refresh() if @rendered then @refresh()
@_disableWindowScrolling() @_disableWindowScrolling()
@$page.addClass 'blur' @$page.addClass "blur"
@$screen.append @$popup @$screen.append @$popup
@$screen.css 'display', '' @$screen.css "display", ""
@$popup.off c.event.click @$popup.off c.event.click
@$popup.on c.event.click, (event)=> @onPopupClicked(event) @$popup.on c.event.click, (event)=> @onPopupClicked(event)
@$hintField.off 'keyup input' @$hintField.off "keyup input"
@$hintField.on 'keyup', (event)=> @onHintKeyPress(event) @$hintField.on "keyup", (event)=> @onHintKeyPress(event)
@$hintField.on 'input', (event)=> @onHintChanged(event) @$hintField.on "input", (event)=> @onHintChanged(event)
@$hintField.focus() @$hintField.focus()
@$closeButton.one 'click', (event)=> @_close() @$closeButton.one "click", (event)=> @_close()
@$screen.one c.event.click, (event)=> @onScreenClicked(event) @$screen.one c.event.click, (event)=> @onScreenClicked(event)
@@ -85,17 +86,17 @@ module.exports = class ItemSelectorController extends BaseController
return false return false
onResultClicked: (controller)-> onResultClicked: (controller)->
@_session.resolve controller.model.slug @_session.resolve controller.model
@_session = null @_session = null
@_close() @_close()
return false return false
onResultSelected: (controller)-> onResultSelected: (controller)->
for c in @_elementControllers for c in @_elementControllers
c.selected = false c.isSelected = false
if controller? if controller?
controller.selected = true controller.isSelected = true
return false return false
@@ -106,14 +107,14 @@ module.exports = class ItemSelectorController extends BaseController
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@$page = $('.page') # find the shared, global page @$page = $(".page") # find the shared, global page
@$screen = $('.view__screen') # find the shared, global screen @$screen = $(".view__screen") # find the shared, global screen
@$closeButton = @$('img.close') @$closeButton = @$("img.close")
@$popup = @$('.view__item_selector_popup') @$popup = @$(".view__item_selector_popup")
@$hintField = @$('.view__item_selector_popup input') @$hintField = @$(".view__item_selector_popup input")
@$searchInput = @$('.search input') @$searchInput = @$(".search input")
@$resultsContainer = @$('.results') @$resultsContainer = @$(".results")
@$popup.detach() @$popup.detach()
super super
@@ -127,16 +128,16 @@ module.exports = class ItemSelectorController extends BaseController
_chooseSelected: -> _chooseSelected: ->
for controller in @_elementControllers for controller in @_elementControllers
if controller.selected if controller.isSelected
@onResultClicked controller @onResultClicked controller
return return
_close: -> _close: ->
@_enableWindowScrolling() @_enableWindowScrolling()
@$page.removeClass 'blur' @$page.removeClass "blur"
@$screen.css 'display', 'none' @$screen.css "display", "none"
@$popup.detach() @$popup.detach()
@model.hint = '' @model.hint = ""
if @_session if @_session
@_session.resolve null @_session.resolve null
@@ -144,28 +145,27 @@ module.exports = class ItemSelectorController extends BaseController
_disableWindowScrolling: -> _disableWindowScrolling: ->
@_windowScrollPosition = $(window).scrollTop() @_windowScrollPosition = $(window).scrollTop()
$('body').addClass('scrollDisabled').css('margin-top', -@_windowScrollPosition) $("body").addClass("scrollDisabled").css("margin-top", -@_windowScrollPosition)
_enableWindowScrolling: -> _enableWindowScrolling: ->
$('body').removeClass('scrollDisabled').css('margin-top', 0) $("body").removeClass("scrollDisabled").css("margin-top", 0)
$(window).scrollTop @_windowScrollPosition $(window).scrollTop @_windowScrollPosition
_refreshResults: -> _refreshResults: ->
index = 0 index = 0
for itemSlug in @model.results for item in @model.results
displayModel = @_modPack.findItemDisplay itemSlug
controller = @_elementControllers[index] controller = @_elementControllers[index]
if not controller? if not controller?
controller = new ElementController controller = new ElementController
model: displayModel model: item
onClicked: (c)=> @onResultClicked(c) onClicked: (c)=> @onResultClicked(c)
onSelected: (c)=> @onResultSelected(c) onSelected: (c)=> @onResultSelected(c)
controller.render show:false controller.render show:false
@_elementControllers[index] = controller @_elementControllers[index] = controller
@$resultsContainer.append controller.$el @$resultsContainer.append controller.$el
else else
controller.model = displayModel controller.model = item
controller.show() controller.show()
index += 1 index += 1
@@ -180,14 +180,17 @@ module.exports = class ItemSelectorController extends BaseController
controller = @_elementControllers[i] controller = @_elementControllers[i]
nextController = @_elementControllers[i + 1] nextController = @_elementControllers[i + 1]
if controller.selected if controller.isSelected
controller.selected = false controller.isSelected = false
nextController.selected = true nextController.isSelected = true
@_showElement nextController.$el @_showElement nextController.$el
return return
[..., controller] = @_elementControllers
controller.isSelected = false
controller = @_elementControllers[0] controller = @_elementControllers[0]
controller.selected = true controller.isSelected = true
@_showElement controller.$el @_showElement controller.$el
_selectPrevious: -> _selectPrevious: ->
@@ -197,14 +200,17 @@ module.exports = class ItemSelectorController extends BaseController
previousController = @_elementControllers[i - 1] previousController = @_elementControllers[i - 1]
controller = @_elementControllers[i] controller = @_elementControllers[i]
if controller.selected if controller.isSelected
previousController.selected = true previousController.isSelected = true
controller.selected = false controller.isSelected = false
@_showElement previousController.$el @_showElement previousController.$el
return return
controller = @_elementControllers[@_elementControllers.length - 1] controller = @_elementControllers[0]
controller.selected = true controller.isSelected = false
[..., controller] = @_elementControllers
controller.isSelected = true
@_showElement controller.$el @_showElement controller.$el
_showElement: ($el)-> _showElement: ($el)->
@@ -5,20 +5,24 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../../base_controller' _ = require "../../../../../underscore"
MarkdownImageController = require './markdown_image/markdown_image_controller' c = require "../../../../../common/constants"
MarkdownImageList = require '../../../../models/site/markdown_image_list' BaseController = require "../../../base_controller"
MarkdownImageController = require "./markdown_image/markdown_image_controller"
MarkdownImageList = require "../../../../models/site/markdown_image_list"
{Observable} = require("crafting-guide-common").util
######################################################################################################################## ########################################################################################################################
module.exports = class MarkdownImageListController extends BaseController module.exports = class MarkdownImageListController extends BaseController
_.extend this, Observable
constructor: (options={})-> constructor: (options={})->
options.model ?= new MarkdownImageList {}, {client:options.client} options.model ?= new MarkdownImageList client:options.client
options.templateName = 'common/markdown_section/markdown_image_list' options.templateName = "common/markdown_section/markdown_image_list"
super options super options
@imageBase = '' @imageBase = ""
@_valid = null @_valid = null
# Public Methods ############################################################################### # Public Methods ###############################################################################
@@ -34,30 +38,23 @@ module.exports = class MarkdownImageListController extends BaseController
# Property Methods ############################################################################# # Property Methods #############################################################################
getImageBase: ->
return @_imageBase
setImageBase: (newImageBase)->
oldImageBase = @_imageBase
return unless oldImageBase isnt newImageBase
@_imageBase = newImageBase
@trigger c.event.change + ':imageBase', this, oldImageBase, newImageBase
@trigger c.event.change, this
getMarkdownText: ->
return @model.markdownText
setMarkdownText: (markdownText)->
@model.markdownText = markdownText
getValid: ->
return @_valid
Object.defineProperties @prototype, Object.defineProperties @prototype,
imageBase: {get:@prototype.getImageBase, set:@prototype.setImageBase}
markdownText: {get:@prototype.getMarkdownText, set:@prototype.setMarkdownText} imageBase:
valid: {get:@prototype.getValid} get: -> return @_imageBase
set: (imageBase)->
@_imageBase = imageBase
@trigger c.event.change
markdownText:
get: -> return @model.markdownText
set: (markdownText)->
@model.markdownText = markdownText
@trigger c.event.change
valid:
get: -> return @_valid
set: -> throw new Error "valid cannot be assigned"
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
@@ -66,7 +63,7 @@ module.exports = class MarkdownImageListController extends BaseController
@_setValid @model.valid @_setValid @model.valid
onDidRender: -> onDidRender: ->
@$imageContainer = @$('.image_container') @$imageContainer = @$(".image_container")
super super
refresh: -> refresh: ->
@@ -90,10 +87,6 @@ module.exports = class MarkdownImageListController extends BaseController
# Private Methods ############################################################################## # Private Methods ##############################################################################
_setValid: (newValid)-> _setValid: (valid)->
oldValid = @_valid @_valid = valid
return if newValid is oldValid
@_valid = newValid
@trigger c.event.change + ':valid', this, oldValid, newValid
@trigger c.event.change @trigger c.event.change
@@ -5,27 +5,28 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
convertMarkdown = require 'marked' convertMarkdown = require "marked"
MarkdownImageListController = require './markdown_image_list/markdown_image_list_controller' ItemDisplay = require "../../../models/site/item_display"
MarkdownImageListController = require "./markdown_image_list/markdown_image_list_controller"
######################################################################################################################## ########################################################################################################################
module.exports = class MarkdownSectionController extends BaseController module.exports = class MarkdownSectionController extends BaseController
@::State = @::State =
appologizing: 'applogizing' appologizing: "applogizing"
confirming: 'confirming' confirming: "confirming"
creating: 'creating' creating: "creating"
editing: 'editing' editing: "editing"
previewing: 'previewing' previewing: "previewing"
viewing: 'viewing' viewing: "viewing"
waiting: 'waiting' waiting: "waiting"
constructor: (options={})-> constructor: (options={})->
if not options.modPack? then throw new Error 'options.modPack is required' if not options.modPack? then throw new Error "options.modPack is required"
options.model ?= null options.model ?= null
options.templateName = 'common/markdown_section' options.templateName = "common/markdown_section"
@_state = @State.waiting @_state = @State.waiting
super options super options
@@ -33,9 +34,9 @@ module.exports = class MarkdownSectionController extends BaseController
@_confirmationMessage = options.confirmationMessage @_confirmationMessage = options.confirmationMessage
@_confirmDuration = options.confirmationDuration or 5000 @_confirmDuration = options.confirmationDuration or 5000
@_enterFeedback = options.enterFeedback or -> # do nothing @_enterFeedback = options.enterFeedback or -> # do nothing
@_imageBase = options.imageBase or '' @_imageBase = options.imageBase or ""
@_modPack = options.modPack @_modPack = options.modPack
@_title = options.title or 'Description' @_title = options.title or "Description"
# @_beginEditing must be a function returning a promise which resolves when all actions necessary prior to an # @_beginEditing must be a function returning a promise which resolves when all actions necessary prior to an
# editing session have been completed (e.g., loading the latest content from a remote server). The promise must # editing session have been completed (e.g., loading the latest content from a remote server). The promise must
@@ -60,7 +61,7 @@ module.exports = class MarkdownSectionController extends BaseController
# Event Methods ################################################################################ # Event Methods ################################################################################
onCancelClicked: (event)-> onCancelClicked: (event)->
tracker.trackEvent c.tracking.category.markdown, 'cancel' tracker.trackEvent c.tracking.category.markdown, "cancel"
@model = @_originalModel @model = @_originalModel
@resetToDefaultState() @resetToDefaultState()
@@ -71,7 +72,7 @@ module.exports = class MarkdownSectionController extends BaseController
onEditClicked: (event)-> onEditClicked: (event)->
return false unless @editable return false unless @editable
tracker.trackEvent c.tracking.category.markdown, 'edit' tracker.trackEvent c.tracking.category.markdown, "edit"
@_originalModel = @model @_originalModel = @model
@state = @State.waiting @state = @State.waiting
@_beginEditing() @_beginEditing()
@@ -85,22 +86,22 @@ module.exports = class MarkdownSectionController extends BaseController
return false return false
onQuestionClicked: (event)-> onQuestionClicked: (event)->
@_enterFeedback '' @_enterFeedback ""
return false return false
onPreviewClicked: (event)-> onPreviewClicked: (event)->
tracker.trackEvent c.tracking.category.markdown, 'preview' tracker.trackEvent c.tracking.category.markdown, "preview"
@_updatePreview() @_updatePreview()
@state = @State.previewing @state = @State.previewing
return false return false
onReturnClicked: (event)-> onReturnClicked: (event)->
tracker.trackEvent c.tracking.category.markdown, 'return' tracker.trackEvent c.tracking.category.markdown, "return"
@state = @State.editing @state = @State.editing
return false return false
onSaveClicked: (event)-> onSaveClicked: (event)->
tracker.trackEvent c.tracking.category.markdown, 'save' tracker.trackEvent c.tracking.category.markdown, "save"
@state = @State.waiting @state = @State.waiting
@_endEditing() @_endEditing()
.then => .then =>
@@ -132,7 +133,7 @@ module.exports = class MarkdownSectionController extends BaseController
return unless newImageBase isnt oldImageBase return unless newImageBase isnt oldImageBase
@_imageBase = newImageBase @_imageBase = newImageBase
@trigger c.event.change + ':imageBase', this, oldImageBase, newImageBase @trigger c.event.change + ":imageBase", this, oldImageBase, newImageBase
@trigger c.event.change, this @trigger c.event.change, this
getImageFiles: -> getImageFiles: ->
@@ -147,7 +148,7 @@ module.exports = class MarkdownSectionController extends BaseController
@_state = newState @_state = newState
logger.verbose => "MarkdownSectionController.#{@cid} changed state from #{oldState} to #{newState}" logger.verbose => "MarkdownSectionController.#{@cid} changed state from #{oldState} to #{newState}"
@trigger c.event.change + ':state', this, oldState, newState @trigger c.event.change + ":state", this, oldState, newState
@tryRefresh() @tryRefresh()
Object.defineProperties @prototype, Object.defineProperties @prototype,
@@ -159,21 +160,21 @@ module.exports = class MarkdownSectionController extends BaseController
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@_imageListController = @addChild MarkdownImageListController, '.view__markdown_image_list', @_imageListController = @addChild MarkdownImageListController, ".view__markdown_image_list",
client: @_client client: @_client
imageBase: @_imageBase imageBase: @_imageBase
@on c.event.change + ':imageBase', => @_imageListController.model.imageBase = @_imageBase @on c.event.change + ":imageBase", => @_imageListController.model.imageBase = @_imageBase
@listenTo @_imageListController, c.event.change + ':valid', => @tryRefresh() @listenTo @_imageListController, c.event.change + ":valid", => @tryRefresh()
@$errorPanel = @$('.error') @$errorPanel = @$(".error")
@$errorText = @$('.error p') @$errorText = @$(".error p")
@$markdownPanel = @$('.markdown') @$markdownPanel = @$(".markdown")
@$previewButton = @$('.button.preview') @$previewButton = @$(".button.preview")
@$questionPanel = @$('.question') @$questionPanel = @$(".question")
@$saveButton = @$('.button.save') @$saveButton = @$(".button.save")
@$sizer = @$('.sizer') @$sizer = @$(".sizer")
@$textarea = @$('textarea') @$textarea = @$("textarea")
@$title = @$('h2') @$title = @$("h2")
@resetToDefaultState() @resetToDefaultState()
@@ -199,14 +200,14 @@ module.exports = class MarkdownSectionController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'click .markdown a': 'routeLinkClick' "click .markdown a": "routeLinkClick"
'click .button.cancel': 'onCancelClicked' "click .button.cancel": "onCancelClicked"
'click .button.edit': 'onEditClicked' "click .button.edit": "onEditClicked"
'click .button.preview': 'onPreviewClicked' "click .button.preview": "onPreviewClicked"
'click .button.return': 'onReturnClicked' "click .button.return": "onReturnClicked"
'click .button.save': 'onSaveClicked' "click .button.save": "onSaveClicked"
'click .question a': 'onQuestionClicked' "click .question a": "onQuestionClicked"
'input textarea': 'onTextChanged' "input textarea": "onTextChanged"
# Private Methods ############################################################################## # Private Methods ##############################################################################
@@ -219,22 +220,22 @@ module.exports = class MarkdownSectionController extends BaseController
result = match result = match
item = @_modPack.findItemByName name item = @_modPack.findItemByName name
if item? if item?
display = @_modPack.findItemDisplay item.slug display = new ItemDisplay item
result = "[#{name}](#{display.itemUrl})" result = "[#{name}](#{display.url})"
return result return result
_updateButtonStates: -> _updateButtonStates: ->
for $button in [ @$previewButton, @$saveButton ] for $button in [ @$previewButton, @$saveButton ]
if @_imageListController.valid if @_imageListController.valid
$button.prop 'disabled', false $button.prop "disabled", false
else else
$button.prop 'disabled', true $button.prop "disabled", true
_updateSizer: -> _updateSizer: ->
text = @model text = @model
if @model? if @model?
text = text.replace /\n/g, '<br>' text = text.replace /\n/g, "<br>"
@$sizer.html text @$sizer.html text
@@ -254,22 +255,22 @@ module.exports = class MarkdownSectionController extends BaseController
logger.verbose => "Updating markdown section visibility for state: #{@state}" logger.verbose => "Updating markdown section visibility for state: #{@state}"
elements = elements =
appologizingPanel: @$('.appologizing') appologizingPanel: @$(".appologizing")
cancelButton: @$('.button.cancel') cancelButton: @$(".button.cancel")
confirmingPanel: @$('.confirming') confirmingPanel: @$(".confirming")
creatingPanel: @$('.creating') creatingPanel: @$(".creating")
editButton: @$('.button.edit') editButton: @$(".button.edit")
editorPanel: @$('.editor') editorPanel: @$(".editor")
footerPanel: @$('.footer') footerPanel: @$(".footer")
imageList: @$('.view__markdown_image_list') imageList: @$(".view__markdown_image_list")
markdownPanel: @$markdownPanel markdownPanel: @$markdownPanel
previewButton: @$previewButton previewButton: @$previewButton
returnButton: @$('.button.return') returnButton: @$(".button.return")
saveButton: @$saveButton saveButton: @$saveButton
waitingPanel: @$('.waiting') waitingPanel: @$(".waiting")
visible = {} visible = {}
errorText = '' errorText = ""
if @state is @State.appologizing if @state is @State.appologizing
visible = appologizingPanel:true visible = appologizingPanel:true
@@ -2,8 +2,5 @@
.toggle .toggle
span.checkbox span.checkbox
span.label I have this mod in my modpack span.label I have this mod in my modpack
.version
span Version:
select
.warning. .warning.
<b>PLEASE NOTE:</b> Crafting plans, search, and other features will ignore items and recipes from this mod. <b>PLEASE NOTE:</b> Crafting plans, search, and other features will ignore items and recipes from this mod.
@@ -5,97 +5,59 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
{Mod} = require('crafting-guide-common').deprecated.game {Mod} = require("crafting-guide-common").models
######################################################################################################################## ########################################################################################################################
module.exports = class ModVersionSelectorController extends BaseController module.exports = class ModVersionSelectorController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.model? then throw new Error 'options.model is required' if options.model?.constructor isnt Mod then throw new Error "options.model must be a Mod"
options.templateName = 'common/mod_version_selector' options.templateName = "common/mod_version_selector"
super options super options
# Event Methods ################################################################################ # Event Methods ################################################################################
onToggleEnabled: -> onToggleEnabled: ->
if @model.activeVersion is Mod.Version.None if not @model.isEnabled
tracker.trackEvent c.tracking.category.modPack, 'toggle-on', @model.slug tracker.trackEvent c.tracking.category.modPack, "toggle-on", @model.id
@model.activeVersion = Mod.Version.Latest @model.isEnabled = true
else else
tracker.trackEvent c.tracking.category.modPack, 'toggle-off', @model.slug tracker.trackEvent c.tracking.category.modPack, "toggle-off", @model.id
@model.activeVersion = Mod.Version.None @model.isEnabled = false
return false return false
onVersionChanged: ->
@model.activeVersion = @$versionSelector.val()
tracker.trackEvent c.tracking.category.modPack, 'select-version', "#{@model.slug}@#{@model.activeVersion}"
return false
# Property Methods #############################################################################
Object.defineProperties @prototype,
effectiveModVersion:
get: ->
modVersion = @model.activeModVersion
modVersion ?= @model.getModVersion Mod.Version.Latest
modVersion.fetch() if modVersion?
return modVersion
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@$toggleSection = @$('.toggle') @$toggleSection = @$(".toggle")
@$versionSection = @$('.version') @$warning = @$(".warning")
@$versionSelector = @$('.version select')
@$warning = @$('.warning')
super super
refresh: -> refresh: ->
console.log "refreshing"
@_refreshEnabled() @_refreshEnabled()
@_refreshVersionSelector()
super super
# Backbone.View Overrides ###################################################################### # Backbone.View Overrides ######################################################################
events: -> events: ->
return _.extend super, return _.extend super,
'change .version select': 'onVersionChanged' "click .toggle": "onToggleEnabled"
'click .toggle': 'onToggleEnabled'
# Private Methods ############################################################################## # Private Methods ##############################################################################
_refreshEnabled: -> _refreshEnabled: ->
if @model.slug in c.requiredMods if @model.id in c.requiredMods
@hide @$toggleSection @hide @$toggleSection
else else
@show @$toggleSection @show @$toggleSection
if @model.activeVersion is Mod.Version.None if not @model.isEnabled
@$toggleSection.removeClass 'enabled' @$toggleSection.removeClass "enabled"
@show @$warning @show @$warning
else else
@$toggleSection.addClass 'enabled' @$toggleSection.addClass "enabled"
@hide @$warning @hide @$warning
_refreshVersionSelector: ->
modVersions = @model.modVersions
if (@model.activeVersion is Mod.Version.None) or modVersions.length < 2
@hide @$versionSection
else
@show @$versionSection
selectedModVersion = @effectiveModVersion
@$versionSelector.empty()
for modVersion in @model.modVersions
$option = $("<option value=\"#{modVersion.version}\">#{modVersion.version}</option>")
if modVersion is selectedModVersion
$option.attr 'selected', 'true'
@$versionSelector.append $option
@$versionSelector.css display:''
@@ -0,0 +1,19 @@
//-
//- Crafting Guide - crafting_table.jade
//-
//- Copyright (c) 2015-2017 by Redwood Labs
//- All rights reserved.
//-
.view__crafting_table
.input_inventory
.view__inventory
.grid_block
.input_grid
.view__crafting_grid
.tool
.output_slot
.view__slot
.multiplier
.output_inventory
.view__inventory
@@ -0,0 +1,103 @@
//
// Crafting Guide - crafting_table.scss
//
// Copyright © 2014-2017 by Redwood Labs
// All rights reserved.
//
.view__crafting_table {
display: flex;
.input_inventory {
flex: 1 1 100%;
display: flex;
margin-right: $size-margin-large;
}
.grid_block {
flex: 1 1 100%;
display: flex;
align-items: center;
justify-content: center;
.input_grid {
flex: 0 0 auto;
align-items : center;
display : flex;
flex-direction : column;
.view__crafting_grid {
flex: 0 0 auto;
}
.tool {
margin-top : $size-margin-small;
font-family : $font-family-text;
font-size : $font-size-medium;
}
}
.output_slot {
flex: 0 0 auto;
margin-left: $size-margin-large;
display : flex;
flex-direction : column;
justify-content : center;
align-items : center;
.view__slot {
border: $size-border-medium solid $color-gray-medium;
}
.multiplier {
font-family : $font-family-header;
font-size : $font-size-large;
margin-top : $size-margin-medium;
}
}
}
.output_inventory {
flex: 1 1 100%;
display: flex;
margin-left: $size-margin-large;
}
}
@include screen-size(mobile) {
.view__crafting_table {
border-bottom: 1px solid $color-gray-light;
padding-bottom: $size-margin-medium;
flex-direction: column;
align-items: center;
.input_inventory {
flex: 0 0 auto;
margin-bottom: $size-margin-small;
}
.grid_block {
flex: 0 0 auto;
.tool {
margin-bottom: $size-margin-medium;
}
}
.output_inventory {
flex: 0 0 auto;
margin-left: 0;
}
.view__inventory {
margin-left: $size-margin-medium;
margin-right: $size-margin-medium;
}
}
}
@@ -0,0 +1,95 @@
#
# Crafting Guide - crafting_table_controller.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require "../../../base_controller"
CraftingGridController = require "../../crafting_grid/crafting_grid_controller"
InventoryController = require "../../inventory/inventory_controller"
ItemDisplay = require "../../../../models/site/item_display"
RecipeDisplay = require "../../../../models/site/recipe_display"
SlotController = require "../../slot/slot_controller"
{StringBuilder} = require("crafting-guide-common").util
########################################################################################################################
module.exports = class CraftingTableController 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/crafting_table"
super options
@_imageLoader = options.imageLoader
@_modPack = options.modPack
@_router = options.router
# BaseController Overrides #####################################################################
onDidRender: ->
options = editable:false, modPack:@_modPack, imageLoader:@_imageLoader, router:@_router
@_inputController = @addChild InventoryController, ".input_inventory .view__inventory", options
@_gridController = @addChild CraftingGridController, ".input_grid .view__crafting_grid", options
@_outputSlotController = @addChild SlotController, ".output_slot .view__slot", options
@_outputController = @addChild InventoryController, ".output_inventory .view__inventory", options
@$inputInventorySection = @$(".input_inventory")
@$multiplier = @$(".multiplier")
@$outputImg = @$(".output.slot img")
@$outputInventorySection = @$(".output_inventory")
@$outputLink = @$(".output.slot a")
@$outputQuantity = @$(".quantity")
@$outputSlotSection = @$(".output_slot")
@$toolContainer = @$(".tool")
super
onWillChangeModel: (oldModel, newModel)->
if not newModel? then throw new Error "model is required"
if newModel.constructor isnt RecipeDisplay then throw new Error "model must be a RecipeDisplay"
return super oldModel, newModel
refresh: ->
@_inputController.model = @model?.getInventory()
@_gridController.model = @model?.recipe
@_outputSlotController.model = @model?.recipe.output
@_outputController.model = @model?.getOutputInventory()
@_refreshMultiplier()
@_refreshSections()
@_refreshTools()
super
# Backbone.View Methods ########################################################################
events: ->
return _.extend super,
"click a": "routeLinkClick"
# Private Methods ##############################################################################
_refreshMultiplier: ->
if @model.multiplier > 1
@$multiplier.html "x#{@model.multiplier}"
else
@$multiplier.html ""
_refreshSections: ->
@$inputInventorySection.css display:(if @model.showInputInventory then "" else "none")
@$outputInventorySection.css display:(if @model.showOutputInventory then "" else "none")
@$outputSlotSection.css display:(if @model.showOutputSlot then "" else "none")
_refreshTools: ->
@$toolContainer.empty()
return unless @model?
toolLinks = []
for itemId, item of @model.tools
display = new ItemDisplay item
toolLinks.push "<a href=\"#{display.url}\">#{display.name}</a>"
@$toolContainer.html toolLinks.join ", "
@@ -1,11 +1,12 @@
### #
Crafting Guide - multiblock_controller.coffee # Crafting Guide - multiblock_controller.coffee
#
# Copyright (c) 2014-2017 by Redwood Labs
# All rights reserved.
#
Copyright (c) 2014-2015 by Redwood Labs BaseController = require "../../../../base_controller"
All rights reserved. ItemDisplay = require "../../../../../models/site/item_display"
###
BaseController = require '../../../base_controller'
######################################################################################################################## ########################################################################################################################
@@ -25,9 +26,9 @@ module.exports = class MultiblockController extends BaseController
@::MAX_DROP_DELAY = 250 # ms @::MAX_DROP_DELAY = 250 # ms
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
options.templateName = 'item_page/multiblock_viewer/multiblock' options.templateName = "common/recipe/multiblock_viewer/multiblock"
super options super options
@_currentLayer = 0 @_currentLayer = 0
@@ -63,11 +64,11 @@ module.exports = class MultiblockController extends BaseController
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@$outline = @$('.outline') @$outline = @$(".outline")
super super
refresh: -> refresh: ->
@$el.css 'height':@_computeMinHeight(), 'width':@_computeMinWidth() @$el.css "height":@_computeMinHeight(), "width":@_computeMinWidth()
@_refreshBlockCache() @_refreshBlockCache()
@_refreshAllBlocks() @_refreshAllBlocks()
@@ -76,7 +77,7 @@ module.exports = class MultiblockController extends BaseController
# Private Methods ############################################################################## # Private Methods ##############################################################################
_computePosition: (x, y, z, options={})-> _computePosition: (x, y, z, options={})->
if not @model? then return left:0, top:-@IMAGE_SIZE, 'z-index':0, opacity:0.0 if not @model? then return left:0, top:-@IMAGE_SIZE, "z-index":0, opacity:0.0
options.hideUpperLayers ?= false options.hideUpperLayers ?= false
pxWidth = @$el.width() pxWidth = @$el.width()
@@ -93,7 +94,7 @@ module.exports = class MultiblockController extends BaseController
zindex = ((@model.width - x) + (@model.depth - z) + ((@model.width * @model.depth) * y)) * 2 zindex = ((@model.width - x) + (@model.depth - z) + ((@model.width * @model.depth) * y)) * 2
return left:left, top:top, 'z-index':zindex, opacity:opacity return left:left, top:top, "z-index":zindex, opacity:opacity
_computeMinHeight: -> _computeMinHeight: ->
return 0 unless @model? return 0 unless @model?
@@ -130,23 +131,23 @@ module.exports = class MultiblockController extends BaseController
for z in [0...@model.depth] for z in [0...@model.depth]
@_blockCache[x][y][z] ?= null @_blockCache[x][y][z] ?= null
for el in @$('.block') for el in @$(".block")
$el = $(el) $el = $(el)
@_blockCache[$el.data('x')][$el.data('y')][$el.data('z')] = $el @_blockCache[$el.data("x")][$el.data("y")][$el.data("z")] = $el
_refreshBlock: (x, y, z)-> _refreshBlock: (x, y, z)->
return unless @model? return unless @model?
stack = @model.getStackAt x, y, z stack = @model.getInputAt x, y, z
$block = @_blockCache[x][y][z] $block = @_blockCache[x][y][z]
position = @_computePosition x, y, z, hideUpperLayers:true position = @_computePosition x, y, z, hideUpperLayers:true
move = false move = false
if stack? if stack?
itemDisplay = @_modPack.findItemDisplay stack.itemSlug itemDisplay = new ItemDisplay stack.item
if not $block? if not $block?
$block = $("<img alt='#{itemDisplay.itemName}' class='block' />") $block = $("<img alt=\"#{itemDisplay.itemName}\" class=\"block\" />")
$block.css position, top:-@IMAGE_SIZE, opacity:0.0 $block.css position, top:-@IMAGE_SIZE, opacity:0.0
@_registerHoverHandlers $block, y, itemDisplay @_registerHoverHandlers $block, y, itemDisplay
@_imageLoader.load itemDisplay.iconUrl, $block @_imageLoader.load itemDisplay.iconUrl, $block
@@ -154,10 +155,10 @@ module.exports = class MultiblockController extends BaseController
@$el.append $block @$el.append $block
move = true move = true
else else
$block.attr 'src', itemDisplay.iconUrl $block.attr "src", itemDisplay.iconUrl
move = true move = true
else if $block? else if $block?
$block.attr 'src', '' $block.attr "src", ""
move = true move = true
if move then _.delay (-> $block.css position), @_randomDropDelay() if move then _.delay (-> $block.css position), @_randomDropDelay()
@@ -174,10 +175,10 @@ module.exports = class MultiblockController extends BaseController
_registerHoverHandlers: ($el, y, itemDisplay)-> _registerHoverHandlers: ($el, y, itemDisplay)->
startHovering = => startHovering = =>
return unless y is @_currentLayer return unless y is @_currentLayer
zIndex = parseInt($el.css('z-index')) + 1 zIndex = parseInt($el.css("z-index")) + 1
zIndex = if _.isNaN(zIndex) then 0 else zIndex zIndex = if _.isNaN(zIndex) then 0 else zIndex
@$outline.css opacity:1.0, top:$el.css('top'), left:$el.css('left'), 'z-index':zIndex @$outline.css opacity:1.0, top:$el.css("top"), left:$el.css("left"), "z-index":zIndex
@_onHovering itemDisplay @_onHovering itemDisplay
if @_hoverTimer? then clearTimeout @_hoverTimer if @_hoverTimer? then clearTimeout @_hoverTimer
@@ -0,0 +1,96 @@
#
# Crafting Guide - multiblock_viewer_controller.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require "../../../base_controller"
InventoryController = require "../../inventory/inventory_controller"
MultiblockController = require "./multiblock/multiblock_controller"
RecipeDisplay = require "../../../../models/site/recipe_display"
########################################################################################################################
module.exports = class MultiblockViewerController 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/multiblock_viewer"
super options
@_imageLoader = options.imageLoader
@_modPack = options.modPack
@_hoverTimer = null
@_router = options.router
# Event Methods ################################################################################
onBackClicked: ->
return if @$backButton.hasClass "disabled"
tracker.trackEvent c.tracking.category.multiblock, "back"
@multiblockController.goBackLayer()
@refresh()
onNextClicked: ->
return if @$nextButton.hasClass "disabled"
tracker.trackEvent c.tracking.category.multiblock, "next"
@multiblockController.goNextLayer()
@refresh()
onBlockHovered: (itemDisplay)->
if itemDisplay?
@$captionText.html itemDisplay.name
@_imageLoader.load itemDisplay.iconUrl, @$captionIcon
else
@$captionText.html "&nbsp;"
@$captionIcon.attr "src", "/images/empty.png"
# BaseController Overrides #####################################################################
onDidRender: ->
baseOptions = imageLoader:@_imageLoader, modPack:@_modPack, router:@_router
options = _.extend {editable:false}, baseOptions
@completeInventoryController = @addChild InventoryController, ".view__inventory.complete", options
@layerInventoryController = @addChild InventoryController, ".view__inventory.layer", options
options = _.extend {onHovering:(itemDisplay)=> @onBlockHovered(itemDisplay)}, baseOptions
@multiblockController = @addChild MultiblockController, ".view__multiblock", options
@$backButton = @$(".button.back")
@$nextButton = @$(".button.next")
@$captionText = @$(".caption p")
@$captionIcon = @$(".caption img")
super
onWillChangeModel: (oldModel, newModel)->
if not newModel? then throw new Error "model is required"
if newModel.constructor isnt RecipeDisplay then throw new Error "model must be a RecipeDisplay"
return super oldModel, newModel
refresh: ->
@completeInventoryController.model = @model.getInventory()
@layerInventoryController.model = @model.getInventory @multiblockController.currentLayer
@multiblockController.model = @model
if @multiblockController.hasBackLayer()
@$backButton.removeClass "disabled"
else
@$backButton.addClass "disabled"
if @multiblockController.hasNextLayer()
@$nextButton.removeClass "disabled"
else
@$nextButton.addClass "disabled"
super
# Backbone.View Overrides ######################################################################
events: ->
_.extend super,
"click .button.back": "onBackClicked"
"click .button.next": "onNextClicked"
+1 -7
View File
@@ -1,14 +1,8 @@
//- //-
//- Crafting Guide - recipe.jade //- Crafting Guide - recipe.jade
//- //-
//- Copyright (c) 2015 by Redwood Labs //- Copyright (c) 2014-2017 by Redwood Labs
//- All rights reserved. //- All rights reserved.
//- //-
.view__recipe .view__recipe
.input
.view__crafting_grid
.tool
.output
.view__slot
.multiplier
@@ -5,93 +5,57 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
CraftingGridController = require '../crafting_grid/crafting_grid_controller' CraftingTableController = require "./crafting_table/crafting_table_controller"
SlotController = require '../slot/slot_controller' MultiblockViewerController = require "./multiblock_viewer/multiblock_viewer_controller"
{StringBuilder} = require('crafting-guide-common').util RecipeDisplay = require "../../../models/site/recipe_display"
######################################################################################################################## ########################################################################################################################
module.exports = class RecipeController extends BaseController module.exports = class RecipeController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error 'options.router is required' if not options.router? then throw new Error "options.router is required"
options.templateName = 'common/recipe' options.templateName = "common/recipe"
super options super options
@_imageLoader = options.imageLoader @_imageLoader = options.imageLoader
@_modPack = options.modPack @_modPack = options.modPack
@_multiplier = options.multiplier
@_router = options.router @_router = options.router
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onWillChangeModel: (oldModel, newModel)->
@_gridController = @addChild CraftingGridController, '.view__crafting_grid', if not newModel? then throw new Error "model is required"
modPack: @_modPack if newModel.constructor isnt RecipeDisplay then throw new Error "model must be a RecipeDisplay"
imageLoader: @_imageLoader if @_typeController? then @_typeController.model = newModel
router: @_router return super oldModel, newModel
@_outputSlotController = @addChild SlotController, '.output .view__slot',
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
@$multiplier = @$('.multiplier')
@$outputImg = @$('.output img')
@$outputLink = @$('.output a')
@$outputQuantity = @$('.quantity')
@$toolContainer = @$('.tool')
super
refresh: -> refresh: ->
@_gridController.model = @model return unless @model?
@_outputSlotController.model = @model?.output?[0] @_refreshRecipeType()
@_refreshMultiplier()
@_refreshTools()
super super
# Property Methods #############################################################################
Object.defineProperties @prototype,
multiplier:
get: ->
@_multiplier ?= 1
return @_multiplier
set: (newMultiplier)->
oldMultiplier = @_multiplier
return if newMultiplier is oldMultiplier
@_multiplier = newMultiplier
@_refreshMultiplier()
@trigger Event.change + ':multiplier', this, oldMultiplier, newMultiplier
@trigger Event.change, this
# Backbone.View Methods ########################################################################
events: ->
return _.extend super,
'click a': 'routeLinkClick'
# Private Methods ############################################################################## # Private Methods ##############################################################################
_refreshMultiplier: -> _lookupControllerFor: (recipeType)->
if @multiplier > 1 if recipeType is RecipeDisplay::RECIPE_TYPE.CRAFTING_TABLE then return CraftingTableController
@$multiplier.html "x#{@multiplier}" if recipeType is RecipeDisplay::RECIPE_TYPE.MULTIBLOCK then return MultiblockViewerController
else
@$multiplier.html ''
_refreshTools: -> _refreshRecipeType: ->
@$toolContainer.empty() return if @_renderedRecipeType is @model.type
return unless @model? @_renderedRecipeType = @model.type
builder = new StringBuilder if @_typeController?
builder.loop @model.tools, delimiter:', ', onEach:(b, stack)=> @_typeController.remove()
display = @_modPack.findItemDisplay stack.itemSlug @_typeController = null
b.push "<a href=\"#{display.itemUrl}\">#{display.itemName}</a>"
@$toolContainer.html builder.toString() return unless @_renderedRecipeType?
TypeController = @_lookupControllerFor @model.type
@$el.append "<div class=\"view__#{@model.type}\"></div>"
options = imageLoader:@_imageLoader, model:@model, modPack:@_modPack, router:@_router
@_typeController = @addChild TypeController, ".view__#{@model.type}", options
@@ -5,18 +5,19 @@
# All rights reserved. # 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 module.exports = class SlotController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error 'options.router is required' if not options.router? then throw new Error "options.router is required"
# options.model should be a Stack options.templateName = "common/slot"
options.templateName = 'common/slot'
options.useAnimations = false options.useAnimations = false
super options super options
@@ -27,27 +28,31 @@ module.exports = class SlotController extends BaseController
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@$link = @$('a') @$link = @$("a")
@$image = @$('img') @$image = @$("img")
@$quantity = @$('.quantity') @$quantity = @$(".quantity")
super
onWillChangeModel: (oldModel, newModel)->
if newModel? and (newModel.constructor isnt Stack) then throw new Error "newModel must be a Stack"
super super
refresh: -> refresh: ->
if @model? if @model?
display = @_modPack.findItemDisplay @model.itemSlug display = new ItemDisplay @model.item
@$link.attr 'href', display.itemUrl @$link.attr "href", display.url
@_imageLoader.load display.iconUrl, @$image @_imageLoader.load display.iconUrl, @$image
if @model.quantity > 1 if @model.quantity > 1
@$quantity.html @model.quantity @$quantity.html @model.quantity
else else
@$quantity.html '' @$quantity.html ""
else else
@$link.removeAttr 'href' @$link.removeAttr "href"
@$quantity.html '' @$quantity.html ""
@$image.attr 'src', '/images/empty.png' @$image.attr "src", "/images/empty.png"
super super
@@ -55,4 +60,4 @@ module.exports = class SlotController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'click a': 'routeLinkClick' "click a": "routeLinkClick"
@@ -6,6 +6,7 @@
# #
BaseController = require '../../base_controller' 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 @_shouldEnableButton = options.shouldEnableButton ?= (model, button)-> true
@_trackingContext = options.trackingContext ?= null @_trackingContext = options.trackingContext ?= null
@_modPack.on c.event.change, => @tryRefresh()
# Event Methods ################################################################################ # Event Methods ################################################################################
onFirstButtonClicked: (event)-> onFirstButtonClicked: (event)->
@@ -71,7 +70,7 @@ module.exports = class StackController extends BaseController
@trigger c.event.change + ':quantity', this, oldQuantity, newQuantity @trigger c.event.change + ':quantity', this, oldQuantity, newQuantity
@trigger c.event.change, this @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: -> onQuantityFieldChanged: ->
return unless @_editable return unless @_editable
@@ -119,11 +118,11 @@ module.exports = class StackController extends BaseController
refresh: -> refresh: ->
if not @model? then throw new Error "must have a model to render" 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 @_imageLoader.load display.iconUrl, @$image
@$nameLink.html display.itemName @$nameLink.html display.name
@$nameLink.attr 'href', display.itemUrl @$nameLink.attr 'href', display.url
quantityText = if @model.quantity > 10000 then "#{@model.quantity / 1000}k" else "#{@model.quantity}" quantityText = if @model.quantity > 10000 then "#{@model.quantity / 1000}k" else "#{@model.quantity}"
@$quantityField.val quantityText @$quantityField.val quantityText
@@ -5,30 +5,31 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
######################################################################################################################## ########################################################################################################################
module.exports = class VideoController extends BaseController module.exports = class VideoController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.model? then throw new Error 'options.model is required' if not options.model? then throw new Error "options.model is required"
options.templateName = 'common/video' options.templateName = "common/video"
super options super options
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@$iframe = @$('iframe') @$iframe = @$("iframe")
@$caption = @$('.caption p') @$caption = @$(".caption p")
super super
refresh: -> refresh: ->
@$caption.html @model.name @$caption.html @model.name
@$iframe.attr 'src', @_createYouTubeUrl() @$iframe.attr "src", @_createYouTubeUrl()
super super
# Private ###################################################################################### # Private ######################################################################################
_createYouTubeUrl: -> _createYouTubeUrl: ->
return "http://www.youtube.com/embed/#{@model.youTubeId}?modestbranding=1&autohide=1&showinfo=0" return "http://www.youtube.com/embed/#{@model.youTubeId}?modestbranding=1&autohide=1&showinfo=0"
+1 -1
View File
@@ -53,4 +53,4 @@
h2 Steps h2 Steps
.panel .panel
section.view__craftsman_working section.view__working_panel
@@ -5,28 +5,28 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../base_controller' CraftPage = require "../../models/site/craft_page"
CraftPage = require '../../models/site/craft_page' WorkingPanelController = require "./working_panel/working_panel_controller"
{Craftsman} = require('crafting-guide-common').deprecated.crafting {Inventory} = require("crafting-guide-common").models
CraftsmanWorkingController = require './craftsman_working/craftsman_working_controller' InventoryController = require "../common/inventory/inventory_controller"
InventoryController = require '../common/inventory/inventory_controller' {Observable} = require("crafting-guide-common").util
PageController = require '../page_controller' PageController = require "../page_controller"
{SimpleInventory} = require('crafting-guide-common').deprecated.crafting StepController = require "./step/step_controller"
StepController = require './step/step_controller'
######################################################################################################################## ########################################################################################################################
module.exports = class CraftPageController extends PageController module.exports = class CraftPageController extends PageController
@::SCROLL_BUFFER = 8 # px @::SCROLL_BUFFER = 8 # px
@::STEP_RENDER_DELAY = 25 # ms
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error 'options.router 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.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' options.templateName = 'craft_page'
super options super options
@@ -35,41 +35,44 @@ module.exports = class CraftPageController extends PageController
@_router = options.router @_router = options.router
@_storage = options.storage @_storage = options.storage
@model.have.on Observable::ANY, this, "onHaveInventoryChanged"
@model.want.on Observable::ANY, this, "onWantInventoryChanged"
# Event Methods ################################################################################ # Event Methods ################################################################################
onHaveInventoryChanged: -> onHaveInventoryChanged: ->
@_storage.store 'crafting-plan:have', @model.craftsman.have.unparse() @_storage.store 'crafting-plan:have', @model.have.toUrlString()
onMoveNeedToHave: (itemSlug)-> onMoveNeedToHave: (item)->
quantity = @_needInventoryController.model.quantityOf itemSlug quantity = @_needInventoryController.model.getQuantity item
@model.craftsman.have.add itemSlug, quantity @model.have.add item, quantity
onRemoveFromHaveInventory: (itemSlug)-> onRemoveFromHave: (item)->
@model.craftsman.have.remove itemSlug @model.have.remove item
onRemoveFromWant: (itemSlug)-> onRemoveFromWant: (item)->
@model.craftsman.want.remove itemSlug @model.want.remove item
@onWantInventoryChanged()
onSampleClicked: (event)-> onSampleClicked: (event)->
$el = $(event.target) $el = $(event.target)
while $el.length > 0 while $el.length > 0
inventoryText = $el.attr 'data-slug' inventoryText = $el.attr "data-slug"
break if inventoryText break if inventoryText
$el = $el.parent() $el = $el.parent()
if inventoryText? if inventoryText?
tracker.trackEvent c.tracking.category.craft, 'add-sample', inventoryText try
sampleInventory = new SimpleInventory tracker.trackEvent c.tracking.category.craft, "add-sample", inventoryText
sampleInventory.parse inventoryText sampleInventory = Inventory.fromUrlString inventoryText, @_modPack
@model.craftsman.want.addInventory sampleInventory @model.want.merge sampleInventory
@_scrollTo @$workingSection @_scrollTo @$workingSection
@onWantInventoryChanged() catch e
logger.error e
return false return false
onWantInventoryChanged: -> onWantInventoryChanged: ->
text = @model.craftsman.want.unparse() text = @model.want.toUrlString()
url = c.url.crafting inventoryText:text url = c.url.crafting inventoryText:text
@router.navigate url @router.navigate url
@@ -79,7 +82,7 @@ module.exports = class CraftPageController extends PageController
return c.text.craftDescription() return c.text.craftDescription()
getTitle: -> getTitle: ->
description = @model.craftsman.want.toDescription() description = @model.want.toDescription()
return null unless description? return null unless description?
return "Crafting Plan for #{description}" return "Crafting Plan for #{description}"
@@ -91,21 +94,19 @@ module.exports = class CraftPageController extends PageController
imageLoader: @_imageLoader imageLoader: @_imageLoader
isAcceptable: (item)=> item.isCraftable isAcceptable: (item)=> item.isCraftable
modPack: @_modPack modPack: @_modPack
model: @model.craftsman.want model: @model.want
router: @_router router: @_router
trackingContext: c.tracking.category.craftWant trackingContext: c.tracking.category.craftWant
@_wantInventoryController.on c.event.button.first, (c, s)=> @onRemoveFromWant(s) @_wantInventoryController.on c.event.button.first, (controller, item)=> @onRemoveFromWant item
@_wantInventoryController.on c.event.change, (c)=> @onWantInventoryChanged()
@_haveInventoryController = @addChild InventoryController, '.have .view__inventory', @_haveInventoryController = @addChild InventoryController, '.have .view__inventory',
firstButtonType: 'down' firstButtonType: 'down'
imageLoader: @_imageLoader imageLoader: @_imageLoader
modPack: @_modPack modPack: @_modPack
model: @model.craftsman.have model: @model.have
router: @_router router: @_router
trackingContext: c.tracking.category.craftHave trackingContext: c.tracking.category.craftHave
@_haveInventoryController.on c.event.button.first, (controller, itemSlug)=> @_haveInventoryController.on c.event.button.first, (controller, item)=> @onRemoveFromHave item
@onRemoveFromHaveInventory itemSlug
@_needInventoryController = @addChild InventoryController, '.need .view__inventory', @_needInventoryController = @addChild InventoryController, '.need .view__inventory',
editable: false editable: false
@@ -115,11 +116,9 @@ module.exports = class CraftPageController extends PageController
model: null model: null
router: @_router router: @_router
trackingContext: c.tracking.category.craftNeed trackingContext: c.tracking.category.craftNeed
@_needInventoryController.on c.event.button.first, (c, s)=> @onMoveNeedToHave(s) @_needInventoryController.on c.event.button.first, (controller, item)=> @onMoveNeedToHave item
@_workingSectionController = @addChild CraftsmanWorkingController, '.view__craftsman_working', @_workingPanelController = @addChild WorkingPanelController, '.view__working_panel', model:@model
model: @model.craftsman
@_workingSectionController.on c.event.click, => @_scrollTo @$workingSection
@$haveSection = @$('section.have') @$haveSection = @$('section.have')
@$instructionsSection = @$('section.instructions') @$instructionsSection = @$('section.instructions')
@@ -128,7 +127,7 @@ module.exports = class CraftPageController extends PageController
@$stepsContainer = @$('section.steps .panel') @$stepsContainer = @$('section.steps .panel')
@$stepsSection = @$('section.steps') @$stepsSection = @$('section.steps')
@$toolsSection = @$('section.tools') @$toolsSection = @$('section.tools')
@$workingSection = @$('.view__craftsman_working') @$workingSection = @$('.view__working_panel')
if c.screen.type.compute() is c.screen.type.mobile if c.screen.type.compute() is c.screen.type.mobile
@$('.view__inventory.large').removeClass 'large' @$('.view__inventory.large').removeClass 'large'
@@ -136,20 +135,15 @@ module.exports = class CraftPageController extends PageController
super super
onWillRender: -> onWillRender: ->
@model.craftsman.have.clear() @model.have.clear()
@model.craftsman.have.parse @_storage.load('crafting-plan:have') @model.have.merge Inventory.fromUrlString @_storage.load('crafting-plan:have')
@model.craftsman.have.on c.event.change, => @onHaveInventoryChanged() @model.have.on Observable::ANY, this, "onHaveInventoryChanged"
@model.want.on Observable::ANY, this, "tryRefresh"
@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
super super
refresh: -> refresh: ->
@_needInventoryController.model = @model.craftsman.plan?.need @_needInventoryController.model = @model.currentPlan?.need
@_refreshOutdated() @_refreshOutdated()
@_refreshSectionVisibility() @_refreshSectionVisibility()
@_refreshSteps() @_refreshSteps()
@@ -165,33 +159,30 @@ module.exports = class CraftPageController extends PageController
# Private Methods ################################################################################ # Private Methods ################################################################################
_addTools: (controller)-> _addTools: (controller)->
controller.model.addToolsTo @model.craftsman.want controller.model.addToolsTo @model.want
_completeStep: (controller)-> _completeStep: (controller)->
controller.markComplete @model.craftsman.have controller.markComplete @model.have
_isAddingToolsPossible: (controller)-> _isAddingToolsPossible: (controller)->
tools = controller.model.recipe.tools tools = (item for itemId, item of controller.model.recipe.tools)
return false unless tools.length > 0 return false unless tools.length > 0
have = @model.craftsman.have have = @model.have
want = @model.craftsman.want want = @model.want
for stack in tools for item in tools
return false if have.hasAtLeast stack.itemSlug return false if @model.have.contains item
return false if want.hasAtLeast stack.itemSlug return false if @model.want.contains item
return true return true
_isStepCompletable: (controller)-> _isStepCompletable: (controller)->
recipe = controller.model.recipe userWantsItem = @model.want.contains controller.model.recipe.output.item
for stack in recipe.output return not userWantsItem
return false if @model.craftsman.want.hasAtLeast stack.itemSlug
return true
_refreshOutdated: -> _refreshOutdated: ->
if @model.craftsman.stage is Craftsman::STAGE.OUTDATED if @model.isOutdated
@$el.addClass 'outdated' @$el.addClass 'outdated'
else else
@$el.removeClass 'outdated' @$el.removeClass 'outdated'
@@ -205,22 +196,25 @@ module.exports = class CraftPageController extends PageController
visibleSections = [] 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] 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 else
visibleSections.push el for el in [@$haveSection, @$wantSection, @$workingSection] visibleSections.push el for el in [@$haveSection, @$wantSection, @$workingSection]
if @model.craftsman.plan? if @model.currentPlan?
visibleSections.push el for el in [@$needSection, @$stepsSection] visibleSections.push el for el in [@$needSection, @$stepsSection]
@hide $el for $el in allSections @hide $el for $el in allSections
@show $el for $el in visibleSections @show $el for $el in visibleSections
_refreshSteps: -> _refreshSteps: ->
steps = @model.craftsman.plan?.steps or [] steps = @model.currentPlan?.steps or []
@_stepControllers ?= [] @_stepControllers ?= []
index = 0 index = 0
@@ -236,10 +230,14 @@ module.exports = class CraftPageController extends PageController
model: step model: step
modPack: @_modPack modPack: @_modPack
router: @_router router: @_router
controller.render()
@$stepsContainer.append controller.$el do (controller, index)=>
@_stepControllers.push controller _.delay (=>
controller.render()
@$stepsContainer.append controller.$el
@_stepControllers.push controller
), (index * @STEP_RENDER_DELAY)
else else
controller.model = step controller.model = step
@@ -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'
+1 -3
View File
@@ -7,9 +7,7 @@
.view__step .view__step
h3 h3
.main_content .view__recipe
.view__inventory
.view__recipe
.buttons .buttons
a.button.tool: .bezel: p <span class="full">show plan for </span>tools a.button.tool: .bezel: p <span class="full">show plan for </span>tools
.button.complete: .bezel: p complete<span class="full"> step</span> .button.complete: .bezel: p complete<span class="full"> step</span>
+1 -18
View File
@@ -25,24 +25,7 @@
margin-bottom: 1em; margin-bottom: 1em;
} }
.main_content { & > .buttons {
display: flex;
.view__inventory {
flex: 50%;
margin-left: $size-margin-large;
.buttons {
display: none;
}
}
.view__recipe {
flex: 50%;
}
}
.buttons {
margin-top: $size-margin-large; margin-top: $size-margin-large;
opacity: 0; opacity: 0;
@@ -5,20 +5,23 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
InventoryController = require '../../common/inventory/inventory_controller' {Inventory} = require("crafting-guide-common").models
RecipeController = require '../../common/recipe/recipe_controller' {CraftingPlanStep} = require("crafting-guide-common").crafting
{SimpleInventory} = require('crafting-guide-common').deprecated.crafting InventoryController = require "../../common/inventory/inventory_controller"
RecipeController = require "../../common/recipe/recipe_controller"
RecipeDisplay = require "../../../models/site/recipe_display"
######################################################################################################################## ########################################################################################################################
module.exports = class StepController extends BaseController module.exports = class StepController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.model? then throw new Error 'options.model is required' if options.model?.constructor isnt CraftingPlanStep
if not options.modPack? then throw new Error 'options.modPack is required' throw new Error "options.model must be a CraftingPlanStep"
if not options.imageLoader? then throw new Error 'options.imageLoader is required' if not options.modPack? then throw new Error "options.modPack is required"
options.templateName = 'craft_page/step' if not options.imageLoader? then throw new Error "options.imageLoader is required"
options.templateName = "craft_page/step"
super options super options
@_imageLoader = options.imageLoader @_imageLoader = options.imageLoader
@@ -33,57 +36,49 @@ module.exports = class StepController extends BaseController
# Public Methods ############################################################################### # Public Methods ###############################################################################
markComplete: (targetInventory)-> markComplete: (targetInventory)->
@$el.addClass 'complete' @$el.addClass "complete"
@$completeButton.addClass 'disabled' @$completeButton.addClass "disabled"
@model.completeInto targetInventory @model.completeInto targetInventory
# Event Methods ################################################################################ # Event Methods ################################################################################
onCompleteButtonClicked: (event)-> onCompleteButtonClicked: (event)->
return if @$completeButton.hasClass 'disabled' return false 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 @onComplete this
onShowToolPlan: (event)-> onShowToolPlan: (event)->
tracker.trackEvent c.tracking.category.navigate, 'show-tool-plan', @$toolButton.attr 'target' return false if @$toolButton.hasClass "disabled"
tracker.trackEvent c.tracking.category.navigate, "show-tool-plan", @$toolButton.attr "target"
return true return true
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@inventoryController = @addChild InventoryController, '.view__inventory', options = imageLoader:@_imageLoader, modPack:@_modPack, router:@_router
editable: false @recipeController = @addChild RecipeController, ".view__recipe", options
imageLoader: @_imageLoader
model: @model.inventory
modPack: @_modPack
router: @_router
@recipeController = @addChild RecipeController, '.view__recipe', @$completeButton = @$(".button.complete")
imageLoader: @_imageLoader @$header = @$("h3")
model: @model.recipe @$toolButton = @$(".button.tool")
modPack: @_modPack @$toolButtonLabel = @$(".button.tool p")
router: @_router
@$completeButton = @$('.button.complete')
@$header = @$('h3')
@$toolButton = @$('.button.tool')
@$toolButtonLabel = @$('.button.tool p')
super super
onWillChangeModel: (oldModel, newModel)-> onWillChangeModel: (oldModel, newModel)->
if not newModel? then throw new Error 'model cannot be null' if not newModel? then throw new Error "model cannot be null"
if @rendered if @rendered
@$el.removeClass 'complete' @$el.removeClass "complete"
@$completeButton.removeClass 'disabled' @$completeButton.removeClass "disabled"
return super return super
refresh: -> refresh: ->
itemDisplay = @_modPack.findItemDisplay @model.recipe.output[0].itemSlug @$header.html "#{@model.number}. #{@model.recipe.output.item.displayName}"
@$header.html "#{@model.number}. #{itemDisplay.itemName}"
@inventoryController.model = @model.inventory @recipeController.model = new RecipeDisplay
@recipeController.model = @model.recipe multiplier: @model.count
@recipeController.multiplier = @model.multiplier recipe: @model.recipe
showInputInventory: true
showOutputSlot: true
@_refreshCompleteButton() @_refreshCompleteButton()
@_refreshToolButton() @_refreshToolButton()
@@ -94,28 +89,27 @@ module.exports = class StepController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'click .button.complete': 'onCompleteButtonClicked' "click .button.complete": "onCompleteButtonClicked"
'click a.button.tool': 'onShowToolPlan' "click .button.tool": "onShowToolPlan"
# Private Methods ############################################################################## # Private Methods ##############################################################################
_refreshToolButton: -> _refreshToolButton: ->
inventory = new SimpleInventory {}, modPack:@_modPack inventory = new Inventory
for toolStack in @model.recipe.tools for itemId, item of @model.recipe.tools
inventory.add toolStack.itemSlug, toolStack.quantity inventory.add item
inventory.localize()
inventoryText = inventory.unparse() inventoryText = inventory.toUrlString()
@$toolButton.attr 'href', "/craft/#{inventoryText}" @$toolButton.attr "href", "/craft/#{inventoryText}"
@$toolButton.attr 'target', inventoryText @$toolButton.attr "target", inventoryText
if @canAddTools this if @canAddTools this
@$toolButton.removeClass 'disabled' @$toolButton.removeClass "disabled"
else else
@$toolButton.addClass 'disabled' @$toolButton.addClass "disabled"
_refreshCompleteButton: -> _refreshCompleteButton: ->
if @canComplete this if @canComplete this
@$completeButton.removeClass 'disabled' @$completeButton.removeClass "disabled"
else else
@$completeButton.addClass 'disabled' @$completeButton.addClass "disabled"
@@ -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'
@@ -6,6 +6,7 @@
# #
BaseController = require '../base_controller' BaseController = require '../base_controller'
ItemDisplay = require "../../models/site/item_display"
ItemSelectorController = require '../common/item_selector/item_selector_controller' ItemSelectorController = require '../common/item_selector/item_selector_controller'
UrlParams = require '../url_params' UrlParams = require '../url_params'
@@ -52,14 +53,14 @@ module.exports = class HeaderController extends BaseController
onSearch: (event, hint='')-> onSearch: (event, hint='')->
tracker.trackEvent c.tracking.category.search, 'launch' tracker.trackEvent c.tracking.category.search, 'launch'
@_selector.launch hint @_selector.launch hint
.then (itemSlug)=> .then (item)=>
if not itemSlug? if not item?
tracker.trackEvent c.tracking.category.search, 'cancel', itemSlug tracker.trackEvent c.tracking.category.search, 'cancel'
return return
tracker.trackEvent c.tracking.category.search, 'complete', itemSlug tracker.trackEvent c.tracking.category.search, 'complete', item.slug
itemDisplay = @_modPack.findItemDisplay itemSlug itemDisplay = new ItemDisplay item
@router.navigate itemDisplay.itemUrl, trigger:true @router.navigate itemDisplay.url, trigger:true
return false return false
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
+1 -6
View File
@@ -7,7 +7,7 @@
.content.view__item_page .content.view__item_page
.left .left
include ../common/youtube/youtube.jade // include ../common/youtube/youtube.jade
.right .right
.about .about
@@ -24,11 +24,6 @@
section.description.view__markdown_section section.description.view__markdown_section
section.multiblock
h2 Multiblock Construction
.panel
.view__multiblock_viewer
section.recipes section.recipes
h2 Recipes h2 Recipes
.panel .panel
+4
View File
@@ -57,6 +57,10 @@
flex: 0 0 auto; flex: 0 0 auto;
} }
} }
.view__recipe + .view__recipe {
margin-top: $size-margin-large;
}
} }
@include screen-size(mobile) { @include screen-size(mobile) {
@@ -5,17 +5,19 @@
# All rights reserved. # All rights reserved.
# #
EditableFile = require '../../models/site/editable_file' EditableFile = require "../../models/site/editable_file"
{Item} = require('crafting-guide-common').deprecated.game {Item} = require("crafting-guide-common").models
ItemGroupController = require '../common/item_group/item_group_controller' {ItemDetail} = require("crafting-guide-common").models
ItemPage = require '../../models/site/item_page' {ItemDetailJsonParser} = require("crafting-guide-common").parsing
{ItemSlug} = require('crafting-guide-common').deprecated.game ItemDisplay = require "../../models/site/item_display"
MarkdownSectionController = require '../common/markdown_section/markdown_section_controller' ItemGroupController = require "../common/item_group/item_group_controller"
MultiblockViewerController = require './multiblock_viewer/multiblock_viewer_controller' ItemPage = require "../../models/site/item_page"
PageController = require '../page_controller' MarkdownSectionController = require "../common/markdown_section/markdown_section_controller"
RecipeDetailController = require './recipe_detail/recipe_detail_controller' PageController = require "../page_controller"
VideoController = require '../common/video/video_controller' RecipeController = require "../common/recipe/recipe_controller"
w = require "when" RecipeDisplay = require "../../models/site/recipe_display"
VideoController = require "../common/video/video_controller"
w = require "when"
######################################################################################################################## ########################################################################################################################
@@ -24,71 +26,52 @@ module.exports = class ItemPageController extends PageController
@::FILE_UPLOAD_DELAY = 250 @::FILE_UPLOAD_DELAY = 250
constructor: (options={})-> constructor: (options={})->
if not options.client? then throw new Error 'options.client is required' if not options.model?.constructor is ItemPage then throw new Error "options.model must be an ItemPage instance"
if not options.itemSlug? then throw new Error 'options.itemSlug is required' if not options.client? then throw new Error "options.client is required"
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error 'options.router is required' if not options.router? then throw new Error "options.router is required"
options.model ?= new ItemPage modPack:options.modPack
options.templateName ?= 'item_page'
options.templateName ?= "item_page"
super options super options
@_client = options.client @_client = options.client
@_descriptionFile = null @_descriptionFile = null
@_enterFeedback = options.enterFeedback @_enterFeedback = options.enterFeedback
@_imageLoader = options.imageLoader @_imageLoader = options.imageLoader
@_itemSlug = options.itemSlug
@_modPack = options.modPack @_modPack = options.modPack
@_router = options.router @_router = options.router
@_triggerEditing = options.login @_triggerEditing = options.login
@_modPack.on c.event.change, =>
@tryRefresh()
@trigger c.event.change
# Event Methods ################################################################################ # Event Methods ################################################################################
craftingPlanButtonClicked: -> craftingPlanButtonClicked: ->
tracker.trackEvent c.tracking.category.craft, 'view-crafting-plan', @model.item.slug tracker.trackEvent c.tracking.category.craft, "view-crafting-plan", @model.item.slug
display = @_modPack.findItemDisplay @model.item.slug @_router.navigate @model.itemDisplay.craftingUrl, trigger:true
@_router.navigate display.craftingUrl, trigger:true
return false return false
# PageController Overrides ##################################################################### # PageController Overrides #####################################################################
getBreadcrumbs: -> getBreadcrumbs: ->
return [] unless @_itemSlug?
display = @_modPack.findItemDisplay @_itemSlug
return [] unless display.itemName? and display.modName
return [ return [
$("<a href='/browse'>Browse</a>") $("<a href=\"/browse\">Browse</a>")
$("<a href='#{c.url.mod modSlug:display.modSlug}'>#{display.modName}</a>") $("<a href=\"#{@model.itemDisplay.modUrl}\">#{@model.itemDisplay.mod.displayName}</a>")
$("<b>#{display.itemName}</b>") $("<b>#{@model.itemDisplay.name}</b>")
] ]
getExtraNav: -> getExtraNav: ->
itemSlug = @_modPack.chooseRandomItem() item = @_modPack.chooseRandomItem()
return null unless itemSlug? return null unless item?
itemDisplay = @_modPack.findItemDisplay itemSlug display = new ItemDisplay item
return $("<a href='#{itemDisplay.itemUrl}'>Random Item</a>") return $("<a href=\"#{display.url}\">Random Item</a>")
getMetaDescription: -> getMetaDescription: ->
return null unless @_itemSlug? data = itemName:@model.item.displayName, modName:@model.item.mod.displayName
display = @_modPack.findItemDisplay @_itemSlug return c.text.itemDescription data
return c.text.itemDescription display
getTitle: -> getTitle: ->
return null unless @_itemSlug? return "#{@model.item.displayName} from #{@model.item.mod.displayName}"
display = @_modPack.findItemDisplay @_itemSlug
return null unless display.itemName? and display.modName?
return "#{display.itemName} from #{display.modName}"
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
@@ -98,12 +81,11 @@ module.exports = class ItemPageController extends PageController
onDidRender: -> onDidRender: ->
options = imageLoader:@_imageLoader, modPack:@_modPack, router:@_router, show:false options = imageLoader:@_imageLoader, modPack:@_modPack, router:@_router, show:false
@_multiblockController = @addChild MultiblockViewerController, '.view__multiblock_viewer', options @_similarItemsController = @addChild ItemGroupController, ".view__item_group.similar", options
@_similarItemsController = @addChild ItemGroupController, '.view__item_group.similar', options @_usedAsToolToMakeController = @addChild ItemGroupController, ".view__item_group.usedAsToolToMake ", options
@_usedAsToolToMakeController = @addChild ItemGroupController, '.view__item_group.usedAsToolToMake ', options @_usedToMakeController = @addChild ItemGroupController, ".view__item_group.usedToMake", options
@_usedToMakeController = @addChild ItemGroupController, '.view__item_group.usedToMake', options
@_descriptionController = @addChild MarkdownSectionController, '.view__markdown_section', @_descriptionController = @addChild MarkdownSectionController, ".view__markdown_section",
client: @_client client: @_client
editable: true editable: true
modPack: @_modPack modPack: @_modPack
@@ -112,37 +94,34 @@ module.exports = class ItemPageController extends PageController
endEditing: => @_endEditingDescription() endEditing: => @_endEditingDescription()
enterFeedback: @_enterFeedback enterFeedback: @_enterFeedback
@$aboutImage = @$('.about img') @$aboutImage = @$(".about img")
@$craftingPlanButton = @$('.button.craftingPlan') @$craftingPlanButton = @$(".button.craftingPlan")
@$name = @$('.about .title') @$name = @$(".about .title")
@$officialLink = @$('.about a.officialLink') @$officialLink = @$(".about a.officialLink")
@$sourceModLink = @$('.about a.sourceMod') @$sourceModLink = @$(".about a.sourceMod")
@$aboutLinks = @$('.about .right') @$aboutLinks = @$(".about .right")
@$multiblockSection = @$('section.multiblock') @$multiblockSection = @$("section.multiblock")
@$recipeContainer = @$('section.recipes .panel') @$recipeContainer = @$("section.recipes .panel")
@$recipesSection = @$('section.recipes') @$recipesSection = @$("section.recipes")
@$recipesSectionTitle = @$('section.recipes h2') @$recipesSectionTitle = @$("section.recipes h2")
@$similarSection = @$('section.similar') @$similarSection = @$("section.similar")
@$usedAsToolToMakeSection = @$('section.usedAsToolToMake') @$usedAsToolToMakeSection = @$("section.usedAsToolToMake")
@$usedToMakeSection = @$('section.usedToMake') @$usedToMakeSection = @$("section.usedToMake")
@$videosContainer = @$('section.videos .panel') @$videosContainer = @$("section.videos .panel")
@$videosSection = @$('section.videos') @$videosSection = @$("section.videos")
@$videosSectionTitle = @$('section.videos h2') @$videosSectionTitle = @$("section.videos h2")
super super
refresh: -> refresh: ->
@_resolveItemSlug()
if @model.item? if @model.item?
display = @_modPack.findItemDisplay @model.item.slug @_imageLoader.load @model.itemDisplay.iconUrl, @$aboutImage
@_imageLoader.load display.iconUrl, @$aboutImage @$name.text @model.itemDisplay.name
@$name.text display.itemName
@_descriptionController.imageBase = c.url.itemImageDir display @_descriptionController.imageBase = c.url.itemImageDir @model.itemDisplay
if @model.item.officialUrl? if @model.item.detail?.links.length > 0
@$officialLink.attr 'href', @model.item.officialUrl @$officialLink.attr "href", @model.item.detail.links[0]
@show @$aboutLinks @show @$aboutLinks
else else
@hide @$aboutLinks @hide @$aboutLinks
@@ -162,7 +141,6 @@ module.exports = class ItemPageController extends PageController
@_refreshSourceMod() @_refreshSourceMod()
@_refreshDescription() @_refreshDescription()
@_refreshMultiblock()
@_refreshRecipes() @_refreshRecipes()
@_refreshSimilarItems() @_refreshSimilarItems()
@_refreshUsedAsToolToMake() @_refreshUsedAsToolToMake()
@@ -179,22 +157,22 @@ module.exports = class ItemPageController extends PageController
events: -> events: ->
return _.extend super, return _.extend super,
'click a.craftingPlan': 'routeLinkClick' "click a.craftingPlan": "routeLinkClick"
'click a.sourceMod': 'routeLinkClick' "click a.sourceMod": "routeLinkClick"
'click .markdown a': 'routeLinkClick' "click .markdown a": "routeLinkClick"
'click .button.craftingPlan': 'craftingPlanButtonClicked' "click .button.craftingPlan": "craftingPlanButtonClicked"
# Private Methods ############################################################################## # Private Methods ##############################################################################
_beginEditingDescription: -> _beginEditingDescription: ->
if not @user? if not @user?
global.site.login() global.site.login()
return w.reject new Error 'must be logged in to edit' return w.reject new Error "must be logged in to edit"
if not @model.item? if not @model.item?
return w.reject new Error 'must have an item' return w.reject new Error "must have an item"
pathArgs = modSlug:@_itemSlug.mod, itemSlug:@_itemSlug.item pathArgs = modSlug:@model.item.mod.id, itemSlug:@model.itemDisplay.itemSlug
attributes = attributes =
fileName: c.gitHub.file.itemDescription.fileName pathArgs fileName: c.gitHub.file.itemDescription.fileName pathArgs
path: c.gitHub.file.itemDescription.path pathArgs path: c.gitHub.file.itemDescription.path pathArgs
@@ -203,27 +181,29 @@ module.exports = class ItemPageController extends PageController
@_descriptionFile.fetch() @_descriptionFile.fetch()
.then => .then =>
if @_descriptionFile.encodedData?.length > 0 if @_descriptionFile.encodedData?.length > 0
@model.item.parse @_descriptionFile.getDecodedData 'utf8' parser = new ItemDetailJsonParser item:@model.item
parser.parse @_descriptionFile.getDecodedData "utf8"
else else
@model.item.description = '' @model.item.detail = new ItemDetail item:@model.item
@_descriptionController.model = @model.item.description @_descriptionController.model = @model.item.detail.description
_endEditingDescription: -> _endEditingDescription: ->
oldDescription = @model.item.description oldDescription = @model.item.detail.description
promises = [] promises = []
saveList = [] saveList = []
for imageFile in @_descriptionController.imageFiles for imageFile in @_descriptionController.imageFiles
saveList.push saveList.push
file: imageFile file: imageFile
message: "User-submitted image for #{@model.item.name} from #{global.hostName}" message: "User-submitted image for #{@model.item.displayName} from #{global.hostName}"
@model.item.description = @_descriptionController.model @model.item.detail.description = @_descriptionController.model
@_descriptionFile.setDecodedData @model.item.unparse() parser = new ItemDetailJsonParser item:@model.item
@_descriptionFile.setDecodedData parser.format @model.item.detail
saveList.push saveList.push
file: @_descriptionFile file: @_descriptionFile
message: "User-submitted text for #{@model.item.name} from #{global.hostName}" message: "User-submitted text for #{@model.item.displayName} from #{global.hostName}"
saveNextFile = (fileList)-> saveNextFile = (fileList)->
return w(true) if fileList.length is 0 return w(true) if fileList.length is 0
@@ -235,42 +215,39 @@ module.exports = class ItemPageController extends PageController
saveNextFile saveList saveNextFile saveList
.catch (e)=> .catch (e)=>
@model.item.description = oldDescription @model.item.detail.description = oldDescription
throw e throw e
_refreshDescription: -> _refreshDescription: ->
if @model.item?.description?.length > 0 if @model.item.detail?.description.length > 0
@_descriptionController.model = @model.item.description @_descriptionController.model = @model.item.detail.description
@_descriptionController.resetToDefaultState() @_descriptionController.resetToDefaultState()
_refreshMultiblock: ->
if @model.item?.multiblock?
@_multiblockController.model = @model.item.multiblock
@show @$multiblockSection
else
@hide @$multiblockSection
_refreshRecipes: -> _refreshRecipes: ->
@_recipeControllers ?= [] @_recipeControllers ?= []
index = 0 index = 0
recipes = @model.findRecipes() recipes = @model.findRecipes()
if recipes?.length > 0 if recipes?.length > 0
@$recipesSectionTitle.html if recipes.length is 1 then 'Recipe' else 'Recipes' @$recipesSectionTitle.html if recipes.length is 1 then "Recipe" else "Recipes"
for recipe in @model.findRecipes() for recipe in recipes
controller = @_recipeControllers[index] controller = @_recipeControllers[index]
model = new RecipeDisplay
recipe: recipe
showInputInventory: true
showOutputInventory: true
if not controller? if not controller?
controller = new RecipeDetailController controller = new RecipeController
imageLoader: @_imageLoader imageLoader: @_imageLoader
modPack: @_modPack modPack: @_modPack
model: recipe model: model
router: @_router router: @_router
@_recipeControllers.push controller @_recipeControllers.push controller
@$recipeContainer.append controller.$el @$recipeContainer.append controller.$el
controller.render() controller.render()
else else
controller.model = recipe controller.model = model
index++ index++
@show @$recipesSection @show @$recipesSection
@@ -281,38 +258,34 @@ module.exports = class ItemPageController extends PageController
@_recipeControllers.pop().remove() @_recipeControllers.pop().remove()
_refreshSimilarItems: -> _refreshSimilarItems: ->
group = @model.item?.group groupName = @model.item.groupName
if group? and group isnt Item.Group.Other if groupName? and groupName isnt Item::DEFAULT_GROUP_NAME
@_similarItemsController.title = "Other #{group}" @_similarItemsController.title = "Other #{groupName}"
@_similarItemsController.model = @model.findSimilarItems() @_similarItemsController.model = @model.findSimilarItems()
else else
@_similarItemsController.model = null @_similarItemsController.model = null
_refreshSourceMod: -> _refreshSourceMod: ->
mod = @model.item?.modVersion?.mod mod = @model.item.mod
if mod?.name?.length > 0 @$sourceModLink.attr "href", c.url.mod @model.itemDisplay
@$sourceModLink.attr 'href', c.url.mod modSlug:mod.slug @$sourceModLink.text mod.name
@$sourceModLink.text mod.name @show @$sourceModLink
@show @$sourceModLink
else
@hide @$sourceModLink
_refreshUsedAsToolToMake: -> _refreshUsedAsToolToMake: ->
@_usedAsToolToMakeController.title = 'Used as Tool to Make' @_usedAsToolToMakeController.title = "Used as Tool to Make"
@_usedAsToolToMakeController.model = @model.findToolForRecipes() @_usedAsToolToMakeController.model = @model.findToolForItems()
_refreshUsedToMake: -> _refreshUsedToMake: ->
@_usedToMakeController.title = 'Used to Make' @_usedToMakeController.title = "Used to Make"
@_usedToMakeController.model = @model.findComponentInItems() @_usedToMakeController.model = @model.findComponentInItems()
_refreshVideos: -> _refreshVideos: ->
@_videoControllers ?= [] @_videoControllers ?= []
index = 0 index = 0
videos = @model?.item?.videos or [] videos = @model.item.detail?.videos
if videos? and videos.length > 0 if videos? and videos.length > 0
@$videosSectionTitle.html if videos.length is 1 then 'Video' else 'Videos' @$videosSectionTitle.html if videos.length is 1 then "Video" else "Videos"
for video in videos for video in videos
controller = @_videoControllers[index] controller = @_videoControllers[index]
@@ -332,15 +305,3 @@ module.exports = class ItemPageController extends PageController
while @_videoControllers.length > index while @_videoControllers.length > index
@_videoControllers.pop().remove() @_videoControllers.pop().remove()
_resolveItemSlug: ->
return if @model.item?
item = @_modPack.findItem @_itemSlug, includeDisabled:true
if item?
if not ItemSlug.equal item.slug, @_itemSlug
@_router.navigate c.url.item(modSlug:item.slug.mod, itemSlug:item.slug.item), trigger:true
return
@model.item = item
item.fetch()
item.on c.event.sync, => @refresh()
@@ -1,99 +0,0 @@
#
# Crafting Guide - multiblock_viewer_controller.coffee
#
# Copyright © 2014-2017 by Redwood Labs
# All rights reserved.
#
BaseController = require '../../base_controller'
InventoryController = require '../../common/inventory/inventory_controller'
MultiblockController = require './multiblock/multiblock_controller'
########################################################################################################################
module.exports = class MultiblockViewerController 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 = 'item_page/multiblock_viewer'
super options
@_imageLoader = options.imageLoader
@_modPack = options.modPack
@_hoverTimer = null
@_router = options.router
# Event Methods ################################################################################
onBackClicked: ->
return if @$backButton.hasClass 'disabled'
tracker.trackEvent c.tracking.category.multiblock, 'back'
@multiblockController.goBackLayer()
@refresh()
onNextClicked: ->
return if @$nextButton.hasClass 'disabled'
tracker.trackEvent c.tracking.category.multiblock, 'next'
@multiblockController.goNextLayer()
@refresh()
onBlockHovered: (itemDisplay)->
if itemDisplay?
@$captionText.html itemDisplay.itemName
@_imageLoader.load itemDisplay.iconUrl, @$captionIcon
else
@$captionText.html '&nbsp;'
@$captionIcon.attr 'src', '/images/empty.png'
# BaseController Overrides #####################################################################
onDidRender: ->
@completeInventoryController = @addChild InventoryController, '.view__inventory.complete',
editable: false
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
@layerInventoryController = @addChild InventoryController, '.view__inventory.layer',
editable: false
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
@multiblockController = @addChild MultiblockController, '.view__multiblock',
imageLoader: @_imageLoader
modPack: @_modPack
onHovering: (itemDisplay)=> @onBlockHovered(itemDisplay)
@$backButton = @$('.button.back')
@$nextButton = @$('.button.next')
@$captionText = @$('.caption p')
@$captionIcon = @$('.caption img')
super
refresh: ->
if @model?
@completeInventoryController.model = @model.inventory
@layerInventoryController.model = @model.getLayerInventory @multiblockController.currentLayer
@multiblockController.model = @model
if @multiblockController.hasBackLayer()
@$backButton.removeClass 'disabled'
else
@$backButton.addClass 'disabled'
if @multiblockController.hasNextLayer()
@$nextButton.removeClass 'disabled'
else
@$nextButton.addClass 'disabled'
super
# Backbone.View Overrides ######################################################################
events: ->
_.extend super,
'click .button.back': 'onBackClicked'
'click .button.next': 'onNextClicked'
@@ -5,21 +5,22 @@
# All rights reserved. # All rights reserved.
# #
BaseController = require '../../base_controller' BaseController = require "../../base_controller"
CraftingGridController = require '../../common/crafting_grid/crafting_grid_controller' CraftingGridController = require "../../common/crafting_grid/crafting_grid_controller"
{Inventory} = require('crafting-guide-common').deprecated.game {Inventory} = require("crafting-guide-common").models
InventoryController = require '../../common/inventory/inventory_controller' InventoryController = require "../../common/inventory/inventory_controller"
{StringBuilder} = require('crafting-guide-common').util ItemDisplay = require "../../../models/site/item_display"
{StringBuilder} = require("crafting-guide-common").util
######################################################################################################################## ########################################################################################################################
module.exports = class RecipeDetailController extends BaseController module.exports = class RecipeDetailController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader 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.modPack? then throw new Error "options.modPack is required"
if not options.router? then throw new Error 'options.router is required' if not options.router? then throw new Error "options.router is required"
options.templateName = 'item_page/recipe_detail' options.templateName = "item_page/recipe_detail"
super options super options
@_imageLoader = options.imageLoader @_imageLoader = options.imageLoader
@@ -29,26 +30,26 @@ module.exports = class RecipeDetailController extends BaseController
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@gridController = @addChild CraftingGridController, '.view__crafting_grid', @gridController = @addChild CraftingGridController, ".view__crafting_grid",
imageLoader: @_imageLoader imageLoader: @_imageLoader
modPack: @_modPack modPack: @_modPack
router: @_router router: @_router
@inputController = @addChild InventoryController, '.input .view__inventory', @inputController = @addChild InventoryController, ".input .view__inventory",
editable: false editable: false
imageLoader: @_imageLoader imageLoader: @_imageLoader
model: new Inventory model: new Inventory
modPack: @_modPack modPack: @_modPack
router: @_router router: @_router
@outputController = @addChild InventoryController, '.output .view__inventory', @outputController = @addChild InventoryController, ".output .view__inventory",
editable: false editable: false
imageLoader: @_imageLoader imageLoader: @_imageLoader
model: new Inventory model: new Inventory
modPack: @_modPack modPack: @_modPack
router: @_router router: @_router
@$toolContainer = @$('.tool') @$toolContainer = @$(".tool")
super super
refresh: -> refresh: ->
@@ -67,33 +68,33 @@ module.exports = class RecipeDetailController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'click a': 'routeLinkClick' "click a": "routeLinkClick"
# Private Methods ############################################################################## # Private Methods ##############################################################################
_refreshInputs: -> _refreshInputs: ->
inputs = @inputController.model inputs = @inputController.model
inputs.clear() inputs.clear()
return unless @model?
if @model? for itemId, item of @model.inputs
for stack in @model.input inputs.add item, @model.computeQuantityRequired item
inputs.add stack.itemSlug, @model.getQuantityRequired stack.itemSlug
_refreshOutputs: -> _refreshOutputs: ->
outputs = @outputController.model outputs = @outputController.model
outputs.clear() outputs.clear()
return unless @model?
if @model? outputs.add @model.output.item, @model.output.quantity
for stack in @model.output for itemId, item of @model.extras
outputs.add stack.itemSlug, @model.getQuantityProduced stack.itemSlug outputs.add item, @model.computeQuantityProduced item
_refreshTools: -> _refreshTools: ->
@$toolContainer.empty() @$toolContainer.empty()
return unless @model? return unless @model?
builder = new StringBuilder toolLinks = []
builder.loop @model.tools, delimiter:', ', onEach:(b, stack)=> for itemId, item of @model.tools
display = @_modPack.findItemDisplay stack.itemSlug display = new ItemDisplay item
b.push "<a href=\"#{display.itemUrl}\">#{display.itemName}</a>" toolLinks.push "<a href=\"#{display.url}\">#{display.name}</a>"
@$toolContainer.html builder.toString() @$toolContainer.html toolLinks.join ", "
@@ -28,27 +28,16 @@ module.exports = class ModPageController extends PageController
@_modPack = options.modPack @_modPack = options.modPack
@_router = options.router @_router = options.router
# Property Methods #############################################################################
Object.defineProperties @prototype,
effectiveModVersion:
get: ->
modVersion = @model.activeModVersion
modVersion ?= @model.getModVersion Mod.Version.Latest
modVersion.fetch() if modVersion?
return modVersion
# PageController Overrides ##################################################################### # PageController Overrides #####################################################################
getBreadcrumbs: -> getBreadcrumbs: ->
return [ return [
$('<a href="/browse">Browse</a>') $('<a href="/browse">Browse</a>')
$("<b>#{@model.name}</b>") $("<b>#{@model.displayName}</b>")
] ]
getTitle: -> getTitle: ->
return @model.name return @model.displayName
# BaseController Overrides ##################################################################### # BaseController Overrides #####################################################################
@@ -92,8 +81,8 @@ module.exports = class ModPageController extends PageController
@$documentationLink.attr 'href', @model.documentationUrl @$documentationLink.attr 'href', @model.documentationUrl
@$downloadLink.attr 'href', @model.downloadUrl @$downloadLink.attr 'href', @model.downloadUrl
@$homePageLink.attr 'href', @model.homePageUrl @$homePageLink.attr 'href', @model.homePageUrl
@$logo.attr 'src', c.url.modIcon modSlug:@model.slug @$logo.attr 'src', c.url.modIcon modId:@model.id
@$title.text @model.name @$title.text @model.displayName
else else
@$author.text '' @$author.text ''
@$description.text '' @$description.text ''
@@ -106,29 +95,24 @@ module.exports = class ModPageController extends PageController
_refreshItemGroups: -> _refreshItemGroups: ->
@_groupControllers ?= [] @_groupControllers ?= []
groupIndex = 0 groupIndex = 0
modVersion = @effectiveModVersion
if modVersion? for groupName, items of @model.itemGroups
modVersion.eachGroup (group)=> controller = @_groupControllers[groupIndex]
controller = @_groupControllers[groupIndex] if not controller?
items = modVersion.allItemsInGroup group controller = new ItemGroupController
if not controller? imageLoader: @_imageLoader
controller = new ItemGroupController model: items
imageLoader: @_imageLoader modPack: @_modPack
model: items router: @_router
modPack: @_modPack title: groupName
router: @_router
title: if group is Item.Group.Other then 'Items' else group
_.defer => @_groupControllers.push controller
@_groupControllers.push controller @$itemGroups.append controller.$el
@$itemGroups.append controller.$el controller.render()
controller.render() else
else controller.model = items
controller.modVersion = modVersion controller.refresh()
controller.model = items groupIndex++
controller.refresh()
groupIndex++
while @_groupControllers.length > groupIndex + 1 while @_groupControllers.length > groupIndex + 1
@_groupControllers.pop().remove() @_groupControllers.pop().remove()
+55 -50
View File
@@ -5,15 +5,16 @@
# All rights reserved. # All rights reserved.
# #
BrowsePageController = require './browse_page/browse_page_controller' BrowsePageController = require "./browse_page/browse_page_controller"
CraftPageController = require './craft_page/craft_page_controller' CraftPageController = require "./craft_page/craft_page_controller"
ItemPageController = require './item_page/item_page_controller' ItemPage = require "../models/site/item_page"
{ItemSlug} = require('crafting-guide-common').deprecated.game ItemPageController = require "./item_page/item_page_controller"
LoginPageController = require './login_page/login_page_controller' {ItemSlug} = require("crafting-guide-common").deprecated.game
ModPageController = require './mod_page/mod_page_controller' LoginPageController = require "./login_page/login_page_controller"
NewsPageController = require './news_page/news_page_controller' ModPageController = require "./mod_page/mod_page_controller"
TutorialPageController = require './tutorial_page/tutorial_page_controller' NewsPageController = require "./news_page/news_page_controller"
UrlParams = require './url_params' TutorialPageController = require "./tutorial_page/tutorial_page_controller"
UrlParams = require "./url_params"
######################################################################################################################## ########################################################################################################################
@@ -34,50 +35,50 @@ module.exports = class Router extends Backbone.Router
tracker.trackPageView() tracker.trackPageView()
routes: routes:
'': 'route__home' '': 'route__home'
'/': 'route__home' '/': 'route__home'
'/index.html': 'route__home' '/index.html': 'route__home'
'browse': 'route__browse' 'browse': 'route__browse'
'browse/': 'route__browse' 'browse/': 'route__browse'
'browse/index.html': 'route__browse' 'browse/index.html': 'route__browse'
'browse/:modSlug': 'route__browseMod' 'browse/:modId': 'route__browseMod'
'browse/:modSlug/': 'route__browseMod' 'browse/:modId/': 'route__browseMod'
'browse/:modSlug/index.html': 'route__browseMod' 'browse/:modId/index.html': 'route__browseMod'
'browse/:modSlug/:itemSlug': 'route__browseModItem' 'browse/:modId/:itemSlug': 'route__browseModItem'
'browse/:modSlug/:itemSlug/': 'route__browseModItem' 'browse/:modId/:itemSlug/': 'route__browseModItem'
'browse/:modSlug/:itemSlug/index.html': 'route__browseModItem' 'browse/:modId/:itemSlug/index.html': 'route__browseModItem'
'browse/:modSlug/tutorials/:tutorialSlug': 'route__browseTutorial' 'browse/:modId/tutorials/:tutorialSlug': 'route__browseTutorial'
'browse/:modSlug/tutorials/:tutorialSlug/': 'route__browseTutorial' 'browse/:modId/tutorials/:tutorialSlug/': 'route__browseTutorial'
'browse/:modSlug/tutorials/:tutorialSlug/index.html': 'route__browseTutorial' 'browse/:modId/tutorials/:tutorialSlug/index.html': 'route__browseTutorial'
'configure': 'route__configure' 'configure': 'route__configure'
'configure/': 'route__configure' 'configure/': 'route__configure'
'configure/index.html': 'route__configure' 'configure/index.html': 'route__configure'
'craft': 'route__craft' 'craft': 'route__craft'
'craft/': 'route__craft' 'craft/': 'route__craft'
'craft/index.html': 'route__craft' 'craft/index.html': 'route__craft'
'craft/:text': 'route__craft' 'craft/:text': 'route__craft'
'craft/:text/': 'route__craft' 'craft/:text/': 'route__craft'
'craft/:text/index.html': 'route__craft' 'craft/:text/index.html': 'route__craft'
'login': 'route__login' 'login': 'route__login'
'login/': 'route__login' 'login/': 'route__login'
'login/index.html': 'route__login' 'login/index.html': 'route__login'
'news': 'route__news' 'news': 'route__news'
'news/': 'route__news' 'news/': 'route__news'
'news/index.html': 'route__news' 'news/index.html': 'route__news'
'item/:itemSlug': 'deprecated__item' 'item/:itemSlug': 'deprecated__item'
'crafting/(:text)': 'deprecated__crafting' 'crafting/(:text)': 'deprecated__crafting'
'mod/:modSlug': 'deprecated__mod' 'mod/:modSlug': 'deprecated__mod'
'mod/:modSlug/:itemSlug': 'deprecated__modItem' 'mod/:modSlug/:itemSlug': 'deprecated__modItem'
# Route Methods ################################################################################ # Route Methods ################################################################################
@@ -92,15 +93,20 @@ module.exports = class Router extends Backbone.Router
route__browse: -> route__browse: ->
@_siteController.setPage 'browse', new BrowsePageController @_makeOptions {} @_siteController.setPage 'browse', new BrowsePageController @_makeOptions {}
route__browseMod: (modSlug)-> route__browseMod: (modId)->
controller = new ModPageController @_makeOptions() controller = new ModPageController @_makeOptions()
controller.model = @_siteController.modPack.getMod modSlug controller.model = @_siteController.modPack.mods[modId]
@_siteController.setPage 'browseMod', controller @_siteController.setPage 'browseMod', controller
route__browseModItem: (modSlug, itemSlug)-> route__browseModItem: (modId, itemSlug)->
item = @_siteController.modPack.findItemBySlug itemSlug, modId:modId
if not item? then throw new Error "could not find item #{modId}__#{itemSlug}"
itemPage = new ItemPage item
itemPage.loadDetails()
params = new UrlParams login:{type:'boolean', default:false} params = new UrlParams login:{type:'boolean', default:false}
slug = new ItemSlug modSlug, itemSlug controller = new ItemPageController @_makeOptions {model:itemPage, login:params.login}
controller = new ItemPageController @_makeOptions {itemSlug:slug, login:params.login}
@_siteController.setPage 'browseModItem', controller @_siteController.setPage 'browseModItem', controller
route__browseTutorial: (modSlug, tutorialSlug)-> route__browseTutorial: (modSlug, tutorialSlug)->
@@ -113,8 +119,7 @@ module.exports = class Router extends Backbone.Router
@route__craft() @route__craft()
route__craft: (text)-> route__craft: (text)->
controller = new CraftPageController @_makeOptions {} controller = new CraftPageController @_makeOptions params:inventoryText:text
controller.model.params = inventoryText:text
@_siteController.setPage 'craft', controller @_siteController.setPage 'craft', controller
route__login: -> route__login: ->
+7 -19
View File
@@ -7,6 +7,7 @@
AdsenseController = require './common/adsense/adsense_controller' AdsenseController = require './common/adsense/adsense_controller'
BaseController = require './base_controller' BaseController = require './base_controller'
c = require "../../common/constants"
FeedbackController = require './feedback/feedback_controller' FeedbackController = require './feedback/feedback_controller'
FileCache = require '../models/site/file_cache' FileCache = require '../models/site/file_cache'
FooterController = require './footer/footer_controller' FooterController = require './footer/footer_controller'
@@ -23,14 +24,14 @@ module.exports = class SiteController extends BaseController
constructor: (options={})-> constructor: (options={})->
if not options.client? then throw new Error 'options.client is required' if not options.client? then throw new Error 'options.client is required'
if not options.modPack? then throw new Error 'options.modPack is required'
if not options.storage? then throw new Error 'options.storage is required' if not options.storage? then throw new Error 'options.storage is required'
options.el = 'html' options.el = 'html'
super options super options
@client = options.client @client = options.client
@fileCache = new FileCache c.url.modpackArchive()
@imageLoader = new ImageLoader defaultUrl:'/images/unknown.png' @imageLoader = new ImageLoader defaultUrl:'/images/unknown.png'
@modPack = new ModPack {}, fileCache:@fileCache @modPack = options.modPack
@router = new Router this @router = new Router this
@storage = options.storage @storage = options.storage
@@ -41,23 +42,6 @@ module.exports = class SiteController extends BaseController
# Public Methods ############################################################################### # Public Methods ###############################################################################
loadDefaultModPack: ->
makeResponder = (m)-> return ->
m.activeModVersion.fetch() if m.activeModVersion?
for modSlug, modData of c.defaultMods
mod = new Mod {slug:modSlug}, {fileCache:@fileCache}
mod.on c.event.change + ':activeModVersion', makeResponder mod
@storage.register "mod:#{mod.slug}", mod, 'activeVersion', modData.defaultVersion
mod.fetch()
@modPack.addMod mod
if global.env isnt 'prerender'
@modPack.once c.event.sync, =>
@$pageContent.removeClass 'hidden'
@$pageContentLoading.addClass 'hidden'
loadCurrentUser: -> loadCurrentUser: ->
@client.getCurrentUser() @client.getCurrentUser()
.then (response)=> .then (response)=>
@@ -129,6 +113,10 @@ module.exports = class SiteController extends BaseController
@_feedbackController = @addChild FeedbackController, '.view__feedback' @_feedbackController = @addChild FeedbackController, '.view__feedback'
if global.env isnt "prerender"
@$pageContent.removeClass "hidden"
@$pageContentLoading.addClass "hidden"
# Private Methods ############################################################################## # Private Methods ##############################################################################
setPage: (page, controller)-> setPage: (page, controller)->
+1 -4
View File
@@ -81,7 +81,7 @@ duration.slow = 1200
exports.gitHub = gitHub = {} exports.gitHub = gitHub = {}
gitHub.file = {} gitHub.file = {}
gitHub.file.itemDescription = {} gitHub.file.itemDescription = {}
gitHub.file.itemDescription.fileName = _.template "item.cg" gitHub.file.itemDescription.fileName = _.template "item.json"
gitHub.file.itemDescription.path = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>" gitHub.file.itemDescription.path = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>"
exports.key = key = {} exports.key = key = {}
@@ -99,9 +99,6 @@ login.clientIds =
'staging': '3d75ed772ce5004180d6' 'staging': '3d75ed772ce5004180d6'
'production': 'ce71be7f66926ff6ff38' 'production': 'ce71be7f66926ff6ff38'
exports.modpack = modpack = {}
modpack.default = "crafting-guide-default"
exports.opacity = opacity = {} exports.opacity = opacity = {}
opacity.hidden = 1e-6 opacity.hidden = 1e-6
opacity.shown = 1 opacity.shown = 1
+1
View File
@@ -41,3 +41,4 @@ module.exports = class CraftingGuideServer
console.log "CraftingGuide is shutting down" console.log "CraftingGuide is shutting down"
@httpServer.close() => @httpServer.close() =>
resolve this resolve this
+1 -1
View File
@@ -26,7 +26,7 @@ exports.installBefore = (app)->
] ]
exports.installAfter = (app)-> exports.installAfter = (app)->
app.use '/data', express.static '../../crafting-guide-data/data/', etag:false, maxAge: 0 app.use '/data', express.static '/src/crafting-guide/data/data/', etag:false, maxAge: 0
app.use express.static './static', etag: false, maxAge: 0 app.use express.static './static', etag: false, maxAge: 0
# Middleware Functions ##################################################################################### # Middleware Functions #####################################################################################