Version 3.0.338

This commit is contained in:
Anja Müller-Meißner 2022-09-06 16:08:19 +02:00 committed by Anja
parent 573fe77e12
commit 0468955d49
751 changed files with 62747 additions and 60672 deletions

View file

@ -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 #
###############################

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.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 -->

View file

@ -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>
@ -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>

View file

@ -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>

View file

@ -177,7 +177,7 @@ namespace TINK
currentVersion: appInfoService.Version,
lastVersion: lastVersion,
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion(),
appFlavor: AppFlavor.LastenradBayern);
flavor: AppFlavor.LastenradBayern);
Log.Debug("Main model successfully constructed.");
return m_oModelRoot;

View file

@ -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}}"

View file

@ -10,6 +10,7 @@ using TINK.ViewModel.Info;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TINK.Model;
namespace TINK.View.Contact
{
@ -27,8 +28,8 @@ namespace TINK.View.Contact
{
InitializeComponent();
ViewModel = new ContactPageViewModel(App.ModelRoot.Uris.ActiveUri,
AppInfo.Name,
ViewModel = new ContactPageViewModel(
App.ModelRoot.Flavor.GetDisplayName(),
() => App.CreateAttachment(),
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
this);

View file

@ -10,77 +10,48 @@
<xct:Popup.Resources>
<x:String x:Key="check_circle">&#xf058;</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>
<StackLayout>
<!-- Head and title - Grid.Row 0 -->
<Grid Grid.Row="0"
<!-- 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>
</StackLayout>
<!-- Co2saving - Grid.Row 1 -->
<!-- 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"/>
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="brockenCheckBox" IsChecked="True" HeightRequest="20"/>
<Label
Grid.Column="1"
FontSize="Medium"
Text= "{x:Static resources:AppResources.MarkingReturnBikeBikeStateIsOK}"/>
</Grid>
</StackLayout>
<Editor
Grid.Row="2"
x:Name="feedbackMessage"
AutoSize="TextChanges"
Placeholder="{x:Static resources:AppResources.MarkingReturnBikeFeedbackInputPlaceholder}"
@ -100,15 +71,14 @@
</DataTrigger>
</Editor.Triggers>
</Editor>
</Grid>
</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>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -770,7 +770,10 @@ namespace TINK.Services.BluetoothLock.BLE
State = (LockitLockingState?)state[0]
}.Build();
Log.ForContext<LockItBase>().Debug("Retrieving lock state (ReadAsync-call) succeeded.{@LockInfoTdo}{StateCharacteristic}{Reading}", lockInfoTdo, ToSerilogString(stateCharacteristic), state);
Log.ForContext<LockItBase>().Debug("Retrieving lock state (ReadAsync-call) succeeded. {@LockInfoTdo}{StateCharacteristic}{Reading}",
lockInfoTdo,
ToSerilogString(stateCharacteristic),
state);
return lockInfoTdo;
}
@ -859,19 +862,29 @@ namespace TINK.Services.BluetoothLock.BLE
/// <param name="counter"></param>
/// <param name="open"></param>
/// <returns>True if opening/ closing command could be written successfully.</returns>
protected async Task<bool> OpenCloseLock(bool open)
protected async Task<bool> OpenCloseLockAsync(bool open)
{
DeviceState deviceState;
Log.ForContext<LockItBase>().Debug("Request to get connection state in context of opening/ closing lock.");
Log.ForContext<LockItBase>().Debug(open
? "Request to get connection state in context of opening lock."
: "Request to get connection state in context of closing lock.");
try
{
deviceState = Device?.State.GetDeviceState()
?? throw new System.Exception("Can not get bluetooth device state. State must not be null.");
?? throw new System.Exception(open
? "Can not open lock. Getting bluetooth device state failed. State must not be null."
: "Can not close lock. Getting bluetooth device state failed. State must not be null.");
}
catch (System.Exception exception)
{
Log.ForContext<LockItBase>().Error("Retrieving bluetooth state failed when opening/ closing lock failed. {Exception}", exception);
throw new System.Exception($"Can not Open/ Close lock. Getting bluetooth failed. {exception.Message}", exception);
Log.ForContext<LockItBase>().Error(open
? "Retrieving bluetooth state failed when opening lock failed. {Exception}"
: "Retrieving bluetooth state failed when closing lock failed. {Exception}",
exception);
throw new System.Exception(open
? $"Can not open lock. Getting bluetooth failed. {exception.Message}"
: $"Can not close lock. Getting bluetooth failed. {exception.Message}",
exception);
}
switch (deviceState)
@ -884,16 +897,22 @@ namespace TINK.Services.BluetoothLock.BLE
default:
// Can not open lock if bluetooth state is not connected.
Log.ForContext<LockItBase>().Debug($"Can not open/ close lock. Unexpected connection state detected {deviceState}.");
Log.ForContext<LockItBase>().Debug(open
? $"Can not open lock. Unexpected connection state detected {deviceState}."
: $"Can not close lock. Unexpected connection state detected {deviceState}.");
return false;
}
Log.ForContext<LockItBase>().Debug($"Connection state before opening/ closing lock is {deviceState}.");
Log.ForContext<LockItBase>().Debug(open
? $"Connection state before opening lock is {deviceState}."
: $"Connection state before closing lock is {deviceState}.");
var activateLockCharacteristic = await GetActivateLockCharacteristicAsync();
if (activateLockCharacteristic == null)
{
Log.ForContext<LockItBase>().Debug("Getting lock control service failed.");
Log.ForContext<LockItBase>().Debug(open
? "Can not open lock. Getting lock control service failed."
: "Can not close lock. Getting lock control service failed.");
return false;
}
@ -909,8 +928,14 @@ namespace TINK.Services.BluetoothLock.BLE
catch (System.Exception exception)
{
ActivateLockWriteCounter--;
Log.ForContext<LockItBase>().Error("Encypting command to open/ close lock failed. {Exception}", exception);
throw new System.Exception($"Can not open/ close lock. Encrypting command to lock/ unlock failed. {exception.Message}", exception);
Log.ForContext<LockItBase>().Error(open
? "Encypting command to open lock failed. {Exception}"
: "Encypting command to close lock failed. {Exception}",
exception);
throw new System.Exception(open
? $"Can not open lock. Encrypting command to lock/ unlock failed. {exception.Message}"
: $"Can not close lock. Encrypting command to lock/ unlock failed. {exception.Message}",
exception);
}
bool success;
@ -924,14 +949,20 @@ namespace TINK.Services.BluetoothLock.BLE
Log.ForContext<LockItBase>().Error(open
? "Writing data to open lock failed.{ActivateLockCharacteristic}{CommandWritten}{Exception}"
: "Writing data to close lock failed.{ActivateLockCharacteristic}{CommandWritten}{Exception}",
ToSerilogString(activateLockCharacteristic), ToSerilogString(stateEnctryped), exception);
throw new System.Exception($"Can not {(open ? "open" : "close")} lock. Writing command to lock/ unlock failed. {exception.Message}", exception);
ToSerilogString(activateLockCharacteristic),
ToSerilogString(stateEnctryped),
exception);
throw new System.Exception(open
? $"Can not open lock. Writing command failed. {exception.Message}"
: $"Can not close lock. Writing command failed. {exception.Message}",
exception);
}
Log.ForContext<LockItBase>().Debug(open
? "Command to open lock written successfully.{ActivateLockCharacteristic}{CommandWritten}"
: "Command to open lock written successfully.{ActivateLockCharacteristic}{CommandWritten}",
ToSerilogString(activateLockCharacteristic), ToSerilogString(stateEnctryped));
: "Command to close lock written successfully.{ActivateLockCharacteristic}{CommandWritten}",
ToSerilogString(activateLockCharacteristic),
ToSerilogString(stateEnctryped));
return success;
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -256,13 +256,13 @@ namespace TINK.Services.BluetoothLock.BLE
if (string.IsNullOrEmpty(name))
{
// Lock without name detected.
Log.ForContext<LockItByScanServiceBase>().Debug($"Lock without name discovered.");
Log.ForContext<LockItByScanServiceBase>().Debug($"Ble decvice without name discovered. RSSI={a.Device.Rssi}, GUID={a.Device.Id}, State={a.Device.State}.");
return;
}
if (targetLocks.Where(x => x != TextToLockItTypeHelper.INVALIDLOCKID).Contains(name.GetBluetoothLockId()))
{
Log.ForContext<LockItByScanServiceBase>().Debug($"New LOCKIT device {name} discovered.");
Log.ForContext<LockItByScanServiceBase>().Debug($"New LOCKIT device {name} discovered. RSSI={a.Device.Rssi}, GUID={a.Device.Id}, State={a.Device.State}.");
newlyDiscovertedDevicesList.Add(a.Device);
@ -274,7 +274,7 @@ namespace TINK.Services.BluetoothLock.BLE
return;
}
Log.ForContext<LockItByScanServiceBase>().Verbose($"Device of unknown advertisement name {name} discovered.");
Log.ForContext<LockItByScanServiceBase>().Verbose($"Device of unknown advertisement name {name} discovered. RSSI={a.Device.Rssi}, GUID={a.Device.Id}, State={a.Device.State}.");
};
try

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Plugin.BLE.Abstractions.Contracts;
@ -71,7 +71,7 @@ namespace TINK.Services.BluetoothLock.BLE
return await Task.FromResult((LockitLockingState?)null);
}
Log.ForContext<LockItEventBased>().Debug($"Request to closed lock. Current lockikng state is {lockingState}, counter value {ActivateLockWriteCounter}.");
Log.ForContext<LockItEventBased>().Debug($"Request to open lock. Current locking state is {lockingState}, counter value {ActivateLockWriteCounter}.");
double batteryPercentage = double.NaN;
@ -102,13 +102,13 @@ namespace TINK.Services.BluetoothLock.BLE
}
catch (System.Exception ex)
{
Log.ForContext<LockItEventBased>().Error("Starting updates wen opening lock failed.{Exception}", ex);
Log.ForContext<LockItEventBased>().Error("Starting updates when opening lock failed.{Exception}", ex);
return await Task.FromResult((LockitLockingState?)null);
}
try
{
var result = await OpenCloseLock(true); // Close lock;
var result = await OpenCloseLockAsync(true); // Close lock;
if (!result)
{
@ -144,14 +144,17 @@ namespace TINK.Services.BluetoothLock.BLE
switch (lockingState.Value)
{
case LockitLockingState.Open:
Log.ForContext<LockItEventBased>().Information($"Lock was opened successfully.");
return lockingState.Value;
case LockitLockingState.CouldntOpenBoldBlocked:
// Expected error. ILockIt count not be opened (Spoke blocks lock, ....)
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Bold is blocked.");
throw new CouldntOpenBoldIsBlockedException();
case LockitLockingState.Unknown:
// Expected error. ILockIt count not be opened (Spoke has blocked/ blocks lock, ....)
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Bold was blocked.");
throw new CouldntOpenBoldWasBlockedException();
default:
@ -160,6 +163,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Unknown
// - LockitLockingState.CouldntOpenBoldBlocked
// Internal error which sould never occure. Lock refuses to open but connection is ok.
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Unexpected lock state {lockingState.Value.GetLockingState()} detected.");
throw new CouldntOpenInconsistentStateExecption(lockingState.Value.GetLockingState());
}
}
@ -219,8 +223,8 @@ namespace TINK.Services.BluetoothLock.BLE
try
{
Log.ForContext<LockItEventBased>().Debug($"Request to closed lock. Current state is {lockingState}, counter value {ActivateLockWriteCounter}.");
var result = await OpenCloseLock(false); // Close lock
Log.ForContext<LockItEventBased>().Debug($"Request to close lock. Current state is {lockingState}, counter value {ActivateLockWriteCounter}.");
var result = await OpenCloseLockAsync(false); // Close lock
if (!result)
{
// State did not change. Return previous state.
@ -254,13 +258,16 @@ namespace TINK.Services.BluetoothLock.BLE
{
case LockitLockingState.CouldntCloseBoldBlocked:
// Expected error. ILockIt could not be closed (Spoke blocks lock, ....)
Log.ForContext<LockItEventBased>().Debug($"Closing lock failed. Bold is blocked.");
throw new CouldntCloseBoldBlockedException();
case LockitLockingState.CouldntCloseMoving:
// Expected error. ILockIt could not be closed (bike is moving)
Log.ForContext<LockItEventBased>().Debug($"Closing lock failed. Bike is moving.");
throw new CouldntCloseMovingException();
case LockitLockingState.Closed:
Log.ForContext<LockItEventBased>().Information($"Lock was closed successfully.");
return lockingState;
default:
@ -269,6 +276,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Unknown
// - LockitLockingState.CouldntOpenBoldBlocked
// Internal error which sould never occurre. Lock refuses to close but connection is ok.
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Unexpected lock state {lockingState.Value.GetLockingState()} detected.");
throw new CouldntCloseInconsistentStateExecption(lockingState.Value.GetLockingState());
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Plugin.BLE.Abstractions.Contracts;
@ -69,9 +69,9 @@ namespace TINK.Services.BluetoothLock.BLE
return await Task.FromResult((LockitLockingState?)null);
}
Log.ForContext<LockItPolling>().Debug($"Request to closed lock. Current lockikng state is {info}, counter value {ActivateLockWriteCounter}.");
Log.ForContext<LockItPolling>().Debug($"Request to open lock. Current locking state is {info}, counter value {ActivateLockWriteCounter}.");
var result = await OpenCloseLock(
var result = await OpenCloseLockAsync(
true); // Close lock);
if (!result)
@ -98,25 +98,29 @@ namespace TINK.Services.BluetoothLock.BLE
&& watch.Elapsed < TimeSpan.FromMilliseconds(OPEN_CLOSE_TIMEOUT_MS))
{
info = await GetLockStateAsync(true); // While opening lock seems not always respond to reading operations.
Log.ForContext<LockItPolling>().Information($"Current lock state is {info?.State.Value}.");
Log.ForContext<LockItPolling>().Debug($"Waiting for lock to open. Current lock state is {info?.State.Value}.");
}
if (info == null)
{
Log.ForContext<LockItPolling>().Fatal($"Opening lock failed. State object is null.");
return null;
}
switch (info.State.Value)
{
case LockitLockingState.Open:
Log.ForContext<LockItPolling>().Information($"Lock was opened successfully.");
return info.State.Value;
case LockitLockingState.CouldntOpenBoldBlocked:
// Expected error. ILockIt count not be opened (Spoke blocks lock, ....)
Log.ForContext<LockItPolling>().Debug($"Opening lock failed. Bold is blocked.");
throw new CouldntOpenBoldIsBlockedException();
case LockitLockingState.Unknown:
// Expected error. ILockIt count not be opened (Spoke has blocked/ blocks lock, ....)
Log.ForContext<LockItPolling>().Debug($"Opening lock failed. Bold was blocked.");
throw new CouldntOpenBoldWasBlockedException();
default:
@ -125,6 +129,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.CouldntCloseMoving (should never happen because command open was send)
// - LockitLockingState.CouldntCloseBoldBlocked (should never happen because command open was send)
// Internal error which sould never occure. Lock refuses to open but connection is ok.
Log.ForContext<LockItPolling>().Debug($"Opening lock failed. Unexpected lock state {info.State.Value.GetLockingState()} detected.");
throw new CouldntOpenInconsistentStateExecption(info.State.Value.GetLockingState());
}
}
@ -154,9 +159,9 @@ namespace TINK.Services.BluetoothLock.BLE
return await Task.FromResult(info.State.Value);
}
Log.ForContext<LockItPolling>().Debug($"Request to closed lock. Current state is {info}, counter value {ActivateLockWriteCounter}.");
Log.ForContext<LockItPolling>().Debug($"Request to close lock. Current locking state is {info}, counter value {ActivateLockWriteCounter}.");
var result = await OpenCloseLock(false); // Close lock
var result = await OpenCloseLockAsync(false); // Close lock
if (!result)
{
// State did not change. Return previous state.
@ -183,11 +188,12 @@ namespace TINK.Services.BluetoothLock.BLE
&& watch.Elapsed < TimeSpan.FromMilliseconds(OPEN_CLOSE_TIMEOUT_MS))
{
info = await GetLockStateAsync(true); ; // While closing lock seems not always respond to reading operations.
Log.ForContext<LockItPolling>().Information($"Current lock state is {info?.State.Value}.");
Log.ForContext<LockItPolling>().Debug($"Waiting for lock to close. Current lock state is {info?.State.Value}.");
}
if (info == null)
{
Log.ForContext<LockItPolling>().Fatal($"Closing lock failed. State object is null.");
return null;
}
@ -195,14 +201,17 @@ namespace TINK.Services.BluetoothLock.BLE
{
case LockitLockingState.CouldntCloseBoldBlocked:
// Expected error. ILockIt could not be closed (Spoke blocks lock, ....)
Log.ForContext<LockItPolling>().Debug($"Closing lock failed. Bold is blocked.");
throw new CouldntCloseBoldBlockedException();
case LockitLockingState.CouldntCloseMoving:
// Expected error. ILockIt could not be closed (bike is moving)
Log.ForContext<LockItPolling>().Debug($"Closing lock failed. Bike is moving.");
throw new CouldntCloseMovingException();
case LockitLockingState.Closed:
// Everything is ok.
Log.ForContext<LockItPolling>().Information($"Lock was closed successfully.");
return info.State.Value;
default:
@ -211,6 +220,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Unknown
// - LockitLockingState.CouldntOpenBoldBlocked
// Internal error which sould never occurre. Lock refuses to close but connection is ok.
Log.ForContext<LockItPolling>().Debug($"Closing lock failed. Unexpected lock state {info.State.Value.GetLockingState()} detected.");
throw new CouldntCloseInconsistentStateExecption(info.State.Value.GetLockingState());
}
}

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.337" android:versionCode="337">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" 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 -->

