Prepare Pro 1.0.1 imports and license tooling
This commit is contained in:
1 parent
62f28c5621
commit
0b5017739c
13 files changed
+437
-48
No files matched your search
+128
-3
@@ -10,6 +10,7 @@
|
||||
@inject MapExportService MapExportService
|
||||
@inject CloudSyncService CloudSyncService
|
||||
@inject AppUpdateService AppUpdateService
|
||||
@inject IncomingFileService IncomingFiles
|
||||
@inject AppLocalizationService L10n
|
||||
@inject EntitlementService Entitlements
|
||||
@implements IAsyncDisposable
|
||||
@@ -741,6 +742,7 @@
|
||||
private bool NavigationMenuOpen { get; set; }
|
||||
private bool HasUnsavedChanges { get; set; }
|
||||
private DotNetObjectReference<Home>? MapCallbackReference { get; set; }
|
||||
private bool MapReady { get; set; }
|
||||
private bool IncludeCadastralParcels { get; set; } = true;
|
||||
private bool IncludeKmlSheetLayer { get; set; }
|
||||
private bool ShowImportedSheetLayer { get; set; }
|
||||
@@ -830,6 +832,7 @@
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
IncomingFiles.FileAvailable += OnIncomingFileAvailable;
|
||||
L10n.Load();
|
||||
L10n.ApplyCulture();
|
||||
await Entitlements.LoadAsync();
|
||||
@@ -878,6 +881,7 @@
|
||||
{
|
||||
MapCallbackReference = DotNetObjectReference.Create(this);
|
||||
await JS.InvokeVoidAsync("lmeMap.init", MapCallbackReference);
|
||||
MapReady = true;
|
||||
await ApplyLocalizationToMapAsync();
|
||||
await ApplyEntitlementsToMapAsync();
|
||||
await ApplyFlagPreferencesToMapAsync();
|
||||
@@ -886,6 +890,7 @@
|
||||
await MigrateLegacyProjectAsync();
|
||||
var offlineCount = await JS.InvokeAsync<int>("lmeMap.getOfflineTileStats");
|
||||
OfflineStatus = offlineCount == 0 ? "Nessuna tessera salvata." : $"{offlineCount} tessere disponibili offline.";
|
||||
await ProcessIncomingFilesAsync();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
@@ -1582,7 +1587,11 @@
|
||||
private async Task RestoreBackup()
|
||||
{
|
||||
if (!CanUse(AppFeatures.ProjectArchive)) { await ShowProRequiredAsync(); return; }
|
||||
var file = await FilePicker.Default.PickAsync(new PickOptions { PickerTitle = "Scegli backup LME" });
|
||||
var file = await FilePicker.Default.PickAsync(new PickOptions
|
||||
{
|
||||
PickerTitle = "Scegli backup LME (.lmebackup.zip)",
|
||||
FileTypes = BackupPickerFileTypes
|
||||
});
|
||||
if (file is null) return;
|
||||
var path = await CopyPickedFileToCacheAsync(file);
|
||||
var count = await ProjectStorageService.RestoreBackupAsync(path);
|
||||
@@ -1593,7 +1602,11 @@
|
||||
private async Task ImportProject()
|
||||
{
|
||||
if (!CanUse(AppFeatures.ProjectArchive)) { await ShowProRequiredAsync(); return; }
|
||||
var file = await FilePicker.Default.PickAsync(new PickOptions { PickerTitle = "Scegli progetto LME" });
|
||||
var file = await FilePicker.Default.PickAsync(new PickOptions
|
||||
{
|
||||
PickerTitle = "Scegli progetto LME (.lmeproject.json)",
|
||||
FileTypes = ProjectPickerFileTypes
|
||||
});
|
||||
if (file is null) return;
|
||||
var path = await CopyPickedFileToCacheAsync(file);
|
||||
var imported = await ProjectStorageService.ImportProjectAsync(path);
|
||||
@@ -1612,6 +1625,117 @@
|
||||
return path;
|
||||
}
|
||||
|
||||
private void OnIncomingFileAvailable()
|
||||
{
|
||||
if (MapReady)
|
||||
{
|
||||
_ = InvokeAsync(ProcessIncomingFilesAsync);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessIncomingFilesAsync()
|
||||
{
|
||||
while (IncomingFiles.TryDequeue(out var incoming) && incoming is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lowerName = incoming.FileName.ToLowerInvariant();
|
||||
if (lowerName.EndsWith(".kml", StringComparison.Ordinal)
|
||||
|| lowerName.EndsWith(".kmz", StringComparison.Ordinal)
|
||||
|| lowerName.EndsWith(".geojson", StringComparison.Ordinal)
|
||||
|| await IsGeoJsonAsync(incoming.Path))
|
||||
{
|
||||
var content = Convert.ToBase64String(await File.ReadAllBytesAsync(incoming.Path));
|
||||
await JS.InvokeAsync<string>("lmeMap.importExternalGisFile", incoming.FileName, content, incoming.ContentType);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lowerName.EndsWith(".zip", StringComparison.Ordinal))
|
||||
{
|
||||
if (!CanUse(AppFeatures.ProjectArchive))
|
||||
{
|
||||
await ShowProRequiredAsync();
|
||||
continue;
|
||||
}
|
||||
|
||||
var count = await ProjectStorageService.RestoreBackupAsync(incoming.Path);
|
||||
await RefreshProjectsAsync();
|
||||
await JS.InvokeVoidAsync("lmeMap.showInfo", $"Backup aperto: {count} progetti ripristinati.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lowerName.EndsWith(".json", StringComparison.Ordinal))
|
||||
{
|
||||
if (!CanUse(AppFeatures.ProjectArchive))
|
||||
{
|
||||
await ShowProRequiredAsync();
|
||||
continue;
|
||||
}
|
||||
|
||||
var imported = await ProjectStorageService.ImportProjectAsync(incoming.Path);
|
||||
await RefreshProjectsAsync();
|
||||
SelectedProjectId = imported.Id;
|
||||
await RefreshProjectVersionsAsync(true);
|
||||
await JS.InvokeVoidAsync("lmeMap.showInfo", $"Progetto aperto: {imported.Name}.");
|
||||
continue;
|
||||
}
|
||||
|
||||
await JS.InvokeVoidAsync("lmeMap.showInfo", $"Formato non riconosciuto: {incoming.FileName}.");
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
await JS.InvokeVoidAsync("lmeMap.showInfo", $"Impossibile aprire {incoming.FileName}: {error.GetBaseException().Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { File.Delete(incoming.Path); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> IsGeoJsonAsync(string path)
|
||||
{
|
||||
if (!Path.GetExtension(path).Equals(".json", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await using var stream = File.OpenRead(path);
|
||||
using var document = await System.Text.Json.JsonDocument.ParseAsync(stream);
|
||||
if (!document.RootElement.TryGetProperty("type", out var typeProperty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var type = typeProperty.GetString();
|
||||
return type is "Feature" or "FeatureCollection" or "Point" or "MultiPoint"
|
||||
or "LineString" or "MultiLineString" or "Polygon" or "MultiPolygon"
|
||||
or "GeometryCollection";
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly FilePickerFileType ProjectPickerFileTypes = new(new Dictionary<DevicePlatform, IEnumerable<string>>
|
||||
{
|
||||
[DevicePlatform.Android] = ["application/json", "text/json", "text/plain", "application/octet-stream"],
|
||||
[DevicePlatform.WinUI] = [".json"],
|
||||
[DevicePlatform.iOS] = ["public.json", "public.data"],
|
||||
[DevicePlatform.macOS] = ["public.json", "public.data"]
|
||||
});
|
||||
|
||||
private static readonly FilePickerFileType BackupPickerFileTypes = new(new Dictionary<DevicePlatform, IEnumerable<string>>
|
||||
{
|
||||
[DevicePlatform.Android] = ["application/zip", "application/x-zip-compressed", "application/octet-stream"],
|
||||
[DevicePlatform.WinUI] = [".zip"],
|
||||
[DevicePlatform.iOS] = ["public.zip-archive", "public.data"],
|
||||
[DevicePlatform.macOS] = ["public.zip-archive", "public.data"]
|
||||
});
|
||||
|
||||
private async Task LoadProjectVersion()
|
||||
{
|
||||
if (SelectedProject is null || string.IsNullOrWhiteSpace(SelectedVersionId)) return;
|
||||
@@ -1928,7 +2052,7 @@
|
||||
UpdateStatus = $"Installata {AppUpdateService.CurrentVersion}. Disponibile {update.Version}.";
|
||||
UpdateDownloadUrl = update.DownloadUrl;
|
||||
}
|
||||
else UpdateStatus = $"Versione {AppUpdateService.CurrentVersion} aggiornata. Ultima release Gitea: {update.Version}.";
|
||||
else UpdateStatus = $"Versione {AppUpdateService.CurrentVersion} aggiornata. Ultima release Pro su Gitea: {update.Version}.";
|
||||
}
|
||||
catch (Exception error) { UpdateStatus = $"Controllo non riuscito: {error.GetBaseException().Message}"; }
|
||||
finally { UpdateBusy = false; }
|
||||
@@ -2349,6 +2473,7 @@
|
||||
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
IncomingFiles.FileAvailable -= OnIncomingFileAvailable;
|
||||
CancelCatalogWork();
|
||||
LocationService.StopTracking();
|
||||
GpsLookupCancellation?.Cancel();
|
||||
|
||||
Reference in new issue
Block a user