mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-04-24 21:56:29 +02:00
Version 3.0.338
This commit is contained in:
parent
573fe77e12
commit
0468955d49
751 changed files with 62747 additions and 60672 deletions
|
@ -4,21 +4,13 @@
|
|||
root = true
|
||||
# All files
|
||||
[*]
|
||||
indent_style = space
|
||||
|
||||
# XML project files
|
||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||
indent_size = 2
|
||||
|
||||
# XML config files
|
||||
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
|
||||
indent_size = 2
|
||||
|
||||
# Code files
|
||||
[*.{cs,csx,vb,vbx}]
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
insert_final_newline = true
|
||||
charset = utf-8-bom
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
end_of_line = crlf
|
||||
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
###############################
|
||||
|
@ -139,4 +131,4 @@ csharp_style_expression_bodied_local_functions = false:silent
|
|||
###############################
|
||||
[*.vb]
|
||||
# Modifier preferences
|
||||
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
||||
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
||||
|
|
|
@ -13,96 +13,96 @@ using Xamarin.Forms.Platform.Android.AppLinks;
|
|||
|
||||
namespace TINK.Droid
|
||||
{
|
||||
[Activity(Label = "LastenradBayern", Icon = "@drawable/sharee", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
[Activity(Label = "LastenradBayern", Icon = "@drawable/sharee", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
|
||||
[IntentFilter(new[] { Intent.ActionView },
|
||||
Categories = new[] { Intent.ActionView, Intent.CategoryBrowsable, Intent.CategoryDefault },
|
||||
DataScheme = "https",
|
||||
DataHost = "sharee.bike",
|
||||
DataPathPrefix = "/lastenrad",
|
||||
AutoVerify = true)]
|
||||
[IntentFilter(new[] { Intent.ActionView },
|
||||
Categories = new[] { Intent.ActionView, Intent.CategoryBrowsable, Intent.CategoryDefault },
|
||||
DataScheme = "https",
|
||||
DataHost = "sharee.bike",
|
||||
DataPathPrefix = "/lastenrad",
|
||||
AutoVerify = true)]
|
||||
|
||||
[IntentFilter(new[] { Intent.ActionView },
|
||||
Categories = new[] { Intent.ActionView, Intent.CategoryBrowsable, Intent.CategoryDefault },
|
||||
DataScheme = "http",
|
||||
DataHost = "sharee.bike",
|
||||
DataPathPrefix = "/lastenrad",
|
||||
AutoVerify = true)]
|
||||
[IntentFilter(new[] { Intent.ActionView },
|
||||
Categories = new[] { Intent.ActionView, Intent.CategoryBrowsable, Intent.CategoryDefault },
|
||||
DataScheme = "http",
|
||||
DataHost = "sharee.bike",
|
||||
DataPathPrefix = "/lastenrad",
|
||||
AutoVerify = true)]
|
||||
|
||||
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
private void initFontScale()
|
||||
{
|
||||
Configuration configuration = Resources.Configuration;
|
||||
configuration.FontScale = (float)1;
|
||||
//0.85 small, 1 standard, 1.15 big,1.3 more bigger ,1.45 supper big
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager.DefaultDisplay.GetMetrics(metrics);
|
||||
metrics.ScaledDensity = configuration.FontScale * metrics.Density;
|
||||
BaseContext.Resources.UpdateConfiguration(configuration, metrics);
|
||||
}
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
initFontScale();
|
||||
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
private void initFontScale()
|
||||
{
|
||||
Configuration configuration = Resources.Configuration;
|
||||
configuration.FontScale = (float)1;
|
||||
//0.85 small, 1 standard, 1.15 big,1.3 more bigger ,1.45 supper big
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
WindowManager.DefaultDisplay.GetMetrics(metrics);
|
||||
metrics.ScaledDensity = configuration.FontScale * metrics.Density;
|
||||
BaseContext.Resources.UpdateConfiguration(configuration, metrics);
|
||||
}
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
initFontScale();
|
||||
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
|
||||
base.OnCreate(bundle);
|
||||
base.OnCreate(bundle);
|
||||
|
||||
global::Xamarin.Forms.Forms.Init(this, bundle);
|
||||
global::Xamarin.Forms.Forms.Init(this, bundle);
|
||||
|
||||
FirebaseApp.InitializeApp(this);
|
||||
AndroidAppLinks.Init(this);
|
||||
FirebaseApp.InitializeApp(this);
|
||||
AndroidAppLinks.Init(this);
|
||||
|
||||
// Initialize xamarin.essentials, see https://docs.microsoft.com/en-us/xamarin/essentials/get-started?tabs=macos%2Candroid.
|
||||
Xamarin.Essentials.Platform.Init(this, bundle);
|
||||
// Initialize xamarin.essentials, see https://docs.microsoft.com/en-us/xamarin/essentials/get-started?tabs=macos%2Candroid.
|
||||
Xamarin.Essentials.Platform.Init(this, bundle);
|
||||
|
||||
// Required for initialization of Maps, see https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/
|
||||
Xamarin.FormsGoogleMaps.Init(this, bundle);
|
||||
// Required for initialization of Maps, see https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/
|
||||
Xamarin.FormsGoogleMaps.Init(this, bundle);
|
||||
|
||||
// Required for initialization of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
|
||||
Xamarin.FormsGoogleMapsBindings.Init();
|
||||
// Required for initialization of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
|
||||
Xamarin.FormsGoogleMapsBindings.Init();
|
||||
|
||||
// Get version name of app.
|
||||
Context context = ApplicationContext;
|
||||
new Model.Device.AppInfo(context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName);
|
||||
// Get version name of app.
|
||||
Context context = ApplicationContext;
|
||||
new Model.Device.AppInfo(context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName);
|
||||
|
||||
Xamarin.Forms.Forms.ViewInitialized += (object sender, Xamarin.Forms.ViewInitializedEventArgs e) =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.View.AutomationId))
|
||||
{
|
||||
e.NativeView.ContentDescription = e.View.AutomationId;
|
||||
}
|
||||
};
|
||||
Xamarin.Forms.Forms.ViewInitialized += (object sender, Xamarin.Forms.ViewInitializedEventArgs e) =>
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.View.AutomationId))
|
||||
{
|
||||
e.NativeView.ContentDescription = e.View.AutomationId;
|
||||
}
|
||||
};
|
||||
|
||||
LoadApplication(new App());
|
||||
}
|
||||
LoadApplication(new App());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles opening the dialog to request for permissions.
|
||||
/// </summary>
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
|
||||
{
|
||||
if (App.PermissionsService.GetType() == typeof(TINK.Services.Permissions.Essentials.Permissions))
|
||||
{
|
||||
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
else if (App.PermissionsService.GetType() == typeof(TINK.Services.Permissions.Plugin.Permissions))
|
||||
{
|
||||
// Bug in 3.0.244 and earlier versions of sharee.bike app: Call of PermissionsImplementation.Current.OnRequestedPermission result was missing.
|
||||
// see https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/136 for further details.
|
||||
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
/// <summary>
|
||||
/// Handles opening the dialog to request for permissions.
|
||||
/// </summary>
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
|
||||
{
|
||||
if (App.PermissionsService.GetType() == typeof(TINK.Services.Permissions.Essentials.Permissions))
|
||||
{
|
||||
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
else if (App.PermissionsService.GetType() == typeof(TINK.Services.Permissions.Plugin.Permissions))
|
||||
{
|
||||
// Bug in 3.0.244 and earlier versions of sharee.bike app: Call of PermissionsImplementation.Current.OnRequestedPermission result was missing.
|
||||
// see https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/136 for further details.
|
||||
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
[Export("TapStation")]
|
||||
public void TapStation(string stationNr)
|
||||
{
|
||||
BackdoorMethodHelpers.DoTapPage(stationNr);
|
||||
}
|
||||
}
|
||||
[Export("TapStation")]
|
||||
public void TapStation(string stationNr)
|
||||
{
|
||||
BackdoorMethodHelpers.DoTapPage(stationNr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,40 +6,40 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(AppInfo))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
/// <summary> Holds information about the TINK- app. </summary>
|
||||
public class AppInfo : IAppInfo
|
||||
{
|
||||
/// <summary> Holds the the version of the app.</summary>
|
||||
private static Version m_oVersion = null;
|
||||
/// <summary> Holds information about the TINK- app. </summary>
|
||||
public class AppInfo : IAppInfo
|
||||
{
|
||||
/// <summary> Holds the the version of the app.</summary>
|
||||
private static Version m_oVersion = null;
|
||||
|
||||
/// <summary> Constructs a app info object. </summary>
|
||||
public AppInfo()
|
||||
{
|
||||
}
|
||||
/// <summary> Constructs a app info object. </summary>
|
||||
public AppInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary> Constructs a app info object for initialization. </summary>
|
||||
/// <param name="p_strVersionText"> Version to initializ object with.</param>
|
||||
internal AppInfo(string p_strVersionText)
|
||||
{
|
||||
if (m_oVersion != null)
|
||||
{
|
||||
// Set version only once.
|
||||
return;
|
||||
}
|
||||
/// <summary> Constructs a app info object for initialization. </summary>
|
||||
/// <param name="p_strVersionText"> Version to initializ object with.</param>
|
||||
internal AppInfo(string p_strVersionText)
|
||||
{
|
||||
if (m_oVersion != null)
|
||||
{
|
||||
// Set version only once.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Version.TryParse(p_strVersionText, out Version l_oVersion))
|
||||
{
|
||||
m_oVersion = new Version(0, 8);
|
||||
}
|
||||
if (!Version.TryParse(p_strVersionText, out Version l_oVersion))
|
||||
{
|
||||
m_oVersion = new Version(0, 8);
|
||||
}
|
||||
|
||||
m_oVersion = l_oVersion;
|
||||
}
|
||||
m_oVersion = l_oVersion;
|
||||
}
|
||||
|
||||
/// <summary> Get the version of the app. </summary>
|
||||
public Version Version => m_oVersion ?? new Version(0, 9);
|
||||
/// <summary> Get the version of the app. </summary>
|
||||
public Version Version => m_oVersion ?? new Version(0, 9);
|
||||
|
||||
/// <summary> Gets the URL to the app store. </summary>
|
||||
/// <value>The store URL.</value>
|
||||
public string StoreUrl => $"https://play.google.com/store/apps/details?id={Android.App.Application.Context.PackageName}";
|
||||
}
|
||||
/// <summary> Gets the URL to the app store. </summary>
|
||||
/// <value>The store URL.</value>
|
||||
public string StoreUrl => $"https://play.google.com/store/apps/details?id={Android.App.Application.Context.PackageName}";
|
||||
}
|
||||
}
|
|
@ -5,19 +5,19 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(TINK.Droid.Model.Device.Device))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
public class Device : ISmartDevice
|
||||
{
|
||||
public string Manufacturer => DeviceInfo.Manufacturer;
|
||||
public class Device : ISmartDevice
|
||||
{
|
||||
public string Manufacturer => DeviceInfo.Manufacturer;
|
||||
|
||||
public string Model => DeviceInfo.Model;
|
||||
public string Model => DeviceInfo.Model;
|
||||
|
||||
public DevicePlatform Platform => DeviceInfo.Platform;
|
||||
public DevicePlatform Platform => DeviceInfo.Platform;
|
||||
|
||||
public string VersionText => DeviceInfo.VersionString;
|
||||
public string VersionText => DeviceInfo.VersionString;
|
||||
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string Identifier
|
||||
=> Android.Provider.Settings.Secure.GetString(Android.App.Application.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
|
||||
}
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string Identifier
|
||||
=> Android.Provider.Settings.Secure.GetString(Android.App.Application.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
|
||||
}
|
||||
}
|
|
@ -6,18 +6,18 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(ExternalBrowseService))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
public class ExternalBrowseService : IExternalBrowserService
|
||||
{
|
||||
/// <summary> Opens an external browser. </summary>
|
||||
/// <param name="p_strUrl">Url to open.</param>
|
||||
public void OpenUrl(string p_strUrl)
|
||||
{
|
||||
var uri = Android.Net.Uri.Parse(p_strUrl);
|
||||
var intent = new Intent(Intent.ActionView, uri);
|
||||
public class ExternalBrowseService : IExternalBrowserService
|
||||
{
|
||||
/// <summary> Opens an external browser. </summary>
|
||||
/// <param name="p_strUrl">Url to open.</param>
|
||||
public void OpenUrl(string p_strUrl)
|
||||
{
|
||||
var uri = Android.Net.Uri.Parse(p_strUrl);
|
||||
var intent = new Intent(Intent.ActionView, uri);
|
||||
|
||||
intent.AddFlags(ActivityFlags.NewTask);
|
||||
intent.AddFlags(ActivityFlags.NewTask);
|
||||
|
||||
Android.App.Application.Context.StartActivity(intent);
|
||||
}
|
||||
}
|
||||
Android.App.Application.Context.StartActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,15 +16,15 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(TINK.Droid.Model.Device.Gps))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
public class Gps : IGeolodationDependent
|
||||
{
|
||||
public bool IsGeolcationEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
LocationManager locationManager = (LocationManager)Android.App.Application.Context.GetSystemService(Context.LocationService);
|
||||
return locationManager.IsProviderEnabled(LocationManager.GpsProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class Gps : IGeolodationDependent
|
||||
{
|
||||
public bool IsGeolcationEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
LocationManager locationManager = (LocationManager)Android.App.Application.Context.GetSystemService(Context.LocationService);
|
||||
return locationManager.IsProviderEnabled(LocationManager.GpsProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,44 +6,44 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(TINK.Droid.Model.Device.SpecialFolder))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
public class SpecialFolder : ISpecialFolder
|
||||
{
|
||||
/// <summary> Get the folder name of external folder to write to. </summary>
|
||||
/// <returns> Name of the external folder. </returns>
|
||||
public string GetExternalFilesDir()
|
||||
{
|
||||
string baseFolderPath = string.Empty;
|
||||
try
|
||||
{
|
||||
var context = Android.App.Application.Context;
|
||||
Java.IO.File[] dirs = context.GetExternalFilesDirs(null);
|
||||
public class SpecialFolder : ISpecialFolder
|
||||
{
|
||||
/// <summary> Get the folder name of external folder to write to. </summary>
|
||||
/// <returns> Name of the external folder. </returns>
|
||||
public string GetExternalFilesDir()
|
||||
{
|
||||
string baseFolderPath = string.Empty;
|
||||
try
|
||||
{
|
||||
var context = Android.App.Application.Context;
|
||||
Java.IO.File[] dirs = context.GetExternalFilesDirs(null);
|
||||
|
||||
foreach (Java.IO.File folder in dirs)
|
||||
{
|
||||
bool IsRemovable = Android.OS.Environment.InvokeIsExternalStorageRemovable(folder);
|
||||
bool IsEmulated = Android.OS.Environment.InvokeIsExternalStorageEmulated(folder);
|
||||
foreach (Java.IO.File folder in dirs)
|
||||
{
|
||||
bool IsRemovable = Android.OS.Environment.InvokeIsExternalStorageRemovable(folder);
|
||||
bool IsEmulated = Android.OS.Environment.InvokeIsExternalStorageEmulated(folder);
|
||||
|
||||
if (IsRemovable
|
||||
&& !IsEmulated)
|
||||
{
|
||||
baseFolderPath = folder.Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsRemovable
|
||||
&& !IsEmulated)
|
||||
{
|
||||
baseFolderPath = folder.Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
Log.Error("Getting external files directory failed. {@l_oException}", l_oException);
|
||||
}
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
Log.Error("Getting external files directory failed. {@l_oException}", l_oException);
|
||||
}
|
||||
|
||||
return baseFolderPath;
|
||||
}
|
||||
return baseFolderPath;
|
||||
}
|
||||
|
||||
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
|
||||
/// <returns>Directory name.</returns>
|
||||
public string GetInternalPersonalDir()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
}
|
||||
}
|
||||
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
|
||||
/// <returns>Directory name.</returns>
|
||||
public string GetInternalPersonalDir()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,13 +4,13 @@ using TINK.Model.Device;
|
|||
[assembly: Xamarin.Forms.Dependency(typeof(TINK.Droid.Model.Device.WebView))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
public class WebView : IWebView
|
||||
{
|
||||
/// <summary> Clears the cookie cache for all web views. </summary>
|
||||
public void ClearCookies()
|
||||
{
|
||||
var cookieManager = CookieManager.Instance;
|
||||
cookieManager.RemoveAllCookie();
|
||||
}
|
||||
}
|
||||
public class WebView : IWebView
|
||||
{
|
||||
/// <summary> Clears the cookie cache for all web views. </summary>
|
||||
public void ClearCookies()
|
||||
{
|
||||
var cookieManager = CookieManager.Instance;
|
||||
cookieManager.RemoveAllCookie();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.337" android:versionCode="337">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.338" android:versionCode="338">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -4,45 +4,45 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.iOS
|
||||
{
|
||||
// The UIApplicationDelegate for the application. This class is responsible for launching the
|
||||
// User Interface of the application, as well as listening (and optionally responding) to
|
||||
// application events from iOS.
|
||||
[Register("AppDelegate")]
|
||||
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
|
||||
{
|
||||
//
|
||||
// This method is invoked when the application has loaded and is ready to run. In this
|
||||
// method you should instantiate the window, load the UI into it and then make the window
|
||||
// visible.
|
||||
//
|
||||
// You have 17 seconds to return from this method, or iOS will terminate your application.
|
||||
//
|
||||
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
|
||||
{
|
||||
global::Xamarin.Forms.Forms.Init();
|
||||
// The UIApplicationDelegate for the application. This class is responsible for launching the
|
||||
// User Interface of the application, as well as listening (and optionally responding) to
|
||||
// application events from iOS.
|
||||
[Register("AppDelegate")]
|
||||
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
|
||||
{
|
||||
//
|
||||
// This method is invoked when the application has loaded and is ready to run. In this
|
||||
// method you should instantiate the window, load the UI into it and then make the window
|
||||
// visible.
|
||||
//
|
||||
// You have 17 seconds to return from this method, or iOS will terminate your application.
|
||||
//
|
||||
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
|
||||
{
|
||||
global::Xamarin.Forms.Forms.Init();
|
||||
|
||||
//Color of Icons in Navigation bar (e.g. burger menu and back arrow)
|
||||
//UINavigationBar.Appearance.TintColor = Color.White.ToUIColor();
|
||||
//Color of Icons in Navigation bar (e.g. burger menu and back arrow)
|
||||
//UINavigationBar.Appearance.TintColor = Color.White.ToUIColor();
|
||||
|
||||
new iOS.Device.AppInfo(NSBundle.MainBundle.InfoDictionary[new NSString("CFBundleShortVersionString")]?.ToString() ?? string.Empty);
|
||||
new iOS.Device.AppInfo(NSBundle.MainBundle.InfoDictionary[new NSString("CFBundleShortVersionString")]?.ToString() ?? string.Empty);
|
||||
|
||||
Forms.ViewInitialized += (object sender, ViewInitializedEventArgs e) =>
|
||||
{
|
||||
// http://developer.xamarin.com/recipes/testcloud/set-accessibilityidentifier-ios/
|
||||
if (null != e.View.AutomationId)
|
||||
{
|
||||
e.NativeView.AccessibilityIdentifier = e.View.AutomationId;
|
||||
}
|
||||
};
|
||||
LoadApplication(new TINK.App());
|
||||
Forms.ViewInitialized += (object sender, ViewInitializedEventArgs e) =>
|
||||
{
|
||||
// http://developer.xamarin.com/recipes/testcloud/set-accessibilityidentifier-ios/
|
||||
if (null != e.View.AutomationId)
|
||||
{
|
||||
e.NativeView.AccessibilityIdentifier = e.View.AutomationId;
|
||||
}
|
||||
};
|
||||
LoadApplication(new TINK.App());
|
||||
|
||||
// Required for initialization of Maps, see https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/
|
||||
Xamarin.FormsGoogleMaps.Init("000000000000000000000000000000000000000");
|
||||
// Required for initialization of Maps, see https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/
|
||||
Xamarin.FormsGoogleMaps.Init("000000000000000000000000000000000000000");
|
||||
|
||||
// Required for initialization of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
|
||||
Xamarin.FormsGoogleMapsBindings.Init();
|
||||
// Required for initialization of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
|
||||
Xamarin.FormsGoogleMapsBindings.Init();
|
||||
|
||||
return base.FinishedLaunching(app, options);
|
||||
}
|
||||
}
|
||||
return base.FinishedLaunching(app, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,41 +7,41 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(AppInfo))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
/// <summary> Holds information about the TINK- app. </summary>
|
||||
public class AppInfo : IAppInfo
|
||||
{
|
||||
/// <summary> Holds the the version of the app.</summary>
|
||||
private static Version m_oVersion = null;
|
||||
/// <summary> Holds information about the TINK- app. </summary>
|
||||
public class AppInfo : IAppInfo
|
||||
{
|
||||
/// <summary> Holds the the version of the app.</summary>
|
||||
private static Version m_oVersion = null;
|
||||
|
||||
/// <summary> Constructs a app info object. </summary>
|
||||
public AppInfo()
|
||||
{
|
||||
}
|
||||
/// <summary> Constructs a app info object. </summary>
|
||||
public AppInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary> Constructs a app info object for initialization. </summary>
|
||||
/// <param name="p_strVersionText"> Version to initializ object with.</param>
|
||||
internal AppInfo(string p_strVersionText)
|
||||
{
|
||||
if (m_oVersion != null)
|
||||
{
|
||||
// Set version only once.
|
||||
return;
|
||||
}
|
||||
/// <summary> Constructs a app info object for initialization. </summary>
|
||||
/// <param name="p_strVersionText"> Version to initializ object with.</param>
|
||||
internal AppInfo(string p_strVersionText)
|
||||
{
|
||||
if (m_oVersion != null)
|
||||
{
|
||||
// Set version only once.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Version.TryParse(p_strVersionText, out Version l_oVersion))
|
||||
{
|
||||
m_oVersion = new Version(0, 8);
|
||||
}
|
||||
if (!Version.TryParse(p_strVersionText, out Version l_oVersion))
|
||||
{
|
||||
m_oVersion = new Version(0, 8);
|
||||
}
|
||||
|
||||
m_oVersion = l_oVersion;
|
||||
}
|
||||
m_oVersion = l_oVersion;
|
||||
}
|
||||
|
||||
/// <summary> Get the version of the app. </summary>
|
||||
public Version Version => m_oVersion ?? new Version(0, 9);
|
||||
/// <summary> Get the version of the app. </summary>
|
||||
public Version Version => m_oVersion ?? new Version(0, 9);
|
||||
|
||||
/// <summary> Gets the URL to the app store. </summary>
|
||||
/// <remarks> TINK Url was @"http://itunes.apple.com/de/app/tink-konstanz/id1181519270?mt=8"</remarks>
|
||||
/// <value>The store URL.</value>
|
||||
public string StoreUrl => $"https://itunes.apple.com/de/app/apple-store/{NSBundle.MainBundle.BundleIdentifier}?mt=8";
|
||||
}
|
||||
/// <summary> Gets the URL to the app store. </summary>
|
||||
/// <remarks> TINK Url was @"http://itunes.apple.com/de/app/tink-konstanz/id1181519270?mt=8"</remarks>
|
||||
/// <value>The store URL.</value>
|
||||
public string StoreUrl => $"https://itunes.apple.com/de/app/apple-store/{NSBundle.MainBundle.BundleIdentifier}?mt=8";
|
||||
}
|
||||
}
|
|
@ -6,30 +6,30 @@ using Xamarin.Essentials;
|
|||
[assembly: Xamarin.Forms.Dependency(typeof(TINK.iOS.Device.Device))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class Device : ISmartDevice
|
||||
{
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);
|
||||
public class Device : ISmartDevice
|
||||
{
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern IntPtr IOServiceMatching(string s);
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern IntPtr IOServiceMatching(string s);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern int IOObjectRelease(uint o);
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern int IOObjectRelease(uint o);
|
||||
|
||||
public string Manufacturer => DeviceInfo.Manufacturer;
|
||||
public string Manufacturer => DeviceInfo.Manufacturer;
|
||||
|
||||
public string Model => DeviceInfo.Model;
|
||||
public string Model => DeviceInfo.Model;
|
||||
|
||||
public DevicePlatform Platform => DeviceInfo.Platform;
|
||||
public DevicePlatform Platform => DeviceInfo.Platform;
|
||||
|
||||
public string VersionText => DeviceInfo.VersionString;
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string Identifier
|
||||
=> UIKit.UIDevice.CurrentDevice?.IdentifierForVendor?.AsString() ?? string.Empty;
|
||||
}
|
||||
public string VersionText => DeviceInfo.VersionString;
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string Identifier
|
||||
=> UIKit.UIDevice.CurrentDevice?.IdentifierForVendor?.AsString() ?? string.Empty;
|
||||
}
|
||||
}
|
|
@ -7,17 +7,17 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(ExternalBrowseService))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class ExternalBrowseService : IExternalBrowserService
|
||||
{
|
||||
/// <summary> Opens an external browser. </summary>
|
||||
/// <param name="p_strUrl">Url to open.</param>
|
||||
public void OpenUrl(string p_strUrl)
|
||||
{
|
||||
var l_oUrl = NSUrl.FromString(p_strUrl);
|
||||
if (l_oUrl == null)
|
||||
return;
|
||||
public class ExternalBrowseService : IExternalBrowserService
|
||||
{
|
||||
/// <summary> Opens an external browser. </summary>
|
||||
/// <param name="p_strUrl">Url to open.</param>
|
||||
public void OpenUrl(string p_strUrl)
|
||||
{
|
||||
var l_oUrl = NSUrl.FromString(p_strUrl);
|
||||
if (l_oUrl == null)
|
||||
return;
|
||||
|
||||
UIApplication.SharedApplication.OpenUrl(l_oUrl);
|
||||
}
|
||||
}
|
||||
UIApplication.SharedApplication.OpenUrl(l_oUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
[assembly: Xamarin.Forms.Dependency(typeof(TINK.iOS.Device.Gps))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class Gps : IGeolodationDependent
|
||||
{
|
||||
public bool IsGeolcationEnabled => true;
|
||||
}
|
||||
public class Gps : IGeolodationDependent
|
||||
{
|
||||
public bool IsGeolcationEnabled => true;
|
||||
}
|
||||
}
|
|
@ -5,23 +5,23 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(TINK.iOS.Device.SpecialFolder))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class SpecialFolder : ISpecialFolder
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the folder name of external folder to write to.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetExternalFilesDir()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
}
|
||||
public class SpecialFolder : ISpecialFolder
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the folder name of external folder to write to.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetExternalFilesDir()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
}
|
||||
|
||||
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
|
||||
/// <returns>Directory name.</returns>
|
||||
public string GetInternalPersonalDir()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
}
|
||||
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
|
||||
/// <returns>Directory name.</returns>
|
||||
public string GetInternalPersonalDir()
|
||||
{
|
||||
return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,14 +5,14 @@ using TINK.Model.Device;
|
|||
[assembly: Xamarin.Forms.Dependency(typeof(TINK.iOS.Device.WebView))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class WebView : IWebView
|
||||
{
|
||||
/// <summary> Clears the cookie cache for all web views. </summary>
|
||||
public void ClearCookies()
|
||||
{
|
||||
NSHttpCookieStorage CookieStorage = NSHttpCookieStorage.SharedStorage;
|
||||
foreach (var cookie in CookieStorage.Cookies)
|
||||
CookieStorage.DeleteCookie(cookie);
|
||||
}
|
||||
}
|
||||
public class WebView : IWebView
|
||||
{
|
||||
/// <summary> Clears the cookie cache for all web views. </summary>
|
||||
public void ClearCookies()
|
||||
{
|
||||
NSHttpCookieStorage CookieStorage = NSHttpCookieStorage.SharedStorage;
|
||||
foreach (var cookie in CookieStorage.Cookies)
|
||||
CookieStorage.DeleteCookie(cookie);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,24 +5,24 @@ using Xamarin.Forms;
|
|||
[assembly: Dependency(typeof(TINK.iOS.Device.IOSCipher))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class IOSCipher : ICipher
|
||||
{
|
||||
/// <summary> Encrypt data.</summary>
|
||||
/// <param name="key">Key to encrypt data.</param>
|
||||
/// <param name="clear">Data to entrycpt.</param>
|
||||
/// <returns></returns>
|
||||
public byte[] Encrypt(byte[] key, byte[] clear)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public class IOSCipher : ICipher
|
||||
{
|
||||
/// <summary> Encrypt data.</summary>
|
||||
/// <param name="key">Key to encrypt data.</param>
|
||||
/// <param name="clear">Data to entrycpt.</param>
|
||||
/// <returns></returns>
|
||||
public byte[] Encrypt(byte[] key, byte[] clear)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Decrypt data. </summary>
|
||||
/// <param name="key">Key to decrypt data with.</param>
|
||||
/// <param name="encrypted">Encrpyted data to decrypt.</param>
|
||||
/// <returns>Decrypted data.</returns>
|
||||
public byte[] Decrypt(byte[] key, byte[] encrypted)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
/// <summary> Decrypt data. </summary>
|
||||
/// <param name="key">Key to decrypt data with.</param>
|
||||
/// <param name="encrypted">Encrpyted data to decrypt.</param>
|
||||
/// <returns>Decrypted data.</returns>
|
||||
public byte[] Decrypt(byte[] key, byte[] encrypted)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
|
@ -6,8 +6,8 @@
|
|||
<array>
|
||||
<string>bluetooth-peripheral</string>
|
||||
</array>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
|
@ -47,7 +47,7 @@
|
|||
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||
<string>Location access is needed to show map at current position and pass position to server when returning bikes.</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>9.0</string>
|
||||
<string>13.0</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>Location access is needed to show map at current position and pass position to server when returning bikes.</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
@ -55,8 +55,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>LastenradBayern</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>337</string>
|
||||
<string>338</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.337</string>
|
||||
<string>3.0.338</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<MtouchArch>i386, x86_64</MtouchArch>
|
||||
<MtouchArch>x86_64</MtouchArch>
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchDebug>true</MtouchDebug>
|
||||
<CodesignProvision>VS: com.TeilRad.LastenradBayern Development</CodesignProvision>
|
||||
|
@ -37,8 +37,8 @@
|
|||
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchArch>i386, x86_64</MtouchArch>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
<MtouchArch>x86_64</MtouchArch>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<CodesignProvision>VS: com.TeilRad.LastenradBayern Development</CodesignProvision>
|
||||
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
|
||||
|
@ -52,11 +52,11 @@
|
|||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<MtouchArch>ARMv7, ARM64</MtouchArch>
|
||||
<MtouchArch>ARM64</MtouchArch>
|
||||
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
|
||||
<MtouchDebug>true</MtouchDebug>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<MtouchLink>None</MtouchLink>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
<MtouchInterpreter>-all</MtouchInterpreter>
|
||||
<CodesignProvision>VS: com.TeilRad.LastenradBayern Development</CodesignProvision>
|
||||
</PropertyGroup>
|
||||
|
@ -67,7 +67,7 @@
|
|||
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<MtouchArch>ARMv7, ARM64</MtouchArch>
|
||||
<MtouchArch>ARM64</MtouchArch>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
|
@ -77,6 +77,7 @@
|
|||
<CrashReportingApiKey>
|
||||
</CrashReportingApiKey>
|
||||
<MtouchLink>SdkOnly</MtouchLink>
|
||||
<MtouchSdkVersion>15.5</MtouchSdkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
|
||||
<DebugType>none</DebugType>
|
||||
|
@ -202,10 +203,10 @@
|
|||
<Version>1.7.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Forms.GoogleMaps">
|
||||
<Version>3.3.0</Version>
|
||||
<Version>5.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
|
||||
<PackageReference Include="Xamarin.Google.iOS.Maps" Version="3.9.0" />
|
||||
<PackageReference Include="Xamarin.Google.iOS.Maps" Version="6.0.1.1" />
|
||||
<PackageReference Include="PInvoke.BCrypt">
|
||||
<Version>0.7.124</Version>
|
||||
</PackageReference>
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace TINK.iOS
|
||||
{
|
||||
public class Application
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, "AppDelegate");
|
||||
}
|
||||
}
|
||||
public class Application
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, "AppDelegate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,166 +30,166 @@ using Arendi.BleLibrary.Local;
|
|||
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
namespace TINK
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
/// <summary>Title of the attachment file.</summary>
|
||||
private const string ATTACHMENTTITLE = "Diagnostics.txt";
|
||||
public partial class App : Application
|
||||
{
|
||||
/// <summary>Title of the attachment file.</summary>
|
||||
private const string ATTACHMENTTITLE = "Diagnostics.txt";
|
||||
|
||||
/// <summary> Model root. </summary>
|
||||
private static TinkApp m_oModelRoot;
|
||||
/// <summary> Model root. </summary>
|
||||
private static TinkApp m_oModelRoot;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model root.
|
||||
/// </summary>
|
||||
public static TinkApp ModelRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_oModelRoot != null)
|
||||
{
|
||||
// Root model already exists, nothing to do.
|
||||
return m_oModelRoot;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the model root.
|
||||
/// </summary>
|
||||
public static TinkApp ModelRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_oModelRoot != null)
|
||||
{
|
||||
// Root model already exists, nothing to do.
|
||||
return m_oModelRoot;
|
||||
}
|
||||
|
||||
// Get folder where to read settings from
|
||||
var specialFolders = DependencyService.Get<ISpecialFolder>();
|
||||
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
|
||||
// Get folder where to read settings from
|
||||
var specialFolders = DependencyService.Get<ISpecialFolder>();
|
||||
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
|
||||
|
||||
// Delete attachtment from previous session.
|
||||
DeleteAttachment(internalPersonalDir);
|
||||
// Delete attachtment from previous session.
|
||||
DeleteAttachment(internalPersonalDir);
|
||||
|
||||
// Setup logger using default settings.
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(Model.Settings.Settings.DEFAULTLOGGINLEVEL),
|
||||
internalPersonalDir);
|
||||
// Setup logger using default settings.
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(Model.Settings.Settings.DEFAULTLOGGINLEVEL),
|
||||
internalPersonalDir);
|
||||
|
||||
// Subscribe to any unhandled/ unobserved exceptions.
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, unobservedTaskExceptionEventArgs) => { Log.Fatal("Unobserved task exception: {Exception}", unobservedTaskExceptionEventArgs.ExceptionObject); };
|
||||
TaskScheduler.UnobservedTaskException += (sender, unhandledExceptionEventArgs) => { Log.Fatal("Unhandled exception: {Exception}", unhandledExceptionEventArgs.Exception); };
|
||||
// Subscribe to any unhandled/ unobserved exceptions.
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, unobservedTaskExceptionEventArgs) => { Log.Fatal("Unobserved task exception: {Exception}", unobservedTaskExceptionEventArgs.ExceptionObject); };
|
||||
TaskScheduler.UnobservedTaskException += (sender, unhandledExceptionEventArgs) => { Log.Fatal("Unhandled exception: {Exception}", unhandledExceptionEventArgs.Exception); };
|
||||
|
||||
// Restore last model state from json- file.
|
||||
Dictionary<string, string> settingsJSON = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
settingsJSON = JsonSettingsDictionary.Deserialize(internalPersonalDir);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("Reading application settings from file failed.", exception);
|
||||
}
|
||||
// Restore last model state from json- file.
|
||||
Dictionary<string, string> settingsJSON = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
settingsJSON = JsonSettingsDictionary.Deserialize(internalPersonalDir);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("Reading application settings from file failed.", exception);
|
||||
}
|
||||
|
||||
Model.Settings.Settings settings;
|
||||
try
|
||||
{
|
||||
settings = new Model.Settings.Settings(
|
||||
null, // Turn off filtering for LastenradBayern- context
|
||||
null, // Turn off filtering for LastenradBayern- context
|
||||
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
|
||||
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
|
||||
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsReportLevelVerbose(settingsJSON),
|
||||
JsonSettingsDictionary.GetExpiresAfter(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveLockService(settingsJSON),
|
||||
JsonSettingsDictionary.GetConnectTimeout(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveGeolocationService(settingsJSON),
|
||||
JsonSettingsDictionary.GetCenterMapToCurrentLocation(settingsJSON),
|
||||
Xamarin.Forms.GoogleMaps.MapSpan.FromCenterAndRadius(new Xamarin.Forms.GoogleMaps.Position(49.30881083492271, 11.358449625922889), Xamarin.Forms.GoogleMaps.Distance.FromKilometers(2.9)),
|
||||
JsonSettingsDictionary.GetLogToExternalFolder(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsSiteCachingOn(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveTheme(settingsJSON) ?? typeof(Themes.LastenradBayern).Name);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("Deserializing application settings from dictionary failed.", exception);
|
||||
settings = new Model.Settings.Settings();
|
||||
}
|
||||
Model.Settings.Settings settings;
|
||||
try
|
||||
{
|
||||
settings = new Model.Settings.Settings(
|
||||
null, // Turn off filtering for LastenradBayern- context
|
||||
null, // Turn off filtering for LastenradBayern- context
|
||||
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
|
||||
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
|
||||
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsReportLevelVerbose(settingsJSON),
|
||||
JsonSettingsDictionary.GetExpiresAfter(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveLockService(settingsJSON),
|
||||
JsonSettingsDictionary.GetConnectTimeout(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveGeolocationService(settingsJSON),
|
||||
JsonSettingsDictionary.GetCenterMapToCurrentLocation(settingsJSON),
|
||||
Xamarin.Forms.GoogleMaps.MapSpan.FromCenterAndRadius(new Xamarin.Forms.GoogleMaps.Position(49.30881083492271, 11.358449625922889), Xamarin.Forms.GoogleMaps.Distance.FromKilometers(2.9)),
|
||||
JsonSettingsDictionary.GetLogToExternalFolder(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsSiteCachingOn(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveTheme(settingsJSON) ?? typeof(Themes.LastenradBayern).Name);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("Deserializing application settings from dictionary failed.", exception);
|
||||
settings = new Model.Settings.Settings();
|
||||
}
|
||||
|
||||
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|
||||
|| settings.LogToExternalFolder)
|
||||
{
|
||||
// Eigher
|
||||
// - logging is not set to default value or
|
||||
// - logging is performed to external folder.
|
||||
// Need to reconfigure.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|
||||
|| settings.LogToExternalFolder)
|
||||
{
|
||||
// Eigher
|
||||
// - logging is not set to default value or
|
||||
// - logging is performed to external folder.
|
||||
// Need to reconfigure.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(settings.MinimumLogEventLevel),
|
||||
!settings.LogToExternalFolder
|
||||
? internalPersonalDir
|
||||
: specialFolders.GetExternalFilesDir());
|
||||
}
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(settings.MinimumLogEventLevel),
|
||||
!settings.LogToExternalFolder
|
||||
? internalPersonalDir
|
||||
: specialFolders.GetExternalFilesDir());
|
||||
}
|
||||
|
||||
// Get auth cookie
|
||||
Log.Debug("Get auth cookie.");
|
||||
IStore store = null;
|
||||
// Get auth cookie
|
||||
Log.Debug("Get auth cookie.");
|
||||
IStore store = null;
|
||||
|
||||
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
|
||||
if (new Version(3, 0, 290) <= lastVersion)
|
||||
{
|
||||
// App versions newer than 3.0.173 stored geolocation service in configuration.
|
||||
// Version 3.0.290: Geolocation service "GeolocationService" is no more supported.
|
||||
// For this reasons a swich of geolocation service is forced when loading configurations from ealier versions.
|
||||
LocationServicesContainer.SetActive(settings.ActiveGeolocationService);
|
||||
}
|
||||
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
|
||||
if (new Version(3, 0, 290) <= lastVersion)
|
||||
{
|
||||
// App versions newer than 3.0.173 stored geolocation service in configuration.
|
||||
// Version 3.0.290: Geolocation service "GeolocationService" is no more supported.
|
||||
// For this reasons a swich of geolocation service is forced when loading configurations from ealier versions.
|
||||
LocationServicesContainer.SetActive(settings.ActiveGeolocationService);
|
||||
}
|
||||
|
||||
store = new Store();
|
||||
store = new Store();
|
||||
|
||||
Barrel.ApplicationId = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
|
||||
Barrel.ApplicationId = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
|
||||
|
||||
var context = SynchronizationContext.Current;
|
||||
var context = SynchronizationContext.Current;
|
||||
|
||||
var appInfoService = DependencyService.Get<IAppInfo>();
|
||||
var appInfoService = DependencyService.Get<IAppInfo>();
|
||||
|
||||
const string MERCHANTID = "0000000000";
|
||||
const string MERCHANTID = "0000000000";
|
||||
|
||||
// Create new app instnace.
|
||||
Log.Debug("Constructing main model...");
|
||||
m_oModelRoot = new TinkApp(
|
||||
settings,
|
||||
store, // Manages user account
|
||||
isConnectedFunc: () => CrossConnectivity.Current.IsConnected,
|
||||
connectorFactory: (isConnected, activeUri, sessionCookie, mail, expiresAfter) => ConnectorFactory.Create(
|
||||
isConnected,
|
||||
activeUri,
|
||||
new Repository.AppContextInfo(MERCHANTID, AppFlavor.LastenradBayern.GetDisplayName().Replace(" ", ""), appInfoService.Version),
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
sessionCookie,
|
||||
mail,
|
||||
expiresAfter),
|
||||
merchantId: MERCHANTID,
|
||||
bluetoothService: BluetoothService, /* locksService */
|
||||
locationPermissionsService: PermissionsService,
|
||||
locationServicesContainer: LocationServicesContainer,
|
||||
locksService: null,
|
||||
device: DependencyService.Get<ISmartDevice>(),
|
||||
specialFolder: specialFolders,
|
||||
cipher: new Cipher(),
|
||||
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),
|
||||
arendiCentral:
|
||||
// Create new app instnace.
|
||||
Log.Debug("Constructing main model...");
|
||||
m_oModelRoot = new TinkApp(
|
||||
settings,
|
||||
store, // Manages user account
|
||||
isConnectedFunc: () => CrossConnectivity.Current.IsConnected,
|
||||
connectorFactory: (isConnected, activeUri, sessionCookie, mail, expiresAfter) => ConnectorFactory.Create(
|
||||
isConnected,
|
||||
activeUri,
|
||||
new Repository.AppContextInfo(MERCHANTID, AppFlavor.LastenradBayern.GetDisplayName().Replace(" ", ""), appInfoService.Version),
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
sessionCookie,
|
||||
mail,
|
||||
expiresAfter),
|
||||
merchantId: MERCHANTID,
|
||||
bluetoothService: BluetoothService, /* locksService */
|
||||
locationPermissionsService: PermissionsService,
|
||||
locationServicesContainer: LocationServicesContainer,
|
||||
locksService: null,
|
||||
device: DependencyService.Get<ISmartDevice>(),
|
||||
specialFolder: specialFolders,
|
||||
cipher: new Cipher(),
|
||||
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),
|
||||
arendiCentral:
|
||||
#if ARENDI
|
||||
DependencyService.Get<ICentral>(),
|
||||
#else
|
||||
|
||||
null,
|
||||
null,
|
||||
#endif
|
||||
postAction: (d, obj) => context.Post(d, obj),
|
||||
currentVersion: appInfoService.Version,
|
||||
lastVersion: lastVersion,
|
||||
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion(),
|
||||
appFlavor: AppFlavor.LastenradBayern);
|
||||
postAction: (d, obj) => context.Post(d, obj),
|
||||
currentVersion: appInfoService.Version,
|
||||
lastVersion: lastVersion,
|
||||
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion(),
|
||||
flavor: AppFlavor.LastenradBayern);
|
||||
|
||||
Log.Debug("Main model successfully constructed.");
|
||||
return m_oModelRoot;
|
||||
}
|
||||
}
|
||||
Log.Debug("Main model successfully constructed.");
|
||||
return m_oModelRoot;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry point of application.
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
/// <summary>
|
||||
/// Entry point of application.
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
#if USEFLYOUT
|
||||
// Use flyout page.
|
||||
|
@ -197,147 +197,147 @@ namespace TINK
|
|||
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.Root.RootPage()) // Show whats new info.
|
||||
: (Page)new View.Root.RootPage(); // Just start sharee- app
|
||||
#else
|
||||
// Use shell.
|
||||
MainPage = ModelRoot.WhatsNew.IsShowRequired
|
||||
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.RootShell.AppShell()) // Show whats new info.
|
||||
: (Page)new View.RootShell.AppShell(); // Just start sharee- app
|
||||
// Use shell.
|
||||
MainPage = ModelRoot.WhatsNew.IsShowRequired
|
||||
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.RootShell.AppShell()) // Show whats new info.
|
||||
: (Page)new View.RootShell.AppShell(); // Just start sharee- app
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Concatenates all log files to a single one. </summary>
|
||||
/// <returns>Full file name of attachment.</returns>
|
||||
public static string CreateAttachment()
|
||||
{
|
||||
var sessionLogFiles = Log.Logger.GetLogFiles().ToArray();
|
||||
/// <summary> Concatenates all log files to a single one. </summary>
|
||||
/// <returns>Full file name of attachment.</returns>
|
||||
public static string CreateAttachment()
|
||||
{
|
||||
var sessionLogFiles = Log.Logger.GetLogFiles().ToArray();
|
||||
|
||||
if (sessionLogFiles.Length < 1)
|
||||
{
|
||||
// Either
|
||||
// - there is no logging file
|
||||
// - an error occurred getting list of log files.
|
||||
return string.Empty;
|
||||
}
|
||||
if (sessionLogFiles.Length < 1)
|
||||
{
|
||||
// Either
|
||||
// - there is no logging file
|
||||
// - an error occurred getting list of log files.
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var fullLogFileName = System.IO.Path.Combine(ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
var fullLogFileName = System.IO.Path.Combine(ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
|
||||
// Stop logging to avoid file access exception.
|
||||
Log.CloseAndFlush();
|
||||
// Stop logging to avoid file access exception.
|
||||
Log.CloseAndFlush();
|
||||
|
||||
System.IO.File.WriteAllLines(
|
||||
fullLogFileName,
|
||||
sessionLogFiles.SelectMany(name =>
|
||||
(new List<string> { $"{{\"SessionFileName\":\"{name}\"}}" })
|
||||
.Concat(System.IO.File.ReadLines(name).ToArray())));
|
||||
System.IO.File.WriteAllLines(
|
||||
fullLogFileName,
|
||||
sessionLogFiles.SelectMany(name =>
|
||||
(new List<string> { $"{{\"SessionFileName\":\"{name}\"}}" })
|
||||
.Concat(System.IO.File.ReadLines(name).ToArray())));
|
||||
|
||||
// Resume logging
|
||||
TinkApp.SetupLogging(
|
||||
ModelRoot.Level,
|
||||
ModelRoot.LogFileParentFolder);
|
||||
// Resume logging
|
||||
TinkApp.SetupLogging(
|
||||
ModelRoot.Level,
|
||||
ModelRoot.LogFileParentFolder);
|
||||
|
||||
return fullLogFileName;
|
||||
}
|
||||
return fullLogFileName;
|
||||
}
|
||||
|
||||
/// <summary>Deletes an attachment if there is one.</summary>
|
||||
/// <param name="folder">Folder to delete, is null folder is queried from model.</param>
|
||||
private static void DeleteAttachment(string folder = null)
|
||||
{
|
||||
var attachment = System.IO.Path.Combine(folder ?? ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
if (!System.IO.File.Exists(attachment))
|
||||
{
|
||||
// No attachment found.
|
||||
return;
|
||||
}
|
||||
/// <summary>Deletes an attachment if there is one.</summary>
|
||||
/// <param name="folder">Folder to delete, is null folder is queried from model.</param>
|
||||
private static void DeleteAttachment(string folder = null)
|
||||
{
|
||||
var attachment = System.IO.Path.Combine(folder ?? ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
if (!System.IO.File.Exists(attachment))
|
||||
{
|
||||
// No attachment found.
|
||||
return;
|
||||
}
|
||||
|
||||
System.IO.File.Delete(attachment);
|
||||
}
|
||||
System.IO.File.Delete(attachment);
|
||||
}
|
||||
|
||||
protected override void OnSleep()
|
||||
{
|
||||
// Handle when your app sleeps
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
protected override void OnSleep()
|
||||
{
|
||||
// Handle when your app sleeps
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
DeleteAttachment();
|
||||
protected override void OnResume()
|
||||
{
|
||||
DeleteAttachment();
|
||||
|
||||
TinkApp.SetupLogging(
|
||||
ModelRoot.Level,
|
||||
ModelRoot.LogFileParentFolder);
|
||||
}
|
||||
TinkApp.SetupLogging(
|
||||
ModelRoot.Level,
|
||||
ModelRoot.LogFileParentFolder);
|
||||
}
|
||||
|
||||
/// <param name="uri">The URI for the request.</param>
|
||||
/// <summary>Overriden to respond when the user initiates an app link request.</summary>
|
||||
protected override void OnAppLinkRequestReceived(Uri uri)
|
||||
{
|
||||
base.OnAppLinkRequestReceived(uri);
|
||||
if (uri.Host.ToLower() == "sharee.bike")
|
||||
{
|
||||
// Input e.g. sharee.bike/sharee?lat=49.921&long=32.51
|
||||
Array segments = Array.ConvertAll(uri.Segments, segment => segment.Replace("/", "")).Skip(1).ToArray();
|
||||
if (uri.Query.Length > 0)
|
||||
{
|
||||
Dictionary<string, string> queryDict = uri.Query
|
||||
.Substring(1)
|
||||
.Split("&")
|
||||
.Select(query => query.Split('='))
|
||||
.ToDictionary(query => query.FirstOrDefault(), query => query.Skip(1).FirstOrDefault());
|
||||
}
|
||||
// segments == ["sharee"]
|
||||
// queryDict == [{["lat", "49.921"]}], {["long", "32.51"]}]
|
||||
// => Navigate and pass params depending on linkinput
|
||||
// If no custom navigation is configured, the app just opens as if the user opened it
|
||||
}
|
||||
}
|
||||
/// <param name="uri">The URI for the request.</param>
|
||||
/// <summary>Overriden to respond when the user initiates an app link request.</summary>
|
||||
protected override void OnAppLinkRequestReceived(Uri uri)
|
||||
{
|
||||
base.OnAppLinkRequestReceived(uri);
|
||||
if (uri.Host.ToLower() == "sharee.bike")
|
||||
{
|
||||
// Input e.g. sharee.bike/sharee?lat=49.921&long=32.51
|
||||
Array segments = Array.ConvertAll(uri.Segments, segment => segment.Replace("/", "")).Skip(1).ToArray();
|
||||
if (uri.Query.Length > 0)
|
||||
{
|
||||
Dictionary<string, string> queryDict = uri.Query
|
||||
.Substring(1)
|
||||
.Split("&")
|
||||
.Select(query => query.Split('='))
|
||||
.ToDictionary(query => query.FirstOrDefault(), query => query.Skip(1).FirstOrDefault());
|
||||
}
|
||||
// segments == ["sharee"]
|
||||
// queryDict == [{["lat", "49.921"]}], {["long", "32.51"]}]
|
||||
// => Navigate and pass params depending on linkinput
|
||||
// If no custom navigation is configured, the app just opens as if the user opened it
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets the current logging level.</summary>
|
||||
/// <returns></returns>
|
||||
private static LogEventLevel GetCurrentLogEventLevel()
|
||||
{
|
||||
foreach (LogEventLevel level in Enum.GetValues(typeof(LogEventLevel)))
|
||||
{
|
||||
if (Log.IsEnabled(level))
|
||||
return level;
|
||||
}
|
||||
/// <summary> Gets the current logging level.</summary>
|
||||
/// <returns></returns>
|
||||
private static LogEventLevel GetCurrentLogEventLevel()
|
||||
{
|
||||
foreach (LogEventLevel level in Enum.GetValues(typeof(LogEventLevel)))
|
||||
{
|
||||
if (Log.IsEnabled(level))
|
||||
return level;
|
||||
}
|
||||
|
||||
return LogEventLevel.Error;
|
||||
}
|
||||
return LogEventLevel.Error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the permission service instance.
|
||||
/// </summary>
|
||||
private static ILocationPermission _PermissionsService = null;
|
||||
/// <summary>
|
||||
/// Holds the permission service instance.
|
||||
/// </summary>
|
||||
private static ILocationPermission _PermissionsService = null;
|
||||
|
||||
/// <summary>
|
||||
/// Service to manage permissions (location) of the app.
|
||||
/// </summary>
|
||||
public static ILocationPermission PermissionsService
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_PermissionsService != null)
|
||||
return _PermissionsService;
|
||||
/// <summary>
|
||||
/// Service to manage permissions (location) of the app.
|
||||
/// </summary>
|
||||
public static ILocationPermission PermissionsService
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_PermissionsService != null)
|
||||
return _PermissionsService;
|
||||
|
||||
_PermissionsService = new TINK.Services.Permissions.Essentials.Permissions();
|
||||
return _PermissionsService;
|
||||
}
|
||||
}
|
||||
_PermissionsService = new TINK.Services.Permissions.Essentials.Permissions();
|
||||
return _PermissionsService;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Service to manage bluetooth stack.</summary>
|
||||
public static Plugin.BLE.Abstractions.Contracts.IBluetoothLE BluetoothService => Plugin.BLE.CrossBluetoothLE.Current;
|
||||
/// <summary> Service to manage bluetooth stack.</summary>
|
||||
public static Plugin.BLE.Abstractions.Contracts.IBluetoothLE BluetoothService => Plugin.BLE.CrossBluetoothLE.Current;
|
||||
|
||||
/// <summary>
|
||||
/// Service container to manage geolocation services.
|
||||
/// </summary>
|
||||
public static IServicesContainer<IGeolocation> LocationServicesContainer { get; }
|
||||
= new ServicesContainerMutableT<IGeolocation>(
|
||||
new HashSet<IGeolocation> {
|
||||
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationAccuracyMediumService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationAccuracyHighService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationAccuracyBestService(DependencyService.Get<IGeolodationDependent>())},
|
||||
Model.Settings.Settings.DefaultLocationService.FullName);
|
||||
}
|
||||
/// <summary>
|
||||
/// Service container to manage geolocation services.
|
||||
/// </summary>
|
||||
public static IServicesContainer<IGeolocation> LocationServicesContainer { get; }
|
||||
= new ServicesContainerMutableT<IGeolocation>(
|
||||
new HashSet<IGeolocation> {
|
||||
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationAccuracyMediumService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationAccuracyHighService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationAccuracyBestService(DependencyService.Get<IGeolodationDependent>())},
|
||||
Model.Settings.Settings.DefaultLocationService.FullName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,34 +5,34 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK
|
||||
{
|
||||
public static class BackdoorMethodHelpers
|
||||
{
|
||||
public static void DoTapPage(string stationId)
|
||||
{
|
||||
Serilog.Log.Information($"Request via backdoor to tap station {stationId}.");
|
||||
var currentPage = GetCurrentPage();
|
||||
var mapPageViewModel = (currentPage as MapPage)?.BindingContext as MapPageViewModel;
|
||||
if (mapPageViewModel == null)
|
||||
{
|
||||
Serilog.Log.Error($"Request via backdoor to tap station {stationId} aborted because current page is not of expected type {typeof(MapPage).Name}. Type detected is {currentPage.GetType().Name}.");
|
||||
return;
|
||||
}
|
||||
public static class BackdoorMethodHelpers
|
||||
{
|
||||
public static void DoTapPage(string stationId)
|
||||
{
|
||||
Serilog.Log.Information($"Request via backdoor to tap station {stationId}.");
|
||||
var currentPage = GetCurrentPage();
|
||||
var mapPageViewModel = (currentPage as MapPage)?.BindingContext as MapPageViewModel;
|
||||
if (mapPageViewModel == null)
|
||||
{
|
||||
Serilog.Log.Error($"Request via backdoor to tap station {stationId} aborted because current page is not of expected type {typeof(MapPage).Name}. Type detected is {currentPage.GetType().Name}.");
|
||||
return;
|
||||
}
|
||||
|
||||
Serilog.Log.Information($"Invoking member to tap.");
|
||||
mapPageViewModel?.OnStationClicked(stationId);
|
||||
}
|
||||
Serilog.Log.Information($"Invoking member to tap.");
|
||||
mapPageViewModel?.OnStationClicked(stationId);
|
||||
}
|
||||
|
||||
/// <summary> Gets the current page assumed that app is master detail page.</summary>
|
||||
/// <returns></returns>
|
||||
static Page GetCurrentPage()
|
||||
{
|
||||
/// <summary> Gets the current page assumed that app is master detail page.</summary>
|
||||
/// <returns></returns>
|
||||
static Page GetCurrentPage()
|
||||
{
|
||||
|
||||
#if USEFLYOUT
|
||||
return (Application.Current.MainPage as FlyoutPage)?.Detail.Navigation.NavigationStack.LastOrDefault();
|
||||
#else
|
||||
return Shell.Current.CurrentPage;
|
||||
return Shell.Current.CurrentPage;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,22 +3,22 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.Model.Device
|
||||
{
|
||||
public class SpecialFolder : ISpecialFolder
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the folder name of external folder to write to.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetExternalFilesDir()
|
||||
{
|
||||
return DependencyService.Get<ISpecialFolder>().GetExternalFilesDir();
|
||||
}
|
||||
public class SpecialFolder : ISpecialFolder
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the folder name of external folder to write to.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetExternalFilesDir()
|
||||
{
|
||||
return DependencyService.Get<ISpecialFolder>().GetExternalFilesDir();
|
||||
}
|
||||
|
||||
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
|
||||
/// <returns>Directory name.</returns>
|
||||
public string GetInternalPersonalDir()
|
||||
{
|
||||
return DependencyService.Get<ISpecialFolder>().GetInternalPersonalDir();
|
||||
}
|
||||
}
|
||||
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
|
||||
/// <returns>Directory name.</returns>
|
||||
public string GetInternalPersonalDir()
|
||||
{
|
||||
return DependencyService.Get<ISpecialFolder>().GetInternalPersonalDir();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,80 +12,80 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
|||
|
||||
namespace TINK.View.Account
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class AccountPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class AccountPage : ContentPage, IViewService
|
||||
public partial class AccountPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
AccountPageViewModel m_oViewModel = null;
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
AccountPageViewModel m_oViewModel = null;
|
||||
|
||||
/// <summary> Constructs a account page. </summary>
|
||||
public AccountPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
/// <summary> Constructs a account page. </summary>
|
||||
public AccountPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
var l_oModel = App.ModelRoot;
|
||||
|
||||
m_oViewModel = new AccountPageViewModel(
|
||||
l_oModel,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
this);
|
||||
m_oViewModel = new AccountPageViewModel(
|
||||
l_oModel,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
this);
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
}
|
||||
BindingContext = m_oViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message. </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
/// <summary> Displays alert message. </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -95,19 +95,19 @@ namespace TINK.View.Account
|
|||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
#if USEFLYOUT
|
||||
|
||||
|
@ -123,34 +123,34 @@ namespace TINK.View.Account
|
|||
}
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
=> await m_oViewModel.OnAppearing();
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
await m_oViewModel.OnDisappearing();
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
=> await m_oViewModel.OnAppearing();
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
await m_oViewModel.OnDisappearing();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,12 +9,12 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Bike
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class BCBike : ViewCell
|
||||
{
|
||||
public BCBike()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class BCBike : ViewCell
|
||||
{
|
||||
public BCBike()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,24 +2,24 @@
|
|||
|
||||
namespace TINK.View.Bike
|
||||
{
|
||||
/// <summary>
|
||||
/// Selects different templates for different bike types (BordComputer bikes, iLockIt bikes).
|
||||
/// </summary>
|
||||
public class BikeViewCellTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
DataTemplate bCBike;
|
||||
DataTemplate iLockIBike;
|
||||
/// <summary>
|
||||
/// Selects different templates for different bike types (BordComputer bikes, iLockIt bikes).
|
||||
/// </summary>
|
||||
public class BikeViewCellTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
DataTemplate bCBike;
|
||||
DataTemplate iLockIBike;
|
||||
|
||||
public BikeViewCellTemplateSelector()
|
||||
{
|
||||
bCBike = new DataTemplate(typeof(BCBike));
|
||||
iLockIBike = new DataTemplate(typeof(ILockItBike));
|
||||
}
|
||||
public BikeViewCellTemplateSelector()
|
||||
{
|
||||
bCBike = new DataTemplate(typeof(BCBike));
|
||||
iLockIBike = new DataTemplate(typeof(ILockItBike));
|
||||
}
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
=> item is TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel ||
|
||||
item is TINK.ViewModel.Bikes.Bike.CopriLock.BikeViewModel
|
||||
? iLockIBike
|
||||
: bCBike;
|
||||
}
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
=> item is TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel ||
|
||||
item is TINK.ViewModel.Bikes.Bike.CopriLock.BikeViewModel
|
||||
? iLockIBike
|
||||
: bCBike;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,36 +9,36 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Bike
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ILockItBike : ViewCell
|
||||
{
|
||||
public ILockItBike()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ILockItBike : ViewCell
|
||||
{
|
||||
public ILockItBike()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
base.OnBindingContextChanged();
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
base.OnBindingContextChanged();
|
||||
|
||||
if (Device.RuntimePlatform != Device.iOS)
|
||||
// Update of size is only required for iOS.
|
||||
return;
|
||||
if (Device.RuntimePlatform != Device.iOS)
|
||||
// Update of size is only required for iOS.
|
||||
return;
|
||||
|
||||
var viewModel = BindingContext as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
if (viewModel == null)
|
||||
return;
|
||||
var viewModel = BindingContext as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
if (viewModel == null)
|
||||
return;
|
||||
|
||||
viewModel.PropertyChanged += (sender, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BC.RequestHandler.Base<IBikeInfoMutable>.IsButtonVisible)
|
||||
|| e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler.Base.IsLockitButtonVisible))
|
||||
{
|
||||
// Force update of view cell on iOS.
|
||||
// https://hausource.visualstudio.com/TINK/_workitems/edit/132
|
||||
ForceUpdateSize();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
viewModel.PropertyChanged += (sender, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BC.RequestHandler.Base<IBikeInfoMutable>.IsButtonVisible)
|
||||
|| e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler.Base.IsLockitButtonVisible))
|
||||
{
|
||||
// Force update of view cell on iOS.
|
||||
// https://hausource.visualstudio.com/TINK/_workitems/edit/132
|
||||
ForceUpdateSize();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,38 +5,38 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.BikesAtStation
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using TINK.Model;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using Plugin.BLE;
|
||||
using TINK.ViewModel.BikesAtStation;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.ViewModel;
|
||||
using TINK.Model;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using Plugin.BLE;
|
||||
using TINK.ViewModel.BikesAtStation;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
{
|
||||
|
||||
private BikesAtStationPageViewModel m_oViewModel;
|
||||
private BikesAtStationPageViewModel m_oViewModel;
|
||||
|
||||
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
|
||||
private bool isInitializationStarted = false;
|
||||
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
|
||||
private bool isInitializationStarted = false;
|
||||
#if TRYNOTBACKSTYLE
|
||||
public BikesAtStationPage()
|
||||
{
|
||||
|
@ -55,140 +55,140 @@ namespace TINK.View.BikesAtStation
|
|||
}
|
||||
|
||||
#else
|
||||
public BikesAtStationPage()
|
||||
{
|
||||
}
|
||||
public BikesAtStationPage()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Don't repeat the initialization if it has been completed already.
|
||||
if (isInitializationStarted) return;
|
||||
isInitializationStarted = true;
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Don't repeat the initialization if it has been completed already.
|
||||
if (isInitializationStarted) return;
|
||||
isInitializationStarted = true;
|
||||
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
#if BACKSTYLE
|
||||
// Hide master- detail menu to force user to navigate using back button.
|
||||
m_oNavigation.IsGestureEnabled = false;
|
||||
#endif
|
||||
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
m_oViewModel = new BikesAtStationPageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
model.SelectedStation,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.LocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<BikesAtStationPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
m_oViewModel = new BikesAtStationPageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
model.SelectedStation,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.LocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<BikesAtStationPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
InitializeComponent();
|
||||
|
||||
#if BACKSTYLE
|
||||
// Hide master- detail menu to force user to navigate using back button.
|
||||
m_oNavigation.IsGestureEnabled = false;
|
||||
#endif
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
BikesAtStationListView.ItemsSource = m_oViewModel;
|
||||
BindingContext = m_oViewModel;
|
||||
BikesAtStationListView.ItemsSource = m_oViewModel;
|
||||
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
}
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await m_oViewModel?.OnDisappearing();
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await m_oViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
#if BACKSTYLE
|
||||
if (m_oNavigation!= null)
|
||||
m_oNavigation.IsGestureEnabled = true; // Enables master- detail menu navigation again when page is unloaded.
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
|
||||
#if USEFLYOUT
|
||||
|
@ -198,27 +198,27 @@ namespace TINK.View.BikesAtStation
|
|||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -239,10 +239,10 @@ namespace TINK.View.BikesAtStation
|
|||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,16 +4,16 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.View
|
||||
{
|
||||
/// <summary> Inverts a bool.</summary>
|
||||
public class BoolInverterConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Inverts a bool.</summary>
|
||||
/// <param name="value">Bool to invert.</param>
|
||||
/// <returns>Inverted bool.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> value is bool flag && !flag;
|
||||
/// <summary> Inverts a bool.</summary>
|
||||
public class BoolInverterConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Inverts a bool.</summary>
|
||||
/// <param name="value">Bool to invert.</param>
|
||||
/// <returns>Inverted bool.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> value is bool flag && !flag;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> value is bool flag && !flag;
|
||||
}
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> value is bool flag && !flag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||
Text="{Binding MailAddressText}"
|
||||
IsEnabled="{Binding IsSendMailAvailable}"
|
||||
Command="{Binding OnMailRequest}"/>
|
||||
Command="{Binding OnMailToOperatorRequest}"/>
|
||||
<!--- Phone -->
|
||||
<Label
|
||||
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||
|
|
|
@ -10,116 +10,117 @@ using TINK.ViewModel.Info;
|
|||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using TINK.Model;
|
||||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class ContactPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class ContactPage : ContentPage, IViewService
|
||||
public partial class ContactPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> View model to notify view model if page appears. </summary>
|
||||
private ContactPageViewModel ViewModel { get; set; }
|
||||
{
|
||||
/// <summary> View model to notify view model if page appears. </summary>
|
||||
private ContactPageViewModel ViewModel { get; set; }
|
||||
|
||||
public ContactPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
public ContactPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ViewModel = new ContactPageViewModel(App.ModelRoot.Uris.ActiveUri,
|
||||
AppInfo.Name,
|
||||
() => App.CreateAttachment(),
|
||||
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
|
||||
this);
|
||||
ViewModel = new ContactPageViewModel(
|
||||
App.ModelRoot.Flavor.GetDisplayName(),
|
||||
() => App.CreateAttachment(),
|
||||
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
|
||||
this);
|
||||
|
||||
ContactPageView.BindingContext = ViewModel;
|
||||
}
|
||||
ContactPageView.BindingContext = ViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Invoked when page is shown. </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.ForContext<ContentPage>().Verbose("OnAppearing...");
|
||||
/// <summary> Invoked when page is shown. </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.ForContext<ContentPage>().Verbose("OnAppearing...");
|
||||
|
||||
await ViewModel.OnAppearing(App.ModelRoot.SelectedStation);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ContentPage>().Error("Invoking OnAppearing on view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
await ViewModel.OnAppearing(App.ModelRoot.SelectedStation);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ContentPage>().Error("Invoking OnAppearing on view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
#if USEFLYOUT
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
|
||||
#else
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
#endif
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
page.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
#if USEFLYOUT
|
||||
|
@ -129,5 +130,5 @@ namespace TINK.View.Contact
|
|||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail { set; private get; }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,67 +8,67 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
using Serilog;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.ViewModel.Contact;
|
||||
using Serilog;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.ViewModel.Contact;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class SelectStationPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class SelectStationPage : ContentPage, IViewService
|
||||
public partial class SelectStationPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
|
||||
|
||||
public SelectStationPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
public SelectStationPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -78,45 +78,45 @@ namespace TINK.View.Contact
|
|||
public void ShowPage(ViewTypes type, string title = null)
|
||||
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Type of page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Type of page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
#if USEFLYOUT
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
|
||||
#else
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
#endif
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
page.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
#if USEFLYOUT
|
||||
|
@ -124,86 +124,86 @@ namespace TINK.View.Contact
|
|||
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
try
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
try
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
|
||||
|
||||
#if TRYNOTBACKSTYLE
|
||||
SelectStationPageViewModel = new SelectStationPageViewModel();
|
||||
#else
|
||||
SelectStationPageViewModel = new SelectStationPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.LocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
SelectStationPageViewModel = new SelectStationPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.LocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Constructing select station view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Constructing select station view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BindingContext = SelectStationPageViewModel;
|
||||
try
|
||||
{
|
||||
BindingContext = SelectStationPageViewModel;
|
||||
|
||||
#if USEFLYOUT
|
||||
SelectStationPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Setting binding/ navigaton on select station failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Setting binding/ navigaton on select station failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Moving and scaling map.");
|
||||
SelectStationPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.Uris.ActiveUri);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Moving and scaling map.");
|
||||
SelectStationPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.Uris.ActiveUri);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Invoking OnAppearing on select station view model.");
|
||||
await SelectStationPageViewModel.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing on select station view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Invoking OnAppearing on select station view model.");
|
||||
await SelectStationPageViewModel.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing on select station view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,53 +7,53 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.CopriWebView
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ManageAccountPage : ContentPage
|
||||
{
|
||||
public ManageAccountPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ManageAccountPage : ContentPage
|
||||
{
|
||||
public ManageAccountPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ManageAccount.Navigating += (sender, ev) =>
|
||||
{
|
||||
if (!ev.Url.ToUpper().EndsWith(".PDF"))
|
||||
{
|
||||
// Stay inside web view except for downloading pdf- files.
|
||||
this.IsEnabled = false;
|
||||
ActivityIndicatorLoading.IsVisible = true;
|
||||
ActivityIndicatorLoading.IsRunning = true;
|
||||
return;
|
||||
}
|
||||
ManageAccount.Navigating += (sender, ev) =>
|
||||
{
|
||||
if (!ev.Url.ToUpper().EndsWith(".PDF"))
|
||||
{
|
||||
// Stay inside web view except for downloading pdf- files.
|
||||
this.IsEnabled = false;
|
||||
ActivityIndicatorLoading.IsVisible = true;
|
||||
ActivityIndicatorLoading.IsRunning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
DependencyService.Get<IExternalBrowserService>().OpenUrl(ev.Url);
|
||||
};
|
||||
DependencyService.Get<IExternalBrowserService>().OpenUrl(ev.Url);
|
||||
};
|
||||
|
||||
ManageAccount.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success)
|
||||
{
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
return;
|
||||
}
|
||||
ManageAccount.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success)
|
||||
{
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Log.ForContext<ManageAccountPage>().Error("Navigation did not succeed.{@Event}{@Sender}", ev, sender);
|
||||
ManageAccount.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann persönliche Daten nicht anzeigen/ verwalten!</b><br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
Log.ForContext<ManageAccountPage>().Error("Navigation did not succeed.{@Event}{@Sender}", ev, sender);
|
||||
ManageAccount.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann persönliche Daten nicht anzeigen/ verwalten!</b><br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
};
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
};
|
||||
|
||||
ManageAccount.BindingContext = new ManageAccountViewModel(
|
||||
App.ModelRoot.ActiveUser.SessionCookie,
|
||||
Model.TinkApp.MerchantId,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
}
|
||||
}
|
||||
ManageAccount.BindingContext = new ManageAccountViewModel(
|
||||
App.ModelRoot.ActiveUser.SessionCookie,
|
||||
Model.TinkApp.MerchantId,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,45 +7,45 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.CopriWebView
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class PasswordForgottenPage : ContentPage
|
||||
{
|
||||
public PasswordForgottenPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class PasswordForgottenPage : ContentPage
|
||||
{
|
||||
public PasswordForgottenPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
PasswordForgottenWebView.Navigating += (sender, ev) =>
|
||||
{
|
||||
this.IsEnabled = false;
|
||||
ActivityIndicatorLoading.IsVisible = true;
|
||||
ActivityIndicatorLoading.IsRunning = true;
|
||||
};
|
||||
PasswordForgottenWebView.Navigating += (sender, ev) =>
|
||||
{
|
||||
this.IsEnabled = false;
|
||||
ActivityIndicatorLoading.IsVisible = true;
|
||||
ActivityIndicatorLoading.IsRunning = true;
|
||||
};
|
||||
|
||||
PasswordForgottenWebView.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success)
|
||||
{
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
return;
|
||||
}
|
||||
PasswordForgottenWebView.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success)
|
||||
{
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Log.ForContext<PasswordForgottenPage>().Error("Navigation did not succeed. {@Event}", ev);
|
||||
PasswordForgottenWebView.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann Passwort vergessen Seite nicht anzeigen!</b><br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
Log.ForContext<PasswordForgottenPage>().Error("Navigation did not succeed. {@Event}", ev);
|
||||
PasswordForgottenWebView.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann Passwort vergessen Seite nicht anzeigen!</b><br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
};
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
};
|
||||
|
||||
PasswordForgottenWebView.BindingContext = new PasswordForgottonViewModel(
|
||||
Model.TinkApp.MerchantId,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
}
|
||||
}
|
||||
PasswordForgottenWebView.BindingContext = new PasswordForgottonViewModel(
|
||||
Model.TinkApp.MerchantId,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,48 +8,48 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.CopriWebView
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RegisterPage : ContentPage
|
||||
{
|
||||
public RegisterPage()
|
||||
{
|
||||
DependencyService.Get<IWebView>().ClearCookies();
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RegisterPage : ContentPage
|
||||
{
|
||||
public RegisterPage()
|
||||
{
|
||||
DependencyService.Get<IWebView>().ClearCookies();
|
||||
|
||||
InitializeComponent();
|
||||
InitializeComponent();
|
||||
|
||||
RegisterView.Navigating += (sender, ev) =>
|
||||
{
|
||||
this.IsEnabled = false;
|
||||
ActivityIndicatorLoading.IsVisible = true;
|
||||
ActivityIndicatorLoading.IsRunning = true;
|
||||
};
|
||||
RegisterView.Navigating += (sender, ev) =>
|
||||
{
|
||||
this.IsEnabled = false;
|
||||
ActivityIndicatorLoading.IsVisible = true;
|
||||
ActivityIndicatorLoading.IsRunning = true;
|
||||
};
|
||||
|
||||
RegisterView.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success)
|
||||
{
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
return;
|
||||
}
|
||||
RegisterView.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success)
|
||||
{
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Log.ForContext<RegisterPage>().Error("Navigation did not succeed. {@Event}", ev);
|
||||
RegisterView.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann Anmeldeseite nicht anzeigen</b>!<br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
Log.ForContext<RegisterPage>().Error("Navigation did not succeed. {@Event}", ev);
|
||||
RegisterView.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann Anmeldeseite nicht anzeigen</b>!<br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
};
|
||||
this.IsEnabled = true;
|
||||
ActivityIndicatorLoading.IsVisible = false;
|
||||
ActivityIndicatorLoading.IsRunning = false;
|
||||
};
|
||||
|
||||
RegisterView.BindingContext = new RegisterPageViewModel(
|
||||
Model.TinkApp.MerchantId,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
RegisterView.BindingContext = new RegisterPageViewModel(
|
||||
Model.TinkApp.MerchantId,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,105 +10,75 @@
|
|||
<xct:Popup.Resources>
|
||||
<x:String x:Key="check_circle"></x:String>
|
||||
</xct:Popup.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<!-- Head and title row -->
|
||||
<RowDefinition Height="auto"/>
|
||||
<!--- Co2saving-->
|
||||
<RowDefinition Height="auto"/>
|
||||
<!--- checkbox and input elements-->
|
||||
<RowDefinition Height="*"/>
|
||||
<!--- ok button-->
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Head and title - Grid.Row 0 -->
|
||||
<Grid Grid.Row="0"
|
||||
<StackLayout>
|
||||
|
||||
<!-- Head and title -->
|
||||
<StackLayout
|
||||
Padding="30"
|
||||
BackgroundColor="{DynamicResource primary-back-title-color}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label Grid.Row="0"
|
||||
<Label
|
||||
HorizontalTextAlignment="Center"
|
||||
FontSize="Large"
|
||||
TextColor="White"
|
||||
Text="{x:Static resources:AppResources.MarkingReturnBikeMainMessage}"/>
|
||||
<Image Grid.Row="1">
|
||||
<Image>
|
||||
<Image.Source>
|
||||
<FontImageSource Size="Title" Glyph="{StaticResource check_circle}" FontFamily="FA-S"/>
|
||||
<FontImageSource Size="60" Glyph="{StaticResource check_circle}" FontFamily="FA-S" Color="White"/>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
</Grid>
|
||||
|
||||
<!-- Co2saving - Grid.Row 1 -->
|
||||
</StackLayout>
|
||||
|
||||
<!-- Co2saving -->
|
||||
<Frame
|
||||
x:Name="Co2SavingFrame"
|
||||
Grid.Row="1">
|
||||
x:Name="Co2SavingFrame">
|
||||
<Label
|
||||
x:Name="Co2SavingLabel"
|
||||
Text=""/>
|
||||
</Frame>
|
||||
|
||||
<!-- Checkbox and input elements - Grid.Row 2-->
|
||||
<ScrollView Grid.Row="2">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<!--- Battery charge level -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!--- Bike is ok GUI -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!--- Feedback edit GUI -->
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Checkbox and input elements -->
|
||||
<ScrollView>
|
||||
<StackLayout>
|
||||
<!-- Battery level -->
|
||||
<sharedGui:BarLevelInputView Grid.Row="0"
|
||||
<sharedGui:BarLevelInputView
|
||||
x:Name="BarLevelInputView"
|
||||
HorizontalOptions="Center"
|
||||
IsVisible="False"/>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Checkbox Is Broken -->
|
||||
<CheckBox x:Name="brockenCheckBox" IsChecked="True" Grid.Column="0"/>
|
||||
<Label
|
||||
Grid.Column="1"
|
||||
<!-- Checkbox Is Broken -->
|
||||
<StackLayout Orientation="Horizontal">
|
||||
<CheckBox x:Name="brockenCheckBox" IsChecked="True" HeightRequest="20"/>
|
||||
<Label
|
||||
FontSize="Medium"
|
||||
Text= "{x:Static resources:AppResources.MarkingReturnBikeBikeStateIsOK}"/>
|
||||
</Grid>
|
||||
<Editor
|
||||
Grid.Row="2"
|
||||
</StackLayout>
|
||||
<Editor
|
||||
x:Name="feedbackMessage"
|
||||
AutoSize="TextChanges"
|
||||
Placeholder="{x:Static resources:AppResources.MarkingReturnBikeFeedbackInputPlaceholder}"
|
||||
Text="">
|
||||
<Editor.Triggers>
|
||||
<DataTrigger TargetType="Editor"
|
||||
<Editor.Triggers>
|
||||
<DataTrigger TargetType="Editor"
|
||||
Binding="{Binding Source={x:Reference brockenCheckBox}, Path=IsChecked}"
|
||||
Value="true">
|
||||
<Setter Property="Placeholder"
|
||||
<Setter Property="Placeholder"
|
||||
Value="{x:Static resources:AppResources.MarkingReturnBikeFeedbackInputPlaceholder}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger TargetType="Editor"
|
||||
</DataTrigger>
|
||||
<DataTrigger TargetType="Editor"
|
||||
Binding="{Binding Source={x:Reference brockenCheckBox}, Path=IsChecked}"
|
||||
Value="false">
|
||||
<Setter Property="Placeholder"
|
||||
<Setter Property="Placeholder"
|
||||
Value="{x:Static resources:AppResources.MarkingReturnBikeErrorDescriptionInputPlaceholder}" />
|
||||
</DataTrigger>
|
||||
</Editor.Triggers>
|
||||
</Editor>
|
||||
</Grid>
|
||||
</DataTrigger>
|
||||
</Editor.Triggers>
|
||||
</Editor>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
<!-- Buttons - Grid.Row 3 -->
|
||||
|
||||
<!-- Buttons -->
|
||||
<Button
|
||||
Grid.Row="3"
|
||||
WidthRequest="100"
|
||||
Clicked="OnOkClicked"
|
||||
Text="OK"
|
||||
Margin="0,0,0,3"/>
|
||||
</Grid>
|
||||
</StackLayout>
|
||||
</xct:Popup>
|
|
@ -5,86 +5,86 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeedbackPopup : Popup<FeedbackPopup.Result>
|
||||
{
|
||||
/// <summary> Constructs user feedback popup.</summary>
|
||||
/// <param name="battery">Object holding info about battery. For some batteries charging level might need to be updated by user.</param>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
public FeedbackPopup(
|
||||
IBattery battery = null,
|
||||
string co2Saving = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
if (string.IsNullOrEmpty(co2Saving))
|
||||
Co2SavingFrame.IsVisible = false;
|
||||
else
|
||||
Co2SavingLabel.Text = co2Saving;
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeedbackPopup : Popup<FeedbackPopup.Result>
|
||||
{
|
||||
/// <summary> Constructs user feedback popup.</summary>
|
||||
/// <param name="battery">Object holding info about battery. For some batteries charging level might need to be updated by user.</param>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
public FeedbackPopup(
|
||||
IBattery battery = null,
|
||||
string co2Saving = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
if (string.IsNullOrEmpty(co2Saving))
|
||||
Co2SavingFrame.IsVisible = false;
|
||||
else
|
||||
Co2SavingLabel.Text = co2Saving;
|
||||
|
||||
if (battery == null
|
||||
|| (battery.IsBackendAccessible.HasValue && battery.IsBackendAccessible.Value))
|
||||
{
|
||||
// Either
|
||||
// - bike has no engine or
|
||||
// - backend can access battery level information
|
||||
// No need to ask user for input.
|
||||
return;
|
||||
}
|
||||
if (battery == null
|
||||
|| (battery.IsBackendAccessible.HasValue && battery.IsBackendAccessible.Value))
|
||||
{
|
||||
// Either
|
||||
// - bike has no engine or
|
||||
// - backend can access battery level information
|
||||
// No need to ask user for input.
|
||||
return;
|
||||
}
|
||||
|
||||
BarLevelInputView.IsVisible = battery?.MaxChargeBars != null;
|
||||
BarLevelInputView.Current = battery?.CurrentChargeBars?.ToString() ?? string.Empty;
|
||||
BarLevelInputView.Maximum = battery?.MaxChargeBars != null ? battery?.MaxChargeBars.ToString() : String.Empty;
|
||||
BarLevelInputView.IsVisible = battery?.MaxChargeBars != null;
|
||||
BarLevelInputView.Current = battery?.CurrentChargeBars?.ToString() ?? string.Empty;
|
||||
BarLevelInputView.Maximum = battery?.MaxChargeBars != null ? battery?.MaxChargeBars.ToString() : String.Empty;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override FeedbackPopup.Result GetLightDismissResult()
|
||||
{
|
||||
return new Result
|
||||
{
|
||||
CurrentChargeBars = int.TryParse(BarLevelInputView.Current, out int current) ? (int?)current : null,
|
||||
IsBikeBroken = brockenCheckBox.IsChecked,
|
||||
Message = feedbackMessage.Text
|
||||
};
|
||||
}
|
||||
protected override FeedbackPopup.Result GetLightDismissResult()
|
||||
{
|
||||
return new Result
|
||||
{
|
||||
CurrentChargeBars = int.TryParse(BarLevelInputView.Current, out int current) ? (int?)current : null,
|
||||
IsBikeBroken = brockenCheckBox.IsChecked,
|
||||
Message = feedbackMessage.Text
|
||||
};
|
||||
}
|
||||
|
||||
private void OnOkClicked(object sender, EventArgs eventArgs)
|
||||
{
|
||||
var result = new Result
|
||||
{
|
||||
CurrentChargeBars = int.TryParse(BarLevelInputView.Current, out int current) ? (int?)current : null,
|
||||
IsBikeBroken = brockenCheckBox.IsChecked,
|
||||
Message = feedbackMessage.Text
|
||||
};
|
||||
private void OnOkClicked(object sender, EventArgs eventArgs)
|
||||
{
|
||||
var result = new Result
|
||||
{
|
||||
CurrentChargeBars = int.TryParse(BarLevelInputView.Current, out int current) ? (int?)current : null,
|
||||
IsBikeBroken = brockenCheckBox.IsChecked,
|
||||
Message = feedbackMessage.Text
|
||||
};
|
||||
|
||||
Dismiss(result);
|
||||
}
|
||||
Dismiss(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
#if USCSHARP9
|
||||
public class Result : IViewService.IUserFeedback
|
||||
#else
|
||||
public new class Result : IUserFeedback
|
||||
public new class Result : IUserFeedback
|
||||
#endif
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the current chargeing level of the battery entered by user in bars, null if unkonwn.
|
||||
/// </summary>
|
||||
public int? CurrentChargeBars { get; set; }
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the current chargeing level of the battery entered by user in bars, null if unkonwn.
|
||||
/// </summary>
|
||||
public int? CurrentChargeBars { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
public bool IsBikeBroken { get; set; }
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
public bool IsBikeBroken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds either
|
||||
/// - general feedback
|
||||
/// - error description of broken bike
|
||||
/// or both.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Holds either
|
||||
/// - general feedback
|
||||
/// - error description of broken bike
|
||||
/// or both.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,34 +5,34 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeesAndBikesPage : TabbedPage
|
||||
{
|
||||
public FeesAndBikesPageViewModel ViewModel { get; }
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeesAndBikesPage : TabbedPage
|
||||
{
|
||||
public FeesAndBikesPageViewModel ViewModel { get; }
|
||||
|
||||
public FeesAndBikesPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
public FeesAndBikesPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ViewModel = new FeesAndBikesPageViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.ResourceUrls.FeesResourcePath,
|
||||
App.ModelRoot.ResourceUrls.BikesResourcePath,
|
||||
App.ModelRoot.IsSiteCachingOn);
|
||||
ViewModel = new FeesAndBikesPageViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.ResourceUrls.FeesResourcePath,
|
||||
App.ModelRoot.ResourceUrls.BikesResourcePath,
|
||||
App.ModelRoot.IsSiteCachingOn);
|
||||
|
||||
BindingContext = ViewModel;
|
||||
BindingContext = ViewModel;
|
||||
|
||||
/// Info about renting.
|
||||
InfoRentBikeWebView.Navigating += ViewModelHelper.OnNavigating;
|
||||
/// Info about renting.
|
||||
InfoRentBikeWebView.Navigating += ViewModelHelper.OnNavigating;
|
||||
|
||||
/// Info about types of bikes.
|
||||
InfoTypesOfBikesWebView.Navigating += ViewModelHelper.OnNavigating;
|
||||
}
|
||||
/// Info about types of bikes.
|
||||
InfoTypesOfBikesWebView.Navigating += ViewModelHelper.OnNavigating;
|
||||
}
|
||||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.OnAppearing();
|
||||
}
|
||||
}
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.OnAppearing();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,141 +12,141 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.FindBike
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FindBikePage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
FindBikePageViewModel m_oViewModel = null;
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FindBikePage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
FindBikePageViewModel m_oViewModel = null;
|
||||
|
||||
public FindBikePage() { }
|
||||
public FindBikePage() { }
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
return;
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
m_oViewModel = new FindBikePageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.LocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Stations,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<FindBikePage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Fahrrad Wählen kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
m_oViewModel = new FindBikePageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.LocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Stations,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<FindBikePage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Fahrrad Wählen kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
FindBikeListView.ItemsSource = m_oViewModel;
|
||||
BindingContext = m_oViewModel;
|
||||
FindBikeListView.ItemsSource = m_oViewModel;
|
||||
|
||||
await m_oViewModel.OnAppearing();
|
||||
}
|
||||
await m_oViewModel.OnAppearing();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => throw new NotSupportedException();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => throw new NotSupportedException();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,65 +11,65 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Info.BikeInfo
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService
|
||||
#endif
|
||||
{
|
||||
public BikeInfoCarouselPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
{
|
||||
public BikeInfoCarouselPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ItemsSource = new BikeInfoViewModel(
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
|
||||
this).CarouselItems;
|
||||
}
|
||||
ItemsSource = new BikeInfoViewModel(
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
|
||||
this).CarouselItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
{
|
||||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
{
|
||||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -79,31 +79,31 @@ namespace TINK.View.Info.BikeInfo
|
|||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -123,7 +123,7 @@ namespace TINK.View.Info.BikeInfo
|
|||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,36 +6,36 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Info
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class InfoPage : TabbedPage
|
||||
{
|
||||
public InfoPageViewModel ViewModel { get; }
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class InfoPage : TabbedPage
|
||||
{
|
||||
public InfoPageViewModel ViewModel { get; }
|
||||
|
||||
public InfoPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
public InfoPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ViewModel = new InfoPageViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.ResourceUrls.AgbResourcePath,
|
||||
App.ModelRoot.ResourceUrls.PrivacyResourcePath,
|
||||
App.ModelRoot.ResourceUrls.ImpressResourcePath,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
resourceName => ViewModelResourceHelper.GetSource(resourceName));
|
||||
TabbedInfoPage.BindingContext = ViewModel;
|
||||
ViewModel = new InfoPageViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.ResourceUrls.AgbResourcePath,
|
||||
App.ModelRoot.ResourceUrls.PrivacyResourcePath,
|
||||
App.ModelRoot.ResourceUrls.ImpressResourcePath,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
resourceName => ViewModelResourceHelper.GetSource(resourceName));
|
||||
TabbedInfoPage.BindingContext = ViewModel;
|
||||
|
||||
InfoLicenses.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoDatenschutz.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoABG.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoLicenses.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoDatenschutz.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoABG.Navigating += ViewModelHelper.OnNavigating;
|
||||
|
||||
InfoImpressum.Navigating += ViewModelHelper.OnNavigating;
|
||||
}
|
||||
InfoImpressum.Navigating += ViewModelHelper.OnNavigating;
|
||||
}
|
||||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.OnAppearing();
|
||||
}
|
||||
}
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.OnAppearing();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,33 +3,33 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.View
|
||||
{
|
||||
public static class ListViewAttachedBehavior
|
||||
{
|
||||
public static readonly BindableProperty CommandProperty =
|
||||
BindableProperty.CreateAttached(
|
||||
"Command",
|
||||
typeof(ICommand),
|
||||
typeof(ListViewAttachedBehavior),
|
||||
null,
|
||||
propertyChanged: OnCommandChanged);
|
||||
public static class ListViewAttachedBehavior
|
||||
{
|
||||
public static readonly BindableProperty CommandProperty =
|
||||
BindableProperty.CreateAttached(
|
||||
"Command",
|
||||
typeof(ICommand),
|
||||
typeof(ListViewAttachedBehavior),
|
||||
null,
|
||||
propertyChanged: OnCommandChanged);
|
||||
|
||||
static void OnCommandChanged(BindableObject view, object oldValue, object newValue)
|
||||
{
|
||||
var entry = view as ListView;
|
||||
if (entry == null)
|
||||
return;
|
||||
static void OnCommandChanged(BindableObject view, object oldValue, object newValue)
|
||||
{
|
||||
var entry = view as ListView;
|
||||
if (entry == null)
|
||||
return;
|
||||
|
||||
entry.ItemTapped += (sender, e) =>
|
||||
{
|
||||
var command = (newValue as ICommand);
|
||||
if (command == null)
|
||||
return;
|
||||
entry.ItemTapped += (sender, e) =>
|
||||
{
|
||||
var command = (newValue as ICommand);
|
||||
if (command == null)
|
||||
return;
|
||||
|
||||
if (command.CanExecute(e.Item))
|
||||
{
|
||||
command.Execute(e.Item);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
if (command.CanExecute(e.Item))
|
||||
{
|
||||
command.Execute(e.Item);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,60 +11,60 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Login
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class LoginPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class LoginPage : ContentPage, IViewService
|
||||
public partial class LoginPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
public LoginPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
{
|
||||
public LoginPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
var l_oModel = App.ModelRoot;
|
||||
#if !BACKSTYLE
|
||||
var l_oViewModel = new LoginPageViewModel(
|
||||
l_oModel,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
this);
|
||||
var l_oViewModel = new LoginPageViewModel(
|
||||
l_oModel,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
this);
|
||||
|
||||
LoginPageView.BindingContext = l_oViewModel;
|
||||
LoginPageView.BindingContext = l_oViewModel;
|
||||
#else
|
||||
LoginPageView.BindingContext = new LoginPageViewModel(l_oModel.ActiveUser, this, Navigation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -74,30 +74,30 @@ namespace TINK.View.Login
|
|||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -117,7 +117,7 @@ namespace TINK.View.Login
|
|||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,72 +8,72 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Map
|
||||
{
|
||||
using Serilog;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.ViewModel.Map;
|
||||
using Serilog;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.ViewModel.Map;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class MapPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class MapPage : ContentPage, IViewService
|
||||
public partial class MapPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private MapPageViewModel MapPageViewModel { get; set; }
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private MapPageViewModel MapPageViewModel { get; set; }
|
||||
|
||||
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
|
||||
private bool isInitializationStarted = false;
|
||||
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
|
||||
private bool isInitializationStarted = false;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs map page instance.
|
||||
/// </summary>
|
||||
public MapPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructs map page instance.
|
||||
/// </summary>
|
||||
public MapPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -83,45 +83,45 @@ namespace TINK.View.Map
|
|||
public void ShowPage(ViewTypes type, string title = null)
|
||||
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Type of page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Type of page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
#if USEFLYOUT
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
|
||||
#else
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
#endif
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
page.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
#if USEFLYOUT
|
||||
|
@ -129,153 +129,153 @@ namespace TINK.View.Map
|
|||
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Don't repeat the initialization if it has been completed already.
|
||||
if (isInitializationStarted) return;
|
||||
isInitializationStarted = true;
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Don't repeat the initialization if it has been completed already.
|
||||
if (isInitializationStarted) return;
|
||||
isInitializationStarted = true;
|
||||
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
try
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
try
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
|
||||
|
||||
#if TRYNOTBACKSTYLE
|
||||
MapPageViewModel = new MapPageViewModel();
|
||||
#else
|
||||
MapPageViewModel = CreateMapPageViewModel();
|
||||
MapPageViewModel = CreateMapPageViewModel();
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Constructing map page view model failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Constructing map page view model failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BindingContext = MapPageViewModel;
|
||||
try
|
||||
{
|
||||
BindingContext = MapPageViewModel;
|
||||
|
||||
#if USEFLYOUT
|
||||
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Setting binding/ navigaton on map page failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Setting binding/ navigaton on map page failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ApplyCustomiOSStyling();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MapPage>().Error("IOS specific styling of map page failed. {Exception}", exception);
|
||||
}
|
||||
try
|
||||
{
|
||||
ApplyCustomiOSStyling();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MapPage>().Error("IOS specific styling of map page failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MapPage>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MapPage>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
PremoveAndScaleMap();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<MapPage>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
PremoveAndScaleMap();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<MapPage>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Invoking OnAppearing on map page view model.");
|
||||
await MapPageViewModel.OnAppearing();
|
||||
try
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Invoking OnAppearing on map page view model.");
|
||||
await MapPageViewModel.OnAppearing();
|
||||
|
||||
isInitializationStarted = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
isInitializationStarted = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Premoves the Map to a certain location.
|
||||
/// </summary>
|
||||
private void PremoveAndScaleMap()
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Moving and scaling map.");
|
||||
MapPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.ActiveMapSpan);
|
||||
}
|
||||
/// <summary>
|
||||
/// Premoves the Map to a certain location.
|
||||
/// </summary>
|
||||
private void PremoveAndScaleMap()
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Moving and scaling map.");
|
||||
MapPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.ActiveMapSpan);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the Map Page's view model.
|
||||
/// </summary>
|
||||
private MapPageViewModel CreateMapPageViewModel()
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
|
||||
return new MapPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.LocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates the Map Page's view model.
|
||||
/// </summary>
|
||||
private MapPageViewModel CreateMapPageViewModel()
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
|
||||
return new MapPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.LocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies iOS specific styling to branded Buttons.
|
||||
/// </summary>
|
||||
private void ApplyCustomiOSStyling()
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
TINKButton.BackgroundColor = Color.LightGray;
|
||||
TINKButton.BorderColor = Color.Black;
|
||||
TINKButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
KonradButton.BackgroundColor = Color.LightGray;
|
||||
KonradButton.BorderColor = Color.Black;
|
||||
KonradButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Applies iOS specific styling to branded Buttons.
|
||||
/// </summary>
|
||||
private void ApplyCustomiOSStyling()
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
TINKButton.BackgroundColor = Color.LightGray;
|
||||
TINKButton.BorderColor = Color.Black;
|
||||
TINKButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
KonradButton.BackgroundColor = Color.LightGray;
|
||||
KonradButton.BorderColor = Color.Black;
|
||||
KonradButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected override async void OnDisappearing()
|
||||
{
|
||||
if (MapPageViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await MapPageViewModel?.OnDisappearing();
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected override async void OnDisappearing()
|
||||
{
|
||||
if (MapPageViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await MapPageViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
base.OnDisappearing();
|
||||
}
|
||||
}
|
||||
base.OnDisappearing();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,93 +8,93 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.MiniSurvey
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MiniSurveyPage : ContentPage, IViewService
|
||||
{
|
||||
public MiniSurveyPage()
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MiniSurveyPage : ContentPage, IViewService
|
||||
{
|
||||
public MiniSurveyPage()
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
var vm = new MiniSurveyViewModel(
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
this);
|
||||
var vm = new MiniSurveyViewModel(
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
this);
|
||||
|
||||
InitializeComponent();
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = vm;
|
||||
MiniSurveyListView.ItemsSource = vm;
|
||||
}
|
||||
BindingContext = vm;
|
||||
MiniSurveyListView.ItemsSource = vm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => Navigation.PopModalAsync();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,12 +3,12 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.MiniSurvey.Question
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class CheckOneViewCell : ViewCell
|
||||
{
|
||||
public CheckOneViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class CheckOneViewCell : ViewCell
|
||||
{
|
||||
public CheckOneViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,12 +4,12 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.MiniSurvey.Question
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FreeTextViewCell : ViewCell
|
||||
{
|
||||
public FreeTextViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FreeTextViewCell : ViewCell
|
||||
{
|
||||
public FreeTextViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,25 +2,25 @@
|
|||
|
||||
namespace TINK.View.MiniSurvey.Question
|
||||
{
|
||||
/// <summary>
|
||||
/// Selects different templates for different question types.
|
||||
/// </summary>
|
||||
public class QuestionViewCellTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
DataTemplate checkOneViewCell;
|
||||
DataTemplate freeTextViewCell;
|
||||
/// <summary>
|
||||
/// Selects different templates for different question types.
|
||||
/// </summary>
|
||||
public class QuestionViewCellTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
DataTemplate checkOneViewCell;
|
||||
DataTemplate freeTextViewCell;
|
||||
|
||||
public QuestionViewCellTemplateSelector()
|
||||
{
|
||||
checkOneViewCell = new DataTemplate(typeof(CheckOneViewCell));
|
||||
freeTextViewCell = new DataTemplate(typeof(FreeTextViewCell));
|
||||
}
|
||||
public QuestionViewCellTemplateSelector()
|
||||
{
|
||||
checkOneViewCell = new DataTemplate(typeof(CheckOneViewCell));
|
||||
freeTextViewCell = new DataTemplate(typeof(FreeTextViewCell));
|
||||
}
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
return item is ViewModel.MiniSurvey.Question.FreeTextViewModel
|
||||
? freeTextViewCell
|
||||
: checkOneViewCell;
|
||||
}
|
||||
}
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
return item is ViewModel.MiniSurvey.Question.FreeTextViewModel
|
||||
? freeTextViewCell
|
||||
: checkOneViewCell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,177 +10,177 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.MyBikes
|
||||
{
|
||||
using Serilog;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.Model.Device;
|
||||
using TINK.ViewModel.MyBikes;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
using Serilog;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
using TINK.Model.Device;
|
||||
using TINK.ViewModel.MyBikes;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MyBikesPage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
MyBikesPageViewModel m_oViewModel = null;
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MyBikesPage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
MyBikesPageViewModel m_oViewModel = null;
|
||||
|
||||
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
|
||||
private bool isInitializationStarted = false;
|
||||
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
|
||||
private bool isInitializationStarted = false;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a my bikes page.
|
||||
/// </summary>
|
||||
public MyBikesPage()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructs a my bikes page.
|
||||
/// </summary>
|
||||
public MyBikesPage()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Don't repeat the initialization if it has been completed already.
|
||||
if (isInitializationStarted) return;
|
||||
isInitializationStarted = true;
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Don't repeat the initialization if it has been completed already.
|
||||
if (isInitializationStarted) return;
|
||||
isInitializationStarted = true;
|
||||
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
m_oViewModel = new MyBikesPageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.LocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Stations,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MyBikesPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
m_oViewModel = new MyBikesPageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.LocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Stations,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MyBikesPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
isInitializationStarted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
MyBikesListView.ItemsSource = m_oViewModel;
|
||||
BindingContext = m_oViewModel;
|
||||
MyBikesListView.ItemsSource = m_oViewModel;
|
||||
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
}
|
||||
await m_oViewModel.OnAppearing();
|
||||
isInitializationStarted = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null (Example: Occured when page to querry for location permissions was opened)
|
||||
return;
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null (Example: Occured when page to querry for location permissions was opened)
|
||||
return;
|
||||
}
|
||||
|
||||
await m_oViewModel.OnDisappearing();
|
||||
}
|
||||
await m_oViewModel.OnDisappearing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => throw new NotSupportedException();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => throw new NotSupportedException();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,35 +8,35 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Root
|
||||
{
|
||||
/// <summary>
|
||||
/// Mamages creation of detail pages if a flyout page menu entry is selected.
|
||||
/// Exposes flyout page style navigation which is used by detail pages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Examples of use cases when detail pages do navigation:
|
||||
// - switch to map page after succesfully logging in/ logging out
|
||||
// - switch to login page form bikes at station page if not yet logged in
|
||||
/// </remarks>
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
/// <summary>
|
||||
/// Mamages creation of detail pages if a flyout page menu entry is selected.
|
||||
/// Exposes flyout page style navigation which is used by detail pages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Examples of use cases when detail pages do navigation:
|
||||
// - switch to map page after succesfully logging in/ logging out
|
||||
// - switch to login page form bikes at station page if not yet logged in
|
||||
/// </remarks>
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class RootPage : FlyoutPage, INavigationMasterDetail
|
||||
#else
|
||||
public partial class RootPage : FlyoutPage
|
||||
public partial class RootPage : FlyoutPage
|
||||
#endif
|
||||
{
|
||||
public RootPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
|
||||
{
|
||||
public RootPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
|
||||
|
||||
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
|
||||
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
|
||||
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
|
||||
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
|
||||
|
||||
var navigationPage = Detail as NavigationPage;
|
||||
if (navigationPage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var navigationPage = Detail as NavigationPage;
|
||||
if (navigationPage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
var detailPage = navigationPage.RootPage as IDetailPage;
|
||||
|
@ -47,38 +47,38 @@ namespace TINK.View.Root
|
|||
|
||||
detailPage.NavigationMasterDetail = this;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called if a flyout page menu entry is selected.
|
||||
/// Creates a new page.
|
||||
/// </summary>
|
||||
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
if (!(e.SelectedItem is RootPageFlyoutMenuItem item))
|
||||
{
|
||||
// Unexpected argument detected.
|
||||
return;
|
||||
}
|
||||
/// <summary>
|
||||
/// Is called if a flyout page menu entry is selected.
|
||||
/// Creates a new page.
|
||||
/// </summary>
|
||||
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
if (!(e.SelectedItem is RootPageFlyoutMenuItem item))
|
||||
{
|
||||
// Unexpected argument detected.
|
||||
return;
|
||||
}
|
||||
|
||||
// Set selected station to new
|
||||
App.ModelRoot.SelectedStation = new NullStation();
|
||||
// Set selected station to new
|
||||
App.ModelRoot.SelectedStation = new NullStation();
|
||||
|
||||
ShowPage(item.TargetType, item.Title);
|
||||
ShowPage(item.TargetType, item.Title);
|
||||
|
||||
IsPresented = false;
|
||||
FlyoutPage.ListView.SelectedItem = null;
|
||||
}
|
||||
IsPresented = false;
|
||||
FlyoutPage.ListView.SelectedItem = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a detail page.
|
||||
/// </summary>
|
||||
/// <param name="typeOfPage">Type of page to show.</param>
|
||||
/// <param name="title">Title of page.</param>
|
||||
public void ShowPage(Type typeOfPage, string title)
|
||||
{
|
||||
var page = (Page)Activator.CreateInstance(typeOfPage);
|
||||
page.Title = title;
|
||||
/// <summary>
|
||||
/// Shows a detail page.
|
||||
/// </summary>
|
||||
/// <param name="typeOfPage">Type of page to show.</param>
|
||||
/// <param name="title">Title of page.</param>
|
||||
public void ShowPage(Type typeOfPage, string title)
|
||||
{
|
||||
var page = (Page)Activator.CreateInstance(typeOfPage);
|
||||
page.Title = title;
|
||||
|
||||
#if USEFLYOUT
|
||||
if (page is IDetailPage detailPage)
|
||||
|
@ -89,7 +89,7 @@ namespace TINK.View.Root
|
|||
}
|
||||
#endif
|
||||
|
||||
Detail = new NavigationPage(page);
|
||||
}
|
||||
}
|
||||
Detail = new NavigationPage(page);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,19 +18,19 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.Root
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RootPageFlyout : ContentPage
|
||||
{
|
||||
public ListView ListView;
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RootPageFlyout : ContentPage
|
||||
{
|
||||
public ListView ListView;
|
||||
|
||||
public RootPageFlyout()
|
||||
{
|
||||
InitializeComponent();
|
||||
public RootPageFlyout()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = new RootPageFlyoutViewModel();
|
||||
BindingContext = new RootPageFlyoutViewModel();
|
||||
|
||||
ListView = MenuItemsListView;
|
||||
}
|
||||
ListView = MenuItemsListView;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,18 +3,18 @@
|
|||
namespace TINK.View.Root
|
||||
{
|
||||
|
||||
public class RootPageFlyoutMenuItem
|
||||
{
|
||||
public RootPageFlyoutMenuItem()
|
||||
{
|
||||
TargetType = typeof(RootPageFlyoutMenuItem);
|
||||
}
|
||||
public int Id { get; set; }
|
||||
public class RootPageFlyoutMenuItem
|
||||
{
|
||||
public RootPageFlyoutMenuItem()
|
||||
{
|
||||
TargetType = typeof(RootPageFlyoutMenuItem);
|
||||
}
|
||||
public int Id { get; set; }
|
||||
|
||||
public string GlyphCode { get; set; }
|
||||
public string GlyphCode { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public Type TargetType { get; set; }
|
||||
}
|
||||
public Type TargetType { get; set; }
|
||||
}
|
||||
}
|
|
@ -4,39 +4,39 @@ using TINK.ViewModel.MasterDetail;
|
|||
|
||||
namespace TINK.View
|
||||
{
|
||||
public class MainPageMenuItem
|
||||
{
|
||||
public MainPageMenuItem()
|
||||
{
|
||||
TargetType = typeof(MapPage);
|
||||
}
|
||||
public class MainPageMenuItem
|
||||
{
|
||||
public MainPageMenuItem()
|
||||
{
|
||||
TargetType = typeof(MapPage);
|
||||
}
|
||||
|
||||
public MainPageMenuItem(
|
||||
int p_iId,
|
||||
Type p_oTypeOfPage,
|
||||
string p_strTitle = null)
|
||||
{
|
||||
TargetType = p_oTypeOfPage;
|
||||
Id = p_iId;
|
||||
Title = p_strTitle ?? Helper.GetCaption(p_oTypeOfPage);
|
||||
}
|
||||
public MainPageMenuItem(
|
||||
int p_iId,
|
||||
Type p_oTypeOfPage,
|
||||
string p_strTitle = null)
|
||||
{
|
||||
TargetType = p_oTypeOfPage;
|
||||
Id = p_iId;
|
||||
Title = p_strTitle ?? Helper.GetCaption(p_oTypeOfPage);
|
||||
}
|
||||
|
||||
public int Id
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public int Id
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string Title
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Type TargetType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
public Type TargetType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,12 +4,12 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.View.RootShell
|
||||
{
|
||||
public partial class AppShell : Shell
|
||||
{
|
||||
public AppShell()
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = new AppShellViewModel();
|
||||
}
|
||||
}
|
||||
public partial class AppShell : Shell
|
||||
{
|
||||
public AppShell()
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = new AppShellViewModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.RootShell
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FlyoutHeader : ContentView
|
||||
{
|
||||
public FlyoutHeader()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FlyoutHeader : ContentView
|
||||
{
|
||||
public FlyoutHeader()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,82 +12,82 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
|||
|
||||
namespace TINK.View.Settings
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class SettingsPage : ContentPage, IViewService
|
||||
public partial class SettingsPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
SettingsPageViewModel m_oViewModel = null;
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
SettingsPageViewModel m_oViewModel = null;
|
||||
|
||||
/// <summary> Constructs a settings page. </summary>
|
||||
public SettingsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
/// <summary> Constructs a settings page. </summary>
|
||||
public SettingsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
var l_oModel = App.ModelRoot;
|
||||
|
||||
m_oViewModel = new SettingsPageViewModel(
|
||||
l_oModel,
|
||||
App.LocationServicesContainer,
|
||||
this);
|
||||
m_oViewModel = new SettingsPageViewModel(
|
||||
l_oModel,
|
||||
App.LocationServicesContainer,
|
||||
this);
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
BindingContext = m_oViewModel;
|
||||
|
||||
Filters.ItemsSource = m_oViewModel.GroupFilter;
|
||||
}
|
||||
Filters.ItemsSource = m_oViewModel.GroupFilter;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message. </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <summary> Displays alert message. </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
|
@ -97,19 +97,19 @@ namespace TINK.View.Settings
|
|||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>Delegate to perform navigation.</summary>
|
||||
|
@ -124,33 +124,33 @@ namespace TINK.View.Settings
|
|||
}
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
|
||||
await m_oViewModel?.OnDisappearing();
|
||||
}
|
||||
await m_oViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
/// <summary> Displays user feedback popup.</summary>
|
||||
/// <param name="co2Saving"> Co2 saving information.</param>
|
||||
/// <returns>User feedback.</returns>
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
|
||||
#endif
|
||||
|
||||
#if USERFEEDBACKDLG_TRYOUT
|
||||
|
@ -164,5 +164,5 @@ namespace TINK.View.Settings
|
|||
"OK");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,20 +4,20 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.View
|
||||
{
|
||||
/// <summary> Converts a string into visible state. If string is null or empty element becomes invisible.</summary>
|
||||
public class StringNotNullOrEmptyToVisibleConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Converts a string into visible state.</summary>
|
||||
/// <param name="value">Text value from view model used to derive whether object is visible or not.</param>
|
||||
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value != null && value is string text && !string.IsNullOrEmpty(text);
|
||||
}
|
||||
/// <summary> Converts a string into visible state. If string is null or empty element becomes invisible.</summary>
|
||||
public class StringNotNullOrEmptyToVisibleConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Converts a string into visible state.</summary>
|
||||
/// <param name="value">Text value from view model used to derive whether object is visible or not.</param>
|
||||
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value != null && value is string text && !string.IsNullOrEmpty(text);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,63 +15,63 @@ using Xamarin.Forms;
|
|||
|
||||
namespace TINK.View
|
||||
{
|
||||
public static class ViewTypesTypeProvider
|
||||
{
|
||||
public static Type GetViewType(this ViewTypes viewType)
|
||||
{
|
||||
switch (viewType)
|
||||
{
|
||||
case ViewTypes.LoginPage:
|
||||
return typeof(LoginPage);
|
||||
public static class ViewTypesTypeProvider
|
||||
{
|
||||
public static Type GetViewType(this ViewTypes viewType)
|
||||
{
|
||||
switch (viewType)
|
||||
{
|
||||
case ViewTypes.LoginPage:
|
||||
return typeof(LoginPage);
|
||||
|
||||
case ViewTypes.MapPage:
|
||||
return typeof(MapPage);
|
||||
case ViewTypes.MapPage:
|
||||
return typeof(MapPage);
|
||||
|
||||
case ViewTypes.RegisterPage:
|
||||
return typeof(RegisterPage);
|
||||
case ViewTypes.RegisterPage:
|
||||
return typeof(RegisterPage);
|
||||
|
||||
case ViewTypes.PasswordForgottenPage:
|
||||
return typeof(PasswordForgottenPage);
|
||||
case ViewTypes.PasswordForgottenPage:
|
||||
return typeof(PasswordForgottenPage);
|
||||
|
||||
case ViewTypes.BikeInfoCarouselPage:
|
||||
return typeof(BikeInfoCarouselPage);
|
||||
case ViewTypes.BikeInfoCarouselPage:
|
||||
return typeof(BikeInfoCarouselPage);
|
||||
|
||||
case ViewTypes.MyBikesPage:
|
||||
return typeof(MyBikesPage);
|
||||
case ViewTypes.MyBikesPage:
|
||||
return typeof(MyBikesPage);
|
||||
|
||||
case ViewTypes.SettingsPage:
|
||||
return typeof(SettingsPage);
|
||||
case ViewTypes.SettingsPage:
|
||||
return typeof(SettingsPage);
|
||||
|
||||
case ViewTypes.TabbedPageInfo:
|
||||
return typeof(InfoPage);
|
||||
case ViewTypes.TabbedPageInfo:
|
||||
return typeof(InfoPage);
|
||||
|
||||
case ViewTypes.FeesAndBikesPage:
|
||||
return typeof(FeesAndBikesPage);
|
||||
case ViewTypes.FeesAndBikesPage:
|
||||
return typeof(FeesAndBikesPage);
|
||||
|
||||
case ViewTypes.ManageAccountPage:
|
||||
return typeof(ManageAccountPage);
|
||||
case ViewTypes.ManageAccountPage:
|
||||
return typeof(ManageAccountPage);
|
||||
|
||||
case ViewTypes.AgbPage:
|
||||
return typeof(AgbPage);
|
||||
case ViewTypes.AgbPage:
|
||||
return typeof(AgbPage);
|
||||
|
||||
case ViewTypes.WhatsNewPage:
|
||||
return typeof(WhatsNewPage);
|
||||
case ViewTypes.WhatsNewPage:
|
||||
return typeof(WhatsNewPage);
|
||||
|
||||
case ViewTypes.BikesAtStation:
|
||||
return typeof(BikesAtStationPage);
|
||||
case ViewTypes.BikesAtStation:
|
||||
return typeof(BikesAtStationPage);
|
||||
|
||||
case ViewTypes.ContactPage:
|
||||
return typeof(ContactPage);
|
||||
case ViewTypes.ContactPage:
|
||||
return typeof(ContactPage);
|
||||
|
||||
case ViewTypes.SelectStationPage:
|
||||
return typeof(SelectStationPage);
|
||||
case ViewTypes.SelectStationPage:
|
||||
return typeof(SelectStationPage);
|
||||
|
||||
case ViewTypes.MiniSurvey:
|
||||
return typeof(MiniSurveyPage);
|
||||
case ViewTypes.MiniSurvey:
|
||||
return typeof(MiniSurveyPage);
|
||||
|
||||
default:
|
||||
return typeof(ContentPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return typeof(ContentPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,76 +9,76 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.WhatsNew.Agb
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class AgbPage : ContentPage, IViewService
|
||||
{
|
||||
public AgbPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class AgbPage : ContentPage, IViewService
|
||||
{
|
||||
public AgbPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
agbViewModel = new AgbViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
(resourceName) => ViewModelResourceHelper.GetSource(resourceName),
|
||||
this);
|
||||
agbViewModel = new AgbViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
|
||||
(resourceName) => ViewModelResourceHelper.GetSource(resourceName),
|
||||
this);
|
||||
|
||||
BindingContext = agbViewModel;
|
||||
}
|
||||
BindingContext = agbViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
/// <summary> Invoked when page is shown. </summary>
|
||||
protected async override void OnAppearing()
|
||||
=> await agbViewModel.OnAppearing();
|
||||
/// <summary> Invoked when page is shown. </summary>
|
||||
protected async override void OnAppearing()
|
||||
=> await agbViewModel.OnAppearing();
|
||||
|
||||
/// <summary> Reference to view model.</summary>
|
||||
AgbViewModel agbViewModel;
|
||||
/// <summary> Reference to view model.</summary>
|
||||
AgbViewModel agbViewModel;
|
||||
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,100 +7,100 @@ using Xamarin.Forms.Xaml;
|
|||
|
||||
namespace TINK.View.WhatsNew
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class WhatsNewPage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Holds a reference on the view model. </summary>
|
||||
private ViewModel.WhatsNew.WhatsNewViewModel WhatsNewViewModel;
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class WhatsNewPage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Holds a reference on the view model. </summary>
|
||||
private ViewModel.WhatsNew.WhatsNewViewModel WhatsNewViewModel;
|
||||
|
||||
/// <summary> Constructs whats new page.</summary>
|
||||
/// <param name="showMasterDetail">Action to invoke master detail page.</param>
|
||||
public WhatsNewPage(Action showMasterDetail)
|
||||
{
|
||||
InitializeComponent();
|
||||
/// <summary> Constructs whats new page.</summary>
|
||||
/// <param name="showMasterDetail">Action to invoke master detail page.</param>
|
||||
public WhatsNewPage(Action showMasterDetail)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
WhatsNewViewModel = new ViewModel.WhatsNew.WhatsNewViewModel(
|
||||
DependencyService.Get<IAppInfo>().Version,
|
||||
App.ModelRoot.WhatsNew.WhatsNewText,
|
||||
App.ModelRoot.WhatsNew.IsShowAgbRequired,
|
||||
showMasterDetail,
|
||||
this);
|
||||
WhatsNewViewModel = new ViewModel.WhatsNew.WhatsNewViewModel(
|
||||
DependencyService.Get<IAppInfo>().Version,
|
||||
App.ModelRoot.WhatsNew.WhatsNewText,
|
||||
App.ModelRoot.WhatsNew.IsShowAgbRequired,
|
||||
showMasterDetail,
|
||||
this);
|
||||
|
||||
BindingContext = WhatsNewViewModel;
|
||||
}
|
||||
BindingContext = WhatsNewViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
|
||||
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotImplementedException(); ;
|
||||
}
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotImplementedException(); ;
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
public async Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// /// </summary>
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// /// </summary>
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
|
||||
if (WhatsNewViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
if (WhatsNewViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
|
||||
WhatsNewViewModel?.OnDisappearing(() =>
|
||||
{
|
||||
App.ModelRoot.WhatsNew.WasShownInCurrentSession = true;
|
||||
App.ModelRoot.Save();
|
||||
});
|
||||
}
|
||||
}
|
||||
WhatsNewViewModel?.OnDisappearing(() =>
|
||||
{
|
||||
App.ModelRoot.WhatsNew.WasShownInCurrentSession = true;
|
||||
App.ModelRoot.Save();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,175 +24,175 @@ using TINK.View.Themes;
|
|||
|
||||
namespace TINK.ViewModel.Root
|
||||
{
|
||||
/// <summary>
|
||||
/// View model for flyout menu entries. Respositility
|
||||
/// - populates entries depending on app state on showing menu
|
||||
/// - updates menu denpending on app state change, i.e. user logs in/ out.
|
||||
/// </summary>
|
||||
public class RootPageFlyoutViewModel : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary to manage collection of menu items.
|
||||
/// </summary>
|
||||
private Dictionary<Type, int> m_oEntryDictionary;
|
||||
/// <summary>
|
||||
/// View model for flyout menu entries. Respositility
|
||||
/// - populates entries depending on app state on showing menu
|
||||
/// - updates menu denpending on app state change, i.e. user logs in/ out.
|
||||
/// </summary>
|
||||
public class RootPageFlyoutViewModel : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary to manage collection of menu items.
|
||||
/// </summary>
|
||||
private Dictionary<Type, int> m_oEntryDictionary;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary> Updates menu entries depending on state. </summary>
|
||||
private void UpdateMenuEntries()
|
||||
{
|
||||
for (int l_iIndex = MenuItems.Count - 1; l_iIndex >= 0; l_iIndex--)
|
||||
{
|
||||
MenuItems.Clear();
|
||||
m_oEntryDictionary.Clear();
|
||||
}
|
||||
/// <summary> Updates menu entries depending on state. </summary>
|
||||
private void UpdateMenuEntries()
|
||||
{
|
||||
for (int l_iIndex = MenuItems.Count - 1; l_iIndex >= 0; l_iIndex--)
|
||||
{
|
||||
MenuItems.Clear();
|
||||
m_oEntryDictionary.Clear();
|
||||
}
|
||||
|
||||
CheckAddItem(typeof(MapPage));
|
||||
CheckAddItem(typeof(MapPage));
|
||||
|
||||
if (App.ModelRoot.ActiveUser.IsLoggedIn)
|
||||
{
|
||||
CheckAddItem(typeof(MyBikesPage));
|
||||
CheckAddItem(typeof(FindBikePage));
|
||||
CheckAddItem(typeof(AccountPage));
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAddItem(typeof(LoginPage));
|
||||
}
|
||||
if (App.ModelRoot.ActiveUser.IsLoggedIn)
|
||||
{
|
||||
CheckAddItem(typeof(MyBikesPage));
|
||||
CheckAddItem(typeof(FindBikePage));
|
||||
CheckAddItem(typeof(AccountPage));
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckAddItem(typeof(LoginPage));
|
||||
}
|
||||
|
||||
if (App.ModelRoot.Uris.ActiveUri.Host.GetIsCopri()
|
||||
|| App.ModelRoot.ActiveUser.IsLoggedIn)
|
||||
{
|
||||
CheckAddItem(typeof(SettingsPage));
|
||||
}
|
||||
if (App.ModelRoot.Uris.ActiveUri.Host.GetIsCopri()
|
||||
|| App.ModelRoot.ActiveUser.IsLoggedIn)
|
||||
{
|
||||
CheckAddItem(typeof(SettingsPage));
|
||||
}
|
||||
|
||||
CheckAddItem(typeof(FeesAndBikesPage)); // Fees and bikes
|
||||
CheckAddItem(typeof(FeesAndBikesPage)); // Fees and bikes
|
||||
|
||||
CheckAddItem(typeof(ContactPage)); // Feedback and contact
|
||||
CheckAddItem(typeof(ContactPage)); // Feedback and contact
|
||||
|
||||
CheckAddItem(typeof(InfoPage)); // About sharee.bike
|
||||
}
|
||||
CheckAddItem(typeof(InfoPage)); // About sharee.bike
|
||||
}
|
||||
|
||||
/// <summary>Adds a menu item to master detail menu.</summary>
|
||||
/// <param name="p_oType">Type decribing entry to be added.</param>
|
||||
private void CheckAddItem(Type p_oType)
|
||||
{
|
||||
if (m_oEntryDictionary.ContainsKey(p_oType))
|
||||
{
|
||||
// Nothing to do because has already been added.
|
||||
return;
|
||||
}
|
||||
/// <summary>Adds a menu item to master detail menu.</summary>
|
||||
/// <param name="p_oType">Type decribing entry to be added.</param>
|
||||
private void CheckAddItem(Type p_oType)
|
||||
{
|
||||
if (m_oEntryDictionary.ContainsKey(p_oType))
|
||||
{
|
||||
// Nothing to do because has already been added.
|
||||
return;
|
||||
}
|
||||
|
||||
m_oEntryDictionary.Add(
|
||||
p_oType,
|
||||
m_oEntryDictionary.Count);
|
||||
m_oEntryDictionary.Add(
|
||||
p_oType,
|
||||
m_oEntryDictionary.Count);
|
||||
|
||||
MenuItems.Add(new RootPageFlyoutMenuItem
|
||||
{
|
||||
TargetType = p_oType,
|
||||
GlyphCode = Helper.GetGlyphCode(p_oType),
|
||||
Title = Helper.GetCaption(p_oType),
|
||||
Id = m_oEntryDictionary[p_oType]
|
||||
});
|
||||
}
|
||||
MenuItems.Add(new RootPageFlyoutMenuItem
|
||||
{
|
||||
TargetType = p_oType,
|
||||
GlyphCode = Helper.GetGlyphCode(p_oType),
|
||||
Title = Helper.GetCaption(p_oType),
|
||||
Id = m_oEntryDictionary[p_oType]
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary> Removes a page from menu.</summary>
|
||||
/// <param name="p_oType"></param>
|
||||
private void RemoveItem(Type p_oType)
|
||||
{
|
||||
if (!m_oEntryDictionary.ContainsKey(p_oType))
|
||||
{
|
||||
// Nothing to do because item was never added/ already removed.
|
||||
return;
|
||||
}
|
||||
/// <summary> Removes a page from menu.</summary>
|
||||
/// <param name="p_oType"></param>
|
||||
private void RemoveItem(Type p_oType)
|
||||
{
|
||||
if (!m_oEntryDictionary.ContainsKey(p_oType))
|
||||
{
|
||||
// Nothing to do because item was never added/ already removed.
|
||||
return;
|
||||
}
|
||||
|
||||
MenuItems.Remove(MenuItems[m_oEntryDictionary[p_oType]]);
|
||||
m_oEntryDictionary.Remove(p_oType);
|
||||
}
|
||||
MenuItems.Remove(MenuItems[m_oEntryDictionary[p_oType]]);
|
||||
m_oEntryDictionary.Remove(p_oType);
|
||||
}
|
||||
|
||||
public RootPageFlyoutViewModel()
|
||||
{
|
||||
MenuItems = new ObservableCollection<RootPageFlyoutMenuItem>();
|
||||
m_oEntryDictionary = new Dictionary<Type, int>();
|
||||
public RootPageFlyoutViewModel()
|
||||
{
|
||||
MenuItems = new ObservableCollection<RootPageFlyoutMenuItem>();
|
||||
m_oEntryDictionary = new Dictionary<Type, int>();
|
||||
|
||||
// Update menu entries on login/ logout actions.
|
||||
App.ModelRoot.ActiveUser.StateChanged += (sender, eventargs) => OnUpdateRequired();
|
||||
// Update menu entries on login/ logout actions.
|
||||
App.ModelRoot.ActiveUser.StateChanged += (sender, eventargs) => OnUpdateRequired();
|
||||
|
||||
// Update flyout view model whenever theme is switched.
|
||||
App.ModelRoot.Themes.PropertyChanged += (sender, eventargs) =>
|
||||
{
|
||||
if (!(sender is ServicesContainerMutableT<object> themes))
|
||||
return;
|
||||
// Update flyout view model whenever theme is switched.
|
||||
App.ModelRoot.Themes.PropertyChanged += (sender, eventargs) =>
|
||||
{
|
||||
if (!(sender is ServicesContainerMutableT<object> themes))
|
||||
return;
|
||||
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active);
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active);
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte)));
|
||||
};
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte)));
|
||||
};
|
||||
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active);
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active);
|
||||
|
||||
UpdateMenuEntries();
|
||||
}
|
||||
UpdateMenuEntries();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the flyout title from theme name
|
||||
/// </summary>
|
||||
/// <param name="theme">Name of theme.</param>
|
||||
/// <returns>Flyout title.</returns>
|
||||
private string GetMasterDetailMenuTitle(object theme)
|
||||
{
|
||||
if (!(theme is ITheme active))
|
||||
return TINK.Themes.LastenradBayern.OPERATORINFO;
|
||||
/// <summary>
|
||||
/// Gets the flyout title from theme name
|
||||
/// </summary>
|
||||
/// <param name="theme">Name of theme.</param>
|
||||
/// <returns>Flyout title.</returns>
|
||||
private string GetMasterDetailMenuTitle(object theme)
|
||||
{
|
||||
if (!(theme is ITheme active))
|
||||
return TINK.Themes.LastenradBayern.OPERATORINFO;
|
||||
|
||||
return $"{(!string.IsNullOrEmpty(active.OperatorInfo) ? ($"{active.OperatorInfo}") : "sharee.bike")}";
|
||||
}
|
||||
return $"{(!string.IsNullOrEmpty(active.OperatorInfo) ? ($"{active.OperatorInfo}") : "sharee.bike")}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the title of the fylout page.
|
||||
/// </summary>
|
||||
public string MasterDetailMenuTitlte { get; private set; }
|
||||
/// <summary>
|
||||
/// Holds the title of the fylout page.
|
||||
/// </summary>
|
||||
public string MasterDetailMenuTitlte { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides collection of menu items for master page.
|
||||
/// </summary>
|
||||
public ObservableCollection<RootPageFlyoutMenuItem> MenuItems
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
/// <summary>
|
||||
/// Provides collection of menu items for master page.
|
||||
/// </summary>
|
||||
public ObservableCollection<RootPageFlyoutMenuItem> MenuItems
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the selected item.
|
||||
/// </summary>
|
||||
public MainPageMenuItem SelectedMenuItem
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the selected item.
|
||||
/// </summary>
|
||||
public MainPageMenuItem SelectedMenuItem
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command object which is invoked from view when an item is selected.
|
||||
/// </summary>
|
||||
public Command MenuItemSelected
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Command(OnUpdateRequired);
|
||||
}
|
||||
/// <summary>
|
||||
/// Command object which is invoked from view when an item is selected.
|
||||
/// </summary>
|
||||
public Command MenuItemSelected
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Command(OnUpdateRequired);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Manges updates required due to selection of a menu or login events.</summary>
|
||||
public void OnUpdateRequired()
|
||||
{
|
||||
/// <summary> Manges updates required due to selection of a menu or login events.</summary>
|
||||
public void OnUpdateRequired()
|
||||
{
|
||||
|
||||
UpdateMenuEntries();
|
||||
UpdateMenuEntries();
|
||||
|
||||
if (SelectedMenuItem == null)
|
||||
{
|
||||
// Nothing to do if no menu entry is selected.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SelectedMenuItem == null)
|
||||
{
|
||||
// Nothing to do if no menu entry is selected.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,104 +12,104 @@ using TINK.ViewModel.Info;
|
|||
|
||||
namespace TINK.ViewModel.MasterDetail
|
||||
{
|
||||
public static class Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a description for a map page used as menu item entry and caption.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of page to get caption for.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetCaption(Type type)
|
||||
{
|
||||
if (type == typeof(MapPage)) // Bikes sites
|
||||
{
|
||||
return AppResources.MarkingMapPage;
|
||||
}
|
||||
else if (type == typeof(FindBikePage)) // Find Bike
|
||||
{
|
||||
return AppResources.MarkingFindBike;
|
||||
}
|
||||
else if (type == typeof(MyBikesPage)) // My Bikes
|
||||
{
|
||||
return AppResources.MarkingMyBikes;
|
||||
}
|
||||
else if (type == typeof(AccountPage)) // Account
|
||||
{
|
||||
return AppResources.MarkingAccount;
|
||||
}
|
||||
else if (type == typeof(LoginPage)) // Login
|
||||
{
|
||||
return AppResources.MarkingLogin;
|
||||
}
|
||||
else if (type == typeof(SettingsPage)) // Settings
|
||||
{
|
||||
return AppResources.MarkingSettings;
|
||||
}
|
||||
else if (type == typeof(FeesAndBikesPage))
|
||||
{
|
||||
return AppResources.MarkingFeesAndBikes;
|
||||
}
|
||||
else if (type == typeof(ContactPage))
|
||||
{
|
||||
return AppResources.MarkingFeedbackAndContact;
|
||||
}
|
||||
else if (type == typeof(InfoPage))
|
||||
{
|
||||
return AppResources.MarkingAbout;
|
||||
}
|
||||
else
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
}
|
||||
public static class Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a description for a map page used as menu item entry and caption.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of page to get caption for.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetCaption(Type type)
|
||||
{
|
||||
if (type == typeof(MapPage)) // Bikes sites
|
||||
{
|
||||
return AppResources.MarkingMapPage;
|
||||
}
|
||||
else if (type == typeof(FindBikePage)) // Find Bike
|
||||
{
|
||||
return AppResources.MarkingFindBike;
|
||||
}
|
||||
else if (type == typeof(MyBikesPage)) // My Bikes
|
||||
{
|
||||
return AppResources.MarkingMyBikes;
|
||||
}
|
||||
else if (type == typeof(AccountPage)) // Account
|
||||
{
|
||||
return AppResources.MarkingAccount;
|
||||
}
|
||||
else if (type == typeof(LoginPage)) // Login
|
||||
{
|
||||
return AppResources.MarkingLogin;
|
||||
}
|
||||
else if (type == typeof(SettingsPage)) // Settings
|
||||
{
|
||||
return AppResources.MarkingSettings;
|
||||
}
|
||||
else if (type == typeof(FeesAndBikesPage))
|
||||
{
|
||||
return AppResources.MarkingFeesAndBikes;
|
||||
}
|
||||
else if (type == typeof(ContactPage))
|
||||
{
|
||||
return AppResources.MarkingFeedbackAndContact;
|
||||
}
|
||||
else if (type == typeof(InfoPage))
|
||||
{
|
||||
return AppResources.MarkingAbout;
|
||||
}
|
||||
else
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a description for a map page used as menu item entry and caption.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of page to get caption for.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetGlyphCode(Type type)
|
||||
{
|
||||
if (type == typeof(MapPage)) // Bikes sites
|
||||
{
|
||||
return "\uf5a0";
|
||||
}
|
||||
else if (type == typeof(FindBikePage)) // My Bikes
|
||||
{
|
||||
return "\uf002";
|
||||
}
|
||||
else if (type == typeof(MyBikesPage)) // My Bikes
|
||||
{
|
||||
return "\uf206";
|
||||
}
|
||||
else if (type == typeof(AccountPage)) // Account
|
||||
{
|
||||
return "\uf007";
|
||||
}
|
||||
else if (type == typeof(LoginPage)) // Login
|
||||
{
|
||||
return "\uf2f6";
|
||||
}
|
||||
else if (type == typeof(SettingsPage)) // Settings
|
||||
{
|
||||
return "\uf013";
|
||||
}
|
||||
else if (type == typeof(FeesAndBikesPage))
|
||||
{
|
||||
return "\uf7d9";
|
||||
}
|
||||
else if (type == typeof(ContactPage))
|
||||
{
|
||||
return "\uf095";
|
||||
}
|
||||
else if (type == typeof(InfoPage))
|
||||
{
|
||||
return "\uf05a";
|
||||
}
|
||||
else
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a description for a map page used as menu item entry and caption.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of page to get caption for.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetGlyphCode(Type type)
|
||||
{
|
||||
if (type == typeof(MapPage)) // Bikes sites
|
||||
{
|
||||
return "\uf5a0";
|
||||
}
|
||||
else if (type == typeof(FindBikePage)) // My Bikes
|
||||
{
|
||||
return "\uf002";
|
||||
}
|
||||
else if (type == typeof(MyBikesPage)) // My Bikes
|
||||
{
|
||||
return "\uf206";
|
||||
}
|
||||
else if (type == typeof(AccountPage)) // Account
|
||||
{
|
||||
return "\uf007";
|
||||
}
|
||||
else if (type == typeof(LoginPage)) // Login
|
||||
{
|
||||
return "\uf2f6";
|
||||
}
|
||||
else if (type == typeof(SettingsPage)) // Settings
|
||||
{
|
||||
return "\uf013";
|
||||
}
|
||||
else if (type == typeof(FeesAndBikesPage))
|
||||
{
|
||||
return "\uf7d9";
|
||||
}
|
||||
else if (type == typeof(ContactPage))
|
||||
{
|
||||
return "\uf095";
|
||||
}
|
||||
else if (type == typeof(InfoPage))
|
||||
{
|
||||
return "\uf05a";
|
||||
}
|
||||
else
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,66 +7,66 @@ using TINK.ViewModel.Info;
|
|||
|
||||
namespace TINK.ViewModel.RootShell
|
||||
{
|
||||
public class AppShellViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public AppShellViewModel()
|
||||
{
|
||||
App.ModelRoot.ActiveUser.StateChanged += (sender, eventargs) =>
|
||||
{
|
||||
// Login state changed. Update related menu entries.
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsMyBikesPageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsFindBikePageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsAccountPageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLoginPageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSettingsPageVisible)));
|
||||
};
|
||||
public class AppShellViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public AppShellViewModel()
|
||||
{
|
||||
App.ModelRoot.ActiveUser.StateChanged += (sender, eventargs) =>
|
||||
{
|
||||
// Login state changed. Update related menu entries.
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsMyBikesPageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsFindBikePageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsAccountPageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLoginPageVisible)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSettingsPageVisible)));
|
||||
};
|
||||
|
||||
// Update flyout view model whenever theme is switched.
|
||||
App.ModelRoot.Themes.PropertyChanged += (sender, eventargs) =>
|
||||
{
|
||||
if (!(sender is ServicesContainerMutableT<object> themes))
|
||||
return;
|
||||
// Update flyout view model whenever theme is switched.
|
||||
App.ModelRoot.Themes.PropertyChanged += (sender, eventargs) =>
|
||||
{
|
||||
if (!(sender is ServicesContainerMutableT<object> themes))
|
||||
return;
|
||||
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active);
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active);
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte)));
|
||||
};
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte)));
|
||||
};
|
||||
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active);
|
||||
}
|
||||
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the flyout title from theme name
|
||||
/// </summary>
|
||||
/// <param name="theme">Name of theme.</param>
|
||||
/// <returns>Flyout title.</returns>
|
||||
private string GetMasterDetailMenuTitle(object theme)
|
||||
{
|
||||
if (!(theme is ITheme active))
|
||||
return TINK.Themes.ShareeBike.OPERATORINFO;
|
||||
/// <summary>
|
||||
/// Gets the flyout title from theme name
|
||||
/// </summary>
|
||||
/// <param name="theme">Name of theme.</param>
|
||||
/// <returns>Flyout title.</returns>
|
||||
private string GetMasterDetailMenuTitle(object theme)
|
||||
{
|
||||
if (!(theme is ITheme active))
|
||||
return TINK.Themes.ShareeBike.OPERATORINFO;
|
||||
|
||||
return $"{(!string.IsNullOrEmpty(active.OperatorInfo) ? ($"{active.OperatorInfo}") : "sharee.bike")}";
|
||||
}
|
||||
return $"{(!string.IsNullOrEmpty(active.OperatorInfo) ? ($"{active.OperatorInfo}") : "sharee.bike")}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the title of the fylout page.
|
||||
/// </summary>
|
||||
public string MasterDetailMenuTitlte { get; private set; }
|
||||
/// <summary>
|
||||
/// Holds the title of the fylout page.
|
||||
/// </summary>
|
||||
public string MasterDetailMenuTitlte { get; private set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public bool IsMyBikesPageVisible => App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
public bool IsMyBikesPageVisible => App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
|
||||
public bool IsFindBikePageVisible => App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
public bool IsFindBikePageVisible => App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
|
||||
public bool IsAccountPageVisible => App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
public bool IsAccountPageVisible => App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
|
||||
public bool IsLoginPageVisible => !App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
public bool IsLoginPageVisible => !App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
|
||||
public bool IsSettingsPageVisible => App.ModelRoot.Uris.ActiveUri.Host.GetIsCopri()
|
||||
|| App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
public bool IsSettingsPageVisible => App.ModelRoot.Uris.ActiveUri.Host.GetIsCopri()
|
||||
|| App.ModelRoot.ActiveUser.IsLoggedIn;
|
||||
|
||||
public string TabbedPageIngoTitle => AppResources.MarkingAbout;
|
||||
public string TabbedPageIngoTitle => AppResources.MarkingAbout;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,38 +5,38 @@ using Serilog;
|
|||
|
||||
namespace TINK.ViewModel
|
||||
{
|
||||
public static class ViewModelResourceHelper
|
||||
{
|
||||
/// <summary> Get ressource prefix depending on platform.</summary>
|
||||
public static string RessourcePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
public static class ViewModelResourceHelper
|
||||
{
|
||||
/// <summary> Get ressource prefix depending on platform.</summary>
|
||||
public static string RessourcePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
#if __IOS__
|
||||
return "TINK.iOS.";
|
||||
return "TINK.iOS.";
|
||||
#endif
|
||||
#if __ANDROID__
|
||||
return "TINK.Droid.";
|
||||
return "TINK.Droid.";
|
||||
#endif
|
||||
#if WINDOWS_UWP
|
||||
return "TINK.WinPhone.";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets an an embedded html ressource.</summary>
|
||||
/// <param name="resrouceName">Name of resource to get.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSource(string resrouceName)
|
||||
{
|
||||
var l_oRessourceName = RessourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {RessourcePrefix}.");
|
||||
// note that the prefix includes the trailing period '.' that is required
|
||||
var assembly = typeof(ViewModelResourceHelper).GetTypeInfo().Assembly;
|
||||
var stream = assembly.GetManifestResourceStream(l_oRessourceName);
|
||||
return stream != null
|
||||
? (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- ressource {0}.</body>", l_oRessourceName);
|
||||
}
|
||||
}
|
||||
/// <summary> Gets an an embedded html ressource.</summary>
|
||||
/// <param name="resrouceName">Name of resource to get.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSource(string resrouceName)
|
||||
{
|
||||
var l_oRessourceName = RessourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {RessourcePrefix}.");
|
||||
// note that the prefix includes the trailing period '.' that is required
|
||||
var assembly = typeof(ViewModelResourceHelper).GetTypeInfo().Assembly;
|
||||
var stream = assembly.GetManifestResourceStream(l_oRessourceName);
|
||||
return stream != null
|
||||
? (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- ressource {0}.</body>", l_oRessourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,147 +16,147 @@ using Xamarin.Essentials;
|
|||
|
||||
namespace TINK.Services.BluetoothLock.BLE
|
||||
{
|
||||
public class LockItByGuidService : LockItServiceBase, ILocksService
|
||||
{
|
||||
/// <summary> Constructs a LockItByGuidService object.</summary>
|
||||
/// <param name="cipher">Encrpyting/ decrypting object.</param>
|
||||
public LockItByGuidService(ICipher cipher) : base(cipher)
|
||||
{
|
||||
}
|
||||
public class LockItByGuidService : LockItServiceBase, ILocksService
|
||||
{
|
||||
/// <summary> Constructs a LockItByGuidService object.</summary>
|
||||
/// <param name="cipher">Encrpyting/ decrypting object.</param>
|
||||
public LockItByGuidService(ICipher cipher) : base(cipher)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary> Checks for locks which have not yet been discoverted and connects them. </summary>
|
||||
/// <remarks> Consists of a bluetooth connect plus invocation of an authentication sequence. </remarks>
|
||||
/// <param name="locksInfo">Locks to reconnect.</param>
|
||||
/// <param name="connectTimeout">Timeout for connect operation of a single lock.</param>
|
||||
protected override async Task<IEnumerable<ILockService>> CheckConnectMissing(IEnumerable<LockInfoAuthTdo> locksInfo, TimeSpan connectTimeout)
|
||||
{
|
||||
if (DeviceInfo.Platform != DevicePlatform.Unknown && MainThread.IsMainThread == false)
|
||||
{
|
||||
throw new System.Exception("Can not connect to locks by guid. Platform must not be unknown and bluetooth code must be run on main thread.");
|
||||
}
|
||||
/// <summary> Checks for locks which have not yet been discoverted and connects them. </summary>
|
||||
/// <remarks> Consists of a bluetooth connect plus invocation of an authentication sequence. </remarks>
|
||||
/// <param name="locksInfo">Locks to reconnect.</param>
|
||||
/// <param name="connectTimeout">Timeout for connect operation of a single lock.</param>
|
||||
protected override async Task<IEnumerable<ILockService>> CheckConnectMissing(IEnumerable<LockInfoAuthTdo> locksInfo, TimeSpan connectTimeout)
|
||||
{
|
||||
if (DeviceInfo.Platform != DevicePlatform.Unknown && MainThread.IsMainThread == false)
|
||||
{
|
||||
throw new System.Exception("Can not connect to locks by guid. Platform must not be unknown and bluetooth code must be run on main thread.");
|
||||
}
|
||||
|
||||
// Get list of target locks without invalid entries.
|
||||
var validLocksInfo = locksInfo
|
||||
.Where(x => x.IsGuidValid)
|
||||
.Where(x => x.K_seed.Length > 0 && x.K_u.Length > 0)
|
||||
.ToList();
|
||||
// Get list of target locks without invalid entries.
|
||||
var validLocksInfo = locksInfo
|
||||
.Where(x => x.IsGuidValid)
|
||||
.Where(x => x.K_seed.Length > 0 && x.K_u.Length > 0)
|
||||
.ToList();
|
||||
|
||||
var locksList = new List<ILockService>();
|
||||
var locksList = new List<ILockService>();
|
||||
|
||||
// Connect to
|
||||
foreach (var lockInfo in validLocksInfo)
|
||||
{
|
||||
if (DeviceList.Any(x => x.Name.GetBluetoothLockId() == lockInfo.Id || x.Guid == lockInfo.Guid))
|
||||
{
|
||||
// Device is already connected.
|
||||
continue;
|
||||
}
|
||||
// Connect to
|
||||
foreach (var lockInfo in validLocksInfo)
|
||||
{
|
||||
if (DeviceList.Any(x => x.Name.GetBluetoothLockId() == lockInfo.Id || x.Guid == lockInfo.Guid))
|
||||
{
|
||||
// Device is already connected.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Connect to device and authenticate.
|
||||
ILockService lockIt = null;
|
||||
try
|
||||
{
|
||||
lockIt = await ConnectByGuid(lockInfo, connectTimeout);
|
||||
}
|
||||
catch (System.Exception exception)
|
||||
{
|
||||
// Member is called for background update of missing devices.
|
||||
// Do not display any error messages.
|
||||
Log.ForContext<LockItByGuidService>().Error($"Authentication failed. {exception.Message}");
|
||||
continue;
|
||||
}
|
||||
if (lockIt == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Connect to device and authenticate.
|
||||
ILockService lockIt = null;
|
||||
try
|
||||
{
|
||||
lockIt = await ConnectByGuid(lockInfo, connectTimeout);
|
||||
}
|
||||
catch (System.Exception exception)
|
||||
{
|
||||
// Member is called for background update of missing devices.
|
||||
// Do not display any error messages.
|
||||
Log.ForContext<LockItByGuidService>().Error($"Authentication failed. {exception.Message}");
|
||||
continue;
|
||||
}
|
||||
if (lockIt == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
locksList.Add(lockIt);
|
||||
}
|
||||
locksList.Add(lockIt);
|
||||
}
|
||||
|
||||
return locksList;
|
||||
}
|
||||
return locksList;
|
||||
}
|
||||
|
||||
/// <summary> Connects to lock.</summary>
|
||||
/// <remarks> Consists of a bluetooth connect plus invocation of an authentication sequence. </remarks>
|
||||