yay, load pets and junk
This commit is contained in:
parent
0e9b76b4d4
commit
72b7ce1ac6
2 changed files with 129 additions and 24 deletions
|
@ -21,21 +21,26 @@
|
||||||
var Neopia = {
|
var Neopia = {
|
||||||
User: {
|
User: {
|
||||||
get: function(id) {
|
get: function(id) {
|
||||||
return Neopia.getJSON("/users/" + id).then(function(response) {
|
return $.getJSON(Neopia.API_URL + "/users/" + id).then(function(response) {
|
||||||
return response.users[0];
|
return response.users[0];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Customization: {
|
Customization: {
|
||||||
get: function(petId) {
|
request: function(petId, type) {
|
||||||
return Neopia.getJSON("/pets/" + petId + "/customization").then(function(response) {
|
return $.ajax({
|
||||||
return response.custom_pet;
|
dataType: "json",
|
||||||
|
type: type,
|
||||||
|
url: Neopia.API_URL + "/pets/" + petId + "/customization"
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
get: function(petId) {
|
||||||
|
return this.request(petId, "GET");
|
||||||
|
},
|
||||||
|
post: function(petId) {
|
||||||
|
return this.request(petId, "POST");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getJSON: function(path) {
|
|
||||||
return $.getJSON(Neopia.API_URL + path);
|
|
||||||
},
|
|
||||||
init: function() {
|
init: function() {
|
||||||
var hostEl = $('meta[name=neopia-host]');
|
var hostEl = $('meta[name=neopia-host]');
|
||||||
if (!hostEl.length) {
|
if (!hostEl.length) {
|
||||||
|
@ -52,12 +57,34 @@
|
||||||
var Modeling = {
|
var Modeling = {
|
||||||
_customizationsByPetId: {},
|
_customizationsByPetId: {},
|
||||||
_customizations: [],
|
_customizations: [],
|
||||||
|
_itemsById: {},
|
||||||
_items: [],
|
_items: [],
|
||||||
_addCustomization: function(customization) {
|
_addCustomization: function(customization) {
|
||||||
this._customizationsByPetId[customization.name] = customization;
|
// Set all equipped, interesting items' statuses as success and cross
|
||||||
|
// them off the list.
|
||||||
|
var itemsById = this._itemsById;
|
||||||
|
var equippedByZone = customization.custom_pet.equipped_by_zone;
|
||||||
|
var closetItems = customization.closet_items;
|
||||||
|
Object.keys(equippedByZone).forEach(function(zoneId) {
|
||||||
|
var equippedClosetId = equippedByZone[zoneId].closet_obj_id;
|
||||||
|
var equippedObjectId = closetItems[equippedClosetId].obj_info_id;
|
||||||
|
if (itemsById.hasOwnProperty(equippedObjectId)) {
|
||||||
|
// TODO: i18n title
|
||||||
|
customization.statusByItemId[equippedObjectId] = "success";
|
||||||
|
itemsById[equippedObjectId].el.find("span[data-body-id=" +
|
||||||
|
customization.custom_pet.body_id + "]").addClass("modeled")
|
||||||
|
.attr("title", "You just finished modeling this—thanks so much!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._customizationsByPetId[customization.custom_pet.name] = customization;
|
||||||
this._customizations = this._buildCustomizations();
|
this._customizations = this._buildCustomizations();
|
||||||
this._update();
|
this._update();
|
||||||
},
|
},
|
||||||
|
_addNewCustomization: function(customization) {
|
||||||
|
customization.loadingForItemId = null;
|
||||||
|
customization.statusByItemId = {};
|
||||||
|
this._addCustomization(customization);
|
||||||
|
},
|
||||||
_buildCustomizations: function() {
|
_buildCustomizations: function() {
|
||||||
var modelCustomizationsByPetId = this._customizationsByPetId;
|
var modelCustomizationsByPetId = this._customizationsByPetId;
|
||||||
return Object.keys(modelCustomizationsByPetId).map(function(petId) {
|
return Object.keys(modelCustomizationsByPetId).map(function(petId) {
|
||||||
|
@ -65,24 +92,27 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
_createItems: function($) {
|
_createItems: function($) {
|
||||||
|
var itemsById = this._itemsById;
|
||||||
this._items = $('#newest-unmodeled-items li').map(function() {
|
this._items = $('#newest-unmodeled-items li').map(function() {
|
||||||
var el = $(this);
|
var el = $(this);
|
||||||
var name = el.find('h2').text();
|
var item = {
|
||||||
return {
|
|
||||||
component: React.renderComponent(<ModelForItem itemName={name} />,
|
|
||||||
el.find('.models').get(0)),
|
|
||||||
el: el,
|
el: el,
|
||||||
id: el.attr('data-item-id'),
|
id: el.attr('data-item-id'),
|
||||||
|
name: el.find('h2').text(),
|
||||||
missingBodyIdsPresenceMap: el.find('span[data-body-id]').toArray().reduce(function(map, node) {
|
missingBodyIdsPresenceMap: el.find('span[data-body-id]').toArray().reduce(function(map, node) {
|
||||||
map[$(node).attr('data-body-id')] = true;
|
map[$(node).attr('data-body-id')] = true;
|
||||||
return map;
|
return map;
|
||||||
}, {})
|
}, {})
|
||||||
};
|
};
|
||||||
|
item.component = React.renderComponent(<ModelForItem item={item} />,
|
||||||
|
el.find('.models').get(0));
|
||||||
|
itemsById[item.id] = item;
|
||||||
|
return item;
|
||||||
}).toArray();
|
}).toArray();
|
||||||
},
|
},
|
||||||
_loadPetCustomization: function(neopiaPetId) {
|
_loadPetCustomization: function(neopiaPetId) {
|
||||||
return Neopia.Customization.get(neopiaPetId)
|
return Neopia.Customization.get(neopiaPetId)
|
||||||
.done(this._addCustomization.bind(this))
|
.done(this._addNewCustomization.bind(this))
|
||||||
.fail(function() {
|
.fail(function() {
|
||||||
console.error("couldn't load pet %s", neopiaPetId);
|
console.error("couldn't load pet %s", neopiaPetId);
|
||||||
});
|
});
|
||||||
|
@ -100,11 +130,23 @@
|
||||||
_loadManyUsersCustomizations: function(neopiaUserIds) {
|
_loadManyUsersCustomizations: function(neopiaUserIds) {
|
||||||
return neopiaUserIds.map(this._loadUserCustomizations.bind(this));
|
return neopiaUserIds.map(this._loadUserCustomizations.bind(this));
|
||||||
},
|
},
|
||||||
|
_startLoading: function(neopiaPetId, itemId) {
|
||||||
|
var customization = this._customizationsByPetId[neopiaPetId];
|
||||||
|
customization.loadingForItemId = itemId;
|
||||||
|
customization.statusByItemId[itemId] = "loading";
|
||||||
|
this._update();
|
||||||
|
},
|
||||||
|
_stopLoading: function(neopiaPetId, itemId, status) {
|
||||||
|
var customization = this._customizationsByPetId[neopiaPetId];
|
||||||
|
customization.loadingForItemId = null;
|
||||||
|
customization.statusByItemId[itemId] = status;
|
||||||
|
this._update();
|
||||||
|
},
|
||||||
_update: function() {
|
_update: function() {
|
||||||
var customizations = this._customizations;
|
var customizations = this._customizations;
|
||||||
this._items.forEach(function(item) {
|
this._items.forEach(function(item) {
|
||||||
var filteredCustomizations = customizations.filter(function(c) {
|
var filteredCustomizations = customizations.filter(function(c) {
|
||||||
return item.missingBodyIdsPresenceMap[c.body_id];
|
return item.missingBodyIdsPresenceMap[c.custom_pet.body_id];
|
||||||
});
|
});
|
||||||
item.component.setState({customizations: filteredCustomizations});
|
item.component.setState({customizations: filteredCustomizations});
|
||||||
});
|
});
|
||||||
|
@ -116,6 +158,29 @@
|
||||||
var search = document.location.search;
|
var search = document.location.search;
|
||||||
var users = search.indexOf('=') >= 0 ? search.split('=')[1].split(',') : '';
|
var users = search.indexOf('=') >= 0 ? search.split('=')[1].split(',') : '';
|
||||||
this._loadManyUsersCustomizations(users);
|
this._loadManyUsersCustomizations(users);
|
||||||
|
},
|
||||||
|
model: function(neopiaPetId, itemId) {
|
||||||
|
var oldCustomization = this._customizationsByPetId[neopiaPetId];
|
||||||
|
var itemsById = this._itemsById;
|
||||||
|
this._startLoading(neopiaPetId, itemId);
|
||||||
|
return Neopia.Customization.post(neopiaPetId)
|
||||||
|
.done(function(newCustomization) {
|
||||||
|
// Add this field as null for consistency.
|
||||||
|
newCustomization.loadingForItemId = null;
|
||||||
|
|
||||||
|
// Copy previous statuses.
|
||||||
|
newCustomization.statusByItemId = oldCustomization.statusByItemId;
|
||||||
|
|
||||||
|
// Set the attempted item's status as unworn (to possibly be
|
||||||
|
// overridden by the upcoming loop in _addCustomization).
|
||||||
|
newCustomization.statusByItemId[itemId] = "unworn";
|
||||||
|
|
||||||
|
// Now, finally, let's overwrite the old customization with the new.
|
||||||
|
Modeling._addCustomization(newCustomization);
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
Modeling._stopLoading(neopiaPetId, itemId, "error");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,15 +189,15 @@
|
||||||
return {customizations: []};
|
return {customizations: []};
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var itemName = this.props.itemName;
|
var item = this.props.item;
|
||||||
function createModelPet(customization) {
|
function createModelPet(customization) {
|
||||||
return <ModelPet customization={customization}
|
return <ModelPet customization={customization}
|
||||||
itemName={itemName}
|
item={item}
|
||||||
key={customization.name} />;
|
key={customization.custom_pet.name} />;
|
||||||
}
|
}
|
||||||
var sortedCustomizations = this.state.customizations.sort(function(a, b) {
|
var sortedCustomizations = this.state.customizations.sort(function(a, b) {
|
||||||
var aName = a.name.toLowerCase();
|
var aName = a.custom_pet.name.toLowerCase();
|
||||||
var bName = b.name.toLowerCase();
|
var bName = b.custom_pet.name.toLowerCase();
|
||||||
if (aName < bName) return -1;
|
if (aName < bName) return -1;
|
||||||
if (aName > bName) return 1;
|
if (aName > bName) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -143,16 +208,38 @@
|
||||||
|
|
||||||
var ModelPet = React.createClass({
|
var ModelPet = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
var petName = this.props.customization.name;
|
var petName = this.props.customization.custom_pet.name;
|
||||||
var itemName = this.props.itemName;
|
var status = this.props.customization.statusByItemId[this.props.item.id];
|
||||||
|
var loadingForItemId = this.props.customization.loadingForItemId;
|
||||||
|
var disabled = (status === "loading"
|
||||||
|
|| status === "success");
|
||||||
|
if (loadingForItemId !== null && loadingForItemId !== this.props.item.id) {
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
var itemName = this.props.item.name;
|
||||||
var imageSrc = "http://pets.neopets.com/cpn/" + petName + "/1/1.png";
|
var imageSrc = "http://pets.neopets.com/cpn/" + petName + "/1/1.png";
|
||||||
// TODO: i18n
|
// TODO: i18n
|
||||||
var title = "Submit " + petName + " as a model, especially if they're " +
|
var title = "Submit " + petName + " as a model, especially if they're " +
|
||||||
"wearing the " + itemName + "!";
|
"wearing the " + itemName + "!";
|
||||||
return <li><button title={title}>
|
if (status === "success") {
|
||||||
|
var statusMessage = "Thanks! <3";
|
||||||
|
} else if (status === "unworn") {
|
||||||
|
var statusMessage = "Not wearing this item.";
|
||||||
|
} else if (status === "error") {
|
||||||
|
var statusMessage = "Couldn't load. Try again?";
|
||||||
|
} else {
|
||||||
|
var statusMessage ="";
|
||||||
|
}
|
||||||
|
return <li data-status={status}><button onClick={this.handleClick} title={title} disabled={disabled}>
|
||||||
<img src={imageSrc} />
|
<img src={imageSrc} />
|
||||||
<span>{petName}</span>
|
<div>
|
||||||
|
<span className="pet-name">{petName}</span>
|
||||||
|
<span className="message">{statusMessage}</span>
|
||||||
|
</div>
|
||||||
</button></li>;
|
</button></li>;
|
||||||
|
},
|
||||||
|
handleClick: function(e) {
|
||||||
|
Modeling.model(this.props.customization.custom_pet.name, this.props.item.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,9 @@ body.outfits-new
|
||||||
p
|
p
|
||||||
font-family: $main-font
|
font-family: $main-font
|
||||||
margin-bottom: .5em
|
margin-bottom: .5em
|
||||||
|
.modeled
|
||||||
|
color: $soft-text-color
|
||||||
|
text-decoration: line-through
|
||||||
|
|
||||||
.models
|
.models
|
||||||
font-size: 85%
|
font-size: 85%
|
||||||
|
@ -236,17 +239,32 @@ body.outfits-new
|
||||||
background: $module-bg-color
|
background: $module-bg-color
|
||||||
border: 1px solid $module-border-color
|
border: 1px solid $module-border-color
|
||||||
padding-right: 8px
|
padding-right: 8px
|
||||||
|
text-align: left
|
||||||
|
|
||||||
&:active
|
&:active
|
||||||
position: relative
|
position: relative
|
||||||
top: 1px
|
top: 1px
|
||||||
|
|
||||||
|
img, div
|
||||||
|
display: inline-block
|
||||||
|
vertical-align: top
|
||||||
|
|
||||||
img
|
img
|
||||||
height: 40px
|
height: 40px
|
||||||
margin-right: 8px
|
margin-right: 8px
|
||||||
vertical-align: middle
|
|
||||||
width: 40px
|
width: 40px
|
||||||
|
|
||||||
|
div
|
||||||
|
line-height: 1.25
|
||||||
|
padding-top: 10px
|
||||||
|
|
||||||
|
.pet-name, .message
|
||||||
|
display: block
|
||||||
|
|
||||||
|
.message
|
||||||
|
font-style: italic
|
||||||
|
font-size: 85%
|
||||||
|
|
||||||
#latest-contribution
|
#latest-contribution
|
||||||
+subtle-banner
|
+subtle-banner
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue