Parcourir la source

Added navmenu with side bar and search track bar.

feature/blazor-frontend
Nemanja Grkovic il y a 3 ans
Parent
révision
a5a60c82ae

+ 1
- 1
GrpcShared/Interfaces/ITrackService.cs Voir le fichier

@@ -15,7 +15,7 @@ namespace GrpcShared.Interfaces
[Service]
public interface ITrackService
{
Task<SearchResponse> ListSearchAsync(SearchRequest request);
Task<IEnumerable<SearchResponse>> ListSearchAsync(SearchRequest request);
Task<SingleTrackResponse> ListSingleTrackAsync(SingleTrackRequest request);
Task<MultipleTrackResponse> ListMultipleTrackAsync(MultipleTrackRequest request);
Task SaveTracks(SaveTracksRequest request);

+ 0
- 1
IdentityProvider/Properties/launchSettings.json Voir le fichier

@@ -11,7 +11,6 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,

"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},

+ 5
- 2
NemAnCore/NemAnBlazor.csproj Voir le fichier

@@ -16,11 +16,14 @@

<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
<PackageReference Include="Blazorise.Bootstrap" Version="1.0.6" />
<PackageReference Include="Blazorise.Components" Version="1.0.6" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.0.6" />
<PackageReference Include="Grpc.Net.Client" Version="2.47.0" />
<PackageReference Include="Grpc.Net.Client.Web" Version="2.47.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.7" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.8" PrivateAssets="all" />
<PackageReference Include="MudBlazor" Version="6.0.14" />
<PackageReference Include="protobuf-net.Grpc" Version="1.0.171" />
</ItemGroup>

+ 28
- 28
NemAnCore/Pages/FetchData.razor Voir le fichier

@@ -36,34 +36,34 @@
private async Task Click()
{

var userInfo = await localStorage.GetItemAsync<string>("user_info");
var user = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage
{
Id = userInfo
});
TokenMessage tokenM = new TokenMessage { Token = user.Token, RefreshToken = user.RefreshToken };
SearchRequest request = new() { Query = "aitch", Type = "track", Token = user.Token };
try
{
SearchResponse searchResponse = await SearchService.GetListSearchAsync(request);
if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
{
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, user, localStorage, identityService);
}
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
return;
}
throw;
}
//var userInfo = await localStorage.GetItemAsync<string>("user_info");
//var user = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage
// {
// Id = userInfo
// });
//TokenMessage tokenM = new TokenMessage { Token = user.Token, RefreshToken = user.RefreshToken };
//SearchRequest request = new() { Query = "aitch", Type = "track", Token = user.Token };
//try
//{
// SearchResponse searchResponse = await SearchService.GetListSearchAsync(request);
// if (searchResponse.ResponseMsg == System.Net.HttpStatusCode.Unauthorized)
// {
// string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, user, localStorage, identityService);
// }
//}
//catch (RpcException e)
//{
// if (e.StatusCode == StatusCode.Cancelled)
// {
// return;
// }
// throw;
//}

}


+ 10
- 10
NemAnCore/Pages/Login.razor Voir le fichier

@@ -11,22 +11,22 @@
@using System.Security.Claims
@inject Blazored.LocalStorage.ILocalStorageService localStorage
@*<Heading Size="HeadingSize.Is1" Margin="Margin.Is3.FromBottom">Dashboard</Heading>*@


<AuthorizeView>
<Authorized>
<p>Dobrodosli @context.User.Claims.FirstOrDefault(x => x.Type == "name")?.Value.ToUpper()</p>
</Authorized>
<NotAuthorized>
<Paragraph>Dobrodošli @context.User.Claims.FirstOrDefault(x => x.Type == "name")?.Value.ToUpper()</Paragraph>
</Authorized>
@*<NotAuthorized>
<Paragraph>
Nisi autorizovan.
<button class="btn btn-primary" @onclick="LoginUser">Login</button>
</NotAuthorized>
</Paragraph>
<button class="btn btn-success" @onclick="LoginUser">Login</button>
</NotAuthorized>*@
</AuthorizeView>

<PageTitle>Index</PageTitle>

<MudText Typo="Typo.h3" GutterBottom="true">Pozdrav Diligent!</MudText>
<MudText Class="mb-8">
Dobrodošli u našu NemAn aplikaciju.
</MudText>




+ 10
- 1
NemAnCore/Program.cs Voir le fichier

