mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-22 13:57:28 +02:00
Version 3.0.255
This commit is contained in:
parent
db9c288584
commit
5a26bf273b
1495 changed files with 159465 additions and 5060 deletions
27
Meinkonrad/TINK/View/Account/AccountPage.xaml
Normal file
27
Meinkonrad/TINK/View/Account/AccountPage.xaml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
x:Class="TINK.View.Account.AccountPage">
|
||||
<ContentPage.Content>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label Text="{Binding LoggedInInfo}" />
|
||||
<Label IsVisible="{Binding IsBookingStateInfoVisible}"
|
||||
Text="{Binding BookingStateInfo}" />
|
||||
<Button Text="Persönliche Daten Verwalten"
|
||||
Command="{Binding OnManageAccount}"
|
||||
IsEnabled="{Binding IsLogoutPossible}"/>
|
||||
<Button Text="Abmelden"
|
||||
Command="{Binding OnLogoutRequest}"
|
||||
IsEnabled="{Binding IsLogoutPossible}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
155
Meinkonrad/TINK/View/Account/AccountPage.xaml.cs
Normal file
155
Meinkonrad/TINK/View/Account/AccountPage.xaml.cs
Normal file
|
@ -0,0 +1,155 @@
|
|||
using TINK.ViewModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using System.Threading.Tasks;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using System;
|
||||
using TINK.Model.Device;
|
||||
using TINK.ViewModel.Account;
|
||||
|
||||
namespace TINK.View.Account
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class AccountPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class AccountPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
AccountPageViewModel m_oViewModel = null;
|
||||
|
||||
/// <summary> Constructs a account page. </summary>
|
||||
public AccountPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
|
||||
m_oViewModel = new AccountPageViewModel(
|
||||
l_oModel,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
this);
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message. </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
#if USEFLYOUT
|
||||
|
||||
/// <summary>Delegate to perform navigation.</summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail
|
||||
{
|
||||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
=> await m_oViewModel.OnAppearing();
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
await m_oViewModel.OnDisappearing();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
90
Meinkonrad/TINK/View/Bike/BCBike.xaml
Normal file
90
Meinkonrad/TINK/View/Bike/BCBike.xaml
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:conv="clr-namespace:TINK.View"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
mc:Ignorable="d"
|
||||
x:Class="TINK.View.Bike.BCBike">
|
||||
<ContentView>
|
||||
<ContentView.Resources>
|
||||
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
|
||||
</ContentView.Resources>
|
||||
<StackLayout
|
||||
Padding="10">
|
||||
<Label
|
||||
FontAttributes="Bold"
|
||||
Text="{Binding Name}"/>
|
||||
<Label
|
||||
Text="{Binding StateText}"
|
||||
TextColor="{Binding StateColor}"/>
|
||||
<Label
|
||||
Text="{Binding ErrorText}"
|
||||
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
|
||||
TextColor="Red"/>
|
||||
<Button
|
||||
Text="{Binding ButtonText}"
|
||||
IsVisible="{Binding IsButtonVisible}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
Command="{Binding OnButtonClicked}"/>
|
||||
<Grid
|
||||
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label
|
||||
Text=
|
||||
"{Binding TariffDescription.Header}"
|
||||
Grid.ColumnSpan="3"
|
||||
FontAttributes="Bold"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFreeTimePerSession}"
|
||||
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="1"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.FreeTimePerSession}"
|
||||
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFeeEuroPerHour}"
|
||||
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="2"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.FeeEuroPerHour}"
|
||||
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionMaxFeeEuroPerDay}"
|
||||
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="3"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.MaxFeeEuroPerDay}"
|
||||
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionAboEuroPerMonth}"
|
||||
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="4"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.AboEuroPerMonth}"
|
||||
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"/>
|
||||
</Grid>
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
</ViewCell>
|
20
Meinkonrad/TINK/View/Bike/BCBike.xaml.cs
Normal file
20
Meinkonrad/TINK/View/Bike/BCBike.xaml.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Bike
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class BCBike : ViewCell
|
||||
{
|
||||
public BCBike()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
26
Meinkonrad/TINK/View/Bike/BikeViewCellTemplateSelector.cs
Normal file
26
Meinkonrad/TINK/View/Bike/BikeViewCellTemplateSelector.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.View.Bike
|
||||
{
|
||||
/// <summary>
|
||||
/// Selects different templates for different bike types (BordComputer bikes, iLockIt bikes).
|
||||
/// </summary>
|
||||
public class BikeViewCellTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
DataTemplate bCBike;
|
||||
DataTemplate iLockIBike;
|
||||
|
||||
public BikeViewCellTemplateSelector()
|
||||
{
|
||||
bCBike = new DataTemplate(typeof(BCBike));
|
||||
iLockIBike = new DataTemplate(typeof(ILockItBike));
|
||||
}
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
return item is TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel
|
||||
? iLockIBike
|
||||
: bCBike;
|
||||
}
|
||||
}
|
||||
}
|
102
Meinkonrad/TINK/View/Bike/ILockItBike.xaml
Normal file
102
Meinkonrad/TINK/View/Bike/ILockItBike.xaml
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:conv="clr-namespace:TINK.View"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
mc:Ignorable="d"
|
||||
x:Class="TINK.View.Bike.ILockItBike">
|
||||
<ContentView>
|
||||
<ContentView.Resources>
|
||||
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
|
||||
</ContentView.Resources>
|
||||
<StackLayout
|
||||
Padding="10">
|
||||
<Label
|
||||
FontAttributes="Bold"
|
||||
FontSize="Large"
|
||||
HorizontalTextAlignment="Center"
|
||||
Text="{Binding Name}"/>
|
||||
<Label
|
||||
FontAttributes="Bold"
|
||||
HorizontalTextAlignment="Center"
|
||||
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
|
||||
Text="{Binding DisplayId}"/>
|
||||
<Label
|
||||
Text="{Binding StateText}"
|
||||
TextColor="{Binding StateColor}"/>
|
||||
<Label
|
||||
Text="{Binding ErrorText}"
|
||||
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
|
||||
TextColor="Red"/>
|
||||
<Button
|
||||
Text="{Binding ButtonText}"
|
||||
IsVisible="{Binding IsButtonVisible}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
Command="{Binding OnButtonClicked}"/>
|
||||
<Button
|
||||
Text="{Binding LockitButtonText}"
|
||||
IsVisible="{Binding IsLockitButtonVisible}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
Command="{Binding OnLockitButtonClicked}"/>
|
||||
<Grid
|
||||
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label
|
||||
Text=
|
||||
"{Binding TariffDescription.Header}"
|
||||
Grid.ColumnSpan="3"
|
||||
FontAttributes="Bold"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFreeTimePerSession}"
|
||||
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="1"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.FreeTimePerSession}"
|
||||
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFeeEuroPerHour}"
|
||||
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="2"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.FeeEuroPerHour}"
|
||||
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionMaxFeeEuroPerDay}"
|
||||
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="3"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.MaxFeeEuroPerDay}"
|
||||
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"/>
|
||||
<Label
|
||||
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionAboEuroPerMonth}"
|
||||
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="4"/>
|
||||
<Label
|
||||
Text="{Binding TariffDescription.AboEuroPerMonth}"
|
||||
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"/>
|
||||
</Grid>
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
</ViewCell>
|
44
Meinkonrad/TINK/View/Bike/ILockItBike.xaml.cs
Normal file
44
Meinkonrad/TINK/View/Bike/ILockItBike.xaml.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bikes.Bike.BluetoothLock;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Bike
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ILockItBike : ViewCell
|
||||
{
|
||||
public ILockItBike()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
base.OnBindingContextChanged();
|
||||
|
||||
if (Device.RuntimePlatform != Device.iOS)
|
||||
// Update of size is only required for iOS.
|
||||
return;
|
||||
|
||||
var viewModel = BindingContext as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
if (viewModel == null)
|
||||
return;
|
||||
|
||||
viewModel.PropertyChanged += (sender, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BC.RequestHandler.Base<IBikeInfoMutable>.IsButtonVisible)
|
||||
|| e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler.Base.IsLockitButtonVisible))
|
||||
{
|
||||
// Force update of view cell on iOS.
|
||||
// https://hausource.visualstudio.com/TINK/_workitems/edit/132
|
||||
ForceUpdateSize();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
73
Meinkonrad/TINK/View/BikesAtStation/BikesAtStationPage.xaml
Normal file
73
Meinkonrad/TINK/View/BikesAtStation/BikesAtStationPage.xaml
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.BikesAtStation.BikesAtStationPage"
|
||||
xmlns:local_bike="clr-namespace:TINK.View.Bike"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
Title="{Binding Title}">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<ContentPage.Content>
|
||||
<Frame>
|
||||
<StackLayout
|
||||
Orientation="Vertical">
|
||||
<Label
|
||||
HorizontalOptions="Center"
|
||||
FontAttributes="Bold"
|
||||
Text="{Binding StationDetailText}"/>
|
||||
<ListView
|
||||
x:Name="BikesAtStationListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
IsVisible="{Binding IsBikesListVisible}"
|
||||
HasUnevenRows="True"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
|
||||
<Label
|
||||
IsVisible="{Binding IsNoBikesAtStationVisible}"
|
||||
VerticalOptions="EndAndExpand"
|
||||
Text="{Binding NoBikesAtStationText}"/>
|
||||
<Label
|
||||
TextType="Html"
|
||||
Text="{Binding ContactSupportHintText}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
<Label
|
||||
IsVisible="{Binding IsLoginRequiredHintVisible}"
|
||||
TextType="Html"
|
||||
Text="{Binding LoginRequiredHintText}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
<StackLayout
|
||||
VerticalOptions="EndAndExpand"
|
||||
Orientation="Horizontal">
|
||||
<Label
|
||||
HeightRequest="20"
|
||||
Text="{Binding StatusInfoText}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="FillAndExpand"/>
|
||||
<ActivityIndicator IsRunning="{Binding IsRunning}"
|
||||
IsVisible="{Binding IsRunning}"
|
||||
HeightRequest="20"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="End">
|
||||
<ActivityIndicator.WidthRequest>
|
||||
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
|
||||
</ActivityIndicator.WidthRequest>
|
||||
<ActivityIndicator.Color>
|
||||
<OnPlatform x:TypeArguments="Color"
|
||||
iOS="#2499CE" WinPhone="#2499CE" />
|
||||
</ActivityIndicator.Color>
|
||||
</ActivityIndicator>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
234
Meinkonrad/TINK/View/BikesAtStation/BikesAtStationPage.xaml.cs
Normal file
234
Meinkonrad/TINK/View/BikesAtStation/BikesAtStationPage.xaml.cs
Normal file
|
@ -0,0 +1,234 @@
|
|||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
|
||||
namespace TINK.View.BikesAtStation
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using TINK.Model;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using Plugin.BLE;
|
||||
using TINK.ViewModel.BikesAtStation;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
|
||||
private BikesAtStationPageViewModel m_oViewModel;
|
||||
#if TRYNOTBACKSTYLE
|
||||
public BikesAtStationPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
|
||||
var l_oViewModel = new BikesAtStationPageViewModel(
|
||||
l_oModel.BikesAtStation,
|
||||
l_oModel.ActiveUser,
|
||||
l_oModel.SelectedStation,
|
||||
this);
|
||||
|
||||
BindingContext = l_oViewModel;
|
||||
BikesAtStationListView.ItemsSource = l_oViewModel;
|
||||
}
|
||||
|
||||
#else
|
||||
public BikesAtStationPage()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
#if BACKSTYLE
|
||||
// Hide master- detail menu to force user to navigate using back button.
|
||||
m_oNavigation.IsGestureEnabled = false;
|
||||
#endif
|
||||
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
m_oViewModel = new BikesAtStationPageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
model.SelectedStation,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.GeolocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<BikesAtStationPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
#if BACKSTYLE
|
||||
// Hide master- detail menu to force user to navigate using back button.
|
||||
m_oNavigation.IsGestureEnabled = false;
|
||||
#endif
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
BikesAtStationListView.ItemsSource = m_oViewModel;
|
||||
|
||||
await m_oViewModel.OnAppearing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await m_oViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
#if BACKSTYLE
|
||||
if (m_oNavigation!= null)
|
||||
m_oNavigation.IsGestureEnabled = true; // Enables master- detail menu navigation again when page is unloaded.
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary> Creates and a page an shows it.</summary>
|
||||
/// <remarks> When user is not logged in navigation to Login page is supported.</remarks>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail
|
||||
{
|
||||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
}
|
||||
}
|
19
Meinkonrad/TINK/View/BoolInverterConverter.cs
Normal file
19
Meinkonrad/TINK/View/BoolInverterConverter.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
/// <summary> Inverts a bool.</summary>
|
||||
public class BoolInverterConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Inverts a bool.</summary>
|
||||
/// <param name="value">Bool to invert.</param>
|
||||
/// <returns>Inverted bool.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> value is bool flag && !flag;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> value is bool flag && !flag;
|
||||
}
|
||||
}
|
72
Meinkonrad/TINK/View/Contact/ContactPage.xaml
Normal file
72
Meinkonrad/TINK/View/Contact/ContactPage.xaml
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:conv="clr-namespace:TINK.View"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.Contact.ContactPage"
|
||||
Title="{x:Static resources:AppResources.MarkingContactPageTitle}">
|
||||
<ContentPage.Resources>
|
||||
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="StringNotNullOrEmpty_Converter"/>
|
||||
<conv:BoolInverterConverter x:Key="BoolInvert_Converter"/>
|
||||
</ContentPage.Resources>
|
||||
<ContentPage.Content>
|
||||
<ScrollView>
|
||||
<Frame>
|
||||
<StackLayout x:Name="ContactPageView">
|
||||
<Frame
|
||||
IsVisible="{Binding
|
||||
Path=IsOperatorInfoAvaliable,
|
||||
Converter={StaticResource BoolInvert_Converter}}">
|
||||
<!-- Button to select station and explanation text -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
TextType="Html"
|
||||
Text="{x:Static resources:AppResources.MarkingContactNoStationInfoAvailableNoButton}"/>
|
||||
<Button
|
||||
Text="{x:Static resources:AppResources.ActionSelectStation}"
|
||||
Command="{Binding OnSelectStationRequest}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding IsOperatorInfoAvaliable}">
|
||||
<!-- Operator info -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding IsOperatorInfoAvaliable}"
|
||||
HorizontalOptions="Center"
|
||||
FontAttributes="Bold"
|
||||
Text="{Binding ProviderNameText}"/>
|
||||
<!--- Mail address -->
|
||||
<Label
|
||||
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||
FormattedText="{Binding MailAddressAndMotivationsText}"/>
|
||||
<Button
|
||||
x:Name="MailAddressButton"
|
||||
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||
Text="{Binding MailAddressText}"
|
||||
IsEnabled="{Binding IsSendMailAvailable}"
|
||||
Command="{Binding OnMailRequest}"/>
|
||||
<!--- Mail address -->
|
||||
<Label
|
||||
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||
FormattedText="{Binding PhoneContactText}"/>
|
||||
<Button
|
||||
x:Name="PhoneNumberButton"
|
||||
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||
Text="{Binding PhoneNumberText}"
|
||||
IsEnabled="{Binding IsDoPhoncallAvailable}"
|
||||
Command="{Binding OnPhoneRequest}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label FormattedText="{Binding LikeTinkApp}"/>
|
||||
<Button Text="{x:Static resources:AppResources.ActionContactRate}"
|
||||
Command="{Binding OnRateRequest}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ScrollView>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
102
Meinkonrad/TINK/View/Contact/ContactPage.xaml.cs
Normal file
102
Meinkonrad/TINK/View/Contact/ContactPage.xaml.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
using TINK.View.MasterDetail;
|
||||
using TINK.ViewModel.Info;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ContactPage : ContentPage, IViewService, IDetailPage
|
||||
|
||||
{
|
||||
public ContactPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
ContactPageView.BindingContext = new ContactPageViewModel(
|
||||
App.ModelRoot.SelectedStation,
|
||||
App.ModelRoot.Uris.ActiveUri,
|
||||
() => App.CreateAttachment(),
|
||||
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
|
||||
this);
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
|
||||
if (!(Activator.CreateInstance(typeOfPage.GetViewType()) is IDetailPage detailPage))
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set reference to navigation object to be able to show page on newly shown detailPage.
|
||||
detailPage.NavigationMasterDetail = NavigationMasterDetail;
|
||||
|
||||
await Navigation.PushAsync((Page)detailPage);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
#if USEFLYOUT
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail { set; private get; }
|
||||
#endif
|
||||
}
|
||||
}
|
49
Meinkonrad/TINK/View/Contact/SelectStationPage.xaml
Normal file
49
Meinkonrad/TINK/View/Contact/SelectStationPage.xaml
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:maps="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps"
|
||||
xmlns:bindings="clr-namespace:Xamarin.Forms.GoogleMaps.Bindings;assembly=Xamarin.Forms.GoogleMaps.Bindings"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.Contact.SelectStationPage"
|
||||
Title="{x:Static resources:AppResources.MarkingSelectStationPage}">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<Grid
|
||||
IsEnabled="{Binding IsMapPageEnabled}"
|
||||
VerticalOptions="FillAndExpand">
|
||||
<maps:Map WidthRequest="320" HeightRequest="800"
|
||||
x:Name="MyMap"
|
||||
IsShowingUser="False"
|
||||
MapType="Street">
|
||||
<maps:Map.Behaviors>
|
||||
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
|
||||
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
|
||||
</maps:Map.Behaviors>
|
||||
</maps:Map>
|
||||
</Grid>
|
||||
<StackLayout
|
||||
Margin="6,3,6,6"
|
||||
VerticalOptions="EndAndExpand"
|
||||
Orientation="Horizontal">
|
||||
<Label
|
||||
HeightRequest="20"
|
||||
Text="{Binding StatusInfoText}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="FillAndExpand"/>
|
||||
<ActivityIndicator IsRunning="{Binding IsRunning}"
|
||||
IsVisible="{Binding IsRunning}"
|
||||
HeightRequest="20"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="End">
|
||||
<ActivityIndicator.WidthRequest>
|
||||
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
|
||||
</ActivityIndicator.WidthRequest>
|
||||
<ActivityIndicator.Color>
|
||||
<OnPlatform x:TypeArguments="Color"
|
||||
iOS="#2499CE" WinPhone="#2499CE" />
|
||||
</ActivityIndicator.Color>
|
||||
</ActivityIndicator>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
207
Meinkonrad/TINK/View/Contact/SelectStationPage.xaml.cs
Normal file
207
Meinkonrad/TINK/View/Contact/SelectStationPage.xaml.cs
Normal file
|
@ -0,0 +1,207 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
using Serilog;
|
||||
using TINK.ViewModel.Contact;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class SelectStationPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class SelectStationPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
|
||||
|
||||
public SelectStationPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes type, string title = null)
|
||||
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Type of page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
#if USEFLYOUT
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
|
||||
#else
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType());
|
||||
#endif
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
page.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary> Delegate to perform navigation.</summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
try
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
|
||||
|
||||
#if TRYNOTBACKSTYLE
|
||||
SelectStationPageViewModel = new SelectStationPageViewModel();
|
||||
#else
|
||||
SelectStationPageViewModel = new SelectStationPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.GeolocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Constructing select station view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BindingContext = SelectStationPageViewModel;
|
||||
|
||||
#if USEFLYOUT
|
||||
SelectStationPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Setting binding/ navigaton on select station failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Moving and scaling map.");
|
||||
SelectStationPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.Uris.ActiveUri);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Verbose("Invoking OnAppearing on select station view model.");
|
||||
await SelectStationPageViewModel.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing on select station view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
Meinkonrad/TINK/View/CopriWebView/ManageAccountPage.xaml
Normal file
18
Meinkonrad/TINK/View/CopriWebView/ManageAccountPage.xaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.CopriWebView.ManageAccountPage">
|
||||
<ContentPage.Content>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackLayout>
|
||||
<WebView x:Name="ManageAccount"
|
||||
HeightRequest="1400"
|
||||
WidthRequest="1000"
|
||||
Source="{Binding Uri}" />
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
42
Meinkonrad/TINK/View/CopriWebView/ManageAccountPage.xaml.cs
Normal file
42
Meinkonrad/TINK/View/CopriWebView/ManageAccountPage.xaml.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using TINK.Model.Device;
|
||||
using TINK.ViewModel.Login;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.CopriWebView
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class ManageAccountPage : ContentPage
|
||||
{
|
||||
public ManageAccountPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
ManageAccount.Navigating += (sender, ev) =>
|
||||
{
|
||||
if (!ev.Url.ToUpper().EndsWith(".PDF"))
|
||||
{
|
||||
// Stay inside web view except for downloading pdf- files.
|
||||
return;
|
||||
}
|
||||
|
||||
DependencyService.Get<IExternalBrowserService>().OpenUrl(ev.Url);
|
||||
};
|
||||
|
||||
ManageAccount.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success) return;
|
||||
|
||||
ManageAccount.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann persönliche Daten nicht anzeigen/ verwalten!</b><br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
};
|
||||
|
||||
ManageAccount.BindingContext = new ManageAccountViewModel(
|
||||
App.ModelRoot.ActiveUser.SessionCookie,
|
||||
Model.TinkApp.MerchantId,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
}
|
||||
}
|
||||
}
|
18
Meinkonrad/TINK/View/CopriWebView/PasswordForgottenPage.xaml
Normal file
18
Meinkonrad/TINK/View/CopriWebView/PasswordForgottenPage.xaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.CopriWebView.PasswordForgottenPage">
|
||||
<ContentPage.Content>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackLayout>
|
||||
<WebView x:Name="PasswordForgottenWebView"
|
||||
HeightRequest="1400"
|
||||
WidthRequest="1000"
|
||||
Source="{Binding Uri}" />
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
using TINK.ViewModel.CopriWebView;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.CopriWebView
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class PasswordForgottenPage : ContentPage
|
||||
{
|
||||
public PasswordForgottenPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
PasswordForgottenWebView.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success) return;
|
||||
|
||||
PasswordForgottenWebView.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann Passwort vergessen Seite nicht anzeigen!</b><br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
};
|
||||
|
||||
PasswordForgottenWebView.BindingContext = new PasswordForgottonViewModel(
|
||||
Model.TinkApp.MerchantId,
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
}
|
||||
}
|
||||
}
|
18
Meinkonrad/TINK/View/CopriWebView/RegisterPage.xaml
Normal file
18
Meinkonrad/TINK/View/CopriWebView/RegisterPage.xaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.CopriWebView.RegisterPage">
|
||||
<ContentPage.Content>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackLayout>
|
||||
<WebView x:Name="RegisterView"
|
||||
HeightRequest="1400"
|
||||
WidthRequest="1000"
|
||||
Source="{Binding Uri}" />
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
33
Meinkonrad/TINK/View/CopriWebView/RegisterPage.xaml.cs
Normal file
33
Meinkonrad/TINK/View/CopriWebView/RegisterPage.xaml.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
using TINK.Model.Device;
|
||||
using TINK.ViewModel.CopriWebView;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.CopriWebView
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RegisterPage : ContentPage
|
||||
{
|
||||
public RegisterPage()
|
||||
{
|
||||
DependencyService.Get<IWebView>().ClearCookies();
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
RegisterView.Navigated += (sender, ev) =>
|
||||
{
|
||||
if (ev.Result == WebNavigationResult.Success) return;
|
||||
|
||||
RegisterView.Source = new HtmlWebViewSource
|
||||
{
|
||||
Html = "<html><b>Kann Anmeldeseite nicht anzeigen</b>!<br>Verbindung mit Internet ok?</html>"
|
||||
};
|
||||
};
|
||||
|
||||
RegisterView.BindingContext = new RegisterPageViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
85
Meinkonrad/TINK/View/FeedbackPopup.xaml
Normal file
85
Meinkonrad/TINK/View/FeedbackPopup.xaml
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<xct:Popup xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
|
||||
xmlns:local="clr-namespace:TINK.View"
|
||||
x:TypeArguments="local:FeedbackPopup+Result"
|
||||
x:Class="TINK.View.FeedbackPopup">
|
||||
<xct:Popup.Resources>
|
||||
<x:String x:Key="check_circle"></x:String>
|
||||
</xct:Popup.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<!-- Head and title row -->
|
||||
<RowDefinition Height="auto"/>
|
||||
<!--- checkbox and input elements-->
|
||||
<RowDefinition Height="*"/>
|
||||
<!--- ok button-->
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid
|
||||
Padding="30"
|
||||
BackgroundColor="{DynamicResource primary-back-title-color}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label
|
||||
HorizontalTextAlignment="Center"
|
||||
FontSize="Large"
|
||||
Text="Fahrrad erfolgreich zurückgegeben!"/>
|
||||
<Image Grid.Row="1">
|
||||
<Image.Source>
|
||||
<FontImageSource Size="Header" Glyph="{StaticResource check_circle}" FontFamily="FA-S"/>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
</Grid>
|
||||
<ScrollView Grid.Row="1">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackLayout
|
||||
Orientation="Vertical">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<CheckBox x:Name="brockenCheckBox" IsChecked="True"/>
|
||||
<Label
|
||||
Grid.Column="1"
|
||||
FontSize="Medium"
|
||||
Text="Rad ist in Ordnung"/>
|
||||
</Grid>
|
||||
<Editor
|
||||
Grid.Row="1"
|
||||
x:Name="feedbackMessage"
|
||||
AutoSize="TextChanges"
|
||||
Placeholder="Bei Bedarf bitte hier Rückmeldung eingeben."
|
||||
Text="">
|
||||
<Editor.Triggers>
|
||||
<DataTrigger TargetType="Editor"
|
||||
Binding="{Binding Source={x:Reference brockenCheckBox}, Path=IsChecked}"
|
||||
Value="true">
|
||||
<Setter Property="Placeholder"
|
||||
Value="Bei Bedarf bitte hier Rückmeldung eingeben." />
|
||||
</DataTrigger>
|
||||
<DataTrigger TargetType="Editor"
|
||||
Binding="{Binding Source={x:Reference brockenCheckBox}, Path=IsChecked}"
|
||||
Value="false">
|
||||
<Setter Property="Placeholder"
|
||||
Value="Bitte Zustand/ Defekt hier beschreiben." />
|
||||
</DataTrigger>
|
||||
</Editor.Triggers>
|
||||
</Editor>
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
</ScrollView>
|
||||
<Button
|
||||
Grid.Row="2"
|
||||
Clicked="OnOkClicked"
|
||||
Text="OK"/>
|
||||
</Grid>
|
||||
</xct:Popup>
|
58
Meinkonrad/TINK/View/FeedbackPopup.xaml.cs
Normal file
58
Meinkonrad/TINK/View/FeedbackPopup.xaml.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using Xamarin.CommunityToolkit.UI.Views;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeedbackPopup : Popup<FeedbackPopup.Result>
|
||||
{
|
||||
public FeedbackPopup()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override FeedbackPopup.Result GetLightDismissResult()
|
||||
{
|
||||
return new Result
|
||||
{
|
||||
Message = feedbackMessage.Text,
|
||||
IsBikeBroken = brockenCheckBox.IsChecked
|
||||
};
|
||||
}
|
||||
|
||||
private void OnOkClicked(object sender, EventArgs eventArgs)
|
||||
{
|
||||
var result = new Result
|
||||
{
|
||||
Message = feedbackMessage.Text,
|
||||
IsBikeBroken = brockenCheckBox.IsChecked
|
||||
};
|
||||
|
||||
Dismiss(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
#if USCSHARP9
|
||||
public class Result : IViewService.IUserFeedback
|
||||
#else
|
||||
public new class Result : IUserFeedback
|
||||
#endif
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
public bool IsBikeBroken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds either
|
||||
/// - general feedback
|
||||
/// - error description of broken bike
|
||||
/// or both.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
29
Meinkonrad/TINK/View/FeesAndBikes/FeesAndBikesPage.xaml
Normal file
29
Meinkonrad/TINK/View/FeesAndBikes/FeesAndBikesPage.xaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.Contact.FeesAndBikesPage">
|
||||
<!--Pages can be added as references or inline-->
|
||||
<ContentPage Title="{x:Static resources:AppResources.MarkingTabFees}">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
x:Name="InfoRentBikeWebView"
|
||||
HeightRequest="1000"
|
||||
WidthRequest="1000"
|
||||
Source="{Binding RentBikeText}"/>
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
<ContentPage Title="{x:Static resources:AppResources.MarkingTabBikes}">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
x:Name="InfoTypesOfBikesWebView"
|
||||
HeightRequest="1000"
|
||||
WidthRequest="1000"
|
||||
Source="{Binding TypesOfBikesText}"/>
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
</TabbedPage>
|
37
Meinkonrad/TINK/View/FeesAndBikes/FeesAndBikesPage.xaml.cs
Normal file
37
Meinkonrad/TINK/View/FeesAndBikes/FeesAndBikesPage.xaml.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using TINK.ViewModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using TINK.ViewModel.Contact;
|
||||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeesAndBikesPage : TabbedPage
|
||||
{
|
||||
public HelpContactViewModel ViewModel { get; }
|
||||
|
||||
public FeesAndBikesPage ()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ViewModel = new HelpContactViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
resourceName => ViewModelResourceHelper.GetSource(resourceName));
|
||||
|
||||
BindingContext = ViewModel;
|
||||
|
||||
/// Info about renting.
|
||||
InfoRentBikeWebView.Navigating += ViewModelHelper.OnNavigating;
|
||||
|
||||
/// Info about types of bikes.
|
||||
InfoTypesOfBikesWebView.Navigating += ViewModelHelper.OnNavigating;
|
||||
}
|
||||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.OnAppearing();
|
||||
}
|
||||
}
|
||||
}
|
60
Meinkonrad/TINK/View/FindBike/FindBikePage.xaml
Normal file
60
Meinkonrad/TINK/View/FindBike/FindBikePage.xaml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.FindBike.FindBikePage"
|
||||
xmlns:local_bike="clr-namespace:TINK.View.Bike">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<ContentPage.Content>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Entry
|
||||
Placeholder="Fahrrad-Nummer bitte hier eingeben"
|
||||
IsVisible="{Binding IsSelectBikeVisible}"
|
||||
MaxLength="10"
|
||||
CursorPosition="0"
|
||||
Text="{Binding BikeIdUserInput}">
|
||||
</Entry>
|
||||
<Button
|
||||
Text="Rad Wählen"
|
||||
IsEnabled="{Binding IsSelectBikeEnabled}"
|
||||
IsVisible="{Binding IsSelectBikeVisible}"
|
||||
Command="{Binding OnSelectBikeRequest}">
|
||||
</Button>
|
||||
<ListView
|
||||
x:Name="FindBikeListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
IsVisible="{Binding IsBikesListVisible}"
|
||||
HasUnevenRows="True"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
|
||||
<StackLayout
|
||||
VerticalOptions="EndAndExpand"
|
||||
Orientation="Horizontal">
|
||||
<Label
|
||||
HeightRequest="20"
|
||||
Text="{Binding StatusInfoText}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="FillAndExpand"/>
|
||||
<ActivityIndicator IsRunning="{Binding IsRunning}"
|
||||
IsVisible="{Binding IsRunning}"
|
||||
HeightRequest="20"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="End">
|
||||
<ActivityIndicator.WidthRequest>
|
||||
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
|
||||
</ActivityIndicator.WidthRequest>
|
||||
<ActivityIndicator.Color>
|
||||
<OnPlatform x:TypeArguments="Color"
|
||||
iOS="#2499CE" WinPhone="#2499CE" />
|
||||
</ActivityIndicator.Color>
|
||||
</ActivityIndicator>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
144
Meinkonrad/TINK/View/FindBike/FindBikePage.xaml.cs
Normal file
144
Meinkonrad/TINK/View/FindBike/FindBikePage.xaml.cs
Normal file
|
@ -0,0 +1,144 @@
|
|||
using Serilog;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.ViewModel.FindBike;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.FindBike
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FindBikePage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
FindBikePageViewModel m_oViewModel = null;
|
||||
|
||||
public FindBikePage () { }
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
m_oViewModel = new FindBikePageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.GeolocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<FindBikePage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Fahrrad Wählen kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
FindBikeListView.ItemsSource = m_oViewModel;
|
||||
|
||||
await m_oViewModel.OnAppearing();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => throw new NotSupportedException();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
}
|
||||
}
|
47
Meinkonrad/TINK/View/Info/BikeInfo/BikeInfoCarouselPage.xaml
Normal file
47
Meinkonrad/TINK/View/Info/BikeInfo/BikeInfoCarouselPage.xaml
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.Info.BikeInfo.BikeInfoCarouselPage">
|
||||
<CarouselPage.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentPage>
|
||||
<ContentPage.Padding>
|
||||
<OnPlatform x:TypeArguments="Thickness">
|
||||
<On Platform="iOS" Value="0,40,0,0" />
|
||||
</OnPlatform>
|
||||
</ContentPage.Padding>
|
||||
<ScrollView Orientation="Vertical">
|
||||
<StackLayout>
|
||||
<Label
|
||||
Text="{Binding Title}"
|
||||
FontSize="Medium"
|
||||
HorizontalOptions="Center"
|
||||
HorizontalTextAlignment="Center"
|
||||
VerticalOptions="EndAndExpand"
|
||||
VerticalTextAlignment="End"/>
|
||||
<Image
|
||||
IsVisible="{Binding IsImageVisble}"
|
||||
Source="{Binding Image}"
|
||||
Aspect="AspectFit"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="FillAndExpand"/>
|
||||
<Label
|
||||
Text="{Binding DescriptionText}"
|
||||
HorizontalOptions="Center"
|
||||
HorizontalTextAlignment="Center"
|
||||
VerticalOptions="StartAndExpand"
|
||||
VerticalTextAlignment="Start"/>
|
||||
<Button
|
||||
Text="Schließen"
|
||||
IsVisible="{Binding IsCloseVisible}"
|
||||
Command="{Binding OnCloseRequest}"
|
||||
VerticalOptions="End"/>
|
||||
<ProgressBar
|
||||
VerticalOptions="End"
|
||||
Progress="{Binding ProgressValue}"/>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</ContentPage>
|
||||
</DataTemplate>
|
||||
</CarouselPage.ItemTemplate>
|
||||
</CarouselPage>
|
128
Meinkonrad/TINK/View/Info/BikeInfo/BikeInfoCarouselPage.xaml.cs
Normal file
128
Meinkonrad/TINK/View/Info/BikeInfo/BikeInfoCarouselPage.xaml.cs
Normal file
|
@ -0,0 +1,128 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Info.BikeInfo;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Info.BikeInfo
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService
|
||||
#endif
|
||||
{
|
||||
public BikeInfoCarouselPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
ItemsSource = new BikeInfoViewModel(
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
|
||||
this).CarouselItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
{
|
||||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail
|
||||
{
|
||||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
40
Meinkonrad/TINK/View/Info/InfoPage.xaml.cs~Backup1
Normal file
40
Meinkonrad/TINK/View/Info/InfoPage.xaml.cs~Backup1
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class InfoPage : ContentPage
|
||||
{
|
||||
public InfoPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
#if __IOS__
|
||||
var resourcePrefix = "TINK.iOS.";
|
||||
#endif
|
||||
#if __ANDROID__
|
||||
var resourcePrefix = "TINK.Droid.";
|
||||
#endif
|
||||
#if WINDOWS_PHONE
|
||||
var resourcePrefix = "TINK.WinPhone.";
|
||||
#endif
|
||||
|
||||
Debug.WriteLine("Using this resource prefix: " + resourcePrefix);
|
||||
// note that the prefix includes the trailing period '.' that is required
|
||||
var assembly = typeof(InfoPage).GetTypeInfo().Assembly;
|
||||
Stream stream = assembly.GetManifestResourceStream
|
||||
(resourcePrefix + "HtmlResouces.Info.html");
|
||||
var l_oHtmlViewSource = new HtmlWebViewSource
|
||||
{
|
||||
Html = (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
|
||||
};
|
||||
InfoWebView.Source = l_oHtmlViewSource;
|
||||
}
|
||||
}
|
||||
}
|
20
Meinkonrad/TINK/View/Info/InfoPage.xaml.cs~HEAD
Normal file
20
Meinkonrad/TINK/View/Info/InfoPage.xaml.cs~HEAD
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Info
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class InfoPage : ContentPage
|
||||
{
|
||||
public InfoPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
}
|
||||
}
|
||||
}
|
52
Meinkonrad/TINK/View/Info/InfoTabbedPage.xaml
Normal file
52
Meinkonrad/TINK/View/Info/InfoTabbedPage.xaml
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.Info.TabbedPageInfo"
|
||||
x:Name="TabbedInfoPage">
|
||||
<!--Pages can be added as references or inline-->
|
||||
<ContentPage Title="App">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
x:Name="InfoLicenses"
|
||||
Source="{Binding InfoLicenses}"
|
||||
HeightRequest="1000"
|
||||
WidthRequest="1000" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
<ContentPage Title="Datenschutz">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
x:Name="InfoDatenschutz"
|
||||
Source="{Binding InfoPrivacy}"
|
||||
HeightRequest="1000"
|
||||
WidthRequest="1000" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
<ContentPage Title="AGB">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
x:Name="InfoABG"
|
||||
Source ="{Binding InfoAgb}"
|
||||
HeightRequest="1000"
|
||||
WidthRequest="1000" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
<ContentPage Title="Impressum">
|
||||
<ContentPage.Content>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
x:Name="InfoImpressum"
|
||||
Source="{Binding InfoImpressum}"
|
||||
HeightRequest="1000"
|
||||
WidthRequest="1000" />
|
||||
</StackLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
</TabbedPage>
|
||||
|
36
Meinkonrad/TINK/View/Info/InfoTabbedPage.xaml.cs
Normal file
36
Meinkonrad/TINK/View/Info/InfoTabbedPage.xaml.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Info;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Info
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class TabbedPageInfo : TabbedPage
|
||||
{
|
||||
public InfoViewModel ViewModel { get; }
|
||||
|
||||
public TabbedPageInfo()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ViewModel = new InfoViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
resourceName => ViewModelResourceHelper.GetSource(resourceName));
|
||||
TabbedInfoPage.BindingContext = ViewModel;
|
||||
|
||||
InfoLicenses.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoDatenschutz.Navigating += ViewModelHelper.OnNavigating;
|
||||
InfoABG.Navigating += ViewModelHelper.OnNavigating;
|
||||
|
||||
InfoImpressum.Navigating += ViewModelHelper.OnNavigating;
|
||||
}
|
||||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
ViewModel.OnAppearing();
|
||||
}
|
||||
}
|
||||
}
|
35
Meinkonrad/TINK/View/ListViewAttachedBehavior.cs
Normal file
35
Meinkonrad/TINK/View/ListViewAttachedBehavior.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
public static class ListViewAttachedBehavior
|
||||
{
|
||||
public static readonly BindableProperty CommandProperty =
|
||||
BindableProperty.CreateAttached(
|
||||
"Command",
|
||||
typeof(ICommand),
|
||||
typeof(ListViewAttachedBehavior),
|
||||
null,
|
||||
propertyChanged: OnCommandChanged);
|
||||
|
||||
static void OnCommandChanged(BindableObject view, object oldValue, object newValue)
|
||||
{
|
||||
var entry = view as ListView;
|
||||
if (entry == null)
|
||||
return;
|
||||
|
||||
entry.ItemTapped += (sender, e) =>
|
||||
{
|
||||
var command = (newValue as ICommand);
|
||||
if (command == null)
|
||||
return;
|
||||
|
||||
if (command.CanExecute(e.Item))
|
||||
{
|
||||
command.Execute(e.Item);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
53
Meinkonrad/TINK/View/Login/LoginPage.xaml
Normal file
53
Meinkonrad/TINK/View/Login/LoginPage.xaml
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.Login.LoginPage">
|
||||
<ScrollView>
|
||||
<Frame>
|
||||
<StackLayout x:Name="LoginPageView">
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label Text="{x:Static resources:AppResources.MarkingLoginEmailAddressLabel}"/>
|
||||
<Entry
|
||||
Placeholder="{x:Static resources:AppResources.MarkingLoginEmailAddressPlaceholder}"
|
||||
Keyboard="Email"
|
||||
AutomationId="mail_address_text"
|
||||
x:Name="EMailEntry"
|
||||
Text="{Binding MailAddress}"
|
||||
IsEnabled="{Binding IsLoggedOut}"/>
|
||||
<Label Text="{x:Static resources:AppResources.MarkingLoginPasswordLabel}"/>
|
||||
<Entry
|
||||
Placeholder="{x:Static resources:AppResources.MarkingLoginPasswordPlaceholder}"
|
||||
AutomationId="password_text"
|
||||
IsPassword="true"
|
||||
x:Name="PasswordEntry"
|
||||
Text="{Binding Password}"
|
||||
IsEnabled="{Binding IsLoggedOut}"/>
|
||||
<Button
|
||||
Text="{x:Static resources:AppResources.ActionLoginLogin}"
|
||||
AutomationId="login_button"
|
||||
Command="{Binding OnLoginRequest}"
|
||||
IsEnabled="{Binding IsLoginRequestAllowed}">
|
||||
</Button>
|
||||
<Button
|
||||
Text="{x:Static resources:AppResources.ActionLoginRegister}"
|
||||
AutomationId="register_button"
|
||||
Command="{Binding OnRegisterRequest}"
|
||||
IsVisible="{Binding IsWebViewElementsVisible}">
|
||||
</Button>
|
||||
<Label
|
||||
IsVisible="{Binding IsRegisterTargetsInfoVisible}"
|
||||
FormattedText="{Binding RegisterTargetsInfo}">
|
||||
</Label>
|
||||
<Button
|
||||
Text="{x:Static resources:AppResources.ActionLoginPasswordForgotten}"
|
||||
AutomationId="password_forgotten_button"
|
||||
Command="{Binding OnPasswordForgottonRequest}">
|
||||
</Button>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ScrollView>
|
||||
</ContentPage>
|
122
Meinkonrad/TINK/View/Login/LoginPage.xaml.cs
Normal file
122
Meinkonrad/TINK/View/Login/LoginPage.xaml.cs
Normal file
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Login
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class LoginPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class LoginPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
public LoginPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
#if !BACKSTYLE
|
||||
var l_oViewModel = new LoginPageViewModel(
|
||||
l_oModel,
|
||||
(url) => DependencyService.Get< IExternalBrowserService>().OpenUrl(url),
|
||||
this);
|
||||
|
||||
LoginPageView.BindingContext = l_oViewModel;
|
||||
#else
|
||||
LoginPageView.BindingContext = new LoginPageViewModel(l_oModel.ActiveUser, this, Navigation);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail
|
||||
{
|
||||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
69
Meinkonrad/TINK/View/Map/MapPage.xaml
Normal file
69
Meinkonrad/TINK/View/Map/MapPage.xaml
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:maps="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps"
|
||||
xmlns:bindings="clr-namespace:Xamarin.Forms.GoogleMaps.Bindings;assembly=Xamarin.Forms.GoogleMaps.Bindings"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.Map.MapPage"
|
||||
Title="{x:Static resources:AppResources.MarkingMapPage}">
|
||||
<StackLayout>
|
||||
<Grid
|
||||
IsEnabled="{Binding IsMapPageEnabled}"
|
||||
VerticalOptions="FillAndExpand">
|
||||
<maps:Map WidthRequest="320" HeightRequest="800"
|
||||
x:Name="MyMap"
|
||||
IsShowingUser="False"
|
||||
MapType="Street">
|
||||
<maps:Map.Behaviors>
|
||||
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
|
||||
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
|
||||
</maps:Map.Behaviors>
|
||||
</maps:Map>
|
||||
<Button
|
||||
x:Name="TINKButton"
|
||||
AutomationId ="FilterTINK_button"
|
||||
Text="TINK"
|
||||
Command="{Binding OnToggleKonradToTink}"
|
||||
IsVisible="{Binding IsToggleVisible}"
|
||||
TextColor ="{Binding TinkColor}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="StartAndExpand"
|
||||
WidthRequest="80">
|
||||
</Button>
|
||||
<Button
|
||||
x:Name="KonradButton"
|
||||
AutomationId ="FilterKonrad_button"
|
||||
Text="Konrad"
|
||||
Command="{Binding OnToggleTinkToKonrad}"
|
||||
IsVisible="{Binding IsToggleVisible}"
|
||||
TextColor="{Binding KonradColor}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="EndAndExpand"
|
||||
WidthRequest="80">
|
||||
</Button>
|
||||
</Grid>
|
||||
<StackLayout
|
||||
Margin="6,3,6,6"
|
||||
VerticalOptions="EndAndExpand"
|
||||
Orientation="Horizontal">
|
||||
<Label
|
||||
HeightRequest="20"
|
||||
Text="{Binding StatusInfoText}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="FillAndExpand"/>
|
||||
<ActivityIndicator IsRunning="{Binding IsRunning}"
|
||||
IsVisible="{Binding IsRunning}"
|
||||
HeightRequest="20"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="End">
|
||||
<ActivityIndicator.WidthRequest>
|
||||
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
|
||||
</ActivityIndicator.WidthRequest>
|
||||
<ActivityIndicator.Color>
|
||||
<OnPlatform x:TypeArguments="Color"
|
||||
iOS="#2499CE" WinPhone="#2499CE" />
|
||||
</ActivityIndicator.Color>
|
||||
</ActivityIndicator>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
243
Meinkonrad/TINK/View/Map/MapPage.xaml.cs
Normal file
243
Meinkonrad/TINK/View/Map/MapPage.xaml.cs
Normal file
|
@ -0,0 +1,243 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Map
|
||||
{
|
||||
using Serilog;
|
||||
using TINK.ViewModel.Map;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class MapPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class MapPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private MapPageViewModel MapPageViewModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs map page instance.
|
||||
/// </summary>
|
||||
public MapPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes type, string title = null)
|
||||
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Type of page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes typeOfPage)
|
||||
{
|
||||
#if USEFLYOUT
|
||||
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
|
||||
#else
|
||||
var page = Activator.CreateInstance(p_oTypeOfPage.GetViewType());
|
||||
#endif
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
page.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary> Delegate to perform navigation.</summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
try
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
|
||||
|
||||
#if TRYNOTBACKSTYLE
|
||||
MapPageViewModel = new MapPageViewModel();
|
||||
#else
|
||||
MapPageViewModel = new MapPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.GeolocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
#endif
|
||||
} catch (Exception exception)
|
||||
{
|
||||
|
||||
Log.ForContext<MapPage>().Error("Constructing map page view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BindingContext = MapPageViewModel;
|
||||
|
||||
#if USEFLYOUT
|
||||
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Setting binding/ navigaton on map page failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
TINKButton.BackgroundColor = Color.LightGray;
|
||||
TINKButton.BorderColor = Color.Black;
|
||||
TINKButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
KonradButton.BackgroundColor = Color.LightGray;
|
||||
KonradButton.BorderColor = Color.Black;
|
||||
KonradButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MapPage>().Error("IOS specific styling of map page failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MapPage>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
Log.ForContext<MapPage>().Verbose("Moving and scaling map.");
|
||||
MapPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.Uris.ActiveUri,
|
||||
App.ModelRoot.GroupFilterMapPage);
|
||||
}
|
||||
catch(Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<MapPage>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<MapPage>().Verbose("Invoking OnAppearing on map page view model.");
|
||||
await MapPageViewModel.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MapPage>().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected override async void OnDisappearing()
|
||||
{
|
||||
if (MapPageViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await MapPageViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
base.OnDisappearing();
|
||||
}
|
||||
}
|
||||
}
|
34
Meinkonrad/TINK/View/MiniSurvey/MiniSurveyPage.xaml
Normal file
34
Meinkonrad/TINK/View/MiniSurvey/MiniSurveyPage.xaml
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local_minisurvey="clr-namespace:TINK.View.MiniSurvey.Question"
|
||||
x:Class="TINK.View.MiniSurvey.MiniSurveyPage">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<local_minisurvey:QuestionViewCellTemplateSelector x:Key="questionViewCellTemplateSelector"/>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<ContentPage.Content>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label
|
||||
FontSize="Large"
|
||||
FontAttributes="Bold"
|
||||
Text="{Binding Title}"/>
|
||||
<Label
|
||||
Text="{Binding Subtitle}"/>
|
||||
<ListView
|
||||
x:Name="MiniSurveyListView"
|
||||
HasUnevenRows="True"
|
||||
ItemTemplate="{StaticResource questionViewCellTemplateSelector}">
|
||||
</ListView>
|
||||
<Label
|
||||
Text="{Binding Footer}"/>
|
||||
<Button
|
||||
IsEnabled="False"
|
||||
Command="{Binding OnButtonClicked}"
|
||||
Text="OK"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
95
Meinkonrad/TINK/View/MiniSurvey/MiniSurveyPage.xaml.cs
Normal file
95
Meinkonrad/TINK/View/MiniSurvey/MiniSurveyPage.xaml.cs
Normal file
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.ViewModel.MiniSurvey;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.MiniSurvey
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MiniSurveyPage : ContentPage, IViewService
|
||||
{
|
||||
public MiniSurveyPage()
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
var vm = new MiniSurveyViewModel(
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
this);
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = vm;
|
||||
MiniSurveyListView.ItemsSource = vm;
|
||||
}
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.MiniSurvey.Question.CheckOneViewCell">
|
||||
<ViewCell.View>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label
|
||||
FontSize="Medium"
|
||||
Text="{Binding QuestionText}" />
|
||||
<Picker
|
||||
Title="{x:Static resources:AppResources.MiniSurveyAskForAnswer}"
|
||||
SelectedItem="{Binding AnswerText}"
|
||||
ItemsSource="{Binding AnswersText}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ViewCell.View>
|
||||
</ViewCell>
|
|
@ -0,0 +1,14 @@
|
|||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.MiniSurvey.Question
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class CheckOneViewCell : ViewCell
|
||||
{
|
||||
public CheckOneViewCell ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
x:Class="TINK.View.MiniSurvey.Question.FreeTextViewCell">
|
||||
<ViewCell.View>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label
|
||||
FontSize="Medium"
|
||||
Text="{Binding QuestionText}" />
|
||||
<Editor
|
||||
AutoSize="TextChanges"
|
||||
Text="{Binding AnswerText}"
|
||||
Placeholder="{x:Static resources:AppResources.MiniSurveyEnterAnswer}">
|
||||
</Editor>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ViewCell.View>
|
||||
</ViewCell>
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.MiniSurvey.Question
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FreeTextViewCell : ViewCell
|
||||
{
|
||||
public FreeTextViewCell ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.View.MiniSurvey.Question
|
||||
{
|
||||
/// <summary>
|
||||
/// Selects different templates for different question types.
|
||||
/// </summary>
|
||||
public class QuestionViewCellTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
DataTemplate checkOneViewCell;
|
||||
DataTemplate freeTextViewCell;
|
||||
|
||||
public QuestionViewCellTemplateSelector()
|
||||
{
|
||||
checkOneViewCell = new DataTemplate(typeof(CheckOneViewCell));
|
||||
freeTextViewCell = new DataTemplate(typeof(FreeTextViewCell));
|
||||
}
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
return item is ViewModel.MiniSurvey.Question.FreeTextViewModel
|
||||
? freeTextViewCell
|
||||
: checkOneViewCell;
|
||||
}
|
||||
}
|
||||
}
|
53
Meinkonrad/TINK/View/MyBikes/MyBikesPage.xaml
Normal file
53
Meinkonrad/TINK/View/MyBikes/MyBikesPage.xaml
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.MyBikes.MyBikesPage"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
xmlns:local_bike="clr-namespace:TINK.View.Bike"
|
||||
Title="{x:Static resources:AppResources.MarkingMyBikes}">
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<ContentPage.Content>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<ListView
|
||||
x:Name="MyBikesListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
IsVisible="{Binding IsBikesListVisible}"
|
||||
HasUnevenRows="True"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
|
||||
<StackLayout
|
||||
VerticalOptions="EndAndExpand"
|
||||
Orientation="Horizontal">
|
||||
<Label
|
||||
IsVisible="{Binding IsNoBikesOccupiedVisible}"
|
||||
VerticalOptions="StartAndExpand"
|
||||
Text="{Binding NoBikesOccupiedText}"/>
|
||||
<Label
|
||||
HeightRequest="20"
|
||||
Text="{Binding StatusInfoText}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="FillAndExpand"/>
|
||||
<ActivityIndicator IsRunning="{Binding IsRunning}"
|
||||
IsVisible="{Binding IsRunning}"
|
||||
HeightRequest="20"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="End">
|
||||
<ActivityIndicator.WidthRequest>
|
||||
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
|
||||
</ActivityIndicator.WidthRequest>
|
||||
<ActivityIndicator.Color>
|
||||
<OnPlatform x:TypeArguments="Color"
|
||||
iOS="#2499CE" WinPhone="#2499CE" />
|
||||
</ActivityIndicator.Color>
|
||||
</ActivityIndicator>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
169
Meinkonrad/TINK/View/MyBikes/MyBikesPage.xaml.cs
Normal file
169
Meinkonrad/TINK/View/MyBikes/MyBikesPage.xaml.cs
Normal file
|
@ -0,0 +1,169 @@
|
|||
using Plugin.Connectivity;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.MyBikes
|
||||
{
|
||||
using Serilog;
|
||||
using TINK.ViewModel.MyBikes;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class MyBikesPage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
MyBikesPageViewModel m_oViewModel = null;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a my bikes page.
|
||||
/// </summary>
|
||||
public MyBikesPage()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
if (m_oViewModel != null)
|
||||
{
|
||||
// No need to create view model, set binding context an items source if already done.
|
||||
// If done twice tap events are fired multiple times (when hiding page using home button).
|
||||
await m_oViewModel.OnAppearing();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var model = App.ModelRoot;
|
||||
|
||||
// Backup synchronization context when called from GUI-thread.
|
||||
var synchronizationContext = SynchronizationContext.Current;
|
||||
|
||||
m_oViewModel = new MyBikesPageViewModel(
|
||||
model.ActiveUser,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
App.GeolocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MyBikesPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
MyBikesListView.ItemsSource = m_oViewModel;
|
||||
|
||||
await m_oViewModel.OnAppearing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null (Example: Occured when page to querry for location permissions was opened)
|
||||
return;
|
||||
}
|
||||
|
||||
await m_oViewModel.OnDisappearing();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="typeOfPage">Page to display.</param>
|
||||
public async Task PushModalAsync(ViewTypes typeOfPage)
|
||||
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
|
||||
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync() => throw new NotSupportedException();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
}
|
||||
}
|
17
Meinkonrad/TINK/View/RootFlyout/RootPage.xaml
Normal file
17
Meinkonrad/TINK/View/RootFlyout/RootPage.xaml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.Root.RootPage"
|
||||
xmlns:pages="clr-namespace:TINK.View.Root"
|
||||
xmlns:mappage="clr-namespace:TINK.View.Map">
|
||||
<FlyoutPage.Flyout>
|
||||
<pages:RootPageFlyout x:Name="FlyoutPage" />
|
||||
</FlyoutPage.Flyout>
|
||||
<FlyoutPage.Detail>
|
||||
<NavigationPage>
|
||||
<x:Arguments>
|
||||
<mappage:MapPage />
|
||||
</x:Arguments>
|
||||
</NavigationPage>
|
||||
</FlyoutPage.Detail>
|
||||
</FlyoutPage>
|
95
Meinkonrad/TINK/View/RootFlyout/RootPage.xaml.cs
Normal file
95
Meinkonrad/TINK/View/RootFlyout/RootPage.xaml.cs
Normal file
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using TINK.Model.Station;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Root
|
||||
{
|
||||
/// <summary>
|
||||
/// Mamages creation of detail pages if a flyout page menu entry is selected.
|
||||
/// Exposes flyout page style navigation which is used by detail pages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Examples of use cases when detail pages do navigation:
|
||||
// - switch to map page after succesfully logging in/ logging out
|
||||
// - switch to login page form bikes at station page if not yet logged in
|
||||
/// </remarks>
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class RootPage : FlyoutPage, INavigationMasterDetail
|
||||
#else
|
||||
public partial class RootPage : FlyoutPage
|
||||
#endif
|
||||
{
|
||||
public RootPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
|
||||
|
||||
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
|
||||
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
|
||||
|
||||
var navigationPage = Detail as NavigationPage;
|
||||
if (navigationPage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
var detailPage = navigationPage.RootPage as IDetailPage;
|
||||
if (detailPage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
detailPage.NavigationMasterDetail = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called if a flyout page menu entry is selected.
|
||||
/// Creates a new page.
|
||||
/// </summary>
|
||||
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
if (!(e.SelectedItem is RootPageFlyoutMenuItem item))
|
||||
{
|
||||
// Unexpected argument detected.
|
||||
return;
|
||||
}
|
||||
|
||||
// Set selected station to new
|
||||
App.ModelRoot.SelectedStation = new NullStation();
|
||||
|
||||
ShowPage(item.TargetType, item.Title);
|
||||
|
||||
IsPresented = false;
|
||||
FlyoutPage.ListView.SelectedItem = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a detail page.
|
||||
/// </summary>
|
||||
/// <param name="typeOfPage">Type of page to show.</param>
|
||||
/// <param name="title">Title of page.</param>
|
||||
public void ShowPage(Type typeOfPage, string title)
|
||||
{
|
||||
var page = (Page)Activator.CreateInstance(typeOfPage);
|
||||
page.Title = title;
|
||||
|
||||
#if USEFLYOUT
|
||||
if (page is IDetailPage detailPage)
|
||||
{
|
||||
// Detail page needs reference to perform navigation.
|
||||
// Examples see above in xdoc of class.
|
||||
detailPage.NavigationMasterDetail = this;
|
||||
}
|
||||
#endif
|
||||
|
||||
Detail = new NavigationPage(page);
|
||||
}
|
||||
}
|
||||
}
|
61
Meinkonrad/TINK/View/RootFlyout/RootPageFlyout.xaml
Normal file
61
Meinkonrad/TINK/View/RootFlyout/RootPageFlyout.xaml
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.Root.RootPageFlyout"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
xmlns:local="clr-namespace:TINK.View"
|
||||
IconImageSource="menu"
|
||||
Title="sharee.bike">
|
||||
<StackLayout>
|
||||
<ListView x:Name="MenuItemsListView"
|
||||
SeparatorVisibility="None"
|
||||
HasUnevenRows="true"
|
||||
local:ListViewAttachedBehavior.Command="{Binding MenuItemSelected}"
|
||||
ItemsSource="{Binding MenuItems}">
|
||||
<ListView.Header>
|
||||
<Grid BackgroundColor="{DynamicResource Key=primary-back-title-color}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="10"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="10"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="80"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="10"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label
|
||||
Grid.Column="1"
|
||||
Grid.Row="2"
|
||||
Text="{Binding MasterDetailMenuTitlte}"
|
||||
Style="{DynamicResource SubtitleStyle}"/>
|
||||
</Grid>
|
||||
</ListView.Header>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell>
|
||||
<Grid Padding="5,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="30"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image>
|
||||
<Image.Source>
|
||||
<FontImageSource Glyph="{Binding GlyphCode}" Color="Black" FontFamily="FA-S"/>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<Label
|
||||
Grid.Column="1"
|
||||
Margin="10, 0, 0, 0"
|
||||
VerticalOptions="FillAndExpand"
|
||||
VerticalTextAlignment="Center"
|
||||
FontSize="18"
|
||||
Text="{Binding Title}"/>
|
||||
</Grid>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
36
Meinkonrad/TINK/View/RootFlyout/RootPageFlyout.xaml.cs
Normal file
36
Meinkonrad/TINK/View/RootFlyout/RootPageFlyout.xaml.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model;
|
||||
using TINK.Services;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.View.Themes;
|
||||
using TINK.ViewModel.Root;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Root
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class RootPageFlyout : ContentPage
|
||||
{
|
||||
public ListView ListView;
|
||||
|
||||
public RootPageFlyout()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
BindingContext = new RootPageFlyoutViewModel();
|
||||
|
||||
ListView = MenuItemsListView;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
20
Meinkonrad/TINK/View/RootFlyout/RootPageFlyoutMenuItem.cs
Normal file
20
Meinkonrad/TINK/View/RootFlyout/RootPageFlyoutMenuItem.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
|
||||
namespace TINK.View.Root
|
||||
{
|
||||
|
||||
public class RootPageFlyoutMenuItem
|
||||
{
|
||||
public RootPageFlyoutMenuItem()
|
||||
{
|
||||
TargetType = typeof(RootPageFlyoutMenuItem);
|
||||
}
|
||||
public int Id { get; set; }
|
||||
|
||||
public string GlyphCode { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public Type TargetType { get; set; }
|
||||
}
|
||||
}
|
42
Meinkonrad/TINK/View/RootMasterDetail/MainPageMenuItem.cs
Normal file
42
Meinkonrad/TINK/View/RootMasterDetail/MainPageMenuItem.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using TINK.View.Map;
|
||||
using TINK.ViewModel.MasterDetail;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
public class MainPageMenuItem
|
||||
{
|
||||
public MainPageMenuItem()
|
||||
{
|
||||
TargetType = typeof(MapPage);
|
||||
}
|
||||
|
||||
public MainPageMenuItem(
|
||||
int p_iId,
|
||||
Type p_oTypeOfPage,
|
||||
string p_strTitle = null)
|
||||
{
|
||||
TargetType = p_oTypeOfPage;
|
||||
Id = p_iId;
|
||||
Title = p_strTitle ?? Helper.GetCaption(p_oTypeOfPage);
|
||||
}
|
||||
|
||||
public int Id
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Type TargetType
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
}
|
109
Meinkonrad/TINK/View/RootShell/AppShell.xaml
Normal file
109
Meinkonrad/TINK/View/RootShell/AppShell.xaml
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
xmlns:mappage="clr-namespace:TINK.View.Map"
|
||||
xmlns:findbike="clr-namespace:TINK.View.FindBike"
|
||||
xmlns:mybikes="clr-namespace:TINK.View.MyBikes"
|
||||
xmlns:account="clr-namespace:TINK.View.Account"
|
||||
xmlns:login="clr-namespace:TINK.View.Login"
|
||||
xmlns:settings="clr-namespace:TINK.View.Settings"
|
||||
xmlns:contact="clr-namespace:TINK.View.Contact"
|
||||
xmlns:info="clr-namespace:TINK.View.Info"
|
||||
xmlns:header="clr-namespace:TINK.View.RootShell"
|
||||
BackgroundColor="{DynamicResource Key=primary-back-title-color}"
|
||||
Title="Shell"
|
||||
x:Class="TINK.View.RootShell.AppShell">
|
||||
<Shell.FlyoutHeader>
|
||||
<header:FlyoutHeader/>
|
||||
</Shell.FlyoutHeader>
|
||||
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingMapPage}"
|
||||
Route="MapPage"
|
||||
ContentTemplate="{DataTemplate mappage:MapPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconMap}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingFindBike}"
|
||||
IsVisible="{Binding IsFindBikePageVisible}"
|
||||
ContentTemplate="{DataTemplate findbike:FindBikePage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconFindBike}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingMyBikes}"
|
||||
IsVisible="{Binding IsMyBikesPageVisible}"
|
||||
ContentTemplate="{DataTemplate mybikes:MyBikesPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconMyBikes}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingAccount}"
|
||||
IsVisible="{Binding IsAccountPageVisible}"
|
||||
ContentTemplate="{DataTemplate account:AccountPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconAccount}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingLogin}"
|
||||
Route="LoginPage"
|
||||
IsVisible="{Binding IsLoginPageVisible}"
|
||||
ContentTemplate="{DataTemplate login:LoginPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconLogin}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingSettings}"
|
||||
IsVisible="{Binding IsSettingsPageVisible}"
|
||||
ContentTemplate="{DataTemplate settings:SettingsPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconSettings}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingFeesAndBikes}"
|
||||
ContentTemplate="{DataTemplate contact:FeesAndBikesPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconFeesAndBikes}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingFeedbackAndContact}"
|
||||
ContentTemplate="{DataTemplate contact:ContactPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconContact}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{Binding TabbedPageIngoTitle}"
|
||||
ContentTemplate="{DataTemplate info:TabbedPageInfo}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconInfo}" Color="Black" FontFamily="FA-S" />
|
||||
</ShellContent.FlyoutIcon>
|
||||
</ShellContent>
|
||||
</FlyoutItem>
|
||||
</Shell>
|
15
Meinkonrad/TINK/View/RootShell/AppShell.xaml.cs
Normal file
15
Meinkonrad/TINK/View/RootShell/AppShell.xaml.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
using TINK.ViewModel.RootShell;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.View.RootShell
|
||||
{
|
||||
public partial class AppShell : Shell
|
||||
{
|
||||
public AppShell()
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = new AppShellViewModel();
|
||||
}
|
||||
}
|
||||
}
|
21
Meinkonrad/TINK/View/RootShell/FlyoutHeader.xaml
Normal file
21
Meinkonrad/TINK/View/RootShell/FlyoutHeader.xaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?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}"
|
||||
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"
|
||||
Text="{Binding MasterDetailMenuTitlte}"/>
|
||||
</Grid>
|
||||
</ContentView>
|
20
Meinkonrad/TINK/View/RootShell/FlyoutHeader.xaml.cs
Normal file
20
Meinkonrad/TINK/View/RootShell/FlyoutHeader.xaml.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.RootShell
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FlyoutHeader : ContentView
|
||||
{
|
||||
public FlyoutHeader ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Xamarin.Forms;
|
||||
using TINK.Model.User.Account;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace TINK.View.Settings
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Translates user permissions into visibility state.
|
||||
/// Used for container which holds a bunch of GUI elemets which migth all/ partly/ none be visible
|
||||
/// If all childs are invisible frame must be invisible as well. As soon as one child is visible frame must be visible as well.
|
||||
/// </summary>
|
||||
public class AnyPermissionToVisibleConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Converts permission value into visible state.</summary>
|
||||
/// <param name="value">Permission value from view model used to derive whether object is visible or not.</param>
|
||||
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return ((Permissions)(value)) != Permissions.None;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return Permissions.None;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Xamarin.Forms;
|
||||
using TINK.Model.User.Account;
|
||||
|
||||
namespace TINK.View.Settings
|
||||
{
|
||||
/// <summary> Translates user permissions into visibility state. </summary>
|
||||
public class PermissionToVisibleConverter : BindableObject, IValueConverter
|
||||
{
|
||||
static readonly BindableProperty VisibleFlagProperty =
|
||||
BindableProperty.Create(nameof(VisibleFlag), typeof(Permissions), typeof(BindableObject));
|
||||
|
||||
/// <summary> Property set from XAML determinig for which permission value object is visible.</summary>
|
||||
public Permissions VisibleFlag
|
||||
{
|
||||
get => (Permissions)GetValue(VisibleFlagProperty);
|
||||
set => SetValue(VisibleFlagProperty, value);
|
||||
}
|
||||
|
||||
/// <summary> Converts permission value into visible state.</summary>
|
||||
/// <param name="value">Permission value from view model used to derive whether object is visible or not.</param>
|
||||
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return ((Permissions)value).HasFlag(VisibleFlag);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return Permissions.None;
|
||||
}
|
||||
}
|
||||
}
|
230
Meinkonrad/TINK/View/Settings/SettingsPage.xaml
Normal file
230
Meinkonrad/TINK/View/Settings/SettingsPage.xaml
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.Settings.SettingsPage"
|
||||
xmlns:conv="clr-namespace:TINK.View.Settings">
|
||||
|
||||
<ContentPage.Resources>
|
||||
<conv:AnyPermissionToVisibleConverter x:Key="Frame_Converter"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="PickCopriServer_Converter" VisibleFlag="PickCopriServer"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="ManagePolling_Converter" VisibleFlag="ManagePolling"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="ManageCopriCacheExpiration_Converter" VisibleFlag="ManageCopriCacheExpiration"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="PickLockServiceImplementation_Converter" VisibleFlag="PickLockServiceImplementation"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="PickLocationServiceImplementation_Converter" VisibleFlag="PickLocationServiceImplementation"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="PickLoggingLevel_Converter" VisibleFlag="PickLoggingLevel"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="ReportLevel_Converter" VisibleFlag="ReportLevel"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="ShowDiagnostics_Converter" VisibleFlag="ShowDiagnostics"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="SwitchSiteCaching_Converter" VisibleFlag="SwitchNoSiteCaching"/>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ContentPage.Content>
|
||||
<ScrollView>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<!--
|
||||
<Button Text="Feedback" Clicked="OnFeedbackClickedAsync"/>
|
||||
-->
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label Text="Karte auf aktuelle Position ausrichten"/>
|
||||
<Switch IsToggled="{Binding CenterMapToCurrentLocation}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<!-- Filter on view TINK/ Konrad -->
|
||||
<Frame IsVisible="{Binding IsGroupFilterVisible}">
|
||||
<StackLayout>
|
||||
<Label Text="Ausblenden/ Einblenden"/>
|
||||
<ListView
|
||||
HasUnevenRows="True"
|
||||
HeightRequest="120"
|
||||
x:Name="Filters">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ViewCell IsEnabled="{Binding IsEnabled}">
|
||||
<StackLayout Orientation="Horizontal">
|
||||
<Label Text="{Binding Text}"/>
|
||||
<Switch IsToggled="{Binding IsActivated}"/>
|
||||
</StackLayout>
|
||||
</ViewCell>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<StackLayout>
|
||||
<!-- Themes -->
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
Text="Theme"/>
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
ItemsSource="{Binding Themes.ServicesTextList}"
|
||||
SelectedItem="{Binding Themes.ActiveText}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- COPRI server selection -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
Text="{Binding CopriServerUriList.CorpiServerUriDescription}"/>
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
ItemsSource="{Binding CopriServerUriList.ServerTextList}"
|
||||
SelectedItem="{Binding CopriServerUriList.NextActiveServerText}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManagePolling_Converter}}"
|
||||
Text="{Binding Polling.PollingText}"/>
|
||||
<Switch
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManagePolling_Converter}}"
|
||||
IsToggled="{Binding Polling.IsActivated}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManagePolling_Converter}}"
|
||||
Text="{Binding Polling.PeriodeTotalSecondsText}"/>
|
||||
<Stepper
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManagePolling_Converter}}"
|
||||
Minimum="5"
|
||||
Increment="5"
|
||||
Maximum="600"
|
||||
IsEnabled="{Binding Polling.IsActivated}"
|
||||
Value="{Binding Polling.PeriodeTotalSeconds}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManageCopriCacheExpiration_Converter}}"
|
||||
Text="Time after which COPRI-cache expires [s]"/>
|
||||
<Slider
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManageCopriCacheExpiration_Converter}}"
|
||||
x:Name="expiresAfter"
|
||||
Minimum="0"
|
||||
Maximum="15"
|
||||
Value="{Binding ExpiresAfterTotalSeconds}"/>
|
||||
<Entry
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ManageCopriCacheExpiration_Converter}}"
|
||||
IsReadOnly="True"
|
||||
Text="{Binding ExpiresAfterTotalSecondsText}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Lock control -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLockServiceImplementation_Converter}}"
|
||||
Text="Lock Control" />
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLockServiceImplementation_Converter}}"
|
||||
ItemsSource="{Binding LocksServices.Services.ServicesTextList}"
|
||||
SelectedItem="{Binding LocksServices.Services.ActiveText}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLockServiceImplementation_Converter}}"
|
||||
Text="Bluetooth Connect Timeout [sec]"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLockServiceImplementation_Converter}}"
|
||||
Text="{Binding LocksServices.ConnectTimeoutSecText}"/>
|
||||
<Stepper
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLockServiceImplementation_Converter}}"
|
||||
Minimum="0.1"
|
||||
Increment="0.25"
|
||||
Maximum="60"
|
||||
Value="{Binding LocksServices.ConnectTimeoutSec}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Geolocation -->
|
||||
<StackLayout>
|
||||
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLocationServiceImplementation_Converter}}"
|
||||
Text="Geolocation Control" />
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLocationServiceImplementation_Converter}}"
|
||||
ItemsSource="{Binding GeolocationServices.ServicesTextList}"
|
||||
SelectedItem="{Binding GeolocationServices.ActiveText}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Web site caching -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchSiteCaching_Converter}}"
|
||||
Text="Caching von Websiten."/>
|
||||
<Switch
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource SwitchSiteCaching_Converter}}"
|
||||
IsToggled="{Binding IsSiteCachingOnDisplayValue}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Logging -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLoggingLevel_Converter}}"
|
||||
Text="Logging level" />
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLoggingLevel_Converter}}"
|
||||
ItemsSource="{Binding LoggingLevels}"
|
||||
SelectedItem="{Binding SelectedLoggingLevel}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLoggingLevel_Converter}}"
|
||||
Text="Logdatei in externen Pfad schreiben"/>
|
||||
<Switch
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickLoggingLevel_Converter}}"
|
||||
IsToggled="{Binding LogToExternalFolderDisplayValue}"
|
||||
IsEnabled="{Binding IsLogToExternalFolderVisible}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Logging -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ReportLevel_Converter}}"
|
||||
Text="Verbose error messages" />
|
||||
<Switch
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ReportLevel_Converter}}"
|
||||
IsToggled="{Binding IsReportLevelVerbose}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Display of parameters -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
Text="Device Identifier" />
|
||||
<Entry
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
IsEnabled="false"
|
||||
Text="{Binding DeviceIdentifier}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
Text="Copri Sitzungkeks"/>
|
||||
<Entry
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
IsEnabled="false"
|
||||
Text="{Binding SessionCookie}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
Text="Interner Pfad (Einstell./ ggf. Logging)"/>
|
||||
<Editor
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
IsEnabled="false"
|
||||
Text="{Binding InternalPath}"/>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
Text="Externer Pfad (Mock/ ggf. Logging)"/>
|
||||
<Editor
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ShowDiagnostics_Converter}}"
|
||||
IsEnabled="false"
|
||||
Text="{Binding ExternalPath}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ScrollView>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
164
Meinkonrad/TINK/View/Settings/SettingsPage.xaml.cs
Normal file
164
Meinkonrad/TINK/View/Settings/SettingsPage.xaml.cs
Normal file
|
@ -0,0 +1,164 @@
|
|||
using TINK.ViewModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using System.Threading.Tasks;
|
||||
#if USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using System;
|
||||
using TINK.Model.Device;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
|
||||
namespace TINK.View.Settings
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEFLYOUT
|
||||
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class SettingsPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
SettingsPageViewModel m_oViewModel = null;
|
||||
|
||||
/// <summary> Constructs a settings page. </summary>
|
||||
public SettingsPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
var l_oModel = App.ModelRoot;
|
||||
|
||||
m_oViewModel = new SettingsPageViewModel(
|
||||
l_oModel,
|
||||
App.GeolocationServicesContainer,
|
||||
this);
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
|
||||
Filters.ItemsSource = m_oViewModel.GroupFilter;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message. </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
/// <summary> Pops a page from the modal stack. </summary>
|
||||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
#if USEFLYOUT
|
||||
/// <summary>Delegate to perform navigation.</summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail
|
||||
{
|
||||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
protected async override void OnDisappearing()
|
||||
{
|
||||
if (m_oViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
|
||||
await m_oViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
|
||||
#if USERFEEDBACKDLG_TRYOUT
|
||||
public async void OnFeedbackClickedAsync(object sender, EventArgs ev)
|
||||
{
|
||||
var result = await DisplayUserFeedbackPopup();
|
||||
|
||||
DisplayAlert(
|
||||
"Title",
|
||||
$"Bike broken: {result.IsBikeBroken}. Message: {result.Message}.",
|
||||
"OK");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
/// <summary> Converts a string into visible state. If string is null or empty element becomes invisible.</summary>
|
||||
public class StringNotNullOrEmptyToVisibleConverter : IValueConverter
|
||||
{
|
||||
/// <summary> Converts a string into visible state.</summary>
|
||||
/// <param name="value">Text value from view model used to derive whether object is visible or not.</param>
|
||||
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value != null && value is string text && !string.IsNullOrEmpty(text);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
77
Meinkonrad/TINK/View/ViewTypesTypeProvider.cs
Normal file
77
Meinkonrad/TINK/View/ViewTypesTypeProvider.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using TINK.View.Contact;
|
||||
using TINK.View.CopriWebView;
|
||||
using TINK.View.Info;
|
||||
using TINK.View.Info.BikeInfo;
|
||||
using TINK.View.Login;
|
||||
using TINK.View.Map;
|
||||
using TINK.View.MyBikes;
|
||||
using TINK.View.Settings;
|
||||
using TINK.View.WhatsNew;
|
||||
using TINK.View.WhatsNew.Agb;
|
||||
using TINK.View.BikesAtStation;
|
||||
using Xamarin.Forms;
|
||||
using TINK.View.MiniSurvey;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
public static class ViewTypesTypeProvider
|
||||
{
|
||||
public static Type GetViewType(this ViewTypes viewType)
|
||||
{
|
||||
switch (viewType)
|
||||
{
|
||||
case ViewTypes.LoginPage:
|
||||
return typeof(LoginPage);
|
||||
|
||||
case ViewTypes.MapPage:
|
||||
return typeof(MapPage);
|
||||
|
||||
case ViewTypes.RegisterPage:
|
||||
return typeof(RegisterPage);
|
||||
|
||||
case ViewTypes.PasswordForgottenPage:
|
||||
return typeof(PasswordForgottenPage);
|
||||
|
||||
case ViewTypes.BikeInfoCarouselPage:
|
||||
return typeof(BikeInfoCarouselPage);
|
||||
|
||||
case ViewTypes.MyBikesPage:
|
||||
return typeof(MyBikesPage);
|
||||
|
||||
case ViewTypes.SettingsPage:
|
||||
return typeof(SettingsPage);
|
||||
|
||||
case ViewTypes.TabbedPageInfo:
|
||||
return typeof(TabbedPageInfo);
|
||||
|
||||
case ViewTypes.FeesAndBikesPage:
|
||||
return typeof(FeesAndBikesPage);
|
||||
|
||||
case ViewTypes.ManageAccountPage:
|
||||
return typeof(ManageAccountPage);
|
||||
|
||||
case ViewTypes.AgbPage:
|
||||
return typeof(AgbPage);
|
||||
|
||||
case ViewTypes.WhatsNewPage:
|
||||
return typeof(WhatsNewPage);
|
||||
|
||||
case ViewTypes.BikesAtStation:
|
||||
return typeof(BikesAtStationPage);
|
||||
|
||||
case ViewTypes.ContactPage:
|
||||
return typeof(ContactPage);
|
||||
|
||||
case ViewTypes.SelectStationPage:
|
||||
return typeof(SelectStationPage);
|
||||
|
||||
case ViewTypes.MiniSurvey:
|
||||
return typeof(MiniSurveyPage);
|
||||
|
||||
default:
|
||||
return typeof(ContentPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
Meinkonrad/TINK/View/WhatsNew/Agb/AgbPage.xaml
Normal file
18
Meinkonrad/TINK/View/WhatsNew/Agb/AgbPage.xaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.WhatsNew.Agb.AgbPage">
|
||||
<ContentPage.Content>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<WebView
|
||||
HeightRequest="1000"
|
||||
WidthRequest="500"
|
||||
Source="{Binding InfoAgb}"/>
|
||||
<Button Text="OK"
|
||||
Command="{Binding OnOk}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
81
Meinkonrad/TINK/View/WhatsNew/Agb/AgbPage.xaml.cs
Normal file
81
Meinkonrad/TINK/View/WhatsNew/Agb/AgbPage.xaml.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.WhatsNew.Agb;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.WhatsNew.Agb
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class AgbPage : ContentPage, IViewService
|
||||
{
|
||||
public AgbPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
agbViewModel = new AgbViewModel(
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
(resourceName) => ViewModelResourceHelper.GetSource(resourceName),
|
||||
this);
|
||||
|
||||
BindingContext = agbViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary> Invoked when page is shown. </summary>
|
||||
protected async override void OnAppearing()
|
||||
=> await agbViewModel.OnAppearing();
|
||||
|
||||
/// <summary> Reference to view model.</summary>
|
||||
AgbViewModel agbViewModel;
|
||||
|
||||
public async Task PopModalAsync()
|
||||
=> await Navigation.PopModalAsync();
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
42
Meinkonrad/TINK/View/WhatsNew/WhatsNewPage.xaml
Normal file
42
Meinkonrad/TINK/View/WhatsNew/WhatsNewPage.xaml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.WhatsNew.WhatsNewPage">
|
||||
<ContentPage.Content>
|
||||
<ScrollView>
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label Text="{Binding WhatsNewTitle}"
|
||||
FontSize="Large"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="CenterAndExpand" />
|
||||
<Frame>
|
||||
<StackLayout>
|
||||
<Label
|
||||
Text="{Binding WhatsNewText}"
|
||||
TextType="Html"/>
|
||||
<Label FormattedText="{Binding AgbChangedText}"
|
||||
IsVisible="{Binding IsAgbChangedVisible}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding OnShowAgbTapped}"/>
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame IsVisible="{Binding IsFeedbackVisible}">
|
||||
<StackLayout>
|
||||
<Label Text="Gibts Verbesserungsvorschläge/ Probleme mit der App?"/>
|
||||
<Button Text="Verbesserungsmail schreiben"/>
|
||||
<Label Text="Die App läuft rund und tut was sie soll? Über eine Bewertung würden wir uns sehr freuen!"/>
|
||||
<Button Text="Bewertung abgeben"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
|
||||
<Button
|
||||
Text="OK"
|
||||
Command="{Binding OnOk}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</ScrollView>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
105
Meinkonrad/TINK/View/WhatsNew/WhatsNewPage.xaml.cs
Normal file
105
Meinkonrad/TINK/View/WhatsNew/WhatsNewPage.xaml.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.WhatsNew
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class WhatsNewPage : ContentPage, IViewService
|
||||
{
|
||||
/// <summary> Holds a reference on the view model. </summary>
|
||||
private ViewModel.WhatsNew.WhatsNewViewModel WhatsNewViewModel;
|
||||
|
||||
/// <summary> Constructs whats new page.</summary>
|
||||
/// <param name="showMasterDetail">Action to invoke master detail page.</param>
|
||||
public WhatsNewPage(Action showMasterDetail)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
WhatsNewViewModel = new ViewModel.WhatsNew.WhatsNewViewModel(
|
||||
DependencyService.Get<IAppInfo>().Version,
|
||||
App.ModelRoot.WhatsNew.WhatsNewText,
|
||||
App.ModelRoot.WhatsNew.IsShowAgbRequired,
|
||||
showMasterDetail,
|
||||
this);
|
||||
|
||||
BindingContext = WhatsNewViewModel;
|
||||
}
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotImplementedException(); ;
|
||||
}
|
||||
|
||||
/// <summary> Pushes a page onto the stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
|
||||
#if USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// /// </summary>
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
|
||||
if (WhatsNewViewModel == null)
|
||||
{
|
||||
// View model might be null.
|
||||
return;
|
||||
}
|
||||
|
||||
WhatsNewViewModel?.OnDisappearing(() =>
|
||||
{
|
||||
App.ModelRoot.SetWhatsNewWasShown();
|
||||
App.ModelRoot.Save();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue