Introducing B3Forge - Candid UI: Seamlessly Integrate and Customize Your dApp Interfaces

Im not sure if I understand, dont you just put in the canister id and it fetches the candid?

Here is a gif of my experience
Error

Yeah, you should enter the candid code manually for now, but good point it should fetch the candid code automatically.
I’ll add it later, thanks for that.

2 Likes

Great! Updated the Candid README page :slight_smile:

For the type selector feature in Candid UI, I don’t have a concrete design yet. A first step can be to brainstorm the properties we need to specify.

1 Like

Thanks to @Gekctek, for pointing that out. Entering the canister ID should fetch the Candid code automatically and place it into the form. This small update should make it even easier to use.

new-playground-update

Additionally, I have fixed a route problem that was showing a “Body does not pass verification” error on some routes, Thank you, @peterparker, for bringing this to my attention.

I appreciate your feedback and the opportunity to improve B3Forge. Please give it a try and let me know if it works for you now.

4 Likes

Great! Thank you for updating the Candid README page. I’m excited for more developers to discover and use B3Forge!

Regarding the type selector feature in Candid UI, I have a few suggestions for properties that could be useful. I’ve also implemented a similar approach in B3Forge, where the input type is guessed based on the name. Here are some ideas to enhance this feature:

  1. blob.type:

    • "file": Allows users to upload a file into a blob value.
    • "image": Displays an image from a blob value.
    • "text": Displays plain text from a blob value.
    • "video": Displays a video from a blob value.
  2. number.format:

    • "currency": Formats the number as currency.
    • "decimal": Allows decimal numbers.
    • "cycle": Handles IC-specific cycle units.
  3. date.format:

    • "date": Standard date picker.
    • "datetime": Date and time picker.
    • "time": Time picker.
  4. string.format:

    • "email": Validates the input as an email address.
    • "url": Validates the input as a URL.
    • "password": Masks the input for password fields.
    • "image": Handles base64-encoded images.
  5. array.layout:

    • "table": Displays array items in a table layout.
    • "list": Displays array items in a list layout.
  6. auto-detection based on keywords:

    • Using predefined keyword lists to automatically suggest input types based on field names. For example:
      • timestamp_keys: Suggests date/time pickers for fields like “createdAt,” “updatedAt,” “timestamp.”
      • value_keys: Suggests numerical input for fields like “amount,” “balance,” “price.”
      • wallet_keys: Suggests financial transaction fields for names like “transfer,” “deposit,” “withdraw.”

This approach can help developers customize the UI more effectively and provide a better user experience. I’m happy to brainstorm more ideas or provide further assistance as needed.

If there’s anything I can do to help make this happen or any contributions needed, I’m ready to assist in any way possible.

Thank you for considering my suggestions!

It’s great! we are looking upon the feedback while having the high hopes about project’s success.

1 Like

blob.type

I would suggest to use MIME types here.

1 Like

This looks really great! :blush: A good idea

1 Like

Thank you for the suggestion! Using MIME types for blob.type is a great idea. Here’s an example of how this could be implemented:

  1. blob.type:
    • "application/pdf": Allows users to upload PDF files.
    • "image/png": Displays a PNG image from a blob value.
    • "text/plain": Displays plain text from a blob value.
    • "video/mp4": Displays an MP4 video from a blob value.

By using MIME types, we can provide a more standardized and flexible way to handle various data types. This approach would enhance the customization options for developers and ensure better compatibility.

Thanks again for the valuable input!

Similarly metadata regarding strings/numbers could follow HTML text input type standards for example.

Overall I would split the candid metadata into various (ICRC?) standards for different purposes, some might be data related (e.g. MIME), some UI related (e.g. input), some might be used for other purposes.

Overall having standardized metadata around candid at some point seems like a very cool concept.

1 Like

I agree that following HTML text input type standards for strings and numbers would be beneficial. Splitting the Candid metadata into various standards for different purposes makes a lot of sense. For example:

  1. Data Related (e.g., MIME Types):

    • blob.type = "application/pdf": Upload PDF files.
    • blob.type = "image/png": Display PNG images.
    • blob.type = "text/plain": Display plain text.
    • blob.type = "video/mp4": Display MP4 videos.
  2. UI Related (e.g., HTML Input Types):

    • string.type = "email": Email input field.
    • string.type = "url": URL input field.
    • string.type = "password": Password input field.
    • number.type = "integer": Integer input field.
    • number.type = "float": Floating-point number input field.
    • number.type = "currency": Currency input field.
    • number.type = "decimal": Decimal number input field.
    • number.type = "cycle": IC-specific cycle units.
  3. Other Purposes (Potential Standards):

    • Standardized metadata for different application purposes such as validation, formatting, and more.

One issue is how to handle chunked files. Not sure if we can standardize that some how or not.

Maybe type a tulple? (blob,?nat) : chunksfile(mimetype )

To handle chunked files, we can use a standardized approach with specific functions for uploading and verifying files. Here’s an example:

type ICRC1000 = record {
  load_chunk: func (blob) -> ();
  size: func () -> (nat);
  hash: func () -> (text);
}

service: {
  upload_profile_pic : () -> (ICRC1000);
}
  • load_chunk(blob): Loads a chunk of the file.
  • size(): Returns the total size of the file after all chunks have been uploaded.
  • hash(): Verifies the file’s integrity by returning the hash of the uploaded file.

Example Usage in JavaScript

Here’s how you can use these functions in JavaScript to manage chunked file uploads:

async function uploadFile(canister, file) {
  const chunkSize = 1024 * 1024; // 1MB chunks
  const totalChunks = Math.ceil(file.size / chunkSize);
  const uploadProfilePic = await canister.upload_profile_pic();

  for (let i = 0; i < totalChunks; i++) {
    const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
    await uploadProfilePic.load_chunk(chunk);
  }

  const fileSize = await uploadProfilePic.size();
  if (fileSize === file.size) {
    const fileHash = await uploadProfilePic.hash();
    console.log('File uploaded successfully with hash:', fileHash);
  } else {
    console.error('Failed to upload all chunks.');
  }
}

In this approach, the main function (upload_profile_pic) returns the functions needed (load_chunk, size, and hash) to upload and verify the file. This allows the frontend to manage chunked file uploads effectively by calling these standardized functions.

Hey, that B3Forge seems super practical! The customizable interfaces and smooth integration are definitely going to help us a lot. I appreciate the focus on security and managing user identities too. Looking forward to seeing more features being added :clap: Great work!

3 Likes

Thank you all! These are all useful suggestions!

Given a type, there are two dimensions to consider: input/output, textual/UI. UI input corresponds to Candid UI input; Textual input corresponds to the Candid assist feature; UI output corresponds to Candid UI rendering; textual output corresponds to dfx pretty printer. Some of the properties make sense for all these dimensions, while some only make sense for a particular dimension. So we need a bit more design here.

Yep, we are doing this already. See the last section of this PR: spec: candid type selector by chenyan-dfinity · Pull Request #555 · dfinity/candid · GitHub

2 Likes