Create button with folder path name

I’m here again asking for help
I would like to create a button that makes me select the folder
and the folder path must be visible in the panel as in the screenshot.

What did you try yourself? What didn’t work when you tried? Did you check documentation about entries?

So I’ve come this far
the button selects the folder but it just gives me the folder name
I would like to see the whole path

this is the string i can’t edit

document.getElementById('spansterde').addEventListener('click', async () => {
  const NameFolder = await fslocal.getFolder(),
    Prime = await fslocal
      .createPersistentToken(NameFolder)
      .then((Second) => {
        return Second
      })
  await iniWrite('FoldersterdeFolderToken', Prime)
  document.getElementById('secure').innerHTML ='...' + NameFolder.name.slice(-20)
  await iniWrite('FoldersterdeFolderName', NameFolder.name)
})

So did you check docs about entries? There’s this nativePath property. And your NameFolder is an entry

I don’t have the native path property
name folder and just one entry.

What do you mean? What does it show if you try to output NameFolder.nativePath?

I did as you suggested I put .nativePath
but now it doesn’t open the folder and nothing happens
see if i made any mistakes

document.getElementById('spansterde').addEventListener('click', async () => {
  const NameFolder.nativePath = await fslocal.getFolder(),
    _0x13fc92 = await fslocal
      .createPersistentToken(NameFolder.nativePath)
      .then((_0x4236df) => {
        return _0x4236df
      })
  await iniWrite('FoldersterdeFolderToken', _0x13fc92)
  document.getElementById('secure').innerHTML =NameFolder.nativePath.name.slice(-20)
  await iniWrite('FoldersterdeFolderName', NameFolder.nativePath.name)
})

but an error pops up in the console
missing initializer in cons declaration

The getFolder method returns an entry, of which nativePath is a property. You need to get the entry before you can access its properties.

document.getElementById('spansterde').addEventListener('click', async () => {
  // Get folder
  const NameFolder = await fslocal.getFolder();
   
  // Generate token
  const token = await fslocal
  .createPersistentToken(NameFolder)

  // Mutate nativePath string (remove last character)
  const formattedPath = NameFolder.nativePath.slice(0, NameFolder.length - 1)
      
  console log("The NameFolder:", NameFolder)

  console.log("NameFolder's path is:", NameFolder.nativePath)
  
  console.log("Named Folder's token:", token)
 
  console.log("The formatted path:", formattedPath)
})

Somewhat unrelated - you’re mixing different asynchronous methods here:

_0x13fc92 = await fslocal
      .createPersistentToken(NameFolder.nativePath)
      .then((_0x4236df) => {
        return _0x4236df
      })

You don’t need to add a .then to an await, this would be the correct way of using async/await:

// Await a return value - JS waits until a return value has been recieved
const aVariable = await someAsyncFunction();
// Variable now available 
console.log(aVariable)

Thanks for your help putting your code
from the console I have this error
unexpected identifier

I can’t help without seeing all your code mate

There’s no NameFolder.nativePath.name - only NameFolder.name or NameFolder.nativePath. Not sure what got you an idea about NameFolder.nativePath.name :thinking:

I honestly don’t even know I’m new to uxp and so I make mistakes, that’s why I turn to you experts to try to understand. Thanks for your help

I’ll just mention that code that contains things like _0x4236df and _0x4236df and_0x13fc92 looks like you might be trying to copy someone’s obfuscated code, @haller. Those would be very unusual variable names for someone who says:

Is that the case here? Are you trying to decipher or copy someone else’s obfuscated UXP code?

I wouldn’t be able to do this because I have no knowledge of uxp these codes you see are clips that I find here and there on github and other sites I’m sorry you think I’m a code stealer. If I had done this I don’t think I would have posted the code right in this forum.

If that’s true, then you might also be concerned the person who wrote the code would be also a member of this forum and would recognize that you are posting code that is not yours, and you are posting it in a place where the developer who wrote the original code does not want it posted. Obfuscated code is usually obfuscated for a reason, basically so that other people can’t use it.

Perhaps you can kindly provide a link to the Github respository where you obtained this code so it can be further investigated since this is looking like a possible violation of Github rules of behavior.

I honestly don’t know if the code has been obfuscated I just know that I have a small project in mind and I wanted to make it happen if a forum user owns the code, I can’t help but apologize, but I don’t feel responsible, because as I said, I take fragments of code to get to my little project. If the owner of the forum believes that I am a shady individual he can close my account, nor does he have the right and the duty. If I’ve done something that breaks the rules, I apologize to everyone.

Ok, let’s calm it down a bit.
I’ve seen @haller 's full code and I can assure you this is someone who doesn’t really have the JS skills yet to really know what they’re doing in UXP.
We’ve all reverse-engineered code to learn and I hardly think this constitutes fraud.

I personally don’t have issues if someone takes tiny piece of my own code if it’s available publicly. I’d be concerned if I saw huge chunks of code copied.

That being said, I still didn’t see a reply to what’s the output for NameFolder.nativePath :thinking:

1 Like

Here’s the complete solution that I wrote for @haller over DM.
I’m providing it for anyone in the future looking for a similar answer, but also so that everyone can be safe in the knowledge that no code is being “stolen” (including my own).

I’ve suggested that @haller takes the time to learn ES6 before attempting UXP.

// Imports
const { app, core } = require("photoshop");
const fs = require("uxp").storage.localFileSystem;

// UI elements
const folderSelectButton = document.querySelector("#folderSelectBtn");
const actionButton = document.querySelector("#saveBtn");
const pathLabel = document.querySelector("#pathLabel");

// Variables
let saveFolder;

// Helper Functions
const writeFileToDataFolder = async (data, filename) => {
  // Stringify data
  const stringifiedData = JSON.stringify([data]);

  // Get data folder
  const dataFolder = await fs.getDataFolder();

  // Create file
  const dataFile = await dataFolder.createFile(`${filename}.json`, {
    overwrite: true,
  });

  // Write data to file
  await dataFile.write(stringifiedData);

  return data;
};

// Main functions
const getAndStoreFolderToken = async () => {
  // Get folder
  const folder = await fs.getFolder();

  // Generate token
  const token = await fs.createPersistentToken(folder);

  // Create folder Object for convenience
  const folderObject = {
    name: folder.name,
    path: folder.nativePath,
    token: token,
    entry: folder,
  };

  // Write as JSON to data folder
  await writeFileToDataFolder(folderObject, "storedFolderDetails");

  // Update UI
  pathLabel.innerHTML = folderObject.path;

  return folder;
};

const saveFile = async (destination, fileName) => {
  // Get active document
  const doc = app.activeDocument;

  // Create file
  const target = await destination.createFile(fileName + ".jpg", {
    overwrite: true,
  });

  // Save file - wrapped in executeAsModal as it changes Photoshop state
  await core.executeAsModal(async () => {
    const savedFile = await doc.saveAs.jpg(target, { quality: 12 }, true);

    return savedFile;
  });
};

// Event listeners
folderSelectButton.addEventListener("click", async () => {
  saveFolder = await getAndStoreFolderToken();
});

actionButton.addEventListener("click", async () => {
  await saveFile(saveFolder, "A new filename");
});

2 Likes