Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
UploadUrlProvider="GetUploadUrl"
OnUploading="() => isManagingFile = true"
OnUploadFailed="HandleOnUploadFailed"
OnUploadComplete="WrapHandled(HandleOnUploadComplete)"
OnUploadComplete="HandleOnUploadComplete"
UploadRequestHttpHeadersProvider="WrapHandled(GetUploadRequestHeaders)">
<LabelTemplate>
<BitCard FullSize>
Expand All @@ -70,6 +70,11 @@
OnClick="WrapHandled(RemoveProductImage)">
@Localizer[nameof(AppStrings.Remove)]
</BitButton>

<BitTextField Multiline
Label="@Localizer[nameof(AppStrings.AltText)]"
@bind-Value="product.PrimaryImageAltText" />
<ValidationMessage For="() => product.PrimaryImageAltText" />
}

<BitLink OnClick="() => fileUploadRef.Browse()" NoUnderline>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ private void GoBack()
NavigationManager.NavigateTo(Urls.ProductsPage);
}

private async Task HandleOnUploadComplete()
private async Task HandleOnUploadComplete(BitFileInfo fileInfo)
{
product.HasPrimaryImage = true;
product.PrimaryImageAltText = fileInfo.Message;
product.ConcurrencyStamp = Guid.NewGuid().ToByteArray(); // To update the product image's url when user changes product image multiple time within the same page.
isManagingFile = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ private async Task<IActionResult> UploadAttachment(Guid attachmentId, Attachment
if (file is null)
throw new BadRequestException();

string? altText = null; // For future use, e.g., AI-generated alt text.

await DbContext.Attachments.Where(att => att.Id == attachmentId).ExecuteDeleteAsync(cancellationToken);

foreach (var kind in kinds)
Expand Down Expand Up @@ -203,21 +205,32 @@ private async Task<IActionResult> UploadAttachment(Guid attachmentId, Attachment
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
if (serviceProvider.GetService<IChatClient>() is IChatClient chatClient)
{
string responseText = (await chatClient.GetResponseAsync([
new ChatMessage(ChatRole.System, "Respond with EXACTLY one word: 'Yes' if the image contains a car, 'No' if it does not. Do NOT describe the image, explain, or add any other text. Violating this will result in an invalid response."),
new ChatMessage(ChatRole.User, "Is this an image of a car?")
var response = await chatClient.GetResponseAsync<AIImageReviewResponse>(
messages: [
new ChatMessage(ChatRole.System, "Return a JSON object with two properties: 'isCar' (boolean, true if the image contains a car, false otherwise) and 'alt' (string, describing the image content). Do not include any other properties or text."),
new ChatMessage(ChatRole.User, "Analyze this image.")
{
Contents = [new DataContent(imageBytes, "image/webp")]
}
],
cancellationToken: cancellationToken,
options: new()
{
Contents = [new DataContent(imageBytes, "image/webp")]
}], cancellationToken: cancellationToken, options: new() { Temperature = 0 })).Text.Trim().ToLower();

if (responseText is "no")
Temperature = 0,
ResponseFormat = ChatResponseFormat.Json,
AdditionalProperties = new()
{
["response_format"] = new { type = "json_object" }
}
});

if (response.Result.IsCar is false)
{
logger.LogWarning("Unexpected AI response for Car detection: {Response}", response.Result.Alt);
return BadRequest(Localizer[nameof(AppStrings.ImageNotCarError)].ToString());
}
else if (responseText is not "yes")
{
logger.LogWarning("Unexpected AI response for car detection: {Response}", responseText);
}

altText = response.Result.Alt;
}
//#endif

Expand Down Expand Up @@ -246,7 +259,7 @@ private async Task<IActionResult> UploadAttachment(Guid attachmentId, Attachment
}
}

return Ok();
return Ok(altText);
}

private string GetFilePath(Guid attachmentId, AttachmentKind kind, string? fileName = null)
Expand All @@ -266,4 +279,12 @@ private string GetFilePath(Guid attachmentId, AttachmentKind kind, string? fileN

return filePath;
}

//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
public class AIImageReviewResponse
{
public bool IsCar { get; set; }
public string? Alt { get; set; }
}
//#endif
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading