Version 3.0.346

This commit is contained in:
Oliver Hauff 2022-10-17 18:45:38 +02:00
parent 1ba809dd59
commit 47c03f43fb
43 changed files with 609 additions and 117 deletions

View file

@ -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.345" android:versionCode="345">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.346" android:versionCode="346">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -55,8 +55,8 @@
<key>CFBundleDisplayName</key>
<string>LastenradBayern</string>
<key>CFBundleVersion</key>
<string>345</string>
<string>346</string>
<key>CFBundleShortVersionString</key>
<string>3.0.345</string>
<string>3.0.346</string>
</dict>
</plist>

View file

@ -20,6 +20,7 @@ using TINK.Services;
using TINK.Services.BluetoothLock.Crypto;
using TINK.Services.Geolocation;
using TINK.Services.Permissions;
using TINK.View;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
#if ARENDI
@ -84,6 +85,7 @@ namespace TINK
settings = new Model.Settings.Settings(
null, // Turn off filtering for LastenradBayern- context
null, // Turn off filtering for LastenradBayern- context
JsonSettingsDictionary.GetStartupSettings(settingsJSON) ?? new StartupSettings(),
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
@ -197,11 +199,12 @@ 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
// Check which page to show first.
var mainPage = new View.RootShell.AppShell();
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = mainPage) // Show whats new info.
: (Page)mainPage; // Just start sharee- app
#endif
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
@ -18,6 +18,11 @@ namespace TINK.View.FindBike
/// <summary> Refernce to view model. </summary>
FindBikePageViewModel m_oViewModel = null;
/// <summary>
/// Holds a value indicating whether page already subscribed to shell item changes or not.
/// </summary>
private bool _IsShellItemChangedReceived = false;
public FindBikePage() { }
/// <summary>
@ -76,6 +81,35 @@ namespace TINK.View.FindBike
await m_oViewModel.OnAppearing();
}
/// <summary>
/// Invoked when page is disappearing to
/// - stop the update process
/// - to subscribe to events.
/// </summary>
protected async override void OnDisappearing()
{
if (!_IsShellItemChangedReceived && Shell.Current != null)
{
// Subscribe to events.
// Do not do this on startup because Shell.Current is null, if FindeBikePage is startup page.
Shell.Current.Navigated += (sender, e) =>
{
if (e.Source != ShellNavigationSource.ShellItemChanged)
{
// Nothing to do.
return;
}
// Reset previous user input after switch of pages to allow user to select a differnt bike if one has been selected before.
m_oViewModel.BikeIdUserInput = String.Empty;
};
}
_IsShellItemChangedReceived = true;
await (m_oViewModel?.OnDisappearing() ?? Task.CompletedTask);
}
/// <summary>
/// Displays alert message.

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
@ -267,7 +267,7 @@ namespace TINK.View.Map
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected override async void OnDisappearing()
protected async override void OnDisappearing()
{
if (MapPageViewModel != null)
{

View file

@ -59,10 +59,20 @@
</ListView>
</StackLayout>
</Frame>
<!-- Picker to selct startup page -->
<Frame IsVisible="False">
<StackLayout>
<Label Text="{x:Static resources:AppResources.MarkingStartupPage}"/>
<Picker
ItemsSource="{Binding StartupSettings.ServicesTextList}"
SelectedItem="{Binding StartupSettings.ActiveText}"/>
</StackLayout>
</Frame>
<!-- Themes -->
<Frame
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchTheme_Converter}}">
<StackLayout>
<!-- Themes -->
<Label
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchTheme_Converter}}"
Text="Theme"/>

View file

@ -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.Meinkonrad" android:versionName="3.0.345" android:versionCode="345">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.346" android:versionCode="346">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -55,8 +55,8 @@
<key>CFBundleDisplayName</key>
<string>Mein konrad</string>
<key>CFBundleVersion</key>
<string>345</string>
<string>346</string>
<key>CFBundleShortVersionString</key>
<string>3.0.345</string>
<string>3.0.346</string>
</dict>
</plist>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -19,6 +19,7 @@ using TINK.Services;
using TINK.Services.BluetoothLock.Crypto;
using TINK.Services.Geolocation;
using TINK.Services.Permissions;
using TINK.View;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
#if ARENDI
@ -83,6 +84,7 @@ namespace TINK
settings = new Model.Settings.Settings(
JsonSettingsDictionary.GetGroupFilterMapPage(settingsJSON) ?? GroupFilterHelper.GetMapPageFilterDefaults, // Activate map filtering for meinkonrad
JsonSettingsDictionary.GetGoupFilterSettings(settingsJSON) ?? GroupFilterHelper.GetSettingsFilterDefaults,// Activate map filtering for meinkonrad
JsonSettingsDictionary.GetStartupSettings(settingsJSON) ?? new StartupSettings(),
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
@ -195,12 +197,12 @@ 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 = new TINK.View.Welcome.WelcomePage();
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
// Check which page to show first.
var mainPage = new View.RootShell.AppShell();
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = mainPage) // Show whats new info.
: (Page)mainPage; // Just start sharee- app
#endif
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
@ -17,6 +17,11 @@ namespace TINK.View.FindBike
/// <summary> Refernce to view model. </summary>
FindBikePageViewModel m_oViewModel = null;
/// <summary>
/// Holds a value indicating whether page already subscribed to shell item changes or not.
/// </summary>
private bool _IsShellItemChangedReceived = false;
public FindBikePage() { }
/// <summary>
@ -75,6 +80,35 @@ namespace TINK.View.FindBike
await m_oViewModel.OnAppearing();
}
/// <summary>
/// Invoked when page is disappearing to
/// - stop the update process
/// - to subscribe to events.
/// </summary>
protected async override void OnDisappearing()
{
if (!_IsShellItemChangedReceived && Shell.Current != null)
{
// Subscribe to events.
// Do not do this on startup because Shell.Current is null, if FindeBikePage is startup page.
Shell.Current.Navigated += (sender, e) =>
{
if (e.Source != ShellNavigationSource.ShellItemChanged)
{
// Nothing to do.
return;
}
// Reset previous user input after switch of pages to allow user to select a differnt bike if one has been selected before.
m_oViewModel.BikeIdUserInput = String.Empty;
};
}
_IsShellItemChangedReceived = true;
await (m_oViewModel?.OnDisappearing() ?? Task.CompletedTask);
}
/// <summary>
/// Displays alert message.

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
@ -267,7 +267,7 @@ namespace TINK.View.Map
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected override async void OnDisappearing()
protected async override void OnDisappearing()
{
if (MapPageViewModel != null)
{

View file

@ -60,10 +60,20 @@
</ListView>
</StackLayout>
</Frame>
<!-- Picker to selct startup page -->
<Frame IsVisible="False">
<StackLayout>
<Label Text="{x:Static resources:AppResources.MarkingStartupPage}"/>
<Picker
ItemsSource="{Binding StartupSettings.ServicesTextList}"
SelectedItem="{Binding StartupSettings.ActiveText}"/>
</StackLayout>
</Frame>
<!-- Themes -->
<Frame
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchTheme_Converter}}">
<StackLayout>
<!-- Themes -->
<Label
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchTheme_Converter}}"
Text="Theme"/>

View file

@ -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.hauffware.sharee" android:versionName="3.0.345" android:versionCode="345">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.346" android:versionCode="346">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -55,8 +55,8 @@
<key>CFBundleDisplayName</key>
<string>sharee.bike</string>
<key>CFBundleVersion</key>
<string>345</string>
<string>346</string>
<key>CFBundleShortVersionString</key>
<string>3.0.345</string>
<string>3.0.346</string>
</dict>
</plist>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -19,6 +19,7 @@ using TINK.Services;
using TINK.Services.BluetoothLock.Crypto;
using TINK.Services.Geolocation;
using TINK.Services.Permissions;
using TINK.View;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
#if ARENDI
@ -83,6 +84,7 @@ namespace TINK
settings = new Model.Settings.Settings(
null, // Turn off filtering for sharee.bike- context
null, // Turn off filtering for sharee.bike- context
JsonSettingsDictionary.GetStartupSettings(settingsJSON) ?? new StartupSettings(),
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
@ -196,10 +198,17 @@ 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.
// Check which page to show first.
var mainPage = new View.RootShell.AppShell();
var currentItem = Activator.CreateInstance(ModelRoot.StartupSettings.StartupPage.GetViewType()) as ContentPage;
if (currentItem != null && ModelRoot.ActiveUser.IsLoggedIn)
{
mainPage.CurrentItem = currentItem;
}
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
? new View.WhatsNew.WhatsNewPage(() => MainPage = mainPage) // Show whats new info.
: (Page)mainPage; // Just start sharee- app
#endif
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
@ -17,6 +17,11 @@ namespace TINK.View.FindBike
/// <summary> Refernce to view model. </summary>
FindBikePageViewModel m_oViewModel = null;
/// <summary>
/// Holds a value indicating whether page already subscribed to shell item changes or not.
/// </summary>
private bool _IsShellItemChangedReceived = false;
public FindBikePage() { }
/// <summary>
@ -69,12 +74,43 @@ namespace TINK.View.FindBike
InitializeComponent();
BindingContext = m_oViewModel;
FindBikeListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
}
/// <summary>
/// Invoked when page is disappearing to
/// - stop the update process
/// - to subscribe to events.
/// </summary>
protected async override void OnDisappearing()
{
if (!_IsShellItemChangedReceived && Shell.Current != null)
{
// Subscribe to events.
// Do not do this on startup because Shell.Current is null, if FindeBikePage is startup page.
Shell.Current.Navigated += (sender, e) =>
{
if (e.Source != ShellNavigationSource.ShellItemChanged)
{
// Nothing to do.
return;
}
// Reset previous user input after switch of pages to allow user to select a differnt bike if one has been selected before.
m_oViewModel.BikeIdUserInput = String.Empty;
};
}
_IsShellItemChangedReceived = true;
await (m_oViewModel?.OnDisappearing() ?? Task.CompletedTask);
}
/// <summary>
/// Displays alert message.

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
@ -267,7 +267,7 @@ namespace TINK.View.Map
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected override async void OnDisappearing()
protected async override void OnDisappearing()
{
if (MapPageViewModel != null)
{

View file

@ -59,10 +59,20 @@
</ListView>
</StackLayout>
</Frame>
<!-- Picker to selct startup page -->
<Frame>
<StackLayout>
<Label Text="{x:Static resources:AppResources.MarkingStartupPage}"/>
<Picker
ItemsSource="{Binding StartupSettings.ServicesTextList}"
SelectedItem="{Binding StartupSettings.ActiveText}"/>
</StackLayout>
</Frame>
<!-- Themes -->
<Frame
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchTheme_Converter}}">
<StackLayout>
<!-- Themes -->
<Label
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchTheme_Converter}}"
Text="Theme"/>