View file

@ -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>
@ -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>Mein konrad</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>

View file

@ -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>Automatic</CodesignProvision>
@ -37,11 +37,12 @@
<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.Meinkonrad Development</CodesignProvision>
<CodesignKey>Apple Development: Oliver Hauff (947JH7MS9L)</CodesignKey>
<MtouchSdkVersion>15.5</MtouchSdkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
@ -52,12 +53,12 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARMv7, ARM64</MtouchArch>
<MtouchArch>ARM64</MtouchArch>
<CodesignKey>Apple Development: Oliver Hauff (947JH7MS9L)</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>VS: com.TeilRad.Meinkonrad Development</CodesignProvision>
<MtouchLink>None</MtouchLink>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchInterpreter>-all</MtouchInterpreter>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
@ -67,7 +68,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 (947JH7MS9L)</CodesignKey>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
@ -77,6 +78,7 @@
</CrashReportingApiKey>
<MtouchLink>SdkOnly</MtouchLink>
<CodesignProvision>VS: com.TeilRad.Meinkonrad Development</CodesignProvision>
<MtouchSdkVersion>15.5</MtouchSdkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
@ -202,10 +204,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>

View file

@ -175,7 +175,7 @@ namespace TINK
currentVersion: appInfoService.Version,
lastVersion: lastVersion,
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion(),
appFlavor: AppFlavor.MeinKonrad);
flavor: AppFlavor.MeinKonrad);
Log.Debug("Main model successfully constructed.");
return m_oModelRoot;

View file

@ -51,7 +51,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}}"

View file

