Compare commits

...

2 Commits

Author SHA1 Message Date
Loretta 72071e7a79 Convert to Devexpress solution; impovements, clean, etc... 2025-09-17 06:02:32 +02:00
Loretta 37ceac59b8 empty 2025-09-17 05:22:26 +02:00
63 changed files with 12718 additions and 689 deletions

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Root Type="DevExpress.CodeRush.Foundation.CodePlaces.Options.FavoritesListContainer">
<Options Language="Neutral">
<Groups />
</Options>
</Root>

View File

@ -1,7 +0,0 @@
namespace FruitBankHybrid.Shared.Common
{
public class Class1
{
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
@ -11,6 +11,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DevExpress.Blazor" Version="25.1.*" />
<PackageReference Include="MessagePack" Version="3.1.4" />
<PackageReference Include="MessagePack.Annotations" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.8" />
@ -62,6 +63,8 @@
<Reference Include="Mango.Nop.Core">
<HintPath>..\..\NopCommerce.Common\4.70\Libraries\Mango.Nop.Core\bin\FruitBank\Debug\net9.0\Mango.Nop.Core.dll</HintPath>
</Reference>
<Reference Include="Nop.Core">
<HintPath>..\..\NopCommerce.Common\4.70\Libraries\Mango.Nop.Core\bin\FruitBank\Debug\net9.0\Nop.Core.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -7,7 +7,7 @@
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
<a href="">Kijelentkezés</a>
</div>
<article class="content px-4">

View File

@ -1,6 +1,6 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">FruitBank</a>
<a class="navbar-brand" href="">FruitBank Measuring</a>
</div>
</div>
@ -10,26 +10,25 @@
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
<span class="icon home-icon" aria-hidden="true"></span> Kezdőlap
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="MeasuringIn">
<span class="icon counter-icon" aria-hidden="true"></span> Bejövő mérés
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="MeasuringOut">
<span class="icon counter-icon" aria-hidden="true"></span> Kimenő mérés
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="Login">
<span class="icon weather-icon" aria-hidden="true"></span> Bejelentkezés
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="chat">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Chat
</NavLink>
</div>
</nav>
</div>

View File

@ -0,0 +1,30 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">FruitBankHybrid</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="icon home-icon" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="icon counter-icon" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="weather">
<span class="icon weather-icon" aria-hidden="true"></span> Weather
</NavLink>
</div>
</nav>
</div>

View File

@ -8,11 +8,12 @@
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 0.3rem;
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
background-color: rgb(10, 14, 57);
}
.top-row {
@ -24,26 +25,21 @@
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
::deep .icon {
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
::deep .home-icon {
--icon-mask-image: var(--icon-home-mask-image);
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
::deep .weather-icon {
--icon-mask-image: var(--icon-weather-mask-image);
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
::deep .counter-icon {
--icon-mask-image: var(--icon-counter-mask-image);
}
.nav-item {

View File

@ -1,60 +0,0 @@
@page "/chat"
@using DevExpress.Blazor
@using DevExpress.Blazor.Internal
@using FruitBankHybrid.Shared.Services
@* @inject ISignalRService SignalR *@
<h3>Measuring</h3>
@* <DxDropDownButton></DxDropDownButton> *@
@* <div>
<DxDropDownButton RenderStyle="ButtonRenderStyle.Secondary"
Text="Select Employee"
CssClass="me-1"
IconCssClass="menu-icon-user-profile menu-icon"
DropDownVisible="DropDownVisible">
<DropDownContentTemplate>
<div>
<DxListBox Data="@Users"
@bind-Value="@SelectedUser"
CssClass="listbox">
<ItemDisplayTemplate>
<div class="listbox-item-template">
<span class="listbox-item-template-name">@context.DataItem.Username</span>
</div>
</ItemDisplayTemplate>
</DxListBox>
</div>
</DropDownContentTemplate>
</DxDropDownButton>
<p class="demo-text cw-400 mt-2">
Selected item: <b>@SelectedUser?.Username</b>
</p>
</div>
*@
<div>
<ul>
@foreach (var user in Users)
{
<li>@user.Username - @user.Email</li>
}
</ul>
</div>
<div>
<input @bind="_userName" placeholder="Your name" />
<input @bind="_message" placeholder="Partner ID..." />
<button @onclick="GetPartner">Get partner</button>
<ul>
@foreach (var m in _messages)
{
<li><b>@m.User:</b> @m.Text</li>
}
</ul>
</div>
@code {
}

View File

@ -1,18 +0,0 @@
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@ -2,13 +2,21 @@
@using FruitBankHybrid.Shared.Services
@inject IFormFactor FormFactor
<PageTitle>Home</PageTitle>
<PageTitle>Kezdőlap</PageTitle>
<h1>Hello, world!</h1>
<h1>Kezdőlap</h1>
Welcome to your new app running on <em>@factor</em> using <em>@platform</em>.
Welcome to your new app running on <em>@Factor</em> using <em>@Platform</em>.
@code {
private string factor => FormFactor.GetFormFactor();
private string platform => FormFactor.GetPlatform();
}
<div class="row cw-480" style="margin-top: 100px;">
<div class="col-md-6">
<NavLink href="MeasuringIn">
<span class="icon counter-icon" aria-hidden="true"></span> Bejövő mérés
</NavLink>
</div>
<div class="col-md-6">
<NavLink href="MeasuringOut">
<span class="icon counter-icon" aria-hidden="true"></span> Kimenő mérés
</NavLink>
</div>
</div>

View File

@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Components;
namespace FruitBankHybrid.Shared.Pages;
public partial class Home : ComponentBase
{
private string Factor => FormFactor.GetFormFactor();
private string Platform => FormFactor.GetPlatform();
}

View File

@ -0,0 +1,53 @@
@page "/Login"
@using Mango.Nop.Core.Dtos
<h3>Bejelentkezés</h3>
<div class="row cw-480" style="margin-top: 30px;">
<div class="col-md-6">
<DxComboBox Data="@Users"
@bind-Value="@SelectedUser"
Text="Select Employee"
ValueFieldName="@nameof(CustomerDto.Id)"
TextFieldName="@nameof(CustomerDto.FullName)"
CssClass="cw-480"
InputId="cbItemTemplate">
<ItemDisplayTemplate>
<div class="combobox-item-template">
<img src="@GetImageFileName(context.DataItem)" alt="@context.DataItem.Email" />
<div class="combobox-item-template-text">
<span>@context.DataItem.FullName</span>
<span class="combobox-item-template-employee-phone">@context.DataItem.Email</span>
</div>
</div>
</ItemDisplayTemplate>
</DxComboBox>
</div>
<div class="col-md-6">
<DxTextBox @bind-Text="@PasswordValue"
@onkeydown="OnPasswordKeyDown"
Password="true"
CssClass="cw-320"
ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto"
BindValueMode="BindValueMode.OnInput"
NullText="Enter password"
InputId="tbPassword" />
</div>
<div class="row cw-480" style="margin-top: 20px;">
<div class="col-md-12">
<DxButton Text="Bejelentkezés"
Click="OnLoginClick"
CssClass="w-100" />
</div>
</div>
<div class="row cw-480" style="margin-top: 30px;">
<div class="col-md-12">
<b>@(LoginModelResponse?.CustomerDto == null ? LoginModelResponse?.ErrorMessage : LoginModelResponse?.CustomerDto.FullName)</b>
</div>
</div>
</div>

View File

@ -0,0 +1,63 @@
using AyCode.Core.Helpers;
using AyCode.Core.Loggers;
using AyCode.Interfaces.Users;
using AyCode.Utils.Extensions;
using FruitBank.Common.Loggers;
using FruitBankHybrid.Shared.Services.Loggers;
using FruitBankHybrid.Shared.Services.SignalRs;
using Mango.Nop.Core.Dtos;
using Mango.Nop.Core.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
namespace FruitBankHybrid.Shared.Pages;
public partial class Login : ComponentBase
{
[Inject] public required IEnumerable<IAcLogWriterClientBase> LogWriters { get; set; }
[Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; }
private ILogger _logger = null!;
private List<CustomerDto> Users { get; set; }
private CustomerDto? SelectedUser { get; set; }
private string PasswordValue { get; set; } = string.Empty;
private MgLoginModelResponse? LoginModelResponse { get; set; }
protected override async Task OnInitializedAsync()
{
_logger = new LoggerClient<Login>(LogWriters.ToArray());
_logger.Info("OnInitializedAsync");
Users = await FruitBankSignalRClient.GetMeasuringUsers() ?? [];
SelectedUser = Users.FirstOrDefault();
await base.OnInitializedAsync();
}
private async Task OnLoginClick()
{
if (SelectedUser == null || PasswordValue.IsNullOrWhiteSpace())
{
LoginModelResponse = new MgLoginModelResponse
{
ErrorMessage = "Válasszon felhsználót és adja meg a jelszavát!"
};
return;
}
LoginModelResponse = await FruitBankSignalRClient.LoginMeasuringUser(SelectedUser.Email, PasswordValue);
}
protected async Task OnPasswordKeyDown(KeyboardEventArgs e)
{
if (e.Key == "Enter") await OnLoginClick();
}
private string GetImageFileName(CustomerDto employee)
{
//return StaticAssetUtils.GetEmployeeImagePath(employee.Id);
return string.Empty;
}
}

View File

@ -0,0 +1,23 @@
.combobox-item-template {
display: flex;
align-items: center;
}
.combobox-item-template > img {
border-radius: 50%;
width: 2rem;
height: 2rem;
}
img + .combobox-item-template-text {
margin-left: 1rem;
}
.combobox-item-template-text {
display: flex;
flex-flow: column;
}
.combobox-item-template-employee-phone {
opacity: 0.65;
}

View File

@ -0,0 +1,74 @@
@page "/MeasuringIn"
@using DevExpress.Blazor
@using DevExpress.Blazor.Internal
@using FruitBank.Common.Entities
@using FruitBankHybrid.Shared.Services
@using Mango.Nop.Core.Dtos
<h3>Bejövő mérés</h3>
<div class="row cw-480" style="margin-top: 50px;">
<div class="col-md-4">
<label for="cbNotMeasuredShippings" class="demo-text mb-1">Szállítmány</label>
<DxComboBox Data="@NotMeasuredShippings"
@bind-Value="@SelectedShipping"
Text="Select shipping"
ValueFieldName="@nameof(Shipping.Id)"
TextFieldName="@nameof(Shipping.ShippingDate)"
CssClass="cw-480"
SelectedDataItemChanged="@((SelectedDataItemChangedEventArgs<Shipping> args) => OnSelectedShippingChanged(args))"
InputId="cbNotMeasuredShippings">
<ItemDisplayTemplate>
<div class="combobox-item-template">
<div class="combobox-item-template-text">
<span>@($"{context.DataItem.ShippingDate} [{context.DataItem.LicencePlate}]")</span>
@* <span class="combobox-item-template-employee-phone">@(string.Join("; ", context.DataItem?.ShippingDocuments?.Select(x => x.Partner?.Name ?? string.Empty)))</span> *@
</div>
</div>
</ItemDisplayTemplate>
</DxComboBox>
</div>
<div class="col-md-4">
<label for="cbShippingDocument" class="demo-text mb-1">Dokumentum</label>
<DxComboBox Data="@SelectedShipping?.ShippingDocuments"
@bind-Value="@SelectedShippingDocument"
Text="Select document"
ValueFieldName="@nameof(ShippingDocument.Id)"
TextFieldName="@(nameof(ShippingDocument.Partner) + '.' + nameof(Partner.Name))"
CssClass="cw-480"
SelectedDataItemChanged="@((SelectedDataItemChangedEventArgs<ShippingDocument> args) => OnSelectedShippingDocumentChanged(args))"
InputId="cbShippingDocument" />
</div>
<div class="col-md-4">
<label for="cbShippingItem" class="demo-text mb-1">Termék</label>
<DxComboBox Data="@SelectedShippingDocument?.ShippingItems"
@bind-Value="@SelectedShippingItem"
Text="Select item"
ValueFieldName="@nameof(ShippingItem.Id)"
TextFieldName="@(nameof(ShippingItem.Name))"
CssClass="cw-480"
InputId="cbShippingItem" />
</div>
</div>
<div class="row cw-480" style="margin-top: 100px;">
<div class="col-md-12">
<input @bind="_userName" placeholder="Your name" />
<input @bind="_message" placeholder="Partner ID..." />
<button @onclick="GetPartner">Get partner</button>
</div>
</div>
<div class="row cw-480">
<div class="col-md-12">
<ul>
@foreach (var m in _messages)
{
<li><b>@m.User:</b> @m.Text</li>
}
</ul>
</div>
</div>

View File

@ -1,11 +1,13 @@
using AyCode.Core.Helpers;
using AyCode.Core.Loggers;
using AyCode.Models.Users;
using DevExpress.Blazor;
using FruitBank.Common.Entities;
using FruitBank.Common.Loggers;
using FruitBank.Common.Models;
using FruitBankHybrid.Shared.Services.Loggers;
using FruitBankHybrid.Shared.Services.SignalRs;
using Mango.Nop.Core.Dtos;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Logging;
using Microsoft.JSInterop;
@ -15,41 +17,51 @@ using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Mango.Nop.Core.Dtos;
using static System.Net.Mime.MediaTypeNames;
using static System.Runtime.InteropServices.JavaScript.JSType;
using ILogger = FruitBank.Common.Loggers.ILogger;
namespace FruitBankHybrid.Shared.Pages
{
public partial class Chat : ComponentBase
public partial class MeasuringIn : ComponentBase
{
[Inject] public required IEnumerable<IAcLogWriterClientBase> LogWriters { get; set; }
[Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; }
private ILogger _logger;
private ILogger _logger = null!;
private List<Shipping> NotMeasuredShippings { get; set; } = null!;
private Shipping? SelectedShipping { get; set; }
private ShippingDocument? SelectedShippingDocument { get; set; }
private ShippingItem? SelectedShippingItem { get; set; }
private string _userName = "Partner name";
private string _message;
private string _message = string.Empty;
private readonly List<(string User, string Text)> _messages = [];
private List<CustomerDto> Users { get; set; } = [];
private bool DropDownVisible { get; set; }
private CustomerDto? SelectedUser { get; set; }
protected override async Task OnInitializedAsync()
{
_logger = new LoggerClient<Chat>(LogWriters.ToArray());
_logger = new LoggerClient<MeasuringIn>(LogWriters.ToArray());
_logger.Info("OnInitializedAsync");
Users.AddRange(await FruitBankSignalRClient.GetMeasuringUsers() ?? []);
//SelectedUser = Users.FirstOrDefault();
//DropDownVisible = false;
NotMeasuredShippings = await FruitBankSignalRClient.GetNotMeasuredShippings() ?? [];
SelectedShipping = NotMeasuredShippings?.FirstOrDefault();
await base.OnInitializedAsync();
}
public void OnSelectedShippingChanged(SelectedDataItemChangedEventArgs<Shipping> eventArgs)
{
SelectedShippingDocument = eventArgs.DataItem.ShippingDocuments?.FirstOrDefault();
SelectedShippingItem = SelectedShippingDocument?.ShippingItems?.FirstOrDefault();
}
public void OnSelectedShippingDocumentChanged(SelectedDataItemChangedEventArgs<ShippingDocument> eventArgs)
{
SelectedShippingItem = eventArgs.DataItem?.ShippingItems?.FirstOrDefault();
}
private async Task GetPartner()
{
var measuringModel = new MeasuringModel();

View File

@ -0,0 +1,6 @@
@page "/MeasuringOut"
<h3>Kimenő mérés</h3>
@code {
}

View File

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FruitBankHybrid.Shared.Pages
{
public partial class MeasuringOut : ComponentBase
{
}
}

View File

@ -1,63 +0,0 @@
@page "/weather"
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
// Simulate asynchronous loading to demonstrate a loading indicator
await Task.Delay(500);
var startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
}).ToArray();
}
private class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

View File

@ -1,5 +1,4 @@
@using Microsoft.AspNetCore.Components.Routing
<Router AppAssembly="typeof(Layout.MainLayout).Assembly">
<Router AppAssembly="typeof(Layout.MainLayout).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FruitBankHybrid.Shared.Services
{
public interface ISignalRService
{
event Action<string, string>? MessageReceived;
Task InitializeAsync();
Task SendMessageAsync(string user, string message);
ValueTask DisposeAsync();
}
}

View File

@ -1,57 +0,0 @@
using FruitBank.Common;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FruitBankHybrid.Shared.Services
{
public class SignalRService : IAsyncDisposable, ISignalRService
{
private HubConnection _hubConnection;
private readonly NavigationManager _navigationManager;
public event Action<string, string>? MessageReceived;
public SignalRService(NavigationManager navigationManager)
{
_navigationManager = navigationManager;
}
public async Task InitializeAsync()
{
// Build the connection (assuming same domain as Blazor app, otherwise use full URL)
_hubConnection = new HubConnectionBuilder()
//.WithUrl(_navigationManager.ToAbsoluteUri($"https://localhost:59579/{FruitBankConstClient.DefaultHubName}"))
.WithUrl(_navigationManager.ToAbsoluteUri($"{FruitBankConstClient.BaseUrl}/{FruitBankConstClient.DefaultHubName}"))
.WithAutomaticReconnect()
.Build();
// Register incoming handler
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
MessageReceived?.Invoke(user, message);
});
await _hubConnection.StartAsync();
}
public async Task SendMessageAsync(string user, string message)
{
if (_hubConnection.State == HubConnectionState.Connected)
await _hubConnection.InvokeAsync("SendMessage", user, message);
}
public async ValueTask DisposeAsync()
{
if (_hubConnection is not null)
{
await _hubConnection.DisposeAsync();
}
}
}
}

View File

@ -6,4 +6,5 @@
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using DevExpress.Blazor

View File

@ -49,3 +49,22 @@ h1:focus {
.darker-border-checkbox.form-check-input {
border-color: #929292;
}
.icon {
--icon-width: 1.25rem;
--icon-height: 1.25rem;
--icon-home-mask-image: url("images/home-fluent.svg");
--icon-weather-mask-image: url("images/weather-fluent.svg");
--icon-counter-mask-image: url("images/counter-fluent.svg");
}
.icon {
width: var(--icon-width);
height: var(--icon-height);
background-color: currentcolor;
mask-position: center center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-image: var(--icon-mask-image);
mask-image: var(--icon-mask-image);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 584 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DevExpress.Blazor" Version="25.1.*" />
<PackageReference Include="MessagePack" Version="3.1.4" />
<PackageReference Include="MessagePack.Annotations" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.8" />

View File

@ -1,7 +1,7 @@
using FruitBankHybrid.Shared.Services;
namespace FruitBankHybrid.Web.Client.Services;
namespace FruitBankHybrid.Web.Client.Services
{
public class FormFactor : IFormFactor
{
public string GetFormFactor()
@ -14,3 +14,4 @@ public class FormFactor : IFormFactor
return Environment.OSVersion.ToString();
}
}
}

View File

@ -8,4 +8,5 @@
@using Microsoft.JSInterop
@using FruitBankHybrid.Shared
@using FruitBankHybrid.Web.Client
@using DevExpress.Blazor

View File

@ -1,4 +1,5 @@
@using DevExpress.Blazor
@using Microsoft.AspNetCore.Mvc.ViewFeatures
@inject IFileVersionProvider FileVersionProvider
<!DOCTYPE html>
<html lang="en">
@ -7,21 +8,16 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="_content/FruitBankHybrid.Shared/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="_content/FruitBankHybrid.Shared/app.css" />
<link rel="stylesheet" href="FruitBankHybrid.Web.styles.css" />
<link rel="icon" type="image/png" href="_content/FruitBankHybrid.Shared/favicon.png" />
@DxResourceManager.RegisterTheme(Themes.Fluent)
@DxResourceManager.RegisterScripts()
<link href=@AppendVersion("css/site.css") rel="stylesheet" />
<link href=@AppendVersion("FruitBankHybrid.Shared.styles.css") rel="stylesheet" />
@DxResourceManager.RegisterTheme(Themes.Fluent)
<link href=@AppendVersion("_content/FruitBankHybrid.Shared/bootstrap/bootstrap.min.css") rel="stylesheet" />
<link href=@AppendVersion("_content/FruitBankHybrid.Shared/app.css") rel="stylesheet" />
<link href=@AppendVersion("FruitBankHybrid.Web.styles.css") rel="stylesheet" />
<link href=@AppendVersion("_content/FruitBankHybrid.Shared/favicon.png") rel="icon" type="image/png" />
<HeadOutlet @rendermode="InteractiveWebAssembly" />
</head>
<body>
<body class="dxbl-theme-fluent">
<Routes @rendermode="InteractiveWebAssembly" />
<script src="_framework/blazor.web.js"></script>
</body>
@ -29,5 +25,5 @@
</html>
@code {
private string AppendVersion(string path) => $"{path}?v={typeof(DevExpress.Blazor.ResourcesConfigurator).Assembly.GetName().Version}";
private string AppendVersion(string path) => FileVersionProvider.AddFileVersionToPath("/", path);
}

View File

@ -10,4 +10,5 @@
@using FruitBankHybrid.Web
@using FruitBankHybrid.Web.Client
@using FruitBankHybrid.Web.Components
@using DevExpress.Blazor

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
@ -6,12 +6,15 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\FruitBank.Common.Server\FruitBank.Common.Server.csproj" />
<ProjectReference Include="..\FruitBank.Common\FruitBank.Common.csproj" />
<ProjectReference Include="..\FruitBankHybrid.Shared.Common\FruitBankHybrid.Shared.Common.csproj" />
<ProjectReference Include="..\FruitBankHybrid.Shared\FruitBankHybrid.Shared.csproj" />
<ProjectReference Include="..\FruitBankHybrid.Web.Client\FruitBankHybrid.Web.Client.csproj" />
<PackageReference Include="DevExpress.Blazor" Version="25.1.*" />
<PackageReference Include="MessagePack" Version="3.1.4" />
<PackageReference Include="MessagePack.Annotations" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.8" />
@ -75,4 +78,6 @@
<Folder Include="Services\SignalRs\" />
</ItemGroup>
</Project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>https</ActiveDebugProfile>
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/MVC/Controller</Controller_SelectedScaffolderCategoryPath>
</PropertyGroup>
</Project>

View File

@ -6,14 +6,12 @@ using FruitBankHybrid.Shared.Services;
using FruitBankHybrid.Web.Components;
using FruitBankHybrid.Web.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents().AddInteractiveWebAssemblyComponents();
builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddInteractiveWebAssemblyComponents();
builder.Services.AddDevExpressBlazor();
builder.Services.AddMvc();
// Add device-specific services used by the FruitBankHybrid.Shared project
builder.Services.AddSingleton<IFormFactor, FormFactor>();
builder.Services.AddSingleton<LoggerToLoggerApiController>();
@ -22,7 +20,6 @@ builder.Services.AddSingleton<IAcLogWriterBase, ConsoleLogWriter>();
//builder.Services.AddScoped<IFruitBankDataControllerServer, FruitBankDataController>();
builder.Services.AddSignalR(options => options.MaximumReceiveMessageSize = 256 * 1024);
var app = builder.Build();
// Configure the HTTP request pipeline.
@ -44,8 +41,10 @@ app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>()
//.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(
typeof(FruitBankHybrid.Shared._Imports).Assembly,

View File

@ -1,41 +0,0 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:38341",
"sslPort": 44381
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "http://localhost:5291",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7144;http://localhost:5291",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -1,7 +1,7 @@
using FruitBankHybrid.Shared.Services;
namespace FruitBankHybrid.Web.Services;
namespace FruitBankHybrid.Web.Services
{
public class FormFactor : IFormFactor
{
public string GetFormFactor()
@ -14,3 +14,4 @@ public class FormFactor : IFormFactor
return Environment.OSVersion.ToString();
}
}
}

View File

@ -1,22 +1,23 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35825.156
VisualStudioVersion = 17.14.36414.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid", "FruitBankHybrid\FruitBankHybrid.csproj", "{9CF098A9-CAED-4645-ABCE-AF46B1EA4607}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid", "FruitBankHybrid\FruitBankHybrid.csproj", "{85ADEDE3-C271-47DF-B273-2EDB32792CEF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Shared", "FruitBankHybrid.Shared\FruitBankHybrid.Shared.csproj", "{A44D38E7-7A95-46A7-A5EE-8927892D1275}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Shared", "FruitBankHybrid.Shared\FruitBankHybrid.Shared.csproj", "{899988C3-8F36-4B19-A1DE-1D1D85F114D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Web", "FruitBankHybrid.Web\FruitBankHybrid.Web.csproj", "{B3E52FA7-643A-4DE2-B9A4-561402A80235}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Web", "FruitBankHybrid.Web\FruitBankHybrid.Web.csproj", "{AB2ED973-EBCD-4098-BF7B-045382221D1B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Web.Client", "FruitBankHybrid.Web.Client\FruitBankHybrid.Web.Client.csproj", "{FD5B9DB9-A9CC-4A8F-ADC5-81EF43DDDD1F}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Web.Client", "FruitBankHybrid.Web.Client\FruitBankHybrid.Web.Client.csproj", "{4E4B641B-1757-4A37-8FFE-769F6E0C98EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Shared.Common", "FruitBankHybrid.Shared.Common\FruitBankHybrid.Shared.Common.csproj", "{6D98A5F8-2A26-4559-B301-5E1E4C728689}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBank.Common", "FruitBank.Common\FruitBank.Common.csproj", "{843805DF-6643-1364-D890-14B2E4826278}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBank.Common", "FruitBank.Common\FruitBank.Common.csproj", "{610EB36E-6823-4334-95E4-435A5E0A94C8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBank.Common.Server", "FruitBank.Common.Server\FruitBank.Common.Server.csproj", "{95069D8D-BCD5-77C6-DFAB-3F4C5ADBA85B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBank.Common.Server", "FruitBank.Common.Server\FruitBank.Common.Server.csproj", "{AD3AB968-A79F-485C-8B3E-B6917A5E4C71}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Shared.Common", "FruitBankHybrid.Shared.Common\FruitBankHybrid.Shared.Common.csproj", "{ABEDC482-1EC3-A770-227F-D69CE16F36A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Shared.Tests", "FruitBankHybrid.Shared.Tests\FruitBankHybrid.Shared.Tests.csproj", "{BE107917-831F-45E6-87F3-96D1DF418309}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FruitBankHybrid.Shared.Tests", "FruitBankHybrid.Shared.Tests\FruitBankHybrid.Shared.Tests.csproj", "{4E4E4917-1CA3-A7D7-40A8-A24A08673EC1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -24,44 +25,43 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9CF098A9-CAED-4645-ABCE-AF46B1EA4607}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CF098A9-CAED-4645-ABCE-AF46B1EA4607}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CF098A9-CAED-4645-ABCE-AF46B1EA4607}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{9CF098A9-CAED-4645-ABCE-AF46B1EA4607}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CF098A9-CAED-4645-ABCE-AF46B1EA4607}.Release|Any CPU.Build.0 = Release|Any CPU
{A44D38E7-7A95-46A7-A5EE-8927892D1275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A44D38E7-7A95-46A7-A5EE-8927892D1275}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A44D38E7-7A95-46A7-A5EE-8927892D1275}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A44D38E7-7A95-46A7-A5EE-8927892D1275}.Release|Any CPU.Build.0 = Release|Any CPU
{B3E52FA7-643A-4DE2-B9A4-561402A80235}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3E52FA7-643A-4DE2-B9A4-561402A80235}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3E52FA7-643A-4DE2-B9A4-561402A80235}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3E52FA7-643A-4DE2-B9A4-561402A80235}.Release|Any CPU.Build.0 = Release|Any CPU
{FD5B9DB9-A9CC-4A8F-ADC5-81EF43DDDD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD5B9DB9-A9CC-4A8F-ADC5-81EF43DDDD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD5B9DB9-A9CC-4A8F-ADC5-81EF43DDDD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD5B9DB9-A9CC-4A8F-ADC5-81EF43DDDD1F}.Release|Any CPU.Build.0 = Release|Any CPU
{6D98A5F8-2A26-4559-B301-5E1E4C728689}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D98A5F8-2A26-4559-B301-5E1E4C728689}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D98A5F8-2A26-4559-B301-5E1E4C728689}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D98A5F8-2A26-4559-B301-5E1E4C728689}.Release|Any CPU.Build.0 = Release|Any CPU
{610EB36E-6823-4334-95E4-435A5E0A94C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{610EB36E-6823-4334-95E4-435A5E0A94C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{610EB36E-6823-4334-95E4-435A5E0A94C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{610EB36E-6823-4334-95E4-435A5E0A94C8}.Release|Any CPU.Build.0 = Release|Any CPU
{AD3AB968-A79F-485C-8B3E-B6917A5E4C71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD3AB968-A79F-485C-8B3E-B6917A5E4C71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD3AB968-A79F-485C-8B3E-B6917A5E4C71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD3AB968-A79F-485C-8B3E-B6917A5E4C71}.Release|Any CPU.Build.0 = Release|Any CPU
{BE107917-831F-45E6-87F3-96D1DF418309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE107917-831F-45E6-87F3-96D1DF418309}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE107917-831F-45E6-87F3-96D1DF418309}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE107917-831F-45E6-87F3-96D1DF418309}.Release|Any CPU.Build.0 = Release|Any CPU
{85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Release|Any CPU.Build.0 = Release|Any CPU
{899988C3-8F36-4B19-A1DE-1D1D85F114D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{899988C3-8F36-4B19-A1DE-1D1D85F114D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{899988C3-8F36-4B19-A1DE-1D1D85F114D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{899988C3-8F36-4B19-A1DE-1D1D85F114D2}.Release|Any CPU.Build.0 = Release|Any CPU
{AB2ED973-EBCD-4098-BF7B-045382221D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB2ED973-EBCD-4098-BF7B-045382221D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB2ED973-EBCD-4098-BF7B-045382221D1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB2ED973-EBCD-4098-BF7B-045382221D1B}.Release|Any CPU.Build.0 = Release|Any CPU
{4E4B641B-1757-4A37-8FFE-769F6E0C98EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E4B641B-1757-4A37-8FFE-769F6E0C98EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E4B641B-1757-4A37-8FFE-769F6E0C98EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E4B641B-1757-4A37-8FFE-769F6E0C98EC}.Release|Any CPU.Build.0 = Release|Any CPU
{843805DF-6643-1364-D890-14B2E4826278}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{843805DF-6643-1364-D890-14B2E4826278}.Debug|Any CPU.Build.0 = Debug|Any CPU
{843805DF-6643-1364-D890-14B2E4826278}.Release|Any CPU.ActiveCfg = Release|Any CPU
{843805DF-6643-1364-D890-14B2E4826278}.Release|Any CPU.Build.0 = Release|Any CPU
{95069D8D-BCD5-77C6-DFAB-3F4C5ADBA85B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95069D8D-BCD5-77C6-DFAB-3F4C5ADBA85B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95069D8D-BCD5-77C6-DFAB-3F4C5ADBA85B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95069D8D-BCD5-77C6-DFAB-3F4C5ADBA85B}.Release|Any CPU.Build.0 = Release|Any CPU
{ABEDC482-1EC3-A770-227F-D69CE16F36A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABEDC482-1EC3-A770-227F-D69CE16F36A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABEDC482-1EC3-A770-227F-D69CE16F36A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABEDC482-1EC3-A770-227F-D69CE16F36A5}.Release|Any CPU.Build.0 = Release|Any CPU
{4E4E4917-1CA3-A7D7-40A8-A24A08673EC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E4E4917-1CA3-A7D7-40A8-A24A08673EC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E4E4917-1CA3-A7D7-40A8-A24A08673EC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E4E4917-1CA3-A7D7-40A8-A24A08673EC1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8A66BC05-F8CF-40E6-8079-FC6E593B0814}
SolutionGuid = {56AB8345-FF24-4E15-AB54-5A898A5EC496}
EndGlobalSection
EndGlobal

View File

@ -21,6 +21,12 @@
<Setter Property="Padding" Value="14,10" />
</Style>
<!--
For information about styling .NET MAUI pages
please refer to the documentation:
https://go.microsoft.com/fwlink/?linkid=2282329
-->
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -1,17 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
<TargetFrameworks>net9.0-android;net9.0-ios</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
<!-- Note for MacCatalyst:
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
<OutputType>Exe</OutputType>
<RootNamespace>FruitBankHybrid</RootNamespace>
@ -22,10 +13,10 @@
<Nullable>enable</Nullable>
<!-- Display name -->
<ApplicationTitle>FruitBankHybrid</ApplicationTitle>
<ApplicationTitle>FruitBank Measuring</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.fruitbankhybrid</ApplicationId>
<ApplicationId>com.companyname.blazorapp.1</ApplicationId>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
@ -39,7 +30,14 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">24.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<UseInterpreter>true</UseInterpreter>
</PropertyGroup>
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'maccatalyst-arm64' and '$(Configuration)' == 'Release'">
<UseInterpreter>true</UseInterpreter>
</PropertyGroup>
<ItemGroup>
@ -61,9 +59,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.100" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.100" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.8" />
<PackageReference Include="DevExpress.Data" Version="25.1.3" />
<!--<PackageReference Include="DevExpress.Maui.Controls" Version="25.1.3" />
<PackageReference Include="DevExpress.Maui.Editors" Version="25.1.3" />
<PackageReference Include="DevExpress.Maui.CollectionView" Version="25.1.3" />-->
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.50" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
@ -83,4 +85,5 @@
</Reference>
</ItemGroup>
</Project>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IsFirstTimeProjectOpen>False</IsFirstTimeProjectOpen>
<ActiveDebugFramework>net9.0-windows10.0.19041.0</ActiveDebugFramework>
<ActiveDebugProfile>Windows Machine</ActiveDebugProfile>
<SelectedPlatformGroup>Emulator</SelectedPlatformGroup>
<DefaultDevice>pixel_7_-_api_35</DefaultDevice>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net9.0-android|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetPlatformIdentifier)'=='iOS'">
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<None Update="App.xaml">
<SubType>Designer</SubType>
</None>
<None Update="MainPage.xaml">
<SubType>Designer</SubType>
</None>
<None Update="Platforms\Windows\App.xaml">
<SubType>Designer</SubType>
</None>
<None Update="Platforms\Windows\Package.appxmanifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
</Project>

View File

@ -1,15 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:dx="http://schemas.devexpress.com/maui"
xmlns:local="clr-namespace:FruitBankHybrid"
xmlns:shared="clr-namespace:FruitBankHybrid.Shared;assembly=FruitBankHybrid.Shared"
x:Class="FruitBankHybrid.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/index.html">
<Grid RowDefinitions="*,Auto">
<BlazorWebView x:Name="blazorWebView"
HostPage="wwwroot/index.html">
<BlazorWebView.RootComponents>
<RootComponent Selector="#app" ComponentType="{x:Type shared:Routes}" />
<RootComponent Selector="#app"
ComponentType="{x:Type shared:Routes}" />
</BlazorWebView.RootComponents>
</BlazorWebView>
<!--<dx:DXButton Clicked="OnActionButtonClick"
Content="Action"
CornerRadius="0"
Grid.Row="1"
Icon="dotnet_bot.png"
IconColor="White" />-->
</Grid>
</ContentPage>

View File

@ -6,5 +6,10 @@
{
InitializeComponent();
}
private void OnActionButtonClick(object sender, EventArgs e)
{
//Add some code here to show how to communicate with a control in BlazorWebView
}
}
}

View File

@ -1,20 +1,24 @@
using Microsoft.Extensions.Logging;
using FruitBankHybrid.Services;
using FruitBankHybrid.Shared.Services;
using FruitBankHybrid.Services;
//using DevExpress.Maui;
using Microsoft.Extensions.Logging;
using FruitBankHybrid.Shared.Services.SignalRs;
using FruitBank.Common.Loggers;
using AyCode.Core.Loggers;
using FruitBankHybrid.Services.Loggers;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
builder.UseMauiApp<App>()
//.UseDevExpress(useLocalization: false)
//.UseDevExpressCollectionView()
//.UseDevExpressControls()
//.UseDevExpressEditors()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
@ -24,15 +28,18 @@ public static class MauiProgram
builder.Services.AddSingleton<IFormFactor, FormFactor>();
//builder.Services.AddScoped<ISignalRService, SignalRService>();
builder.Services.AddScoped<FruitBankSignalRClient>();
#if DEBUG
builder.Services.AddSingleton<IAcLogWriterClientBase, BrowserConsoleLogWriter>();
#endif
builder.Services.AddSingleton<IAcLogWriterClientBase, SignaRClientLogItemWriter>();
//builder.Services.AddSingleton<SessionService>();
builder.Services.AddMauiBlazorWebView();
builder.Services.AddDevExpressBlazor();
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
@ -42,3 +49,4 @@ public static class MauiProgram
return builder.Build();
}
}
}

