Skip to content

Commit

Permalink
merge with dev-app-3
Browse files Browse the repository at this point in the history
  • Loading branch information
ghuotvez committed Aug 30, 2024
2 parents 55d5530 + 2410635 commit 591b7c3
Show file tree
Hide file tree
Showing 157 changed files with 28,578 additions and 2,672 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,5 @@ MigrationBackup/
.ionide/

# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd
/GSCFieldApp/DevelopmentNotes.md
62 changes: 62 additions & 0 deletions DevelopmentNotes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# VISUAL STUDIO

## Build errors

### Hitting a Zip exception

It happens when an Android emulator has been launched, it seems to lock some files. Restarting VS will fix this and the emulator
can still be kept opened while VS restarts.

---

# ANDROID
## Useful commands in Adb

### Accessing the device (plugged in android phone or emulator)

Apply this command while the device is running
`adb shell`

### Accessing app files

For security purposes all the app files are found within the app own folder behind some permission.

#### Enabling permission

Not doing this will result in a "permission denied" message.

`run-as GSCFieldApp.GSCFieldApp`

#### Accessing/Reading the files

This is how we can see if the geopackage have been written properly within the app folder.

`cd files`
`ls`

#### Copying files into PC

`adb pull /storage/self/primary/download/asd_DSA.gpkg W:\Transit\Gab`

#### Copying files to Android

`adb push "C:\Users\ghuotvez\AppData\Local\Xamarin\Mono for Android\Archives\GSCFieldApp.GSCFieldApp.apk" /storage/self/primary/download`

## Publishing

App needs to be deployed and build first.

In debug mode, app package has around 150Mb.
In release with coding trimming and code shrinker it goes down to 42Mb.
In release mode with ahead of time enabled to goes up to 56Mb, but the code should be faster.

### Pub Android
Password is gscfieldapp for current key

## Coding style

Usually class names should use CamelCasing, but for some reasons the model class in which CamalCasing is used,
do not work well with the observableProperty inside the viewmodels. EM is a good example, passing the whole
class to refill the form wasn't working until I removed the capital case M in the class name.

---
23 changes: 23 additions & 0 deletions GSCFieldApp.Testing/GSCFieldApp.Testing.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
11 changes: 11 additions & 0 deletions GSCFieldApp.Testing/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace GSCFieldApp.Testing
{
public class UnitTest1
{
[Fact]
public void Test1()
{

}
}
}
64 changes: 61 additions & 3 deletions GSCFieldApp/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
namespace GSCFieldApp;
using GSCFieldApp.Services;

namespace GSCFieldApp;

public partial class App : Application
{
public App()
public LocalizationResourceManager LocalizationResourceManager
=> LocalizationResourceManager.Instance; // Will be used for in code dynamic local strings

public App()
{
InitializeComponent();

MainPage = new AppShell();
}

//MainPage.Loaded += MainPage_Loaded;

}

/// <summary>
/// Track loaded event and ask for desired permission before moving on.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void MainPage_Loaded(object sender, EventArgs e)
{
await CheckAndRequestLocationPermission();
}

/// <summary>
/// TODO Make sure to properly ask for permission
/// https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/permissions?view=net-maui-8.0&tabs=android
/// For now this method doesn't show anything on screen that would help
/// user to actually enable location in settings.
/// </summary>
/// <returns></returns>
public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{

PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

if (status == PermissionStatus.Granted)
return status;

if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
{
// Prompt the user to turn on in settings
// On iOS once a permission has been denied it may not be requested again from the application
return status;
}

if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
{
// Prompt the user with additional information as to why the permission is needed
bool answer = await Shell.Current.DisplayAlert(LocalizationResourceManager["DisplayAlertGPSDenied"].ToString(),
LocalizationResourceManager["DisplayAlertGPSMessage"].ToString(),
LocalizationResourceManager["GenericButtonYes"].ToString(),
LocalizationResourceManager["GenericButtonNo"].ToString());
}

await MainThread.InvokeOnMainThreadAsync(async () =>
{
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

});

return status;
}
}
67 changes: 45 additions & 22 deletions GSCFieldApp/AppShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,61 @@
Shell.FlyoutBehavior="Flyout">

<ShellContent
Title="GSC Field App"
ContentTemplate="{DataTemplate views:FieldBooksPage}"
Route="FieldBooksPage" />
Title="GSC Field App" FlyoutItemIsVisible="True"
ContentTemplate="{DataTemplate views:FieldBooksPage}" Route="FieldBooksPage"/>

