feat: complete UM Trace iOS and field UI integration
This commit is contained in:
35
FieldLogger/Views/Controls/AppStatusBar.xaml
Normal file
35
FieldLogger/Views/Controls/AppStatusBar.xaml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
x:Class="FieldLogger.Views.Controls.AppStatusBar"
|
||||
x:DataType="vm:AppStatusViewModel">
|
||||
<Border BackgroundColor="{DynamicResource UlColorSurfaceStrong}"
|
||||
StrokeThickness="0" Padding="12,8">
|
||||
<Grid RowDefinitions="Auto,Auto" RowSpacing="4">
|
||||
<Grid ColumnDefinitions="*,*" ColumnSpacing="12">
|
||||
<HorizontalStackLayout Spacing="6">
|
||||
<Label Text="●" FontSize="13"
|
||||
TextColor="{Binding LocatorState, Converter={StaticResource StateColor}}"
|
||||
VerticalTextAlignment="Center" />
|
||||
<Label Text="{Binding LocatorStatus}" FontSize="12"
|
||||
TextColor="{DynamicResource UlColorOnStrong}"
|
||||
LineBreakMode="TailTruncation" />
|
||||
</HorizontalStackLayout>
|
||||
<HorizontalStackLayout Grid.Column="1" Spacing="6">
|
||||
<Label Text="●" FontSize="13"
|
||||
TextColor="{Binding GnssState, Converter={StaticResource StateColor}}"
|
||||
VerticalTextAlignment="Center" />
|
||||
<Label Text="{Binding GnssStatus}" FontSize="12"
|
||||
TextColor="{DynamicResource UlColorOnStrong}"
|
||||
LineBreakMode="TailTruncation" />
|
||||
</HorizontalStackLayout>
|
||||
</Grid>
|
||||
<Label Grid.Row="1" Text="{Binding PositionSummary}" FontSize="12"
|
||||
FontFamily="{StaticResource UlTypeFamilyMono}"
|
||||
TextColor="{DynamicResource UlColorOnStrong}"
|
||||
LineBreakMode="TailTruncation"
|
||||
SemanticProperties.Description="Current GNSS fix type, estimated accuracy, satellites, and correction age" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</ContentView>
|
||||
40
FieldLogger/Views/Controls/AppStatusBar.xaml.cs
Normal file
40
FieldLogger/Views/Controls/AppStatusBar.xaml.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using FieldLogger.ViewModels;
|
||||
|
||||
namespace FieldLogger.Views.Controls;
|
||||
|
||||
public partial class AppStatusBar : ContentView
|
||||
{
|
||||
private IDispatcherTimer? _staleTimer;
|
||||
|
||||
public AppStatusBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnHandlerChanged()
|
||||
{
|
||||
base.OnHandlerChanged();
|
||||
|
||||
if (Handler is null)
|
||||
{
|
||||
_staleTimer?.Stop();
|
||||
_staleTimer = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_staleTimer is not null)
|
||||
return;
|
||||
|
||||
_staleTimer = Dispatcher.CreateTimer();
|
||||
_staleTimer.Interval = TimeSpan.FromSeconds(1);
|
||||
_staleTimer.Tick += (_, _) => (BindingContext as AppStatusViewModel)?.Refresh();
|
||||
_staleTimer.Start();
|
||||
(BindingContext as AppStatusViewModel)?.Refresh();
|
||||
}
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
base.OnBindingContextChanged();
|
||||
(BindingContext as AppStatusViewModel)?.Refresh();
|
||||
}
|
||||
}
|
||||
15
FieldLogger/Views/Controls/FloatingMenuButton.xaml
Normal file
15
FieldLogger/Views/Controls/FloatingMenuButton.xaml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="FieldLogger.Views.Controls.FloatingMenuButton">
|
||||
<Button Text="☰" FontSize="24" FontAttributes="Bold"
|
||||
WidthRequest="56" HeightRequest="56" CornerRadius="28"
|
||||
Padding="0" Margin="16"
|
||||
BackgroundColor="{DynamicResource UlColorPrimary}"
|
||||
TextColor="{DynamicResource UlColorOnPrimary}"
|
||||
BorderColor="{DynamicResource UlColorSurfaceRaised}" BorderWidth="2"
|
||||
Clicked="OnMenuClicked"
|
||||
SemanticProperties.Description="Open UM Trace menu"
|
||||
MinimumHeightRequest="{StaticResource UlTouchComfortable}"
|
||||
MinimumWidthRequest="{StaticResource UlTouchComfortable}" />
|
||||
</ContentView>
|
||||
15
FieldLogger/Views/Controls/FloatingMenuButton.xaml.cs
Normal file
15
FieldLogger/Views/Controls/FloatingMenuButton.xaml.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace FieldLogger.Views.Controls;
|
||||
|
||||
public partial class FloatingMenuButton : ContentView
|
||||
{
|
||||
public FloatingMenuButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnMenuClicked(object? sender, EventArgs e)
|
||||
{
|
||||
if (Shell.Current is not null)
|
||||
Shell.Current.FlyoutIsPresented = true;
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,13 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
xmlns:models="clr-namespace:FieldLogger.Models"
|
||||
xmlns:controls="clr-namespace:FieldLogger.Views.Controls"
|
||||
x:Class="FieldLogger.Views.DebugPage"
|
||||
x:DataType="vm:DebugViewModel"
|
||||
Title="Debug">
|
||||
<ScrollView>
|
||||
Title="Device Console">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<controls:AppStatusBar x:Name="AppStatus" />
|
||||
<ScrollView Grid.Row="1">
|
||||
<VerticalStackLayout Padding="16" Spacing="12">
|
||||
|
||||
<Label Text="Connection Status" FontAttributes="Bold" FontSize="16" />
|
||||
@@ -88,4 +91,5 @@
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
|
||||
@@ -6,11 +6,12 @@ public partial class DebugPage : ContentPage
|
||||
{
|
||||
private readonly DebugViewModel _viewModel;
|
||||
|
||||
public DebugPage(DebugViewModel viewModel)
|
||||
public DebugPage(DebugViewModel viewModel, AppStatusViewModel appStatusViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
_viewModel = viewModel;
|
||||
BindingContext = viewModel;
|
||||
AppStatus.BindingContext = appStatusViewModel;
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
|
||||
@@ -3,16 +3,19 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
xmlns:models="clr-namespace:FieldLogger.Models"
|
||||
xmlns:controls="clr-namespace:FieldLogger.Views.Controls"
|
||||
x:Class="FieldLogger.Views.HomePage"
|
||||
x:DataType="vm:HomeViewModel"
|
||||
Title="Field Logger"
|
||||
Title="Debug"
|
||||
BackgroundColor="{DynamicResource UlColorCanvas}">
|
||||
<ScrollView>
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<controls:AppStatusBar x:Name="AppStatus" />
|
||||
<ScrollView Grid.Row="1">
|
||||
<VerticalStackLayout Padding="16" Spacing="16">
|
||||
<VerticalStackLayout Spacing="4">
|
||||
<Label Text="FIELD LOGGER" FontSize="14" FontAttributes="Bold" CharacterSpacing="1.5"
|
||||
<Label Text="UM TRACE DEBUG" FontSize="14" FontAttributes="Bold" CharacterSpacing="1.5"
|
||||
TextColor="{DynamicResource UlColorPrimary}" />
|
||||
<Label Text="Live field capture" Style="{StaticResource UlPageTitle}"
|
||||
<Label Text="Capture diagnostics" Style="{StaticResource UlPageTitle}"
|
||||
TextColor="{DynamicResource UlColorText}"
|
||||
SemanticProperties.HeadingLevel="Level1" />
|
||||
</VerticalStackLayout>
|
||||
@@ -187,6 +190,13 @@
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
|
||||
<Button Style="{StaticResource UlButtonSecondary}"
|
||||
Text="Open device console" Command="{Binding OpenDeviceConsoleCommand}"
|
||||
IsVisible="{Binding IsDeviceConsoleAvailable}"
|
||||
MinimumHeightRequest="{StaticResource UlTouchMinimum}"
|
||||
SemanticProperties.Description="Open raw locator and GNSS device messages" />
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
|
||||
@@ -7,10 +7,11 @@ public partial class HomePage : ContentPage
|
||||
private readonly HomeViewModel _viewModel;
|
||||
private bool _initialized;
|
||||
|
||||
public HomePage(HomeViewModel viewModel)
|
||||
public HomePage(HomeViewModel viewModel, AppStatusViewModel appStatusViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = _viewModel = viewModel;
|
||||
AppStatus.BindingContext = appStatusViewModel;
|
||||
}
|
||||
|
||||
protected override async void OnAppearing()
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
xmlns:models="clr-namespace:FieldLogger.Models"
|
||||
xmlns:controls="clr-namespace:FieldLogger.Views.Controls"
|
||||
x:Class="FieldLogger.Views.JobDetailPage"
|
||||
x:DataType="vm:JobDetailViewModel"
|
||||
Title="{Binding JobName}"
|
||||
BackgroundColor="{DynamicResource UlColorCanvas}">
|
||||
<Grid RowDefinitions="Auto,*" Padding="16" RowSpacing="16">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<controls:AppStatusBar x:Name="AppStatus" />
|
||||
<Grid Grid.Row="1" RowDefinitions="Auto,*" Padding="16" RowSpacing="16">
|
||||
<Border Style="{StaticResource UlCard}" BackgroundColor="{DynamicResource UlColorSurfaceRaised}"
|
||||
Stroke="{DynamicResource UlColorBorder}" StrokeShape="RoundRectangle 12" Padding="16">
|
||||
<Grid RowDefinitions="Auto,Auto" ColumnDefinitions="*,Auto" RowSpacing="6" ColumnSpacing="12">
|
||||
@@ -37,7 +40,7 @@
|
||||
<VerticalStackLayout Spacing="8">
|
||||
<Label Text="No captures for this job" Style="{StaticResource UlEmptyStateTitle}"
|
||||
HorizontalTextAlignment="Center" TextColor="{DynamicResource UlColorText}" />
|
||||
<Label Text="Return Home and press LOG on the receiver when the job is active."
|
||||
<Label Text="Open Debug from Settings and press LOG on the receiver when the job is active."
|
||||
Style="{StaticResource UlEmptyStateBody}"
|
||||
FontSize="16" HorizontalTextAlignment="Center"
|
||||
TextColor="{DynamicResource UlColorTextMuted}" />
|
||||
@@ -103,4 +106,5 @@
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
|
||||
@@ -6,10 +6,11 @@ public partial class JobDetailPage : ContentPage
|
||||
{
|
||||
private readonly JobDetailViewModel _viewModel;
|
||||
|
||||
public JobDetailPage(JobDetailViewModel viewModel)
|
||||
public JobDetailPage(JobDetailViewModel viewModel, AppStatusViewModel appStatusViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = _viewModel = viewModel;
|
||||
AppStatus.BindingContext = appStatusViewModel;
|
||||
}
|
||||
|
||||
protected override async void OnAppearing()
|
||||
|
||||
@@ -2,11 +2,18 @@
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
xmlns:controls="clr-namespace:FieldLogger.Views.Controls"
|
||||
x:Class="FieldLogger.Views.JobsPage"
|
||||
x:DataType="vm:JobsViewModel"
|
||||
Title="Jobs"
|
||||
Shell.NavBarIsVisible="False"
|
||||
BackgroundColor="{DynamicResource UlColorCanvas}">
|
||||
<Grid RowDefinitions="Auto,Auto,*" Padding="16" RowSpacing="16">
|
||||
<Grid RowDefinitions="Auto,*"
|
||||
HorizontalOptions="Fill" VerticalOptions="Fill">
|
||||
<controls:AppStatusBar x:Name="AppStatus" />
|
||||
|
||||
<Grid Grid.Row="1" RowDefinitions="Auto,Auto,*" Padding="16" RowSpacing="16"
|
||||
HorizontalOptions="Fill" VerticalOptions="Fill">
|
||||
<VerticalStackLayout Spacing="4">
|
||||
<Label Text="FIELD WORK" FontSize="14" FontAttributes="Bold" CharacterSpacing="1.5"
|
||||
TextColor="{DynamicResource UlColorPrimary}" />
|
||||
@@ -22,9 +29,15 @@
|
||||
MinimumHeightRequest="{StaticResource UlTouchComfortable}" FontSize="16" FontAttributes="Bold"
|
||||
SemanticProperties.Description="Create a new job and make it active" />
|
||||
|
||||
<RefreshView Grid.Row="2" Command="{Binding RefreshCommand}" IsRefreshing="{Binding IsBusy}">
|
||||
<RefreshView Grid.Row="2"
|
||||
Command="{Binding RefreshCommand}"
|
||||
IsRefreshing="{Binding IsRefreshing, Mode=OneWay}"
|
||||
HorizontalOptions="Fill" VerticalOptions="Fill">
|
||||
<CollectionView ItemsSource="{Binding Jobs}"
|
||||
SelectionMode="None"
|
||||
ItemSizingStrategy="MeasureFirstItem"
|
||||
ItemsUpdatingScrollMode="KeepItemsInView"
|
||||
HorizontalOptions="Fill" VerticalOptions="Fill"
|
||||
SemanticProperties.Description="Jobs available on this device">
|
||||
<CollectionView.EmptyView>
|
||||
<Border Style="{StaticResource UlCard}" BackgroundColor="{DynamicResource UlColorSurfaceRaised}"
|
||||
@@ -88,7 +101,15 @@
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
<CollectionView.Footer>
|
||||
<!-- Keeps the final row scrollable above the overlaid menu without
|
||||
reserving a permanent bottom band in the page layout. -->
|
||||
<ContentView HeightRequest="72" />
|
||||
</CollectionView.Footer>
|
||||
</CollectionView>
|
||||
</RefreshView>
|
||||
</Grid>
|
||||
|
||||
<controls:FloatingMenuButton Grid.RowSpan="2" HorizontalOptions="End" VerticalOptions="End" ZIndex="20" />
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
|
||||
@@ -6,15 +6,16 @@ public partial class JobsPage : ContentPage
|
||||
{
|
||||
private readonly JobsViewModel _viewModel;
|
||||
|
||||
public JobsPage(JobsViewModel viewModel)
|
||||
public JobsPage(JobsViewModel viewModel, AppStatusViewModel appStatusViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = _viewModel = viewModel;
|
||||
AppStatus.BindingContext = appStatusViewModel;
|
||||
}
|
||||
|
||||
protected override async void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
await _viewModel.RefreshAsync();
|
||||
await _viewModel.LoadAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,34 +2,31 @@
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
xmlns:controls="clr-namespace:FieldLogger.Views.Controls"
|
||||
x:Class="FieldLogger.Views.MapPage"
|
||||
x:DataType="vm:MapViewModel"
|
||||
Title="Map"
|
||||
Shell.NavBarIsVisible="False"
|
||||
BackgroundColor="{DynamicResource UlColorMap}">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Border Style="{StaticResource UlCard}" Margin="12" Padding="16" BackgroundColor="{DynamicResource UlColorSurfaceRaised}"
|
||||
Stroke="{DynamicResource UlColorBorder}" StrokeShape="RoundRectangle 12"
|
||||
ZIndex="1">
|
||||
<Grid RowDefinitions="Auto,Auto" ColumnDefinitions="*,Auto" RowSpacing="4" ColumnSpacing="12">
|
||||
<VerticalStackLayout>
|
||||
<Label Text="LIVE MAP" FontSize="14" FontAttributes="Bold" CharacterSpacing="1.5"
|
||||
TextColor="{DynamicResource UlColorPrimary}" />
|
||||
<Label Text="{Binding JobName, TargetNullValue='No active job'}"
|
||||
Style="{StaticResource UlSectionTitle}" TextColor="{DynamicResource UlColorText}"
|
||||
SemanticProperties.HeadingLevel="Level1" />
|
||||
</VerticalStackLayout>
|
||||
<Button Grid.Column="1" Style="{StaticResource UlButtonSecondary}"
|
||||
Text="Refresh" Clicked="OnRefreshClicked"
|
||||
MinimumHeightRequest="{StaticResource UlTouchMinimum}" MinimumWidthRequest="88"
|
||||
SemanticProperties.Description="Refresh captured points on the map" />
|
||||
<Label Grid.Row="1" Grid.ColumnSpan="2" Text="{Binding StatusText}" FontSize="14"
|
||||
TextColor="{DynamicResource UlColorTextMuted}"
|
||||
SemanticProperties.Description="Current map data status" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<Grid>
|
||||
<!-- Populated in code-behind: native Map control on iOS/Android/macOS, Google Maps WebView on Windows. -->
|
||||
<ContentView Grid.RowSpan="2" x:Name="MapHost"
|
||||
<ContentView x:Name="MapHost"
|
||||
BackgroundColor="{DynamicResource UlColorMap}"
|
||||
SemanticProperties.Description="Map of locally captured points for the selected job" />
|
||||
|
||||
<controls:AppStatusBar x:Name="AppStatus" VerticalOptions="Start" ZIndex="20" />
|
||||
|
||||
<Button Text="↻" FontSize="22" FontAttributes="Bold"
|
||||
WidthRequest="48" HeightRequest="48" CornerRadius="24" Padding="0"
|
||||
Margin="16,82,16,16" HorizontalOptions="End" VerticalOptions="Start"
|
||||
BackgroundColor="{DynamicResource UlColorSurfaceRaised}"
|
||||
TextColor="{DynamicResource UlColorPrimary}"
|
||||
BorderColor="{DynamicResource UlColorBorder}" BorderWidth="1"
|
||||
Clicked="OnRefreshClicked" ZIndex="20"
|
||||
MinimumHeightRequest="{StaticResource UlTouchMinimum}"
|
||||
MinimumWidthRequest="{StaticResource UlTouchMinimum}"
|
||||
SemanticProperties.Description="Refresh captured points on the map" />
|
||||
|
||||
<controls:FloatingMenuButton HorizontalOptions="End" VerticalOptions="End" ZIndex="20" />
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
|
||||
@@ -23,10 +23,11 @@ public partial class MapPage : ContentPage
|
||||
private Map? _map;
|
||||
#endif
|
||||
|
||||
public MapPage(MapViewModel viewModel)
|
||||
public MapPage(MapViewModel viewModel, AppStatusViewModel appStatusViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = _viewModel = viewModel;
|
||||
AppStatus.BindingContext = appStatusViewModel;
|
||||
}
|
||||
|
||||
protected override async void OnAppearing()
|
||||
|
||||
@@ -2,11 +2,20 @@
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:vm="clr-namespace:FieldLogger.ViewModels"
|
||||
xmlns:controls="clr-namespace:FieldLogger.Views.Controls"
|
||||
x:Class="FieldLogger.Views.SettingsPage"
|
||||
x:DataType="vm:SettingsViewModel"
|
||||
Title="Settings">
|
||||
<ScrollView>
|
||||
<VerticalStackLayout Padding="16" Spacing="12">
|
||||
Title="Settings"
|
||||
Shell.NavBarIsVisible="False"
|
||||
BackgroundColor="{DynamicResource UlColorCanvas}">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<controls:AppStatusBar x:Name="AppStatus" />
|
||||
<ScrollView Grid.Row="1">
|
||||
<VerticalStackLayout Padding="16,16,16,88" Spacing="12">
|
||||
|
||||
<Label Text="Settings" Style="{StaticResource UlPageTitle}"
|
||||
TextColor="{DynamicResource UlColorText}"
|
||||
SemanticProperties.HeadingLevel="Level1" />
|
||||
|
||||
<Label Text="Devices" FontAttributes="Bold" FontSize="16" />
|
||||
|
||||
@@ -40,36 +49,33 @@
|
||||
</VerticalStackLayout>
|
||||
</Border>
|
||||
|
||||
<Label Text="Map" FontAttributes="Bold" FontSize="16" Margin="0,12,0,0" />
|
||||
<Border StrokeThickness="0" Background="{AppThemeBinding Light=#F2F2F7, Dark=#1C1C1E}" StrokeShape="RoundRectangle 12" Padding="12">
|
||||
<VerticalStackLayout Spacing="6">
|
||||
<Label Text="Google Maps API Key (Windows map view)" FontSize="12" TextColor="Gray" />
|
||||
<Entry Text="{Binding MapsApiKey}" Placeholder="AIza…" IsPassword="False" />
|
||||
<Label FontSize="11" TextColor="Gray"
|
||||
Text="On Android the key is configured in AndroidManifest.xml; iOS and macOS use Apple Maps and need no key." />
|
||||
</VerticalStackLayout>
|
||||
</Border>
|
||||
|
||||
<Label Text="Sync" FontAttributes="Bold" FontSize="16" Margin="0,12,0,0" />
|
||||
<Border StrokeThickness="0" Background="{AppThemeBinding Light=#F2F2F7, Dark=#1C1C1E}" StrokeShape="RoundRectangle 12" Padding="12">
|
||||
<VerticalStackLayout Spacing="8">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Label Text="Durable cloud sync" VerticalOptions="Center" />
|
||||
<Switch Grid.Column="1" IsToggled="{Binding MqttEnabled}" />
|
||||
<VerticalStackLayout Spacing="8" Margin="0,12,0,0">
|
||||
<Label Text="Diagnostics" FontAttributes="Bold" FontSize="16" />
|
||||
<Border Style="{StaticResource UlCard}"
|
||||
BackgroundColor="{DynamicResource UlColorSurfaceRaised}"
|
||||
Stroke="{DynamicResource UlColorBorder}" StrokeShape="RoundRectangle 12" Padding="12">
|
||||
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="12">
|
||||
<VerticalStackLayout Spacing="2" VerticalOptions="Center">
|
||||
<Label Text="Debug" FontAttributes="Bold" FontSize="16"
|
||||
TextColor="{DynamicResource UlColorText}" />
|
||||
<Label Text="Capture readiness, device state, sync, recent points, and console tools"
|
||||
FontSize="12" TextColor="{DynamicResource UlColorTextMuted}" />
|
||||
</VerticalStackLayout>
|
||||
<Button Grid.Column="1" Text="Open" Command="{Binding OpenDebugCommand}"
|
||||
Style="{StaticResource UlButtonSecondary}"
|
||||
MinimumHeightRequest="{StaticResource UlTouchMinimum}"
|
||||
SemanticProperties.Description="Open UM Trace diagnostics" />
|
||||
</Grid>
|
||||
<Entry Text="{Binding MqttHost}" Placeholder="dev.hub.umagul.net" />
|
||||
<Entry Text="{Binding MqttPort}" Placeholder="443 (WSS) or 8884 (MQTTS)" Keyboard="Numeric" />
|
||||
<Entry Text="{Binding MqttOrgId}" Placeholder="Organization ID / MQTT username" />
|
||||
<Entry Text="{Binding MqttPassword}" Placeholder="New MQTT password (stored securely)" IsPassword="True" />
|
||||
<Label Text="{Binding MqttClientId, StringFormat='Client: {0}'}" FontSize="10" TextColor="Gray" />
|
||||
<Label Text="{Binding SyncStatus}" FontSize="12" TextColor="DodgerBlue" />
|
||||
<Button Text="Save & Connect" Command="{Binding SaveSyncCommand}" />
|
||||
</VerticalStackLayout>
|
||||
</Border>
|
||||
</Border>
|
||||
</VerticalStackLayout>
|
||||
|
||||
<Label Text="{Binding AppVersion, StringFormat='Field Logger v{0}'}"
|
||||
FontSize="11" TextColor="Gray" HorizontalOptions="Center" Margin="0,20,0,0" />
|
||||
<Label Text="{Binding AppVersion, StringFormat='UM Trace v{0}'}"
|
||||
FontSize="11" TextColor="{DynamicResource UlColorTextMuted}"
|
||||
HorizontalOptions="Center" Margin="0,20,0,0" />
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
|
||||
<controls:FloatingMenuButton Grid.RowSpan="2" HorizontalOptions="End" VerticalOptions="End" ZIndex="20" />
|
||||
</Grid>
|
||||
</ContentPage>
|
||||
|
||||
@@ -4,9 +4,10 @@ namespace FieldLogger.Views;
|
||||
|
||||
public partial class SettingsPage : ContentPage
|
||||
{
|
||||
public SettingsPage(SettingsViewModel viewModel)
|
||||
public SettingsPage(SettingsViewModel viewModel, AppStatusViewModel appStatusViewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
BindingContext = viewModel;
|
||||
AppStatus.BindingContext = appStatusViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user