From 4efb23b301d75caeb992a6d0bf35be0e2a464d1f Mon Sep 17 00:00:00 2001
From: Paul-Winpenny <92634321+Paul-Winpenny@users.noreply.github.com>
Date: Fri, 18 Oct 2024 15:46:46 +0100
Subject: [PATCH] Wifi networks list is now present, also minor style changes.

---
 App/RobobinApp/Models/BluetoothDevice.cs      |  21 +++
 App/RobobinApp/Models/WifiNetwork.cs          |  14 ++
 App/RobobinApp/RobobinApp.csproj              |   9 +-
 .../ViewModels/ConnectionPageViewModel.cs     |  61 ++++----
 App/RobobinApp/Views/ConnectionPage.xaml      | 146 ++++++++++++------
 5 files changed, 174 insertions(+), 77 deletions(-)
 create mode 100644 App/RobobinApp/Models/BluetoothDevice.cs
 create mode 100644 App/RobobinApp/Models/WifiNetwork.cs

diff --git a/App/RobobinApp/Models/BluetoothDevice.cs b/App/RobobinApp/Models/BluetoothDevice.cs
new file mode 100644
index 00000000..c4a552e5
--- /dev/null
+++ b/App/RobobinApp/Models/BluetoothDevice.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobobinApp.Models
+{
+    public class BluetoothDevice
+    {
+        public string Name { get; set; }
+        public string MacAddress { get; set; }
+
+        public BluetoothDevice(string name, string macAddress)
+        {
+            Name = name;
+            MacAddress = macAddress;
+        }
+    }
+}
+
diff --git a/App/RobobinApp/Models/WifiNetwork.cs b/App/RobobinApp/Models/WifiNetwork.cs
new file mode 100644
index 00000000..0e0e8303
--- /dev/null
+++ b/App/RobobinApp/Models/WifiNetwork.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobobinApp.Models
+{
+    public class WifiNetwork
+    {
+        public string SSID { get; set; }
+        public string SignalStrength { get; set; }
+    }
+}
diff --git a/App/RobobinApp/RobobinApp.csproj b/App/RobobinApp/RobobinApp.csproj
index 421fce80..47ae3c5d 100644
--- a/App/RobobinApp/RobobinApp.csproj
+++ b/App/RobobinApp/RobobinApp.csproj
@@ -1,20 +1,19 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
-        <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
+        <TargetFrameworks>net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
         <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
         <OutputType>Exe</OutputType>
-        <RootNamespace>MauiApp1</RootNamespace>
+		<RootNamespace>Robobin</RootNamespace>
         <UseMaui>true</UseMaui>
         <SingleProject>true</SingleProject>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
-        <ApplicationTitle>MauiApp1</ApplicationTitle>
-        <ApplicationId>com.companyname.mauiapp1</ApplicationId>
+        <ApplicationTitle>Robobin</ApplicationTitle>
+        <ApplicationId>com.companyname.robobin</ApplicationId>
         <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
         <ApplicationVersion>1</ApplicationVersion>
         <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
         <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
-        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
         <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
         <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
         <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
diff --git a/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs b/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
index 8c08c32b..8a728f5b 100644
--- a/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
+++ b/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
@@ -9,6 +9,9 @@ using Plugin.BLE.Abstractions.Exceptions;
 using Plugin.BLE.Abstractions.EventArgs;
 using System.Threading.Tasks;
 using Plugin.BLE.Abstractions;