View file

@ -1,7 +1,8 @@
using System;
using System;
using TINK.View.BikesAtStation;
using TINK.View.Contact;
using TINK.View.CopriWebView;
using TINK.View.FindBike;
using TINK.View.Info;
using TINK.View.Info.BikeInfo;
using TINK.View.Login;
@ -69,6 +70,9 @@ namespace TINK.View
case ViewTypes.MiniSurvey:
return typeof(MiniSurveyPage);
case ViewTypes.FindBikePage:
return typeof(FindBikePage);
default:
return typeof(ContentPage);
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading;
@ -6,6 +6,7 @@ using Serilog.Events;
using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi.ServerUris;
using TINK.Model.Settings;
using TINK.Model.Station;
using TINK.Services;
using TINK.Services.BluetoothLock;
@ -65,6 +66,9 @@ namespace TINK.Model
/// <summary> Holds the filters loaded from settings. </summary>
IGroupFilterSettings FilterGroupSetting { get; set; }
/// <summary>Settings determining the startup behavior of the app.</summary>
IStartupSettings StartupSettings { get; }
/// <summary> Value indicating whether map is centerted to current position or not. </summary>
bool CenterMapToCurrentLocation { get; set; }
@ -84,10 +88,9 @@ namespace TINK.Model
/// <summary> Gets a value indicating whether reporting level is verbose or not.</summary>
bool IsReportLevelVerbose { get; set; }
/// <summary> Updates logging level. </summary>
/// <param name="p_oNewLevel">New level to set.</param>
void UpdateLoggingLevel(LogEventLevel p_oNewLevel);
/// <param name="newLogLevel">New level to set.</param>
void UpdateLoggingLevel(LogEventLevel newLogLevel);
/// <summary>Holds uris of copri servers. </summary>
CopriServerUriList Uris { get; }
@ -113,7 +116,7 @@ namespace TINK.Model
/// <summary> Holds the stations availalbe. </summary>
IEnumerable<IStation> Stations { get; set; }
/// <summary> Holds the Urs to query resources from. </summary>
IResourceUrls ResourceUrls { get; set; }
}

View file

@ -0,0 +1,9 @@
namespace TINK.Model.Settings
{
/// <summary> Settings determining the startup behavior of the app. </summary>
public interface IStartupSettings
{
/// <summary> Holds the page to show when apps starts. </summary>
ViewTypes StartupPage { get; set; }
}
}

View file