View File

@ -2,9 +2,10 @@
using Android.Content.PM;
using Android.OS;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}
}

View File

@ -1,8 +1,8 @@
using Android.App;
using Android.Runtime;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
[Application]
public class MainApplication : MauiApplication
{
@ -13,3 +13,4 @@ public class MainApplication : MauiApplication
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}

View File

@ -1,9 +1,10 @@
using Foundation;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}

View File

@ -1,8 +1,8 @@
using ObjCRuntime;
using UIKit;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
public class Program
{
// This is the main entry point of the application.
@ -13,3 +13,4 @@ public class Program
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using Microsoft.Maui;
using Microsoft.Maui.Hosting;
namespace FruitBankHybrid;
class Program : MauiApplication
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
static void Main(string[] args)
{
var app = new Program();
app.Run(args);
}
}

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="maui-application-id-placeholder" version="0.0.0" api-version="8" xmlns="http://tizen.org/ns/packages">
<profile name="common" />
<ui-application appid="maui-application-id-placeholder" exec="FruitBankHybrid.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
<label>maui-application-title-placeholder</label>
<icon>maui-appicon-placeholder</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
</ui-application>
<shortcut-list />
<privileges>
<privilege>http://tizen.org/privilege/internet</privilege>
</privileges>
<dependencies />
<provides-appdefined-privileges />
</manifest>