+using RobobinApp.Models;
+using System.Net.NetworkInformation; 
+using System.Collections.Generic;
 
 namespace RobobinApp.ViewModels
 {
@@ -18,12 +21,16 @@ namespace RobobinApp.ViewModels
         private IDevice _connectedDevice;  // Track the connected device
         public ICommand GoHomeCommand { get; }
         public ObservableCollection<BluetoothDevice> BluetoothDevices { get; }
+        public ObservableCollection<WifiNetwork> WifiNetworks { get; }
+
         public ICommand ConnectCommand { get; }
-        public ICommand SendWifiInfoCommand { get;  }
-        public ICommand DisconnectCommand { get; }  // Command for disconnecting
-        private bool _isConnected;  // Track connection state
+        public ICommand SendWifiInfoCommand { get; }
+        public ICommand DisconnectCommand { get; }
+        private bool _isConnected;
         private string ssid;
         private string password;
+        public bool IsBluetoothDeviceSelectionVisible => !IsWifiNetworkSelectionVisible;
+
         public bool IsConnected
         {
             get => _isConnected;
@@ -58,6 +65,17 @@ namespace RobobinApp.ViewModels
         private readonly IAdapter _adapter;
         private readonly IBluetoothLE _bluetoothLE;
         public string ConnectButtonText => IsConnected ? "Disconnect" : "Connect";
+        private bool _isWifiNetworkSelectionVisible;
+        public bool IsWifiNetworkSelectionVisible
+        {
+            get => _isWifiNetworkSelectionVisible;
+            set
+            {
+                _isWifiNetworkSelectionVisible = value;
+                OnPropertyChanged();
+                OnPropertyChanged(nameof(IsBluetoothDeviceSelectionVisible));
+            }
+        }
 
         public ConnectionPageViewModel()
         {
@@ -70,6 +88,7 @@ namespace RobobinApp.ViewModels
             _bluetoothLE = CrossBluetoothLE.Current;
             _adapter = _bluetoothLE.Adapter;
             _adapter.DeviceDiscovered += OnDeviceDiscovered;
+            IsWifiNetworkSelectionVisible = false;
 
             Debug.WriteLine("Checking and requesting Bluetooth permissions.");
             CheckAndRequestBluetoothPermissions();
@@ -208,31 +227,20 @@ namespace RobobinApp.ViewModels
 
         private void OnDeviceDiscovered(object sender, DeviceEventArgs e)
         {
-            Debug.WriteLine($"Discovered device: ID={e.Device.Id}, Name={e.Device.Name}, State={e.Device.State}, RSSI={e.Device.Rssi}");
+            Debug.WriteLine($"Discovered device: {e.Device.Name ?? e.Device.Id.ToString()}");
 
-            // Filter out devices that are not in a ready state
-            //if (e.Device.State != DeviceState.Connected && e.Device.State != DeviceState.Disconnected)
-            //{
-            //    Debug.WriteLine($"Device {e.Device.Name} is not in a fully ready state (State: {e.Device.State}). Skipping.");
-            //    return;
-            //}
-
-            var bluetoothDevice = new BluetoothDevice
-            {
-                Name = string.IsNullOrWhiteSpace(e.Device.Name) ? e.Device.Id.ToString() : e.Device.Name,
-                MacAddress = e.Device.Id.ToString()
-            };
+            var bluetoothDevice = new BluetoothDevice(
+                string.IsNullOrWhiteSpace(e.Device.Name) ? e.Device.Id.ToString() : e.Device.Name,
+                e.Device.Id.ToString()
+            );
 
             if (!BluetoothDevices.Any(d => d.MacAddress == bluetoothDevice.MacAddress))
             {
-                Device.BeginInvokeOnMainThread(() =>
-                {
-                    BluetoothDevices.Add(bluetoothDevice);
-                    Debug.WriteLine($"Added device to list: {bluetoothDevice.Name} ({bluetoothDevice.MacAddress})");
-                });
+                Device.BeginInvokeOnMainThread(() => BluetoothDevices.Add(bluetoothDevice));
             }
         }
 
+
         private async Task<IDevice> TryConnectAsync(Guid deviceId, int retryCount = 3)
         {
             IDevice device = null;
@@ -295,6 +303,7 @@ namespace RobobinApp.ViewModels
 
                             if (characteristic.Id == Guid.Parse("6e400002-b5a3-f393-e0a9-e50e24dcca9e"))
                             {
+                                IsWifiNetworkSelectionVisible = true;
                                 Debug.WriteLine("Found RX characteristic (for writing data)");
                                 // Convert the string to a byte array
                                 byte[] data = System.Text.Encoding.UTF8.GetBytes("Hello World");
@@ -338,9 +347,10 @@ namespace RobobinApp.ViewModels
                     Debug.WriteLine($"Attempting to disconnect from {_connectedDevice.Name}");
                     await _adapter.DisconnectDeviceAsync(_connectedDevice);
                     Debug.WriteLine("Disconnected successfully.");
-
+                    IsWifiNetworkSelectionVisible = false;
                     // Dispose of the device reference
-                    _connectedDevice.Dispose();
+                    if (_connectedDevice != null)
+                        _connectedDevice.Dispose();
                     _connectedDevice = null;
                     IsConnected = false;
                     await Application.Current.MainPage.DisplayAlert("Disconnected", "Device disconnected successfully.", "OK");
@@ -356,11 +366,6 @@ namespace RobobinApp.ViewModels
                 Debug.WriteLine("No device to disconnect.");
             }
         }
-    }
 
-    public class BluetoothDevice
-    {
-        public string Name { get; set; }
-        public string MacAddress { get; set; }
     }
 }
diff --git a/App/RobobinApp/Views/ConnectionPage.xaml b/App/RobobinApp/Views/ConnectionPage.xaml
index 7d7ae169..d7592573 100644
--- a/App/RobobinApp/Views/ConnectionPage.xaml
+++ b/App/RobobinApp/Views/ConnectionPage.xaml
@@ -3,6 +3,35 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
              x:Class="RobobinApp.Views.ConnectionPage"
              Title="Connect to Robobin">
+    <ContentPage.Resources>
+        <ResourceDictionary>
+            <Style x:Key="HeaderLabelStyle" TargetType="Label">
+                <Setter Property="FontSize" Value="Medium" />
+                <Setter Property="TextColor" Value="DarkSlateBlue" />
+                <Setter Property="HorizontalOptions" Value="Center" />
+                <Setter Property="VerticalOptions" Value="Start" />
+            </Style>
+
+            <Style x:Key="ButtonStyle" TargetType="Button">
+                <Setter Property="BackgroundColor" Value="LightBlue" />
+                <Setter Property="TextColor" Value="White" />
+                <Setter Property="Padding" Value="10,5" />
+                <Setter Property="CornerRadius" Value="5" />
+                <Setter Property="FontAttributes" Value="Bold" />
+            </Style>
+
+ 
+
+            <Style x:Key="ListViewStyle" TargetType="ListView">
+                <Setter Property="BackgroundColor" Value="White" />
+                <Setter Property="SeparatorVisibility" Value="Default" />
+                <Setter Property="SeparatorColor" Value="LightGray" />
+                <Setter Property="SelectedItem" Value="Blue" />
+                <Setter Property="VerticalScrollBarVisibility" Value="Always"/>
+
+            </Style>
+        </ResourceDictionary>
+    </ContentPage.Resources>
 
     <ContentPage.MenuBarItems>
         <MenuBarItem Text="Menu">
@@ -11,56 +40,85 @@
     </ContentPage.MenuBarItems>
 
     <StackLayout Padding="20">
-        <Label Text="Select a Bluetooth Device" 
-               FontSize="Medium" 
-               HorizontalOptions="Center" 
-               VerticalOptions="Start" />
-
-        <ListView x:Name="DeviceListView"
-                  ItemsSource="{Binding BluetoothDevices}"
-                  SelectedItem="{Binding SelectedDevice}"
-                  VerticalOptions="FillAndExpand">
-            <ListView.ItemTemplate>
-                <DataTemplate>
-                    <TextCell Text="{Binding Name}" />
-                </DataTemplate>
-            </ListView.ItemTemplate>
-        </ListView>
-
-        <Button Text="{Binding ConnectButtonText}" 
-                Command="{Binding ConnectCommand}" 
-                IsEnabled="{Binding SelectedDevice, Converter={StaticResource NullToBooleanConverter}}" 
-                HorizontalOptions="Center" 
-                VerticalOptions="End" />
-
-        <!-- Section for SSID and Password - Initially Hidden -->
-        <StackLayout IsVisible="{Binding IsConnected}" 
-                     Padding="10" 
-                     BackgroundColor="LightGray"
-                     HorizontalOptions="FillAndExpand" 
-                     VerticalOptions="Start">
-            <Label Text="SSID:" 
+        <StackLayout IsVisible="{Binding IsBluetoothDeviceSelectionVisible}">
+            <Label Text="Select a Bluetooth Device" 
                    FontSize="Medium" 
-                   HorizontalOptions="Start" />
-            <Entry x:Name="SSIDEntry" 
-                   Placeholder="Enter SSID" 
-                   Text="{Binding SSID}" 
-                   HorizontalOptions="Fill" />
+                   HorizontalOptions="Center" 
+                   VerticalOptions="Start" />
 
-            <Label Text="Password:" 
-                   FontSize="Medium" 
-                   HorizontalOptions="Start" />
-            <Entry x:Name="PasswordEntry" 
-                   Placeholder="Enter Password" 
-                   Text="{Binding Password}" 
-                   IsPassword="True" 
-                   HorizontalOptions="Fill" />
+            <ListView x:Name="DeviceListView"
+                      ItemsSource="{Binding BluetoothDevices}"
+                      SelectedItem="{Binding SelectedDevice}"
+                      VerticalOptions="FillAndExpand">
+                <ListView.ItemTemplate>
+                    <DataTemplate>
+                        <TextCell Text="{Binding Name}" />
+                    </DataTemplate>
+                </ListView.ItemTemplate>
+            </ListView>
 
-            <Button Text="Send WiFi Information" 
-                    Command="{Binding SendWifiInfoCommand}" 
+            <Button Text="{Binding ConnectButtonText}" 
+                    Command="{Binding ConnectCommand}" 
+                    IsEnabled="{Binding SelectedDevice, Converter={StaticResource NullToBooleanConverter}}" 
                     HorizontalOptions="Center" 
                     VerticalOptions="End" />
         </StackLayout>
 
+        <StackLayout IsVisible="{Binding IsWifiNetworkSelectionVisible}">
+            <Grid Padding="10" HorizontalOptions="FillAndExpand">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="*" />
+                    <ColumnDefinition Width="Auto" />
+                </Grid.ColumnDefinitions>
+
+                <Label Text="{Binding SelectedDevice.Name}" 
+                       FontSize="Medium" 
+                       HorizontalOptions="Start" 
+                       VerticalOptions="Center" 
+                       Grid.Column="0" />
+
+                <Button Text="Disconnect" 
+                        Command="{Binding DisconnectCommand}" 
+                        HorizontalOptions="End" 
+                        VerticalOptions="Center" 
+                        Grid.Column="1" />
+            </Grid>
+
+            <Label Text="Select a WiFi Network" 
+                   FontSize="Medium" 
+                   HorizontalOptions="Center" 
+                   VerticalOptions="Start" />
+
+            <ListView x:Name="WifiListView"
+                      ItemsSource="{Binding AvailableWifiNetworks}"
+                      SelectedItem="{Binding SelectedWifiNetwork}"
+                      VerticalOptions="FillAndExpand">
+                <ListView.ItemTemplate>
+                    <DataTemplate>
+                        <TextCell Text="{Binding SSID}" />
+                    </DataTemplate>
+                </ListView.ItemTemplate>
+            </ListView>
+
+            <!-- Section for Password Input -->
+            <StackLayout Padding="10" 
+                         BackgroundColor="LightGray"
+                         HorizontalOptions="FillAndExpand" 
+                         VerticalOptions="Start">
+                <Label Text="Password:" 
+                       FontSize="Medium" 
+                       HorizontalOptions="Start" />
+                <Entry x:Name="PasswordEntry" 
+                       Placeholder="Enter Password" 
+                       Text="{Binding Password}" 
+                       IsPassword="True" 
+                       HorizontalOptions="Fill" />
+
+                <Button Text="Send WiFi Information" 
+                        Command="{Binding SendWifiInfoCommand}" 
+                        HorizontalOptions="Center" 
+                        VerticalOptions="End" />
+            </StackLayout>
+        </StackLayout>
     </StackLayout>
 </ContentPage>
-- 
GitLab