<MenuItem Text="{local:Localize ShellFieldBooksTitle}" Command="{Binding NavigateToFieldBooksCommand}">
<MenuItem.IconImageSource>
<FontImageSource Glyph="&#xF125F;" FontFamily="MatDesign" Color="Black"/>
</MenuItem.IconImageSource>
</MenuItem>
<FlyoutItem Title="{local:Localize ShellFieldBooksTitle}">
<FlyoutItem.FlyoutIcon>
<FontImageSource Glyph="&#xF125F;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</FlyoutItem.FlyoutIcon>
<ShellContent ContentTemplate="{DataTemplate views:FieldBooksPage}" />
</FlyoutItem>

<MenuItem Text="{local:Localize ShellFieldNotesTitle}" Command="{Binding NavigateToFieldNotesCommand}">
<MenuItem.IconImageSource>
<FontImageSource Glyph="&#xF039B;" FontFamily="MatDesign" Color="Black"/>
</MenuItem.IconImageSource>
</MenuItem>
<FlyoutItem Title="{local:Localize ShellFieldNotesTitle}">
<FlyoutItem.FlyoutIcon>
<FontImageSource Glyph="&#xF039B;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</FlyoutItem.FlyoutIcon>
<ShellContent ContentTemplate="{DataTemplate views:FieldNotesPage}" Route="FieldNotesPage"/>
</FlyoutItem>

<MenuItem Text="{local:Localize ShellMapTitle}" Command="{Binding NavigateToMapCommand}">
<MenuItem.IconImageSource>
<FontImageSource Glyph="&#xF01E7;" FontFamily="MatDesign" Color="Black"/>
</MenuItem.IconImageSource>
</MenuItem>
<FlyoutItem Title="{local:Localize ShellMapTitle}" >
<FlyoutItem.FlyoutIcon>
<FontImageSource Glyph="&#xF01E7;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</FlyoutItem.FlyoutIcon>
<ShellContent ContentTemplate="{DataTemplate views:MapPage}" Route="MapPage"/>
</FlyoutItem>

<MenuItem Text="{local:Localize ShellQuickBackupTitle}" Command="{Binding DoBackupCommand}" >
<MenuItem.IconImageSource>
<FontImageSource Glyph="&#xF0818;" FontFamily="MatDesign" Color="Black"/>
<FontImageSource Glyph="&#xF0818;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</MenuItem.IconImageSource>
</MenuItem>

<MenuItem Text="{local:Localize ShellSettingsTitle}" Command="{Binding NavigateToSettingsCommand}" >
<MenuItem Text="{local:Localize ShellQuickPhotoBackupTitle}" Command="{Binding DoPhotoBackupCommand}" >
<MenuItem.IconImageSource>
<FontImageSource Glyph="&#xF08BB;" FontFamily="MatDesign" Color="Black"/>
<FontImageSource Glyph="&#xF0693;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</MenuItem.IconImageSource>
</MenuItem>


<FlyoutItem Title="{local:Localize ShellPicklistEditorTitle}" >
<FlyoutItem.FlyoutIcon>
<FontImageSource Glyph="&#xF0900;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</FlyoutItem.FlyoutIcon>
<ShellContent ContentTemplate="{DataTemplate views:PicklistPage}" Route="PicklistPage"/>
</FlyoutItem>

<FlyoutItem Title="{local:Localize ShellSettingsTitle}" >
<FlyoutItem.FlyoutIcon>
<FontImageSource Glyph="&#xF08BB;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</FlyoutItem.FlyoutIcon>
<ShellContent ContentTemplate="{DataTemplate views:SettingsPage}" Route="SettingsPage"/>
</FlyoutItem>

<FlyoutItem Title="{local:Localize ShellAboutTitle}">
<FlyoutItem.FlyoutIcon>
<FontImageSource Glyph="&#xF02FD;" FontFamily="MatDesign" Color="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}"/>
</FlyoutItem.FlyoutIcon>
<ShellContent ContentTemplate="{DataTemplate views:AboutPage}" Route="AboutPage"/>
</FlyoutItem>

</Shell>
65 changes: 33 additions & 32 deletions GSCFieldApp/AppShell.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,55 +1,46 @@
using GSCFieldApp.Views;
using BruTile.Wms;
using CommunityToolkit.Maui.Alerts;
using CommunityToolkit.Maui.Storage;
using GSCFieldApp.Dictionaries;
using GSCFieldApp.Services;
using GSCFieldApp.Services.DatabaseServices;
using GSCFieldApp.Views;
using Microsoft.Extensions.Localization;
using Microsoft.Maui.Controls.Xaml;
using System.Text;
using System.Windows.Input;