View File

@ -3,8 +3,8 @@
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace FruitBankHybrid.WinUI;
namespace FruitBankHybrid.WinUI
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
@ -22,3 +22,4 @@ public partial class App : MauiWinUIApplication
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}

View File

@ -8,7 +8,7 @@
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
<mp:PhoneIdentity PhoneProductId="E9B56D96-D519-4E1B-AE48-77DC7AE73AED" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<mp:PhoneIdentity PhoneProductId="10836226-17FE-45AD-8C96-8DB8D4D78222" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>$placeholder$</DisplayName>

View File

@ -1,9 +1,10 @@
using Foundation;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}

View File

@ -1,8 +1,8 @@
using ObjCRuntime;
using UIKit;
namespace FruitBankHybrid;
namespace FruitBankHybrid
{
public class Program
{
// This is the main entry point of the application.
@ -13,3 +13,4 @@ public class Program
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}

View File

@ -1,8 +0,0 @@
{
"profiles": {
"Windows Machine": {
"commandName": "Project",
"nativeDebugging": false
}
}
}

View File

@ -1,7 +1,7 @@
using FruitBankHybrid.Shared.Services;
namespace FruitBankHybrid.Services;
namespace FruitBankHybrid.Services
{
public class FormFactor : IFormFactor
{
public string GetFormFactor()
@ -14,3 +14,4 @@ public class FormFactor : IFormFactor
return DeviceInfo.Platform.ToString() + " - " + DeviceInfo.VersionString;
}
}
}

