Sfoglia il codice sorgente

avalonia: Added "Images" list to Task editor

Kenric Nugteren 1 mese fa
parent
commit
f5e31c5db2

+ 1 - 0
PRS.Avalonia/PRS.Avalonia.Android/MainActivity.cs

@@ -33,6 +33,7 @@ public class MainActivity : AvaloniaMainActivity<App>
         PlatformTools.Register<IPdfRenderer, Android_PdfRenderer>();
         PlatformTools.Register<IBluetooth, Android_Bluetooth>();
         PlatformTools.Register<ICameraViewControl, Android_CameraViewControl>();
+        PlatformTools.Register<IPermissions, Android_Permissions>();
         
         
         

+ 1 - 0
PRS.Avalonia/PRS.Avalonia.Desktop/Program.cs

@@ -24,6 +24,7 @@ sealed class Program
         PlatformTools.Register<IBluetooth, Desktop_Bluetooth>();
         PlatformTools.Register<IAppVersion, Desktop_AppVersion>();
         PlatformTools.Register<IImageTools, Desktop_ImageTools>();
+        PlatformTools.Register<IPermissions, Desktop_Permissions>();
             
         return AppBuilder.Configure<App>()
             .UsePlatformDetect()

+ 49 - 0
PRS.Avalonia/PRS.Avalonia/Components/DocumentList/DocumentList.axaml.cs

@@ -3,6 +3,12 @@ using Avalonia.Controls;
 using Avalonia.Markup.Xaml;
 using CommunityToolkit.Mvvm.Input;
 using InABox.Avalonia;
+using InABox.Avalonia.Dialogs;
+using InABox.Avalonia.Platform;
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
 
 namespace PRS.Avalonia.Components;
 
@@ -33,4 +39,47 @@ public partial class DocumentList : UserControl
             x.DocumentID = shell.DocumentID;
         });
     }
+
+    public async Task<bool> AddImage<T, TOptions, TShell>(TOptions options, Func<TShell, Task<bool>>? customiseShell = null)
+        where T : MobileDocumentSource
+        where TOptions : MobileImageOptions<T>
+        where TShell : class, IEntityDocumentShell
+    {
+        if(Repository is null)
+        {
+            return false;
+        }
+        MobileDocument? file = null;
+        try
+        {
+            file = await MobileDocument.From(App.TopLevel, options);
+        }
+        catch(Exception e)
+        {
+            MobileLogging.LogExceptionMessage(e);
+            await MessageDialog.ShowError(e);
+        }
+
+        if(file?.Data is not null && file.Data.Length > 0)
+        {
+            var ext = Path.GetExtension(file.FileName);
+            file.FileName = Path.ChangeExtension(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), ext);
+            var shell = Repository.AddItem() as TShell
+                ?? throw new Exception("Repository is not of correct type");
+
+            var confirm = customiseShell is null || await customiseShell.Invoke(shell);
+            if (confirm)
+            {
+                await ProgressDialog.Execute("Saving Image", () =>
+                {
+                    shell.Thumbnail = PlatformTools.ImageTools.CreateThumbnail(file.Data, 256, 256);
+                    shell.FileName = file.FileName;
+
+                    var documentShell = EntityDocumentUtils.SaveDocument<TShell>(file, () => shell, "Created on Mobile Device");
+                });
+                return true;
+            }
+        }
+        return false;
+    }
 }

+ 2 - 2
PRS.Avalonia/PRS.Avalonia/Components/DocumentList/DocumentPageView.axaml

@@ -9,8 +9,8 @@
 	<Grid>
 		<components:DocumentViewer Name="Viewer"
 								   IsVisible="{Binding Document,Converter={x:Static ObjectConverters.IsNotNull}}"
-								   FileName="{Binding Document.FileName, FallbackValue=''}"
-								   Data="{Binding Document.Data, FallbackValue=''}"/>
+								   FileName="{Binding Document.FileName, FallbackValue=x:Null}"
+								   Data="{Binding Document.Data, FallbackValue=x:Null}"/>
 		<Label Name="NoImage"
 			   Content="File Not Available!"
 			   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

+ 2 - 1
PRS.Avalonia/PRS.Avalonia/Modules/MyTasks/TaskEditView.axaml

