| @page "/doneimage" | |||||
| <div class="text-center"> | |||||
| <img src="./images/done.png" class="w-50" alt="Done!" /> | |||||
| </div> | |||||
| @code { | |||||
| } |
| @page "/failureimage" | |||||
| <div class="text-center"> | |||||
| <img src="./images/failure.png" class="w-50" alt="Failure!" /> | |||||
| </div> | |||||
| @code { | |||||
| } |
| @using cwebplusApp.Shared.Services; | |||||
| @implements IDisposable; | |||||
| @inject OnlineStatusProvider OnlineStatusProvider; | |||||
| <div class="row no-gutters w-100 justify-content-end" style="position: absolute;"> | |||||
| @if (isOffline) { | |||||
| <MatIcon Style="padding-right:0.5rem"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> | |||||
| <path d="M0 0h24v24H0V0z" fill="none" /> | |||||
| <path d="M21 11l2-2c-3.73-3.73-8.87-5.15-13.7-4.31l2.58 2.58c3.3-.02 6.61 1.22 9.12 3.73zm-2 2c-1.08-1.08-2.36-1.85-3.72-2.33l3.02 3.02.7-.69zM9 17l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zM3.41 1.64L2 3.05 5.05 6.1C3.59 6.83 2.22 7.79 1 9l2 2c1.23-1.23 2.65-2.16 4.17-2.78l2.24 2.24C7.79 10.89 6.27 11.74 5 13l2 2c1.35-1.35 3.11-2.04 4.89-2.06l7.08 7.08 1.41-1.41L3.41 1.64z" /> | |||||
| </svg> | |||||
| </MatIcon> | |||||
| } | |||||
| </div> | |||||
| @code { | |||||
| private bool isOffline; | |||||
| public void Dispose() { | |||||
| OnlineStatusProvider.RemoveOnlineStatusChangeCallBack(OnOnlineStatusChanged); | |||||
| } | |||||
| protected override void OnInitialized() { | |||||
| base.OnInitialized(); | |||||
| OnlineStatusProvider.AddOnlineStatusChangeCallBack(OnOnlineStatusChanged); | |||||
| OnOnlineStatusChanged(OnlineStatusProvider.Online); | |||||
| } | |||||
| private void OnOnlineStatusChanged(bool isOnline) { | |||||
| this.isOffline = !isOnline; | |||||
| StateHasChanged(); | |||||
| } | |||||
| } |
| @using cwebplusApp.Shared.Services; | @using cwebplusApp.Shared.Services; | ||||
| @using cwebplusApp.Shared.Models; | @using cwebplusApp.Shared.Models; | ||||
| @using cwebplusApp.Components; | |||||
| @inject NavigationManager NavigationManager; | @inject NavigationManager NavigationManager; | ||||
| @inject IStringLocalizer<Resources> i18n; | @inject IStringLocalizer<Resources> i18n; | ||||
| @inject PageHistoryManager PageHistoryManager; | @inject PageHistoryManager PageHistoryManager; | ||||
| @inject ReportDataProvider ReportDataProvider; | @inject ReportDataProvider ReportDataProvider; | ||||
| @inject ILFBicycleRest ILFBicycleRest; | |||||
| @inject IBicycleRestService IBicycleRestService; | |||||
| @inject Toaster Toaster; | @inject Toaster Toaster; | ||||
| @inject AppState AppState; | @inject AppState AppState; | ||||
| base.OnInitialized(); | base.OnInitialized(); | ||||
| PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | ||||
| try { | try { | ||||
| response = await ILFBicycleRest.SendFoundReport(ReportDataProvider.Report); | |||||
| response = await IBicycleRestService.SendFoundReport(ReportDataProvider.Report); | |||||
| responseOk = System.Net.HttpStatusCode.OK == response.StatusCode ? true : false; | responseOk = System.Net.HttpStatusCode.OK == response.StatusCode ? true : false; | ||||
| } catch (HttpRequestException ex) { | } catch (HttpRequestException ex) { | ||||
| response = new(i18n.GetString("FoundBike"), new string[] { ex.Message }); | response = new(i18n.GetString("FoundBike"), new string[] { ex.Message }); |
| @page "/fundvelo/keydata/Found" | @page "/fundvelo/keydata/Found" | ||||
| @inherits CaritasServiceFundVeloKeyDataPageBase | @inherits CaritasServiceFundVeloKeyDataPageBase | ||||
| @implements IDisposable; | |||||
| @using cwebplusApp.Shared.Models; | @using cwebplusApp.Shared.Models; | ||||
| @using cwebplusApp.Shared.Services; | @using cwebplusApp.Shared.Services; | ||||
| @inject Toaster Toaster | @inject Toaster Toaster | ||||
| @inject IJSRuntime JS | @inject IJSRuntime JS | ||||
| @inject ReportDataProvider ReportDataProvider | @inject ReportDataProvider ReportDataProvider | ||||
| @inject OnlineStatusProvider OnlineStatusProvider | |||||
| <div class="row px-3 h-100"> | <div class="row px-3 h-100"> | ||||
| <div class="row no-gutters align-items-center justify-content-center w-100" style="padding-top:1em"> | <div class="row no-gutters align-items-center justify-content-center w-100" style="padding-top:1em"> | ||||
| </MatCard> | </MatCard> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-1 justify-content-center" style="text-align: center"> | |||||
| <MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default" @onclick="InitializeMapPosition"> | |||||
| <label> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" height="48px" width="48px" viewBox="0 0 24 24" fill="#000000"> | |||||
| <path d="M0 0h24v24H0V0z" fill="none" /> | |||||
| <path d="M13 3.06V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06c-.46-4.17-3.77-7.48-7.94-7.94zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" /> | |||||
| <circle cx="12" cy="12" opacity=".3" r="2" /> | |||||
| <path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" /> | |||||
| </svg> | |||||
| </label> | |||||
| </MatRipple> | |||||
| </div> | |||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-3"> | |||||
| <div class="w-100 fv-osm-tile map-wrapper"> | |||||
| <Map @ref="mapRef" MapOptions="@mapOptions" AfterRender="AfterRenderMap"></Map> | |||||
| @if (OnlineStatusProvider.Online) { | |||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-1 justify-content-center" style="text-align: center"> | |||||
| <MatRipple class="inputfile-mat-ripple" Color="@MatRippleColor.Default" @onclick="InitializeMapPosition"> | |||||
| <label> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" height="48px" width="48px" viewBox="0 0 24 24" fill="#000000"> | |||||
| <path d="M0 0h24v24H0V0z" fill="none" /> | |||||
| <path d="M13 3.06V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06c-.46-4.17-3.77-7.48-7.94-7.94zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z" /> | |||||
| <circle cx="12" cy="12" opacity=".3" r="2" /> | |||||
| <path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z" /> | |||||
| </svg> | |||||
| </label> | |||||
| </MatRipple> | |||||
| </div> | </div> | ||||
| </div> | |||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-3"> | |||||
| <div class="w-100 fv-osm-tile map-wrapper"> | |||||
| <Map @ref="mapRef" MapOptions="@mapOptions" AfterRender="AfterRenderMap"></Map> | |||||
| </div> | |||||
| </div> | |||||
| } | |||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-8-tablet mat-layout-grid-cell-span-4-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-8-tablet mat-layout-grid-cell-span-4-desktop"> | ||||
| <div class="mat-layout-grid-inner"> | <div class="mat-layout-grid-inner"> | ||||
| <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | <div class="mat-layout-grid-cell mat-layout-grid-cell-span-4-phone mat-layout-grid-cell-span-4-tablet mat-layout-grid-cell-span-12-desktop"> | ||||
| private string remark; | private string remark; | ||||
| private bool abholadresseIsNotContact; | private bool abholadresseIsNotContact; | ||||
| public void Dispose() { | |||||
| OnlineStatusProvider.RemoveOnlineStatusChangeCallBack(OnOnlineStatusChanged); | |||||
| } | |||||
| protected async override void OnInitialized() { | protected async override void OnInitialized() { | ||||
| base.OnInitialized(); | base.OnInitialized(); | ||||
| await GetColors(); | await GetColors(); | ||||
| await GetBrands(); | await GetBrands(); | ||||
| refreshGUIFromDto(); | refreshGUIFromDto(); | ||||
| PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | ||||
| OnlineStatusProvider.AddOnlineStatusChangeCallBack(OnOnlineStatusChanged); | |||||
| StateHasChanged(); | |||||
| } | |||||
| private void OnOnlineStatusChanged(bool isOnline) { | |||||
| StateHasChanged(); | StateHasChanged(); | ||||
| } | } | ||||
| bicycleGeoPosition.Longitude = report.GeographicInfo.Longitude; | bicycleGeoPosition.Longitude = report.GeographicInfo.Longitude; | ||||
| imgUrl = report.FotoString; | imgUrl = report.FotoString; | ||||
| selectedColor = Array.Find(Colors, color => color.Id == report.FarbeId); | selectedColor = Array.Find(Colors, color => color.Id == report.FarbeId); | ||||
| selectedBrand = String.IsNullOrEmpty(report.NeueMarke) ? Array.Find(Brands, brand => brand.Id == report.MarkeId): new Brand(-999, report.NeueMarke); | |||||
| selectedBrand = String.IsNullOrEmpty(report.NeueMarke) ? Array.Find(Brands, brand => brand.Id == report.MarkeId) : new Brand(-999, report.NeueMarke); | |||||
| selectedBcType = Array.Find(BicycleTypes, bcType => bcType.Id == report.TypId); | selectedBcType = Array.Find(BicycleTypes, bcType => bcType.Id == report.TypId); | ||||
| frameNumber = report.RahmenNummer; | frameNumber = report.RahmenNummer; | ||||
| remark = report.Bemerkung; | remark = report.Bemerkung; |
| @using cwebplusApp.Shared.Services; | @using cwebplusApp.Shared.Services; | ||||
| @using cwebplusApp.Shared.Models; | @using cwebplusApp.Shared.Models; | ||||
| @using cwebplusApp.Components; | |||||
| @inject NavigationManager NavigationManager; | @inject NavigationManager NavigationManager; | ||||
| @inject IStringLocalizer<Resources> i18n; | @inject IStringLocalizer<Resources> i18n; | ||||
| @inject PageHistoryManager PageHistoryManager; | @inject PageHistoryManager PageHistoryManager; | ||||
| @inject ReportDataProvider ReportDataProvider; | @inject ReportDataProvider ReportDataProvider; | ||||
| @inject ILFBicycleRest ILFBicycleRest; | |||||
| @inject IBicycleRestService IBicycleRestService; | |||||
| @inject Toaster Toaster; | @inject Toaster Toaster; | ||||
| @inject AppState AppState; | @inject AppState AppState; | ||||
| base.OnInitialized(); | base.OnInitialized(); | ||||
| PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | PageHistoryManager.AddPageToHistory(NavigationManager.Uri); | ||||
| try { | try { | ||||
| response = await ILFBicycleRest.SendMissingReport(ReportDataProvider.Report); | |||||
| response = await IBicycleRestService.SendMissingReport(ReportDataProvider.Report); | |||||
| responseOk = System.Net.HttpStatusCode.OK == response.StatusCode ? true : false; | responseOk = System.Net.HttpStatusCode.OK == response.StatusCode ? true : false; | ||||
| } catch (HttpRequestException ex) { | } catch (HttpRequestException ex) { | ||||
| response = new(i18n.GetString("MissingBike"), new string[] { ex.Message }); | response = new(i18n.GetString("MissingBike"), new string[] { ex.Message }); |
| @page "/" | @page "/" | ||||
| @using cwebplusApp.Shared.Services; | @using cwebplusApp.Shared.Services; | ||||
| @using System.Threading; | |||||
| @using Microsoft.Extensions.Configuration; | @using Microsoft.Extensions.Configuration; | ||||
| @inject NavigationManager NavigationManager; | @inject NavigationManager NavigationManager; | ||||
| @inject MasterDataService MasterDataService; | @inject MasterDataService MasterDataService; | ||||
| @inject Toaster Toaster; | @inject Toaster Toaster; | ||||
| @inject IConfiguration Configuration; | @inject IConfiguration Configuration; | ||||
| @inject ILFBicycleRest ILFBicycleRest; | |||||
| @inject IBicycleRestService IBicycleRestService; | |||||
| <div class="row h-100 justify-content-center"> | <div class="row h-100 justify-content-center"> | ||||
| showProgressCircle = true; | showProgressCircle = true; | ||||
| StateHasChanged(); | StateHasChanged(); | ||||
| try { | try { | ||||
| ILFBicycleRest.Initialize(Configuration); | |||||
| IBicycleRestService.Initialize(Configuration); | |||||
| await MasterDataService.SynchronizeMasterdata(); | await MasterDataService.SynchronizeMasterdata(); | ||||
| } catch (Exception) { | } catch (Exception) { | ||||
| Toaster.ShowWarning(i18n.GetString("Warning.Masterdata.Title"), i18n.GetString("Warning.Masterdata.Msg")); | Toaster.ShowWarning(i18n.GetString("Warning.Masterdata.Title"), i18n.GetString("Warning.Masterdata.Msg")); |
| builder.Services.AddMatBlazor(); | builder.Services.AddMatBlazor(); | ||||
| builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | ||||
| builder.Services.AddSingleton<ILFBicycleRest, LFBicycleRest>(); | |||||
| builder.Services.AddSingleton<IBicycleRestService, BicycleRestService>(); | |||||
| builder.Services.AddSingleton<AppState>(); | builder.Services.AddSingleton<AppState>(); | ||||
| builder.Services.AddSingleton<PageHistoryManager>(); | builder.Services.AddSingleton<PageHistoryManager>(); | ||||
| builder.Services.AddSingleton<ReportDataProvider>(); | builder.Services.AddSingleton<ReportDataProvider>(); | ||||
| builder.Services.AddSingleton<OnlineStatusProvider>(); | |||||
| builder.Services.AddScoped<Toaster>(); | builder.Services.AddScoped<Toaster>(); | ||||
| builder.Services.AddScoped<UserDataProvider>(); | builder.Services.AddScoped<UserDataProvider>(); | ||||
| builder.Services.AddScoped<MasterDataService>(); | builder.Services.AddScoped<MasterDataService>(); |
| @using cwebplusApp.Shared.Services; | @using cwebplusApp.Shared.Services; | ||||
| @using cwebplusApp.Components; | |||||
| @inject AppState AppState; | @inject AppState AppState; | ||||
| @inject NavigationManager NavigationManager; | @inject NavigationManager NavigationManager; | ||||
| </MatList> | </MatList> | ||||
| </MatDrawer> | </MatDrawer> | ||||
| </MatDrawerContainer> | </MatDrawerContainer> | ||||
| </MatAppBarContent> | </MatAppBarContent> | ||||
| </MatAppBarContainer> | </MatAppBarContainer> | ||||
| </div> | </div> | ||||
| <OnlineStatusIndicator /> | |||||
| } | } | ||||
| using cwebplusApp.Shared.Models; | |||||
| using Microsoft.AspNetCore.Components; | |||||
| using Microsoft.Extensions.Configuration; | |||||
| using Newtonsoft.Json; | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Globalization; | |||||
| using System.Net.Http; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace cwebplusApp.Shared.Services { | |||||
| // REST interface responsible to submit lost or found reports and get the available master data. | |||||
| public class BicycleRestService : IBicycleRestService { | |||||
| private static readonly string VERSION = "v1"; | |||||
| private HttpClient httpClient; | |||||
| [Inject] | |||||
| public IConfiguration Configuration { get; set; } | |||||
| public void Initialize(IConfiguration configuration) { | |||||
| this.Configuration = configuration; | |||||
| string hostBaseUrl = Configuration.GetValue<string>("host_base_url"); | |||||
| if (!String.IsNullOrEmpty(hostBaseUrl)) { | |||||
| this.httpClient = new HttpClient { BaseAddress = new Uri(hostBaseUrl) }; | |||||
| } | |||||
| } | |||||
| public async Task<List<ColorItem>> GetColors() { | |||||
| if (httpClient != null) { | |||||
| string subResourceUrl = Configuration.GetValue<string>("subresource_url_colors"); | |||||
| if (!String.IsNullOrEmpty(subResourceUrl)) { | |||||
| HttpResponseMessage httpResult = await httpClient.GetAsync(string.Format(subResourceUrl, VERSION, CultureInfo.CurrentCulture.TwoLetterISOLanguageName)); | |||||
| if (httpResult.StatusCode == System.Net.HttpStatusCode.OK) { | |||||
| ColorItem[] colors = JsonConvert.DeserializeObject<ColorItem[]>(await httpResult.Content.ReadAsStringAsync()); | |||||
| return new List<ColorItem>(colors); | |||||
| } | |||||
| throw new HttpRequestException("HTTP error " + httpResult.StatusCode); | |||||
| } | |||||
| } | |||||
| throw new HttpRequestException("HTTP client not initialized!"); | |||||
| } | |||||
| public async Task<List<BicycleType>> GetBicycleTypes() { | |||||
| if (httpClient != null) { | |||||
| string subResourceUrl = Configuration.GetValue<string>("subresource_url_types"); | |||||
| if (!String.IsNullOrEmpty(subResourceUrl)) { | |||||
| HttpResponseMessage httpResult = await httpClient.GetAsync(string.Format(subResourceUrl, VERSION, CultureInfo.CurrentCulture.TwoLetterISOLanguageName)); | |||||
| if (httpResult.StatusCode == System.Net.HttpStatusCode.OK) { | |||||
| BicycleType[] bicycleTypes = JsonConvert.DeserializeObject<BicycleType[]>(await httpResult.Content.ReadAsStringAsync()); | |||||
| return new List<BicycleType>(bicycleTypes); | |||||
| } | |||||
| throw new HttpRequestException("HTTP error " + httpResult.StatusCode); | |||||
| } | |||||
| } | |||||
| throw new HttpRequestException("HTTP client not initialized!"); | |||||
| } | |||||
| public async Task<List<Brand>> GetBrands() { | |||||
| if (httpClient != null) { | |||||
| string subResourceUrl = Configuration.GetValue<string>("subresource_url_brands"); | |||||
| if (!String.IsNullOrEmpty(subResourceUrl)) { | |||||
| HttpResponseMessage httpResult = await httpClient.GetAsync(string.Format(subResourceUrl, VERSION, CultureInfo.CurrentCulture.TwoLetterISOLanguageName)); | |||||
| if (httpResult.StatusCode == System.Net.HttpStatusCode.OK) { | |||||
| Brand[] brands = JsonConvert.DeserializeObject<Brand[]>(await httpResult.Content.ReadAsStringAsync()); | |||||
| return new List<Brand>(brands); | |||||
| } | |||||
| throw new HttpRequestException("HTTP error " + httpResult.StatusCode); | |||||
| } | |||||
| } | |||||
| throw new HttpRequestException("HTTP client not initialized!"); | |||||
| } | |||||
| public async Task<ReportResponse> SendFoundReport(Report report) { | |||||
| string subResourceUrl = Configuration.GetValue<string>("subresource_url_foundreport"); | |||||
| return await SendReport(report, subResourceUrl); | |||||
| } | |||||
| public async Task<ReportResponse> SendMissingReport(Report report) { | |||||
| string subResourceUrl = Configuration.GetValue<string>("subresource_url_missingreport"); | |||||
| return await SendReport(report, subResourceUrl); | |||||
| } | |||||
| protected async Task<ReportResponse> SendReport(Report report, string subResourceUrl) { | |||||
| if (httpClient != null) { | |||||
| if (!String.IsNullOrEmpty(subResourceUrl)) { | |||||
| string reportJson = JsonConvert.SerializeObject(report); | |||||
| HttpContent content = new StringContent(reportJson, Encoding.UTF8, "application/json"); | |||||
| HttpResponseMessage httpResult = await httpClient.PostAsync(string.Format(subResourceUrl, VERSION, CultureInfo.CurrentCulture.TwoLetterISOLanguageName), content); | |||||
| string msg = await httpResult.Content.ReadAsStringAsync(); | |||||
| ReportResponse response = JsonConvert.DeserializeObject<ReportResponse>(msg); | |||||
| response.StatusCode = httpResult.StatusCode; | |||||
| return response; | |||||
| } | |||||
| } | |||||
| throw new HttpRequestException("HTTP client not initialized!"); | |||||
| } | |||||
| } | |||||
| } |
| using cwebplusApp.Shared.Models; | |||||
| using Microsoft.Extensions.Configuration; | |||||
| using System.Collections.Generic; | |||||
| using System.Threading.Tasks; | |||||
| namespace cwebplusApp.Shared.Services { | |||||
| public interface IBicycleRestService { | |||||
| void Initialize(IConfiguration configuration); | |||||
| Task<List<ColorItem>> GetColors(); | |||||
| Task<List<BicycleType>> GetBicycleTypes(); | |||||
| Task<List<Brand>> GetBrands(); | |||||
| Task<ReportResponse> SendFoundReport(Report report); | |||||
| Task<ReportResponse> SendMissingReport(Report report); | |||||
| } | |||||
| } |
| namespace cwebplusApp.Shared.Services { | namespace cwebplusApp.Shared.Services { | ||||
| public class MasterDataService { | public class MasterDataService { | ||||
| private readonly ILFBicycleRest _lFBicycleRest; | |||||
| private readonly IBicycleRestService _bicycleRestService; | |||||
| private readonly IJSRuntime _jsRuntime; | |||||
| private readonly IStringLocalizer<Resources> _i18n; | |||||
| private readonly OnlineStatusProvider _onlineStatusProvider; | |||||
| private const string KeyNameColors = "colors"; | private const string KeyNameColors = "colors"; | ||||
| private const string KeyNameBcTypes = "bicycleTypes"; | private const string KeyNameBcTypes = "bicycleTypes"; | ||||
| private const string KeyNameBrands = "brands"; | private const string KeyNameBrands = "brands"; | ||||
| private readonly IJSRuntime _jsRuntime; | |||||
| private readonly IStringLocalizer<Resources> _i18n; | |||||
| private bool _initializedColors; | private bool _initializedColors; | ||||
| private bool _initializedBcTypes; | private bool _initializedBcTypes; | ||||
| private bool _initializedBrands; | private bool _initializedBrands; | ||||
| public event EventHandler Changed; | public event EventHandler Changed; | ||||
| public MasterDataService(IJSRuntime jsRuntime, ILFBicycleRest lFBicycleRest, IStringLocalizer<Resources> i18n) { | |||||
| public MasterDataService(IJSRuntime jsRuntime, IBicycleRestService bicycleRestService, IStringLocalizer<Resources> i18n, OnlineStatusProvider onlineStatusProvider) { | |||||
| _jsRuntime = jsRuntime; | _jsRuntime = jsRuntime; | ||||
| _lFBicycleRest = lFBicycleRest; | |||||
| _bicycleRestService = bicycleRestService; | |||||
| _i18n = i18n; | _i18n = i18n; | ||||
| _onlineStatusProvider = onlineStatusProvider; | |||||
| _firstActivation = true; | _firstActivation = true; | ||||
| _brands = Defaults.GetBrandDefaults(_i18n).ToArray(); | _brands = Defaults.GetBrandDefaults(_i18n).ToArray(); | ||||
| _colors = Defaults.GetColorDefaults(_i18n).ToArray(); | _colors = Defaults.GetColorDefaults(_i18n).ToArray(); | ||||
| } | } | ||||
| public async Task SynchronizeMasterdata() { | public async Task SynchronizeMasterdata() { | ||||
| try { | |||||
| await SynchronizeColors(); | |||||
| await SynchronizeBcTypes(); | |||||
| await SynchronizeBrands(); | |||||
| } finally { | |||||
| _firstActivation = false; | |||||
| if (_onlineStatusProvider.Online) { | |||||
| try { | |||||
| await SynchronizeColors(); | |||||
| await SynchronizeBcTypes(); | |||||
| await SynchronizeBrands(); | |||||
| } finally { | |||||
| _firstActivation = false; | |||||
| } | |||||
| } else { | |||||
| throw new Exception("No internet connection available!"); | |||||
| } | } | ||||
| } | } | ||||
| public async Task SynchronizeColors() { | public async Task SynchronizeColors() { | ||||
| ColorItem[] colors = (await _lFBicycleRest.GetColors()).ToArray(); | |||||
| ColorItem[] colors = (await _bicycleRestService.GetColors()).ToArray(); | |||||
| if (colors != null && colors.Length > 0) { | if (colors != null && colors.Length > 0) { | ||||
| _colors = colors; | _colors = colors; | ||||
| await SaveColorsToStorage(colors); | await SaveColorsToStorage(colors); | ||||
| } | } | ||||
| public async Task SynchronizeBcTypes() { | public async Task SynchronizeBcTypes() { | ||||
| BicycleType[] bicycleTypes = (await _lFBicycleRest.GetBicycleTypes()).ToArray(); | |||||
| BicycleType[] bicycleTypes = (await _bicycleRestService.GetBicycleTypes()).ToArray(); | |||||
| if (bicycleTypes != null && bicycleTypes.Length > 0) { | if (bicycleTypes != null && bicycleTypes.Length > 0) { | ||||
| _bicycleTypes = bicycleTypes; | _bicycleTypes = bicycleTypes; | ||||
| await SaveBcTypesToStorage(bicycleTypes); | await SaveBcTypesToStorage(bicycleTypes); | ||||
| } | } | ||||
| public async Task SynchronizeBrands() { | public async Task SynchronizeBrands() { | ||||
| Brand[] brands = (await _lFBicycleRest.GetBrands()).ToArray(); | |||||
| Brand[] brands = (await _bicycleRestService.GetBrands()).ToArray(); | |||||
| if (brands != null && brands.Length > 0) { | if (brands != null && brands.Length > 0) { | ||||
| _brands = brands; | _brands = brands; | ||||
| await SaveBrandsToStorage(brands); | await SaveBrandsToStorage(brands); |
| using Microsoft.JSInterop; | |||||
| using System.Collections.Generic; | |||||
| namespace cwebplusApp.Shared.Services { | |||||
| public class OnlineStatusProvider { | |||||
| public bool Online { get => online; } | |||||
| public delegate void OnlineStatusChangeCallBack(bool online); | |||||
| public IJSRuntime JSRuntime { get; set; } | |||||
| private bool online; | |||||
| private HashSet<OnlineStatusChangeCallBack> OnlineStatusChangeCallBacks; | |||||
| public OnlineStatusProvider(IJSRuntime jSRuntime) { | |||||
| this.JSRuntime = jSRuntime; | |||||
| OnlineStatusChangeCallBacks = new(); | |||||
| var dotNetObjRef = DotNetObjectReference.Create(this); | |||||
| JSRuntime.InvokeVoidAsync("registerOnlineStatusHandler", dotNetObjRef); | |||||
| } | |||||
| [JSInvokable] | |||||
| public void SetOnlineStatus(bool isOnline) { | |||||
| this.online = isOnline; | |||||
| foreach (OnlineStatusChangeCallBack OnlineStatusCallBack in OnlineStatusChangeCallBacks) { | |||||
| OnlineStatusCallBack?.Invoke(isOnline); | |||||
| } | |||||
| } | |||||
| public void AddOnlineStatusChangeCallBack(OnlineStatusChangeCallBack listener) { | |||||
| OnlineStatusChangeCallBacks.Add(listener); | |||||
| } | |||||
| public void RemoveOnlineStatusChangeCallBack(OnlineStatusChangeCallBack listener) { | |||||
| OnlineStatusChangeCallBacks.Remove(listener); | |||||
| } | |||||
| } | |||||
| } |
| await component.invokeMethodAsync("OnStorageUpdated", e.key); | await component.invokeMethodAsync("OnStorageUpdated", e.key); | ||||
| }); | }); | ||||
| } | } | ||||
| function registerOnlineStatusHandler(dotNetObjRef) { | |||||
| function onlineStatusHandler() { | |||||
| dotNetObjRef.invokeMethodAsync("SetOnlineStatus", navigator.onLine); | |||||
| }; | |||||
| onlineStatusHandler(); | |||||
| window.addEventListener("online", onlineStatusHandler); | |||||
| window.addEventListener("offline", onlineStatusHandler); | |||||
| } | |||||
| </script> | </script> | ||||
| <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" | <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" |
| cache.put(event.request, response.clone()); | cache.put(event.request, response.clone()); | ||||
| return response; | return response; | ||||
| }); | }); | ||||
| }); | |||||
| }).catch(function () { | |||||
| var cr; | |||||
| console.log('catch network fetch failure 1'); | |||||
| event.waitUntil( | |||||
| caches.match(event.request).then(cacheRes => { | |||||
| console.log('catch network fetch failure 2'); | |||||
| console.log(cacheRes); | |||||
| cr = cacheRes; | |||||
| }) | |||||
| ); | |||||
| console.log('catch network fetch failure 3'); | |||||
| console.log(cr); | |||||
| return cr; | |||||
| //fromCache(event.request); | |||||
| }) | |||||
| } else { | } else { | ||||
| event.respondWith( | event.respondWith( | ||||
| caches.match(event.request).then(cacheRes => { | caches.match(event.request).then(cacheRes => { | ||||
| }) | }) | ||||
| ); | ); | ||||
| } | } | ||||
| }); | |||||
| }); | |||||
| //self.addEventListener('fetch', event => { | |||||
| // if (event.request.url.endsWith(appsettings_url)) { | |||||
| // networkOrCache(event.request); | |||||
| // } else { | |||||
| // event.respondWith( | |||||
| // caches.match(event.request).then(cacheRes => { | |||||
| // return cacheRes || fetch(event.request); | |||||
| // }) | |||||
| // ); | |||||
| // } | |||||
| //}); | |||||
| //function networkOrCache(request) { | |||||
| // return fetch(request).then(function (response) { | |||||
| // caches.open(staticCacheName).then(function (cache) { | |||||
| // console.log('update cache'); | |||||
| // cache.put(request, response.clone()); | |||||
| // }); | |||||
| // return response.ok ? response : fromCache(request); | |||||
| // //}).catch(function () { | |||||
| // // return fromCache(request); | |||||
| // }); | |||||
| //} | |||||
| //function fromCache(request) { | |||||
| // return caches.open(staticCacheName).then(function (cache) { | |||||
| // return cache.match(request).then(function (matching) { | |||||
| // return matching || Promise.reject('request-not-in-cache'); | |||||
| // }); | |||||
| // }); | |||||
| //} |