namespace GSCFieldApp;

public partial class AppShell : Shell
{
public ICommand NavigateToSettingsCommand { get; private set; }
public ICommand NavigateToFieldBooksCommand { get; private set; }
public ICommand NavigateToFieldNotesCommand { get; private set; }
public ICommand NavigateToMapCommand { get; private set; }
public ICommand DoBackupCommand { get; private set; }
public ICommand DoPhotoBackupCommand { get; private set; }

public AppShell()
{
InitializeComponent();

#region MENU ROUTING
//Registering some routing to other pages from app shell
Routing.RegisterRoute(nameof(DetailPage), typeof(DetailPage));
Routing.RegisterRoute(nameof(SettingsPage), typeof(SettingsPage));
Routing.RegisterRoute(nameof(FieldBooksPage), typeof(FieldBooksPage));
Routing.RegisterRoute(nameof(FieldNotesPage), typeof(FieldNotesPage));
Routing.RegisterRoute(nameof(MapPage), typeof(MapPage));
//Routing.RegisterRoute(nameof(SettingsPage), typeof(SettingsPage));
//Routing.RegisterRoute(nameof(FieldBooksPage), typeof(FieldBooksPage));
//Routing.RegisterRoute(nameof(FieldNotesPage), typeof(FieldNotesPage));
//Routing.RegisterRoute(nameof(MapPage), typeof(MapPage));
//Routing.RegisterRoute(nameof(PicklistPage), typeof(PicklistPage));

//Will be used to trigger a backup process
DoBackupCommand = new Command(async () =>
{
AppFileServices fileServices = new AppFileServices();
await fileServices.SaveBackupDBFile(CancellationToken.None);

//Will be used to navigate to setting page
NavigateToSettingsCommand = new Command(async () => {
//await GoToAsync(nameof(SettingsPage));
await DisplayAlert("Alert", "Not yet implemented", "OK");
});

//Will be used to navigate to field books page
NavigateToFieldBooksCommand = new Command(async () => {
await GoToAsync("///" + nameof(FieldBooksPage));
});

//Will be used to navigate to field books page
NavigateToFieldNotesCommand = new Command(async () => {

DoPhotoBackupCommand = new Command(async () => {
await DisplayAlert("Alert", "Not yet implemented", "OK");
});

//Will be used to navigate to field books page
NavigateToMapCommand = new Command(async () => {
await GoToAsync(nameof(MapPage));
});

//Will be used to trigger a backup process
DoBackupCommand = new Command(async () =>
{
await DisplayAlert("Alert", "Not yet implemented", "OK");
});

#endregion
Expand All @@ -58,11 +49,21 @@ public AppShell()

Routing.RegisterRoute(nameof(FieldBookPage), typeof(FieldBookPage));
Routing.RegisterRoute(nameof(StationPage), typeof(StationPage));
Routing.RegisterRoute(nameof(EarthmatPage), typeof(EarthmatPage));
Routing.RegisterRoute(nameof(SamplePage), typeof(SamplePage));
Routing.RegisterRoute(nameof(DocumentPage), typeof(DocumentPage));
Routing.RegisterRoute(nameof(StructurePage), typeof(StructurePage));
Routing.RegisterRoute(nameof(PaleoflowPage), typeof(PaleoflowPage));
Routing.RegisterRoute(nameof(FossilPage), typeof(FossilPage));
Routing.RegisterRoute(nameof(EnvironmentPage), typeof(EnvironmentPage));
Routing.RegisterRoute(nameof(MineralPage), typeof(MineralPage));
Routing.RegisterRoute(nameof(MineralizationAlterationPage), typeof(MineralizationAlterationPage));
Routing.RegisterRoute(nameof(LocationPage), typeof(LocationPage));
Routing.RegisterRoute(nameof(DrillHolePage), typeof(DrillHolePage));

#endregion

BindingContext = this;
}


}
23 changes: 23 additions & 0 deletions GSCFieldApp/Controls/ComboBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GSCFieldApp.Controls
{
public class ComboBox
{
public List<ComboBoxItem> cboxItems
{
get;
set;
}
public int cboxDefaultItemIndex { get; set; }

public ComboBox()
{
cboxItems = new List<ComboBoxItem>();
}
}
}
Loading

0 comments on commit 591b7c3

Please sign in to comment.