View File

@ -1,56 +0,0 @@
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
namespace FruitBankHybrid.Shared.Services
{
public class SignalRService : IAsyncDisposable, ISignalRService
{
private HubConnection _hubConnection;
private readonly NavigationManager _navigationManager;
public event Action<string, string>? MessageReceived;
public SignalRService(NavigationManager navigationManager)
{
_navigationManager = navigationManager;
}
public async Task InitializeAsync()
{
// Build the connection (assuming same domain as Blazor app, otherwise use full URL)
_hubConnection = new HubConnectionBuilder()
.WithUrl(_navigationManager.ToAbsoluteUri("https://localhost:59579/fbhub/"))
//.WithUrl(_navigationManager.ToAbsoluteUri("http://10.0.2.2:59580/fbhub"))
.WithAutomaticReconnect()
.Build();
// Register incoming handler
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
MessageReceived?.Invoke(user, message);
});
await _hubConnection.StartAsync();
}
public async Task SendMessageAsync(string user, string message)
{
if (_hubConnection.State == HubConnectionState.Connected)
await _hubConnection.InvokeAsync("SendMessage", user, message);
}
public async ValueTask DisposeAsync()
{
if (_hubConnection is not null)
{
await _hubConnection.DisposeAsync();
}
}
}
}

View File

@ -1,14 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<title>FruitBankHybrid</title>
<title>FruitBankHybrid Measuring</title>
<base href="/" />
<link rel="stylesheet" href="_content/FruitBankHybrid.Shared/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="_content/FruitBankHybrid.Shared/app.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="FruitBankHybrid.styles.css" />
<link href="_content/DevExpress.Blazor.Themes.Fluent/core.min.css" data-theme-id="fluent-blueLight" rel="stylesheet" />
<link href="_content/DevExpress.Blazor.Themes.Fluent/global.min.css" data-theme-id="fluent-blueLight" rel="stylesheet" />
<link href="_content/DevExpress.Blazor.Themes.Fluent/modes/light.min.css" data-theme-id="fluent-blueLight" rel="stylesheet" />
<link href="_content/DevExpress.Blazor.Themes.Fluent/accents/blue.min.css" data-theme-id="fluent-blueLight" rel="stylesheet" />
<link href="_content/FruitBankHybrid.Shared/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="_content/FruitBankHybrid.Shared/app.css" rel="stylesheet" />
<link href="app.css" rel="stylesheet" />
<link href="FruitBankHybrid.styles.css" rel="stylesheet" />
<link rel="icon" href="data:,">
</head>