@@ -4,6 +4,7 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:modules="using:PRS.Avalonia.Modules"
              xmlns:components="using:InABox.Avalonia.Components"
+             xmlns:prsComponents="using:PRS.Avalonia.Components"
              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
              x:Class="PRS.Avalonia.Modules.TaskEditView"
 			 x:DataType="modules:TaskEditViewModel">
@@ -67,7 +68,7 @@
             </Border>
         </TabItem>
         <TabItem Header="Images">
-			
+			<prsComponents:DocumentList Name="Documents" Repository="{Binding Documents}"/>
         </TabItem>
         <TabItem Header="Forms">
         </TabItem>

+ 18 - 0
PRS.Avalonia/PRS.Avalonia/Modules/MyTasks/TaskEditView.axaml.cs

@@ -1,10 +1,12 @@
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Markup.Xaml;
+using InABox.Avalonia;
 using InABox.Avalonia.Components;
 using InABox.Avalonia.Converters;
 using InABox.Core;
 using System;
+using System.Threading.Tasks;
 
 namespace PRS.Avalonia.Modules;
 
@@ -39,6 +41,22 @@ public partial class TaskEditView : UserControl
         base.OnDataContextChanged(e);
         
         ViewModel = DataContext as TaskEditViewModel;
+        if(ViewModel is not null)
+        {
+            Task<bool> CustomiseShell(KanbanDocumentShell shell)
+            {
+                shell.ParentID = ViewModel?.Shell.ID ?? Guid.Empty;
+                return Task.FromResult(true);
+            }
+            ViewModel.TakePhotoAction = async () =>
+            {
+                await Documents.AddImage<MobileDocumentCameraSource, MobileDocumentCameraOptions, KanbanDocumentShell>(PhotoUtils.CreateCameraOptions(), CustomiseShell);
+            };
+            ViewModel.BrowseLibraryAction = async () =>
+            {
+                await Documents.AddImage<MobileDocumentPhotoLibrarySource, MobileDocumentPhotoLibraryOptions, KanbanDocumentShell>(PhotoUtils.CreatePhotoLibraryOptions(), CustomiseShell);
+            };
+        }
     }
 
     private void TextBox_TextChanged(object sender, TextChangedEventArgs e)

+ 17 - 4
PRS.Avalonia/PRS.Avalonia/Modules/MyTasks/TaskEditViewModel.cs

@@ -35,6 +35,12 @@ internal partial class TaskEditViewModel : ModuleViewModel
     [ObservableProperty]
     private KanbanDocumentModel _documents;
 
+    [ObservableProperty]
+    private Func<Task>? _takePhotoAction;
+
+    [ObservableProperty]
+    private Func<Task>? _browseLibraryAction;
+
     [ObservableProperty]
     private int _selectedTab;
 
@@ -89,13 +95,19 @@ internal partial class TaskEditViewModel : ModuleViewModel
 
     private async Task<bool> TakePhoto()
     {
-        await MessageDialog.ShowMessage("Unimplemented");
+        if(TakePhotoAction is not null)
+        {
+            await TakePhotoAction();
+        }
         return true;
     }
 
     private async Task<bool> BrowseLibrary()
     {
-        await MessageDialog.ShowMessage("Unimplemented");
+        if(BrowseLibraryAction is not null)
+        {
+            await BrowseLibraryAction();
+        }
         return true;
     }
 
@@ -131,10 +143,11 @@ internal partial class TaskEditViewModel : ModuleViewModel
         return true;
     }
 
-    protected override Task<TimeSpan> OnRefresh()
+    protected override async Task<TimeSpan> OnRefresh()
     {
         CanEditDescription = Shell.ManagerID == Repositories.Me.ID;
-        return Task.FromResult(TimeSpan.Zero);
+        await Documents.RefreshAsync(true);
+        return TimeSpan.Zero;
     }
 
     public void Changed()

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/ViewModelBase.cs

@@ -134,7 +134,7 @@ public abstract partial class ViewModelBase : ObservableValidator, IViewModelBas
         Save,
         KeepEditing
     }
-    protected bool ConfirmChanges(IShell item)
+    protected static bool ConfirmChanges(IShell item)
     {
         if (item.IsChanged())
         {