So, I might’ve got a bit carried away
Here’s a full prototype, the only thing I’ve not cracked is getting the smart object edits to update the master document. The file saves, but it doesn’t update, and I’m not sure I’m using placedLayerUpdateAllModified
correctly. Perhaps @Maher has some bright ideas as to what’s going on with that!
const { app, core, action } = require("photoshop");
const fs = require("uxp").storage.localFileSystem;
const batchPlay = action.batchPlay;
const executeAsModal = core.executeAsModal;
const makeDefaultDocument = async () => {
const result = await batchPlay(
[
{
_obj: "make",
new: {
_obj: "document",
artboard: false,
autoPromoteBackgroundLayer: false,
preset: "Default Photoshop Size",
},
},
],
{}
);
return result[0];
};
const makeNewLayer = async (id) => {
const result = await batchPlay(
[
{
_obj: "make",
_target: [
{
_ref: "layer",
},
],
layerID: id,
},
],
{}
);
return result[0];
};
const convertToSmartObject = async (docId, layerId) => {
return await batchPlay([{ _obj: "newPlacedLayer" }], {});
};
const openSmartObject = async (layerId) => {
const result = await batchPlay(
[
{
_obj: "placedLayerEditContents",
layerID: layerId,
},
],
{}
);
return result[0];
};
const makeSolidColour = async (red, green, blue) => {
const result = await batchPlay(
[
{
_obj: "make",
_target: [
{
_ref: "contentLayer",
},
],
using: {
_obj: "contentLayer",
type: {
_obj: "solidColorLayer",
color: {
_obj: "RGBColor",
red: red,
grain: green,
blue: blue,
},
},
},
},
],
{}
);
return result[0];
};
const updateSmartObjectLink = async (id, layerId) => {
const result = await batchPlay(
[
{
_obj: "placedLayerUpdateAllModified",
documentID: id,
layerIDs: [layerId],
},
],
{}
);
return result;
};
const saveDocument = async (id, filename, folder) => {
// Create file
const file = await folder.createFile(filename, {
overwrite: true,
});
// Generate token
const token = await fs.createSessionToken(file);
const result = await batchPlay(
[
{
_obj: "save",
in: {
_path: token,
_kind: "local",
},
saveStage: {
_enum: "saveStageType",
_value: "saveBegin",
},
documentID: id,
},
],
{}
);
return result;
};
const closeDocument = async (id) => {
const result = await batchPlay(
[
{
_obj: "close",
saving: {
_enum: "yesNo",
_value: "no",
},
documentID: id,
},
],
{}
);
return result;
};
const activateDocument = (id) => {
app.activeDocument = app.documents.find((doc) => doc.id === id);
};
const makeAndOpenSmartObject = async (masterDocId) => {
// Make new layer
const newLayer = await makeNewLayer(masterDocId);
// Convert new layer to smart object
await convertToSmartObject(masterDocId, newLayer.layerID);
// Open smart object
const smartObjectDoc = await openSmartObject(newLayer.layerID);
return {
newLayer,
smartObjectDoc,
};
};
const main = async () => {
await executeAsModal(async () => {
try {
// Get folder for saving
const saveFolder = await fs.getFolder();
// Make master document
const masterDoc = await makeDefaultDocument();
// Make and open smart object
const { newLayer, smartObjectDoc } = await makeAndOpenSmartObject(
masterDoc.documentID
);
// Perform edit to smart object
await makeSolidColour(0, 0, 255);
// Generate filename from layer id
const filename = `SmartObject_${newLayer.layerID}`;
// Update master doc
await updateSmartObjectLink(masterDoc.documentID, newLayer.layerID);
// Save smart object
await saveDocument(smartObjectDoc.documentID, filename, saveFolder);
// Close smart object
await closeDocument(smartObjectDoc.documentID);
// Activate master document
activateDocument(masterDoc.documentID);
} catch (error) {
console.log("💥", error);
}
});
};