@ -1,6 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Serilog.Events;
@ -39,6 +40,9 @@ namespace TINK.Model.Settings
/// <summary> Key of the center to ... entry. </summary>
public const string CENTERMAPTOCURRENTLOCATION = "CenterMapToCurrentLocation";
/// <summary> Key of the center to ... entry. </summary>
public const string STARTUPSETTINGS = "StartupSettings";
public const string LOGTOEXTERNALFOLDER = "LogToExternalFolder";
public const string THEMEKEY = "Theme";
@ -49,7 +53,7 @@ namespace TINK.Model.Settings
/// <param name="settingsJSON">Dictionary to get value from.</param>
public static T? GetNullableEntry<T>(
string keyName,
Dictionary<string, string> settingsJSON) where T : struct
IDictionary<string, string> settingsJSON) where T : struct
{
if (!settingsJSON.TryGetValue(keyName, out string boolText)
|| string.IsNullOrEmpty(boolText))
@ -65,7 +69,7 @@ namespace TINK.Model.Settings
/// <param name="settingsJSON">Dictionary to get value from.</param>
public static T GetEntry<T>(
string keyName,
Dictionary<string, string> settingsJSON,
IDictionary<string, string> settingsJSON,
Func<string, string> legacyValueConverter = null) where T : class
{
if (string.IsNullOrEmpty(keyName)
@ -465,7 +469,7 @@ namespace TINK.Model.Settings
public static bool? GetIsSiteCachingOn(Dictionary<string, string> settingsJSON) => GetNullableEntry<bool>(ISSITECACHINGON, settingsJSON);
/// <summary> Sets whether to store logging data on SD card or not.</summary>
/// <param name="settingsJSON">Dictionary to get value from.</param>
/// <param name="settingsJSON">Dictionary to write value to.</param>
public static Dictionary<string, string> SetLogToExternalFolder(this IDictionary<string, string> targetDictionary, bool useSdCard) => SetEntry(useSdCard, LOGTOEXTERNALFOLDER, targetDictionary);
/// <summary> Sets active theme.</summary>
@ -550,5 +554,28 @@ namespace TINK.Model.Settings
settings["FilterCollection"] = JsonConvert.SerializeObject(p_oFilterCollection);
return settings;
}
/// <summary>
/// Gets the startup settings from dictionary.
/// </summary>
/// <param name="settings">Settings objet to load from.</param>
public static StartupSettings GetStartupSettings(this IDictionary<string, string> settingsJSON)
=> GetEntry<StartupSettings>(STARTUPSETTINGS, settingsJSON) ?? new StartupSettings();
/// <summary> Sets the startup settings.</summary>
/// <param name="settingsJSON">Dictionary to write value to.</param>
public static IDictionary<string, string> SetStartupSettings(
this IDictionary<string, string> settingsJSON,
IStartupSettings startupSettings)
{
if (settingsJSON == null
|| startupSettings == null)
{
return settingsJSON;
}
settingsJSON[STARTUPSETTINGS] = JsonConvert.SerializeObject(startupSettings);
return settingsJSON;
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using Serilog.Events;
using TINK.Services.BluetoothLock;
using TINK.Services.CopriApi.ServerUris;
@ -27,6 +27,7 @@ namespace TINK.Model.Settings
/// <summary> Constructs settings object. </summary>
/// <param name="groupFilterMapPage">filter which is applied on the map view. Either TINK or Konrad stations are displayed.</param>
/// <param name="groupFilterSettings"></param>
/// <param name="startupSettings">Settings determining the startup behavior of the app.</param>
/// <param name="activeUri"></param>
/// <param name="pollingParameters"></param>
/// <param name="minimumLogEventLevel">Minimum logging level to be applied.</param>
@ -38,6 +39,7 @@ namespace TINK.Model.Settings
public Settings(
IGroupFilterMapPage groupFilterMapPage = null,
IGroupFilterSettings groupFilterSettings = null,
IStartupSettings startupSettings = null,
Uri activeUri = null,
PollingParameters pollingParameters = null,
LogEventLevel? minimumLogEventLevel = null,
@ -54,6 +56,7 @@ namespace TINK.Model.Settings
{
GroupFilterMapPage = groupFilterMapPage ?? new GroupFilterMapPage(); // Default behaviour: No filtering.
GroupFilterSettings = groupFilterSettings ?? new GroupFilterSettings(); // Default behaviour: No filtering.
StartupSettings = startupSettings ?? new StartupSettings();
ActiveUri = GetActiveUri(activeUri);
PollingParameters = pollingParameters ?? PollingParameters.Default;
MinimumLogEventLevel = minimumLogEventLevel ?? DEFAULTLOGGINLEVEL;
@ -75,6 +78,9 @@ namespace TINK.Model.Settings
/// <summary> Holds the filters loaded from settings. </summary>
public IGroupFilterSettings GroupFilterSettings { get; }
/// <summary> Holds the stettings determining app startup behavior. </summary>
public IStartupSettings StartupSettings { get; }
/// <summary> Holds the uri to connect to. </summary>
public Uri ActiveUri { get; }

View file

@ -0,0 +1,11 @@
namespace TINK.Model.Settings
{
/// <summary> Settings determining the startup behavior of the app. </summary>
public class StartupSettings : IStartupSettings
{
public static ViewTypes DefaultStartupPage => ViewTypes.MapPage;
/// <summary> Holds the page to show when apps starts. </summary>
public ViewTypes StartupPage { get; set; } = DefaultStartupPage;
}
}

View file

@ -52,6 +52,9 @@ namespace TINK.Model
/// <summary> Holds the filters loaded from settings. </summary>
public IGroupFilterSettings FilterGroupSetting { get; set; }
/// <summary> Settings determining the startup behavior of the app.</summary>
public IStartupSettings StartupSettings { get; private set; }
/// <summary> Holds the filter which is applied on the map view. Either TINK or Konrad stations are displayed. </summary>
private IGroupFilterMapPage m_oFilterDictionaryMapPage;
@ -73,9 +76,17 @@ namespace TINK.Model
/// <summary> Holds the map span to display either default span or span centered to current position depending on option <see cref="CenterMapToCurrentLocation"/>.</summary>
public Xamarin.Forms.GoogleMaps.MapSpan ActiveMapSpan
=> CenterMapToCurrentLocation
? UserMapSpan ?? HomeMapSpan
: HomeMapSpan;
{
get
{
if (CenterMapToCurrentLocation == false)
{
return HomeMapSpan;
}
return UserMapSpan ?? HomeMapSpan;
}
}
/// <summary> Gets the minimum logging level. </summary>
public LogEventLevel MinimumLogEventLevel { get; set; }
@ -95,6 +106,7 @@ namespace TINK.Model
.SetCopriHostUri(NextActiveUri.AbsoluteUri)
.SetPollingParameters(Polling)
.SetGroupFilterSettings(FilterGroupSetting)
.SetStartupSettings(StartupSettings)
.SetAppVersion(AppVersion)
.SetMinimumLoggingLevel(MinimumLogEventLevel)
.SetIsReportLevelVerbose(IsReportLevelVerbose)
@ -238,6 +250,8 @@ namespace TINK.Model
FilterGroupSetting = settings.GroupFilterSettings;
GroupFilterMapPage = settings.GroupFilterMapPage;
StartupSettings = settings.StartupSettings;
CenterMapToCurrentLocation = settings.CenterMapToCurrentLocation;
HomeMapSpan = settings.MapSpan;

View file

@ -614,7 +614,17 @@ namespace TINK.Model
new Version(3, 0, 345),
AppResources.ChangeLog_3_0_345_LB,
new List<AppFlavor> { AppFlavor.LastenradBayern }
}
},
{
new Version(3, 0, 346),
AppResources.ChangeLog_3_0_346_LB_MK,
new List<AppFlavor> { AppFlavor.LastenradBayern, AppFlavor.MeinKonrad }
},
{
new Version(3, 0, 346),
AppResources.ChangeLog_3_0_346_SB,
new List<AppFlavor> { AppFlavor.ShareeBike }
},
};
/// <summary> Manges the whats new information.</summary>

View file

@ -668,6 +668,30 @@ namespace TINK.MultilingualResources {
}
}
/// <summary>
/// Looks up a localized string similar to &lt;i&gt;Select Bike&lt;/i&gt; page revised..
/// </summary>
public static string ChangeLog_3_0_346_LB_MK {
get {
return ResourceManager.GetString("ChangeLog_3_0_346_LB_MK", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;i&gt;Select Bike&lt;/i&gt;- page revised.&lt;br/&gt;
///Setting added to select whether the app starts up showing either
///&lt;ul&gt;
///&lt;li/&gt;&lt;i&gt;Bike Locations&lt;/i&gt; or
///&lt;li/&gt;&lt;i&gt;Select Bike&lt;/i&gt;
///&lt;/ul&gt;
///page..
/// </summary>
public static string ChangeLog_3_0_346_SB {
get {
return ResourceManager.GetString("ChangeLog_3_0_346_SB", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to We have fixed some bugs. Enjoy the ride!.
/// </summary>
@ -2113,6 +2137,15 @@ namespace TINK.MultilingualResources {
}
}
/// <summary>
/// Looks up a localized string similar to Startup page.
/// </summary>
public static string MarkingStartupPage {
get {
return ResourceManager.GetString("MarkingStartupPage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to App.
/// </summary>

View file

@ -1063,4 +1063,19 @@ Sie können nun auf einen Blick sehen, welche App-Version Sie installiert haben:
- Einstellungen sind auch ohne Anmeldung verfügbar.
- Die Reihenfolge der Karteikarten auf der Seite Bedienung wurde getauscht.</value>
</data>
<data name="MarkingStartupPage" xml:space="preserve">
<value>Startseite</value>
</data>
<data name="ChangeLog_3_0_346_LB_MK" xml:space="preserve">
<value>&lt;i&gt;Rad auswählen&lt;/i&gt; Seite überarbeitet.</value>
</data>
<data name="ChangeLog_3_0_346_SB" xml:space="preserve">
<value>&lt;i&gt;Rad auswählen&lt;/i&gt;- Seite überarbeitet.&lt;br/&gt;
Einstellung hinzugefügt mit der festgelegt werden kann, ob die App mit der Seite
&lt;ul&gt;
&lt;li/&gt;&lt;i&gt;Radstandorte&lt;/i&gt; oder
&lt;li/&gt;&lt;i&gt;Rad auswählen&lt;/i&gt;
&lt;/ul&gt;
gestartet wird.</value>
</data>
</root>

View file

@ -1155,4 +1155,19 @@ You can now see at a glance which app version you have installed: in the menu at
- Settings are available even if no user is logged in.
- Order of tabs on instructions page were switched.</value>
</data>
<data name="MarkingStartupPage" xml:space="preserve">
<value>Startup page</value>
</data>
<data name="ChangeLog_3_0_346_LB_MK" xml:space="preserve">
<value>&lt;i&gt;Select Bike&lt;/i&gt; page revised.</value>
</data>
<data name="ChangeLog_3_0_346_SB" xml:space="preserve">
<value>&lt;i&gt;Select Bike&lt;/i&gt;- page revised.&lt;br/&gt;
Setting added to select whether the app starts up showing either
&lt;ul&gt;
&lt;li/&gt;&lt;i&gt;Bike Locations&lt;/i&gt; or
&lt;li/&gt;&lt;i&gt;Select Bike&lt;/i&gt;
&lt;/ul&gt;
page.</value>
</data>
</root>

View file

@ -1446,6 +1446,30 @@ Sie können nun auf einen Blick sehen, welche App-Version Sie installiert haben:
- Einstellungen sind auch ohne Anmeldung verfügbar.
- Die Reihenfolge der Karteikarten auf der Seite Bedienung wurde getauscht.</target>
</trans-unit>
<trans-unit id="MarkingStartupPage" translate="yes" xml:space="preserve">
<source>Startup page</source>
<target state="translated">Startseite</target>
</trans-unit>
<trans-unit id="ChangeLog_3_0_346_LB_MK" translate="yes" xml:space="preserve">
<source><bpt id="1">&lt;i&gt;</bpt>Select Bike<ept id="1">&lt;/i&gt;</ept> page revised.</source>
<target state="translated"><bpt id="1">&lt;i&gt;</bpt>Rad auswählen<ept id="1">&lt;/i&gt;</ept> Seite überarbeitet.</target>
</trans-unit>
<trans-unit id="ChangeLog_3_0_346_SB" translate="yes" xml:space="preserve">
<source><bpt id="1">&lt;i&gt;</bpt>Select Bike<ept id="1">&lt;/i&gt;</ept>- page revised.&lt;br/&gt;
Setting added to select whether the app starts up showing either
<bpt id="2">&lt;ul&gt;</bpt>
&lt;li/&gt;<bpt id="3">&lt;i&gt;</bpt>Bike Locations<ept id="3">&lt;/i&gt;</ept> or
&lt;li/&gt;<bpt id="4">&lt;i&gt;</bpt>Select Bike<ept id="4">&lt;/i&gt;</ept>
<ept id="2">&lt;/ul&gt;</ept>
page.</source>
<target state="translated"><bpt id="1">&lt;i&gt;</bpt>Rad auswählen<ept id="1">&lt;/i&gt;</ept>- Seite überarbeitet.&lt;br/&gt;
Einstellung hinzugefügt mit der festgelegt werden kann, ob die App mit der Seite
<bpt id="2">&lt;ul&gt;</bpt>
&lt;li/&gt;<bpt id="3">&lt;i&gt;</bpt>Radstandorte<ept id="3">&lt;/i&gt;</ept> oder
&lt;li/&gt;<bpt id="4">&lt;i&gt;</bpt>Rad auswählen<ept id="4">&lt;/i&gt;</ept>
<ept id="2">&lt;/ul&gt;</ept>
gestartet wird.</target>
</trans-unit>
</group>
</body>
</file>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
@ -218,6 +218,12 @@ namespace TINK.ViewModel.Bikes
}
break;
case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
// Empty collection.
// Occurs in context of find bike page when searching for second, third, ... bike (reopen of page via flyout).
ClearItems();
break;
}
}
@ -442,11 +448,17 @@ namespace TINK.ViewModel.Bikes
}
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// Invoked when page is shown and starts update process.
/// </summary>
/// <param name="updateAction"> Update fuction passed as argument by child class.</param>
protected async Task OnAppearing(Action updateAction)
=> await StartUpdateTask(updateAction);
/// <summary>
/// Starts update process.
/// </summary>
/// <param name="updateAction"> Update fuction passed as argument by child class.</param>
public async Task StartUpdateTask(Action updateAction)
{
m_oViewUpdateManager = new PollingUpdateTaskManager(updateAction);
@ -465,10 +477,7 @@ namespace TINK.ViewModel.Bikes
/// Invoked when page is shutdown.
/// Currently invoked by code behind, would be nice if called by XAML in future versions.
/// </summary>
public async Task OnDisappearing()
{
await m_oViewUpdateManager.StopUpdatePeridically();
}
public virtual async Task OnDisappearing()
=> await m_oViewUpdateManager.StopUpdatePeridically();
}
}

View file

@ -13,9 +13,11 @@ using TINK.Model.Bikes;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi;
using TINK.Model.Station;
using TINK.Model.User;
using TINK.MultilingualResources;
using TINK.Repository.Exception;
using TINK.Services.BluetoothLock;
using TINK.Services.BluetoothLock.Tdo;
using TINK.Services.Geolocation;
@ -43,6 +45,7 @@ namespace TINK.ViewModel.FindBike
}
bikeIdUserInput = value;
base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(BikeIdUserInput)));
base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsSelectBikeEnabled)));
}
}
@ -123,14 +126,29 @@ namespace TINK.ViewModel.FindBike
/// </summary>
public async Task OnAppearing()
{
IsIdle = false;
Log.ForContext<FindBikePageViewModel>().Information("User request to show page FindBike- page re-appearing");
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
if (string.IsNullOrEmpty(BikeIdUserInput) /* Find bike page flyout was taped */
&& BikeCollection.Count > 0 /* Bike was successfully selected */)
{
// Find bike page flyout was taped and page was already opened before and bike has been selected.
// Clear bike collection to allow user to enter bike id and search for bike.
BikeCollection.Clear();
}
var bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
if (BikeCollection.Count > 0)
{
// Page is appearing not because page flyout was taped.
// Bike has already been selected.
// Restart update.
await StartUpdateTask(() => UpdateTask());
Exception = bikes.Exception; // Update communication error from query for bikes occupied.
Bikes = bikes.Response;
ActionText = "";
IsIdle = true;
return;
}
ActionText = "";
IsIdle = true;
@ -142,6 +160,48 @@ namespace TINK.ViewModel.FindBike
/// <summary> Select a bike by ID</summary>
public async Task SelectBike()
{
// Get List of bike to be able to connect to.
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
IsIdle = false;
Result<BikeCollection> bikes = null;
try
{
bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
}
catch (Exception exception)
{
if (exception is WebConnectFailureException)
{
// Copri server is not reachable.
Log.ForContext<FindBikePageViewModel>().Information("Getting bikes failed failed (Copri server not reachable).");
await ViewService.DisplayAdvancedAlert(
AppResources.ErrorReturnBikeNoWebTitle,
string.Format("{0}\r\n{1}", AppResources.ErrorReturnBikeNoWebMessage, WebConnectFailureException.GetHintToPossibleExceptionsReasons),
exception.Message,
AppResources.MessageAnswerOk);
}
else
{
Log.ForContext<FindBikePageViewModel>().Error("Getting bikes failed. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.MessageTitleHint,
exception.Message,
AppResources.MessageAnswerOk);
}
ActionText = "";
IsIdle = true;
return;
}
finally
{
Exception = bikes?.Exception ?? null; // Update communication error from query for bikes occupied.
Bikes = bikes.Response;
}
try
{
var selectedBike = Bikes.FirstOrDefault(x => x.Id.Equals(BikeIdUserInput.Trim(), StringComparison.OrdinalIgnoreCase));
@ -152,6 +212,9 @@ namespace TINK.ViewModel.FindBike
AppResources.MessageTitleHint,
string.Format(AppResources.MessageErrorSelectBikeNoBikeFound, BikeIdUserInput),
AppResources.MessageAnswerOk);
ActionText = "";
IsIdle = true;
return;
}
@ -193,7 +256,7 @@ namespace TINK.ViewModel.FindBike
// User decided not to give access to locations permissions.
BikeCollection.Update(bikeCollection, Stations);
//await OnAppearing(() => UpdateTask());
await StartUpdateTask(() => UpdateTask());
ActionText = "";
IsIdle = true;
@ -215,7 +278,7 @@ namespace TINK.ViewModel.FindBike
BikeCollection.Update(bikeCollection, Stations);
await OnAppearing(() => UpdateTask());
await StartUpdateTask(() => UpdateTask());
ActionText = "";
IsIdle = true;
@ -232,7 +295,7 @@ namespace TINK.ViewModel.FindBike
BikeCollection.Update(bikeCollection, Stations);
await OnAppearing(() => UpdateTask());
await StartUpdateTask(() => UpdateTask());
ActionText = "";
IsIdle = true;
@ -259,7 +322,7 @@ namespace TINK.ViewModel.FindBike
BikeCollection.Update(bikeCollection.UpdateLockInfo(locksInfo), Stations);
await OnAppearing(() => UpdateTask());
await StartUpdateTask(() => UpdateTask());
ActionText = "";
IsIdle = true;
@ -272,6 +335,9 @@ namespace TINK.ViewModel.FindBike
AppResources.MessageAnswerOk);
Log.ForContext<FindBikePageViewModel>().Error("Running command to select bike failed. {Exception}", exception);
ActionText = "";
IsIdle = true;
return;
}
}

