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