@@ -1,5 +1,8 @@
global using Microsoft.AspNetCore.Components.Authorization;
using Blazored.LocalStorage;
using Blazorise;
using Blazorise.Bootstrap;
using Blazorise.Icons.FontAwesome;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using Microsoft.AspNetCore.Components;
@@ -25,7 +28,13 @@ builder.Services.AddScoped(_ =>
});
builder.Services.AddAuthorizationCore();
//builder.Services.AddScoped<AuthenticationStateProvider, AuthClientService>();
builder.Services.AddMudServices();
builder.Services
.AddBlazorise(options =>
{
options.Immediate = true;
})
.AddBootstrapProviders()
.AddFontAwesomeIcons();

builder.Services.AddScoped<ITrackClientService, TrackClientService>();
builder.Services.AddScoped<IAuthClientService, AuthClientService>();

+ 8
- 7
NemAnCore/Properties/launchSettings.json Voir le fichier

@@ -1,16 +1,17 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true
},
"profiles": {
"NemAnCore": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"hotReloadProfile": "aspnetcore",
"hotReloadEnabled": false
}
},
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true
}
}

}

+ 1
- 1
NemAnCore/Services/Interfaces/ITrackClientService.cs Voir le fichier

@@ -8,7 +8,7 @@ namespace NemAnBlazor.Services.Interfaces
{
public interface ITrackClientService
{
Task<SearchResponse> GetListSearchAsync(SearchRequest request);
Task<IEnumerable<SearchResponse>> GetListSearchAsync(SearchRequest request);
Task<SingleTrackResponse> GetListSingleTrackAsync(SingleTrackRequest request);
Task<MultipleTrackResponse> GetListMultipleTrackAsync(MultipleTrackRequest request);
Task PutSaveTracks(SaveTracksRequest request);

+ 1
- 1
NemAnCore/Services/TrackClientService.cs Voir le fichier

@@ -20,7 +20,7 @@ namespace NemAnBlazor.Services
}


public async Task<SearchResponse> GetListSearchAsync(SearchRequest request)
public async Task<IEnumerable<SearchResponse>> GetListSearchAsync(SearchRequest request)
{
return await _serviceClient.ListSearchAsync(request);
}

+ 87
- 0
NemAnCore/Shared/HeaderBar.razor Voir le fichier

@@ -0,0 +1,87 @@
@using Grpc.Core
@using GrpcShared.DTO
@using GrpcShared.DTO.Auth
@using GrpcShared.DTO.Search
@using NemAnBlazor.Services.Interfaces
@using System.Net
@inject NavigationManager NavigationManager
@inject Blazored.LocalStorage.ILocalStorageService localStorage
@inject ITrackClientService SearchService
@inject IAuthClientService AuthService
@inject IIdentityClientService identityService

<Bar Breakpoint="Breakpoint.Desktop"
Background="Background.Body"
ThemeContrast="ThemeContrast.Light">
<BarToggler />
<BarMenu>
<BarStart>
<Autocomplete TItem="SearchResponse"
TValue="string"
Data="@Searches"
TextField="@(( item ) => item!.Tracks!.Items!.FirstOrDefault()!.Name)"
ValueField="@(( item ) => item!.Tracks!.Items!.FirstOrDefault()!.Name)"
Filter="AutocompleteFilter.StartsWith"
Placeholder="Search..."
FreeTyping>

</Autocomplete>
</BarStart>
<BarEnd>
<BarItem>
<Button class="btn btn-success" @onclick="LoginUser">Log in</Button>
</BarItem>
</BarEnd>
</BarMenu>
</Bar>

@code {
public IEnumerable<SearchResponse>? Searches;
private string? search;


private async Task LoginUser()
{
CodeRequest authParams = await AuthService.GetAuthParams();
string url = $"https://accounts.spotify.com/en/authorize?client_id={authParams.ClientId}&redirect_uri={authParams.RedirectURI}&response_type={authParams.ResponseType}&scope={authParams.Scope}&show_dialog={authParams.ShowDialog}";
NavigationManager.NavigateTo(url);

}

protected override async Task OnInitializedAsync(){

var userInfo = await localStorage.GetItemAsync<string>("user_info");
if (userInfo != null) NavigationManager.NavigateTo("/home");


var user = await identityService.GetTokenByIdAsync(new GrpcShared.DTO.Db.DbRequestMessage
{
Id = userInfo!
});

TokenMessage tokenM = new TokenMessage { Token = user.Token, RefreshToken = user.RefreshToken };

SearchRequest request = new() { Query = search, Type = "track", Token = user.Token };

try
{
Searches = await SearchService.GetListSearchAsync(request);

if (Searches == null)
{
string? tempToken = await SpotifyHelper.TryRefreshToken(AuthService, tokenM, user, localStorage, identityService);
}

await base.OnInitializedAsync();
}
catch (RpcException e)
{
if (e.StatusCode == StatusCode.Cancelled)
{
return;
}
throw;
}

}
}

+ 14
- 28
NemAnCore/Shared/MainLayout.razor Voir le fichier

@@ -1,31 +1,17 @@
@inherits LayoutComponentBase

<MudThemeProvider />
<MudDialogProvider />
<MudSnackbarProvider />

<MudLayout>
<MudAppBar Elevation="0">
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
</MudAppBar>
<MudDrawer @bind-Open="_drawerOpen" Elevation="1">
<MudDrawerHeader>
<MudText Typo="Typo.h6">Spotify</MudText>
</MudDrawerHeader>
<NavMenu />
</MudDrawer>
<MudMainContent>
<MudContainer MaxWidth="MaxWidth.Large" Class="my-16 pt-16">
<Layout Sider>
<LayoutSider>
<LayoutSiderContent>
<NavMenu />
</LayoutSiderContent>
</LayoutSider>
<Layout>
<LayoutHeader Fixed>
<HeaderBar />
</LayoutHeader>
<LayoutContent Padding="Padding.Is4.OnX" Background="Background.Light">
@Body
</MudContainer>
</MudMainContent>
</MudLayout>

@code {
bool _drawerOpen = true;

void DrawerToggle()
{
_drawerOpen = !_drawerOpen;
}
}
</LayoutContent>
</Layout>
</Layout>

+ 33
- 13
NemAnCore/Shared/NavMenu.razor Voir le fichier

@@ -1,16 +1,36 @@
<MudNavMenu>
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Dashboard</MudNavLink>
<MudNavLink Href="home" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Home</MudNavLink>
<MudNavLink Href="search" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.List">Search</MudNavLink>
</MudNavMenu>
<Bar Mode="BarMode.VerticalInline"
CollapseMode="BarCollapseMode.Small"
Breakpoint="Breakpoint.Desktop"
NavigationBreakpoint="Breakpoint.Tablet"
ThemeContrast="ThemeContrast.Dark"
Background="Background.Body">
<BarToggler/>
<BarBrand>
<BarItem>
<BarLink To="">
<img src="/spotify-icon-marilyn-scott-0.png" style="width: 32px; height: 32px; padding: 1px" />
Spotify
</BarLink>
</BarItem>
</BarBrand>
<BarMenu>
<BarStart>
<BarItem>
<BarLink To="">
<BarIcon IconName="IconName.Dashboard" />
Dashboard
</BarLink>
</BarItem>
<BarItem>
<BarLink To="/home">
<BarIcon IconName="IconName.Home" />
Home
</BarLink>
</BarItem>
</BarStart>
</BarMenu>
</Bar>

@code {
private bool collapseNavMenu = true;

private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}

+ 2
- 1
NemAnCore/_Imports.razor Voir le fichier

@@ -10,4 +10,5 @@
@using NemAnBlazor.Shared
@using System.Web
@using Microsoft.AspNetCore.Components.Authorization
@using MudBlazor
@using Blazorise
@using Blazorise.Components

+ 8
- 3
NemAnCore/wwwroot/index.html Voir le fichier

@@ -9,8 +9,11 @@
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="NemAnBlazor.styles.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css">

<link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
<link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" />
</head>

<body>
@@ -22,7 +25,9 @@
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
</body>

</html>

BIN
NemAnCore/wwwroot/spotify-icon-marilyn-scott-0.png Voir le fichier


+ 2
- 2
gRPCServer/Services/TrackService.cs Voir le fichier

@@ -26,14 +26,14 @@ namespace SpotifyService.Services
{
_httpClientFactory = httpClientFactory;
}
public async Task<SearchResponse> ListSearchAsync(SearchRequest request)
public async Task<IEnumerable<SearchResponse>> ListSearchAsync(SearchRequest request)
{

var client = _httpClientFactory.CreateClient("HttpClient");

string url = $"search?q={request.Query}&type={request.Type}";

return await HttpUtils.HttpUtils<SearchResponse>.GetData(client, url, request.Token!);
return await HttpUtils.HttpUtils<IEnumerable<SearchResponse>>.GetData(client, url, request.Token!);


}

Chargement…
Annuler
Enregistrer