@ -10,6 +10,7 @@ using TINK.ViewModel.Info;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TINK.Model;
namespace TINK.View.Contact
{
@ -28,8 +29,8 @@ namespace TINK.View.Contact
{
InitializeComponent();
ViewModel = new ContactPageViewModel(App.ModelRoot.Uris.ActiveUri,
AppInfo.Name,
ViewModel = new ContactPageViewModel(
App.ModelRoot.Flavor.GetDisplayName(),
() => App.CreateAttachment(),
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
this);

View file

@ -10,76 +10,47 @@
<xct:Popup.Resources>
<x:String x:Key="check_circle">&#xf058;</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>
<StackLayout>
<!-- Head and title - Grid.Row 0 -->
<Grid Grid.Row="0"
<!-- 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>
</StackLayout>
<!-- Co2saving - Grid.Row 1-->
<!-- 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"/>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Checkbox Is Broken -->
<CheckBox x:Name="brockenCheckBox" IsChecked="True"/>
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="brockenCheckBox" IsChecked="True" HeightRequest="20"/>
<Label
Grid.Column="1"
FontSize="Medium"
Text= "{x:Static resources:AppResources.MarkingReturnBikeBikeStateIsOK}"/>
</Grid>
</StackLayout>
<Editor
Grid.Row="2"
x:Name="feedbackMessage"
AutoSize="TextChanges"
Placeholder="{x:Static resources:AppResources.MarkingReturnBikeFeedbackInputPlaceholder}"
@ -99,15 +70,14 @@
</DataTrigger>
</Editor.Triggers>
</Editor>
</Grid>
</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>

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="preferExternal" package="com.hauffware.sharee" android:versionName="3.0.337" android:versionCode="337">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" 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 -->

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Before After
Before After

View file

@ -303,6 +303,18 @@
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\bike_City_SoleHumanPowered_Two.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\bike_Cargo_SoleHumanPowered_Two.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\bike_Cargo_SoleHumanPowered_Trike.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\bike_Cargo_Pedelec_Two.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\battery_undefined.png" />
</ItemGroup>

View file

@ -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>
@ -49,14 +49,14 @@
<key>CFBundleIdentifier</key>
<string>com.TeilRad.sharee.bike</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>CFBundleDisplayName</key>
<string>sharee.bike</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>

View file

@ -0,0 +1,393 @@
{
"images" : [
{
"filename" : "bike_Cargo_Pedelec_Two.svg",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal"
},
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone"
},
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 101.92409 64.545211"
version="1.1"
id="svg15"
sodipodi:docname="bike_Cargo_Pedelec_Two.svg"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
inkscape:export-filename="C:\Users\Anja\Desktop\bike_Cargo_Pedelec_Two.png"
inkscape:export-xdpi="160"
inkscape:export-ydpi="160"
width="101.9241"
height="64.545212"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="8"
inkscape:cx="30.375"
inkscape:cy="30.5"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g1756"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<defs
id="defs11">
<linearGradient
id="linearGradient21170"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop21168" />
</linearGradient>
<style
id="style2">.a{fill:url(#a);}</style>
<linearGradient
id="a"
x1="5.6700001"
y1="42.59"
x2="107.72"
y2="42.59"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#e3000f"
id="stop4" />
<stop
offset="0.35"
stop-color="#e50064"
id="stop6" />
<stop
offset="0.7"
stop-color="#e3000f"
id="stop8" />
</linearGradient>
<linearGradient
id="b"
x1="76.912148"
y1="27.697437"
x2="77.972641"
y2="32.467815"
xlink:href="#linearGradient2645"
gradientTransform="translate(-75.921777,-16.221715)" />
<linearGradient
id="linearGradient2645"
x1="29.34"
y1="42.529999"
x2="82.709999"
y2="42.529999"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#e50064"
id="stop2641" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1157">
<use
x="0"
y="0"
xlink:href="#g1153"
id="use1159"
width="100%"
height="100%" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1760">
<use
x="0"
y="0"
xlink:href="#g1756"
id="use1762"
width="100%"
height="100%" />
</clipPath>
</defs>
<g
id="g17575"
transform="translate(-0.12590681,13.468085)">
<path
style="fill:#b3b3b3;stroke:#b3b3b3;stroke-width:0.3125;stroke-linejoin:round;stroke-opacity:1"
d="m 53.10453,27.496642 c -1.365507,-4.854721 -2.472007,-8.837499 -2.458888,-8.850617 0.01312,-0.01312 0.316185,0.0202 0.67348,0.07403 0.357295,0.05384 3.855878,0.55963 7.774628,1.123984 3.91875,0.564354 10.654687,1.534491 14.96875,2.15586 4.314062,0.621369 9.039062,1.299643 10.5,1.507275 1.460937,0.207633 2.692874,0.389076 2.737637,0.403209 0.05233,0.01652 -0.304708,0.60484 -1,1.647778 -1.59254,2.388813 -5.588598,8.24135 -5.849355,8.566836 -0.423446,0.528559 -1.548293,1.593501 -1.861353,1.762224 l -0.312599,0.168475 -8.93529,0.09474 c -4.91441,0.05211 -10.019561,0.112341 -11.34478,0.133854 l -2.40949,0.03912 z"
id="path10538" />
<g
id="g1155"
clip-path="url(#clipPath1157)">
<g
inkscape:label="Clip"
id="g1153">
<g
id="g1676">
<g
inkscape:label="Clip"
id="g1756">
<path
class="a"
d="m 98.06,48.87 c -1.08675,0.002 -0.3125,0.0625 -0.3125,0.0625 l -1.25625,-9.24 v 0 c 0.04999,-0.0817 -0.33875,0.8225 0,0 -0.330139,-2.17133 -1.75335,-2.193894 -2.369308,-0.218228 L 55.676612,33.666942 51,17.66 c -0.162566,-0.361677 -0.52348,-0.593133 -0.92,-0.59 h -8 c -1.333333,0 -1.333333,2 0,2 h 7.37 l 9.4975,34.465 c 0,0 -7.891361,-0.03193 -11.774542,-0.44597 -0.253575,-0.02704 -0.760725,-1.252257 -0.760725,-1.252257 L 36.81,30.47 h 2.48 c 1.333333,0 1.333333,-2 0,-2 h -7.15 c -1.333333,0 -1.333333,2 0,2 h 2.46 l 1.28,2.84 -4.8,5.61 C 17.735485,29.534713 0.56014352,43.794826 7.3158706,58.635275 10.307452,65.206945 17.328658,68.961292 24.45441,67.797984 31.580212,66.634667 37.044172,60.842047 37.79,53.66 l 6.809262,0.06886 c 0,0 0.706271,1.019124 1.258238,1.181141 4.813226,1.41281 38.4375,0.25 38.4375,0.25 1.296848,0.0041 3.134532,-2.141688 3.855,-3.22 l 6.829277,-10.246859 0.966288,7.461018 c -7.38317,1.624614 -8.627918,8.794136 -6.702179,13.208842 1.925701,4.414616 6.815063,6.728004 11.451424,5.42055 4.63636,-1.307454 7.59673,-5.834467 6.93229,-10.604757 C 106.96264,52.408406 102.87743,48.860173 98.06,48.87 Z m -51.647767,2.966777 c -27.161489,-23.177851 -13.580744,-11.588926 0,0 z M 36.8,35.33 44.16,51.66 h -6.3 C 37.77054,47.281695 35.882608,43.133307 32.64,40.19 Z m -0.95,16.33 h -13 l 8.51,-9.95 c 2.781324,2.572511 4.401296,6.162427 4.49,9.95 z M 21.77,66 C 12.379755,65.910757 5.73832,56.784352 8.5413004,47.821822 11.344281,38.859292 22.002151,35.143146 29.77,40.42 L 19.87,52 c -0.558169,0.652484 -0.08861,1.658681 0.77,1.65 H 35.76 C 34.881746,60.707408 28.881844,66.003962 21.77,66 Z m 64.7,-15.2 c -0.342505,0.521592 -1.98852,2.365305 -2.6125,2.36125 l -22.632789,0.2431 -4.994876,-17.752706 36.905,5.316524 c 1.068416,0.132096 1.233154,-2.54192 0.987107,-1.493864 L 90.94,44.21 c -0.0052,0.02305 -0.0052,0.04695 0,0.07 z M 98.06,66.09 C 90.441219,66.14162 86.565784,53.944828 96.252291,51.02934 L 97.15,59 c 0.16695,0.350555 0.521731,0.57278 0.91,0.57 0.148015,6.4e-5 0.294434,-0.03058 0.43,-0.09 0.517009,-0.223359 0.747671,-0.829412 0.51,-1.34 l -0.91,-7.27 c 0.752402,-0.24499 -0.791283,1.44e-4 0,0 4.20289,0 7.61,3.407113 7.61,7.61 0,4.202887 -3.40711,7.61 -7.61,7.61 z"
transform="translate(-5.67,-17.07)"
id="path13"
style="fill:#000000"
sodipodi:nodetypes="cccccccccssccsccsssscccssccsccccsssccccccccccccccscccccccccccccsccccccccss" />
<path
class="b"
d="m 24.754995,-9.3865128 -7.33214,-3.7397952 c -1.512762,-0.785808 -3.34742,-0.170262 -4.087906,1.371589 l -0.63309,1.256408 -4.0089251,-2.171341 c -2.1332702,-1.318731 -3.2138586,0.795626 -1.0131331,1.669574 l 4.0799312,2.3431428 -1.9279665,3.984418 -4.3335107,-2.0965059 c -1.889426,-1.1455656 -3.000817,0.8618846 -0.969749,1.7112586 l 4.4164471,2.2261306 -0.560302,1.2851591 c -0.215908,0.46059 -0.322424,0.96784597 -0.31104,1.48098397 0.0062,1.14296103 0.6635559,2.18548893 1.6827393,2.66870793 l 7.4979008,3.821812 c 3.121621,1.939052 6.029839,0.384269 7.90617,-2.602122 0.521472,-0.829975 0.885647,-1.386181 1.179185,-1.882121 0.07188,-0.12137 4.493305,2.327998 4.625114,2.342684 0.485864,0.05413 1.920831,-0.315256 0.870928,-1.809358 -0.133947,-0.190626 -4.441543,-2.22771893 -4.516806,-2.41140593 -0.130626,-0.318832 0.301309,-1.08736197 0.378436,-1.31973797 1.373204,-4.1372931 0.574222,-6.3585284 -2.942284,-8.1294875 z M 22.616378,3.4933391 c -0.960278,1.5200657 -2.834395,2.077363 -4.303829,1.204932 l -8.237875,-4.58987893 5.634421,-11.64934817 4.343249,2.1491121 -0.161627,2.339236 -5.600275,4.941352 4.970173,0.054161 -1.425714,4.638675 4.172274,-5.9531713 -4.203141,-0.027851 2.086683,-3.653166 0.161627,-2.3392361 3.889954,1.9248139 c 1.60516,0.664411 2.627869,2.1531545 2.20324,3.9092814 -0.690684,3.01533371 -1.800506,4.8140634 -3.52916,7.0510878 z"
id="path16"
sodipodi:nodetypes="cccccccccccccccsssssscccccccccccccccccc"
style="fill-opacity:1;stroke-width:1.53824" />
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8 KiB

View file

@ -0,0 +1,393 @@
{
"images" : [
{
"filename" : "bike_Cargo_SoleHumanPowered_Trike.svg",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal"
},
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone"
},
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 91.801248 51.357448"
version="1.1"
id="svg15"
sodipodi:docname="bike_Cargo_SoleHumanPowered_Trike.svg"
width="91.801247"
height="51.357449"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
inkscape:export-filename="C:\Users\Anja\Desktop\bike_Cargo_SoleHumanPowered_Trike.png"
inkscape:export-xdpi="160"
inkscape:export-ydpi="160"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="5.8317717"
inkscape:cx="34.46637"
inkscape:cy="11.660264"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg15"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<defs
id="defs11">
<style
id="style2">.a{fill:url(#a);}</style>
<linearGradient
id="a"
x1="11.34"
y1="42.59"
x2="102.05"
y2="42.59"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#e3000f"
id="stop4" />
<stop
offset="0.35"
stop-color="#e50064"
id="stop6" />
<stop
offset="0.7"
stop-color="#e3000f"
id="stop8" />
</linearGradient>
</defs>
<path
class="a"
d="M 48.016289,12.218801 45.096078,0.59 C 44.93499,0.231641 44.578977,8.2e-4 44.186078,0 h -8 c -1.333333,0 0.30636,3.2976596 0,2 h 7.31 l 7.791377,34.208096 -9.995186,0.0306 L 30.966078,13.4 h 2.46 c 1.333333,0 1.333333,-2 0,-2 h -7.1 c -1.333333,0 0.615878,3.18257 0,2 h 2.45 l 1.27,2.84 -4.78,5.61 c -2.690366,-1.941909 -5.922018,-2.991147 -9.24,-3 C 2.1885842,18.854233 -5.1179525,35.231658 4.1200482,45.532232 13.358048,55.832805 30.43125,50.345426 31.936078,36.59 c 0,0 3.143177,-0.0024 6.912435,0.04183 0,0 0.595033,1.753983 2.40706,1.746618 C 46.298177,38.357953 57.696078,38.22 57.696078,38.22 c -0.08852,0.539303 0.01804,-0.546221 0,0 -0.201334,7.19541 5.57678,13.137449 12.775,13.137449 7.19822,0 12.976334,-5.942039 12.775,-13.137449 -0.0015,-0.545138 -0.03819,-1.08961 -0.11,-1.63 h 0.07 c 1.688893,0.0074 3.180011,-1.100733 3.66,-2.72 L 90.364604,21.725697 C 90.981744,19.947459 91.085635,19.19495 91.286825,18.2944 78.095021,16.184174 61.720902,14.259525 48.016289,12.218801 Z M 30.946078,18.26 l 7.32,16.33 h -6.26 c -0.08291,-4.3735 -1.959474,-8.52075 -5.19,-11.47 z m -0.94,16.33 h -12.94 l 8.46,-9.95 c 2.777628,2.574224 4.393892,6.163916 4.48,9.95 z m -13.98,14.34 c -7.7513218,0 -14.0349938,-6.283684 -14.0349938,-14.035 0,-7.751316 6.283672,-14.035 14.0349938,-14.035 2.839528,-0.0048 5.611711,0.864573 7.94,2.49 l -9.83,11.58 c -0.558169,0.652484 -0.08861,1.658681 0.77,1.65 h 15 c -0.835032,7.035815 -6.794815,12.338649 -13.88,12.35 z m 54.704343,0.36008 c -9.643334,0.03568 -14.374032,-12.301066 -7.651182,-18.957144 6.852019,-6.783963 17.658402,-1.700595 18.16397,7.471246 0.01659,5.964685 -4.548103,11.469352 -10.512788,11.485898 z M 88.696078,21.2 l -3.7,12.09 c -0.230581,0.773408 -0.942955,1.3026 -1.75,1.3 h -0.49 c -3.184372,-10.948285 -18.039946,-12.53136 -23.46,-2.5 l -1.524323,3.987808 -4.626021,0.08287 -4.805923,-22.165049 38.765642,5.167498 c 0.529506,0.07076 1.929985,0.469696 1.929985,0.469696 0,0 -0.19484,1.049698 -0.33936,1.567177 z"
id="path13"
sodipodi:nodetypes="cccssccccssssccccsccsccscccccccccccccccccscccccccsccccccccccccc"
style="fill:#000000" />
<path
style="fill:#999999;stroke:#000000;stroke-width:0.606254;stroke-linejoin:round"
d="M 53.220207,36.107626 C 53.112163,35.67535 48.428326,14.1175 48.438406,14.098881 c 0.04051,-0.07484 39.038877,5.189778 39.724278,5.362608 l 0.801507,0.202109 -0.114537,0.565454 c -0.23382,1.154332 -4.005865,13.303935 -4.226723,13.6141 -0.243717,0.342269 -1.019677,0.713316 -1.491739,0.713316 -0.239157,0 -0.327556,-0.120613 -0.555413,-0.757817 -1.310086,-3.663656 -4.237805,-6.541672 -7.898702,-7.764603 -4.540999,-1.516931 -9.586601,-0.442985 -12.944334,2.755176 -1.561782,1.48756 -2.2544,2.597661 -3.220065,5.16099 -0.389405,1.033663 -0.741743,1.913511 -0.782974,1.955218 -0.07332,0.07416 -4.491978,0.272286 -4.509497,0.202194 z"
id="path2372" />
<ellipse
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:3.09276;stroke-linejoin:round"
id="path849"
cx="70.464157"
cy="38.653477"
rx="1.5"
ry="1.4999988" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -0,0 +1,393 @@
{
"images" : [
{
"filename" : "bike_Cargo_SoleHumanPowered_Two.svg",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal"
},
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone"
},
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 102.05 51.02"
version="1.1"
id="svg15"
sodipodi:docname="icon_lastenrad.svg"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="27"
inkscape:cy="-8.75"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg15" />
<defs
id="defs11">
<style
id="style2">.a{fill:url(#a);}</style>
<linearGradient
id="a"
x1="5.67"
y1="42.59"
x2="107.72"
y2="42.59"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#e3000f"
id="stop4" />
<stop
offset="0.35"
stop-color="#e50064"
id="stop6" />
<stop
offset="0.7"
stop-color="#e3000f"
id="stop8" />
</linearGradient>
</defs>
<path
class="a"
d="m 98.06,48.87 c -1.08675,0.002 -0.3125,0.0625 -0.3125,0.0625 l -1.25625,-9.24 v 0 c 0.04999,-0.0817 -0.33875,0.8225 0,0 -0.330139,-2.17133 -1.75335,-2.193894 -2.369308,-0.218228 L 55.676612,33.666942 51,17.66 c -0.162566,-0.361677 -0.52348,-0.593133 -0.92,-0.59 h -8 c -1.333333,0 -1.333333,2 0,2 h 7.37 l 9.4975,34.465 c 0,0 -7.891361,-0.03193 -11.774542,-0.44597 -0.253575,-0.02704 -0.760725,-1.252257 -0.760725,-1.252257 L 36.81,30.47 h 2.48 c 1.333333,0 1.333333,-2 0,-2 h -7.15 c -1.333333,0 -1.333333,2 0,2 h 2.46 l 1.28,2.84 -4.8,5.61 C 17.735485,29.534713 0.56014352,43.794826 7.3158706,58.635275 10.307452,65.206945 17.328658,68.961292 24.45441,67.797984 31.580212,66.634667 37.044172,60.842047 37.79,53.66 l 6.809262,0.06886 c 0,0 0.706271,1.019124 1.258238,1.181141 4.813226,1.41281 38.4375,0.25 38.4375,0.25 1.296848,0.0041 3.134532,-2.141688 3.855,-3.22 l 6.829277,-10.246859 0.966288,7.461018 c -7.38317,1.624614 -8.627918,8.794136 -6.702179,13.208842 1.925701,4.414616 6.815063,6.728004 11.451424,5.42055 4.63636,-1.307454 7.59673,-5.834467 6.93229,-10.604757 C 106.96264,52.408406 102.87743,48.860173 98.06,48.87 Z m -51.647767,2.966777 c -27.161489,-23.177851 -13.580744,-11.588926 0,0 z M 36.8,35.33 44.16,51.66 h -6.3 C 37.77054,47.281695 35.882608,43.133307 32.64,40.19 Z m -0.95,16.33 h -13 l 8.51,-9.95 c 2.781324,2.572511 4.401296,6.162427 4.49,9.95 z M 21.77,66 C 12.379755,65.910757 5.73832,56.784352 8.5413004,47.821822 11.344281,38.859292 22.002151,35.143146 29.77,40.42 L 19.87,52 c -0.558169,0.652484 -0.08861,1.658681 0.77,1.65 H 35.76 C 34.881746,60.707408 28.881844,66.003962 21.77,66 Z m 64.7,-15.2 c -0.342505,0.521592 -1.98852,2.365305 -2.6125,2.36125 l -22.632789,0.2431 -4.994876,-17.752706 36.905,5.316524 c 1.068416,0.132096 1.233154,-2.54192 0.987107,-1.493864 L 90.94,44.21 c -0.0052,0.02305 -0.0052,0.04695 0,0.07 z M 98.06,66.09 C 90.441219,66.14162 86.565784,53.944828 96.252291,51.02934 L 97.15,59 c 0.16695,0.350555 0.521731,0.57278 0.91,0.57 0.148015,6.4e-5 0.294434,-0.03058 0.43,-0.09 0.517009,-0.223359 0.747671,-0.829412 0.51,-1.34 l -0.91,-7.27 c 0.752402,-0.24499 -0.791283,1.44e-4 0,0 4.20289,0 7.61,3.407113 7.61,7.61 0,4.202887 -3.40711,7.61 -7.61,7.61 z"
transform="translate(-5.67,-17.07)"
id="path13"
style="fill:#000000"
sodipodi:nodetypes="cccccccccssccsccsssscccssccsccccsssccccccccccccccscccccccccccccsccccccccss" />
<path
style="fill:#b3b3b3;stroke:#b3b3b3;stroke-width:0.3125;stroke-linejoin:round;stroke-opacity:1"
d="m 53.10453,27.496642 c -1.365507,-4.854721 -2.472007,-8.837499 -2.458888,-8.850617 0.01312,-0.01312 0.316185,0.0202 0.67348,0.07403 0.357295,0.05384 3.855878,0.55963 7.774628,1.123984 3.91875,0.564354 10.654687,1.534491 14.96875,2.15586 4.314062,0.621369 9.039062,1.299643 10.5,1.507275 1.460937,0.207633 2.692874,0.389076 2.737637,0.403209 0.05233,0.01652 -0.304708,0.60484 -1,1.647778 -1.59254,2.388813 -5.588598,8.24135 -5.849355,8.566836 -0.423446,0.528559 -1.548293,1.593501 -1.861353,1.762224 l -0.312599,0.168475 -8.93529,0.09474 c -4.91441,0.05211 -10.019561,0.112341 -11.34478,0.133854 l -2.40949,0.03912 z"
id="path10538" />
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -0,0 +1,393 @@
{
"images" : [
{
"filename" : "bike_City_SoleHumanPowered_Two.svg",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal"
},
{
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
},
{
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone"
},
{
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x"
},
{
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x"
},
{
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x"
},
{
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "1x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "2x",
"subtype" : "retina4"
},
{
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "iphone",
"scale" : "3x",
"subtype" : "retina4"
},
{
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad"
},
{
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "1x"
},
{
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "ipad",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "2x"
},
{
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "light"
}
],
"idiom" : "car",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "car",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 80.537954 51.365249"
version="1.1"
id="svg15"
sodipodi:docname="bike_City_SoleHumanPowered_Two.svg"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
width="80.537956"
height="51.36525"
inkscape:export-filename="C:\Users\Anja\Desktop\bike_City_SoleHumanPowered_Two.png"
inkscape:export-xdpi="160"
inkscape:export-ydpi="160"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview17"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="4.7152334"
inkscape:cx="21.207858"
inkscape:cy="-19.935386"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg15"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<defs
id="defs11">
<style
id="style2">.a{fill:url(#a);}</style>
<linearGradient
id="a"
x1="17.049999"
y1="42.639999"
x2="96.379997"
y2="42.639999"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
stop-color="#e3000f"
id="stop4" />
<stop
offset="0.35"
stop-color="#e50064"
id="stop6" />
<stop
offset="0.7"
stop-color="#e3000f"
id="stop8" />
</linearGradient>
</defs>
<path
class="a"
d="M 65.61155,34.882754 C 59.860052,21.645078 56.372737,12.535602 50.494929,0.58000308 50.33089,0.22554908 49.9755,-9.6292241e-4 49.584929,3.0775894e-6 h -8 c -1.333333,0 -1.333333,2.0000000224106 0,2.0000000224106 h 7.34 l 6.163711,13.3422209 -24.901865,1.393763 1.22369,2.013909 24.426816,-1.456587 C 47.0108,26.450616 47.48674,26.220333 40.690515,33.792942 37.128789,28.327805 30.485433,16.964001 27.284929,11.510003 h 2.26 c 1.333333,0 1.333333,-1.9999999 0,-1.9999999 h -7.12 c -1.333333,0 -1.333333,1.9999999 0,1.9999999 h 2.59 c 0.01476,0.09121 0.04521,0.179181 0.09,0.26 l 3.67,6.27 c -0.02908,0.02042 -0.0559,0.04389 -0.08,0.07 l -3,3.49 C 12.193953,12.00822 -5.2991211,26.430709 1.5266829,41.510267 c 3.021776,6.675705 10.1428891,10.496994 17.3754021,9.322314 7.232564,-1.174688 12.779588,-7.053511 13.532844,-14.342578 6.165532,0.08103 7.249282,0.576389 9.187264,-0.547377 l 15.27392,-16.834241 c 1.329007,3.177414 7.040596,16.581344 7.040596,16.581344 2.101982,1.482199 1.674841,-0.806975 1.674841,-0.806975 z m -35.756621,-15.002751 8.59,14.65 h -5.93 c -0.07159,-4.440483 -1.970829,-8.654995 -5.25,-11.65 z m 0.66,14.65 h -13.26 l 8.7,-10.12 c 2.824032,2.602606 4.469816,6.240654 4.56,10.08 z m -14.22,14.51 C 6.6775779,49.054516 -0.18809906,39.728144 2.6827189,30.549316 5.5535359,21.370487 16.509767,17.618186 24.404929,23.110003 l -10.08,11.77 c -0.230655,0.279688 -0.291874,0.662307 -0.16,1 0.164039,0.354454 0.519429,0.580966 0.91,0.58 h 15.35 c -0.845626,7.166018 -6.914269,12.568957 -14.13,12.58 z m 50.81,-9.81 c -44.693333,-26.153333 -22.346667,-13.076667 0,0 z"
id="path13"
sodipodi:nodetypes="cccsscccccccsssscccccsscccsccccccccccccscccccccc"
style="fill:#000000" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.95112;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path870"
cx="64.579956"
cy="35.406952"
rx="14.982438"
ry="14.982738" />
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -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.sharee.bike Development</CodesignProvision>
@ -37,11 +37,12 @@
<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.sharee.bike Development</CodesignProvision>
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
<MtouchSdkVersion>15.5</MtouchSdkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>true</DebugSymbols>
@ -52,12 +53,12 @@
<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>
<CodesignProvision>VS: com.TeilRad.sharee.bike Development</CodesignProvision>
<MtouchLink>None</MtouchLink>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchInterpreter>-all</MtouchInterpreter>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
@ -67,7 +68,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 +78,7 @@
<CrashReportingApiKey>
</CrashReportingApiKey>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchSdkVersion>15.5</MtouchSdkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
@ -202,10 +204,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>
@ -375,6 +377,30 @@
<ImageAsset Include="Media.xcassets\AppIcons.appiconset\1024-1.png">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_Cargo_Pedelec_Two.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_Cargo_Pedelec_Two.imageset\bike_Cargo_Pedelec_Two.svg">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_Cargo_SoleHumanPowered_Trike.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_Cargo_SoleHumanPowered_Trike.imageset\bike_Cargo_SoleHumanPowered_Trike.svg">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_Cargo_SoleHumanPowered_Two.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_Cargo_SoleHumanPowered_Two.imageset\bike_Cargo_SoleHumanPowered_Two.svg">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_City_SoleHumanPowered_Two.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\bike_City_SoleHumanPowered_Two.imageset\bike_City_SoleHumanPowered_Two.svg">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\battery_0_5.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
@ -432,6 +458,10 @@
<Folder Include="Media.xcassets\battery_4_5.imageset\" />
<Folder Include="Media.xcassets\battery_5_5.imageset\" />
<Folder Include="Media.xcassets\battery_undefined.imageset\" />
<Folder Include="Media.xcassets\bike_Cargo_Pedelec_Two.imageset\" />
<Folder Include="Media.xcassets\bike_Cargo_SoleHumanPowered_Trike.imageset\" />
<Folder Include="Media.xcassets\bike_Cargo_SoleHumanPowered_Two.imageset\" />
<Folder Include="Media.xcassets\bike_City_SoleHumanPowered_Two.imageset\" />
<Folder Include="Media.xcassets\Open_Blue.imageset\" />
<Folder Include="Media.xcassets\Open_Green.imageset\" />
<Folder Include="Media.xcassets\Open_LightBlue.imageset\" />

View file

@ -176,7 +176,7 @@ namespace TINK
currentVersion: appInfoService.Version,
lastVersion: lastVersion,
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion(),
appFlavor: AppFlavor.ShareeBike);
flavor: AppFlavor.ShareeBike);
Log.Debug("Main model successfully constructed.");
return m_oModelRoot;

View file

@ -14,23 +14,42 @@
</ContentView.Resources>
<StackLayout
Padding="10">
<!-- Name of the bike -->
<Label
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Center"
Text="{Binding Name}"/>
<!-- Id of the bike -->
<Label
FontAttributes="Bold"
HorizontalTextAlignment="Center"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
<Grid Padding="0,0,5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Icon of the bike -->
<Image
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"
HorizontalOptions="Start"
VerticalOptions="End"
Grid.Column="0"/>
<!-- Battery level -->
<sharedGui:BarLevelView
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
Grid.Column="1"
VerticalOptions="End"
IsVisible="{Binding IsBatteryChargeVisible}"/>
<!-- Name of the bike -->
<StackLayout Grid.Column="1" Grid.ColumnSpan="2">
<Label
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
<!-- Id of the bike -->
<Label
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
</StackLayout>
</Grid>
<!-- Rental state -->
<Label
Text="{Binding StateText}"

View file

@ -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}}"

View file

@ -10,6 +10,7 @@ using TINK.ViewModel.Info;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TINK.Model;
namespace TINK.View.Contact
{
@ -28,8 +29,8 @@ namespace TINK.View.Contact
{
InitializeComponent();
ViewModel = new ContactPageViewModel(App.ModelRoot.Uris.ActiveUri,
AppInfo.Name,
ViewModel = new ContactPageViewModel(
App.ModelRoot.Flavor.GetDisplayName(),
() => App.CreateAttachment(),
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
this);

View file

@ -10,76 +10,48 @@
<xct:Popup.Resources>
<x:String x:Key="check_circle">&#xf058;</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
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>
</StackLayout>
<!-- Co2saving - Grid.Row 1 -->
<!-- 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"/>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Checkbox Is Broken -->
<CheckBox x:Name="brockenCheckBox" IsChecked="True"/>
<StackLayout Orientation="Horizontal">
<CheckBox x:Name="brockenCheckBox" IsChecked="True" HeightRequest="20"/>
<Label
Grid.Column="1"
FontSize="Medium"
Text= "{x:Static resources:AppResources.MarkingReturnBikeBikeStateIsOK}"/>
</Grid>
</StackLayout>
<Editor
Grid.Row="2"
x:Name="feedbackMessage"
AutoSize="TextChanges"
Placeholder="{x:Static resources:AppResources.MarkingReturnBikeFeedbackInputPlaceholder}"
@ -99,15 +71,14 @@
</DataTrigger>
</Editor.Triggers>
</Editor>
</Grid>
</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>

View file

@ -24,7 +24,7 @@
Route="MapPage"
ContentTemplate="{DataTemplate mappage:MapPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconMap}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconMap}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -34,7 +34,7 @@
IsVisible="{Binding IsFindBikePageVisible}"
ContentTemplate="{DataTemplate findbike:FindBikePage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconFindBike}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconFindBike}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -44,7 +44,7 @@
IsVisible="{Binding IsMyBikesPageVisible}"
ContentTemplate="{DataTemplate mybikes:MyBikesPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconMyBikes}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconMyBikes}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -54,7 +54,7 @@
IsVisible="{Binding IsAccountPageVisible}"
ContentTemplate="{DataTemplate account:AccountPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconAccount}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconAccount}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -65,7 +65,7 @@
IsVisible="{Binding IsLoginPageVisible}"
ContentTemplate="{DataTemplate login:LoginPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconLogin}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconLogin}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -75,7 +75,7 @@
IsVisible="{Binding IsSettingsPageVisible}"
ContentTemplate="{DataTemplate settings:SettingsPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconSettings}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconSettings}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -84,7 +84,7 @@
Title="{x:Static resources:AppResources.MarkingFeesAndBikes}"
ContentTemplate="{DataTemplate contact:FeesAndBikesPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconFeesAndBikes}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconFeesAndBikes}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -94,7 +94,7 @@
Route="ContactPage"
ContentTemplate="{DataTemplate contact:ContactPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconContact}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconContact}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
@ -103,7 +103,7 @@
Title="{Binding TabbedPageIngoTitle}"
ContentTemplate="{DataTemplate info:InfoPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconInfo}" Color="Black" FontFamily="FA-S" />
<FontImageSource Glyph="{StaticResource IconInfo}" Color="{DynamicResource Key=primary-back-title-color}" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>

View file

@ -1,21 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
BackgroundColor="{DynamicResource Key=primary-back-title-color}"
BackgroundColor="LightGray"
x:Class="TINK.View.RootShell.FlyoutHeader">
<Grid Padding="5,10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Image
HeightRequest="140"
Aspect="AspectFit"
Source="sharee_no_background.png" />
<Label
HorizontalOptions="CenterAndExpand"
FontSize="Large"
Grid.Row="1"
<StackLayout Orientation="Horizontal"
VerticalOptions="Center"
HeightRequest="100">
<Label HorizontalOptions="EndAndExpand"
VerticalOptions="CenterAndExpand"
FontSize="Title"
FontAttributes="Bold"
TextColor="DimGray"
Text="{Binding MasterDetailMenuTitlte}"/>
</Grid>
<Image HeightRequest="90"
WidthRequest="90"
Aspect="AspectFit"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
Source="sharee_no_background.png"/>
</StackLayout>
</ContentView>

View file

@ -31,5 +31,10 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
public LockInfoMutable LockInfo { get; }
ILockInfoMutable IBikeInfoMutable.LockInfo => LockInfo;
public new string ToString()
{
return $"Id={Id}{(TypeOfBike != null ? $";type={TypeOfBike}" : "")};state={State}";
}
}
}

View file

@ -95,6 +95,9 @@ namespace TINK.Model
/// <summary> Holds the different lock service implementations.</summary>
LocksServicesContainerMutable LocksServices { get; }
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or Lastenrad Bayern.</summary>
AppFlavor Flavor { get; }
/// <summary> Holds available app themes.</summary>
ServicesContainerMutable Themes { get; }

View file

@ -175,7 +175,7 @@ namespace TINK.Model
Version currentVersion = null,
Version lastVersion = null,
Version whatsNewShownInVersion = null,
AppFlavor appFlavor = AppFlavor.ShareeBike)
AppFlavor flavor = AppFlavor.ShareeBike)
{
PostAction = postAction
?? ((d, obj) => d(obj));
@ -188,6 +188,8 @@ namespace TINK.Model
Cipher = cipher ?? new Cipher();
Flavor = flavor;
var locksServices = locksService != null
? new HashSet<ILocksService> { locksService }
: new HashSet<ILocksService> {
@ -286,7 +288,7 @@ namespace TINK.Model
IsReportLevelVerbose = settings.IsReportLevelVerbose;
WhatsNew = new WhatsNew(AppVersion, lastVersion, whatsNewShownInVersion, appFlavor, SmartDevice.Platform);
WhatsNew = new WhatsNew(AppVersion, lastVersion, whatsNewShownInVersion, Flavor, SmartDevice.Platform);
if (Themes.Active.GetType().FullName == typeof(Themes.ShareeBike).FullName)
{
@ -382,6 +384,9 @@ namespace TINK.Model
/// <summary> Holds available app themes.</summary>
public IServicesContainer<IGeolocation> GeolocationServices { get; }
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or Lastenrad Bayern.</summary>
public AppFlavor Flavor { get; private set; }
/// <summary> Manages the different types of LocksService objects.</summary>
public ServicesContainerMutable Themes { get; private set; }
@ -437,6 +442,8 @@ namespace TINK.Model
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(levelSwitch)
.MinimumLevel.Override("TINK.Services.BluetoothLock.BLE", LogEventLevel.Debug) /* Scanning, connect and management functionality */
.MinimumLevel.Override("TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler", LogEventLevel.Information) /* Provides use case context */
.WriteTo.Debug()
.WriteTo.File(logFilePath, Logging.RollingInterval.Session)
.WriteTo.Logger(lg => lg

View file

@ -574,6 +574,16 @@ namespace TINK.Model
new Version(3, 0, 337),
AppResources.ChangeLog_MinorBugFixes,
new List<AppFlavor> { AppFlavor.LastenradBayern }
},
{
new Version(3, 0, 338),
AppResources.ChangeLog3_0_338_LB_MK,
new List<AppFlavor> { AppFlavor.LastenradBayern, AppFlavor.MeinKonrad }
},
{
new Version(3, 0, 338),
AppResources.ChangeLog3_0_338_SB,
new List<AppFlavor> { AppFlavor.ShareeBike }
}
};

View file

@ -1184,6 +1184,32 @@ namespace TINK.MultilingualResources {
}
}
/// <summary>
/// Looks up a localized string similar to Besides minor bug fixes we have simplified the contact procedure:
///- For acute questions/problems about the bike or rental process, please contact the fleet operator.
///- For communication with the app developers, select &quot;Feedback about the App&quot;.
///To better analyze and improve processes in the app, please accept attaching your log file to your message. We appreciate both critical and positive feedback!.
/// </summary>
public static string ChangeLog3_0_338_LB_MK {
get {
return ResourceManager.GetString("ChangeLog3_0_338_LB_MK", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Besides minor bug fixes we have simplified the contact procedure:
///- For acute questions/problems about the bike or rental process, please contact the fleet operator.
///- For communication with the app developers, select &quot;Feedback about the App&quot;.
///To better analyze and improve processes in the app, please accept attaching your log file to your message. We appreciate both critical and positive feedback!
///
///In addition: Small graphics let you see at a glance what type of bike it is..
/// </summary>
public static string ChangeLog3_0_338_SB {
get {
return ResourceManager.GetString("ChangeLog3_0_338_SB", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to query available bikes..
/// </summary>
@ -1194,7 +1220,7 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Lock of rented bike cannot be be connected right now..
/// Looks up a localized string similar to Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again..
/// </summary>
public static string ErrorBookedSearchMessage {
get {
@ -1203,11 +1229,7 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Lock of rented bike cannot be be connected right now.
///If the bike is nearby:
///- restart app and repeat action
///- restart phone and repeat action
///to connect the lock..
/// Looks up a localized string similar to Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process..
/// </summary>
public static string ErrorBookedSearchMessageEscalationLevel1 {
get {
@ -1216,19 +1238,12 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Lock of rented bike cannot be be connected right now.
///If the bike is nearby:
///- restart app and repeat action
///- restart phone and repeat action
///to connect the lock.
/// Looks up a localized string similar to Unfortunately, it is still not possible to establish a connection between your mobile device and the bike lock. Please contact customer support.
///
///Return bike manually.
///Steps 1: Close lock manually if lock is still open
///- close app
///- press on button at the top of the lock until it starts blinking
///- wait until lock is closed completely
///Step 2:
///- contact support regarding manual locking please to terminate rent.
///As a last resort, please close the lock by hand AND contact customer support so that they can terminate your chargeable rental. To do this:
///1. close the app,
///2. press the button at the top of the lock briefly and quickly release it as soon as it starts flashing,
///3. wait until the lock is completely closed and remains closed..
/// </summary>
public static string ErrorBookedSearchMessageEscalationLevel2 {
get {
@ -1455,7 +1470,7 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Lock of reserved bike can not be found..
/// Looks up a localized string similar to Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again..
/// </summary>
public static string ErrorReservedSearchMessage {
get {
@ -1464,11 +1479,7 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Lock of reserved bike cannot be be connected right now.
///If the bike is nearby:
///- restart app and repeat action
///- restart phone and repeat action
///to connect the lock.
/// Looks up a localized string similar to Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process..
/// </summary>
public static string ErrorReservedSearchMessageEscalationLevel1 {
get {
@ -2697,6 +2708,15 @@ namespace TINK.MultilingualResources {
}
}
/// <summary>
/// Looks up a localized string similar to No, do not attach file.
/// </summary>
public static string QuestionSupportmailAnswerNo {
get {
return ResourceManager.GetString("QuestionSupportmailAnswerNo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} request.
/// </summary>
@ -2707,7 +2727,9 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Attach file containing diagnosis information to mail?.
/// Looks up a localized string similar to I hereby consent to the transmission of my log file.
///
///The log file contains your app usage data as well as system information. The data will only be used for diagnostic purposes or to improve the app..
/// </summary>
public static string QuestionSupportmailAttachment {
get {
@ -2724,6 +2746,15 @@ namespace TINK.MultilingualResources {
}
}
/// <summary>
/// Looks up a localized string similar to Consent.
/// </summary>
public static string QuestionSupportmailTitle {
get {
return ResourceManager.GetString("QuestionSupportmailTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Question.
/// </summary>
@ -2876,5 +2907,23 @@ namespace TINK.MultilingualResources {
return ResourceManager.GetString("StatusTextReservationExpiredRemaining", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}-app request.
/// </summary>
public static string SupportmailSubjectAppmail {
get {
return ResourceManager.GetString("SupportmailSubjectAppmail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} request.
/// </summary>
public static string SupportmailSubjectOperatormail {
get {
return ResourceManager.GetString("SupportmailSubjectOperatormail", resourceCulture);
}
}
}
}

View file

@ -106,10 +106,10 @@
<value>Schloss kann erst geschlossen werden, wenn Rad nicht mehr bewegt wird. Bitte Rad abstellen und Vorgang wiederholen.</value>
</data>
<data name="ErrorBookedSearchMessage" xml:space="preserve">
<value>Das Schloss des gemieteten Rads kann im Moment nicht verbunden werden.</value>
<value>Ihr mobiles Gerät verbindet sich nicht mit dem Fahrradschloss. Bitte treten Sie möglichst nah an das Rad heran und probieren Sie es erneut. </value>
</data>
<data name="ErrorReservedSearchMessage" xml:space="preserve">
<value>Schloss des reservierten Rads kann nicht gefunden werden.</value>
<value>Ihr mobiles Gerät verbindet sich nicht mit dem Fahrradschloss. Bitte treten Sie möglichst nah an das Rad heran und probieren Sie es erneut. </value>
</data>
<data name="ActivityTextBikesAtStationGetBikes" xml:space="preserve">
<value>Lade Räder an Station...</value>
@ -170,7 +170,9 @@ Eine Radrückgabe ist nur möglich, wenn das Rad in Reichweite ist und Standorti
<value>Ja</value>
</data>
<data name="QuestionSupportmailAttachment" xml:space="preserve">
<value>Soll der Mail eine Datei mit Diagnoseinformationen angehängt werden?</value>
<value>Hiermit stimme ich der Übermittlung meiner Protokolldatei zu.
Die Protokolldatei enthält Ihre App-Nutzungsdaten sowie Systeminformationen. Die Daten werden ausschließlich für Diagnosezwecke bzw. Verbesserung der App verwendet.</value>
</data>
<data name="QuestionTitle" xml:space="preserve">
<value>Frage</value>
@ -750,11 +752,7 @@ Fehlerbehebung: Supportmails können wieder verschickt werden.</value>
<value>Fehlerbehebung: App schließt sich nicht mehr auf Fahrrad Wählen-Seite.</value>
</data>
<data name="ErrorBookedSearchMessageEscalationLevel1" xml:space="preserve">
<value>Das Schloss des gemieteten Fahrrads kann im Moment nicht verbunden werden.
Wenn das Fahrrad in der Nähe ist:
- App neu starten und Vorgang wiederholen
- Telefon neu starten und Vorgang wiederholen
um das Schloss zu verbinden.</value>
<value>Ihr mobiles Gerät verbindet sich immer noch nicht mit dem Fahrradschloss. Bitte starten Sie die App oder sogar Ihr mobiles Gerät neu und wiederholen Sie den Vorgang.</value>
</data>
<data name="MessageAnswerCancel" xml:space="preserve">
<value>Abbrechen</value>
@ -766,19 +764,12 @@ um das Schloss zu verbinden.</value>
<value>Fehler beim Verbinden mit Schloss!</value>
</data>
<data name="ErrorBookedSearchMessageEscalationLevel2" xml:space="preserve">
<value>Das Schloss des gemieteten Fahrrads kann im Moment nicht verbunden werden.
Wenn das Fahrrad in der Nähe ist:
- App neu starten und Vorgang wiederholen
- Telefon neu starten und Vorgang wiederholen
um das Schloss zu verbinden.
<value>Es kann leider weiterhin keine Verbindung zwischen Ihrem mobilen Gerät und dem Fahrradschloss aufgebaut werden. Bitte kontaktieren Sie den Kundensupport.
Manuelle Fahrradrückgabe.
Schitt 1: Schloss manuell schließen wenn nötig. Dazu
- App schließen
- auf den Knopf oben am Schloss drücken, bis dieser zu blinken beginnt
- warten, bis das Schloss vollständig geschlossen ist
Schritt 2:
- Support bitte bezüglich der manuellen Schließung kontaktieren um Miete abzuschließen</value>
Als aller letzten Ausweg das Schloss bitte per Hand schließen UND den Kundensupport zu kontaktieren, damit dieser Ihre kostenpflichtige Miete beenden kann. Dazu:
1. App schließen,
2. auf den Knopf oben am Schloss kurz drücken und schnell loslassen sobald bis dieser zu blinken beginnt,
3. warten, bis das Schloss vollständig geschlossen ist und geschlossen bleibt. </value>
</data>
<data name="ChangeLog3_0_278" xml:space="preserve">
<value>Hinweise hinzugefügt, um das Schließen des Schlosses zu erleichtern, falls dies nicht beim ersten Versuch gelingt.</value>
@ -828,11 +819,7 @@ Schritt 2:
- die Standorterkennung deaktiviert ist.</value>
</data>
<data name="ErrorReservedSearchMessageEscalationLevel1" xml:space="preserve">
<value>Das Schloss des reservierten Fahrrads kann im Moment nicht verbunden werden.
Wenn das Fahrrad in der Nähe ist:
- App neu starten und Vorgang wiederholen
- Telefon neu starten und Vorgang wiederholen
um das Schloss zu verbinden.</value>
<value>Ihr mobiles Gerät verbindet sich immer noch nicht mit dem Fahrradschloss. Bitte starten Sie die App oder sogar Ihr mobiles Gerät neu und wiederholen Sie den Vorgang.</value>
</data>
<data name="ChangeLog3_0_282" xml:space="preserve">
<value>Freigabe-Erlaubnisanfragen unter iOS ausführlicher formuliert.
@ -1007,4 +994,30 @@ Kleinere Fehlerbehebungen.
<data name="ChangeLog_MinorBugFixes" xml:space="preserve">
<value>Wir haben einige Fehler behoben. Genießen Sie die Fahrt!</value>
</data>
<data name="ChangeLog3_0_338_LB_MK" xml:space="preserve">
<value>Neben kleineren Fehlerbehebungen haben wir die Kontaktaufnahme vereinfacht:
- Bei akuten Fragen/Problemen zum Rad bzw. Mietvorgang bitte den Flottenbetreiber kontaktieren.
- Für eine Kommunikation mit den App-Entwicklern, wählen Sie "Rückmeldung zur App".
Um Prozesse in der App besser analysieren und verbessern zu können, akzeptieren Sie bitte das Anhängen Ihrer Protokolldatei an Ihre Nachricht. Wir freuen uns sowohl über kritische als auch über positive Rückmeldungen!</value>
</data>
<data name="ChangeLog3_0_338_SB" xml:space="preserve">
<value>Neben kleineren Fehlerbehebungen haben wir die Kontaktaufnahme vereinfacht:
- Bei akuten Fragen/Problemen zum Rad bzw. Mietvorgang bitte den Flottenbetreiber kontaktieren.
- Für eine Kommunikation mit den App-Entwicklern, wählen Sie "Rückmeldung zur App".
Um Prozesse in der App besser analysieren und verbessern zu können, akzeptieren Sie bitte das Anhängen Ihrer Protokolldatei an Ihre Nachricht. Wir freuen uns sowohl über kritische als auch über positive Rückmeldungen!
Außerdem: Kleine Grafiken lassen auf einen Blick erkennen um was für einen Rad-Typ es sich handelt.</value>
</data>
<data name="SupportmailSubjectAppmail" xml:space="preserve">
<value>{0}-App Anfrage</value>
</data>
<data name="SupportmailSubjectOperatormail" xml:space="preserve">
<value>{0} Anfrage</value>
</data>
<data name="QuestionSupportmailAnswerNo" xml:space="preserve">
<value>Nein, Datei nicht anhängen</value>
</data>
<data name="QuestionSupportmailTitle" xml:space="preserve">
<value>Einwilligung</value>
</data>
</root>

View file

@ -148,7 +148,7 @@
<value>Loading Stations and Bikes...</value>
</data>
<data name="ErrorBookedSearchMessage" xml:space="preserve">
<value>Lock of rented bike cannot be be connected right now.</value>
<value>Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again.</value>
</data>
<data name="ErrorCloseLockBoldBlockedMessage" xml:space="preserve">
<value>Lock is blocked. Please ensure that no spoke or any other obstacle prevents the lock from closing and try again.</value>
@ -157,7 +157,7 @@
<value>Lock can only be closed if bike is not moving. Please park bike and try again.</value>
</data>
<data name="ErrorReservedSearchMessage" xml:space="preserve">
<value>Lock of reserved bike can not be found.</value>
<value>Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again.</value>
</data>
<data name="ErrorReturnBikeLockClosedNoGPSMessage" xml:space="preserve">
<value>Returning bike at an unknown location is not possible.
@ -267,7 +267,9 @@ Please login to app once again.</value>
<value>{0} request</value>
</data>
<data name="QuestionSupportmailAttachment" xml:space="preserve">
<value>Attach file containing diagnosis information to mail?</value>
<value>I hereby consent to the transmission of my log file.
The log file contains your app usage data as well as system information. The data will only be used for diagnostic purposes or to improve the app.</value>
</data>
<data name="QuestionSupportmailSubject" xml:space="preserve">
<value>Does your request/ comment relate to the {0}-app or to a more general subject?</value>
@ -845,11 +847,7 @@ Bugfix: Sending support mails works again. </value>
<value>Bugfix: No more closing of app on Select Bike page.</value>
</data>
<data name="ErrorBookedSearchMessageEscalationLevel1" xml:space="preserve">
<value>Lock of rented bike cannot be be connected right now.
If the bike is nearby:
- restart app and repeat action
- restart phone and repeat action
to connect the lock.</value>
<value>Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process.</value>
</data>
<data name="MessageAnswerCancel" xml:space="preserve">
<value>Cancel</value>
@ -861,19 +859,12 @@ to connect the lock.</value>
<value>Error when connecting with lock!</value>
</data>
<data name="ErrorBookedSearchMessageEscalationLevel2" xml:space="preserve">
<value>Lock of rented bike cannot be be connected right now.
If the bike is nearby:
- restart app and repeat action
- restart phone and repeat action
to connect the lock.
<value>Unfortunately, it is still not possible to establish a connection between your mobile device and the bike lock. Please contact customer support.
Return bike manually.
Steps 1: Close lock manually if lock is still open
- close app
- press on button at the top of the lock until it starts blinking
- wait until lock is closed completely
Step 2:
- contact support regarding manual locking please to terminate rent</value>
As a last resort, please close the lock by hand AND contact customer support so that they can terminate your chargeable rental. To do this:
1. close the app,
2. press the button at the top of the lock briefly and quickly release it as soon as it starts flashing,
3. wait until the lock is completely closed and remains closed.</value>
</data>
<data name="ChangeLog3_0_278" xml:space="preserve">
<value>Hints added to ease closing of lock in case closing does not succeed on first try.</value>
@ -921,11 +912,7 @@ Step 2:
- location is off.</value>
</data>
<data name="ErrorReservedSearchMessageEscalationLevel1" xml:space="preserve">
<value>Lock of reserved bike cannot be be connected right now.
If the bike is nearby:
- restart app and repeat action
- restart phone and repeat action
to connect the lock</value>
<value>Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process.</value>
</data>
<data name="ChangeLog3_0_282" xml:space="preserve">
<value>Permission requests messages on iOS formulated in more detail.
@ -1099,4 +1086,30 @@ Minor bugfixes.</value>
<data name="ChangeLog_MinorBugFixes" xml:space="preserve">
<value>We have fixed some bugs. Enjoy the ride!</value>
</data>
<data name="ChangeLog3_0_338_LB_MK" xml:space="preserve">
<value>Besides minor bug fixes we have simplified the contact procedure:
- For acute questions/problems about the bike or rental process, please contact the fleet operator.
- For communication with the app developers, select "Feedback about the App".
To better analyze and improve processes in the app, please accept attaching your log file to your message. We appreciate both critical and positive feedback!</value>
</data>
<data name="ChangeLog3_0_338_SB" xml:space="preserve">
<value>Besides minor bug fixes we have simplified the contact procedure:
- For acute questions/problems about the bike or rental process, please contact the fleet operator.
- For communication with the app developers, select "Feedback about the App".
To better analyze and improve processes in the app, please accept attaching your log file to your message. We appreciate both critical and positive feedback!
In addition: Small graphics let you see at a glance what type of bike it is.</value>
</data>
<data name="SupportmailSubjectAppmail" xml:space="preserve">
<value>{0}-app request</value>
</data>
<data name="SupportmailSubjectOperatormail" xml:space="preserve">
<value>{0} request</value>
</data>
<data name="QuestionSupportmailAnswerNo" xml:space="preserve">
<value>No, do not attach file</value>
</data>
<data name="QuestionSupportmailTitle" xml:space="preserve">
<value>Consent</value>
</data>
</root>

View file

@ -131,12 +131,12 @@
<target state="final">Schloss kann erst geschlossen werden, wenn Rad nicht mehr bewegt wird. Bitte Rad abstellen und Vorgang wiederholen.</target>
</trans-unit>
<trans-unit id="ErrorBookedSearchMessage" translate="yes" xml:space="preserve">
<source>Lock of rented bike cannot be be connected right now.</source>
<target state="translated">Das Schloss des gemieteten Rads kann im Moment nicht verbunden werden.</target>
<source>Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again.</source>
<target state="translated">Ihr mobiles Gerät verbindet sich nicht mit dem Fahrradschloss. Bitte treten Sie möglichst nah an das Rad heran und probieren Sie es erneut. </target>
</trans-unit>
<trans-unit id="ErrorReservedSearchMessage" translate="yes" xml:space="preserve">
<source>Lock of reserved bike can not be found.</source>
<target state="translated">Schloss des reservierten Rads kann nicht gefunden werden.</target>
<source>Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again.</source>
<target state="translated">Ihr mobiles Gerät verbindet sich nicht mit dem Fahrradschloss. Bitte treten Sie möglichst nah an das Rad heran und probieren Sie es erneut. </target>
</trans-unit>
<trans-unit id="ActivityTextBikesAtStationGetBikes" translate="yes" xml:space="preserve">
<source>Loading bikes located at station...</source>
@ -219,8 +219,12 @@ Eine Radrückgabe ist nur möglich, wenn das Rad in Reichweite ist und Standorti
<target state="translated">Ja</target>
</trans-unit>
<trans-unit id="QuestionSupportmailAttachment" translate="yes" xml:space="preserve">
<source>Attach file containing diagnosis information to mail?</source>
<target state="translated">Soll der Mail eine Datei mit Diagnoseinformationen angehängt werden?</target>
<source>I hereby consent to the transmission of my log file.
The log file contains your app usage data as well as system information. The data will only be used for diagnostic purposes or to improve the app.</source>
<target state="translated">Hiermit stimme ich der Übermittlung meiner Protokolldatei zu.
Die Protokolldatei enthält Ihre App-Nutzungsdaten sowie Systeminformationen. Die Daten werden ausschließlich für Diagnosezwecke bzw. Verbesserung der App verwendet.</target>
</trans-unit>
<trans-unit id="QuestionTitle" translate="yes" xml:space="preserve">
<source>Question</source>
@ -1007,16 +1011,8 @@ Fehlerbehebung: Supportmails können wieder verschickt werden.</target>
<target state="translated">Fehlerbehebung: App schließt sich nicht mehr auf Fahrrad Wählen-Seite.</target>
</trans-unit>
<trans-unit id="ErrorBookedSearchMessageEscalationLevel1" translate="yes" xml:space="preserve">
<source>Lock of rented bike cannot be be connected right now.
If the bike is nearby:
- restart app and repeat action
- restart phone and repeat action
to connect the lock.</source>
<target state="translated">Das Schloss des gemieteten Fahrrads kann im Moment nicht verbunden werden.
Wenn das Fahrrad in der Nähe ist:
- App neu starten und Vorgang wiederholen
- Telefon neu starten und Vorgang wiederholen
um das Schloss zu verbinden.</target>
<source>Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process.</source>
<target state="translated">Ihr mobiles Gerät verbindet sich immer noch nicht mit dem Fahrradschloss. Bitte starten Sie die App oder sogar Ihr mobiles Gerät neu und wiederholen Sie den Vorgang.</target>
</trans-unit>
<trans-unit id="MessageAnswerCancel" translate="yes" xml:space="preserve">
<source>Cancel</source>
@ -1031,32 +1027,18 @@ um das Schloss zu verbinden.</target>
<target state="translated">Fehler beim Verbinden mit Schloss!</target>
</trans-unit>
<trans-unit id="ErrorBookedSearchMessageEscalationLevel2" translate="yes" xml:space="preserve">
<source>Lock of rented bike cannot be be connected right now.
If the bike is nearby:
- restart app and repeat action
- restart phone and repeat action
to connect the lock.
<source>Unfortunately, it is still not possible to establish a connection between your mobile device and the bike lock. Please contact customer support.
Return bike manually.
Steps 1: Close lock manually if lock is still open
- close app
- press on button at the top of the lock until it starts blinking
- wait until lock is closed completely
Step 2:
- contact support regarding manual locking please to terminate rent</source>
<target state="translated">Das Schloss des gemieteten Fahrrads kann im Moment nicht verbunden werden.
Wenn das Fahrrad in der Nähe ist:
- App neu starten und Vorgang wiederholen
- Telefon neu starten und Vorgang wiederholen
um das Schloss zu verbinden.
As a last resort, please close the lock by hand AND contact customer support so that they can terminate your chargeable rental. To do this:
1. close the app,
2. press the button at the top of the lock briefly and quickly release it as soon as it starts flashing,
3. wait until the lock is completely closed and remains closed.</source>
<target state="translated">Es kann leider weiterhin keine Verbindung zwischen Ihrem mobilen Gerät und dem Fahrradschloss aufgebaut werden. Bitte kontaktieren Sie den Kundensupport.
Manuelle Fahrradrückgabe.
Schitt 1: Schloss manuell schließen wenn nötig. Dazu
- App schließen
- auf den Knopf oben am Schloss drücken, bis dieser zu blinken beginnt
- warten, bis das Schloss vollständig geschlossen ist
Schritt 2:
- Support bitte bezüglich der manuellen Schließung kontaktieren um Miete abzuschließen</target>
Als aller letzten Ausweg das Schloss bitte per Hand schließen UND den Kundensupport zu kontaktieren, damit dieser Ihre kostenpflichtige Miete beenden kann. Dazu:
1. App schließen,
2. auf den Knopf oben am Schloss kurz drücken und schnell loslassen sobald bis dieser zu blinken beginnt,
3. warten, bis das Schloss vollständig geschlossen ist und geschlossen bleibt. </target>
</trans-unit>
<trans-unit id="ChangeLog3_0_278" translate="yes" xml:space="preserve">
<source>Hints added to ease closing of lock in case closing does not succeed on first try.</source>
@ -1123,16 +1105,8 @@ Schritt 2:
- die Standorterkennung deaktiviert ist.</target>
</trans-unit>
<trans-unit id="ErrorReservedSearchMessageEscalationLevel1" translate="yes" xml:space="preserve">
<source>Lock of reserved bike cannot be be connected right now.
If the bike is nearby:
- restart app and repeat action
- restart phone and repeat action
to connect the lock</source>
<target state="translated">Das Schloss des reservierten Fahrrads kann im Moment nicht verbunden werden.
Wenn das Fahrrad in der Nähe ist:
- App neu starten und Vorgang wiederholen
- Telefon neu starten und Vorgang wiederholen
um das Schloss zu verbinden.</target>
<source>Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process.</source>
<target state="translated">Ihr mobiles Gerät verbindet sich immer noch nicht mit dem Fahrradschloss. Bitte starten Sie die App oder sogar Ihr mobiles Gerät neu und wiederholen Sie den Vorgang.</target>
</trans-unit>
<trans-unit id="ChangeLog3_0_282" translate="yes" xml:space="preserve">
<source>Permission requests messages on iOS formulated in more detail.
@ -1370,6 +1344,46 @@ Kleinere Fehlerbehebungen.
<source>We have fixed some bugs. Enjoy the ride!</source>
<target state="translated">Wir haben einige Fehler behoben. Genießen Sie die Fahrt!</target>
</trans-unit>
<trans-unit id="ChangeLog3_0_338_LB_MK" translate="yes" xml:space="preserve">
<source>Besides minor bug fixes we have simplified the contact procedure:
- For acute questions/problems about the bike or rental process, please contact the fleet operator.
- For communication with the app developers, select "Feedback about the App".
To better analyze and improve processes in the app, please accept attaching your log file to your message. We appreciate both critical and positive feedback!</source>
<target state="translated">Neben kleineren Fehlerbehebungen haben wir die Kontaktaufnahme vereinfacht:
- Bei akuten Fragen/Problemen zum Rad bzw. Mietvorgang bitte den Flottenbetreiber kontaktieren.
- Für eine Kommunikation mit den App-Entwicklern, wählen Sie "Rückmeldung zur App".
Um Prozesse in der App besser analysieren und verbessern zu können, akzeptieren Sie bitte das Anhängen Ihrer Protokolldatei an Ihre Nachricht. Wir freuen uns sowohl über kritische als auch über positive Rückmeldungen!</target>
</trans-unit>
<trans-unit id="ChangeLog3_0_338_SB" translate="yes" xml:space="preserve">
<source>Besides minor bug fixes we have simplified the contact procedure:
- For acute questions/problems about the bike or rental process, please contact the fleet operator.
- For communication with the app developers, select "Feedback about the App".
To better analyze and improve processes in the app, please accept attaching your log file to your message. We appreciate both critical and positive feedback!
In addition: Small graphics let you see at a glance what type of bike it is.</source>
<target state="translated">Neben kleineren Fehlerbehebungen haben wir die Kontaktaufnahme vereinfacht:
- Bei akuten Fragen/Problemen zum Rad bzw. Mietvorgang bitte den Flottenbetreiber kontaktieren.
- Für eine Kommunikation mit den App-Entwicklern, wählen Sie "Rückmeldung zur App".
Um Prozesse in der App besser analysieren und verbessern zu können, akzeptieren Sie bitte das Anhängen Ihrer Protokolldatei an Ihre Nachricht. Wir freuen uns sowohl über kritische als auch über positive Rückmeldungen!
Außerdem: Kleine Grafiken lassen auf einen Blick erkennen um was für einen Rad-Typ es sich handelt.</target>
</trans-unit>
<trans-unit id="SupportmailSubjectAppmail" translate="yes" xml:space="preserve">
<source>{0}-app request</source>
<target state="translated">{0}-App Anfrage</target>
</trans-unit>
<trans-unit id="SupportmailSubjectOperatormail" translate="yes" xml:space="preserve">
<source>{0} request</source>
<target state="translated">{0} Anfrage</target>
</trans-unit>
<trans-unit id="QuestionSupportmailAnswerNo" translate="yes" xml:space="preserve">
<source>No, do not attach file</source>
<target state="translated">Nein, Datei nicht anhängen</target>
</trans-unit>
<trans-unit id="QuestionSupportmailTitle" translate="yes" xml:space="preserve">
<source>Consent</source>
<target state="translated">Einwilligung</target>
</trans-unit>
</group>
</body>
</file>

View file

@ -46,7 +46,7 @@
<PackageReference Include="Xam.Plugins.Messaging" Version="5.2.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.3" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2515" />
<PackageReference Include="Xamarin.Forms.GoogleMaps" Version="3.3.0" />
<PackageReference Include="Xamarin.Forms.GoogleMaps" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="NETStandard.Library" Version="2.0.3" />

View file

@ -8,7 +8,6 @@ using TINK.Model;
using TINK.MultilingualResources;
using TINK.Repository.Exception;
using TINK.View;
using TINK.ViewModel.Info;
using TINK.ViewModel.Settings;
namespace TINK.ViewModel.Account
@ -280,7 +279,7 @@ namespace TINK.ViewModel.Account
{
await m_oViewService.DisplayAlert(
AppResources.MessageLogoutErrorTitle,
string.Format(AppResources.MessageAppVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
string.Format(AppResources.MessageAppVersionIsOutdated, TinkApp.Flavor.GetDisplayName()),
AppResources.MessageAnswerOk);
// Restart polling again.

View file

@ -36,7 +36,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
IUser activeUser) : base(
selectedBike,
AppResources.ActionReturn, // Copri button text "Miete beenden"
true, // Show button to enabled returning of bike.
false, // Do no more allow to return bike.
isConnectedDelegate,
connectorFactory,
geolocation,

View file

@ -159,7 +159,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
}
else if (exception is OutOfReachException)
{
Log.ForContext<BookedDisconnected>().Debug("Lock can not be found. {Exception}", exception);
Log.ForContext<BookedDisconnected>().Debug("Lock can not be found because out of reach. {Exception}", exception);
continueConnect = await ViewService.DisplayAlert(
AppResources.MessageConnectLockErrorTitle,

View file

@ -236,7 +236,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
}
else if (exception is OutOfReachException)
{
Log.ForContext<ReservedDisconnected>().Debug("Lock state can not be retrieved. {Exception}", exception);
Log.ForContext<ReservedDisconnected>().Debug("Lock can not be found because out of reach.. {Exception}", exception);
continueConnect = await ViewService.DisplayAlert(
AppResources.MessageErrorConnectTitle,

View file

@ -5,7 +5,6 @@ using System.Threading.Tasks;
using System.Windows.Input;
using Plugin.Messaging;
using Serilog;
using TINK.Model.Services.CopriApi.ServerUris;
using TINK.Model.Station;
using TINK.MultilingualResources;
using TINK.View;
@ -28,10 +27,8 @@ namespace TINK.ViewModel.Info
/// <summary> Station selected by user. </summary>
private IStation SelectedStation { get; set; } = new NullStation();
Uri ActiveUri { get; }
/// <summary> Holds the name of the app (sharee.bike, Mein konrad, ...)</summary>
string AppName { get; }
string AppFlavorName { get; }
/// <summary> Holds a reference to the external trigger service. </summary>
private Action OpenUrlInExternalBrowser { get; }
@ -42,20 +39,17 @@ namespace TINK.ViewModel.Info
public event PropertyChangedEventHandler PropertyChanged;
/// <summary> Constructs a contact page view model. </summary>
/// <param name="appFlavorName">Holds the name of the app.</param>
/// <param name="openUrlInExternalBrowser">Action to open an external browser.</param>
/// <param name="viewService">View service to notify user.</param>
public ContactPageViewModel(
Uri activeUri,
string appName,
string appFlavorName,
Func<string> createAttachment,
Action openUrlInExternalBrowser,
IViewService viewService)
{
ActiveUri = activeUri
?? throw new ArgumentException("Can not instantiate contact page view model- object. No active uri available.");
AppName = !string.IsNullOrEmpty(appName)
? appName
AppFlavorName = !string.IsNullOrEmpty(appFlavorName)
? appFlavorName
: throw new ArgumentException("Can not instantiate contact page view model- object. No app name availalbe.");
CreateAttachment = createAttachment
@ -90,26 +84,7 @@ namespace TINK.ViewModel.Info
}
/// <summary> Command object to bind mail button to view model. </summary>
public ICommand OnMailRequest
=> new Command(
async () =>
{
if (await DoSendMailToOperator())
{
// Mail sent to operator or no mailer availble.
return;
}
await DoSendMailAppRelated(
new List<string> { MailAddressText },
MailAddressText.ToUpper() != APPSUPPORTMAILADDRESS.ToUpper()
? new List<string> { APPSUPPORTMAILADDRESS }
: new List<string>());
},
() => IsSendMailAvailable);
/// <summary> Command object to bind mail app releated button to model. </summary>
public ICommand OnSendAppFeedbackMailRequest
public ICommand OnMailToOperatorRequest
=> new Command(
async () => await DoSendMailToOperator(),
() => IsSendMailAvailable);
@ -117,7 +92,7 @@ namespace TINK.ViewModel.Info
/// <summary> Command object to bind mail app releated button to model. </summary>
public ICommand OnMailAppRelatedRequest
=> new Command(
async () => await DoSendMailAppRelated(new List<string> { APPSUPPORTMAILADDRESS }, new List<string>()),
async () => await DoSendMailAppRelated(),
() => IsSendMailAvailable);
/// <summary>True if sending mail is possible.</summary>
@ -146,32 +121,43 @@ namespace TINK.ViewModel.Info
=> MailAddressText.Length > 0 || PhoneNumberText.Length > 0;
/// <returns> Returns true if eithe mail was sent or if no mailer available.</returns>
public async Task<bool> DoSendMailToOperator()
public async Task DoSendMailToOperator()
{
try
{
if (!IsSendMailAvailable)
{
// Nothing to do because email can not be sent.
return true;
return;
}
// Ask whether mail is operator or app specific.
var operatorRelatedMail = await ViewService.DisplayAlert(
AppResources.QuestionTitle,
string.Format(AppResources.QuestionSupportmailSubject, GetAppName(ActiveUri)),
string.Format(AppResources.QuestionSupportmailAnswerOperator, GetAppName(ActiveUri)),
string.Format(AppResources.QuestionSupportmailAnswerApp, GetAppName(ActiveUri)));
string.Format(AppResources.QuestionSupportmailSubject, AppFlavorName),
string.Format(AppResources.QuestionSupportmailAnswerOperator, AppFlavorName),
string.Format(AppResources.QuestionSupportmailAnswerApp, AppFlavorName));
if (operatorRelatedMail)
{
// Send operator related support mail.
await Email.ComposeAsync(new EmailMessage { To = new List<string> { MailAddressText }, Subject = $"{GetAppName(ActiveUri)} Anfrage" });
return true;
// Send operator related support mail to operator.
await Email.ComposeAsync(new EmailMessage
{
To = new List<string> { MailAddressText },
Subject = string.Format(AppResources.SupportmailSubjectOperatormail, AppFlavorName)
});
return;
}
return false;
// Send app-related related support mail to operator.
await Email.ComposeAsync(new EmailMessage
{
To = new List<string> { MailAddressText },
Cc = APPSUPPORTMAILADDRESS.ToUpper() != MailAddressText.ToUpper() ? new List<string> { APPSUPPORTMAILADDRESS } : new List<string>(),
Subject = string.Format(AppResources.SupportmailSubjectAppmail, AppFlavorName)
});
return;
}
catch (Exception exception)
{
@ -181,28 +167,27 @@ namespace TINK.ViewModel.Info
AppResources.ErrorSupportmailMailingFailed,
exception.Message,
AppResources.MessageAnswerOk);
return true;
return;
}
}
/// <summary> Request to send a app related mail. </summary>
public async Task DoSendMailAppRelated(List<string> to, List<string> cc)
public async Task DoSendMailAppRelated()
{
try
{
// Send app related mail
// Ask for permission to append diagnostics.
var appendFile = false;
appendFile = await ViewService.DisplayAlert(
AppResources.QuestionTitle,
AppResources.QuestionSupportmailTitle,
AppResources.QuestionSupportmailAttachment,
AppResources.QuestionAnswerYes,
AppResources.QuestionAnswerNo);
AppResources.QuestionSupportmailAnswerNo);
var message = new EmailMessage
{
To = to,
Cc = cc,
Subject = $"{GetAppName(ActiveUri)}-App Anfrage"
To = new List<string> { APPSUPPORTMAILADDRESS },
Subject = string.Format(AppResources.SupportmailSubjectAppmail, AppFlavorName)
};
if (appendFile == false)
@ -225,7 +210,8 @@ namespace TINK.ViewModel.Info
AppResources.ErrorSupportmailCreateAttachment,
exception.Message,
AppResources.MessageAnswerOk);
Log.Error("An error occurred creating attachment. {@Exception)", exception);
Log.ForContext<ContactPageViewModel>().Error("An error occurred creating attachment for app mail. {@Exception)", exception);
}
if (!string.IsNullOrEmpty(logFileName))
@ -238,7 +224,7 @@ namespace TINK.ViewModel.Info
}
catch (Exception exception)
{
Log.Error("An unexpected error occurred sending mail. {@Exception}", exception);
Log.ForContext<ContactPageViewModel>().Error("An unexpected error occurred sending mail. {@Exception}", exception);
await ViewService.DisplayAdvancedAlert(
AppResources.MessageWaring,
AppResources.ErrorSupportmailMailingFailed,
@ -332,9 +318,9 @@ namespace TINK.ViewModel.Info
{
get
{
var l_oHint = new FormattedString();
l_oHint.Spans.Add(new Span { Text = string.Format(AppResources.MessageRateMail, AppName) });
return l_oHint;
var hint = new FormattedString();
hint.Spans.Add(new Span { Text = string.Format(AppResources.MessageRateMail, AppFlavorName) });
return hint;
}
}
@ -364,28 +350,10 @@ namespace TINK.ViewModel.Info
var l_oHint = new FormattedString();
l_oHint.Spans.Add(new Span
{
Text = string.Format(AppResources.MessagePhoneMail, GetAppName(ActiveUri)) + $"{(OfficeHoursText.Length > 0 ? $" {OfficeHoursText}" : string.Empty)}"
Text = string.Format(AppResources.MessagePhoneMail, AppFlavorName) + $"{(OfficeHoursText.Length > 0 ? $" {OfficeHoursText}" : string.Empty)}"
});
return l_oHint;
}
}
/// <summary>Gets the application name.</summary>
public static string GetAppName(Uri activeUri)
{
switch (activeUri.AbsoluteUri)
{
case CopriServerUriList.TINK_DEVEL:
case CopriServerUriList.TINK_LIVE:
return "TINK";
case CopriServerUriList.SHAREE_DEVEL:
case CopriServerUriList.SHAREE_LIVE:
return "sharee.bike";
default:
return "Teilrad";
}
}
}
}

View file

@ -19,7 +19,6 @@ using TINK.Services.Permissions;
using Xamarin.Essentials;
using System.Threading;
using TINK.MultilingualResources;
using TINK.ViewModel.Info;
using TINK.Repository;
using TINK.Services.Geolocation;
using TINK.Model.State;
@ -353,7 +352,7 @@ namespace TINK.ViewModel.Contact
{
await ViewService.DisplayAlert(
AppResources.MessageWaring,
string.Format(AppResources.MessageCopriVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
string.Format(AppResources.MessageCopriVersionIsOutdated, TinkApp.Flavor.GetDisplayName()),
AppResources.MessageAnswerOk);
Log.ForContext<SelectStationPageViewModel>().Error($"Outdated version of app detected. Version expected is {resultStationsAndBikes.Response.StationsAll.CopriVersion}.");
@ -363,7 +362,7 @@ namespace TINK.ViewModel.Contact
{
await ViewService.DisplayAlert(
AppResources.MessageWaring,
string.Format(AppResources.MessageAppVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
string.Format(AppResources.MessageAppVersionIsOutdated, TinkApp.Flavor.GetDisplayName()),
AppResources.MessageAnswerOk);
Log.ForContext<SelectStationPageViewModel>().Error($"Outdated version of app detected. Version expected is {resultStationsAndBikes.Response.StationsAll.CopriVersion}.");

View file

@ -12,7 +12,6 @@ using TINK.Model.User.Account;
using TINK.MultilingualResources;
using TINK.Repository.Exception;
using TINK.View;
using TINK.ViewModel.Info;
using TINK.ViewModel.Map;
using Xamarin.Forms;
@ -258,7 +257,9 @@ namespace TINK.ViewModel
{
await m_oViewService.DisplayAlert(
AppResources.MessageLoginErrorTitle,
string.Format(AppResources.MessageAppVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
string.Format(
AppResources.MessageAppVersionIsOutdated,
TinkApp.Flavor.GetDisplayName()),
AppResources.MessageAnswerOk);
return;

View file

@ -23,7 +23,6 @@ using Xamarin.Essentials;
using System.Threading;
using TINK.MultilingualResources;
using TINK.Services.BluetoothLock;
using TINK.ViewModel.Info;
using TINK.Repository;
using TINK.Services.Geolocation;
using TINK.Model.State;
@ -460,7 +459,7 @@ namespace TINK.ViewModel.Map
{
await ViewService.DisplayAlert(
AppResources.MessageWaring,
string.Format(AppResources.MessageCopriVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
string.Format(AppResources.MessageCopriVersionIsOutdated, TinkApp.Flavor.GetDisplayName()),
AppResources.MessageAnswerOk);
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {stations.CopriVersion}.");
@ -470,7 +469,7 @@ namespace TINK.ViewModel.Map
{
await ViewService.DisplayAlert(
AppResources.MessageWaring,
string.Format(AppResources.MessageAppVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
string.Format(AppResources.MessageAppVersionIsOutdated, TinkApp.Flavor.GetDisplayName()),
AppResources.MessageAnswerOk);
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {stations.CopriVersion}.");

View file

@ -81,7 +81,7 @@ namespace TINK.ViewModel
throw new Exception($"Can not terminate periodical update task, context {GetType().Name} at {DateTime.Now}. No task running.");
}
Log.Information($"Request to terminate update cycle, context {GetType().Name} at {DateTime.Now}.");
Log.ForContext<PollingUpdateTask>().Information($"Request to terminate update cycle, context {GetType().Name} at {DateTime.Now}.");
CanellationTokenSource.Cancel();
try
@ -109,6 +109,7 @@ namespace TINK.ViewModel
{
// Polling update was canceled.
// Nothing to notice/ worry about.
Log.ForContext<PollingUpdateTask>().Debug($"Update cycle terminated.");
}
else if (aggregateException.InnerExceptions.Count() > 0 &&
aggregateException.InnerExceptions.First(x => !x.GetIsConnectFailureException()) == null) // There is no exception which is not of type connect failure.
@ -123,6 +124,8 @@ namespace TINK.ViewModel
}
}
}
Log.ForContext<PollingUpdateTask>().Debug($"Update cycle terminated (not canceled).");
}
}
}

View file

@ -13,7 +13,7 @@
<PackageReference Include="NSubstitute" Version="4.4.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
</ItemGroup>
<ItemGroup>

View file

@ -14,7 +14,7 @@
<ItemGroup>
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
</ItemGroup>
<ItemGroup>

View file

@ -32,7 +32,7 @@
<PackageReference Include="NSubstitute" Version="4.4.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.3" />
</ItemGroup>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
@ -46,8 +46,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IUser>());
// Verify prerequisites.
Assert.AreEqual("Return bike", handler.ButtonText);
Assert.IsTrue(handler.IsButtonVisible);
//Assert.AreEqual("Return bike", handler.ButtonText);
//Assert.IsTrue(handler.IsButtonVisible);
Assert.AreEqual("Open lock", handler.LockitButtonText);
Assert.IsTrue(handler.IsLockitButtonVisible);
}
@ -99,8 +99,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -370,8 +370,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -440,8 +440,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -510,8 +510,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -578,8 +578,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -645,8 +645,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -705,7 +705,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -887,8 +887,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1070,7 +1071,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -1199,7 +1200,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -1264,7 +1265,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -1330,7 +1331,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
@ -377,7 +377,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = "";
viewService.DisplayAdvancedAlert(
"Error when connecting with lock!",
"Lock of rented bike cannot be be connected right now.",
"Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again.",
"",
"Retry",
"Cancel");

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
@ -660,8 +660,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -737,8 +737,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -810,8 +810,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -886,8 +886,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -962,8 +962,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1036,8 +1036,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1095,8 +1095,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1277,8 +1278,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1339,8 +1341,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1402,8 +1405,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
@ -105,7 +105,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -286,8 +286,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -469,7 +470,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -534,7 +535,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -599,7 +600,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -664,7 +665,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -730,7 +731,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -789,9 +790,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Verify state "Booked Open" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -972,8 +973,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1034,8 +1036,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -1097,8 +1100,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
@ -677,7 +677,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = "";
viewService.DisplayAdvancedAlert(
"Error when connecting to lock!",
"Lock of reserved bike can not be found.",
"Your mobile device does not connect to the bike lock. Please step as close as possible to the bike and try again.",
"",
"Retry",
"Cancel");

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
@ -107,7 +107,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -288,8 +288,8 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -472,7 +472,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -537,7 +537,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -603,7 +603,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state "Booked Closed" after action
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
@ -663,8 +663,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -842,8 +843,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -904,8 +906,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
@ -967,8 +970,9 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
// Following two assertions are deactivated temporarily in context of issue https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/440/.
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}

View file

@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -93,9 +93,9 @@ namespace TestShareeLib.UseCases.Startup
// Verify buttons
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are shown.");
Assert.AreEqual(Color.White, viewModel.TinkColor, "TINK bikes are shown.");
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are hidden.");
Assert.AreEqual(Color.FromRgba(0, 0, 0, 0), viewModel.KonradColor, "Konrad bikes are hidden.");
var statusInfoText = viewModel.StatusInfoText;
Assert.That(
@ -173,9 +173,9 @@ namespace TestShareeLib.UseCases.Startup
// Verify buttons
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
Assert.AreEqual(Color.Gray, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.FromRgba(0, 0, 0, 0), viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.Red, viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual(Color.White, viewModel.KonradColor, "Konrad bikes are shown.");
Assert.IsTrue(
new[] { "Updating...", "" }.Contains(viewModel.StatusInfoText),
@ -392,9 +392,9 @@ namespace TestShareeLib.UseCases.Startup
// Verify buttons
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.White, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual(Color.FromRgba(0, 0, 0, 0), viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual("Offline.", viewModel.StatusInfoText);
@ -482,9 +482,9 @@ namespace TestShareeLib.UseCases.Startup
// Verify buttons
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.White, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual(Color.FromRgba(0, 0, 0, 0), viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual("Connection interrupted, server unreachable.", viewModel.StatusInfoText);
}
@ -572,9 +572,9 @@ namespace TestShareeLib.UseCases.Startup
// Verify buttons
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.White, viewModel.TinkColor, "TINK bikes are hidden.");
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual(Color.FromRgba(0, 0, 0, 0), viewModel.KonradColor, "Konrad bikes are shown.");
Assert.AreEqual("Connection interrupted.", viewModel.StatusInfoText);
}