View file

@ -1,4 +1,4 @@
using Xamarin.Forms;
using Xamarin.Forms;
using TINK.View;
using TINK.Model.Station;
using System;

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Linq;
namespace TINK.ViewModel.Settings
{
/// <summary> Manages data to be shown by a picker. </summary>
public class PickerViewModel : ServicesViewModel
{
/// <summary>Constructs view model ensuring consistency. </summary>
/// <param name="serviceToText"> Dictionary holding values and display text to mange and display by picker.</param>
/// <param name="active">Value of entry for which the display text has to be shown.</param>
public PickerViewModel(
IDictionary<string, string> serviceToText,
string active) : base(serviceToText.Select(x => x.Key), serviceToText, active)
{
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
@ -8,6 +8,7 @@ using Serilog.Events;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.User.Account;
using TINK.MultilingualResources;
using TINK.Repository.Exception;
using TINK.Services;
using TINK.Services.BluetoothLock;
@ -44,6 +45,9 @@ namespace TINK.ViewModel
/// <summary> Manages selection of locks services.</summary>
public LocksServicesViewModel LocksServices { get; }
/// <summary>Settings determining the startup behavior of the app.</summary>
public ServicesViewModel StartupSettings { get; }
/// <summary> Manages selection of geolocation services.</summary>
public ServicesViewModel GeolocationServices { get; }
@ -155,6 +159,13 @@ namespace TINK.ViewModel
{ typeof(GeolocationAccuracyBestService).FullName, "Best Accuracy" },
{ typeof(SimulatedGeolocationService).FullName, "Simulation-AlwaysSamePosition" } },
GeoloctionServicesContainer.Active.GetType().FullName);
StartupSettings = new PickerViewModel(
new Dictionary<string, string> {
{ ViewTypes.MapPage.ToString(), AppResources.MarkingMapPage },
{ ViewTypes.FindBikePage.ToString(), AppResources.MarkingFindBike },
},
tinkApp.StartupSettings.StartupPage.ToString());
}
/// <summary>
@ -259,6 +270,8 @@ namespace TINK.ViewModel
TinkApp.GroupFilterMapPage,
TinkApp.ActiveUser.DoFilter(TinkApp.FilterGroupSetting.DoFilter()));
TinkApp.StartupSettings.StartupPage = Enum.TryParse(StartupSettings.Active, out ViewTypes startupPage) ? startupPage : Model.Settings.StartupSettings.DefaultStartupPage;
TinkApp.CenterMapToCurrentLocation = CenterMapToCurrentLocation;
if (IsLogToExternalFolderVisible)

