sharee.bike-App/TINKLib/View/WebViewHelper.cs
2022-10-03 17:55:10 +02:00

175 lines
5.4 KiB
C#

using System.Linq;
using Serilog;
using TINK.Model.Device;
using Xamarin.Forms;
namespace TINK.View
{
public static class WebViewHelper
{
/// <summary> Rountes request to browser if internal URI was detected or displays link in app otherwise. </summary>
/// <param name="sender">Sender of the event.</param>
/// <param name="eventArgs">Event arguments</param>
public static void SelectDisplayTarget(object sender, WebNavigatingEventArgs eventArgs)
{
if (!eventArgs.Url.ToUpper().StartsWith("HTTP"))
{
// An internal link was detected.
// Stay inside WebView
eventArgs.Cancel = false;
return;
}
// Do not navigate outside the document on web view.
eventArgs.Cancel = true;
// Open external link in browser.
DependencyService.Get<IExternalBrowserService>().OpenUrl(eventArgs.Url);
}
/// <summary> Routes request to broswer to download pdf- documents or displays link in app otherwise. </summary>
/// <param name="sender">Sender of the event.</param>
/// <param name="eventArgs">Event arguments</param>
public static void SetBusyAndDisplayOrDownload(object sender, WebNavigatingEventArgs eventArgs)
{
if (!eventArgs.Url.ToUpper().EndsWith(".PDF"))
{
// Stay inside web view except for downloading pdf- files.
SetBusy(sender);
eventArgs.Cancel = false;
return;
}
// Do not navigate outside the document on web view.
eventArgs.Cancel = true;
// Open external link in browser.
DependencyService.Get<IExternalBrowserService>().OpenUrl(eventArgs.Url);
}
/// <summary>
/// Disables WebView and shows ActivityIndicator.
/// </summary>
/// <remarks>
/// Prerequisites: Both WebView and ActivityInicator must be located on the same Grid object.
/// </remarks>
/// <param name="sender"></param>
private static void SetBusy(object sender)
{
if (!(sender is WebView webView))
{
// Nothing to do if sender is not a web view.
Log.Error($"Unexpected call of {nameof(SetBusy)} detected. Argument must not be of type {sender.GetType()}.");
return;
}
if (!(webView.Parent is Grid grid))
{
// Nothing to do if web view is not located on grid.
Log.Error($"Unexpected call of {nameof(SetBusy)} detected. Parent of argument must not be of type {webView.Parent.GetType()}.");
return;
}
grid.IsEnabled = false;
var indicator = grid.Children.OfType<ActivityIndicator>().FirstOrDefault();
if (indicator == null)
{
// Nothing to do if there is not activity indicator.
Log.Error($"Unexpected call of {nameof(SetBusy)} detected. No activity indicator found.");
return;
}
indicator.IsVisible = true;
indicator.IsRunning = true;
}
/// <summary>
/// Enables WebView and hides ActivityIndicator and sets error text to WebView in case an error occurred.
/// </summary>
/// <remarks>
/// Prerequisites: Both WebView and ActivityInicator must be located on the same Grid object.
/// </remarks>
/// <param name="htmlErrorMessage">HTML showing an error message.</param>
public static void SetIdleAndHandleError(
object sender,
WebNavigatedEventArgs eventArgs,
string htmlErrorMessage)
{
if (!(sender is WebView webView))
{
// Nothing to do if sender is not a web view.
Log.Error($"Unexpected call of {nameof(SetIdleAndHandleError)} detected. Argument must not be of type {sender.GetType()}.");
return;
}
if (!(webView.Parent is Grid grid))
{
// Nothing to do if web view is not located on grid.
Log.Error($"Unexpected call of {nameof(SetIdleAndHandleError)} detected. Parent of argument must not be of type {webView.Parent.GetType()}.");
return;
}
var indicator = grid.Children.OfType<ActivityIndicator>().FirstOrDefault();
if (indicator == null)
{
// Nothing to do if there is not activity indicator.
Log.Error($"Unexpected call of {nameof(SetIdleAndHandleError)} detected. No activity indicator found.");
}
if (eventArgs.Result == WebNavigationResult.Success)
{
// Uri could be loaded successfully.
grid.IsEnabled = true;
if (indicator != null)
{
indicator.IsVisible = false;
indicator.IsRunning = false;
}
return;
}
// Navigation failed.
Log.Error("Navigation did not succeed.{@Event}{@Sender}", eventArgs, sender);
webView.Source = new HtmlWebViewSource
{
Html = !string.IsNullOrEmpty(htmlErrorMessage) ? htmlErrorMessage : $"Navigation to {eventArgs.Url} failed."
};
grid.IsEnabled = true;
if (indicator != null)
{
indicator.IsVisible = false;
indicator.IsRunning = false;
}
}
/// <summary>
/// Sets error text to WebView in case an error occurred.
/// </summary>
/// <param name="htmlErrorMessage">HTML showing an error message.</param>
public static void HandleError(
object sender,
WebNavigatedEventArgs eventArgs,
string htmlErrorMessage)
{
if (eventArgs.Result == WebNavigationResult.Success)
{
// Uri could be loaded successfully.
return;
}
if (!(sender is WebView webView))
{
// Nothing to do if sender is not a web view.
Log.Error($"Unexpected call of {nameof(HandleError)} detected. Argument must not be of type {sender.GetType()}.");
return;
}
// Navigation failed.
Log.Error("Navigation did not succeed.{@Event}{@Sender}", eventArgs, sender);
webView.Source = new HtmlWebViewSource
{
Html = !string.IsNullOrEmpty(htmlErrorMessage) ? htmlErrorMessage : $"Navigation to {eventArgs.Url} failed."
};
}
}
}