TooTallNate / nx.js

JavaScript runtime for Nintendo Switch homebrew applications
https://nxjs.n8.io
MIT License
156 stars 6 forks source link

Implement Switch Album API #116

Closed LauraWebdev closed 6 months ago

LauraWebdev commented 6 months ago

It would be awesome if one could access the Switch album through nxjs, people could, for example, create apps that upload the taken screenshots to an online service, or serve a simple webapp for browsing the screenshot files on their PC (like on the stock OS with the mobile app feature).

I've tried to come up with a small data schema for reading album entries by looking at the documentation over at https://switchbrew.org/wiki/Capture_services and tried to fit it into a JS API as best as I could. I bet there is tons of room for improvement, especially coming from a TypeScript standpoint.

Data Schema

Switch
    Album
        Mount()                     [function]
        Unmount()                   [function]
        isMounted                   [bool]
        usage                       []
        fileSize                    []
        Files                       [array]
            File
                Delete()            [function]
                file                [blob]?
                thumbnail           [blob]?
                programId           []
                fileName            []
                storage             [nand,sd]
                dateTime            [datetime]
                uniqueId            []
                contentType         [screenshot,movie,extramovie]

I'm sure we will need to manually mount/unmount the album, especially since they can get quite big. File & thumbnail were set as blob in this schema because that's what ultimately is utilized with Switch.Application's icons already.

Examples

I've tried to come up with three examples utilizing the API.

Example 1 (List Metadata)

Switch.Album.Mount();

console.log(`Album Usage: ${Switch.Album.usage}`);
console.log(`Album Size: ${Switch.Album.fileSIze}`);

for (const { file } of Switch.Album.Files) {
    console.log(`-- ${file.uniqueId} --------`);
    console.log(`Program Id: ${file.programId}`);
    console.log(`File Name: ${file.fileName}`);
    console.log(`Storage Location: ${file.storage === 'nand' ? 'NAND' : 'SD'}`);
    console.log(`Date Time: ${new Date(file.dateTime).toDateString()}`);
    console.log(`Unique ID: ${file.uniqueId}`);
    console.log(`contentType: ${file.contentType === 'screenshot' ? 'Image' : 'Video'}`);
}

Switch.Album.Unmount();

Example 2 (Displaying album in a grid)

const imageWidth = 320;
const imageHeight = 180;

Switch.Album.Mount();

for (const { file } of Switch.Album.Files) {
    const image = new Image();
    image.onload = () => {
        if (x + imageWidth >= screen.width) {
            x = gap;
            y += imageHeight + 40 + gap;
        }
        ctx.drawImage(image, x, y);
        ctx.fillText(file.fileName, x + imageWidth / 2, y + imageHeight + 20, imageWidth);
        x += imageWidth + gap;
    };
    const url = URL.createObjectURL(new Blob([file.thumbnail]));
    image.src = url;
}

Switch.Album.Unmount();

Example 3 (Count album entries by app)

Switch.Album.Mount();

for (const app of Switch.Application) {
    let appFiles = Switch.Album.Files.filter(x.programid === app.id);

    let screenshotCount = appFiles.filter(x => x.contentType == "screenshot").length;
    let movieCount = appFiles.filter(x => x.contentType == "movie").length;
    let extramovieCount = appFiles.filter(x => x.contentType == "extramovie").length;

    console.log(`${app.name}: S=${screenshotCount} M=${movieCount} E=${extramovieCount}`);
}

Switch.Album.Unmount();
TooTallNate commented 6 months ago

@LauraWebdev I've added a preliminary version of the new API in https://github.com/TooTallNate/nx.js/pull/120, which I believe covers the use cases in your examples. Let me know if there's any features missing that you would like to see.