View file

@ -1,4 +1,4 @@
namespace TINK
namespace TINK
{
/// <summary> Holds a entry for each page of the TINK app.</summary>
public enum ViewTypes
@ -18,6 +18,7 @@
BikesAtStation,
ContactPage,
SelectStationPage,
MiniSurvey
MiniSurvey,
FindBikePage
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NUnit.Framework;
@ -172,5 +172,31 @@ namespace TestTINKLib.Model.Settings
settings["Theme"],
Is.EqualTo(JsonConvert.SerializeObject(typeof(TINK.Themes.Konrad).Name)));
}
[Test]
public void TestGetStartupSettingsStartupPage() => Assert.That(
JsonSettingsDictionary.GetStartupSettings(new Dictionary<string, string> {
{
"StartupSettings",
JsonConvert.SerializeObject(new StartupSettings { StartupPage = TINK.ViewTypes.ContactPage})
}
}).StartupPage,
Is.EqualTo(TINK.ViewTypes.ContactPage));
[Test]
public void TestSetStartupSettingsStartupPage()
{
var settings = JsonSettingsDictionary.SetStartupSettings(
new Dictionary<string, string>(),
new StartupSettings { StartupPage = TINK.ViewTypes.ContactPage });
Assert.That(
settings,
Contains.Key("StartupSettings"));
Assert.That(
settings["StartupSettings"],
Is.EqualTo(JsonConvert.SerializeObject(new StartupSettings { StartupPage = TINK.ViewTypes.ContactPage })));
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -15,6 +15,7 @@ using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Services;
@ -45,9 +46,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
var bluetooth = Substitute.For<IBluetoothLE>();
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -130,9 +132,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -212,9 +215,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -336,9 +340,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -463,9 +468,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -587,9 +593,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -709,9 +716,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -824,9 +832,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -902,9 +911,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -973,9 +983,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
timeOut.MultiConnect.Returns(new TimeSpan(0));
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -1054,9 +1065,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
timeOut.MultiConnect.Returns(new TimeSpan(0));
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -1128,9 +1140,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
timeOut.MultiConnect.Returns(new TimeSpan(0));
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -1218,9 +1231,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
timeOut.MultiConnect.Returns(new TimeSpan(0));
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000),
true),

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NSubstitute;
@ -14,6 +14,7 @@ using TestFramework.Services.CopriApi.Connector;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Services.CopriApi;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Services;
@ -38,6 +39,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Account
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -82,6 +84,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Account
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -125,6 +128,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Account
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -167,6 +171,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Account
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -209,6 +214,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Account
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,

