hooray, animated items seem to be working?! ^w^
This commit is contained in:
parent
a4d159381c
commit
d27395bda2
5 changed files with 134 additions and 397 deletions
|
@ -6,6 +6,7 @@ import { CSSTransition, TransitionGroup } from "react-transition-group";
|
||||||
|
|
||||||
import OutfitCanvas, {
|
import OutfitCanvas, {
|
||||||
OutfitCanvasImage,
|
OutfitCanvasImage,
|
||||||
|
OutfitCanvasMovie,
|
||||||
loadImage,
|
loadImage,
|
||||||
useEaselDependenciesLoader,
|
useEaselDependenciesLoader,
|
||||||
} from "./OutfitCanvas";
|
} from "./OutfitCanvas";
|
||||||
|
@ -152,13 +153,21 @@ export function OutfitLayers({
|
||||||
!loadingEasel && (
|
!loadingEasel && (
|
||||||
<FullScreenCenter>
|
<FullScreenCenter>
|
||||||
<OutfitCanvas width={canvasSize} height={canvasSize}>
|
<OutfitCanvas width={canvasSize} height={canvasSize}>
|
||||||
{visibleLayers.map((layer) => (
|
{visibleLayers.map((layer) =>
|
||||||
|
layer.canvasMovieLibraryUrl ? (
|
||||||
|
<OutfitCanvasMovie
|
||||||
|
key={layer.id}
|
||||||
|
librarySrc={layer.canvasMovieLibraryUrl}
|
||||||
|
zIndex={layer.zone.depth}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<OutfitCanvasImage
|
<OutfitCanvasImage
|
||||||
key={layer.id}
|
key={layer.id}
|
||||||
src={getBestImageUrlForLayer(layer)}
|
src={getBestImageUrlForLayer(layer)}
|
||||||
zIndex={layer.zone.depth}
|
zIndex={layer.zone.depth}
|
||||||
/>
|
/>
|
||||||
))}
|
)
|
||||||
|
)}
|
||||||
</OutfitCanvas>
|
</OutfitCanvas>
|
||||||
</FullScreenCenter>
|
</FullScreenCenter>
|
||||||
)
|
)
|
||||||
|
|
|
@ -144,6 +144,7 @@ export const itemAppearanceFragment = gql`
|
||||||
id
|
id
|
||||||
remoteId # HACK: This is for Support tools, but other views don't need it
|
remoteId # HACK: This is for Support tools, but other views don't need it
|
||||||
svgUrl
|
svgUrl
|
||||||
|
canvasMovieLibraryUrl
|
||||||
imageUrl(size: SIZE_600)
|
imageUrl(size: SIZE_600)
|
||||||
swfUrl # HACK: This is for Support tools, but other views don't need it
|
swfUrl # HACK: This is for Support tools, but other views don't need it
|
||||||
bodyId
|
bodyId
|
||||||
|
@ -166,6 +167,7 @@ export const petAppearanceFragment = gql`
|
||||||
layers {
|
layers {
|
||||||
id
|
id
|
||||||
svgUrl
|
svgUrl
|
||||||
|
canvasMovieLibraryUrl
|
||||||
imageUrl(size: SIZE_600)
|
imageUrl(size: SIZE_600)
|
||||||
zone {
|
zone {
|
||||||
id
|
id
|
||||||
|
|
|
@ -65,7 +65,14 @@ describe("Item", () => {
|
||||||
const res = await query({
|
const res = await query({
|
||||||
query: gql`
|
query: gql`
|
||||||
query {
|
query {
|
||||||
items(ids: ["38912", "38911", "37375"]) {
|
items(
|
||||||
|
ids: [
|
||||||
|
"38912" # Zafara Agent Robe
|
||||||
|
"38911" # Zafara Agent Hood
|
||||||
|
"37375" # Moon and Stars Background
|
||||||
|
"78244" # Bubbles on Water Foreground
|
||||||
|
]
|
||||||
|
) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
|
||||||
|
@ -75,6 +82,7 @@ describe("Item", () => {
|
||||||
remoteId
|
remoteId
|
||||||
imageUrl(size: SIZE_600)
|
imageUrl(size: SIZE_600)
|
||||||
svgUrl
|
svgUrl
|
||||||
|
canvasMovieLibraryUrl
|
||||||
zone {
|
zone {
|
||||||
id
|
id
|
||||||
depth
|
depth
|
||||||
|
@ -96,11 +104,12 @@ describe("Item", () => {
|
||||||
expect(getDbCalls()).toMatchInlineSnapshot(`
|
expect(getDbCalls()).toMatchInlineSnapshot(`
|
||||||
Array [
|
Array [
|
||||||
Array [
|
Array [
|
||||||
"SELECT * FROM item_translations WHERE item_id IN (?,?,?) AND locale = \\"en\\"",
|
"SELECT * FROM item_translations WHERE item_id IN (?,?,?,?) AND locale = \\"en\\"",
|
||||||
Array [
|
Array [
|
||||||
"38912",
|
"38912",
|
||||||
"38911",
|
"38911",
|
||||||
"37375",
|
"37375",
|
||||||
|
"78244",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
Array [
|
Array [
|
||||||
|
@ -115,7 +124,7 @@ describe("Item", () => {
|
||||||
INNER JOIN parents_swf_assets rel ON
|
INNER JOIN parents_swf_assets rel ON
|
||||||
rel.parent_type = \\"Item\\" AND
|
rel.parent_type = \\"Item\\" AND
|
||||||
rel.swf_asset_id = sa.id
|
rel.swf_asset_id = sa.id
|
||||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||||
Array [
|
Array [
|
||||||
"38912",
|
"38912",
|
||||||
"180",
|
"180",
|
||||||
|
@ -123,30 +132,35 @@ describe("Item", () => {
|
||||||
"180",
|
"180",
|
||||||
"37375",
|
"37375",
|
||||||
"180",
|
"180",
|
||||||
|
"78244",
|
||||||
|
"180",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
Array [
|
Array [
|
||||||
"SELECT * FROM items WHERE id IN (?,?,?)",
|
"SELECT * FROM items WHERE id IN (?,?,?,?)",
|
||||||
Array [
|
Array [
|
||||||
"38912",
|
"38912",
|
||||||
"38911",
|
"38911",
|
||||||
"37375",
|
"37375",
|
||||||
|
"78244",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
Array [
|
Array [
|
||||||
"SELECT * FROM zones WHERE id IN (?,?,?)",
|
"SELECT * FROM zones WHERE id IN (?,?,?,?)",
|
||||||
Array [
|
Array [
|
||||||
"26",
|
"26",
|
||||||
"40",
|
"40",
|
||||||
"3",
|
"3",
|
||||||
|
"45",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
Array [
|
Array [
|
||||||
"SELECT * FROM zone_translations WHERE zone_id IN (?,?,?) AND locale = \\"en\\"",
|
"SELECT * FROM zone_translations WHERE zone_id IN (?,?,?,?) AND locale = \\"en\\"",
|
||||||
Array [
|
Array [
|
||||||
"26",
|
"26",
|
||||||
"40",
|
"40",
|
||||||
"3",
|
"3",
|
||||||
|
"45",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,8 +7,9 @@ Object {
|
||||||
"appearanceOn": Object {
|
"appearanceOn": Object {
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"canvasMovieLibraryUrl": null,
|
||||||
"id": "37128",
|
"id": "37128",
|
||||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14856/600x600.png?v2-1587653266000",
|
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14856/600x600.png?v2-1577836800000",
|
||||||
"remoteId": "14856",
|
"remoteId": "14856",
|
||||||
"svgUrl": null,
|
"svgUrl": null,
|
||||||
"zone": Object {
|
"zone": Object {
|
||||||
|
@ -34,8 +35,9 @@ Object {
|
||||||
"appearanceOn": Object {
|
"appearanceOn": Object {
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"canvasMovieLibraryUrl": null,
|
||||||
"id": "37129",
|
"id": "37129",
|
||||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14857/600x600.png?v2-0",
|
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14857/600x600.png?v2-1577836800000",
|
||||||
"remoteId": "14857",
|
"remoteId": "14857",
|
||||||
"svgUrl": null,
|
"svgUrl": null,
|
||||||
"zone": Object {
|
"zone": Object {
|
||||||
|
@ -61,8 +63,9 @@ Object {
|
||||||
"appearanceOn": Object {
|
"appearanceOn": Object {
|
||||||
"layers": Array [
|
"layers": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"canvasMovieLibraryUrl": null,
|
||||||
"id": "30203",
|
"id": "30203",
|
||||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/006/6829/600x600.png?v2-1598519675000",
|
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/006/6829/600x600.png?v2-1577836800000",
|
||||||
"remoteId": "6829",
|
"remoteId": "6829",
|
||||||
"svgUrl": null,
|
"svgUrl": null,
|
||||||
"zone": Object {
|
"zone": Object {
|
||||||
|
@ -77,366 +80,28 @@ Object {
|
||||||
"id": "37375",
|
"id": "37375",
|
||||||
"name": "Moon and Stars Background",
|
"name": "Moon and Stars Background",
|
||||||
},
|
},
|
||||||
],
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for all-species Maraquan item: db 1`] = `
|
|
||||||
Array [
|
|
||||||
Array [
|
|
||||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
|
||||||
FROM items
|
|
||||||
INNER JOIN parents_swf_assets ON
|
|
||||||
items.id = parents_swf_assets.parent_id AND
|
|
||||||
parents_swf_assets.parent_type = \\"Item\\"
|
|
||||||
INNER JOIN swf_assets ON
|
|
||||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
|
||||||
INNER JOIN pet_types ON
|
|
||||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
|
||||||
INNER JOIN colors ON
|
|
||||||
pet_types.color_id = colors.id
|
|
||||||
WHERE items.id IN (?)
|
|
||||||
GROUP BY pet_types.body_id
|
|
||||||
ORDER BY
|
|
||||||
pet_types.species_id,
|
|
||||||
colors.standard DESC",
|
|
||||||
Array [
|
|
||||||
"77530",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
|
||||||
INNER JOIN parents_swf_assets rel ON
|
|
||||||
rel.parent_type = \\"Item\\" AND
|
|
||||||
rel.swf_asset_id = sa.id
|
|
||||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
|
||||||
Array [
|
|
||||||
"77530",
|
|
||||||
"112",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Object {
|
Object {
|
||||||
"nestTables": true,
|
"appearanceOn": Object {
|
||||||
"sql": "
|
"layers": Array [
|
||||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
Object {
|
||||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
"canvasMovieLibraryUrl": "http://images.neopets.com/cp/items/data/000/000/564/564507_fc3216b9b8/all-item_foreground_lower.js",
|
||||||
WHERE pet_types.body_id = ?
|
"id": "468155",
|
||||||
ORDER BY
|
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/564/564507/600x600.png?v2-1577836800000",
|
||||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
"remoteId": "564507",
|
||||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
"svgUrl": null,
|
||||||
pet_states.female = ? DESC, -- Prefer given gender
|
"zone": Object {
|
||||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
"depth": 50,
|
||||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
"id": "45",
|
||||||
LIMIT 1",
|
"label": "Lower Foreground Item",
|
||||||
"values": Array [
|
|
||||||
"112",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
Array [
|
|
||||||
"112",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
|
||||||
INNER JOIN parents_swf_assets rel ON
|
|
||||||
rel.parent_type = \\"PetState\\" AND
|
|
||||||
rel.swf_asset_id = sa.id
|
|
||||||
WHERE rel.parent_id IN (?)",
|
|
||||||
Array [
|
|
||||||
"5233",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT * FROM color_translations
|
|
||||||
WHERE color_id IN (?) AND locale = \\"en\\"",
|
|
||||||
Array [
|
|
||||||
"44",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT * FROM species_translations
|
|
||||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
|
||||||
Array [
|
|
||||||
"1",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for all-species Maraquan item: item layers 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"id": "442864",
|
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
`;
|
"restrictedZones": Array [],
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for all-species Maraquan item: pet layers 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"id": "2652",
|
|
||||||
},
|
},
|
||||||
Object {
|
"id": "78244",
|
||||||
"id": "2653",
|
"name": "Bubbles on Water Foreground",
|
||||||
},
|
},
|
||||||
Object {
|
|
||||||
"id": "2654",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "2656",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"id": "2663",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for all-species item: db 1`] = `
|
|
||||||
Array [
|
|
||||||
Array [
|
|
||||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
|
||||||
FROM items
|
|
||||||
INNER JOIN parents_swf_assets ON
|
|
||||||
items.id = parents_swf_assets.parent_id AND
|
|
||||||
parents_swf_assets.parent_type = \\"Item\\"
|
|
||||||
INNER JOIN swf_assets ON
|
|
||||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
|
||||||
INNER JOIN pet_types ON
|
|
||||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
|
||||||
INNER JOIN colors ON
|
|
||||||
pet_types.color_id = colors.id
|
|
||||||
WHERE items.id IN (?)
|
|
||||||
GROUP BY pet_types.body_id
|
|
||||||
ORDER BY
|
|
||||||
pet_types.species_id,
|
|
||||||
colors.standard DESC",
|
|
||||||
Array [
|
|
||||||
"74967",
|
|
||||||
],
|
],
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
|
||||||
INNER JOIN parents_swf_assets rel ON
|
|
||||||
rel.parent_type = \\"Item\\" AND
|
|
||||||
rel.swf_asset_id = sa.id
|
|
||||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
|
||||||
Array [
|
|
||||||
"74967",
|
|
||||||
"93",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT * FROM species_translations
|
|
||||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
|
||||||
Array [
|
|
||||||
"1",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"nestTables": true,
|
|
||||||
"sql": "
|
|
||||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
|
||||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
|
||||||
WHERE pet_types.body_id = ?
|
|
||||||
ORDER BY
|
|
||||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
|
||||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
|
||||||
pet_states.female = ? DESC, -- Prefer given gender
|
|
||||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
|
||||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
|
||||||
LIMIT 1",
|
|
||||||
"values": Array [
|
|
||||||
"93",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
Array [
|
|
||||||
"93",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for all-species item: item layers 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"id": "395679",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for all-species item: pet layers 1`] = `
|
|
||||||
Object {
|
|
||||||
"id": "5161",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for bodyId=0 item: db 1`] = `
|
|
||||||
Array [
|
|
||||||
Array [
|
|
||||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
|
||||||
FROM items
|
|
||||||
INNER JOIN parents_swf_assets ON
|
|
||||||
items.id = parents_swf_assets.parent_id AND
|
|
||||||
parents_swf_assets.parent_type = \\"Item\\"
|
|
||||||
INNER JOIN swf_assets ON
|
|
||||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
|
||||||
INNER JOIN pet_types ON
|
|
||||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
|
||||||
INNER JOIN colors ON
|
|
||||||
pet_types.color_id = colors.id
|
|
||||||
WHERE items.id IN (?)
|
|
||||||
GROUP BY pet_types.body_id
|
|
||||||
ORDER BY
|
|
||||||
pet_types.species_id,
|
|
||||||
colors.standard DESC",
|
|
||||||
Array [
|
|
||||||
"37375",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
|
||||||
INNER JOIN parents_swf_assets rel ON
|
|
||||||
rel.parent_type = \\"Item\\" AND
|
|
||||||
rel.swf_asset_id = sa.id
|
|
||||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
|
||||||
Array [
|
|
||||||
"37375",
|
|
||||||
"93",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT * FROM species_translations
|
|
||||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
|
||||||
Array [
|
|
||||||
"1",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"nestTables": true,
|
|
||||||
"sql": "
|
|
||||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
|
||||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
|
||||||
WHERE pet_types.body_id = ?
|
|
||||||
ORDER BY
|
|
||||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
|
||||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
|
||||||
pet_states.female = ? DESC, -- Prefer given gender
|
|
||||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
|
||||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
|
||||||
LIMIT 1",
|
|
||||||
"values": Array [
|
|
||||||
"93",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
Array [
|
|
||||||
"93",
|
|
||||||
true,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for bodyId=0 item: item layers 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"id": "30203",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for bodyId=0 item: pet layers 1`] = `
|
|
||||||
Object {
|
|
||||||
"id": "5161",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for single-species item: db 1`] = `
|
|
||||||
Array [
|
|
||||||
Array [
|
|
||||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
|
||||||
FROM items
|
|
||||||
INNER JOIN parents_swf_assets ON
|
|
||||||
items.id = parents_swf_assets.parent_id AND
|
|
||||||
parents_swf_assets.parent_type = \\"Item\\"
|
|
||||||
INNER JOIN swf_assets ON
|
|
||||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
|
||||||
INNER JOIN pet_types ON
|
|
||||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
|
||||||
INNER JOIN colors ON
|
|
||||||
pet_types.color_id = colors.id
|
|
||||||
WHERE items.id IN (?)
|
|
||||||
GROUP BY pet_types.body_id
|
|
||||||
ORDER BY
|
|
||||||
pet_types.species_id,
|
|
||||||
colors.standard DESC",
|
|
||||||
Array [
|
|
||||||
"38911",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
|
||||||
INNER JOIN parents_swf_assets rel ON
|
|
||||||
rel.parent_type = \\"Item\\" AND
|
|
||||||
rel.swf_asset_id = sa.id
|
|
||||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
|
||||||
Array [
|
|
||||||
"38911",
|
|
||||||
"180",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
"SELECT * FROM species_translations
|
|
||||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
|
||||||
Array [
|
|
||||||
"54",
|
|
||||||
],
|
|
||||||
],
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"nestTables": true,
|
|
||||||
"sql": "
|
|
||||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
|
||||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
|
||||||
WHERE pet_types.body_id = ?
|
|
||||||
ORDER BY
|
|
||||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
|
||||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
|
||||||
pet_states.female = ? DESC, -- Prefer given gender
|
|
||||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
|
||||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
|
||||||
LIMIT 1",
|
|
||||||
"values": Array [
|
|
||||||
"180",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
Array [
|
|
||||||
"180",
|
|
||||||
false,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for single-species item: item layers 1`] = `
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"id": "37129",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Item loads canonical appearance for single-species item: pet layers 1`] = `
|
|
||||||
Object {
|
|
||||||
"id": "17861",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,14 @@ const typeDefs = gql`
|
||||||
"""
|
"""
|
||||||
swfUrl: String
|
swfUrl: String
|
||||||
|
|
||||||
|
"""
|
||||||
|
This layer as an HTML canvas library JS file, if available.
|
||||||
|
|
||||||
|
This will be empty for layers that don't animate, and might also be empty
|
||||||
|
for animated layers not yet converted by Neopets.
|
||||||
|
"""
|
||||||
|
canvasMovieLibraryUrl: String
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This layer can fit on PetAppearances with the same bodyId. "0" is a
|
This layer can fit on PetAppearances with the same bodyId. "0" is a
|
||||||
special body ID that indicates it fits all PetAppearances.
|
special body ID that indicates it fits all PetAppearances.
|
||||||
|
@ -111,30 +119,7 @@ const resolvers = {
|
||||||
// When the manifest is specifically null, that means we don't know if
|
// When the manifest is specifically null, that means we don't know if
|
||||||
// it exists yet. Load it to find out!
|
// it exists yet. Load it to find out!
|
||||||
if (manifest === null) {
|
if (manifest === null) {
|
||||||
manifest = await loadAssetManifest(layer.url);
|
manifest = await loadAndCacheAssetManifest(db, layer);
|
||||||
|
|
||||||
// Then, write the new manifest. We make sure to write an empty string
|
|
||||||
// if there was no manifest, to signify that it doesn't exist, so we
|
|
||||||
// don't need to bother looking it up again.
|
|
||||||
//
|
|
||||||
// TODO: Someday the manifests will all exist, right? So we'll want to
|
|
||||||
// reload all the missing ones at that time.
|
|
||||||
manifest = manifest || "";
|
|
||||||
const [
|
|
||||||
result,
|
|
||||||
] = await db.execute(
|
|
||||||
`UPDATE swf_assets SET manifest = ? WHERE id = ? LIMIT 1;`,
|
|
||||||
[manifest, layer.id]
|
|
||||||
);
|
|
||||||
if (result.affectedRows !== 1) {
|
|
||||||
throw new Error(
|
|
||||||
`Expected to affect 1 asset, but affected ${result.affectedRows}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
`Loaded and saved manifest for ${layer.type} ${layer.remoteId}. ` +
|
|
||||||
`DTI ID: ${layer.id}. Exists?: ${Boolean(manifest)}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!manifest) {
|
if (!manifest) {
|
||||||
|
@ -163,6 +148,39 @@ const resolvers = {
|
||||||
const url = new URL(assetDatum.path, "http://images.neopets.com");
|
const url = new URL(assetDatum.path, "http://images.neopets.com");
|
||||||
return url.toString();
|
return url.toString();
|
||||||
},
|
},
|
||||||
|
canvasMovieLibraryUrl: async ({ id }, _, { db, swfAssetLoader }) => {
|
||||||
|
const layer = await swfAssetLoader.load(id);
|
||||||
|
let manifest = layer.manifest && JSON.parse(layer.manifest);
|
||||||
|
|
||||||
|
// When the manifest is specifically null, that means we don't know if
|
||||||
|
// it exists yet. Load it to find out!
|
||||||
|
if (manifest === null) {
|
||||||
|
manifest = await loadAndCacheAssetManifest(db, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!manifest) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manifest.assets.length !== 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const asset = manifest.assets[0];
|
||||||
|
if (asset.format !== "lod") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsAssetDatum = asset.assetData.find((ad) =>
|
||||||
|
ad.path.endsWith(".js")
|
||||||
|
);
|
||||||
|
if (!jsAssetDatum) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL(jsAssetDatum.path, "http://images.neopets.com");
|
||||||
|
return url.toString();
|
||||||
|
},
|
||||||
item: async ({ id }, _, { db }) => {
|
item: async ({ id }, _, { db }) => {
|
||||||
// TODO: If this becomes a popular request, we'll definitely need to
|
// TODO: If this becomes a popular request, we'll definitely need to
|
||||||
// loaderize this! I'm cheating for now because it's just Support, one at
|
// loaderize this! I'm cheating for now because it's just Support, one at
|
||||||
|
@ -207,6 +225,35 @@ async function loadAssetManifest(swfUrl) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadAndCacheAssetManifest(db, layer) {
|
||||||
|
let manifest = await loadAssetManifest(layer.url);
|
||||||
|
|
||||||
|
// Then, write the new manifest. We make sure to write an empty string
|
||||||
|
// if there was no manifest, to signify that it doesn't exist, so we
|
||||||
|
// don't need to bother looking it up again.
|
||||||
|
//
|
||||||
|
// TODO: Someday the manifests will all exist, right? So we'll want to
|
||||||
|
// reload all the missing ones at that time.
|
||||||
|
manifest = manifest || "";
|
||||||
|
const [
|
||||||
|
result,
|
||||||
|
] = await db.execute(
|
||||||
|
`UPDATE swf_assets SET manifest = ? WHERE id = ? LIMIT 1;`,
|
||||||
|
[manifest, layer.id]
|
||||||
|
);
|
||||||
|
if (result.affectedRows !== 1) {
|
||||||
|
throw new Error(
|
||||||
|
`Expected to affect 1 asset, but affected ${result.affectedRows}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`Loaded and saved manifest for ${layer.type} ${layer.remoteId}. ` +
|
||||||
|
`DTI ID: ${layer.id}. Exists?: ${Boolean(manifest)}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
const SWF_URL_PATTERN = /^http:\/\/images\.neopets\.com\/cp\/(.+?)\/swf\/(.+?)\.swf$/;
|
const SWF_URL_PATTERN = /^http:\/\/images\.neopets\.com\/cp\/(.+?)\/swf\/(.+?)\.swf$/;
|
||||||
|
|
||||||
function convertSwfUrlToManifestUrl(swfUrl) {
|
function convertSwfUrlToManifestUrl(swfUrl) {
|
||||||
|
|
Loading…
Reference in a new issue