Skip to content

Commit

Permalink
Adding ability to list and update existent Video Plans
Browse files Browse the repository at this point in the history
  • Loading branch information
efonsecab committed Apr 10, 2024
1 parent 4406ece commit 4113956
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace FairPlayCombined.Models.FairPlayTube.VideoPlan
{
public class VideoPlanModel : IListModel
{
public long VideoPlanId { get; set; }
[Required]
public string? ApplicationUserId { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using FairPlayCombined.DataAccess.Models.FairPlayTubeSchema;
using FairPlayCombined.Models.FairPlayTube.VideoPlan;
using FairPlayCombined.Models.Pagination;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace FairPlayCombined.Services.FairPlayTube
{
Expand All @@ -17,5 +19,21 @@ namespace FairPlayCombined.Services.FairPlayTube
>]
public partial class VideoPlanService : BaseService
{
public async Task UpdateVideoPlanAsync(UpdateVideoPlanModel createModel,
CancellationToken cancellationToken)
{
logger.LogInformation(message: "Start of method: {methodName}", nameof(UpdateVideoPlanAsync));
var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
VideoPlan entity = await dbContext.VideoPlan
.SingleAsync(p=>p.VideoPlanId == createModel.VideoPlanId,
cancellationToken:cancellationToken);

entity.ApplicationUserId = createModel.ApplicationUserId;
entity.VideoName = createModel.VideoName;
entity.VideoDescription = createModel.VideoDescription;
entity.VideoScript = createModel.VideoScript;

await dbContext.SaveChangesAsync(cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<FluentNavLink Href="/Creator/NewVideoRecommendation">Recommendations</FluentNavLink>
<FluentNavLink Href="/Creator/NewVideoScript">New Video Script</FluentNavLink>
<FluentNavLink Href="/Creator/CreateVideoPlan">Create Video Plan</FluentNavLink>
<FluentNavLink Href="/Creator/MyVideoPlans">My Video Plans</FluentNavLink>
<FluentNavLink Href="/User/MyFunds">My Funds</FluentNavLink>
</FluentNavGroup>
<div class="nav-item px-3">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@inject IToastService toastService
@inject IUserProviderService userProviderService
@inject YouTubeClientService youTubeClientService
@inject ILogger<UploadMyVideo> logger
@inject ILogger<CreateVideoPlan> logger
@inject NavigationManager navigationManager

<FluentLabel Typo="Typography.H3">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
@page "/Creator/MyVideoPlans"
@implements IDisposable

@using FairPlayCombined.Common
@using FairPlayCombined.Common.FairPlayTube.Enums
@using FairPlayCombined.Interfaces
@using FairPlayCombined.Models.FairPlayTube.VideoInfo
@using FairPlayCombined.Models.FairPlayTube.VideoPlan
@using FairPlayCombined.Services.Common
@using FairPlayCombined.Services.FairPlayTube
@using FairPlayTube.Components.Spinners
@using Google.Apis.YouTube.v3.Data

@attribute [Authorize]
@rendermode RenderMode.InteractiveServer

@inject VideoPlanService videoPlanService
@inject IToastService toastService
@inject IUserProviderService userProviderService
@inject ILogger<MyVideoPlans> logger

<FluentLabel Typo="Typography.H3">
My Video Plans
</FluentLabel>
<LoadingIndicator ShowSpinners="this.IsBusy"></LoadingIndicator>


<FluentDataGrid ItemsProvider="this.itemsProvider">
<TemplateColumn>
<FluentAnchor data-enhance-nav="false"
data-bs-toggle="tooltip" data-bs-placement="top" title="Edit"
IconStart="@(new Icons.Regular.Size20.Edit())"
Href="@($"/Creator/UpdateVideoPlan/{context.VideoPlanId}")">
Edit
</FluentAnchor>
</TemplateColumn>
<PropertyColumn Property="@(p=>p.VideoName)"></PropertyColumn>
<PropertyColumn Property="@(p=>p.VideoDescription)"></PropertyColumn>
<PropertyColumn Property="@(p=>p.VideoScript)"></PropertyColumn>
</FluentDataGrid>
<FluentPaginator State="this.paginationState"></FluentPaginator>
@code {
private readonly CancellationTokenSource cancellationTokenSource = new();
private bool IsBusy { get; set; }
private PaginationState paginationState = new()
{
ItemsPerPage = Constants.Pagination.PageSize
};
private GridItemsProvider<VideoPlanModel>? itemsProvider;

protected override void OnInitialized()
{
this.itemsProvider = async req =>
{
this.IsBusy = true;
StateHasChanged();
var items = await this.videoPlanService.GetPaginatedVideoPlanAsync(paginationRequest: new()
{
PageSize = paginationState.ItemsPerPage
}, cancellationToken:this.cancellationTokenSource.Token);
this.IsBusy = false;
StateHasChanged();
var result = GridItemsProviderResult.From<VideoPlanModel>(items!.Items!, items.TotalItems);
return result;
};
}

void IDisposable.Dispose()
{
this.cancellationTokenSource.Dispose();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
@page "/Creator/UpdateVideoPlan/{VideoPlanId:long}"
@implements IDisposable

@using FairPlayCombined.Common
@using FairPlayCombined.Common.FairPlayTube.Enums
@using FairPlayCombined.Interfaces
@using FairPlayCombined.Models.FairPlayTube.VideoInfo
@using FairPlayCombined.Models.FairPlayTube.VideoPlan
@using FairPlayCombined.Services.Common
@using FairPlayCombined.Services.FairPlayTube
@using FairPlayTube.Components.Spinners
@using Google.Apis.YouTube.v3.Data
@attribute [Authorize]
@rendermode RenderMode.InteractiveServer

@inject PromptGeneratorService promptGeneratorService
@inject OpenAIService openAIService
@inject AzureVideoIndexerServiceConfiguration azureVideoIndexerServiceConfiguration
@inject AzureVideoIndexerService azureVideoIndexerService
@inject VideoPlanService videoPlanService
@inject IToastService toastService
@inject IUserProviderService userProviderService
@inject YouTubeClientService youTubeClientService
@inject ILogger<CreateVideoPlan> logger
@inject NavigationManager navigationManager

<FluentLabel Typo="Typography.H3">
Update Video Plan
</FluentLabel>
<LoadingIndicator ShowSpinners="this.IsBusy"></LoadingIndicator>

<FluentEditForm FormName="frmUpdateVideoPlan" Model="this.updateVideoPlanModel"
OnValidSubmit="OnValidSubmitAsync">
<div>
<DataAnnotationsValidator></DataAnnotationsValidator>
<FluentValidationSummary></FluentValidationSummary>
</div>
<div>
<FluentLabel Typo="Typography.Body">Name</FluentLabel>
<FluentTextField @bind-Value="this.updateVideoPlanModel.VideoName" Maxlength="50" style="width:100%;"></FluentTextField>
</div>
<div>
<FluentAccordion>
<FluentAccordionItem Heading="Description" Expanded="true">
<FluentTextArea @bind-Value="this.updateVideoPlanModel.VideoDescription" Rows="10" Maxlength="500" style="width:100%;"></FluentTextArea>
</FluentAccordionItem>
</FluentAccordion>
</div>
<div>
<FluentAccordion>
<FluentAccordionItem Heading="Video Script" Expanded="true">
<FluentTextArea @bind-Value="this.updateVideoPlanModel.VideoScript" Rows="40" Maxlength="3000" style="width:100%;"></FluentTextArea>
</FluentAccordionItem>
</FluentAccordion>
</div>
<div>
@if (!this.IsPlanCreated)
{
<FluentButton Type="ButtonType.Submit">Save</FluentButton>
}
else
{
<FluentLabel Typo="Typography.Body">Your Plan has been updated</FluentLabel>
}
</div>
</FluentEditForm>

<div>
@if (!String.IsNullOrWhiteSpace(this.GeneratedYouTubeThumbnailUri))
{
<a data-enhance-nav="false" href="@this.GeneratedYouTubeThumbnailUri" target="_blank">
<img class="@ThemeConfiguration.Images.ThumbnailDefaultCss" src="@this.GeneratedYouTubeThumbnailUri" />
</a>
<p>
<FluentLabel Typo="Typography.Body">
@this.RevisedPrompt
</FluentLabel>
</p>
}
</div>

@code {
[Parameter]
public long? VideoPlanId { get; set; }
[SupplyParameterFromForm]
private UpdateVideoPlanModel updateVideoPlanModel { get; set; } = new();
private readonly CancellationTokenSource cancellationTokenSource = new();
private bool IsBusy { get; set; }
private string? GeneratedYouTubeThumbnailUri { get; set; }
private string? RevisedPrompt { get; set; }
private bool IsPlanCreated { get; set; }
private VideoPlanModel? originalVideoPlan { get; set; }

protected override async Task OnInitializedAsync()
{
try
{
this.IsBusy = true;
StateHasChanged();
this.updateVideoPlanModel.ApplicationUserId = this.userProviderService.GetCurrentUserId();
if (this.originalVideoPlan is null)
{
this.originalVideoPlan = await this.videoPlanService.GetVideoPlanByIdAsync(this.VideoPlanId!.Value, this.cancellationTokenSource.Token);
this.updateVideoPlanModel.VideoPlanId = this.VideoPlanId.Value;
this.updateVideoPlanModel.VideoName = this.originalVideoPlan.VideoName;
this.updateVideoPlanModel.VideoDescription = this.originalVideoPlan.VideoDescription;
this.updateVideoPlanModel.VideoScript = this.originalVideoPlan.VideoScript;
}
}
catch (Exception ex)
{
this.toastService.ShowError(ex.Message);
}
finally
{
this.IsBusy = false;
StateHasChanged();
}
}

private async Task OnValidSubmitAsync()
{
try
{
this.IsBusy = true;
StateHasChanged();
await this.videoPlanService.UpdateVideoPlanAsync(
this.updateVideoPlanModel, this.cancellationTokenSource.Token);
this.toastService.ShowSuccess("Your Plan has been updated");
StateHasChanged();
this.IsPlanCreated = true;
var promptInfo = await this.promptGeneratorService.GetPromptCompleteInfoAsync(promptName:
"YouTubeThumbnail", cancellationToken: this.cancellationTokenSource.Token);
string prompt = $"{promptInfo!.BaseText}. Video Title: {this.updateVideoPlanModel.VideoName}. Video Description: {this.updateVideoPlanModel.VideoDescription}. Video Script: {this.updateVideoPlanModel.VideoScript}";
if (prompt.Length > 4000)
prompt = prompt.Substring(0, 4000);
var result = await this.openAIService.GenerateDallE3ImageAsync(prompt, this.cancellationTokenSource.Token);
if (result != null)
{
this.GeneratedYouTubeThumbnailUri = result!.data![0]!.url!;
this.RevisedPrompt = result!.data[0]!.revised_prompt;
this.toastService.ShowSuccess("Your thumbnail has been created");
}
else
{
this.toastService.ShowError("Your thumbnail could not be created");
}
}
catch (Exception ex)
{
this.toastService.ShowError(ex.Message);
}
finally
{
this.IsBusy = false;
StateHasChanged();
}
}

void IDisposable.Dispose()
{
this.cancellationTokenSource.Dispose();
}
}
3 changes: 3 additions & 0 deletions src/FairPlayCombinedSln/FairPlayTube/FairPlayTube.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
<ProjectReference Include="..\FairPlayCombinedSln.ServiceDefaults\FairPlayCombinedSln.ServiceDefaults.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="Components\Pages\Creator\UpdateVideoPlan.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
<Content Update="Components\Pages\Creator\NewVideoScript.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
Expand Down

0 comments on commit 4113956

Please sign in to comment.