View file

@ -14,6 +14,7 @@ using TestFramework.Services.CopriApi.Connector;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Services.CopriApi;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Services;
@ -34,9 +35,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -114,9 +116,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct_KonradActive()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -191,9 +194,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct_KonradOnly()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CITYBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.Off }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -263,9 +267,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct_TinkOnly()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -335,9 +340,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct_Offline()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -409,9 +415,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct_WebConnectCommunicationError()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -498,9 +505,10 @@ namespace TestShareeLib.UseCases.Startup
public async Task TestConstruct_GeneralPurposeCommunicationError()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { FilterHelper.CARGOBIKE, FilterState.On }, { FilterHelper.CITYBIKE, FilterState.On } }),
new StartupSettings(),
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -15,6 +15,7 @@ using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Services;
@ -64,6 +65,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -160,6 +162,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -264,6 +267,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -363,6 +367,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -460,6 +465,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -551,6 +557,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -617,6 +624,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -686,6 +694,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
@ -771,6 +780,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using NSubstitute;
using NUnit.Framework;
@ -9,6 +9,7 @@ using TestFramework.Model.User.Account;
using TestFramework.Services.BluetoothLock;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Services;
using TINK.Services.Geolocation;
@ -35,9 +36,10 @@ namespace TestTINKLib.Fixtures.UseCases.SelectStation
new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1));
var l_oTinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new Settings(
new TINK.ViewModel.Map.GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,