Browse Source

Offline mode

master
Flo Smilari 4 years ago
parent
commit
cea0385089

+ 9
- 0
Components/WarningImage.razor View File

@@ -0,0 +1,9 @@
@page "/warningimage"
<div class="text-center">
<img src="./images/warning.png" class="w-50" alt="Warning!" />
</div>
@code {
}

+ 36
- 24
Pages/CaritasServiceFundVeloFoundConclusion.razor View File

@@ -16,7 +16,7 @@
<div class="row no-gutters align-items-start justify-content-center w-100">
<MatHeadline4 Style="font-family:Ubuntu;padding-top:1em">@i18n["Confirmation"]</MatHeadline4>
</div>
@if (responseOk) {
@if (ResposeStatus.OK == responseStatus) {
<div class="row no-gutters align-items-start justify-content-center w-100" style="height:fit-content">
<div class="w-100" style="text-align: center">
<MatHeadline6 Style="font-family:Ubuntu">@i18n["FinishedTextFound"]</MatHeadline6>
@@ -26,26 +26,30 @@
</div>
</div>
}
<div class="row no-gutters align-items-start justify-content-center w-100" style="height:fit-content">
@if (running) {
<div style="width:48px;margin:0 auto;">
<MatProgressCircle Indeterminate="true" Size="MatProgressCircleSize.Large" />
</div>
<div class="w-100" style="text-align:center;">
<h6 style="font-style:italic;padding-bottom:1em">@i18n["Info.Report.Transmitting"]</h6>
</div>
<div class="row no-gutters align-items-start justify-content-center w-100" style="height:fit-content">
@if (running) {
<div style="width:48px;margin:0 auto;">
<MatProgressCircle Indeterminate="true" Size="MatProgressCircleSize.Large" />
</div>
<div class="w-100" style="text-align:center;">
<h6 style="font-style:italic;padding-bottom:1em">@i18n["Info.Report.Transmitting"]</h6>
</div>
} else {
if (ResposeStatus.OK == responseStatus) {
<Animate Animation="Animations.ZoomIn" Duration="TimeSpan.FromSeconds(2.5)">
<DoneImage></DoneImage>
</Animate>
} else if (ResposeStatus.Error == responseStatus) {
<Animate Animation="Animations.ZoomIn" Duration="TimeSpan.FromSeconds(2.5)">
<FailureImage></FailureImage>
</Animate>
} else {
if (responseOk) {
<Animate Animation="Animations.ZoomIn" Duration="TimeSpan.FromSeconds(2.5)">
<DoneImage></DoneImage>
</Animate>
} else {
<Animate Animation="Animations.ZoomIn" Duration="TimeSpan.FromSeconds(2.5)">
<FailureImage></FailureImage>
</Animate>
}
<Animate Animation="Animations.ZoomIn" Duration="TimeSpan.FromSeconds(2.5)">
<WarningImage></WarningImage>
</Animate>
}
</div>
}
</div>
<div class="row no-gutters align-items-end justify-content-center w-100" style="padding-bottom:2em;padding-top:2em">
<div class="col w-100 text-center">
<MatButton Class="w-50" Raised="true" @onclick="Finished">@i18n["Finished"]</MatButton>
@@ -56,8 +60,14 @@
@code {
enum ResposeStatus : ushort {
OK = 1,
Error = 10,
NoConnection = 20
}
private Animate doneAnimZoom;
private bool responseOk = false;
private ResposeStatus responseStatus = ResposeStatus.NoConnection;
private bool running = true;
private string referenceNumber;
ReportResponse response;
@@ -67,19 +77,21 @@
PageHistoryManager.AddPageToHistory(NavigationManager.Uri);
try {
response = await IBicycleRestService.SendFoundReport(ReportDataProvider.Report);
responseOk = System.Net.HttpStatusCode.OK == response.StatusCode ? true : false;
responseStatus = response==null ? ResposeStatus.NoConnection : System.Net.HttpStatusCode.OK == response.StatusCode ? ResposeStatus.OK : ResposeStatus.Error;
} catch (HttpRequestException ex) {
response = new(i18n.GetString("FoundBike"), new string[] { ex.Message });
responseOk = false;
responseStatus = ResposeStatus.Error;
}
running = false;
if (responseOk) {
if (ResposeStatus.OK == responseStatus) {
Toaster.ShowSuccess(i18n.GetString("FoundBike"), response.Message);
referenceNumber = (response.Data != null && response.Data.Length > 0) ? response.Data[0] : "-";
PageHistoryManager.Reset();
} else {
} else if (ResposeStatus.Error == responseStatus) {
Toaster.ShowError(response.Message, response.GetDataAsFormattedList());
} else {
Toaster.ShowWarning(i18n.GetString("Warning.NoConnection.Title"), i18n.GetString("Warning.NoConnection.Msg"));
}
StateHasChanged();
AppState.NotifyChanged();

+ 7
- 6
Pages/IndexPage.razor View File

@@ -11,6 +11,7 @@
@inject Toaster Toaster;
@inject IConfiguration Configuration;
@inject IBicycleRestService IBicycleRestService;
@inject OnlineStatusProvider OnlineStatusProvider;
<div class="row h-100 justify-content-center">
@@ -21,9 +22,9 @@
<div class="row align-items-end vw-100 h-50">
<div class="col text-center">
<h3 style="font-style:italic;padding-bottom:1em">@i18n["Welcome"]</h3>
<div>
<MatButton Disabled="@btnDisabled" Raised="true" Style="width:50%" @onclick="@((e) => ButtonClicked())">@i18n["Login"]</MatButton>
</div>
@*<div>
<MatButton Disabled="@btnDisabled" Raised="true" Style="width:50%" @onclick="@((e) => NavigateToNext())">@i18n["Login"]</MatButton>
</div>*@
</div>
</div>
<div class="row align-items-center justify-content-center vw-100 h-25">
@@ -51,12 +52,13 @@
showProgressCircle = true;
StateHasChanged();
try {
IBicycleRestService.Initialize(Configuration);
IBicycleRestService.Initialize(Configuration, OnlineStatusProvider);
await MasterDataService.SynchronizeMasterdata();
} catch (Exception) {
Toaster.ShowWarning(i18n.GetString("Warning.Masterdata.Title"), i18n.GetString("Warning.Masterdata.Msg"));
} finally {
showProgressCircle = false;
NavigateToNext();
}
}
btnDisabled = false;
@@ -64,8 +66,7 @@
StateHasChanged();
}
private void ButtonClicked() {
private void NavigateToNext() {
NavigationManager.NavigateTo("./caritas_services");
AppState.LoggedIn = true;
}
}

+ 20
- 24
Shared/NavMenu.razor View File

@@ -18,7 +18,7 @@
<MatAppBarSection>
<MatIconButton Icon="menu" OnClick="@((e) => ButtonClicked())"></MatIconButton>
@if (PageHistoryManager.CanGoBack()) {
<MatIconButton Icon="keyboard_backspace" OnClick="@((e) => ButtonBackClicked())" Disabled="@BackButtonDisabled()"></MatIconButton>
<MatIconButton Icon="@MatIconNames.Keyboard_backspace" OnClick="@((e) => ButtonBackClicked())" Disabled="@BackButtonDisabled()"></MatIconButton>
}
<MatAppBarTitle Class="navBar-title">@LocationUrl</MatAppBarTitle>
</MatAppBarSection>
@@ -49,19 +49,19 @@
</MatRipple>
<MatRipple Class="navmenu-mat-ripple" Color="@MatRippleColor.Default">
<MatListItem Class="@((Index == 3) ? "bg-primary-color text-white" : "")" Style="margin-left:0;margin-right:0"
Href="info"
Disabled="true"
Href="extras"
@onclick="@((e) => ButtonClicked(3))">
<MatIcon Icon="@MatIconNames.Error_outline" Style="transform: rotate(180deg)"></MatIcon>
<MatListItemText Style="padding-left:0.5em">@i18n["info"]</MatListItemText>
<MatIcon Icon="@MatIconNames.View_quilt"></MatIcon>
<MatListItemText Style="padding-left:0.5em">@i18n["Extras"]</MatListItemText>
</MatListItem>
</MatRipple>
<MatRipple Class="navmenu-mat-ripple" Color="@MatRippleColor.Default">
<MatListItem Class="@((Index == 4) ? "bg-primary-color text-white" : "")" Style="margin-left:0;margin-right:0"
href=""
Match="NavLinkMatch.All"
Href="info"
@onclick="@((e) => ButtonClicked(4))">
<MatIcon Icon="@MatIconNames.Exit_to_app"></MatIcon>
<MatListItemText Style="padding-left:0.5em">@i18n["Logout"]</MatListItemText>
<MatIcon Icon="@MatIconNames.Error_outline" Style="transform: rotate(180deg)"></MatIcon>
<MatListItemText Style="padding-left:0.5em">@i18n["info"]</MatListItemText>
</MatListItem>
</MatRipple>
</MatList>
@@ -95,10 +95,12 @@
}
protected override void OnInitialized() {
base.OnInitialized();
AppState.OnChange += StateHasChanged;
NavigationManager.LocationChanged += LocationChanged;
PageHistoryManager.AddPageToHistory(NavigationManager.Uri);
base.OnInitialized();
locUrl = i18n.GetString(NavigationManager.Uri.Replace(NavigationManager.BaseUri, ""));
StateHasChanged();
}
private void ButtonClicked() {
@@ -108,9 +110,6 @@
private void ButtonClicked(int _Index) {
Index = _Index;
ButtonClicked();
if (_Index == 4) {
AppState.LoggedIn = false;
}
}
private void ButtonBackClicked() {
@@ -125,9 +124,9 @@
} else if (e.Location.Contains("account")) {
Index = 2;
} else if (e.Location.Contains("info")) {
Index = 3;
} else {
Index = 4;
} else {
Index = 3;
}
StateHasChanged();
}
@@ -142,19 +141,16 @@
string baseUri = NavigationManager.BaseUri;
string delta = uri.Replace(baseUri, "");
if (delta == null || delta.Equals("")) {
if (delta.Equals("caritas_services")) {
Index = 1;
} else if (delta.Equals("account")) {
Index = 2;
} else if (delta.Equals("info")) {
Index = 4;
return false;
} else {
if (delta.Equals("caritas_services")) {
Index = 1;
} else if (delta.Equals("account")) {
Index = 2;
} else if (delta.Equals("info")) {
Index = 3;
}
return true;
Index = 3;
}
return true;
}
private bool BackButtonDisabled() {

+ 9
- 0
Shared/ResourceFiles/Resources.de.resx View File

@@ -285,6 +285,9 @@
<data name="Error.PhotoOrPictureToBig.Title" xml:space="preserve">
<value>Bilddatei zu gross!</value>
</data>
<data name="Extras" xml:space="preserve">
<value>Extras</value>
</data>
<data name="Female" xml:space="preserve">
<value>Frau</value>
</data>
@@ -447,6 +450,12 @@
<data name="Warning.Masterdata.Title" xml:space="preserve">
<value>Stammdaten nicht verfügbar!</value>
</data>
<data name="Warning.NoConnection.Msg" xml:space="preserve">
<value>Die Meldung konnte nicht übertragen werde. Sie wurde gespeichert und wird sobald wie möglich übertragen.</value>
</data>
<data name="Warning.NoConnection.Title" xml:space="preserve">
<value>Keine Verbindung zum Internet!</value>
</data>
<data name="Warning.Nominatim.Msg" xml:space="preserve">
<value>Die Adresse konnte beim Aufrufen des Nominatim-Dienstes nicht aufgelöst werden. Bitte geben Sie die Straße und Postleitzahl/Ort manuell ein.</value>
</data>

+ 9
- 0
Shared/ResourceFiles/Resources.fr.resx View File

@@ -285,6 +285,9 @@
<data name="Error.PhotoOrPictureToBig.Title" xml:space="preserve">
<value>La taille de la photo est trop grande!</value>
</data>
<data name="Extras" xml:space="preserve">
<value>Extras</value>
</data>
<data name="Female" xml:space="preserve">
<value>Madame</value>
</data>
@@ -447,6 +450,12 @@
<data name="Warning.Masterdata.Title" xml:space="preserve">
<value>Les données de base ne sont pas disponibles!</value>
</data>
<data name="Warning.NoConnection.Msg" xml:space="preserve">
<value>Le message n'a pas pu être transmis. Il a été sauvegardé et sera transmis dès que possible.</value>
</data>
<data name="Warning.NoConnection.Title" xml:space="preserve">
<value>Pas de connexion à l'internet !</value>
</data>
<data name="Warning.Nominatim.Msg" xml:space="preserve">
<value>L'adresse n'a pas pu être résolue en invoquant le service Nominatim. Veuillez saisir l'adresse en indiquant la rue et le code postal/ville.</value>
</data>

+ 9
- 0
Shared/ResourceFiles/Resources.it.resx View File

@@ -285,6 +285,9 @@
<data name="Error.PhotoOrPictureToBig.Title" xml:space="preserve">
<value>Dimensione dell'immagine troppo grande!</value>
</data>
<data name="Extras" xml:space="preserve">
<value>Extras</value>
</data>
<data name="Female" xml:space="preserve">
<value>Signora</value>
</data>
@@ -447,6 +450,12 @@
<data name="Warning.Masterdata.Title" xml:space="preserve">
<value>Dati anagrafici non disponibili!</value>
</data>
<data name="Warning.NoConnection.Msg" xml:space="preserve">
<value>Il messaggio non può essere trasmesso. È stato salvato e sarà trasmesso al più presto.</value>
</data>
<data name="Warning.NoConnection.Title" xml:space="preserve">
<value>Nessuna connessione a Internet!</value>
</data>
<data name="Warning.Nominatim.Msg" xml:space="preserve">
<value>L'indirizzo non può essere risolto invocando il servizio Nominatim. Si prega di digitare la via e CAP/città.</value>
</data>

+ 9
- 0
Shared/ResourceFiles/Resources.resx View File

@@ -285,6 +285,9 @@
<data name="Error.PhotoOrPictureToBig.Title" xml:space="preserve">
<value>Size of picture to big!</value>
</data>
<data name="Extras" xml:space="preserve">
<value>Extras</value>
</data>
<data name="Female" xml:space="preserve">
<value>Madam</value>
</data>
@@ -447,6 +450,12 @@
<data name="Warning.Masterdata.Title" xml:space="preserve">
<value>Master data not available!</value>
</data>
<data name="Warning.NoConnection.Msg" xml:space="preserve">
<value>The report could not be transmitted. It was stored and will be transmitted as soon as possible!</value>
</data>
<data name="Warning.NoConnection.Title" xml:space="preserve">
<value>No connection to the internet!</value>
</data>
<data name="Warning.Nominatim.Msg" xml:space="preserve">
<value>The address could not be resolved invoking Nominatim service. Please type in the address street and zip/town.</value>
</data>

+ 18
- 13
Shared/Services/BicycleRestService.cs View File

@@ -1,5 +1,4 @@
using cwebplusApp.Shared.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
@@ -17,11 +16,12 @@ namespace cwebplusApp.Shared.Services {
private static readonly string VERSION = "v1";
private HttpClient httpClient;
[Inject]
public IConfiguration Configuration { get; set; }
public OnlineStatusProvider OnlineStatusProvider { get; set; }
public void Initialize(IConfiguration configuration) {
public void Initialize(IConfiguration configuration, OnlineStatusProvider onlineStatusProvider) {
this.Configuration = configuration;
this.OnlineStatusProvider = onlineStatusProvider;
string hostBaseUrl = Configuration.GetValue<string>("host_base_url");
if (!String.IsNullOrEmpty(hostBaseUrl)) {
this.httpClient = new HttpClient { BaseAddress = new Uri(hostBaseUrl) };
@@ -87,18 +87,23 @@ namespace cwebplusApp.Shared.Services {
}
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;
if (OnlineStatusProvider.Online) {
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!");
} else {
//TODO: Save to app storage
return null;
}
throw new HttpRequestException("HTTP client not initialized!");
}
}
}

+ 1
- 1
Shared/Services/IBicycleRestService.cs View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace cwebplusApp.Shared.Services {
public interface IBicycleRestService {
void Initialize(IConfiguration configuration);
void Initialize(IConfiguration configuration, OnlineStatusProvider onlineStatusProvider);
Task<List<ColorItem>> GetColors();

BIN
wwwroot/images/warning.png View File


+ 20
- 63
wwwroot/service-worker.js View File

@@ -29,6 +29,8 @@ const assets = [
'images/caritas_logo.png',
'images/integrate_logo.png',
'images/done.png',
'images/failure.png',
'images/warning.png',
'images/icon_camera.png',
'images/icon_driveupload.png',
'images/icon_location.png',
@@ -84,68 +86,23 @@ self.addEventListener('activate', event => {
});
// fetch events (appsettings are always first fetched from network)
self.addEventListener('fetch', event => {
if (event.request.url.endsWith(appsettings_url)) {
fetch(event.request).then(function (response) {
return caches.open(staticCacheName).then(function (cache) {
console.log('update cache');
cache.put(event.request, response.clone());
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 {
event.respondWith(
caches.match(event.request).then(cacheRes => {
return cacheRes || fetch(event.request);
})
);
}
});
//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);
// })
// );
// }
//});
self.addEventListener('fetch', function (event) {
event.respondWith(networkOrCache(event.request).catch(function () {
}));
})
//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 networkOrCache(request) {
return fetch(request).then(function (response) {
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');
// });
// });
//}
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');
});
});
}

Loading…
Cancel
Save